aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sound/pci/hda/hda_codec.c53
-rw-r--r--sound/pci/hda/hda_codec.h1
-rw-r--r--sound/pci/hda/hda_generic.c3
-rw-r--r--sound/pci/hda/hda_intel.c30
-rw-r--r--sound/pci/hda/hda_local.h14
-rw-r--r--sound/pci/hda/hda_proc.c31
-rw-r--r--sound/pci/hda/patch_analog.c36
-rw-r--r--sound/pci/hda/patch_cirrus.c14
-rw-r--r--sound/pci/hda/patch_cmedia.c11
-rw-r--r--sound/pci/hda/patch_conexant.c1
-rw-r--r--sound/pci/hda/patch_realtek.c127
-rw-r--r--sound/pci/hda/patch_si3054.c1
-rw-r--r--sound/pci/hda/patch_sigmatel.c64
-rw-r--r--sound/pci/hda/patch_via.c274
14 files changed, 491 insertions, 169 deletions
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index 950ee5cfcacf..b3554df740ff 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -931,6 +931,7 @@ static void snd_hda_codec_free(struct hda_codec *codec)
931#endif 931#endif
932 list_del(&codec->list); 932 list_del(&codec->list);
933 snd_array_free(&codec->mixers); 933 snd_array_free(&codec->mixers);
934 snd_array_free(&codec->nids);
934 codec->bus->caddr_tbl[codec->addr] = NULL; 935 codec->bus->caddr_tbl[codec->addr] = NULL;
935 if (codec->patch_ops.free) 936 if (codec->patch_ops.free)
936 codec->patch_ops.free(codec); 937 codec->patch_ops.free(codec);
@@ -985,7 +986,8 @@ int /*__devinit*/ snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr
985 mutex_init(&codec->control_mutex); 986 mutex_init(&codec->control_mutex);
986 init_hda_cache(&codec->amp_cache, sizeof(struct hda_amp_info)); 987 init_hda_cache(&codec->amp_cache, sizeof(struct hda_amp_info));
987 init_hda_cache(&codec->cmd_cache, sizeof(struct hda_cache_head)); 988 init_hda_cache(&codec->cmd_cache, sizeof(struct hda_cache_head));
988 snd_array_init(&codec->mixers, sizeof(struct hda_nid_item), 60); 989 snd_array_init(&codec->mixers, sizeof(struct hda_nid_item), 32);
990 snd_array_init(&codec->nids, sizeof(struct hda_nid_item), 32);
989 snd_array_init(&codec->init_pins, sizeof(struct hda_pincfg), 16); 991 snd_array_init(&codec->init_pins, sizeof(struct hda_pincfg), 16);
990 snd_array_init(&codec->driver_pins, sizeof(struct hda_pincfg), 16); 992 snd_array_init(&codec->driver_pins, sizeof(struct hda_pincfg), 16);
991 if (codec->bus->modelname) { 993 if (codec->bus->modelname) {
@@ -1706,7 +1708,7 @@ struct snd_kcontrol *snd_hda_find_mixer_ctl(struct hda_codec *codec,
1706EXPORT_SYMBOL_HDA(snd_hda_find_mixer_ctl); 1708EXPORT_SYMBOL_HDA(snd_hda_find_mixer_ctl);
1707 1709
1708/** 1710/**
1709 * snd_hda_ctl-add - Add a control element and assign to the codec 1711 * snd_hda_ctl_add - Add a control element and assign to the codec
1710 * @codec: HD-audio codec 1712 * @codec: HD-audio codec
1711 * @nid: corresponding NID (optional) 1713 * @nid: corresponding NID (optional)
1712 * @kctl: the control element to assign 1714 * @kctl: the control element to assign
@@ -1721,19 +1723,25 @@ EXPORT_SYMBOL_HDA(snd_hda_find_mixer_ctl);
1721 * 1723 *
1722 * snd_hda_ctl_add() checks the control subdev id field whether 1724 * snd_hda_ctl_add() checks the control subdev id field whether
1723 * #HDA_SUBDEV_NID_FLAG bit is set. If set (and @nid is zero), the lower 1725 * #HDA_SUBDEV_NID_FLAG bit is set. If set (and @nid is zero), the lower
1724 * bits value is taken as the NID to assign. 1726 * bits value is taken as the NID to assign. The #HDA_NID_ITEM_AMP bit
1727 * specifies if kctl->private_value is a HDA amplifier value.
1725 */ 1728 */
1726int snd_hda_ctl_add(struct hda_codec *codec, hda_nid_t nid, 1729int snd_hda_ctl_add(struct hda_codec *codec, hda_nid_t nid,
1727 struct snd_kcontrol *kctl) 1730 struct snd_kcontrol *kctl)
1728{ 1731{
1729 int err; 1732 int err;
1733 unsigned short flags = 0;
1730 struct hda_nid_item *item; 1734 struct hda_nid_item *item;
1731 1735
1732 if (kctl->id.subdevice & HDA_SUBDEV_NID_FLAG) { 1736 if (kctl->id.subdevice & HDA_SUBDEV_AMP_FLAG) {
1737 flags |= HDA_NID_ITEM_AMP;
1733 if (nid == 0) 1738 if (nid == 0)
1734 nid = kctl->id.subdevice & 0xffff; 1739 nid = get_amp_nid_(kctl->private_value);
1735 kctl->id.subdevice = 0;
1736 } 1740 }
1741 if ((kctl->id.subdevice & HDA_SUBDEV_NID_FLAG) != 0 && nid == 0)
1742 nid = kctl->id.subdevice & 0xffff;
1743 if (kctl->id.subdevice & (HDA_SUBDEV_NID_FLAG|HDA_SUBDEV_AMP_FLAG))
1744 kctl->id.subdevice = 0;
1737 err = snd_ctl_add(codec->bus->card, kctl); 1745 err = snd_ctl_add(codec->bus->card, kctl);
1738 if (err < 0) 1746 if (err < 0)
1739 return err; 1747 return err;
@@ -1742,11 +1750,41 @@ int snd_hda_ctl_add(struct hda_codec *codec, hda_nid_t nid,
1742 return -ENOMEM; 1750 return -ENOMEM;
1743 item->kctl = kctl; 1751 item->kctl = kctl;
1744 item->nid = nid; 1752 item->nid = nid;
1753 item->flags = flags;
1745 return 0; 1754 return 0;
1746} 1755}
1747EXPORT_SYMBOL_HDA(snd_hda_ctl_add); 1756EXPORT_SYMBOL_HDA(snd_hda_ctl_add);
1748 1757
1749/** 1758/**
1759 * snd_hda_add_nid - Assign a NID to a control element
1760 * @codec: HD-audio codec
1761 * @nid: corresponding NID (optional)
1762 * @kctl: the control element to assign
1763 * @index: index to kctl
1764 *
1765 * Add the given control element to an array inside the codec instance.
1766 * This function is used when #snd_hda_ctl_add cannot be used for 1:1
1767 * NID:KCTL mapping - for example "Capture Source" selector.
1768 */
1769int snd_hda_add_nid(struct hda_codec *codec, struct snd_kcontrol *kctl,
1770 unsigned int index, hda_nid_t nid)
1771{
1772 struct hda_nid_item *item;
1773
1774 if (nid > 0) {
1775 item = snd_array_new(&codec->nids);
1776 if (!item)
1777 return -ENOMEM;
1778 item->kctl = kctl;
1779 item->index = index;
1780 item->nid = nid;
1781 return 0;
1782 }
1783 return -EINVAL;
1784}
1785EXPORT_SYMBOL_HDA(snd_hda_add_nid);
1786
1787/**
1750 * snd_hda_ctls_clear - Clear all controls assigned to the given codec 1788 * snd_hda_ctls_clear - Clear all controls assigned to the given codec
1751 * @codec: HD-audio codec 1789 * @codec: HD-audio codec
1752 */ 1790 */
@@ -1757,6 +1795,7 @@ void snd_hda_ctls_clear(struct hda_codec *codec)
1757 for (i = 0; i < codec->mixers.used; i++) 1795 for (i = 0; i < codec->mixers.used; i++)
1758 snd_ctl_remove(codec->bus->card, items[i].kctl); 1796 snd_ctl_remove(codec->bus->card, items[i].kctl);
1759 snd_array_free(&codec->mixers); 1797 snd_array_free(&codec->mixers);
1798 snd_array_free(&codec->nids);
1760} 1799}
1761 1800
1762/* pseudo device locking 1801/* pseudo device locking
@@ -3476,6 +3515,8 @@ int snd_hda_add_new_ctls(struct hda_codec *codec, struct snd_kcontrol_new *knew)
3476 3515
3477 for (; knew->name; knew++) { 3516 for (; knew->name; knew++) {
3478 struct snd_kcontrol *kctl; 3517 struct snd_kcontrol *kctl;
3518 if (knew->iface == -1) /* skip this codec private value */
3519 continue;
3479 kctl = snd_ctl_new1(knew, codec); 3520 kctl = snd_ctl_new1(knew, codec);
3480 if (!kctl) 3521 if (!kctl)
3481 return -ENOMEM; 3522 return -ENOMEM;
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h
index 1d541b7f5547..0d08ad5bd898 100644
--- a/sound/pci/hda/hda_codec.h
+++ b/sound/pci/hda/hda_codec.h
@@ -789,6 +789,7 @@ struct hda_codec {
789 u32 *wcaps; 789 u32 *wcaps;
790 790
791 struct snd_array mixers; /* list of assigned mixer elements */ 791 struct snd_array mixers; /* list of assigned mixer elements */
792 struct snd_array nids; /* list of mapped mixer elements */
792 793
793 struct hda_cache_rec amp_cache; /* cache for amp access */ 794 struct hda_cache_rec amp_cache; /* cache for amp access */
794 struct hda_cache_rec cmd_cache; /* cache for other commands */ 795 struct hda_cache_rec cmd_cache; /* cache for other commands */
diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c
index 092c6a7c2ff3..5ea21285ee1f 100644
--- a/sound/pci/hda/hda_generic.c
+++ b/sound/pci/hda/hda_generic.c
@@ -861,7 +861,8 @@ static int build_input_controls(struct hda_codec *codec)
861 } 861 }
862 862
863 /* create input MUX if multiple sources are available */ 863 /* create input MUX if multiple sources are available */
864 err = snd_hda_ctl_add(codec, 0, snd_ctl_new1(&cap_sel, codec)); 864 err = snd_hda_ctl_add(codec, spec->adc_node->nid,
865 snd_ctl_new1(&cap_sel, codec));
865 if (err < 0) 866 if (err < 0)
866 return err; 867 return err;
867 868
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index ec9c348336cc..1f516e668d88 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -2704,32 +2704,10 @@ static struct pci_device_id azx_ids[] = {
2704 /* ULI M5461 */ 2704 /* ULI M5461 */
2705 { PCI_DEVICE(0x10b9, 0x5461), .driver_data = AZX_DRIVER_ULI }, 2705 { PCI_DEVICE(0x10b9, 0x5461), .driver_data = AZX_DRIVER_ULI },
2706 /* NVIDIA MCP */ 2706 /* NVIDIA MCP */
2707 { PCI_DEVICE(0x10de, 0x026c), .driver_data = AZX_DRIVER_NVIDIA }, 2707 { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID),
2708 { PCI_DEVICE(0x10de, 0x0371), .driver_data = AZX_DRIVER_NVIDIA }, 2708 .class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8,
2709 { PCI_DEVICE(0x10de, 0x03e4), .driver_data = AZX_DRIVER_NVIDIA }, 2709 .class_mask = 0xffffff,
2710 { PCI_DEVICE(0x10de, 0x03f0), .driver_data = AZX_DRIVER_NVIDIA }, 2710 .driver_data = AZX_DRIVER_NVIDIA },
2711 { PCI_DEVICE(0x10de, 0x044a), .driver_data = AZX_DRIVER_NVIDIA },
2712 { PCI_DEVICE(0x10de, 0x044b), .driver_data = AZX_DRIVER_NVIDIA },
2713 { PCI_DEVICE(0x10de, 0x055c), .driver_data = AZX_DRIVER_NVIDIA },
2714 { PCI_DEVICE(0x10de, 0x055d), .driver_data = AZX_DRIVER_NVIDIA },
2715 { PCI_DEVICE(0x10de, 0x0590), .driver_data = AZX_DRIVER_NVIDIA },
2716 { PCI_DEVICE(0x10de, 0x0774), .driver_data = AZX_DRIVER_NVIDIA },
2717 { PCI_DEVICE(0x10de, 0x0775), .driver_data = AZX_DRIVER_NVIDIA },
2718 { PCI_DEVICE(0x10de, 0x0776), .driver_data = AZX_DRIVER_NVIDIA },
2719 { PCI_DEVICE(0x10de, 0x0777), .driver_data = AZX_DRIVER_NVIDIA },
2720 { PCI_DEVICE(0x10de, 0x07fc), .driver_data = AZX_DRIVER_NVIDIA },
2721 { PCI_DEVICE(0x10de, 0x07fd), .driver_data = AZX_DRIVER_NVIDIA },
2722 { PCI_DEVICE(0x10de, 0x0ac0), .driver_data = AZX_DRIVER_NVIDIA },
2723 { PCI_DEVICE(0x10de, 0x0ac1), .driver_data = AZX_DRIVER_NVIDIA },
2724 { PCI_DEVICE(0x10de, 0x0ac2), .driver_data = AZX_DRIVER_NVIDIA },
2725 { PCI_DEVICE(0x10de, 0x0ac3), .driver_data = AZX_DRIVER_NVIDIA },
2726 { PCI_DEVICE(0x10de, 0x0be2), .driver_data = AZX_DRIVER_NVIDIA },
2727 { PCI_DEVICE(0x10de, 0x0be3), .driver_data = AZX_DRIVER_NVIDIA },
2728 { PCI_DEVICE(0x10de, 0x0be4), .driver_data = AZX_DRIVER_NVIDIA },
2729 { PCI_DEVICE(0x10de, 0x0d94), .driver_data = AZX_DRIVER_NVIDIA },
2730 { PCI_DEVICE(0x10de, 0x0d95), .driver_data = AZX_DRIVER_NVIDIA },
2731 { PCI_DEVICE(0x10de, 0x0d96), .driver_data = AZX_DRIVER_NVIDIA },
2732 { PCI_DEVICE(0x10de, 0x0d97), .driver_data = AZX_DRIVER_NVIDIA },
2733 /* Teradici */ 2711 /* Teradici */
2734 { PCI_DEVICE(0x6549, 0x1200), .driver_data = AZX_DRIVER_TERA }, 2712 { PCI_DEVICE(0x6549, 0x1200), .driver_data = AZX_DRIVER_TERA },
2735 /* Creative X-Fi (CA0110-IBG) */ 2713 /* Creative X-Fi (CA0110-IBG) */
diff --git a/sound/pci/hda/hda_local.h b/sound/pci/hda/hda_local.h
index 5778ae882b83..7cee364976ff 100644
--- a/sound/pci/hda/hda_local.h
+++ b/sound/pci/hda/hda_local.h
@@ -31,6 +31,7 @@
31 * in snd_hda_ctl_add(), so that this value won't appear in the outside. 31 * in snd_hda_ctl_add(), so that this value won't appear in the outside.
32 */ 32 */
33#define HDA_SUBDEV_NID_FLAG (1U << 31) 33#define HDA_SUBDEV_NID_FLAG (1U << 31)
34#define HDA_SUBDEV_AMP_FLAG (1U << 30)
34 35
35/* 36/*
36 * for mixer controls 37 * for mixer controls
@@ -42,7 +43,7 @@
42/* mono volume with index (index=0,1,...) (channel=1,2) */ 43/* mono volume with index (index=0,1,...) (channel=1,2) */
43#define HDA_CODEC_VOLUME_MONO_IDX(xname, xcidx, nid, channel, xindex, direction) \ 44#define HDA_CODEC_VOLUME_MONO_IDX(xname, xcidx, nid, channel, xindex, direction) \
44 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xcidx, \ 45 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xcidx, \
45 .subdevice = HDA_SUBDEV_NID_FLAG | (nid), \ 46 .subdevice = HDA_SUBDEV_AMP_FLAG, \
46 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | \ 47 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | \
47 SNDRV_CTL_ELEM_ACCESS_TLV_READ | \ 48 SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
48 SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK, \ 49 SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK, \
@@ -63,7 +64,7 @@
63/* mono mute switch with index (index=0,1,...) (channel=1,2) */ 64/* mono mute switch with index (index=0,1,...) (channel=1,2) */
64#define HDA_CODEC_MUTE_MONO_IDX(xname, xcidx, nid, channel, xindex, direction) \ 65#define HDA_CODEC_MUTE_MONO_IDX(xname, xcidx, nid, channel, xindex, direction) \
65 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xcidx, \ 66 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xcidx, \
66 .subdevice = HDA_SUBDEV_NID_FLAG | (nid), \ 67 .subdevice = HDA_SUBDEV_AMP_FLAG, \
67 .info = snd_hda_mixer_amp_switch_info, \ 68 .info = snd_hda_mixer_amp_switch_info, \
68 .get = snd_hda_mixer_amp_switch_get, \ 69 .get = snd_hda_mixer_amp_switch_get, \
69 .put = snd_hda_mixer_amp_switch_put, \ 70 .put = snd_hda_mixer_amp_switch_put, \
@@ -81,7 +82,7 @@
81/* special beep mono mute switch with index (index=0,1,...) (channel=1,2) */ 82/* special beep mono mute switch with index (index=0,1,...) (channel=1,2) */
82#define HDA_CODEC_MUTE_BEEP_MONO_IDX(xname, xcidx, nid, channel, xindex, direction) \ 83#define HDA_CODEC_MUTE_BEEP_MONO_IDX(xname, xcidx, nid, channel, xindex, direction) \
83 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xcidx, \ 84 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xcidx, \
84 .subdevice = HDA_SUBDEV_NID_FLAG | (nid), \ 85 .subdevice = HDA_SUBDEV_AMP_FLAG, \
85 .info = snd_hda_mixer_amp_switch_info, \ 86 .info = snd_hda_mixer_amp_switch_info, \
86 .get = snd_hda_mixer_amp_switch_get, \ 87 .get = snd_hda_mixer_amp_switch_get, \
87 .put = snd_hda_mixer_amp_switch_put_beep, \ 88 .put = snd_hda_mixer_amp_switch_put_beep, \
@@ -464,13 +465,20 @@ u32 snd_hda_query_pin_caps(struct hda_codec *codec, hda_nid_t nid);
464u32 snd_hda_pin_sense(struct hda_codec *codec, hda_nid_t nid); 465u32 snd_hda_pin_sense(struct hda_codec *codec, hda_nid_t nid);
465int snd_hda_jack_detect(struct hda_codec *codec, hda_nid_t nid); 466int snd_hda_jack_detect(struct hda_codec *codec, hda_nid_t nid);
466 467
468/* flags for hda_nid_item */
469#define HDA_NID_ITEM_AMP (1<<0)
470
467struct hda_nid_item { 471struct hda_nid_item {
468 struct snd_kcontrol *kctl; 472 struct snd_kcontrol *kctl;
473 unsigned int index;
469 hda_nid_t nid; 474 hda_nid_t nid;
475 unsigned short flags;
470}; 476};
471 477
472int snd_hda_ctl_add(struct hda_codec *codec, hda_nid_t nid, 478int snd_hda_ctl_add(struct hda_codec *codec, hda_nid_t nid,
473 struct snd_kcontrol *kctl); 479 struct snd_kcontrol *kctl);
480int snd_hda_add_nid(struct hda_codec *codec, struct snd_kcontrol *kctl,
481 unsigned int index, hda_nid_t nid);
474void snd_hda_ctls_clear(struct hda_codec *codec); 482void snd_hda_ctls_clear(struct hda_codec *codec);
475 483
476/* 484/*
diff --git a/sound/pci/hda/hda_proc.c b/sound/pci/hda/hda_proc.c
index c9afc04adac8..f97d35de66c4 100644
--- a/sound/pci/hda/hda_proc.c
+++ b/sound/pci/hda/hda_proc.c
@@ -61,18 +61,29 @@ static const char *get_wid_type_name(unsigned int wid_value)
61 return "UNKNOWN Widget"; 61 return "UNKNOWN Widget";
62} 62}
63 63
64static void print_nid_mixers(struct snd_info_buffer *buffer, 64static void print_nid_array(struct snd_info_buffer *buffer,
65 struct hda_codec *codec, hda_nid_t nid) 65 struct hda_codec *codec, hda_nid_t nid,
66 struct snd_array *array)
66{ 67{
67 int i; 68 int i;
68 struct hda_nid_item *items = codec->mixers.list; 69 struct hda_nid_item *items = array->list, *item;
69 struct snd_kcontrol *kctl; 70 struct snd_kcontrol *kctl;
70 for (i = 0; i < codec->mixers.used; i++) { 71 for (i = 0; i < array->used; i++) {
71 if (items[i].nid == nid) { 72 item = &items[i];
72 kctl = items[i].kctl; 73 if (item->nid == nid) {
74 kctl = item->kctl;
73 snd_iprintf(buffer, 75 snd_iprintf(buffer,
74 " Control: name=\"%s\", index=%i, device=%i\n", 76 " Control: name=\"%s\", index=%i, device=%i\n",
75 kctl->id.name, kctl->id.index, kctl->id.device); 77 kctl->id.name, kctl->id.index + item->index,
78 kctl->id.device);
79 if (item->flags & HDA_NID_ITEM_AMP)
80 snd_iprintf(buffer,
81 " ControlAmp: chs=%lu, dir=%s, "
82 "idx=%lu, ofs=%lu\n",
83 get_amp_channels(kctl),
84 get_amp_direction(kctl) ? "Out" : "In",
85 get_amp_index(kctl),
86 get_amp_offset(kctl));
76 } 87 }
77 } 88 }
78} 89}
@@ -528,7 +539,8 @@ static void print_gpio(struct snd_info_buffer *buffer,
528 (data & (1<<i)) ? 1 : 0, 539 (data & (1<<i)) ? 1 : 0,
529 (unsol & (1<<i)) ? 1 : 0); 540 (unsol & (1<<i)) ? 1 : 0);
530 /* FIXME: add GPO and GPI pin information */ 541 /* FIXME: add GPO and GPI pin information */
531 print_nid_mixers(buffer, codec, nid); 542 print_nid_array(buffer, codec, nid, &codec->mixers);
543 print_nid_array(buffer, codec, nid, &codec->nids);
532} 544}
533 545
534static void print_codec_info(struct snd_info_entry *entry, 546static void print_codec_info(struct snd_info_entry *entry,
@@ -608,7 +620,8 @@ static void print_codec_info(struct snd_info_entry *entry,
608 snd_iprintf(buffer, " CP"); 620 snd_iprintf(buffer, " CP");
609 snd_iprintf(buffer, "\n"); 621 snd_iprintf(buffer, "\n");
610 622
611 print_nid_mixers(buffer, codec, nid); 623 print_nid_array(buffer, codec, nid, &codec->mixers);
624 print_nid_array(buffer, codec, nid, &codec->nids);
612 print_nid_pcms(buffer, codec, nid); 625 print_nid_pcms(buffer, codec, nid);
613 626
614 /* volume knob is a special widget that always have connection 627 /* volume knob is a special widget that always have connection
diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c
index 1a36137e13ec..45ee352df329 100644
--- a/sound/pci/hda/patch_analog.c
+++ b/sound/pci/hda/patch_analog.c
@@ -174,6 +174,7 @@ static struct snd_kcontrol_new ad_beep_mixer[] = {
174static int ad198x_build_controls(struct hda_codec *codec) 174static int ad198x_build_controls(struct hda_codec *codec)
175{ 175{
176 struct ad198x_spec *spec = codec->spec; 176 struct ad198x_spec *spec = codec->spec;
177 struct snd_kcontrol *kctl;
177 unsigned int i; 178 unsigned int i;
178 int err; 179 int err;
179 180
@@ -208,9 +209,7 @@ static int ad198x_build_controls(struct hda_codec *codec)
208 if (!kctl) 209 if (!kctl)
209 return -ENOMEM; 210 return -ENOMEM;
210 kctl->private_value = spec->beep_amp; 211 kctl->private_value = spec->beep_amp;
211 err = snd_hda_ctl_add(codec, 212 err = snd_hda_ctl_add(codec, 0, kctl);
212 get_amp_nid_(spec->beep_amp),
213 kctl);
214 if (err < 0) 213 if (err < 0)
215 return err; 214 return err;
216 } 215 }
@@ -239,6 +238,27 @@ static int ad198x_build_controls(struct hda_codec *codec)
239 } 238 }
240 239
241 ad198x_free_kctls(codec); /* no longer needed */ 240 ad198x_free_kctls(codec); /* no longer needed */
241
242 /* assign Capture Source enums to NID */
243 kctl = snd_hda_find_mixer_ctl(codec, "Capture Source");
244 if (!kctl)
245 kctl = snd_hda_find_mixer_ctl(codec, "Input Source");
246 for (i = 0; kctl && i < kctl->count; i++) {
247 err = snd_hda_add_nid(codec, kctl, i, spec->capsrc_nids[i]);
248 if (err < 0)
249 return err;
250 }
251
252 /* assign IEC958 enums to NID */
253 kctl = snd_hda_find_mixer_ctl(codec,
254 SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source");
255 if (kctl) {
256 err = snd_hda_add_nid(codec, kctl, 0,
257 spec->multiout.dig_out_nid);
258 if (err < 0)
259 return err;
260 }
261
242 return 0; 262 return 0;
243} 263}
244 264
@@ -701,6 +721,7 @@ static struct snd_kcontrol_new ad1986a_laptop_eapd_mixers[] = {
701 { 721 {
702 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 722 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
703 .name = "External Amplifier", 723 .name = "External Amplifier",
724 .subdevice = HDA_SUBDEV_NID_FLAG | 0x1b,
704 .info = ad198x_eapd_info, 725 .info = ad198x_eapd_info,
705 .get = ad198x_eapd_get, 726 .get = ad198x_eapd_get,
706 .put = ad198x_eapd_put, 727 .put = ad198x_eapd_put,
@@ -808,6 +829,7 @@ static struct snd_kcontrol_new ad1986a_automute_master_mixers[] = {
808 { 829 {
809 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 830 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
810 .name = "Master Playback Switch", 831 .name = "Master Playback Switch",
832 .subdevice = HDA_SUBDEV_AMP_FLAG,
811 .info = snd_hda_mixer_amp_switch_info, 833 .info = snd_hda_mixer_amp_switch_info,
812 .get = snd_hda_mixer_amp_switch_get, 834 .get = snd_hda_mixer_amp_switch_get,
813 .put = ad1986a_hp_master_sw_put, 835 .put = ad1986a_hp_master_sw_put,
@@ -1608,6 +1630,7 @@ static struct snd_kcontrol_new ad1981_hp_mixers[] = {
1608 HDA_BIND_VOL("Master Playback Volume", &ad1981_hp_bind_master_vol), 1630 HDA_BIND_VOL("Master Playback Volume", &ad1981_hp_bind_master_vol),
1609 { 1631 {
1610 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1632 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1633 .subdevice = HDA_SUBDEV_NID_FLAG | 0x05,
1611 .name = "Master Playback Switch", 1634 .name = "Master Playback Switch",
1612 .info = ad198x_eapd_info, 1635 .info = ad198x_eapd_info,
1613 .get = ad198x_eapd_get, 1636 .get = ad198x_eapd_get,
@@ -2129,6 +2152,7 @@ static struct snd_kcontrol_new ad1988_laptop_mixers[] = {
2129 { 2152 {
2130 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2153 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2131 .name = "External Amplifier", 2154 .name = "External Amplifier",
2155 .subdevice = HDA_SUBDEV_NID_FLAG | 0x12,
2132 .info = ad198x_eapd_info, 2156 .info = ad198x_eapd_info,
2133 .get = ad198x_eapd_get, 2157 .get = ad198x_eapd_get,
2134 .put = ad198x_eapd_put, 2158 .put = ad198x_eapd_put,
@@ -2250,6 +2274,7 @@ static struct snd_kcontrol_new ad1988_spdif_out_mixers[] = {
2250 { 2274 {
2251 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2275 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2252 .name = "IEC958 Playback Source", 2276 .name = "IEC958 Playback Source",
2277 .subdevice = HDA_SUBDEV_NID_FLAG | 0x1b,
2253 .info = ad1988_spdif_playback_source_info, 2278 .info = ad1988_spdif_playback_source_info,
2254 .get = ad1988_spdif_playback_source_get, 2279 .get = ad1988_spdif_playback_source_get,
2255 .put = ad1988_spdif_playback_source_put, 2280 .put = ad1988_spdif_playback_source_put,
@@ -2582,7 +2607,7 @@ static int add_control(struct ad198x_spec *spec, int type, const char *name,
2582 if (! knew->name) 2607 if (! knew->name)
2583 return -ENOMEM; 2608 return -ENOMEM;
2584 if (get_amp_nid_(val)) 2609 if (get_amp_nid_(val))
2585 knew->subdevice = HDA_SUBDEV_NID_FLAG | get_amp_nid_(val); 2610 knew->subdevice = HDA_SUBDEV_AMP_FLAG;
2586 knew->private_value = val; 2611 knew->private_value = val;
2587 return 0; 2612 return 0;
2588} 2613}
@@ -3736,6 +3761,7 @@ static struct snd_kcontrol_new ad1884a_laptop_mixers[] = {
3736 { 3761 {
3737 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 3762 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3738 .name = "Master Playback Switch", 3763 .name = "Master Playback Switch",
3764 .subdevice = HDA_SUBDEV_AMP_FLAG,
3739 .info = snd_hda_mixer_amp_switch_info, 3765 .info = snd_hda_mixer_amp_switch_info,
3740 .get = snd_hda_mixer_amp_switch_get, 3766 .get = snd_hda_mixer_amp_switch_get,
3741 .put = ad1884a_mobile_master_sw_put, 3767 .put = ad1884a_mobile_master_sw_put,
@@ -3764,6 +3790,7 @@ static struct snd_kcontrol_new ad1884a_mobile_mixers[] = {
3764 { 3790 {
3765 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 3791 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3766 .name = "Master Playback Switch", 3792 .name = "Master Playback Switch",
3793 .subdevice = HDA_SUBDEV_AMP_FLAG,
3767 .info = snd_hda_mixer_amp_switch_info, 3794 .info = snd_hda_mixer_amp_switch_info,
3768 .get = snd_hda_mixer_amp_switch_get, 3795 .get = snd_hda_mixer_amp_switch_get,
3769 .put = ad1884a_mobile_master_sw_put, 3796 .put = ad1884a_mobile_master_sw_put,
@@ -4105,6 +4132,7 @@ static struct snd_kcontrol_new ad1984a_touchsmart_mixers[] = {
4105/* HDA_CODEC_MUTE("Master Playback Switch", 0x21, 0x0, HDA_OUTPUT),*/ 4132/* HDA_CODEC_MUTE("Master Playback Switch", 0x21, 0x0, HDA_OUTPUT),*/
4106 { 4133 {
4107 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 4134 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4135 .subdevice = HDA_SUBDEV_AMP_FLAG,
4108 .name = "Master Playback Switch", 4136 .name = "Master Playback Switch",
4109 .info = snd_hda_mixer_amp_switch_info, 4137 .info = snd_hda_mixer_amp_switch_info,
4110 .get = snd_hda_mixer_amp_switch_get, 4138 .get = snd_hda_mixer_amp_switch_get,
diff --git a/sound/pci/hda/patch_cirrus.c b/sound/pci/hda/patch_cirrus.c
index fe0423c39598..7de782a5b8f4 100644
--- a/sound/pci/hda/patch_cirrus.c
+++ b/sound/pci/hda/patch_cirrus.c
@@ -501,7 +501,8 @@ static int add_mute(struct hda_codec *codec, const char *name, int index,
501 knew.private_value = pval; 501 knew.private_value = pval;
502 snprintf(tmp, sizeof(tmp), "%s %s Switch", name, dir_sfx[dir]); 502 snprintf(tmp, sizeof(tmp), "%s %s Switch", name, dir_sfx[dir]);
503 *kctlp = snd_ctl_new1(&knew, codec); 503 *kctlp = snd_ctl_new1(&knew, codec);
504 return snd_hda_ctl_add(codec, get_amp_nid_(pval), *kctlp); 504 (*kctlp)->id.subdevice = HDA_SUBDEV_AMP_FLAG;
505 return snd_hda_ctl_add(codec, 0, *kctlp);
505} 506}
506 507
507static int add_volume(struct hda_codec *codec, const char *name, 508static int add_volume(struct hda_codec *codec, const char *name,
@@ -514,7 +515,8 @@ static int add_volume(struct hda_codec *codec, const char *name,
514 knew.private_value = pval; 515 knew.private_value = pval;
515 snprintf(tmp, sizeof(tmp), "%s %s Volume", name, dir_sfx[dir]); 516 snprintf(tmp, sizeof(tmp), "%s %s Volume", name, dir_sfx[dir]);
516 *kctlp = snd_ctl_new1(&knew, codec); 517 *kctlp = snd_ctl_new1(&knew, codec);
517 return snd_hda_ctl_add(codec, get_amp_nid_(pval), *kctlp); 518 (*kctlp)->id.subdevice = HDA_SUBDEV_AMP_FLAG;
519 return snd_hda_ctl_add(codec, 0, *kctlp);
518} 520}
519 521
520static void fix_volume_caps(struct hda_codec *codec, hda_nid_t dac) 522static void fix_volume_caps(struct hda_codec *codec, hda_nid_t dac)
@@ -751,6 +753,7 @@ static int build_input(struct hda_codec *codec)
751 spec->capture_bind[1] = make_bind_capture(codec, &snd_hda_bind_vol); 753 spec->capture_bind[1] = make_bind_capture(codec, &snd_hda_bind_vol);
752 for (i = 0; i < 2; i++) { 754 for (i = 0; i < 2; i++) {
753 struct snd_kcontrol *kctl; 755 struct snd_kcontrol *kctl;
756 int n;
754 if (!spec->capture_bind[i]) 757 if (!spec->capture_bind[i])
755 return -ENOMEM; 758 return -ENOMEM;
756 kctl = snd_ctl_new1(&cs_capture_ctls[i], codec); 759 kctl = snd_ctl_new1(&cs_capture_ctls[i], codec);
@@ -760,6 +763,13 @@ static int build_input(struct hda_codec *codec)
760 err = snd_hda_ctl_add(codec, 0, kctl); 763 err = snd_hda_ctl_add(codec, 0, kctl);
761 if (err < 0) 764 if (err < 0)
762 return err; 765 return err;
766 for (n = 0; n < AUTO_PIN_LAST; n++) {
767 if (!spec->adc_nid[n])
768 continue;
769 err = snd_hda_add_nid(codec, kctl, 0, spec->adc_nid[i]);
770 if (err < 0)
771 return err;
772 }
763 } 773 }
764 774
765 if (spec->num_inputs > 1 && !spec->mic_detect) { 775 if (spec->num_inputs > 1 && !spec->mic_detect) {
diff --git a/sound/pci/hda/patch_cmedia.c b/sound/pci/hda/patch_cmedia.c
index a45c1169762b..ff60908f4554 100644
--- a/sound/pci/hda/patch_cmedia.c
+++ b/sound/pci/hda/patch_cmedia.c
@@ -315,7 +315,8 @@ static struct hda_verb cmi9880_allout_init[] = {
315static int cmi9880_build_controls(struct hda_codec *codec) 315static int cmi9880_build_controls(struct hda_codec *codec)
316{ 316{
317 struct cmi_spec *spec = codec->spec; 317 struct cmi_spec *spec = codec->spec;
318 int err; 318 struct snd_kcontrol *kctl;
319 int i, err;
319 320
320 err = snd_hda_add_new_ctls(codec, cmi9880_basic_mixer); 321 err = snd_hda_add_new_ctls(codec, cmi9880_basic_mixer);
321 if (err < 0) 322 if (err < 0)
@@ -340,6 +341,14 @@ static int cmi9880_build_controls(struct hda_codec *codec)
340 if (err < 0) 341 if (err < 0)
341 return err; 342 return err;
342 } 343 }
344
345 /* assign Capture Source enums to NID */
346 kctl = snd_hda_find_mixer_ctl(codec, "Capture Source");
347 for (i = 0; kctl && i < kctl->count; i++) {
348 err = snd_hda_add_nid(codec, kctl, i, spec->adc_nids[i]);
349 if (err < 0)
350 return err;
351 }
343 return 0; 352 return 0;
344} 353}
345 354
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c
index c578c28f368e..947785f43b28 100644
--- a/sound/pci/hda/patch_conexant.c
+++ b/sound/pci/hda/patch_conexant.c
@@ -2187,6 +2187,7 @@ static struct snd_kcontrol_new cxt5066_mixer_master_olpc[] = {
2187 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | 2187 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
2188 SNDRV_CTL_ELEM_ACCESS_TLV_READ | 2188 SNDRV_CTL_ELEM_ACCESS_TLV_READ |
2189 SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK, 2189 SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK,
2190 .subdevice = HDA_SUBDEV_AMP_FLAG,
2190 .info = snd_hda_mixer_amp_volume_info, 2191 .info = snd_hda_mixer_amp_volume_info,
2191 .get = snd_hda_mixer_amp_volume_get, 2192 .get = snd_hda_mixer_amp_volume_get,
2192 .put = snd_hda_mixer_amp_volume_put, 2193 .put = snd_hda_mixer_amp_volume_put,
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index c7465053d6bb..6361e6b3c9c5 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -633,6 +633,7 @@ static int alc_pin_mode_put(struct snd_kcontrol *kcontrol,
633 633
634#define ALC_PIN_MODE(xname, nid, dir) \ 634#define ALC_PIN_MODE(xname, nid, dir) \
635 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \ 635 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
636 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
636 .info = alc_pin_mode_info, \ 637 .info = alc_pin_mode_info, \
637 .get = alc_pin_mode_get, \ 638 .get = alc_pin_mode_get, \
638 .put = alc_pin_mode_put, \ 639 .put = alc_pin_mode_put, \
@@ -684,6 +685,7 @@ static int alc_gpio_data_put(struct snd_kcontrol *kcontrol,
684} 685}
685#define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \ 686#define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \
686 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \ 687 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
688 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
687 .info = alc_gpio_data_info, \ 689 .info = alc_gpio_data_info, \
688 .get = alc_gpio_data_get, \ 690 .get = alc_gpio_data_get, \
689 .put = alc_gpio_data_put, \ 691 .put = alc_gpio_data_put, \
@@ -738,6 +740,7 @@ static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol,
738} 740}
739#define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \ 741#define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \
740 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \ 742 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
743 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
741 .info = alc_spdif_ctrl_info, \ 744 .info = alc_spdif_ctrl_info, \
742 .get = alc_spdif_ctrl_get, \ 745 .get = alc_spdif_ctrl_get, \
743 .put = alc_spdif_ctrl_put, \ 746 .put = alc_spdif_ctrl_put, \
@@ -791,6 +794,7 @@ static int alc_eapd_ctrl_put(struct snd_kcontrol *kcontrol,
791 794
792#define ALC_EAPD_CTRL_SWITCH(xname, nid, mask) \ 795#define ALC_EAPD_CTRL_SWITCH(xname, nid, mask) \
793 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \ 796 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
797 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
794 .info = alc_eapd_ctrl_info, \ 798 .info = alc_eapd_ctrl_info, \
795 .get = alc_eapd_ctrl_get, \ 799 .get = alc_eapd_ctrl_get, \
796 .put = alc_eapd_ctrl_put, \ 800 .put = alc_eapd_ctrl_put, \
@@ -2443,6 +2447,15 @@ static const char *alc_slave_sws[] = {
2443 * build control elements 2447 * build control elements
2444 */ 2448 */
2445 2449
2450#define NID_MAPPING (-1)
2451
2452#define SUBDEV_SPEAKER_ (0 << 6)
2453#define SUBDEV_HP_ (1 << 6)
2454#define SUBDEV_LINE_ (2 << 6)
2455#define SUBDEV_SPEAKER(x) (SUBDEV_SPEAKER_ | ((x) & 0x3f))
2456#define SUBDEV_HP(x) (SUBDEV_HP_ | ((x) & 0x3f))
2457#define SUBDEV_LINE(x) (SUBDEV_LINE_ | ((x) & 0x3f))
2458
2446static void alc_free_kctls(struct hda_codec *codec); 2459static void alc_free_kctls(struct hda_codec *codec);
2447 2460
2448#ifdef CONFIG_SND_HDA_INPUT_BEEP 2461#ifdef CONFIG_SND_HDA_INPUT_BEEP
@@ -2457,8 +2470,11 @@ static struct snd_kcontrol_new alc_beep_mixer[] = {
2457static int alc_build_controls(struct hda_codec *codec) 2470static int alc_build_controls(struct hda_codec *codec)
2458{ 2471{
2459 struct alc_spec *spec = codec->spec; 2472 struct alc_spec *spec = codec->spec;
2460 int err; 2473 struct snd_kcontrol *kctl;
2461 int i; 2474 struct snd_kcontrol_new *knew;
2475 int i, j, err;
2476 unsigned int u;
2477 hda_nid_t nid;
2462 2478
2463 for (i = 0; i < spec->num_mixers; i++) { 2479 for (i = 0; i < spec->num_mixers; i++) {
2464 err = snd_hda_add_new_ctls(codec, spec->mixers[i]); 2480 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
@@ -2499,8 +2515,7 @@ static int alc_build_controls(struct hda_codec *codec)
2499 if (!kctl) 2515 if (!kctl)
2500 return -ENOMEM; 2516 return -ENOMEM;
2501 kctl->private_value = spec->beep_amp; 2517 kctl->private_value = spec->beep_amp;
2502 err = snd_hda_ctl_add(codec, 2518 err = snd_hda_ctl_add(codec, 0, kctl);
2503 get_amp_nid_(spec->beep_amp), kctl);
2504 if (err < 0) 2519 if (err < 0)
2505 return err; 2520 return err;
2506 } 2521 }
@@ -2527,6 +2542,75 @@ static int alc_build_controls(struct hda_codec *codec)
2527 } 2542 }
2528 2543
2529 alc_free_kctls(codec); /* no longer needed */ 2544 alc_free_kctls(codec); /* no longer needed */
2545
2546 /* assign Capture Source enums to NID */
2547 kctl = snd_hda_find_mixer_ctl(codec, "Capture Source");
2548 if (!kctl)
2549 kctl = snd_hda_find_mixer_ctl(codec, "Input Source");
2550 for (i = 0; kctl && i < kctl->count; i++) {
2551 hda_nid_t *nids = spec->capsrc_nids;
2552 if (!nids)
2553 nids = spec->adc_nids;
2554 err = snd_hda_add_nid(codec, kctl, i, nids[i]);
2555 if (err < 0)
2556 return err;
2557 }
2558 if (spec->cap_mixer) {
2559 const char *kname = kctl ? kctl->id.name : NULL;
2560 for (knew = spec->cap_mixer; knew->name; knew++) {
2561 if (kname && strcmp(knew->name, kname) == 0)
2562 continue;
2563 kctl = snd_hda_find_mixer_ctl(codec, knew->name);
2564 for (i = 0; kctl && i < kctl->count; i++) {
2565 err = snd_hda_add_nid(codec, kctl, i,
2566 spec->adc_nids[i]);
2567 if (err < 0)
2568 return err;
2569 }
2570 }
2571 }
2572
2573 /* other nid->control mapping */
2574 for (i = 0; i < spec->num_mixers; i++) {
2575 for (knew = spec->mixers[i]; knew->name; knew++) {
2576 if (knew->iface != NID_MAPPING)
2577 continue;
2578 kctl = snd_hda_find_mixer_ctl(codec, knew->name);
2579 if (kctl == NULL)
2580 continue;
2581 u = knew->subdevice;
2582 for (j = 0; j < 4; j++, u >>= 8) {
2583 nid = u & 0x3f;
2584 if (nid == 0)
2585 continue;
2586 switch (u & 0xc0) {
2587 case SUBDEV_SPEAKER_:
2588 nid = spec->autocfg.speaker_pins[nid];
2589 break;
2590 case SUBDEV_LINE_:
2591 nid = spec->autocfg.line_out_pins[nid];
2592 break;
2593 case SUBDEV_HP_:
2594 nid = spec->autocfg.hp_pins[nid];
2595 break;
2596 default:
2597 continue;
2598 }
2599 err = snd_hda_add_nid(codec, kctl, 0, nid);
2600 if (err < 0)
2601 return err;
2602 }
2603 u = knew->private_value;
2604 for (j = 0; j < 4; j++, u >>= 8) {
2605 nid = u & 0xff;
2606 if (nid == 0)
2607 continue;
2608 err = snd_hda_add_nid(codec, kctl, 0, nid);
2609 if (err < 0)
2610 return err;
2611 }
2612 }
2613 }
2530 return 0; 2614 return 0;
2531} 2615}
2532 2616
@@ -3832,6 +3916,7 @@ static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
3832#define PIN_CTL_TEST(xname,nid) { \ 3916#define PIN_CTL_TEST(xname,nid) { \
3833 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 3917 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
3834 .name = xname, \ 3918 .name = xname, \
3919 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
3835 .info = alc_test_pin_ctl_info, \ 3920 .info = alc_test_pin_ctl_info, \
3836 .get = alc_test_pin_ctl_get, \ 3921 .get = alc_test_pin_ctl_get, \
3837 .put = alc_test_pin_ctl_put, \ 3922 .put = alc_test_pin_ctl_put, \
@@ -3841,6 +3926,7 @@ static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
3841#define PIN_SRC_TEST(xname,nid) { \ 3926#define PIN_SRC_TEST(xname,nid) { \
3842 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 3927 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
3843 .name = xname, \ 3928 .name = xname, \
3929 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
3844 .info = alc_test_pin_src_info, \ 3930 .info = alc_test_pin_src_info, \
3845 .get = alc_test_pin_src_get, \ 3931 .get = alc_test_pin_src_get, \
3846 .put = alc_test_pin_src_put, \ 3932 .put = alc_test_pin_src_put, \
@@ -4380,7 +4466,7 @@ static int add_control(struct alc_spec *spec, int type, const char *name,
4380 if (!knew->name) 4466 if (!knew->name)
4381 return -ENOMEM; 4467 return -ENOMEM;
4382 if (get_amp_nid_(val)) 4468 if (get_amp_nid_(val))
4383 knew->subdevice = HDA_SUBDEV_NID_FLAG | get_amp_nid_(val); 4469 knew->subdevice = HDA_SUBDEV_AMP_FLAG;
4384 knew->private_value = val; 4470 knew->private_value = val;
4385 return 0; 4471 return 0;
4386} 4472}
@@ -5131,6 +5217,7 @@ static struct snd_kcontrol_new alc260_hp_output_mixer[] = {
5131 { 5217 {
5132 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 5218 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5133 .name = "Master Playback Switch", 5219 .name = "Master Playback Switch",
5220 .subdevice = HDA_SUBDEV_NID_FLAG | 0x11,
5134 .info = snd_ctl_boolean_mono_info, 5221 .info = snd_ctl_boolean_mono_info,
5135 .get = alc260_hp_master_sw_get, 5222 .get = alc260_hp_master_sw_get,
5136 .put = alc260_hp_master_sw_put, 5223 .put = alc260_hp_master_sw_put,
@@ -5169,6 +5256,7 @@ static struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
5169 { 5256 {
5170 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 5257 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5171 .name = "Master Playback Switch", 5258 .name = "Master Playback Switch",
5259 .subdevice = HDA_SUBDEV_NID_FLAG | 0x11,
5172 .info = snd_ctl_boolean_mono_info, 5260 .info = snd_ctl_boolean_mono_info,
5173 .get = alc260_hp_master_sw_get, 5261 .get = alc260_hp_master_sw_get,
5174 .put = alc260_hp_master_sw_put, 5262 .put = alc260_hp_master_sw_put,
@@ -10248,8 +10336,14 @@ static int alc262_hp_master_sw_put(struct snd_kcontrol *kcontrol,
10248 .info = snd_ctl_boolean_mono_info, \ 10336 .info = snd_ctl_boolean_mono_info, \
10249 .get = alc262_hp_master_sw_get, \ 10337 .get = alc262_hp_master_sw_get, \
10250 .put = alc262_hp_master_sw_put, \ 10338 .put = alc262_hp_master_sw_put, \
10339 }, \
10340 { \
10341 .iface = NID_MAPPING, \
10342 .name = "Master Playback Switch", \
10343 .private_value = 0x15 | (0x16 << 8) | (0x1b << 16), \
10251 } 10344 }
10252 10345
10346
10253static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = { 10347static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
10254 ALC262_HP_MASTER_SWITCH, 10348 ALC262_HP_MASTER_SWITCH,
10255 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 10349 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
@@ -10407,6 +10501,12 @@ static int alc262_hippo_master_sw_put(struct snd_kcontrol *kcontrol,
10407 .info = snd_ctl_boolean_mono_info, \ 10501 .info = snd_ctl_boolean_mono_info, \
10408 .get = alc262_hippo_master_sw_get, \ 10502 .get = alc262_hippo_master_sw_get, \
10409 .put = alc262_hippo_master_sw_put, \ 10503 .put = alc262_hippo_master_sw_put, \
10504 }, \
10505 { \
10506 .iface = NID_MAPPING, \
10507 .name = "Master Playback Switch", \
10508 .subdevice = SUBDEV_HP(0) | (SUBDEV_LINE(0) << 8) | \
10509 (SUBDEV_SPEAKER(0) << 16), \
10410 } 10510 }
10411 10511
10412static struct snd_kcontrol_new alc262_hippo_mixer[] = { 10512static struct snd_kcontrol_new alc262_hippo_mixer[] = {
@@ -10887,11 +10987,17 @@ static struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
10887 { 10987 {
10888 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 10988 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10889 .name = "Master Playback Switch", 10989 .name = "Master Playback Switch",
10990 .subdevice = HDA_SUBDEV_AMP_FLAG,
10890 .info = snd_hda_mixer_amp_switch_info, 10991 .info = snd_hda_mixer_amp_switch_info,
10891 .get = snd_hda_mixer_amp_switch_get, 10992 .get = snd_hda_mixer_amp_switch_get,
10892 .put = alc262_fujitsu_master_sw_put, 10993 .put = alc262_fujitsu_master_sw_put,
10893 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), 10994 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
10894 }, 10995 },
10996 {
10997 .iface = NID_MAPPING,
10998 .name = "Master Playback Switch",
10999 .private_value = 0x1b,
11000 },
10895 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 11001 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10896 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 11002 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
10897 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 11003 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
@@ -10922,6 +11028,7 @@ static struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = {
10922 { 11028 {
10923 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 11029 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10924 .name = "Master Playback Switch", 11030 .name = "Master Playback Switch",
11031 .subdevice = HDA_SUBDEV_AMP_FLAG,
10925 .info = snd_hda_mixer_amp_switch_info, 11032 .info = snd_hda_mixer_amp_switch_info,
10926 .get = snd_hda_mixer_amp_switch_get, 11033 .get = snd_hda_mixer_amp_switch_get,
10927 .put = alc262_lenovo_3000_master_sw_put, 11034 .put = alc262_lenovo_3000_master_sw_put,
@@ -11076,6 +11183,11 @@ static struct snd_kcontrol_new alc262_ultra_capture_mixer[] = {
11076 .get = alc_mux_enum_get, 11183 .get = alc_mux_enum_get,
11077 .put = alc262_ultra_mux_enum_put, 11184 .put = alc262_ultra_mux_enum_put,
11078 }, 11185 },
11186 {
11187 .iface = NID_MAPPING,
11188 .name = "Capture Source",
11189 .private_value = 0x15,
11190 },
11079 { } /* end */ 11191 { } /* end */
11080}; 11192};
11081 11193
@@ -12094,6 +12206,7 @@ static struct snd_kcontrol_new alc268_acer_aspire_one_mixer[] = {
12094 { 12206 {
12095 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 12207 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12096 .name = "Master Playback Switch", 12208 .name = "Master Playback Switch",
12209 .subdevice = HDA_SUBDEV_AMP_FLAG,
12097 .info = snd_hda_mixer_amp_switch_info, 12210 .info = snd_hda_mixer_amp_switch_info,
12098 .get = snd_hda_mixer_amp_switch_get, 12211 .get = snd_hda_mixer_amp_switch_get,
12099 .put = alc268_acer_master_sw_put, 12212 .put = alc268_acer_master_sw_put,
@@ -12109,6 +12222,7 @@ static struct snd_kcontrol_new alc268_acer_mixer[] = {
12109 { 12222 {
12110 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 12223 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12111 .name = "Master Playback Switch", 12224 .name = "Master Playback Switch",
12225 .subdevice = HDA_SUBDEV_AMP_FLAG,
12112 .info = snd_hda_mixer_amp_switch_info, 12226 .info = snd_hda_mixer_amp_switch_info,
12113 .get = snd_hda_mixer_amp_switch_get, 12227 .get = snd_hda_mixer_amp_switch_get,
12114 .put = alc268_acer_master_sw_put, 12228 .put = alc268_acer_master_sw_put,
@@ -12126,6 +12240,7 @@ static struct snd_kcontrol_new alc268_acer_dmic_mixer[] = {
12126 { 12240 {
12127 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 12241 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12128 .name = "Master Playback Switch", 12242 .name = "Master Playback Switch",
12243 .subdevice = HDA_SUBDEV_AMP_FLAG,
12129 .info = snd_hda_mixer_amp_switch_info, 12244 .info = snd_hda_mixer_amp_switch_info,
12130 .get = snd_hda_mixer_amp_switch_get, 12245 .get = snd_hda_mixer_amp_switch_get,
12131 .put = alc268_acer_master_sw_put, 12246 .put = alc268_acer_master_sw_put,
@@ -13078,6 +13193,7 @@ static struct snd_kcontrol_new alc269_quanta_fl1_mixer[] = {
13078 { 13193 {
13079 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 13194 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13080 .name = "Master Playback Switch", 13195 .name = "Master Playback Switch",
13196 .subdevice = HDA_SUBDEV_AMP_FLAG,
13081 .info = snd_hda_mixer_amp_switch_info, 13197 .info = snd_hda_mixer_amp_switch_info,
13082 .get = snd_hda_mixer_amp_switch_get, 13198 .get = snd_hda_mixer_amp_switch_get,
13083 .put = alc268_acer_master_sw_put, 13199 .put = alc268_acer_master_sw_put,
@@ -13098,6 +13214,7 @@ static struct snd_kcontrol_new alc269_lifebook_mixer[] = {
13098 { 13214 {
13099 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 13215 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13100 .name = "Master Playback Switch", 13216 .name = "Master Playback Switch",
13217 .subdevice = HDA_SUBDEV_AMP_FLAG,
13101 .info = snd_hda_mixer_amp_switch_info, 13218 .info = snd_hda_mixer_amp_switch_info,
13102 .get = snd_hda_mixer_amp_switch_get, 13219 .get = snd_hda_mixer_amp_switch_get,
13103 .put = alc268_acer_master_sw_put, 13220 .put = alc268_acer_master_sw_put,
diff --git a/sound/pci/hda/patch_si3054.c b/sound/pci/hda/patch_si3054.c
index 43b436c5d01b..f419ee8d75f0 100644
--- a/sound/pci/hda/patch_si3054.c
+++ b/sound/pci/hda/patch_si3054.c
@@ -122,6 +122,7 @@ static int si3054_switch_put(struct snd_kcontrol *kcontrol,
122#define SI3054_KCONTROL(kname,reg,mask) { \ 122#define SI3054_KCONTROL(kname,reg,mask) { \
123 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 123 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
124 .name = kname, \ 124 .name = kname, \
125 .subdevice = HDA_SUBDEV_NID_FLAG | reg, \
125 .info = si3054_switch_info, \ 126 .info = si3054_switch_info, \
126 .get = si3054_switch_get, \ 127 .get = si3054_switch_get, \
127 .put = si3054_switch_put, \ 128 .put = si3054_switch_put, \
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
index eeda7beeb57a..247be19e17b8 100644
--- a/sound/pci/hda/patch_sigmatel.c
+++ b/sound/pci/hda/patch_sigmatel.c
@@ -2688,7 +2688,7 @@ static struct snd_kcontrol_new *
2688stac_control_new(struct sigmatel_spec *spec, 2688stac_control_new(struct sigmatel_spec *spec,
2689 struct snd_kcontrol_new *ktemp, 2689 struct snd_kcontrol_new *ktemp,
2690 const char *name, 2690 const char *name,
2691 hda_nid_t nid) 2691 unsigned int subdev)
2692{ 2692{
2693 struct snd_kcontrol_new *knew; 2693 struct snd_kcontrol_new *knew;
2694 2694
@@ -2704,8 +2704,7 @@ stac_control_new(struct sigmatel_spec *spec,
2704 spec->kctls.alloced--; 2704 spec->kctls.alloced--;
2705 return NULL; 2705 return NULL;
2706 } 2706 }
2707 if (nid) 2707 knew->subdevice = subdev;
2708 knew->subdevice = HDA_SUBDEV_NID_FLAG | nid;
2709 return knew; 2708 return knew;
2710} 2709}
2711 2710
@@ -2715,7 +2714,7 @@ static int stac92xx_add_control_temp(struct sigmatel_spec *spec,
2715 unsigned long val) 2714 unsigned long val)
2716{ 2715{
2717 struct snd_kcontrol_new *knew = stac_control_new(spec, ktemp, name, 2716 struct snd_kcontrol_new *knew = stac_control_new(spec, ktemp, name,
2718 get_amp_nid_(val)); 2717 HDA_SUBDEV_AMP_FLAG);
2719 if (!knew) 2718 if (!knew)
2720 return -ENOMEM; 2719 return -ENOMEM;
2721 knew->index = idx; 2720 knew->index = idx;
@@ -5407,6 +5406,54 @@ static int stac92hd71bxx_connected_smuxes(struct hda_codec *codec,
5407 return 0; 5406 return 0;
5408} 5407}
5409 5408
5409/* HP dv7 bass switch - GPIO5 */
5410#define stac_hp_bass_gpio_info snd_ctl_boolean_mono_info
5411static int stac_hp_bass_gpio_get(struct snd_kcontrol *kcontrol,
5412 struct snd_ctl_elem_value *ucontrol)
5413{
5414 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
5415 struct sigmatel_spec *spec = codec->spec;
5416 ucontrol->value.integer.value[0] = !!(spec->gpio_data & 0x20);
5417 return 0;
5418}
5419
5420static int stac_hp_bass_gpio_put(struct snd_kcontrol *kcontrol,
5421 struct snd_ctl_elem_value *ucontrol)
5422{
5423 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
5424 struct sigmatel_spec *spec = codec->spec;
5425 unsigned int gpio_data;
5426
5427 gpio_data = (spec->gpio_data & ~0x20) |
5428 (ucontrol->value.integer.value[0] ? 0x20 : 0);
5429 if (gpio_data == spec->gpio_data)
5430 return 0;
5431 spec->gpio_data = gpio_data;
5432 stac_gpio_set(codec, spec->gpio_mask, spec->gpio_dir, spec->gpio_data);
5433 return 1;
5434}
5435
5436static struct snd_kcontrol_new stac_hp_bass_sw_ctrl = {
5437 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5438 .info = stac_hp_bass_gpio_info,
5439 .get = stac_hp_bass_gpio_get,
5440 .put = stac_hp_bass_gpio_put,
5441};
5442
5443static int stac_add_hp_bass_switch(struct hda_codec *codec)
5444{
5445 struct sigmatel_spec *spec = codec->spec;
5446
5447 if (!stac_control_new(spec, &stac_hp_bass_sw_ctrl,
5448 "Bass Speaker Playback Switch", 0))
5449 return -ENOMEM;
5450
5451 spec->gpio_mask |= 0x20;
5452 spec->gpio_dir |= 0x20;
5453 spec->gpio_data |= 0x20;
5454 return 0;
5455}
5456
5410static int patch_stac92hd71bxx(struct hda_codec *codec) 5457static int patch_stac92hd71bxx(struct hda_codec *codec)
5411{ 5458{
5412 struct sigmatel_spec *spec; 5459 struct sigmatel_spec *spec;
@@ -5647,6 +5694,15 @@ again:
5647 return err; 5694 return err;
5648 } 5695 }
5649 5696
5697 /* enable bass on HP dv7 */
5698 if (spec->board_config == STAC_HP_DV5) {
5699 unsigned int cap;
5700 cap = snd_hda_param_read(codec, 0x1, AC_PAR_GPIO_CAP);
5701 cap &= AC_GPIO_IO_COUNT;
5702 if (cap >= 6)
5703 stac_add_hp_bass_switch(codec);
5704 }
5705
5650 codec->proc_widget_hook = stac92hd7x_proc_hook; 5706 codec->proc_widget_hook = stac92hd7x_proc_hook;
5651 5707
5652 return 0; 5708 return 0;
diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c
index b70e26ad263f..9ddc37300f6b 100644
--- a/sound/pci/hda/patch_via.c
+++ b/sound/pci/hda/patch_via.c
@@ -54,6 +54,8 @@
54#include "hda_codec.h" 54#include "hda_codec.h"
55#include "hda_local.h" 55#include "hda_local.h"
56 56
57#define NID_MAPPING (-1)
58
57/* amp values */ 59/* amp values */
58#define AMP_VAL_IDX_SHIFT 19 60#define AMP_VAL_IDX_SHIFT 19
59#define AMP_VAL_IDX_MASK (0x0f<<19) 61#define AMP_VAL_IDX_MASK (0x0f<<19)
@@ -157,6 +159,19 @@ struct via_spec {
157#endif 159#endif
158}; 160};
159 161
162static struct via_spec * via_new_spec(struct hda_codec *codec)
163{
164 struct via_spec *spec;
165
166 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
167 if (spec == NULL)
168 return NULL;
169
170 codec->spec = spec;
171 spec->codec = codec;
172 return spec;
173}
174
160static enum VIA_HDA_CODEC get_codec_type(struct hda_codec *codec) 175static enum VIA_HDA_CODEC get_codec_type(struct hda_codec *codec)
161{ 176{
162 u32 vendor_id = codec->vendor_id; 177 u32 vendor_id = codec->vendor_id;
@@ -443,11 +458,27 @@ static int via_add_control(struct via_spec *spec, int type, const char *name,
443 if (!knew->name) 458 if (!knew->name)
444 return -ENOMEM; 459 return -ENOMEM;
445 if (get_amp_nid_(val)) 460 if (get_amp_nid_(val))
446 knew->subdevice = HDA_SUBDEV_NID_FLAG | get_amp_nid_(val); 461 knew->subdevice = HDA_SUBDEV_AMP_FLAG;
447 knew->private_value = val; 462 knew->private_value = val;
448 return 0; 463 return 0;
449} 464}
450 465
466static struct snd_kcontrol_new *via_clone_control(struct via_spec *spec,
467 struct snd_kcontrol_new *tmpl)
468{
469 struct snd_kcontrol_new *knew;
470
471 snd_array_init(&spec->kctls, sizeof(*knew), 32);
472 knew = snd_array_new(&spec->kctls);
473 if (!knew)
474 return NULL;
475 *knew = *tmpl;
476 knew->name = kstrdup(tmpl->name, GFP_KERNEL);
477 if (!knew->name)
478 return NULL;
479 return 0;
480}
481
451static void via_free_kctls(struct hda_codec *codec) 482static void via_free_kctls(struct hda_codec *codec)
452{ 483{
453 struct via_spec *spec = codec->spec; 484 struct via_spec *spec = codec->spec;
@@ -1088,24 +1119,9 @@ static int via_independent_hp_get(struct snd_kcontrol *kcontrol,
1088 struct snd_ctl_elem_value *ucontrol) 1119 struct snd_ctl_elem_value *ucontrol)
1089{ 1120{
1090 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 1121 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1091 struct via_spec *spec = codec->spec; 1122 hda_nid_t nid = kcontrol->private_value;
1092 hda_nid_t nid;
1093 unsigned int pinsel; 1123 unsigned int pinsel;
1094 1124
1095 switch (spec->codec_type) {
1096 case VT1718S:
1097 nid = 0x34;
1098 break;
1099 case VT2002P:
1100 nid = 0x35;
1101 break;
1102 case VT1812:
1103 nid = 0x3d;
1104 break;
1105 default:
1106 nid = spec->autocfg.hp_pins[0];
1107 break;
1108 }
1109 /* use !! to translate conn sel 2 for VT1718S */ 1125 /* use !! to translate conn sel 2 for VT1718S */
1110 pinsel = !!snd_hda_codec_read(codec, nid, 0, 1126 pinsel = !!snd_hda_codec_read(codec, nid, 0,
1111 AC_VERB_GET_CONNECT_SEL, 1127 AC_VERB_GET_CONNECT_SEL,
@@ -1127,29 +1143,24 @@ static void activate_ctl(struct hda_codec *codec, const char *name, int active)
1127 } 1143 }
1128} 1144}
1129 1145
1146static hda_nid_t side_mute_channel(struct via_spec *spec)
1147{
1148 switch (spec->codec_type) {
1149 case VT1708: return 0x1b;
1150 case VT1709_10CH: return 0x29;
1151 case VT1708B_8CH: /* fall thru */
1152 case VT1708S: return 0x27;
1153 default: return 0;
1154 }
1155}
1156
1130static int update_side_mute_status(struct hda_codec *codec) 1157static int update_side_mute_status(struct hda_codec *codec)
1131{ 1158{
1132 /* mute side channel */ 1159 /* mute side channel */
1133 struct via_spec *spec = codec->spec; 1160 struct via_spec *spec = codec->spec;
1134 unsigned int parm = spec->hp_independent_mode 1161 unsigned int parm = spec->hp_independent_mode
1135 ? AMP_OUT_MUTE : AMP_OUT_UNMUTE; 1162 ? AMP_OUT_MUTE : AMP_OUT_UNMUTE;
1136 hda_nid_t sw3; 1163 hda_nid_t sw3 = side_mute_channel(spec);
1137
1138 switch (spec->codec_type) {
1139 case VT1708:
1140 sw3 = 0x1b;
1141 break;
1142 case VT1709_10CH:
1143 sw3 = 0x29;
1144 break;
1145 case VT1708B_8CH:
1146 case VT1708S:
1147 sw3 = 0x27;
1148 break;
1149 default:
1150 sw3 = 0;
1151 break;
1152 }
1153 1164
1154 if (sw3) 1165 if (sw3)
1155 snd_hda_codec_write(codec, sw3, 0, AC_VERB_SET_AMP_GAIN_MUTE, 1166 snd_hda_codec_write(codec, sw3, 0, AC_VERB_SET_AMP_GAIN_MUTE,
@@ -1162,28 +1173,11 @@ static int via_independent_hp_put(struct snd_kcontrol *kcontrol,
1162{ 1173{
1163 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 1174 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1164 struct via_spec *spec = codec->spec; 1175 struct via_spec *spec = codec->spec;
1165 hda_nid_t nid = spec->autocfg.hp_pins[0]; 1176 hda_nid_t nid = kcontrol->private_value;
1166 unsigned int pinsel = ucontrol->value.enumerated.item[0]; 1177 unsigned int pinsel = ucontrol->value.enumerated.item[0];
1167 /* Get Independent Mode index of headphone pin widget */ 1178 /* Get Independent Mode index of headphone pin widget */
1168 spec->hp_independent_mode = spec->hp_independent_mode_index == pinsel 1179 spec->hp_independent_mode = spec->hp_independent_mode_index == pinsel
1169 ? 1 : 0; 1180 ? 1 : 0;
1170
1171 switch (spec->codec_type) {
1172 case VT1718S:
1173 nid = 0x34;
1174 pinsel = pinsel ? 2 : 0; /* indep HP use AOW4 (index 2) */
1175 spec->multiout.num_dacs = 4;
1176 break;
1177 case VT2002P:
1178 nid = 0x35;
1179 break;
1180 case VT1812:
1181 nid = 0x3d;
1182 break;
1183 default:
1184 nid = spec->autocfg.hp_pins[0];
1185 break;
1186 }
1187 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, pinsel); 1181 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, pinsel);
1188 1182
1189 if (spec->multiout.hp_nid && spec->multiout.hp_nid 1183 if (spec->multiout.hp_nid && spec->multiout.hp_nid
@@ -1207,18 +1201,55 @@ static int via_independent_hp_put(struct snd_kcontrol *kcontrol,
1207 return 0; 1201 return 0;
1208} 1202}
1209 1203
1210static struct snd_kcontrol_new via_hp_mixer[] = { 1204static struct snd_kcontrol_new via_hp_mixer[2] = {
1211 { 1205 {
1212 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1206 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1213 .name = "Independent HP", 1207 .name = "Independent HP",
1214 .count = 1,
1215 .info = via_independent_hp_info, 1208 .info = via_independent_hp_info,
1216 .get = via_independent_hp_get, 1209 .get = via_independent_hp_get,
1217 .put = via_independent_hp_put, 1210 .put = via_independent_hp_put,
1218 }, 1211 },
1219 { } /* end */ 1212 {
1213 .iface = NID_MAPPING,
1214 .name = "Independent HP",
1215 },
1220}; 1216};
1221 1217
1218static int via_hp_build(struct via_spec *spec)
1219{
1220 struct snd_kcontrol_new *knew;
1221 hda_nid_t nid;
1222
1223 knew = via_clone_control(spec, &via_hp_mixer[0]);
1224 if (knew == NULL)
1225 return -ENOMEM;
1226
1227 switch (spec->codec_type) {
1228 case VT1718S:
1229 nid = 0x34;
1230 break;
1231 case VT2002P:
1232 nid = 0x35;
1233 break;
1234 case VT1812:
1235 nid = 0x3d;
1236 break;
1237 default:
1238 nid = spec->autocfg.hp_pins[0];
1239 break;
1240 }
1241
1242 knew->subdevice = HDA_SUBDEV_NID_FLAG | nid;
1243 knew->private_value = nid;
1244
1245 knew = via_clone_control(spec, &via_hp_mixer[1]);
1246 if (knew == NULL)
1247 return -ENOMEM;
1248 knew->subdevice = side_mute_channel(spec);
1249
1250 return 0;
1251}
1252
1222static void notify_aa_path_ctls(struct hda_codec *codec) 1253static void notify_aa_path_ctls(struct hda_codec *codec)
1223{ 1254{
1224 int i; 1255 int i;
@@ -1376,7 +1407,7 @@ static int via_smart51_put(struct snd_kcontrol *kcontrol,
1376 return 1; 1407 return 1;
1377} 1408}
1378 1409
1379static struct snd_kcontrol_new via_smart51_mixer[] = { 1410static struct snd_kcontrol_new via_smart51_mixer[2] = {
1380 { 1411 {
1381 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1412 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1382 .name = "Smart 5.1", 1413 .name = "Smart 5.1",
@@ -1385,9 +1416,36 @@ static struct snd_kcontrol_new via_smart51_mixer[] = {
1385 .get = via_smart51_get, 1416 .get = via_smart51_get,
1386 .put = via_smart51_put, 1417 .put = via_smart51_put,
1387 }, 1418 },
1388 {} /* end */ 1419 {
1420 .iface = NID_MAPPING,
1421 .name = "Smart 5.1",
1422 }
1389}; 1423};
1390 1424
1425static int via_smart51_build(struct via_spec *spec)
1426{
1427 struct snd_kcontrol_new *knew;
1428 int index[] = { AUTO_PIN_MIC, AUTO_PIN_FRONT_MIC, AUTO_PIN_LINE };
1429 hda_nid_t nid;
1430 int i;
1431
1432 knew = via_clone_control(spec, &via_smart51_mixer[0]);
1433 if (knew == NULL)
1434 return -ENOMEM;
1435
1436 for (i = 0; i < ARRAY_SIZE(index); i++) {
1437 nid = spec->autocfg.input_pins[index[i]];
1438 if (nid) {
1439 knew = via_clone_control(spec, &via_smart51_mixer[1]);
1440 if (knew == NULL)
1441 return -ENOMEM;
1442 knew->subdevice = nid;
1443 }
1444 }
1445
1446 return 0;
1447}
1448
1391/* capture mixer elements */ 1449/* capture mixer elements */
1392static struct snd_kcontrol_new vt1708_capture_mixer[] = { 1450static struct snd_kcontrol_new vt1708_capture_mixer[] = {
1393 HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_INPUT), 1451 HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_INPUT),
@@ -1819,8 +1877,9 @@ static struct hda_pcm_stream vt1708_pcm_digital_capture = {
1819static int via_build_controls(struct hda_codec *codec) 1877static int via_build_controls(struct hda_codec *codec)
1820{ 1878{
1821 struct via_spec *spec = codec->spec; 1879 struct via_spec *spec = codec->spec;
1822 int err; 1880 struct snd_kcontrol *kctl;
1823 int i; 1881 struct snd_kcontrol_new *knew;
1882 int err, i;
1824 1883
1825 for (i = 0; i < spec->num_mixers; i++) { 1884 for (i = 0; i < spec->num_mixers; i++) {
1826 err = snd_hda_add_new_ctls(codec, spec->mixers[i]); 1885 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
@@ -1845,6 +1904,27 @@ static int via_build_controls(struct hda_codec *codec)
1845 return err; 1904 return err;
1846 } 1905 }
1847 1906
1907 /* assign Capture Source enums to NID */
1908 kctl = snd_hda_find_mixer_ctl(codec, "Input Source");
1909 for (i = 0; kctl && i < kctl->count; i++) {
1910 err = snd_hda_add_nid(codec, kctl, i, spec->mux_nids[i]);
1911 if (err < 0)
1912 return err;
1913 }
1914
1915 /* other nid->control mapping */
1916 for (i = 0; i < spec->num_mixers; i++) {
1917 for (knew = spec->mixers[i]; knew->name; knew++) {
1918 if (knew->iface != NID_MAPPING)
1919 continue;
1920 kctl = snd_hda_find_mixer_ctl(codec, knew->name);
1921 if (kctl == NULL)
1922 continue;
1923 err = snd_hda_add_nid(codec, kctl, 0,
1924 knew->subdevice);
1925 }
1926 }
1927
1848 /* init power states */ 1928 /* init power states */
1849 set_jack_power_state(codec); 1929 set_jack_power_state(codec);
1850 analog_low_current_mode(codec, 1); 1930 analog_low_current_mode(codec, 1);
@@ -2481,9 +2561,9 @@ static int vt1708_parse_auto_config(struct hda_codec *codec)
2481 spec->input_mux = &spec->private_imux[0]; 2561 spec->input_mux = &spec->private_imux[0];
2482 2562
2483 if (spec->hp_mux) 2563 if (spec->hp_mux)
2484 spec->mixers[spec->num_mixers++] = via_hp_mixer; 2564 via_hp_build(spec);
2485 2565
2486 spec->mixers[spec->num_mixers++] = via_smart51_mixer; 2566 via_smart51_build(spec);
2487 return 1; 2567 return 1;
2488} 2568}
2489 2569
@@ -2554,12 +2634,10 @@ static int patch_vt1708(struct hda_codec *codec)
2554 int err; 2634 int err;
2555 2635
2556 /* create a codec specific record */ 2636 /* create a codec specific record */
2557 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 2637 spec = via_new_spec(codec);
2558 if (spec == NULL) 2638 if (spec == NULL)
2559 return -ENOMEM; 2639 return -ENOMEM;
2560 2640
2561 codec->spec = spec;
2562
2563 /* automatic parse from the BIOS config */ 2641 /* automatic parse from the BIOS config */
2564 err = vt1708_parse_auto_config(codec); 2642 err = vt1708_parse_auto_config(codec);
2565 if (err < 0) { 2643 if (err < 0) {
@@ -2597,7 +2675,6 @@ static int patch_vt1708(struct hda_codec *codec)
2597#ifdef CONFIG_SND_HDA_POWER_SAVE 2675#ifdef CONFIG_SND_HDA_POWER_SAVE
2598 spec->loopback.amplist = vt1708_loopbacks; 2676 spec->loopback.amplist = vt1708_loopbacks;
2599#endif 2677#endif
2600 spec->codec = codec;
2601 INIT_DELAYED_WORK(&spec->vt1708_hp_work, vt1708_update_hp_jack_state); 2678 INIT_DELAYED_WORK(&spec->vt1708_hp_work, vt1708_update_hp_jack_state);
2602 return 0; 2679 return 0;
2603} 2680}
@@ -3010,9 +3087,9 @@ static int vt1709_parse_auto_config(struct hda_codec *codec)
3010 spec->input_mux = &spec->private_imux[0]; 3087 spec->input_mux = &spec->private_imux[0];
3011 3088
3012 if (spec->hp_mux) 3089 if (spec->hp_mux)
3013 spec->mixers[spec->num_mixers++] = via_hp_mixer; 3090 via_hp_build(spec);
3014 3091
3015 spec->mixers[spec->num_mixers++] = via_smart51_mixer; 3092 via_smart51_build(spec);
3016 return 1; 3093 return 1;
3017} 3094}
3018 3095
@@ -3032,12 +3109,10 @@ static int patch_vt1709_10ch(struct hda_codec *codec)
3032 int err; 3109 int err;
3033 3110
3034 /* create a codec specific record */ 3111 /* create a codec specific record */
3035 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 3112 spec = via_new_spec(codec);
3036 if (spec == NULL) 3113 if (spec == NULL)
3037 return -ENOMEM; 3114 return -ENOMEM;
3038 3115
3039 codec->spec = spec;
3040
3041 err = vt1709_parse_auto_config(codec); 3116 err = vt1709_parse_auto_config(codec);
3042 if (err < 0) { 3117 if (err < 0) {
3043 via_free(codec); 3118 via_free(codec);
@@ -3126,12 +3201,10 @@ static int patch_vt1709_6ch(struct hda_codec *codec)
3126 int err; 3201 int err;
3127 3202
3128 /* create a codec specific record */ 3203 /* create a codec specific record */
3129 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 3204 spec = via_new_spec(codec);
3130 if (spec == NULL) 3205 if (spec == NULL)
3131 return -ENOMEM; 3206 return -ENOMEM;
3132 3207
3133 codec->spec = spec;
3134
3135 err = vt1709_parse_auto_config(codec); 3208 err = vt1709_parse_auto_config(codec);
3136 if (err < 0) { 3209 if (err < 0) {
3137 via_free(codec); 3210 via_free(codec);
@@ -3581,9 +3654,9 @@ static int vt1708B_parse_auto_config(struct hda_codec *codec)
3581 spec->input_mux = &spec->private_imux[0]; 3654 spec->input_mux = &spec->private_imux[0];
3582 3655
3583 if (spec->hp_mux) 3656 if (spec->hp_mux)
3584 spec->mixers[spec->num_mixers++] = via_hp_mixer; 3657 via_hp_build(spec);
3585 3658
3586 spec->mixers[spec->num_mixers++] = via_smart51_mixer; 3659 via_smart51_build(spec);
3587 return 1; 3660 return 1;
3588} 3661}
3589 3662
@@ -3605,12 +3678,10 @@ static int patch_vt1708B_8ch(struct hda_codec *codec)
3605 if (get_codec_type(codec) == VT1708BCE) 3678 if (get_codec_type(codec) == VT1708BCE)
3606 return patch_vt1708S(codec); 3679 return patch_vt1708S(codec);
3607 /* create a codec specific record */ 3680 /* create a codec specific record */
3608 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 3681 spec = via_new_spec(codec);
3609 if (spec == NULL) 3682 if (spec == NULL)
3610 return -ENOMEM; 3683 return -ENOMEM;
3611 3684
3612 codec->spec = spec;
3613
3614 /* automatic parse from the BIOS config */ 3685 /* automatic parse from the BIOS config */
3615 err = vt1708B_parse_auto_config(codec); 3686 err = vt1708B_parse_auto_config(codec);
3616 if (err < 0) { 3687 if (err < 0) {
@@ -3657,12 +3728,10 @@ static int patch_vt1708B_4ch(struct hda_codec *codec)
3657 int err; 3728 int err;
3658 3729
3659 /* create a codec specific record */ 3730 /* create a codec specific record */
3660 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 3731 spec = via_new_spec(codec);
3661 if (spec == NULL) 3732 if (spec == NULL)
3662 return -ENOMEM; 3733 return -ENOMEM;
3663 3734
3664 codec->spec = spec;
3665
3666 /* automatic parse from the BIOS config */ 3735 /* automatic parse from the BIOS config */
3667 err = vt1708B_parse_auto_config(codec); 3736 err = vt1708B_parse_auto_config(codec);
3668 if (err < 0) { 3737 if (err < 0) {
@@ -4071,9 +4140,9 @@ static int vt1708S_parse_auto_config(struct hda_codec *codec)
4071 spec->input_mux = &spec->private_imux[0]; 4140 spec->input_mux = &spec->private_imux[0];
4072 4141
4073 if (spec->hp_mux) 4142 if (spec->hp_mux)
4074 spec->mixers[spec->num_mixers++] = via_hp_mixer; 4143 via_hp_build(spec);
4075 4144
4076 spec->mixers[spec->num_mixers++] = via_smart51_mixer; 4145 via_smart51_build(spec);
4077 return 1; 4146 return 1;
4078} 4147}
4079 4148
@@ -4103,12 +4172,10 @@ static int patch_vt1708S(struct hda_codec *codec)
4103 int err; 4172 int err;
4104 4173
4105 /* create a codec specific record */ 4174 /* create a codec specific record */
4106 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 4175 spec = via_new_spec(codec);
4107 if (spec == NULL) 4176 if (spec == NULL)
4108 return -ENOMEM; 4177 return -ENOMEM;
4109 4178
4110 codec->spec = spec;
4111
4112 /* automatic parse from the BIOS config */ 4179 /* automatic parse from the BIOS config */
4113 err = vt1708S_parse_auto_config(codec); 4180 err = vt1708S_parse_auto_config(codec);
4114 if (err < 0) { 4181 if (err < 0) {
@@ -4443,7 +4510,7 @@ static int vt1702_parse_auto_config(struct hda_codec *codec)
4443 spec->input_mux = &spec->private_imux[0]; 4510 spec->input_mux = &spec->private_imux[0];
4444 4511
4445 if (spec->hp_mux) 4512 if (spec->hp_mux)
4446 spec->mixers[spec->num_mixers++] = via_hp_mixer; 4513 via_hp_build(spec);
4447 4514
4448 return 1; 4515 return 1;
4449} 4516}
@@ -4464,12 +4531,10 @@ static int patch_vt1702(struct hda_codec *codec)
4464 int err; 4531 int err;
4465 4532
4466 /* create a codec specific record */ 4533 /* create a codec specific record */
4467 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 4534 spec = via_new_spec(codec);
4468 if (spec == NULL) 4535 if (spec == NULL)
4469 return -ENOMEM; 4536 return -ENOMEM;
4470 4537
4471 codec->spec = spec;
4472
4473 /* automatic parse from the BIOS config */ 4538 /* automatic parse from the BIOS config */
4474 err = vt1702_parse_auto_config(codec); 4539 err = vt1702_parse_auto_config(codec);
4475 if (err < 0) { 4540 if (err < 0) {
@@ -4865,9 +4930,9 @@ static int vt1718S_parse_auto_config(struct hda_codec *codec)
4865 spec->input_mux = &spec->private_imux[0]; 4930 spec->input_mux = &spec->private_imux[0];
4866 4931
4867 if (spec->hp_mux) 4932 if (spec->hp_mux)
4868 spec->mixers[spec->num_mixers++] = via_hp_mixer; 4933 via_hp_build(spec);
4869 4934
4870 spec->mixers[spec->num_mixers++] = via_smart51_mixer; 4935 via_smart51_build(spec);
4871 4936
4872 return 1; 4937 return 1;
4873} 4938}
@@ -4888,12 +4953,10 @@ static int patch_vt1718S(struct hda_codec *codec)
4888 int err; 4953 int err;
4889 4954
4890 /* create a codec specific record */ 4955 /* create a codec specific record */
4891 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 4956 spec = via_new_spec(codec);
4892 if (spec == NULL) 4957 if (spec == NULL)
4893 return -ENOMEM; 4958 return -ENOMEM;
4894 4959
4895 codec->spec = spec;
4896
4897 /* automatic parse from the BIOS config */ 4960 /* automatic parse from the BIOS config */
4898 err = vt1718S_parse_auto_config(codec); 4961 err = vt1718S_parse_auto_config(codec);
4899 if (err < 0) { 4962 if (err < 0) {
@@ -5014,6 +5077,7 @@ static struct snd_kcontrol_new vt1716s_dmic_mixer[] = {
5014 { 5077 {
5015 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 5078 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5016 .name = "Digital Mic Capture Switch", 5079 .name = "Digital Mic Capture Switch",
5080 .subdevice = HDA_SUBDEV_NID_FLAG | 0x26,
5017 .count = 1, 5081 .count = 1,
5018 .info = vt1716s_dmic_info, 5082 .info = vt1716s_dmic_info,
5019 .get = vt1716s_dmic_get, 5083 .get = vt1716s_dmic_get,
@@ -5361,9 +5425,9 @@ static int vt1716S_parse_auto_config(struct hda_codec *codec)
5361 spec->input_mux = &spec->private_imux[0]; 5425 spec->input_mux = &spec->private_imux[0];
5362 5426
5363 if (spec->hp_mux) 5427 if (spec->hp_mux)
5364 spec->mixers[spec->num_mixers++] = via_hp_mixer; 5428 via_hp_build(spec);
5365 5429
5366 spec->mixers[spec->num_mixers++] = via_smart51_mixer; 5430 via_smart51_build(spec);
5367 5431
5368 return 1; 5432 return 1;
5369} 5433}
@@ -5384,12 +5448,10 @@ static int patch_vt1716S(struct hda_codec *codec)
5384 int err; 5448 int err;
5385 5449
5386 /* create a codec specific record */ 5450 /* create a codec specific record */
5387 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 5451 spec = via_new_spec(codec);
5388 if (spec == NULL) 5452 if (spec == NULL)
5389 return -ENOMEM; 5453 return -ENOMEM;
5390 5454
5391 codec->spec = spec;
5392
5393 /* automatic parse from the BIOS config */ 5455 /* automatic parse from the BIOS config */
5394 err = vt1716S_parse_auto_config(codec); 5456 err = vt1716S_parse_auto_config(codec);
5395 if (err < 0) { 5457 if (err < 0) {
@@ -5719,7 +5781,7 @@ static int vt2002P_parse_auto_config(struct hda_codec *codec)
5719 spec->input_mux = &spec->private_imux[0]; 5781 spec->input_mux = &spec->private_imux[0];
5720 5782
5721 if (spec->hp_mux) 5783 if (spec->hp_mux)
5722 spec->mixers[spec->num_mixers++] = via_hp_mixer; 5784 via_hp_build(spec);
5723 5785
5724 return 1; 5786 return 1;
5725} 5787}
@@ -5741,12 +5803,10 @@ static int patch_vt2002P(struct hda_codec *codec)
5741 int err; 5803 int err;
5742 5804
5743 /* create a codec specific record */ 5805 /* create a codec specific record */
5744 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 5806 spec = via_new_spec(codec);
5745 if (spec == NULL) 5807 if (spec == NULL)
5746 return -ENOMEM; 5808 return -ENOMEM;
5747 5809
5748 codec->spec = spec;
5749
5750 /* automatic parse from the BIOS config */ 5810 /* automatic parse from the BIOS config */
5751 err = vt2002P_parse_auto_config(codec); 5811 err = vt2002P_parse_auto_config(codec);
5752 if (err < 0) { 5812 if (err < 0) {
@@ -6070,7 +6130,7 @@ static int vt1812_parse_auto_config(struct hda_codec *codec)
6070 spec->input_mux = &spec->private_imux[0]; 6130 spec->input_mux = &spec->private_imux[0];
6071 6131
6072 if (spec->hp_mux) 6132 if (spec->hp_mux)
6073 spec->mixers[spec->num_mixers++] = via_hp_mixer; 6133 via_hp_build(spec);
6074 6134
6075 return 1; 6135 return 1;
6076} 6136}
@@ -6092,12 +6152,10 @@ static int patch_vt1812(struct hda_codec *codec)
6092 int err; 6152 int err;
6093 6153
6094 /* create a codec specific record */ 6154 /* create a codec specific record */
6095 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 6155 spec = via_new_spec(codec);
6096 if (spec == NULL) 6156 if (spec == NULL)
6097 return -ENOMEM; 6157 return -ENOMEM;
6098 6158
6099 codec->spec = spec;
6100
6101 /* automatic parse from the BIOS config */ 6159 /* automatic parse from the BIOS config */
6102 err = vt1812_parse_auto_config(codec); 6160 err = vt1812_parse_auto_config(codec);
6103 if (err < 0) { 6161 if (err < 0) {