diff options
Diffstat (limited to 'sound/pci/hda/hda_codec.c')
-rw-r--r-- | sound/pci/hda/hda_codec.c | 81 |
1 files changed, 73 insertions, 8 deletions
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index f98b47cd6cf..76d3c4c049d 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c | |||
@@ -824,6 +824,9 @@ int snd_hda_add_pincfg(struct hda_codec *codec, struct snd_array *list, | |||
824 | struct hda_pincfg *pin; | 824 | struct hda_pincfg *pin; |
825 | unsigned int oldcfg; | 825 | unsigned int oldcfg; |
826 | 826 | ||
827 | if (get_wcaps_type(get_wcaps(codec, nid)) != AC_WID_PIN) | ||
828 | return -EINVAL; | ||
829 | |||
827 | oldcfg = snd_hda_codec_get_pincfg(codec, nid); | 830 | oldcfg = snd_hda_codec_get_pincfg(codec, nid); |
828 | pin = look_up_pincfg(codec, list, nid); | 831 | pin = look_up_pincfg(codec, list, nid); |
829 | if (!pin) { | 832 | if (!pin) { |
@@ -899,6 +902,25 @@ static void restore_pincfgs(struct hda_codec *codec) | |||
899 | } | 902 | } |
900 | } | 903 | } |
901 | 904 | ||
905 | /** | ||
906 | * snd_hda_shutup_pins - Shut up all pins | ||
907 | * @codec: the HDA codec | ||
908 | * | ||
909 | * Clear all pin controls to shup up before suspend for avoiding click noise. | ||
910 | * The controls aren't cached so that they can be resumed properly. | ||
911 | */ | ||
912 | void snd_hda_shutup_pins(struct hda_codec *codec) | ||
913 | { | ||
914 | int i; | ||
915 | for (i = 0; i < codec->init_pins.used; i++) { | ||
916 | struct hda_pincfg *pin = snd_array_elem(&codec->init_pins, i); | ||
917 | /* use read here for syncing after issuing each verb */ | ||
918 | snd_hda_codec_read(codec, pin->nid, 0, | ||
919 | AC_VERB_SET_PIN_WIDGET_CONTROL, 0); | ||
920 | } | ||
921 | } | ||
922 | EXPORT_SYMBOL_HDA(snd_hda_shutup_pins); | ||
923 | |||
902 | static void init_hda_cache(struct hda_cache_rec *cache, | 924 | static void init_hda_cache(struct hda_cache_rec *cache, |
903 | unsigned int record_size); | 925 | unsigned int record_size); |
904 | static void free_hda_cache(struct hda_cache_rec *cache); | 926 | static void free_hda_cache(struct hda_cache_rec *cache); |
@@ -931,6 +953,7 @@ static void snd_hda_codec_free(struct hda_codec *codec) | |||
931 | #endif | 953 | #endif |
932 | list_del(&codec->list); | 954 | list_del(&codec->list); |
933 | snd_array_free(&codec->mixers); | 955 | snd_array_free(&codec->mixers); |
956 | snd_array_free(&codec->nids); | ||
934 | codec->bus->caddr_tbl[codec->addr] = NULL; | 957 | codec->bus->caddr_tbl[codec->addr] = NULL; |
935 | if (codec->patch_ops.free) | 958 | if (codec->patch_ops.free) |
936 | codec->patch_ops.free(codec); | 959 | codec->patch_ops.free(codec); |
@@ -985,7 +1008,8 @@ int /*__devinit*/ snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr | |||
985 | mutex_init(&codec->control_mutex); | 1008 | mutex_init(&codec->control_mutex); |
986 | init_hda_cache(&codec->amp_cache, sizeof(struct hda_amp_info)); | 1009 | init_hda_cache(&codec->amp_cache, sizeof(struct hda_amp_info)); |
987 | init_hda_cache(&codec->cmd_cache, sizeof(struct hda_cache_head)); | 1010 | init_hda_cache(&codec->cmd_cache, sizeof(struct hda_cache_head)); |
988 | snd_array_init(&codec->mixers, sizeof(struct hda_nid_item), 60); | 1011 | snd_array_init(&codec->mixers, sizeof(struct hda_nid_item), 32); |
1012 | snd_array_init(&codec->nids, sizeof(struct hda_nid_item), 32); | ||
989 | snd_array_init(&codec->init_pins, sizeof(struct hda_pincfg), 16); | 1013 | snd_array_init(&codec->init_pins, sizeof(struct hda_pincfg), 16); |
990 | snd_array_init(&codec->driver_pins, sizeof(struct hda_pincfg), 16); | 1014 | snd_array_init(&codec->driver_pins, sizeof(struct hda_pincfg), 16); |
991 | if (codec->bus->modelname) { | 1015 | if (codec->bus->modelname) { |
@@ -1708,7 +1732,7 @@ struct snd_kcontrol *snd_hda_find_mixer_ctl(struct hda_codec *codec, | |||
1708 | EXPORT_SYMBOL_HDA(snd_hda_find_mixer_ctl); | 1732 | EXPORT_SYMBOL_HDA(snd_hda_find_mixer_ctl); |
1709 | 1733 | ||
1710 | /** | 1734 | /** |
1711 | * snd_hda_ctl-add - Add a control element and assign to the codec | 1735 | * snd_hda_ctl_add - Add a control element and assign to the codec |
1712 | * @codec: HD-audio codec | 1736 | * @codec: HD-audio codec |
1713 | * @nid: corresponding NID (optional) | 1737 | * @nid: corresponding NID (optional) |
1714 | * @kctl: the control element to assign | 1738 | * @kctl: the control element to assign |
@@ -1723,19 +1747,25 @@ EXPORT_SYMBOL_HDA(snd_hda_find_mixer_ctl); | |||
1723 | * | 1747 | * |
1724 | * snd_hda_ctl_add() checks the control subdev id field whether | 1748 | * snd_hda_ctl_add() checks the control subdev id field whether |
1725 | * #HDA_SUBDEV_NID_FLAG bit is set. If set (and @nid is zero), the lower | 1749 | * #HDA_SUBDEV_NID_FLAG bit is set. If set (and @nid is zero), the lower |
1726 | * bits value is taken as the NID to assign. | 1750 | * bits value is taken as the NID to assign. The #HDA_NID_ITEM_AMP bit |
1751 | * specifies if kctl->private_value is a HDA amplifier value. | ||
1727 | */ | 1752 | */ |
1728 | int snd_hda_ctl_add(struct hda_codec *codec, hda_nid_t nid, | 1753 | int snd_hda_ctl_add(struct hda_codec *codec, hda_nid_t nid, |
1729 | struct snd_kcontrol *kctl) | 1754 | struct snd_kcontrol *kctl) |
1730 | { | 1755 | { |
1731 | int err; | 1756 | int err; |
1757 | unsigned short flags = 0; | ||
1732 | struct hda_nid_item *item; | 1758 | struct hda_nid_item *item; |
1733 | 1759 | ||
1734 | if (kctl->id.subdevice & HDA_SUBDEV_NID_FLAG) { | 1760 | if (kctl->id.subdevice & HDA_SUBDEV_AMP_FLAG) { |
1761 | flags |= HDA_NID_ITEM_AMP; | ||
1735 | if (nid == 0) | 1762 | if (nid == 0) |
1736 | nid = kctl->id.subdevice & 0xffff; | 1763 | nid = get_amp_nid_(kctl->private_value); |
1737 | kctl->id.subdevice = 0; | ||
1738 | } | 1764 | } |
1765 | if ((kctl->id.subdevice & HDA_SUBDEV_NID_FLAG) != 0 && nid == 0) | ||
1766 | nid = kctl->id.subdevice & 0xffff; | ||
1767 | if (kctl->id.subdevice & (HDA_SUBDEV_NID_FLAG|HDA_SUBDEV_AMP_FLAG)) | ||
1768 | kctl->id.subdevice = 0; | ||
1739 | err = snd_ctl_add(codec->bus->card, kctl); | 1769 | err = snd_ctl_add(codec->bus->card, kctl); |
1740 | if (err < 0) | 1770 | if (err < 0) |
1741 | return err; | 1771 | return err; |
@@ -1744,11 +1774,41 @@ int snd_hda_ctl_add(struct hda_codec *codec, hda_nid_t nid, | |||
1744 | return -ENOMEM; | 1774 | return -ENOMEM; |
1745 | item->kctl = kctl; | 1775 | item->kctl = kctl; |
1746 | item->nid = nid; | 1776 | item->nid = nid; |
1777 | item->flags = flags; | ||
1747 | return 0; | 1778 | return 0; |
1748 | } | 1779 | } |
1749 | EXPORT_SYMBOL_HDA(snd_hda_ctl_add); | 1780 | EXPORT_SYMBOL_HDA(snd_hda_ctl_add); |
1750 | 1781 | ||
1751 | /** | 1782 | /** |
1783 | * snd_hda_add_nid - Assign a NID to a control element | ||
1784 | * @codec: HD-audio codec | ||
1785 | * @nid: corresponding NID (optional) | ||
1786 | * @kctl: the control element to assign | ||
1787 | * @index: index to kctl | ||
1788 | * | ||
1789 | * Add the given control element to an array inside the codec instance. | ||
1790 | * This function is used when #snd_hda_ctl_add cannot be used for 1:1 | ||
1791 | * NID:KCTL mapping - for example "Capture Source" selector. | ||
1792 | */ | ||
1793 | int snd_hda_add_nid(struct hda_codec *codec, struct snd_kcontrol *kctl, | ||
1794 | unsigned int index, hda_nid_t nid) | ||
1795 | { | ||
1796 | struct hda_nid_item *item; | ||
1797 | |||
1798 | if (nid > 0) { | ||
1799 | item = snd_array_new(&codec->nids); | ||
1800 | if (!item) | ||
1801 | return -ENOMEM; | ||
1802 | item->kctl = kctl; | ||
1803 | item->index = index; | ||
1804 | item->nid = nid; | ||
1805 | return 0; | ||
1806 | } | ||
1807 | return -EINVAL; | ||
1808 | } | ||
1809 | EXPORT_SYMBOL_HDA(snd_hda_add_nid); | ||
1810 | |||
1811 | /** | ||
1752 | * snd_hda_ctls_clear - Clear all controls assigned to the given codec | 1812 | * snd_hda_ctls_clear - Clear all controls assigned to the given codec |
1753 | * @codec: HD-audio codec | 1813 | * @codec: HD-audio codec |
1754 | */ | 1814 | */ |
@@ -1759,6 +1819,7 @@ void snd_hda_ctls_clear(struct hda_codec *codec) | |||
1759 | for (i = 0; i < codec->mixers.used; i++) | 1819 | for (i = 0; i < codec->mixers.used; i++) |
1760 | snd_ctl_remove(codec->bus->card, items[i].kctl); | 1820 | snd_ctl_remove(codec->bus->card, items[i].kctl); |
1761 | snd_array_free(&codec->mixers); | 1821 | snd_array_free(&codec->mixers); |
1822 | snd_array_free(&codec->nids); | ||
1762 | } | 1823 | } |
1763 | 1824 | ||
1764 | /* pseudo device locking | 1825 | /* pseudo device locking |
@@ -2706,7 +2767,8 @@ static void hda_set_power_state(struct hda_codec *codec, hda_nid_t fg, | |||
2706 | snd_hda_codec_read(codec, fg, 0, AC_VERB_SET_POWER_STATE, | 2767 | snd_hda_codec_read(codec, fg, 0, AC_VERB_SET_POWER_STATE, |
2707 | power_state); | 2768 | power_state); |
2708 | /* partial workaround for "azx_get_response timeout" */ | 2769 | /* partial workaround for "azx_get_response timeout" */ |
2709 | if (power_state == AC_PWRST_D0) | 2770 | if (power_state == AC_PWRST_D0 && |
2771 | (codec->vendor_id & 0xffff0000) == 0x14f10000) | ||
2710 | msleep(10); | 2772 | msleep(10); |
2711 | 2773 | ||
2712 | nid = codec->start_nid; | 2774 | nid = codec->start_nid; |
@@ -2740,7 +2802,6 @@ static void hda_set_power_state(struct hda_codec *codec, hda_nid_t fg, | |||
2740 | if (power_state == AC_PWRST_D0) { | 2802 | if (power_state == AC_PWRST_D0) { |
2741 | unsigned long end_time; | 2803 | unsigned long end_time; |
2742 | int state; | 2804 | int state; |
2743 | msleep(10); | ||
2744 | /* wait until the codec reachs to D0 */ | 2805 | /* wait until the codec reachs to D0 */ |
2745 | end_time = jiffies + msecs_to_jiffies(500); | 2806 | end_time = jiffies + msecs_to_jiffies(500); |
2746 | do { | 2807 | do { |
@@ -3214,6 +3275,8 @@ const char *snd_hda_pcm_type_name[HDA_PCM_NTYPES] = { | |||
3214 | 3275 | ||
3215 | /* | 3276 | /* |
3216 | * get the empty PCM device number to assign | 3277 | * get the empty PCM device number to assign |
3278 | * | ||
3279 | * note the max device number is limited by HDA_MAX_PCMS, currently 10 | ||
3217 | */ | 3280 | */ |
3218 | static int get_empty_pcm_device(struct hda_bus *bus, int type) | 3281 | static int get_empty_pcm_device(struct hda_bus *bus, int type) |
3219 | { | 3282 | { |
@@ -3478,6 +3541,8 @@ int snd_hda_add_new_ctls(struct hda_codec *codec, struct snd_kcontrol_new *knew) | |||
3478 | 3541 | ||
3479 | for (; knew->name; knew++) { | 3542 | for (; knew->name; knew++) { |
3480 | struct snd_kcontrol *kctl; | 3543 | struct snd_kcontrol *kctl; |
3544 | if (knew->iface == -1) /* skip this codec private value */ | ||
3545 | continue; | ||
3481 | kctl = snd_ctl_new1(knew, codec); | 3546 | kctl = snd_ctl_new1(knew, codec); |
3482 | if (!kctl) | 3547 | if (!kctl) |
3483 | return -ENOMEM; | 3548 | return -ENOMEM; |