aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/emu10k1/emu10k1_main.c
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2005-11-17 10:14:10 -0500
committerJaroslav Kysela <perex@suse.cz>2006-01-03 06:27:58 -0500
commit09668b441dacdf4640509b640ad73e24efd5204f (patch)
tree177d0548acbcca4432f82ce6f3aa397cba5ba528 /sound/pci/emu10k1/emu10k1_main.c
parentfe8be10786c040bce53c18048d75b1b23aec64ae (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_main.c')
-rw-r--r--sound/pci/emu10k1/emu10k1_main.c308
1 files changed, 202 insertions, 106 deletions
diff --git a/sound/pci/emu10k1/emu10k1_main.c b/sound/pci/emu10k1/emu10k1_main.c
index f9855073a0a9..cc36b748d9a5 100644
--- a/sound/pci/emu10k1/emu10k1_main.c
+++ b/sound/pci/emu10k1/emu10k1_main.c
@@ -42,12 +42,6 @@
42#include "p16v.h" 42#include "p16v.h"
43#include "tina2.h" 43#include "tina2.h"
44 44
45#if 0
46MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>, Creative Labs, Inc.");
47MODULE_DESCRIPTION("Routines for control of EMU10K1 chips");
48MODULE_LICENSE("GPL");
49#endif
50
51/************************************************************************* 45/*************************************************************************
52 * EMU10K1 init / done 46 * EMU10K1 init / done
53 *************************************************************************/ 47 *************************************************************************/
@@ -97,17 +91,14 @@ void snd_emu10k1_voice_init(struct snd_emu10k1 * emu, int ch)
97 } 91 }
98} 92}
99 93
100static int __devinit snd_emu10k1_init(struct snd_emu10k1 * emu, int enable_ir) 94static int snd_emu10k1_init(struct snd_emu10k1 *emu, int enable_ir, int resume)
101{ 95{
102 int ch, idx, err;
103 unsigned int silent_page; 96 unsigned int silent_page;
104 97 int ch;
105 emu->fx8010.itram_size = (16 * 1024)/2;
106 emu->fx8010.etram_pages.area = NULL;
107 emu->fx8010.etram_pages.bytes = 0;
108 98
109 /* disable audio and lock cache */ 99 /* disable audio and lock cache */
110 outl(HCFG_LOCKSOUNDCACHE | HCFG_LOCKTANKCACHE_MASK | HCFG_MUTEBUTTONENABLE, emu->port + HCFG); 100 outl(HCFG_LOCKSOUNDCACHE | HCFG_LOCKTANKCACHE_MASK | HCFG_MUTEBUTTONENABLE,
101 emu->port + HCFG);
111 102
112 /* reset recording buffers */ 103 /* reset recording buffers */
113 snd_emu10k1_ptr_write(emu, MICBS, 0, ADCBS_BUFSIZE_NONE); 104 snd_emu10k1_ptr_write(emu, MICBS, 0, ADCBS_BUFSIZE_NONE);
@@ -128,48 +119,17 @@ static int __devinit snd_emu10k1_init(struct snd_emu10k1 * emu, int enable_ir)
128 /* set SPDIF bypass mode */ 119 /* set SPDIF bypass mode */
129 snd_emu10k1_ptr_write(emu, SPBYPASS, 0, SPBYPASS_FORMAT); 120 snd_emu10k1_ptr_write(emu, SPBYPASS, 0, SPBYPASS_FORMAT);
130 /* enable rear left + rear right AC97 slots */ 121 /* enable rear left + rear right AC97 slots */
131 snd_emu10k1_ptr_write(emu, AC97SLOT, 0, AC97SLOT_REAR_RIGHT | AC97SLOT_REAR_LEFT); 122 snd_emu10k1_ptr_write(emu, AC97SLOT, 0, AC97SLOT_REAR_RIGHT |
123 AC97SLOT_REAR_LEFT);
132 } 124 }
133 125
134 /* init envelope engine */ 126 /* init envelope engine */
135 for (ch = 0; ch < NUM_G; ch++) { 127 for (ch = 0; ch < NUM_G; ch++)
136 emu->voices[ch].emu = emu;
137 emu->voices[ch].number = ch;
138 snd_emu10k1_voice_init(emu, ch); 128 snd_emu10k1_voice_init(emu, ch);
139 }
140 129
141 /* 130 snd_emu10k1_ptr_write(emu, SPCS0, 0, emu->spdif_bits[0]);
142 * Init to 0x02109204 : 131 snd_emu10k1_ptr_write(emu, SPCS1, 0, emu->spdif_bits[1]);
143 * Clock accuracy = 0 (1000ppm) 132 snd_emu10k1_ptr_write(emu, SPCS2, 0, emu->spdif_bits[2]);
144 * Sample Rate = 2 (48kHz)
145 * Audio Channel = 1 (Left of 2)
146 * Source Number = 0 (Unspecified)
147 * Generation Status = 1 (Original for Cat Code 12)
148 * Cat Code = 12 (Digital Signal Mixer)
149 * Mode = 0 (Mode 0)
150 * Emphasis = 0 (None)
151 * CP = 1 (Copyright unasserted)
152 * AN = 0 (Audio data)
153 * P = 0 (Consumer)
154 */
155 snd_emu10k1_ptr_write(emu, SPCS0, 0,
156 emu->spdif_bits[0] =
157 SPCS_CLKACCY_1000PPM | SPCS_SAMPLERATE_48 |
158 SPCS_CHANNELNUM_LEFT | SPCS_SOURCENUM_UNSPEC |
159 SPCS_GENERATIONSTATUS | 0x00001200 |
160 0x00000000 | SPCS_EMPHASIS_NONE | SPCS_COPYRIGHT);
161 snd_emu10k1_ptr_write(emu, SPCS1, 0,
162 emu->spdif_bits[1] =
163 SPCS_CLKACCY_1000PPM | SPCS_SAMPLERATE_48 |
164 SPCS_CHANNELNUM_LEFT | SPCS_SOURCENUM_UNSPEC |
165 SPCS_GENERATIONSTATUS | 0x00001200 |
166 0x00000000 | SPCS_EMPHASIS_NONE | SPCS_COPYRIGHT);
167 snd_emu10k1_ptr_write(emu, SPCS2, 0,
168 emu->spdif_bits[2] =
169 SPCS_CLKACCY_1000PPM | SPCS_SAMPLERATE_48 |
170 SPCS_CHANNELNUM_LEFT | SPCS_SOURCENUM_UNSPEC |
171 SPCS_GENERATIONSTATUS | 0x00001200 |
172 0x00000000 | SPCS_EMPHASIS_NONE | SPCS_COPYRIGHT);
173 133
174 if (emu->card_capabilities->ca0151_chip) { /* audigy2 */ 134 if (emu->card_capabilities->ca0151_chip) { /* audigy2 */
175 /* Hacks for Alice3 to work independent of haP16V driver */ 135 /* Hacks for Alice3 to work independent of haP16V driver */
@@ -196,7 +156,7 @@ static int __devinit snd_emu10k1_init(struct snd_emu10k1 * emu, int enable_ir)
196 /* Hacks for Alice3 to work independent of haP16V driver */ 156 /* Hacks for Alice3 to work independent of haP16V driver */
197 u32 tmp; 157 u32 tmp;
198 158
199 snd_printk(KERN_ERR "Audigy2 value:Special config.\n"); 159 snd_printk(KERN_INFO "Audigy2 value: Special config.\n");
200 //Setup SRCMulti_I2S SamplingRate 160 //Setup SRCMulti_I2S SamplingRate
201 tmp = snd_emu10k1_ptr_read(emu, A_SPDIF_SAMPLERATE, 0); 161 tmp = snd_emu10k1_ptr_read(emu, A_SPDIF_SAMPLERATE, 0);
202 tmp &= 0xfffff1ff; 162 tmp &= 0xfffff1ff;
@@ -221,14 +181,6 @@ static int __devinit snd_emu10k1_init(struct snd_emu10k1 * emu, int enable_ir)
221 outl(tmp, emu->port + A_IOCFG); 181 outl(tmp, emu->port + A_IOCFG);
222 } 182 }
223 183
224
225 /*
226 * Clear page with silence & setup all pointers to this page
227 */
228 memset(emu->silent_page.area, 0, PAGE_SIZE);
229 silent_page = emu->silent_page.addr << 1;
230 for (idx = 0; idx < MAXPAGES; idx++)
231 ((u32 *)emu->ptb_pages.area)[idx] = cpu_to_le32(silent_page | idx);
232 snd_emu10k1_ptr_write(emu, PTB, 0, emu->ptb_pages.addr); 184 snd_emu10k1_ptr_write(emu, PTB, 0, emu->ptb_pages.addr);
233 snd_emu10k1_ptr_write(emu, TCB, 0, 0); /* taken from original driver */ 185 snd_emu10k1_ptr_write(emu, TCB, 0, 0); /* taken from original driver */
234 snd_emu10k1_ptr_write(emu, TCBS, 0, 4); /* taken from original driver */ 186 snd_emu10k1_ptr_write(emu, TCBS, 0, 4); /* taken from original driver */
@@ -287,12 +239,11 @@ static int __devinit snd_emu10k1_init(struct snd_emu10k1 * emu, int enable_ir)
287 outl(reg | A_IOCFG_GPOUT0, emu->port + A_IOCFG); 239 outl(reg | A_IOCFG_GPOUT0, emu->port + A_IOCFG);
288 } 240 }
289 241
290 /* 242 return 0;
291 * Initialize the effect engine 243}
292 */
293 if ((err = snd_emu10k1_init_efx(emu)) < 0)
294 return err;
295 244
245static void snd_emu10k1_audio_enable(struct snd_emu10k1 *emu)
246{
296 /* 247 /*
297 * Enable the audio bit 248 * Enable the audio bit
298 */ 249 */
@@ -335,15 +286,9 @@ static int __devinit snd_emu10k1_init(struct snd_emu10k1 * emu, int enable_ir)
335#endif 286#endif
336 287
337 snd_emu10k1_intr_enable(emu, INTE_PCIERRORENABLE); 288 snd_emu10k1_intr_enable(emu, INTE_PCIERRORENABLE);
338
339 emu->reserved_page = (struct snd_emu10k1_memblk *)snd_emu10k1_synth_alloc(emu, 4096);
340 if (emu->reserved_page)
341 emu->reserved_page->map_locked = 1;
342
343 return 0;
344} 289}
345 290
346static int snd_emu10k1_done(struct snd_emu10k1 * emu) 291int snd_emu10k1_done(struct snd_emu10k1 * emu)
347{ 292{
348 int ch; 293 int ch;
349 294
@@ -382,18 +327,10 @@ static int snd_emu10k1_done(struct snd_emu10k1 * emu)
382 snd_emu10k1_ptr_write(emu, SOLEL, 0, 0); 327 snd_emu10k1_ptr_write(emu, SOLEL, 0, 0);
383 snd_emu10k1_ptr_write(emu, SOLEH, 0, 0); 328 snd_emu10k1_ptr_write(emu, SOLEH, 0, 0);
384 329
385 /* remove reserved page */
386 if (emu->reserved_page != NULL) {
387 snd_emu10k1_synth_free(emu, (struct snd_util_memblk *)emu->reserved_page);
388 emu->reserved_page = NULL;
389 }
390
391 /* disable audio and lock cache */ 330 /* disable audio and lock cache */
392 outl(HCFG_LOCKSOUNDCACHE | HCFG_LOCKTANKCACHE_MASK | HCFG_MUTEBUTTONENABLE, emu->port + HCFG); 331 outl(HCFG_LOCKSOUNDCACHE | HCFG_LOCKTANKCACHE_MASK | HCFG_MUTEBUTTONENABLE, emu->port + HCFG);
393 snd_emu10k1_ptr_write(emu, PTB, 0, 0); 332 snd_emu10k1_ptr_write(emu, PTB, 0, 0);
394 333
395 snd_emu10k1_free_efx(emu);
396
397 return 0; 334 return 0;
398} 335}
399 336
@@ -609,11 +546,22 @@ static int __devinit snd_emu10k1_cardbus_init(struct snd_emu10k1 * emu)
609 * Create the EMU10K1 instance 546 * Create the EMU10K1 instance
610 */ 547 */
611 548
549#ifdef CONFIG_PM
550static int alloc_pm_buffer(struct snd_emu10k1 *emu);
551static void free_pm_buffer(struct snd_emu10k1 *emu);
552#endif
553
612static int snd_emu10k1_free(struct snd_emu10k1 *emu) 554static int snd_emu10k1_free(struct snd_emu10k1 *emu)
613{ 555{
614 if (emu->port) { /* avoid access to already used hardware */ 556 if (emu->port) { /* avoid access to already used hardware */
615 snd_emu10k1_fx8010_tram_setup(emu, 0); 557 snd_emu10k1_fx8010_tram_setup(emu, 0);
616 snd_emu10k1_done(emu); 558 snd_emu10k1_done(emu);
559 /* remove reserved page */
560 if (emu->reserved_page) {
561 snd_emu10k1_synth_free(emu, (struct snd_util_memblk *)emu->reserved_page);
562 emu->reserved_page = NULL;
563 }
564 snd_emu10k1_free_efx(emu);
617 } 565 }
618 if (emu->memhdr) 566 if (emu->memhdr)
619 snd_util_memhdr_free(emu->memhdr); 567 snd_util_memhdr_free(emu->memhdr);
@@ -623,13 +571,16 @@ static int snd_emu10k1_free(struct snd_emu10k1 *emu)
623 snd_dma_free_pages(&emu->ptb_pages); 571 snd_dma_free_pages(&emu->ptb_pages);
624 vfree(emu->page_ptr_table); 572 vfree(emu->page_ptr_table);
625 vfree(emu->page_addr_table); 573 vfree(emu->page_addr_table);
574#ifdef CONFIG_PM
575 free_pm_buffer(emu);
576#endif
626 if (emu->irq >= 0) 577 if (emu->irq >= 0)
627 free_irq(emu->irq, (void *)emu); 578 free_irq(emu->irq, (void *)emu);
628 if (emu->port) 579 if (emu->port)
629 pci_release_regions(emu->pci); 580 pci_release_regions(emu->pci);
630 pci_disable_device(emu->pci);
631 if (emu->card_capabilities->ca0151_chip) /* P16V */ 581 if (emu->card_capabilities->ca0151_chip) /* P16V */
632 snd_p16v_free(emu); 582 snd_p16v_free(emu);
583 pci_disable_device(emu->pci);
633 kfree(emu); 584 kfree(emu);
634 return 0; 585 return 0;
635} 586}
@@ -900,9 +851,10 @@ int __devinit snd_emu10k1_create(struct snd_card *card,
900 struct snd_emu10k1 ** remu) 851 struct snd_emu10k1 ** remu)
901{ 852{
902 struct snd_emu10k1 *emu; 853 struct snd_emu10k1 *emu;
903 int err; 854 int idx, err;
904 int is_audigy; 855 int is_audigy;
905 unsigned char revision; 856 unsigned char revision;
857 unsigned int silent_page;
906 const struct snd_emu_chip_details *c; 858 const struct snd_emu_chip_details *c;
907 static struct snd_device_ops ops = { 859 static struct snd_device_ops ops = {
908 .dev_free = snd_emu10k1_dev_free, 860 .dev_free = snd_emu10k1_dev_free,
@@ -1012,34 +964,34 @@ int __devinit snd_emu10k1_create(struct snd_card *card,
1012 emu->port = pci_resource_start(pci, 0); 964 emu->port = pci_resource_start(pci, 0);
1013 965
1014 if (request_irq(pci->irq, snd_emu10k1_interrupt, SA_INTERRUPT|SA_SHIRQ, "EMU10K1", (void *)emu)) { 966 if (request_irq(pci->irq, snd_emu10k1_interrupt, SA_INTERRUPT|SA_SHIRQ, "EMU10K1", (void *)emu)) {
1015 snd_emu10k1_free(emu); 967 err = -EBUSY;
1016 return -EBUSY; 968 goto error;
1017 } 969 }
1018 emu->irq = pci->irq; 970 emu->irq = pci->irq;
1019 971
1020 emu->max_cache_pages = max_cache_bytes >> PAGE_SHIFT; 972 emu->max_cache_pages = max_cache_bytes >> PAGE_SHIFT;
1021 if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(pci), 973 if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(pci),
1022 32 * 1024, &emu->ptb_pages) < 0) { 974 32 * 1024, &emu->ptb_pages) < 0) {
1023 snd_emu10k1_free(emu); 975 err = -ENOMEM;
1024 return -ENOMEM; 976 goto error;
1025 } 977 }
1026 978
1027 emu->page_ptr_table = (void **)vmalloc(emu->max_cache_pages * sizeof(void*)); 979 emu->page_ptr_table = (void **)vmalloc(emu->max_cache_pages * sizeof(void*));
1028 emu->page_addr_table = (unsigned long*)vmalloc(emu->max_cache_pages * sizeof(unsigned long)); 980 emu->page_addr_table = (unsigned long*)vmalloc(emu->max_cache_pages * sizeof(unsigned long));
1029 if (emu->page_ptr_table == NULL || emu->page_addr_table == NULL) { 981 if (emu->page_ptr_table == NULL || emu->page_addr_table == NULL) {
1030 snd_emu10k1_free(emu); 982 err = -ENOMEM;
1031 return -ENOMEM; 983 goto error;
1032 } 984 }
1033 985
1034 if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(pci), 986 if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(pci),
1035 EMUPAGESIZE, &emu->silent_page) < 0) { 987 EMUPAGESIZE, &emu->silent_page) < 0) {
1036 snd_emu10k1_free(emu); 988 err = -ENOMEM;
1037 return -ENOMEM; 989 goto error;
1038 } 990 }
1039 emu->memhdr = snd_util_memhdr_new(emu->max_cache_pages * PAGE_SIZE); 991 emu->memhdr = snd_util_memhdr_new(emu->max_cache_pages * PAGE_SIZE);
1040 if (emu->memhdr == NULL) { 992 if (emu->memhdr == NULL) {
1041 snd_emu10k1_free(emu); 993 err = -ENOMEM;
1042 return -ENOMEM; 994 goto error;
1043 } 995 }
1044 emu->memhdr->block_extra_size = sizeof(struct snd_emu10k1_memblk) - 996 emu->memhdr->block_extra_size = sizeof(struct snd_emu10k1_memblk) -
1045 sizeof(struct snd_util_memblk); 997 sizeof(struct snd_util_memblk);
@@ -1053,40 +1005,184 @@ int __devinit snd_emu10k1_create(struct snd_card *card,
1053 extout_mask = 0x7fff; 1005 extout_mask = 0x7fff;
1054 emu->fx8010.extin_mask = extin_mask; 1006 emu->fx8010.extin_mask = extin_mask;
1055 emu->fx8010.extout_mask = extout_mask; 1007 emu->fx8010.extout_mask = extout_mask;
1008 emu->enable_ir = enable_ir;
1056 1009
1057 if (emu->card_capabilities->ecard) { 1010 if (emu->card_capabilities->ecard) {
1058 if ((err = snd_emu10k1_ecard_init(emu)) < 0) { 1011 if ((err = snd_emu10k1_ecard_init(emu)) < 0)
1059 snd_emu10k1_free(emu); 1012 goto error;
1060 return err;
1061 }
1062 } else if (emu->card_capabilities->ca_cardbus_chip) { 1013 } else if (emu->card_capabilities->ca_cardbus_chip) {
1063 if ((err = snd_emu10k1_cardbus_init(emu)) < 0) { 1014 if ((err = snd_emu10k1_cardbus_init(emu)) < 0)
1064 snd_emu10k1_free(emu); 1015 goto error;
1065 return err;
1066 }
1067 } else { 1016 } else {
1068 /* 5.1: Enable the additional AC97 Slots. If the emu10k1 version 1017 /* 5.1: Enable the additional AC97 Slots. If the emu10k1 version
1069 does not support this, it shouldn't do any harm */ 1018 does not support this, it shouldn't do any harm */
1070 snd_emu10k1_ptr_write(emu, AC97SLOT, 0, AC97SLOT_CNTR|AC97SLOT_LFE); 1019 snd_emu10k1_ptr_write(emu, AC97SLOT, 0, AC97SLOT_CNTR|AC97SLOT_LFE);
1071 } 1020 }
1072 1021
1073 if ((err = snd_emu10k1_init(emu, enable_ir)) < 0) { 1022 /* initialize TRAM setup */
1074 snd_emu10k1_free(emu); 1023 emu->fx8010.itram_size = (16 * 1024)/2;
1075 return err; 1024 emu->fx8010.etram_pages.area = NULL;
1076 } 1025 emu->fx8010.etram_pages.bytes = 0;
1077 1026
1078 if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, emu, &ops)) < 0) { 1027 /*
1079 snd_emu10k1_free(emu); 1028 * Init to 0x02109204 :
1080 return err; 1029 * Clock accuracy = 0 (1000ppm)
1030 * Sample Rate = 2 (48kHz)
1031 * Audio Channel = 1 (Left of 2)
1032 * Source Number = 0 (Unspecified)
1033 * Generation Status = 1 (Original for Cat Code 12)
1034 * Cat Code = 12 (Digital Signal Mixer)
1035 * Mode = 0 (Mode 0)
1036 * Emphasis = 0 (None)
1037 * CP = 1 (Copyright unasserted)
1038 * AN = 0 (Audio data)
1039 * P = 0 (Consumer)
1040 */
1041 emu->spdif_bits[0] = emu->spdif_bits[1] =
1042 emu->spdif_bits[2] = SPCS_CLKACCY_1000PPM | SPCS_SAMPLERATE_48 |
1043 SPCS_CHANNELNUM_LEFT | SPCS_SOURCENUM_UNSPEC |
1044 SPCS_GENERATIONSTATUS | 0x00001200 |
1045 0x00000000 | SPCS_EMPHASIS_NONE | SPCS_COPYRIGHT;
1046
1047 emu->reserved_page = (struct snd_emu10k1_memblk *)
1048 snd_emu10k1_synth_alloc(emu, 4096);
1049 if (emu->reserved_page)
1050 emu->reserved_page->map_locked = 1;
1051
1052 /* Clear silent pages and set up pointers */
1053 memset(emu->silent_page.area, 0, PAGE_SIZE);
1054 silent_page = emu->silent_page.addr << 1;
1055 for (idx = 0; idx < MAXPAGES; idx++)
1056 ((u32 *)emu->ptb_pages.area)[idx] = cpu_to_le32(silent_page | idx);
1057
1058 /* set up voice indices */
1059 for (idx = 0; idx < NUM_G; idx++) {
1060 emu->voices[idx].emu = emu;
1061 emu->voices[idx].number = idx;
1081 } 1062 }
1082 1063
1064 if ((err = snd_emu10k1_init(emu, enable_ir, 0)) < 0)
1065 goto error;
1066#ifdef CONFIG_PM
1067 if ((err = alloc_pm_buffer(emu)) < 0)
1068 goto error;
1069#endif
1070
1071 /* Initialize the effect engine */
1072 if ((err = snd_emu10k1_init_efx(emu)) < 0)
1073 goto error;
1074 snd_emu10k1_audio_enable(emu);
1075
1076 if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, emu, &ops)) < 0)
1077 goto error;
1078
1083 snd_emu10k1_proc_init(emu); 1079 snd_emu10k1_proc_init(emu);
1084 1080
1085 snd_card_set_dev(card, &pci->dev); 1081 snd_card_set_dev(card, &pci->dev);
1086 *remu = emu; 1082 *remu = emu;
1087 return 0; 1083 return 0;
1084
1085 error:
1086 snd_emu10k1_free(emu);
1087 return err;
1088} 1088}
1089 1089
1090#ifdef CONFIG_PM
1091static unsigned char saved_regs[] = {
1092 CPF, PTRX, CVCF, VTFT, Z1, Z2, PSST, DSL, CCCA, CCR, CLP,
1093 FXRT, MAPA, MAPB, ENVVOL, ATKHLDV, DCYSUSV, LFOVAL1, ENVVAL,
1094 ATKHLDM, DCYSUSM, LFOVAL2, IP, IFATN, PEFE, FMMOD, TREMFRQ, FM2FRQ2,
1095 TEMPENV, ADCCR, FXWC, MICBA, ADCBA, FXBA,
1096 MICBS, ADCBS, FXBS, CDCS, GPSCS, SPCS0, SPCS1, SPCS2,
1097 SPBYPASS, AC97SLOT, CDSRCS, GPSRCS, ZVSRCS, MICIDX, ADCIDX, FXIDX,
1098 0xff /* end */
1099};
1100static unsigned char saved_regs_audigy[] = {
1101 A_ADCIDX, A_MICIDX, A_FXWC1, A_FXWC2, A_SAMPLE_RATE,
1102 A_FXRT2, A_SENDAMOUNTS, A_FXRT1,
1103 0xff /* end */
1104};
1105
1106static int __devinit alloc_pm_buffer(struct snd_emu10k1 *emu)
1107{
1108 int size;
1109
1110 size = ARRAY_SIZE(saved_regs);
1111 if (emu->audigy)
1112 size += ARRAY_SIZE(saved_regs_audigy);
1113 emu->saved_ptr = vmalloc(4 * NUM_G * size);
1114 if (! emu->saved_ptr)
1115 return -ENOMEM;
1116 if (snd_emu10k1_efx_alloc_pm_buffer(emu) < 0)
1117 return -ENOMEM;
1118 if (emu->card_capabilities->ca0151_chip &&
1119 snd_p16v_alloc_pm_buffer(emu) < 0)
1120 return -ENOMEM;
1121 return 0;
1122}
1123
1124static void free_pm_buffer(struct snd_emu10k1 *emu)
1125{
1126 vfree(emu->saved_ptr);
1127 snd_emu10k1_efx_free_pm_buffer(emu);
1128 if (emu->card_capabilities->ca0151_chip)
1129 snd_p16v_free_pm_buffer(emu);
1130}
1131
1132void snd_emu10k1_suspend_regs(struct snd_emu10k1 *emu)
1133{
1134 int i;
1135 unsigned char *reg;
1136 unsigned int *val;
1137
1138 val = emu->saved_ptr;
1139 for (reg = saved_regs; *reg != 0xff; reg++)
1140 for (i = 0; i < NUM_G; i++, val++)
1141 *val = snd_emu10k1_ptr_read(emu, *reg, i);
1142 if (emu->audigy) {
1143 for (reg = saved_regs_audigy; *reg != 0xff; reg++)
1144 for (i = 0; i < NUM_G; i++, val++)
1145 *val = snd_emu10k1_ptr_read(emu, *reg, i);
1146 }
1147 if (emu->audigy)
1148 emu->saved_a_iocfg = inl(emu->port + A_IOCFG);
1149 emu->saved_hcfg = inl(emu->port + HCFG);
1150}
1151
1152void snd_emu10k1_resume_init(struct snd_emu10k1 *emu)
1153{
1154 if (emu->card_capabilities->ecard)
1155 snd_emu10k1_ecard_init(emu);
1156 else
1157 snd_emu10k1_ptr_write(emu, AC97SLOT, 0, AC97SLOT_CNTR|AC97SLOT_LFE);
1158 snd_emu10k1_init(emu, emu->enable_ir, 1);
1159}
1160
1161void snd_emu10k1_resume_regs(struct snd_emu10k1 *emu)
1162{
1163 int i;
1164 unsigned char *reg;
1165 unsigned int *val;
1166
1167 snd_emu10k1_audio_enable(emu);
1168
1169 /* resore for spdif */
1170 if (emu->audigy)
1171 outl(emu->port + A_IOCFG, emu->saved_a_iocfg);
1172 outl(emu->port + HCFG, emu->saved_hcfg);
1173
1174 val = emu->saved_ptr;
1175 for (reg = saved_regs; *reg != 0xff; reg++)
1176 for (i = 0; i < NUM_G; i++, val++)
1177 snd_emu10k1_ptr_write(emu, *reg, i, *val);
1178 if (emu->audigy) {
1179 for (reg = saved_regs_audigy; *reg != 0xff; reg++)
1180 for (i = 0; i < NUM_G; i++, val++)
1181 snd_emu10k1_ptr_write(emu, *reg, i, *val);
1182 }
1183}
1184#endif
1185
1090/* memory.c */ 1186/* memory.c */
1091EXPORT_SYMBOL(snd_emu10k1_synth_alloc); 1187EXPORT_SYMBOL(snd_emu10k1_synth_alloc);
1092EXPORT_SYMBOL(snd_emu10k1_synth_free); 1188EXPORT_SYMBOL(snd_emu10k1_synth_free);