aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci
diff options
context:
space:
mode:
authorJaroslav Kysela <perex@perex.cz>2009-12-08 10:13:32 -0500
committerJaroslav Kysela <perex@perex.cz>2009-12-15 03:33:04 -0500
commit5b0cb1d850c26893b1468b3a519433a1b7a176be (patch)
treec6f4ab97db6de9230b02d6cfce8976b762f3b485 /sound/pci
parentf40542532e96dda5506eb76badea322f2ae4731c (diff)
ALSA: hda - add more NID->Control mapping
This set of changes add missing NID values to some static control elemenents. Also, it handles all "Capture Source" or "Input Source" controls. Signed-off-by: Jaroslav Kysela <perex@perex.cz>
Diffstat (limited to 'sound/pci')
-rw-r--r--sound/pci/hda/hda_codec.c64
-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.h5
-rw-r--r--sound/pci/hda/hda_proc.c23
-rw-r--r--sound/pci/hda/patch_analog.c31
-rw-r--r--sound/pci/hda/patch_cirrus.c4
-rw-r--r--sound/pci/hda/patch_cmedia.c12
-rw-r--r--sound/pci/hda/patch_realtek.c120
-rw-r--r--sound/pci/hda/patch_si3054.c1
-rw-r--r--sound/pci/hda/patch_via.c273
11 files changed, 415 insertions, 122 deletions
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index 9cfdb771928c..20100b1548e1 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
@@ -1747,6 +1749,35 @@ int snd_hda_ctl_add(struct hda_codec *codec, hda_nid_t nid,
1747EXPORT_SYMBOL_HDA(snd_hda_ctl_add); 1749EXPORT_SYMBOL_HDA(snd_hda_ctl_add);
1748 1750
1749/** 1751/**
1752 * snd_hda_add_nid - Assign a NID to a control element
1753 * @codec: HD-audio codec
1754 * @nid: corresponding NID (optional)
1755 * @kctl: the control element to assign
1756 * @index: index to kctl
1757 *
1758 * Add the given control element to an array inside the codec instance.
1759 * This function is used when #snd_hda_ctl_add cannot be used for 1:1
1760 * NID:KCTL mapping - for example "Capture Source" selector.
1761 */
1762int snd_hda_add_nid(struct hda_codec *codec, struct snd_kcontrol *kctl,
1763 unsigned int index, hda_nid_t nid)
1764{
1765 struct hda_nid_item *item;
1766
1767 if (nid > 0) {
1768 item = snd_array_new(&codec->nids);
1769 if (!item)
1770 return -ENOMEM;
1771 item->kctl = kctl;
1772 item->index = index;
1773 item->nid = nid;
1774 return 0;
1775 }
1776 return -EINVAL;
1777}
1778EXPORT_SYMBOL_HDA(snd_hda_add_nid);
1779
1780/**
1750 * snd_hda_ctls_clear - Clear all controls assigned to the given codec 1781 * snd_hda_ctls_clear - Clear all controls assigned to the given codec
1751 * @codec: HD-audio codec 1782 * @codec: HD-audio codec
1752 */ 1783 */
@@ -1757,6 +1788,7 @@ void snd_hda_ctls_clear(struct hda_codec *codec)
1757 for (i = 0; i < codec->mixers.used; i++) 1788 for (i = 0; i < codec->mixers.used; i++)
1758 snd_ctl_remove(codec->bus->card, items[i].kctl); 1789 snd_ctl_remove(codec->bus->card, items[i].kctl);
1759 snd_array_free(&codec->mixers); 1790 snd_array_free(&codec->mixers);
1791 snd_array_free(&codec->nids);
1760} 1792}
1761 1793
1762/* pseudo device locking 1794/* pseudo device locking
@@ -3476,6 +3508,8 @@ int snd_hda_add_new_ctls(struct hda_codec *codec, struct snd_kcontrol_new *knew)
3476 3508
3477 for (; knew->name; knew++) { 3509 for (; knew->name; knew++) {
3478 struct snd_kcontrol *kctl; 3510 struct snd_kcontrol *kctl;
3511 if (knew->iface == -1) /* skip this codec private value */
3512 continue;
3479 kctl = snd_ctl_new1(knew, codec); 3513 kctl = snd_ctl_new1(knew, codec);
3480 if (!kctl) 3514 if (!kctl)
3481 return -ENOMEM; 3515 return -ENOMEM;
@@ -3496,6 +3530,32 @@ int snd_hda_add_new_ctls(struct hda_codec *codec, struct snd_kcontrol_new *knew)
3496} 3530}
3497EXPORT_SYMBOL_HDA(snd_hda_add_new_ctls); 3531EXPORT_SYMBOL_HDA(snd_hda_add_new_ctls);
3498 3532
3533/**
3534 * snd_hda_add_nids - assign nids to controls from the array
3535 * @codec: the HDA codec
3536 * @kctl: struct snd_kcontrol
3537 * @index: index to kctl
3538 * @nids: the array of hda_nid_t
3539 * @size: count of hda_nid_t items
3540 *
3541 * This helper function assigns NIDs in the given array to a control element.
3542 *
3543 * Returns 0 if successful, or a negative error code.
3544 */
3545int snd_hda_add_nids(struct hda_codec *codec, struct snd_kcontrol *kctl,
3546 unsigned int index, hda_nid_t *nids, unsigned int size)
3547{
3548 int err;
3549
3550 for ( ; size > 0; size--, nids++) {
3551 err = snd_hda_add_nid(codec, kctl, index, *nids);
3552 if (err < 0)
3553 return err;
3554 }
3555 return 0;
3556}
3557EXPORT_SYMBOL_HDA(snd_hda_add_nids);
3558
3499#ifdef CONFIG_SND_HDA_POWER_SAVE 3559#ifdef CONFIG_SND_HDA_POWER_SAVE
3500static void hda_set_power_state(struct hda_codec *codec, hda_nid_t fg, 3560static void hda_set_power_state(struct hda_codec *codec, hda_nid_t fg,
3501 unsigned int power_state); 3561 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..98cf3f4f3755 100644
--- a/sound/pci/hda/hda_local.h
+++ b/sound/pci/hda/hda_local.h
@@ -342,6 +342,8 @@ int snd_hda_check_board_codec_sid_config(struct hda_codec *codec,
342 const struct snd_pci_quirk *tbl); 342 const struct snd_pci_quirk *tbl);
343int snd_hda_add_new_ctls(struct hda_codec *codec, 343int snd_hda_add_new_ctls(struct hda_codec *codec,
344 struct snd_kcontrol_new *knew); 344 struct snd_kcontrol_new *knew);
345int snd_hda_add_nids(struct hda_codec *codec, struct snd_kcontrol *kctl,
346 unsigned int index, hda_nid_t *nids, unsigned int size);
345 347
346/* 348/*
347 * unsolicited event handler 349 * unsolicited event handler
@@ -466,11 +468,14 @@ int snd_hda_jack_detect(struct hda_codec *codec, hda_nid_t nid);
466 468
467struct hda_nid_item { 469struct hda_nid_item {
468 struct snd_kcontrol *kctl; 470 struct snd_kcontrol *kctl;
471 unsigned int index;
469 hda_nid_t nid; 472 hda_nid_t nid;
470}; 473};
471 474
472int snd_hda_ctl_add(struct hda_codec *codec, hda_nid_t nid, 475int snd_hda_ctl_add(struct hda_codec *codec, hda_nid_t nid,
473 struct snd_kcontrol *kctl); 476 struct snd_kcontrol *kctl);
477int snd_hda_add_nid(struct hda_codec *codec, struct snd_kcontrol *kctl,
478 unsigned int index, hda_nid_t nid);
474void snd_hda_ctls_clear(struct hda_codec *codec); 479void snd_hda_ctls_clear(struct hda_codec *codec);
475 480
476/* 481/*
diff --git a/sound/pci/hda/hda_proc.c b/sound/pci/hda/hda_proc.c
index c9afc04adac8..2e27d6a8b446 100644
--- a/sound/pci/hda/hda_proc.c
+++ b/sound/pci/hda/hda_proc.c
@@ -61,18 +61,21 @@ 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);
76 } 79 }
77 } 80 }
78} 81}
@@ -528,7 +531,8 @@ static void print_gpio(struct snd_info_buffer *buffer,
528 (data & (1<<i)) ? 1 : 0, 531 (data & (1<<i)) ? 1 : 0,
529 (unsol & (1<<i)) ? 1 : 0); 532 (unsol & (1<<i)) ? 1 : 0);
530 /* FIXME: add GPO and GPI pin information */ 533 /* FIXME: add GPO and GPI pin information */
531 print_nid_mixers(buffer, codec, nid); 534 print_nid_array(buffer, codec, nid, &codec->mixers);
535 print_nid_array(buffer, codec, nid, &codec->nids);
532} 536}
533 537
534static void print_codec_info(struct snd_info_entry *entry, 538static void print_codec_info(struct snd_info_entry *entry,
@@ -608,7 +612,8 @@ static void print_codec_info(struct snd_info_entry *entry,
608 snd_iprintf(buffer, " CP"); 612 snd_iprintf(buffer, " CP");
609 snd_iprintf(buffer, "\n"); 613 snd_iprintf(buffer, "\n");
610 614
611 print_nid_mixers(buffer, codec, nid); 615 print_nid_array(buffer, codec, nid, &codec->mixers);
616 print_nid_array(buffer, codec, nid, &codec->nids);
612 print_nid_pcms(buffer, codec, nid); 617 print_nid_pcms(buffer, codec, nid);
613 618
614 /* volume knob is a special widget that always have connection 619 /* 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 447eda1f6770..d418842373fd 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
@@ -239,6 +240,28 @@ static int ad198x_build_controls(struct hda_codec *codec)
239 } 240 }
240 241
241 ad198x_free_kctls(codec); /* no longer needed */ 242 ad198x_free_kctls(codec); /* no longer needed */
243
244 /* assign Capture Source enums to NID */
245 kctl = snd_hda_find_mixer_ctl(codec, "Capture Source");
246 if (!kctl)
247 kctl = snd_hda_find_mixer_ctl(codec, "Input Source");
248 for (i = 0; kctl && i < kctl->count; i++) {
249 err = snd_hda_add_nids(codec, kctl, i, spec->capsrc_nids,
250 spec->input_mux->num_items);
251 if (err < 0)
252 return err;
253 }
254
255 /* assign IEC958 enums to NID */
256 kctl = snd_hda_find_mixer_ctl(codec,
257 SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source");
258 if (kctl) {
259 err = snd_hda_add_nid(codec, kctl, 0,
260 spec->multiout.dig_out_nid);
261 if (err < 0)
262 return err;
263 }
264
242 return 0; 265 return 0;
243} 266}
244 267
@@ -701,6 +724,7 @@ static struct snd_kcontrol_new ad1986a_laptop_eapd_mixers[] = {
701 { 724 {
702 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 725 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
703 .name = "External Amplifier", 726 .name = "External Amplifier",
727 .subdevice = HDA_SUBDEV_NID_FLAG | 0x1b,
704 .info = ad198x_eapd_info, 728 .info = ad198x_eapd_info,
705 .get = ad198x_eapd_get, 729 .get = ad198x_eapd_get,
706 .put = ad198x_eapd_put, 730 .put = ad198x_eapd_put,
@@ -808,6 +832,7 @@ static struct snd_kcontrol_new ad1986a_automute_master_mixers[] = {
808 { 832 {
809 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 833 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
810 .name = "Master Playback Switch", 834 .name = "Master Playback Switch",
835 .subdevice = HDA_SUBDEV_NID_FLAG | 0x1a,
811 .info = snd_hda_mixer_amp_switch_info, 836 .info = snd_hda_mixer_amp_switch_info,
812 .get = snd_hda_mixer_amp_switch_get, 837 .get = snd_hda_mixer_amp_switch_get,
813 .put = ad1986a_hp_master_sw_put, 838 .put = ad1986a_hp_master_sw_put,
@@ -1608,6 +1633,7 @@ static struct snd_kcontrol_new ad1981_hp_mixers[] = {
1608 HDA_BIND_VOL("Master Playback Volume", &ad1981_hp_bind_master_vol), 1633 HDA_BIND_VOL("Master Playback Volume", &ad1981_hp_bind_master_vol),
1609 { 1634 {
1610 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1635 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1636 .subdevice = HDA_SUBDEV_NID_FLAG | 0x05,
1611 .name = "Master Playback Switch", 1637 .name = "Master Playback Switch",
1612 .info = ad198x_eapd_info, 1638 .info = ad198x_eapd_info,
1613 .get = ad198x_eapd_get, 1639 .get = ad198x_eapd_get,
@@ -2121,6 +2147,7 @@ static struct snd_kcontrol_new ad1988_laptop_mixers[] = {
2121 { 2147 {
2122 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2148 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2123 .name = "External Amplifier", 2149 .name = "External Amplifier",
2150 .subdevice = HDA_SUBDEV_NID_FLAG | 0x12,
2124 .info = ad198x_eapd_info, 2151 .info = ad198x_eapd_info,
2125 .get = ad198x_eapd_get, 2152 .get = ad198x_eapd_get,
2126 .put = ad198x_eapd_put, 2153 .put = ad198x_eapd_put,
@@ -2242,6 +2269,7 @@ static struct snd_kcontrol_new ad1988_spdif_out_mixers[] = {
2242 { 2269 {
2243 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2270 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2244 .name = "IEC958 Playback Source", 2271 .name = "IEC958 Playback Source",
2272 .subdevice = HDA_SUBDEV_NID_FLAG | 0x1b,
2245 .info = ad1988_spdif_playback_source_info, 2273 .info = ad1988_spdif_playback_source_info,
2246 .get = ad1988_spdif_playback_source_get, 2274 .get = ad1988_spdif_playback_source_get,
2247 .put = ad1988_spdif_playback_source_put, 2275 .put = ad1988_spdif_playback_source_put,
@@ -3728,6 +3756,7 @@ static struct snd_kcontrol_new ad1884a_laptop_mixers[] = {
3728 { 3756 {
3729 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 3757 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3730 .name = "Master Playback Switch", 3758 .name = "Master Playback Switch",
3759 .subdevice = HDA_SUBDEV_NID_FLAG | 0x21,
3731 .info = snd_hda_mixer_amp_switch_info, 3760 .info = snd_hda_mixer_amp_switch_info,
3732 .get = snd_hda_mixer_amp_switch_get, 3761 .get = snd_hda_mixer_amp_switch_get,
3733 .put = ad1884a_mobile_master_sw_put, 3762 .put = ad1884a_mobile_master_sw_put,
@@ -3756,6 +3785,7 @@ static struct snd_kcontrol_new ad1884a_mobile_mixers[] = {
3756 { 3785 {
3757 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 3786 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3758 .name = "Master Playback Switch", 3787 .name = "Master Playback Switch",
3788 .subdevice = HDA_SUBDEV_NID_FLAG | 0x21,
3759 .info = snd_hda_mixer_amp_switch_info, 3789 .info = snd_hda_mixer_amp_switch_info,
3760 .get = snd_hda_mixer_amp_switch_get, 3790 .get = snd_hda_mixer_amp_switch_get,
3761 .put = ad1884a_mobile_master_sw_put, 3791 .put = ad1884a_mobile_master_sw_put,
@@ -4097,6 +4127,7 @@ static struct snd_kcontrol_new ad1984a_touchsmart_mixers[] = {
4097/* HDA_CODEC_MUTE("Master Playback Switch", 0x21, 0x0, HDA_OUTPUT),*/ 4127/* HDA_CODEC_MUTE("Master Playback Switch", 0x21, 0x0, HDA_OUTPUT),*/
4098 { 4128 {
4099 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 4129 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4130 .subdevice = HDA_SUBDEV_NID_FLAG | 0x21,
4100 .name = "Master Playback Switch", 4131 .name = "Master Playback Switch",
4101 .info = snd_hda_mixer_amp_switch_info, 4132 .info = snd_hda_mixer_amp_switch_info,
4102 .get = snd_hda_mixer_amp_switch_get, 4133 .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..d0b8c6dc7322 100644
--- a/sound/pci/hda/patch_cirrus.c
+++ b/sound/pci/hda/patch_cirrus.c
@@ -759,6 +759,10 @@ static int build_input(struct hda_codec *codec)
759 err = snd_hda_ctl_add(codec, 0, kctl); 759 err = snd_hda_ctl_add(codec, 0, kctl);
760 if (err < 0) 760 if (err < 0)
761 return err; 761 return err;
762 err = snd_hda_add_nids(codec, kctl, 0, spec->adc_nid,
763 spec->num_inputs);
764 if (err < 0)
765 return err;
762 } 766 }
763 767
764 if (spec->num_inputs > 1 && !spec->mic_detect) { 768 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_realtek.c b/sound/pci/hda/patch_realtek.c
index 888b6313eeca..6b0b8728f6b7 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]);
@@ -2494,6 +2510,73 @@ static int alc_build_controls(struct hda_codec *codec)
2494 } 2510 }
2495 2511
2496 alc_free_kctls(codec); /* no longer needed */ 2512 alc_free_kctls(codec); /* no longer needed */
2513
2514 /* assign Capture Source enums to NID */
2515 kctl = snd_hda_find_mixer_ctl(codec, "Capture Source");
2516 if (!kctl)
2517 kctl = snd_hda_find_mixer_ctl(codec, "Input Source");
2518 for (i = 0; kctl && i < kctl->count; i++) {
2519 err = snd_hda_add_nids(codec, kctl, i, spec->capsrc_nids,
2520 spec->input_mux->num_items);
2521 if (err < 0)
2522 return err;
2523 }
2524 if (spec->cap_mixer) {
2525 const char *kname = kctl ? kctl->id.name : NULL;
2526 for (knew = spec->cap_mixer; knew->name; knew++) {
2527 if (kname && strcmp(knew->name, kname) == 0)
2528 continue;
2529 kctl = snd_hda_find_mixer_ctl(codec, knew->name);
2530 for (i = 0; kctl && i < kctl->count; i++) {
2531 err = snd_hda_add_nid(codec, kctl, i,
2532 spec->adc_nids[i]);
2533 if (err < 0)
2534 return err;
2535 }
2536 }
2537 }
2538
2539 /* other nid->control mapping */
2540 for (i = 0; i < spec->num_mixers; i++) {
2541 for (knew = spec->mixers[i]; knew->name; knew++) {
2542 if (knew->iface != NID_MAPPING)
2543 continue;
2544 kctl = snd_hda_find_mixer_ctl(codec, knew->name);
2545 if (kctl == NULL)
2546 continue;
2547 u = knew->subdevice;
2548 for (j = 0; j < 4; j++, u >>= 8) {
2549 nid = u & 0x3f;
2550 if (nid == 0)
2551 continue;
2552 switch (u & 0xc0) {
2553 case SUBDEV_SPEAKER_:
2554 nid = spec->autocfg.speaker_pins[nid];
2555 break;
2556 case SUBDEV_LINE_:
2557 nid = spec->autocfg.line_out_pins[nid];
2558 break;
2559 case SUBDEV_HP_:
2560 nid = spec->autocfg.hp_pins[nid];
2561 break;
2562 default:
2563 continue;
2564 }
2565 err = snd_hda_add_nid(codec, kctl, 0, nid);
2566 if (err < 0)
2567 return err;
2568 }
2569 u = knew->private_value;
2570 for (j = 0; j < 4; j++, u >>= 8) {
2571 nid = u & 0xff;
2572 if (nid == 0)
2573 continue;
2574 err = snd_hda_add_nid(codec, kctl, 0, nid);
2575 if (err < 0)
2576 return err;
2577 }
2578 }
2579 }
2497 return 0; 2580 return 0;
2498} 2581}
2499 2582
@@ -3781,6 +3864,7 @@ static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
3781#define PIN_CTL_TEST(xname,nid) { \ 3864#define PIN_CTL_TEST(xname,nid) { \
3782 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 3865 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
3783 .name = xname, \ 3866 .name = xname, \
3867 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
3784 .info = alc_test_pin_ctl_info, \ 3868 .info = alc_test_pin_ctl_info, \
3785 .get = alc_test_pin_ctl_get, \ 3869 .get = alc_test_pin_ctl_get, \
3786 .put = alc_test_pin_ctl_put, \ 3870 .put = alc_test_pin_ctl_put, \
@@ -3790,6 +3874,7 @@ static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
3790#define PIN_SRC_TEST(xname,nid) { \ 3874#define PIN_SRC_TEST(xname,nid) { \
3791 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 3875 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
3792 .name = xname, \ 3876 .name = xname, \
3877 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
3793 .info = alc_test_pin_src_info, \ 3878 .info = alc_test_pin_src_info, \
3794 .get = alc_test_pin_src_get, \ 3879 .get = alc_test_pin_src_get, \
3795 .put = alc_test_pin_src_put, \ 3880 .put = alc_test_pin_src_put, \
@@ -5080,6 +5165,7 @@ static struct snd_kcontrol_new alc260_hp_output_mixer[] = {
5080 { 5165 {
5081 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 5166 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5082 .name = "Master Playback Switch", 5167 .name = "Master Playback Switch",
5168 .subdevice = HDA_SUBDEV_NID_FLAG | 0x11,
5083 .info = snd_ctl_boolean_mono_info, 5169 .info = snd_ctl_boolean_mono_info,
5084 .get = alc260_hp_master_sw_get, 5170 .get = alc260_hp_master_sw_get,
5085 .put = alc260_hp_master_sw_put, 5171 .put = alc260_hp_master_sw_put,
@@ -5118,6 +5204,7 @@ static struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
5118 { 5204 {
5119 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 5205 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5120 .name = "Master Playback Switch", 5206 .name = "Master Playback Switch",
5207 .subdevice = HDA_SUBDEV_NID_FLAG | 0x11,
5121 .info = snd_ctl_boolean_mono_info, 5208 .info = snd_ctl_boolean_mono_info,
5122 .get = alc260_hp_master_sw_get, 5209 .get = alc260_hp_master_sw_get,
5123 .put = alc260_hp_master_sw_put, 5210 .put = alc260_hp_master_sw_put,
@@ -10188,8 +10275,14 @@ static int alc262_hp_master_sw_put(struct snd_kcontrol *kcontrol,
10188 .info = snd_ctl_boolean_mono_info, \ 10275 .info = snd_ctl_boolean_mono_info, \
10189 .get = alc262_hp_master_sw_get, \ 10276 .get = alc262_hp_master_sw_get, \
10190 .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), \
10191 } 10283 }
10192 10284
10285
10193static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = { 10286static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
10194 ALC262_HP_MASTER_SWITCH, 10287 ALC262_HP_MASTER_SWITCH,
10195 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 10288 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
@@ -10347,6 +10440,12 @@ static int alc262_hippo_master_sw_put(struct snd_kcontrol *kcontrol,
10347 .info = snd_ctl_boolean_mono_info, \ 10440 .info = snd_ctl_boolean_mono_info, \
10348 .get = alc262_hippo_master_sw_get, \ 10441 .get = alc262_hippo_master_sw_get, \
10349 .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), \
10350 } 10449 }
10351 10450
10352static struct snd_kcontrol_new alc262_hippo_mixer[] = { 10451static struct snd_kcontrol_new alc262_hippo_mixer[] = {
@@ -10820,11 +10919,17 @@ static struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
10820 { 10919 {
10821 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 10920 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10822 .name = "Master Playback Switch", 10921 .name = "Master Playback Switch",
10922 .subdevice = HDA_SUBDEV_NID_FLAG | 0x14,
10823 .info = snd_hda_mixer_amp_switch_info, 10923 .info = snd_hda_mixer_amp_switch_info,
10824 .get = snd_hda_mixer_amp_switch_get, 10924 .get = snd_hda_mixer_amp_switch_get,
10825 .put = alc262_fujitsu_master_sw_put, 10925 .put = alc262_fujitsu_master_sw_put,
10826 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), 10926 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
10827 }, 10927 },
10928 {
10929 .iface = NID_MAPPING,
10930 .name = "Master Playback Switch",
10931 .private_value = 0x1b,
10932 },
10828 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 10933 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10829 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 10934 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
10830 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 10935 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
@@ -10855,6 +10960,7 @@ static struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = {
10855 { 10960 {
10856 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 10961 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10857 .name = "Master Playback Switch", 10962 .name = "Master Playback Switch",
10963 .subdevice = HDA_SUBDEV_NID_FLAG | 0x1b,
10858 .info = snd_hda_mixer_amp_switch_info, 10964 .info = snd_hda_mixer_amp_switch_info,
10859 .get = snd_hda_mixer_amp_switch_get, 10965 .get = snd_hda_mixer_amp_switch_get,
10860 .put = alc262_lenovo_3000_master_sw_put, 10966 .put = alc262_lenovo_3000_master_sw_put,
@@ -11009,6 +11115,11 @@ static struct snd_kcontrol_new alc262_ultra_capture_mixer[] = {
11009 .get = alc_mux_enum_get, 11115 .get = alc_mux_enum_get,
11010 .put = alc262_ultra_mux_enum_put, 11116 .put = alc262_ultra_mux_enum_put,
11011 }, 11117 },
11118 {
11119 .iface = NID_MAPPING,
11120 .name = "Capture Source",
11121 .private_value = 0x15,
11122 },
11012 { } /* end */ 11123 { } /* end */
11013}; 11124};
11014 11125
@@ -12026,6 +12137,7 @@ static struct snd_kcontrol_new alc268_acer_aspire_one_mixer[] = {
12026 { 12137 {
12027 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 12138 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12028 .name = "Master Playback Switch", 12139 .name = "Master Playback Switch",
12140 .subdevice = HDA_SUBDEV_NID_FLAG | 0x14,
12029 .info = snd_hda_mixer_amp_switch_info, 12141 .info = snd_hda_mixer_amp_switch_info,
12030 .get = snd_hda_mixer_amp_switch_get, 12142 .get = snd_hda_mixer_amp_switch_get,
12031 .put = alc268_acer_master_sw_put, 12143 .put = alc268_acer_master_sw_put,
@@ -12041,6 +12153,7 @@ static struct snd_kcontrol_new alc268_acer_mixer[] = {
12041 { 12153 {
12042 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 12154 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12043 .name = "Master Playback Switch", 12155 .name = "Master Playback Switch",
12156 .subdevice = HDA_SUBDEV_NID_FLAG | 0x14,
12044 .info = snd_hda_mixer_amp_switch_info, 12157 .info = snd_hda_mixer_amp_switch_info,
12045 .get = snd_hda_mixer_amp_switch_get, 12158 .get = snd_hda_mixer_amp_switch_get,
12046 .put = alc268_acer_master_sw_put, 12159 .put = alc268_acer_master_sw_put,
@@ -12058,6 +12171,7 @@ static struct snd_kcontrol_new alc268_acer_dmic_mixer[] = {
12058 { 12171 {
12059 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 12172 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12060 .name = "Master Playback Switch", 12173 .name = "Master Playback Switch",
12174 .subdevice = HDA_SUBDEV_NID_FLAG | 0x14,
12061 .info = snd_hda_mixer_amp_switch_info, 12175 .info = snd_hda_mixer_amp_switch_info,
12062 .get = snd_hda_mixer_amp_switch_get, 12176 .get = snd_hda_mixer_amp_switch_get,
12063 .put = alc268_acer_master_sw_put, 12177 .put = alc268_acer_master_sw_put,
@@ -13010,6 +13124,7 @@ static struct snd_kcontrol_new alc269_quanta_fl1_mixer[] = {
13010 { 13124 {
13011 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 13125 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13012 .name = "Master Playback Switch", 13126 .name = "Master Playback Switch",
13127 .subdevice = HDA_SUBDEV_NID_FLAG | 0x14,
13013 .info = snd_hda_mixer_amp_switch_info, 13128 .info = snd_hda_mixer_amp_switch_info,
13014 .get = snd_hda_mixer_amp_switch_get, 13129 .get = snd_hda_mixer_amp_switch_get,
13015 .put = alc268_acer_master_sw_put, 13130 .put = alc268_acer_master_sw_put,
@@ -13030,6 +13145,7 @@ static struct snd_kcontrol_new alc269_lifebook_mixer[] = {
13030 { 13145 {
13031 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 13146 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13032 .name = "Master Playback Switch", 13147 .name = "Master Playback Switch",
13148 .subdevice = HDA_SUBDEV_NID_FLAG | 0x14,
13033 .info = snd_hda_mixer_amp_switch_info, 13149 .info = snd_hda_mixer_amp_switch_info,
13034 .get = snd_hda_mixer_amp_switch_get, 13150 .get = snd_hda_mixer_amp_switch_get,
13035 .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_via.c b/sound/pci/hda/patch_via.c
index b70e26ad263f..64995e8e3a72 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;
@@ -448,6 +463,22 @@ static int via_add_control(struct via_spec *spec, int type, const char *name,
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) {