diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-03-01 11:58:44 -0500 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-03-01 11:58:44 -0500 |
| commit | 524df55725217b13d5a232fb5badb5846418ea0e (patch) | |
| tree | c041613577ac7e68737cfd8af16a37d1ed37e6af /sound/pci/hda/hda_codec.c | |
| parent | 0f4533979473a456a8adb3869365e12c7a99cf65 (diff) | |
| parent | 6679ee1870f7ccdd48e2e5c57919240b8f19a6dc (diff) | |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound-2.6
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound-2.6: (252 commits)
ASoC: Check progress when reporting periods from i.MX FIQ handler
ASoC: Remove a unused variables from i.MX FIQ runtime data
ALSA: hda - Add/fix ALC269 FSC and Quanta models
ALSA: hda - Add ALC670 codec support
OMAP4: PMIC: Add support for twl6030 codec
ALSA: hda - remove unnecessary msleep on power state transitions
usb/gadget/{f_audio,gmidi}.c: follow recent changes in audio.h
ASoC: fsi: Modify over/under run error settlement
ASoC: OMAP4: Add McPDM platform driver
ASoC: OMAP4: Add support for McPDM
ASoC: OMAP: data_type and sync_mode configurable in audio dma
ALSA: hda - Add missing description in HD-Audio-Models.txt
ALSA: add support for Macbook Air 2,1 internal speaker
ALSA: usbaudio: consolidate header files
ALSA: usbmixer: bail out early when parsing audio class v2 descriptors
ALSA: usbaudio: implement basic set of class v2.0 parser
ALSA: usbaudio: introduce new types for audio class v2
ALSA: usbaudio: parse USB descriptors with structs
ALSA: hda - enable snoop for Intel Cougar Point
ALSA: hda - Remove identical definitions for macmini3 model
...
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 f98b47cd6cfb..76d3c4c049db 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; |
