diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-07-12 17:44:43 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-07-12 17:44:43 -0400 |
| commit | 7e48c02829ad6a824775a78bf100acbcbac2871f (patch) | |
| tree | 9f9cb4a2cd18e64a63535878d30253236ccca5e0 | |
| parent | 9f71963702764243d0835b07660ae505b66ca09f (diff) | |
| parent | ac0547dc62e67a3e0b0c1628b6e49efba8f517db (diff) | |
Merge branch 'fix/hda' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound-2.6
* 'fix/hda' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound-2.6:
ALSA: hda - Restore cleared pin controls on resume
| -rw-r--r-- | sound/pci/hda/hda_codec.c | 27 | ||||
| -rw-r--r-- | sound/pci/hda/hda_codec.h | 5 |
2 files changed, 31 insertions, 1 deletions
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index a3d638c8c1fd..ba2098d20ccc 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c | |||
| @@ -784,6 +784,9 @@ static int read_pin_defaults(struct hda_codec *codec) | |||
| 784 | pin->nid = nid; | 784 | pin->nid = nid; |
| 785 | pin->cfg = snd_hda_codec_read(codec, nid, 0, | 785 | pin->cfg = snd_hda_codec_read(codec, nid, 0, |
| 786 | AC_VERB_GET_CONFIG_DEFAULT, 0); | 786 | AC_VERB_GET_CONFIG_DEFAULT, 0); |
| 787 | pin->ctrl = snd_hda_codec_read(codec, nid, 0, | ||
| 788 | AC_VERB_GET_PIN_WIDGET_CONTROL, | ||
| 789 | 0); | ||
| 787 | } | 790 | } |
| 788 | return 0; | 791 | return 0; |
| 789 | } | 792 | } |
| @@ -912,15 +915,38 @@ static void restore_pincfgs(struct hda_codec *codec) | |||
| 912 | void snd_hda_shutup_pins(struct hda_codec *codec) | 915 | void snd_hda_shutup_pins(struct hda_codec *codec) |
| 913 | { | 916 | { |
| 914 | int i; | 917 | int i; |
| 918 | /* don't shut up pins when unloading the driver; otherwise it breaks | ||
| 919 | * the default pin setup at the next load of the driver | ||
| 920 | */ | ||
| 921 | if (codec->bus->shutdown) | ||
| 922 | return; | ||
| 915 | for (i = 0; i < codec->init_pins.used; i++) { | 923 | for (i = 0; i < codec->init_pins.used; i++) { |
| 916 | struct hda_pincfg *pin = snd_array_elem(&codec->init_pins, i); | 924 | struct hda_pincfg *pin = snd_array_elem(&codec->init_pins, i); |
| 917 | /* use read here for syncing after issuing each verb */ | 925 | /* use read here for syncing after issuing each verb */ |
| 918 | snd_hda_codec_read(codec, pin->nid, 0, | 926 | snd_hda_codec_read(codec, pin->nid, 0, |
| 919 | AC_VERB_SET_PIN_WIDGET_CONTROL, 0); | 927 | AC_VERB_SET_PIN_WIDGET_CONTROL, 0); |
| 920 | } | 928 | } |
| 929 | codec->pins_shutup = 1; | ||
| 921 | } | 930 | } |
| 922 | EXPORT_SYMBOL_HDA(snd_hda_shutup_pins); | 931 | EXPORT_SYMBOL_HDA(snd_hda_shutup_pins); |
| 923 | 932 | ||
| 933 | /* Restore the pin controls cleared previously via snd_hda_shutup_pins() */ | ||
| 934 | static void restore_shutup_pins(struct hda_codec *codec) | ||
| 935 | { | ||
| 936 | int i; | ||
| 937 | if (!codec->pins_shutup) | ||
| 938 | return; | ||
| 939 | if (codec->bus->shutdown) | ||
| 940 | return; | ||
| 941 | for (i = 0; i < codec->init_pins.used; i++) { | ||
| 942 | struct hda_pincfg *pin = snd_array_elem(&codec->init_pins, i); | ||
| 943 | snd_hda_codec_write(codec, pin->nid, 0, | ||
| 944 | AC_VERB_SET_PIN_WIDGET_CONTROL, | ||
| 945 | pin->ctrl); | ||
| 946 | } | ||
| 947 | codec->pins_shutup = 0; | ||
| 948 | } | ||
| 949 | |||
| 924 | static void init_hda_cache(struct hda_cache_rec *cache, | 950 | static void init_hda_cache(struct hda_cache_rec *cache, |
| 925 | unsigned int record_size); | 951 | unsigned int record_size); |
| 926 | static void free_hda_cache(struct hda_cache_rec *cache); | 952 | static void free_hda_cache(struct hda_cache_rec *cache); |
| @@ -2907,6 +2933,7 @@ static void hda_call_codec_resume(struct hda_codec *codec) | |||
| 2907 | codec->afg ? codec->afg : codec->mfg, | 2933 | codec->afg ? codec->afg : codec->mfg, |
| 2908 | AC_PWRST_D0); | 2934 | AC_PWRST_D0); |
| 2909 | restore_pincfgs(codec); /* restore all current pin configs */ | 2935 | restore_pincfgs(codec); /* restore all current pin configs */ |
| 2936 | restore_shutup_pins(codec); | ||
| 2910 | hda_exec_init_verbs(codec); | 2937 | hda_exec_init_verbs(codec); |
| 2911 | if (codec->patch_ops.resume) | 2938 | if (codec->patch_ops.resume) |
| 2912 | codec->patch_ops.resume(codec); | 2939 | codec->patch_ops.resume(codec); |
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h index 49e939e7e5cd..5991d14e1ec0 100644 --- a/sound/pci/hda/hda_codec.h +++ b/sound/pci/hda/hda_codec.h | |||
| @@ -821,6 +821,7 @@ struct hda_codec { | |||
| 821 | unsigned int pin_amp_workaround:1; /* pin out-amp takes index | 821 | unsigned int pin_amp_workaround:1; /* pin out-amp takes index |
| 822 | * (e.g. Conexant codecs) | 822 | * (e.g. Conexant codecs) |
| 823 | */ | 823 | */ |
| 824 | unsigned int pins_shutup:1; /* pins are shut up */ | ||
| 824 | unsigned int no_trigger_sense:1; /* don't trigger at pin-sensing */ | 825 | unsigned int no_trigger_sense:1; /* don't trigger at pin-sensing */ |
| 825 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 826 | #ifdef CONFIG_SND_HDA_POWER_SAVE |
| 826 | unsigned int power_on :1; /* current (global) power-state */ | 827 | unsigned int power_on :1; /* current (global) power-state */ |
| @@ -897,7 +898,9 @@ void snd_hda_codec_resume_cache(struct hda_codec *codec); | |||
| 897 | /* the struct for codec->pin_configs */ | 898 | /* the struct for codec->pin_configs */ |
| 898 | struct hda_pincfg { | 899 | struct hda_pincfg { |
| 899 | hda_nid_t nid; | 900 | hda_nid_t nid; |
| 900 | unsigned int cfg; | 901 | unsigned char ctrl; /* current pin control value */ |
| 902 | unsigned char pad; /* reserved */ | ||
| 903 | unsigned int cfg; /* default configuration */ | ||
| 901 | }; | 904 | }; |
| 902 | 905 | ||
| 903 | unsigned int snd_hda_codec_get_pincfg(struct hda_codec *codec, hda_nid_t nid); | 906 | unsigned int snd_hda_codec_get_pincfg(struct hda_codec *codec, hda_nid_t nid); |
