diff options
author | Takashi Iwai <tiwai@suse.de> | 2007-08-10 11:09:26 -0400 |
---|---|---|
committer | Jaroslav Kysela <perex@perex.cz> | 2007-10-16 09:58:43 -0400 |
commit | 82beb8fd365afe3891b277c46425083f13e23c56 (patch) | |
tree | a564d7228b59170aa490d4fc9284b5fa4442adb0 /sound/pci/hda/patch_analog.c | |
parent | b3ac56364126f78cae94eb2a75b72d9ea85aca9d (diff) |
[ALSA] hda-codec - optimize resume using caches
So far, the driver looked the table of snd_kcontrol_new used for creating
mixer elements and forces to call each of its put callbacks in PM resume
code. This is too ugly and hackish.
Now, the resume is simplified using the codec amp and command register
caches. The driver simply restores the values that have been written
in the cache table. With this simplification, most codec support codes
don't require any special resume callback.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Jaroslav Kysela <perex@suse.cz>
Diffstat (limited to 'sound/pci/hda/patch_analog.c')
-rw-r--r-- | sound/pci/hda/patch_analog.c | 68 |
1 files changed, 25 insertions, 43 deletions
diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c index cc2e944cc59f..f20ddd85db22 100644 --- a/sound/pci/hda/patch_analog.c +++ b/sound/pci/hda/patch_analog.c | |||
@@ -318,31 +318,11 @@ static void ad198x_free(struct hda_codec *codec) | |||
318 | kfree(codec->spec); | 318 | kfree(codec->spec); |
319 | } | 319 | } |
320 | 320 | ||
321 | #ifdef CONFIG_PM | ||
322 | static int ad198x_resume(struct hda_codec *codec) | ||
323 | { | ||
324 | struct ad198x_spec *spec = codec->spec; | ||
325 | int i; | ||
326 | |||
327 | codec->patch_ops.init(codec); | ||
328 | for (i = 0; i < spec->num_mixers; i++) | ||
329 | snd_hda_resume_ctls(codec, spec->mixers[i]); | ||
330 | if (spec->multiout.dig_out_nid) | ||
331 | snd_hda_resume_spdif_out(codec); | ||
332 | if (spec->dig_in_nid) | ||
333 | snd_hda_resume_spdif_in(codec); | ||
334 | return 0; | ||
335 | } | ||
336 | #endif | ||
337 | |||
338 | static struct hda_codec_ops ad198x_patch_ops = { | 321 | static struct hda_codec_ops ad198x_patch_ops = { |
339 | .build_controls = ad198x_build_controls, | 322 | .build_controls = ad198x_build_controls, |
340 | .build_pcms = ad198x_build_pcms, | 323 | .build_pcms = ad198x_build_pcms, |
341 | .init = ad198x_init, | 324 | .init = ad198x_init, |
342 | .free = ad198x_free, | 325 | .free = ad198x_free, |
343 | #ifdef CONFIG_PM | ||
344 | .resume = ad198x_resume, | ||
345 | #endif | ||
346 | }; | 326 | }; |
347 | 327 | ||
348 | 328 | ||
@@ -376,12 +356,12 @@ static int ad198x_eapd_put(struct snd_kcontrol *kcontrol, | |||
376 | eapd = ucontrol->value.integer.value[0]; | 356 | eapd = ucontrol->value.integer.value[0]; |
377 | if (invert) | 357 | if (invert) |
378 | eapd = !eapd; | 358 | eapd = !eapd; |
379 | if (eapd == spec->cur_eapd && ! codec->in_resume) | 359 | if (eapd == spec->cur_eapd) |
380 | return 0; | 360 | return 0; |
381 | spec->cur_eapd = eapd; | 361 | spec->cur_eapd = eapd; |
382 | snd_hda_codec_write(codec, nid, | 362 | snd_hda_codec_write_cache(codec, nid, |
383 | 0, AC_VERB_SET_EAPD_BTLENABLE, | 363 | 0, AC_VERB_SET_EAPD_BTLENABLE, |
384 | eapd ? 0x02 : 0x00); | 364 | eapd ? 0x02 : 0x00); |
385 | return 1; | 365 | return 1; |
386 | } | 366 | } |
387 | 367 | ||
@@ -882,8 +862,9 @@ static int ad1983_spdif_route_put(struct snd_kcontrol *kcontrol, struct snd_ctl_ | |||
882 | 862 | ||
883 | if (spec->spdif_route != ucontrol->value.enumerated.item[0]) { | 863 | if (spec->spdif_route != ucontrol->value.enumerated.item[0]) { |
884 | spec->spdif_route = ucontrol->value.enumerated.item[0]; | 864 | spec->spdif_route = ucontrol->value.enumerated.item[0]; |
885 | snd_hda_codec_write(codec, spec->multiout.dig_out_nid, 0, | 865 | snd_hda_codec_write_cache(codec, spec->multiout.dig_out_nid, 0, |
886 | AC_VERB_SET_CONNECT_SEL, spec->spdif_route); | 866 | AC_VERB_SET_CONNECT_SEL, |
867 | spec->spdif_route); | ||
887 | return 1; | 868 | return 1; |
888 | } | 869 | } |
889 | return 0; | 870 | return 0; |
@@ -1824,33 +1805,34 @@ static int ad1988_spdif_playback_source_put(struct snd_kcontrol *kcontrol, | |||
1824 | AC_VERB_GET_AMP_GAIN_MUTE, | 1805 | AC_VERB_GET_AMP_GAIN_MUTE, |
1825 | AC_AMP_GET_INPUT); | 1806 | AC_AMP_GET_INPUT); |
1826 | change = sel & 0x80; | 1807 | change = sel & 0x80; |
1827 | if (change || codec->in_resume) { | 1808 | if (change) { |
1828 | snd_hda_codec_write(codec, 0x1d, 0, | 1809 | snd_hda_codec_write_cache(codec, 0x1d, 0, |
1829 | AC_VERB_SET_AMP_GAIN_MUTE, | 1810 | AC_VERB_SET_AMP_GAIN_MUTE, |
1830 | AMP_IN_UNMUTE(0)); | 1811 | AMP_IN_UNMUTE(0)); |
1831 | snd_hda_codec_write(codec, 0x1d, 0, | 1812 | snd_hda_codec_write_cache(codec, 0x1d, 0, |
1832 | AC_VERB_SET_AMP_GAIN_MUTE, | 1813 | AC_VERB_SET_AMP_GAIN_MUTE, |
1833 | AMP_IN_MUTE(1)); | 1814 | AMP_IN_MUTE(1)); |
1834 | } | 1815 | } |
1835 | } else { | 1816 | } else { |
1836 | sel = snd_hda_codec_read(codec, 0x1d, 0, | 1817 | sel = snd_hda_codec_read(codec, 0x1d, 0, |
1837 | AC_VERB_GET_AMP_GAIN_MUTE, | 1818 | AC_VERB_GET_AMP_GAIN_MUTE, |
1838 | AC_AMP_GET_INPUT | 0x01); | 1819 | AC_AMP_GET_INPUT | 0x01); |
1839 | change = sel & 0x80; | 1820 | change = sel & 0x80; |
1840 | if (change || codec->in_resume) { | 1821 | if (change) { |
1841 | snd_hda_codec_write(codec, 0x1d, 0, | 1822 | snd_hda_codec_write_cache(codec, 0x1d, 0, |
1842 | AC_VERB_SET_AMP_GAIN_MUTE, | 1823 | AC_VERB_SET_AMP_GAIN_MUTE, |
1843 | AMP_IN_MUTE(0)); | 1824 | AMP_IN_MUTE(0)); |
1844 | snd_hda_codec_write(codec, 0x1d, 0, | 1825 | snd_hda_codec_write_cache(codec, 0x1d, 0, |
1845 | AC_VERB_SET_AMP_GAIN_MUTE, | 1826 | AC_VERB_SET_AMP_GAIN_MUTE, |
1846 | AMP_IN_UNMUTE(1)); | 1827 | AMP_IN_UNMUTE(1)); |
1847 | } | 1828 | } |
1848 | sel = snd_hda_codec_read(codec, 0x0b, 0, | 1829 | sel = snd_hda_codec_read(codec, 0x0b, 0, |
1849 | AC_VERB_GET_CONNECT_SEL, 0) + 1; | 1830 | AC_VERB_GET_CONNECT_SEL, 0) + 1; |
1850 | change |= sel != val; | 1831 | change |= sel != val; |
1851 | if (change || codec->in_resume) | 1832 | if (change) |
1852 | snd_hda_codec_write(codec, 0x0b, 0, | 1833 | snd_hda_codec_write_cache(codec, 0x0b, 0, |
1853 | AC_VERB_SET_CONNECT_SEL, val - 1); | 1834 | AC_VERB_SET_CONNECT_SEL, |
1835 | val - 1); | ||
1854 | } | 1836 | } |
1855 | return change; | 1837 | return change; |
1856 | } | 1838 | } |