blob: e3a14068115cf3a1e60581c62932987a5471506f [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
2 * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
3 * Creative Labs, Inc.
4 * Routines for control of EMU10K1 chips
5 *
6 * Copyright (c) by James Courtier-Dutton <James@superbug.demon.co.uk>
7 * Added support for Audigy 2 Value.
8 *
9 *
10 * BUGS:
11 * --
12 *
13 * TODO:
14 * --
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
25 *
26 * You should have received a copy of the GNU General Public License
27 * along with this program; if not, write to the Free Software
28 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
29 *
30 */
31
32#include <sound/driver.h>
33#include <linux/delay.h>
34#include <linux/init.h>
35#include <linux/interrupt.h>
36#include <linux/pci.h>
37#include <linux/slab.h>
38#include <linux/vmalloc.h>
39
40#include <sound/core.h>
41#include <sound/emu10k1.h>
42#include "p16v.h"
James Courtier-Duttone2b15f82005-11-11 23:39:05 +010043#include "tina2.h"
Linus Torvalds1da177e2005-04-16 15:20:36 -070044
James Courtier-Dutton19b99fb2005-12-04 18:03:03 +010045
Linus Torvalds1da177e2005-04-16 15:20:36 -070046/*************************************************************************
47 * EMU10K1 init / done
48 *************************************************************************/
49
Takashi Iwaieb4698f2005-11-17 14:50:13 +010050void snd_emu10k1_voice_init(struct snd_emu10k1 * emu, int ch)
Linus Torvalds1da177e2005-04-16 15:20:36 -070051{
52 snd_emu10k1_ptr_write(emu, DCYSUSV, ch, 0);
53 snd_emu10k1_ptr_write(emu, IP, ch, 0);
54 snd_emu10k1_ptr_write(emu, VTFT, ch, 0xffff);
55 snd_emu10k1_ptr_write(emu, CVCF, ch, 0xffff);
56 snd_emu10k1_ptr_write(emu, PTRX, ch, 0);
57 snd_emu10k1_ptr_write(emu, CPF, ch, 0);
58 snd_emu10k1_ptr_write(emu, CCR, ch, 0);
59
60 snd_emu10k1_ptr_write(emu, PSST, ch, 0);
61 snd_emu10k1_ptr_write(emu, DSL, ch, 0x10);
62 snd_emu10k1_ptr_write(emu, CCCA, ch, 0);
63 snd_emu10k1_ptr_write(emu, Z1, ch, 0);
64 snd_emu10k1_ptr_write(emu, Z2, ch, 0);
65 snd_emu10k1_ptr_write(emu, FXRT, ch, 0x32100000);
66
67 snd_emu10k1_ptr_write(emu, ATKHLDM, ch, 0);
68 snd_emu10k1_ptr_write(emu, DCYSUSM, ch, 0);
69 snd_emu10k1_ptr_write(emu, IFATN, ch, 0xffff);
70 snd_emu10k1_ptr_write(emu, PEFE, ch, 0);
71 snd_emu10k1_ptr_write(emu, FMMOD, ch, 0);
72 snd_emu10k1_ptr_write(emu, TREMFRQ, ch, 24); /* 1 Hz */
73 snd_emu10k1_ptr_write(emu, FM2FRQ2, ch, 24); /* 1 Hz */
74 snd_emu10k1_ptr_write(emu, TEMPENV, ch, 0);
75
76 /*** these are last so OFF prevents writing ***/
77 snd_emu10k1_ptr_write(emu, LFOVAL2, ch, 0);
78 snd_emu10k1_ptr_write(emu, LFOVAL1, ch, 0);
79 snd_emu10k1_ptr_write(emu, ATKHLDV, ch, 0);
80 snd_emu10k1_ptr_write(emu, ENVVOL, ch, 0);
81 snd_emu10k1_ptr_write(emu, ENVVAL, ch, 0);
82
83 /* Audigy extra stuffs */
84 if (emu->audigy) {
85 snd_emu10k1_ptr_write(emu, 0x4c, ch, 0); /* ?? */
86 snd_emu10k1_ptr_write(emu, 0x4d, ch, 0); /* ?? */
87 snd_emu10k1_ptr_write(emu, 0x4e, ch, 0); /* ?? */
88 snd_emu10k1_ptr_write(emu, 0x4f, ch, 0); /* ?? */
89 snd_emu10k1_ptr_write(emu, A_FXRT1, ch, 0x03020100);
90 snd_emu10k1_ptr_write(emu, A_FXRT2, ch, 0x3f3f3f3f);
91 snd_emu10k1_ptr_write(emu, A_SENDAMOUNTS, ch, 0);
92 }
93}
94
Takashi Iwai09668b42005-11-17 16:14:10 +010095static int snd_emu10k1_init(struct snd_emu10k1 *emu, int enable_ir, int resume)
Linus Torvalds1da177e2005-04-16 15:20:36 -070096{
Linus Torvalds1da177e2005-04-16 15:20:36 -070097 unsigned int silent_page;
Takashi Iwai09668b42005-11-17 16:14:10 +010098 int ch;
Linus Torvalds1da177e2005-04-16 15:20:36 -070099
100 /* disable audio and lock cache */
Takashi Iwai09668b42005-11-17 16:14:10 +0100101 outl(HCFG_LOCKSOUNDCACHE | HCFG_LOCKTANKCACHE_MASK | HCFG_MUTEBUTTONENABLE,
102 emu->port + HCFG);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700103
104 /* reset recording buffers */
105 snd_emu10k1_ptr_write(emu, MICBS, 0, ADCBS_BUFSIZE_NONE);
106 snd_emu10k1_ptr_write(emu, MICBA, 0, 0);
107 snd_emu10k1_ptr_write(emu, FXBS, 0, ADCBS_BUFSIZE_NONE);
108 snd_emu10k1_ptr_write(emu, FXBA, 0, 0);
109 snd_emu10k1_ptr_write(emu, ADCBS, 0, ADCBS_BUFSIZE_NONE);
110 snd_emu10k1_ptr_write(emu, ADCBA, 0, 0);
111
112 /* disable channel interrupt */
113 outl(0, emu->port + INTE);
114 snd_emu10k1_ptr_write(emu, CLIEL, 0, 0);
115 snd_emu10k1_ptr_write(emu, CLIEH, 0, 0);
116 snd_emu10k1_ptr_write(emu, SOLEL, 0, 0);
117 snd_emu10k1_ptr_write(emu, SOLEH, 0, 0);
118
119 if (emu->audigy){
120 /* set SPDIF bypass mode */
121 snd_emu10k1_ptr_write(emu, SPBYPASS, 0, SPBYPASS_FORMAT);
122 /* enable rear left + rear right AC97 slots */
Takashi Iwai09668b42005-11-17 16:14:10 +0100123 snd_emu10k1_ptr_write(emu, AC97SLOT, 0, AC97SLOT_REAR_RIGHT |
124 AC97SLOT_REAR_LEFT);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700125 }
126
127 /* init envelope engine */
Takashi Iwai09668b42005-11-17 16:14:10 +0100128 for (ch = 0; ch < NUM_G; ch++)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700129 snd_emu10k1_voice_init(emu, ch);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700130
Takashi Iwai09668b42005-11-17 16:14:10 +0100131 snd_emu10k1_ptr_write(emu, SPCS0, 0, emu->spdif_bits[0]);
132 snd_emu10k1_ptr_write(emu, SPCS1, 0, emu->spdif_bits[1]);
133 snd_emu10k1_ptr_write(emu, SPCS2, 0, emu->spdif_bits[2]);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700134
Lee Revell2b637da2005-03-30 13:51:18 +0200135 if (emu->card_capabilities->ca0151_chip) { /* audigy2 */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700136 /* Hacks for Alice3 to work independent of haP16V driver */
137 u32 tmp;
138
139 //Setup SRCMulti_I2S SamplingRate
140 tmp = snd_emu10k1_ptr_read(emu, A_SPDIF_SAMPLERATE, 0);
141 tmp &= 0xfffff1ff;
142 tmp |= (0x2<<9);
143 snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, 0, tmp);
144
145 /* Setup SRCSel (Enable Spdif,I2S SRCMulti) */
146 snd_emu10k1_ptr20_write(emu, SRCSel, 0, 0x14);
147 /* Setup SRCMulti Input Audio Enable */
148 /* Use 0xFFFFFFFF to enable P16V sounds. */
149 snd_emu10k1_ptr20_write(emu, SRCMULTI_ENABLE, 0, 0xFFFFFFFF);
150
151 /* Enabled Phased (8-channel) P16V playback */
152 outl(0x0201, emu->port + HCFG2);
153 /* Set playback routing. */
James Courtier-Duttonfd9a98e2005-04-10 15:43:35 +0200154 snd_emu10k1_ptr20_write(emu, CAPTURE_P16V_SOURCE, 0, 0x78e4);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700155 }
James Courtier-Duttone0474e52005-07-02 16:33:34 +0200156 if (emu->card_capabilities->ca0108_chip) { /* audigy2 Value */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700157 /* Hacks for Alice3 to work independent of haP16V driver */
158 u32 tmp;
159
Takashi Iwai09668b42005-11-17 16:14:10 +0100160 snd_printk(KERN_INFO "Audigy2 value: Special config.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700161 //Setup SRCMulti_I2S SamplingRate
162 tmp = snd_emu10k1_ptr_read(emu, A_SPDIF_SAMPLERATE, 0);
163 tmp &= 0xfffff1ff;
164 tmp |= (0x2<<9);
165 snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, 0, tmp);
166
167 /* Setup SRCSel (Enable Spdif,I2S SRCMulti) */
168 outl(0x600000, emu->port + 0x20);
169 outl(0x14, emu->port + 0x24);
170
171 /* Setup SRCMulti Input Audio Enable */
172 outl(0x7b0000, emu->port + 0x20);
173 outl(0xFF000000, emu->port + 0x24);
174
175 /* Setup SPDIF Out Audio Enable */
176 /* The Audigy 2 Value has a separate SPDIF out,
177 * so no need for a mixer switch
178 */
179 outl(0x7a0000, emu->port + 0x20);
180 outl(0xFF000000, emu->port + 0x24);
181 tmp = inl(emu->port + A_IOCFG) & ~0x8; /* Clear bit 3 */
182 outl(tmp, emu->port + A_IOCFG);
183 }
James Courtier-Dutton27fe8642005-12-21 15:06:08 +0100184 if (emu->card_capabilities->spi_dac) { /* Audigy 2 ZS Notebook with DAC Wolfson WM8768/WM8568 */
185 u32 tmp;
186 tmp = snd_emu10k1_spi_write(emu, 0x00ff);
187 tmp = snd_emu10k1_spi_write(emu, 0x02ff);
188 tmp = snd_emu10k1_spi_write(emu, 0x0400);
189 tmp = snd_emu10k1_spi_write(emu, 0x0520);
190 tmp = snd_emu10k1_spi_write(emu, 0x0600);
191 tmp = snd_emu10k1_spi_write(emu, 0x08ff);
192 tmp = snd_emu10k1_spi_write(emu, 0x0aff);
193 tmp = snd_emu10k1_spi_write(emu, 0x0cff);
194 tmp = snd_emu10k1_spi_write(emu, 0x0eff);
195 tmp = snd_emu10k1_spi_write(emu, 0x10ff);
196 tmp = snd_emu10k1_spi_write(emu, 0x1200);
197 tmp = snd_emu10k1_spi_write(emu, 0x1400);
198 tmp = snd_emu10k1_spi_write(emu, 0x1480);
199 tmp = snd_emu10k1_spi_write(emu, 0x1800);
200 tmp = snd_emu10k1_spi_write(emu, 0x1aff);
201 tmp = snd_emu10k1_spi_write(emu, 0x1cff);
202 tmp = snd_emu10k1_spi_write(emu, 0x1e00);
203 tmp = snd_emu10k1_spi_write(emu, 0x0530);
204 tmp = snd_emu10k1_spi_write(emu, 0x0602);
205 tmp = snd_emu10k1_spi_write(emu, 0x0622);
206 tmp = snd_emu10k1_spi_write(emu, 0x1400);
207 snd_emu10k1_ptr20_write(emu, 0x60, 0, 0x10);
James Courtier-Duttonccadc3e2005-12-21 15:31:02 +0100208 /* Enable GPIOs
209 * GPIO0: Unknown
210 * GPIO1: Speakers-enabled.
211 * GPIO2: Unknown
212 * GPIO3: Unknown
213 * GPIO4: IEC958 Output on.
214 * GPIO5: Unknown
215 * GPIO6: Unknown
216 * GPIO7: Unknown
217 */
218 outl(0x76, emu->port + A_IOCFG); /* Windows uses 0x3f76 */
219
James Courtier-Dutton27fe8642005-12-21 15:06:08 +0100220 }
221
Linus Torvalds1da177e2005-04-16 15:20:36 -0700222 snd_emu10k1_ptr_write(emu, PTB, 0, emu->ptb_pages.addr);
223 snd_emu10k1_ptr_write(emu, TCB, 0, 0); /* taken from original driver */
224 snd_emu10k1_ptr_write(emu, TCBS, 0, 4); /* taken from original driver */
225
226 silent_page = (emu->silent_page.addr << 1) | MAP_PTI_MASK;
227 for (ch = 0; ch < NUM_G; ch++) {
228 snd_emu10k1_ptr_write(emu, MAPA, ch, silent_page);
229 snd_emu10k1_ptr_write(emu, MAPB, ch, silent_page);
230 }
231
232 /*
233 * Hokay, setup HCFG
234 * Mute Disable Audio = 0
235 * Lock Tank Memory = 1
236 * Lock Sound Memory = 0
237 * Auto Mute = 1
238 */
239 if (emu->audigy) {
240 if (emu->revision == 4) /* audigy2 */
241 outl(HCFG_AUDIOENABLE |
242 HCFG_AC3ENABLE_CDSPDIF |
243 HCFG_AC3ENABLE_GPSPDIF |
244 HCFG_AUTOMUTE | HCFG_JOYENABLE, emu->port + HCFG);
245 else
246 outl(HCFG_AUTOMUTE | HCFG_JOYENABLE, emu->port + HCFG);
James Courtier-Duttone0474e52005-07-02 16:33:34 +0200247 /* FIXME: Remove all these emu->model and replace it with a card recognition parameter,
248 * e.g. card_capabilities->joystick */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700249 } else if (emu->model == 0x20 ||
250 emu->model == 0xc400 ||
251 (emu->model == 0x21 && emu->revision < 6))
252 outl(HCFG_LOCKTANKCACHE_MASK | HCFG_AUTOMUTE, emu->port + HCFG);
253 else
254 // With on-chip joystick
255 outl(HCFG_LOCKTANKCACHE_MASK | HCFG_AUTOMUTE | HCFG_JOYENABLE, emu->port + HCFG);
256
257 if (enable_ir) { /* enable IR for SB Live */
James Courtier-Dutton19b99fb2005-12-04 18:03:03 +0100258 if ( emu->card_capabilities->emu1212m) {
259 ; /* Disable all access to A_IOCFG for the emu1212m */
260 } else if (emu->audigy) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700261 unsigned int reg = inl(emu->port + A_IOCFG);
262 outl(reg | A_IOCFG_GPOUT2, emu->port + A_IOCFG);
263 udelay(500);
264 outl(reg | A_IOCFG_GPOUT1 | A_IOCFG_GPOUT2, emu->port + A_IOCFG);
265 udelay(100);
266 outl(reg, emu->port + A_IOCFG);
267 } else {
268 unsigned int reg = inl(emu->port + HCFG);
269 outl(reg | HCFG_GPOUT2, emu->port + HCFG);
270 udelay(500);
271 outl(reg | HCFG_GPOUT1 | HCFG_GPOUT2, emu->port + HCFG);
272 udelay(100);
273 outl(reg, emu->port + HCFG);
274 }
275 }
276
James Courtier-Dutton19b99fb2005-12-04 18:03:03 +0100277 if ( emu->card_capabilities->emu1212m) {
278 ; /* Disable all access to A_IOCFG for the emu1212m */
279 } else if (emu->audigy) { /* enable analog output */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700280 unsigned int reg = inl(emu->port + A_IOCFG);
281 outl(reg | A_IOCFG_GPOUT0, emu->port + A_IOCFG);
282 }
283
Takashi Iwai09668b42005-11-17 16:14:10 +0100284 return 0;
285}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700286
Takashi Iwai09668b42005-11-17 16:14:10 +0100287static void snd_emu10k1_audio_enable(struct snd_emu10k1 *emu)
288{
Linus Torvalds1da177e2005-04-16 15:20:36 -0700289 /*
290 * Enable the audio bit
291 */
292 outl(inl(emu->port + HCFG) | HCFG_AUDIOENABLE, emu->port + HCFG);
293
294 /* Enable analog/digital outs on audigy */
James Courtier-Dutton19b99fb2005-12-04 18:03:03 +0100295 if ( emu->card_capabilities->emu1212m) {
296 ; /* Disable all access to A_IOCFG for the emu1212m */
297 } else if (emu->audigy) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700298 outl(inl(emu->port + A_IOCFG) & ~0x44, emu->port + A_IOCFG);
299
James Courtier-Duttone0474e52005-07-02 16:33:34 +0200300 if (emu->card_capabilities->ca0151_chip) { /* audigy2 */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700301 /* Unmute Analog now. Set GPO6 to 1 for Apollo.
302 * This has to be done after init ALice3 I2SOut beyond 48KHz.
303 * So, sequence is important. */
304 outl(inl(emu->port + A_IOCFG) | 0x0040, emu->port + A_IOCFG);
James Courtier-Duttone0474e52005-07-02 16:33:34 +0200305 } else if (emu->card_capabilities->ca0108_chip) { /* audigy2 value */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700306 /* Unmute Analog now. */
307 outl(inl(emu->port + A_IOCFG) | 0x0060, emu->port + A_IOCFG);
308 } else {
309 /* Disable routing from AC97 line out to Front speakers */
310 outl(inl(emu->port + A_IOCFG) | 0x0080, emu->port + A_IOCFG);
311 }
312 }
313
314#if 0
315 {
316 unsigned int tmp;
317 /* FIXME: the following routine disables LiveDrive-II !! */
318 // TOSLink detection
319 emu->tos_link = 0;
320 tmp = inl(emu->port + HCFG);
321 if (tmp & (HCFG_GPINPUT0 | HCFG_GPINPUT1)) {
322 outl(tmp|0x800, emu->port + HCFG);
323 udelay(50);
324 if (tmp != (inl(emu->port + HCFG) & ~0x800)) {
325 emu->tos_link = 1;
326 outl(tmp, emu->port + HCFG);
327 }
328 }
329 }
330#endif
331
332 snd_emu10k1_intr_enable(emu, INTE_PCIERRORENABLE);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700333}
334
Takashi Iwai09668b42005-11-17 16:14:10 +0100335int snd_emu10k1_done(struct snd_emu10k1 * emu)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700336{
337 int ch;
338
339 outl(0, emu->port + INTE);
340
341 /*
342 * Shutdown the chip
343 */
344 for (ch = 0; ch < NUM_G; ch++)
345 snd_emu10k1_ptr_write(emu, DCYSUSV, ch, 0);
346 for (ch = 0; ch < NUM_G; ch++) {
347 snd_emu10k1_ptr_write(emu, VTFT, ch, 0);
348 snd_emu10k1_ptr_write(emu, CVCF, ch, 0);
349 snd_emu10k1_ptr_write(emu, PTRX, ch, 0);
350 snd_emu10k1_ptr_write(emu, CPF, ch, 0);
351 }
352
353 /* reset recording buffers */
354 snd_emu10k1_ptr_write(emu, MICBS, 0, 0);
355 snd_emu10k1_ptr_write(emu, MICBA, 0, 0);
356 snd_emu10k1_ptr_write(emu, FXBS, 0, 0);
357 snd_emu10k1_ptr_write(emu, FXBA, 0, 0);
358 snd_emu10k1_ptr_write(emu, FXWC, 0, 0);
359 snd_emu10k1_ptr_write(emu, ADCBS, 0, ADCBS_BUFSIZE_NONE);
360 snd_emu10k1_ptr_write(emu, ADCBA, 0, 0);
361 snd_emu10k1_ptr_write(emu, TCBS, 0, TCBS_BUFFSIZE_16K);
362 snd_emu10k1_ptr_write(emu, TCB, 0, 0);
363 if (emu->audigy)
364 snd_emu10k1_ptr_write(emu, A_DBG, 0, A_DBG_SINGLE_STEP);
365 else
366 snd_emu10k1_ptr_write(emu, DBG, 0, EMU10K1_DBG_SINGLE_STEP);
367
368 /* disable channel interrupt */
369 snd_emu10k1_ptr_write(emu, CLIEL, 0, 0);
370 snd_emu10k1_ptr_write(emu, CLIEH, 0, 0);
371 snd_emu10k1_ptr_write(emu, SOLEL, 0, 0);
372 snd_emu10k1_ptr_write(emu, SOLEH, 0, 0);
373
Linus Torvalds1da177e2005-04-16 15:20:36 -0700374 /* disable audio and lock cache */
375 outl(HCFG_LOCKSOUNDCACHE | HCFG_LOCKTANKCACHE_MASK | HCFG_MUTEBUTTONENABLE, emu->port + HCFG);
376 snd_emu10k1_ptr_write(emu, PTB, 0, 0);
377
Linus Torvalds1da177e2005-04-16 15:20:36 -0700378 return 0;
379}
380
381/*************************************************************************
382 * ECARD functional implementation
383 *************************************************************************/
384
385/* In A1 Silicon, these bits are in the HC register */
386#define HOOKN_BIT (1L << 12)
387#define HANDN_BIT (1L << 11)
388#define PULSEN_BIT (1L << 10)
389
390#define EC_GDI1 (1 << 13)
391#define EC_GDI0 (1 << 14)
392
393#define EC_NUM_CONTROL_BITS 20
394
395#define EC_AC3_DATA_SELN 0x0001L
396#define EC_EE_DATA_SEL 0x0002L
397#define EC_EE_CNTRL_SELN 0x0004L
398#define EC_EECLK 0x0008L
399#define EC_EECS 0x0010L
400#define EC_EESDO 0x0020L
401#define EC_TRIM_CSN 0x0040L
402#define EC_TRIM_SCLK 0x0080L
403#define EC_TRIM_SDATA 0x0100L
404#define EC_TRIM_MUTEN 0x0200L
405#define EC_ADCCAL 0x0400L
406#define EC_ADCRSTN 0x0800L
407#define EC_DACCAL 0x1000L
408#define EC_DACMUTEN 0x2000L
409#define EC_LEDN 0x4000L
410
411#define EC_SPDIF0_SEL_SHIFT 15
412#define EC_SPDIF1_SEL_SHIFT 17
413#define EC_SPDIF0_SEL_MASK (0x3L << EC_SPDIF0_SEL_SHIFT)
414#define EC_SPDIF1_SEL_MASK (0x7L << EC_SPDIF1_SEL_SHIFT)
415#define EC_SPDIF0_SELECT(_x) (((_x) << EC_SPDIF0_SEL_SHIFT) & EC_SPDIF0_SEL_MASK)
416#define EC_SPDIF1_SELECT(_x) (((_x) << EC_SPDIF1_SEL_SHIFT) & EC_SPDIF1_SEL_MASK)
417#define EC_CURRENT_PROM_VERSION 0x01 /* Self-explanatory. This should
418 * be incremented any time the EEPROM's
419 * format is changed. */
420
421#define EC_EEPROM_SIZE 0x40 /* ECARD EEPROM has 64 16-bit words */
422
423/* Addresses for special values stored in to EEPROM */
424#define EC_PROM_VERSION_ADDR 0x20 /* Address of the current prom version */
425#define EC_BOARDREV0_ADDR 0x21 /* LSW of board rev */
426#define EC_BOARDREV1_ADDR 0x22 /* MSW of board rev */
427
428#define EC_LAST_PROMFILE_ADDR 0x2f
429
430#define EC_SERIALNUM_ADDR 0x30 /* First word of serial number. The
431 * can be up to 30 characters in length
432 * and is stored as a NULL-terminated
433 * ASCII string. Any unused bytes must be
434 * filled with zeros */
435#define EC_CHECKSUM_ADDR 0x3f /* Location at which checksum is stored */
436
437
438/* Most of this stuff is pretty self-evident. According to the hardware
439 * dudes, we need to leave the ADCCAL bit low in order to avoid a DC
440 * offset problem. Weird.
441 */
442#define EC_RAW_RUN_MODE (EC_DACMUTEN | EC_ADCRSTN | EC_TRIM_MUTEN | \
443 EC_TRIM_CSN)
444
445
446#define EC_DEFAULT_ADC_GAIN 0xC4C4
447#define EC_DEFAULT_SPDIF0_SEL 0x0
448#define EC_DEFAULT_SPDIF1_SEL 0x4
449
450/**************************************************************************
451 * @func Clock bits into the Ecard's control latch. The Ecard uses a
452 * control latch will is loaded bit-serially by toggling the Modem control
453 * lines from function 2 on the E8010. This function hides these details
454 * and presents the illusion that we are actually writing to a distinct
455 * register.
456 */
457
Takashi Iwaieb4698f2005-11-17 14:50:13 +0100458static void snd_emu10k1_ecard_write(struct snd_emu10k1 * emu, unsigned int value)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700459{
460 unsigned short count;
461 unsigned int data;
462 unsigned long hc_port;
463 unsigned int hc_value;
464
465 hc_port = emu->port + HCFG;
466 hc_value = inl(hc_port) & ~(HOOKN_BIT | HANDN_BIT | PULSEN_BIT);
467 outl(hc_value, hc_port);
468
469 for (count = 0; count < EC_NUM_CONTROL_BITS; count++) {
470
471 /* Set up the value */
472 data = ((value & 0x1) ? PULSEN_BIT : 0);
473 value >>= 1;
474
475 outl(hc_value | data, hc_port);
476
477 /* Clock the shift register */
478 outl(hc_value | data | HANDN_BIT, hc_port);
479 outl(hc_value | data, hc_port);
480 }
481
482 /* Latch the bits */
483 outl(hc_value | HOOKN_BIT, hc_port);
484 outl(hc_value, hc_port);
485}
486
487/**************************************************************************
488 * @func Set the gain of the ECARD's CS3310 Trim/gain controller. The
489 * trim value consists of a 16bit value which is composed of two
490 * 8 bit gain/trim values, one for the left channel and one for the
491 * right channel. The following table maps from the Gain/Attenuation
492 * value in decibels into the corresponding bit pattern for a single
493 * channel.
494 */
495
Takashi Iwaieb4698f2005-11-17 14:50:13 +0100496static void snd_emu10k1_ecard_setadcgain(struct snd_emu10k1 * emu,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700497 unsigned short gain)
498{
499 unsigned int bit;
500
501 /* Enable writing to the TRIM registers */
502 snd_emu10k1_ecard_write(emu, emu->ecard_ctrl & ~EC_TRIM_CSN);
503
504 /* Do it again to insure that we meet hold time requirements */
505 snd_emu10k1_ecard_write(emu, emu->ecard_ctrl & ~EC_TRIM_CSN);
506
507 for (bit = (1 << 15); bit; bit >>= 1) {
508 unsigned int value;
509
510 value = emu->ecard_ctrl & ~(EC_TRIM_CSN | EC_TRIM_SDATA);
511
512 if (gain & bit)
513 value |= EC_TRIM_SDATA;
514
515 /* Clock the bit */
516 snd_emu10k1_ecard_write(emu, value);
517 snd_emu10k1_ecard_write(emu, value | EC_TRIM_SCLK);
518 snd_emu10k1_ecard_write(emu, value);
519 }
520
521 snd_emu10k1_ecard_write(emu, emu->ecard_ctrl);
522}
523
Takashi Iwaieb4698f2005-11-17 14:50:13 +0100524static int __devinit snd_emu10k1_ecard_init(struct snd_emu10k1 * emu)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700525{
526 unsigned int hc_value;
527
528 /* Set up the initial settings */
529 emu->ecard_ctrl = EC_RAW_RUN_MODE |
530 EC_SPDIF0_SELECT(EC_DEFAULT_SPDIF0_SEL) |
531 EC_SPDIF1_SELECT(EC_DEFAULT_SPDIF1_SEL);
532
533 /* Step 0: Set the codec type in the hardware control register
534 * and enable audio output */
535 hc_value = inl(emu->port + HCFG);
536 outl(hc_value | HCFG_AUDIOENABLE | HCFG_CODECFORMAT_I2S, emu->port + HCFG);
537 inl(emu->port + HCFG);
538
539 /* Step 1: Turn off the led and deassert TRIM_CS */
540 snd_emu10k1_ecard_write(emu, EC_ADCCAL | EC_LEDN | EC_TRIM_CSN);
541
542 /* Step 2: Calibrate the ADC and DAC */
543 snd_emu10k1_ecard_write(emu, EC_DACCAL | EC_LEDN | EC_TRIM_CSN);
544
545 /* Step 3: Wait for awhile; XXX We can't get away with this
546 * under a real operating system; we'll need to block and wait that
547 * way. */
548 snd_emu10k1_wait(emu, 48000);
549
550 /* Step 4: Switch off the DAC and ADC calibration. Note
551 * That ADC_CAL is actually an inverted signal, so we assert
552 * it here to stop calibration. */
553 snd_emu10k1_ecard_write(emu, EC_ADCCAL | EC_LEDN | EC_TRIM_CSN);
554
555 /* Step 4: Switch into run mode */
556 snd_emu10k1_ecard_write(emu, emu->ecard_ctrl);
557
558 /* Step 5: Set the analog input gain */
559 snd_emu10k1_ecard_setadcgain(emu, EC_DEFAULT_ADC_GAIN);
560
561 return 0;
562}
563
Takashi Iwaieb4698f2005-11-17 14:50:13 +0100564static int __devinit snd_emu10k1_cardbus_init(struct snd_emu10k1 * emu)
James Courtier-Duttond83c6712005-10-31 10:27:41 +0000565{
566 unsigned long special_port;
567 unsigned int value;
568
569 /* Special initialisation routine
570 * before the rest of the IO-Ports become active.
571 */
572 special_port = emu->port + 0x38;
573 value = inl(special_port);
574 outl(0x00d00000, special_port);
575 value = inl(special_port);
576 outl(0x00d00001, special_port);
577 value = inl(special_port);
578 outl(0x00d0005f, special_port);
579 value = inl(special_port);
580 outl(0x00d0007f, special_port);
581 value = inl(special_port);
582 outl(0x0090007f, special_port);
583 value = inl(special_port);
584
James Courtier-Duttone2b15f82005-11-11 23:39:05 +0100585 snd_emu10k1_ptr20_write(emu, TINA2_VOLUME, 0, 0xfefefefe); /* Defaults to 0x30303030 */
James Courtier-Duttond83c6712005-10-31 10:27:41 +0000586 return 0;
587}
588
James Courtier-Dutton19b99fb2005-12-04 18:03:03 +0100589static int snd_emu1212m_fpga_write(struct snd_emu10k1 * emu, int reg, int value)
590{
591 if (reg<0 || reg>0x3f)
592 return 1;
593 reg+=0x40; /* 0x40 upwards are registers. */
594 if (value<0 || value>0x3f) /* 0 to 0x3f are values */
595 return 1;
596 outl(reg, emu->port + A_IOCFG);
597 outl(reg | 0x80, emu->port + A_IOCFG); /* High bit clocks the value into the fpga. */
598 outl(value, emu->port + A_IOCFG);
599 outl(value | 0x80 , emu->port + A_IOCFG); /* High bit clocks the value into the fpga. */
600
601 return 0;
602}
603
604static int snd_emu1212m_fpga_read(struct snd_emu10k1 * emu, int reg, int *value)
605{
606 if (reg<0 || reg>0x3f)
607 return 1;
608 reg+=0x40; /* 0x40 upwards are registers. */
609 outl(reg, emu->port + A_IOCFG);
610 outl(reg | 0x80, emu->port + A_IOCFG); /* High bit clocks the value into the fpga. */
611 *value = inl(emu->port + A_IOCFG);
612
613 return 0;
614}
615
616static int snd_emu1212m_fpga_netlist_write(struct snd_emu10k1 * emu, int reg, int value)
617{
618 snd_emu1212m_fpga_write(emu, 0x00, ((reg >> 8) & 0x3f) );
619 snd_emu1212m_fpga_write(emu, 0x01, (reg & 0x3f) );
620 snd_emu1212m_fpga_write(emu, 0x02, ((value >> 8) & 0x3f) );
621 snd_emu1212m_fpga_write(emu, 0x03, (value & 0x3f) );
622
623 return 0;
624}
625
626static int __devinit snd_emu10k1_emu1212m_init(struct snd_emu10k1 * emu)
627{
628 unsigned int i;
629 int tmp;
630
631 snd_printk(KERN_ERR "emu1212m: Special config.\n");
632 outl(0x0005a00c, emu->port + HCFG);
633 outl(0x0005a004, emu->port + HCFG);
634 outl(0x0005a000, emu->port + HCFG);
635 outl(0x0005a000, emu->port + HCFG);
636
637 snd_emu1212m_fpga_read(emu, 0x22, &tmp );
638 snd_emu1212m_fpga_read(emu, 0x23, &tmp );
639 snd_emu1212m_fpga_read(emu, 0x24, &tmp );
640 snd_emu1212m_fpga_write(emu, 0x04, 0x01 );
641 snd_emu1212m_fpga_read(emu, 0x0b, &tmp );
642 snd_emu1212m_fpga_write(emu, 0x0b, 0x01 );
643 snd_emu1212m_fpga_read(emu, 0x10, &tmp );
644 snd_emu1212m_fpga_write(emu, 0x10, 0x00 );
645 snd_emu1212m_fpga_read(emu, 0x11, &tmp );
646 snd_emu1212m_fpga_write(emu, 0x11, 0x30 );
647 snd_emu1212m_fpga_read(emu, 0x13, &tmp );
648 snd_emu1212m_fpga_write(emu, 0x13, 0x0f );
649 snd_emu1212m_fpga_read(emu, 0x11, &tmp );
650 snd_emu1212m_fpga_write(emu, 0x11, 0x30 );
651 snd_emu1212m_fpga_read(emu, 0x0a, &tmp );
652 snd_emu1212m_fpga_write(emu, 0x0a, 0x10 );
653 snd_emu1212m_fpga_write(emu, 0x0c, 0x19 );
654 snd_emu1212m_fpga_write(emu, 0x12, 0x0c );
655 snd_emu1212m_fpga_write(emu, 0x09, 0x0f );
656 snd_emu1212m_fpga_write(emu, 0x06, 0x00 );
657 snd_emu1212m_fpga_write(emu, 0x05, 0x00 );
658 snd_emu1212m_fpga_write(emu, 0x0e, 0x12 );
659 snd_emu1212m_fpga_netlist_write(emu, 0x0000, 0x0200);
660 snd_emu1212m_fpga_netlist_write(emu, 0x0001, 0x0201);
661 snd_emu1212m_fpga_netlist_write(emu, 0x0002, 0x0500);
662 snd_emu1212m_fpga_netlist_write(emu, 0x0003, 0x0501);
663 snd_emu1212m_fpga_netlist_write(emu, 0x0004, 0x0400);
664 snd_emu1212m_fpga_netlist_write(emu, 0x0005, 0x0401);
665 snd_emu1212m_fpga_netlist_write(emu, 0x0006, 0x0402);
666 snd_emu1212m_fpga_netlist_write(emu, 0x0007, 0x0403);
667 snd_emu1212m_fpga_netlist_write(emu, 0x0008, 0x0404);
668 snd_emu1212m_fpga_netlist_write(emu, 0x0009, 0x0405);
669 snd_emu1212m_fpga_netlist_write(emu, 0x000a, 0x0406);
670 snd_emu1212m_fpga_netlist_write(emu, 0x000b, 0x0407);
671 snd_emu1212m_fpga_netlist_write(emu, 0x000c, 0x0100);
672 snd_emu1212m_fpga_netlist_write(emu, 0x000d, 0x0104);
673 snd_emu1212m_fpga_netlist_write(emu, 0x000e, 0x0200);
674 snd_emu1212m_fpga_netlist_write(emu, 0x000f, 0x0201);
675 for (i=0;i < 0x20;i++) {
676 snd_emu1212m_fpga_netlist_write(emu, 0x0100+i, 0x0000);
677 }
678 for (i=0;i < 4;i++) {
679 snd_emu1212m_fpga_netlist_write(emu, 0x0200+i, 0x0000);
680 }
681 for (i=0;i < 7;i++) {
682 snd_emu1212m_fpga_netlist_write(emu, 0x0300+i, 0x0000);
683 }
684 for (i=0;i < 7;i++) {
685 snd_emu1212m_fpga_netlist_write(emu, 0x0400+i, 0x0000);
686 }
687 snd_emu1212m_fpga_netlist_write(emu, 0x0500, 0x0108);
688 snd_emu1212m_fpga_netlist_write(emu, 0x0501, 0x010c);
689 snd_emu1212m_fpga_netlist_write(emu, 0x0600, 0x0110);
690 snd_emu1212m_fpga_netlist_write(emu, 0x0601, 0x0114);
691 snd_emu1212m_fpga_netlist_write(emu, 0x0700, 0x0118);
692 snd_emu1212m_fpga_netlist_write(emu, 0x0701, 0x011c);
693 snd_emu1212m_fpga_write(emu, 0x07, 0x01 );
694
695 snd_emu1212m_fpga_read(emu, 0x21, &tmp );
696
697 outl(0x0000a000, emu->port + HCFG);
698 outl(0x0000a001, emu->port + HCFG);
699 /* Initial boot complete. Now patches */
700
701 snd_emu1212m_fpga_read(emu, 0x21, &tmp );
702 snd_emu1212m_fpga_write(emu, 0x0c, 0x19 );
703 snd_emu1212m_fpga_write(emu, 0x12, 0x0c );
704 snd_emu1212m_fpga_write(emu, 0x0c, 0x19 );
705 snd_emu1212m_fpga_write(emu, 0x12, 0x0c );
706 snd_emu1212m_fpga_read(emu, 0x0a, &tmp );
707 snd_emu1212m_fpga_write(emu, 0x0a, 0x10 );
708
709 snd_emu1212m_fpga_read(emu, 0x20, &tmp );
710 snd_emu1212m_fpga_read(emu, 0x21, &tmp );
711
712 snd_emu1212m_fpga_netlist_write(emu, 0x0300, 0x0312);
713 snd_emu1212m_fpga_netlist_write(emu, 0x0301, 0x0313);
714 snd_emu1212m_fpga_netlist_write(emu, 0x0200, 0x0302);
715 snd_emu1212m_fpga_netlist_write(emu, 0x0201, 0x0303);
716
717 return 0;
718}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700719/*
720 * Create the EMU10K1 instance
721 */
722
Takashi Iwai09668b42005-11-17 16:14:10 +0100723#ifdef CONFIG_PM
724static int alloc_pm_buffer(struct snd_emu10k1 *emu);
725static void free_pm_buffer(struct snd_emu10k1 *emu);
726#endif
727
Takashi Iwaieb4698f2005-11-17 14:50:13 +0100728static int snd_emu10k1_free(struct snd_emu10k1 *emu)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700729{
730 if (emu->port) { /* avoid access to already used hardware */
731 snd_emu10k1_fx8010_tram_setup(emu, 0);
732 snd_emu10k1_done(emu);
Takashi Iwai09668b42005-11-17 16:14:10 +0100733 /* remove reserved page */
734 if (emu->reserved_page) {
735 snd_emu10k1_synth_free(emu, (struct snd_util_memblk *)emu->reserved_page);
736 emu->reserved_page = NULL;
737 }
738 snd_emu10k1_free_efx(emu);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700739 }
740 if (emu->memhdr)
741 snd_util_memhdr_free(emu->memhdr);
742 if (emu->silent_page.area)
743 snd_dma_free_pages(&emu->silent_page);
744 if (emu->ptb_pages.area)
745 snd_dma_free_pages(&emu->ptb_pages);
746 vfree(emu->page_ptr_table);
747 vfree(emu->page_addr_table);
Takashi Iwai09668b42005-11-17 16:14:10 +0100748#ifdef CONFIG_PM
749 free_pm_buffer(emu);
750#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700751 if (emu->irq >= 0)
752 free_irq(emu->irq, (void *)emu);
753 if (emu->port)
754 pci_release_regions(emu->pci);
Lee Revell2b637da2005-03-30 13:51:18 +0200755 if (emu->card_capabilities->ca0151_chip) /* P16V */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700756 snd_p16v_free(emu);
Takashi Iwai09668b42005-11-17 16:14:10 +0100757 pci_disable_device(emu->pci);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700758 kfree(emu);
759 return 0;
760}
761
Takashi Iwaieb4698f2005-11-17 14:50:13 +0100762static int snd_emu10k1_dev_free(struct snd_device *device)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700763{
Takashi Iwaieb4698f2005-11-17 14:50:13 +0100764 struct snd_emu10k1 *emu = device->device_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700765 return snd_emu10k1_free(emu);
766}
767
Takashi Iwaieb4698f2005-11-17 14:50:13 +0100768static struct snd_emu_chip_details emu_chip_details[] = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700769 /* Audigy 2 Value AC3 out does not work yet. Need to find out how to turn off interpolators.*/
James Courtier-Dutton88dc0e52005-07-03 12:54:29 +0200770 /* Tested by James@superbug.co.uk 3rd July 2005 */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700771 {.vendor = 0x1102, .device = 0x0008, .subsystem = 0x10011102,
772 .driver = "Audigy2", .name = "Audigy 2 Value [SB0400]",
Takashi Iwaiaec72e02005-03-30 14:22:25 +0200773 .id = "Audigy2",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700774 .emu10k2_chip = 1,
775 .ca0108_chip = 1,
Peter Zubaj26689072005-04-01 11:15:07 +0200776 .spk71 = 1,
777 .ac97_chip = 1} ,
James Courtier-Duttond83c6712005-10-31 10:27:41 +0000778 /* Audigy 2 ZS Notebook Cardbus card.*/
779 /* Tested by James@superbug.co.uk 30th October 2005 */
780 /* Not working yet, but progressing. */
781 {.vendor = 0x1102, .device = 0x0008, .subsystem = 0x20011102,
782 .driver = "Audigy2", .name = "Audigy 2 ZS Notebook [SB0530]",
783 .id = "Audigy2",
784 .emu10k2_chip = 1,
785 .ca0108_chip = 1,
786 .ca_cardbus_chip = 1,
James Courtier-Dutton27fe8642005-12-21 15:06:08 +0100787 .spi_dac = 1,
James Courtier-Duttond83c6712005-10-31 10:27:41 +0000788 .spk71 = 1} ,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700789 {.vendor = 0x1102, .device = 0x0008,
790 .driver = "Audigy2", .name = "Audigy 2 Value [Unknown]",
Takashi Iwaiaec72e02005-03-30 14:22:25 +0200791 .id = "Audigy2",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700792 .emu10k2_chip = 1,
Peter Zubaj26689072005-04-01 11:15:07 +0200793 .ca0108_chip = 1,
794 .ac97_chip = 1} ,
James Courtier-Dutton7c1d5492005-07-10 11:50:36 +0200795 /* Tested by James@superbug.co.uk 8th July 2005. No sound available yet. */
796 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x40011102,
797 .driver = "Audigy2", .name = "E-mu 1212m [4001]",
798 .id = "EMU1212m",
799 .emu10k2_chip = 1,
800 .ca0102_chip = 1,
James Courtier-Dutton19b99fb2005-12-04 18:03:03 +0100801 .emu1212m = 1} ,
James Courtier-Dutton88dc0e52005-07-03 12:54:29 +0200802 /* Tested by James@superbug.co.uk 3rd July 2005 */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700803 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x20071102,
804 .driver = "Audigy2", .name = "Audigy 4 PRO [SB0380]",
Takashi Iwaiaec72e02005-03-30 14:22:25 +0200805 .id = "Audigy2",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700806 .emu10k2_chip = 1,
807 .ca0102_chip = 1,
808 .ca0151_chip = 1,
809 .spk71 = 1,
810 .spdif_bug = 1,
811 .ac97_chip = 1} ,
Lee Revellf6f8bb62005-11-07 14:59:19 +0100812 /* Tested by shane-alsa@cm.nu 5th Nov 2005 */
813 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x20061102,
814 .driver = "Audigy2", .name = "Audigy 2 [2006]",
815 .id = "Audigy2",
816 .emu10k2_chip = 1,
817 .ca0102_chip = 1,
818 .ca0151_chip = 1,
819 .spk71 = 1,
820 .spdif_bug = 1,
821 .ac97_chip = 1} ,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700822 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x20021102,
823 .driver = "Audigy2", .name = "Audigy 2 ZS [SB0350]",
Takashi Iwaiaec72e02005-03-30 14:22:25 +0200824 .id = "Audigy2",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700825 .emu10k2_chip = 1,
826 .ca0102_chip = 1,
827 .ca0151_chip = 1,
828 .spk71 = 1,
829 .spdif_bug = 1,
830 .ac97_chip = 1} ,
831 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x20011102,
832 .driver = "Audigy2", .name = "Audigy 2 ZS [2001]",
Takashi Iwaiaec72e02005-03-30 14:22:25 +0200833 .id = "Audigy2",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700834 .emu10k2_chip = 1,
835 .ca0102_chip = 1,
836 .ca0151_chip = 1,
837 .spk71 = 1,
838 .spdif_bug = 1,
839 .ac97_chip = 1} ,
840 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x10071102,
841 .driver = "Audigy2", .name = "Audigy 2 [SB0240]",
Takashi Iwaiaec72e02005-03-30 14:22:25 +0200842 .id = "Audigy2",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700843 .emu10k2_chip = 1,
844 .ca0102_chip = 1,
845 .ca0151_chip = 1,
846 .spk71 = 1,
847 .spdif_bug = 1,
848 .ac97_chip = 1} ,
849 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x10051102,
850 .driver = "Audigy2", .name = "Audigy 2 EX [1005]",
Takashi Iwaiaec72e02005-03-30 14:22:25 +0200851 .id = "Audigy2",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700852 .emu10k2_chip = 1,
853 .ca0102_chip = 1,
854 .ca0151_chip = 1,
Lee Revell2f020aa2005-11-07 14:54:24 +0100855 .spk71 = 1,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700856 .spdif_bug = 1} ,
857 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x10021102,
858 .driver = "Audigy2", .name = "Audigy 2 Platinum [SB0240P]",
Takashi Iwaiaec72e02005-03-30 14:22:25 +0200859 .id = "Audigy2",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700860 .emu10k2_chip = 1,
861 .ca0102_chip = 1,
862 .ca0151_chip = 1,
863 .spk71 = 1,
864 .spdif_bug = 1,
865 .ac97_chip = 1} ,
Takashi Iwaibdaed502005-04-07 15:48:42 +0200866 {.vendor = 0x1102, .device = 0x0004, .revision = 0x04,
867 .driver = "Audigy2", .name = "Audigy 2 [Unknown]",
868 .id = "Audigy2",
869 .emu10k2_chip = 1,
870 .ca0102_chip = 1,
871 .ca0151_chip = 1,
872 .spdif_bug = 1,
873 .ac97_chip = 1} ,
Peter Zubaj26689072005-04-01 11:15:07 +0200874 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x00531102,
875 .driver = "Audigy", .name = "Audigy 1 [SB0090]",
876 .id = "Audigy",
877 .emu10k2_chip = 1,
878 .ca0102_chip = 1,
879 .ac97_chip = 1} ,
James Courtier-Duttonae3a72d2005-07-06 22:36:18 +0200880 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x00521102,
881 .driver = "Audigy", .name = "Audigy 1 ES [SB0160]",
882 .id = "Audigy",
883 .emu10k2_chip = 1,
884 .ca0102_chip = 1,
885 .spdif_bug = 1,
886 .ac97_chip = 1} ,
Arnaud Patarda6c17ec2005-05-27 12:31:34 +0200887 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x00511102,
888 .driver = "Audigy", .name = "Audigy 1 [SB0090]",
889 .id = "Audigy",
890 .emu10k2_chip = 1,
891 .ca0102_chip = 1,
892 .ac97_chip = 1} ,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700893 {.vendor = 0x1102, .device = 0x0004,
Takashi Iwaibdaed502005-04-07 15:48:42 +0200894 .driver = "Audigy", .name = "Audigy 1 [Unknown]",
Takashi Iwaiaec72e02005-03-30 14:22:25 +0200895 .id = "Audigy",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700896 .emu10k2_chip = 1,
897 .ca0102_chip = 1,
Peter Zubaj26689072005-04-01 11:15:07 +0200898 .ac97_chip = 1} ,
James Courtier-Duttona6f61922005-07-03 12:32:40 +0200899 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x806B1102,
900 .driver = "EMU10K1", .name = "SBLive! [SB0105]",
James Courtier-Dutton2b6b22f2005-06-18 13:50:22 +0200901 .id = "Live",
902 .emu10k1_chip = 1,
903 .ac97_chip = 1,
904 .sblive51 = 1} ,
905 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x806A1102,
906 .driver = "EMU10K1", .name = "SBLive! Value [SB0103]",
907 .id = "Live",
908 .emu10k1_chip = 1,
909 .ac97_chip = 1,
910 .sblive51 = 1} ,
James Courtier-Duttona6f61922005-07-03 12:32:40 +0200911 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80691102,
912 .driver = "EMU10K1", .name = "SBLive! Value [SB0101]",
913 .id = "Live",
914 .emu10k1_chip = 1,
915 .ac97_chip = 1,
916 .sblive51 = 1} ,
Lee Revellc6c0b842005-08-29 17:42:00 +0200917 /* Tested by Thomas Zehetbauer 27th Aug 2005 */
918 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80651102,
919 .driver = "EMU10K1", .name = "SB Live 5.1 [SB0220]",
920 .id = "Live",
921 .emu10k1_chip = 1,
922 .ac97_chip = 1,
923 .sblive51 = 1} ,
Gergely Tamasa8ee7292005-12-06 14:10:57 +0100924 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x100a1102,
925 .driver = "EMU10K1", .name = "SB Live 5.1 [SB0220]",
926 .id = "Live",
927 .emu10k1_chip = 1,
928 .ac97_chip = 1,
929 .sblive51 = 1} ,
James Courtier-Duttona6f61922005-07-03 12:32:40 +0200930 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80641102,
931 .driver = "EMU10K1", .name = "SB Live 5.1",
932 .id = "Live",
933 .emu10k1_chip = 1,
934 .ac97_chip = 1,
935 .sblive51 = 1} ,
James Courtier-Duttonafe0f1f2005-09-10 10:24:10 +0200936 /* Tested by alsa bugtrack user "hus" bug #1297 12th Aug 2005 */
James Courtier-Duttona6f61922005-07-03 12:32:40 +0200937 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80611102,
Takashi Iwaif12aa402005-09-30 16:56:59 +0200938 .driver = "EMU10K1", .name = "SBLive 5.1 [SB0060]",
James Courtier-Duttona6f61922005-07-03 12:32:40 +0200939 .id = "Live",
940 .emu10k1_chip = 1,
Takashi Iwaif12aa402005-09-30 16:56:59 +0200941 .ac97_chip = 2, /* ac97 is optional; both SBLive 5.1 and platinum
942 * share the same IDs!
943 */
James Courtier-Duttona6f61922005-07-03 12:32:40 +0200944 .sblive51 = 1} ,
945 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80511102,
946 .driver = "EMU10K1", .name = "SBLive! Value [CT4850]",
947 .id = "Live",
948 .emu10k1_chip = 1,
949 .ac97_chip = 1,
950 .sblive51 = 1} ,
951 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80401102,
952 .driver = "EMU10K1", .name = "SBLive! Platinum [CT4760P]",
953 .id = "Live",
954 .emu10k1_chip = 1,
955 .ac97_chip = 1} ,
956 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80321102,
957 .driver = "EMU10K1", .name = "SBLive! Value [CT4871]",
958 .id = "Live",
959 .emu10k1_chip = 1,
960 .ac97_chip = 1,
961 .sblive51 = 1} ,
962 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80311102,
963 .driver = "EMU10K1", .name = "SBLive! Value [CT4831]",
964 .id = "Live",
965 .emu10k1_chip = 1,
966 .ac97_chip = 1,
967 .sblive51 = 1} ,
968 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80281102,
969 .driver = "EMU10K1", .name = "SBLive! Value [CT4870]",
970 .id = "Live",
971 .emu10k1_chip = 1,
972 .ac97_chip = 1,
973 .sblive51 = 1} ,
James Courtier-Dutton88dc0e52005-07-03 12:54:29 +0200974 /* Tested by James@superbug.co.uk 3rd July 2005 */
James Courtier-Duttona6f61922005-07-03 12:32:40 +0200975 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80271102,
976 .driver = "EMU10K1", .name = "SBLive! Value [CT4832]",
977 .id = "Live",
978 .emu10k1_chip = 1,
979 .ac97_chip = 1,
980 .sblive51 = 1} ,
981 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80261102,
982 .driver = "EMU10K1", .name = "SBLive! Value [CT4830]",
983 .id = "Live",
984 .emu10k1_chip = 1,
985 .ac97_chip = 1,
986 .sblive51 = 1} ,
987 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80231102,
988 .driver = "EMU10K1", .name = "SB PCI512 [CT4790]",
989 .id = "Live",
990 .emu10k1_chip = 1,
991 .ac97_chip = 1,
992 .sblive51 = 1} ,
993 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80221102,
994 .driver = "EMU10K1", .name = "SBLive! Value [CT4780]",
995 .id = "Live",
996 .emu10k1_chip = 1,
997 .ac97_chip = 1,
998 .sblive51 = 1} ,
999 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x40011102,
1000 .driver = "EMU10K1", .name = "E-mu APS [4001]",
1001 .id = "APS",
1002 .emu10k1_chip = 1,
1003 .ecard = 1} ,
1004 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x00211102,
1005 .driver = "EMU10K1", .name = "SBLive! [CT4620]",
1006 .id = "Live",
1007 .emu10k1_chip = 1,
1008 .ac97_chip = 1,
1009 .sblive51 = 1} ,
1010 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x00201102,
1011 .driver = "EMU10K1", .name = "SBLive! Value [CT4670]",
James Courtier-Dutton2b6b22f2005-06-18 13:50:22 +02001012 .id = "Live",
1013 .emu10k1_chip = 1,
1014 .ac97_chip = 1,
1015 .sblive51 = 1} ,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001016 {.vendor = 0x1102, .device = 0x0002,
1017 .driver = "EMU10K1", .name = "SB Live [Unknown]",
Takashi Iwaiaec72e02005-03-30 14:22:25 +02001018 .id = "Live",
Linus Torvalds1da177e2005-04-16 15:20:36 -07001019 .emu10k1_chip = 1,
Lee Revell2b637da2005-03-30 13:51:18 +02001020 .ac97_chip = 1,
1021 .sblive51 = 1} ,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001022 { } /* terminator */
1023};
1024
Takashi Iwaieb4698f2005-11-17 14:50:13 +01001025int __devinit snd_emu10k1_create(struct snd_card *card,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001026 struct pci_dev * pci,
1027 unsigned short extin_mask,
1028 unsigned short extout_mask,
1029 long max_cache_bytes,
1030 int enable_ir,
James Courtier-Duttone66bc8b2005-07-06 22:21:51 +02001031 uint subsystem,
Takashi Iwaieb4698f2005-11-17 14:50:13 +01001032 struct snd_emu10k1 ** remu)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001033{
Takashi Iwaieb4698f2005-11-17 14:50:13 +01001034 struct snd_emu10k1 *emu;
Takashi Iwai09668b42005-11-17 16:14:10 +01001035 int idx, err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001036 int is_audigy;
1037 unsigned char revision;
Takashi Iwai09668b42005-11-17 16:14:10 +01001038 unsigned int silent_page;
Takashi Iwaieb4698f2005-11-17 14:50:13 +01001039 const struct snd_emu_chip_details *c;
1040 static struct snd_device_ops ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001041 .dev_free = snd_emu10k1_dev_free,
1042 };
1043
1044 *remu = NULL;
1045
1046 /* enable PCI device */
1047 if ((err = pci_enable_device(pci)) < 0)
1048 return err;
1049
Takashi Iwaie560d8d2005-09-09 14:21:46 +02001050 emu = kzalloc(sizeof(*emu), GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001051 if (emu == NULL) {
1052 pci_disable_device(pci);
1053 return -ENOMEM;
1054 }
1055 emu->card = card;
1056 spin_lock_init(&emu->reg_lock);
1057 spin_lock_init(&emu->emu_lock);
1058 spin_lock_init(&emu->voice_lock);
1059 spin_lock_init(&emu->synth_lock);
1060 spin_lock_init(&emu->memblk_lock);
1061 init_MUTEX(&emu->ptb_lock);
1062 init_MUTEX(&emu->fx8010.lock);
1063 INIT_LIST_HEAD(&emu->mapped_link_head);
1064 INIT_LIST_HEAD(&emu->mapped_order_link_head);
1065 emu->pci = pci;
1066 emu->irq = -1;
1067 emu->synth = NULL;
1068 emu->get_synth_voice = NULL;
1069 /* read revision & serial */
1070 pci_read_config_byte(pci, PCI_REVISION_ID, &revision);
1071 emu->revision = revision;
1072 pci_read_config_dword(pci, PCI_SUBSYSTEM_VENDOR_ID, &emu->serial);
1073 pci_read_config_word(pci, PCI_SUBSYSTEM_ID, &emu->model);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001074 snd_printdd("vendor=0x%x, device=0x%x, subsystem_vendor_id=0x%x, subsystem_id=0x%x\n",pci->vendor, pci->device, emu->serial, emu->model);
1075
1076 for (c = emu_chip_details; c->vendor; c++) {
1077 if (c->vendor == pci->vendor && c->device == pci->device) {
James Courtier-Duttone66bc8b2005-07-06 22:21:51 +02001078 if (subsystem) {
1079 if (c->subsystem && (c->subsystem == subsystem) ) {
1080 break;
1081 } else continue;
1082 } else {
1083 if (c->subsystem && (c->subsystem != emu->serial) )
1084 continue;
1085 if (c->revision && c->revision != emu->revision)
1086 continue;
1087 }
Takashi Iwaibdaed502005-04-07 15:48:42 +02001088 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001089 }
1090 }
1091 if (c->vendor == 0) {
1092 snd_printk(KERN_ERR "emu10k1: Card not recognised\n");
1093 kfree(emu);
1094 pci_disable_device(pci);
1095 return -ENOENT;
1096 }
1097 emu->card_capabilities = c;
James Courtier-Duttone66bc8b2005-07-06 22:21:51 +02001098 if (c->subsystem && !subsystem)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001099 snd_printdd("Sound card name=%s\n", c->name);
James Courtier-Duttone66bc8b2005-07-06 22:21:51 +02001100 else if (subsystem)
1101 snd_printdd("Sound card name=%s, vendor=0x%x, device=0x%x, subsystem=0x%x. Forced to subsytem=0x%x\n",
1102 c->name, pci->vendor, pci->device, emu->serial, c->subsystem);
1103 else
1104 snd_printdd("Sound card name=%s, vendor=0x%x, device=0x%x, subsystem=0x%x.\n",
1105 c->name, pci->vendor, pci->device, emu->serial);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001106
Takashi Iwai85a655d2005-03-30 14:40:25 +02001107 if (!*card->id && c->id) {
1108 int i, n = 0;
Takashi Iwaiaec72e02005-03-30 14:22:25 +02001109 strlcpy(card->id, c->id, sizeof(card->id));
Takashi Iwai85a655d2005-03-30 14:40:25 +02001110 for (;;) {
1111 for (i = 0; i < snd_ecards_limit; i++) {
1112 if (snd_cards[i] && !strcmp(snd_cards[i]->id, card->id))
1113 break;
1114 }
1115 if (i >= snd_ecards_limit)
1116 break;
1117 n++;
1118 if (n >= SNDRV_CARDS)
1119 break;
1120 snprintf(card->id, sizeof(card->id), "%s_%d", c->id, n);
1121 }
1122 }
Takashi Iwaiaec72e02005-03-30 14:22:25 +02001123
Linus Torvalds1da177e2005-04-16 15:20:36 -07001124 is_audigy = emu->audigy = c->emu10k2_chip;
1125
1126 /* set the DMA transfer mask */
1127 emu->dma_mask = is_audigy ? AUDIGY_DMA_MASK : EMU10K1_DMA_MASK;
1128 if (pci_set_dma_mask(pci, emu->dma_mask) < 0 ||
1129 pci_set_consistent_dma_mask(pci, emu->dma_mask) < 0) {
1130 snd_printk(KERN_ERR "architecture does not support PCI busmaster DMA with mask 0x%lx\n", emu->dma_mask);
1131 kfree(emu);
1132 pci_disable_device(pci);
1133 return -ENXIO;
1134 }
1135 if (is_audigy)
1136 emu->gpr_base = A_FXGPREGBASE;
1137 else
1138 emu->gpr_base = FXGPREGBASE;
1139
1140 if ((err = pci_request_regions(pci, "EMU10K1")) < 0) {
1141 kfree(emu);
1142 pci_disable_device(pci);
1143 return err;
1144 }
1145 emu->port = pci_resource_start(pci, 0);
1146
1147 if (request_irq(pci->irq, snd_emu10k1_interrupt, SA_INTERRUPT|SA_SHIRQ, "EMU10K1", (void *)emu)) {
Takashi Iwai09668b42005-11-17 16:14:10 +01001148 err = -EBUSY;
1149 goto error;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001150 }
1151 emu->irq = pci->irq;
1152
1153 emu->max_cache_pages = max_cache_bytes >> PAGE_SHIFT;
1154 if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(pci),
1155 32 * 1024, &emu->ptb_pages) < 0) {
Takashi Iwai09668b42005-11-17 16:14:10 +01001156 err = -ENOMEM;
1157 goto error;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001158 }
1159
1160 emu->page_ptr_table = (void **)vmalloc(emu->max_cache_pages * sizeof(void*));
1161 emu->page_addr_table = (unsigned long*)vmalloc(emu->max_cache_pages * sizeof(unsigned long));
1162 if (emu->page_ptr_table == NULL || emu->page_addr_table == NULL) {
Takashi Iwai09668b42005-11-17 16:14:10 +01001163 err = -ENOMEM;
1164 goto error;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001165 }
1166
1167 if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(pci),
1168 EMUPAGESIZE, &emu->silent_page) < 0) {
Takashi Iwai09668b42005-11-17 16:14:10 +01001169 err = -ENOMEM;
1170 goto error;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001171 }
1172 emu->memhdr = snd_util_memhdr_new(emu->max_cache_pages * PAGE_SIZE);
1173 if (emu->memhdr == NULL) {
Takashi Iwai09668b42005-11-17 16:14:10 +01001174 err = -ENOMEM;
1175 goto error;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001176 }
Takashi Iwaieb4698f2005-11-17 14:50:13 +01001177 emu->memhdr->block_extra_size = sizeof(struct snd_emu10k1_memblk) -
1178 sizeof(struct snd_util_memblk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001179
1180 pci_set_master(pci);
1181
Linus Torvalds1da177e2005-04-16 15:20:36 -07001182 emu->fx8010.fxbus_mask = 0x303f;
1183 if (extin_mask == 0)
1184 extin_mask = 0x3fcf;
1185 if (extout_mask == 0)
1186 extout_mask = 0x7fff;
1187 emu->fx8010.extin_mask = extin_mask;
1188 emu->fx8010.extout_mask = extout_mask;
Takashi Iwai09668b42005-11-17 16:14:10 +01001189 emu->enable_ir = enable_ir;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001190
Lee Revell2b637da2005-03-30 13:51:18 +02001191 if (emu->card_capabilities->ecard) {
Takashi Iwai09668b42005-11-17 16:14:10 +01001192 if ((err = snd_emu10k1_ecard_init(emu)) < 0)
1193 goto error;
James Courtier-Duttond83c6712005-10-31 10:27:41 +00001194 } else if (emu->card_capabilities->ca_cardbus_chip) {
Takashi Iwai09668b42005-11-17 16:14:10 +01001195 if ((err = snd_emu10k1_cardbus_init(emu)) < 0)
1196 goto error;
James Courtier-Dutton19b99fb2005-12-04 18:03:03 +01001197 } else if (emu->card_capabilities->emu1212m) {
1198 if ((err = snd_emu10k1_emu1212m_init(emu)) < 0) {
1199 snd_emu10k1_free(emu);
1200 return err;
1201 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001202 } else {
1203 /* 5.1: Enable the additional AC97 Slots. If the emu10k1 version
1204 does not support this, it shouldn't do any harm */
1205 snd_emu10k1_ptr_write(emu, AC97SLOT, 0, AC97SLOT_CNTR|AC97SLOT_LFE);
1206 }
1207
Takashi Iwai09668b42005-11-17 16:14:10 +01001208 /* initialize TRAM setup */
1209 emu->fx8010.itram_size = (16 * 1024)/2;
1210 emu->fx8010.etram_pages.area = NULL;
1211 emu->fx8010.etram_pages.bytes = 0;
1212
1213 /*
1214 * Init to 0x02109204 :
1215 * Clock accuracy = 0 (1000ppm)
1216 * Sample Rate = 2 (48kHz)
1217 * Audio Channel = 1 (Left of 2)
1218 * Source Number = 0 (Unspecified)
1219 * Generation Status = 1 (Original for Cat Code 12)
1220 * Cat Code = 12 (Digital Signal Mixer)
1221 * Mode = 0 (Mode 0)
1222 * Emphasis = 0 (None)
1223 * CP = 1 (Copyright unasserted)
1224 * AN = 0 (Audio data)
1225 * P = 0 (Consumer)
1226 */
1227 emu->spdif_bits[0] = emu->spdif_bits[1] =
1228 emu->spdif_bits[2] = SPCS_CLKACCY_1000PPM | SPCS_SAMPLERATE_48 |
1229 SPCS_CHANNELNUM_LEFT | SPCS_SOURCENUM_UNSPEC |
1230 SPCS_GENERATIONSTATUS | 0x00001200 |
1231 0x00000000 | SPCS_EMPHASIS_NONE | SPCS_COPYRIGHT;
1232
1233 emu->reserved_page = (struct snd_emu10k1_memblk *)
1234 snd_emu10k1_synth_alloc(emu, 4096);
1235 if (emu->reserved_page)
1236 emu->reserved_page->map_locked = 1;
1237
1238 /* Clear silent pages and set up pointers */
1239 memset(emu->silent_page.area, 0, PAGE_SIZE);
1240 silent_page = emu->silent_page.addr << 1;
1241 for (idx = 0; idx < MAXPAGES; idx++)
1242 ((u32 *)emu->ptb_pages.area)[idx] = cpu_to_le32(silent_page | idx);
1243
1244 /* set up voice indices */
1245 for (idx = 0; idx < NUM_G; idx++) {
1246 emu->voices[idx].emu = emu;
1247 emu->voices[idx].number = idx;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001248 }
1249
Takashi Iwai09668b42005-11-17 16:14:10 +01001250 if ((err = snd_emu10k1_init(emu, enable_ir, 0)) < 0)
1251 goto error;
1252#ifdef CONFIG_PM
1253 if ((err = alloc_pm_buffer(emu)) < 0)
1254 goto error;
1255#endif
1256
1257 /* Initialize the effect engine */
1258 if ((err = snd_emu10k1_init_efx(emu)) < 0)
1259 goto error;
1260 snd_emu10k1_audio_enable(emu);
1261
1262 if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, emu, &ops)) < 0)
1263 goto error;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001264
Takashi Iwaiadf1b3d2005-12-01 10:49:58 +01001265#ifdef CONFIG_PROC_FS
Linus Torvalds1da177e2005-04-16 15:20:36 -07001266 snd_emu10k1_proc_init(emu);
Takashi Iwaiadf1b3d2005-12-01 10:49:58 +01001267#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -07001268
1269 snd_card_set_dev(card, &pci->dev);
1270 *remu = emu;
1271 return 0;
Takashi Iwai09668b42005-11-17 16:14:10 +01001272
1273 error:
1274 snd_emu10k1_free(emu);
1275 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001276}
1277
Takashi Iwai09668b42005-11-17 16:14:10 +01001278#ifdef CONFIG_PM
1279static unsigned char saved_regs[] = {
1280 CPF, PTRX, CVCF, VTFT, Z1, Z2, PSST, DSL, CCCA, CCR, CLP,
1281 FXRT, MAPA, MAPB, ENVVOL, ATKHLDV, DCYSUSV, LFOVAL1, ENVVAL,
1282 ATKHLDM, DCYSUSM, LFOVAL2, IP, IFATN, PEFE, FMMOD, TREMFRQ, FM2FRQ2,
1283 TEMPENV, ADCCR, FXWC, MICBA, ADCBA, FXBA,
1284 MICBS, ADCBS, FXBS, CDCS, GPSCS, SPCS0, SPCS1, SPCS2,
1285 SPBYPASS, AC97SLOT, CDSRCS, GPSRCS, ZVSRCS, MICIDX, ADCIDX, FXIDX,
1286 0xff /* end */
1287};
1288static unsigned char saved_regs_audigy[] = {
1289 A_ADCIDX, A_MICIDX, A_FXWC1, A_FXWC2, A_SAMPLE_RATE,
1290 A_FXRT2, A_SENDAMOUNTS, A_FXRT1,
1291 0xff /* end */
1292};
1293
1294static int __devinit alloc_pm_buffer(struct snd_emu10k1 *emu)
1295{
1296 int size;
1297
1298 size = ARRAY_SIZE(saved_regs);
1299 if (emu->audigy)
1300 size += ARRAY_SIZE(saved_regs_audigy);
1301 emu->saved_ptr = vmalloc(4 * NUM_G * size);
1302 if (! emu->saved_ptr)
1303 return -ENOMEM;
1304 if (snd_emu10k1_efx_alloc_pm_buffer(emu) < 0)
1305 return -ENOMEM;
1306 if (emu->card_capabilities->ca0151_chip &&
1307 snd_p16v_alloc_pm_buffer(emu) < 0)
1308 return -ENOMEM;
1309 return 0;
1310}
1311
1312static void free_pm_buffer(struct snd_emu10k1 *emu)
1313{
1314 vfree(emu->saved_ptr);
1315 snd_emu10k1_efx_free_pm_buffer(emu);
1316 if (emu->card_capabilities->ca0151_chip)
1317 snd_p16v_free_pm_buffer(emu);
1318}
1319
1320void snd_emu10k1_suspend_regs(struct snd_emu10k1 *emu)
1321{
1322 int i;
1323 unsigned char *reg;
1324 unsigned int *val;
1325
1326 val = emu->saved_ptr;
1327 for (reg = saved_regs; *reg != 0xff; reg++)
1328 for (i = 0; i < NUM_G; i++, val++)
1329 *val = snd_emu10k1_ptr_read(emu, *reg, i);
1330 if (emu->audigy) {
1331 for (reg = saved_regs_audigy; *reg != 0xff; reg++)
1332 for (i = 0; i < NUM_G; i++, val++)
1333 *val = snd_emu10k1_ptr_read(emu, *reg, i);
1334 }
1335 if (emu->audigy)
1336 emu->saved_a_iocfg = inl(emu->port + A_IOCFG);
1337 emu->saved_hcfg = inl(emu->port + HCFG);
1338}
1339
1340void snd_emu10k1_resume_init(struct snd_emu10k1 *emu)
1341{
1342 if (emu->card_capabilities->ecard)
1343 snd_emu10k1_ecard_init(emu);
1344 else
1345 snd_emu10k1_ptr_write(emu, AC97SLOT, 0, AC97SLOT_CNTR|AC97SLOT_LFE);
1346 snd_emu10k1_init(emu, emu->enable_ir, 1);
1347}
1348
1349void snd_emu10k1_resume_regs(struct snd_emu10k1 *emu)
1350{
1351 int i;
1352 unsigned char *reg;
1353 unsigned int *val;
1354
1355 snd_emu10k1_audio_enable(emu);
1356
1357 /* resore for spdif */
1358 if (emu->audigy)
1359 outl(emu->port + A_IOCFG, emu->saved_a_iocfg);
1360 outl(emu->port + HCFG, emu->saved_hcfg);
1361
1362 val = emu->saved_ptr;
1363 for (reg = saved_regs; *reg != 0xff; reg++)
1364 for (i = 0; i < NUM_G; i++, val++)
1365 snd_emu10k1_ptr_write(emu, *reg, i, *val);
1366 if (emu->audigy) {
1367 for (reg = saved_regs_audigy; *reg != 0xff; reg++)
1368 for (i = 0; i < NUM_G; i++, val++)
1369 snd_emu10k1_ptr_write(emu, *reg, i, *val);
1370 }
1371}
1372#endif
1373
Linus Torvalds1da177e2005-04-16 15:20:36 -07001374/* memory.c */
1375EXPORT_SYMBOL(snd_emu10k1_synth_alloc);
1376EXPORT_SYMBOL(snd_emu10k1_synth_free);
1377EXPORT_SYMBOL(snd_emu10k1_synth_bzero);
1378EXPORT_SYMBOL(snd_emu10k1_synth_copy_from_user);
1379EXPORT_SYMBOL(snd_emu10k1_memblk_map);
1380/* voice.c */
1381EXPORT_SYMBOL(snd_emu10k1_voice_alloc);
1382EXPORT_SYMBOL(snd_emu10k1_voice_free);
1383/* io.c */
1384EXPORT_SYMBOL(snd_emu10k1_ptr_read);
1385EXPORT_SYMBOL(snd_emu10k1_ptr_write);