diff options
author | Jaroslav Kysela <perex@perex.cz> | 2009-12-08 10:13:32 -0500 |
---|---|---|
committer | Jaroslav Kysela <perex@perex.cz> | 2009-12-15 03:33:04 -0500 |
commit | 5b0cb1d850c26893b1468b3a519433a1b7a176be (patch) | |
tree | c6f4ab97db6de9230b02d6cfce8976b762f3b485 /sound/pci | |
parent | f40542532e96dda5506eb76badea322f2ae4731c (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.c | 64 | ||||
-rw-r--r-- | sound/pci/hda/hda_codec.h | 1 | ||||
-rw-r--r-- | sound/pci/hda/hda_generic.c | 3 | ||||
-rw-r--r-- | sound/pci/hda/hda_local.h | 5 | ||||
-rw-r--r-- | sound/pci/hda/hda_proc.c | 23 | ||||
-rw-r--r-- | sound/pci/hda/patch_analog.c | 31 | ||||
-rw-r--r-- | sound/pci/hda/patch_cirrus.c | 4 | ||||
-rw-r--r-- | sound/pci/hda/patch_cmedia.c | 12 | ||||
-rw-r--r-- | sound/pci/hda/patch_realtek.c | 120 | ||||
-rw-r--r-- | sound/pci/hda/patch_si3054.c | 1 | ||||
-rw-r--r-- | sound/pci/hda/patch_via.c | 273 |
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, | |||
1706 | EXPORT_SYMBOL_HDA(snd_hda_find_mixer_ctl); | 1708 | EXPORT_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, | |||
1747 | EXPORT_SYMBOL_HDA(snd_hda_ctl_add); | 1749 | EXPORT_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 | */ | ||
1762 | int 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 | } | ||
1778 | EXPORT_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 | } |
3497 | EXPORT_SYMBOL_HDA(snd_hda_add_new_ctls); | 3531 | EXPORT_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 | */ | ||
3545 | int 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 | } | ||
3557 | EXPORT_SYMBOL_HDA(snd_hda_add_nids); | ||
3558 | |||
3499 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 3559 | #ifdef CONFIG_SND_HDA_POWER_SAVE |
3500 | static void hda_set_power_state(struct hda_codec *codec, hda_nid_t fg, | 3560 | static 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); |
343 | int snd_hda_add_new_ctls(struct hda_codec *codec, | 343 | int snd_hda_add_new_ctls(struct hda_codec *codec, |
344 | struct snd_kcontrol_new *knew); | 344 | struct snd_kcontrol_new *knew); |
345 | int 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 | ||
467 | struct hda_nid_item { | 469 | struct 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 | ||
472 | int snd_hda_ctl_add(struct hda_codec *codec, hda_nid_t nid, | 475 | int snd_hda_ctl_add(struct hda_codec *codec, hda_nid_t nid, |
473 | struct snd_kcontrol *kctl); | 476 | struct snd_kcontrol *kctl); |
477 | int snd_hda_add_nid(struct hda_codec *codec, struct snd_kcontrol *kctl, | ||
478 | unsigned int index, hda_nid_t nid); | ||
474 | void snd_hda_ctls_clear(struct hda_codec *codec); | 479 | void 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 | ||
64 | static void print_nid_mixers(struct snd_info_buffer *buffer, | 64 | static 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 | ||
534 | static void print_codec_info(struct snd_info_entry *entry, | 538 | static 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[] = { | |||
174 | static int ad198x_build_controls(struct hda_codec *codec) | 174 | static 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[] = { | |||
315 | static int cmi9880_build_controls(struct hda_codec *codec) | 315 | static 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 | |||
2413 | static void alc_free_kctls(struct hda_codec *codec); | 2426 | static 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[] = { | |||
2424 | static int alc_build_controls(struct hda_codec *codec) | 2437 | static 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 | |||
10193 | static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = { | 10286 | static 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 | ||
10352 | static struct snd_kcontrol_new alc262_hippo_mixer[] = { | 10451 | static 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 | ||
162 | static 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 | |||
160 | static enum VIA_HDA_CODEC get_codec_type(struct hda_codec *codec) | 175 | static 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 | ||
466 | static 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 | |||
451 | static void via_free_kctls(struct hda_codec *codec) | 482 | static 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 | ||
1146 | static 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 | |||
1130 | static int update_side_mute_status(struct hda_codec *codec) | 1157 | static 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 | ||
1210 | static struct snd_kcontrol_new via_hp_mixer[] = { | 1204 | static 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 | ||
1218 | static 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 | |||
1222 | static void notify_aa_path_ctls(struct hda_codec *codec) | 1253 | static 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 | ||
1379 | static struct snd_kcontrol_new via_smart51_mixer[] = { | 1410 | static 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 | ||
1425 | static 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 */ |
1392 | static struct snd_kcontrol_new vt1708_capture_mixer[] = { | 1450 | static 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 = { | |||
1819 | static int via_build_controls(struct hda_codec *codec) | 1877 | static 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) { |