blob: eb093700fa71ac5374b932a2fe534e1fa80e9b60 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
2 * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
3 * Creative Labs, Inc.
4 * Routines for control of EMU10K1 chips
5 *
6 * Copyright (c) by James Courtier-Dutton <James@superbug.demon.co.uk>
7 * Added support for Audigy 2 Value.
8 *
9 *
10 * BUGS:
11 * --
12 *
13 * TODO:
14 * --
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
25 *
26 * You should have received a copy of the GNU General Public License
27 * along with this program; if not, write to the Free Software
28 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
29 *
30 */
31
32#include <sound/driver.h>
33#include <linux/delay.h>
34#include <linux/init.h>
35#include <linux/interrupt.h>
36#include <linux/pci.h>
37#include <linux/slab.h>
38#include <linux/vmalloc.h>
39
40#include <sound/core.h>
41#include <sound/emu10k1.h>
42#include "p16v.h"
James Courtier-Duttone2b15f82005-11-11 23:39:05 +010043#include "tina2.h"
Linus Torvalds1da177e2005-04-16 15:20:36 -070044
James Courtier-Dutton19b99fb2005-12-04 18:03:03 +010045
Linus Torvalds1da177e2005-04-16 15:20:36 -070046/*************************************************************************
47 * EMU10K1 init / done
48 *************************************************************************/
49
Takashi Iwaieb4698f2005-11-17 14:50:13 +010050void snd_emu10k1_voice_init(struct snd_emu10k1 * emu, int ch)
Linus Torvalds1da177e2005-04-16 15:20:36 -070051{
52 snd_emu10k1_ptr_write(emu, DCYSUSV, ch, 0);
53 snd_emu10k1_ptr_write(emu, IP, ch, 0);
54 snd_emu10k1_ptr_write(emu, VTFT, ch, 0xffff);
55 snd_emu10k1_ptr_write(emu, CVCF, ch, 0xffff);
56 snd_emu10k1_ptr_write(emu, PTRX, ch, 0);
57 snd_emu10k1_ptr_write(emu, CPF, ch, 0);
58 snd_emu10k1_ptr_write(emu, CCR, ch, 0);
59
60 snd_emu10k1_ptr_write(emu, PSST, ch, 0);
61 snd_emu10k1_ptr_write(emu, DSL, ch, 0x10);
62 snd_emu10k1_ptr_write(emu, CCCA, ch, 0);
63 snd_emu10k1_ptr_write(emu, Z1, ch, 0);
64 snd_emu10k1_ptr_write(emu, Z2, ch, 0);
65 snd_emu10k1_ptr_write(emu, FXRT, ch, 0x32100000);
66
67 snd_emu10k1_ptr_write(emu, ATKHLDM, ch, 0);
68 snd_emu10k1_ptr_write(emu, DCYSUSM, ch, 0);
69 snd_emu10k1_ptr_write(emu, IFATN, ch, 0xffff);
70 snd_emu10k1_ptr_write(emu, PEFE, ch, 0);
71 snd_emu10k1_ptr_write(emu, FMMOD, ch, 0);
72 snd_emu10k1_ptr_write(emu, TREMFRQ, ch, 24); /* 1 Hz */
73 snd_emu10k1_ptr_write(emu, FM2FRQ2, ch, 24); /* 1 Hz */
74 snd_emu10k1_ptr_write(emu, TEMPENV, ch, 0);
75
76 /*** these are last so OFF prevents writing ***/
77 snd_emu10k1_ptr_write(emu, LFOVAL2, ch, 0);
78 snd_emu10k1_ptr_write(emu, LFOVAL1, ch, 0);
79 snd_emu10k1_ptr_write(emu, ATKHLDV, ch, 0);
80 snd_emu10k1_ptr_write(emu, ENVVOL, ch, 0);
81 snd_emu10k1_ptr_write(emu, ENVVAL, ch, 0);
82
83 /* Audigy extra stuffs */
84 if (emu->audigy) {
85 snd_emu10k1_ptr_write(emu, 0x4c, ch, 0); /* ?? */
86 snd_emu10k1_ptr_write(emu, 0x4d, ch, 0); /* ?? */
87 snd_emu10k1_ptr_write(emu, 0x4e, ch, 0); /* ?? */
88 snd_emu10k1_ptr_write(emu, 0x4f, ch, 0); /* ?? */
89 snd_emu10k1_ptr_write(emu, A_FXRT1, ch, 0x03020100);
90 snd_emu10k1_ptr_write(emu, A_FXRT2, ch, 0x3f3f3f3f);
91 snd_emu10k1_ptr_write(emu, A_SENDAMOUNTS, ch, 0);
92 }
93}
94
Takashi Iwai09668b42005-11-17 16:14:10 +010095static int snd_emu10k1_init(struct snd_emu10k1 *emu, int enable_ir, int resume)
Linus Torvalds1da177e2005-04-16 15:20:36 -070096{
Linus Torvalds1da177e2005-04-16 15:20:36 -070097 unsigned int silent_page;
Takashi Iwai09668b42005-11-17 16:14:10 +010098 int ch;
Linus Torvalds1da177e2005-04-16 15:20:36 -070099
100 /* disable audio and lock cache */
Takashi Iwai09668b42005-11-17 16:14:10 +0100101 outl(HCFG_LOCKSOUNDCACHE | HCFG_LOCKTANKCACHE_MASK | HCFG_MUTEBUTTONENABLE,
102 emu->port + HCFG);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700103
104 /* reset recording buffers */
105 snd_emu10k1_ptr_write(emu, MICBS, 0, ADCBS_BUFSIZE_NONE);
106 snd_emu10k1_ptr_write(emu, MICBA, 0, 0);
107 snd_emu10k1_ptr_write(emu, FXBS, 0, ADCBS_BUFSIZE_NONE);
108 snd_emu10k1_ptr_write(emu, FXBA, 0, 0);
109 snd_emu10k1_ptr_write(emu, ADCBS, 0, ADCBS_BUFSIZE_NONE);
110 snd_emu10k1_ptr_write(emu, ADCBA, 0, 0);
111
112 /* disable channel interrupt */
113 outl(0, emu->port + INTE);
114 snd_emu10k1_ptr_write(emu, CLIEL, 0, 0);
115 snd_emu10k1_ptr_write(emu, CLIEH, 0, 0);
116 snd_emu10k1_ptr_write(emu, SOLEL, 0, 0);
117 snd_emu10k1_ptr_write(emu, SOLEH, 0, 0);
118
119 if (emu->audigy){
120 /* set SPDIF bypass mode */
121 snd_emu10k1_ptr_write(emu, SPBYPASS, 0, SPBYPASS_FORMAT);
122 /* enable rear left + rear right AC97 slots */
Takashi Iwai09668b42005-11-17 16:14:10 +0100123 snd_emu10k1_ptr_write(emu, AC97SLOT, 0, AC97SLOT_REAR_RIGHT |
124 AC97SLOT_REAR_LEFT);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700125 }
126
127 /* init envelope engine */
Takashi Iwai09668b42005-11-17 16:14:10 +0100128 for (ch = 0; ch < NUM_G; ch++)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700129 snd_emu10k1_voice_init(emu, ch);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700130
Takashi Iwai09668b42005-11-17 16:14:10 +0100131 snd_emu10k1_ptr_write(emu, SPCS0, 0, emu->spdif_bits[0]);
132 snd_emu10k1_ptr_write(emu, SPCS1, 0, emu->spdif_bits[1]);
133 snd_emu10k1_ptr_write(emu, SPCS2, 0, emu->spdif_bits[2]);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700134
Lee Revell2b637da2005-03-30 13:51:18 +0200135 if (emu->card_capabilities->ca0151_chip) { /* audigy2 */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700136 /* Hacks for Alice3 to work independent of haP16V driver */
137 u32 tmp;
138
139 //Setup SRCMulti_I2S SamplingRate
140 tmp = snd_emu10k1_ptr_read(emu, A_SPDIF_SAMPLERATE, 0);
141 tmp &= 0xfffff1ff;
142 tmp |= (0x2<<9);
143 snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, 0, tmp);
144
145 /* Setup SRCSel (Enable Spdif,I2S SRCMulti) */
146 snd_emu10k1_ptr20_write(emu, SRCSel, 0, 0x14);
147 /* Setup SRCMulti Input Audio Enable */
148 /* Use 0xFFFFFFFF to enable P16V sounds. */
149 snd_emu10k1_ptr20_write(emu, SRCMULTI_ENABLE, 0, 0xFFFFFFFF);
150
151 /* Enabled Phased (8-channel) P16V playback */
152 outl(0x0201, emu->port + HCFG2);
153 /* Set playback routing. */
James Courtier-Duttonfd9a98e2005-04-10 15:43:35 +0200154 snd_emu10k1_ptr20_write(emu, CAPTURE_P16V_SOURCE, 0, 0x78e4);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700155 }
James Courtier-Duttone0474e52005-07-02 16:33:34 +0200156 if (emu->card_capabilities->ca0108_chip) { /* audigy2 Value */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700157 /* Hacks for Alice3 to work independent of haP16V driver */
158 u32 tmp;
159
Takashi Iwai09668b42005-11-17 16:14:10 +0100160 snd_printk(KERN_INFO "Audigy2 value: Special config.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700161 //Setup SRCMulti_I2S SamplingRate
162 tmp = snd_emu10k1_ptr_read(emu, A_SPDIF_SAMPLERATE, 0);
163 tmp &= 0xfffff1ff;
164 tmp |= (0x2<<9);
165 snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, 0, tmp);
166
167 /* Setup SRCSel (Enable Spdif,I2S SRCMulti) */
168 outl(0x600000, emu->port + 0x20);
169 outl(0x14, emu->port + 0x24);
170
171 /* Setup SRCMulti Input Audio Enable */
172 outl(0x7b0000, emu->port + 0x20);
173 outl(0xFF000000, emu->port + 0x24);
174
175 /* Setup SPDIF Out Audio Enable */
176 /* The Audigy 2 Value has a separate SPDIF out,
177 * so no need for a mixer switch
178 */
179 outl(0x7a0000, emu->port + 0x20);
180 outl(0xFF000000, emu->port + 0x24);
181 tmp = inl(emu->port + A_IOCFG) & ~0x8; /* Clear bit 3 */
182 outl(tmp, emu->port + A_IOCFG);
183 }
James Courtier-Dutton27fe8642005-12-21 15:06:08 +0100184 if (emu->card_capabilities->spi_dac) { /* Audigy 2 ZS Notebook with DAC Wolfson WM8768/WM8568 */
185 u32 tmp;
186 tmp = snd_emu10k1_spi_write(emu, 0x00ff);
187 tmp = snd_emu10k1_spi_write(emu, 0x02ff);
188 tmp = snd_emu10k1_spi_write(emu, 0x0400);
189 tmp = snd_emu10k1_spi_write(emu, 0x0520);
190 tmp = snd_emu10k1_spi_write(emu, 0x0600);
191 tmp = snd_emu10k1_spi_write(emu, 0x08ff);
192 tmp = snd_emu10k1_spi_write(emu, 0x0aff);
193 tmp = snd_emu10k1_spi_write(emu, 0x0cff);
194 tmp = snd_emu10k1_spi_write(emu, 0x0eff);
195 tmp = snd_emu10k1_spi_write(emu, 0x10ff);
196 tmp = snd_emu10k1_spi_write(emu, 0x1200);
197 tmp = snd_emu10k1_spi_write(emu, 0x1400);
198 tmp = snd_emu10k1_spi_write(emu, 0x1480);
199 tmp = snd_emu10k1_spi_write(emu, 0x1800);
200 tmp = snd_emu10k1_spi_write(emu, 0x1aff);
201 tmp = snd_emu10k1_spi_write(emu, 0x1cff);
202 tmp = snd_emu10k1_spi_write(emu, 0x1e00);
203 tmp = snd_emu10k1_spi_write(emu, 0x0530);
204 tmp = snd_emu10k1_spi_write(emu, 0x0602);
205 tmp = snd_emu10k1_spi_write(emu, 0x0622);
206 tmp = snd_emu10k1_spi_write(emu, 0x1400);
207 snd_emu10k1_ptr20_write(emu, 0x60, 0, 0x10);
208 }
209
Linus Torvalds1da177e2005-04-16 15:20:36 -0700210 snd_emu10k1_ptr_write(emu, PTB, 0, emu->ptb_pages.addr);
211 snd_emu10k1_ptr_write(emu, TCB, 0, 0); /* taken from original driver */
212 snd_emu10k1_ptr_write(emu, TCBS, 0, 4); /* taken from original driver */
213
214 silent_page = (emu->silent_page.addr << 1) | MAP_PTI_MASK;
215 for (ch = 0; ch < NUM_G; ch++) {
216 snd_emu10k1_ptr_write(emu, MAPA, ch, silent_page);
217 snd_emu10k1_ptr_write(emu, MAPB, ch, silent_page);
218 }
219
220 /*
221 * Hokay, setup HCFG
222 * Mute Disable Audio = 0
223 * Lock Tank Memory = 1
224 * Lock Sound Memory = 0
225 * Auto Mute = 1
226 */
227 if (emu->audigy) {
228 if (emu->revision == 4) /* audigy2 */
229 outl(HCFG_AUDIOENABLE |
230 HCFG_AC3ENABLE_CDSPDIF |
231 HCFG_AC3ENABLE_GPSPDIF |
232 HCFG_AUTOMUTE | HCFG_JOYENABLE, emu->port + HCFG);
233 else
234 outl(HCFG_AUTOMUTE | HCFG_JOYENABLE, emu->port + HCFG);
James Courtier-Duttone0474e52005-07-02 16:33:34 +0200235 /* FIXME: Remove all these emu->model and replace it with a card recognition parameter,
236 * e.g. card_capabilities->joystick */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700237 } else if (emu->model == 0x20 ||
238 emu->model == 0xc400 ||
239 (emu->model == 0x21 && emu->revision < 6))
240 outl(HCFG_LOCKTANKCACHE_MASK | HCFG_AUTOMUTE, emu->port + HCFG);
241 else
242 // With on-chip joystick
243 outl(HCFG_LOCKTANKCACHE_MASK | HCFG_AUTOMUTE | HCFG_JOYENABLE, emu->port + HCFG);
244
245 if (enable_ir) { /* enable IR for SB Live */
James Courtier-Dutton19b99fb2005-12-04 18:03:03 +0100246 if ( emu->card_capabilities->emu1212m) {
247 ; /* Disable all access to A_IOCFG for the emu1212m */
248 } else if (emu->audigy) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700249 unsigned int reg = inl(emu->port + A_IOCFG);
250 outl(reg | A_IOCFG_GPOUT2, emu->port + A_IOCFG);
251 udelay(500);
252 outl(reg | A_IOCFG_GPOUT1 | A_IOCFG_GPOUT2, emu->port + A_IOCFG);
253 udelay(100);
254 outl(reg, emu->port + A_IOCFG);
255 } else {
256 unsigned int reg = inl(emu->port + HCFG);
257 outl(reg | HCFG_GPOUT2, emu->port + HCFG);
258 udelay(500);
259 outl(reg | HCFG_GPOUT1 | HCFG_GPOUT2, emu->port + HCFG);
260 udelay(100);
261 outl(reg, emu->port + HCFG);
262 }
263 }
264
James Courtier-Dutton19b99fb2005-12-04 18:03:03 +0100265 if ( emu->card_capabilities->emu1212m) {
266 ; /* Disable all access to A_IOCFG for the emu1212m */
267 } else if (emu->audigy) { /* enable analog output */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700268 unsigned int reg = inl(emu->port + A_IOCFG);
269 outl(reg | A_IOCFG_GPOUT0, emu->port + A_IOCFG);
270 }
271
Takashi Iwai09668b42005-11-17 16:14:10 +0100272 return 0;
273}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700274
Takashi Iwai09668b42005-11-17 16:14:10 +0100275static void snd_emu10k1_audio_enable(struct snd_emu10k1 *emu)
276{
Linus Torvalds1da177e2005-04-16 15:20:36 -0700277 /*
278 * Enable the audio bit
279 */
280 outl(inl(emu->port + HCFG) | HCFG_AUDIOENABLE, emu->port + HCFG);
281
282 /* Enable analog/digital outs on audigy */
James Courtier-Dutton19b99fb2005-12-04 18:03:03 +0100283 if ( emu->card_capabilities->emu1212m) {
284 ; /* Disable all access to A_IOCFG for the emu1212m */
285 } else if (emu->audigy) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700286 outl(inl(emu->port + A_IOCFG) & ~0x44, emu->port + A_IOCFG);
287
James Courtier-Duttone0474e52005-07-02 16:33:34 +0200288 if (emu->card_capabilities->ca0151_chip) { /* audigy2 */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700289 /* Unmute Analog now. Set GPO6 to 1 for Apollo.
290 * This has to be done after init ALice3 I2SOut beyond 48KHz.
291 * So, sequence is important. */
292 outl(inl(emu->port + A_IOCFG) | 0x0040, emu->port + A_IOCFG);
James Courtier-Duttone0474e52005-07-02 16:33:34 +0200293 } else if (emu->card_capabilities->ca0108_chip) { /* audigy2 value */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700294 /* Unmute Analog now. */
295 outl(inl(emu->port + A_IOCFG) | 0x0060, emu->port + A_IOCFG);
296 } else {
297 /* Disable routing from AC97 line out to Front speakers */
298 outl(inl(emu->port + A_IOCFG) | 0x0080, emu->port + A_IOCFG);
299 }
300 }
301
302#if 0
303 {
304 unsigned int tmp;
305 /* FIXME: the following routine disables LiveDrive-II !! */
306 // TOSLink detection
307 emu->tos_link = 0;
308 tmp = inl(emu->port + HCFG);
309 if (tmp & (HCFG_GPINPUT0 | HCFG_GPINPUT1)) {
310 outl(tmp|0x800, emu->port + HCFG);
311 udelay(50);
312 if (tmp != (inl(emu->port + HCFG) & ~0x800)) {
313 emu->tos_link = 1;
314 outl(tmp, emu->port + HCFG);
315 }
316 }
317 }
318#endif
319
320 snd_emu10k1_intr_enable(emu, INTE_PCIERRORENABLE);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700321}
322
Takashi Iwai09668b42005-11-17 16:14:10 +0100323int snd_emu10k1_done(struct snd_emu10k1 * emu)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700324{
325 int ch;
326
327 outl(0, emu->port + INTE);
328
329 /*
330 * Shutdown the chip
331 */
332 for (ch = 0; ch < NUM_G; ch++)
333 snd_emu10k1_ptr_write(emu, DCYSUSV, ch, 0);
334 for (ch = 0; ch < NUM_G; ch++) {
335 snd_emu10k1_ptr_write(emu, VTFT, ch, 0);
336 snd_emu10k1_ptr_write(emu, CVCF, ch, 0);
337 snd_emu10k1_ptr_write(emu, PTRX, ch, 0);
338 snd_emu10k1_ptr_write(emu, CPF, ch, 0);
339 }
340
341 /* reset recording buffers */
342 snd_emu10k1_ptr_write(emu, MICBS, 0, 0);
343 snd_emu10k1_ptr_write(emu, MICBA, 0, 0);
344 snd_emu10k1_ptr_write(emu, FXBS, 0, 0);
345 snd_emu10k1_ptr_write(emu, FXBA, 0, 0);
346 snd_emu10k1_ptr_write(emu, FXWC, 0, 0);
347 snd_emu10k1_ptr_write(emu, ADCBS, 0, ADCBS_BUFSIZE_NONE);
348 snd_emu10k1_ptr_write(emu, ADCBA, 0, 0);
349 snd_emu10k1_ptr_write(emu, TCBS, 0, TCBS_BUFFSIZE_16K);
350 snd_emu10k1_ptr_write(emu, TCB, 0, 0);
351 if (emu->audigy)
352 snd_emu10k1_ptr_write(emu, A_DBG, 0, A_DBG_SINGLE_STEP);
353 else
354 snd_emu10k1_ptr_write(emu, DBG, 0, EMU10K1_DBG_SINGLE_STEP);
355
356 /* disable channel interrupt */
357 snd_emu10k1_ptr_write(emu, CLIEL, 0, 0);
358 snd_emu10k1_ptr_write(emu, CLIEH, 0, 0);
359 snd_emu10k1_ptr_write(emu, SOLEL, 0, 0);
360 snd_emu10k1_ptr_write(emu, SOLEH, 0, 0);
361
Linus Torvalds1da177e2005-04-16 15:20:36 -0700362 /* disable audio and lock cache */
363 outl(HCFG_LOCKSOUNDCACHE | HCFG_LOCKTANKCACHE_MASK | HCFG_MUTEBUTTONENABLE, emu->port + HCFG);
364 snd_emu10k1_ptr_write(emu, PTB, 0, 0);
365
Linus Torvalds1da177e2005-04-16 15:20:36 -0700366 return 0;
367}
368
369/*************************************************************************
370 * ECARD functional implementation
371 *************************************************************************/
372
373/* In A1 Silicon, these bits are in the HC register */
374#define HOOKN_BIT (1L << 12)
375#define HANDN_BIT (1L << 11)
376#define PULSEN_BIT (1L << 10)
377
378#define EC_GDI1 (1 << 13)
379#define EC_GDI0 (1 << 14)
380
381#define EC_NUM_CONTROL_BITS 20
382
383#define EC_AC3_DATA_SELN 0x0001L
384#define EC_EE_DATA_SEL 0x0002L
385#define EC_EE_CNTRL_SELN 0x0004L
386#define EC_EECLK 0x0008L
387#define EC_EECS 0x0010L
388#define EC_EESDO 0x0020L
389#define EC_TRIM_CSN 0x0040L
390#define EC_TRIM_SCLK 0x0080L
391#define EC_TRIM_SDATA 0x0100L
392#define EC_TRIM_MUTEN 0x0200L
393#define EC_ADCCAL 0x0400L
394#define EC_ADCRSTN 0x0800L
395#define EC_DACCAL 0x1000L
396#define EC_DACMUTEN 0x2000L
397#define EC_LEDN 0x4000L
398
399#define EC_SPDIF0_SEL_SHIFT 15
400#define EC_SPDIF1_SEL_SHIFT 17
401#define EC_SPDIF0_SEL_MASK (0x3L << EC_SPDIF0_SEL_SHIFT)
402#define EC_SPDIF1_SEL_MASK (0x7L << EC_SPDIF1_SEL_SHIFT)
403#define EC_SPDIF0_SELECT(_x) (((_x) << EC_SPDIF0_SEL_SHIFT) & EC_SPDIF0_SEL_MASK)
404#define EC_SPDIF1_SELECT(_x) (((_x) << EC_SPDIF1_SEL_SHIFT) & EC_SPDIF1_SEL_MASK)
405#define EC_CURRENT_PROM_VERSION 0x01 /* Self-explanatory. This should
406 * be incremented any time the EEPROM's
407 * format is changed. */
408
409#define EC_EEPROM_SIZE 0x40 /* ECARD EEPROM has 64 16-bit words */
410
411/* Addresses for special values stored in to EEPROM */
412#define EC_PROM_VERSION_ADDR 0x20 /* Address of the current prom version */
413#define EC_BOARDREV0_ADDR 0x21 /* LSW of board rev */
414#define EC_BOARDREV1_ADDR 0x22 /* MSW of board rev */
415
416#define EC_LAST_PROMFILE_ADDR 0x2f
417
418#define EC_SERIALNUM_ADDR 0x30 /* First word of serial number. The
419 * can be up to 30 characters in length
420 * and is stored as a NULL-terminated
421 * ASCII string. Any unused bytes must be
422 * filled with zeros */
423#define EC_CHECKSUM_ADDR 0x3f /* Location at which checksum is stored */
424
425
426/* Most of this stuff is pretty self-evident. According to the hardware
427 * dudes, we need to leave the ADCCAL bit low in order to avoid a DC
428 * offset problem. Weird.
429 */
430#define EC_RAW_RUN_MODE (EC_DACMUTEN | EC_ADCRSTN | EC_TRIM_MUTEN | \
431 EC_TRIM_CSN)
432
433
434#define EC_DEFAULT_ADC_GAIN 0xC4C4
435#define EC_DEFAULT_SPDIF0_SEL 0x0
436#define EC_DEFAULT_SPDIF1_SEL 0x4
437
438/**************************************************************************
439 * @func Clock bits into the Ecard's control latch. The Ecard uses a
440 * control latch will is loaded bit-serially by toggling the Modem control
441 * lines from function 2 on the E8010. This function hides these details
442 * and presents the illusion that we are actually writing to a distinct
443 * register.
444 */
445
Takashi Iwaieb4698f2005-11-17 14:50:13 +0100446static void snd_emu10k1_ecard_write(struct snd_emu10k1 * emu, unsigned int value)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700447{
448 unsigned short count;
449 unsigned int data;
450 unsigned long hc_port;
451 unsigned int hc_value;
452
453 hc_port = emu->port + HCFG;
454 hc_value = inl(hc_port) & ~(HOOKN_BIT | HANDN_BIT | PULSEN_BIT);
455 outl(hc_value, hc_port);
456
457 for (count = 0; count < EC_NUM_CONTROL_BITS; count++) {
458
459 /* Set up the value */
460 data = ((value & 0x1) ? PULSEN_BIT : 0);
461 value >>= 1;
462
463 outl(hc_value | data, hc_port);
464
465 /* Clock the shift register */
466 outl(hc_value | data | HANDN_BIT, hc_port);
467 outl(hc_value | data, hc_port);
468 }
469
470 /* Latch the bits */
471 outl(hc_value | HOOKN_BIT, hc_port);
472 outl(hc_value, hc_port);
473}
474
475/**************************************************************************
476 * @func Set the gain of the ECARD's CS3310 Trim/gain controller. The
477 * trim value consists of a 16bit value which is composed of two
478 * 8 bit gain/trim values, one for the left channel and one for the
479 * right channel. The following table maps from the Gain/Attenuation
480 * value in decibels into the corresponding bit pattern for a single
481 * channel.
482 */
483
Takashi Iwaieb4698f2005-11-17 14:50:13 +0100484static void snd_emu10k1_ecard_setadcgain(struct snd_emu10k1 * emu,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700485 unsigned short gain)
486{
487 unsigned int bit;
488
489 /* Enable writing to the TRIM registers */
490 snd_emu10k1_ecard_write(emu, emu->ecard_ctrl & ~EC_TRIM_CSN);
491
492 /* Do it again to insure that we meet hold time requirements */
493 snd_emu10k1_ecard_write(emu, emu->ecard_ctrl & ~EC_TRIM_CSN);
494
495 for (bit = (1 << 15); bit; bit >>= 1) {
496 unsigned int value;
497
498 value = emu->ecard_ctrl & ~(EC_TRIM_CSN | EC_TRIM_SDATA);
499
500 if (gain & bit)
501 value |= EC_TRIM_SDATA;
502
503 /* Clock the bit */
504 snd_emu10k1_ecard_write(emu, value);
505 snd_emu10k1_ecard_write(emu, value | EC_TRIM_SCLK);
506 snd_emu10k1_ecard_write(emu, value);
507 }
508
509 snd_emu10k1_ecard_write(emu, emu->ecard_ctrl);
510}
511
Takashi Iwaieb4698f2005-11-17 14:50:13 +0100512static int __devinit snd_emu10k1_ecard_init(struct snd_emu10k1 * emu)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700513{
514 unsigned int hc_value;
515
516 /* Set up the initial settings */
517 emu->ecard_ctrl = EC_RAW_RUN_MODE |
518 EC_SPDIF0_SELECT(EC_DEFAULT_SPDIF0_SEL) |
519 EC_SPDIF1_SELECT(EC_DEFAULT_SPDIF1_SEL);
520
521 /* Step 0: Set the codec type in the hardware control register
522 * and enable audio output */
523 hc_value = inl(emu->port + HCFG);
524 outl(hc_value | HCFG_AUDIOENABLE | HCFG_CODECFORMAT_I2S, emu->port + HCFG);
525 inl(emu->port + HCFG);
526
527 /* Step 1: Turn off the led and deassert TRIM_CS */
528 snd_emu10k1_ecard_write(emu, EC_ADCCAL | EC_LEDN | EC_TRIM_CSN);
529
530 /* Step 2: Calibrate the ADC and DAC */
531 snd_emu10k1_ecard_write(emu, EC_DACCAL | EC_LEDN | EC_TRIM_CSN);
532
533 /* Step 3: Wait for awhile; XXX We can't get away with this
534 * under a real operating system; we'll need to block and wait that
535 * way. */
536 snd_emu10k1_wait(emu, 48000);
537
538 /* Step 4: Switch off the DAC and ADC calibration. Note
539 * That ADC_CAL is actually an inverted signal, so we assert
540 * it here to stop calibration. */
541 snd_emu10k1_ecard_write(emu, EC_ADCCAL | EC_LEDN | EC_TRIM_CSN);
542
543 /* Step 4: Switch into run mode */
544 snd_emu10k1_ecard_write(emu, emu->ecard_ctrl);
545
546 /* Step 5: Set the analog input gain */
547 snd_emu10k1_ecard_setadcgain(emu, EC_DEFAULT_ADC_GAIN);
548
549 return 0;
550}
551
Takashi Iwaieb4698f2005-11-17 14:50:13 +0100552static int __devinit snd_emu10k1_cardbus_init(struct snd_emu10k1 * emu)
James Courtier-Duttond83c6712005-10-31 10:27:41 +0000553{
554 unsigned long special_port;
555 unsigned int value;
556
557 /* Special initialisation routine
558 * before the rest of the IO-Ports become active.
559 */
560 special_port = emu->port + 0x38;
561 value = inl(special_port);
562 outl(0x00d00000, special_port);
563 value = inl(special_port);
564 outl(0x00d00001, special_port);
565 value = inl(special_port);
566 outl(0x00d0005f, special_port);
567 value = inl(special_port);
568 outl(0x00d0007f, special_port);
569 value = inl(special_port);
570 outl(0x0090007f, special_port);
571 value = inl(special_port);
572
James Courtier-Duttone2b15f82005-11-11 23:39:05 +0100573 snd_emu10k1_ptr20_write(emu, TINA2_VOLUME, 0, 0xfefefefe); /* Defaults to 0x30303030 */
James Courtier-Duttond83c6712005-10-31 10:27:41 +0000574 return 0;
575}
576
James Courtier-Dutton19b99fb2005-12-04 18:03:03 +0100577static int snd_emu1212m_fpga_write(struct snd_emu10k1 * emu, int reg, int value)
578{
579 if (reg<0 || reg>0x3f)
580 return 1;
581 reg+=0x40; /* 0x40 upwards are registers. */
582 if (value<0 || value>0x3f) /* 0 to 0x3f are values */
583 return 1;
584 outl(reg, emu->port + A_IOCFG);
585 outl(reg | 0x80, emu->port + A_IOCFG); /* High bit clocks the value into the fpga. */
586 outl(value, emu->port + A_IOCFG);
587 outl(value | 0x80 , emu->port + A_IOCFG); /* High bit clocks the value into the fpga. */
588
589 return 0;
590}
591
592static int snd_emu1212m_fpga_read(struct snd_emu10k1 * emu, int reg, int *value)
593{
594 if (reg<0 || reg>0x3f)
595 return 1;
596 reg+=0x40; /* 0x40 upwards are registers. */
597 outl(reg, emu->port + A_IOCFG);
598 outl(reg | 0x80, emu->port + A_IOCFG); /* High bit clocks the value into the fpga. */
599 *value = inl(emu->port + A_IOCFG);
600
601 return 0;
602}
603
604static int snd_emu1212m_fpga_netlist_write(struct snd_emu10k1 * emu, int reg, int value)
605{
606 snd_emu1212m_fpga_write(emu, 0x00, ((reg >> 8) & 0x3f) );
607 snd_emu1212m_fpga_write(emu, 0x01, (reg & 0x3f) );
608 snd_emu1212m_fpga_write(emu, 0x02, ((value >> 8) & 0x3f) );
609 snd_emu1212m_fpga_write(emu, 0x03, (value & 0x3f) );
610
611 return 0;
612}
613
614static int __devinit snd_emu10k1_emu1212m_init(struct snd_emu10k1 * emu)
615{
616 unsigned int i;
617 int tmp;
618
619 snd_printk(KERN_ERR "emu1212m: Special config.\n");
620 outl(0x0005a00c, emu->port + HCFG);
621 outl(0x0005a004, emu->port + HCFG);
622 outl(0x0005a000, emu->port + HCFG);
623 outl(0x0005a000, emu->port + HCFG);
624
625 snd_emu1212m_fpga_read(emu, 0x22, &tmp );
626 snd_emu1212m_fpga_read(emu, 0x23, &tmp );
627 snd_emu1212m_fpga_read(emu, 0x24, &tmp );
628 snd_emu1212m_fpga_write(emu, 0x04, 0x01 );
629 snd_emu1212m_fpga_read(emu, 0x0b, &tmp );
630 snd_emu1212m_fpga_write(emu, 0x0b, 0x01 );
631 snd_emu1212m_fpga_read(emu, 0x10, &tmp );
632 snd_emu1212m_fpga_write(emu, 0x10, 0x00 );
633 snd_emu1212m_fpga_read(emu, 0x11, &tmp );
634 snd_emu1212m_fpga_write(emu, 0x11, 0x30 );
635 snd_emu1212m_fpga_read(emu, 0x13, &tmp );
636 snd_emu1212m_fpga_write(emu, 0x13, 0x0f );
637 snd_emu1212m_fpga_read(emu, 0x11, &tmp );
638 snd_emu1212m_fpga_write(emu, 0x11, 0x30 );
639 snd_emu1212m_fpga_read(emu, 0x0a, &tmp );
640 snd_emu1212m_fpga_write(emu, 0x0a, 0x10 );
641 snd_emu1212m_fpga_write(emu, 0x0c, 0x19 );
642 snd_emu1212m_fpga_write(emu, 0x12, 0x0c );
643 snd_emu1212m_fpga_write(emu, 0x09, 0x0f );
644 snd_emu1212m_fpga_write(emu, 0x06, 0x00 );
645 snd_emu1212m_fpga_write(emu, 0x05, 0x00 );
646 snd_emu1212m_fpga_write(emu, 0x0e, 0x12 );
647 snd_emu1212m_fpga_netlist_write(emu, 0x0000, 0x0200);
648 snd_emu1212m_fpga_netlist_write(emu, 0x0001, 0x0201);
649 snd_emu1212m_fpga_netlist_write(emu, 0x0002, 0x0500);
650 snd_emu1212m_fpga_netlist_write(emu, 0x0003, 0x0501);
651 snd_emu1212m_fpga_netlist_write(emu, 0x0004, 0x0400);
652 snd_emu1212m_fpga_netlist_write(emu, 0x0005, 0x0401);
653 snd_emu1212m_fpga_netlist_write(emu, 0x0006, 0x0402);
654 snd_emu1212m_fpga_netlist_write(emu, 0x0007, 0x0403);
655 snd_emu1212m_fpga_netlist_write(emu, 0x0008, 0x0404);
656 snd_emu1212m_fpga_netlist_write(emu, 0x0009, 0x0405);
657 snd_emu1212m_fpga_netlist_write(emu, 0x000a, 0x0406);
658 snd_emu1212m_fpga_netlist_write(emu, 0x000b, 0x0407);
659 snd_emu1212m_fpga_netlist_write(emu, 0x000c, 0x0100);
660 snd_emu1212m_fpga_netlist_write(emu, 0x000d, 0x0104);
661 snd_emu1212m_fpga_netlist_write(emu, 0x000e, 0x0200);
662 snd_emu1212m_fpga_netlist_write(emu, 0x000f, 0x0201);
663 for (i=0;i < 0x20;i++) {
664 snd_emu1212m_fpga_netlist_write(emu, 0x0100+i, 0x0000);
665 }
666 for (i=0;i < 4;i++) {
667 snd_emu1212m_fpga_netlist_write(emu, 0x0200+i, 0x0000);
668 }
669 for (i=0;i < 7;i++) {
670 snd_emu1212m_fpga_netlist_write(emu, 0x0300+i, 0x0000);
671 }
672 for (i=0;i < 7;i++) {
673 snd_emu1212m_fpga_netlist_write(emu, 0x0400+i, 0x0000);
674 }
675 snd_emu1212m_fpga_netlist_write(emu, 0x0500, 0x0108);
676 snd_emu1212m_fpga_netlist_write(emu, 0x0501, 0x010c);
677 snd_emu1212m_fpga_netlist_write(emu, 0x0600, 0x0110);
678 snd_emu1212m_fpga_netlist_write(emu, 0x0601, 0x0114);
679 snd_emu1212m_fpga_netlist_write(emu, 0x0700, 0x0118);
680 snd_emu1212m_fpga_netlist_write(emu, 0x0701, 0x011c);
681 snd_emu1212m_fpga_write(emu, 0x07, 0x01 );
682
683 snd_emu1212m_fpga_read(emu, 0x21, &tmp );
684
685 outl(0x0000a000, emu->port + HCFG);
686 outl(0x0000a001, emu->port + HCFG);
687 /* Initial boot complete. Now patches */
688
689 snd_emu1212m_fpga_read(emu, 0x21, &tmp );
690 snd_emu1212m_fpga_write(emu, 0x0c, 0x19 );
691 snd_emu1212m_fpga_write(emu, 0x12, 0x0c );
692 snd_emu1212m_fpga_write(emu, 0x0c, 0x19 );
693 snd_emu1212m_fpga_write(emu, 0x12, 0x0c );
694 snd_emu1212m_fpga_read(emu, 0x0a, &tmp );
695 snd_emu1212m_fpga_write(emu, 0x0a, 0x10 );
696
697 snd_emu1212m_fpga_read(emu, 0x20, &tmp );
698 snd_emu1212m_fpga_read(emu, 0x21, &tmp );
699
700 snd_emu1212m_fpga_netlist_write(emu, 0x0300, 0x0312);
701 snd_emu1212m_fpga_netlist_write(emu, 0x0301, 0x0313);
702 snd_emu1212m_fpga_netlist_write(emu, 0x0200, 0x0302);
703 snd_emu1212m_fpga_netlist_write(emu, 0x0201, 0x0303);
704
705 return 0;
706}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700707/*
708 * Create the EMU10K1 instance
709 */
710
Takashi Iwai09668b42005-11-17 16:14:10 +0100711#ifdef CONFIG_PM
712static int alloc_pm_buffer(struct snd_emu10k1 *emu);
713static void free_pm_buffer(struct snd_emu10k1 *emu);
714#endif
715
Takashi Iwaieb4698f2005-11-17 14:50:13 +0100716static int snd_emu10k1_free(struct snd_emu10k1 *emu)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700717{
718 if (emu->port) { /* avoid access to already used hardware */
719 snd_emu10k1_fx8010_tram_setup(emu, 0);
720 snd_emu10k1_done(emu);
Takashi Iwai09668b42005-11-17 16:14:10 +0100721 /* remove reserved page */
722 if (emu->reserved_page) {
723 snd_emu10k1_synth_free(emu, (struct snd_util_memblk *)emu->reserved_page);
724 emu->reserved_page = NULL;
725 }
726 snd_emu10k1_free_efx(emu);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700727 }
728 if (emu->memhdr)
729 snd_util_memhdr_free(emu->memhdr);
730 if (emu->silent_page.area)
731 snd_dma_free_pages(&emu->silent_page);
732 if (emu->ptb_pages.area)
733 snd_dma_free_pages(&emu->ptb_pages);
734 vfree(emu->page_ptr_table);
735 vfree(emu->page_addr_table);
Takashi Iwai09668b42005-11-17 16:14:10 +0100736#ifdef CONFIG_PM
737 free_pm_buffer(emu);
738#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700739 if (emu->irq >= 0)
740 free_irq(emu->irq, (void *)emu);
741 if (emu->port)
742 pci_release_regions(emu->pci);
Lee Revell2b637da2005-03-30 13:51:18 +0200743 if (emu->card_capabilities->ca0151_chip) /* P16V */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700744 snd_p16v_free(emu);
Takashi Iwai09668b42005-11-17 16:14:10 +0100745 pci_disable_device(emu->pci);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700746 kfree(emu);
747 return 0;
748}
749
Takashi Iwaieb4698f2005-11-17 14:50:13 +0100750static int snd_emu10k1_dev_free(struct snd_device *device)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700751{
Takashi Iwaieb4698f2005-11-17 14:50:13 +0100752 struct snd_emu10k1 *emu = device->device_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700753 return snd_emu10k1_free(emu);
754}
755
Takashi Iwaieb4698f2005-11-17 14:50:13 +0100756static struct snd_emu_chip_details emu_chip_details[] = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700757 /* 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 +0200758 /* Tested by James@superbug.co.uk 3rd July 2005 */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700759 {.vendor = 0x1102, .device = 0x0008, .subsystem = 0x10011102,
760 .driver = "Audigy2", .name = "Audigy 2 Value [SB0400]",
Takashi Iwaiaec72e02005-03-30 14:22:25 +0200761 .id = "Audigy2",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700762 .emu10k2_chip = 1,
763 .ca0108_chip = 1,
Peter Zubaj26689072005-04-01 11:15:07 +0200764 .spk71 = 1,
765 .ac97_chip = 1} ,
James Courtier-Duttond83c6712005-10-31 10:27:41 +0000766 /* Audigy 2 ZS Notebook Cardbus card.*/
767 /* Tested by James@superbug.co.uk 30th October 2005 */
768 /* Not working yet, but progressing. */
769 {.vendor = 0x1102, .device = 0x0008, .subsystem = 0x20011102,
770 .driver = "Audigy2", .name = "Audigy 2 ZS Notebook [SB0530]",
771 .id = "Audigy2",
772 .emu10k2_chip = 1,
773 .ca0108_chip = 1,
774 .ca_cardbus_chip = 1,
James Courtier-Dutton27fe8642005-12-21 15:06:08 +0100775 .spi_dac = 1,
James Courtier-Duttond83c6712005-10-31 10:27:41 +0000776 .spk71 = 1} ,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700777 {.vendor = 0x1102, .device = 0x0008,
778 .driver = "Audigy2", .name = "Audigy 2 Value [Unknown]",
Takashi Iwaiaec72e02005-03-30 14:22:25 +0200779 .id = "Audigy2",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700780 .emu10k2_chip = 1,
Peter Zubaj26689072005-04-01 11:15:07 +0200781 .ca0108_chip = 1,
782 .ac97_chip = 1} ,
James Courtier-Dutton7c1d5492005-07-10 11:50:36 +0200783 /* Tested by James@superbug.co.uk 8th July 2005. No sound available yet. */
784 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x40011102,
785 .driver = "Audigy2", .name = "E-mu 1212m [4001]",
786 .id = "EMU1212m",
787 .emu10k2_chip = 1,
788 .ca0102_chip = 1,
James Courtier-Dutton19b99fb2005-12-04 18:03:03 +0100789 .emu1212m = 1} ,
James Courtier-Dutton88dc0e52005-07-03 12:54:29 +0200790 /* Tested by James@superbug.co.uk 3rd July 2005 */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700791 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x20071102,
792 .driver = "Audigy2", .name = "Audigy 4 PRO [SB0380]",
Takashi Iwaiaec72e02005-03-30 14:22:25 +0200793 .id = "Audigy2",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700794 .emu10k2_chip = 1,
795 .ca0102_chip = 1,
796 .ca0151_chip = 1,
797 .spk71 = 1,
798 .spdif_bug = 1,
799 .ac97_chip = 1} ,
Lee Revellf6f8bb62005-11-07 14:59:19 +0100800 /* Tested by shane-alsa@cm.nu 5th Nov 2005 */
801 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x20061102,
802 .driver = "Audigy2", .name = "Audigy 2 [2006]",
803 .id = "Audigy2",
804 .emu10k2_chip = 1,
805 .ca0102_chip = 1,
806 .ca0151_chip = 1,
807 .spk71 = 1,
808 .spdif_bug = 1,
809 .ac97_chip = 1} ,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700810 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x20021102,
811 .driver = "Audigy2", .name = "Audigy 2 ZS [SB0350]",
Takashi Iwaiaec72e02005-03-30 14:22:25 +0200812 .id = "Audigy2",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700813 .emu10k2_chip = 1,
814 .ca0102_chip = 1,
815 .ca0151_chip = 1,
816 .spk71 = 1,
817 .spdif_bug = 1,
818 .ac97_chip = 1} ,
819 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x20011102,
820 .driver = "Audigy2", .name = "Audigy 2 ZS [2001]",
Takashi Iwaiaec72e02005-03-30 14:22:25 +0200821 .id = "Audigy2",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700822 .emu10k2_chip = 1,
823 .ca0102_chip = 1,
824 .ca0151_chip = 1,
825 .spk71 = 1,
826 .spdif_bug = 1,
827 .ac97_chip = 1} ,
828 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x10071102,
829 .driver = "Audigy2", .name = "Audigy 2 [SB0240]",
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} ,
837 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x10051102,
838 .driver = "Audigy2", .name = "Audigy 2 EX [1005]",
Takashi Iwaiaec72e02005-03-30 14:22:25 +0200839 .id = "Audigy2",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700840 .emu10k2_chip = 1,
841 .ca0102_chip = 1,
842 .ca0151_chip = 1,
Lee Revell2f020aa2005-11-07 14:54:24 +0100843 .spk71 = 1,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700844 .spdif_bug = 1} ,
845 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x10021102,
846 .driver = "Audigy2", .name = "Audigy 2 Platinum [SB0240P]",
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} ,
Takashi Iwaibdaed502005-04-07 15:48:42 +0200854 {.vendor = 0x1102, .device = 0x0004, .revision = 0x04,
855 .driver = "Audigy2", .name = "Audigy 2 [Unknown]",
856 .id = "Audigy2",
857 .emu10k2_chip = 1,
858 .ca0102_chip = 1,
859 .ca0151_chip = 1,
860 .spdif_bug = 1,
861 .ac97_chip = 1} ,
Peter Zubaj26689072005-04-01 11:15:07 +0200862 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x00531102,
863 .driver = "Audigy", .name = "Audigy 1 [SB0090]",
864 .id = "Audigy",
865 .emu10k2_chip = 1,
866 .ca0102_chip = 1,
867 .ac97_chip = 1} ,
James Courtier-Duttonae3a72d2005-07-06 22:36:18 +0200868 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x00521102,
869 .driver = "Audigy", .name = "Audigy 1 ES [SB0160]",
870 .id = "Audigy",
871 .emu10k2_chip = 1,
872 .ca0102_chip = 1,
873 .spdif_bug = 1,
874 .ac97_chip = 1} ,
Arnaud Patarda6c17ec2005-05-27 12:31:34 +0200875 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x00511102,
876 .driver = "Audigy", .name = "Audigy 1 [SB0090]",
877 .id = "Audigy",
878 .emu10k2_chip = 1,
879 .ca0102_chip = 1,
880 .ac97_chip = 1} ,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700881 {.vendor = 0x1102, .device = 0x0004,
Takashi Iwaibdaed502005-04-07 15:48:42 +0200882 .driver = "Audigy", .name = "Audigy 1 [Unknown]",
Takashi Iwaiaec72e02005-03-30 14:22:25 +0200883 .id = "Audigy",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700884 .emu10k2_chip = 1,
885 .ca0102_chip = 1,
Peter Zubaj26689072005-04-01 11:15:07 +0200886 .ac97_chip = 1} ,
James Courtier-Duttona6f61922005-07-03 12:32:40 +0200887 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x806B1102,
888 .driver = "EMU10K1", .name = "SBLive! [SB0105]",
James Courtier-Dutton2b6b22f2005-06-18 13:50:22 +0200889 .id = "Live",
890 .emu10k1_chip = 1,
891 .ac97_chip = 1,
892 .sblive51 = 1} ,
893 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x806A1102,
894 .driver = "EMU10K1", .name = "SBLive! Value [SB0103]",
895 .id = "Live",
896 .emu10k1_chip = 1,
897 .ac97_chip = 1,
898 .sblive51 = 1} ,
James Courtier-Duttona6f61922005-07-03 12:32:40 +0200899 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80691102,
900 .driver = "EMU10K1", .name = "SBLive! Value [SB0101]",
901 .id = "Live",
902 .emu10k1_chip = 1,
903 .ac97_chip = 1,
904 .sblive51 = 1} ,
Lee Revellc6c0b842005-08-29 17:42:00 +0200905 /* Tested by Thomas Zehetbauer 27th Aug 2005 */
906 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80651102,
907 .driver = "EMU10K1", .name = "SB Live 5.1 [SB0220]",
908 .id = "Live",
909 .emu10k1_chip = 1,
910 .ac97_chip = 1,
911 .sblive51 = 1} ,
Gergely Tamasa8ee7292005-12-06 14:10:57 +0100912 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x100a1102,
913 .driver = "EMU10K1", .name = "SB Live 5.1 [SB0220]",
914 .id = "Live",
915 .emu10k1_chip = 1,
916 .ac97_chip = 1,
917 .sblive51 = 1} ,
James Courtier-Duttona6f61922005-07-03 12:32:40 +0200918 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80641102,
919 .driver = "EMU10K1", .name = "SB Live 5.1",
920 .id = "Live",
921 .emu10k1_chip = 1,
922 .ac97_chip = 1,
923 .sblive51 = 1} ,
James Courtier-Duttonafe0f1f2005-09-10 10:24:10 +0200924 /* Tested by alsa bugtrack user "hus" bug #1297 12th Aug 2005 */
James Courtier-Duttona6f61922005-07-03 12:32:40 +0200925 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80611102,
Takashi Iwaif12aa402005-09-30 16:56:59 +0200926 .driver = "EMU10K1", .name = "SBLive 5.1 [SB0060]",
James Courtier-Duttona6f61922005-07-03 12:32:40 +0200927 .id = "Live",
928 .emu10k1_chip = 1,
Takashi Iwaif12aa402005-09-30 16:56:59 +0200929 .ac97_chip = 2, /* ac97 is optional; both SBLive 5.1 and platinum
930 * share the same IDs!
931 */
James Courtier-Duttona6f61922005-07-03 12:32:40 +0200932 .sblive51 = 1} ,
933 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80511102,
934 .driver = "EMU10K1", .name = "SBLive! Value [CT4850]",
935 .id = "Live",
936 .emu10k1_chip = 1,
937 .ac97_chip = 1,
938 .sblive51 = 1} ,
939 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80401102,
940 .driver = "EMU10K1", .name = "SBLive! Platinum [CT4760P]",
941 .id = "Live",
942 .emu10k1_chip = 1,
943 .ac97_chip = 1} ,
944 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80321102,
945 .driver = "EMU10K1", .name = "SBLive! Value [CT4871]",
946 .id = "Live",
947 .emu10k1_chip = 1,
948 .ac97_chip = 1,
949 .sblive51 = 1} ,
950 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80311102,
951 .driver = "EMU10K1", .name = "SBLive! Value [CT4831]",
952 .id = "Live",
953 .emu10k1_chip = 1,
954 .ac97_chip = 1,
955 .sblive51 = 1} ,
956 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80281102,
957 .driver = "EMU10K1", .name = "SBLive! Value [CT4870]",
958 .id = "Live",
959 .emu10k1_chip = 1,
960 .ac97_chip = 1,
961 .sblive51 = 1} ,
James Courtier-Dutton88dc0e52005-07-03 12:54:29 +0200962 /* Tested by James@superbug.co.uk 3rd July 2005 */
James Courtier-Duttona6f61922005-07-03 12:32:40 +0200963 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80271102,
964 .driver = "EMU10K1", .name = "SBLive! Value [CT4832]",
965 .id = "Live",
966 .emu10k1_chip = 1,
967 .ac97_chip = 1,
968 .sblive51 = 1} ,
969 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80261102,
970 .driver = "EMU10K1", .name = "SBLive! Value [CT4830]",
971 .id = "Live",
972 .emu10k1_chip = 1,
973 .ac97_chip = 1,
974 .sblive51 = 1} ,
975 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80231102,
976 .driver = "EMU10K1", .name = "SB PCI512 [CT4790]",
977 .id = "Live",
978 .emu10k1_chip = 1,
979 .ac97_chip = 1,
980 .sblive51 = 1} ,
981 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80221102,
982 .driver = "EMU10K1", .name = "SBLive! Value [CT4780]",
983 .id = "Live",
984 .emu10k1_chip = 1,
985 .ac97_chip = 1,
986 .sblive51 = 1} ,
987 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x40011102,
988 .driver = "EMU10K1", .name = "E-mu APS [4001]",
989 .id = "APS",
990 .emu10k1_chip = 1,
991 .ecard = 1} ,
992 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x00211102,
993 .driver = "EMU10K1", .name = "SBLive! [CT4620]",
994 .id = "Live",
995 .emu10k1_chip = 1,
996 .ac97_chip = 1,
997 .sblive51 = 1} ,
998 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x00201102,
999 .driver = "EMU10K1", .name = "SBLive! Value [CT4670]",
James Courtier-Dutton2b6b22f2005-06-18 13:50:22 +02001000 .id = "Live",
1001 .emu10k1_chip = 1,
1002 .ac97_chip = 1,
1003 .sblive51 = 1} ,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001004 {.vendor = 0x1102, .device = 0x0002,
1005 .driver = "EMU10K1", .name = "SB Live [Unknown]",
Takashi Iwaiaec72e02005-03-30 14:22:25 +02001006 .id = "Live",
Linus Torvalds1da177e2005-04-16 15:20:36 -07001007 .emu10k1_chip = 1,
Lee Revell2b637da2005-03-30 13:51:18 +02001008 .ac97_chip = 1,
1009 .sblive51 = 1} ,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001010 { } /* terminator */
1011};
1012
Takashi Iwaieb4698f2005-11-17 14:50:13 +01001013int __devinit snd_emu10k1_create(struct snd_card *card,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001014 struct pci_dev * pci,
1015 unsigned short extin_mask,
1016 unsigned short extout_mask,
1017 long max_cache_bytes,
1018 int enable_ir,
James Courtier-Duttone66bc8b2005-07-06 22:21:51 +02001019 uint subsystem,
Takashi Iwaieb4698f2005-11-17 14:50:13 +01001020 struct snd_emu10k1 ** remu)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001021{
Takashi Iwaieb4698f2005-11-17 14:50:13 +01001022 struct snd_emu10k1 *emu;
Takashi Iwai09668b42005-11-17 16:14:10 +01001023 int idx, err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001024 int is_audigy;
1025 unsigned char revision;
Takashi Iwai09668b42005-11-17 16:14:10 +01001026 unsigned int silent_page;
Takashi Iwaieb4698f2005-11-17 14:50:13 +01001027 const struct snd_emu_chip_details *c;
1028 static struct snd_device_ops ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001029 .dev_free = snd_emu10k1_dev_free,
1030 };
1031
1032 *remu = NULL;
1033
1034 /* enable PCI device */
1035 if ((err = pci_enable_device(pci)) < 0)
1036 return err;
1037
Takashi Iwaie560d8d2005-09-09 14:21:46 +02001038 emu = kzalloc(sizeof(*emu), GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001039 if (emu == NULL) {
1040 pci_disable_device(pci);
1041 return -ENOMEM;
1042 }
1043 emu->card = card;
1044 spin_lock_init(&emu->reg_lock);
1045 spin_lock_init(&emu->emu_lock);
1046 spin_lock_init(&emu->voice_lock);
1047 spin_lock_init(&emu->synth_lock);
1048 spin_lock_init(&emu->memblk_lock);
1049 init_MUTEX(&emu->ptb_lock);
1050 init_MUTEX(&emu->fx8010.lock);
1051 INIT_LIST_HEAD(&emu->mapped_link_head);
1052 INIT_LIST_HEAD(&emu->mapped_order_link_head);
1053 emu->pci = pci;
1054 emu->irq = -1;
1055 emu->synth = NULL;
1056 emu->get_synth_voice = NULL;
1057 /* read revision & serial */
1058 pci_read_config_byte(pci, PCI_REVISION_ID, &revision);
1059 emu->revision = revision;
1060 pci_read_config_dword(pci, PCI_SUBSYSTEM_VENDOR_ID, &emu->serial);
1061 pci_read_config_word(pci, PCI_SUBSYSTEM_ID, &emu->model);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001062 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);
1063
1064 for (c = emu_chip_details; c->vendor; c++) {
1065 if (c->vendor == pci->vendor && c->device == pci->device) {
James Courtier-Duttone66bc8b2005-07-06 22:21:51 +02001066 if (subsystem) {
1067 if (c->subsystem && (c->subsystem == subsystem) ) {
1068 break;
1069 } else continue;
1070 } else {
1071 if (c->subsystem && (c->subsystem != emu->serial) )
1072 continue;
1073 if (c->revision && c->revision != emu->revision)
1074 continue;
1075 }
Takashi Iwaibdaed502005-04-07 15:48:42 +02001076 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001077 }
1078 }
1079 if (c->vendor == 0) {
1080 snd_printk(KERN_ERR "emu10k1: Card not recognised\n");
1081 kfree(emu);
1082 pci_disable_device(pci);
1083 return -ENOENT;
1084 }
1085 emu->card_capabilities = c;
James Courtier-Duttone66bc8b2005-07-06 22:21:51 +02001086 if (c->subsystem && !subsystem)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001087 snd_printdd("Sound card name=%s\n", c->name);
James Courtier-Duttone66bc8b2005-07-06 22:21:51 +02001088 else if (subsystem)
1089 snd_printdd("Sound card name=%s, vendor=0x%x, device=0x%x, subsystem=0x%x. Forced to subsytem=0x%x\n",
1090 c->name, pci->vendor, pci->device, emu->serial, c->subsystem);
1091 else
1092 snd_printdd("Sound card name=%s, vendor=0x%x, device=0x%x, subsystem=0x%x.\n",
1093 c->name, pci->vendor, pci->device, emu->serial);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001094
Takashi Iwai85a655d2005-03-30 14:40:25 +02001095 if (!*card->id && c->id) {
1096 int i, n = 0;
Takashi Iwaiaec72e02005-03-30 14:22:25 +02001097 strlcpy(card->id, c->id, sizeof(card->id));
Takashi Iwai85a655d2005-03-30 14:40:25 +02001098 for (;;) {
1099 for (i = 0; i < snd_ecards_limit; i++) {
1100 if (snd_cards[i] && !strcmp(snd_cards[i]->id, card->id))
1101 break;
1102 }
1103 if (i >= snd_ecards_limit)
1104 break;
1105 n++;
1106 if (n >= SNDRV_CARDS)
1107 break;
1108 snprintf(card->id, sizeof(card->id), "%s_%d", c->id, n);
1109 }
1110 }
Takashi Iwaiaec72e02005-03-30 14:22:25 +02001111
Linus Torvalds1da177e2005-04-16 15:20:36 -07001112 is_audigy = emu->audigy = c->emu10k2_chip;
1113
1114 /* set the DMA transfer mask */
1115 emu->dma_mask = is_audigy ? AUDIGY_DMA_MASK : EMU10K1_DMA_MASK;
1116 if (pci_set_dma_mask(pci, emu->dma_mask) < 0 ||
1117 pci_set_consistent_dma_mask(pci, emu->dma_mask) < 0) {
1118 snd_printk(KERN_ERR "architecture does not support PCI busmaster DMA with mask 0x%lx\n", emu->dma_mask);
1119 kfree(emu);
1120 pci_disable_device(pci);
1121 return -ENXIO;
1122 }
1123 if (is_audigy)
1124 emu->gpr_base = A_FXGPREGBASE;
1125 else
1126 emu->gpr_base = FXGPREGBASE;
1127
1128 if ((err = pci_request_regions(pci, "EMU10K1")) < 0) {
1129 kfree(emu);
1130 pci_disable_device(pci);
1131 return err;
1132 }
1133 emu->port = pci_resource_start(pci, 0);
1134
1135 if (request_irq(pci->irq, snd_emu10k1_interrupt, SA_INTERRUPT|SA_SHIRQ, "EMU10K1", (void *)emu)) {
Takashi Iwai09668b42005-11-17 16:14:10 +01001136 err = -EBUSY;
1137 goto error;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001138 }
1139 emu->irq = pci->irq;
1140
1141 emu->max_cache_pages = max_cache_bytes >> PAGE_SHIFT;
1142 if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(pci),
1143 32 * 1024, &emu->ptb_pages) < 0) {
Takashi Iwai09668b42005-11-17 16:14:10 +01001144 err = -ENOMEM;
1145 goto error;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001146 }
1147
1148 emu->page_ptr_table = (void **)vmalloc(emu->max_cache_pages * sizeof(void*));
1149 emu->page_addr_table = (unsigned long*)vmalloc(emu->max_cache_pages * sizeof(unsigned long));
1150 if (emu->page_ptr_table == NULL || emu->page_addr_table == NULL) {
Takashi Iwai09668b42005-11-17 16:14:10 +01001151 err = -ENOMEM;
1152 goto error;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001153 }
1154
1155 if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(pci),
1156 EMUPAGESIZE, &emu->silent_page) < 0) {
Takashi Iwai09668b42005-11-17 16:14:10 +01001157 err = -ENOMEM;
1158 goto error;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001159 }
1160 emu->memhdr = snd_util_memhdr_new(emu->max_cache_pages * PAGE_SIZE);
1161 if (emu->memhdr == NULL) {
Takashi Iwai09668b42005-11-17 16:14:10 +01001162 err = -ENOMEM;
1163 goto error;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001164 }
Takashi Iwaieb4698f2005-11-17 14:50:13 +01001165 emu->memhdr->block_extra_size = sizeof(struct snd_emu10k1_memblk) -
1166 sizeof(struct snd_util_memblk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001167
1168 pci_set_master(pci);
1169
Linus Torvalds1da177e2005-04-16 15:20:36 -07001170 emu->fx8010.fxbus_mask = 0x303f;
1171 if (extin_mask == 0)
1172 extin_mask = 0x3fcf;
1173 if (extout_mask == 0)
1174 extout_mask = 0x7fff;
1175 emu->fx8010.extin_mask = extin_mask;
1176 emu->fx8010.extout_mask = extout_mask;
Takashi Iwai09668b42005-11-17 16:14:10 +01001177 emu->enable_ir = enable_ir;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001178
Lee Revell2b637da2005-03-30 13:51:18 +02001179 if (emu->card_capabilities->ecard) {
Takashi Iwai09668b42005-11-17 16:14:10 +01001180 if ((err = snd_emu10k1_ecard_init(emu)) < 0)
1181 goto error;
James Courtier-Duttond83c6712005-10-31 10:27:41 +00001182 } else if (emu->card_capabilities->ca_cardbus_chip) {
Takashi Iwai09668b42005-11-17 16:14:10 +01001183 if ((err = snd_emu10k1_cardbus_init(emu)) < 0)
1184 goto error;
James Courtier-Dutton19b99fb2005-12-04 18:03:03 +01001185 } else if (emu->card_capabilities->emu1212m) {
1186 if ((err = snd_emu10k1_emu1212m_init(emu)) < 0) {
1187 snd_emu10k1_free(emu);
1188 return err;
1189 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001190 } else {
1191 /* 5.1: Enable the additional AC97 Slots. If the emu10k1 version
1192 does not support this, it shouldn't do any harm */
1193 snd_emu10k1_ptr_write(emu, AC97SLOT, 0, AC97SLOT_CNTR|AC97SLOT_LFE);
1194 }
1195
Takashi Iwai09668b42005-11-17 16:14:10 +01001196 /* initialize TRAM setup */
1197 emu->fx8010.itram_size = (16 * 1024)/2;
1198 emu->fx8010.etram_pages.area = NULL;
1199 emu->fx8010.etram_pages.bytes = 0;
1200
1201 /*
1202 * Init to 0x02109204 :
1203 * Clock accuracy = 0 (1000ppm)
1204 * Sample Rate = 2 (48kHz)
1205 * Audio Channel = 1 (Left of 2)
1206 * Source Number = 0 (Unspecified)
1207 * Generation Status = 1 (Original for Cat Code 12)
1208 * Cat Code = 12 (Digital Signal Mixer)
1209 * Mode = 0 (Mode 0)
1210 * Emphasis = 0 (None)
1211 * CP = 1 (Copyright unasserted)
1212 * AN = 0 (Audio data)
1213 * P = 0 (Consumer)
1214 */
1215 emu->spdif_bits[0] = emu->spdif_bits[1] =
1216 emu->spdif_bits[2] = SPCS_CLKACCY_1000PPM | SPCS_SAMPLERATE_48 |
1217 SPCS_CHANNELNUM_LEFT | SPCS_SOURCENUM_UNSPEC |
1218 SPCS_GENERATIONSTATUS | 0x00001200 |
1219 0x00000000 | SPCS_EMPHASIS_NONE | SPCS_COPYRIGHT;
1220
1221 emu->reserved_page = (struct snd_emu10k1_memblk *)
1222 snd_emu10k1_synth_alloc(emu, 4096);
1223 if (emu->reserved_page)
1224 emu->reserved_page->map_locked = 1;
1225
1226 /* Clear silent pages and set up pointers */
1227 memset(emu->silent_page.area, 0, PAGE_SIZE);
1228 silent_page = emu->silent_page.addr << 1;
1229 for (idx = 0; idx < MAXPAGES; idx++)
1230 ((u32 *)emu->ptb_pages.area)[idx] = cpu_to_le32(silent_page | idx);
1231
1232 /* set up voice indices */
1233 for (idx = 0; idx < NUM_G; idx++) {
1234 emu->voices[idx].emu = emu;
1235 emu->voices[idx].number = idx;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001236 }
1237
Takashi Iwai09668b42005-11-17 16:14:10 +01001238 if ((err = snd_emu10k1_init(emu, enable_ir, 0)) < 0)
1239 goto error;
1240#ifdef CONFIG_PM
1241 if ((err = alloc_pm_buffer(emu)) < 0)
1242 goto error;
1243#endif
1244
1245 /* Initialize the effect engine */
1246 if ((err = snd_emu10k1_init_efx(emu)) < 0)
1247 goto error;
1248 snd_emu10k1_audio_enable(emu);
1249
1250 if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, emu, &ops)) < 0)
1251 goto error;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001252
Takashi Iwaiadf1b3d2005-12-01 10:49:58 +01001253#ifdef CONFIG_PROC_FS
Linus Torvalds1da177e2005-04-16 15:20:36 -07001254 snd_emu10k1_proc_init(emu);
Takashi Iwaiadf1b3d2005-12-01 10:49:58 +01001255#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -07001256
1257 snd_card_set_dev(card, &pci->dev);
1258 *remu = emu;
1259 return 0;
Takashi Iwai09668b42005-11-17 16:14:10 +01001260
1261 error:
1262 snd_emu10k1_free(emu);
1263 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001264}
1265
Takashi Iwai09668b42005-11-17 16:14:10 +01001266#ifdef CONFIG_PM
1267static unsigned char saved_regs[] = {
1268 CPF, PTRX, CVCF, VTFT, Z1, Z2, PSST, DSL, CCCA, CCR, CLP,
1269 FXRT, MAPA, MAPB, ENVVOL, ATKHLDV, DCYSUSV, LFOVAL1, ENVVAL,
1270 ATKHLDM, DCYSUSM, LFOVAL2, IP, IFATN, PEFE, FMMOD, TREMFRQ, FM2FRQ2,
1271 TEMPENV, ADCCR, FXWC, MICBA, ADCBA, FXBA,
1272 MICBS, ADCBS, FXBS, CDCS, GPSCS, SPCS0, SPCS1, SPCS2,
1273 SPBYPASS, AC97SLOT, CDSRCS, GPSRCS, ZVSRCS, MICIDX, ADCIDX, FXIDX,
1274 0xff /* end */
1275};
1276static unsigned char saved_regs_audigy[] = {
1277 A_ADCIDX, A_MICIDX, A_FXWC1, A_FXWC2, A_SAMPLE_RATE,
1278 A_FXRT2, A_SENDAMOUNTS, A_FXRT1,
1279 0xff /* end */
1280};
1281
1282static int __devinit alloc_pm_buffer(struct snd_emu10k1 *emu)
1283{
1284 int size;
1285
1286 size = ARRAY_SIZE(saved_regs);
1287 if (emu->audigy)
1288 size += ARRAY_SIZE(saved_regs_audigy);
1289 emu->saved_ptr = vmalloc(4 * NUM_G * size);
1290 if (! emu->saved_ptr)
1291 return -ENOMEM;
1292 if (snd_emu10k1_efx_alloc_pm_buffer(emu) < 0)
1293 return -ENOMEM;
1294 if (emu->card_capabilities->ca0151_chip &&
1295 snd_p16v_alloc_pm_buffer(emu) < 0)
1296 return -ENOMEM;
1297 return 0;
1298}
1299
1300static void free_pm_buffer(struct snd_emu10k1 *emu)
1301{
1302 vfree(emu->saved_ptr);
1303 snd_emu10k1_efx_free_pm_buffer(emu);
1304 if (emu->card_capabilities->ca0151_chip)
1305 snd_p16v_free_pm_buffer(emu);
1306}
1307
1308void snd_emu10k1_suspend_regs(struct snd_emu10k1 *emu)
1309{
1310 int i;
1311 unsigned char *reg;
1312 unsigned int *val;
1313
1314 val = emu->saved_ptr;
1315 for (reg = saved_regs; *reg != 0xff; reg++)
1316 for (i = 0; i < NUM_G; i++, val++)
1317 *val = snd_emu10k1_ptr_read(emu, *reg, i);
1318 if (emu->audigy) {
1319 for (reg = saved_regs_audigy; *reg != 0xff; reg++)
1320 for (i = 0; i < NUM_G; i++, val++)
1321 *val = snd_emu10k1_ptr_read(emu, *reg, i);
1322 }
1323 if (emu->audigy)
1324 emu->saved_a_iocfg = inl(emu->port + A_IOCFG);
1325 emu->saved_hcfg = inl(emu->port + HCFG);
1326}
1327
1328void snd_emu10k1_resume_init(struct snd_emu10k1 *emu)
1329{
1330 if (emu->card_capabilities->ecard)
1331 snd_emu10k1_ecard_init(emu);
1332 else
1333 snd_emu10k1_ptr_write(emu, AC97SLOT, 0, AC97SLOT_CNTR|AC97SLOT_LFE);
1334 snd_emu10k1_init(emu, emu->enable_ir, 1);
1335}
1336
1337void snd_emu10k1_resume_regs(struct snd_emu10k1 *emu)
1338{
1339 int i;
1340 unsigned char *reg;
1341 unsigned int *val;
1342
1343 snd_emu10k1_audio_enable(emu);
1344
1345 /* resore for spdif */
1346 if (emu->audigy)
1347 outl(emu->port + A_IOCFG, emu->saved_a_iocfg);
1348 outl(emu->port + HCFG, emu->saved_hcfg);
1349
1350 val = emu->saved_ptr;
1351 for (reg = saved_regs; *reg != 0xff; reg++)
1352 for (i = 0; i < NUM_G; i++, val++)
1353 snd_emu10k1_ptr_write(emu, *reg, i, *val);
1354 if (emu->audigy) {
1355 for (reg = saved_regs_audigy; *reg != 0xff; reg++)
1356 for (i = 0; i < NUM_G; i++, val++)
1357 snd_emu10k1_ptr_write(emu, *reg, i, *val);
1358 }
1359}
1360#endif
1361
Linus Torvalds1da177e2005-04-16 15:20:36 -07001362/* memory.c */
1363EXPORT_SYMBOL(snd_emu10k1_synth_alloc);
1364EXPORT_SYMBOL(snd_emu10k1_synth_free);
1365EXPORT_SYMBOL(snd_emu10k1_synth_bzero);
1366EXPORT_SYMBOL(snd_emu10k1_synth_copy_from_user);
1367EXPORT_SYMBOL(snd_emu10k1_memblk_map);
1368/* voice.c */
1369EXPORT_SYMBOL(snd_emu10k1_voice_alloc);
1370EXPORT_SYMBOL(snd_emu10k1_voice_free);
1371/* io.c */
1372EXPORT_SYMBOL(snd_emu10k1_ptr_read);
1373EXPORT_SYMBOL(snd_emu10k1_ptr_write);