blob: f8e2ccd50d60a3bed3468ab64bb7124a8647064e [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 }
184
Linus Torvalds1da177e2005-04-16 15:20:36 -0700185 snd_emu10k1_ptr_write(emu, PTB, 0, emu->ptb_pages.addr);
186 snd_emu10k1_ptr_write(emu, TCB, 0, 0); /* taken from original driver */
187 snd_emu10k1_ptr_write(emu, TCBS, 0, 4); /* taken from original driver */
188
189 silent_page = (emu->silent_page.addr << 1) | MAP_PTI_MASK;
190 for (ch = 0; ch < NUM_G; ch++) {
191 snd_emu10k1_ptr_write(emu, MAPA, ch, silent_page);
192 snd_emu10k1_ptr_write(emu, MAPB, ch, silent_page);
193 }
194
195 /*
196 * Hokay, setup HCFG
197 * Mute Disable Audio = 0
198 * Lock Tank Memory = 1
199 * Lock Sound Memory = 0
200 * Auto Mute = 1
201 */
202 if (emu->audigy) {
203 if (emu->revision == 4) /* audigy2 */
204 outl(HCFG_AUDIOENABLE |
205 HCFG_AC3ENABLE_CDSPDIF |
206 HCFG_AC3ENABLE_GPSPDIF |
207 HCFG_AUTOMUTE | HCFG_JOYENABLE, emu->port + HCFG);
208 else
209 outl(HCFG_AUTOMUTE | HCFG_JOYENABLE, emu->port + HCFG);
James Courtier-Duttone0474e52005-07-02 16:33:34 +0200210 /* FIXME: Remove all these emu->model and replace it with a card recognition parameter,
211 * e.g. card_capabilities->joystick */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700212 } else if (emu->model == 0x20 ||
213 emu->model == 0xc400 ||
214 (emu->model == 0x21 && emu->revision < 6))
215 outl(HCFG_LOCKTANKCACHE_MASK | HCFG_AUTOMUTE, emu->port + HCFG);
216 else
217 // With on-chip joystick
218 outl(HCFG_LOCKTANKCACHE_MASK | HCFG_AUTOMUTE | HCFG_JOYENABLE, emu->port + HCFG);
219
220 if (enable_ir) { /* enable IR for SB Live */
James Courtier-Dutton19b99fb2005-12-04 18:03:03 +0100221 if ( emu->card_capabilities->emu1212m) {
222 ; /* Disable all access to A_IOCFG for the emu1212m */
223 } else if (emu->audigy) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700224 unsigned int reg = inl(emu->port + A_IOCFG);
225 outl(reg | A_IOCFG_GPOUT2, emu->port + A_IOCFG);
226 udelay(500);
227 outl(reg | A_IOCFG_GPOUT1 | A_IOCFG_GPOUT2, emu->port + A_IOCFG);
228 udelay(100);
229 outl(reg, emu->port + A_IOCFG);
230 } else {
231 unsigned int reg = inl(emu->port + HCFG);
232 outl(reg | HCFG_GPOUT2, emu->port + HCFG);
233 udelay(500);
234 outl(reg | HCFG_GPOUT1 | HCFG_GPOUT2, emu->port + HCFG);
235 udelay(100);
236 outl(reg, emu->port + HCFG);
237 }
238 }
239
James Courtier-Dutton19b99fb2005-12-04 18:03:03 +0100240 if ( emu->card_capabilities->emu1212m) {
241 ; /* Disable all access to A_IOCFG for the emu1212m */
242 } else if (emu->audigy) { /* enable analog output */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700243 unsigned int reg = inl(emu->port + A_IOCFG);
244 outl(reg | A_IOCFG_GPOUT0, emu->port + A_IOCFG);
245 }
246
Takashi Iwai09668b42005-11-17 16:14:10 +0100247 return 0;
248}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700249
Takashi Iwai09668b42005-11-17 16:14:10 +0100250static void snd_emu10k1_audio_enable(struct snd_emu10k1 *emu)
251{
Linus Torvalds1da177e2005-04-16 15:20:36 -0700252 /*
253 * Enable the audio bit
254 */
255 outl(inl(emu->port + HCFG) | HCFG_AUDIOENABLE, emu->port + HCFG);
256
257 /* Enable analog/digital outs on audigy */
James Courtier-Dutton19b99fb2005-12-04 18:03:03 +0100258 if ( emu->card_capabilities->emu1212m) {
259 ; /* Disable all access to A_IOCFG for the emu1212m */
260 } else if (emu->audigy) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700261 outl(inl(emu->port + A_IOCFG) & ~0x44, emu->port + A_IOCFG);
262
James Courtier-Duttone0474e52005-07-02 16:33:34 +0200263 if (emu->card_capabilities->ca0151_chip) { /* audigy2 */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700264 /* Unmute Analog now. Set GPO6 to 1 for Apollo.
265 * This has to be done after init ALice3 I2SOut beyond 48KHz.
266 * So, sequence is important. */
267 outl(inl(emu->port + A_IOCFG) | 0x0040, emu->port + A_IOCFG);
James Courtier-Duttone0474e52005-07-02 16:33:34 +0200268 } else if (emu->card_capabilities->ca0108_chip) { /* audigy2 value */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700269 /* Unmute Analog now. */
270 outl(inl(emu->port + A_IOCFG) | 0x0060, emu->port + A_IOCFG);
271 } else {
272 /* Disable routing from AC97 line out to Front speakers */
273 outl(inl(emu->port + A_IOCFG) | 0x0080, emu->port + A_IOCFG);
274 }
275 }
276
277#if 0
278 {
279 unsigned int tmp;
280 /* FIXME: the following routine disables LiveDrive-II !! */
281 // TOSLink detection
282 emu->tos_link = 0;
283 tmp = inl(emu->port + HCFG);
284 if (tmp & (HCFG_GPINPUT0 | HCFG_GPINPUT1)) {
285 outl(tmp|0x800, emu->port + HCFG);
286 udelay(50);
287 if (tmp != (inl(emu->port + HCFG) & ~0x800)) {
288 emu->tos_link = 1;
289 outl(tmp, emu->port + HCFG);
290 }
291 }
292 }
293#endif
294
295 snd_emu10k1_intr_enable(emu, INTE_PCIERRORENABLE);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700296}
297
Takashi Iwai09668b42005-11-17 16:14:10 +0100298int snd_emu10k1_done(struct snd_emu10k1 * emu)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700299{
300 int ch;
301
302 outl(0, emu->port + INTE);
303
304 /*
305 * Shutdown the chip
306 */
307 for (ch = 0; ch < NUM_G; ch++)
308 snd_emu10k1_ptr_write(emu, DCYSUSV, ch, 0);
309 for (ch = 0; ch < NUM_G; ch++) {
310 snd_emu10k1_ptr_write(emu, VTFT, ch, 0);
311 snd_emu10k1_ptr_write(emu, CVCF, ch, 0);
312 snd_emu10k1_ptr_write(emu, PTRX, ch, 0);
313 snd_emu10k1_ptr_write(emu, CPF, ch, 0);
314 }
315
316 /* reset recording buffers */
317 snd_emu10k1_ptr_write(emu, MICBS, 0, 0);
318 snd_emu10k1_ptr_write(emu, MICBA, 0, 0);
319 snd_emu10k1_ptr_write(emu, FXBS, 0, 0);
320 snd_emu10k1_ptr_write(emu, FXBA, 0, 0);
321 snd_emu10k1_ptr_write(emu, FXWC, 0, 0);
322 snd_emu10k1_ptr_write(emu, ADCBS, 0, ADCBS_BUFSIZE_NONE);
323 snd_emu10k1_ptr_write(emu, ADCBA, 0, 0);
324 snd_emu10k1_ptr_write(emu, TCBS, 0, TCBS_BUFFSIZE_16K);
325 snd_emu10k1_ptr_write(emu, TCB, 0, 0);
326 if (emu->audigy)
327 snd_emu10k1_ptr_write(emu, A_DBG, 0, A_DBG_SINGLE_STEP);
328 else
329 snd_emu10k1_ptr_write(emu, DBG, 0, EMU10K1_DBG_SINGLE_STEP);
330
331 /* disable channel interrupt */
332 snd_emu10k1_ptr_write(emu, CLIEL, 0, 0);
333 snd_emu10k1_ptr_write(emu, CLIEH, 0, 0);
334 snd_emu10k1_ptr_write(emu, SOLEL, 0, 0);
335 snd_emu10k1_ptr_write(emu, SOLEH, 0, 0);
336
Linus Torvalds1da177e2005-04-16 15:20:36 -0700337 /* disable audio and lock cache */
338 outl(HCFG_LOCKSOUNDCACHE | HCFG_LOCKTANKCACHE_MASK | HCFG_MUTEBUTTONENABLE, emu->port + HCFG);
339 snd_emu10k1_ptr_write(emu, PTB, 0, 0);
340
Linus Torvalds1da177e2005-04-16 15:20:36 -0700341 return 0;
342}
343
344/*************************************************************************
345 * ECARD functional implementation
346 *************************************************************************/
347
348/* In A1 Silicon, these bits are in the HC register */
349#define HOOKN_BIT (1L << 12)
350#define HANDN_BIT (1L << 11)
351#define PULSEN_BIT (1L << 10)
352
353#define EC_GDI1 (1 << 13)
354#define EC_GDI0 (1 << 14)
355
356#define EC_NUM_CONTROL_BITS 20
357
358#define EC_AC3_DATA_SELN 0x0001L
359#define EC_EE_DATA_SEL 0x0002L
360#define EC_EE_CNTRL_SELN 0x0004L
361#define EC_EECLK 0x0008L
362#define EC_EECS 0x0010L
363#define EC_EESDO 0x0020L
364#define EC_TRIM_CSN 0x0040L
365#define EC_TRIM_SCLK 0x0080L
366#define EC_TRIM_SDATA 0x0100L
367#define EC_TRIM_MUTEN 0x0200L
368#define EC_ADCCAL 0x0400L
369#define EC_ADCRSTN 0x0800L
370#define EC_DACCAL 0x1000L
371#define EC_DACMUTEN 0x2000L
372#define EC_LEDN 0x4000L
373
374#define EC_SPDIF0_SEL_SHIFT 15
375#define EC_SPDIF1_SEL_SHIFT 17
376#define EC_SPDIF0_SEL_MASK (0x3L << EC_SPDIF0_SEL_SHIFT)
377#define EC_SPDIF1_SEL_MASK (0x7L << EC_SPDIF1_SEL_SHIFT)
378#define EC_SPDIF0_SELECT(_x) (((_x) << EC_SPDIF0_SEL_SHIFT) & EC_SPDIF0_SEL_MASK)
379#define EC_SPDIF1_SELECT(_x) (((_x) << EC_SPDIF1_SEL_SHIFT) & EC_SPDIF1_SEL_MASK)
380#define EC_CURRENT_PROM_VERSION 0x01 /* Self-explanatory. This should
381 * be incremented any time the EEPROM's
382 * format is changed. */
383
384#define EC_EEPROM_SIZE 0x40 /* ECARD EEPROM has 64 16-bit words */
385
386/* Addresses for special values stored in to EEPROM */
387#define EC_PROM_VERSION_ADDR 0x20 /* Address of the current prom version */
388#define EC_BOARDREV0_ADDR 0x21 /* LSW of board rev */
389#define EC_BOARDREV1_ADDR 0x22 /* MSW of board rev */
390
391#define EC_LAST_PROMFILE_ADDR 0x2f
392
393#define EC_SERIALNUM_ADDR 0x30 /* First word of serial number. The
394 * can be up to 30 characters in length
395 * and is stored as a NULL-terminated
396 * ASCII string. Any unused bytes must be
397 * filled with zeros */
398#define EC_CHECKSUM_ADDR 0x3f /* Location at which checksum is stored */
399
400
401/* Most of this stuff is pretty self-evident. According to the hardware
402 * dudes, we need to leave the ADCCAL bit low in order to avoid a DC
403 * offset problem. Weird.
404 */
405#define EC_RAW_RUN_MODE (EC_DACMUTEN | EC_ADCRSTN | EC_TRIM_MUTEN | \
406 EC_TRIM_CSN)
407
408
409#define EC_DEFAULT_ADC_GAIN 0xC4C4
410#define EC_DEFAULT_SPDIF0_SEL 0x0
411#define EC_DEFAULT_SPDIF1_SEL 0x4
412
413/**************************************************************************
414 * @func Clock bits into the Ecard's control latch. The Ecard uses a
415 * control latch will is loaded bit-serially by toggling the Modem control
416 * lines from function 2 on the E8010. This function hides these details
417 * and presents the illusion that we are actually writing to a distinct
418 * register.
419 */
420
Takashi Iwaieb4698f2005-11-17 14:50:13 +0100421static void snd_emu10k1_ecard_write(struct snd_emu10k1 * emu, unsigned int value)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700422{
423 unsigned short count;
424 unsigned int data;
425 unsigned long hc_port;
426 unsigned int hc_value;
427
428 hc_port = emu->port + HCFG;
429 hc_value = inl(hc_port) & ~(HOOKN_BIT | HANDN_BIT | PULSEN_BIT);
430 outl(hc_value, hc_port);
431
432 for (count = 0; count < EC_NUM_CONTROL_BITS; count++) {
433
434 /* Set up the value */
435 data = ((value & 0x1) ? PULSEN_BIT : 0);
436 value >>= 1;
437
438 outl(hc_value | data, hc_port);
439
440 /* Clock the shift register */
441 outl(hc_value | data | HANDN_BIT, hc_port);
442 outl(hc_value | data, hc_port);
443 }
444
445 /* Latch the bits */
446 outl(hc_value | HOOKN_BIT, hc_port);
447 outl(hc_value, hc_port);
448}
449
450/**************************************************************************
451 * @func Set the gain of the ECARD's CS3310 Trim/gain controller. The
452 * trim value consists of a 16bit value which is composed of two
453 * 8 bit gain/trim values, one for the left channel and one for the
454 * right channel. The following table maps from the Gain/Attenuation
455 * value in decibels into the corresponding bit pattern for a single
456 * channel.
457 */
458
Takashi Iwaieb4698f2005-11-17 14:50:13 +0100459static void snd_emu10k1_ecard_setadcgain(struct snd_emu10k1 * emu,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700460 unsigned short gain)
461{
462 unsigned int bit;
463
464 /* Enable writing to the TRIM registers */
465 snd_emu10k1_ecard_write(emu, emu->ecard_ctrl & ~EC_TRIM_CSN);
466
467 /* Do it again to insure that we meet hold time requirements */
468 snd_emu10k1_ecard_write(emu, emu->ecard_ctrl & ~EC_TRIM_CSN);
469
470 for (bit = (1 << 15); bit; bit >>= 1) {
471 unsigned int value;
472
473 value = emu->ecard_ctrl & ~(EC_TRIM_CSN | EC_TRIM_SDATA);
474
475 if (gain & bit)
476 value |= EC_TRIM_SDATA;
477
478 /* Clock the bit */
479 snd_emu10k1_ecard_write(emu, value);
480 snd_emu10k1_ecard_write(emu, value | EC_TRIM_SCLK);
481 snd_emu10k1_ecard_write(emu, value);
482 }
483
484 snd_emu10k1_ecard_write(emu, emu->ecard_ctrl);
485}
486
Takashi Iwaieb4698f2005-11-17 14:50:13 +0100487static int __devinit snd_emu10k1_ecard_init(struct snd_emu10k1 * emu)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700488{
489 unsigned int hc_value;
490
491 /* Set up the initial settings */
492 emu->ecard_ctrl = EC_RAW_RUN_MODE |
493 EC_SPDIF0_SELECT(EC_DEFAULT_SPDIF0_SEL) |
494 EC_SPDIF1_SELECT(EC_DEFAULT_SPDIF1_SEL);
495
496 /* Step 0: Set the codec type in the hardware control register
497 * and enable audio output */
498 hc_value = inl(emu->port + HCFG);
499 outl(hc_value | HCFG_AUDIOENABLE | HCFG_CODECFORMAT_I2S, emu->port + HCFG);
500 inl(emu->port + HCFG);
501
502 /* Step 1: Turn off the led and deassert TRIM_CS */
503 snd_emu10k1_ecard_write(emu, EC_ADCCAL | EC_LEDN | EC_TRIM_CSN);
504
505 /* Step 2: Calibrate the ADC and DAC */
506 snd_emu10k1_ecard_write(emu, EC_DACCAL | EC_LEDN | EC_TRIM_CSN);
507
508 /* Step 3: Wait for awhile; XXX We can't get away with this
509 * under a real operating system; we'll need to block and wait that
510 * way. */
511 snd_emu10k1_wait(emu, 48000);
512
513 /* Step 4: Switch off the DAC and ADC calibration. Note
514 * That ADC_CAL is actually an inverted signal, so we assert
515 * it here to stop calibration. */
516 snd_emu10k1_ecard_write(emu, EC_ADCCAL | EC_LEDN | EC_TRIM_CSN);
517
518 /* Step 4: Switch into run mode */
519 snd_emu10k1_ecard_write(emu, emu->ecard_ctrl);
520
521 /* Step 5: Set the analog input gain */
522 snd_emu10k1_ecard_setadcgain(emu, EC_DEFAULT_ADC_GAIN);
523
524 return 0;
525}
526
Takashi Iwaieb4698f2005-11-17 14:50:13 +0100527static int __devinit snd_emu10k1_cardbus_init(struct snd_emu10k1 * emu)
James Courtier-Duttond83c6712005-10-31 10:27:41 +0000528{
529 unsigned long special_port;
530 unsigned int value;
531
532 /* Special initialisation routine
533 * before the rest of the IO-Ports become active.
534 */
535 special_port = emu->port + 0x38;
536 value = inl(special_port);
537 outl(0x00d00000, special_port);
538 value = inl(special_port);
539 outl(0x00d00001, special_port);
540 value = inl(special_port);
541 outl(0x00d0005f, special_port);
542 value = inl(special_port);
543 outl(0x00d0007f, special_port);
544 value = inl(special_port);
545 outl(0x0090007f, special_port);
546 value = inl(special_port);
547
James Courtier-Duttone2b15f82005-11-11 23:39:05 +0100548 snd_emu10k1_ptr20_write(emu, TINA2_VOLUME, 0, 0xfefefefe); /* Defaults to 0x30303030 */
James Courtier-Duttond83c6712005-10-31 10:27:41 +0000549 return 0;
550}
551
James Courtier-Dutton19b99fb2005-12-04 18:03:03 +0100552static int snd_emu1212m_fpga_write(struct snd_emu10k1 * emu, int reg, int value)
553{
554 if (reg<0 || reg>0x3f)
555 return 1;
556 reg+=0x40; /* 0x40 upwards are registers. */
557 if (value<0 || value>0x3f) /* 0 to 0x3f are values */
558 return 1;
559 outl(reg, emu->port + A_IOCFG);
560 outl(reg | 0x80, emu->port + A_IOCFG); /* High bit clocks the value into the fpga. */
561 outl(value, emu->port + A_IOCFG);
562 outl(value | 0x80 , emu->port + A_IOCFG); /* High bit clocks the value into the fpga. */
563
564 return 0;
565}
566
567static int snd_emu1212m_fpga_read(struct snd_emu10k1 * emu, int reg, int *value)
568{
569 if (reg<0 || reg>0x3f)
570 return 1;
571 reg+=0x40; /* 0x40 upwards are registers. */
572 outl(reg, emu->port + A_IOCFG);
573 outl(reg | 0x80, emu->port + A_IOCFG); /* High bit clocks the value into the fpga. */
574 *value = inl(emu->port + A_IOCFG);
575
576 return 0;
577}
578
579static int snd_emu1212m_fpga_netlist_write(struct snd_emu10k1 * emu, int reg, int value)
580{
581 snd_emu1212m_fpga_write(emu, 0x00, ((reg >> 8) & 0x3f) );
582 snd_emu1212m_fpga_write(emu, 0x01, (reg & 0x3f) );
583 snd_emu1212m_fpga_write(emu, 0x02, ((value >> 8) & 0x3f) );
584 snd_emu1212m_fpga_write(emu, 0x03, (value & 0x3f) );
585
586 return 0;
587}
588
589static int __devinit snd_emu10k1_emu1212m_init(struct snd_emu10k1 * emu)
590{
591 unsigned int i;
592 int tmp;
593
594 snd_printk(KERN_ERR "emu1212m: Special config.\n");
595 outl(0x0005a00c, emu->port + HCFG);
596 outl(0x0005a004, emu->port + HCFG);
597 outl(0x0005a000, emu->port + HCFG);
598 outl(0x0005a000, emu->port + HCFG);
599
600 snd_emu1212m_fpga_read(emu, 0x22, &tmp );
601 snd_emu1212m_fpga_read(emu, 0x23, &tmp );
602 snd_emu1212m_fpga_read(emu, 0x24, &tmp );
603 snd_emu1212m_fpga_write(emu, 0x04, 0x01 );
604 snd_emu1212m_fpga_read(emu, 0x0b, &tmp );
605 snd_emu1212m_fpga_write(emu, 0x0b, 0x01 );
606 snd_emu1212m_fpga_read(emu, 0x10, &tmp );
607 snd_emu1212m_fpga_write(emu, 0x10, 0x00 );
608 snd_emu1212m_fpga_read(emu, 0x11, &tmp );
609 snd_emu1212m_fpga_write(emu, 0x11, 0x30 );
610 snd_emu1212m_fpga_read(emu, 0x13, &tmp );
611 snd_emu1212m_fpga_write(emu, 0x13, 0x0f );
612 snd_emu1212m_fpga_read(emu, 0x11, &tmp );
613 snd_emu1212m_fpga_write(emu, 0x11, 0x30 );
614 snd_emu1212m_fpga_read(emu, 0x0a, &tmp );
615 snd_emu1212m_fpga_write(emu, 0x0a, 0x10 );
616 snd_emu1212m_fpga_write(emu, 0x0c, 0x19 );
617 snd_emu1212m_fpga_write(emu, 0x12, 0x0c );
618 snd_emu1212m_fpga_write(emu, 0x09, 0x0f );
619 snd_emu1212m_fpga_write(emu, 0x06, 0x00 );
620 snd_emu1212m_fpga_write(emu, 0x05, 0x00 );
621 snd_emu1212m_fpga_write(emu, 0x0e, 0x12 );
622 snd_emu1212m_fpga_netlist_write(emu, 0x0000, 0x0200);
623 snd_emu1212m_fpga_netlist_write(emu, 0x0001, 0x0201);
624 snd_emu1212m_fpga_netlist_write(emu, 0x0002, 0x0500);
625 snd_emu1212m_fpga_netlist_write(emu, 0x0003, 0x0501);
626 snd_emu1212m_fpga_netlist_write(emu, 0x0004, 0x0400);
627 snd_emu1212m_fpga_netlist_write(emu, 0x0005, 0x0401);
628 snd_emu1212m_fpga_netlist_write(emu, 0x0006, 0x0402);
629 snd_emu1212m_fpga_netlist_write(emu, 0x0007, 0x0403);
630 snd_emu1212m_fpga_netlist_write(emu, 0x0008, 0x0404);
631 snd_emu1212m_fpga_netlist_write(emu, 0x0009, 0x0405);
632 snd_emu1212m_fpga_netlist_write(emu, 0x000a, 0x0406);
633 snd_emu1212m_fpga_netlist_write(emu, 0x000b, 0x0407);
634 snd_emu1212m_fpga_netlist_write(emu, 0x000c, 0x0100);
635 snd_emu1212m_fpga_netlist_write(emu, 0x000d, 0x0104);
636 snd_emu1212m_fpga_netlist_write(emu, 0x000e, 0x0200);
637 snd_emu1212m_fpga_netlist_write(emu, 0x000f, 0x0201);
638 for (i=0;i < 0x20;i++) {
639 snd_emu1212m_fpga_netlist_write(emu, 0x0100+i, 0x0000);
640 }
641 for (i=0;i < 4;i++) {
642 snd_emu1212m_fpga_netlist_write(emu, 0x0200+i, 0x0000);
643 }
644 for (i=0;i < 7;i++) {
645 snd_emu1212m_fpga_netlist_write(emu, 0x0300+i, 0x0000);
646 }
647 for (i=0;i < 7;i++) {
648 snd_emu1212m_fpga_netlist_write(emu, 0x0400+i, 0x0000);
649 }
650 snd_emu1212m_fpga_netlist_write(emu, 0x0500, 0x0108);
651 snd_emu1212m_fpga_netlist_write(emu, 0x0501, 0x010c);
652 snd_emu1212m_fpga_netlist_write(emu, 0x0600, 0x0110);
653 snd_emu1212m_fpga_netlist_write(emu, 0x0601, 0x0114);
654 snd_emu1212m_fpga_netlist_write(emu, 0x0700, 0x0118);
655 snd_emu1212m_fpga_netlist_write(emu, 0x0701, 0x011c);
656 snd_emu1212m_fpga_write(emu, 0x07, 0x01 );
657
658 snd_emu1212m_fpga_read(emu, 0x21, &tmp );
659
660 outl(0x0000a000, emu->port + HCFG);
661 outl(0x0000a001, emu->port + HCFG);
662 /* Initial boot complete. Now patches */
663
664 snd_emu1212m_fpga_read(emu, 0x21, &tmp );
665 snd_emu1212m_fpga_write(emu, 0x0c, 0x19 );
666 snd_emu1212m_fpga_write(emu, 0x12, 0x0c );
667 snd_emu1212m_fpga_write(emu, 0x0c, 0x19 );
668 snd_emu1212m_fpga_write(emu, 0x12, 0x0c );
669 snd_emu1212m_fpga_read(emu, 0x0a, &tmp );
670 snd_emu1212m_fpga_write(emu, 0x0a, 0x10 );
671
672 snd_emu1212m_fpga_read(emu, 0x20, &tmp );
673 snd_emu1212m_fpga_read(emu, 0x21, &tmp );
674
675 snd_emu1212m_fpga_netlist_write(emu, 0x0300, 0x0312);
676 snd_emu1212m_fpga_netlist_write(emu, 0x0301, 0x0313);
677 snd_emu1212m_fpga_netlist_write(emu, 0x0200, 0x0302);
678 snd_emu1212m_fpga_netlist_write(emu, 0x0201, 0x0303);
679
680 return 0;
681}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700682/*
683 * Create the EMU10K1 instance
684 */
685
Takashi Iwai09668b42005-11-17 16:14:10 +0100686#ifdef CONFIG_PM
687static int alloc_pm_buffer(struct snd_emu10k1 *emu);
688static void free_pm_buffer(struct snd_emu10k1 *emu);
689#endif
690
Takashi Iwaieb4698f2005-11-17 14:50:13 +0100691static int snd_emu10k1_free(struct snd_emu10k1 *emu)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700692{
693 if (emu->port) { /* avoid access to already used hardware */
694 snd_emu10k1_fx8010_tram_setup(emu, 0);
695 snd_emu10k1_done(emu);
Takashi Iwai09668b42005-11-17 16:14:10 +0100696 /* remove reserved page */
697 if (emu->reserved_page) {
698 snd_emu10k1_synth_free(emu, (struct snd_util_memblk *)emu->reserved_page);
699 emu->reserved_page = NULL;
700 }
701 snd_emu10k1_free_efx(emu);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700702 }
703 if (emu->memhdr)
704 snd_util_memhdr_free(emu->memhdr);
705 if (emu->silent_page.area)
706 snd_dma_free_pages(&emu->silent_page);
707 if (emu->ptb_pages.area)
708 snd_dma_free_pages(&emu->ptb_pages);
709 vfree(emu->page_ptr_table);
710 vfree(emu->page_addr_table);
Takashi Iwai09668b42005-11-17 16:14:10 +0100711#ifdef CONFIG_PM
712 free_pm_buffer(emu);
713#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700714 if (emu->irq >= 0)
715 free_irq(emu->irq, (void *)emu);
716 if (emu->port)
717 pci_release_regions(emu->pci);
Lee Revell2b637da2005-03-30 13:51:18 +0200718 if (emu->card_capabilities->ca0151_chip) /* P16V */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700719 snd_p16v_free(emu);
Takashi Iwai09668b42005-11-17 16:14:10 +0100720 pci_disable_device(emu->pci);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700721 kfree(emu);
722 return 0;
723}
724
Takashi Iwaieb4698f2005-11-17 14:50:13 +0100725static int snd_emu10k1_dev_free(struct snd_device *device)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700726{
Takashi Iwaieb4698f2005-11-17 14:50:13 +0100727 struct snd_emu10k1 *emu = device->device_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700728 return snd_emu10k1_free(emu);
729}
730
Takashi Iwaieb4698f2005-11-17 14:50:13 +0100731static struct snd_emu_chip_details emu_chip_details[] = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700732 /* 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 +0200733 /* Tested by James@superbug.co.uk 3rd July 2005 */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700734 {.vendor = 0x1102, .device = 0x0008, .subsystem = 0x10011102,
735 .driver = "Audigy2", .name = "Audigy 2 Value [SB0400]",
Takashi Iwaiaec72e02005-03-30 14:22:25 +0200736 .id = "Audigy2",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700737 .emu10k2_chip = 1,
738 .ca0108_chip = 1,
Peter Zubaj26689072005-04-01 11:15:07 +0200739 .spk71 = 1,
740 .ac97_chip = 1} ,
James Courtier-Duttond83c6712005-10-31 10:27:41 +0000741 /* Audigy 2 ZS Notebook Cardbus card.*/
742 /* Tested by James@superbug.co.uk 30th October 2005 */
743 /* Not working yet, but progressing. */
744 {.vendor = 0x1102, .device = 0x0008, .subsystem = 0x20011102,
745 .driver = "Audigy2", .name = "Audigy 2 ZS Notebook [SB0530]",
746 .id = "Audigy2",
747 .emu10k2_chip = 1,
748 .ca0108_chip = 1,
749 .ca_cardbus_chip = 1,
750 .spk71 = 1} ,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700751 {.vendor = 0x1102, .device = 0x0008,
752 .driver = "Audigy2", .name = "Audigy 2 Value [Unknown]",
Takashi Iwaiaec72e02005-03-30 14:22:25 +0200753 .id = "Audigy2",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700754 .emu10k2_chip = 1,
Peter Zubaj26689072005-04-01 11:15:07 +0200755 .ca0108_chip = 1,
756 .ac97_chip = 1} ,
James Courtier-Dutton7c1d5492005-07-10 11:50:36 +0200757 /* Tested by James@superbug.co.uk 8th July 2005. No sound available yet. */
758 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x40011102,
759 .driver = "Audigy2", .name = "E-mu 1212m [4001]",
760 .id = "EMU1212m",
761 .emu10k2_chip = 1,
762 .ca0102_chip = 1,
James Courtier-Dutton19b99fb2005-12-04 18:03:03 +0100763 .emu1212m = 1} ,
James Courtier-Dutton88dc0e52005-07-03 12:54:29 +0200764 /* Tested by James@superbug.co.uk 3rd July 2005 */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700765 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x20071102,
766 .driver = "Audigy2", .name = "Audigy 4 PRO [SB0380]",
Takashi Iwaiaec72e02005-03-30 14:22:25 +0200767 .id = "Audigy2",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700768 .emu10k2_chip = 1,
769 .ca0102_chip = 1,
770 .ca0151_chip = 1,
771 .spk71 = 1,
772 .spdif_bug = 1,
773 .ac97_chip = 1} ,
Lee Revellf6f8bb62005-11-07 14:59:19 +0100774 /* Tested by shane-alsa@cm.nu 5th Nov 2005 */
775 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x20061102,
776 .driver = "Audigy2", .name = "Audigy 2 [2006]",
777 .id = "Audigy2",
778 .emu10k2_chip = 1,
779 .ca0102_chip = 1,
780 .ca0151_chip = 1,
781 .spk71 = 1,
782 .spdif_bug = 1,
783 .ac97_chip = 1} ,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700784 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x20021102,
785 .driver = "Audigy2", .name = "Audigy 2 ZS [SB0350]",
Takashi Iwaiaec72e02005-03-30 14:22:25 +0200786 .id = "Audigy2",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700787 .emu10k2_chip = 1,
788 .ca0102_chip = 1,
789 .ca0151_chip = 1,
790 .spk71 = 1,
791 .spdif_bug = 1,
792 .ac97_chip = 1} ,
793 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x20011102,
794 .driver = "Audigy2", .name = "Audigy 2 ZS [2001]",
Takashi Iwaiaec72e02005-03-30 14:22:25 +0200795 .id = "Audigy2",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700796 .emu10k2_chip = 1,
797 .ca0102_chip = 1,
798 .ca0151_chip = 1,
799 .spk71 = 1,
800 .spdif_bug = 1,
801 .ac97_chip = 1} ,
802 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x10071102,
803 .driver = "Audigy2", .name = "Audigy 2 [SB0240]",
Takashi Iwaiaec72e02005-03-30 14:22:25 +0200804 .id = "Audigy2",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700805 .emu10k2_chip = 1,
806 .ca0102_chip = 1,
807 .ca0151_chip = 1,
808 .spk71 = 1,
809 .spdif_bug = 1,
810 .ac97_chip = 1} ,
811 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x10051102,
812 .driver = "Audigy2", .name = "Audigy 2 EX [1005]",
Takashi Iwaiaec72e02005-03-30 14:22:25 +0200813 .id = "Audigy2",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700814 .emu10k2_chip = 1,
815 .ca0102_chip = 1,
816 .ca0151_chip = 1,
Lee Revell2f020aa2005-11-07 14:54:24 +0100817 .spk71 = 1,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700818 .spdif_bug = 1} ,
819 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x10021102,
820 .driver = "Audigy2", .name = "Audigy 2 Platinum [SB0240P]",
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} ,
Takashi Iwaibdaed502005-04-07 15:48:42 +0200828 {.vendor = 0x1102, .device = 0x0004, .revision = 0x04,
829 .driver = "Audigy2", .name = "Audigy 2 [Unknown]",
830 .id = "Audigy2",
831 .emu10k2_chip = 1,
832 .ca0102_chip = 1,
833 .ca0151_chip = 1,
834 .spdif_bug = 1,
835 .ac97_chip = 1} ,
Peter Zubaj26689072005-04-01 11:15:07 +0200836 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x00531102,
837 .driver = "Audigy", .name = "Audigy 1 [SB0090]",
838 .id = "Audigy",
839 .emu10k2_chip = 1,
840 .ca0102_chip = 1,
841 .ac97_chip = 1} ,
James Courtier-Duttonae3a72d2005-07-06 22:36:18 +0200842 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x00521102,
843 .driver = "Audigy", .name = "Audigy 1 ES [SB0160]",
844 .id = "Audigy",
845 .emu10k2_chip = 1,
846 .ca0102_chip = 1,
847 .spdif_bug = 1,
848 .ac97_chip = 1} ,
Arnaud Patarda6c17ec2005-05-27 12:31:34 +0200849 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x00511102,
850 .driver = "Audigy", .name = "Audigy 1 [SB0090]",
851 .id = "Audigy",
852 .emu10k2_chip = 1,
853 .ca0102_chip = 1,
854 .ac97_chip = 1} ,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700855 {.vendor = 0x1102, .device = 0x0004,
Takashi Iwaibdaed502005-04-07 15:48:42 +0200856 .driver = "Audigy", .name = "Audigy 1 [Unknown]",
Takashi Iwaiaec72e02005-03-30 14:22:25 +0200857 .id = "Audigy",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700858 .emu10k2_chip = 1,
859 .ca0102_chip = 1,
Peter Zubaj26689072005-04-01 11:15:07 +0200860 .ac97_chip = 1} ,
James Courtier-Duttona6f61922005-07-03 12:32:40 +0200861 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x806B1102,
862 .driver = "EMU10K1", .name = "SBLive! [SB0105]",
James Courtier-Dutton2b6b22f2005-06-18 13:50:22 +0200863 .id = "Live",
864 .emu10k1_chip = 1,
865 .ac97_chip = 1,
866 .sblive51 = 1} ,
867 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x806A1102,
868 .driver = "EMU10K1", .name = "SBLive! Value [SB0103]",
869 .id = "Live",
870 .emu10k1_chip = 1,
871 .ac97_chip = 1,
872 .sblive51 = 1} ,
James Courtier-Duttona6f61922005-07-03 12:32:40 +0200873 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80691102,
874 .driver = "EMU10K1", .name = "SBLive! Value [SB0101]",
875 .id = "Live",
876 .emu10k1_chip = 1,
877 .ac97_chip = 1,
878 .sblive51 = 1} ,
Lee Revellc6c0b842005-08-29 17:42:00 +0200879 /* Tested by Thomas Zehetbauer 27th Aug 2005 */
880 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80651102,
881 .driver = "EMU10K1", .name = "SB Live 5.1 [SB0220]",
882 .id = "Live",
883 .emu10k1_chip = 1,
884 .ac97_chip = 1,
885 .sblive51 = 1} ,
Gergely Tamasa8ee7292005-12-06 14:10:57 +0100886 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x100a1102,
887 .driver = "EMU10K1", .name = "SB Live 5.1 [SB0220]",
888 .id = "Live",
889 .emu10k1_chip = 1,
890 .ac97_chip = 1,
891 .sblive51 = 1} ,
James Courtier-Duttona6f61922005-07-03 12:32:40 +0200892 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80641102,
893 .driver = "EMU10K1", .name = "SB Live 5.1",
894 .id = "Live",
895 .emu10k1_chip = 1,
896 .ac97_chip = 1,
897 .sblive51 = 1} ,
James Courtier-Duttonafe0f1f2005-09-10 10:24:10 +0200898 /* Tested by alsa bugtrack user "hus" bug #1297 12th Aug 2005 */
James Courtier-Duttona6f61922005-07-03 12:32:40 +0200899 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80611102,
Takashi Iwaif12aa402005-09-30 16:56:59 +0200900 .driver = "EMU10K1", .name = "SBLive 5.1 [SB0060]",
James Courtier-Duttona6f61922005-07-03 12:32:40 +0200901 .id = "Live",
902 .emu10k1_chip = 1,
Takashi Iwaif12aa402005-09-30 16:56:59 +0200903 .ac97_chip = 2, /* ac97 is optional; both SBLive 5.1 and platinum
904 * share the same IDs!
905 */
James Courtier-Duttona6f61922005-07-03 12:32:40 +0200906 .sblive51 = 1} ,
907 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80511102,
908 .driver = "EMU10K1", .name = "SBLive! Value [CT4850]",
909 .id = "Live",
910 .emu10k1_chip = 1,
911 .ac97_chip = 1,
912 .sblive51 = 1} ,
913 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80401102,
914 .driver = "EMU10K1", .name = "SBLive! Platinum [CT4760P]",
915 .id = "Live",
916 .emu10k1_chip = 1,
917 .ac97_chip = 1} ,
918 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80321102,
919 .driver = "EMU10K1", .name = "SBLive! Value [CT4871]",
920 .id = "Live",
921 .emu10k1_chip = 1,
922 .ac97_chip = 1,
923 .sblive51 = 1} ,
924 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80311102,
925 .driver = "EMU10K1", .name = "SBLive! Value [CT4831]",
926 .id = "Live",
927 .emu10k1_chip = 1,
928 .ac97_chip = 1,
929 .sblive51 = 1} ,
930 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80281102,
931 .driver = "EMU10K1", .name = "SBLive! Value [CT4870]",
932 .id = "Live",
933 .emu10k1_chip = 1,
934 .ac97_chip = 1,
935 .sblive51 = 1} ,
James Courtier-Dutton88dc0e52005-07-03 12:54:29 +0200936 /* Tested by James@superbug.co.uk 3rd July 2005 */
James Courtier-Duttona6f61922005-07-03 12:32:40 +0200937 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80271102,
938 .driver = "EMU10K1", .name = "SBLive! Value [CT4832]",
939 .id = "Live",
940 .emu10k1_chip = 1,
941 .ac97_chip = 1,
942 .sblive51 = 1} ,
943 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80261102,
944 .driver = "EMU10K1", .name = "SBLive! Value [CT4830]",
945 .id = "Live",
946 .emu10k1_chip = 1,
947 .ac97_chip = 1,
948 .sblive51 = 1} ,
949 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80231102,
950 .driver = "EMU10K1", .name = "SB PCI512 [CT4790]",
951 .id = "Live",
952 .emu10k1_chip = 1,
953 .ac97_chip = 1,
954 .sblive51 = 1} ,
955 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80221102,
956 .driver = "EMU10K1", .name = "SBLive! Value [CT4780]",
957 .id = "Live",
958 .emu10k1_chip = 1,
959 .ac97_chip = 1,
960 .sblive51 = 1} ,
961 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x40011102,
962 .driver = "EMU10K1", .name = "E-mu APS [4001]",
963 .id = "APS",
964 .emu10k1_chip = 1,
965 .ecard = 1} ,
966 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x00211102,
967 .driver = "EMU10K1", .name = "SBLive! [CT4620]",
968 .id = "Live",
969 .emu10k1_chip = 1,
970 .ac97_chip = 1,
971 .sblive51 = 1} ,
972 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x00201102,
973 .driver = "EMU10K1", .name = "SBLive! Value [CT4670]",
James Courtier-Dutton2b6b22f2005-06-18 13:50:22 +0200974 .id = "Live",
975 .emu10k1_chip = 1,
976 .ac97_chip = 1,
977 .sblive51 = 1} ,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700978 {.vendor = 0x1102, .device = 0x0002,
979 .driver = "EMU10K1", .name = "SB Live [Unknown]",
Takashi Iwaiaec72e02005-03-30 14:22:25 +0200980 .id = "Live",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700981 .emu10k1_chip = 1,
Lee Revell2b637da2005-03-30 13:51:18 +0200982 .ac97_chip = 1,
983 .sblive51 = 1} ,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700984 { } /* terminator */
985};
986
Takashi Iwaieb4698f2005-11-17 14:50:13 +0100987int __devinit snd_emu10k1_create(struct snd_card *card,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700988 struct pci_dev * pci,
989 unsigned short extin_mask,
990 unsigned short extout_mask,
991 long max_cache_bytes,
992 int enable_ir,
James Courtier-Duttone66bc8b2005-07-06 22:21:51 +0200993 uint subsystem,
Takashi Iwaieb4698f2005-11-17 14:50:13 +0100994 struct snd_emu10k1 ** remu)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700995{
Takashi Iwaieb4698f2005-11-17 14:50:13 +0100996 struct snd_emu10k1 *emu;
Takashi Iwai09668b42005-11-17 16:14:10 +0100997 int idx, err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700998 int is_audigy;
999 unsigned char revision;
Takashi Iwai09668b42005-11-17 16:14:10 +01001000 unsigned int silent_page;
Takashi Iwaieb4698f2005-11-17 14:50:13 +01001001 const struct snd_emu_chip_details *c;
1002 static struct snd_device_ops ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001003 .dev_free = snd_emu10k1_dev_free,
1004 };
1005
1006 *remu = NULL;
1007
1008 /* enable PCI device */
1009 if ((err = pci_enable_device(pci)) < 0)
1010 return err;
1011
Takashi Iwaie560d8d2005-09-09 14:21:46 +02001012 emu = kzalloc(sizeof(*emu), GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001013 if (emu == NULL) {
1014 pci_disable_device(pci);
1015 return -ENOMEM;
1016 }
1017 emu->card = card;
1018 spin_lock_init(&emu->reg_lock);
1019 spin_lock_init(&emu->emu_lock);
1020 spin_lock_init(&emu->voice_lock);
1021 spin_lock_init(&emu->synth_lock);
1022 spin_lock_init(&emu->memblk_lock);
1023 init_MUTEX(&emu->ptb_lock);
1024 init_MUTEX(&emu->fx8010.lock);
1025 INIT_LIST_HEAD(&emu->mapped_link_head);
1026 INIT_LIST_HEAD(&emu->mapped_order_link_head);
1027 emu->pci = pci;
1028 emu->irq = -1;
1029 emu->synth = NULL;
1030 emu->get_synth_voice = NULL;
1031 /* read revision & serial */
1032 pci_read_config_byte(pci, PCI_REVISION_ID, &revision);
1033 emu->revision = revision;
1034 pci_read_config_dword(pci, PCI_SUBSYSTEM_VENDOR_ID, &emu->serial);
1035 pci_read_config_word(pci, PCI_SUBSYSTEM_ID, &emu->model);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001036 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);
1037
1038 for (c = emu_chip_details; c->vendor; c++) {
1039 if (c->vendor == pci->vendor && c->device == pci->device) {
James Courtier-Duttone66bc8b2005-07-06 22:21:51 +02001040 if (subsystem) {
1041 if (c->subsystem && (c->subsystem == subsystem) ) {
1042 break;
1043 } else continue;
1044 } else {
1045 if (c->subsystem && (c->subsystem != emu->serial) )
1046 continue;
1047 if (c->revision && c->revision != emu->revision)
1048 continue;
1049 }
Takashi Iwaibdaed502005-04-07 15:48:42 +02001050 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001051 }
1052 }
1053 if (c->vendor == 0) {
1054 snd_printk(KERN_ERR "emu10k1: Card not recognised\n");
1055 kfree(emu);
1056 pci_disable_device(pci);
1057 return -ENOENT;
1058 }
1059 emu->card_capabilities = c;
James Courtier-Duttone66bc8b2005-07-06 22:21:51 +02001060 if (c->subsystem && !subsystem)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001061 snd_printdd("Sound card name=%s\n", c->name);
James Courtier-Duttone66bc8b2005-07-06 22:21:51 +02001062 else if (subsystem)
1063 snd_printdd("Sound card name=%s, vendor=0x%x, device=0x%x, subsystem=0x%x. Forced to subsytem=0x%x\n",
1064 c->name, pci->vendor, pci->device, emu->serial, c->subsystem);
1065 else
1066 snd_printdd("Sound card name=%s, vendor=0x%x, device=0x%x, subsystem=0x%x.\n",
1067 c->name, pci->vendor, pci->device, emu->serial);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001068
Takashi Iwai85a655d2005-03-30 14:40:25 +02001069 if (!*card->id && c->id) {
1070 int i, n = 0;
Takashi Iwaiaec72e02005-03-30 14:22:25 +02001071 strlcpy(card->id, c->id, sizeof(card->id));
Takashi Iwai85a655d2005-03-30 14:40:25 +02001072 for (;;) {
1073 for (i = 0; i < snd_ecards_limit; i++) {
1074 if (snd_cards[i] && !strcmp(snd_cards[i]->id, card->id))
1075 break;
1076 }
1077 if (i >= snd_ecards_limit)
1078 break;
1079 n++;
1080 if (n >= SNDRV_CARDS)
1081 break;
1082 snprintf(card->id, sizeof(card->id), "%s_%d", c->id, n);
1083 }
1084 }
Takashi Iwaiaec72e02005-03-30 14:22:25 +02001085
Linus Torvalds1da177e2005-04-16 15:20:36 -07001086 is_audigy = emu->audigy = c->emu10k2_chip;
1087
1088 /* set the DMA transfer mask */
1089 emu->dma_mask = is_audigy ? AUDIGY_DMA_MASK : EMU10K1_DMA_MASK;
1090 if (pci_set_dma_mask(pci, emu->dma_mask) < 0 ||
1091 pci_set_consistent_dma_mask(pci, emu->dma_mask) < 0) {
1092 snd_printk(KERN_ERR "architecture does not support PCI busmaster DMA with mask 0x%lx\n", emu->dma_mask);
1093 kfree(emu);
1094 pci_disable_device(pci);
1095 return -ENXIO;
1096 }
1097 if (is_audigy)
1098 emu->gpr_base = A_FXGPREGBASE;
1099 else
1100 emu->gpr_base = FXGPREGBASE;
1101
1102 if ((err = pci_request_regions(pci, "EMU10K1")) < 0) {
1103 kfree(emu);
1104 pci_disable_device(pci);
1105 return err;
1106 }
1107 emu->port = pci_resource_start(pci, 0);
1108
1109 if (request_irq(pci->irq, snd_emu10k1_interrupt, SA_INTERRUPT|SA_SHIRQ, "EMU10K1", (void *)emu)) {
Takashi Iwai09668b42005-11-17 16:14:10 +01001110 err = -EBUSY;
1111 goto error;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001112 }
1113 emu->irq = pci->irq;
1114
1115 emu->max_cache_pages = max_cache_bytes >> PAGE_SHIFT;
1116 if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(pci),
1117 32 * 1024, &emu->ptb_pages) < 0) {
Takashi Iwai09668b42005-11-17 16:14:10 +01001118 err = -ENOMEM;
1119 goto error;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001120 }
1121
1122 emu->page_ptr_table = (void **)vmalloc(emu->max_cache_pages * sizeof(void*));
1123 emu->page_addr_table = (unsigned long*)vmalloc(emu->max_cache_pages * sizeof(unsigned long));
1124 if (emu->page_ptr_table == NULL || emu->page_addr_table == NULL) {
Takashi Iwai09668b42005-11-17 16:14:10 +01001125 err = -ENOMEM;
1126 goto error;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001127 }
1128
1129 if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(pci),
1130 EMUPAGESIZE, &emu->silent_page) < 0) {
Takashi Iwai09668b42005-11-17 16:14:10 +01001131 err = -ENOMEM;
1132 goto error;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001133 }
1134 emu->memhdr = snd_util_memhdr_new(emu->max_cache_pages * PAGE_SIZE);
1135 if (emu->memhdr == NULL) {
Takashi Iwai09668b42005-11-17 16:14:10 +01001136 err = -ENOMEM;
1137 goto error;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001138 }
Takashi Iwaieb4698f2005-11-17 14:50:13 +01001139 emu->memhdr->block_extra_size = sizeof(struct snd_emu10k1_memblk) -
1140 sizeof(struct snd_util_memblk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001141
1142 pci_set_master(pci);
1143
Linus Torvalds1da177e2005-04-16 15:20:36 -07001144 emu->fx8010.fxbus_mask = 0x303f;
1145 if (extin_mask == 0)
1146 extin_mask = 0x3fcf;
1147 if (extout_mask == 0)
1148 extout_mask = 0x7fff;
1149 emu->fx8010.extin_mask = extin_mask;
1150 emu->fx8010.extout_mask = extout_mask;
Takashi Iwai09668b42005-11-17 16:14:10 +01001151 emu->enable_ir = enable_ir;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001152
Lee Revell2b637da2005-03-30 13:51:18 +02001153 if (emu->card_capabilities->ecard) {
Takashi Iwai09668b42005-11-17 16:14:10 +01001154 if ((err = snd_emu10k1_ecard_init(emu)) < 0)
1155 goto error;
James Courtier-Duttond83c6712005-10-31 10:27:41 +00001156 } else if (emu->card_capabilities->ca_cardbus_chip) {
Takashi Iwai09668b42005-11-17 16:14:10 +01001157 if ((err = snd_emu10k1_cardbus_init(emu)) < 0)
1158 goto error;
James Courtier-Dutton19b99fb2005-12-04 18:03:03 +01001159 } else if (emu->card_capabilities->emu1212m) {
1160 if ((err = snd_emu10k1_emu1212m_init(emu)) < 0) {
1161 snd_emu10k1_free(emu);
1162 return err;
1163 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001164 } else {
1165 /* 5.1: Enable the additional AC97 Slots. If the emu10k1 version
1166 does not support this, it shouldn't do any harm */
1167 snd_emu10k1_ptr_write(emu, AC97SLOT, 0, AC97SLOT_CNTR|AC97SLOT_LFE);
1168 }
1169
Takashi Iwai09668b42005-11-17 16:14:10 +01001170 /* initialize TRAM setup */
1171 emu->fx8010.itram_size = (16 * 1024)/2;
1172 emu->fx8010.etram_pages.area = NULL;
1173 emu->fx8010.etram_pages.bytes = 0;
1174
1175 /*
1176 * Init to 0x02109204 :
1177 * Clock accuracy = 0 (1000ppm)
1178 * Sample Rate = 2 (48kHz)
1179 * Audio Channel = 1 (Left of 2)
1180 * Source Number = 0 (Unspecified)
1181 * Generation Status = 1 (Original for Cat Code 12)
1182 * Cat Code = 12 (Digital Signal Mixer)
1183 * Mode = 0 (Mode 0)
1184 * Emphasis = 0 (None)
1185 * CP = 1 (Copyright unasserted)
1186 * AN = 0 (Audio data)
1187 * P = 0 (Consumer)
1188 */
1189 emu->spdif_bits[0] = emu->spdif_bits[1] =
1190 emu->spdif_bits[2] = SPCS_CLKACCY_1000PPM | SPCS_SAMPLERATE_48 |
1191 SPCS_CHANNELNUM_LEFT | SPCS_SOURCENUM_UNSPEC |
1192 SPCS_GENERATIONSTATUS | 0x00001200 |
1193 0x00000000 | SPCS_EMPHASIS_NONE | SPCS_COPYRIGHT;
1194
1195 emu->reserved_page = (struct snd_emu10k1_memblk *)
1196 snd_emu10k1_synth_alloc(emu, 4096);
1197 if (emu->reserved_page)
1198 emu->reserved_page->map_locked = 1;
1199
1200 /* Clear silent pages and set up pointers */
1201 memset(emu->silent_page.area, 0, PAGE_SIZE);
1202 silent_page = emu->silent_page.addr << 1;
1203 for (idx = 0; idx < MAXPAGES; idx++)
1204 ((u32 *)emu->ptb_pages.area)[idx] = cpu_to_le32(silent_page | idx);
1205
1206 /* set up voice indices */
1207 for (idx = 0; idx < NUM_G; idx++) {
1208 emu->voices[idx].emu = emu;
1209 emu->voices[idx].number = idx;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001210 }
1211
Takashi Iwai09668b42005-11-17 16:14:10 +01001212 if ((err = snd_emu10k1_init(emu, enable_ir, 0)) < 0)
1213 goto error;
1214#ifdef CONFIG_PM
1215 if ((err = alloc_pm_buffer(emu)) < 0)
1216 goto error;
1217#endif
1218
1219 /* Initialize the effect engine */
1220 if ((err = snd_emu10k1_init_efx(emu)) < 0)
1221 goto error;
1222 snd_emu10k1_audio_enable(emu);
1223
1224 if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, emu, &ops)) < 0)
1225 goto error;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001226
Takashi Iwaiadf1b3d2005-12-01 10:49:58 +01001227#ifdef CONFIG_PROC_FS
Linus Torvalds1da177e2005-04-16 15:20:36 -07001228 snd_emu10k1_proc_init(emu);
Takashi Iwaiadf1b3d2005-12-01 10:49:58 +01001229#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -07001230
1231 snd_card_set_dev(card, &pci->dev);
1232 *remu = emu;
1233 return 0;
Takashi Iwai09668b42005-11-17 16:14:10 +01001234
1235 error:
1236 snd_emu10k1_free(emu);
1237 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001238}
1239
Takashi Iwai09668b42005-11-17 16:14:10 +01001240#ifdef CONFIG_PM
1241static unsigned char saved_regs[] = {
1242 CPF, PTRX, CVCF, VTFT, Z1, Z2, PSST, DSL, CCCA, CCR, CLP,
1243 FXRT, MAPA, MAPB, ENVVOL, ATKHLDV, DCYSUSV, LFOVAL1, ENVVAL,
1244 ATKHLDM, DCYSUSM, LFOVAL2, IP, IFATN, PEFE, FMMOD, TREMFRQ, FM2FRQ2,
1245 TEMPENV, ADCCR, FXWC, MICBA, ADCBA, FXBA,
1246 MICBS, ADCBS, FXBS, CDCS, GPSCS, SPCS0, SPCS1, SPCS2,
1247 SPBYPASS, AC97SLOT, CDSRCS, GPSRCS, ZVSRCS, MICIDX, ADCIDX, FXIDX,
1248 0xff /* end */
1249};
1250static unsigned char saved_regs_audigy[] = {
1251 A_ADCIDX, A_MICIDX, A_FXWC1, A_FXWC2, A_SAMPLE_RATE,
1252 A_FXRT2, A_SENDAMOUNTS, A_FXRT1,
1253 0xff /* end */
1254};
1255
1256static int __devinit alloc_pm_buffer(struct snd_emu10k1 *emu)
1257{
1258 int size;
1259
1260 size = ARRAY_SIZE(saved_regs);
1261 if (emu->audigy)
1262 size += ARRAY_SIZE(saved_regs_audigy);
1263 emu->saved_ptr = vmalloc(4 * NUM_G * size);
1264 if (! emu->saved_ptr)
1265 return -ENOMEM;
1266 if (snd_emu10k1_efx_alloc_pm_buffer(emu) < 0)
1267 return -ENOMEM;
1268 if (emu->card_capabilities->ca0151_chip &&
1269 snd_p16v_alloc_pm_buffer(emu) < 0)
1270 return -ENOMEM;
1271 return 0;
1272}
1273
1274static void free_pm_buffer(struct snd_emu10k1 *emu)
1275{
1276 vfree(emu->saved_ptr);
1277 snd_emu10k1_efx_free_pm_buffer(emu);
1278 if (emu->card_capabilities->ca0151_chip)
1279 snd_p16v_free_pm_buffer(emu);
1280}
1281
1282void snd_emu10k1_suspend_regs(struct snd_emu10k1 *emu)
1283{
1284 int i;
1285 unsigned char *reg;
1286 unsigned int *val;
1287
1288 val = emu->saved_ptr;
1289 for (reg = saved_regs; *reg != 0xff; reg++)
1290 for (i = 0; i < NUM_G; i++, val++)
1291 *val = snd_emu10k1_ptr_read(emu, *reg, i);
1292 if (emu->audigy) {
1293 for (reg = saved_regs_audigy; *reg != 0xff; reg++)
1294 for (i = 0; i < NUM_G; i++, val++)
1295 *val = snd_emu10k1_ptr_read(emu, *reg, i);
1296 }
1297 if (emu->audigy)
1298 emu->saved_a_iocfg = inl(emu->port + A_IOCFG);
1299 emu->saved_hcfg = inl(emu->port + HCFG);
1300}
1301
1302void snd_emu10k1_resume_init(struct snd_emu10k1 *emu)
1303{
1304 if (emu->card_capabilities->ecard)
1305 snd_emu10k1_ecard_init(emu);
1306 else
1307 snd_emu10k1_ptr_write(emu, AC97SLOT, 0, AC97SLOT_CNTR|AC97SLOT_LFE);
1308 snd_emu10k1_init(emu, emu->enable_ir, 1);
1309}
1310
1311void snd_emu10k1_resume_regs(struct snd_emu10k1 *emu)
1312{
1313 int i;
1314 unsigned char *reg;
1315 unsigned int *val;
1316
1317 snd_emu10k1_audio_enable(emu);
1318
1319 /* resore for spdif */
1320 if (emu->audigy)
1321 outl(emu->port + A_IOCFG, emu->saved_a_iocfg);
1322 outl(emu->port + HCFG, emu->saved_hcfg);
1323
1324 val = emu->saved_ptr;
1325 for (reg = saved_regs; *reg != 0xff; reg++)
1326 for (i = 0; i < NUM_G; i++, val++)
1327 snd_emu10k1_ptr_write(emu, *reg, i, *val);
1328 if (emu->audigy) {
1329 for (reg = saved_regs_audigy; *reg != 0xff; reg++)
1330 for (i = 0; i < NUM_G; i++, val++)
1331 snd_emu10k1_ptr_write(emu, *reg, i, *val);
1332 }
1333}
1334#endif
1335
Linus Torvalds1da177e2005-04-16 15:20:36 -07001336/* memory.c */
1337EXPORT_SYMBOL(snd_emu10k1_synth_alloc);
1338EXPORT_SYMBOL(snd_emu10k1_synth_free);
1339EXPORT_SYMBOL(snd_emu10k1_synth_bzero);
1340EXPORT_SYMBOL(snd_emu10k1_synth_copy_from_user);
1341EXPORT_SYMBOL(snd_emu10k1_memblk_map);
1342/* voice.c */
1343EXPORT_SYMBOL(snd_emu10k1_voice_alloc);
1344EXPORT_SYMBOL(snd_emu10k1_voice_free);
1345/* io.c */
1346EXPORT_SYMBOL(snd_emu10k1_ptr_read);
1347EXPORT_SYMBOL(snd_emu10k1_ptr_write);