blob: cec7305b77e1dc6f88fd63c09db24e58c09b8228 [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
James Courtier-Dutton18f3c592005-12-21 22:05:29 +010095static unsigned int spi_dac_init[] = {
96 0x00ff,
97 0x02ff,
98 0x0400,
99 0x0520,
100 0x0600,
101 0x08ff,
102 0x0aff,
103 0x0cff,
104 0x0eff,
105 0x10ff,
106 0x1200,
107 0x1400,
108 0x1480,
109 0x1800,
110 0x1aff,
111 0x1cff,
112 0x1e00,
113 0x0530,
114 0x0602,
115 0x0622,
116 0x1400,
117};
118
Takashi Iwai09668b42005-11-17 16:14:10 +0100119static int snd_emu10k1_init(struct snd_emu10k1 *emu, int enable_ir, int resume)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700120{
Linus Torvalds1da177e2005-04-16 15:20:36 -0700121 unsigned int silent_page;
Takashi Iwai09668b42005-11-17 16:14:10 +0100122 int ch;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700123
124 /* disable audio and lock cache */
Takashi Iwai09668b42005-11-17 16:14:10 +0100125 outl(HCFG_LOCKSOUNDCACHE | HCFG_LOCKTANKCACHE_MASK | HCFG_MUTEBUTTONENABLE,
126 emu->port + HCFG);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700127
128 /* reset recording buffers */
129 snd_emu10k1_ptr_write(emu, MICBS, 0, ADCBS_BUFSIZE_NONE);
130 snd_emu10k1_ptr_write(emu, MICBA, 0, 0);
131 snd_emu10k1_ptr_write(emu, FXBS, 0, ADCBS_BUFSIZE_NONE);
132 snd_emu10k1_ptr_write(emu, FXBA, 0, 0);
133 snd_emu10k1_ptr_write(emu, ADCBS, 0, ADCBS_BUFSIZE_NONE);
134 snd_emu10k1_ptr_write(emu, ADCBA, 0, 0);
135
136 /* disable channel interrupt */
137 outl(0, emu->port + INTE);
138 snd_emu10k1_ptr_write(emu, CLIEL, 0, 0);
139 snd_emu10k1_ptr_write(emu, CLIEH, 0, 0);
140 snd_emu10k1_ptr_write(emu, SOLEL, 0, 0);
141 snd_emu10k1_ptr_write(emu, SOLEH, 0, 0);
142
143 if (emu->audigy){
144 /* set SPDIF bypass mode */
145 snd_emu10k1_ptr_write(emu, SPBYPASS, 0, SPBYPASS_FORMAT);
146 /* enable rear left + rear right AC97 slots */
Takashi Iwai09668b42005-11-17 16:14:10 +0100147 snd_emu10k1_ptr_write(emu, AC97SLOT, 0, AC97SLOT_REAR_RIGHT |
148 AC97SLOT_REAR_LEFT);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700149 }
150
151 /* init envelope engine */
Takashi Iwai09668b42005-11-17 16:14:10 +0100152 for (ch = 0; ch < NUM_G; ch++)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700153 snd_emu10k1_voice_init(emu, ch);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700154
Takashi Iwai09668b42005-11-17 16:14:10 +0100155 snd_emu10k1_ptr_write(emu, SPCS0, 0, emu->spdif_bits[0]);
156 snd_emu10k1_ptr_write(emu, SPCS1, 0, emu->spdif_bits[1]);
157 snd_emu10k1_ptr_write(emu, SPCS2, 0, emu->spdif_bits[2]);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700158
Lee Revell2b637da2005-03-30 13:51:18 +0200159 if (emu->card_capabilities->ca0151_chip) { /* audigy2 */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700160 /* Hacks for Alice3 to work independent of haP16V driver */
161 u32 tmp;
162
163 //Setup SRCMulti_I2S SamplingRate
164 tmp = snd_emu10k1_ptr_read(emu, A_SPDIF_SAMPLERATE, 0);
165 tmp &= 0xfffff1ff;
166 tmp |= (0x2<<9);
167 snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, 0, tmp);
168
169 /* Setup SRCSel (Enable Spdif,I2S SRCMulti) */
170 snd_emu10k1_ptr20_write(emu, SRCSel, 0, 0x14);
171 /* Setup SRCMulti Input Audio Enable */
172 /* Use 0xFFFFFFFF to enable P16V sounds. */
173 snd_emu10k1_ptr20_write(emu, SRCMULTI_ENABLE, 0, 0xFFFFFFFF);
174
175 /* Enabled Phased (8-channel) P16V playback */
176 outl(0x0201, emu->port + HCFG2);
177 /* Set playback routing. */
James Courtier-Duttonfd9a98e2005-04-10 15:43:35 +0200178 snd_emu10k1_ptr20_write(emu, CAPTURE_P16V_SOURCE, 0, 0x78e4);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700179 }
James Courtier-Duttone0474e52005-07-02 16:33:34 +0200180 if (emu->card_capabilities->ca0108_chip) { /* audigy2 Value */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700181 /* Hacks for Alice3 to work independent of haP16V driver */
182 u32 tmp;
183
Takashi Iwai09668b42005-11-17 16:14:10 +0100184 snd_printk(KERN_INFO "Audigy2 value: Special config.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700185 //Setup SRCMulti_I2S SamplingRate
186 tmp = snd_emu10k1_ptr_read(emu, A_SPDIF_SAMPLERATE, 0);
187 tmp &= 0xfffff1ff;
188 tmp |= (0x2<<9);
189 snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, 0, tmp);
190
191 /* Setup SRCSel (Enable Spdif,I2S SRCMulti) */
192 outl(0x600000, emu->port + 0x20);
193 outl(0x14, emu->port + 0x24);
194
195 /* Setup SRCMulti Input Audio Enable */
196 outl(0x7b0000, emu->port + 0x20);
197 outl(0xFF000000, emu->port + 0x24);
198
199 /* Setup SPDIF Out Audio Enable */
200 /* The Audigy 2 Value has a separate SPDIF out,
201 * so no need for a mixer switch
202 */
203 outl(0x7a0000, emu->port + 0x20);
204 outl(0xFF000000, emu->port + 0x24);
205 tmp = inl(emu->port + A_IOCFG) & ~0x8; /* Clear bit 3 */
206 outl(tmp, emu->port + A_IOCFG);
207 }
James Courtier-Dutton27fe8642005-12-21 15:06:08 +0100208 if (emu->card_capabilities->spi_dac) { /* Audigy 2 ZS Notebook with DAC Wolfson WM8768/WM8568 */
James Courtier-Dutton18f3c592005-12-21 22:05:29 +0100209 int size, n;
210
211 size = ARRAY_SIZE(spi_dac_init);
212 for (n=0; n < size; n++)
213 snd_emu10k1_spi_write(emu, spi_dac_init[n]);
214
James Courtier-Dutton27fe8642005-12-21 15:06:08 +0100215 snd_emu10k1_ptr20_write(emu, 0x60, 0, 0x10);
James Courtier-Duttonccadc3e2005-12-21 15:31:02 +0100216 /* Enable GPIOs
217 * GPIO0: Unknown
218 * GPIO1: Speakers-enabled.
219 * GPIO2: Unknown
220 * GPIO3: Unknown
221 * GPIO4: IEC958 Output on.
222 * GPIO5: Unknown
223 * GPIO6: Unknown
224 * GPIO7: Unknown
225 */
226 outl(0x76, emu->port + A_IOCFG); /* Windows uses 0x3f76 */
227
James Courtier-Dutton27fe8642005-12-21 15:06:08 +0100228 }
229
Linus Torvalds1da177e2005-04-16 15:20:36 -0700230 snd_emu10k1_ptr_write(emu, PTB, 0, emu->ptb_pages.addr);
231 snd_emu10k1_ptr_write(emu, TCB, 0, 0); /* taken from original driver */
232 snd_emu10k1_ptr_write(emu, TCBS, 0, 4); /* taken from original driver */
233
234 silent_page = (emu->silent_page.addr << 1) | MAP_PTI_MASK;
235 for (ch = 0; ch < NUM_G; ch++) {
236 snd_emu10k1_ptr_write(emu, MAPA, ch, silent_page);
237 snd_emu10k1_ptr_write(emu, MAPB, ch, silent_page);
238 }
239
240 /*
241 * Hokay, setup HCFG
242 * Mute Disable Audio = 0
243 * Lock Tank Memory = 1
244 * Lock Sound Memory = 0
245 * Auto Mute = 1
246 */
247 if (emu->audigy) {
248 if (emu->revision == 4) /* audigy2 */
249 outl(HCFG_AUDIOENABLE |
250 HCFG_AC3ENABLE_CDSPDIF |
251 HCFG_AC3ENABLE_GPSPDIF |
252 HCFG_AUTOMUTE | HCFG_JOYENABLE, emu->port + HCFG);
253 else
254 outl(HCFG_AUTOMUTE | HCFG_JOYENABLE, emu->port + HCFG);
James Courtier-Duttone0474e52005-07-02 16:33:34 +0200255 /* FIXME: Remove all these emu->model and replace it with a card recognition parameter,
256 * e.g. card_capabilities->joystick */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700257 } else if (emu->model == 0x20 ||
258 emu->model == 0xc400 ||
259 (emu->model == 0x21 && emu->revision < 6))
260 outl(HCFG_LOCKTANKCACHE_MASK | HCFG_AUTOMUTE, emu->port + HCFG);
261 else
262 // With on-chip joystick
263 outl(HCFG_LOCKTANKCACHE_MASK | HCFG_AUTOMUTE | HCFG_JOYENABLE, emu->port + HCFG);
264
265 if (enable_ir) { /* enable IR for SB Live */
James Courtier-Dutton19b99fb2005-12-04 18:03:03 +0100266 if ( emu->card_capabilities->emu1212m) {
267 ; /* Disable all access to A_IOCFG for the emu1212m */
268 } else if (emu->audigy) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700269 unsigned int reg = inl(emu->port + A_IOCFG);
270 outl(reg | A_IOCFG_GPOUT2, emu->port + A_IOCFG);
271 udelay(500);
272 outl(reg | A_IOCFG_GPOUT1 | A_IOCFG_GPOUT2, emu->port + A_IOCFG);
273 udelay(100);
274 outl(reg, emu->port + A_IOCFG);
275 } else {
276 unsigned int reg = inl(emu->port + HCFG);
277 outl(reg | HCFG_GPOUT2, emu->port + HCFG);
278 udelay(500);
279 outl(reg | HCFG_GPOUT1 | HCFG_GPOUT2, emu->port + HCFG);
280 udelay(100);
281 outl(reg, emu->port + HCFG);
282 }
283 }
284
James Courtier-Dutton19b99fb2005-12-04 18:03:03 +0100285 if ( emu->card_capabilities->emu1212m) {
286 ; /* Disable all access to A_IOCFG for the emu1212m */
287 } else if (emu->audigy) { /* enable analog output */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700288 unsigned int reg = inl(emu->port + A_IOCFG);
289 outl(reg | A_IOCFG_GPOUT0, emu->port + A_IOCFG);
290 }
291
Takashi Iwai09668b42005-11-17 16:14:10 +0100292 return 0;
293}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700294
Takashi Iwai09668b42005-11-17 16:14:10 +0100295static void snd_emu10k1_audio_enable(struct snd_emu10k1 *emu)
296{
Linus Torvalds1da177e2005-04-16 15:20:36 -0700297 /*
298 * Enable the audio bit
299 */
300 outl(inl(emu->port + HCFG) | HCFG_AUDIOENABLE, emu->port + HCFG);
301
302 /* Enable analog/digital outs on audigy */
James Courtier-Dutton19b99fb2005-12-04 18:03:03 +0100303 if ( emu->card_capabilities->emu1212m) {
304 ; /* Disable all access to A_IOCFG for the emu1212m */
305 } else if (emu->audigy) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700306 outl(inl(emu->port + A_IOCFG) & ~0x44, emu->port + A_IOCFG);
307
James Courtier-Duttone0474e52005-07-02 16:33:34 +0200308 if (emu->card_capabilities->ca0151_chip) { /* audigy2 */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700309 /* Unmute Analog now. Set GPO6 to 1 for Apollo.
310 * This has to be done after init ALice3 I2SOut beyond 48KHz.
311 * So, sequence is important. */
312 outl(inl(emu->port + A_IOCFG) | 0x0040, emu->port + A_IOCFG);
James Courtier-Duttone0474e52005-07-02 16:33:34 +0200313 } else if (emu->card_capabilities->ca0108_chip) { /* audigy2 value */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700314 /* Unmute Analog now. */
315 outl(inl(emu->port + A_IOCFG) | 0x0060, emu->port + A_IOCFG);
316 } else {
317 /* Disable routing from AC97 line out to Front speakers */
318 outl(inl(emu->port + A_IOCFG) | 0x0080, emu->port + A_IOCFG);
319 }
320 }
321
322#if 0
323 {
324 unsigned int tmp;
325 /* FIXME: the following routine disables LiveDrive-II !! */
326 // TOSLink detection
327 emu->tos_link = 0;
328 tmp = inl(emu->port + HCFG);
329 if (tmp & (HCFG_GPINPUT0 | HCFG_GPINPUT1)) {
330 outl(tmp|0x800, emu->port + HCFG);
331 udelay(50);
332 if (tmp != (inl(emu->port + HCFG) & ~0x800)) {
333 emu->tos_link = 1;
334 outl(tmp, emu->port + HCFG);
335 }
336 }
337 }
338#endif
339
340 snd_emu10k1_intr_enable(emu, INTE_PCIERRORENABLE);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700341}
342
Takashi Iwai09668b42005-11-17 16:14:10 +0100343int snd_emu10k1_done(struct snd_emu10k1 * emu)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700344{
345 int ch;
346
347 outl(0, emu->port + INTE);
348
349 /*
350 * Shutdown the chip
351 */
352 for (ch = 0; ch < NUM_G; ch++)
353 snd_emu10k1_ptr_write(emu, DCYSUSV, ch, 0);
354 for (ch = 0; ch < NUM_G; ch++) {
355 snd_emu10k1_ptr_write(emu, VTFT, ch, 0);
356 snd_emu10k1_ptr_write(emu, CVCF, ch, 0);
357 snd_emu10k1_ptr_write(emu, PTRX, ch, 0);
358 snd_emu10k1_ptr_write(emu, CPF, ch, 0);
359 }
360
361 /* reset recording buffers */
362 snd_emu10k1_ptr_write(emu, MICBS, 0, 0);
363 snd_emu10k1_ptr_write(emu, MICBA, 0, 0);
364 snd_emu10k1_ptr_write(emu, FXBS, 0, 0);
365 snd_emu10k1_ptr_write(emu, FXBA, 0, 0);
366 snd_emu10k1_ptr_write(emu, FXWC, 0, 0);
367 snd_emu10k1_ptr_write(emu, ADCBS, 0, ADCBS_BUFSIZE_NONE);
368 snd_emu10k1_ptr_write(emu, ADCBA, 0, 0);
369 snd_emu10k1_ptr_write(emu, TCBS, 0, TCBS_BUFFSIZE_16K);
370 snd_emu10k1_ptr_write(emu, TCB, 0, 0);
371 if (emu->audigy)
372 snd_emu10k1_ptr_write(emu, A_DBG, 0, A_DBG_SINGLE_STEP);
373 else
374 snd_emu10k1_ptr_write(emu, DBG, 0, EMU10K1_DBG_SINGLE_STEP);
375
376 /* disable channel interrupt */
377 snd_emu10k1_ptr_write(emu, CLIEL, 0, 0);
378 snd_emu10k1_ptr_write(emu, CLIEH, 0, 0);
379 snd_emu10k1_ptr_write(emu, SOLEL, 0, 0);
380 snd_emu10k1_ptr_write(emu, SOLEH, 0, 0);
381
Linus Torvalds1da177e2005-04-16 15:20:36 -0700382 /* disable audio and lock cache */
383 outl(HCFG_LOCKSOUNDCACHE | HCFG_LOCKTANKCACHE_MASK | HCFG_MUTEBUTTONENABLE, emu->port + HCFG);
384 snd_emu10k1_ptr_write(emu, PTB, 0, 0);
385
Linus Torvalds1da177e2005-04-16 15:20:36 -0700386 return 0;
387}
388
389/*************************************************************************
390 * ECARD functional implementation
391 *************************************************************************/
392
393/* In A1 Silicon, these bits are in the HC register */
394#define HOOKN_BIT (1L << 12)
395#define HANDN_BIT (1L << 11)
396#define PULSEN_BIT (1L << 10)
397
398#define EC_GDI1 (1 << 13)
399#define EC_GDI0 (1 << 14)
400
401#define EC_NUM_CONTROL_BITS 20
402
403#define EC_AC3_DATA_SELN 0x0001L
404#define EC_EE_DATA_SEL 0x0002L
405#define EC_EE_CNTRL_SELN 0x0004L
406#define EC_EECLK 0x0008L
407#define EC_EECS 0x0010L
408#define EC_EESDO 0x0020L
409#define EC_TRIM_CSN 0x0040L
410#define EC_TRIM_SCLK 0x0080L
411#define EC_TRIM_SDATA 0x0100L
412#define EC_TRIM_MUTEN 0x0200L
413#define EC_ADCCAL 0x0400L
414#define EC_ADCRSTN 0x0800L
415#define EC_DACCAL 0x1000L
416#define EC_DACMUTEN 0x2000L
417#define EC_LEDN 0x4000L
418
419#define EC_SPDIF0_SEL_SHIFT 15
420#define EC_SPDIF1_SEL_SHIFT 17
421#define EC_SPDIF0_SEL_MASK (0x3L << EC_SPDIF0_SEL_SHIFT)
422#define EC_SPDIF1_SEL_MASK (0x7L << EC_SPDIF1_SEL_SHIFT)
423#define EC_SPDIF0_SELECT(_x) (((_x) << EC_SPDIF0_SEL_SHIFT) & EC_SPDIF0_SEL_MASK)
424#define EC_SPDIF1_SELECT(_x) (((_x) << EC_SPDIF1_SEL_SHIFT) & EC_SPDIF1_SEL_MASK)
425#define EC_CURRENT_PROM_VERSION 0x01 /* Self-explanatory. This should
426 * be incremented any time the EEPROM's
427 * format is changed. */
428
429#define EC_EEPROM_SIZE 0x40 /* ECARD EEPROM has 64 16-bit words */
430
431/* Addresses for special values stored in to EEPROM */
432#define EC_PROM_VERSION_ADDR 0x20 /* Address of the current prom version */
433#define EC_BOARDREV0_ADDR 0x21 /* LSW of board rev */
434#define EC_BOARDREV1_ADDR 0x22 /* MSW of board rev */
435
436#define EC_LAST_PROMFILE_ADDR 0x2f
437
438#define EC_SERIALNUM_ADDR 0x30 /* First word of serial number. The
439 * can be up to 30 characters in length
440 * and is stored as a NULL-terminated
441 * ASCII string. Any unused bytes must be
442 * filled with zeros */
443#define EC_CHECKSUM_ADDR 0x3f /* Location at which checksum is stored */
444
445
446/* Most of this stuff is pretty self-evident. According to the hardware
447 * dudes, we need to leave the ADCCAL bit low in order to avoid a DC
448 * offset problem. Weird.
449 */
450#define EC_RAW_RUN_MODE (EC_DACMUTEN | EC_ADCRSTN | EC_TRIM_MUTEN | \
451 EC_TRIM_CSN)
452
453
454#define EC_DEFAULT_ADC_GAIN 0xC4C4
455#define EC_DEFAULT_SPDIF0_SEL 0x0
456#define EC_DEFAULT_SPDIF1_SEL 0x4
457
458/**************************************************************************
459 * @func Clock bits into the Ecard's control latch. The Ecard uses a
460 * control latch will is loaded bit-serially by toggling the Modem control
461 * lines from function 2 on the E8010. This function hides these details
462 * and presents the illusion that we are actually writing to a distinct
463 * register.
464 */
465
Takashi Iwaieb4698f2005-11-17 14:50:13 +0100466static void snd_emu10k1_ecard_write(struct snd_emu10k1 * emu, unsigned int value)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700467{
468 unsigned short count;
469 unsigned int data;
470 unsigned long hc_port;
471 unsigned int hc_value;
472
473 hc_port = emu->port + HCFG;
474 hc_value = inl(hc_port) & ~(HOOKN_BIT | HANDN_BIT | PULSEN_BIT);
475 outl(hc_value, hc_port);
476
477 for (count = 0; count < EC_NUM_CONTROL_BITS; count++) {
478
479 /* Set up the value */
480 data = ((value & 0x1) ? PULSEN_BIT : 0);
481 value >>= 1;
482
483 outl(hc_value | data, hc_port);
484
485 /* Clock the shift register */
486 outl(hc_value | data | HANDN_BIT, hc_port);
487 outl(hc_value | data, hc_port);
488 }
489
490 /* Latch the bits */
491 outl(hc_value | HOOKN_BIT, hc_port);
492 outl(hc_value, hc_port);
493}
494
495/**************************************************************************
496 * @func Set the gain of the ECARD's CS3310 Trim/gain controller. The
497 * trim value consists of a 16bit value which is composed of two
498 * 8 bit gain/trim values, one for the left channel and one for the
499 * right channel. The following table maps from the Gain/Attenuation
500 * value in decibels into the corresponding bit pattern for a single
501 * channel.
502 */
503
Takashi Iwaieb4698f2005-11-17 14:50:13 +0100504static void snd_emu10k1_ecard_setadcgain(struct snd_emu10k1 * emu,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700505 unsigned short gain)
506{
507 unsigned int bit;
508
509 /* Enable writing to the TRIM registers */
510 snd_emu10k1_ecard_write(emu, emu->ecard_ctrl & ~EC_TRIM_CSN);
511
512 /* Do it again to insure that we meet hold time requirements */
513 snd_emu10k1_ecard_write(emu, emu->ecard_ctrl & ~EC_TRIM_CSN);
514
515 for (bit = (1 << 15); bit; bit >>= 1) {
516 unsigned int value;
517
518 value = emu->ecard_ctrl & ~(EC_TRIM_CSN | EC_TRIM_SDATA);
519
520 if (gain & bit)
521 value |= EC_TRIM_SDATA;
522
523 /* Clock the bit */
524 snd_emu10k1_ecard_write(emu, value);
525 snd_emu10k1_ecard_write(emu, value | EC_TRIM_SCLK);
526 snd_emu10k1_ecard_write(emu, value);
527 }
528
529 snd_emu10k1_ecard_write(emu, emu->ecard_ctrl);
530}
531
Takashi Iwaieb4698f2005-11-17 14:50:13 +0100532static int __devinit snd_emu10k1_ecard_init(struct snd_emu10k1 * emu)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700533{
534 unsigned int hc_value;
535
536 /* Set up the initial settings */
537 emu->ecard_ctrl = EC_RAW_RUN_MODE |
538 EC_SPDIF0_SELECT(EC_DEFAULT_SPDIF0_SEL) |
539 EC_SPDIF1_SELECT(EC_DEFAULT_SPDIF1_SEL);
540
541 /* Step 0: Set the codec type in the hardware control register
542 * and enable audio output */
543 hc_value = inl(emu->port + HCFG);
544 outl(hc_value | HCFG_AUDIOENABLE | HCFG_CODECFORMAT_I2S, emu->port + HCFG);
545 inl(emu->port + HCFG);
546
547 /* Step 1: Turn off the led and deassert TRIM_CS */
548 snd_emu10k1_ecard_write(emu, EC_ADCCAL | EC_LEDN | EC_TRIM_CSN);
549
550 /* Step 2: Calibrate the ADC and DAC */
551 snd_emu10k1_ecard_write(emu, EC_DACCAL | EC_LEDN | EC_TRIM_CSN);
552
553 /* Step 3: Wait for awhile; XXX We can't get away with this
554 * under a real operating system; we'll need to block and wait that
555 * way. */
556 snd_emu10k1_wait(emu, 48000);
557
558 /* Step 4: Switch off the DAC and ADC calibration. Note
559 * That ADC_CAL is actually an inverted signal, so we assert
560 * it here to stop calibration. */
561 snd_emu10k1_ecard_write(emu, EC_ADCCAL | EC_LEDN | EC_TRIM_CSN);
562
563 /* Step 4: Switch into run mode */
564 snd_emu10k1_ecard_write(emu, emu->ecard_ctrl);
565
566 /* Step 5: Set the analog input gain */
567 snd_emu10k1_ecard_setadcgain(emu, EC_DEFAULT_ADC_GAIN);
568
569 return 0;
570}
571
Takashi Iwaieb4698f2005-11-17 14:50:13 +0100572static int __devinit snd_emu10k1_cardbus_init(struct snd_emu10k1 * emu)
James Courtier-Duttond83c6712005-10-31 10:27:41 +0000573{
574 unsigned long special_port;
575 unsigned int value;
576
577 /* Special initialisation routine
578 * before the rest of the IO-Ports become active.
579 */
580 special_port = emu->port + 0x38;
581 value = inl(special_port);
582 outl(0x00d00000, special_port);
583 value = inl(special_port);
584 outl(0x00d00001, special_port);
585 value = inl(special_port);
586 outl(0x00d0005f, special_port);
587 value = inl(special_port);
588 outl(0x00d0007f, special_port);
589 value = inl(special_port);
590 outl(0x0090007f, special_port);
591 value = inl(special_port);
592
James Courtier-Duttone2b15f82005-11-11 23:39:05 +0100593 snd_emu10k1_ptr20_write(emu, TINA2_VOLUME, 0, 0xfefefefe); /* Defaults to 0x30303030 */
James Courtier-Duttond83c6712005-10-31 10:27:41 +0000594 return 0;
595}
596
James Courtier-Dutton19b99fb2005-12-04 18:03:03 +0100597static int snd_emu1212m_fpga_write(struct snd_emu10k1 * emu, int reg, int value)
598{
599 if (reg<0 || reg>0x3f)
600 return 1;
601 reg+=0x40; /* 0x40 upwards are registers. */
602 if (value<0 || value>0x3f) /* 0 to 0x3f are values */
603 return 1;
604 outl(reg, emu->port + A_IOCFG);
605 outl(reg | 0x80, emu->port + A_IOCFG); /* High bit clocks the value into the fpga. */
606 outl(value, emu->port + A_IOCFG);
607 outl(value | 0x80 , emu->port + A_IOCFG); /* High bit clocks the value into the fpga. */
608
609 return 0;
610}
611
612static int snd_emu1212m_fpga_read(struct snd_emu10k1 * emu, int reg, int *value)
613{
614 if (reg<0 || reg>0x3f)
615 return 1;
616 reg+=0x40; /* 0x40 upwards are registers. */
617 outl(reg, emu->port + A_IOCFG);
618 outl(reg | 0x80, emu->port + A_IOCFG); /* High bit clocks the value into the fpga. */
619 *value = inl(emu->port + A_IOCFG);
620
621 return 0;
622}
623
624static int snd_emu1212m_fpga_netlist_write(struct snd_emu10k1 * emu, int reg, int value)
625{
626 snd_emu1212m_fpga_write(emu, 0x00, ((reg >> 8) & 0x3f) );
627 snd_emu1212m_fpga_write(emu, 0x01, (reg & 0x3f) );
628 snd_emu1212m_fpga_write(emu, 0x02, ((value >> 8) & 0x3f) );
629 snd_emu1212m_fpga_write(emu, 0x03, (value & 0x3f) );
630
631 return 0;
632}
633
634static int __devinit snd_emu10k1_emu1212m_init(struct snd_emu10k1 * emu)
635{
636 unsigned int i;
637 int tmp;
638
639 snd_printk(KERN_ERR "emu1212m: Special config.\n");
640 outl(0x0005a00c, emu->port + HCFG);
641 outl(0x0005a004, emu->port + HCFG);
642 outl(0x0005a000, emu->port + HCFG);
643 outl(0x0005a000, emu->port + HCFG);
644
645 snd_emu1212m_fpga_read(emu, 0x22, &tmp );
646 snd_emu1212m_fpga_read(emu, 0x23, &tmp );
647 snd_emu1212m_fpga_read(emu, 0x24, &tmp );
648 snd_emu1212m_fpga_write(emu, 0x04, 0x01 );
649 snd_emu1212m_fpga_read(emu, 0x0b, &tmp );
650 snd_emu1212m_fpga_write(emu, 0x0b, 0x01 );
651 snd_emu1212m_fpga_read(emu, 0x10, &tmp );
652 snd_emu1212m_fpga_write(emu, 0x10, 0x00 );
653 snd_emu1212m_fpga_read(emu, 0x11, &tmp );
654 snd_emu1212m_fpga_write(emu, 0x11, 0x30 );
655 snd_emu1212m_fpga_read(emu, 0x13, &tmp );
656 snd_emu1212m_fpga_write(emu, 0x13, 0x0f );
657 snd_emu1212m_fpga_read(emu, 0x11, &tmp );
658 snd_emu1212m_fpga_write(emu, 0x11, 0x30 );
659 snd_emu1212m_fpga_read(emu, 0x0a, &tmp );
660 snd_emu1212m_fpga_write(emu, 0x0a, 0x10 );
661 snd_emu1212m_fpga_write(emu, 0x0c, 0x19 );
662 snd_emu1212m_fpga_write(emu, 0x12, 0x0c );
663 snd_emu1212m_fpga_write(emu, 0x09, 0x0f );
664 snd_emu1212m_fpga_write(emu, 0x06, 0x00 );
665 snd_emu1212m_fpga_write(emu, 0x05, 0x00 );
666 snd_emu1212m_fpga_write(emu, 0x0e, 0x12 );
667 snd_emu1212m_fpga_netlist_write(emu, 0x0000, 0x0200);
668 snd_emu1212m_fpga_netlist_write(emu, 0x0001, 0x0201);
669 snd_emu1212m_fpga_netlist_write(emu, 0x0002, 0x0500);
670 snd_emu1212m_fpga_netlist_write(emu, 0x0003, 0x0501);
671 snd_emu1212m_fpga_netlist_write(emu, 0x0004, 0x0400);
672 snd_emu1212m_fpga_netlist_write(emu, 0x0005, 0x0401);
673 snd_emu1212m_fpga_netlist_write(emu, 0x0006, 0x0402);
674 snd_emu1212m_fpga_netlist_write(emu, 0x0007, 0x0403);
675 snd_emu1212m_fpga_netlist_write(emu, 0x0008, 0x0404);
676 snd_emu1212m_fpga_netlist_write(emu, 0x0009, 0x0405);
677 snd_emu1212m_fpga_netlist_write(emu, 0x000a, 0x0406);
678 snd_emu1212m_fpga_netlist_write(emu, 0x000b, 0x0407);
679 snd_emu1212m_fpga_netlist_write(emu, 0x000c, 0x0100);
680 snd_emu1212m_fpga_netlist_write(emu, 0x000d, 0x0104);
681 snd_emu1212m_fpga_netlist_write(emu, 0x000e, 0x0200);
682 snd_emu1212m_fpga_netlist_write(emu, 0x000f, 0x0201);
683 for (i=0;i < 0x20;i++) {
684 snd_emu1212m_fpga_netlist_write(emu, 0x0100+i, 0x0000);
685 }
686 for (i=0;i < 4;i++) {
687 snd_emu1212m_fpga_netlist_write(emu, 0x0200+i, 0x0000);
688 }
689 for (i=0;i < 7;i++) {
690 snd_emu1212m_fpga_netlist_write(emu, 0x0300+i, 0x0000);
691 }
692 for (i=0;i < 7;i++) {
693 snd_emu1212m_fpga_netlist_write(emu, 0x0400+i, 0x0000);
694 }
695 snd_emu1212m_fpga_netlist_write(emu, 0x0500, 0x0108);
696 snd_emu1212m_fpga_netlist_write(emu, 0x0501, 0x010c);
697 snd_emu1212m_fpga_netlist_write(emu, 0x0600, 0x0110);
698 snd_emu1212m_fpga_netlist_write(emu, 0x0601, 0x0114);
699 snd_emu1212m_fpga_netlist_write(emu, 0x0700, 0x0118);
700 snd_emu1212m_fpga_netlist_write(emu, 0x0701, 0x011c);
701 snd_emu1212m_fpga_write(emu, 0x07, 0x01 );
702
703 snd_emu1212m_fpga_read(emu, 0x21, &tmp );
704
705 outl(0x0000a000, emu->port + HCFG);
706 outl(0x0000a001, emu->port + HCFG);
707 /* Initial boot complete. Now patches */
708
709 snd_emu1212m_fpga_read(emu, 0x21, &tmp );
710 snd_emu1212m_fpga_write(emu, 0x0c, 0x19 );
711 snd_emu1212m_fpga_write(emu, 0x12, 0x0c );
712 snd_emu1212m_fpga_write(emu, 0x0c, 0x19 );
713 snd_emu1212m_fpga_write(emu, 0x12, 0x0c );
714 snd_emu1212m_fpga_read(emu, 0x0a, &tmp );
715 snd_emu1212m_fpga_write(emu, 0x0a, 0x10 );
716
717 snd_emu1212m_fpga_read(emu, 0x20, &tmp );
718 snd_emu1212m_fpga_read(emu, 0x21, &tmp );
719
720 snd_emu1212m_fpga_netlist_write(emu, 0x0300, 0x0312);
721 snd_emu1212m_fpga_netlist_write(emu, 0x0301, 0x0313);
722 snd_emu1212m_fpga_netlist_write(emu, 0x0200, 0x0302);
723 snd_emu1212m_fpga_netlist_write(emu, 0x0201, 0x0303);
724
725 return 0;
726}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700727/*
728 * Create the EMU10K1 instance
729 */
730
Takashi Iwai09668b42005-11-17 16:14:10 +0100731#ifdef CONFIG_PM
732static int alloc_pm_buffer(struct snd_emu10k1 *emu);
733static void free_pm_buffer(struct snd_emu10k1 *emu);
734#endif
735
Takashi Iwaieb4698f2005-11-17 14:50:13 +0100736static int snd_emu10k1_free(struct snd_emu10k1 *emu)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700737{
738 if (emu->port) { /* avoid access to already used hardware */
739 snd_emu10k1_fx8010_tram_setup(emu, 0);
740 snd_emu10k1_done(emu);
Takashi Iwai09668b42005-11-17 16:14:10 +0100741 /* remove reserved page */
742 if (emu->reserved_page) {
743 snd_emu10k1_synth_free(emu, (struct snd_util_memblk *)emu->reserved_page);
744 emu->reserved_page = NULL;
745 }
746 snd_emu10k1_free_efx(emu);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700747 }
748 if (emu->memhdr)
749 snd_util_memhdr_free(emu->memhdr);
750 if (emu->silent_page.area)
751 snd_dma_free_pages(&emu->silent_page);
752 if (emu->ptb_pages.area)
753 snd_dma_free_pages(&emu->ptb_pages);
754 vfree(emu->page_ptr_table);
755 vfree(emu->page_addr_table);
Takashi Iwai09668b42005-11-17 16:14:10 +0100756#ifdef CONFIG_PM
757 free_pm_buffer(emu);
758#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700759 if (emu->irq >= 0)
760 free_irq(emu->irq, (void *)emu);
761 if (emu->port)
762 pci_release_regions(emu->pci);
Lee Revell2b637da2005-03-30 13:51:18 +0200763 if (emu->card_capabilities->ca0151_chip) /* P16V */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700764 snd_p16v_free(emu);
Takashi Iwai09668b42005-11-17 16:14:10 +0100765 pci_disable_device(emu->pci);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700766 kfree(emu);
767 return 0;
768}
769
Takashi Iwaieb4698f2005-11-17 14:50:13 +0100770static int snd_emu10k1_dev_free(struct snd_device *device)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700771{
Takashi Iwaieb4698f2005-11-17 14:50:13 +0100772 struct snd_emu10k1 *emu = device->device_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700773 return snd_emu10k1_free(emu);
774}
775
Takashi Iwaieb4698f2005-11-17 14:50:13 +0100776static struct snd_emu_chip_details emu_chip_details[] = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700777 /* 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 +0200778 /* Tested by James@superbug.co.uk 3rd July 2005 */
James Courtier-Dutton54efc962005-12-22 12:58:41 +0100779 /* DSP: CA0108-IAT
780 * DAC: CS4382-KQ
781 * ADC: Philips 1361T
782 * AC97: STAC9750
783 * CA0151: None
784 */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700785 {.vendor = 0x1102, .device = 0x0008, .subsystem = 0x10011102,
786 .driver = "Audigy2", .name = "Audigy 2 Value [SB0400]",
Takashi Iwaiaec72e02005-03-30 14:22:25 +0200787 .id = "Audigy2",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700788 .emu10k2_chip = 1,
789 .ca0108_chip = 1,
Peter Zubaj26689072005-04-01 11:15:07 +0200790 .spk71 = 1,
791 .ac97_chip = 1} ,
James Courtier-Duttond83c6712005-10-31 10:27:41 +0000792 /* Audigy 2 ZS Notebook Cardbus card.*/
James Courtier-Duttonf951fd32005-12-22 13:05:23 +0100793 /* Tested by James@superbug.co.uk 22th December 2005 */
794 /* Audio output 7.1/Headphones working.
795 * Digital output working. (AC3 not checked, only PCM)
796 * Audio inputs not tested.
797 */
798 /* DSP: Tiny2
799 * DAC: Wolfson WM8768/WM8568
800 * ADC: Wolfson WM8775
801 * AC97: None
802 * CA0151: None
803 */
James Courtier-Duttond83c6712005-10-31 10:27:41 +0000804 {.vendor = 0x1102, .device = 0x0008, .subsystem = 0x20011102,
805 .driver = "Audigy2", .name = "Audigy 2 ZS Notebook [SB0530]",
806 .id = "Audigy2",
807 .emu10k2_chip = 1,
808 .ca0108_chip = 1,
809 .ca_cardbus_chip = 1,
James Courtier-Dutton27fe8642005-12-21 15:06:08 +0100810 .spi_dac = 1,
James Courtier-Duttond83c6712005-10-31 10:27:41 +0000811 .spk71 = 1} ,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700812 {.vendor = 0x1102, .device = 0x0008,
813 .driver = "Audigy2", .name = "Audigy 2 Value [Unknown]",
Takashi Iwaiaec72e02005-03-30 14:22:25 +0200814 .id = "Audigy2",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700815 .emu10k2_chip = 1,
Peter Zubaj26689072005-04-01 11:15:07 +0200816 .ca0108_chip = 1,
817 .ac97_chip = 1} ,
James Courtier-Dutton7c1d5492005-07-10 11:50:36 +0200818 /* Tested by James@superbug.co.uk 8th July 2005. No sound available yet. */
819 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x40011102,
820 .driver = "Audigy2", .name = "E-mu 1212m [4001]",
821 .id = "EMU1212m",
822 .emu10k2_chip = 1,
823 .ca0102_chip = 1,
James Courtier-Dutton19b99fb2005-12-04 18:03:03 +0100824 .emu1212m = 1} ,
James Courtier-Dutton88dc0e52005-07-03 12:54:29 +0200825 /* Tested by James@superbug.co.uk 3rd July 2005 */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700826 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x20071102,
827 .driver = "Audigy2", .name = "Audigy 4 PRO [SB0380]",
Takashi Iwaiaec72e02005-03-30 14:22:25 +0200828 .id = "Audigy2",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700829 .emu10k2_chip = 1,
830 .ca0102_chip = 1,
831 .ca0151_chip = 1,
832 .spk71 = 1,
833 .spdif_bug = 1,
834 .ac97_chip = 1} ,
Lee Revellf6f8bb62005-11-07 14:59:19 +0100835 /* Tested by shane-alsa@cm.nu 5th Nov 2005 */
836 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x20061102,
837 .driver = "Audigy2", .name = "Audigy 2 [2006]",
838 .id = "Audigy2",
839 .emu10k2_chip = 1,
840 .ca0102_chip = 1,
841 .ca0151_chip = 1,
842 .spk71 = 1,
843 .spdif_bug = 1,
844 .ac97_chip = 1} ,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700845 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x20021102,
846 .driver = "Audigy2", .name = "Audigy 2 ZS [SB0350]",
Takashi Iwaiaec72e02005-03-30 14:22:25 +0200847 .id = "Audigy2",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700848 .emu10k2_chip = 1,
849 .ca0102_chip = 1,
850 .ca0151_chip = 1,
851 .spk71 = 1,
852 .spdif_bug = 1,
853 .ac97_chip = 1} ,
854 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x20011102,
855 .driver = "Audigy2", .name = "Audigy 2 ZS [2001]",
Takashi Iwaiaec72e02005-03-30 14:22:25 +0200856 .id = "Audigy2",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700857 .emu10k2_chip = 1,
858 .ca0102_chip = 1,
859 .ca0151_chip = 1,
860 .spk71 = 1,
861 .spdif_bug = 1,
862 .ac97_chip = 1} ,
James Courtier-Dutton54efc962005-12-22 12:58:41 +0100863 /* Audigy 2 */
864 /* Tested by James@superbug.co.uk 3rd July 2005 */
865 /* DSP: CA0102-IAT
866 * DAC: CS4382-KQ
867 * ADC: Philips 1361T
868 * AC97: STAC9721
869 * CA0151: Yes
870 */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700871 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x10071102,
872 .driver = "Audigy2", .name = "Audigy 2 [SB0240]",
Takashi Iwaiaec72e02005-03-30 14:22:25 +0200873 .id = "Audigy2",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700874 .emu10k2_chip = 1,
875 .ca0102_chip = 1,
876 .ca0151_chip = 1,
877 .spk71 = 1,
878 .spdif_bug = 1,
879 .ac97_chip = 1} ,
880 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x10051102,
881 .driver = "Audigy2", .name = "Audigy 2 EX [1005]",
Takashi Iwaiaec72e02005-03-30 14:22:25 +0200882 .id = "Audigy2",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700883 .emu10k2_chip = 1,
884 .ca0102_chip = 1,
885 .ca0151_chip = 1,
Lee Revell2f020aa2005-11-07 14:54:24 +0100886 .spk71 = 1,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700887 .spdif_bug = 1} ,
888 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x10021102,
889 .driver = "Audigy2", .name = "Audigy 2 Platinum [SB0240P]",
Takashi Iwaiaec72e02005-03-30 14:22:25 +0200890 .id = "Audigy2",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700891 .emu10k2_chip = 1,
892 .ca0102_chip = 1,
893 .ca0151_chip = 1,
894 .spk71 = 1,
895 .spdif_bug = 1,
896 .ac97_chip = 1} ,
Takashi Iwaibdaed502005-04-07 15:48:42 +0200897 {.vendor = 0x1102, .device = 0x0004, .revision = 0x04,
898 .driver = "Audigy2", .name = "Audigy 2 [Unknown]",
899 .id = "Audigy2",
900 .emu10k2_chip = 1,
901 .ca0102_chip = 1,
902 .ca0151_chip = 1,
903 .spdif_bug = 1,
904 .ac97_chip = 1} ,
Peter Zubaj26689072005-04-01 11:15:07 +0200905 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x00531102,
906 .driver = "Audigy", .name = "Audigy 1 [SB0090]",
907 .id = "Audigy",
908 .emu10k2_chip = 1,
909 .ca0102_chip = 1,
910 .ac97_chip = 1} ,
James Courtier-Duttonae3a72d2005-07-06 22:36:18 +0200911 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x00521102,
912 .driver = "Audigy", .name = "Audigy 1 ES [SB0160]",
913 .id = "Audigy",
914 .emu10k2_chip = 1,
915 .ca0102_chip = 1,
916 .spdif_bug = 1,
917 .ac97_chip = 1} ,
Arnaud Patarda6c17ec2005-05-27 12:31:34 +0200918 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x00511102,
919 .driver = "Audigy", .name = "Audigy 1 [SB0090]",
920 .id = "Audigy",
921 .emu10k2_chip = 1,
922 .ca0102_chip = 1,
923 .ac97_chip = 1} ,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700924 {.vendor = 0x1102, .device = 0x0004,
Takashi Iwaibdaed502005-04-07 15:48:42 +0200925 .driver = "Audigy", .name = "Audigy 1 [Unknown]",
Takashi Iwaiaec72e02005-03-30 14:22:25 +0200926 .id = "Audigy",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700927 .emu10k2_chip = 1,
928 .ca0102_chip = 1,
Peter Zubaj26689072005-04-01 11:15:07 +0200929 .ac97_chip = 1} ,
James Courtier-Duttona6f61922005-07-03 12:32:40 +0200930 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x806B1102,
931 .driver = "EMU10K1", .name = "SBLive! [SB0105]",
James Courtier-Dutton2b6b22f2005-06-18 13:50:22 +0200932 .id = "Live",
933 .emu10k1_chip = 1,
934 .ac97_chip = 1,
935 .sblive51 = 1} ,
936 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x806A1102,
937 .driver = "EMU10K1", .name = "SBLive! Value [SB0103]",
938 .id = "Live",
939 .emu10k1_chip = 1,
940 .ac97_chip = 1,
941 .sblive51 = 1} ,
James Courtier-Duttona6f61922005-07-03 12:32:40 +0200942 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80691102,
943 .driver = "EMU10K1", .name = "SBLive! Value [SB0101]",
944 .id = "Live",
945 .emu10k1_chip = 1,
946 .ac97_chip = 1,
947 .sblive51 = 1} ,
Lee Revellc6c0b842005-08-29 17:42:00 +0200948 /* Tested by Thomas Zehetbauer 27th Aug 2005 */
949 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80651102,
950 .driver = "EMU10K1", .name = "SB Live 5.1 [SB0220]",
951 .id = "Live",
952 .emu10k1_chip = 1,
953 .ac97_chip = 1,
954 .sblive51 = 1} ,
Gergely Tamasa8ee7292005-12-06 14:10:57 +0100955 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x100a1102,
956 .driver = "EMU10K1", .name = "SB Live 5.1 [SB0220]",
957 .id = "Live",
958 .emu10k1_chip = 1,
959 .ac97_chip = 1,
960 .sblive51 = 1} ,
James Courtier-Duttona6f61922005-07-03 12:32:40 +0200961 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80641102,
962 .driver = "EMU10K1", .name = "SB Live 5.1",
963 .id = "Live",
964 .emu10k1_chip = 1,
965 .ac97_chip = 1,
966 .sblive51 = 1} ,
James Courtier-Duttonafe0f1f2005-09-10 10:24:10 +0200967 /* Tested by alsa bugtrack user "hus" bug #1297 12th Aug 2005 */
James Courtier-Duttona6f61922005-07-03 12:32:40 +0200968 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80611102,
Takashi Iwaif12aa402005-09-30 16:56:59 +0200969 .driver = "EMU10K1", .name = "SBLive 5.1 [SB0060]",
James Courtier-Duttona6f61922005-07-03 12:32:40 +0200970 .id = "Live",
971 .emu10k1_chip = 1,
Takashi Iwaif12aa402005-09-30 16:56:59 +0200972 .ac97_chip = 2, /* ac97 is optional; both SBLive 5.1 and platinum
973 * share the same IDs!
974 */
James Courtier-Duttona6f61922005-07-03 12:32:40 +0200975 .sblive51 = 1} ,
976 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80511102,
977 .driver = "EMU10K1", .name = "SBLive! Value [CT4850]",
978 .id = "Live",
979 .emu10k1_chip = 1,
980 .ac97_chip = 1,
981 .sblive51 = 1} ,
982 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80401102,
983 .driver = "EMU10K1", .name = "SBLive! Platinum [CT4760P]",
984 .id = "Live",
985 .emu10k1_chip = 1,
986 .ac97_chip = 1} ,
987 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80321102,
988 .driver = "EMU10K1", .name = "SBLive! Value [CT4871]",
989 .id = "Live",
990 .emu10k1_chip = 1,
991 .ac97_chip = 1,
992 .sblive51 = 1} ,
993 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80311102,
994 .driver = "EMU10K1", .name = "SBLive! Value [CT4831]",
995 .id = "Live",
996 .emu10k1_chip = 1,
997 .ac97_chip = 1,
998 .sblive51 = 1} ,
999 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80281102,
1000 .driver = "EMU10K1", .name = "SBLive! Value [CT4870]",
1001 .id = "Live",
1002 .emu10k1_chip = 1,
1003 .ac97_chip = 1,
1004 .sblive51 = 1} ,
James Courtier-Dutton88dc0e52005-07-03 12:54:29 +02001005 /* Tested by James@superbug.co.uk 3rd July 2005 */
James Courtier-Duttona6f61922005-07-03 12:32:40 +02001006 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80271102,
1007 .driver = "EMU10K1", .name = "SBLive! Value [CT4832]",
1008 .id = "Live",
1009 .emu10k1_chip = 1,
1010 .ac97_chip = 1,
1011 .sblive51 = 1} ,
1012 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80261102,
1013 .driver = "EMU10K1", .name = "SBLive! Value [CT4830]",
1014 .id = "Live",
1015 .emu10k1_chip = 1,
1016 .ac97_chip = 1,
1017 .sblive51 = 1} ,
1018 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80231102,
1019 .driver = "EMU10K1", .name = "SB PCI512 [CT4790]",
1020 .id = "Live",
1021 .emu10k1_chip = 1,
1022 .ac97_chip = 1,
1023 .sblive51 = 1} ,
1024 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80221102,
1025 .driver = "EMU10K1", .name = "SBLive! Value [CT4780]",
1026 .id = "Live",
1027 .emu10k1_chip = 1,
1028 .ac97_chip = 1,
1029 .sblive51 = 1} ,
1030 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x40011102,
1031 .driver = "EMU10K1", .name = "E-mu APS [4001]",
1032 .id = "APS",
1033 .emu10k1_chip = 1,
1034 .ecard = 1} ,
1035 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x00211102,
1036 .driver = "EMU10K1", .name = "SBLive! [CT4620]",
1037 .id = "Live",
1038 .emu10k1_chip = 1,
1039 .ac97_chip = 1,
1040 .sblive51 = 1} ,
1041 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x00201102,
1042 .driver = "EMU10K1", .name = "SBLive! Value [CT4670]",
James Courtier-Dutton2b6b22f2005-06-18 13:50:22 +02001043 .id = "Live",
1044 .emu10k1_chip = 1,
1045 .ac97_chip = 1,
1046 .sblive51 = 1} ,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001047 {.vendor = 0x1102, .device = 0x0002,
1048 .driver = "EMU10K1", .name = "SB Live [Unknown]",
Takashi Iwaiaec72e02005-03-30 14:22:25 +02001049 .id = "Live",
Linus Torvalds1da177e2005-04-16 15:20:36 -07001050 .emu10k1_chip = 1,
Lee Revell2b637da2005-03-30 13:51:18 +02001051 .ac97_chip = 1,
1052 .sblive51 = 1} ,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001053 { } /* terminator */
1054};
1055
Takashi Iwaieb4698f2005-11-17 14:50:13 +01001056int __devinit snd_emu10k1_create(struct snd_card *card,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001057 struct pci_dev * pci,
1058 unsigned short extin_mask,
1059 unsigned short extout_mask,
1060 long max_cache_bytes,
1061 int enable_ir,
James Courtier-Duttone66bc8b2005-07-06 22:21:51 +02001062 uint subsystem,
Takashi Iwaieb4698f2005-11-17 14:50:13 +01001063 struct snd_emu10k1 ** remu)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001064{
Takashi Iwaieb4698f2005-11-17 14:50:13 +01001065 struct snd_emu10k1 *emu;
Takashi Iwai09668b42005-11-17 16:14:10 +01001066 int idx, err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001067 int is_audigy;
1068 unsigned char revision;
Takashi Iwai09668b42005-11-17 16:14:10 +01001069 unsigned int silent_page;
Takashi Iwaieb4698f2005-11-17 14:50:13 +01001070 const struct snd_emu_chip_details *c;
1071 static struct snd_device_ops ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001072 .dev_free = snd_emu10k1_dev_free,
1073 };
1074
1075 *remu = NULL;
1076
1077 /* enable PCI device */
1078 if ((err = pci_enable_device(pci)) < 0)
1079 return err;
1080
Takashi Iwaie560d8d2005-09-09 14:21:46 +02001081 emu = kzalloc(sizeof(*emu), GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001082 if (emu == NULL) {
1083 pci_disable_device(pci);
1084 return -ENOMEM;
1085 }
1086 emu->card = card;
1087 spin_lock_init(&emu->reg_lock);
1088 spin_lock_init(&emu->emu_lock);
1089 spin_lock_init(&emu->voice_lock);
1090 spin_lock_init(&emu->synth_lock);
1091 spin_lock_init(&emu->memblk_lock);
1092 init_MUTEX(&emu->ptb_lock);
1093 init_MUTEX(&emu->fx8010.lock);
1094 INIT_LIST_HEAD(&emu->mapped_link_head);
1095 INIT_LIST_HEAD(&emu->mapped_order_link_head);
1096 emu->pci = pci;
1097 emu->irq = -1;
1098 emu->synth = NULL;
1099 emu->get_synth_voice = NULL;
1100 /* read revision & serial */
1101 pci_read_config_byte(pci, PCI_REVISION_ID, &revision);
1102 emu->revision = revision;
1103 pci_read_config_dword(pci, PCI_SUBSYSTEM_VENDOR_ID, &emu->serial);
1104 pci_read_config_word(pci, PCI_SUBSYSTEM_ID, &emu->model);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001105 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);
1106
1107 for (c = emu_chip_details; c->vendor; c++) {
1108 if (c->vendor == pci->vendor && c->device == pci->device) {
James Courtier-Duttone66bc8b2005-07-06 22:21:51 +02001109 if (subsystem) {
1110 if (c->subsystem && (c->subsystem == subsystem) ) {
1111 break;
1112 } else continue;
1113 } else {
1114 if (c->subsystem && (c->subsystem != emu->serial) )
1115 continue;
1116 if (c->revision && c->revision != emu->revision)
1117 continue;
1118 }
Takashi Iwaibdaed502005-04-07 15:48:42 +02001119 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001120 }
1121 }
1122 if (c->vendor == 0) {
1123 snd_printk(KERN_ERR "emu10k1: Card not recognised\n");
1124 kfree(emu);
1125 pci_disable_device(pci);
1126 return -ENOENT;
1127 }
1128 emu->card_capabilities = c;
James Courtier-Duttone66bc8b2005-07-06 22:21:51 +02001129 if (c->subsystem && !subsystem)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001130 snd_printdd("Sound card name=%s\n", c->name);
James Courtier-Duttone66bc8b2005-07-06 22:21:51 +02001131 else if (subsystem)
1132 snd_printdd("Sound card name=%s, vendor=0x%x, device=0x%x, subsystem=0x%x. Forced to subsytem=0x%x\n",
1133 c->name, pci->vendor, pci->device, emu->serial, c->subsystem);
1134 else
1135 snd_printdd("Sound card name=%s, vendor=0x%x, device=0x%x, subsystem=0x%x.\n",
1136 c->name, pci->vendor, pci->device, emu->serial);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001137
Takashi Iwai85a655d2005-03-30 14:40:25 +02001138 if (!*card->id && c->id) {
1139 int i, n = 0;
Takashi Iwaiaec72e02005-03-30 14:22:25 +02001140 strlcpy(card->id, c->id, sizeof(card->id));
Takashi Iwai85a655d2005-03-30 14:40:25 +02001141 for (;;) {
1142 for (i = 0; i < snd_ecards_limit; i++) {
1143 if (snd_cards[i] && !strcmp(snd_cards[i]->id, card->id))
1144 break;
1145 }
1146 if (i >= snd_ecards_limit)
1147 break;
1148 n++;
1149 if (n >= SNDRV_CARDS)
1150 break;
1151 snprintf(card->id, sizeof(card->id), "%s_%d", c->id, n);
1152 }
1153 }
Takashi Iwaiaec72e02005-03-30 14:22:25 +02001154
Linus Torvalds1da177e2005-04-16 15:20:36 -07001155 is_audigy = emu->audigy = c->emu10k2_chip;
1156
1157 /* set the DMA transfer mask */
1158 emu->dma_mask = is_audigy ? AUDIGY_DMA_MASK : EMU10K1_DMA_MASK;
1159 if (pci_set_dma_mask(pci, emu->dma_mask) < 0 ||
1160 pci_set_consistent_dma_mask(pci, emu->dma_mask) < 0) {
1161 snd_printk(KERN_ERR "architecture does not support PCI busmaster DMA with mask 0x%lx\n", emu->dma_mask);
1162 kfree(emu);
1163 pci_disable_device(pci);
1164 return -ENXIO;
1165 }
1166 if (is_audigy)
1167 emu->gpr_base = A_FXGPREGBASE;
1168 else
1169 emu->gpr_base = FXGPREGBASE;
1170
1171 if ((err = pci_request_regions(pci, "EMU10K1")) < 0) {
1172 kfree(emu);
1173 pci_disable_device(pci);
1174 return err;
1175 }
1176 emu->port = pci_resource_start(pci, 0);
1177
1178 if (request_irq(pci->irq, snd_emu10k1_interrupt, SA_INTERRUPT|SA_SHIRQ, "EMU10K1", (void *)emu)) {
Takashi Iwai09668b42005-11-17 16:14:10 +01001179 err = -EBUSY;
1180 goto error;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001181 }
1182 emu->irq = pci->irq;
1183
1184 emu->max_cache_pages = max_cache_bytes >> PAGE_SHIFT;
1185 if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(pci),
1186 32 * 1024, &emu->ptb_pages) < 0) {
Takashi Iwai09668b42005-11-17 16:14:10 +01001187 err = -ENOMEM;
1188 goto error;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001189 }
1190
1191 emu->page_ptr_table = (void **)vmalloc(emu->max_cache_pages * sizeof(void*));
1192 emu->page_addr_table = (unsigned long*)vmalloc(emu->max_cache_pages * sizeof(unsigned long));
1193 if (emu->page_ptr_table == NULL || emu->page_addr_table == NULL) {
Takashi Iwai09668b42005-11-17 16:14:10 +01001194 err = -ENOMEM;
1195 goto error;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001196 }
1197
1198 if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(pci),
1199 EMUPAGESIZE, &emu->silent_page) < 0) {
Takashi Iwai09668b42005-11-17 16:14:10 +01001200 err = -ENOMEM;
1201 goto error;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001202 }
1203 emu->memhdr = snd_util_memhdr_new(emu->max_cache_pages * PAGE_SIZE);
1204 if (emu->memhdr == NULL) {
Takashi Iwai09668b42005-11-17 16:14:10 +01001205 err = -ENOMEM;
1206 goto error;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001207 }
Takashi Iwaieb4698f2005-11-17 14:50:13 +01001208 emu->memhdr->block_extra_size = sizeof(struct snd_emu10k1_memblk) -
1209 sizeof(struct snd_util_memblk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001210
1211 pci_set_master(pci);
1212
Linus Torvalds1da177e2005-04-16 15:20:36 -07001213 emu->fx8010.fxbus_mask = 0x303f;
1214 if (extin_mask == 0)
1215 extin_mask = 0x3fcf;
1216 if (extout_mask == 0)
1217 extout_mask = 0x7fff;
1218 emu->fx8010.extin_mask = extin_mask;
1219 emu->fx8010.extout_mask = extout_mask;
Takashi Iwai09668b42005-11-17 16:14:10 +01001220 emu->enable_ir = enable_ir;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001221
Lee Revell2b637da2005-03-30 13:51:18 +02001222 if (emu->card_capabilities->ecard) {
Takashi Iwai09668b42005-11-17 16:14:10 +01001223 if ((err = snd_emu10k1_ecard_init(emu)) < 0)
1224 goto error;
James Courtier-Duttond83c6712005-10-31 10:27:41 +00001225 } else if (emu->card_capabilities->ca_cardbus_chip) {
Takashi Iwai09668b42005-11-17 16:14:10 +01001226 if ((err = snd_emu10k1_cardbus_init(emu)) < 0)
1227 goto error;
James Courtier-Dutton19b99fb2005-12-04 18:03:03 +01001228 } else if (emu->card_capabilities->emu1212m) {
1229 if ((err = snd_emu10k1_emu1212m_init(emu)) < 0) {
1230 snd_emu10k1_free(emu);
1231 return err;
1232 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001233 } else {
1234 /* 5.1: Enable the additional AC97 Slots. If the emu10k1 version
1235 does not support this, it shouldn't do any harm */
1236 snd_emu10k1_ptr_write(emu, AC97SLOT, 0, AC97SLOT_CNTR|AC97SLOT_LFE);
1237 }
1238
Takashi Iwai09668b42005-11-17 16:14:10 +01001239 /* initialize TRAM setup */
1240 emu->fx8010.itram_size = (16 * 1024)/2;
1241 emu->fx8010.etram_pages.area = NULL;
1242 emu->fx8010.etram_pages.bytes = 0;
1243
1244 /*
1245 * Init to 0x02109204 :
1246 * Clock accuracy = 0 (1000ppm)
1247 * Sample Rate = 2 (48kHz)
1248 * Audio Channel = 1 (Left of 2)
1249 * Source Number = 0 (Unspecified)
1250 * Generation Status = 1 (Original for Cat Code 12)
1251 * Cat Code = 12 (Digital Signal Mixer)
1252 * Mode = 0 (Mode 0)
1253 * Emphasis = 0 (None)
1254 * CP = 1 (Copyright unasserted)
1255 * AN = 0 (Audio data)
1256 * P = 0 (Consumer)
1257 */
1258 emu->spdif_bits[0] = emu->spdif_bits[1] =
1259 emu->spdif_bits[2] = SPCS_CLKACCY_1000PPM | SPCS_SAMPLERATE_48 |
1260 SPCS_CHANNELNUM_LEFT | SPCS_SOURCENUM_UNSPEC |
1261 SPCS_GENERATIONSTATUS | 0x00001200 |
1262 0x00000000 | SPCS_EMPHASIS_NONE | SPCS_COPYRIGHT;
1263
1264 emu->reserved_page = (struct snd_emu10k1_memblk *)
1265 snd_emu10k1_synth_alloc(emu, 4096);
1266 if (emu->reserved_page)
1267 emu->reserved_page->map_locked = 1;
1268
1269 /* Clear silent pages and set up pointers */
1270 memset(emu->silent_page.area, 0, PAGE_SIZE);
1271 silent_page = emu->silent_page.addr << 1;
1272 for (idx = 0; idx < MAXPAGES; idx++)
1273 ((u32 *)emu->ptb_pages.area)[idx] = cpu_to_le32(silent_page | idx);
1274
1275 /* set up voice indices */
1276 for (idx = 0; idx < NUM_G; idx++) {
1277 emu->voices[idx].emu = emu;
1278 emu->voices[idx].number = idx;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001279 }
1280
Takashi Iwai09668b42005-11-17 16:14:10 +01001281 if ((err = snd_emu10k1_init(emu, enable_ir, 0)) < 0)
1282 goto error;
1283#ifdef CONFIG_PM
1284 if ((err = alloc_pm_buffer(emu)) < 0)
1285 goto error;
1286#endif
1287
1288 /* Initialize the effect engine */
1289 if ((err = snd_emu10k1_init_efx(emu)) < 0)
1290 goto error;
1291 snd_emu10k1_audio_enable(emu);
1292
1293 if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, emu, &ops)) < 0)
1294 goto error;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001295
Takashi Iwaiadf1b3d2005-12-01 10:49:58 +01001296#ifdef CONFIG_PROC_FS
Linus Torvalds1da177e2005-04-16 15:20:36 -07001297 snd_emu10k1_proc_init(emu);
Takashi Iwaiadf1b3d2005-12-01 10:49:58 +01001298#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -07001299
1300 snd_card_set_dev(card, &pci->dev);
1301 *remu = emu;
1302 return 0;
Takashi Iwai09668b42005-11-17 16:14:10 +01001303
1304 error:
1305 snd_emu10k1_free(emu);
1306 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001307}
1308
Takashi Iwai09668b42005-11-17 16:14:10 +01001309#ifdef CONFIG_PM
1310static unsigned char saved_regs[] = {
1311 CPF, PTRX, CVCF, VTFT, Z1, Z2, PSST, DSL, CCCA, CCR, CLP,
1312 FXRT, MAPA, MAPB, ENVVOL, ATKHLDV, DCYSUSV, LFOVAL1, ENVVAL,
1313 ATKHLDM, DCYSUSM, LFOVAL2, IP, IFATN, PEFE, FMMOD, TREMFRQ, FM2FRQ2,
1314 TEMPENV, ADCCR, FXWC, MICBA, ADCBA, FXBA,
1315 MICBS, ADCBS, FXBS, CDCS, GPSCS, SPCS0, SPCS1, SPCS2,
1316 SPBYPASS, AC97SLOT, CDSRCS, GPSRCS, ZVSRCS, MICIDX, ADCIDX, FXIDX,
1317 0xff /* end */
1318};
1319static unsigned char saved_regs_audigy[] = {
1320 A_ADCIDX, A_MICIDX, A_FXWC1, A_FXWC2, A_SAMPLE_RATE,
1321 A_FXRT2, A_SENDAMOUNTS, A_FXRT1,
1322 0xff /* end */
1323};
1324
1325static int __devinit alloc_pm_buffer(struct snd_emu10k1 *emu)
1326{
1327 int size;
1328
1329 size = ARRAY_SIZE(saved_regs);
1330 if (emu->audigy)
1331 size += ARRAY_SIZE(saved_regs_audigy);
1332 emu->saved_ptr = vmalloc(4 * NUM_G * size);
1333 if (! emu->saved_ptr)
1334 return -ENOMEM;
1335 if (snd_emu10k1_efx_alloc_pm_buffer(emu) < 0)
1336 return -ENOMEM;
1337 if (emu->card_capabilities->ca0151_chip &&
1338 snd_p16v_alloc_pm_buffer(emu) < 0)
1339 return -ENOMEM;
1340 return 0;
1341}
1342
1343static void free_pm_buffer(struct snd_emu10k1 *emu)
1344{
1345 vfree(emu->saved_ptr);
1346 snd_emu10k1_efx_free_pm_buffer(emu);
1347 if (emu->card_capabilities->ca0151_chip)
1348 snd_p16v_free_pm_buffer(emu);
1349}
1350
1351void snd_emu10k1_suspend_regs(struct snd_emu10k1 *emu)
1352{
1353 int i;
1354 unsigned char *reg;
1355 unsigned int *val;
1356
1357 val = emu->saved_ptr;
1358 for (reg = saved_regs; *reg != 0xff; reg++)
1359 for (i = 0; i < NUM_G; i++, val++)
1360 *val = snd_emu10k1_ptr_read(emu, *reg, i);
1361 if (emu->audigy) {
1362 for (reg = saved_regs_audigy; *reg != 0xff; reg++)
1363 for (i = 0; i < NUM_G; i++, val++)
1364 *val = snd_emu10k1_ptr_read(emu, *reg, i);
1365 }
1366 if (emu->audigy)
1367 emu->saved_a_iocfg = inl(emu->port + A_IOCFG);
1368 emu->saved_hcfg = inl(emu->port + HCFG);
1369}
1370
1371void snd_emu10k1_resume_init(struct snd_emu10k1 *emu)
1372{
1373 if (emu->card_capabilities->ecard)
1374 snd_emu10k1_ecard_init(emu);
1375 else
1376 snd_emu10k1_ptr_write(emu, AC97SLOT, 0, AC97SLOT_CNTR|AC97SLOT_LFE);
1377 snd_emu10k1_init(emu, emu->enable_ir, 1);
1378}
1379
1380void snd_emu10k1_resume_regs(struct snd_emu10k1 *emu)
1381{
1382 int i;
1383 unsigned char *reg;
1384 unsigned int *val;
1385
1386 snd_emu10k1_audio_enable(emu);
1387
1388 /* resore for spdif */
1389 if (emu->audigy)
1390 outl(emu->port + A_IOCFG, emu->saved_a_iocfg);
1391 outl(emu->port + HCFG, emu->saved_hcfg);
1392
1393 val = emu->saved_ptr;
1394 for (reg = saved_regs; *reg != 0xff; reg++)
1395 for (i = 0; i < NUM_G; i++, val++)
1396 snd_emu10k1_ptr_write(emu, *reg, i, *val);
1397 if (emu->audigy) {
1398 for (reg = saved_regs_audigy; *reg != 0xff; reg++)
1399 for (i = 0; i < NUM_G; i++, val++)
1400 snd_emu10k1_ptr_write(emu, *reg, i, *val);
1401 }
1402}
1403#endif
1404
Linus Torvalds1da177e2005-04-16 15:20:36 -07001405/* memory.c */
1406EXPORT_SYMBOL(snd_emu10k1_synth_alloc);
1407EXPORT_SYMBOL(snd_emu10k1_synth_free);
1408EXPORT_SYMBOL(snd_emu10k1_synth_bzero);
1409EXPORT_SYMBOL(snd_emu10k1_synth_copy_from_user);
1410EXPORT_SYMBOL(snd_emu10k1_memblk_map);
1411/* voice.c */
1412EXPORT_SYMBOL(snd_emu10k1_voice_alloc);
1413EXPORT_SYMBOL(snd_emu10k1_voice_free);
1414/* io.c */
1415EXPORT_SYMBOL(snd_emu10k1_ptr_read);
1416EXPORT_SYMBOL(snd_emu10k1_ptr_write);