diff options
author | Takashi Iwai <tiwai@suse.de> | 2012-12-14 04:32:21 -0500 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2013-01-12 02:30:02 -0500 |
commit | 280e57d544f5f9f599de8e11aacb7c087da254b8 (patch) | |
tree | a1e7ae6afbe3c0ef804cbe5ce42d14f0a127594d /sound/pci/hda/hda_codec.c | |
parent | c370dd6e9faae4b2e699a1f210827aceaa0c3399 (diff) |
ALSA: hda - Introduce snd_hda_codec_amp_init*()
The new function snd_hda_codec_amp_init() (and the stereo variant)
initializes the amp value only once at the first access. If the amp
was already initialized or updated, this won't do anything more.
It's useful for initializing the input amps that are in the part of
the path but never used.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci/hda/hda_codec.c')
-rw-r--r-- | sound/pci/hda/hda_codec.c | 71 |
1 files changed, 52 insertions, 19 deletions
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index 2f890af820b2..0037147dcd54 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c | |||
@@ -1765,7 +1765,7 @@ EXPORT_SYMBOL_HDA(snd_hda_override_pin_caps); | |||
1765 | */ | 1765 | */ |
1766 | static struct hda_amp_info * | 1766 | static struct hda_amp_info * |
1767 | update_amp_hash(struct hda_codec *codec, hda_nid_t nid, int ch, | 1767 | update_amp_hash(struct hda_codec *codec, hda_nid_t nid, int ch, |
1768 | int direction, int index) | 1768 | int direction, int index, bool init_only) |
1769 | { | 1769 | { |
1770 | struct hda_amp_info *info; | 1770 | struct hda_amp_info *info; |
1771 | unsigned int parm, val = 0; | 1771 | unsigned int parm, val = 0; |
@@ -1791,7 +1791,8 @@ update_amp_hash(struct hda_codec *codec, hda_nid_t nid, int ch, | |||
1791 | } | 1791 | } |
1792 | info->vol[ch] = val; | 1792 | info->vol[ch] = val; |
1793 | info->head.val |= INFO_AMP_VOL(ch); | 1793 | info->head.val |= INFO_AMP_VOL(ch); |
1794 | } | 1794 | } else if (init_only) |
1795 | return NULL; | ||
1795 | return info; | 1796 | return info; |
1796 | } | 1797 | } |
1797 | 1798 | ||
@@ -1832,7 +1833,7 @@ int snd_hda_codec_amp_read(struct hda_codec *codec, hda_nid_t nid, int ch, | |||
1832 | unsigned int val = 0; | 1833 | unsigned int val = 0; |
1833 | 1834 | ||
1834 | mutex_lock(&codec->hash_mutex); | 1835 | mutex_lock(&codec->hash_mutex); |
1835 | info = update_amp_hash(codec, nid, ch, direction, index); | 1836 | info = update_amp_hash(codec, nid, ch, direction, index, false); |
1836 | if (info) | 1837 | if (info) |
1837 | val = info->vol[ch]; | 1838 | val = info->vol[ch]; |
1838 | mutex_unlock(&codec->hash_mutex); | 1839 | mutex_unlock(&codec->hash_mutex); |
@@ -1840,21 +1841,9 @@ int snd_hda_codec_amp_read(struct hda_codec *codec, hda_nid_t nid, int ch, | |||
1840 | } | 1841 | } |
1841 | EXPORT_SYMBOL_HDA(snd_hda_codec_amp_read); | 1842 | EXPORT_SYMBOL_HDA(snd_hda_codec_amp_read); |
1842 | 1843 | ||
1843 | /** | 1844 | static int codec_amp_update(struct hda_codec *codec, hda_nid_t nid, int ch, |
1844 | * snd_hda_codec_amp_update - update the AMP value | 1845 | int direction, int idx, int mask, int val, |
1845 | * @codec: HD-audio codec | 1846 | bool init_only) |
1846 | * @nid: NID to read the AMP value | ||
1847 | * @ch: channel (left=0 or right=1) | ||
1848 | * @direction: #HDA_INPUT or #HDA_OUTPUT | ||
1849 | * @idx: the index value (only for input direction) | ||
1850 | * @mask: bit mask to set | ||
1851 | * @val: the bits value to set | ||
1852 | * | ||
1853 | * Update the AMP value with a bit mask. | ||
1854 | * Returns 0 if the value is unchanged, 1 if changed. | ||
1855 | */ | ||
1856 | int snd_hda_codec_amp_update(struct hda_codec *codec, hda_nid_t nid, int ch, | ||
1857 | int direction, int idx, int mask, int val) | ||
1858 | { | 1847 | { |
1859 | struct hda_amp_info *info; | 1848 | struct hda_amp_info *info; |
1860 | 1849 | ||
@@ -1863,7 +1852,7 @@ int snd_hda_codec_amp_update(struct hda_codec *codec, hda_nid_t nid, int ch, | |||
1863 | val &= mask; | 1852 | val &= mask; |
1864 | 1853 | ||
1865 | mutex_lock(&codec->hash_mutex); | 1854 | mutex_lock(&codec->hash_mutex); |
1866 | info = update_amp_hash(codec, nid, ch, direction, idx); | 1855 | info = update_amp_hash(codec, nid, ch, direction, idx, init_only); |
1867 | if (!info) { | 1856 | if (!info) { |
1868 | mutex_unlock(&codec->hash_mutex); | 1857 | mutex_unlock(&codec->hash_mutex); |
1869 | return 0; | 1858 | return 0; |
@@ -1881,6 +1870,25 @@ int snd_hda_codec_amp_update(struct hda_codec *codec, hda_nid_t nid, int ch, | |||
1881 | put_vol_mute(codec, info, nid, ch, direction, idx, val); | 1870 | put_vol_mute(codec, info, nid, ch, direction, idx, val); |
1882 | return 1; | 1871 | return 1; |
1883 | } | 1872 | } |
1873 | |||
1874 | /** | ||
1875 | * snd_hda_codec_amp_update - update the AMP value | ||
1876 | * @codec: HD-audio codec | ||
1877 | * @nid: NID to read the AMP value | ||
1878 | * @ch: channel (left=0 or right=1) | ||
1879 | * @direction: #HDA_INPUT or #HDA_OUTPUT | ||
1880 | * @idx: the index value (only for input direction) | ||
1881 | * @mask: bit mask to set | ||
1882 | * @val: the bits value to set | ||
1883 | * | ||
1884 | * Update the AMP value with a bit mask. | ||
1885 | * Returns 0 if the value is unchanged, 1 if changed. | ||
1886 | */ | ||
1887 | int snd_hda_codec_amp_update(struct hda_codec *codec, hda_nid_t nid, int ch, | ||
1888 | int direction, int idx, int mask, int val) | ||
1889 | { | ||
1890 | return codec_amp_update(codec, nid, ch, direction, idx, mask, val, false); | ||
1891 | } | ||
1884 | EXPORT_SYMBOL_HDA(snd_hda_codec_amp_update); | 1892 | EXPORT_SYMBOL_HDA(snd_hda_codec_amp_update); |
1885 | 1893 | ||
1886 | /** | 1894 | /** |
@@ -1909,6 +1917,31 @@ int snd_hda_codec_amp_stereo(struct hda_codec *codec, hda_nid_t nid, | |||
1909 | } | 1917 | } |
1910 | EXPORT_SYMBOL_HDA(snd_hda_codec_amp_stereo); | 1918 | EXPORT_SYMBOL_HDA(snd_hda_codec_amp_stereo); |
1911 | 1919 | ||
1920 | /* Works like snd_hda_codec_amp_update() but it writes the value only at | ||
1921 | * the first access. If the amp was already initialized / updated beforehand, | ||
1922 | * this does nothing. | ||
1923 | */ | ||
1924 | int snd_hda_codec_amp_init(struct hda_codec *codec, hda_nid_t nid, int ch, | ||
1925 | int dir, int idx, int mask, int val) | ||
1926 | { | ||
1927 | return codec_amp_update(codec, nid, ch, dir, idx, mask, val, true); | ||
1928 | } | ||
1929 | EXPORT_SYMBOL_HDA(snd_hda_codec_amp_init); | ||
1930 | |||
1931 | int snd_hda_codec_amp_init_stereo(struct hda_codec *codec, hda_nid_t nid, | ||
1932 | int dir, int idx, int mask, int val) | ||
1933 | { | ||
1934 | int ch, ret = 0; | ||
1935 | |||
1936 | if (snd_BUG_ON(mask & ~0xff)) | ||
1937 | mask &= 0xff; | ||
1938 | for (ch = 0; ch < 2; ch++) | ||
1939 | ret |= snd_hda_codec_amp_init(codec, nid, ch, dir, | ||
1940 | idx, mask, val); | ||
1941 | return ret; | ||
1942 | } | ||
1943 | EXPORT_SYMBOL_HDA(snd_hda_codec_amp_init_stereo); | ||
1944 | |||
1912 | /** | 1945 | /** |
1913 | * snd_hda_codec_resume_amp - Resume all AMP commands from the cache | 1946 | * snd_hda_codec_resume_amp - Resume all AMP commands from the cache |
1914 | * @codec: HD-audio codec | 1947 | * @codec: HD-audio codec |