diff options
author | Takashi Iwai <tiwai@suse.de> | 2005-11-17 10:14:10 -0500 |
---|---|---|
committer | Jaroslav Kysela <perex@suse.cz> | 2006-01-03 06:27:58 -0500 |
commit | 09668b441dacdf4640509b640ad73e24efd5204f (patch) | |
tree | 177d0548acbcca4432f82ce6f3aa397cba5ba528 /sound/pci/emu10k1/emu10k1.c | |
parent | fe8be10786c040bce53c18048d75b1b23aec64ae (diff) |
[ALSA] emu10k1 - Add PM support
Modules: EMU10K1/EMU10K2 driver
Add PM support to emu10k1 driver.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci/emu10k1/emu10k1.c')
-rw-r--r-- | sound/pci/emu10k1/emu10k1.c | 144 |
1 files changed, 91 insertions, 53 deletions
diff --git a/sound/pci/emu10k1/emu10k1.c b/sound/pci/emu10k1/emu10k1.c index 9be900224771..2dfa932f7825 100644 --- a/sound/pci/emu10k1/emu10k1.c +++ b/sound/pci/emu10k1/emu10k1.c | |||
@@ -125,65 +125,43 @@ static int __devinit snd_card_emu10k1_probe(struct pci_dev *pci, | |||
125 | if ((err = snd_emu10k1_create(card, pci, extin[dev], extout[dev], | 125 | if ((err = snd_emu10k1_create(card, pci, extin[dev], extout[dev], |
126 | (long)max_buffer_size[dev] * 1024 * 1024, | 126 | (long)max_buffer_size[dev] * 1024 * 1024, |
127 | enable_ir[dev], subsystem[dev], | 127 | enable_ir[dev], subsystem[dev], |
128 | &emu)) < 0) { | 128 | &emu)) < 0) |
129 | snd_card_free(card); | 129 | goto error; |
130 | return err; | 130 | card->private_data = emu; |
131 | } | 131 | if ((err = snd_emu10k1_pcm(emu, 0, NULL)) < 0) |
132 | if ((err = snd_emu10k1_pcm(emu, 0, NULL)) < 0) { | 132 | goto error; |
133 | snd_card_free(card); | 133 | if ((err = snd_emu10k1_pcm_mic(emu, 1, NULL)) < 0) |
134 | return err; | 134 | goto error; |
135 | } | 135 | if ((err = snd_emu10k1_pcm_efx(emu, 2, NULL)) < 0) |
136 | if ((err = snd_emu10k1_pcm_mic(emu, 1, NULL)) < 0) { | 136 | goto error; |
137 | snd_card_free(card); | ||
138 | return err; | ||
139 | } | ||
140 | if ((err = snd_emu10k1_pcm_efx(emu, 2, NULL)) < 0) { | ||
141 | snd_card_free(card); | ||
142 | return err; | ||
143 | } | ||
144 | /* This stores the periods table. */ | 137 | /* This stores the periods table. */ |
145 | if (emu->card_capabilities->ca0151_chip) { /* P16V */ | 138 | if (emu->card_capabilities->ca0151_chip) { /* P16V */ |
146 | if(snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(pci), 1024, &emu->p16v_buffer) < 0) { | 139 | if ((err = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(pci), |
147 | snd_p16v_free(emu); | 140 | 1024, &emu->p16v_buffer)) < 0) |
148 | return -ENOMEM; | 141 | goto error; |
149 | } | ||
150 | } | 142 | } |
151 | 143 | ||
152 | if ((err = snd_emu10k1_mixer(emu, 0, 3)) < 0) { | 144 | if ((err = snd_emu10k1_mixer(emu, 0, 3)) < 0) |
153 | snd_card_free(card); | 145 | goto error; |
154 | return err; | ||
155 | } | ||
156 | 146 | ||
157 | if ((err = snd_emu10k1_timer(emu, 0)) < 0) { | 147 | if ((err = snd_emu10k1_timer(emu, 0)) < 0) |
158 | snd_card_free(card); | 148 | goto error; |
159 | return err; | ||
160 | } | ||
161 | 149 | ||
162 | if ((err = snd_emu10k1_pcm_multi(emu, 3, NULL)) < 0) { | 150 | if ((err = snd_emu10k1_pcm_multi(emu, 3, NULL)) < 0) |
163 | snd_card_free(card); | 151 | goto error; |
164 | return err; | 152 | if (emu->card_capabilities->ca0151_chip) { /* P16V */ |
165 | } | 153 | if ((err = snd_p16v_pcm(emu, 4, NULL)) < 0) |
166 | if (emu->card_capabilities->ca0151_chip) { /* P16V */ | 154 | goto error; |
167 | if ((err = snd_p16v_pcm(emu, 4, NULL)) < 0) { | ||
168 | snd_card_free(card); | ||
169 | return err; | ||
170 | } | ||
171 | } | 155 | } |
172 | if (emu->audigy) { | 156 | if (emu->audigy) { |
173 | if ((err = snd_emu10k1_audigy_midi(emu)) < 0) { | 157 | if ((err = snd_emu10k1_audigy_midi(emu)) < 0) |
174 | snd_card_free(card); | 158 | goto error; |
175 | return err; | ||
176 | } | ||
177 | } else { | 159 | } else { |
178 | if ((err = snd_emu10k1_midi(emu)) < 0) { | 160 | if ((err = snd_emu10k1_midi(emu)) < 0) |
179 | snd_card_free(card); | 161 | goto error; |
180 | return err; | ||
181 | } | ||
182 | } | ||
183 | if ((err = snd_emu10k1_fx8010_new(emu, 0, NULL)) < 0) { | ||
184 | snd_card_free(card); | ||
185 | return err; | ||
186 | } | 162 | } |
163 | if ((err = snd_emu10k1_fx8010_new(emu, 0, NULL)) < 0) | ||
164 | goto error; | ||
187 | #ifdef ENABLE_SYNTH | 165 | #ifdef ENABLE_SYNTH |
188 | if (snd_seq_device_new(card, 1, SNDRV_SEQ_DEV_ID_EMU10K1_SYNTH, | 166 | if (snd_seq_device_new(card, 1, SNDRV_SEQ_DEV_ID_EMU10K1_SYNTH, |
189 | sizeof(struct snd_emu10k1_synth_arg), &wave) < 0 || | 167 | sizeof(struct snd_emu10k1_synth_arg), &wave) < 0 || |
@@ -206,13 +184,16 @@ static int __devinit snd_card_emu10k1_probe(struct pci_dev *pci, | |||
206 | "%s (rev.%d, serial:0x%x) at 0x%lx, irq %i", | 184 | "%s (rev.%d, serial:0x%x) at 0x%lx, irq %i", |
207 | card->shortname, emu->revision, emu->serial, emu->port, emu->irq); | 185 | card->shortname, emu->revision, emu->serial, emu->port, emu->irq); |
208 | 186 | ||
209 | if ((err = snd_card_register(card)) < 0) { | 187 | if ((err = snd_card_register(card)) < 0) |
210 | snd_card_free(card); | 188 | goto error; |
211 | return err; | 189 | |
212 | } | ||
213 | pci_set_drvdata(pci, card); | 190 | pci_set_drvdata(pci, card); |
214 | dev++; | 191 | dev++; |
215 | return 0; | 192 | return 0; |
193 | |||
194 | error: | ||
195 | snd_card_free(card); | ||
196 | return err; | ||
216 | } | 197 | } |
217 | 198 | ||
218 | static void __devexit snd_card_emu10k1_remove(struct pci_dev *pci) | 199 | static void __devexit snd_card_emu10k1_remove(struct pci_dev *pci) |
@@ -221,11 +202,68 @@ static void __devexit snd_card_emu10k1_remove(struct pci_dev *pci) | |||
221 | pci_set_drvdata(pci, NULL); | 202 | pci_set_drvdata(pci, NULL); |
222 | } | 203 | } |
223 | 204 | ||
205 | |||
206 | #ifdef CONFIG_PM | ||
207 | static int snd_emu10k1_suspend(struct pci_dev *pci, pm_message_t state) | ||
208 | { | ||
209 | struct snd_card *card = pci_get_drvdata(pci); | ||
210 | struct snd_emu10k1 *emu = card->private_data; | ||
211 | |||
212 | snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); | ||
213 | |||
214 | snd_pcm_suspend_all(emu->pcm); | ||
215 | snd_pcm_suspend_all(emu->pcm_mic); | ||
216 | snd_pcm_suspend_all(emu->pcm_efx); | ||
217 | snd_pcm_suspend_all(emu->pcm_multi); | ||
218 | snd_pcm_suspend_all(emu->pcm_p16v); | ||
219 | |||
220 | snd_ac97_suspend(emu->ac97); | ||
221 | |||
222 | snd_emu10k1_efx_suspend(emu); | ||
223 | snd_emu10k1_suspend_regs(emu); | ||
224 | if (emu->card_capabilities->ca0151_chip) | ||
225 | snd_p16v_suspend(emu); | ||
226 | |||
227 | snd_emu10k1_done(emu); | ||
228 | |||
229 | pci_set_power_state(pci, PCI_D3hot); | ||
230 | pci_disable_device(pci); | ||
231 | pci_save_state(pci); | ||
232 | return 0; | ||
233 | } | ||
234 | |||
235 | int snd_emu10k1_resume(struct pci_dev *pci) | ||
236 | { | ||
237 | struct snd_card *card = pci_get_drvdata(pci); | ||
238 | struct snd_emu10k1 *emu = card->private_data; | ||
239 | |||
240 | pci_restore_state(pci); | ||
241 | pci_enable_device(pci); | ||
242 | pci_set_power_state(pci, PCI_D0); | ||
243 | pci_set_master(pci); | ||
244 | |||
245 | snd_emu10k1_resume_init(emu); | ||
246 | snd_emu10k1_efx_resume(emu); | ||
247 | snd_ac97_resume(emu->ac97); | ||
248 | snd_emu10k1_resume_regs(emu); | ||
249 | |||
250 | if (emu->card_capabilities->ca0151_chip) | ||
251 | snd_p16v_resume(emu); | ||
252 | |||
253 | snd_power_change_state(card, SNDRV_CTL_POWER_D0); | ||
254 | return 0; | ||
255 | } | ||
256 | #endif | ||
257 | |||
224 | static struct pci_driver driver = { | 258 | static struct pci_driver driver = { |
225 | .name = "EMU10K1_Audigy", | 259 | .name = "EMU10K1_Audigy", |
226 | .id_table = snd_emu10k1_ids, | 260 | .id_table = snd_emu10k1_ids, |
227 | .probe = snd_card_emu10k1_probe, | 261 | .probe = snd_card_emu10k1_probe, |
228 | .remove = __devexit_p(snd_card_emu10k1_remove), | 262 | .remove = __devexit_p(snd_card_emu10k1_remove), |
263 | #ifdef CONFIG_PM | ||
264 | .suspend = snd_emu10k1_suspend, | ||
265 | .resume = snd_emu10k1_resume, | ||
266 | #endif | ||
229 | }; | 267 | }; |
230 | 268 | ||
231 | static int __init alsa_card_emu10k1_init(void) | 269 | static int __init alsa_card_emu10k1_init(void) |