blob: 103a3f7708b7865dcf47a06f997826241ff6a2d3 [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>
Ingo Molnar62932df2006-01-16 16:34:20 +010039#include <linux/mutex.h>
40
Linus Torvalds1da177e2005-04-16 15:20:36 -070041
42#include <sound/core.h>
43#include <sound/emu10k1.h>
44#include "p16v.h"
James Courtier-Duttone2b15f82005-11-11 23:39:05 +010045#include "tina2.h"
Linus Torvalds1da177e2005-04-16 15:20:36 -070046
James Courtier-Dutton19b99fb2005-12-04 18:03:03 +010047
Linus Torvalds1da177e2005-04-16 15:20:36 -070048/*************************************************************************
49 * EMU10K1 init / done
50 *************************************************************************/
51
Takashi Iwaieb4698f2005-11-17 14:50:13 +010052void snd_emu10k1_voice_init(struct snd_emu10k1 * emu, int ch)
Linus Torvalds1da177e2005-04-16 15:20:36 -070053{
54 snd_emu10k1_ptr_write(emu, DCYSUSV, ch, 0);
55 snd_emu10k1_ptr_write(emu, IP, ch, 0);
56 snd_emu10k1_ptr_write(emu, VTFT, ch, 0xffff);
57 snd_emu10k1_ptr_write(emu, CVCF, ch, 0xffff);
58 snd_emu10k1_ptr_write(emu, PTRX, ch, 0);
59 snd_emu10k1_ptr_write(emu, CPF, ch, 0);
60 snd_emu10k1_ptr_write(emu, CCR, ch, 0);
61
62 snd_emu10k1_ptr_write(emu, PSST, ch, 0);
63 snd_emu10k1_ptr_write(emu, DSL, ch, 0x10);
64 snd_emu10k1_ptr_write(emu, CCCA, ch, 0);
65 snd_emu10k1_ptr_write(emu, Z1, ch, 0);
66 snd_emu10k1_ptr_write(emu, Z2, ch, 0);
67 snd_emu10k1_ptr_write(emu, FXRT, ch, 0x32100000);
68
69 snd_emu10k1_ptr_write(emu, ATKHLDM, ch, 0);
70 snd_emu10k1_ptr_write(emu, DCYSUSM, ch, 0);
71 snd_emu10k1_ptr_write(emu, IFATN, ch, 0xffff);
72 snd_emu10k1_ptr_write(emu, PEFE, ch, 0);
73 snd_emu10k1_ptr_write(emu, FMMOD, ch, 0);
74 snd_emu10k1_ptr_write(emu, TREMFRQ, ch, 24); /* 1 Hz */
75 snd_emu10k1_ptr_write(emu, FM2FRQ2, ch, 24); /* 1 Hz */
76 snd_emu10k1_ptr_write(emu, TEMPENV, ch, 0);
77
78 /*** these are last so OFF prevents writing ***/
79 snd_emu10k1_ptr_write(emu, LFOVAL2, ch, 0);
80 snd_emu10k1_ptr_write(emu, LFOVAL1, ch, 0);
81 snd_emu10k1_ptr_write(emu, ATKHLDV, ch, 0);
82 snd_emu10k1_ptr_write(emu, ENVVOL, ch, 0);
83 snd_emu10k1_ptr_write(emu, ENVVAL, ch, 0);
84
85 /* Audigy extra stuffs */
86 if (emu->audigy) {
87 snd_emu10k1_ptr_write(emu, 0x4c, ch, 0); /* ?? */
88 snd_emu10k1_ptr_write(emu, 0x4d, ch, 0); /* ?? */
89 snd_emu10k1_ptr_write(emu, 0x4e, ch, 0); /* ?? */
90 snd_emu10k1_ptr_write(emu, 0x4f, ch, 0); /* ?? */
91 snd_emu10k1_ptr_write(emu, A_FXRT1, ch, 0x03020100);
92 snd_emu10k1_ptr_write(emu, A_FXRT2, ch, 0x3f3f3f3f);
93 snd_emu10k1_ptr_write(emu, A_SENDAMOUNTS, ch, 0);
94 }
95}
96
James Courtier-Dutton18f3c592005-12-21 22:05:29 +010097static unsigned int spi_dac_init[] = {
98 0x00ff,
99 0x02ff,
100 0x0400,
101 0x0520,
102 0x0600,
103 0x08ff,
104 0x0aff,
105 0x0cff,
106 0x0eff,
107 0x10ff,
108 0x1200,
109 0x1400,
110 0x1480,
111 0x1800,
112 0x1aff,
113 0x1cff,
114 0x1e00,
115 0x0530,
116 0x0602,
117 0x0622,
118 0x1400,
119};
120
Takashi Iwai09668b42005-11-17 16:14:10 +0100121static int snd_emu10k1_init(struct snd_emu10k1 *emu, int enable_ir, int resume)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700122{
Linus Torvalds1da177e2005-04-16 15:20:36 -0700123 unsigned int silent_page;
Takashi Iwai09668b42005-11-17 16:14:10 +0100124 int ch;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700125
126 /* disable audio and lock cache */
Takashi Iwai09668b42005-11-17 16:14:10 +0100127 outl(HCFG_LOCKSOUNDCACHE | HCFG_LOCKTANKCACHE_MASK | HCFG_MUTEBUTTONENABLE,
128 emu->port + HCFG);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700129
130 /* reset recording buffers */
131 snd_emu10k1_ptr_write(emu, MICBS, 0, ADCBS_BUFSIZE_NONE);
132 snd_emu10k1_ptr_write(emu, MICBA, 0, 0);
133 snd_emu10k1_ptr_write(emu, FXBS, 0, ADCBS_BUFSIZE_NONE);
134 snd_emu10k1_ptr_write(emu, FXBA, 0, 0);
135 snd_emu10k1_ptr_write(emu, ADCBS, 0, ADCBS_BUFSIZE_NONE);
136 snd_emu10k1_ptr_write(emu, ADCBA, 0, 0);
137
138 /* disable channel interrupt */
139 outl(0, emu->port + INTE);
140 snd_emu10k1_ptr_write(emu, CLIEL, 0, 0);
141 snd_emu10k1_ptr_write(emu, CLIEH, 0, 0);
142 snd_emu10k1_ptr_write(emu, SOLEL, 0, 0);
143 snd_emu10k1_ptr_write(emu, SOLEH, 0, 0);
144
145 if (emu->audigy){
146 /* set SPDIF bypass mode */
147 snd_emu10k1_ptr_write(emu, SPBYPASS, 0, SPBYPASS_FORMAT);
148 /* enable rear left + rear right AC97 slots */
Takashi Iwai09668b42005-11-17 16:14:10 +0100149 snd_emu10k1_ptr_write(emu, AC97SLOT, 0, AC97SLOT_REAR_RIGHT |
150 AC97SLOT_REAR_LEFT);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700151 }
152
153 /* init envelope engine */
Takashi Iwai09668b42005-11-17 16:14:10 +0100154 for (ch = 0; ch < NUM_G; ch++)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700155 snd_emu10k1_voice_init(emu, ch);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700156
Takashi Iwai09668b42005-11-17 16:14:10 +0100157 snd_emu10k1_ptr_write(emu, SPCS0, 0, emu->spdif_bits[0]);
158 snd_emu10k1_ptr_write(emu, SPCS1, 0, emu->spdif_bits[1]);
159 snd_emu10k1_ptr_write(emu, SPCS2, 0, emu->spdif_bits[2]);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700160
Lee Revell2b637da2005-03-30 13:51:18 +0200161 if (emu->card_capabilities->ca0151_chip) { /* audigy2 */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700162 /* Hacks for Alice3 to work independent of haP16V driver */
163 u32 tmp;
164
165 //Setup SRCMulti_I2S SamplingRate
166 tmp = snd_emu10k1_ptr_read(emu, A_SPDIF_SAMPLERATE, 0);
167 tmp &= 0xfffff1ff;
168 tmp |= (0x2<<9);
169 snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, 0, tmp);
170
171 /* Setup SRCSel (Enable Spdif,I2S SRCMulti) */
172 snd_emu10k1_ptr20_write(emu, SRCSel, 0, 0x14);
173 /* Setup SRCMulti Input Audio Enable */
174 /* Use 0xFFFFFFFF to enable P16V sounds. */
175 snd_emu10k1_ptr20_write(emu, SRCMULTI_ENABLE, 0, 0xFFFFFFFF);
176
177 /* Enabled Phased (8-channel) P16V playback */
178 outl(0x0201, emu->port + HCFG2);
179 /* Set playback routing. */
James Courtier-Duttonfd9a98e2005-04-10 15:43:35 +0200180 snd_emu10k1_ptr20_write(emu, CAPTURE_P16V_SOURCE, 0, 0x78e4);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700181 }
James Courtier-Duttone0474e52005-07-02 16:33:34 +0200182 if (emu->card_capabilities->ca0108_chip) { /* audigy2 Value */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700183 /* Hacks for Alice3 to work independent of haP16V driver */
184 u32 tmp;
185
Takashi Iwai09668b42005-11-17 16:14:10 +0100186 snd_printk(KERN_INFO "Audigy2 value: Special config.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700187 //Setup SRCMulti_I2S SamplingRate
188 tmp = snd_emu10k1_ptr_read(emu, A_SPDIF_SAMPLERATE, 0);
189 tmp &= 0xfffff1ff;
190 tmp |= (0x2<<9);
191 snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, 0, tmp);
192
193 /* Setup SRCSel (Enable Spdif,I2S SRCMulti) */
194 outl(0x600000, emu->port + 0x20);
195 outl(0x14, emu->port + 0x24);
196
197 /* Setup SRCMulti Input Audio Enable */
198 outl(0x7b0000, emu->port + 0x20);
199 outl(0xFF000000, emu->port + 0x24);
200
201 /* Setup SPDIF Out Audio Enable */
202 /* The Audigy 2 Value has a separate SPDIF out,
203 * so no need for a mixer switch
204 */
205 outl(0x7a0000, emu->port + 0x20);
206 outl(0xFF000000, emu->port + 0x24);
207 tmp = inl(emu->port + A_IOCFG) & ~0x8; /* Clear bit 3 */
208 outl(tmp, emu->port + A_IOCFG);
209 }
James Courtier-Dutton27fe8642005-12-21 15:06:08 +0100210 if (emu->card_capabilities->spi_dac) { /* Audigy 2 ZS Notebook with DAC Wolfson WM8768/WM8568 */
James Courtier-Dutton18f3c592005-12-21 22:05:29 +0100211 int size, n;
212
213 size = ARRAY_SIZE(spi_dac_init);
214 for (n=0; n < size; n++)
215 snd_emu10k1_spi_write(emu, spi_dac_init[n]);
216
James Courtier-Dutton27fe8642005-12-21 15:06:08 +0100217 snd_emu10k1_ptr20_write(emu, 0x60, 0, 0x10);
James Courtier-Duttonccadc3e2005-12-21 15:31:02 +0100218 /* Enable GPIOs
219 * GPIO0: Unknown
220 * GPIO1: Speakers-enabled.
221 * GPIO2: Unknown
222 * GPIO3: Unknown
223 * GPIO4: IEC958 Output on.
224 * GPIO5: Unknown
225 * GPIO6: Unknown
226 * GPIO7: Unknown
227 */
228 outl(0x76, emu->port + A_IOCFG); /* Windows uses 0x3f76 */
229
James Courtier-Dutton27fe8642005-12-21 15:06:08 +0100230 }
231
Linus Torvalds1da177e2005-04-16 15:20:36 -0700232 snd_emu10k1_ptr_write(emu, PTB, 0, emu->ptb_pages.addr);
233 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 */
235
236 silent_page = (emu->silent_page.addr << 1) | MAP_PTI_MASK;
237 for (ch = 0; ch < NUM_G; ch++) {
238 snd_emu10k1_ptr_write(emu, MAPA, ch, silent_page);
239 snd_emu10k1_ptr_write(emu, MAPB, ch, silent_page);
240 }
241
242 /*
243 * Hokay, setup HCFG
244 * Mute Disable Audio = 0
245 * Lock Tank Memory = 1
246 * Lock Sound Memory = 0
247 * Auto Mute = 1
248 */
249 if (emu->audigy) {
250 if (emu->revision == 4) /* audigy2 */
251 outl(HCFG_AUDIOENABLE |
252 HCFG_AC3ENABLE_CDSPDIF |
253 HCFG_AC3ENABLE_GPSPDIF |
254 HCFG_AUTOMUTE | HCFG_JOYENABLE, emu->port + HCFG);
255 else
256 outl(HCFG_AUTOMUTE | HCFG_JOYENABLE, emu->port + HCFG);
James Courtier-Duttone0474e52005-07-02 16:33:34 +0200257 /* FIXME: Remove all these emu->model and replace it with a card recognition parameter,
258 * e.g. card_capabilities->joystick */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700259 } else if (emu->model == 0x20 ||
260 emu->model == 0xc400 ||
261 (emu->model == 0x21 && emu->revision < 6))
262 outl(HCFG_LOCKTANKCACHE_MASK | HCFG_AUTOMUTE, emu->port + HCFG);
263 else
264 // With on-chip joystick
265 outl(HCFG_LOCKTANKCACHE_MASK | HCFG_AUTOMUTE | HCFG_JOYENABLE, emu->port + HCFG);
266
267 if (enable_ir) { /* enable IR for SB Live */
James Courtier-Dutton19b99fb2005-12-04 18:03:03 +0100268 if ( emu->card_capabilities->emu1212m) {
269 ; /* Disable all access to A_IOCFG for the emu1212m */
270 } else if (emu->audigy) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700271 unsigned int reg = inl(emu->port + A_IOCFG);
272 outl(reg | A_IOCFG_GPOUT2, emu->port + A_IOCFG);
273 udelay(500);
274 outl(reg | A_IOCFG_GPOUT1 | A_IOCFG_GPOUT2, emu->port + A_IOCFG);
275 udelay(100);
276 outl(reg, emu->port + A_IOCFG);
277 } else {
278 unsigned int reg = inl(emu->port + HCFG);
279 outl(reg | HCFG_GPOUT2, emu->port + HCFG);
280 udelay(500);
281 outl(reg | HCFG_GPOUT1 | HCFG_GPOUT2, emu->port + HCFG);
282 udelay(100);
283 outl(reg, emu->port + HCFG);
284 }
285 }
286
James Courtier-Dutton19b99fb2005-12-04 18:03:03 +0100287 if ( emu->card_capabilities->emu1212m) {
288 ; /* Disable all access to A_IOCFG for the emu1212m */
289 } else if (emu->audigy) { /* enable analog output */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700290 unsigned int reg = inl(emu->port + A_IOCFG);
291 outl(reg | A_IOCFG_GPOUT0, emu->port + A_IOCFG);
292 }
293
Takashi Iwai09668b42005-11-17 16:14:10 +0100294 return 0;
295}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700296
Takashi Iwai09668b42005-11-17 16:14:10 +0100297static void snd_emu10k1_audio_enable(struct snd_emu10k1 *emu)
298{
Linus Torvalds1da177e2005-04-16 15:20:36 -0700299 /*
300 * Enable the audio bit
301 */
302 outl(inl(emu->port + HCFG) | HCFG_AUDIOENABLE, emu->port + HCFG);
303
304 /* Enable analog/digital outs on audigy */
James Courtier-Dutton19b99fb2005-12-04 18:03:03 +0100305 if ( emu->card_capabilities->emu1212m) {
306 ; /* Disable all access to A_IOCFG for the emu1212m */
307 } else if (emu->audigy) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700308 outl(inl(emu->port + A_IOCFG) & ~0x44, emu->port + A_IOCFG);
309
James Courtier-Duttone0474e52005-07-02 16:33:34 +0200310 if (emu->card_capabilities->ca0151_chip) { /* audigy2 */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700311 /* Unmute Analog now. Set GPO6 to 1 for Apollo.
312 * This has to be done after init ALice3 I2SOut beyond 48KHz.
313 * So, sequence is important. */
314 outl(inl(emu->port + A_IOCFG) | 0x0040, emu->port + A_IOCFG);
James Courtier-Duttone0474e52005-07-02 16:33:34 +0200315 } else if (emu->card_capabilities->ca0108_chip) { /* audigy2 value */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700316 /* Unmute Analog now. */
317 outl(inl(emu->port + A_IOCFG) | 0x0060, emu->port + A_IOCFG);
318 } else {
319 /* Disable routing from AC97 line out to Front speakers */
320 outl(inl(emu->port + A_IOCFG) | 0x0080, emu->port + A_IOCFG);
321 }
322 }
323
324#if 0
325 {
326 unsigned int tmp;
327 /* FIXME: the following routine disables LiveDrive-II !! */
328 // TOSLink detection
329 emu->tos_link = 0;
330 tmp = inl(emu->port + HCFG);
331 if (tmp & (HCFG_GPINPUT0 | HCFG_GPINPUT1)) {
332 outl(tmp|0x800, emu->port + HCFG);
333 udelay(50);
334 if (tmp != (inl(emu->port + HCFG) & ~0x800)) {
335 emu->tos_link = 1;
336 outl(tmp, emu->port + HCFG);
337 }
338 }
339 }
340#endif
341
342 snd_emu10k1_intr_enable(emu, INTE_PCIERRORENABLE);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700343}
344
Takashi Iwai09668b42005-11-17 16:14:10 +0100345int snd_emu10k1_done(struct snd_emu10k1 * emu)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700346{
347 int ch;
348
349 outl(0, emu->port + INTE);
350
351 /*
352 * Shutdown the chip
353 */
354 for (ch = 0; ch < NUM_G; ch++)
355 snd_emu10k1_ptr_write(emu, DCYSUSV, ch, 0);
356 for (ch = 0; ch < NUM_G; ch++) {
357 snd_emu10k1_ptr_write(emu, VTFT, ch, 0);
358 snd_emu10k1_ptr_write(emu, CVCF, ch, 0);
359 snd_emu10k1_ptr_write(emu, PTRX, ch, 0);
360 snd_emu10k1_ptr_write(emu, CPF, ch, 0);
361 }
362
363 /* reset recording buffers */
364 snd_emu10k1_ptr_write(emu, MICBS, 0, 0);
365 snd_emu10k1_ptr_write(emu, MICBA, 0, 0);
366 snd_emu10k1_ptr_write(emu, FXBS, 0, 0);
367 snd_emu10k1_ptr_write(emu, FXBA, 0, 0);
368 snd_emu10k1_ptr_write(emu, FXWC, 0, 0);
369 snd_emu10k1_ptr_write(emu, ADCBS, 0, ADCBS_BUFSIZE_NONE);
370 snd_emu10k1_ptr_write(emu, ADCBA, 0, 0);
371 snd_emu10k1_ptr_write(emu, TCBS, 0, TCBS_BUFFSIZE_16K);
372 snd_emu10k1_ptr_write(emu, TCB, 0, 0);
373 if (emu->audigy)
374 snd_emu10k1_ptr_write(emu, A_DBG, 0, A_DBG_SINGLE_STEP);
375 else
376 snd_emu10k1_ptr_write(emu, DBG, 0, EMU10K1_DBG_SINGLE_STEP);
377
378 /* disable channel interrupt */
379 snd_emu10k1_ptr_write(emu, CLIEL, 0, 0);
380 snd_emu10k1_ptr_write(emu, CLIEH, 0, 0);
381 snd_emu10k1_ptr_write(emu, SOLEL, 0, 0);
382 snd_emu10k1_ptr_write(emu, SOLEH, 0, 0);
383
Linus Torvalds1da177e2005-04-16 15:20:36 -0700384 /* disable audio and lock cache */
385 outl(HCFG_LOCKSOUNDCACHE | HCFG_LOCKTANKCACHE_MASK | HCFG_MUTEBUTTONENABLE, emu->port + HCFG);
386 snd_emu10k1_ptr_write(emu, PTB, 0, 0);
387
Linus Torvalds1da177e2005-04-16 15:20:36 -0700388 return 0;
389}
390
391/*************************************************************************
392 * ECARD functional implementation
393 *************************************************************************/
394
395/* In A1 Silicon, these bits are in the HC register */
396#define HOOKN_BIT (1L << 12)
397#define HANDN_BIT (1L << 11)
398#define PULSEN_BIT (1L << 10)
399
400#define EC_GDI1 (1 << 13)
401#define EC_GDI0 (1 << 14)
402
403#define EC_NUM_CONTROL_BITS 20
404
405#define EC_AC3_DATA_SELN 0x0001L
406#define EC_EE_DATA_SEL 0x0002L
407#define EC_EE_CNTRL_SELN 0x0004L
408#define EC_EECLK 0x0008L
409#define EC_EECS 0x0010L
410#define EC_EESDO 0x0020L
411#define EC_TRIM_CSN 0x0040L
412#define EC_TRIM_SCLK 0x0080L
413#define EC_TRIM_SDATA 0x0100L
414#define EC_TRIM_MUTEN 0x0200L
415#define EC_ADCCAL 0x0400L
416#define EC_ADCRSTN 0x0800L
417#define EC_DACCAL 0x1000L
418#define EC_DACMUTEN 0x2000L
419#define EC_LEDN 0x4000L
420
421#define EC_SPDIF0_SEL_SHIFT 15
422#define EC_SPDIF1_SEL_SHIFT 17
423#define EC_SPDIF0_SEL_MASK (0x3L << EC_SPDIF0_SEL_SHIFT)
424#define EC_SPDIF1_SEL_MASK (0x7L << EC_SPDIF1_SEL_SHIFT)
425#define EC_SPDIF0_SELECT(_x) (((_x) << EC_SPDIF0_SEL_SHIFT) & EC_SPDIF0_SEL_MASK)
426#define EC_SPDIF1_SELECT(_x) (((_x) << EC_SPDIF1_SEL_SHIFT) & EC_SPDIF1_SEL_MASK)
427#define EC_CURRENT_PROM_VERSION 0x01 /* Self-explanatory. This should
428 * be incremented any time the EEPROM's
429 * format is changed. */
430
431#define EC_EEPROM_SIZE 0x40 /* ECARD EEPROM has 64 16-bit words */
432
433/* Addresses for special values stored in to EEPROM */
434#define EC_PROM_VERSION_ADDR 0x20 /* Address of the current prom version */
435#define EC_BOARDREV0_ADDR 0x21 /* LSW of board rev */
436#define EC_BOARDREV1_ADDR 0x22 /* MSW of board rev */
437
438#define EC_LAST_PROMFILE_ADDR 0x2f
439
440#define EC_SERIALNUM_ADDR 0x30 /* First word of serial number. The
441 * can be up to 30 characters in length
442 * and is stored as a NULL-terminated
443 * ASCII string. Any unused bytes must be
444 * filled with zeros */
445#define EC_CHECKSUM_ADDR 0x3f /* Location at which checksum is stored */
446
447
448/* Most of this stuff is pretty self-evident. According to the hardware
449 * dudes, we need to leave the ADCCAL bit low in order to avoid a DC
450 * offset problem. Weird.
451 */
452#define EC_RAW_RUN_MODE (EC_DACMUTEN | EC_ADCRSTN | EC_TRIM_MUTEN | \
453 EC_TRIM_CSN)
454
455
456#define EC_DEFAULT_ADC_GAIN 0xC4C4
457#define EC_DEFAULT_SPDIF0_SEL 0x0
458#define EC_DEFAULT_SPDIF1_SEL 0x4
459
460/**************************************************************************
461 * @func Clock bits into the Ecard's control latch. The Ecard uses a
462 * control latch will is loaded bit-serially by toggling the Modem control
463 * lines from function 2 on the E8010. This function hides these details
464 * and presents the illusion that we are actually writing to a distinct
465 * register.
466 */
467
Takashi Iwaieb4698f2005-11-17 14:50:13 +0100468static void snd_emu10k1_ecard_write(struct snd_emu10k1 * emu, unsigned int value)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700469{
470 unsigned short count;
471 unsigned int data;
472 unsigned long hc_port;
473 unsigned int hc_value;
474
475 hc_port = emu->port + HCFG;
476 hc_value = inl(hc_port) & ~(HOOKN_BIT | HANDN_BIT | PULSEN_BIT);
477 outl(hc_value, hc_port);
478
479 for (count = 0; count < EC_NUM_CONTROL_BITS; count++) {
480
481 /* Set up the value */
482 data = ((value & 0x1) ? PULSEN_BIT : 0);
483 value >>= 1;
484
485 outl(hc_value | data, hc_port);
486
487 /* Clock the shift register */
488 outl(hc_value | data | HANDN_BIT, hc_port);
489 outl(hc_value | data, hc_port);
490 }
491
492 /* Latch the bits */
493 outl(hc_value | HOOKN_BIT, hc_port);
494 outl(hc_value, hc_port);
495}
496
497/**************************************************************************
498 * @func Set the gain of the ECARD's CS3310 Trim/gain controller. The
499 * trim value consists of a 16bit value which is composed of two
500 * 8 bit gain/trim values, one for the left channel and one for the
501 * right channel. The following table maps from the Gain/Attenuation
502 * value in decibels into the corresponding bit pattern for a single
503 * channel.
504 */
505
Takashi Iwaieb4698f2005-11-17 14:50:13 +0100506static void snd_emu10k1_ecard_setadcgain(struct snd_emu10k1 * emu,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700507 unsigned short gain)
508{
509 unsigned int bit;
510
511 /* Enable writing to the TRIM registers */
512 snd_emu10k1_ecard_write(emu, emu->ecard_ctrl & ~EC_TRIM_CSN);
513
514 /* Do it again to insure that we meet hold time requirements */
515 snd_emu10k1_ecard_write(emu, emu->ecard_ctrl & ~EC_TRIM_CSN);
516
517 for (bit = (1 << 15); bit; bit >>= 1) {
518 unsigned int value;
519
520 value = emu->ecard_ctrl & ~(EC_TRIM_CSN | EC_TRIM_SDATA);
521
522 if (gain & bit)
523 value |= EC_TRIM_SDATA;
524
525 /* Clock the bit */
526 snd_emu10k1_ecard_write(emu, value);
527 snd_emu10k1_ecard_write(emu, value | EC_TRIM_SCLK);
528 snd_emu10k1_ecard_write(emu, value);
529 }
530
531 snd_emu10k1_ecard_write(emu, emu->ecard_ctrl);
532}
533
Takashi Iwaieb4698f2005-11-17 14:50:13 +0100534static int __devinit snd_emu10k1_ecard_init(struct snd_emu10k1 * emu)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700535{
536 unsigned int hc_value;
537
538 /* Set up the initial settings */
539 emu->ecard_ctrl = EC_RAW_RUN_MODE |
540 EC_SPDIF0_SELECT(EC_DEFAULT_SPDIF0_SEL) |
541 EC_SPDIF1_SELECT(EC_DEFAULT_SPDIF1_SEL);
542
543 /* Step 0: Set the codec type in the hardware control register
544 * and enable audio output */
545 hc_value = inl(emu->port + HCFG);
546 outl(hc_value | HCFG_AUDIOENABLE | HCFG_CODECFORMAT_I2S, emu->port + HCFG);
547 inl(emu->port + HCFG);
548
549 /* Step 1: Turn off the led and deassert TRIM_CS */
550 snd_emu10k1_ecard_write(emu, EC_ADCCAL | EC_LEDN | EC_TRIM_CSN);
551
552 /* Step 2: Calibrate the ADC and DAC */
553 snd_emu10k1_ecard_write(emu, EC_DACCAL | EC_LEDN | EC_TRIM_CSN);
554
555 /* Step 3: Wait for awhile; XXX We can't get away with this
556 * under a real operating system; we'll need to block and wait that
557 * way. */
558 snd_emu10k1_wait(emu, 48000);
559
560 /* Step 4: Switch off the DAC and ADC calibration. Note
561 * That ADC_CAL is actually an inverted signal, so we assert
562 * it here to stop calibration. */
563 snd_emu10k1_ecard_write(emu, EC_ADCCAL | EC_LEDN | EC_TRIM_CSN);
564
565 /* Step 4: Switch into run mode */
566 snd_emu10k1_ecard_write(emu, emu->ecard_ctrl);
567
568 /* Step 5: Set the analog input gain */
569 snd_emu10k1_ecard_setadcgain(emu, EC_DEFAULT_ADC_GAIN);
570
571 return 0;
572}
573
Takashi Iwaieb4698f2005-11-17 14:50:13 +0100574static int __devinit snd_emu10k1_cardbus_init(struct snd_emu10k1 * emu)
James Courtier-Duttond83c6712005-10-31 10:27:41 +0000575{
576 unsigned long special_port;
577 unsigned int value;
578
579 /* Special initialisation routine
580 * before the rest of the IO-Ports become active.
581 */
582 special_port = emu->port + 0x38;
583 value = inl(special_port);
584 outl(0x00d00000, special_port);
585 value = inl(special_port);
586 outl(0x00d00001, special_port);
587 value = inl(special_port);
588 outl(0x00d0005f, special_port);
589 value = inl(special_port);
590 outl(0x00d0007f, special_port);
591 value = inl(special_port);
592 outl(0x0090007f, special_port);
593 value = inl(special_port);
594
James Courtier-Duttone2b15f82005-11-11 23:39:05 +0100595 snd_emu10k1_ptr20_write(emu, TINA2_VOLUME, 0, 0xfefefefe); /* Defaults to 0x30303030 */
James Courtier-Duttond83c6712005-10-31 10:27:41 +0000596 return 0;
597}
598
James Courtier-Dutton19b99fb2005-12-04 18:03:03 +0100599static int snd_emu1212m_fpga_write(struct snd_emu10k1 * emu, int reg, int value)
600{
601 if (reg<0 || reg>0x3f)
602 return 1;
603 reg+=0x40; /* 0x40 upwards are registers. */
604 if (value<0 || value>0x3f) /* 0 to 0x3f are values */
605 return 1;
606 outl(reg, emu->port + A_IOCFG);
607 outl(reg | 0x80, emu->port + A_IOCFG); /* High bit clocks the value into the fpga. */
608 outl(value, emu->port + A_IOCFG);
609 outl(value | 0x80 , emu->port + A_IOCFG); /* High bit clocks the value into the fpga. */
610
611 return 0;
612}
613
614static int snd_emu1212m_fpga_read(struct snd_emu10k1 * emu, int reg, int *value)
615{
616 if (reg<0 || reg>0x3f)
617 return 1;
618 reg+=0x40; /* 0x40 upwards are registers. */
619 outl(reg, emu->port + A_IOCFG);
620 outl(reg | 0x80, emu->port + A_IOCFG); /* High bit clocks the value into the fpga. */
621 *value = inl(emu->port + A_IOCFG);
622
623 return 0;
624}
625
626static int snd_emu1212m_fpga_netlist_write(struct snd_emu10k1 * emu, int reg, int value)
627{
628 snd_emu1212m_fpga_write(emu, 0x00, ((reg >> 8) & 0x3f) );
629 snd_emu1212m_fpga_write(emu, 0x01, (reg & 0x3f) );
630 snd_emu1212m_fpga_write(emu, 0x02, ((value >> 8) & 0x3f) );
631 snd_emu1212m_fpga_write(emu, 0x03, (value & 0x3f) );
632
633 return 0;
634}
635
636static int __devinit snd_emu10k1_emu1212m_init(struct snd_emu10k1 * emu)
637{
638 unsigned int i;
639 int tmp;
640
641 snd_printk(KERN_ERR "emu1212m: Special config.\n");
642 outl(0x0005a00c, emu->port + HCFG);
643 outl(0x0005a004, emu->port + HCFG);
644 outl(0x0005a000, emu->port + HCFG);
645 outl(0x0005a000, emu->port + HCFG);
646
647 snd_emu1212m_fpga_read(emu, 0x22, &tmp );
648 snd_emu1212m_fpga_read(emu, 0x23, &tmp );
649 snd_emu1212m_fpga_read(emu, 0x24, &tmp );
650 snd_emu1212m_fpga_write(emu, 0x04, 0x01 );
651 snd_emu1212m_fpga_read(emu, 0x0b, &tmp );
652 snd_emu1212m_fpga_write(emu, 0x0b, 0x01 );
653 snd_emu1212m_fpga_read(emu, 0x10, &tmp );
654 snd_emu1212m_fpga_write(emu, 0x10, 0x00 );
655 snd_emu1212m_fpga_read(emu, 0x11, &tmp );
656 snd_emu1212m_fpga_write(emu, 0x11, 0x30 );
657 snd_emu1212m_fpga_read(emu, 0x13, &tmp );
658 snd_emu1212m_fpga_write(emu, 0x13, 0x0f );
659 snd_emu1212m_fpga_read(emu, 0x11, &tmp );
660 snd_emu1212m_fpga_write(emu, 0x11, 0x30 );
661 snd_emu1212m_fpga_read(emu, 0x0a, &tmp );
662 snd_emu1212m_fpga_write(emu, 0x0a, 0x10 );
663 snd_emu1212m_fpga_write(emu, 0x0c, 0x19 );
664 snd_emu1212m_fpga_write(emu, 0x12, 0x0c );
665 snd_emu1212m_fpga_write(emu, 0x09, 0x0f );
666 snd_emu1212m_fpga_write(emu, 0x06, 0x00 );
667 snd_emu1212m_fpga_write(emu, 0x05, 0x00 );
668 snd_emu1212m_fpga_write(emu, 0x0e, 0x12 );
669 snd_emu1212m_fpga_netlist_write(emu, 0x0000, 0x0200);
670 snd_emu1212m_fpga_netlist_write(emu, 0x0001, 0x0201);
671 snd_emu1212m_fpga_netlist_write(emu, 0x0002, 0x0500);
672 snd_emu1212m_fpga_netlist_write(emu, 0x0003, 0x0501);
673 snd_emu1212m_fpga_netlist_write(emu, 0x0004, 0x0400);
674 snd_emu1212m_fpga_netlist_write(emu, 0x0005, 0x0401);
675 snd_emu1212m_fpga_netlist_write(emu, 0x0006, 0x0402);
676 snd_emu1212m_fpga_netlist_write(emu, 0x0007, 0x0403);
677 snd_emu1212m_fpga_netlist_write(emu, 0x0008, 0x0404);
678 snd_emu1212m_fpga_netlist_write(emu, 0x0009, 0x0405);
679 snd_emu1212m_fpga_netlist_write(emu, 0x000a, 0x0406);
680 snd_emu1212m_fpga_netlist_write(emu, 0x000b, 0x0407);
681 snd_emu1212m_fpga_netlist_write(emu, 0x000c, 0x0100);
682 snd_emu1212m_fpga_netlist_write(emu, 0x000d, 0x0104);
683 snd_emu1212m_fpga_netlist_write(emu, 0x000e, 0x0200);
684 snd_emu1212m_fpga_netlist_write(emu, 0x000f, 0x0201);
685 for (i=0;i < 0x20;i++) {
686 snd_emu1212m_fpga_netlist_write(emu, 0x0100+i, 0x0000);
687 }
688 for (i=0;i < 4;i++) {
689 snd_emu1212m_fpga_netlist_write(emu, 0x0200+i, 0x0000);
690 }
691 for (i=0;i < 7;i++) {
692 snd_emu1212m_fpga_netlist_write(emu, 0x0300+i, 0x0000);
693 }
694 for (i=0;i < 7;i++) {
695 snd_emu1212m_fpga_netlist_write(emu, 0x0400+i, 0x0000);
696 }
697 snd_emu1212m_fpga_netlist_write(emu, 0x0500, 0x0108);
698 snd_emu1212m_fpga_netlist_write(emu, 0x0501, 0x010c);
699 snd_emu1212m_fpga_netlist_write(emu, 0x0600, 0x0110);
700 snd_emu1212m_fpga_netlist_write(emu, 0x0601, 0x0114);
701 snd_emu1212m_fpga_netlist_write(emu, 0x0700, 0x0118);
702 snd_emu1212m_fpga_netlist_write(emu, 0x0701, 0x011c);
703 snd_emu1212m_fpga_write(emu, 0x07, 0x01 );
704
705 snd_emu1212m_fpga_read(emu, 0x21, &tmp );
706
707 outl(0x0000a000, emu->port + HCFG);
708 outl(0x0000a001, emu->port + HCFG);
709 /* Initial boot complete. Now patches */
710
711 snd_emu1212m_fpga_read(emu, 0x21, &tmp );
712 snd_emu1212m_fpga_write(emu, 0x0c, 0x19 );
713 snd_emu1212m_fpga_write(emu, 0x12, 0x0c );
714 snd_emu1212m_fpga_write(emu, 0x0c, 0x19 );
715 snd_emu1212m_fpga_write(emu, 0x12, 0x0c );
716 snd_emu1212m_fpga_read(emu, 0x0a, &tmp );
717 snd_emu1212m_fpga_write(emu, 0x0a, 0x10 );
718
719 snd_emu1212m_fpga_read(emu, 0x20, &tmp );
720 snd_emu1212m_fpga_read(emu, 0x21, &tmp );
721
722 snd_emu1212m_fpga_netlist_write(emu, 0x0300, 0x0312);
723 snd_emu1212m_fpga_netlist_write(emu, 0x0301, 0x0313);
724 snd_emu1212m_fpga_netlist_write(emu, 0x0200, 0x0302);
725 snd_emu1212m_fpga_netlist_write(emu, 0x0201, 0x0303);
726
727 return 0;
728}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700729/*
730 * Create the EMU10K1 instance
731 */
732
Takashi Iwai09668b42005-11-17 16:14:10 +0100733#ifdef CONFIG_PM
734static int alloc_pm_buffer(struct snd_emu10k1 *emu);
735static void free_pm_buffer(struct snd_emu10k1 *emu);
736#endif
737
Takashi Iwaieb4698f2005-11-17 14:50:13 +0100738static int snd_emu10k1_free(struct snd_emu10k1 *emu)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700739{
740 if (emu->port) { /* avoid access to already used hardware */
741 snd_emu10k1_fx8010_tram_setup(emu, 0);
742 snd_emu10k1_done(emu);
Takashi Iwai09668b42005-11-17 16:14:10 +0100743 /* remove reserved page */
744 if (emu->reserved_page) {
745 snd_emu10k1_synth_free(emu, (struct snd_util_memblk *)emu->reserved_page);
746 emu->reserved_page = NULL;
747 }
748 snd_emu10k1_free_efx(emu);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700749 }
750 if (emu->memhdr)
751 snd_util_memhdr_free(emu->memhdr);
752 if (emu->silent_page.area)
753 snd_dma_free_pages(&emu->silent_page);
754 if (emu->ptb_pages.area)
755 snd_dma_free_pages(&emu->ptb_pages);
756 vfree(emu->page_ptr_table);
757 vfree(emu->page_addr_table);
Takashi Iwai09668b42005-11-17 16:14:10 +0100758#ifdef CONFIG_PM
759 free_pm_buffer(emu);
760#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700761 if (emu->irq >= 0)
762 free_irq(emu->irq, (void *)emu);
763 if (emu->port)
764 pci_release_regions(emu->pci);
Lee Revell2b637da2005-03-30 13:51:18 +0200765 if (emu->card_capabilities->ca0151_chip) /* P16V */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700766 snd_p16v_free(emu);
Takashi Iwai09668b42005-11-17 16:14:10 +0100767 pci_disable_device(emu->pci);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700768 kfree(emu);
769 return 0;
770}
771
Takashi Iwaieb4698f2005-11-17 14:50:13 +0100772static int snd_emu10k1_dev_free(struct snd_device *device)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700773{
Takashi Iwaieb4698f2005-11-17 14:50:13 +0100774 struct snd_emu10k1 *emu = device->device_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700775 return snd_emu10k1_free(emu);
776}
777
Takashi Iwaieb4698f2005-11-17 14:50:13 +0100778static struct snd_emu_chip_details emu_chip_details[] = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700779 /* 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 +0200780 /* Tested by James@superbug.co.uk 3rd July 2005 */
James Courtier-Dutton54efc962005-12-22 12:58:41 +0100781 /* DSP: CA0108-IAT
782 * DAC: CS4382-KQ
783 * ADC: Philips 1361T
784 * AC97: STAC9750
785 * CA0151: None
786 */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700787 {.vendor = 0x1102, .device = 0x0008, .subsystem = 0x10011102,
788 .driver = "Audigy2", .name = "Audigy 2 Value [SB0400]",
Takashi Iwaiaec72e02005-03-30 14:22:25 +0200789 .id = "Audigy2",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700790 .emu10k2_chip = 1,
791 .ca0108_chip = 1,
Peter Zubaj26689072005-04-01 11:15:07 +0200792 .spk71 = 1,
793 .ac97_chip = 1} ,
James Courtier-Duttond83c6712005-10-31 10:27:41 +0000794 /* Audigy 2 ZS Notebook Cardbus card.*/
James Courtier-Duttonf951fd32005-12-22 13:05:23 +0100795 /* Tested by James@superbug.co.uk 22th December 2005 */
796 /* Audio output 7.1/Headphones working.
797 * Digital output working. (AC3 not checked, only PCM)
798 * Audio inputs not tested.
799 */
800 /* DSP: Tiny2
801 * DAC: Wolfson WM8768/WM8568
802 * ADC: Wolfson WM8775
803 * AC97: None
804 * CA0151: None
805 */
James Courtier-Duttond83c6712005-10-31 10:27:41 +0000806 {.vendor = 0x1102, .device = 0x0008, .subsystem = 0x20011102,
807 .driver = "Audigy2", .name = "Audigy 2 ZS Notebook [SB0530]",
808 .id = "Audigy2",
809 .emu10k2_chip = 1,
810 .ca0108_chip = 1,
811 .ca_cardbus_chip = 1,
James Courtier-Dutton27fe8642005-12-21 15:06:08 +0100812 .spi_dac = 1,
James Courtier-Duttond83c6712005-10-31 10:27:41 +0000813 .spk71 = 1} ,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700814 {.vendor = 0x1102, .device = 0x0008,
815 .driver = "Audigy2", .name = "Audigy 2 Value [Unknown]",
Takashi Iwaiaec72e02005-03-30 14:22:25 +0200816 .id = "Audigy2",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700817 .emu10k2_chip = 1,
Peter Zubaj26689072005-04-01 11:15:07 +0200818 .ca0108_chip = 1,
819 .ac97_chip = 1} ,
James Courtier-Dutton7c1d5492005-07-10 11:50:36 +0200820 /* Tested by James@superbug.co.uk 8th July 2005. No sound available yet. */
821 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x40011102,
822 .driver = "Audigy2", .name = "E-mu 1212m [4001]",
823 .id = "EMU1212m",
824 .emu10k2_chip = 1,
825 .ca0102_chip = 1,
James Courtier-Dutton19b99fb2005-12-04 18:03:03 +0100826 .emu1212m = 1} ,
James Courtier-Dutton88dc0e52005-07-03 12:54:29 +0200827 /* Tested by James@superbug.co.uk 3rd July 2005 */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700828 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x20071102,
829 .driver = "Audigy2", .name = "Audigy 4 PRO [SB0380]",
Takashi Iwaiaec72e02005-03-30 14:22:25 +0200830 .id = "Audigy2",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700831 .emu10k2_chip = 1,
832 .ca0102_chip = 1,
833 .ca0151_chip = 1,
834 .spk71 = 1,
835 .spdif_bug = 1,
836 .ac97_chip = 1} ,
Lee Revellf6f8bb62005-11-07 14:59:19 +0100837 /* Tested by shane-alsa@cm.nu 5th Nov 2005 */
838 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x20061102,
839 .driver = "Audigy2", .name = "Audigy 2 [2006]",
840 .id = "Audigy2",
841 .emu10k2_chip = 1,
842 .ca0102_chip = 1,
843 .ca0151_chip = 1,
844 .spk71 = 1,
845 .spdif_bug = 1,
846 .ac97_chip = 1} ,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700847 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x20021102,
848 .driver = "Audigy2", .name = "Audigy 2 ZS [SB0350]",
Takashi Iwaiaec72e02005-03-30 14:22:25 +0200849 .id = "Audigy2",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700850 .emu10k2_chip = 1,
851 .ca0102_chip = 1,
852 .ca0151_chip = 1,
853 .spk71 = 1,
854 .spdif_bug = 1,
855 .ac97_chip = 1} ,
856 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x20011102,
857 .driver = "Audigy2", .name = "Audigy 2 ZS [2001]",
Takashi Iwaiaec72e02005-03-30 14:22:25 +0200858 .id = "Audigy2",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700859 .emu10k2_chip = 1,
860 .ca0102_chip = 1,
861 .ca0151_chip = 1,
862 .spk71 = 1,
863 .spdif_bug = 1,
864 .ac97_chip = 1} ,
James Courtier-Dutton54efc962005-12-22 12:58:41 +0100865 /* Audigy 2 */
866 /* Tested by James@superbug.co.uk 3rd July 2005 */
867 /* DSP: CA0102-IAT
868 * DAC: CS4382-KQ
869 * ADC: Philips 1361T
870 * AC97: STAC9721
871 * CA0151: Yes
872 */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700873 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x10071102,
874 .driver = "Audigy2", .name = "Audigy 2 [SB0240]",
Takashi Iwaiaec72e02005-03-30 14:22:25 +0200875 .id = "Audigy2",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700876 .emu10k2_chip = 1,
877 .ca0102_chip = 1,
878 .ca0151_chip = 1,
879 .spk71 = 1,
880 .spdif_bug = 1,
881 .ac97_chip = 1} ,
882 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x10051102,
883 .driver = "Audigy2", .name = "Audigy 2 EX [1005]",
Takashi Iwaiaec72e02005-03-30 14:22:25 +0200884 .id = "Audigy2",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700885 .emu10k2_chip = 1,
886 .ca0102_chip = 1,
887 .ca0151_chip = 1,
Lee Revell2f020aa2005-11-07 14:54:24 +0100888 .spk71 = 1,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700889 .spdif_bug = 1} ,
890 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x10021102,
891 .driver = "Audigy2", .name = "Audigy 2 Platinum [SB0240P]",
Takashi Iwaiaec72e02005-03-30 14:22:25 +0200892 .id = "Audigy2",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700893 .emu10k2_chip = 1,
894 .ca0102_chip = 1,
895 .ca0151_chip = 1,
896 .spk71 = 1,
897 .spdif_bug = 1,
898 .ac97_chip = 1} ,
Takashi Iwaibdaed502005-04-07 15:48:42 +0200899 {.vendor = 0x1102, .device = 0x0004, .revision = 0x04,
900 .driver = "Audigy2", .name = "Audigy 2 [Unknown]",
901 .id = "Audigy2",
902 .emu10k2_chip = 1,
903 .ca0102_chip = 1,
904 .ca0151_chip = 1,
905 .spdif_bug = 1,
906 .ac97_chip = 1} ,
Peter Zubaj26689072005-04-01 11:15:07 +0200907 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x00531102,
908 .driver = "Audigy", .name = "Audigy 1 [SB0090]",
909 .id = "Audigy",
910 .emu10k2_chip = 1,
911 .ca0102_chip = 1,
912 .ac97_chip = 1} ,
James Courtier-Duttonae3a72d2005-07-06 22:36:18 +0200913 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x00521102,
914 .driver = "Audigy", .name = "Audigy 1 ES [SB0160]",
915 .id = "Audigy",
916 .emu10k2_chip = 1,
917 .ca0102_chip = 1,
918 .spdif_bug = 1,
919 .ac97_chip = 1} ,
Arnaud Patarda6c17ec2005-05-27 12:31:34 +0200920 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x00511102,
921 .driver = "Audigy", .name = "Audigy 1 [SB0090]",
922 .id = "Audigy",
923 .emu10k2_chip = 1,
924 .ca0102_chip = 1,
925 .ac97_chip = 1} ,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700926 {.vendor = 0x1102, .device = 0x0004,
Takashi Iwaibdaed502005-04-07 15:48:42 +0200927 .driver = "Audigy", .name = "Audigy 1 [Unknown]",
Takashi Iwaiaec72e02005-03-30 14:22:25 +0200928 .id = "Audigy",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700929 .emu10k2_chip = 1,
930 .ca0102_chip = 1,
Peter Zubaj26689072005-04-01 11:15:07 +0200931 .ac97_chip = 1} ,
James Courtier-Duttona6f61922005-07-03 12:32:40 +0200932 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x806B1102,
933 .driver = "EMU10K1", .name = "SBLive! [SB0105]",
James Courtier-Dutton2b6b22f2005-06-18 13:50:22 +0200934 .id = "Live",
935 .emu10k1_chip = 1,
936 .ac97_chip = 1,
937 .sblive51 = 1} ,
938 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x806A1102,
939 .driver = "EMU10K1", .name = "SBLive! Value [SB0103]",
940 .id = "Live",
941 .emu10k1_chip = 1,
942 .ac97_chip = 1,
943 .sblive51 = 1} ,
James Courtier-Duttona6f61922005-07-03 12:32:40 +0200944 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80691102,
945 .driver = "EMU10K1", .name = "SBLive! Value [SB0101]",
946 .id = "Live",
947 .emu10k1_chip = 1,
948 .ac97_chip = 1,
949 .sblive51 = 1} ,
James Courtier-Dutton0ba656d2005-12-26 15:30:03 +0100950 /* Tested by ALSA bug#1680 26th December 2005 */
951 /* note: It really has SB0220 written on the card. */
952 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80661102,
953 .driver = "EMU10K1", .name = "SB Live 5.1 Dell OEM [SB0220]",
954 .id = "Live",
955 .emu10k1_chip = 1,
956 .ac97_chip = 1,
957 .sblive51 = 1} ,
Lee Revellc6c0b842005-08-29 17:42:00 +0200958 /* Tested by Thomas Zehetbauer 27th Aug 2005 */
959 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80651102,
960 .driver = "EMU10K1", .name = "SB Live 5.1 [SB0220]",
961 .id = "Live",
962 .emu10k1_chip = 1,
963 .ac97_chip = 1,
964 .sblive51 = 1} ,
Gergely Tamasa8ee7292005-12-06 14:10:57 +0100965 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x100a1102,
966 .driver = "EMU10K1", .name = "SB Live 5.1 [SB0220]",
967 .id = "Live",
968 .emu10k1_chip = 1,
969 .ac97_chip = 1,
970 .sblive51 = 1} ,
James Courtier-Duttona6f61922005-07-03 12:32:40 +0200971 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80641102,
972 .driver = "EMU10K1", .name = "SB Live 5.1",
973 .id = "Live",
974 .emu10k1_chip = 1,
975 .ac97_chip = 1,
976 .sblive51 = 1} ,
James Courtier-Duttonafe0f1f2005-09-10 10:24:10 +0200977 /* Tested by alsa bugtrack user "hus" bug #1297 12th Aug 2005 */
James Courtier-Duttona6f61922005-07-03 12:32:40 +0200978 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80611102,
Takashi Iwaif12aa402005-09-30 16:56:59 +0200979 .driver = "EMU10K1", .name = "SBLive 5.1 [SB0060]",
James Courtier-Duttona6f61922005-07-03 12:32:40 +0200980 .id = "Live",
981 .emu10k1_chip = 1,
Takashi Iwaif12aa402005-09-30 16:56:59 +0200982 .ac97_chip = 2, /* ac97 is optional; both SBLive 5.1 and platinum
983 * share the same IDs!
984 */
James Courtier-Duttona6f61922005-07-03 12:32:40 +0200985 .sblive51 = 1} ,
986 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80511102,
987 .driver = "EMU10K1", .name = "SBLive! Value [CT4850]",
988 .id = "Live",
989 .emu10k1_chip = 1,
990 .ac97_chip = 1,
991 .sblive51 = 1} ,
992 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80401102,
993 .driver = "EMU10K1", .name = "SBLive! Platinum [CT4760P]",
994 .id = "Live",
995 .emu10k1_chip = 1,
996 .ac97_chip = 1} ,
997 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80321102,
998 .driver = "EMU10K1", .name = "SBLive! Value [CT4871]",
999 .id = "Live",
1000 .emu10k1_chip = 1,
1001 .ac97_chip = 1,
1002 .sblive51 = 1} ,
1003 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80311102,
1004 .driver = "EMU10K1", .name = "SBLive! Value [CT4831]",
1005 .id = "Live",
1006 .emu10k1_chip = 1,
1007 .ac97_chip = 1,
1008 .sblive51 = 1} ,
1009 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80281102,
1010 .driver = "EMU10K1", .name = "SBLive! Value [CT4870]",
1011 .id = "Live",
1012 .emu10k1_chip = 1,
1013 .ac97_chip = 1,
1014 .sblive51 = 1} ,
James Courtier-Dutton88dc0e52005-07-03 12:54:29 +02001015 /* Tested by James@superbug.co.uk 3rd July 2005 */
James Courtier-Duttona6f61922005-07-03 12:32:40 +02001016 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80271102,
1017 .driver = "EMU10K1", .name = "SBLive! Value [CT4832]",
1018 .id = "Live",
1019 .emu10k1_chip = 1,
1020 .ac97_chip = 1,
1021 .sblive51 = 1} ,
1022 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80261102,
1023 .driver = "EMU10K1", .name = "SBLive! Value [CT4830]",
1024 .id = "Live",
1025 .emu10k1_chip = 1,
1026 .ac97_chip = 1,
1027 .sblive51 = 1} ,
1028 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80231102,
1029 .driver = "EMU10K1", .name = "SB PCI512 [CT4790]",
1030 .id = "Live",
1031 .emu10k1_chip = 1,
1032 .ac97_chip = 1,
1033 .sblive51 = 1} ,
1034 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80221102,
1035 .driver = "EMU10K1", .name = "SBLive! Value [CT4780]",
1036 .id = "Live",
1037 .emu10k1_chip = 1,
1038 .ac97_chip = 1,
1039 .sblive51 = 1} ,
1040 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x40011102,
1041 .driver = "EMU10K1", .name = "E-mu APS [4001]",
1042 .id = "APS",
1043 .emu10k1_chip = 1,
1044 .ecard = 1} ,
1045 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x00211102,
1046 .driver = "EMU10K1", .name = "SBLive! [CT4620]",
1047 .id = "Live",
1048 .emu10k1_chip = 1,
1049 .ac97_chip = 1,
1050 .sblive51 = 1} ,
1051 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x00201102,
1052 .driver = "EMU10K1", .name = "SBLive! Value [CT4670]",
James Courtier-Dutton2b6b22f2005-06-18 13:50:22 +02001053 .id = "Live",
1054 .emu10k1_chip = 1,
1055 .ac97_chip = 1,
1056 .sblive51 = 1} ,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001057 {.vendor = 0x1102, .device = 0x0002,
1058 .driver = "EMU10K1", .name = "SB Live [Unknown]",
Takashi Iwaiaec72e02005-03-30 14:22:25 +02001059 .id = "Live",
Linus Torvalds1da177e2005-04-16 15:20:36 -07001060 .emu10k1_chip = 1,
Lee Revell2b637da2005-03-30 13:51:18 +02001061 .ac97_chip = 1,
1062 .sblive51 = 1} ,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001063 { } /* terminator */
1064};
1065
Takashi Iwaieb4698f2005-11-17 14:50:13 +01001066int __devinit snd_emu10k1_create(struct snd_card *card,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001067 struct pci_dev * pci,
1068 unsigned short extin_mask,
1069 unsigned short extout_mask,
1070 long max_cache_bytes,
1071 int enable_ir,
James Courtier-Duttone66bc8b2005-07-06 22:21:51 +02001072 uint subsystem,
Takashi Iwaieb4698f2005-11-17 14:50:13 +01001073 struct snd_emu10k1 ** remu)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001074{
Takashi Iwaieb4698f2005-11-17 14:50:13 +01001075 struct snd_emu10k1 *emu;
Takashi Iwai09668b42005-11-17 16:14:10 +01001076 int idx, err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001077 int is_audigy;
1078 unsigned char revision;
Takashi Iwai09668b42005-11-17 16:14:10 +01001079 unsigned int silent_page;
Takashi Iwaieb4698f2005-11-17 14:50:13 +01001080 const struct snd_emu_chip_details *c;
1081 static struct snd_device_ops ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001082 .dev_free = snd_emu10k1_dev_free,
1083 };
1084
1085 *remu = NULL;
1086
1087 /* enable PCI device */
1088 if ((err = pci_enable_device(pci)) < 0)
1089 return err;
1090
Takashi Iwaie560d8d2005-09-09 14:21:46 +02001091 emu = kzalloc(sizeof(*emu), GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001092 if (emu == NULL) {
1093 pci_disable_device(pci);
1094 return -ENOMEM;
1095 }
1096 emu->card = card;
1097 spin_lock_init(&emu->reg_lock);
1098 spin_lock_init(&emu->emu_lock);
1099 spin_lock_init(&emu->voice_lock);
1100 spin_lock_init(&emu->synth_lock);
1101 spin_lock_init(&emu->memblk_lock);
Ingo Molnar62932df2006-01-16 16:34:20 +01001102 mutex_init(&emu->fx8010.lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001103 INIT_LIST_HEAD(&emu->mapped_link_head);
1104 INIT_LIST_HEAD(&emu->mapped_order_link_head);
1105 emu->pci = pci;
1106 emu->irq = -1;
1107 emu->synth = NULL;
1108 emu->get_synth_voice = NULL;
1109 /* read revision & serial */
1110 pci_read_config_byte(pci, PCI_REVISION_ID, &revision);
1111 emu->revision = revision;
1112 pci_read_config_dword(pci, PCI_SUBSYSTEM_VENDOR_ID, &emu->serial);
1113 pci_read_config_word(pci, PCI_SUBSYSTEM_ID, &emu->model);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001114 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);
1115
1116 for (c = emu_chip_details; c->vendor; c++) {
1117 if (c->vendor == pci->vendor && c->device == pci->device) {
James Courtier-Duttone66bc8b2005-07-06 22:21:51 +02001118 if (subsystem) {
1119 if (c->subsystem && (c->subsystem == subsystem) ) {
1120 break;
1121 } else continue;
1122 } else {
1123 if (c->subsystem && (c->subsystem != emu->serial) )
1124 continue;
1125 if (c->revision && c->revision != emu->revision)
1126 continue;
1127 }
Takashi Iwaibdaed502005-04-07 15:48:42 +02001128 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001129 }
1130 }
1131 if (c->vendor == 0) {
1132 snd_printk(KERN_ERR "emu10k1: Card not recognised\n");
1133 kfree(emu);
1134 pci_disable_device(pci);
1135 return -ENOENT;
1136 }
1137 emu->card_capabilities = c;
James Courtier-Duttone66bc8b2005-07-06 22:21:51 +02001138 if (c->subsystem && !subsystem)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001139 snd_printdd("Sound card name=%s\n", c->name);
James Courtier-Duttone66bc8b2005-07-06 22:21:51 +02001140 else if (subsystem)
1141 snd_printdd("Sound card name=%s, vendor=0x%x, device=0x%x, subsystem=0x%x. Forced to subsytem=0x%x\n",
1142 c->name, pci->vendor, pci->device, emu->serial, c->subsystem);
1143 else
1144 snd_printdd("Sound card name=%s, vendor=0x%x, device=0x%x, subsystem=0x%x.\n",
1145 c->name, pci->vendor, pci->device, emu->serial);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001146
Takashi Iwai85a655d2005-03-30 14:40:25 +02001147 if (!*card->id && c->id) {
1148 int i, n = 0;
Takashi Iwaiaec72e02005-03-30 14:22:25 +02001149 strlcpy(card->id, c->id, sizeof(card->id));
Takashi Iwai85a655d2005-03-30 14:40:25 +02001150 for (;;) {
1151 for (i = 0; i < snd_ecards_limit; i++) {
1152 if (snd_cards[i] && !strcmp(snd_cards[i]->id, card->id))
1153 break;
1154 }
1155 if (i >= snd_ecards_limit)
1156 break;
1157 n++;
1158 if (n >= SNDRV_CARDS)
1159 break;
1160 snprintf(card->id, sizeof(card->id), "%s_%d", c->id, n);
1161 }
1162 }
Takashi Iwaiaec72e02005-03-30 14:22:25 +02001163
Linus Torvalds1da177e2005-04-16 15:20:36 -07001164 is_audigy = emu->audigy = c->emu10k2_chip;
1165
1166 /* set the DMA transfer mask */
1167 emu->dma_mask = is_audigy ? AUDIGY_DMA_MASK : EMU10K1_DMA_MASK;
1168 if (pci_set_dma_mask(pci, emu->dma_mask) < 0 ||
1169 pci_set_consistent_dma_mask(pci, emu->dma_mask) < 0) {
1170 snd_printk(KERN_ERR "architecture does not support PCI busmaster DMA with mask 0x%lx\n", emu->dma_mask);
1171 kfree(emu);
1172 pci_disable_device(pci);
1173 return -ENXIO;
1174 }
1175 if (is_audigy)
1176 emu->gpr_base = A_FXGPREGBASE;
1177 else
1178 emu->gpr_base = FXGPREGBASE;
1179
1180 if ((err = pci_request_regions(pci, "EMU10K1")) < 0) {
1181 kfree(emu);
1182 pci_disable_device(pci);
1183 return err;
1184 }
1185 emu->port = pci_resource_start(pci, 0);
1186
1187 if (request_irq(pci->irq, snd_emu10k1_interrupt, SA_INTERRUPT|SA_SHIRQ, "EMU10K1", (void *)emu)) {
Takashi Iwai09668b42005-11-17 16:14:10 +01001188 err = -EBUSY;
1189 goto error;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001190 }
1191 emu->irq = pci->irq;
1192
1193 emu->max_cache_pages = max_cache_bytes >> PAGE_SHIFT;
1194 if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(pci),
1195 32 * 1024, &emu->ptb_pages) < 0) {
Takashi Iwai09668b42005-11-17 16:14:10 +01001196 err = -ENOMEM;
1197 goto error;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001198 }
1199
1200 emu->page_ptr_table = (void **)vmalloc(emu->max_cache_pages * sizeof(void*));
1201 emu->page_addr_table = (unsigned long*)vmalloc(emu->max_cache_pages * sizeof(unsigned long));
1202 if (emu->page_ptr_table == NULL || emu->page_addr_table == NULL) {
Takashi Iwai09668b42005-11-17 16:14:10 +01001203 err = -ENOMEM;
1204 goto error;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001205 }
1206
1207 if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(pci),
1208 EMUPAGESIZE, &emu->silent_page) < 0) {
Takashi Iwai09668b42005-11-17 16:14:10 +01001209 err = -ENOMEM;
1210 goto error;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001211 }
1212 emu->memhdr = snd_util_memhdr_new(emu->max_cache_pages * PAGE_SIZE);
1213 if (emu->memhdr == NULL) {
Takashi Iwai09668b42005-11-17 16:14:10 +01001214 err = -ENOMEM;
1215 goto error;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001216 }
Takashi Iwaieb4698f2005-11-17 14:50:13 +01001217 emu->memhdr->block_extra_size = sizeof(struct snd_emu10k1_memblk) -
1218 sizeof(struct snd_util_memblk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001219
1220 pci_set_master(pci);
1221
Linus Torvalds1da177e2005-04-16 15:20:36 -07001222 emu->fx8010.fxbus_mask = 0x303f;
1223 if (extin_mask == 0)
1224 extin_mask = 0x3fcf;
1225 if (extout_mask == 0)
1226 extout_mask = 0x7fff;
1227 emu->fx8010.extin_mask = extin_mask;
1228 emu->fx8010.extout_mask = extout_mask;
Takashi Iwai09668b42005-11-17 16:14:10 +01001229 emu->enable_ir = enable_ir;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001230
Lee Revell2b637da2005-03-30 13:51:18 +02001231 if (emu->card_capabilities->ecard) {
Takashi Iwai09668b42005-11-17 16:14:10 +01001232 if ((err = snd_emu10k1_ecard_init(emu)) < 0)
1233 goto error;
James Courtier-Duttond83c6712005-10-31 10:27:41 +00001234 } else if (emu->card_capabilities->ca_cardbus_chip) {
Takashi Iwai09668b42005-11-17 16:14:10 +01001235 if ((err = snd_emu10k1_cardbus_init(emu)) < 0)
1236 goto error;
James Courtier-Dutton19b99fb2005-12-04 18:03:03 +01001237 } else if (emu->card_capabilities->emu1212m) {
1238 if ((err = snd_emu10k1_emu1212m_init(emu)) < 0) {
1239 snd_emu10k1_free(emu);
1240 return err;
1241 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001242 } else {
1243 /* 5.1: Enable the additional AC97 Slots. If the emu10k1 version
1244 does not support this, it shouldn't do any harm */
1245 snd_emu10k1_ptr_write(emu, AC97SLOT, 0, AC97SLOT_CNTR|AC97SLOT_LFE);
1246 }
1247
Takashi Iwai09668b42005-11-17 16:14:10 +01001248 /* initialize TRAM setup */
1249 emu->fx8010.itram_size = (16 * 1024)/2;
1250 emu->fx8010.etram_pages.area = NULL;
1251 emu->fx8010.etram_pages.bytes = 0;
1252
1253 /*
1254 * Init to 0x02109204 :
1255 * Clock accuracy = 0 (1000ppm)
1256 * Sample Rate = 2 (48kHz)
1257 * Audio Channel = 1 (Left of 2)
1258 * Source Number = 0 (Unspecified)
1259 * Generation Status = 1 (Original for Cat Code 12)
1260 * Cat Code = 12 (Digital Signal Mixer)
1261 * Mode = 0 (Mode 0)
1262 * Emphasis = 0 (None)
1263 * CP = 1 (Copyright unasserted)
1264 * AN = 0 (Audio data)
1265 * P = 0 (Consumer)
1266 */
1267 emu->spdif_bits[0] = emu->spdif_bits[1] =
1268 emu->spdif_bits[2] = SPCS_CLKACCY_1000PPM | SPCS_SAMPLERATE_48 |
1269 SPCS_CHANNELNUM_LEFT | SPCS_SOURCENUM_UNSPEC |
1270 SPCS_GENERATIONSTATUS | 0x00001200 |
1271 0x00000000 | SPCS_EMPHASIS_NONE | SPCS_COPYRIGHT;
1272
1273 emu->reserved_page = (struct snd_emu10k1_memblk *)
1274 snd_emu10k1_synth_alloc(emu, 4096);
1275 if (emu->reserved_page)
1276 emu->reserved_page->map_locked = 1;
1277
1278 /* Clear silent pages and set up pointers */
1279 memset(emu->silent_page.area, 0, PAGE_SIZE);
1280 silent_page = emu->silent_page.addr << 1;
1281 for (idx = 0; idx < MAXPAGES; idx++)
1282 ((u32 *)emu->ptb_pages.area)[idx] = cpu_to_le32(silent_page | idx);
1283
1284 /* set up voice indices */
1285 for (idx = 0; idx < NUM_G; idx++) {
1286 emu->voices[idx].emu = emu;
1287 emu->voices[idx].number = idx;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001288 }
1289
Takashi Iwai09668b42005-11-17 16:14:10 +01001290 if ((err = snd_emu10k1_init(emu, enable_ir, 0)) < 0)
1291 goto error;
1292#ifdef CONFIG_PM
1293 if ((err = alloc_pm_buffer(emu)) < 0)
1294 goto error;
1295#endif
1296
1297 /* Initialize the effect engine */
1298 if ((err = snd_emu10k1_init_efx(emu)) < 0)
1299 goto error;
1300 snd_emu10k1_audio_enable(emu);
1301
1302 if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, emu, &ops)) < 0)
1303 goto error;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001304
Takashi Iwaiadf1b3d2005-12-01 10:49:58 +01001305#ifdef CONFIG_PROC_FS
Linus Torvalds1da177e2005-04-16 15:20:36 -07001306 snd_emu10k1_proc_init(emu);
Takashi Iwaiadf1b3d2005-12-01 10:49:58 +01001307#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -07001308
1309 snd_card_set_dev(card, &pci->dev);
1310 *remu = emu;
1311 return 0;
Takashi Iwai09668b42005-11-17 16:14:10 +01001312
1313 error:
1314 snd_emu10k1_free(emu);
1315 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001316}
1317
Takashi Iwai09668b42005-11-17 16:14:10 +01001318#ifdef CONFIG_PM
1319static unsigned char saved_regs[] = {
1320 CPF, PTRX, CVCF, VTFT, Z1, Z2, PSST, DSL, CCCA, CCR, CLP,
1321 FXRT, MAPA, MAPB, ENVVOL, ATKHLDV, DCYSUSV, LFOVAL1, ENVVAL,
1322 ATKHLDM, DCYSUSM, LFOVAL2, IP, IFATN, PEFE, FMMOD, TREMFRQ, FM2FRQ2,
1323 TEMPENV, ADCCR, FXWC, MICBA, ADCBA, FXBA,
1324 MICBS, ADCBS, FXBS, CDCS, GPSCS, SPCS0, SPCS1, SPCS2,
1325 SPBYPASS, AC97SLOT, CDSRCS, GPSRCS, ZVSRCS, MICIDX, ADCIDX, FXIDX,
1326 0xff /* end */
1327};
1328static unsigned char saved_regs_audigy[] = {
1329 A_ADCIDX, A_MICIDX, A_FXWC1, A_FXWC2, A_SAMPLE_RATE,
1330 A_FXRT2, A_SENDAMOUNTS, A_FXRT1,
1331 0xff /* end */
1332};
1333
1334static int __devinit alloc_pm_buffer(struct snd_emu10k1 *emu)
1335{
1336 int size;
1337
1338 size = ARRAY_SIZE(saved_regs);
1339 if (emu->audigy)
1340 size += ARRAY_SIZE(saved_regs_audigy);
1341 emu->saved_ptr = vmalloc(4 * NUM_G * size);
1342 if (! emu->saved_ptr)
1343 return -ENOMEM;
1344 if (snd_emu10k1_efx_alloc_pm_buffer(emu) < 0)
1345 return -ENOMEM;
1346 if (emu->card_capabilities->ca0151_chip &&
1347 snd_p16v_alloc_pm_buffer(emu) < 0)
1348 return -ENOMEM;
1349 return 0;
1350}
1351
1352static void free_pm_buffer(struct snd_emu10k1 *emu)
1353{
1354 vfree(emu->saved_ptr);
1355 snd_emu10k1_efx_free_pm_buffer(emu);
1356 if (emu->card_capabilities->ca0151_chip)
1357 snd_p16v_free_pm_buffer(emu);
1358}
1359
1360void snd_emu10k1_suspend_regs(struct snd_emu10k1 *emu)
1361{
1362 int i;
1363 unsigned char *reg;
1364 unsigned int *val;
1365
1366 val = emu->saved_ptr;
1367 for (reg = saved_regs; *reg != 0xff; reg++)
1368 for (i = 0; i < NUM_G; i++, val++)
1369 *val = snd_emu10k1_ptr_read(emu, *reg, i);
1370 if (emu->audigy) {
1371 for (reg = saved_regs_audigy; *reg != 0xff; reg++)
1372 for (i = 0; i < NUM_G; i++, val++)
1373 *val = snd_emu10k1_ptr_read(emu, *reg, i);
1374 }
1375 if (emu->audigy)
1376 emu->saved_a_iocfg = inl(emu->port + A_IOCFG);
1377 emu->saved_hcfg = inl(emu->port + HCFG);
1378}
1379
1380void snd_emu10k1_resume_init(struct snd_emu10k1 *emu)
1381{
1382 if (emu->card_capabilities->ecard)
1383 snd_emu10k1_ecard_init(emu);
1384 else
1385 snd_emu10k1_ptr_write(emu, AC97SLOT, 0, AC97SLOT_CNTR|AC97SLOT_LFE);
1386 snd_emu10k1_init(emu, emu->enable_ir, 1);
1387}
1388
1389void snd_emu10k1_resume_regs(struct snd_emu10k1 *emu)
1390{
1391 int i;
1392 unsigned char *reg;
1393 unsigned int *val;
1394
1395 snd_emu10k1_audio_enable(emu);
1396
1397 /* resore for spdif */
1398 if (emu->audigy)
1399 outl(emu->port + A_IOCFG, emu->saved_a_iocfg);
1400 outl(emu->port + HCFG, emu->saved_hcfg);
1401
1402 val = emu->saved_ptr;
1403 for (reg = saved_regs; *reg != 0xff; reg++)
1404 for (i = 0; i < NUM_G; i++, val++)
1405 snd_emu10k1_ptr_write(emu, *reg, i, *val);
1406 if (emu->audigy) {
1407 for (reg = saved_regs_audigy; *reg != 0xff; reg++)
1408 for (i = 0; i < NUM_G; i++, val++)
1409 snd_emu10k1_ptr_write(emu, *reg, i, *val);
1410 }
1411}
1412#endif
1413
Linus Torvalds1da177e2005-04-16 15:20:36 -07001414/* memory.c */
1415EXPORT_SYMBOL(snd_emu10k1_synth_alloc);
1416EXPORT_SYMBOL(snd_emu10k1_synth_free);
1417EXPORT_SYMBOL(snd_emu10k1_synth_bzero);
1418EXPORT_SYMBOL(snd_emu10k1_synth_copy_from_user);
1419EXPORT_SYMBOL(snd_emu10k1_memblk_map);
1420/* voice.c */
1421EXPORT_SYMBOL(snd_emu10k1_voice_alloc);
1422EXPORT_SYMBOL(snd_emu10k1_voice_free);
1423/* io.c */
1424EXPORT_SYMBOL(snd_emu10k1_ptr_read);
1425EXPORT_SYMBOL(snd_emu10k1_ptr_write);