aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/hda
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2010-01-12 03:40:08 -0500
committerTakashi Iwai <tiwai@suse.de>2010-01-12 03:40:08 -0500
commita29fb94ff48cba620e1ac1317f5eef5920ead3ff (patch)
tree2fb8e026712bdf7848ea400e25118f6a58824a02 /sound/pci/hda
parent52a7a5835173af61b9f6c3038212370d9717526f (diff)
parentdd3533eca859a6debb1565503ec03e68354e08e0 (diff)
Merge commit alsa/devel into topic/misc
Conflicts: include/sound/version.h
Diffstat (limited to 'sound/pci/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 950ee5cfcacf..d2f10b1c3a8a 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 fe0423c39598..093cfbb55e9e 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)
@@ -760,6 +762,10 @@ static int build_input(struct hda_codec *codec)
760 err = snd_hda_ctl_add(codec, 0, kctl); 762 err = snd_hda_ctl_add(codec, 0, kctl);
761 if (err < 0) 763 if (err < 0)
762 return err; 764 return err;
765 err = snd_hda_add_nids(codec, kctl, 0, spec->adc_nid,
766 spec->num_inputs);
767 if (err < 0)
768 return err;
763 } 769 }
764 770
765 if (spec->num_inputs > 1 && !spec->mic_detect) { 771 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 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..aeb23ef6afe5 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,73 @@ 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 err = snd_hda_add_nids(codec, kctl, i, spec->capsrc_nids,
2552 spec->input_mux->num_items);
2553 if (err < 0)
2554 return err;
2555 }
2556 if (spec->cap_mixer) {
2557 const char *kname = kctl ? kctl->id.name : NULL;
2558 for (knew = spec->cap_mixer; knew->name; knew++) {
2559 if (kname && strcmp(knew->name, kname) == 0)
2560 continue;
2561 kctl = snd_hda_find_mixer_ctl(codec, knew->name);
2562 for (i = 0; kctl && i < kctl->count; i++) {
2563 err = snd_hda_add_nid(codec, kctl, i,
2564 spec->adc_nids[i]);
2565 if (err < 0)
2566 return err;
2567 }
2568 }
2569 }
2570
2571 /* other nid->control mapping */
2572 for (i = 0; i < spec->num_mixers; i++) {
2573 for (knew = spec->mixers[i]; knew->name; knew++) {
2574 if (knew->iface != NID_MAPPING)
2575 continue;
2576 kctl = snd_hda_find_mixer_ctl(codec, knew->name);
2577 if (kctl == NULL)
2578 continue;
2579 u = knew->subdevice;
2580 for (j = 0; j < 4; j++, u >>= 8) {
2581 nid = u & 0x3f;
2582 if (nid == 0)
2583 continue;
2584 switch (u & 0xc0) {
2585 case SUBDEV_SPEAKER_:
2586 nid = spec->autocfg.speaker_pins[nid];
2587 break;
2588 case SUBDEV_LINE_:
2589 nid = spec->autocfg.line_out_pins[nid];
2590 break;
2591 case SUBDEV_HP_:
2592 nid = spec->autocfg.hp_pins[nid];
2593 break;
2594 default:
2595 continue;
2596 }
2597 err = snd_hda_add_nid(codec, kctl, 0, nid);
2598 if (err < 0)
2599 return err;
2600 }
2601 u = knew->private_value;
2602 for (j = 0; j < 4; j++, u >>= 8) {
2603 nid = u & 0xff;
2604 if (nid == 0)
2605 continue;
2606 err = snd_hda_add_nid(codec, kctl, 0, nid);
2607 if (err < 0)
2608 return err;
2609 }
2610 }
2611 }
2530 return 0; 2612 return 0;
2531} 2613}
2532 2614
@@ -3832,6 +3914,7 @@ static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
3832#define PIN_CTL_TEST(xname,nid) { \ 3914#define PIN_CTL_TEST(xname,nid) { \
3833 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 3915 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
3834 .name = xname, \ 3916 .name = xname, \
3917 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
3835 .info = alc_test_pin_ctl_info, \ 3918 .info = alc_test_pin_ctl_info, \
3836 .get = alc_test_pin_ctl_get, \ 3919 .get = alc_test_pin_ctl_get, \
3837 .put = alc_test_pin_ctl_put, \ 3920 .put = alc_test_pin_ctl_put, \
@@ -3841,6 +3924,7 @@ static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
3841#define PIN_SRC_TEST(xname,nid) { \ 3924#define PIN_SRC_TEST(xname,nid) { \
3842 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 3925 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
3843 .name = xname, \ 3926 .name = xname, \
3927 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
3844 .info = alc_test_pin_src_info, \ 3928 .info = alc_test_pin_src_info, \
3845 .get = alc_test_pin_src_get, \ 3929 .get = alc_test_pin_src_get, \
3846 .put = alc_test_pin_src_put, \ 3930 .put = alc_test_pin_src_put, \
@@ -4380,7 +4464,7 @@ static int add_control(struct alc_spec *spec, int type, const char *name,
4380 if (!knew->name) 4464 if (!knew->name)
4381 return -ENOMEM; 4465 return -ENOMEM;
4382 if (get_amp_nid_(val)) 4466 if (get_amp_nid_(val))
4383 knew->subdevice = HDA_SUBDEV_NID_FLAG | get_amp_nid_(val); 4467 knew->subdevice = HDA_SUBDEV_AMP_FLAG;
4384 knew->private_value = val; 4468 knew->private_value = val;
4385 return 0; 4469 return 0;
4386} 4470}
@@ -5131,6 +5215,7 @@ static struct snd_kcontrol_new alc260_hp_output_mixer[] = {
5131 { 5215 {
5132 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 5216 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5133 .name = "Master Playback Switch", 5217 .name = "Master Playback Switch",
5218 .subdevice = HDA_SUBDEV_NID_FLAG | 0x11,
5134 .info = snd_ctl_boolean_mono_info, 5219 .info = snd_ctl_boolean_mono_info,
5135 .get = alc260_hp_master_sw_get, 5220 .get = alc260_hp_master_sw_get,
5136 .put = alc260_hp_master_sw_put, 5221 .put = alc260_hp_master_sw_put,
@@ -5169,6 +5254,7 @@ static struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
5169 { 5254 {
5170 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 5255 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5171 .name = "Master Playback Switch", 5256 .name = "Master Playback Switch",
5257 .subdevice = HDA_SUBDEV_NID_FLAG | 0x11,
5172 .info = snd_ctl_boolean_mono_info, 5258 .info = snd_ctl_boolean_mono_info,
5173 .get = alc260_hp_master_sw_get, 5259 .get = alc260_hp_master_sw_get,
5174 .put = alc260_hp_master_sw_put, 5260 .put = alc260_hp_master_sw_put,
@@ -10248,8 +10334,14 @@ static int alc262_hp_master_sw_put(struct snd_kcontrol *kcontrol,
10248 .info = snd_ctl_boolean_mono_info, \ 10334 .info = snd_ctl_boolean_mono_info, \
10249 .get = alc262_hp_master_sw_get, \ 10335 .get = alc262_hp_master_sw_get, \
10250 .put = alc262_hp_master_sw_put, \ 10336 .put = alc262_hp_master_sw_put, \
10337 }, \
10338 { \
10339 .iface = NID_MAPPING, \
10340 .name = "Master Playback Switch", \
10341 .private_value = 0x15 | (0x16 << 8) | (0x1b << 16), \
10251 } 10342 }
10252 10343
10344
10253static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = { 10345static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
10254 ALC262_HP_MASTER_SWITCH, 10346 ALC262_HP_MASTER_SWITCH,
10255 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 10347 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
@@ -10407,6 +10499,12 @@ static int alc262_hippo_master_sw_put(struct snd_kcontrol *kcontrol,
10407 .info = snd_ctl_boolean_mono_info, \ 10499 .info = snd_ctl_boolean_mono_info, \
10408 .get = alc262_hippo_master_sw_get, \ 10500 .get = alc262_hippo_master_sw_get, \
10409 .put = alc262_hippo_master_sw_put, \ 10501 .put = alc262_hippo_master_sw_put, \
10502 }, \
10503 { \
10504 .iface = NID_MAPPING, \
10505 .name = "Master Playback Switch", \
10506 .subdevice = SUBDEV_HP(0) | (SUBDEV_LINE(0) << 8) | \
10507 (SUBDEV_SPEAKER(0) << 16), \
10410 } 10508 }
10411 10509
10412static struct snd_kcontrol_new alc262_hippo_mixer[] = { 10510static struct snd_kcontrol_new alc262_hippo_mixer[] = {
@@ -10887,11 +10985,17 @@ static struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
10887 { 10985 {
10888 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 10986 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10889 .name = "Master Playback Switch", 10987 .name = "Master Playback Switch",
10988 .subdevice = HDA_SUBDEV_AMP_FLAG,
10890 .info = snd_hda_mixer_amp_switch_info, 10989 .info = snd_hda_mixer_amp_switch_info,
10891 .get = snd_hda_mixer_amp_switch_get, 10990 .get = snd_hda_mixer_amp_switch_get,
10892 .put = alc262_fujitsu_master_sw_put, 10991 .put = alc262_fujitsu_master_sw_put,
10893 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), 10992 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
10894 }, 10993 },
10994 {
10995 .iface = NID_MAPPING,
10996 .name = "Master Playback Switch",
10997 .private_value = 0x1b,
10998 },
10895 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 10999 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10896 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 11000 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
10897 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 11001 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
@@ -10922,6 +11026,7 @@ static struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = {
10922 { 11026 {
10923 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 11027 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10924 .name = "Master Playback Switch", 11028 .name = "Master Playback Switch",
11029 .subdevice = HDA_SUBDEV_AMP_FLAG,
10925 .info = snd_hda_mixer_amp_switch_info, 11030 .info = snd_hda_mixer_amp_switch_info,
10926 .get = snd_hda_mixer_amp_switch_get, 11031 .get = snd_hda_mixer_amp_switch_get,
10927 .put = alc262_lenovo_3000_master_sw_put, 11032 .put = alc262_lenovo_3000_master_sw_put,
@@ -11076,6 +11181,11 @@ static struct snd_kcontrol_new alc262_ultra_capture_mixer[] = {
11076 .get = alc_mux_enum_get, 11181 .get = alc_mux_enum_get,
11077 .put = alc262_ultra_mux_enum_put, 11182 .put = alc262_ultra_mux_enum_put,
11078 }, 11183 },
11184 {
11185 .iface = NID_MAPPING,
11186 .name = "Capture Source",
11187 .private_value = 0x15,
11188 },
11079 { } /* end */ 11189 { } /* end */
11080}; 11190};
11081 11191
@@ -12094,6 +12204,7 @@ static struct snd_kcontrol_new alc268_acer_aspire_one_mixer[] = {
12094 { 12204 {
12095 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 12205 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12096 .name = "Master Playback Switch", 12206 .name = "Master Playback Switch",
12207 .subdevice = HDA_SUBDEV_AMP_FLAG,
12097 .info = snd_hda_mixer_amp_switch_info, 12208 .info = snd_hda_mixer_amp_switch_info,
12098 .get = snd_hda_mixer_amp_switch_get, 12209 .get = snd_hda_mixer_amp_switch_get,
12099 .put = alc268_acer_master_sw_put, 12210 .put = alc268_acer_master_sw_put,
@@ -12109,6 +12220,7 @@ static struct snd_kcontrol_new alc268_acer_mixer[] = {
12109 { 12220 {
12110 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 12221 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12111 .name = "Master Playback Switch", 12222 .name = "Master Playback Switch",
12223 .subdevice = HDA_SUBDEV_AMP_FLAG,
12112 .info = snd_hda_mixer_amp_switch_info, 12224 .info = snd_hda_mixer_amp_switch_info,
12113 .get = snd_hda_mixer_amp_switch_get, 12225 .get = snd_hda_mixer_amp_switch_get,
12114 .put = alc268_acer_master_sw_put, 12226 .put = alc268_acer_master_sw_put,
@@ -12126,6 +12238,7 @@ static struct snd_kcontrol_new alc268_acer_dmic_mixer[] = {
12126 { 12238 {
12127 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 12239 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12128 .name = "Master Playback Switch", 12240 .name = "Master Playback Switch",
12241 .subdevice = HDA_SUBDEV_AMP_FLAG,
12129 .info = snd_hda_mixer_amp_switch_info, 12242 .info = snd_hda_mixer_amp_switch_info,
12130 .get = snd_hda_mixer_amp_switch_get, 12243 .get = snd_hda_mixer_amp_switch_get,
12131 .put = alc268_acer_master_sw_put, 12244 .put = alc268_acer_master_sw_put,
@@ -13078,6 +13191,7 @@ static struct snd_kcontrol_new alc269_quanta_fl1_mixer[] = {
13078 { 13191 {
13079 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 13192 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13080 .name = "Master Playback Switch", 13193 .name = "Master Playback Switch",
13194 .subdevice = HDA_SUBDEV_AMP_FLAG,
13081 .info = snd_hda_mixer_amp_switch_info, 13195 .info = snd_hda_mixer_amp_switch_info,
13082 .get = snd_hda_mixer_amp_switch_get, 13196 .get = snd_hda_mixer_amp_switch_get,
13083 .put = alc268_acer_master_sw_put, 13197 .put = alc268_acer_master_sw_put,
@@ -13098,6 +13212,7 @@ static struct snd_kcontrol_new alc269_lifebook_mixer[] = {
13098 { 13212 {
13099 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 13213 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13100 .name = "Master Playback Switch", 13214 .name = "Master Playback Switch",
13215 .subdevice = HDA_SUBDEV_AMP_FLAG,
13101 .info = snd_hda_mixer_amp_switch_info, 13216 .info = snd_hda_mixer_amp_switch_info,
13102 .get = snd_hda_mixer_amp_switch_get, 13217 .get = snd_hda_mixer_amp_switch_get,
13103 .put = alc268_acer_master_sw_put, 13218 .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..74d5d333ed6c 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;
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) {