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