aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2009-12-15 04:45:10 -0500
committerTakashi Iwai <tiwai@suse.de>2009-12-15 04:45:10 -0500
commit709350506567029021b8a38ee7e65bc246fceabc (patch)
tree94e3865d62b9b964e2272d0844629ec88808cb42
parenta9e060571a057c132240753b7f815f4a1e0320a3 (diff)
parent5e26dfd0615868872cb44842f1e1428c7b414ab0 (diff)
Merge remote branch 'alsa/devel' into topic/hda
-rw-r--r--sound/pci/hda/hda_codec.c79
-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_local.h16
-rw-r--r--sound/pci/hda/hda_proc.c31
-rw-r--r--sound/pci/hda/patch_analog.c37
-rw-r--r--sound/pci/hda/patch_cirrus.c10
-rw-r--r--sound/pci/hda/patch_cmedia.c12
-rw-r--r--sound/pci/hda/patch_conexant.c1
-rw-r--r--sound/pci/hda/patch_realtek.c125
-rw-r--r--sound/pci/hda/patch_si3054.c1
-rw-r--r--sound/pci/hda/patch_sigmatel.c7
-rw-r--r--sound/pci/hda/patch_via.c275
13 files changed, 455 insertions, 143 deletions
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index 9cfdb771928c..c848ec0f085e 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;
@@ -3496,6 +3537,32 @@ int snd_hda_add_new_ctls(struct hda_codec *codec, struct snd_kcontrol_new *knew)
3496} 3537}
3497EXPORT_SYMBOL_HDA(snd_hda_add_new_ctls); 3538EXPORT_SYMBOL_HDA(snd_hda_add_new_ctls);
3498 3539
3540/**
3541 * snd_hda_add_nids - assign nids to controls from the array
3542 * @codec: the HDA codec
3543 * @kctl: struct snd_kcontrol
3544 * @index: index to kctl
3545 * @nids: the array of hda_nid_t
3546 * @size: count of hda_nid_t items
3547 *
3548 * This helper function assigns NIDs in the given array to a control element.
3549 *
3550 * Returns 0 if successful, or a negative error code.
3551 */
3552int snd_hda_add_nids(struct hda_codec *codec, struct snd_kcontrol *kctl,
3553 unsigned int index, hda_nid_t *nids, unsigned int size)
3554{
3555 int err;
3556
3557 for ( ; size > 0; size--, nids++) {
3558 err = snd_hda_add_nid(codec, kctl, index, *nids);
3559 if (err < 0)
3560 return err;
3561 }
3562 return 0;
3563}
3564EXPORT_SYMBOL_HDA(snd_hda_add_nids);
3565
3499#ifdef CONFIG_SND_HDA_POWER_SAVE 3566#ifdef CONFIG_SND_HDA_POWER_SAVE
3500static void hda_set_power_state(struct hda_codec *codec, hda_nid_t fg, 3567static void hda_set_power_state(struct hda_codec *codec, hda_nid_t fg,
3501 unsigned int power_state); 3568 unsigned int power_state);
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_local.h b/sound/pci/hda/hda_local.h
index 5778ae882b83..d505d052972e 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, \
@@ -342,6 +343,8 @@ int snd_hda_check_board_codec_sid_config(struct hda_codec *codec,
342 const struct snd_pci_quirk *tbl); 343 const struct snd_pci_quirk *tbl);
343int snd_hda_add_new_ctls(struct hda_codec *codec, 344int snd_hda_add_new_ctls(struct hda_codec *codec,
344 struct snd_kcontrol_new *knew); 345 struct snd_kcontrol_new *knew);
346int snd_hda_add_nids(struct hda_codec *codec, struct snd_kcontrol *kctl,
347 unsigned int index, hda_nid_t *nids, unsigned int size);
345 348
346/* 349/*
347 * unsolicited event handler 350 * unsolicited event handler
@@ -464,13 +467,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); 467u32 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); 468int snd_hda_jack_detect(struct hda_codec *codec, hda_nid_t nid);
466 469
470/* flags for hda_nid_item */
471#define HDA_NID_ITEM_AMP (1<<0)
472
467struct hda_nid_item { 473struct hda_nid_item {
468 struct snd_kcontrol *kctl; 474 struct snd_kcontrol *kctl;
475 unsigned int index;
469 hda_nid_t nid; 476 hda_nid_t nid;
477 unsigned short flags;
470}; 478};
471 479
472int snd_hda_ctl_add(struct hda_codec *codec, hda_nid_t nid, 480int snd_hda_ctl_add(struct hda_codec *codec, hda_nid_t nid,
473 struct snd_kcontrol *kctl); 481 struct snd_kcontrol *kctl);
482int snd_hda_add_nid(struct hda_codec *codec, struct snd_kcontrol *kctl,
483 unsigned int index, hda_nid_t nid);
474void snd_hda_ctls_clear(struct hda_codec *codec); 484void snd_hda_ctls_clear(struct hda_codec *codec);
475 485
476/* 486/*
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..92b72d4f3984 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,28 @@ 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_nids(codec, kctl, i, spec->capsrc_nids,
248 spec->input_mux->num_items);
249 if (err < 0)
250 return err;
251 }
252
253 /* assign IEC958 enums to NID */
254 kctl = snd_hda_find_mixer_ctl(codec,
255 SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source");
256 if (kctl) {
257 err = snd_hda_add_nid(codec, kctl, 0,
258 spec->multiout.dig_out_nid);
259 if (err < 0)
260 return err;
261 }
262
242 return 0; 263 return 0;
243} 264}
244 265
@@ -701,6 +722,7 @@ static struct snd_kcontrol_new ad1986a_laptop_eapd_mixers[] = {
701 { 722 {
702 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 723 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
703 .name = "External Amplifier", 724 .name = "External Amplifier",
725 .subdevice = HDA_SUBDEV_NID_FLAG | 0x1b,
704 .info = ad198x_eapd_info, 726 .info = ad198x_eapd_info,
705 .get = ad198x_eapd_get, 727 .get = ad198x_eapd_get,
706 .put = ad198x_eapd_put, 728 .put = ad198x_eapd_put,
@@ -808,6 +830,7 @@ static struct snd_kcontrol_new ad1986a_automute_master_mixers[] = {
808 { 830 {
809 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 831 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
810 .name = "Master Playback Switch", 832 .name = "Master Playback Switch",
833 .subdevice = HDA_SUBDEV_AMP_FLAG,
811 .info = snd_hda_mixer_amp_switch_info, 834 .info = snd_hda_mixer_amp_switch_info,
812 .get = snd_hda_mixer_amp_switch_get, 835 .get = snd_hda_mixer_amp_switch_get,
813 .put = ad1986a_hp_master_sw_put, 836 .put = ad1986a_hp_master_sw_put,
@@ -1608,6 +1631,7 @@ static struct snd_kcontrol_new ad1981_hp_mixers[] = {
1608 HDA_BIND_VOL("Master Playback Volume", &ad1981_hp_bind_master_vol), 1631 HDA_BIND_VOL("Master Playback Volume", &ad1981_hp_bind_master_vol),
1609 { 1632 {
1610 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1633 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1634 .subdevice = HDA_SUBDEV_NID_FLAG | 0x05,
1611 .name = "Master Playback Switch", 1635 .name = "Master Playback Switch",
1612 .info = ad198x_eapd_info, 1636 .info = ad198x_eapd_info,
1613 .get = ad198x_eapd_get, 1637 .get = ad198x_eapd_get,
@@ -2129,6 +2153,7 @@ static struct snd_kcontrol_new ad1988_laptop_mixers[] = {
2129 { 2153 {
2130 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2154 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2131 .name = "External Amplifier", 2155 .name = "External Amplifier",
2156 .subdevice = HDA_SUBDEV_NID_FLAG | 0x12,
2132 .info = ad198x_eapd_info, 2157 .info = ad198x_eapd_info,
2133 .get = ad198x_eapd_get, 2158 .get = ad198x_eapd_get,
2134 .put = ad198x_eapd_put, 2159 .put = ad198x_eapd_put,
@@ -2250,6 +2275,7 @@ static struct snd_kcontrol_new ad1988_spdif_out_mixers[] = {
2250 { 2275 {
2251 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2276 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2252 .name = "IEC958 Playback Source", 2277 .name = "IEC958 Playback Source",
2278 .subdevice = HDA_SUBDEV_NID_FLAG | 0x1b,
2253 .info = ad1988_spdif_playback_source_info, 2279 .info = ad1988_spdif_playback_source_info,
2254 .get = ad1988_spdif_playback_source_get, 2280 .get = ad1988_spdif_playback_source_get,
2255 .put = ad1988_spdif_playback_source_put, 2281 .put = ad1988_spdif_playback_source_put,
@@ -2582,7 +2608,7 @@ static int add_control(struct ad198x_spec *spec, int type, const char *name,
2582 if (! knew->name) 2608 if (! knew->name)
2583 return -ENOMEM; 2609 return -ENOMEM;
2584 if (get_amp_nid_(val)) 2610 if (get_amp_nid_(val))
2585 knew->subdevice = HDA_SUBDEV_NID_FLAG | get_amp_nid_(val); 2611 knew->subdevice = HDA_SUBDEV_AMP_FLAG;
2586 knew->private_value = val; 2612 knew->private_value = val;
2587 return 0; 2613 return 0;
2588} 2614}
@@ -3736,6 +3762,7 @@ static struct snd_kcontrol_new ad1884a_laptop_mixers[] = {
3736 { 3762 {
3737 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 3763 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3738 .name = "Master Playback Switch", 3764 .name = "Master Playback Switch",
3765 .subdevice = HDA_SUBDEV_AMP_FLAG,
3739 .info = snd_hda_mixer_amp_switch_info, 3766 .info = snd_hda_mixer_amp_switch_info,
3740 .get = snd_hda_mixer_amp_switch_get, 3767 .get = snd_hda_mixer_amp_switch_get,
3741 .put = ad1884a_mobile_master_sw_put, 3768 .put = ad1884a_mobile_master_sw_put,
@@ -3764,6 +3791,7 @@ static struct snd_kcontrol_new ad1884a_mobile_mixers[] = {
3764 { 3791 {
3765 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 3792 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3766 .name = "Master Playback Switch", 3793 .name = "Master Playback Switch",
3794 .subdevice = HDA_SUBDEV_AMP_FLAG,
3767 .info = snd_hda_mixer_amp_switch_info, 3795 .info = snd_hda_mixer_amp_switch_info,
3768 .get = snd_hda_mixer_amp_switch_get, 3796 .get = snd_hda_mixer_amp_switch_get,
3769 .put = ad1884a_mobile_master_sw_put, 3797 .put = ad1884a_mobile_master_sw_put,
@@ -4105,6 +4133,7 @@ static struct snd_kcontrol_new ad1984a_touchsmart_mixers[] = {
4105/* HDA_CODEC_MUTE("Master Playback Switch", 0x21, 0x0, HDA_OUTPUT),*/ 4133/* HDA_CODEC_MUTE("Master Playback Switch", 0x21, 0x0, HDA_OUTPUT),*/
4106 { 4134 {
4107 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 4135 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4136 .subdevice = HDA_SUBDEV_AMP_FLAG,
4108 .name = "Master Playback Switch", 4137 .name = "Master Playback Switch",
4109 .info = snd_hda_mixer_amp_switch_info, 4138 .info = snd_hda_mixer_amp_switch_info,
4110 .get = snd_hda_mixer_amp_switch_get, 4139 .get = snd_hda_mixer_amp_switch_get,
diff --git a/sound/pci/hda/patch_cirrus.c b/sound/pci/hda/patch_cirrus.c
index 4b200da1bd18..eeb91f6a06c2 100644
--- a/sound/pci/hda/patch_cirrus.c
+++ b/sound/pci/hda/patch_cirrus.c
@@ -500,7 +500,8 @@ static int add_mute(struct hda_codec *codec, const char *name, int index,
500 knew.private_value = pval; 500 knew.private_value = pval;
501 snprintf(tmp, sizeof(tmp), "%s %s Switch", name, dir_sfx[dir]); 501 snprintf(tmp, sizeof(tmp), "%s %s Switch", name, dir_sfx[dir]);
502 *kctlp = snd_ctl_new1(&knew, codec); 502 *kctlp = snd_ctl_new1(&knew, codec);
503 return snd_hda_ctl_add(codec, get_amp_nid_(pval), *kctlp); 503 (*kctlp)->id.subdevice = HDA_SUBDEV_AMP_FLAG;
504 return snd_hda_ctl_add(codec, 0, *kctlp);
504} 505}
505 506
506static int add_volume(struct hda_codec *codec, const char *name, 507static int add_volume(struct hda_codec *codec, const char *name,
@@ -513,7 +514,8 @@ static int add_volume(struct hda_codec *codec, const char *name,
513 knew.private_value = pval; 514 knew.private_value = pval;
514 snprintf(tmp, sizeof(tmp), "%s %s Volume", name, dir_sfx[dir]); 515 snprintf(tmp, sizeof(tmp), "%s %s Volume", name, dir_sfx[dir]);
515 *kctlp = snd_ctl_new1(&knew, codec); 516 *kctlp = snd_ctl_new1(&knew, codec);
516 return snd_hda_ctl_add(codec, get_amp_nid_(pval), *kctlp); 517 (*kctlp)->id.subdevice = HDA_SUBDEV_AMP_FLAG;
518 return snd_hda_ctl_add(codec, 0, *kctlp);
517} 519}
518 520
519static void fix_volume_caps(struct hda_codec *codec, hda_nid_t dac) 521static void fix_volume_caps(struct hda_codec *codec, hda_nid_t dac)
@@ -759,6 +761,10 @@ static int build_input(struct hda_codec *codec)
759 err = snd_hda_ctl_add(codec, 0, kctl); 761 err = snd_hda_ctl_add(codec, 0, kctl);
760 if (err < 0) 762 if (err < 0)
761 return err; 763 return err;
764 err = snd_hda_add_nids(codec, kctl, 0, spec->adc_nid,
765 spec->num_inputs);
766 if (err < 0)
767 return err;
762 } 768 }
763 769
764 if (spec->num_inputs > 1 && !spec->mic_detect) { 770 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..cc1c22370a60 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,15 @@ 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_nids(codec, kctl, i, spec->adc_nids,
349 spec->input_mux->num_items);
350 if (err < 0)
351 return err;
352 }
343 return 0; 353 return 0;
344} 354}
345 355
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c
index a09c03c3f62b..1ab2958a290b 100644
--- a/sound/pci/hda/patch_conexant.c
+++ b/sound/pci/hda/patch_conexant.c
@@ -2178,6 +2178,7 @@ static struct snd_kcontrol_new cxt5066_mixer_master_olpc[] = {
2178 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | 2178 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
2179 SNDRV_CTL_ELEM_ACCESS_TLV_READ | 2179 SNDRV_CTL_ELEM_ACCESS_TLV_READ |
2180 SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK, 2180 SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK,
2181 .subdevice = HDA_SUBDEV_AMP_FLAG,
2181 .info = snd_hda_mixer_amp_volume_info, 2182 .info = snd_hda_mixer_amp_volume_info,
2182 .get = snd_hda_mixer_amp_volume_get, 2183 .get = snd_hda_mixer_amp_volume_get,
2183 .put = snd_hda_mixer_amp_volume_put, 2184 .put = snd_hda_mixer_amp_volume_put,
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index aeed4cc5aa79..f88577897e46 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -627,6 +627,7 @@ static int alc_pin_mode_put(struct snd_kcontrol *kcontrol,
627 627
628#define ALC_PIN_MODE(xname, nid, dir) \ 628#define ALC_PIN_MODE(xname, nid, dir) \
629 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \ 629 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
630 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
630 .info = alc_pin_mode_info, \ 631 .info = alc_pin_mode_info, \
631 .get = alc_pin_mode_get, \ 632 .get = alc_pin_mode_get, \
632 .put = alc_pin_mode_put, \ 633 .put = alc_pin_mode_put, \
@@ -678,6 +679,7 @@ static int alc_gpio_data_put(struct snd_kcontrol *kcontrol,
678} 679}
679#define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \ 680#define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \
680 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \ 681 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
682 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
681 .info = alc_gpio_data_info, \ 683 .info = alc_gpio_data_info, \
682 .get = alc_gpio_data_get, \ 684 .get = alc_gpio_data_get, \
683 .put = alc_gpio_data_put, \ 685 .put = alc_gpio_data_put, \
@@ -732,6 +734,7 @@ static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol,
732} 734}
733#define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \ 735#define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \
734 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \ 736 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
737 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
735 .info = alc_spdif_ctrl_info, \ 738 .info = alc_spdif_ctrl_info, \
736 .get = alc_spdif_ctrl_get, \ 739 .get = alc_spdif_ctrl_get, \
737 .put = alc_spdif_ctrl_put, \ 740 .put = alc_spdif_ctrl_put, \
@@ -785,6 +788,7 @@ static int alc_eapd_ctrl_put(struct snd_kcontrol *kcontrol,
785 788
786#define ALC_EAPD_CTRL_SWITCH(xname, nid, mask) \ 789#define ALC_EAPD_CTRL_SWITCH(xname, nid, mask) \
787 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \ 790 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
791 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
788 .info = alc_eapd_ctrl_info, \ 792 .info = alc_eapd_ctrl_info, \
789 .get = alc_eapd_ctrl_get, \ 793 .get = alc_eapd_ctrl_get, \
790 .put = alc_eapd_ctrl_put, \ 794 .put = alc_eapd_ctrl_put, \
@@ -2410,6 +2414,15 @@ static const char *alc_slave_sws[] = {
2410 * build control elements 2414 * build control elements
2411 */ 2415 */
2412 2416
2417#define NID_MAPPING (-1)
2418
2419#define SUBDEV_SPEAKER_ (0 << 6)
2420#define SUBDEV_HP_ (1 << 6)
2421#define SUBDEV_LINE_ (2 << 6)
2422#define SUBDEV_SPEAKER(x) (SUBDEV_SPEAKER_ | ((x) & 0x3f))
2423#define SUBDEV_HP(x) (SUBDEV_HP_ | ((x) & 0x3f))
2424#define SUBDEV_LINE(x) (SUBDEV_LINE_ | ((x) & 0x3f))
2425
2413static void alc_free_kctls(struct hda_codec *codec); 2426static void alc_free_kctls(struct hda_codec *codec);
2414 2427
2415#ifdef CONFIG_SND_HDA_INPUT_BEEP 2428#ifdef CONFIG_SND_HDA_INPUT_BEEP
@@ -2424,8 +2437,11 @@ static struct snd_kcontrol_new alc_beep_mixer[] = {
2424static int alc_build_controls(struct hda_codec *codec) 2437static int alc_build_controls(struct hda_codec *codec)
2425{ 2438{
2426 struct alc_spec *spec = codec->spec; 2439 struct alc_spec *spec = codec->spec;
2427 int err; 2440 struct snd_kcontrol *kctl;
2428 int i; 2441 struct snd_kcontrol_new *knew;
2442 int i, j, err;
2443 unsigned int u;
2444 hda_nid_t nid;
2429 2445
2430 for (i = 0; i < spec->num_mixers; i++) { 2446 for (i = 0; i < spec->num_mixers; i++) {
2431 err = snd_hda_add_new_ctls(codec, spec->mixers[i]); 2447 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
@@ -2466,8 +2482,7 @@ static int alc_build_controls(struct hda_codec *codec)
2466 if (!kctl) 2482 if (!kctl)
2467 return -ENOMEM; 2483 return -ENOMEM;
2468 kctl->private_value = spec->beep_amp; 2484 kctl->private_value = spec->beep_amp;
2469 err = snd_hda_ctl_add(codec, 2485 err = snd_hda_ctl_add(codec, 0, kctl);
2470 get_amp_nid_(spec->beep_amp), kctl);
2471 if (err < 0) 2486 if (err < 0)
2472 return err; 2487 return err;
2473 } 2488 }
@@ -2494,6 +2509,73 @@ static int alc_build_controls(struct hda_codec *codec)
2494 } 2509 }
2495 2510
2496 alc_free_kctls(codec); /* no longer needed */ 2511 alc_free_kctls(codec); /* no longer needed */
2512
2513 /* assign Capture Source enums to NID */
2514 kctl = snd_hda_find_mixer_ctl(codec, "Capture Source");
2515 if (!kctl)
2516 kctl = snd_hda_find_mixer_ctl(codec, "Input Source");
2517 for (i = 0; kctl && i < kctl->count; i++) {
2518 err = snd_hda_add_nids(codec, kctl, i, spec->capsrc_nids,
2519 spec->input_mux->num_items);
2520 if (err < 0)
2521 return err;
2522 }
2523 if (spec->cap_mixer) {
2524 const char *kname = kctl ? kctl->id.name : NULL;
2525 for (knew = spec->cap_mixer; knew->name; knew++) {
2526 if (kname && strcmp(knew->name, kname) == 0)
2527 continue;
2528 kctl = snd_hda_find_mixer_ctl(codec, knew->name);
2529 for (i = 0; kctl && i < kctl->count; i++) {
2530 err = snd_hda_add_nid(codec, kctl, i,
2531 spec->adc_nids[i]);
2532 if (err < 0)
2533 return err;
2534 }
2535 }
2536 }
2537
2538 /* other nid->control mapping */
2539 for (i = 0; i < spec->num_mixers; i++) {
2540 for (knew = spec->mixers[i]; knew->name; knew++) {
2541 if (knew->iface != NID_MAPPING)
2542 continue;
2543 kctl = snd_hda_find_mixer_ctl(codec, knew->name);
2544 if (kctl == NULL)
2545 continue;
2546 u = knew->subdevice;
2547 for (j = 0; j < 4; j++, u >>= 8) {
2548 nid = u & 0x3f;
2549 if (nid == 0)
2550 continue;
2551 switch (u & 0xc0) {
2552 case SUBDEV_SPEAKER_:
2553 nid = spec->autocfg.speaker_pins[nid];
2554 break;
2555 case SUBDEV_LINE_:
2556 nid = spec->autocfg.line_out_pins[nid];
2557 break;
2558 case SUBDEV_HP_:
2559 nid = spec->autocfg.hp_pins[nid];
2560 break;
2561 default:
2562 continue;
2563 }
2564 err = snd_hda_add_nid(codec, kctl, 0, nid);
2565 if (err < 0)
2566 return err;
2567 }
2568 u = knew->private_value;
2569 for (j = 0; j < 4; j++, u >>= 8) {
2570 nid = u & 0xff;
2571 if (nid == 0)
2572 continue;
2573 err = snd_hda_add_nid(codec, kctl, 0, nid);
2574 if (err < 0)
2575 return err;
2576 }
2577 }
2578 }
2497 return 0; 2579 return 0;
2498} 2580}
2499 2581
@@ -3781,6 +3863,7 @@ static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
3781#define PIN_CTL_TEST(xname,nid) { \ 3863#define PIN_CTL_TEST(xname,nid) { \
3782 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 3864 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
3783 .name = xname, \ 3865 .name = xname, \
3866 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
3784 .info = alc_test_pin_ctl_info, \ 3867 .info = alc_test_pin_ctl_info, \
3785 .get = alc_test_pin_ctl_get, \ 3868 .get = alc_test_pin_ctl_get, \
3786 .put = alc_test_pin_ctl_put, \ 3869 .put = alc_test_pin_ctl_put, \
@@ -3790,6 +3873,7 @@ static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
3790#define PIN_SRC_TEST(xname,nid) { \ 3873#define PIN_SRC_TEST(xname,nid) { \
3791 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 3874 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
3792 .name = xname, \ 3875 .name = xname, \
3876 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
3793 .info = alc_test_pin_src_info, \ 3877 .info = alc_test_pin_src_info, \
3794 .get = alc_test_pin_src_get, \ 3878 .get = alc_test_pin_src_get, \
3795 .put = alc_test_pin_src_put, \ 3879 .put = alc_test_pin_src_put, \
@@ -4329,7 +4413,7 @@ static int add_control(struct alc_spec *spec, int type, const char *name,
4329 if (!knew->name) 4413 if (!knew->name)
4330 return -ENOMEM; 4414 return -ENOMEM;
4331 if (get_amp_nid_(val)) 4415 if (get_amp_nid_(val))
4332 knew->subdevice = HDA_SUBDEV_NID_FLAG | get_amp_nid_(val); 4416 knew->subdevice = HDA_SUBDEV_AMP_FLAG;
4333 knew->private_value = val; 4417 knew->private_value = val;
4334 return 0; 4418 return 0;
4335} 4419}
@@ -5080,6 +5164,7 @@ static struct snd_kcontrol_new alc260_hp_output_mixer[] = {
5080 { 5164 {
5081 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 5165 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5082 .name = "Master Playback Switch", 5166 .name = "Master Playback Switch",
5167 .subdevice = HDA_SUBDEV_NID_FLAG | 0x11,
5083 .info = snd_ctl_boolean_mono_info, 5168 .info = snd_ctl_boolean_mono_info,
5084 .get = alc260_hp_master_sw_get, 5169 .get = alc260_hp_master_sw_get,
5085 .put = alc260_hp_master_sw_put, 5170 .put = alc260_hp_master_sw_put,
@@ -5118,6 +5203,7 @@ static struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
5118 { 5203 {
5119 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 5204 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5120 .name = "Master Playback Switch", 5205 .name = "Master Playback Switch",
5206 .subdevice = HDA_SUBDEV_NID_FLAG | 0x11,
5121 .info = snd_ctl_boolean_mono_info, 5207 .info = snd_ctl_boolean_mono_info,
5122 .get = alc260_hp_master_sw_get, 5208 .get = alc260_hp_master_sw_get,
5123 .put = alc260_hp_master_sw_put, 5209 .put = alc260_hp_master_sw_put,
@@ -10189,8 +10275,14 @@ static int alc262_hp_master_sw_put(struct snd_kcontrol *kcontrol,
10189 .info = snd_ctl_boolean_mono_info, \ 10275 .info = snd_ctl_boolean_mono_info, \
10190 .get = alc262_hp_master_sw_get, \ 10276 .get = alc262_hp_master_sw_get, \
10191 .put = alc262_hp_master_sw_put, \ 10277 .put = alc262_hp_master_sw_put, \
10278 }, \
10279 { \
10280 .iface = NID_MAPPING, \
10281 .name = "Master Playback Switch", \
10282 .private_value = 0x15 | (0x16 << 8) | (0x1b << 16), \
10192 } 10283 }
10193 10284
10285
10194static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = { 10286static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
10195 ALC262_HP_MASTER_SWITCH, 10287 ALC262_HP_MASTER_SWITCH,
10196 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 10288 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
@@ -10348,6 +10440,12 @@ static int alc262_hippo_master_sw_put(struct snd_kcontrol *kcontrol,
10348 .info = snd_ctl_boolean_mono_info, \ 10440 .info = snd_ctl_boolean_mono_info, \
10349 .get = alc262_hippo_master_sw_get, \ 10441 .get = alc262_hippo_master_sw_get, \
10350 .put = alc262_hippo_master_sw_put, \ 10442 .put = alc262_hippo_master_sw_put, \
10443 }, \
10444 { \
10445 .iface = NID_MAPPING, \
10446 .name = "Master Playback Switch", \
10447 .subdevice = SUBDEV_HP(0) | (SUBDEV_LINE(0) << 8) | \
10448 (SUBDEV_SPEAKER(0) << 16), \
10351 } 10449 }
10352 10450
10353static struct snd_kcontrol_new alc262_hippo_mixer[] = { 10451static struct snd_kcontrol_new alc262_hippo_mixer[] = {
@@ -10821,11 +10919,17 @@ static struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
10821 { 10919 {
10822 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 10920 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10823 .name = "Master Playback Switch", 10921 .name = "Master Playback Switch",
10922 .subdevice = HDA_SUBDEV_AMP_FLAG,
10824 .info = snd_hda_mixer_amp_switch_info, 10923 .info = snd_hda_mixer_amp_switch_info,
10825 .get = snd_hda_mixer_amp_switch_get, 10924 .get = snd_hda_mixer_amp_switch_get,
10826 .put = alc262_fujitsu_master_sw_put, 10925 .put = alc262_fujitsu_master_sw_put,
10827 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), 10926 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
10828 }, 10927 },
10928 {
10929 .iface = NID_MAPPING,
10930 .name = "Master Playback Switch",
10931 .private_value = 0x1b,
10932 },
10829 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 10933 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10830 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 10934 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
10831 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 10935 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
@@ -10856,6 +10960,7 @@ static struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = {
10856 { 10960 {
10857 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 10961 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10858 .name = "Master Playback Switch", 10962 .name = "Master Playback Switch",
10963 .subdevice = HDA_SUBDEV_AMP_FLAG,
10859 .info = snd_hda_mixer_amp_switch_info, 10964 .info = snd_hda_mixer_amp_switch_info,
10860 .get = snd_hda_mixer_amp_switch_get, 10965 .get = snd_hda_mixer_amp_switch_get,
10861 .put = alc262_lenovo_3000_master_sw_put, 10966 .put = alc262_lenovo_3000_master_sw_put,
@@ -11010,6 +11115,11 @@ static struct snd_kcontrol_new alc262_ultra_capture_mixer[] = {
11010 .get = alc_mux_enum_get, 11115 .get = alc_mux_enum_get,
11011 .put = alc262_ultra_mux_enum_put, 11116 .put = alc262_ultra_mux_enum_put,
11012 }, 11117 },
11118 {
11119 .iface = NID_MAPPING,
11120 .name = "Capture Source",
11121 .private_value = 0x15,
11122 },
11013 { } /* end */ 11123 { } /* end */
11014}; 11124};
11015 11125
@@ -12027,6 +12137,7 @@ static struct snd_kcontrol_new alc268_acer_aspire_one_mixer[] = {
12027 { 12137 {
12028 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 12138 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12029 .name = "Master Playback Switch", 12139 .name = "Master Playback Switch",
12140 .subdevice = HDA_SUBDEV_AMP_FLAG,
12030 .info = snd_hda_mixer_amp_switch_info, 12141 .info = snd_hda_mixer_amp_switch_info,
12031 .get = snd_hda_mixer_amp_switch_get, 12142 .get = snd_hda_mixer_amp_switch_get,
12032 .put = alc268_acer_master_sw_put, 12143 .put = alc268_acer_master_sw_put,
@@ -12042,6 +12153,7 @@ static struct snd_kcontrol_new alc268_acer_mixer[] = {
12042 { 12153 {
12043 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 12154 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12044 .name = "Master Playback Switch", 12155 .name = "Master Playback Switch",
12156 .subdevice = HDA_SUBDEV_AMP_FLAG,
12045 .info = snd_hda_mixer_amp_switch_info, 12157 .info = snd_hda_mixer_amp_switch_info,
12046 .get = snd_hda_mixer_amp_switch_get, 12158 .get = snd_hda_mixer_amp_switch_get,
12047 .put = alc268_acer_master_sw_put, 12159 .put = alc268_acer_master_sw_put,
@@ -12059,6 +12171,7 @@ static struct snd_kcontrol_new alc268_acer_dmic_mixer[] = {
12059 { 12171 {
12060 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 12172 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12061 .name = "Master Playback Switch", 12173 .name = "Master Playback Switch",
12174 .subdevice = HDA_SUBDEV_AMP_FLAG,
12062 .info = snd_hda_mixer_amp_switch_info, 12175 .info = snd_hda_mixer_amp_switch_info,
12063 .get = snd_hda_mixer_amp_switch_get, 12176 .get = snd_hda_mixer_amp_switch_get,
12064 .put = alc268_acer_master_sw_put, 12177 .put = alc268_acer_master_sw_put,
@@ -13011,6 +13124,7 @@ static struct snd_kcontrol_new alc269_quanta_fl1_mixer[] = {
13011 { 13124 {
13012 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 13125 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13013 .name = "Master Playback Switch", 13126 .name = "Master Playback Switch",
13127 .subdevice = HDA_SUBDEV_AMP_FLAG,
13014 .info = snd_hda_mixer_amp_switch_info, 13128 .info = snd_hda_mixer_amp_switch_info,
13015 .get = snd_hda_mixer_amp_switch_get, 13129 .get = snd_hda_mixer_amp_switch_get,
13016 .put = alc268_acer_master_sw_put, 13130 .put = alc268_acer_master_sw_put,
@@ -13031,6 +13145,7 @@ static struct snd_kcontrol_new alc269_lifebook_mixer[] = {
13031 { 13145 {
13032 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 13146 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13033 .name = "Master Playback Switch", 13147 .name = "Master Playback Switch",
13148 .subdevice = HDA_SUBDEV_AMP_FLAG,
13034 .info = snd_hda_mixer_amp_switch_info, 13149 .info = snd_hda_mixer_amp_switch_info,
13035 .get = snd_hda_mixer_amp_switch_get, 13150 .get = snd_hda_mixer_amp_switch_get,
13036 .put = alc268_acer_master_sw_put, 13151 .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 3d59f8325848..0bafea9d5106 100644
--- a/sound/pci/hda/patch_sigmatel.c
+++ b/sound/pci/hda/patch_sigmatel.c
@@ -2685,7 +2685,7 @@ static struct snd_kcontrol_new *
2685stac_control_new(struct sigmatel_spec *spec, 2685stac_control_new(struct sigmatel_spec *spec,
2686 struct snd_kcontrol_new *ktemp, 2686 struct snd_kcontrol_new *ktemp,
2687 const char *name, 2687 const char *name,
2688 hda_nid_t nid) 2688 unsigned int subdev)
2689{ 2689{
2690 struct snd_kcontrol_new *knew; 2690 struct snd_kcontrol_new *knew;
2691 2691
@@ -2701,8 +2701,7 @@ stac_control_new(struct sigmatel_spec *spec,
2701 spec->kctls.alloced--; 2701 spec->kctls.alloced--;
2702 return NULL; 2702 return NULL;
2703 } 2703 }
2704 if (nid) 2704 knew->subdevice = subdev;
2705 knew->subdevice = HDA_SUBDEV_NID_FLAG | nid;
2706 return knew; 2705 return knew;
2707} 2706}
2708 2707
@@ -2712,7 +2711,7 @@ static int stac92xx_add_control_temp(struct sigmatel_spec *spec,
2712 unsigned long val) 2711 unsigned long val)
2713{ 2712{
2714 struct snd_kcontrol_new *knew = stac_control_new(spec, ktemp, name, 2713 struct snd_kcontrol_new *knew = stac_control_new(spec, ktemp, name,
2715 get_amp_nid_(val)); 2714 HDA_SUBDEV_AMP_FLAG);
2716 if (!knew) 2715 if (!knew)
2717 return -ENOMEM; 2716 return -ENOMEM;
2718 knew->index = idx; 2717 knew->index = idx;
diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c
index b70e26ad263f..de4839e46762 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,28 @@ 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_nids(codec, kctl, i, spec->mux_nids,
1911 spec->input_mux->num_items);
1912 if (err < 0)
1913 return err;
1914 }
1915
1916 /* other nid->control mapping */
1917 for (i = 0; i < spec->num_mixers; i++) {
1918 for (knew = spec->mixers[i]; knew->name; knew++) {
1919 if (knew->iface != NID_MAPPING)
1920 continue;
1921 kctl = snd_hda_find_mixer_ctl(codec, knew->name);
1922 if (kctl == NULL)
1923 continue;
1924 err = snd_hda_add_nid(codec, kctl, 0,
1925 knew->subdevice);
1926 }
1927 }
1928
1848 /* init power states */ 1929 /* init power states */
1849 set_jack_power_state(codec); 1930 set_jack_power_state(codec);
1850 analog_low_current_mode(codec, 1); 1931 analog_low_current_mode(codec, 1);
@@ -2481,9 +2562,9 @@ static int vt1708_parse_auto_config(struct hda_codec *codec)
2481 spec->input_mux = &spec->private_imux[0]; 2562 spec->input_mux = &spec->private_imux[0];
2482 2563
2483 if (spec->hp_mux) 2564 if (spec->hp_mux)
2484 spec->mixers[spec->num_mixers++] = via_hp_mixer; 2565 via_hp_build(spec);
2485 2566
2486 spec->mixers[spec->num_mixers++] = via_smart51_mixer; 2567 via_smart51_build(spec);
2487 return 1; 2568 return 1;
2488} 2569}
2489 2570
@@ -2554,12 +2635,10 @@ static int patch_vt1708(struct hda_codec *codec)
2554 int err; 2635 int err;
2555 2636
2556 /* create a codec specific record */ 2637 /* create a codec specific record */
2557 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 2638 spec = via_new_spec(codec);
2558 if (spec == NULL) 2639 if (spec == NULL)
2559 return -ENOMEM; 2640 return -ENOMEM;
2560 2641
2561 codec->spec = spec;
2562
2563 /* automatic parse from the BIOS config */ 2642 /* automatic parse from the BIOS config */
2564 err = vt1708_parse_auto_config(codec); 2643 err = vt1708_parse_auto_config(codec);
2565 if (err < 0) { 2644 if (err < 0) {
@@ -2597,7 +2676,6 @@ static int patch_vt1708(struct hda_codec *codec)
2597#ifdef CONFIG_SND_HDA_POWER_SAVE 2676#ifdef CONFIG_SND_HDA_POWER_SAVE
2598 spec->loopback.amplist = vt1708_loopbacks; 2677 spec->loopback.amplist = vt1708_loopbacks;
2599#endif 2678#endif
2600 spec->codec = codec;
2601 INIT_DELAYED_WORK(&spec->vt1708_hp_work, vt1708_update_hp_jack_state); 2679 INIT_DELAYED_WORK(&spec->vt1708_hp_work, vt1708_update_hp_jack_state);
2602 return 0; 2680 return 0;
2603} 2681}
@@ -3010,9 +3088,9 @@ static int vt1709_parse_auto_config(struct hda_codec *codec)
3010 spec->input_mux = &spec->private_imux[0]; 3088 spec->input_mux = &spec->private_imux[0];
3011 3089
3012 if (spec->hp_mux) 3090 if (spec->hp_mux)
3013 spec->mixers[spec->num_mixers++] = via_hp_mixer; 3091 via_hp_build(spec);
3014 3092
3015 spec->mixers[spec->num_mixers++] = via_smart51_mixer; 3093 via_smart51_build(spec);
3016 return 1; 3094 return 1;
3017} 3095}
3018 3096
@@ -3032,12 +3110,10 @@ static int patch_vt1709_10ch(struct hda_codec *codec)
3032 int err; 3110 int err;
3033 3111
3034 /* create a codec specific record */ 3112 /* create a codec specific record */
3035 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 3113 spec = via_new_spec(codec);
3036 if (spec == NULL) 3114 if (spec == NULL)
3037 return -ENOMEM; 3115 return -ENOMEM;
3038 3116
3039 codec->spec = spec;
3040
3041 err = vt1709_parse_auto_config(codec); 3117 err = vt1709_parse_auto_config(codec);
3042 if (err < 0) { 3118 if (err < 0) {
3043 via_free(codec); 3119 via_free(codec);
@@ -3126,12 +3202,10 @@ static int patch_vt1709_6ch(struct hda_codec *codec)
3126 int err; 3202 int err;
3127 3203
3128 /* create a codec specific record */ 3204 /* create a codec specific record */
3129 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 3205 spec = via_new_spec(codec);
3130 if (spec == NULL) 3206 if (spec == NULL)
3131 return -ENOMEM; 3207 return -ENOMEM;
3132 3208
3133 codec->spec = spec;
3134
3135 err = vt1709_parse_auto_config(codec); 3209 err = vt1709_parse_auto_config(codec);
3136 if (err < 0) { 3210 if (err < 0) {
3137 via_free(codec); 3211 via_free(codec);
@@ -3581,9 +3655,9 @@ static int vt1708B_parse_auto_config(struct hda_codec *codec)
3581 spec->input_mux = &spec->private_imux[0]; 3655 spec->input_mux = &spec->private_imux[0];
3582 3656
3583 if (spec->hp_mux) 3657 if (spec->hp_mux)
3584 spec->mixers[spec->num_mixers++] = via_hp_mixer; 3658 via_hp_build(spec);
3585 3659
3586 spec->mixers[spec->num_mixers++] = via_smart51_mixer; 3660 via_smart51_build(spec);
3587 return 1; 3661 return 1;
3588} 3662}
3589 3663
@@ -3605,12 +3679,10 @@ static int patch_vt1708B_8ch(struct hda_codec *codec)
3605 if (get_codec_type(codec) == VT1708BCE) 3679 if (get_codec_type(codec) == VT1708BCE)
3606 return patch_vt1708S(codec); 3680 return patch_vt1708S(codec);
3607 /* create a codec specific record */ 3681 /* create a codec specific record */
3608 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 3682 spec = via_new_spec(codec);
3609 if (spec == NULL) 3683 if (spec == NULL)
3610 return -ENOMEM; 3684 return -ENOMEM;
3611 3685
3612 codec->spec = spec;
3613
3614 /* automatic parse from the BIOS config */ 3686 /* automatic parse from the BIOS config */
3615 err = vt1708B_parse_auto_config(codec); 3687 err = vt1708B_parse_auto_config(codec);
3616 if (err < 0) { 3688 if (err < 0) {
@@ -3657,12 +3729,10 @@ static int patch_vt1708B_4ch(struct hda_codec *codec)
3657 int err; 3729 int err;
3658 3730
3659 /* create a codec specific record */ 3731 /* create a codec specific record */
3660 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 3732 spec = via_new_spec(codec);
3661 if (spec == NULL) 3733 if (spec == NULL)
3662 return -ENOMEM; 3734 return -ENOMEM;
3663 3735
3664 codec->spec = spec;
3665
3666 /* automatic parse from the BIOS config */ 3736 /* automatic parse from the BIOS config */
3667 err = vt1708B_parse_auto_config(codec); 3737 err = vt1708B_parse_auto_config(codec);
3668 if (err < 0) { 3738 if (err < 0) {
@@ -4071,9 +4141,9 @@ static int vt1708S_parse_auto_config(struct hda_codec *codec)
4071 spec->input_mux = &spec->private_imux[0]; 4141 spec->input_mux = &spec->private_imux[0];
4072 4142
4073 if (spec->hp_mux) 4143 if (spec->hp_mux)
4074 spec->mixers[spec->num_mixers++] = via_hp_mixer; 4144 via_hp_build(spec);
4075 4145
4076 spec->mixers[spec->num_mixers++] = via_smart51_mixer; 4146 via_smart51_build(spec);
4077 return 1; 4147 return 1;
4078} 4148}
4079 4149
@@ -4103,12 +4173,10 @@ static int patch_vt1708S(struct hda_codec *codec)
4103 int err; 4173 int err;
4104 4174
4105 /* create a codec specific record */ 4175 /* create a codec specific record */
4106 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 4176 spec = via_new_spec(codec);
4107 if (spec == NULL) 4177 if (spec == NULL)
4108 return -ENOMEM; 4178 return -ENOMEM;
4109 4179
4110 codec->spec = spec;
4111
4112 /* automatic parse from the BIOS config */ 4180 /* automatic parse from the BIOS config */
4113 err = vt1708S_parse_auto_config(codec); 4181 err = vt1708S_parse_auto_config(codec);
4114 if (err < 0) { 4182 if (err < 0) {
@@ -4443,7 +4511,7 @@ static int vt1702_parse_auto_config(struct hda_codec *codec)
4443 spec->input_mux = &spec->private_imux[0]; 4511 spec->input_mux = &spec->private_imux[0];
4444 4512
4445 if (spec->hp_mux) 4513 if (spec->hp_mux)
4446 spec->mixers[spec->num_mixers++] = via_hp_mixer; 4514 via_hp_build(spec);
4447 4515
4448 return 1; 4516 return 1;
4449} 4517}
@@ -4464,12 +4532,10 @@ static int patch_vt1702(struct hda_codec *codec)
4464 int err; 4532 int err;
4465 4533
4466 /* create a codec specific record */ 4534 /* create a codec specific record */
4467 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 4535 spec = via_new_spec(codec);
4468 if (spec == NULL) 4536 if (spec == NULL)
4469 return -ENOMEM; 4537 return -ENOMEM;
4470 4538
4471 codec->spec = spec;
4472
4473 /* automatic parse from the BIOS config */ 4539 /* automatic parse from the BIOS config */
4474 err = vt1702_parse_auto_config(codec); 4540 err = vt1702_parse_auto_config(codec);
4475 if (err < 0) { 4541 if (err < 0) {
@@ -4865,9 +4931,9 @@ static int vt1718S_parse_auto_config(struct hda_codec *codec)
4865 spec->input_mux = &spec->private_imux[0]; 4931 spec->input_mux = &spec->private_imux[0];
4866 4932
4867 if (spec->hp_mux) 4933 if (spec->hp_mux)
4868 spec->mixers[spec->num_mixers++] = via_hp_mixer; 4934 via_hp_build(spec);
4869 4935
4870 spec->mixers[spec->num_mixers++] = via_smart51_mixer; 4936 via_smart51_build(spec);
4871 4937
4872 return 1; 4938 return 1;
4873} 4939}
@@ -4888,12 +4954,10 @@ static int patch_vt1718S(struct hda_codec *codec)
4888 int err; 4954 int err;
4889 4955
4890 /* create a codec specific record */ 4956 /* create a codec specific record */
4891 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 4957 spec = via_new_spec(codec);
4892 if (spec == NULL) 4958 if (spec == NULL)
4893 return -ENOMEM; 4959 return -ENOMEM;
4894 4960
4895 codec->spec = spec;
4896
4897 /* automatic parse from the BIOS config */ 4961 /* automatic parse from the BIOS config */
4898 err = vt1718S_parse_auto_config(codec); 4962 err = vt1718S_parse_auto_config(codec);
4899 if (err < 0) { 4963 if (err < 0) {
@@ -5014,6 +5078,7 @@ static struct snd_kcontrol_new vt1716s_dmic_mixer[] = {
5014 { 5078 {
5015 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 5079 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5016 .name = "Digital Mic Capture Switch", 5080 .name = "Digital Mic Capture Switch",
5081 .subdevice = HDA_SUBDEV_NID_FLAG | 0x26,
5017 .count = 1, 5082 .count = 1,
5018 .info = vt1716s_dmic_info, 5083 .info = vt1716s_dmic_info,
5019 .get = vt1716s_dmic_get, 5084 .get = vt1716s_dmic_get,
@@ -5361,9 +5426,9 @@ static int vt1716S_parse_auto_config(struct hda_codec *codec)
5361 spec->input_mux = &spec->private_imux[0]; 5426 spec->input_mux = &spec->private_imux[0];
5362 5427
5363 if (spec->hp_mux) 5428 if (spec->hp_mux)
5364 spec->mixers[spec->num_mixers++] = via_hp_mixer; 5429 via_hp_build(spec);
5365 5430
5366 spec->mixers[spec->num_mixers++] = via_smart51_mixer; 5431 via_smart51_build(spec);
5367 5432
5368 return 1; 5433 return 1;
5369} 5434}
@@ -5384,12 +5449,10 @@ static int patch_vt1716S(struct hda_codec *codec)
5384 int err; 5449 int err;
5385 5450
5386 /* create a codec specific record */ 5451 /* create a codec specific record */
5387 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 5452 spec = via_new_spec(codec);
5388 if (spec == NULL) 5453 if (spec == NULL)
5389 return -ENOMEM; 5454 return -ENOMEM;
5390 5455
5391 codec->spec = spec;
5392
5393 /* automatic parse from the BIOS config */ 5456 /* automatic parse from the BIOS config */
5394 err = vt1716S_parse_auto_config(codec); 5457 err = vt1716S_parse_auto_config(codec);
5395 if (err < 0) { 5458 if (err < 0) {
@@ -5719,7 +5782,7 @@ static int vt2002P_parse_auto_config(struct hda_codec *codec)
5719 spec->input_mux = &spec->private_imux[0]; 5782 spec->input_mux = &spec->private_imux[0];
5720 5783
5721 if (spec->hp_mux) 5784 if (spec->hp_mux)
5722 spec->mixers[spec->num_mixers++] = via_hp_mixer; 5785 via_hp_build(spec);
5723 5786
5724 return 1; 5787 return 1;
5725} 5788}
@@ -5741,12 +5804,10 @@ static int patch_vt2002P(struct hda_codec *codec)
5741 int err; 5804 int err;
5742 5805
5743 /* create a codec specific record */ 5806 /* create a codec specific record */
5744 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 5807 spec = via_new_spec(codec);
5745 if (spec == NULL) 5808 if (spec == NULL)
5746 return -ENOMEM; 5809 return -ENOMEM;
5747 5810
5748 codec->spec = spec;
5749
5750 /* automatic parse from the BIOS config */ 5811 /* automatic parse from the BIOS config */
5751 err = vt2002P_parse_auto_config(codec); 5812 err = vt2002P_parse_auto_config(codec);
5752 if (err < 0) { 5813 if (err < 0) {
@@ -6070,7 +6131,7 @@ static int vt1812_parse_auto_config(struct hda_codec *codec)
6070 spec->input_mux = &spec->private_imux[0]; 6131 spec->input_mux = &spec->private_imux[0];
6071 6132
6072 if (spec->hp_mux) 6133 if (spec->hp_mux)
6073 spec->mixers[spec->num_mixers++] = via_hp_mixer; 6134 via_hp_build(spec);
6074 6135
6075 return 1; 6136 return 1;
6076} 6137}
@@ -6092,12 +6153,10 @@ static int patch_vt1812(struct hda_codec *codec)
6092 int err; 6153 int err;
6093 6154
6094 /* create a codec specific record */ 6155 /* create a codec specific record */
6095 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 6156 spec = via_new_spec(codec);
6096 if (spec == NULL) 6157 if (spec == NULL)
6097 return -ENOMEM; 6158 return -ENOMEM;
6098 6159
6099 codec->spec = spec;
6100
6101 /* automatic parse from the BIOS config */ 6160 /* automatic parse from the BIOS config */
6102 err = vt1812_parse_auto_config(codec); 6161 err = vt1812_parse_auto_config(codec);
6103 if (err < 0) { 6162 if (err < 0) {