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_main.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_main.c')
-rw-r--r-- | sound/pci/emu10k1/emu10k1_main.c | 308 |
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 | ||
46 | MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>, Creative Labs, Inc."); | ||
47 | MODULE_DESCRIPTION("Routines for control of EMU10K1 chips"); | ||
48 | MODULE_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 | ||
100 | static int __devinit snd_emu10k1_init(struct snd_emu10k1 * emu, int enable_ir) | 94 | static 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 | ||
245 | static 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 | ||
346 | static int snd_emu10k1_done(struct snd_emu10k1 * emu) | 291 | int 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 | ||
550 | static int alloc_pm_buffer(struct snd_emu10k1 *emu); | ||
551 | static void free_pm_buffer(struct snd_emu10k1 *emu); | ||
552 | #endif | ||
553 | |||
612 | static int snd_emu10k1_free(struct snd_emu10k1 *emu) | 554 | static 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 | ||
1091 | static 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 | }; | ||
1100 | static 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 | |||
1106 | static 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 | |||
1124 | static 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 | |||
1132 | void 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 | |||
1152 | void 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 | |||
1161 | void 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 */ |
1091 | EXPORT_SYMBOL(snd_emu10k1_synth_alloc); | 1187 | EXPORT_SYMBOL(snd_emu10k1_synth_alloc); |
1092 | EXPORT_SYMBOL(snd_emu10k1_synth_free); | 1188 | EXPORT_SYMBOL(snd_emu10k1_synth_free); |