ftp://ftp.kernel.org/pub/linux/kernel/v2.6/linux-2.6.6.tar.bz2
[linux-2.6.git] / sound / pci / emu10k1 / emufx.c
1 /*
2  *  Copyright (c) by Jaroslav Kysela <perex@suse.cz>
3  *                   Creative Labs, Inc.
4  *  Routines for effect processor FX8010
5  *
6  *  BUGS:
7  *    --
8  *
9  *  TODO:
10  *    --
11  *
12  *   This program is free software; you can redistribute it and/or modify
13  *   it under the terms of the GNU General Public License as published by
14  *   the Free Software Foundation; either version 2 of the License, or
15  *   (at your option) any later version.
16  *
17  *   This program is distributed in the hope that it will be useful,
18  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
19  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  *   GNU General Public License for more details.
21  *
22  *   You should have received a copy of the GNU General Public License
23  *   along with this program; if not, write to the Free Software
24  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
25  *
26  */
27
28 #include <sound/driver.h>
29 #include <linux/pci.h>
30 #include <linux/delay.h>
31 #include <linux/slab.h>
32 #include <linux/init.h>
33 #include <sound/core.h>
34 #include <sound/emu10k1.h>
35
36 #define chip_t emu10k1_t
37
38 #if 0           /* for testing purposes - digital out -> capture */
39 #define EMU10K1_CAPTURE_DIGITAL_OUT
40 #endif
41 #if 0           /* for testing purposes - set S/PDIF to AC3 output */
42 #define EMU10K1_SET_AC3_IEC958
43 #endif
44 #if 0           /* for testing purposes - feed the front signal to Center/LFE outputs */
45 #define EMU10K1_CENTER_LFE_FROM_FRONT
46 #endif
47
48 /*
49  *  Tables
50  */ 
51
52 static char *fxbuses[16] = {
53         /* 0x00 */ "PCM Left",
54         /* 0x01 */ "PCM Right",
55         /* 0x02 */ "PCM Surround Left",
56         /* 0x03 */ "PCM Surround Right",
57         /* 0x04 */ "MIDI Left",
58         /* 0x05 */ "MIDI Right",
59         /* 0x06 */ "Center",
60         /* 0x07 */ "LFE",
61         /* 0x08 */ NULL,
62         /* 0x09 */ NULL,
63         /* 0x0a */ NULL,
64         /* 0x0b */ NULL,
65         /* 0x0c */ "MIDI Reverb",
66         /* 0x0d */ "MIDI Chorus",
67         /* 0x0e */ NULL,
68         /* 0x0f */ NULL
69 };
70
71 static char *creative_ins[16] = {
72         /* 0x00 */ "AC97 Left",
73         /* 0x01 */ "AC97 Right",
74         /* 0x02 */ "TTL IEC958 Left",
75         /* 0x03 */ "TTL IEC958 Right",
76         /* 0x04 */ "Zoom Video Left",
77         /* 0x05 */ "Zoom Video Right",
78         /* 0x06 */ "Optical IEC958 Left",
79         /* 0x07 */ "Optical IEC958 Right",
80         /* 0x08 */ "Line/Mic 1 Left",
81         /* 0x09 */ "Line/Mic 1 Right",
82         /* 0x0a */ "Coaxial IEC958 Left",
83         /* 0x0b */ "Coaxial IEC958 Right",
84         /* 0x0c */ "Line/Mic 2 Left",
85         /* 0x0d */ "Line/Mic 2 Right",
86         /* 0x0e */ NULL,
87         /* 0x0f */ NULL
88 };
89
90 static char *audigy_ins[16] = {
91         /* 0x00 */ "AC97 Left",
92         /* 0x01 */ "AC97 Right",
93         /* 0x02 */ "Audigy CD Left",
94         /* 0x03 */ "Audigy CD Right",
95         /* 0x04 */ "Optical IEC958 Left",
96         /* 0x05 */ "Optical IEC958 Right",
97         /* 0x06 */ NULL,
98         /* 0x07 */ NULL,
99         /* 0x08 */ "Line/Mic 2 Left",
100         /* 0x09 */ "Line/Mic 2 Right",
101         /* 0x0a */ "SPDIF Left",
102         /* 0x0b */ "SPDIF Right",
103         /* 0x0c */ "Aux2 Left",
104         /* 0x0d */ "Aux2 Right",
105         /* 0x0e */ NULL,
106         /* 0x0f */ NULL
107 };
108
109 static char *creative_outs[32] = {
110         /* 0x00 */ "AC97 Left",
111         /* 0x01 */ "AC97 Right",
112         /* 0x02 */ "Optical IEC958 Left",
113         /* 0x03 */ "Optical IEC958 Right",
114         /* 0x04 */ "Center",
115         /* 0x05 */ "LFE",
116         /* 0x06 */ "Headphone Left",
117         /* 0x07 */ "Headphone Right",
118         /* 0x08 */ "Surround Left",
119         /* 0x09 */ "Surround Right",
120         /* 0x0a */ "PCM Capture Left",
121         /* 0x0b */ "PCM Capture Right",
122         /* 0x0c */ "MIC Capture",
123         /* 0x0d */ NULL,
124         /* 0x0e */ NULL,
125         /* 0x0f */ NULL,
126         /* 0x10 */ NULL,
127         /* 0x11 */ "Analog Center",
128         /* 0x12 */ "Analog LFE",
129         /* 0x13 */ NULL,
130         /* 0x14 */ NULL,
131         /* 0x15 */ NULL,
132         /* 0x16 */ NULL,
133         /* 0x17 */ NULL,
134         /* 0x18 */ NULL,
135         /* 0x19 */ NULL,
136         /* 0x1a */ NULL,
137         /* 0x1b */ NULL,
138         /* 0x1c */ NULL,
139         /* 0x1d */ NULL,
140         /* 0x1e */ NULL,
141         /* 0x1f */ NULL,
142 };
143
144 static char *audigy_outs[32] = {
145         /* 0x00 */ "Digital Front Left",
146         /* 0x01 */ "Digital Front Right",
147         /* 0x02 */ "Digital Center",
148         /* 0x03 */ "Digital LEF",
149         /* 0x04 */ "Headphone Left",
150         /* 0x05 */ "Headphone Right",
151         /* 0x06 */ "Digital Rear Left",
152         /* 0x07 */ "Digital Rear Right",
153         /* 0x08 */ "Front Left",
154         /* 0x09 */ "Front Right",
155         /* 0x0a */ "Center",
156         /* 0x0b */ "LFE",
157         /* 0x0c */ NULL,
158         /* 0x0d */ NULL,
159         /* 0x0e */ "Rear Left",
160         /* 0x0f */ "Rear Right",
161         /* 0x10 */ "AC97 Front Left",
162         /* 0x11 */ "AC97 Front Right",
163         /* 0x12 */ "ADC Caputre Left",
164         /* 0x13 */ "ADC Capture Right",
165         /* 0x14 */ NULL,
166         /* 0x15 */ NULL,
167         /* 0x16 */ NULL,
168         /* 0x17 */ NULL,
169         /* 0x18 */ NULL,
170         /* 0x19 */ NULL,
171         /* 0x1a */ NULL,
172         /* 0x1b */ NULL,
173         /* 0x1c */ NULL,
174         /* 0x1d */ NULL,
175         /* 0x1e */ NULL,
176         /* 0x1f */ NULL,
177 };
178
179 static const u32 bass_table[41][5] = {
180         { 0x3e4f844f, 0x84ed4cc3, 0x3cc69927, 0x7b03553a, 0xc4da8486 },
181         { 0x3e69a17a, 0x84c280fb, 0x3cd77cd4, 0x7b2f2a6f, 0xc4b08d1d },
182         { 0x3e82ff42, 0x849991d5, 0x3ce7466b, 0x7b5917c6, 0xc48863ee },
183         { 0x3e9bab3c, 0x847267f0, 0x3cf5ffe8, 0x7b813560, 0xc461f22c },
184         { 0x3eb3b275, 0x844ced29, 0x3d03b295, 0x7ba79a1c, 0xc43d223b },
185         { 0x3ecb2174, 0x84290c8b, 0x3d106714, 0x7bcc5ba3, 0xc419dfa5 },
186         { 0x3ee2044b, 0x8406b244, 0x3d1c2561, 0x7bef8e77, 0xc3f8170f },
187         { 0x3ef86698, 0x83e5cb96, 0x3d26f4d8, 0x7c114600, 0xc3d7b625 },
188         { 0x3f0e5390, 0x83c646c9, 0x3d30dc39, 0x7c319498, 0xc3b8ab97 },
189         { 0x3f23d60b, 0x83a81321, 0x3d39e1af, 0x7c508b9c, 0xc39ae704 },
190         { 0x3f38f884, 0x838b20d2, 0x3d420ad2, 0x7c6e3b75, 0xc37e58f1 },
191         { 0x3f4dc52c, 0x836f60ef, 0x3d495cab, 0x7c8ab3a6, 0xc362f2be },
192         { 0x3f6245e8, 0x8354c565, 0x3d4fdbb8, 0x7ca602d6, 0xc348a69b },
193         { 0x3f76845f, 0x833b40ec, 0x3d558bf0, 0x7cc036df, 0xc32f677c },
194         { 0x3f8a8a03, 0x8322c6fb, 0x3d5a70c4, 0x7cd95cd7, 0xc317290b },
195         { 0x3f9e6014, 0x830b4bc3, 0x3d5e8d25, 0x7cf1811a, 0xc2ffdfa5 },
196         { 0x3fb20fae, 0x82f4c420, 0x3d61e37f, 0x7d08af56, 0xc2e9804a },
197         { 0x3fc5a1cc, 0x82df2592, 0x3d6475c3, 0x7d1ef294, 0xc2d40096 },
198         { 0x3fd91f55, 0x82ca6632, 0x3d664564, 0x7d345541, 0xc2bf56b9 },
199         { 0x3fec9120, 0x82b67cac, 0x3d675356, 0x7d48e138, 0xc2ab796e },
200         { 0x40000000, 0x82a36037, 0x3d67a012, 0x7d5c9fc9, 0xc2985fee },
201         { 0x401374c7, 0x8291088a, 0x3d672b93, 0x7d6f99c3, 0xc28601f2 },
202         { 0x4026f857, 0x827f6dd7, 0x3d65f559, 0x7d81d77c, 0xc27457a3 },
203         { 0x403a939f, 0x826e88c5, 0x3d63fc63, 0x7d9360d4, 0xc2635996 },
204         { 0x404e4faf, 0x825e5266, 0x3d613f32, 0x7da43d42, 0xc25300c6 },
205         { 0x406235ba, 0x824ec434, 0x3d5dbbc3, 0x7db473d7, 0xc243468e },
206         { 0x40764f1f, 0x823fd80c, 0x3d596f8f, 0x7dc40b44, 0xc23424a2 },
207         { 0x408aa576, 0x82318824, 0x3d545787, 0x7dd309e2, 0xc2259509 },
208         { 0x409f4296, 0x8223cf0b, 0x3d4e7012, 0x7de175b5, 0xc2179218 },
209         { 0x40b430a0, 0x8216a7a1, 0x3d47b505, 0x7def5475, 0xc20a1670 },
210         { 0x40c97a0a, 0x820a0d12, 0x3d4021a1, 0x7dfcab8d, 0xc1fd1cf5 },
211         { 0x40df29a6, 0x81fdfad6, 0x3d37b08d, 0x7e098028, 0xc1f0a0ca },
212         { 0x40f54ab1, 0x81f26ca9, 0x3d2e5bd1, 0x7e15d72b, 0xc1e49d52 },
213         { 0x410be8da, 0x81e75e89, 0x3d241cce, 0x7e21b544, 0xc1d90e24 },
214         { 0x41231051, 0x81dcccb3, 0x3d18ec37, 0x7e2d1ee6, 0xc1cdef10 },
215         { 0x413acdd0, 0x81d2b39e, 0x3d0cc20a, 0x7e38184e, 0xc1c33c13 },
216         { 0x41532ea7, 0x81c90ffb, 0x3cff9585, 0x7e42a58b, 0xc1b8f15a },
217         { 0x416c40cd, 0x81bfdeb2, 0x3cf15d21, 0x7e4cca7c, 0xc1af0b3f },
218         { 0x418612ea, 0x81b71cdc, 0x3ce20e85, 0x7e568ad3, 0xc1a58640 },
219         { 0x41a0b465, 0x81aec7c5, 0x3cd19e7c, 0x7e5fea1e, 0xc19c5f03 },
220         { 0x41bc3573, 0x81a6dcea, 0x3cc000e9, 0x7e68ebc2, 0xc1939250 }
221 };
222
223 static const u32 treble_table[41][5] = {
224         { 0x0125cba9, 0xfed5debd, 0x00599b6c, 0x0d2506da, 0xfa85b354 },
225         { 0x0142f67e, 0xfeb03163, 0x0066cd0f, 0x0d14c69d, 0xfa914473 },
226         { 0x016328bd, 0xfe860158, 0x0075b7f2, 0x0d03eb27, 0xfa9d32d2 },
227         { 0x0186b438, 0xfe56c982, 0x00869234, 0x0cf27048, 0xfaa97fca },
228         { 0x01adf358, 0xfe21f5fe, 0x00999842, 0x0ce051c2, 0xfab62ca5 },
229         { 0x01d949fa, 0xfde6e287, 0x00af0d8d, 0x0ccd8b4a, 0xfac33aa7 },
230         { 0x02092669, 0xfda4d8bf, 0x00c73d4c, 0x0cba1884, 0xfad0ab07 },
231         { 0x023e0268, 0xfd5b0e4a, 0x00e27b54, 0x0ca5f509, 0xfade7ef2 },
232         { 0x0278645c, 0xfd08a2b0, 0x01012509, 0x0c911c63, 0xfaecb788 },
233         { 0x02b8e091, 0xfcac9d1a, 0x0123a262, 0x0c7b8a14, 0xfafb55df },
234         { 0x03001a9a, 0xfc45e9ce, 0x014a6709, 0x0c65398f, 0xfb0a5aff },
235         { 0x034ec6d7, 0xfbd3576b, 0x0175f397, 0x0c4e2643, 0xfb19c7e4 },
236         { 0x03a5ac15, 0xfb5393ee, 0x01a6d6ed, 0x0c364b94, 0xfb299d7c },
237         { 0x0405a562, 0xfac52968, 0x01ddafae, 0x0c1da4e2, 0xfb39dca5 },
238         { 0x046fa3fe, 0xfa267a66, 0x021b2ddd, 0x0c042d8d, 0xfb4a8631 },
239         { 0x04e4b17f, 0xf975be0f, 0x0260149f, 0x0be9e0f2, 0xfb5b9ae0 },
240         { 0x0565f220, 0xf8b0fbe5, 0x02ad3c29, 0x0bceba73, 0xfb6d1b60 },
241         { 0x05f4a745, 0xf7d60722, 0x030393d4, 0x0bb2b578, 0xfb7f084d },
242         { 0x06923236, 0xf6e279bd, 0x03642465, 0x0b95cd75, 0xfb916233 },
243         { 0x07401713, 0xf5d3aef9, 0x03d01283, 0x0b77fded, 0xfba42984 },
244         { 0x08000000, 0xf4a6bd88, 0x0448a161, 0x0b594278, 0xfbb75e9f },
245         { 0x08d3c097, 0xf3587131, 0x04cf35a4, 0x0b3996c9, 0xfbcb01cb },
246         { 0x09bd59a2, 0xf1e543f9, 0x05655880, 0x0b18f6b2, 0xfbdf1333 },
247         { 0x0abefd0f, 0xf04956ca, 0x060cbb12, 0x0af75e2c, 0xfbf392e8 },
248         { 0x0bdb123e, 0xee806984, 0x06c739fe, 0x0ad4c962, 0xfc0880dd },
249         { 0x0d143a94, 0xec85d287, 0x0796e150, 0x0ab134b0, 0xfc1ddce5 },
250         { 0x0e6d5664, 0xea547598, 0x087df0a0, 0x0a8c9cb6, 0xfc33a6ad },
251         { 0x0fe98a2a, 0xe7e6ba35, 0x097edf83, 0x0a66fe5b, 0xfc49ddc2 },
252         { 0x118c4421, 0xe536813a, 0x0a9c6248, 0x0a4056d7, 0xfc608185 },
253         { 0x1359422e, 0xe23d19eb, 0x0bd96efb, 0x0a18a3bf, 0xfc77912c },
254         { 0x1554982b, 0xdef33645, 0x0d3942bd, 0x09efe312, 0xfc8f0bc1 },
255         { 0x1782b68a, 0xdb50deb1, 0x0ebf676d, 0x09c6133f, 0xfca6f019 },
256         { 0x19e8715d, 0xd74d64fd, 0x106fb999, 0x099b3337, 0xfcbf3cd6 },
257         { 0x1c8b07b8, 0xd2df56ab, 0x124e6ec8, 0x096f4274, 0xfcd7f060 },
258         { 0x1f702b6d, 0xcdfc6e92, 0x14601c10, 0x0942410b, 0xfcf108e5 },
259         { 0x229e0933, 0xc89985cd, 0x16a9bcfa, 0x09142fb5, 0xfd0a8451 },
260         { 0x261b5118, 0xc2aa8409, 0x1930bab6, 0x08e50fdc, 0xfd24604d },
261         { 0x29ef3f5d, 0xbc224f28, 0x1bfaf396, 0x08b4e3aa, 0xfd3e9a3b },
262         { 0x2e21a59b, 0xb4f2ba46, 0x1f0ec2d6, 0x0883ae15, 0xfd592f33 },
263         { 0x32baf44b, 0xad0c7429, 0x227308a3, 0x085172eb, 0xfd741bfd },
264         { 0x37c4448b, 0xa45ef51d, 0x262f3267, 0x081e36dc, 0xfd8f5d14 }
265 };
266
267 static const u32 db_table[101] = {
268         0x00000000, 0x01571f82, 0x01674b41, 0x01783a1b, 0x0189f540,
269         0x019c8651, 0x01aff763, 0x01c45306, 0x01d9a446, 0x01eff6b8,
270         0x0207567a, 0x021fd03d, 0x0239714c, 0x02544792, 0x027061a1,
271         0x028dcebb, 0x02ac9edc, 0x02cce2bf, 0x02eeabe8, 0x03120cb0,
272         0x0337184e, 0x035de2df, 0x03868173, 0x03b10a18, 0x03dd93e9,
273         0x040c3713, 0x043d0cea, 0x04702ff3, 0x04a5bbf2, 0x04ddcdfb,
274         0x0518847f, 0x0555ff62, 0x05966005, 0x05d9c95d, 0x06206005,
275         0x066a4a52, 0x06b7b067, 0x0708bc4c, 0x075d9a01, 0x07b6779d,
276         0x08138561, 0x0874f5d5, 0x08dafde1, 0x0945d4ed, 0x09b5b4fd,
277         0x0a2adad1, 0x0aa58605, 0x0b25f936, 0x0bac7a24, 0x0c3951d8,
278         0x0ccccccc, 0x0d673b17, 0x0e08f093, 0x0eb24510, 0x0f639481,
279         0x101d3f2d, 0x10dfa9e6, 0x11ab3e3f, 0x12806ac3, 0x135fa333,
280         0x144960c5, 0x153e2266, 0x163e6cfe, 0x174acbb7, 0x1863d04d,
281         0x198a1357, 0x1abe349f, 0x1c00db77, 0x1d52b712, 0x1eb47ee6,
282         0x2026f30f, 0x21aadcb6, 0x23410e7e, 0x24ea64f9, 0x26a7c71d,
283         0x287a26c4, 0x2a62812c, 0x2c61df84, 0x2e795779, 0x30aa0bcf,
284         0x32f52cfe, 0x355bf9d8, 0x37dfc033, 0x3a81dda4, 0x3d43c038,
285         0x4026e73c, 0x432ce40f, 0x46575af8, 0x49a8040f, 0x4d20ac2a,
286         0x50c335d3, 0x54919a57, 0x588dead1, 0x5cba514a, 0x611911ea,
287         0x65ac8c2f, 0x6a773c39, 0x6f7bbc23, 0x74bcc56c, 0x7a3d3272,
288         0x7fffffff,
289 };
290
291 static const u32 onoff_table[2] = {
292         0x00000000, 0x00000001
293 };
294
295 /*
296  */
297  
298 static inline mm_segment_t snd_enter_user(void)
299 {
300         mm_segment_t fs = get_fs();
301         set_fs(get_ds());
302         return fs;
303 }
304
305 static inline void snd_leave_user(mm_segment_t fs)
306 {
307         set_fs(fs);
308 }
309
310 /*
311  *   controls
312  */
313
314 static int snd_emu10k1_gpr_ctl_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
315 {
316         snd_emu10k1_fx8010_ctl_t *ctl = (snd_emu10k1_fx8010_ctl_t *)kcontrol->private_value;
317
318         if (ctl->min == 0 && ctl->max == 1)
319                 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
320         else
321                 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
322         uinfo->count = ctl->vcount;
323         uinfo->value.integer.min = ctl->min;
324         uinfo->value.integer.max = ctl->max;
325         return 0;
326 }
327
328 static int snd_emu10k1_gpr_ctl_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
329 {
330         emu10k1_t *emu = snd_kcontrol_chip(kcontrol);
331         snd_emu10k1_fx8010_ctl_t *ctl = (snd_emu10k1_fx8010_ctl_t *)kcontrol->private_value;
332         unsigned long flags;
333         unsigned int i;
334         
335         spin_lock_irqsave(&emu->reg_lock, flags);
336         for (i = 0; i < ctl->vcount; i++)
337                 ucontrol->value.integer.value[i] = ctl->value[i];
338         spin_unlock_irqrestore(&emu->reg_lock, flags);
339         return 0;
340 }
341
342 static int snd_emu10k1_gpr_ctl_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
343 {
344         emu10k1_t *emu = snd_kcontrol_chip(kcontrol);
345         snd_emu10k1_fx8010_ctl_t *ctl = (snd_emu10k1_fx8010_ctl_t *)kcontrol->private_value;
346         unsigned long flags;
347         unsigned int nval, val;
348         unsigned int i, j;
349         int change = 0;
350         
351         spin_lock_irqsave(&emu->reg_lock, flags);
352         for (i = 0; i < ctl->vcount; i++) {
353                 nval = ucontrol->value.integer.value[i];
354                 if (nval < ctl->min)
355                         nval = ctl->min;
356                 if (nval > ctl->max)
357                         nval = ctl->max;
358                 if (nval != ctl->value[i])
359                         change = 1;
360                 val = ctl->value[i] = nval;
361                 switch (ctl->translation) {
362                 case EMU10K1_GPR_TRANSLATION_NONE:
363                         snd_emu10k1_ptr_write(emu, emu->gpr_base + ctl->gpr[i], 0, val);
364                         break;
365                 case EMU10K1_GPR_TRANSLATION_TABLE100:
366                         snd_emu10k1_ptr_write(emu, emu->gpr_base + ctl->gpr[i], 0, db_table[val]);
367                         break;
368                 case EMU10K1_GPR_TRANSLATION_BASS:
369                         snd_runtime_check((ctl->count % 5) == 0 && (ctl->count / 5) == ctl->vcount, change = -EIO; goto __error);
370                         for (j = 0; j < 5; j++)
371                                 snd_emu10k1_ptr_write(emu, emu->gpr_base + ctl->gpr[j * ctl->vcount + i], 0, bass_table[val][j]);
372                         break;
373                 case EMU10K1_GPR_TRANSLATION_TREBLE:
374                         snd_runtime_check((ctl->count % 5) == 0 && (ctl->count / 5) == ctl->vcount, change = -EIO; goto __error);
375                         for (j = 0; j < 5; j++)
376                                 snd_emu10k1_ptr_write(emu, emu->gpr_base + ctl->gpr[j * ctl->vcount + i], 0, treble_table[val][j]);
377                         break;
378                 case EMU10K1_GPR_TRANSLATION_ONOFF:
379                         snd_emu10k1_ptr_write(emu, emu->gpr_base + ctl->gpr[i], 0, onoff_table[val]);
380                         break;
381                 }
382         }
383       __error:
384         spin_unlock_irqrestore(&emu->reg_lock, flags);
385         return change;
386 }
387
388 /*
389  *   Interrupt handler
390  */
391
392 static void snd_emu10k1_fx8010_interrupt(emu10k1_t *emu)
393 {
394         snd_emu10k1_fx8010_irq_t *irq, *nirq;
395
396         irq = emu->fx8010.irq_handlers;
397         while (irq) {
398                 nirq = irq->next;       /* irq ptr can be removed from list */
399                 if (snd_emu10k1_ptr_read(emu, emu->gpr_base + irq->gpr_running, 0) & 0xffff0000) {
400                         if (irq->handler)
401                                 irq->handler(emu, irq->private_data);
402                         snd_emu10k1_ptr_write(emu, emu->gpr_base + irq->gpr_running, 0, 1);
403                 }
404                 irq = nirq;
405         }
406 }
407
408 static int snd_emu10k1_fx8010_register_irq_handler(emu10k1_t *emu,
409                                                    snd_fx8010_irq_handler_t *handler,
410                                                    unsigned char gpr_running,
411                                                    void *private_data,
412                                                    snd_emu10k1_fx8010_irq_t **r_irq)
413 {
414         snd_emu10k1_fx8010_irq_t *irq;
415         unsigned long flags;
416         
417         snd_runtime_check(emu, return -EINVAL);
418         snd_runtime_check(handler, return -EINVAL);
419         irq = kmalloc(sizeof(*irq), GFP_ATOMIC);
420         if (irq == NULL)
421                 return -ENOMEM;
422         irq->handler = handler;
423         irq->gpr_running = gpr_running;
424         irq->private_data = private_data;
425         irq->next = NULL;
426         spin_lock_irqsave(&emu->fx8010.irq_lock, flags);
427         if (emu->fx8010.irq_handlers == NULL) {
428                 emu->fx8010.irq_handlers = irq;
429                 emu->dsp_interrupt = snd_emu10k1_fx8010_interrupt;
430                 snd_emu10k1_intr_enable(emu, INTE_FXDSPENABLE);
431         } else {
432                 irq->next = emu->fx8010.irq_handlers;
433                 emu->fx8010.irq_handlers = irq;
434         }
435         spin_unlock_irqrestore(&emu->fx8010.irq_lock, flags);
436         if (r_irq)
437                 *r_irq = irq;
438         return 0;
439 }
440
441 static int snd_emu10k1_fx8010_unregister_irq_handler(emu10k1_t *emu,
442                                                      snd_emu10k1_fx8010_irq_t *irq)
443 {
444         snd_emu10k1_fx8010_irq_t *tmp;
445         unsigned long flags;
446         
447         snd_runtime_check(irq, return -EINVAL);
448         spin_lock_irqsave(&emu->fx8010.irq_lock, flags);
449         if ((tmp = emu->fx8010.irq_handlers) == irq) {
450                 emu->fx8010.irq_handlers = tmp->next;
451                 if (emu->fx8010.irq_handlers == NULL) {
452                         snd_emu10k1_intr_disable(emu, INTE_FXDSPENABLE);
453                         emu->dsp_interrupt = NULL;
454                 }
455         } else {
456                 while (tmp && tmp->next != irq)
457                         tmp = tmp->next;
458                 if (tmp)
459                         tmp->next = tmp->next->next;
460         }
461         spin_unlock_irqrestore(&emu->fx8010.irq_lock, flags);
462         kfree(irq);
463         return 0;
464 }
465
466 /*
467  *   PCM streams
468  */
469
470 #define INITIAL_TRAM_SHIFT     14
471 #define INITIAL_TRAM_POS(size) ((((size) / 2) - INITIAL_TRAM_SHIFT) - 1)
472
473 static void snd_emu10k1_fx8010_playback_irq(emu10k1_t *emu, void *private_data)
474 {
475         snd_pcm_substream_t *substream = snd_magic_cast(snd_pcm_substream_t, private_data, return);
476         snd_pcm_period_elapsed(substream);
477 }
478
479 static void snd_emu10k1_fx8010_playback_tram_poke1(unsigned short *dst_left,
480                                                    unsigned short *dst_right,
481                                                    unsigned short *src,
482                                                    unsigned int count,
483                                                    unsigned int tram_shift)
484 {
485         // printk("tram_poke1: dst_left = 0x%p, dst_right = 0x%p, src = 0x%p, count = 0x%x\n", dst_left, dst_right, src, count);
486         if ((tram_shift & 1) == 0) {
487                 while (count--) {
488                         *dst_left-- = *src++;
489                         *dst_right-- = *src++;
490                 }
491         } else {
492                 while (count--) {
493                         *dst_right-- = *src++;
494                         *dst_left-- = *src++;
495                 }
496         }
497 }
498
499 static void snd_emu10k1_fx8010_playback_tram_poke(emu10k1_t *emu,
500                                                   unsigned int *tram_pos,
501                                                   unsigned int *tram_shift,
502                                                   unsigned int tram_size,
503                                                   unsigned short *src,
504                                                   unsigned int frames)
505 {
506         unsigned int count;
507
508         while (frames > *tram_pos) {
509                 count = *tram_pos + 1;
510                 snd_emu10k1_fx8010_playback_tram_poke1((unsigned short *)emu->fx8010.etram_pages.area + *tram_pos,
511                                                        (unsigned short *)emu->fx8010.etram_pages.area + *tram_pos + tram_size / 2,
512                                                        src, count, *tram_shift);
513                 src += count * 2;
514                 frames -= count;
515                 *tram_pos = (tram_size / 2) - 1;
516                 (*tram_shift)++;
517         }
518         snd_emu10k1_fx8010_playback_tram_poke1((unsigned short *)emu->fx8010.etram_pages.area + *tram_pos,
519                                                (unsigned short *)emu->fx8010.etram_pages.area + *tram_pos + tram_size / 2,
520                                                src, frames, *tram_shift++);
521         *tram_pos -= frames;
522 }
523
524 static int snd_emu10k1_fx8010_playback_transfer(snd_pcm_substream_t *substream)
525 {
526         emu10k1_t *emu = snd_pcm_substream_chip(substream);
527         snd_pcm_runtime_t *runtime = substream->runtime;
528         snd_emu10k1_fx8010_pcm_t *pcm = &emu->fx8010.pcm[substream->number];
529         snd_pcm_uframes_t appl_ptr = runtime->control->appl_ptr;
530         snd_pcm_sframes_t diff = appl_ptr - pcm->appl_ptr;
531         snd_pcm_uframes_t buffer_size = pcm->buffer_size / 2;
532
533         if (diff) {
534                 if (diff < -(snd_pcm_sframes_t) (runtime->boundary / 2))
535                         diff += runtime->boundary;
536                 pcm->sw_ready += diff;
537                 pcm->appl_ptr = appl_ptr;
538         }
539         while (pcm->hw_ready < buffer_size &&
540                pcm->sw_ready > 0) {
541                 size_t hw_to_end = buffer_size - pcm->hw_data;
542                 size_t sw_to_end = (runtime->buffer_size << 2) - pcm->sw_data;
543                 size_t tframes = buffer_size - pcm->hw_ready;
544                 if (pcm->sw_ready < tframes)
545                         tframes = pcm->sw_ready;
546                 if (hw_to_end < tframes)
547                         tframes = hw_to_end;
548                 if (sw_to_end < tframes)
549                         tframes = sw_to_end;
550                 snd_emu10k1_fx8010_playback_tram_poke(emu, &pcm->tram_pos, &pcm->tram_shift,
551                                                       pcm->buffer_size,
552                                                       (unsigned short *)(runtime->dma_area + (pcm->sw_data << 2)),
553                                                       tframes);
554                 pcm->hw_data += tframes;
555                 if (pcm->hw_data == buffer_size)
556                         pcm->hw_data = 0;
557                 pcm->sw_data += tframes;
558                 if (pcm->sw_data == runtime->buffer_size)
559                         pcm->sw_data = 0;
560                 pcm->hw_ready += tframes;
561                 pcm->sw_ready -= tframes;
562         }
563         return 0;
564 }
565
566 static int snd_emu10k1_fx8010_playback_hw_params(snd_pcm_substream_t * substream,
567                                                  snd_pcm_hw_params_t * hw_params)
568 {
569         return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
570 }
571
572 static int snd_emu10k1_fx8010_playback_hw_free(snd_pcm_substream_t * substream)
573 {
574         emu10k1_t *emu = snd_pcm_substream_chip(substream);
575         snd_emu10k1_fx8010_pcm_t *pcm = &emu->fx8010.pcm[substream->number];
576         unsigned int i;
577
578         for (i = 0; i < pcm->channels; i++)
579                 snd_emu10k1_ptr_write(emu, TANKMEMADDRREGBASE + 0x80 + pcm->etram[i], 0, 0);
580         snd_pcm_lib_free_pages(substream);
581         return 0;
582 }
583
584 static int snd_emu10k1_fx8010_playback_prepare(snd_pcm_substream_t * substream)
585 {
586         emu10k1_t *emu = snd_pcm_substream_chip(substream);
587         snd_pcm_runtime_t *runtime = substream->runtime;
588         snd_emu10k1_fx8010_pcm_t *pcm = &emu->fx8010.pcm[substream->number];
589         unsigned int i;
590         
591         // printk("prepare: etram_pages = 0x%p, dma_area = 0x%x, buffer_size = 0x%x (0x%x)\n", emu->fx8010.etram_pages, runtime->dma_area, runtime->buffer_size, runtime->buffer_size << 2);
592         pcm->sw_data = pcm->sw_io = pcm->sw_ready = 0;
593         pcm->hw_data = pcm->hw_io = pcm->hw_ready = 0;
594         pcm->tram_pos = INITIAL_TRAM_POS(pcm->buffer_size);
595         pcm->tram_shift = 0;
596         pcm->appl_ptr = 0;
597         snd_emu10k1_ptr_write(emu, emu->gpr_base + pcm->gpr_running, 0, 0);     /* reset */
598         snd_emu10k1_ptr_write(emu, emu->gpr_base + pcm->gpr_trigger, 0, 0);     /* reset */
599         snd_emu10k1_ptr_write(emu, emu->gpr_base + pcm->gpr_size, 0, runtime->buffer_size);
600         snd_emu10k1_ptr_write(emu, emu->gpr_base + pcm->gpr_ptr, 0, 0);         /* reset ptr number */
601         snd_emu10k1_ptr_write(emu, emu->gpr_base + pcm->gpr_count, 0, runtime->period_size);
602         snd_emu10k1_ptr_write(emu, emu->gpr_base + pcm->gpr_tmpcount, 0, runtime->period_size);
603         for (i = 0; i < pcm->channels; i++)
604                 snd_emu10k1_ptr_write(emu, TANKMEMADDRREGBASE + 0x80 + pcm->etram[i], 0, (TANKMEMADDRREG_READ|TANKMEMADDRREG_ALIGN) + i * (runtime->buffer_size / pcm->channels));
605         return 0;
606 }
607
608 static int snd_emu10k1_fx8010_playback_trigger(snd_pcm_substream_t * substream, int cmd)
609 {
610         emu10k1_t *emu = snd_pcm_substream_chip(substream);
611         snd_emu10k1_fx8010_pcm_t *pcm = &emu->fx8010.pcm[substream->number];
612         unsigned long flags;
613         int result = 0;
614
615         spin_lock_irqsave(&emu->reg_lock, flags);
616         switch (cmd) {
617         case SNDRV_PCM_TRIGGER_START:
618                 /* follow thru */
619         case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
620 #ifdef EMU10K1_SET_AC3_IEC958
621         {
622                 int i;
623                 for (i = 0; i < 3; i++) {
624                         unsigned int bits;
625                         bits = SPCS_CLKACCY_1000PPM | SPCS_SAMPLERATE_48 |
626                                SPCS_CHANNELNUM_LEFT | SPCS_SOURCENUM_UNSPEC | SPCS_GENERATIONSTATUS |
627                                0x00001200 | SPCS_EMPHASIS_NONE | SPCS_COPYRIGHT | SPCS_NOTAUDIODATA;
628                         snd_emu10k1_ptr_write(emu, SPCS0 + i, 0, bits);
629                 }
630         }
631 #endif
632                 result = snd_emu10k1_fx8010_register_irq_handler(emu, snd_emu10k1_fx8010_playback_irq, pcm->gpr_running, substream, &pcm->irq);
633                 if (result < 0)
634                         goto __err;
635                 snd_emu10k1_fx8010_playback_transfer(substream);        /* roll the ball */
636                 snd_emu10k1_ptr_write(emu, emu->gpr_base + pcm->gpr_trigger, 0, 1);
637                 break;
638         case SNDRV_PCM_TRIGGER_STOP:
639         case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
640                 snd_emu10k1_fx8010_unregister_irq_handler(emu, pcm->irq); pcm->irq = NULL;
641                 snd_emu10k1_ptr_write(emu, emu->gpr_base + pcm->gpr_trigger, 0, 0);
642                 pcm->tram_pos = INITIAL_TRAM_POS(pcm->buffer_size);
643                 pcm->tram_shift = 0;
644                 break;
645         default:
646                 result = -EINVAL;
647                 break;
648         }
649       __err:
650         spin_unlock_irqrestore(&emu->reg_lock, flags);
651         return result;
652 }
653
654 static snd_pcm_uframes_t snd_emu10k1_fx8010_playback_pointer(snd_pcm_substream_t * substream)
655 {
656         emu10k1_t *emu = snd_pcm_substream_chip(substream);
657         snd_pcm_runtime_t *runtime = substream->runtime;
658         snd_emu10k1_fx8010_pcm_t *pcm = &emu->fx8010.pcm[substream->number];
659         size_t ptr;
660         snd_pcm_sframes_t frames;
661
662         if (!snd_emu10k1_ptr_read(emu, emu->gpr_base + pcm->gpr_trigger, 0))
663                 return 0;
664         ptr = snd_emu10k1_ptr_read(emu, emu->gpr_base + pcm->gpr_ptr, 0);
665         frames = ptr - pcm->hw_io;
666         if (frames < 0)
667                 frames += runtime->buffer_size;
668         pcm->hw_io = ptr;
669         pcm->hw_ready -= frames;
670         pcm->sw_io += frames;
671         if (pcm->sw_io >= runtime->buffer_size)
672                 pcm->sw_io -= runtime->buffer_size;
673         snd_emu10k1_fx8010_playback_transfer(substream);
674         return pcm->sw_io;
675 }
676
677 static snd_pcm_hardware_t snd_emu10k1_fx8010_playback =
678 {
679         .info =                 (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
680                                  /* SNDRV_PCM_INFO_MMAP_VALID | */ SNDRV_PCM_INFO_PAUSE),
681         .formats =              SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE,
682         .rates =                SNDRV_PCM_RATE_48000,
683         .rate_min =             48000,
684         .rate_max =             48000,
685         .channels_min =         1,
686         .channels_max =         1,
687         .buffer_bytes_max =     (128*1024),
688         .period_bytes_min =     1024,
689         .period_bytes_max =     (128*1024),
690         .periods_min =          1,
691         .periods_max =          1024,
692         .fifo_size =            0,
693 };
694
695 static int snd_emu10k1_fx8010_playback_open(snd_pcm_substream_t * substream)
696 {
697         emu10k1_t *emu = snd_pcm_substream_chip(substream);
698         snd_pcm_runtime_t *runtime = substream->runtime;
699         snd_emu10k1_fx8010_pcm_t *pcm = &emu->fx8010.pcm[substream->number];
700
701         runtime->hw = snd_emu10k1_fx8010_playback;
702         runtime->hw.channels_min = runtime->hw.channels_max = pcm->channels;
703         runtime->hw.period_bytes_max = (pcm->buffer_size * 2) / 2;
704         spin_lock(&emu->reg_lock);
705         if (pcm->valid == 0) {
706                 spin_unlock(&emu->reg_lock);
707                 return -ENODEV;
708         }
709         pcm->opened = 1;
710         spin_unlock(&emu->reg_lock);
711         return 0;
712 }
713
714 static int snd_emu10k1_fx8010_playback_close(snd_pcm_substream_t * substream)
715 {
716         emu10k1_t *emu = snd_pcm_substream_chip(substream);
717         snd_emu10k1_fx8010_pcm_t *pcm = &emu->fx8010.pcm[substream->number];
718
719         spin_lock(&emu->reg_lock);
720         pcm->opened = 0;
721         spin_unlock(&emu->reg_lock);
722         return 0;
723 }
724
725 static snd_pcm_ops_t snd_emu10k1_fx8010_playback_ops = {
726         .open =                 snd_emu10k1_fx8010_playback_open,
727         .close =                snd_emu10k1_fx8010_playback_close,
728         .ioctl =                snd_pcm_lib_ioctl,
729         .hw_params =            snd_emu10k1_fx8010_playback_hw_params,
730         .hw_free =              snd_emu10k1_fx8010_playback_hw_free,
731         .prepare =              snd_emu10k1_fx8010_playback_prepare,
732         .trigger =              snd_emu10k1_fx8010_playback_trigger,
733         .pointer =              snd_emu10k1_fx8010_playback_pointer,
734         .ack =                  snd_emu10k1_fx8010_playback_transfer,
735 };
736
737 static void snd_emu10k1_fx8010_pcm_free(snd_pcm_t *pcm)
738 {
739         emu10k1_t *emu = snd_magic_cast(emu10k1_t, pcm->private_data, return);
740         emu->pcm_fx8010 = NULL;
741         snd_pcm_lib_preallocate_free_for_all(pcm);
742 }
743
744 int snd_emu10k1_fx8010_pcm(emu10k1_t * emu, int device, snd_pcm_t ** rpcm)
745 {
746         snd_pcm_t *pcm;
747         int err;
748
749         if (rpcm)
750                 *rpcm = NULL;
751
752         if ((err = snd_pcm_new(emu->card, "emu10k1", device, 8, 0, &pcm)) < 0)
753                 return err;
754
755         pcm->private_data = emu;
756         pcm->private_free = snd_emu10k1_fx8010_pcm_free;
757
758         snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_emu10k1_fx8010_playback_ops);
759
760         pcm->info_flags = 0;
761         strcpy(pcm->name, "EMU10K1 FX8010");
762         emu->pcm_fx8010 = pcm;
763         
764         snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(emu->pci), 64*1024, 0);
765
766         if (rpcm)
767                 *rpcm = pcm;
768
769         return 0;
770 }
771
772 /*************************************************************************
773  * EMU10K1 effect manager
774  *************************************************************************/
775
776 static void snd_emu10k1_write_op(emu10k1_fx8010_code_t *icode, unsigned int *ptr,
777                                  u32 op, u32 r, u32 a, u32 x, u32 y)
778 {
779         snd_assert(*ptr < 512, return);
780         set_bit(*ptr, icode->code_valid);
781         icode->code[*ptr    ][0] = ((x & 0x3ff) << 10) | (y & 0x3ff);
782         icode->code[(*ptr)++][1] = ((op & 0x0f) << 20) | ((r & 0x3ff) << 10) | (a & 0x3ff);
783 }
784
785 #define OP(icode, ptr, op, r, a, x, y) \
786         snd_emu10k1_write_op(icode, ptr, op, r, a, x, y)
787
788 static void snd_emu10k1_audigy_write_op(emu10k1_fx8010_code_t *icode, unsigned int *ptr,
789                                         u32 op, u32 r, u32 a, u32 x, u32 y)
790 {
791         snd_assert(*ptr < 512, return);
792         set_bit(*ptr, icode->code_valid);
793         icode->code[*ptr    ][0] = ((x & 0x7ff) << 12) | (y & 0x7ff);
794         icode->code[(*ptr)++][1] = ((op & 0x0f) << 24) | ((r & 0x7ff) << 12) | (a & 0x7ff);
795 }
796
797 #define A_OP(icode, ptr, op, r, a, x, y) \
798         snd_emu10k1_audigy_write_op(icode, ptr, op, r, a, x, y)
799
800 void snd_emu10k1_efx_write(emu10k1_t *emu, unsigned int pc, unsigned int data)
801 {
802         pc += emu->audigy ? A_MICROCODEBASE : MICROCODEBASE;
803         snd_emu10k1_ptr_write(emu, pc, 0, data);
804 }
805
806 unsigned int snd_emu10k1_efx_read(emu10k1_t *emu, unsigned int pc)
807 {
808         pc += emu->audigy ? A_MICROCODEBASE : MICROCODEBASE;
809         return snd_emu10k1_ptr_read(emu, pc, 0);
810 }
811
812 static void snd_emu10k1_gpr_poke(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
813 {
814         int gpr;
815
816         for (gpr = 0; gpr < 0x100; gpr++) {
817                 if (!test_bit(gpr, icode->gpr_valid))
818                         continue;
819                 snd_emu10k1_ptr_write(emu, emu->gpr_base + gpr, 0, icode->gpr_map[gpr]);
820         }
821 }
822
823 static void snd_emu10k1_gpr_peek(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
824 {
825         int gpr;
826
827         for (gpr = 0; gpr < 0x100; gpr++) {
828                 set_bit(gpr, icode->gpr_valid);
829                 icode->gpr_map[gpr] = snd_emu10k1_ptr_read(emu, emu->gpr_base + gpr, 0);
830         }
831 }
832
833 static void snd_emu10k1_tram_poke(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
834 {
835         int tram;
836
837         for (tram = 0; tram < 0xa0; tram++) {
838                 if (!test_bit(tram, icode->tram_valid))
839                         continue;
840                 snd_emu10k1_ptr_write(emu, TANKMEMDATAREGBASE + tram, 0, icode->tram_data_map[tram]);
841                 snd_emu10k1_ptr_write(emu, TANKMEMADDRREGBASE + tram, 0, icode->tram_addr_map[tram]);
842         }
843 }
844
845 static void snd_emu10k1_tram_peek(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
846 {
847         int tram;
848
849         memset(icode->tram_valid, 0, sizeof(icode->tram_valid));
850         for (tram = 0; tram < 0xa0; tram++) {
851                 set_bit(tram, icode->tram_valid);
852                 icode->tram_data_map[tram] = snd_emu10k1_ptr_read(emu, TANKMEMDATAREGBASE + tram, 0);
853                 icode->tram_addr_map[tram] = snd_emu10k1_ptr_read(emu, TANKMEMADDRREGBASE + tram, 0);
854         }
855 }
856
857 static void snd_emu10k1_code_poke(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
858 {
859         u32 pc;
860
861         for (pc = 0; pc < 512; pc++) {
862                 if (!test_bit(pc, icode->code_valid))
863                         continue;
864                 snd_emu10k1_efx_write(emu, pc * 2, icode->code[pc][0]);
865                 snd_emu10k1_efx_write(emu, pc * 2 + 1, icode->code[pc][1]);
866         }
867 }
868
869 static void snd_emu10k1_code_peek(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
870 {
871         u32 pc;
872
873         memset(icode->code_valid, 0, sizeof(icode->code_valid));
874         for (pc = 0; pc < 512; pc++) {
875                 set_bit(pc, icode->code_valid);
876                 icode->code[pc][0] = snd_emu10k1_efx_read(emu, pc * 2);
877                 icode->code[pc][1] = snd_emu10k1_efx_read(emu, pc * 2 + 1);
878         }
879 }
880
881 static snd_emu10k1_fx8010_ctl_t *snd_emu10k1_look_for_ctl(emu10k1_t *emu, snd_ctl_elem_id_t *id)
882 {
883         snd_emu10k1_fx8010_ctl_t *ctl;
884         snd_kcontrol_t *kcontrol;
885         struct list_head *list;
886         
887         list_for_each(list, &emu->fx8010.gpr_ctl) {
888                 ctl = emu10k1_gpr_ctl(list);
889                 kcontrol = ctl->kcontrol;
890                 if (kcontrol->id.iface == id->iface &&
891                     !strcmp(kcontrol->id.name, id->name) &&
892                     kcontrol->id.index == id->index)
893                         return ctl;
894         }
895         return NULL;
896 }
897
898 static int snd_emu10k1_verify_controls(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
899 {
900         unsigned int i;
901         snd_ctl_elem_id_t *_id, id;
902         emu10k1_fx8010_control_gpr_t *_gctl, gctl;
903         
904         for (i = 0, _id = icode->gpr_del_controls;
905              i < icode->gpr_del_control_count; i++, _id++) {
906                 if (copy_from_user(&id, _id, sizeof(id)))
907                         return -EFAULT;
908                 if (snd_emu10k1_look_for_ctl(emu, &id) == NULL)
909                         return -ENOENT;
910         }
911         for (i = 0, _gctl = icode->gpr_add_controls;
912              i < icode->gpr_add_control_count; i++, _gctl++) {
913                 if (copy_from_user(&gctl, _gctl, sizeof(gctl)))
914                         return -EFAULT;
915                 if (snd_emu10k1_look_for_ctl(emu, &gctl.id))
916                         continue;
917                 down_read(&emu->card->controls_rwsem);
918                 if (snd_ctl_find_id(emu->card, &gctl.id) != NULL) {
919                         up_read(&emu->card->controls_rwsem);
920                         return -EEXIST;
921                 }
922                 up_read(&emu->card->controls_rwsem);
923                 if (gctl.id.iface != SNDRV_CTL_ELEM_IFACE_MIXER &&
924                     gctl.id.iface != SNDRV_CTL_ELEM_IFACE_PCM)
925                         return -EINVAL;
926         }
927         for (i = 0, _gctl = icode->gpr_list_controls;
928              i < icode->gpr_list_control_count; i++, _gctl++) {
929                 /* FIXME: we need to check the WRITE access */
930                 if (copy_from_user(&gctl, _gctl, sizeof(gctl)))
931                         return -EFAULT;
932         }
933         return 0;
934 }
935
936 static void snd_emu10k1_ctl_private_free(snd_kcontrol_t *kctl)
937 {
938         snd_emu10k1_fx8010_ctl_t *ctl;
939         
940         ctl = (snd_emu10k1_fx8010_ctl_t *)kctl->private_value;
941         kctl->private_value = 0;
942         list_del(&ctl->list);
943         kfree(ctl);
944 }
945
946 static void snd_emu10k1_add_controls(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
947 {
948         unsigned int i, j;
949         emu10k1_fx8010_control_gpr_t *_gctl, gctl;
950         snd_emu10k1_fx8010_ctl_t *ctl, nctl;
951         snd_kcontrol_new_t knew;
952         snd_kcontrol_t *kctl;
953         snd_ctl_elem_value_t *val;
954
955         val = (snd_ctl_elem_value_t *)kmalloc(sizeof(*val), GFP_KERNEL);
956         if (!val)
957                 return;
958         for (i = 0, _gctl = icode->gpr_add_controls;
959              i < icode->gpr_add_control_count; i++, _gctl++) {
960                 if (copy_from_user(&gctl, _gctl, sizeof(gctl)))
961                         break;
962                 snd_runtime_check(gctl.id.iface == SNDRV_CTL_ELEM_IFACE_MIXER ||
963                                   gctl.id.iface == SNDRV_CTL_ELEM_IFACE_PCM, continue);
964                 snd_runtime_check(gctl.id.name[0] != '\0', continue);
965                 ctl = snd_emu10k1_look_for_ctl(emu, &gctl.id);
966                 memset(&knew, 0, sizeof(knew));
967                 knew.iface = gctl.id.iface;
968                 knew.name = gctl.id.name;
969                 knew.index = gctl.id.index;
970                 knew.device = gctl.id.device;
971                 knew.subdevice = gctl.id.subdevice;
972                 knew.info = snd_emu10k1_gpr_ctl_info;
973                 knew.get = snd_emu10k1_gpr_ctl_get;
974                 knew.put = snd_emu10k1_gpr_ctl_put;
975                 memset(&nctl, 0, sizeof(nctl));
976                 nctl.vcount = gctl.vcount;
977                 nctl.count = gctl.count;
978                 for (j = 0; j < 32; j++) {
979                         nctl.gpr[j] = gctl.gpr[j];
980                         nctl.value[j] = ~gctl.value[j]; /* inverted, we want to write new value in gpr_ctl_put() */
981                         val->value.integer.value[j] = gctl.value[j];
982                 }
983                 nctl.min = gctl.min;
984                 nctl.max = gctl.max;
985                 nctl.translation = gctl.translation;
986                 if (ctl == NULL) {
987                         ctl = (snd_emu10k1_fx8010_ctl_t *)kmalloc(sizeof(*ctl), GFP_KERNEL);
988                         if (ctl == NULL)
989                                 continue;
990                         knew.private_value = (unsigned long)ctl;
991                         memcpy(ctl, &nctl, sizeof(nctl));
992                         if (snd_ctl_add(emu->card, kctl = snd_ctl_new1(&knew, emu)) < 0) {
993                                 kfree(ctl);
994                                 continue;
995                         }
996                         kctl->private_free = snd_emu10k1_ctl_private_free;
997                         ctl->kcontrol = kctl;
998                         list_add_tail(&ctl->list, &emu->fx8010.gpr_ctl);
999                 } else {
1000                         /* overwrite */
1001                         nctl.list = ctl->list;
1002                         nctl.kcontrol = ctl->kcontrol;
1003                         memcpy(ctl, &nctl, sizeof(nctl));
1004                         snd_ctl_notify(emu->card, SNDRV_CTL_EVENT_MASK_VALUE |
1005                                                   SNDRV_CTL_EVENT_MASK_INFO, &ctl->kcontrol->id);
1006                 }
1007                 snd_emu10k1_gpr_ctl_put(ctl->kcontrol, val);
1008         }
1009         kfree(val);
1010 }
1011
1012 static void snd_emu10k1_del_controls(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
1013 {
1014         unsigned int i;
1015         snd_ctl_elem_id_t *_id, id;
1016         snd_emu10k1_fx8010_ctl_t *ctl;
1017         snd_card_t *card = emu->card;
1018         
1019         for (i = 0, _id = icode->gpr_del_controls;
1020              i < icode->gpr_del_control_count; i++, _id++) {
1021                 snd_runtime_check(copy_from_user(&id, _id, sizeof(id)) == 0, continue);
1022                 down_write(&card->controls_rwsem);
1023                 ctl = snd_emu10k1_look_for_ctl(emu, &id);
1024                 if (ctl)
1025                         snd_ctl_remove(card, ctl->kcontrol);
1026                 up_write(&card->controls_rwsem);
1027         }
1028 }
1029
1030 static int snd_emu10k1_list_controls(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
1031 {
1032         unsigned int i = 0, j;
1033         unsigned int total = 0;
1034         emu10k1_fx8010_control_gpr_t *_gctl, gctl;
1035         snd_emu10k1_fx8010_ctl_t *ctl;
1036         snd_ctl_elem_id_t *id;
1037         struct list_head *list;
1038
1039         _gctl = icode->gpr_list_controls;       
1040         list_for_each(list, &emu->fx8010.gpr_ctl) {
1041                 ctl = emu10k1_gpr_ctl(list);
1042                 total++;
1043                 if (_gctl && i < icode->gpr_list_control_count) {
1044                         memset(&gctl, 0, sizeof(gctl));
1045                         id = &ctl->kcontrol->id;
1046                         gctl.id.iface = id->iface;
1047                         strlcpy(gctl.id.name, id->name, sizeof(gctl.id.name));
1048                         gctl.id.index = id->index;
1049                         gctl.id.device = id->device;
1050                         gctl.id.subdevice = id->subdevice;
1051                         gctl.vcount = ctl->vcount;
1052                         gctl.count = ctl->count;
1053                         for (j = 0; j < 32; j++) {
1054                                 gctl.gpr[j] = ctl->gpr[j];
1055                                 gctl.value[j] = ctl->value[j];
1056                         }
1057                         gctl.min = ctl->min;
1058                         gctl.max = ctl->max;
1059                         gctl.translation = ctl->translation;
1060                         if (copy_to_user(_gctl, &gctl, sizeof(gctl)))
1061                                 return -EFAULT;
1062                         _gctl++;
1063                         i++;
1064                 }
1065         }
1066         icode->gpr_list_control_total = total;
1067         return 0;
1068 }
1069
1070 static int snd_emu10k1_icode_poke(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
1071 {
1072         int err = 0;
1073
1074         down(&emu->fx8010.lock);
1075         if ((err = snd_emu10k1_verify_controls(emu, icode)) < 0)
1076                 goto __error;
1077         strlcpy(emu->fx8010.name, icode->name, sizeof(emu->fx8010.name));
1078         /* stop FX processor - this may be dangerous, but it's better to miss
1079            some samples than generate wrong ones - [jk] */
1080         if (emu->audigy)
1081                 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg | A_DBG_SINGLE_STEP);
1082         else
1083                 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg | EMU10K1_DBG_SINGLE_STEP);
1084         /* ok, do the main job */
1085         snd_emu10k1_del_controls(emu, icode);
1086         snd_emu10k1_gpr_poke(emu, icode);
1087         snd_emu10k1_tram_poke(emu, icode);
1088         snd_emu10k1_code_poke(emu, icode);
1089         snd_emu10k1_add_controls(emu, icode);
1090         /* start FX processor when the DSP code is updated */
1091         if (emu->audigy)
1092                 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg);
1093         else
1094                 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg);
1095       __error:
1096         up(&emu->fx8010.lock);
1097         return err;
1098 }
1099
1100 static int snd_emu10k1_icode_peek(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
1101 {
1102         int err;
1103
1104         down(&emu->fx8010.lock);
1105         strlcpy(icode->name, emu->fx8010.name, sizeof(icode->name));
1106         /* ok, do the main job */
1107         snd_emu10k1_gpr_peek(emu, icode);
1108         snd_emu10k1_tram_peek(emu, icode);
1109         snd_emu10k1_code_peek(emu, icode);
1110         err = snd_emu10k1_list_controls(emu, icode);
1111         up(&emu->fx8010.lock);
1112         return err;
1113 }
1114
1115 static int snd_emu10k1_ipcm_poke(emu10k1_t *emu, emu10k1_fx8010_pcm_t *ipcm)
1116 {
1117         unsigned int i;
1118         int err = 0;
1119         snd_emu10k1_fx8010_pcm_t *pcm;
1120
1121         if (ipcm->substream >= EMU10K1_FX8010_PCM_COUNT)
1122                 return -EINVAL;
1123         if (ipcm->channels > 32)
1124                 return -EINVAL;
1125         pcm = &emu->fx8010.pcm[ipcm->substream];
1126         down(&emu->fx8010.lock);
1127         spin_lock_irq(&emu->reg_lock);
1128         if (pcm->opened) {
1129                 err = -EBUSY;
1130                 goto __error;
1131         }
1132         if (ipcm->channels == 0) {      /* remove */
1133                 pcm->valid = 0;
1134         } else {
1135                 /* FIXME: we need to add universal code to the PCM transfer routine */
1136                 if (ipcm->channels != 2) {
1137                         err = -EINVAL;
1138                         goto __error;
1139                 }
1140                 pcm->valid = 1;
1141                 pcm->opened = 0;
1142                 pcm->channels = ipcm->channels;
1143                 pcm->tram_start = ipcm->tram_start;
1144                 pcm->buffer_size = ipcm->buffer_size;
1145                 pcm->gpr_size = ipcm->gpr_size;
1146                 pcm->gpr_count = ipcm->gpr_count;
1147                 pcm->gpr_tmpcount = ipcm->gpr_tmpcount;
1148                 pcm->gpr_ptr = ipcm->gpr_ptr;
1149                 pcm->gpr_trigger = ipcm->gpr_trigger;
1150                 pcm->gpr_running = ipcm->gpr_running;
1151                 for (i = 0; i < pcm->channels; i++)
1152                         pcm->etram[i] = ipcm->etram[i];
1153         }
1154       __error:
1155         spin_unlock_irq(&emu->reg_lock);
1156         up(&emu->fx8010.lock);
1157         return err;
1158 }
1159
1160 static int snd_emu10k1_ipcm_peek(emu10k1_t *emu, emu10k1_fx8010_pcm_t *ipcm)
1161 {
1162         unsigned int i;
1163         int err = 0;
1164         snd_emu10k1_fx8010_pcm_t *pcm;
1165
1166         if (ipcm->substream >= EMU10K1_FX8010_PCM_COUNT)
1167                 return -EINVAL;
1168         pcm = &emu->fx8010.pcm[ipcm->substream];
1169         down(&emu->fx8010.lock);
1170         spin_lock_irq(&emu->reg_lock);
1171         ipcm->channels = pcm->channels;
1172         ipcm->tram_start = pcm->tram_start;
1173         ipcm->buffer_size = pcm->buffer_size;
1174         ipcm->gpr_size = pcm->gpr_size;
1175         ipcm->gpr_ptr = pcm->gpr_ptr;
1176         ipcm->gpr_count = pcm->gpr_count;
1177         ipcm->gpr_tmpcount = pcm->gpr_tmpcount;
1178         ipcm->gpr_trigger = pcm->gpr_trigger;
1179         ipcm->gpr_running = pcm->gpr_running;
1180         for (i = 0; i < pcm->channels; i++)
1181                 ipcm->etram[i] = pcm->etram[i];
1182         ipcm->res1 = ipcm->res2 = 0;
1183         ipcm->pad = 0;
1184         spin_unlock_irq(&emu->reg_lock);
1185         up(&emu->fx8010.lock);
1186         return err;
1187 }
1188
1189 #define SND_EMU10K1_GPR_CONTROLS        41
1190 #define SND_EMU10K1_INPUTS              10
1191 #define SND_EMU10K1_PLAYBACK_CHANNELS   6
1192 #define SND_EMU10K1_CAPTURE_CHANNELS    4
1193
1194 static void __devinit snd_emu10k1_init_mono_control(emu10k1_fx8010_control_gpr_t *ctl, const char *name, int gpr, int defval)
1195 {
1196         ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1197         strcpy(ctl->id.name, name);
1198         ctl->vcount = ctl->count = 1;
1199         ctl->gpr[0] = gpr + 0; ctl->value[0] = defval;
1200         ctl->min = 0;
1201         ctl->max = 100;
1202         ctl->translation = EMU10K1_GPR_TRANSLATION_TABLE100;    
1203 }
1204
1205 static void __devinit snd_emu10k1_init_stereo_control(emu10k1_fx8010_control_gpr_t *ctl, const char *name, int gpr, int defval)
1206 {
1207         ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1208         strcpy(ctl->id.name, name);
1209         ctl->vcount = ctl->count = 2;
1210         ctl->gpr[0] = gpr + 0; ctl->value[0] = defval;
1211         ctl->gpr[1] = gpr + 1; ctl->value[1] = defval;
1212         ctl->min = 0;
1213         ctl->max = 100;
1214         ctl->translation = EMU10K1_GPR_TRANSLATION_TABLE100;
1215 }
1216
1217 static void __devinit snd_emu10k1_init_mono_onoff_control(emu10k1_fx8010_control_gpr_t *ctl, const char *name, int gpr, int defval)
1218 {
1219         ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1220         strcpy(ctl->id.name, name);
1221         ctl->vcount = ctl->count = 1;
1222         ctl->gpr[0] = gpr + 0; ctl->value[0] = defval;
1223         ctl->min = 0;
1224         ctl->max = 1;
1225         ctl->translation = EMU10K1_GPR_TRANSLATION_ONOFF;
1226 }
1227
1228 static void __devinit snd_emu10k1_init_stereo_onoff_control(emu10k1_fx8010_control_gpr_t *ctl, const char *name, int gpr, int defval)
1229 {
1230         ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1231         strcpy(ctl->id.name, name);
1232         ctl->vcount = ctl->count = 2;
1233         ctl->gpr[0] = gpr + 0; ctl->value[0] = defval;
1234         ctl->gpr[1] = gpr + 1; ctl->value[1] = defval;
1235         ctl->min = 0;
1236         ctl->max = 1;
1237         ctl->translation = EMU10K1_GPR_TRANSLATION_ONOFF;
1238 }
1239
1240
1241 /*
1242  * initial DSP configuration for Audigy
1243  */
1244
1245 static int __devinit _snd_emu10k1_audigy_init_efx(emu10k1_t *emu)
1246 {
1247         int err, i, z, gpr, nctl;
1248         const int playback = 10;
1249         const int capture = playback + (SND_EMU10K1_PLAYBACK_CHANNELS * 2); /* we reserve 10 voices */
1250         const int stereo_mix = capture + 2;
1251         const int tmp = 0x88;
1252         u32 ptr;
1253         emu10k1_fx8010_code_t *icode;
1254         emu10k1_fx8010_control_gpr_t *controls, *ctl;
1255         mm_segment_t seg;
1256
1257         spin_lock_init(&emu->fx8010.irq_lock);
1258         INIT_LIST_HEAD(&emu->fx8010.gpr_ctl);
1259
1260         if ((icode = snd_kcalloc(sizeof(emu10k1_fx8010_code_t), GFP_KERNEL)) == NULL)
1261                 return -ENOMEM;
1262         if ((controls = snd_kcalloc(sizeof(emu10k1_fx8010_control_gpr_t) * SND_EMU10K1_GPR_CONTROLS, GFP_KERNEL)) == NULL) {
1263                 kfree(icode);
1264                 return -ENOMEM;
1265         }
1266
1267         /* clear free GPRs */
1268         for (i = 0; i < 256; i++)
1269                 set_bit(i, icode->gpr_valid);
1270
1271         strcpy(icode->name, "Audigy DSP code for ALSA");
1272         ptr = 0;
1273         nctl = 0;
1274         gpr = stereo_mix + 10;
1275
1276         /* stop FX processor */
1277         snd_emu10k1_ptr_write(emu, A_DBG, 0, (emu->fx8010.dbg = 0) | A_DBG_SINGLE_STEP);
1278
1279         /* PCM front Playback Volume (independent from stereo mix) */
1280         A_OP(icode, &ptr, iMAC0, A_GPR(playback), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LEFT_FRONT));
1281         A_OP(icode, &ptr, iMAC0, A_GPR(playback+1), A_C_00000000, A_GPR(gpr+1), A_FXBUS(FXBUS_PCM_RIGHT_FRONT));
1282         snd_emu10k1_init_stereo_control(&controls[nctl++], "PCM Front Playback Volume", gpr, 100);
1283         gpr += 2;
1284         
1285         /* PCM Surround Playback (independent from stereo mix) */
1286         A_OP(icode, &ptr, iMAC0, A_GPR(playback+2), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LEFT_REAR));
1287         A_OP(icode, &ptr, iMAC0, A_GPR(playback+3), A_C_00000000, A_GPR(gpr+1), A_FXBUS(FXBUS_PCM_RIGHT_REAR));
1288         snd_emu10k1_init_stereo_control(&controls[nctl++], "PCM Surround Playback Volume", gpr, 100);
1289         gpr += 2;
1290
1291         /* PCM Center Playback (independent from stereo mix) */
1292         A_OP(icode, &ptr, iMAC0, A_GPR(playback+4), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_CENTER));
1293         snd_emu10k1_init_mono_control(&controls[nctl++], "PCM Center Playback Volume", gpr, 100);
1294         gpr++;
1295
1296         /* PCM LFE Playback (independent from stereo mix) */
1297         A_OP(icode, &ptr, iMAC0, A_GPR(playback+5), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LFE));
1298         snd_emu10k1_init_mono_control(&controls[nctl++], "PCM LFE Playback Volume", gpr, 100);
1299         gpr++;
1300         
1301         /*
1302          * Stereo Mix
1303          */
1304         /* Wave (PCM) Playback Volume (will be renamed later) */
1305         A_OP(icode, &ptr, iMAC0, A_GPR(stereo_mix), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LEFT));
1306         A_OP(icode, &ptr, iMAC0, A_GPR(stereo_mix+1), A_C_00000000, A_GPR(gpr+1), A_FXBUS(FXBUS_PCM_RIGHT));
1307         snd_emu10k1_init_stereo_control(&controls[nctl++], "Wave Playback Volume", gpr, 100);
1308         gpr += 2;
1309
1310         /* Music Playback */
1311         A_OP(icode, &ptr, iMAC0, A_GPR(stereo_mix+0), A_GPR(stereo_mix+0), A_GPR(gpr), A_FXBUS(FXBUS_MIDI_LEFT));
1312         A_OP(icode, &ptr, iMAC0, A_GPR(stereo_mix+1), A_GPR(stereo_mix+1), A_GPR(gpr+1), A_FXBUS(FXBUS_MIDI_RIGHT));
1313         snd_emu10k1_init_stereo_control(&controls[nctl++], "Music Playback Volume", gpr, 100);
1314         gpr += 2;
1315
1316         /* Wave (PCM) Capture */
1317         A_OP(icode, &ptr, iMAC0, A_GPR(capture+0), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LEFT));
1318         A_OP(icode, &ptr, iMAC0, A_GPR(capture+1), A_C_00000000, A_GPR(gpr+1), A_FXBUS(FXBUS_PCM_RIGHT));
1319         snd_emu10k1_init_stereo_control(&controls[nctl++], "PCM Capture Volume", gpr, 0);
1320         gpr += 2;
1321
1322         /* Music Capture */
1323         A_OP(icode, &ptr, iMAC0, A_GPR(capture+0), A_GPR(capture+0), A_GPR(gpr), A_FXBUS(FXBUS_MIDI_LEFT));
1324         A_OP(icode, &ptr, iMAC0, A_GPR(capture+1), A_GPR(capture+1), A_GPR(gpr+1), A_FXBUS(FXBUS_MIDI_RIGHT));
1325         snd_emu10k1_init_stereo_control(&controls[nctl++], "Music Capture Volume", gpr, 0);
1326         gpr += 2;
1327
1328         /*
1329          * inputs
1330          */
1331 #define A_ADD_VOLUME_IN(var,vol,input) \
1332 A_OP(icode, &ptr, iMAC0, A_GPR(var), A_GPR(var), A_GPR(vol), A_EXTIN(input))
1333
1334         /* AC'97 Playback Volume - used only for mic (renamed later) */
1335         A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_AC97_L);
1336         A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_AC97_R);
1337         snd_emu10k1_init_stereo_control(&controls[nctl++], "AMic Playback Volume", gpr, 0);
1338         gpr += 2;
1339         /* AC'97 Capture Volume - used only for mic */
1340         A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_AC97_L);
1341         A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_AC97_R);
1342         snd_emu10k1_init_stereo_control(&controls[nctl++], "Mic Capture Volume", gpr, 0);
1343         gpr += 2;
1344
1345         /* mic capture buffer */        
1346         A_OP(icode, &ptr, iINTERP, A_EXTOUT(A_EXTOUT_MIC_CAP), A_EXTIN(A_EXTIN_AC97_L), 0xcd, A_EXTIN(A_EXTIN_AC97_R));
1347
1348         /* Audigy CD Playback Volume */
1349         A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_SPDIF_CD_L);
1350         A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_SPDIF_CD_R);
1351         snd_emu10k1_init_stereo_control(&controls[nctl++],
1352                                         emu->no_ac97 ? "CD Playback Volume" : "Audigy CD Playback Volume",
1353                                         gpr, 0);
1354         gpr += 2;
1355         /* Audigy CD Capture Volume */
1356         A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_SPDIF_CD_L);
1357         A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_SPDIF_CD_R);
1358         snd_emu10k1_init_stereo_control(&controls[nctl++],
1359                                         emu->no_ac97 ? "CD Capture Volume" : "Audigy CD Capture Volume",
1360                                         gpr, 0);
1361         gpr += 2;
1362
1363         /* Optical SPDIF Playback Volume */
1364         A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_OPT_SPDIF_L);
1365         A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_OPT_SPDIF_R);
1366         snd_emu10k1_init_stereo_control(&controls[nctl++], "IEC958 Optical Playback Volume", gpr, 0);
1367         gpr += 2;
1368         /* Optical SPDIF Capture Volume */
1369         A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_OPT_SPDIF_L);
1370         A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_OPT_SPDIF_R);
1371         snd_emu10k1_init_stereo_control(&controls[nctl++], "IEC958 Optical Capture Volume", gpr, 0);
1372         gpr += 2;
1373
1374         /* Line2 Playback Volume */
1375         A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_LINE2_L);
1376         A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_LINE2_R);
1377         snd_emu10k1_init_stereo_control(&controls[nctl++],
1378                                         emu->no_ac97 ? "Line Playback Volume" : "Line2 Playback Volume",
1379                                         gpr, 0);
1380         gpr += 2;
1381         /* Line2 Capture Volume */
1382         A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_LINE2_L);
1383         A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_LINE2_R);
1384         snd_emu10k1_init_stereo_control(&controls[nctl++],
1385                                         emu->no_ac97 ? "Line Capture Volume" : "Line2 Capture Volume",
1386                                         gpr, 0);
1387         gpr += 2;
1388         
1389         /* Philips ADC Playback Volume */
1390         A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_ADC_L);
1391         A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_ADC_R);
1392         snd_emu10k1_init_stereo_control(&controls[nctl++], "Analog Mix Playback Volume", gpr, 0);
1393         gpr += 2;
1394         /* Philips ADC Capture Volume */
1395         A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_ADC_L);
1396         A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_ADC_R);
1397         snd_emu10k1_init_stereo_control(&controls[nctl++], "Analog Mix Capture Volume", gpr, 0);
1398         gpr += 2;
1399
1400         /* Aux2 Playback Volume */
1401         A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_AUX2_L);
1402         A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_AUX2_R);
1403         snd_emu10k1_init_stereo_control(&controls[nctl++],
1404                                         emu->no_ac97 ? "Aux Playback Volume" : "Aux2 Playback Volume",
1405                                         gpr, 0);
1406         gpr += 2;
1407         /* Aux2 Capture Volume */
1408         A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_AUX2_L);
1409         A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_AUX2_R);
1410         snd_emu10k1_init_stereo_control(&controls[nctl++],
1411                                         emu->no_ac97 ? "Aux Capture Volume" : "Aux2 Capture Volume",
1412                                         gpr, 0);
1413         gpr += 2;
1414         
1415         /* Stereo Mix Front Playback Volume */
1416         A_OP(icode, &ptr, iMAC0, A_GPR(playback), A_GPR(playback), A_GPR(gpr), A_GPR(stereo_mix));
1417         A_OP(icode, &ptr, iMAC0, A_GPR(playback+1), A_GPR(playback+1), A_GPR(gpr+1), A_GPR(stereo_mix+1));
1418         snd_emu10k1_init_stereo_control(&controls[nctl++], "Front Playback Volume", gpr, 100);
1419         gpr += 2;
1420         
1421         /* Stereo Mix Surround Playback */
1422         A_OP(icode, &ptr, iMAC0, A_GPR(playback+2), A_GPR(playback+2), A_GPR(gpr), A_GPR(stereo_mix));
1423         A_OP(icode, &ptr, iMAC0, A_GPR(playback+3), A_GPR(playback+3), A_GPR(gpr+1), A_GPR(stereo_mix+1));
1424         snd_emu10k1_init_stereo_control(&controls[nctl++], "Surround Playback Volume", gpr, 0);
1425         gpr += 2;
1426
1427         /* Stereo Mix Center Playback */
1428         /* Center = sub = Left/2 + Right/2 */
1429         A_OP(icode, &ptr, iINTERP, A_GPR(tmp), A_GPR(stereo_mix), 0xcd, A_GPR(stereo_mix+1));
1430         A_OP(icode, &ptr, iMAC0, A_GPR(playback+4), A_GPR(playback+4), A_GPR(gpr), A_GPR(tmp));
1431         snd_emu10k1_init_mono_control(&controls[nctl++], "Center Playback Volume", gpr, 0);
1432         gpr++;
1433
1434         /* Stereo Mix LFE Playback */
1435         A_OP(icode, &ptr, iMAC0, A_GPR(playback+5), A_GPR(playback+5), A_GPR(gpr), A_GPR(tmp));
1436         snd_emu10k1_init_mono_control(&controls[nctl++], "LFE Playback Volume", gpr, 0);
1437         gpr++;
1438
1439         /*
1440          * outputs
1441          */
1442 #define A_PUT_OUTPUT(out,src) A_OP(icode, &ptr, iACC3, A_EXTOUT(out), A_C_00000000, A_C_00000000, A_GPR(src))
1443 #define A_PUT_STEREO_OUTPUT(out1,out2,src) \
1444         {A_PUT_OUTPUT(out1,src); A_PUT_OUTPUT(out2,src+1);}
1445
1446 #define _A_SWITCH(icode, ptr, dst, src, sw) \
1447         A_OP((icode), ptr, iMACINT0, dst, A_C_00000000, src, sw);
1448 #define A_SWITCH(icode, ptr, dst, src, sw) \
1449                 _A_SWITCH(icode, ptr, A_GPR(dst), A_GPR(src), A_GPR(sw))
1450 #define _A_SWITCH_NEG(icode, ptr, dst, src) \
1451         A_OP((icode), ptr, iANDXOR, dst, src, A_C_00000001, A_C_00000001);
1452 #define A_SWITCH_NEG(icode, ptr, dst, src) \
1453                 _A_SWITCH_NEG(icode, ptr, A_GPR(dst), A_GPR(src))
1454
1455
1456         /*
1457          *  Process tone control
1458          */
1459         A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 0), A_GPR(playback + 0), A_C_00000000, A_C_00000000); /* left */
1460         A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 1), A_GPR(playback + 1), A_C_00000000, A_C_00000000); /* right */
1461         A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 2), A_GPR(playback + 2), A_C_00000000, A_C_00000000); /* rear left */
1462         A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 3), A_GPR(playback + 3), A_C_00000000, A_C_00000000); /* rear right */
1463         A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 4), A_GPR(playback + 4), A_C_00000000, A_C_00000000); /* center */
1464         A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 5), A_GPR(playback + 5), A_C_00000000, A_C_00000000); /* LFE */
1465
1466         ctl = &controls[nctl + 0];
1467         ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1468         strcpy(ctl->id.name, "Tone Control - Bass");
1469         ctl->vcount = 2;
1470         ctl->count = 10;
1471         ctl->min = 0;
1472         ctl->max = 40;
1473         ctl->value[0] = ctl->value[1] = 20;
1474         ctl->translation = EMU10K1_GPR_TRANSLATION_BASS;
1475         ctl = &controls[nctl + 1];
1476         ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1477         strcpy(ctl->id.name, "Tone Control - Treble");
1478         ctl->vcount = 2;
1479         ctl->count = 10;
1480         ctl->min = 0;
1481         ctl->max = 40;
1482         ctl->value[0] = ctl->value[1] = 20;
1483         ctl->translation = EMU10K1_GPR_TRANSLATION_TREBLE;
1484
1485 #define BASS_GPR        0x8c
1486 #define TREBLE_GPR      0x96
1487
1488         for (z = 0; z < 5; z++) {
1489                 int j;
1490                 for (j = 0; j < 2; j++) {
1491                         controls[nctl + 0].gpr[z * 2 + j] = BASS_GPR + z * 2 + j;
1492                         controls[nctl + 1].gpr[z * 2 + j] = TREBLE_GPR + z * 2 + j;
1493                 }
1494         }
1495         for (z = 0; z < 3; z++) {               /* front/rear/center-lfe */
1496                 int j, k, l, d;
1497                 for (j = 0; j < 2; j++) {       /* left/right */
1498                         k = 0xb0 + (z * 8) + (j * 4);
1499                         l = 0xe0 + (z * 8) + (j * 4);
1500                         d = playback + SND_EMU10K1_PLAYBACK_CHANNELS + z * 2 + j;
1501
1502                         A_OP(icode, &ptr, iMAC0, A_C_00000000, A_C_00000000, A_GPR(d), A_GPR(BASS_GPR + 0 + j));
1503                         A_OP(icode, &ptr, iMACMV, A_GPR(k+1), A_GPR(k), A_GPR(k+1), A_GPR(BASS_GPR + 4 + j));
1504                         A_OP(icode, &ptr, iMACMV, A_GPR(k), A_GPR(d), A_GPR(k), A_GPR(BASS_GPR + 2 + j));
1505                         A_OP(icode, &ptr, iMACMV, A_GPR(k+3), A_GPR(k+2), A_GPR(k+3), A_GPR(BASS_GPR + 8 + j));
1506                         A_OP(icode, &ptr, iMAC0, A_GPR(k+2), A_GPR_ACCU, A_GPR(k+2), A_GPR(BASS_GPR + 6 + j));
1507                         A_OP(icode, &ptr, iACC3, A_GPR(k+2), A_GPR(k+2), A_GPR(k+2), A_C_00000000);
1508
1509                         A_OP(icode, &ptr, iMAC0, A_C_00000000, A_C_00000000, A_GPR(k+2), A_GPR(TREBLE_GPR + 0 + j));
1510                         A_OP(icode, &ptr, iMACMV, A_GPR(l+1), A_GPR(l), A_GPR(l+1), A_GPR(TREBLE_GPR + 4 + j));
1511                         A_OP(icode, &ptr, iMACMV, A_GPR(l), A_GPR(k+2), A_GPR(l), A_GPR(TREBLE_GPR + 2 + j));
1512                         A_OP(icode, &ptr, iMACMV, A_GPR(l+3), A_GPR(l+2), A_GPR(l+3), A_GPR(TREBLE_GPR + 8 + j));
1513                         A_OP(icode, &ptr, iMAC0, A_GPR(l+2), A_GPR_ACCU, A_GPR(l+2), A_GPR(TREBLE_GPR + 6 + j));
1514                         A_OP(icode, &ptr, iMACINT0, A_GPR(l+2), A_C_00000000, A_GPR(l+2), A_C_00000010);
1515
1516                         A_OP(icode, &ptr, iACC3, A_GPR(d), A_GPR(l+2), A_C_00000000, A_C_00000000);
1517
1518                         if (z == 2)     /* center */
1519                                 break;
1520                 }
1521         }
1522         nctl += 2;
1523
1524 #undef BASS_GPR
1525 #undef TREBLE_GPR
1526
1527         for (z = 0; z < 6; z++) {
1528                 A_SWITCH(icode, &ptr, tmp + 0, playback + SND_EMU10K1_PLAYBACK_CHANNELS + z, gpr + 0);
1529                 A_SWITCH_NEG(icode, &ptr, tmp + 1, gpr + 0);
1530                 A_SWITCH(icode, &ptr, tmp + 1, playback + z, tmp + 1);
1531                 A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + z), A_GPR(tmp + 0), A_GPR(tmp + 1), A_C_00000000);
1532         }
1533         snd_emu10k1_init_stereo_onoff_control(controls + nctl++, "Tone Control - Switch", gpr, 0);
1534         gpr += 2;
1535
1536         /* Master volume (will be renamed later) */
1537         A_OP(icode, &ptr, iMAC0, A_GPR(playback+0+SND_EMU10K1_PLAYBACK_CHANNELS), A_C_00000000, A_GPR(gpr), A_GPR(playback+0+SND_EMU10K1_PLAYBACK_CHANNELS));
1538         A_OP(icode, &ptr, iMAC0, A_GPR(playback+1+SND_EMU10K1_PLAYBACK_CHANNELS), A_C_00000000, A_GPR(gpr+1), A_GPR(playback+1+SND_EMU10K1_PLAYBACK_CHANNELS));
1539         A_OP(icode, &ptr, iMAC0, A_GPR(playback+2+SND_EMU10K1_PLAYBACK_CHANNELS), A_C_00000000, A_GPR(gpr+1), A_GPR(playback+2+SND_EMU10K1_PLAYBACK_CHANNELS));
1540         A_OP(icode, &ptr, iMAC0, A_GPR(playback+3+SND_EMU10K1_PLAYBACK_CHANNELS), A_C_00000000, A_GPR(gpr+1), A_GPR(playback+3+SND_EMU10K1_PLAYBACK_CHANNELS));
1541         A_OP(icode, &ptr, iMAC0, A_GPR(playback+4+SND_EMU10K1_PLAYBACK_CHANNELS), A_C_00000000, A_GPR(gpr+1), A_GPR(playback+4+SND_EMU10K1_PLAYBACK_CHANNELS));
1542         A_OP(icode, &ptr, iMAC0, A_GPR(playback+5+SND_EMU10K1_PLAYBACK_CHANNELS), A_C_00000000, A_GPR(gpr+1), A_GPR(playback+5+SND_EMU10K1_PLAYBACK_CHANNELS));
1543         snd_emu10k1_init_stereo_control(&controls[nctl++], "Wave Master Playback Volume", gpr, 0);
1544         gpr += 2;
1545
1546         /* analog speakers */
1547         A_PUT_STEREO_OUTPUT(A_EXTOUT_AFRONT_L, A_EXTOUT_AFRONT_R, playback + SND_EMU10K1_PLAYBACK_CHANNELS);
1548         A_PUT_STEREO_OUTPUT(A_EXTOUT_AREAR_L, A_EXTOUT_AREAR_R, playback+2 + SND_EMU10K1_PLAYBACK_CHANNELS);
1549         A_PUT_OUTPUT(A_EXTOUT_ACENTER, playback+4 + SND_EMU10K1_PLAYBACK_CHANNELS);
1550         A_PUT_OUTPUT(A_EXTOUT_ALFE, playback+5 + SND_EMU10K1_PLAYBACK_CHANNELS);
1551
1552         /* headphone */
1553         A_PUT_STEREO_OUTPUT(A_EXTOUT_HEADPHONE_L, A_EXTOUT_HEADPHONE_R, playback + SND_EMU10K1_PLAYBACK_CHANNELS);
1554
1555         /* digital outputs */
1556         /* A_PUT_STEREO_OUTPUT(A_EXTOUT_FRONT_L, A_EXTOUT_FRONT_R, playback + SND_EMU10K1_PLAYBACK_CHANNELS); */
1557
1558         /* IEC958 Optical Raw Playback Switch */ 
1559         icode->gpr_map[gpr++] = 0x1008;
1560         icode->gpr_map[gpr++] = 0xffff0000;
1561         for (z = 0; z < 2; z++) {
1562                 A_OP(icode, &ptr, iMAC0, A_GPR(tmp + 2), A_FXBUS(FXBUS_PT_LEFT + z), A_C_00000000, A_C_00000000);
1563                 A_OP(icode, &ptr, iSKIP, A_GPR_COND, A_GPR_COND, A_GPR(gpr - 2), A_C_00000001);
1564                 A_OP(icode, &ptr, iACC3, A_GPR(tmp + 2), A_C_00000000, A_C_00010000, A_GPR(tmp + 2));
1565                 A_OP(icode, &ptr, iANDXOR, A_GPR(tmp + 2), A_GPR(tmp + 2), A_GPR(gpr - 1), A_C_00000000);
1566                 A_SWITCH(icode, &ptr, tmp + 0, tmp + 2, gpr + z);
1567                 A_SWITCH_NEG(icode, &ptr, tmp + 1, gpr + z);
1568                 A_SWITCH(icode, &ptr, tmp + 1, playback + SND_EMU10K1_PLAYBACK_CHANNELS + z, tmp + 1);
1569                 A_OP(icode, &ptr, iACC3, A_EXTOUT(A_EXTOUT_FRONT_L + z), A_GPR(tmp + 0), A_GPR(tmp + 1), A_C_00000000);
1570         }
1571         snd_emu10k1_init_stereo_onoff_control(controls + nctl++, "IEC958 Optical Raw Playback Switch", gpr, 0);
1572         gpr += 2;
1573         
1574         A_PUT_STEREO_OUTPUT(A_EXTOUT_REAR_L, A_EXTOUT_REAR_R, playback+2 + SND_EMU10K1_PLAYBACK_CHANNELS);
1575         A_PUT_OUTPUT(A_EXTOUT_CENTER, playback+4 + SND_EMU10K1_PLAYBACK_CHANNELS);
1576         A_PUT_OUTPUT(A_EXTOUT_LFE, playback+5 + SND_EMU10K1_PLAYBACK_CHANNELS);
1577
1578         /* ADC buffer */
1579         A_PUT_OUTPUT(A_EXTOUT_ADC_CAP_L, capture);
1580         A_PUT_OUTPUT(A_EXTOUT_ADC_CAP_R, capture+1);
1581
1582         /*
1583          * ok, set up done..
1584          */
1585
1586         if (gpr > tmp) {
1587                 snd_BUG();
1588                 err = -EIO;
1589                 goto __err;
1590         }
1591         /* clear remaining instruction memory */
1592         while (ptr < 0x200)
1593                 A_OP(icode, &ptr, 0x0f, 0xc0, 0xc0, 0xcf, 0xc0);
1594
1595         seg = snd_enter_user();
1596         icode->gpr_add_control_count = nctl;
1597         icode->gpr_add_controls = controls;
1598         err = snd_emu10k1_icode_poke(emu, icode);
1599         snd_leave_user(seg);
1600
1601  __err:
1602         kfree(controls);
1603         kfree(icode);
1604         return err;
1605 }
1606
1607
1608 /*
1609  * initial DSP configuration for Emu10k1
1610  */
1611
1612 /* when volume = max, then copy only to avoid volume modification */
1613 /* with iMAC0 (negative values) */
1614 static void __devinit _volume(emu10k1_fx8010_code_t *icode, u32 *ptr, u32 dst, u32 src, u32 vol)
1615 {
1616         OP(icode, ptr, iMAC0, dst, C_00000000, src, vol);
1617         OP(icode, ptr, iANDXOR, C_00000000, vol, C_ffffffff, C_7fffffff);
1618         OP(icode, ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, C_00000001);
1619         OP(icode, ptr, iACC3, dst, src, C_00000000, C_00000000);
1620 }
1621 static void __devinit _volume_add(emu10k1_fx8010_code_t *icode, u32 *ptr, u32 dst, u32 src, u32 vol)
1622 {
1623         OP(icode, ptr, iANDXOR, C_00000000, vol, C_ffffffff, C_7fffffff);
1624         OP(icode, ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, C_00000002);
1625         OP(icode, ptr, iMACINT0, dst, dst, src, C_00000001);
1626         OP(icode, ptr, iSKIP, C_00000000, C_7fffffff, C_7fffffff, C_00000001);
1627         OP(icode, ptr, iMAC0, dst, dst, src, vol);
1628 }
1629 static void __devinit _volume_out(emu10k1_fx8010_code_t *icode, u32 *ptr, u32 dst, u32 src, u32 vol)
1630 {
1631         OP(icode, ptr, iANDXOR, C_00000000, vol, C_ffffffff, C_7fffffff);
1632         OP(icode, ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, C_00000002);
1633         OP(icode, ptr, iACC3, dst, src, C_00000000, C_00000000);
1634         OP(icode, ptr, iSKIP, C_00000000, C_7fffffff, C_7fffffff, C_00000001);
1635         OP(icode, ptr, iMAC0, dst, C_00000000, src, vol);
1636 }
1637
1638 #define VOLUME(icode, ptr, dst, src, vol) \
1639                 _volume(icode, ptr, GPR(dst), GPR(src), GPR(vol))
1640 #define VOLUME_IN(icode, ptr, dst, src, vol) \
1641                 _volume(icode, ptr, GPR(dst), EXTIN(src), GPR(vol))
1642 #define VOLUME_ADD(icode, ptr, dst, src, vol) \
1643                 _volume_add(icode, ptr, GPR(dst), GPR(src), GPR(vol))
1644 #define VOLUME_ADDIN(icode, ptr, dst, src, vol) \
1645                 _volume_add(icode, ptr, GPR(dst), EXTIN(src), GPR(vol))
1646 #define VOLUME_OUT(icode, ptr, dst, src, vol) \
1647                 _volume_out(icode, ptr, EXTOUT(dst), GPR(src), GPR(vol))
1648 #define _SWITCH(icode, ptr, dst, src, sw) \
1649         OP((icode), ptr, iMACINT0, dst, C_00000000, src, sw);
1650 #define SWITCH(icode, ptr, dst, src, sw) \
1651                 _SWITCH(icode, ptr, GPR(dst), GPR(src), GPR(sw))
1652 #define SWITCH_IN(icode, ptr, dst, src, sw) \
1653                 _SWITCH(icode, ptr, GPR(dst), EXTIN(src), GPR(sw))
1654 #define _SWITCH_NEG(icode, ptr, dst, src) \
1655         OP((icode), ptr, iANDXOR, dst, src, C_00000001, C_00000001);
1656 #define SWITCH_NEG(icode, ptr, dst, src) \
1657                 _SWITCH_NEG(icode, ptr, GPR(dst), GPR(src))
1658
1659
1660 static int __devinit _snd_emu10k1_init_efx(emu10k1_t *emu)
1661 {
1662         int err, i, z, gpr, tmp, playback, capture;
1663         u32 ptr;
1664         emu10k1_fx8010_code_t *icode;
1665         emu10k1_fx8010_pcm_t *ipcm;
1666         emu10k1_fx8010_control_gpr_t *controls, *ctl;
1667         mm_segment_t seg;
1668
1669         spin_lock_init(&emu->fx8010.irq_lock);
1670         INIT_LIST_HEAD(&emu->fx8010.gpr_ctl);
1671
1672         if ((icode = snd_kcalloc(sizeof(emu10k1_fx8010_code_t), GFP_KERNEL)) == NULL)
1673                 return -ENOMEM;
1674         if ((controls = snd_kcalloc(sizeof(emu10k1_fx8010_control_gpr_t) * SND_EMU10K1_GPR_CONTROLS, GFP_KERNEL)) == NULL) {
1675                 kfree(icode);
1676                 return -ENOMEM;
1677         }
1678         if ((ipcm = snd_kcalloc(sizeof(emu10k1_fx8010_pcm_t), GFP_KERNEL)) == NULL) {
1679                 kfree(controls);
1680                 kfree(icode);
1681                 return -ENOMEM;
1682         }
1683         
1684         /* clear free GPRs */
1685         for (i = 0; i < 256; i++)
1686                 set_bit(i, icode->gpr_valid);
1687
1688         /* clear TRAM data & address lines */
1689         for (i = 0; i < 160; i++)
1690                 set_bit(i, icode->tram_valid);
1691
1692         strcpy(icode->name, "SB Live! FX8010 code for ALSA v1.2 by Jaroslav Kysela");
1693         ptr = 0; i = 0;
1694         /* we have 10 inputs */
1695         playback = SND_EMU10K1_INPUTS;
1696         /* we have 6 playback channels and tone control doubles */
1697         capture = playback + (SND_EMU10K1_PLAYBACK_CHANNELS * 2);
1698         gpr = capture + SND_EMU10K1_CAPTURE_CHANNELS;
1699         tmp = 0x88;     /* we need 4 temporary GPR */
1700         /* from 0x8c to 0xff is the area for tone control */
1701
1702         /* stop FX processor */
1703         snd_emu10k1_ptr_write(emu, DBG, 0, (emu->fx8010.dbg = 0) | EMU10K1_DBG_SINGLE_STEP);
1704
1705         /*
1706          *  Process FX Buses
1707          */
1708         OP(icode, &ptr, iMACINT0, GPR(0), C_00000000, FXBUS(FXBUS_PCM_LEFT), C_00000004);
1709         OP(icode, &ptr, iMACINT0, GPR(1), C_00000000, FXBUS(FXBUS_PCM_RIGHT), C_00000004);
1710         OP(icode, &ptr, iMACINT0, GPR(2), C_00000000, FXBUS(FXBUS_MIDI_LEFT), C_00000004);
1711         OP(icode, &ptr, iMACINT0, GPR(3), C_00000000, FXBUS(FXBUS_MIDI_RIGHT), C_00000004);
1712         OP(icode, &ptr, iMACINT0, GPR(4), C_00000000, FXBUS(FXBUS_PCM_LEFT_REAR), C_00000004);
1713         OP(icode, &ptr, iMACINT0, GPR(5), C_00000000, FXBUS(FXBUS_PCM_RIGHT_REAR), C_00000004);
1714         OP(icode, &ptr, iMACINT0, GPR(6), C_00000000, FXBUS(FXBUS_PCM_CENTER), C_00000004);
1715         OP(icode, &ptr, iMACINT0, GPR(7), C_00000000, FXBUS(FXBUS_PCM_LFE), C_00000004);
1716         OP(icode, &ptr, iMACINT0, GPR(8), C_00000000, C_00000000, C_00000000);  /* S/PDIF left */
1717         OP(icode, &ptr, iMACINT0, GPR(9), C_00000000, C_00000000, C_00000000);  /* S/PDIF right */
1718
1719         /* Raw S/PDIF PCM */
1720         ipcm->substream = 0;
1721         ipcm->channels = 2;
1722         ipcm->tram_start = 0;
1723         ipcm->buffer_size = (64 * 1024) / 2;
1724         ipcm->gpr_size = gpr++;
1725         ipcm->gpr_ptr = gpr++;
1726         ipcm->gpr_count = gpr++;
1727         ipcm->gpr_tmpcount = gpr++;
1728         ipcm->gpr_trigger = gpr++;
1729         ipcm->gpr_running = gpr++;
1730         ipcm->etram[0] = 0;
1731         ipcm->etram[1] = 1;
1732
1733         icode->gpr_map[gpr + 0] = 0xfffff000;
1734         icode->gpr_map[gpr + 1] = 0xffff0000;
1735         icode->gpr_map[gpr + 2] = 0x70000000;
1736         icode->gpr_map[gpr + 3] = 0x00000007;
1737         icode->gpr_map[gpr + 4] = 0x001f << 11;
1738         icode->gpr_map[gpr + 5] = 0x001c << 11;
1739         icode->gpr_map[gpr + 6] = (0x22  - 0x01) - 1;   /* skip at 01 to 22 */
1740         icode->gpr_map[gpr + 7] = (0x22  - 0x06) - 1;   /* skip at 06 to 22 */
1741         icode->gpr_map[gpr + 8] = 0x2000000 + (2<<11);
1742         icode->gpr_map[gpr + 9] = 0x4000000 + (2<<11);
1743         icode->gpr_map[gpr + 10] = 1<<11;
1744         icode->gpr_map[gpr + 11] = (0x24 - 0x0a) - 1;   /* skip at 0a to 24 */
1745         icode->gpr_map[gpr + 12] = 0;
1746
1747         /* if the trigger flag is not set, skip */
1748         /* 00: */ OP(icode, &ptr, iMAC0, C_00000000, GPR(ipcm->gpr_trigger), C_00000000, C_00000000);
1749         /* 01: */ OP(icode, &ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_ZERO, GPR(gpr + 6));
1750         /* if the running flag is set, we're running */
1751         /* 02: */ OP(icode, &ptr, iMAC0, C_00000000, GPR(ipcm->gpr_running), C_00000000, C_00000000);
1752         /* 03: */ OP(icode, &ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, C_00000004);
1753         /* wait until ((GPR_DBAC>>11) & 0x1f) == 0x1c) */
1754         /* 04: */ OP(icode, &ptr, iANDXOR, GPR(tmp + 0), GPR_DBAC, GPR(gpr + 4), C_00000000);
1755         /* 05: */ OP(icode, &ptr, iMACINT0, C_00000000, GPR(tmp + 0), C_ffffffff, GPR(gpr + 5));
1756         /* 06: */ OP(icode, &ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, GPR(gpr + 7));
1757         /* 07: */ OP(icode, &ptr, iACC3, GPR(gpr + 12), C_00000010, C_00000001, C_00000000);
1758
1759         /* 08: */ OP(icode, &ptr, iANDXOR, GPR(ipcm->gpr_running), GPR(ipcm->gpr_running), C_00000000, C_00000001);
1760         /* 09: */ OP(icode, &ptr, iACC3, GPR(gpr + 12), GPR(gpr + 12), C_ffffffff, C_00000000);
1761         /* 0a: */ OP(icode, &ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, GPR(gpr + 11));
1762         /* 0b: */ OP(icode, &ptr, iACC3, GPR(gpr + 12), C_00000001, C_00000000, C_00000000);
1763
1764         /* 0c: */ OP(icode, &ptr, iANDXOR, GPR(tmp + 0), ETRAM_DATA(ipcm->etram[0]), GPR(gpr + 0), C_00000000);
1765         /* 0d: */ OP(icode, &ptr, iLOG, GPR(tmp + 0), GPR(tmp + 0), GPR(gpr + 3), C_00000000);
1766         /* 0e: */ OP(icode, &ptr, iANDXOR, GPR(8), GPR(tmp + 0), GPR(gpr + 1), GPR(gpr + 2));
1767         /* 0f: */ OP(icode, &ptr, iSKIP, C_00000000, GPR_COND, CC_REG_MINUS, C_00000001);
1768         /* 10: */ OP(icode, &ptr, iANDXOR, GPR(8), GPR(8), GPR(gpr + 1), GPR(gpr + 2));
1769
1770         /* 11: */ OP(icode, &ptr, iANDXOR, GPR(tmp + 0), ETRAM_DATA(ipcm->etram[1]), GPR(gpr + 0), C_00000000);
1771         /* 12: */ OP(icode, &ptr, iLOG, GPR(tmp + 0), GPR(tmp + 0), GPR(gpr + 3), C_00000000);
1772         /* 13: */ OP(icode, &ptr, iANDXOR, GPR(9), GPR(tmp + 0), GPR(gpr + 1), GPR(gpr + 2));
1773         /* 14: */ OP(icode, &ptr, iSKIP, C_00000000, GPR_COND, CC_REG_MINUS, C_00000001);
1774         /* 15: */ OP(icode, &ptr, iANDXOR, GPR(9), GPR(9), GPR(gpr + 1), GPR(gpr + 2));
1775
1776         /* 16: */ OP(icode, &ptr, iACC3, GPR(tmp + 0), GPR(ipcm->gpr_ptr), C_00000001, C_00000000);
1777         /* 17: */ OP(icode, &ptr, iMACINT0, C_00000000, GPR(tmp + 0), C_ffffffff, GPR(ipcm->gpr_size));
1778         /* 18: */ OP(icode, &ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_MINUS, C_00000001);
1779         /* 19: */ OP(icode, &ptr, iACC3, GPR(tmp + 0), C_00000000, C_00000000, C_00000000);
1780         /* 1a: */ OP(icode, &ptr, iACC3, GPR(ipcm->gpr_ptr), GPR(tmp + 0), C_00000000, C_00000000);
1781         
1782         /* 1b: */ OP(icode, &ptr, iACC3, GPR(ipcm->gpr_tmpcount), GPR(ipcm->gpr_tmpcount), C_ffffffff, C_00000000);
1783         /* 1c: */ OP(icode, &ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, C_00000002);
1784         /* 1d: */ OP(icode, &ptr, iACC3, GPR(ipcm->gpr_tmpcount), GPR(ipcm->gpr_count), C_00000000, C_00000000);
1785         /* 1e: */ OP(icode, &ptr, iACC3, GPR_IRQ, C_80000000, C_00000000, C_00000000);
1786         /* 1f: */ OP(icode, &ptr, iANDXOR, GPR(ipcm->gpr_running), GPR(ipcm->gpr_running), C_00000001, C_00010000);
1787
1788         /* 20: */ OP(icode, &ptr, iANDXOR, GPR(ipcm->gpr_running), GPR(ipcm->gpr_running), C_00010000, C_00000001);
1789         /* 21: */ OP(icode, &ptr, iSKIP, C_00000000, C_7fffffff, C_7fffffff, C_00000002);
1790
1791         /* 22: */ OP(icode, &ptr, iMACINT1, ETRAM_ADDR(ipcm->etram[0]), GPR(gpr + 8), GPR_DBAC, C_ffffffff);
1792         /* 23: */ OP(icode, &ptr, iMACINT1, ETRAM_ADDR(ipcm->etram[1]), GPR(gpr + 9), GPR_DBAC, C_ffffffff);
1793
1794         /* 24: */
1795         gpr += 13;
1796
1797         /* Wave Playback Volume */
1798         for (z = 0; z < 2; z++)
1799                 VOLUME(icode, &ptr, playback + z, z, gpr + z);
1800         snd_emu10k1_init_stereo_control(controls + i++, "Wave Playback Volume", gpr, 100);
1801         gpr += 2;
1802
1803         /* Wave Surround Playback Volume */
1804         for (z = 0; z < 2; z++)
1805                 VOLUME(icode, &ptr, playback + 2 + z, z, gpr + z);
1806         snd_emu10k1_init_stereo_control(controls + i++, "Wave Surround Playback Volume", gpr, 0);
1807         gpr += 2;
1808         
1809         /* Wave Center/LFE Playback Volume */
1810         OP(icode, &ptr, iACC3, GPR(tmp + 0), FXBUS(FXBUS_PCM_LEFT), FXBUS(FXBUS_PCM_RIGHT), C_00000000);
1811         OP(icode, &ptr, iMACINT0, GPR(tmp + 0), C_00000000, GPR(tmp + 0), C_00000002);
1812         VOLUME(icode, &ptr, playback + 4, tmp + 0, gpr);
1813         snd_emu10k1_init_mono_control(controls + i++, "Wave Center Playback Volume", gpr++, 0);
1814         VOLUME(icode, &ptr, playback + 5, tmp + 0, gpr);
1815         snd_emu10k1_init_mono_control(controls + i++, "Wave LFE Playback Volume", gpr++, 0);
1816
1817         /* Wave Capture Volume + Switch */
1818         for (z = 0; z < 2; z++) {
1819                 SWITCH(icode, &ptr, tmp + 0, z, gpr + 2 + z);
1820                 VOLUME(icode, &ptr, capture + z, tmp + 0, gpr + z);
1821         }
1822         snd_emu10k1_init_stereo_control(controls + i++, "Wave Capture Volume", gpr, 0);
1823         snd_emu10k1_init_stereo_onoff_control(controls + i++, "Wave Capture Switch", gpr + 2, 0);
1824         gpr += 4;
1825
1826         /* Music Playback Volume */
1827         for (z = 0; z < 2; z++)
1828                 VOLUME_ADD(icode, &ptr, playback + z, 2 + z, gpr + z);
1829         snd_emu10k1_init_stereo_control(controls + i++, "Music Playback Volume", gpr, 100);
1830         gpr += 2;
1831
1832         /* Music Capture Volume + Switch */
1833         for (z = 0; z < 2; z++) {
1834                 SWITCH(icode, &ptr, tmp + 0, 2 + z, gpr + 2 + z);
1835                 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
1836         }
1837         snd_emu10k1_init_stereo_control(controls + i++, "Music Capture Volume", gpr, 0);
1838         snd_emu10k1_init_stereo_onoff_control(controls + i++, "Music Capture Switch", gpr + 2, 0);
1839         gpr += 4;
1840
1841         /* Surround Digital Playback Volume (renamed later without Digital) */
1842         for (z = 0; z < 2; z++)
1843                 VOLUME_ADD(icode, &ptr, playback + 2 + z, 4 + z, gpr + z);
1844         snd_emu10k1_init_stereo_control(controls + i++, "Surround Digital Playback Volume", gpr, 100);
1845         gpr += 2;
1846
1847         /* Surround Capture Volume + Switch */
1848         for (z = 0; z < 2; z++) {
1849                 SWITCH(icode, &ptr, tmp + 0, 4 + z, gpr + 2 + z);
1850                 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
1851         }
1852         snd_emu10k1_init_stereo_control(controls + i++, "Surround Capture Volume", gpr, 0);
1853         snd_emu10k1_init_stereo_onoff_control(controls + i++, "Surround Capture Switch", gpr + 2, 0);
1854         gpr += 4;
1855
1856         /* Center Playback Volume (renamed later without Digital) */
1857         VOLUME_ADD(icode, &ptr, playback + 4, 6, gpr);
1858         snd_emu10k1_init_mono_control(controls + i++, "Center Digital Playback Volume", gpr++, 100);
1859
1860         /* LFE Playback Volume + Switch (renamed later without Digital) */
1861         VOLUME_ADD(icode, &ptr, playback + 5, 7, gpr);
1862         snd_emu10k1_init_mono_control(controls + i++, "LFE Digital Playback Volume", gpr++, 100);
1863
1864         /*
1865          *  Process inputs
1866          */
1867
1868         if (emu->fx8010.extin_mask & ((1<<EXTIN_AC97_L)|(1<<EXTIN_AC97_R))) {
1869                 /* AC'97 Playback Volume */
1870                 VOLUME_ADDIN(icode, &ptr, playback + 0, EXTIN_AC97_L, gpr); gpr++;
1871                 VOLUME_ADDIN(icode, &ptr, playback + 1, EXTIN_AC97_R, gpr); gpr++;
1872                 snd_emu10k1_init_stereo_control(controls + i++, "AC97 Playback Volume", gpr-2, 0);
1873                 /* AC'97 Capture Volume */
1874                 VOLUME_ADDIN(icode, &ptr, capture + 0, EXTIN_AC97_L, gpr); gpr++;
1875                 VOLUME_ADDIN(icode, &ptr, capture + 1, EXTIN_AC97_R, gpr); gpr++;
1876                 snd_emu10k1_init_stereo_control(controls + i++, "AC97 Capture Volume", gpr-2, 100);
1877         }
1878         
1879         if (emu->fx8010.extin_mask & ((1<<EXTIN_SPDIF_CD_L)|(1<<EXTIN_SPDIF_CD_R))) {
1880                 /* IEC958 TTL Playback Volume */
1881                 for (z = 0; z < 2; z++)
1882                         VOLUME_ADDIN(icode, &ptr, playback + z, EXTIN_SPDIF_CD_L + z, gpr + z);
1883                 snd_emu10k1_init_stereo_control(controls + i++, "IEC958 TTL Playback Volume", gpr, 0);
1884                 gpr += 2;
1885         
1886                 /* IEC958 TTL Capture Volume + Switch */
1887                 for (z = 0; z < 2; z++) {
1888                         SWITCH_IN(icode, &ptr, tmp + 0, EXTIN_SPDIF_CD_L + z, gpr + 2 + z);
1889                         VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
1890                 }
1891                 snd_emu10k1_init_stereo_control(controls + i++, "IEC958 TTL Capture Volume", gpr, 0);
1892                 snd_emu10k1_init_stereo_onoff_control(controls + i++, "IEC958 TTL Capture Switch", gpr + 2, 0);
1893                 gpr += 4;
1894         }
1895         
1896         if (emu->fx8010.extin_mask & ((1<<EXTIN_ZOOM_L)|(1<<EXTIN_ZOOM_R))) {
1897                 /* Zoom Video Playback Volume */
1898                 for (z = 0; z < 2; z++)
1899                         VOLUME_ADDIN(icode, &ptr, playback + z, EXTIN_ZOOM_L + z, gpr + z);
1900                 snd_emu10k1_init_stereo_control(controls + i++, "Zoom Video Playback Volume", gpr, 0);
1901                 gpr += 2;
1902         
1903                 /* Zoom Video Capture Volume + Switch */
1904                 for (z = 0; z < 2; z++) {
1905                         SWITCH_IN(icode, &ptr, tmp + 0, EXTIN_ZOOM_L + z, gpr + 2 + z);
1906                         VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
1907                 }
1908                 snd_emu10k1_init_stereo_control(controls + i++, "Zoom Video Capture Volume", gpr, 0);
1909                 snd_emu10k1_init_stereo_onoff_control(controls + i++, "Zoom Video Capture Switch", gpr + 2, 0);
1910                 gpr += 4;
1911         }
1912         
1913         if (emu->fx8010.extin_mask & ((1<<EXTIN_TOSLINK_L)|(1<<EXTIN_TOSLINK_R))) {
1914                 /* IEC958 Optical Playback Volume */
1915                 for (z = 0; z < 2; z++)
1916                         VOLUME_ADDIN(icode, &ptr, playback + z, EXTIN_TOSLINK_L + z, gpr + z);
1917                 snd_emu10k1_init_stereo_control(controls + i++, "IEC958 LiveDrive Playback Volume", gpr, 0);
1918                 gpr += 2;
1919         
1920                 /* IEC958 Optical Capture Volume */
1921                 for (z = 0; z < 2; z++) {
1922                         SWITCH_IN(icode, &ptr, tmp + 0, EXTIN_TOSLINK_L + z, gpr + 2 + z);
1923                         VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
1924                 }
1925                 snd_emu10k1_init_stereo_control(controls + i++, "IEC958 LiveDrive Capture Volume", gpr, 0);
1926                 snd_emu10k1_init_stereo_onoff_control(controls + i++, "IEC958 LiveDrive Capture Switch", gpr + 2, 0);
1927                 gpr += 4;
1928         }
1929         
1930         if (emu->fx8010.extin_mask & ((1<<EXTIN_LINE1_L)|(1<<EXTIN_LINE1_R))) {
1931                 /* Line LiveDrive Playback Volume */
1932                 for (z = 0; z < 2; z++)
1933                         VOLUME_ADDIN(icode, &ptr, playback + z, EXTIN_LINE1_L + z, gpr + z);
1934                 snd_emu10k1_init_stereo_control(controls + i++, "Line LiveDrive Playback Volume", gpr, 0);
1935                 gpr += 2;
1936         
1937                 /* Line LiveDrive Capture Volume + Switch */
1938                 for (z = 0; z < 2; z++) {
1939                         SWITCH_IN(icode, &ptr, tmp + 0, EXTIN_LINE1_L + z, gpr + 2 + z);
1940                         VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
1941                 }
1942                 snd_emu10k1_init_stereo_control(controls + i++, "Line LiveDrive Capture Volume", gpr, 0);
1943                 snd_emu10k1_init_stereo_onoff_control(controls + i++, "Line LiveDrive Capture Switch", gpr + 2, 0);
1944                 gpr += 4;
1945         }
1946         
1947         if (emu->fx8010.extin_mask & ((1<<EXTIN_COAX_SPDIF_L)|(1<<EXTIN_COAX_SPDIF_R))) {
1948                 /* IEC958 Coax Playback Volume */
1949                 for (z = 0; z < 2; z++)
1950                         VOLUME_ADDIN(icode, &ptr, playback + z, EXTIN_COAX_SPDIF_L + z, gpr + z);
1951                 snd_emu10k1_init_stereo_control(controls + i++, "IEC958 Coaxial Playback Volume", gpr, 0);
1952                 gpr += 2;
1953         
1954                 /* IEC958 Coax Capture Volume + Switch */
1955                 for (z = 0; z < 2; z++) {
1956                         SWITCH_IN(icode, &ptr, tmp + 0, EXTIN_COAX_SPDIF_L + z, gpr + 2 + z);
1957                         VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
1958                 }
1959                 snd_emu10k1_init_stereo_control(controls + i++, "IEC958 Coaxial Capture Volume", gpr, 0);
1960                 snd_emu10k1_init_stereo_onoff_control(controls + i++, "IEC958 Coaxial Capture Switch", gpr + 2, 0);
1961                 gpr += 4;
1962         }
1963         
1964         if (emu->fx8010.extin_mask & ((1<<EXTIN_LINE2_L)|(1<<EXTIN_LINE2_R))) {
1965                 /* Line LiveDrive Playback Volume */
1966                 for (z = 0; z < 2; z++)
1967                         VOLUME_ADDIN(icode, &ptr, playback + z, EXTIN_LINE2_L + z, gpr + z);
1968                 snd_emu10k1_init_stereo_control(controls + i++, "Line2 LiveDrive Playback Volume", gpr, 0);
1969                 controls[i-1].id.index = 1;
1970                 gpr += 2;
1971         
1972                 /* Line LiveDrive Capture Volume */
1973                 for (z = 0; z < 2; z++) {
1974                         SWITCH_IN(icode, &ptr, tmp + 0, EXTIN_LINE2_L + z, gpr + 2 + z);
1975                         VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
1976                 }
1977                 snd_emu10k1_init_stereo_control(controls + i++, "Line2 LiveDrive Capture Volume", gpr, 0);
1978                 controls[i-1].id.index = 1;
1979                 snd_emu10k1_init_stereo_onoff_control(controls + i++, "Line2 LiveDrive Capture Switch", gpr + 2, 0);
1980                 controls[i-1].id.index = 1;
1981                 gpr += 4;
1982         }
1983
1984         /*
1985          *  Process tone control
1986          */
1987         OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 0), GPR(playback + 0), C_00000000, C_00000000); /* left */
1988         OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 1), GPR(playback + 1), C_00000000, C_00000000); /* right */
1989         OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 2), GPR(playback + 2), C_00000000, C_00000000); /* rear left */
1990         OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 3), GPR(playback + 3), C_00000000, C_00000000); /* rear right */
1991         OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 4), GPR(playback + 4), C_00000000, C_00000000); /* center */
1992         OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 5), GPR(playback + 5), C_00000000, C_00000000); /* LFE */
1993
1994         ctl = &controls[i + 0];
1995         ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1996         strcpy(ctl->id.name, "Tone Control - Bass");
1997         ctl->vcount = 2;
1998         ctl->count = 10;
1999         ctl->min = 0;
2000         ctl->max = 40;
2001         ctl->value[0] = ctl->value[1] = 20;
2002         ctl->translation = EMU10K1_GPR_TRANSLATION_BASS;
2003         ctl = &controls[i + 1];
2004         ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
2005         strcpy(ctl->id.name, "Tone Control - Treble");
2006         ctl->vcount = 2;
2007         ctl->count = 10;
2008         ctl->min = 0;
2009         ctl->max = 40;
2010         ctl->value[0] = ctl->value[1] = 20;
2011         ctl->translation = EMU10K1_GPR_TRANSLATION_TREBLE;
2012
2013 #define BASS_GPR        0x8c
2014 #define TREBLE_GPR      0x96
2015
2016         for (z = 0; z < 5; z++) {
2017                 int j;
2018                 for (j = 0; j < 2; j++) {
2019                         controls[i + 0].gpr[z * 2 + j] = BASS_GPR + z * 2 + j;
2020                         controls[i + 1].gpr[z * 2 + j] = TREBLE_GPR + z * 2 + j;
2021                 }
2022         }
2023         for (z = 0; z < 3; z++) {               /* front/rear/center-lfe */
2024                 int j, k, l, d;
2025                 for (j = 0; j < 2; j++) {       /* left/right */
2026                         k = 0xa0 + (z * 8) + (j * 4);
2027                         l = 0xd0 + (z * 8) + (j * 4);
2028                         d = playback + SND_EMU10K1_PLAYBACK_CHANNELS + z * 2 + j;
2029
2030                         OP(icode, &ptr, iMAC0, C_00000000, C_00000000, GPR(d), GPR(BASS_GPR + 0 + j));
2031                         OP(icode, &ptr, iMACMV, GPR(k+1), GPR(k), GPR(k+1), GPR(BASS_GPR + 4 + j));
2032                         OP(icode, &ptr, iMACMV, GPR(k), GPR(d), GPR(k), GPR(BASS_GPR + 2 + j));
2033                         OP(icode, &ptr, iMACMV, GPR(k+3), GPR(k+2), GPR(k+3), GPR(BASS_GPR + 8 + j));
2034                         OP(icode, &ptr, iMAC0, GPR(k+2), GPR_ACCU, GPR(k+2), GPR(BASS_GPR + 6 + j));
2035                         OP(icode, &ptr, iACC3, GPR(k+2), GPR(k+2), GPR(k+2), C_00000000);
2036
2037                         OP(icode, &ptr, iMAC0, C_00000000, C_00000000, GPR(k+2), GPR(TREBLE_GPR + 0 + j));
2038                         OP(icode, &ptr, iMACMV, GPR(l+1), GPR(l), GPR(l+1), GPR(TREBLE_GPR + 4 + j));
2039                         OP(icode, &ptr, iMACMV, GPR(l), GPR(k+2), GPR(l), GPR(TREBLE_GPR + 2 + j));
2040                         OP(icode, &ptr, iMACMV, GPR(l+3), GPR(l+2), GPR(l+3), GPR(TREBLE_GPR + 8 + j));
2041                         OP(icode, &ptr, iMAC0, GPR(l+2), GPR_ACCU, GPR(l+2), GPR(TREBLE_GPR + 6 + j));
2042                         OP(icode, &ptr, iMACINT0, GPR(l+2), C_00000000, GPR(l+2), C_00000010);
2043
2044                         OP(icode, &ptr, iACC3, GPR(d), GPR(l+2), C_00000000, C_00000000);
2045
2046                         if (z == 2)     /* center */
2047                                 break;
2048                 }
2049         }
2050         i += 2;
2051
2052 #undef BASS_GPR
2053 #undef TREBLE_GPR
2054
2055         for (z = 0; z < 6; z++) {
2056                 SWITCH(icode, &ptr, tmp + 0, playback + SND_EMU10K1_PLAYBACK_CHANNELS + z, gpr + 0);
2057                 SWITCH_NEG(icode, &ptr, tmp + 1, gpr + 0);
2058                 SWITCH(icode, &ptr, tmp + 1, playback + z, tmp + 1);
2059                 OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + z), GPR(tmp + 0), GPR(tmp + 1), C_00000000);
2060         }
2061         snd_emu10k1_init_stereo_onoff_control(controls + i++, "Tone Control - Switch", gpr, 0);
2062         gpr += 2;
2063
2064         /*
2065          *  Process outputs
2066          */
2067         if (emu->fx8010.extout_mask & ((1<<EXTOUT_AC97_L)|(1<<EXTOUT_AC97_R))) {
2068                 /* AC'97 Playback Volume */
2069
2070                 for (z = 0; z < 2; z++)
2071                         OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_AC97_L + z), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + z), C_00000000, C_00000000);
2072         }
2073
2074         if (emu->fx8010.extout_mask & ((1<<EXTOUT_TOSLINK_L)|(1<<EXTOUT_TOSLINK_R))) {
2075                 /* IEC958 Optical Raw Playback Switch */
2076
2077                 for (z = 0; z < 2; z++) {
2078                         SWITCH(icode, &ptr, tmp + 0, 8 + z, gpr + z);
2079                         SWITCH_NEG(icode, &ptr, tmp + 1, gpr + z);
2080                         SWITCH(icode, &ptr, tmp + 1, playback + SND_EMU10K1_PLAYBACK_CHANNELS + z, tmp + 1);
2081                         OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_TOSLINK_L + z), GPR(tmp + 0), GPR(tmp + 1), C_00000000);
2082 #ifdef EMU10K1_CAPTURE_DIGITAL_OUT
2083                         OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_ADC_CAP_L + z), GPR(tmp + 0), GPR(tmp + 1), C_00000000);
2084 #endif
2085                 }
2086
2087                 snd_emu10k1_init_stereo_onoff_control(controls + i++, "IEC958 Optical Raw Playback Switch", gpr, 0);
2088                 gpr += 2;
2089         }
2090
2091         if (emu->fx8010.extout_mask & ((1<<EXTOUT_HEADPHONE_L)|(1<<EXTOUT_HEADPHONE_R))) {
2092                 /* Headphone Playback Volume */
2093
2094                 for (z = 0; z < 2; z++) {
2095                         SWITCH(icode, &ptr, tmp + 0, playback + SND_EMU10K1_PLAYBACK_CHANNELS + 4 + z, gpr + 2 + z);
2096                         SWITCH_NEG(icode, &ptr, tmp + 1, gpr + 2 + z);
2097                         SWITCH(icode, &ptr, tmp + 1, playback + SND_EMU10K1_PLAYBACK_CHANNELS + z, tmp + 1);
2098                         OP(icode, &ptr, iACC3, GPR(tmp + 0), GPR(tmp + 0), GPR(tmp + 1), C_00000000);
2099                         VOLUME_OUT(icode, &ptr, EXTOUT_HEADPHONE_L + z, tmp + 0, gpr + z);
2100                 }
2101
2102                 snd_emu10k1_init_stereo_control(controls + i++, "Headphone Playback Volume", gpr + 0, 0);
2103                 controls[i-1].id.index = 1;     /* AC'97 can have also Headphone control */
2104                 snd_emu10k1_init_mono_onoff_control(controls + i++, "Headphone Center Playback Switch", gpr + 2, 0);
2105                 controls[i-1].id.index = 1;
2106                 snd_emu10k1_init_mono_onoff_control(controls + i++, "Headphone LFE Playback Switch", gpr + 3, 0);
2107                 controls[i-1].id.index = 1;
2108
2109                 gpr += 4;
2110         }
2111         
2112         if (emu->fx8010.extout_mask & ((1<<EXTOUT_REAR_L)|(1<<EXTOUT_REAR_R)))
2113                 for (z = 0; z < 2; z++)
2114                         OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_REAR_L + z), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 2 + z), C_00000000, C_00000000);
2115
2116         if (emu->fx8010.extout_mask & (1<<EXTOUT_CENTER)) {
2117 #ifndef EMU10K1_CENTER_LFE_FROM_FRONT
2118                 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_CENTER), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 4), C_00000000, C_00000000);
2119                 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_ACENTER), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 4), C_00000000, C_00000000);
2120 #else
2121                 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_CENTER), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 0), C_00000000, C_00000000);
2122                 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_ACENTER), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 0), C_00000000, C_00000000);
2123 #endif
2124         }
2125
2126         if (emu->fx8010.extout_mask & (1<<EXTOUT_LFE)) {
2127 #ifndef EMU10K1_CENTER_LFE_FROM_FRONT
2128                 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_LFE), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 5), C_00000000, C_00000000);
2129                 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_ALFE), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 5), C_00000000, C_00000000);
2130 #else
2131                 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_LFE), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 1), C_00000000, C_00000000);
2132                 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_ALFE), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 1), C_00000000, C_00000000);
2133 #endif
2134         }
2135         
2136 #ifndef EMU10K1_CAPTURE_DIGITAL_OUT
2137         for (z = 0; z < 2; z++)
2138                 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_ADC_CAP_L + z), GPR(capture + z), C_00000000, C_00000000);
2139 #endif
2140         
2141         if (emu->fx8010.extout_mask & (1<<EXTOUT_MIC_CAP))
2142                 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_MIC_CAP), GPR(capture + 2), C_00000000, C_00000000);
2143
2144         if (gpr > tmp) {
2145                 snd_BUG();
2146                 err = -EIO;
2147                 goto __err;
2148         }
2149         if (i > SND_EMU10K1_GPR_CONTROLS) {
2150                 snd_BUG();
2151                 err = -EIO;
2152                 goto __err;
2153         }
2154         
2155         /* clear remaining instruction memory */
2156         while (ptr < 0x200)
2157                 OP(icode, &ptr, iACC3, C_00000000, C_00000000, C_00000000, C_00000000);
2158
2159         if ((err = snd_emu10k1_fx8010_tram_setup(emu, ipcm->buffer_size)) < 0)
2160                 goto __err;
2161         seg = snd_enter_user();
2162         icode->gpr_add_control_count = i;
2163         icode->gpr_add_controls = controls;
2164         err = snd_emu10k1_icode_poke(emu, icode);
2165         snd_leave_user(seg);
2166         if (err >= 0)
2167                 err = snd_emu10k1_ipcm_poke(emu, ipcm);
2168       __err:
2169         kfree(ipcm);
2170         kfree(controls);
2171         kfree(icode);
2172         return err;
2173 }
2174
2175 int __devinit snd_emu10k1_init_efx(emu10k1_t *emu)
2176 {
2177         if (emu->audigy)
2178                 return _snd_emu10k1_audigy_init_efx(emu);
2179         else
2180                 return _snd_emu10k1_init_efx(emu);
2181 }
2182
2183 void snd_emu10k1_free_efx(emu10k1_t *emu)
2184 {
2185         /* stop processor */
2186         if (emu->audigy)
2187                 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg = A_DBG_SINGLE_STEP);
2188         else
2189                 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg = EMU10K1_DBG_SINGLE_STEP);
2190 }
2191
2192 #if 0 // FIXME: who use them?
2193 int snd_emu10k1_fx8010_tone_control_activate(emu10k1_t *emu, int output)
2194 {
2195         snd_runtime_check(output >= 0 && output < 6, return -EINVAL);
2196         snd_emu10k1_ptr_write(emu, emu->gpr_base + 0x94 + output, 0, 1);
2197         return 0;
2198 }
2199
2200 int snd_emu10k1_fx8010_tone_control_deactivate(emu10k1_t *emu, int output)
2201 {
2202         snd_runtime_check(output >= 0 && output < 6, return -EINVAL);
2203         snd_emu10k1_ptr_write(emu, emu->gpr_base + 0x94 + output, 0, 0);
2204         return 0;
2205 }
2206 #endif
2207
2208 int snd_emu10k1_fx8010_tram_setup(emu10k1_t *emu, u32 size)
2209 {
2210         u8 size_reg = 0;
2211
2212         /* size is in samples */
2213         if (size != 0) {
2214                 size = (size - 1) >> 13;
2215
2216                 while (size) {
2217                         size >>= 1;
2218                         size_reg++;
2219                 }
2220                 size = 0x2000 << size_reg;
2221         }
2222         if (emu->fx8010.etram_pages.bytes == size)
2223                 return 0;
2224         spin_lock_irq(&emu->emu_lock);
2225         outl(HCFG_LOCKTANKCACHE_MASK | inl(emu->port + HCFG), emu->port + HCFG);
2226         spin_unlock_irq(&emu->emu_lock);
2227         snd_emu10k1_ptr_write(emu, TCB, 0, 0);
2228         snd_emu10k1_ptr_write(emu, TCBS, 0, 0);
2229         if (emu->fx8010.etram_pages.area != NULL) {
2230                 snd_dma_free_pages(&emu->dma_dev, &emu->fx8010.etram_pages);
2231                 emu->fx8010.etram_pages.area = NULL;
2232                 emu->fx8010.etram_pages.bytes = 0;
2233         }
2234
2235         if (size > 0) {
2236                 if (snd_dma_alloc_pages(&emu->dma_dev, size * 2, &emu->fx8010.etram_pages) < 0)
2237                         return -ENOMEM;
2238                 memset(emu->fx8010.etram_pages.area, 0, size * 2);
2239                 snd_emu10k1_ptr_write(emu, TCB, 0, emu->fx8010.etram_pages.addr);
2240                 snd_emu10k1_ptr_write(emu, TCBS, 0, size_reg);
2241                 spin_lock_irq(&emu->emu_lock);
2242                 outl(inl(emu->port + HCFG) & ~HCFG_LOCKTANKCACHE_MASK, emu->port + HCFG);
2243                 spin_unlock_irq(&emu->emu_lock);        
2244         }
2245
2246         return 0;
2247 }
2248
2249 static int snd_emu10k1_fx8010_open(snd_hwdep_t * hw, struct file *file)
2250 {
2251         return 0;
2252 }
2253
2254 static void copy_string(char *dst, char *src, char *null, int idx)
2255 {
2256         if (src == NULL)
2257                 sprintf(dst, "%s %02X", null, idx);
2258         else
2259                 strcpy(dst, src);
2260 }
2261
2262 static int snd_emu10k1_fx8010_info(emu10k1_t *emu, emu10k1_fx8010_info_t *info)
2263 {
2264         char **fxbus, **extin, **extout;
2265         unsigned short fxbus_mask, extin_mask, extout_mask;
2266         int res;
2267
2268         memset(info, 0, sizeof(info));
2269         info->card = emu->card_type;
2270         info->internal_tram_size = emu->fx8010.itram_size;
2271         info->external_tram_size = emu->fx8010.etram_pages.bytes;
2272         fxbus = fxbuses;
2273         extin = emu->audigy ? audigy_ins : creative_ins;
2274         extout = emu->audigy ? audigy_outs : creative_outs;
2275         fxbus_mask = emu->fx8010.fxbus_mask;
2276         extin_mask = emu->fx8010.extin_mask;
2277         extout_mask = emu->fx8010.extout_mask;
2278         for (res = 0; res < 16; res++, fxbus++, extin++, extout++) {
2279                 copy_string(info->fxbus_names[res], fxbus_mask & (1 << res) ? *fxbus : NULL, "FXBUS", res);
2280                 copy_string(info->extin_names[res], extin_mask & (1 << res) ? *extin : NULL, "Unused", res);
2281                 copy_string(info->extout_names[res], extout_mask & (1 << res) ? *extout : NULL, "Unused", res);
2282         }
2283         for (res = 16; res < 32; res++, extout++)
2284                 copy_string(info->extout_names[res], extout_mask & (1 << res) ? *extout : NULL, "Unused", res);
2285         info->gpr_controls = emu->fx8010.gpr_count;
2286         return 0;
2287 }
2288
2289 static int snd_emu10k1_fx8010_ioctl(snd_hwdep_t * hw, struct file *file, unsigned int cmd, unsigned long arg)
2290 {
2291         emu10k1_t *emu = snd_magic_cast(emu10k1_t, hw->private_data, return -ENXIO);
2292         emu10k1_fx8010_info_t *info;
2293         emu10k1_fx8010_code_t *icode;
2294         emu10k1_fx8010_pcm_t *ipcm;
2295         unsigned int addr;
2296         int res;
2297         
2298         switch (cmd) {
2299         case SNDRV_EMU10K1_IOCTL_INFO:
2300                 info = (emu10k1_fx8010_info_t *)kmalloc(sizeof(*info), GFP_KERNEL);
2301                 if (!info)
2302                         return -ENOMEM;
2303                 if ((res = snd_emu10k1_fx8010_info(emu, info)) < 0) {
2304                         kfree(info);
2305                         return res;
2306                 }
2307                 if (copy_to_user((void *)arg, info, sizeof(*info))) {
2308                         kfree(info);
2309                         return -EFAULT;
2310                 }
2311                 kfree(info);
2312                 return 0;
2313         case SNDRV_EMU10K1_IOCTL_CODE_POKE:
2314                 if (!capable(CAP_SYS_ADMIN))
2315                         return -EPERM;
2316                 icode = (emu10k1_fx8010_code_t *)kmalloc(sizeof(*icode), GFP_KERNEL);
2317                 if (icode == NULL)
2318                         return -ENOMEM;
2319                 if (copy_from_user(icode, (void *)arg, sizeof(*icode))) {
2320                         kfree(icode);
2321                         return -EFAULT;
2322                 }
2323                 res = snd_emu10k1_icode_poke(emu, icode);
2324                 kfree(icode);
2325                 return res;
2326         case SNDRV_EMU10K1_IOCTL_CODE_PEEK:
2327                 icode = (emu10k1_fx8010_code_t *)kmalloc(sizeof(*icode), GFP_KERNEL);
2328                 if (icode == NULL)
2329                         return -ENOMEM;
2330                 if (copy_from_user(icode, (void *)arg, sizeof(*icode))) {
2331                         kfree(icode);
2332                         return -EFAULT;
2333                 }
2334                 res = snd_emu10k1_icode_peek(emu, icode);
2335                 if (res == 0 && copy_to_user((void *)arg, icode, sizeof(*icode))) {
2336                         kfree(icode);
2337                         return -EFAULT;
2338                 }
2339                 kfree(icode);
2340                 return res;
2341         case SNDRV_EMU10K1_IOCTL_PCM_POKE:
2342                 if (emu->audigy)
2343                         return -EINVAL;
2344                 ipcm = (emu10k1_fx8010_pcm_t *)kmalloc(sizeof(*ipcm), GFP_KERNEL);
2345                 if (ipcm == NULL)
2346                         return -ENOMEM;
2347                 if (copy_from_user(ipcm, (void *)arg, sizeof(*ipcm))) {
2348                         kfree(ipcm);
2349                         return -EFAULT;
2350                 }
2351                 res = snd_emu10k1_ipcm_poke(emu, ipcm);
2352                 kfree(ipcm);
2353                 return res;
2354         case SNDRV_EMU10K1_IOCTL_PCM_PEEK:
2355                 if (emu->audigy)
2356                         return -EINVAL;
2357                 ipcm = (emu10k1_fx8010_pcm_t *)snd_kcalloc(sizeof(*ipcm), GFP_KERNEL);
2358                 if (ipcm == NULL)
2359                         return -ENOMEM;
2360                 if (copy_from_user(ipcm, (void *)arg, sizeof(*ipcm))) {
2361                         kfree(ipcm);
2362                         return -EFAULT;
2363                 }
2364                 res = snd_emu10k1_ipcm_peek(emu, ipcm);
2365                 if (res == 0 && copy_to_user((void *)arg, ipcm, sizeof(*ipcm))) {
2366                         kfree(ipcm);
2367                         return -EFAULT;
2368                 }
2369                 kfree(ipcm);
2370                 return res;
2371         case SNDRV_EMU10K1_IOCTL_TRAM_SETUP:
2372                 if (emu->audigy)
2373                         return -EINVAL;
2374                 if (!capable(CAP_SYS_ADMIN))
2375                         return -EPERM;
2376                 if (get_user(addr, (unsigned int *)arg))
2377                         return -EFAULT;
2378                 down(&emu->fx8010.lock);
2379                 res = snd_emu10k1_fx8010_tram_setup(emu, addr);
2380                 up(&emu->fx8010.lock);
2381                 return res;
2382         case SNDRV_EMU10K1_IOCTL_STOP:
2383                 if (!capable(CAP_SYS_ADMIN))
2384                         return -EPERM;
2385                 if (emu->audigy)
2386                         snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg |= A_DBG_SINGLE_STEP);
2387                 else
2388                         snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg |= EMU10K1_DBG_SINGLE_STEP);
2389                 return 0;
2390         case SNDRV_EMU10K1_IOCTL_CONTINUE:
2391                 if (!capable(CAP_SYS_ADMIN))
2392                         return -EPERM;
2393                 if (emu->audigy)
2394                         snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg = 0);
2395                 else
2396                         snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg = 0);
2397                 return 0;
2398         case SNDRV_EMU10K1_IOCTL_ZERO_TRAM_COUNTER:
2399                 if (!capable(CAP_SYS_ADMIN))
2400                         return -EPERM;
2401                 if (emu->audigy)
2402                         snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg | A_DBG_ZC);
2403                 else
2404                         snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg | EMU10K1_DBG_ZC);
2405                 udelay(10);
2406                 if (emu->audigy)
2407                         snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg);
2408                 else
2409                         snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg);
2410                 return 0;
2411         case SNDRV_EMU10K1_IOCTL_SINGLE_STEP:
2412                 if (!capable(CAP_SYS_ADMIN))
2413                         return -EPERM;
2414                 if (get_user(addr, (unsigned int *)arg))
2415                         return -EFAULT;
2416                 if (addr > 0x1ff)
2417                         return -EINVAL;
2418                 if (emu->audigy)
2419                         snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg |= A_DBG_SINGLE_STEP | addr);
2420                 else
2421                         snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg |= EMU10K1_DBG_SINGLE_STEP | addr);
2422                 udelay(10);
2423                 if (emu->audigy)
2424                         snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg |= A_DBG_SINGLE_STEP | A_DBG_STEP_ADDR | addr);
2425                 else
2426                         snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg |= EMU10K1_DBG_SINGLE_STEP | EMU10K1_DBG_STEP | addr);
2427                 return 0;
2428         case SNDRV_EMU10K1_IOCTL_DBG_READ:
2429                 if (emu->audigy)
2430                         addr = snd_emu10k1_ptr_read(emu, A_DBG, 0);
2431                 else
2432                         addr = snd_emu10k1_ptr_read(emu, DBG, 0);
2433                 if (put_user(addr, (unsigned int *)arg))
2434                         return -EFAULT;
2435                 return 0;
2436         }
2437         return -ENOTTY;
2438 }
2439
2440 static int snd_emu10k1_fx8010_release(snd_hwdep_t * hw, struct file *file)
2441 {
2442         return 0;
2443 }
2444
2445 int __devinit snd_emu10k1_fx8010_new(emu10k1_t *emu, int device, snd_hwdep_t ** rhwdep)
2446 {
2447         snd_hwdep_t *hw;
2448         int err;
2449         
2450         if (rhwdep)
2451                 *rhwdep = NULL;
2452         if ((err = snd_hwdep_new(emu->card, "FX8010", device, &hw)) < 0)
2453                 return err;
2454         strcpy(hw->name, "EMU10K1 (FX8010)");
2455         hw->iface = SNDRV_HWDEP_IFACE_EMU10K1;
2456         hw->ops.open = snd_emu10k1_fx8010_open;
2457         hw->ops.ioctl = snd_emu10k1_fx8010_ioctl;
2458         hw->ops.release = snd_emu10k1_fx8010_release;
2459         hw->private_data = emu;
2460         if (rhwdep)
2461                 *rhwdep = hw;
2462         return 0;
2463 }