patch-2_6_7-vs1_9_1_12
[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 */ "AC97 Surround Left",
124         /* 0x0e */ "AC97 Surround Right",
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 __user *_id;
902         snd_ctl_elem_id_t id;
903         emu10k1_fx8010_control_gpr_t __user *_gctl;
904         emu10k1_fx8010_control_gpr_t gctl;
905         
906         for (i = 0, _id = icode->gpr_del_controls;
907              i < icode->gpr_del_control_count; i++, _id++) {
908                 if (copy_from_user(&id, _id, sizeof(id)))
909                         return -EFAULT;
910                 if (snd_emu10k1_look_for_ctl(emu, &id) == NULL)
911                         return -ENOENT;
912         }
913         for (i = 0, _gctl = icode->gpr_add_controls;
914              i < icode->gpr_add_control_count; i++, _gctl++) {
915                 if (copy_from_user(&gctl, _gctl, sizeof(gctl)))
916                         return -EFAULT;
917                 if (snd_emu10k1_look_for_ctl(emu, &gctl.id))
918                         continue;
919                 down_read(&emu->card->controls_rwsem);
920                 if (snd_ctl_find_id(emu->card, &gctl.id) != NULL) {
921                         up_read(&emu->card->controls_rwsem);
922                         return -EEXIST;
923                 }
924                 up_read(&emu->card->controls_rwsem);
925                 if (gctl.id.iface != SNDRV_CTL_ELEM_IFACE_MIXER &&
926                     gctl.id.iface != SNDRV_CTL_ELEM_IFACE_PCM)
927                         return -EINVAL;
928         }
929         for (i = 0, _gctl = icode->gpr_list_controls;
930              i < icode->gpr_list_control_count; i++, _gctl++) {
931                 /* FIXME: we need to check the WRITE access */
932                 if (copy_from_user(&gctl, _gctl, sizeof(gctl)))
933                         return -EFAULT;
934         }
935         return 0;
936 }
937
938 static void snd_emu10k1_ctl_private_free(snd_kcontrol_t *kctl)
939 {
940         snd_emu10k1_fx8010_ctl_t *ctl;
941         
942         ctl = (snd_emu10k1_fx8010_ctl_t *)kctl->private_value;
943         kctl->private_value = 0;
944         list_del(&ctl->list);
945         kfree(ctl);
946 }
947
948 static void snd_emu10k1_add_controls(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
949 {
950         unsigned int i, j;
951         emu10k1_fx8010_control_gpr_t __user *_gctl;
952         emu10k1_fx8010_control_gpr_t gctl;
953         snd_emu10k1_fx8010_ctl_t *ctl, nctl;
954         snd_kcontrol_new_t knew;
955         snd_kcontrol_t *kctl;
956         snd_ctl_elem_value_t *val;
957
958         val = (snd_ctl_elem_value_t *)kmalloc(sizeof(*val), GFP_KERNEL);
959         if (!val)
960                 return;
961         for (i = 0, _gctl = icode->gpr_add_controls;
962              i < icode->gpr_add_control_count; i++, _gctl++) {
963                 if (copy_from_user(&gctl, _gctl, sizeof(gctl)))
964                         break;
965                 snd_runtime_check(gctl.id.iface == SNDRV_CTL_ELEM_IFACE_MIXER ||
966                                   gctl.id.iface == SNDRV_CTL_ELEM_IFACE_PCM, continue);
967                 snd_runtime_check(gctl.id.name[0] != '\0', continue);
968                 ctl = snd_emu10k1_look_for_ctl(emu, &gctl.id);
969                 memset(&knew, 0, sizeof(knew));
970                 knew.iface = gctl.id.iface;
971                 knew.name = gctl.id.name;
972                 knew.index = gctl.id.index;
973                 knew.device = gctl.id.device;
974                 knew.subdevice = gctl.id.subdevice;
975                 knew.info = snd_emu10k1_gpr_ctl_info;
976                 knew.get = snd_emu10k1_gpr_ctl_get;
977                 knew.put = snd_emu10k1_gpr_ctl_put;
978                 memset(&nctl, 0, sizeof(nctl));
979                 nctl.vcount = gctl.vcount;
980                 nctl.count = gctl.count;
981                 for (j = 0; j < 32; j++) {
982                         nctl.gpr[j] = gctl.gpr[j];
983                         nctl.value[j] = ~gctl.value[j]; /* inverted, we want to write new value in gpr_ctl_put() */
984                         val->value.integer.value[j] = gctl.value[j];
985                 }
986                 nctl.min = gctl.min;
987                 nctl.max = gctl.max;
988                 nctl.translation = gctl.translation;
989                 if (ctl == NULL) {
990                         ctl = (snd_emu10k1_fx8010_ctl_t *)kmalloc(sizeof(*ctl), GFP_KERNEL);
991                         if (ctl == NULL)
992                                 continue;
993                         knew.private_value = (unsigned long)ctl;
994                         memcpy(ctl, &nctl, sizeof(nctl));
995                         if (snd_ctl_add(emu->card, kctl = snd_ctl_new1(&knew, emu)) < 0) {
996                                 kfree(ctl);
997                                 continue;
998                         }
999                         kctl->private_free = snd_emu10k1_ctl_private_free;
1000                         ctl->kcontrol = kctl;
1001                         list_add_tail(&ctl->list, &emu->fx8010.gpr_ctl);
1002                 } else {
1003                         /* overwrite */
1004                         nctl.list = ctl->list;
1005                         nctl.kcontrol = ctl->kcontrol;
1006                         memcpy(ctl, &nctl, sizeof(nctl));
1007                         snd_ctl_notify(emu->card, SNDRV_CTL_EVENT_MASK_VALUE |
1008                                                   SNDRV_CTL_EVENT_MASK_INFO, &ctl->kcontrol->id);
1009                 }
1010                 snd_emu10k1_gpr_ctl_put(ctl->kcontrol, val);
1011         }
1012         kfree(val);
1013 }
1014
1015 static void snd_emu10k1_del_controls(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
1016 {
1017         unsigned int i;
1018         snd_ctl_elem_id_t id;
1019         snd_ctl_elem_id_t __user *_id;
1020         snd_emu10k1_fx8010_ctl_t *ctl;
1021         snd_card_t *card = emu->card;
1022         
1023         for (i = 0, _id = icode->gpr_del_controls;
1024              i < icode->gpr_del_control_count; i++, _id++) {
1025                 snd_runtime_check(copy_from_user(&id, _id, sizeof(id)) == 0, continue);
1026                 down_write(&card->controls_rwsem);
1027                 ctl = snd_emu10k1_look_for_ctl(emu, &id);
1028                 if (ctl)
1029                         snd_ctl_remove(card, ctl->kcontrol);
1030                 up_write(&card->controls_rwsem);
1031         }
1032 }
1033
1034 static int snd_emu10k1_list_controls(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
1035 {
1036         unsigned int i = 0, j;
1037         unsigned int total = 0;
1038         emu10k1_fx8010_control_gpr_t gctl;
1039         emu10k1_fx8010_control_gpr_t __user *_gctl;
1040         snd_emu10k1_fx8010_ctl_t *ctl;
1041         snd_ctl_elem_id_t *id;
1042         struct list_head *list;
1043
1044         _gctl = icode->gpr_list_controls;       
1045         list_for_each(list, &emu->fx8010.gpr_ctl) {
1046                 ctl = emu10k1_gpr_ctl(list);
1047                 total++;
1048                 if (_gctl && i < icode->gpr_list_control_count) {
1049                         memset(&gctl, 0, sizeof(gctl));
1050                         id = &ctl->kcontrol->id;
1051                         gctl.id.iface = id->iface;
1052                         strlcpy(gctl.id.name, id->name, sizeof(gctl.id.name));
1053                         gctl.id.index = id->index;
1054                         gctl.id.device = id->device;
1055                         gctl.id.subdevice = id->subdevice;
1056                         gctl.vcount = ctl->vcount;
1057                         gctl.count = ctl->count;
1058                         for (j = 0; j < 32; j++) {
1059                                 gctl.gpr[j] = ctl->gpr[j];
1060                                 gctl.value[j] = ctl->value[j];
1061                         }
1062                         gctl.min = ctl->min;
1063                         gctl.max = ctl->max;
1064                         gctl.translation = ctl->translation;
1065                         if (copy_to_user(_gctl, &gctl, sizeof(gctl)))
1066                                 return -EFAULT;
1067                         _gctl++;
1068                         i++;
1069                 }
1070         }
1071         icode->gpr_list_control_total = total;
1072         return 0;
1073 }
1074
1075 static int snd_emu10k1_icode_poke(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
1076 {
1077         int err = 0;
1078
1079         down(&emu->fx8010.lock);
1080         if ((err = snd_emu10k1_verify_controls(emu, icode)) < 0)
1081                 goto __error;
1082         strlcpy(emu->fx8010.name, icode->name, sizeof(emu->fx8010.name));
1083         /* stop FX processor - this may be dangerous, but it's better to miss
1084            some samples than generate wrong ones - [jk] */
1085         if (emu->audigy)
1086                 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg | A_DBG_SINGLE_STEP);
1087         else
1088                 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg | EMU10K1_DBG_SINGLE_STEP);
1089         /* ok, do the main job */
1090         snd_emu10k1_del_controls(emu, icode);
1091         snd_emu10k1_gpr_poke(emu, icode);
1092         snd_emu10k1_tram_poke(emu, icode);
1093         snd_emu10k1_code_poke(emu, icode);
1094         snd_emu10k1_add_controls(emu, icode);
1095         /* start FX processor when the DSP code is updated */
1096         if (emu->audigy)
1097                 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg);
1098         else
1099                 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg);
1100       __error:
1101         up(&emu->fx8010.lock);
1102         return err;
1103 }
1104
1105 static int snd_emu10k1_icode_peek(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
1106 {
1107         int err;
1108
1109         down(&emu->fx8010.lock);
1110         strlcpy(icode->name, emu->fx8010.name, sizeof(icode->name));
1111         /* ok, do the main job */
1112         snd_emu10k1_gpr_peek(emu, icode);
1113         snd_emu10k1_tram_peek(emu, icode);
1114         snd_emu10k1_code_peek(emu, icode);
1115         err = snd_emu10k1_list_controls(emu, icode);
1116         up(&emu->fx8010.lock);
1117         return err;
1118 }
1119
1120 static int snd_emu10k1_ipcm_poke(emu10k1_t *emu, emu10k1_fx8010_pcm_t *ipcm)
1121 {
1122         unsigned int i;
1123         int err = 0;
1124         snd_emu10k1_fx8010_pcm_t *pcm;
1125
1126         if (ipcm->substream >= EMU10K1_FX8010_PCM_COUNT)
1127                 return -EINVAL;
1128         if (ipcm->channels > 32)
1129                 return -EINVAL;
1130         pcm = &emu->fx8010.pcm[ipcm->substream];
1131         down(&emu->fx8010.lock);
1132         spin_lock_irq(&emu->reg_lock);
1133         if (pcm->opened) {
1134                 err = -EBUSY;
1135                 goto __error;
1136         }
1137         if (ipcm->channels == 0) {      /* remove */
1138                 pcm->valid = 0;
1139         } else {
1140                 /* FIXME: we need to add universal code to the PCM transfer routine */
1141                 if (ipcm->channels != 2) {
1142                         err = -EINVAL;
1143                         goto __error;
1144                 }
1145                 pcm->valid = 1;
1146                 pcm->opened = 0;
1147                 pcm->channels = ipcm->channels;
1148                 pcm->tram_start = ipcm->tram_start;
1149                 pcm->buffer_size = ipcm->buffer_size;
1150                 pcm->gpr_size = ipcm->gpr_size;
1151                 pcm->gpr_count = ipcm->gpr_count;
1152                 pcm->gpr_tmpcount = ipcm->gpr_tmpcount;
1153                 pcm->gpr_ptr = ipcm->gpr_ptr;
1154                 pcm->gpr_trigger = ipcm->gpr_trigger;
1155                 pcm->gpr_running = ipcm->gpr_running;
1156                 for (i = 0; i < pcm->channels; i++)
1157                         pcm->etram[i] = ipcm->etram[i];
1158         }
1159       __error:
1160         spin_unlock_irq(&emu->reg_lock);
1161         up(&emu->fx8010.lock);
1162         return err;
1163 }
1164
1165 static int snd_emu10k1_ipcm_peek(emu10k1_t *emu, emu10k1_fx8010_pcm_t *ipcm)
1166 {
1167         unsigned int i;
1168         int err = 0;
1169         snd_emu10k1_fx8010_pcm_t *pcm;
1170
1171         if (ipcm->substream >= EMU10K1_FX8010_PCM_COUNT)
1172                 return -EINVAL;
1173         pcm = &emu->fx8010.pcm[ipcm->substream];
1174         down(&emu->fx8010.lock);
1175         spin_lock_irq(&emu->reg_lock);
1176         ipcm->channels = pcm->channels;
1177         ipcm->tram_start = pcm->tram_start;
1178         ipcm->buffer_size = pcm->buffer_size;
1179         ipcm->gpr_size = pcm->gpr_size;
1180         ipcm->gpr_ptr = pcm->gpr_ptr;
1181         ipcm->gpr_count = pcm->gpr_count;
1182         ipcm->gpr_tmpcount = pcm->gpr_tmpcount;
1183         ipcm->gpr_trigger = pcm->gpr_trigger;
1184         ipcm->gpr_running = pcm->gpr_running;
1185         for (i = 0; i < pcm->channels; i++)
1186                 ipcm->etram[i] = pcm->etram[i];
1187         ipcm->res1 = ipcm->res2 = 0;
1188         ipcm->pad = 0;
1189         spin_unlock_irq(&emu->reg_lock);
1190         up(&emu->fx8010.lock);
1191         return err;
1192 }
1193
1194 #define SND_EMU10K1_GPR_CONTROLS        41
1195 #define SND_EMU10K1_INPUTS              10
1196 #define SND_EMU10K1_PLAYBACK_CHANNELS   6
1197 #define SND_EMU10K1_CAPTURE_CHANNELS    4
1198
1199 static void __devinit snd_emu10k1_init_mono_control(emu10k1_fx8010_control_gpr_t *ctl, const char *name, int gpr, int defval)
1200 {
1201         ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1202         strcpy(ctl->id.name, name);
1203         ctl->vcount = ctl->count = 1;
1204         ctl->gpr[0] = gpr + 0; ctl->value[0] = defval;
1205         ctl->min = 0;
1206         ctl->max = 100;
1207         ctl->translation = EMU10K1_GPR_TRANSLATION_TABLE100;    
1208 }
1209
1210 static void __devinit snd_emu10k1_init_stereo_control(emu10k1_fx8010_control_gpr_t *ctl, const char *name, int gpr, int defval)
1211 {
1212         ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1213         strcpy(ctl->id.name, name);
1214         ctl->vcount = ctl->count = 2;
1215         ctl->gpr[0] = gpr + 0; ctl->value[0] = defval;
1216         ctl->gpr[1] = gpr + 1; ctl->value[1] = defval;
1217         ctl->min = 0;
1218         ctl->max = 100;
1219         ctl->translation = EMU10K1_GPR_TRANSLATION_TABLE100;
1220 }
1221
1222 static void __devinit snd_emu10k1_init_mono_onoff_control(emu10k1_fx8010_control_gpr_t *ctl, const char *name, int gpr, int defval)
1223 {
1224         ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1225         strcpy(ctl->id.name, name);
1226         ctl->vcount = ctl->count = 1;
1227         ctl->gpr[0] = gpr + 0; ctl->value[0] = defval;
1228         ctl->min = 0;
1229         ctl->max = 1;
1230         ctl->translation = EMU10K1_GPR_TRANSLATION_ONOFF;
1231 }
1232
1233 static void __devinit snd_emu10k1_init_stereo_onoff_control(emu10k1_fx8010_control_gpr_t *ctl, const char *name, int gpr, int defval)
1234 {
1235         ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1236         strcpy(ctl->id.name, name);
1237         ctl->vcount = ctl->count = 2;
1238         ctl->gpr[0] = gpr + 0; ctl->value[0] = defval;
1239         ctl->gpr[1] = gpr + 1; ctl->value[1] = defval;
1240         ctl->min = 0;
1241         ctl->max = 1;
1242         ctl->translation = EMU10K1_GPR_TRANSLATION_ONOFF;
1243 }
1244
1245
1246 /*
1247  * initial DSP configuration for Audigy
1248  */
1249
1250 static int __devinit _snd_emu10k1_audigy_init_efx(emu10k1_t *emu)
1251 {
1252         int err, i, z, gpr, nctl;
1253         const int playback = 10;
1254         const int capture = playback + (SND_EMU10K1_PLAYBACK_CHANNELS * 2); /* we reserve 10 voices */
1255         const int stereo_mix = capture + 2;
1256         const int tmp = 0x88;
1257         u32 ptr;
1258         emu10k1_fx8010_code_t *icode;
1259         emu10k1_fx8010_control_gpr_t *controls, *ctl;
1260         mm_segment_t seg;
1261
1262         spin_lock_init(&emu->fx8010.irq_lock);
1263         INIT_LIST_HEAD(&emu->fx8010.gpr_ctl);
1264
1265         if ((icode = snd_kcalloc(sizeof(emu10k1_fx8010_code_t), GFP_KERNEL)) == NULL)
1266                 return -ENOMEM;
1267         if ((controls = snd_kcalloc(sizeof(emu10k1_fx8010_control_gpr_t) * SND_EMU10K1_GPR_CONTROLS, GFP_KERNEL)) == NULL) {
1268                 kfree(icode);
1269                 return -ENOMEM;
1270         }
1271
1272         /* clear free GPRs */
1273         for (i = 0; i < 256; i++)
1274                 set_bit(i, icode->gpr_valid);
1275
1276         strcpy(icode->name, "Audigy DSP code for ALSA");
1277         ptr = 0;
1278         nctl = 0;
1279         gpr = stereo_mix + 10;
1280
1281         /* stop FX processor */
1282         snd_emu10k1_ptr_write(emu, A_DBG, 0, (emu->fx8010.dbg = 0) | A_DBG_SINGLE_STEP);
1283
1284         /* PCM front Playback Volume (independent from stereo mix) */
1285         A_OP(icode, &ptr, iMAC0, A_GPR(playback), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LEFT_FRONT));
1286         A_OP(icode, &ptr, iMAC0, A_GPR(playback+1), A_C_00000000, A_GPR(gpr+1), A_FXBUS(FXBUS_PCM_RIGHT_FRONT));
1287         snd_emu10k1_init_stereo_control(&controls[nctl++], "PCM Front Playback Volume", gpr, 100);
1288         gpr += 2;
1289         
1290         /* PCM Surround Playback (independent from stereo mix) */
1291         A_OP(icode, &ptr, iMAC0, A_GPR(playback+2), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LEFT_REAR));
1292         A_OP(icode, &ptr, iMAC0, A_GPR(playback+3), A_C_00000000, A_GPR(gpr+1), A_FXBUS(FXBUS_PCM_RIGHT_REAR));
1293         snd_emu10k1_init_stereo_control(&controls[nctl++], "PCM Surround Playback Volume", gpr, 100);
1294         gpr += 2;
1295
1296         /* PCM Center Playback (independent from stereo mix) */
1297         A_OP(icode, &ptr, iMAC0, A_GPR(playback+4), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_CENTER));
1298         snd_emu10k1_init_mono_control(&controls[nctl++], "PCM Center Playback Volume", gpr, 100);
1299         gpr++;
1300
1301         /* PCM LFE Playback (independent from stereo mix) */
1302         A_OP(icode, &ptr, iMAC0, A_GPR(playback+5), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LFE));
1303         snd_emu10k1_init_mono_control(&controls[nctl++], "PCM LFE Playback Volume", gpr, 100);
1304         gpr++;
1305         
1306         /*
1307          * Stereo Mix
1308          */
1309         /* Wave (PCM) Playback Volume (will be renamed later) */
1310         A_OP(icode, &ptr, iMAC0, A_GPR(stereo_mix), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LEFT));
1311         A_OP(icode, &ptr, iMAC0, A_GPR(stereo_mix+1), A_C_00000000, A_GPR(gpr+1), A_FXBUS(FXBUS_PCM_RIGHT));
1312         snd_emu10k1_init_stereo_control(&controls[nctl++], "Wave Playback Volume", gpr, 100);
1313         gpr += 2;
1314
1315         /* Music Playback */
1316         A_OP(icode, &ptr, iMAC0, A_GPR(stereo_mix+0), A_GPR(stereo_mix+0), A_GPR(gpr), A_FXBUS(FXBUS_MIDI_LEFT));
1317         A_OP(icode, &ptr, iMAC0, A_GPR(stereo_mix+1), A_GPR(stereo_mix+1), A_GPR(gpr+1), A_FXBUS(FXBUS_MIDI_RIGHT));
1318         snd_emu10k1_init_stereo_control(&controls[nctl++], "Music Playback Volume", gpr, 100);
1319         gpr += 2;
1320
1321         /* Wave (PCM) Capture */
1322         A_OP(icode, &ptr, iMAC0, A_GPR(capture+0), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LEFT));
1323         A_OP(icode, &ptr, iMAC0, A_GPR(capture+1), A_C_00000000, A_GPR(gpr+1), A_FXBUS(FXBUS_PCM_RIGHT));
1324         snd_emu10k1_init_stereo_control(&controls[nctl++], "PCM Capture Volume", gpr, 0);
1325         gpr += 2;
1326
1327         /* Music Capture */
1328         A_OP(icode, &ptr, iMAC0, A_GPR(capture+0), A_GPR(capture+0), A_GPR(gpr), A_FXBUS(FXBUS_MIDI_LEFT));
1329         A_OP(icode, &ptr, iMAC0, A_GPR(capture+1), A_GPR(capture+1), A_GPR(gpr+1), A_FXBUS(FXBUS_MIDI_RIGHT));
1330         snd_emu10k1_init_stereo_control(&controls[nctl++], "Music Capture Volume", gpr, 0);
1331         gpr += 2;
1332
1333         /*
1334          * inputs
1335          */
1336 #define A_ADD_VOLUME_IN(var,vol,input) \
1337 A_OP(icode, &ptr, iMAC0, A_GPR(var), A_GPR(var), A_GPR(vol), A_EXTIN(input))
1338
1339         /* AC'97 Playback Volume - used only for mic (renamed later) */
1340         A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_AC97_L);
1341         A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_AC97_R);
1342         snd_emu10k1_init_stereo_control(&controls[nctl++], "AMic Playback Volume", gpr, 0);
1343         gpr += 2;
1344         /* AC'97 Capture Volume - used only for mic */
1345         A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_AC97_L);
1346         A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_AC97_R);
1347         snd_emu10k1_init_stereo_control(&controls[nctl++], "Mic Capture Volume", gpr, 0);
1348         gpr += 2;
1349
1350         /* mic capture buffer */        
1351         A_OP(icode, &ptr, iINTERP, A_EXTOUT(A_EXTOUT_MIC_CAP), A_EXTIN(A_EXTIN_AC97_L), 0xcd, A_EXTIN(A_EXTIN_AC97_R));
1352
1353         /* Audigy CD Playback Volume */
1354         A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_SPDIF_CD_L);
1355         A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_SPDIF_CD_R);
1356         snd_emu10k1_init_stereo_control(&controls[nctl++],
1357                                         emu->no_ac97 ? "CD Playback Volume" : "Audigy CD Playback Volume",
1358                                         gpr, 0);
1359         gpr += 2;
1360         /* Audigy CD Capture Volume */
1361         A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_SPDIF_CD_L);
1362         A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_SPDIF_CD_R);
1363         snd_emu10k1_init_stereo_control(&controls[nctl++],
1364                                         emu->no_ac97 ? "CD Capture Volume" : "Audigy CD Capture Volume",
1365                                         gpr, 0);
1366         gpr += 2;
1367
1368         /* Optical SPDIF Playback Volume */
1369         A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_OPT_SPDIF_L);
1370         A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_OPT_SPDIF_R);
1371         snd_emu10k1_init_stereo_control(&controls[nctl++], "IEC958 Optical Playback Volume", gpr, 0);
1372         gpr += 2;
1373         /* Optical SPDIF Capture Volume */
1374         A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_OPT_SPDIF_L);
1375         A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_OPT_SPDIF_R);
1376         snd_emu10k1_init_stereo_control(&controls[nctl++], "IEC958 Optical Capture Volume", gpr, 0);
1377         gpr += 2;
1378
1379         /* Line2 Playback Volume */
1380         A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_LINE2_L);
1381         A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_LINE2_R);
1382         snd_emu10k1_init_stereo_control(&controls[nctl++],
1383                                         emu->no_ac97 ? "Line Playback Volume" : "Line2 Playback Volume",
1384                                         gpr, 0);
1385         gpr += 2;
1386         /* Line2 Capture Volume */
1387         A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_LINE2_L);
1388         A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_LINE2_R);
1389         snd_emu10k1_init_stereo_control(&controls[nctl++],
1390                                         emu->no_ac97 ? "Line Capture Volume" : "Line2 Capture Volume",
1391                                         gpr, 0);
1392         gpr += 2;
1393         
1394         /* Philips ADC Playback Volume */
1395         A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_ADC_L);
1396         A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_ADC_R);
1397         snd_emu10k1_init_stereo_control(&controls[nctl++], "Analog Mix Playback Volume", gpr, 0);
1398         gpr += 2;
1399         /* Philips ADC Capture Volume */
1400         A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_ADC_L);
1401         A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_ADC_R);
1402         snd_emu10k1_init_stereo_control(&controls[nctl++], "Analog Mix Capture Volume", gpr, 0);
1403         gpr += 2;
1404
1405         /* Aux2 Playback Volume */
1406         A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_AUX2_L);
1407         A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_AUX2_R);
1408         snd_emu10k1_init_stereo_control(&controls[nctl++],
1409                                         emu->no_ac97 ? "Aux Playback Volume" : "Aux2 Playback Volume",
1410                                         gpr, 0);
1411         gpr += 2;
1412         /* Aux2 Capture Volume */
1413         A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_AUX2_L);
1414         A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_AUX2_R);
1415         snd_emu10k1_init_stereo_control(&controls[nctl++],
1416                                         emu->no_ac97 ? "Aux Capture Volume" : "Aux2 Capture Volume",
1417                                         gpr, 0);
1418         gpr += 2;
1419         
1420         /* Stereo Mix Front Playback Volume */
1421         A_OP(icode, &ptr, iMAC0, A_GPR(playback), A_GPR(playback), A_GPR(gpr), A_GPR(stereo_mix));
1422         A_OP(icode, &ptr, iMAC0, A_GPR(playback+1), A_GPR(playback+1), A_GPR(gpr+1), A_GPR(stereo_mix+1));
1423         snd_emu10k1_init_stereo_control(&controls[nctl++], "Front Playback Volume", gpr, 100);
1424         gpr += 2;
1425         
1426         /* Stereo Mix Surround Playback */
1427         A_OP(icode, &ptr, iMAC0, A_GPR(playback+2), A_GPR(playback+2), A_GPR(gpr), A_GPR(stereo_mix));
1428         A_OP(icode, &ptr, iMAC0, A_GPR(playback+3), A_GPR(playback+3), A_GPR(gpr+1), A_GPR(stereo_mix+1));
1429         snd_emu10k1_init_stereo_control(&controls[nctl++], "Surround Playback Volume", gpr, 0);
1430         gpr += 2;
1431
1432         /* Stereo Mix Center Playback */
1433         /* Center = sub = Left/2 + Right/2 */
1434         A_OP(icode, &ptr, iINTERP, A_GPR(tmp), A_GPR(stereo_mix), 0xcd, A_GPR(stereo_mix+1));
1435         A_OP(icode, &ptr, iMAC0, A_GPR(playback+4), A_GPR(playback+4), A_GPR(gpr), A_GPR(tmp));
1436         snd_emu10k1_init_mono_control(&controls[nctl++], "Center Playback Volume", gpr, 0);
1437         gpr++;
1438
1439         /* Stereo Mix LFE Playback */
1440         A_OP(icode, &ptr, iMAC0, A_GPR(playback+5), A_GPR(playback+5), A_GPR(gpr), A_GPR(tmp));
1441         snd_emu10k1_init_mono_control(&controls[nctl++], "LFE Playback Volume", gpr, 0);
1442         gpr++;
1443
1444         /*
1445          * outputs
1446          */
1447 #define A_PUT_OUTPUT(out,src) A_OP(icode, &ptr, iACC3, A_EXTOUT(out), A_C_00000000, A_C_00000000, A_GPR(src))
1448 #define A_PUT_STEREO_OUTPUT(out1,out2,src) \
1449         {A_PUT_OUTPUT(out1,src); A_PUT_OUTPUT(out2,src+1);}
1450
1451 #define _A_SWITCH(icode, ptr, dst, src, sw) \
1452         A_OP((icode), ptr, iMACINT0, dst, A_C_00000000, src, sw);
1453 #define A_SWITCH(icode, ptr, dst, src, sw) \
1454                 _A_SWITCH(icode, ptr, A_GPR(dst), A_GPR(src), A_GPR(sw))
1455 #define _A_SWITCH_NEG(icode, ptr, dst, src) \
1456         A_OP((icode), ptr, iANDXOR, dst, src, A_C_00000001, A_C_00000001);
1457 #define A_SWITCH_NEG(icode, ptr, dst, src) \
1458                 _A_SWITCH_NEG(icode, ptr, A_GPR(dst), A_GPR(src))
1459
1460
1461         /*
1462          *  Process tone control
1463          */
1464         A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 0), A_GPR(playback + 0), A_C_00000000, A_C_00000000); /* left */
1465         A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 1), A_GPR(playback + 1), A_C_00000000, A_C_00000000); /* right */
1466         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 */
1467         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 */
1468         A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 4), A_GPR(playback + 4), A_C_00000000, A_C_00000000); /* center */
1469         A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 5), A_GPR(playback + 5), A_C_00000000, A_C_00000000); /* LFE */
1470
1471         ctl = &controls[nctl + 0];
1472         ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1473         strcpy(ctl->id.name, "Tone Control - Bass");
1474         ctl->vcount = 2;
1475         ctl->count = 10;
1476         ctl->min = 0;
1477         ctl->max = 40;
1478         ctl->value[0] = ctl->value[1] = 20;
1479         ctl->translation = EMU10K1_GPR_TRANSLATION_BASS;
1480         ctl = &controls[nctl + 1];
1481         ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1482         strcpy(ctl->id.name, "Tone Control - Treble");
1483         ctl->vcount = 2;
1484         ctl->count = 10;
1485         ctl->min = 0;
1486         ctl->max = 40;
1487         ctl->value[0] = ctl->value[1] = 20;
1488         ctl->translation = EMU10K1_GPR_TRANSLATION_TREBLE;
1489
1490 #define BASS_GPR        0x8c
1491 #define TREBLE_GPR      0x96
1492
1493         for (z = 0; z < 5; z++) {
1494                 int j;
1495                 for (j = 0; j < 2; j++) {
1496                         controls[nctl + 0].gpr[z * 2 + j] = BASS_GPR + z * 2 + j;
1497                         controls[nctl + 1].gpr[z * 2 + j] = TREBLE_GPR + z * 2 + j;
1498                 }
1499         }
1500         for (z = 0; z < 3; z++) {               /* front/rear/center-lfe */
1501                 int j, k, l, d;
1502                 for (j = 0; j < 2; j++) {       /* left/right */
1503                         k = 0xb0 + (z * 8) + (j * 4);
1504                         l = 0xe0 + (z * 8) + (j * 4);
1505                         d = playback + SND_EMU10K1_PLAYBACK_CHANNELS + z * 2 + j;
1506
1507                         A_OP(icode, &ptr, iMAC0, A_C_00000000, A_C_00000000, A_GPR(d), A_GPR(BASS_GPR + 0 + j));
1508                         A_OP(icode, &ptr, iMACMV, A_GPR(k+1), A_GPR(k), A_GPR(k+1), A_GPR(BASS_GPR + 4 + j));
1509                         A_OP(icode, &ptr, iMACMV, A_GPR(k), A_GPR(d), A_GPR(k), A_GPR(BASS_GPR + 2 + j));
1510                         A_OP(icode, &ptr, iMACMV, A_GPR(k+3), A_GPR(k+2), A_GPR(k+3), A_GPR(BASS_GPR + 8 + j));
1511                         A_OP(icode, &ptr, iMAC0, A_GPR(k+2), A_GPR_ACCU, A_GPR(k+2), A_GPR(BASS_GPR + 6 + j));
1512                         A_OP(icode, &ptr, iACC3, A_GPR(k+2), A_GPR(k+2), A_GPR(k+2), A_C_00000000);
1513
1514                         A_OP(icode, &ptr, iMAC0, A_C_00000000, A_C_00000000, A_GPR(k+2), A_GPR(TREBLE_GPR + 0 + j));
1515                         A_OP(icode, &ptr, iMACMV, A_GPR(l+1), A_GPR(l), A_GPR(l+1), A_GPR(TREBLE_GPR + 4 + j));
1516                         A_OP(icode, &ptr, iMACMV, A_GPR(l), A_GPR(k+2), A_GPR(l), A_GPR(TREBLE_GPR + 2 + j));
1517                         A_OP(icode, &ptr, iMACMV, A_GPR(l+3), A_GPR(l+2), A_GPR(l+3), A_GPR(TREBLE_GPR + 8 + j));
1518                         A_OP(icode, &ptr, iMAC0, A_GPR(l+2), A_GPR_ACCU, A_GPR(l+2), A_GPR(TREBLE_GPR + 6 + j));
1519                         A_OP(icode, &ptr, iMACINT0, A_GPR(l+2), A_C_00000000, A_GPR(l+2), A_C_00000010);
1520
1521                         A_OP(icode, &ptr, iACC3, A_GPR(d), A_GPR(l+2), A_C_00000000, A_C_00000000);
1522
1523                         if (z == 2)     /* center */
1524                                 break;
1525                 }
1526         }
1527         nctl += 2;
1528
1529 #undef BASS_GPR
1530 #undef TREBLE_GPR
1531
1532         for (z = 0; z < 6; z++) {
1533                 A_SWITCH(icode, &ptr, tmp + 0, playback + SND_EMU10K1_PLAYBACK_CHANNELS + z, gpr + 0);
1534                 A_SWITCH_NEG(icode, &ptr, tmp + 1, gpr + 0);
1535                 A_SWITCH(icode, &ptr, tmp + 1, playback + z, tmp + 1);
1536                 A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + z), A_GPR(tmp + 0), A_GPR(tmp + 1), A_C_00000000);
1537         }
1538         snd_emu10k1_init_stereo_onoff_control(controls + nctl++, "Tone Control - Switch", gpr, 0);
1539         gpr += 2;
1540
1541         /* Master volume (will be renamed later) */
1542         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));
1543         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));
1544         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));
1545         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));
1546         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));
1547         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));
1548         snd_emu10k1_init_stereo_control(&controls[nctl++], "Wave Master Playback Volume", gpr, 0);
1549         gpr += 2;
1550
1551         /* analog speakers */
1552         A_PUT_STEREO_OUTPUT(A_EXTOUT_AFRONT_L, A_EXTOUT_AFRONT_R, playback + SND_EMU10K1_PLAYBACK_CHANNELS);
1553         A_PUT_STEREO_OUTPUT(A_EXTOUT_AREAR_L, A_EXTOUT_AREAR_R, playback+2 + SND_EMU10K1_PLAYBACK_CHANNELS);
1554         A_PUT_OUTPUT(A_EXTOUT_ACENTER, playback+4 + SND_EMU10K1_PLAYBACK_CHANNELS);
1555         A_PUT_OUTPUT(A_EXTOUT_ALFE, playback+5 + SND_EMU10K1_PLAYBACK_CHANNELS);
1556
1557         /* headphone */
1558         A_PUT_STEREO_OUTPUT(A_EXTOUT_HEADPHONE_L, A_EXTOUT_HEADPHONE_R, playback + SND_EMU10K1_PLAYBACK_CHANNELS);
1559
1560         /* digital outputs */
1561         /* A_PUT_STEREO_OUTPUT(A_EXTOUT_FRONT_L, A_EXTOUT_FRONT_R, playback + SND_EMU10K1_PLAYBACK_CHANNELS); */
1562
1563         /* IEC958 Optical Raw Playback Switch */ 
1564         icode->gpr_map[gpr++] = 0x1008;
1565         icode->gpr_map[gpr++] = 0xffff0000;
1566         for (z = 0; z < 2; z++) {
1567                 A_OP(icode, &ptr, iMAC0, A_GPR(tmp + 2), A_FXBUS(FXBUS_PT_LEFT + z), A_C_00000000, A_C_00000000);
1568                 A_OP(icode, &ptr, iSKIP, A_GPR_COND, A_GPR_COND, A_GPR(gpr - 2), A_C_00000001);
1569                 A_OP(icode, &ptr, iACC3, A_GPR(tmp + 2), A_C_00000000, A_C_00010000, A_GPR(tmp + 2));
1570                 A_OP(icode, &ptr, iANDXOR, A_GPR(tmp + 2), A_GPR(tmp + 2), A_GPR(gpr - 1), A_C_00000000);
1571                 A_SWITCH(icode, &ptr, tmp + 0, tmp + 2, gpr + z);
1572                 A_SWITCH_NEG(icode, &ptr, tmp + 1, gpr + z);
1573                 A_SWITCH(icode, &ptr, tmp + 1, playback + SND_EMU10K1_PLAYBACK_CHANNELS + z, tmp + 1);
1574                 A_OP(icode, &ptr, iACC3, A_EXTOUT(A_EXTOUT_FRONT_L + z), A_GPR(tmp + 0), A_GPR(tmp + 1), A_C_00000000);
1575         }
1576         snd_emu10k1_init_stereo_onoff_control(controls + nctl++, "IEC958 Optical Raw Playback Switch", gpr, 0);
1577         gpr += 2;
1578         
1579         A_PUT_STEREO_OUTPUT(A_EXTOUT_REAR_L, A_EXTOUT_REAR_R, playback+2 + SND_EMU10K1_PLAYBACK_CHANNELS);
1580         A_PUT_OUTPUT(A_EXTOUT_CENTER, playback+4 + SND_EMU10K1_PLAYBACK_CHANNELS);
1581         A_PUT_OUTPUT(A_EXTOUT_LFE, playback+5 + SND_EMU10K1_PLAYBACK_CHANNELS);
1582
1583         /* ADC buffer */
1584         A_PUT_OUTPUT(A_EXTOUT_ADC_CAP_L, capture);
1585         A_PUT_OUTPUT(A_EXTOUT_ADC_CAP_R, capture+1);
1586
1587         /*
1588          * ok, set up done..
1589          */
1590
1591         if (gpr > tmp) {
1592                 snd_BUG();
1593                 err = -EIO;
1594                 goto __err;
1595         }
1596         /* clear remaining instruction memory */
1597         while (ptr < 0x200)
1598                 A_OP(icode, &ptr, 0x0f, 0xc0, 0xc0, 0xcf, 0xc0);
1599
1600         seg = snd_enter_user();
1601         icode->gpr_add_control_count = nctl;
1602         icode->gpr_add_controls = controls;
1603         err = snd_emu10k1_icode_poke(emu, icode);
1604         snd_leave_user(seg);
1605
1606  __err:
1607         kfree(controls);
1608         kfree(icode);
1609         return err;
1610 }
1611
1612
1613 /*
1614  * initial DSP configuration for Emu10k1
1615  */
1616
1617 /* when volume = max, then copy only to avoid volume modification */
1618 /* with iMAC0 (negative values) */
1619 static void __devinit _volume(emu10k1_fx8010_code_t *icode, u32 *ptr, u32 dst, u32 src, u32 vol)
1620 {
1621         OP(icode, ptr, iMAC0, dst, C_00000000, src, vol);
1622         OP(icode, ptr, iANDXOR, C_00000000, vol, C_ffffffff, C_7fffffff);
1623         OP(icode, ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, C_00000001);
1624         OP(icode, ptr, iACC3, dst, src, C_00000000, C_00000000);
1625 }
1626 static void __devinit _volume_add(emu10k1_fx8010_code_t *icode, u32 *ptr, u32 dst, u32 src, u32 vol)
1627 {
1628         OP(icode, ptr, iANDXOR, C_00000000, vol, C_ffffffff, C_7fffffff);
1629         OP(icode, ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, C_00000002);
1630         OP(icode, ptr, iMACINT0, dst, dst, src, C_00000001);
1631         OP(icode, ptr, iSKIP, C_00000000, C_7fffffff, C_7fffffff, C_00000001);
1632         OP(icode, ptr, iMAC0, dst, dst, src, vol);
1633 }
1634 static void __devinit _volume_out(emu10k1_fx8010_code_t *icode, u32 *ptr, u32 dst, u32 src, u32 vol)
1635 {
1636         OP(icode, ptr, iANDXOR, C_00000000, vol, C_ffffffff, C_7fffffff);
1637         OP(icode, ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, C_00000002);
1638         OP(icode, ptr, iACC3, dst, src, C_00000000, C_00000000);
1639         OP(icode, ptr, iSKIP, C_00000000, C_7fffffff, C_7fffffff, C_00000001);
1640         OP(icode, ptr, iMAC0, dst, C_00000000, src, vol);
1641 }
1642
1643 #define VOLUME(icode, ptr, dst, src, vol) \
1644                 _volume(icode, ptr, GPR(dst), GPR(src), GPR(vol))
1645 #define VOLUME_IN(icode, ptr, dst, src, vol) \
1646                 _volume(icode, ptr, GPR(dst), EXTIN(src), GPR(vol))
1647 #define VOLUME_ADD(icode, ptr, dst, src, vol) \
1648                 _volume_add(icode, ptr, GPR(dst), GPR(src), GPR(vol))
1649 #define VOLUME_ADDIN(icode, ptr, dst, src, vol) \
1650                 _volume_add(icode, ptr, GPR(dst), EXTIN(src), GPR(vol))
1651 #define VOLUME_OUT(icode, ptr, dst, src, vol) \
1652                 _volume_out(icode, ptr, EXTOUT(dst), GPR(src), GPR(vol))
1653 #define _SWITCH(icode, ptr, dst, src, sw) \
1654         OP((icode), ptr, iMACINT0, dst, C_00000000, src, sw);
1655 #define SWITCH(icode, ptr, dst, src, sw) \
1656                 _SWITCH(icode, ptr, GPR(dst), GPR(src), GPR(sw))
1657 #define SWITCH_IN(icode, ptr, dst, src, sw) \
1658                 _SWITCH(icode, ptr, GPR(dst), EXTIN(src), GPR(sw))
1659 #define _SWITCH_NEG(icode, ptr, dst, src) \
1660         OP((icode), ptr, iANDXOR, dst, src, C_00000001, C_00000001);
1661 #define SWITCH_NEG(icode, ptr, dst, src) \
1662                 _SWITCH_NEG(icode, ptr, GPR(dst), GPR(src))
1663
1664
1665 static int __devinit _snd_emu10k1_init_efx(emu10k1_t *emu)
1666 {
1667         int err, i, z, gpr, tmp, playback, capture;
1668         u32 ptr;
1669         emu10k1_fx8010_code_t *icode;
1670         emu10k1_fx8010_pcm_t *ipcm;
1671         emu10k1_fx8010_control_gpr_t *controls, *ctl;
1672         mm_segment_t seg;
1673
1674         spin_lock_init(&emu->fx8010.irq_lock);
1675         INIT_LIST_HEAD(&emu->fx8010.gpr_ctl);
1676
1677         if ((icode = snd_kcalloc(sizeof(emu10k1_fx8010_code_t), GFP_KERNEL)) == NULL)
1678                 return -ENOMEM;
1679         if ((controls = snd_kcalloc(sizeof(emu10k1_fx8010_control_gpr_t) * SND_EMU10K1_GPR_CONTROLS, GFP_KERNEL)) == NULL) {
1680                 kfree(icode);
1681                 return -ENOMEM;
1682         }
1683         if ((ipcm = snd_kcalloc(sizeof(emu10k1_fx8010_pcm_t), GFP_KERNEL)) == NULL) {
1684                 kfree(controls);
1685                 kfree(icode);
1686                 return -ENOMEM;
1687         }
1688         
1689         /* clear free GPRs */
1690         for (i = 0; i < 256; i++)
1691                 set_bit(i, icode->gpr_valid);
1692
1693         /* clear TRAM data & address lines */
1694         for (i = 0; i < 160; i++)
1695                 set_bit(i, icode->tram_valid);
1696
1697         strcpy(icode->name, "SB Live! FX8010 code for ALSA v1.2 by Jaroslav Kysela");
1698         ptr = 0; i = 0;
1699         /* we have 10 inputs */
1700         playback = SND_EMU10K1_INPUTS;
1701         /* we have 6 playback channels and tone control doubles */
1702         capture = playback + (SND_EMU10K1_PLAYBACK_CHANNELS * 2);
1703         gpr = capture + SND_EMU10K1_CAPTURE_CHANNELS;
1704         tmp = 0x88;     /* we need 4 temporary GPR */
1705         /* from 0x8c to 0xff is the area for tone control */
1706
1707         /* stop FX processor */
1708         snd_emu10k1_ptr_write(emu, DBG, 0, (emu->fx8010.dbg = 0) | EMU10K1_DBG_SINGLE_STEP);
1709
1710         /*
1711          *  Process FX Buses
1712          */
1713         OP(icode, &ptr, iMACINT0, GPR(0), C_00000000, FXBUS(FXBUS_PCM_LEFT), C_00000004);
1714         OP(icode, &ptr, iMACINT0, GPR(1), C_00000000, FXBUS(FXBUS_PCM_RIGHT), C_00000004);
1715         OP(icode, &ptr, iMACINT0, GPR(2), C_00000000, FXBUS(FXBUS_MIDI_LEFT), C_00000004);
1716         OP(icode, &ptr, iMACINT0, GPR(3), C_00000000, FXBUS(FXBUS_MIDI_RIGHT), C_00000004);
1717         OP(icode, &ptr, iMACINT0, GPR(4), C_00000000, FXBUS(FXBUS_PCM_LEFT_REAR), C_00000004);
1718         OP(icode, &ptr, iMACINT0, GPR(5), C_00000000, FXBUS(FXBUS_PCM_RIGHT_REAR), C_00000004);
1719         OP(icode, &ptr, iMACINT0, GPR(6), C_00000000, FXBUS(FXBUS_PCM_CENTER), C_00000004);
1720         OP(icode, &ptr, iMACINT0, GPR(7), C_00000000, FXBUS(FXBUS_PCM_LFE), C_00000004);
1721         OP(icode, &ptr, iMACINT0, GPR(8), C_00000000, C_00000000, C_00000000);  /* S/PDIF left */
1722         OP(icode, &ptr, iMACINT0, GPR(9), C_00000000, C_00000000, C_00000000);  /* S/PDIF right */
1723
1724         /* Raw S/PDIF PCM */
1725         ipcm->substream = 0;
1726         ipcm->channels = 2;
1727         ipcm->tram_start = 0;
1728         ipcm->buffer_size = (64 * 1024) / 2;
1729         ipcm->gpr_size = gpr++;
1730         ipcm->gpr_ptr = gpr++;
1731         ipcm->gpr_count = gpr++;
1732         ipcm->gpr_tmpcount = gpr++;
1733         ipcm->gpr_trigger = gpr++;
1734         ipcm->gpr_running = gpr++;
1735         ipcm->etram[0] = 0;
1736         ipcm->etram[1] = 1;
1737
1738         icode->gpr_map[gpr + 0] = 0xfffff000;
1739         icode->gpr_map[gpr + 1] = 0xffff0000;
1740         icode->gpr_map[gpr + 2] = 0x70000000;
1741         icode->gpr_map[gpr + 3] = 0x00000007;
1742         icode->gpr_map[gpr + 4] = 0x001f << 11;
1743         icode->gpr_map[gpr + 5] = 0x001c << 11;
1744         icode->gpr_map[gpr + 6] = (0x22  - 0x01) - 1;   /* skip at 01 to 22 */
1745         icode->gpr_map[gpr + 7] = (0x22  - 0x06) - 1;   /* skip at 06 to 22 */
1746         icode->gpr_map[gpr + 8] = 0x2000000 + (2<<11);
1747         icode->gpr_map[gpr + 9] = 0x4000000 + (2<<11);
1748         icode->gpr_map[gpr + 10] = 1<<11;
1749         icode->gpr_map[gpr + 11] = (0x24 - 0x0a) - 1;   /* skip at 0a to 24 */
1750         icode->gpr_map[gpr + 12] = 0;
1751
1752         /* if the trigger flag is not set, skip */
1753         /* 00: */ OP(icode, &ptr, iMAC0, C_00000000, GPR(ipcm->gpr_trigger), C_00000000, C_00000000);
1754         /* 01: */ OP(icode, &ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_ZERO, GPR(gpr + 6));
1755         /* if the running flag is set, we're running */
1756         /* 02: */ OP(icode, &ptr, iMAC0, C_00000000, GPR(ipcm->gpr_running), C_00000000, C_00000000);
1757         /* 03: */ OP(icode, &ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, C_00000004);
1758         /* wait until ((GPR_DBAC>>11) & 0x1f) == 0x1c) */
1759         /* 04: */ OP(icode, &ptr, iANDXOR, GPR(tmp + 0), GPR_DBAC, GPR(gpr + 4), C_00000000);
1760         /* 05: */ OP(icode, &ptr, iMACINT0, C_00000000, GPR(tmp + 0), C_ffffffff, GPR(gpr + 5));
1761         /* 06: */ OP(icode, &ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, GPR(gpr + 7));
1762         /* 07: */ OP(icode, &ptr, iACC3, GPR(gpr + 12), C_00000010, C_00000001, C_00000000);
1763
1764         /* 08: */ OP(icode, &ptr, iANDXOR, GPR(ipcm->gpr_running), GPR(ipcm->gpr_running), C_00000000, C_00000001);
1765         /* 09: */ OP(icode, &ptr, iACC3, GPR(gpr + 12), GPR(gpr + 12), C_ffffffff, C_00000000);
1766         /* 0a: */ OP(icode, &ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, GPR(gpr + 11));
1767         /* 0b: */ OP(icode, &ptr, iACC3, GPR(gpr + 12), C_00000001, C_00000000, C_00000000);
1768
1769         /* 0c: */ OP(icode, &ptr, iANDXOR, GPR(tmp + 0), ETRAM_DATA(ipcm->etram[0]), GPR(gpr + 0), C_00000000);
1770         /* 0d: */ OP(icode, &ptr, iLOG, GPR(tmp + 0), GPR(tmp + 0), GPR(gpr + 3), C_00000000);
1771         /* 0e: */ OP(icode, &ptr, iANDXOR, GPR(8), GPR(tmp + 0), GPR(gpr + 1), GPR(gpr + 2));
1772         /* 0f: */ OP(icode, &ptr, iSKIP, C_00000000, GPR_COND, CC_REG_MINUS, C_00000001);
1773         /* 10: */ OP(icode, &ptr, iANDXOR, GPR(8), GPR(8), GPR(gpr + 1), GPR(gpr + 2));
1774
1775         /* 11: */ OP(icode, &ptr, iANDXOR, GPR(tmp + 0), ETRAM_DATA(ipcm->etram[1]), GPR(gpr + 0), C_00000000);
1776         /* 12: */ OP(icode, &ptr, iLOG, GPR(tmp + 0), GPR(tmp + 0), GPR(gpr + 3), C_00000000);
1777         /* 13: */ OP(icode, &ptr, iANDXOR, GPR(9), GPR(tmp + 0), GPR(gpr + 1), GPR(gpr + 2));
1778         /* 14: */ OP(icode, &ptr, iSKIP, C_00000000, GPR_COND, CC_REG_MINUS, C_00000001);
1779         /* 15: */ OP(icode, &ptr, iANDXOR, GPR(9), GPR(9), GPR(gpr + 1), GPR(gpr + 2));
1780
1781         /* 16: */ OP(icode, &ptr, iACC3, GPR(tmp + 0), GPR(ipcm->gpr_ptr), C_00000001, C_00000000);
1782         /* 17: */ OP(icode, &ptr, iMACINT0, C_00000000, GPR(tmp + 0), C_ffffffff, GPR(ipcm->gpr_size));
1783         /* 18: */ OP(icode, &ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_MINUS, C_00000001);
1784         /* 19: */ OP(icode, &ptr, iACC3, GPR(tmp + 0), C_00000000, C_00000000, C_00000000);
1785         /* 1a: */ OP(icode, &ptr, iACC3, GPR(ipcm->gpr_ptr), GPR(tmp + 0), C_00000000, C_00000000);
1786         
1787         /* 1b: */ OP(icode, &ptr, iACC3, GPR(ipcm->gpr_tmpcount), GPR(ipcm->gpr_tmpcount), C_ffffffff, C_00000000);
1788         /* 1c: */ OP(icode, &ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, C_00000002);
1789         /* 1d: */ OP(icode, &ptr, iACC3, GPR(ipcm->gpr_tmpcount), GPR(ipcm->gpr_count), C_00000000, C_00000000);
1790         /* 1e: */ OP(icode, &ptr, iACC3, GPR_IRQ, C_80000000, C_00000000, C_00000000);
1791         /* 1f: */ OP(icode, &ptr, iANDXOR, GPR(ipcm->gpr_running), GPR(ipcm->gpr_running), C_00000001, C_00010000);
1792
1793         /* 20: */ OP(icode, &ptr, iANDXOR, GPR(ipcm->gpr_running), GPR(ipcm->gpr_running), C_00010000, C_00000001);
1794         /* 21: */ OP(icode, &ptr, iSKIP, C_00000000, C_7fffffff, C_7fffffff, C_00000002);
1795
1796         /* 22: */ OP(icode, &ptr, iMACINT1, ETRAM_ADDR(ipcm->etram[0]), GPR(gpr + 8), GPR_DBAC, C_ffffffff);
1797         /* 23: */ OP(icode, &ptr, iMACINT1, ETRAM_ADDR(ipcm->etram[1]), GPR(gpr + 9), GPR_DBAC, C_ffffffff);
1798
1799         /* 24: */
1800         gpr += 13;
1801
1802         /* Wave Playback Volume */
1803         for (z = 0; z < 2; z++)
1804                 VOLUME(icode, &ptr, playback + z, z, gpr + z);
1805         snd_emu10k1_init_stereo_control(controls + i++, "Wave Playback Volume", gpr, 100);
1806         gpr += 2;
1807
1808         /* Wave Surround Playback Volume */
1809         for (z = 0; z < 2; z++)
1810                 VOLUME(icode, &ptr, playback + 2 + z, z, gpr + z);
1811         snd_emu10k1_init_stereo_control(controls + i++, "Wave Surround Playback Volume", gpr, 0);
1812         gpr += 2;
1813         
1814         /* Wave Center/LFE Playback Volume */
1815         OP(icode, &ptr, iACC3, GPR(tmp + 0), FXBUS(FXBUS_PCM_LEFT), FXBUS(FXBUS_PCM_RIGHT), C_00000000);
1816         OP(icode, &ptr, iMACINT0, GPR(tmp + 0), C_00000000, GPR(tmp + 0), C_00000002);
1817         VOLUME(icode, &ptr, playback + 4, tmp + 0, gpr);
1818         snd_emu10k1_init_mono_control(controls + i++, "Wave Center Playback Volume", gpr++, 0);
1819         VOLUME(icode, &ptr, playback + 5, tmp + 0, gpr);
1820         snd_emu10k1_init_mono_control(controls + i++, "Wave LFE Playback Volume", gpr++, 0);
1821
1822         /* Wave Capture Volume + Switch */
1823         for (z = 0; z < 2; z++) {
1824                 SWITCH(icode, &ptr, tmp + 0, z, gpr + 2 + z);
1825                 VOLUME(icode, &ptr, capture + z, tmp + 0, gpr + z);
1826         }
1827         snd_emu10k1_init_stereo_control(controls + i++, "Wave Capture Volume", gpr, 0);
1828         snd_emu10k1_init_stereo_onoff_control(controls + i++, "Wave Capture Switch", gpr + 2, 0);
1829         gpr += 4;
1830
1831         /* Music Playback Volume */
1832         for (z = 0; z < 2; z++)
1833                 VOLUME_ADD(icode, &ptr, playback + z, 2 + z, gpr + z);
1834         snd_emu10k1_init_stereo_control(controls + i++, "Music Playback Volume", gpr, 100);
1835         gpr += 2;
1836
1837         /* Music Capture Volume + Switch */
1838         for (z = 0; z < 2; z++) {
1839                 SWITCH(icode, &ptr, tmp + 0, 2 + z, gpr + 2 + z);
1840                 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
1841         }
1842         snd_emu10k1_init_stereo_control(controls + i++, "Music Capture Volume", gpr, 0);
1843         snd_emu10k1_init_stereo_onoff_control(controls + i++, "Music Capture Switch", gpr + 2, 0);
1844         gpr += 4;
1845
1846         /* Surround Digital Playback Volume (renamed later without Digital) */
1847         for (z = 0; z < 2; z++)
1848                 VOLUME_ADD(icode, &ptr, playback + 2 + z, 4 + z, gpr + z);
1849         snd_emu10k1_init_stereo_control(controls + i++, "Surround Digital Playback Volume", gpr, 100);
1850         gpr += 2;
1851
1852         /* Surround Capture Volume + Switch */
1853         for (z = 0; z < 2; z++) {
1854                 SWITCH(icode, &ptr, tmp + 0, 4 + z, gpr + 2 + z);
1855                 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
1856         }
1857         snd_emu10k1_init_stereo_control(controls + i++, "Surround Capture Volume", gpr, 0);
1858         snd_emu10k1_init_stereo_onoff_control(controls + i++, "Surround Capture Switch", gpr + 2, 0);
1859         gpr += 4;
1860
1861         /* Center Playback Volume (renamed later without Digital) */
1862         VOLUME_ADD(icode, &ptr, playback + 4, 6, gpr);
1863         snd_emu10k1_init_mono_control(controls + i++, "Center Digital Playback Volume", gpr++, 100);
1864
1865         /* LFE Playback Volume + Switch (renamed later without Digital) */
1866         VOLUME_ADD(icode, &ptr, playback + 5, 7, gpr);
1867         snd_emu10k1_init_mono_control(controls + i++, "LFE Digital Playback Volume", gpr++, 100);
1868
1869         /*
1870          *  Process inputs
1871          */
1872
1873         if (emu->fx8010.extin_mask & ((1<<EXTIN_AC97_L)|(1<<EXTIN_AC97_R))) {
1874                 /* AC'97 Playback Volume */
1875                 VOLUME_ADDIN(icode, &ptr, playback + 0, EXTIN_AC97_L, gpr); gpr++;
1876                 VOLUME_ADDIN(icode, &ptr, playback + 1, EXTIN_AC97_R, gpr); gpr++;
1877                 snd_emu10k1_init_stereo_control(controls + i++, "AC97 Playback Volume", gpr-2, 0);
1878                 /* AC'97 Capture Volume */
1879                 VOLUME_ADDIN(icode, &ptr, capture + 0, EXTIN_AC97_L, gpr); gpr++;
1880                 VOLUME_ADDIN(icode, &ptr, capture + 1, EXTIN_AC97_R, gpr); gpr++;
1881                 snd_emu10k1_init_stereo_control(controls + i++, "AC97 Capture Volume", gpr-2, 100);
1882         }
1883         
1884         if (emu->fx8010.extin_mask & ((1<<EXTIN_SPDIF_CD_L)|(1<<EXTIN_SPDIF_CD_R))) {
1885                 /* IEC958 TTL Playback Volume */
1886                 for (z = 0; z < 2; z++)
1887                         VOLUME_ADDIN(icode, &ptr, playback + z, EXTIN_SPDIF_CD_L + z, gpr + z);
1888                 snd_emu10k1_init_stereo_control(controls + i++, "IEC958 TTL Playback Volume", gpr, 0);
1889                 gpr += 2;
1890         
1891                 /* IEC958 TTL Capture Volume + Switch */
1892                 for (z = 0; z < 2; z++) {
1893                         SWITCH_IN(icode, &ptr, tmp + 0, EXTIN_SPDIF_CD_L + z, gpr + 2 + z);
1894                         VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
1895                 }
1896                 snd_emu10k1_init_stereo_control(controls + i++, "IEC958 TTL Capture Volume", gpr, 0);
1897                 snd_emu10k1_init_stereo_onoff_control(controls + i++, "IEC958 TTL Capture Switch", gpr + 2, 0);
1898                 gpr += 4;
1899         }
1900         
1901         if (emu->fx8010.extin_mask & ((1<<EXTIN_ZOOM_L)|(1<<EXTIN_ZOOM_R))) {
1902                 /* Zoom Video Playback Volume */
1903                 for (z = 0; z < 2; z++)
1904                         VOLUME_ADDIN(icode, &ptr, playback + z, EXTIN_ZOOM_L + z, gpr + z);
1905                 snd_emu10k1_init_stereo_control(controls + i++, "Zoom Video Playback Volume", gpr, 0);
1906                 gpr += 2;
1907         
1908                 /* Zoom Video Capture Volume + Switch */
1909                 for (z = 0; z < 2; z++) {
1910                         SWITCH_IN(icode, &ptr, tmp + 0, EXTIN_ZOOM_L + z, gpr + 2 + z);
1911                         VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
1912                 }
1913                 snd_emu10k1_init_stereo_control(controls + i++, "Zoom Video Capture Volume", gpr, 0);
1914                 snd_emu10k1_init_stereo_onoff_control(controls + i++, "Zoom Video Capture Switch", gpr + 2, 0);
1915                 gpr += 4;
1916         }
1917         
1918         if (emu->fx8010.extin_mask & ((1<<EXTIN_TOSLINK_L)|(1<<EXTIN_TOSLINK_R))) {
1919                 /* IEC958 Optical Playback Volume */
1920                 for (z = 0; z < 2; z++)
1921                         VOLUME_ADDIN(icode, &ptr, playback + z, EXTIN_TOSLINK_L + z, gpr + z);
1922                 snd_emu10k1_init_stereo_control(controls + i++, "IEC958 LiveDrive Playback Volume", gpr, 0);
1923                 gpr += 2;
1924         
1925                 /* IEC958 Optical Capture Volume */
1926                 for (z = 0; z < 2; z++) {
1927                         SWITCH_IN(icode, &ptr, tmp + 0, EXTIN_TOSLINK_L + z, gpr + 2 + z);
1928                         VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
1929                 }
1930                 snd_emu10k1_init_stereo_control(controls + i++, "IEC958 LiveDrive Capture Volume", gpr, 0);
1931                 snd_emu10k1_init_stereo_onoff_control(controls + i++, "IEC958 LiveDrive Capture Switch", gpr + 2, 0);
1932                 gpr += 4;
1933         }
1934         
1935         if (emu->fx8010.extin_mask & ((1<<EXTIN_LINE1_L)|(1<<EXTIN_LINE1_R))) {
1936                 /* Line LiveDrive Playback Volume */
1937                 for (z = 0; z < 2; z++)
1938                         VOLUME_ADDIN(icode, &ptr, playback + z, EXTIN_LINE1_L + z, gpr + z);
1939                 snd_emu10k1_init_stereo_control(controls + i++, "Line LiveDrive Playback Volume", gpr, 0);
1940                 gpr += 2;
1941         
1942                 /* Line LiveDrive Capture Volume + Switch */
1943                 for (z = 0; z < 2; z++) {
1944                         SWITCH_IN(icode, &ptr, tmp + 0, EXTIN_LINE1_L + z, gpr + 2 + z);
1945                         VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
1946                 }
1947                 snd_emu10k1_init_stereo_control(controls + i++, "Line LiveDrive Capture Volume", gpr, 0);
1948                 snd_emu10k1_init_stereo_onoff_control(controls + i++, "Line LiveDrive Capture Switch", gpr + 2, 0);
1949                 gpr += 4;
1950         }
1951         
1952         if (emu->fx8010.extin_mask & ((1<<EXTIN_COAX_SPDIF_L)|(1<<EXTIN_COAX_SPDIF_R))) {
1953                 /* IEC958 Coax Playback Volume */
1954                 for (z = 0; z < 2; z++)
1955                         VOLUME_ADDIN(icode, &ptr, playback + z, EXTIN_COAX_SPDIF_L + z, gpr + z);
1956                 snd_emu10k1_init_stereo_control(controls + i++, "IEC958 Coaxial Playback Volume", gpr, 0);
1957                 gpr += 2;
1958         
1959                 /* IEC958 Coax Capture Volume + Switch */
1960                 for (z = 0; z < 2; z++) {
1961                         SWITCH_IN(icode, &ptr, tmp + 0, EXTIN_COAX_SPDIF_L + z, gpr + 2 + z);
1962                         VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
1963                 }
1964                 snd_emu10k1_init_stereo_control(controls + i++, "IEC958 Coaxial Capture Volume", gpr, 0);
1965                 snd_emu10k1_init_stereo_onoff_control(controls + i++, "IEC958 Coaxial Capture Switch", gpr + 2, 0);
1966                 gpr += 4;
1967         }
1968         
1969         if (emu->fx8010.extin_mask & ((1<<EXTIN_LINE2_L)|(1<<EXTIN_LINE2_R))) {
1970                 /* Line LiveDrive Playback Volume */
1971                 for (z = 0; z < 2; z++)
1972                         VOLUME_ADDIN(icode, &ptr, playback + z, EXTIN_LINE2_L + z, gpr + z);
1973                 snd_emu10k1_init_stereo_control(controls + i++, "Line2 LiveDrive Playback Volume", gpr, 0);
1974                 controls[i-1].id.index = 1;
1975                 gpr += 2;
1976         
1977                 /* Line LiveDrive Capture Volume */
1978                 for (z = 0; z < 2; z++) {
1979                         SWITCH_IN(icode, &ptr, tmp + 0, EXTIN_LINE2_L + z, gpr + 2 + z);
1980                         VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
1981                 }
1982                 snd_emu10k1_init_stereo_control(controls + i++, "Line2 LiveDrive Capture Volume", gpr, 0);
1983                 controls[i-1].id.index = 1;
1984                 snd_emu10k1_init_stereo_onoff_control(controls + i++, "Line2 LiveDrive Capture Switch", gpr + 2, 0);
1985                 controls[i-1].id.index = 1;
1986                 gpr += 4;
1987         }
1988
1989         /*
1990          *  Process tone control
1991          */
1992         OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 0), GPR(playback + 0), C_00000000, C_00000000); /* left */
1993         OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 1), GPR(playback + 1), C_00000000, C_00000000); /* right */
1994         OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 2), GPR(playback + 2), C_00000000, C_00000000); /* rear left */
1995         OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 3), GPR(playback + 3), C_00000000, C_00000000); /* rear right */
1996         OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 4), GPR(playback + 4), C_00000000, C_00000000); /* center */
1997         OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 5), GPR(playback + 5), C_00000000, C_00000000); /* LFE */
1998
1999         ctl = &controls[i + 0];
2000         ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
2001         strcpy(ctl->id.name, "Tone Control - Bass");
2002         ctl->vcount = 2;
2003         ctl->count = 10;
2004         ctl->min = 0;
2005         ctl->max = 40;
2006         ctl->value[0] = ctl->value[1] = 20;
2007         ctl->translation = EMU10K1_GPR_TRANSLATION_BASS;
2008         ctl = &controls[i + 1];
2009         ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
2010         strcpy(ctl->id.name, "Tone Control - Treble");
2011         ctl->vcount = 2;
2012         ctl->count = 10;
2013         ctl->min = 0;
2014         ctl->max = 40;
2015         ctl->value[0] = ctl->value[1] = 20;
2016         ctl->translation = EMU10K1_GPR_TRANSLATION_TREBLE;
2017
2018 #define BASS_GPR        0x8c
2019 #define TREBLE_GPR      0x96
2020
2021         for (z = 0; z < 5; z++) {
2022                 int j;
2023                 for (j = 0; j < 2; j++) {
2024                         controls[i + 0].gpr[z * 2 + j] = BASS_GPR + z * 2 + j;
2025                         controls[i + 1].gpr[z * 2 + j] = TREBLE_GPR + z * 2 + j;
2026                 }
2027         }
2028         for (z = 0; z < 3; z++) {               /* front/rear/center-lfe */
2029                 int j, k, l, d;
2030                 for (j = 0; j < 2; j++) {       /* left/right */
2031                         k = 0xa0 + (z * 8) + (j * 4);
2032                         l = 0xd0 + (z * 8) + (j * 4);
2033                         d = playback + SND_EMU10K1_PLAYBACK_CHANNELS + z * 2 + j;
2034
2035                         OP(icode, &ptr, iMAC0, C_00000000, C_00000000, GPR(d), GPR(BASS_GPR + 0 + j));
2036                         OP(icode, &ptr, iMACMV, GPR(k+1), GPR(k), GPR(k+1), GPR(BASS_GPR + 4 + j));
2037                         OP(icode, &ptr, iMACMV, GPR(k), GPR(d), GPR(k), GPR(BASS_GPR + 2 + j));
2038                         OP(icode, &ptr, iMACMV, GPR(k+3), GPR(k+2), GPR(k+3), GPR(BASS_GPR + 8 + j));
2039                         OP(icode, &ptr, iMAC0, GPR(k+2), GPR_ACCU, GPR(k+2), GPR(BASS_GPR + 6 + j));
2040                         OP(icode, &ptr, iACC3, GPR(k+2), GPR(k+2), GPR(k+2), C_00000000);
2041
2042                         OP(icode, &ptr, iMAC0, C_00000000, C_00000000, GPR(k+2), GPR(TREBLE_GPR + 0 + j));
2043                         OP(icode, &ptr, iMACMV, GPR(l+1), GPR(l), GPR(l+1), GPR(TREBLE_GPR + 4 + j));
2044                         OP(icode, &ptr, iMACMV, GPR(l), GPR(k+2), GPR(l), GPR(TREBLE_GPR + 2 + j));
2045                         OP(icode, &ptr, iMACMV, GPR(l+3), GPR(l+2), GPR(l+3), GPR(TREBLE_GPR + 8 + j));
2046                         OP(icode, &ptr, iMAC0, GPR(l+2), GPR_ACCU, GPR(l+2), GPR(TREBLE_GPR + 6 + j));
2047                         OP(icode, &ptr, iMACINT0, GPR(l+2), C_00000000, GPR(l+2), C_00000010);
2048
2049                         OP(icode, &ptr, iACC3, GPR(d), GPR(l+2), C_00000000, C_00000000);
2050
2051                         if (z == 2)     /* center */
2052                                 break;
2053                 }
2054         }
2055         i += 2;
2056
2057 #undef BASS_GPR
2058 #undef TREBLE_GPR
2059
2060         for (z = 0; z < 6; z++) {
2061                 SWITCH(icode, &ptr, tmp + 0, playback + SND_EMU10K1_PLAYBACK_CHANNELS + z, gpr + 0);
2062                 SWITCH_NEG(icode, &ptr, tmp + 1, gpr + 0);
2063                 SWITCH(icode, &ptr, tmp + 1, playback + z, tmp + 1);
2064                 OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + z), GPR(tmp + 0), GPR(tmp + 1), C_00000000);
2065         }
2066         snd_emu10k1_init_stereo_onoff_control(controls + i++, "Tone Control - Switch", gpr, 0);
2067         gpr += 2;
2068
2069         /*
2070          *  Process outputs
2071          */
2072         if (emu->fx8010.extout_mask & ((1<<EXTOUT_AC97_L)|(1<<EXTOUT_AC97_R))) {
2073                 /* AC'97 Playback Volume */
2074
2075                 for (z = 0; z < 2; z++)
2076                         OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_AC97_L + z), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + z), C_00000000, C_00000000);
2077         }
2078
2079         if (emu->fx8010.extout_mask & ((1<<EXTOUT_TOSLINK_L)|(1<<EXTOUT_TOSLINK_R))) {
2080                 /* IEC958 Optical Raw Playback Switch */
2081
2082                 for (z = 0; z < 2; z++) {
2083                         SWITCH(icode, &ptr, tmp + 0, 8 + z, gpr + z);
2084                         SWITCH_NEG(icode, &ptr, tmp + 1, gpr + z);
2085                         SWITCH(icode, &ptr, tmp + 1, playback + SND_EMU10K1_PLAYBACK_CHANNELS + z, tmp + 1);
2086                         OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_TOSLINK_L + z), GPR(tmp + 0), GPR(tmp + 1), C_00000000);
2087 #ifdef EMU10K1_CAPTURE_DIGITAL_OUT
2088                         OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_ADC_CAP_L + z), GPR(tmp + 0), GPR(tmp + 1), C_00000000);
2089 #endif
2090                 }
2091
2092                 snd_emu10k1_init_stereo_onoff_control(controls + i++, "IEC958 Optical Raw Playback Switch", gpr, 0);
2093                 gpr += 2;
2094         }
2095
2096         if (emu->fx8010.extout_mask & ((1<<EXTOUT_HEADPHONE_L)|(1<<EXTOUT_HEADPHONE_R))) {
2097                 /* Headphone Playback Volume */
2098
2099                 for (z = 0; z < 2; z++) {
2100                         SWITCH(icode, &ptr, tmp + 0, playback + SND_EMU10K1_PLAYBACK_CHANNELS + 4 + z, gpr + 2 + z);
2101                         SWITCH_NEG(icode, &ptr, tmp + 1, gpr + 2 + z);
2102                         SWITCH(icode, &ptr, tmp + 1, playback + SND_EMU10K1_PLAYBACK_CHANNELS + z, tmp + 1);
2103                         OP(icode, &ptr, iACC3, GPR(tmp + 0), GPR(tmp + 0), GPR(tmp + 1), C_00000000);
2104                         VOLUME_OUT(icode, &ptr, EXTOUT_HEADPHONE_L + z, tmp + 0, gpr + z);
2105                 }
2106
2107                 snd_emu10k1_init_stereo_control(controls + i++, "Headphone Playback Volume", gpr + 0, 0);
2108                 controls[i-1].id.index = 1;     /* AC'97 can have also Headphone control */
2109                 snd_emu10k1_init_mono_onoff_control(controls + i++, "Headphone Center Playback Switch", gpr + 2, 0);
2110                 controls[i-1].id.index = 1;
2111                 snd_emu10k1_init_mono_onoff_control(controls + i++, "Headphone LFE Playback Switch", gpr + 3, 0);
2112                 controls[i-1].id.index = 1;
2113
2114                 gpr += 4;
2115         }
2116         
2117         if (emu->fx8010.extout_mask & ((1<<EXTOUT_REAR_L)|(1<<EXTOUT_REAR_R)))
2118                 for (z = 0; z < 2; z++)
2119                         OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_REAR_L + z), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 2 + z), C_00000000, C_00000000);
2120
2121         if (emu->fx8010.extout_mask & ((1<<EXTOUT_AC97_REAR_L)|(1<<EXTOUT_AC97_REAR_R)))
2122                 for (z = 0; z < 2; z++)
2123                         OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_AC97_REAR_L + z), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 2 + z), C_00000000, C_00000000);
2124
2125         if (emu->fx8010.extout_mask & (1<<EXTOUT_AC97_CENTER)) {
2126 #ifndef EMU10K1_CENTER_LFE_FROM_FRONT
2127                 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_AC97_CENTER), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 4), C_00000000, C_00000000);
2128                 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_ACENTER), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 4), C_00000000, C_00000000);
2129 #else
2130                 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_AC97_CENTER), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 0), C_00000000, C_00000000);
2131                 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_ACENTER), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 0), C_00000000, C_00000000);
2132 #endif
2133         }
2134
2135         if (emu->fx8010.extout_mask & (1<<EXTOUT_AC97_LFE)) {
2136 #ifndef EMU10K1_CENTER_LFE_FROM_FRONT
2137                 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_AC97_LFE), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 5), C_00000000, C_00000000);
2138                 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_ALFE), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 5), C_00000000, C_00000000);
2139 #else
2140                 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_AC97_LFE), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 1), C_00000000, C_00000000);
2141                 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_ALFE), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 1), C_00000000, C_00000000);
2142 #endif
2143         }
2144         
2145 #ifndef EMU10K1_CAPTURE_DIGITAL_OUT
2146         for (z = 0; z < 2; z++)
2147                 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_ADC_CAP_L + z), GPR(capture + z), C_00000000, C_00000000);
2148 #endif
2149         
2150         if (emu->fx8010.extout_mask & (1<<EXTOUT_MIC_CAP))
2151                 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_MIC_CAP), GPR(capture + 2), C_00000000, C_00000000);
2152
2153         if (gpr > tmp) {
2154                 snd_BUG();
2155                 err = -EIO;
2156                 goto __err;
2157         }
2158         if (i > SND_EMU10K1_GPR_CONTROLS) {
2159                 snd_BUG();
2160                 err = -EIO;
2161                 goto __err;
2162         }
2163         
2164         /* clear remaining instruction memory */
2165         while (ptr < 0x200)
2166                 OP(icode, &ptr, iACC3, C_00000000, C_00000000, C_00000000, C_00000000);
2167
2168         if ((err = snd_emu10k1_fx8010_tram_setup(emu, ipcm->buffer_size)) < 0)
2169                 goto __err;
2170         seg = snd_enter_user();
2171         icode->gpr_add_control_count = i;
2172         icode->gpr_add_controls = controls;
2173         err = snd_emu10k1_icode_poke(emu, icode);
2174         snd_leave_user(seg);
2175         if (err >= 0)
2176                 err = snd_emu10k1_ipcm_poke(emu, ipcm);
2177       __err:
2178         kfree(ipcm);
2179         kfree(controls);
2180         kfree(icode);
2181         return err;
2182 }
2183
2184 int __devinit snd_emu10k1_init_efx(emu10k1_t *emu)
2185 {
2186         if (emu->audigy)
2187                 return _snd_emu10k1_audigy_init_efx(emu);
2188         else
2189                 return _snd_emu10k1_init_efx(emu);
2190 }
2191
2192 void snd_emu10k1_free_efx(emu10k1_t *emu)
2193 {
2194         /* stop processor */
2195         if (emu->audigy)
2196                 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg = A_DBG_SINGLE_STEP);
2197         else
2198                 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg = EMU10K1_DBG_SINGLE_STEP);
2199 }
2200
2201 #if 0 // FIXME: who use them?
2202 int snd_emu10k1_fx8010_tone_control_activate(emu10k1_t *emu, int output)
2203 {
2204         snd_runtime_check(output >= 0 && output < 6, return -EINVAL);
2205         snd_emu10k1_ptr_write(emu, emu->gpr_base + 0x94 + output, 0, 1);
2206         return 0;
2207 }
2208
2209 int snd_emu10k1_fx8010_tone_control_deactivate(emu10k1_t *emu, int output)
2210 {
2211         snd_runtime_check(output >= 0 && output < 6, return -EINVAL);
2212         snd_emu10k1_ptr_write(emu, emu->gpr_base + 0x94 + output, 0, 0);
2213         return 0;
2214 }
2215 #endif
2216
2217 int snd_emu10k1_fx8010_tram_setup(emu10k1_t *emu, u32 size)
2218 {
2219         u8 size_reg = 0;
2220
2221         /* size is in samples */
2222         if (size != 0) {
2223                 size = (size - 1) >> 13;
2224
2225                 while (size) {
2226                         size >>= 1;
2227                         size_reg++;
2228                 }
2229                 size = 0x2000 << size_reg;
2230         }
2231         if (emu->fx8010.etram_pages.bytes == size)
2232                 return 0;
2233         spin_lock_irq(&emu->emu_lock);
2234         outl(HCFG_LOCKTANKCACHE_MASK | inl(emu->port + HCFG), emu->port + HCFG);
2235         spin_unlock_irq(&emu->emu_lock);
2236         snd_emu10k1_ptr_write(emu, TCB, 0, 0);
2237         snd_emu10k1_ptr_write(emu, TCBS, 0, 0);
2238         if (emu->fx8010.etram_pages.area != NULL) {
2239                 snd_dma_free_pages(&emu->dma_dev, &emu->fx8010.etram_pages);
2240                 emu->fx8010.etram_pages.area = NULL;
2241                 emu->fx8010.etram_pages.bytes = 0;
2242         }
2243
2244         if (size > 0) {
2245                 if (snd_dma_alloc_pages(&emu->dma_dev, size * 2, &emu->fx8010.etram_pages) < 0)
2246                         return -ENOMEM;
2247                 memset(emu->fx8010.etram_pages.area, 0, size * 2);
2248                 snd_emu10k1_ptr_write(emu, TCB, 0, emu->fx8010.etram_pages.addr);
2249                 snd_emu10k1_ptr_write(emu, TCBS, 0, size_reg);
2250                 spin_lock_irq(&emu->emu_lock);
2251                 outl(inl(emu->port + HCFG) & ~HCFG_LOCKTANKCACHE_MASK, emu->port + HCFG);
2252                 spin_unlock_irq(&emu->emu_lock);        
2253         }
2254
2255         return 0;
2256 }
2257
2258 static int snd_emu10k1_fx8010_open(snd_hwdep_t * hw, struct file *file)
2259 {
2260         return 0;
2261 }
2262
2263 static void copy_string(char *dst, char *src, char *null, int idx)
2264 {
2265         if (src == NULL)
2266                 sprintf(dst, "%s %02X", null, idx);
2267         else
2268                 strcpy(dst, src);
2269 }
2270
2271 static int snd_emu10k1_fx8010_info(emu10k1_t *emu, emu10k1_fx8010_info_t *info)
2272 {
2273         char **fxbus, **extin, **extout;
2274         unsigned short fxbus_mask, extin_mask, extout_mask;
2275         int res;
2276
2277         memset(info, 0, sizeof(info));
2278         info->card = emu->card_type;
2279         info->internal_tram_size = emu->fx8010.itram_size;
2280         info->external_tram_size = emu->fx8010.etram_pages.bytes;
2281         fxbus = fxbuses;
2282         extin = emu->audigy ? audigy_ins : creative_ins;
2283         extout = emu->audigy ? audigy_outs : creative_outs;
2284         fxbus_mask = emu->fx8010.fxbus_mask;
2285         extin_mask = emu->fx8010.extin_mask;
2286         extout_mask = emu->fx8010.extout_mask;
2287         for (res = 0; res < 16; res++, fxbus++, extin++, extout++) {
2288                 copy_string(info->fxbus_names[res], fxbus_mask & (1 << res) ? *fxbus : NULL, "FXBUS", res);
2289                 copy_string(info->extin_names[res], extin_mask & (1 << res) ? *extin : NULL, "Unused", res);
2290                 copy_string(info->extout_names[res], extout_mask & (1 << res) ? *extout : NULL, "Unused", res);
2291         }
2292         for (res = 16; res < 32; res++, extout++)
2293                 copy_string(info->extout_names[res], extout_mask & (1 << res) ? *extout : NULL, "Unused", res);
2294         info->gpr_controls = emu->fx8010.gpr_count;
2295         return 0;
2296 }
2297
2298 static int snd_emu10k1_fx8010_ioctl(snd_hwdep_t * hw, struct file *file, unsigned int cmd, unsigned long arg)
2299 {
2300         emu10k1_t *emu = snd_magic_cast(emu10k1_t, hw->private_data, return -ENXIO);
2301         emu10k1_fx8010_info_t *info;
2302         emu10k1_fx8010_code_t *icode;
2303         emu10k1_fx8010_pcm_t *ipcm;
2304         unsigned int addr;
2305         void __user *argp = (void __user *)arg;
2306         int res;
2307         
2308         switch (cmd) {
2309         case SNDRV_EMU10K1_IOCTL_INFO:
2310                 info = (emu10k1_fx8010_info_t *)kmalloc(sizeof(*info), GFP_KERNEL);
2311                 if (!info)
2312                         return -ENOMEM;
2313                 if ((res = snd_emu10k1_fx8010_info(emu, info)) < 0) {
2314                         kfree(info);
2315                         return res;
2316                 }
2317                 if (copy_to_user(argp, info, sizeof(*info))) {
2318                         kfree(info);
2319                         return -EFAULT;
2320                 }
2321                 kfree(info);
2322                 return 0;
2323         case SNDRV_EMU10K1_IOCTL_CODE_POKE:
2324                 if (!capable(CAP_SYS_ADMIN))
2325                         return -EPERM;
2326                 icode = (emu10k1_fx8010_code_t *)kmalloc(sizeof(*icode), GFP_KERNEL);
2327                 if (icode == NULL)
2328                         return -ENOMEM;
2329                 if (copy_from_user(icode, argp, sizeof(*icode))) {
2330                         kfree(icode);
2331                         return -EFAULT;
2332                 }
2333                 res = snd_emu10k1_icode_poke(emu, icode);
2334                 kfree(icode);
2335                 return res;
2336         case SNDRV_EMU10K1_IOCTL_CODE_PEEK:
2337                 icode = (emu10k1_fx8010_code_t *)kmalloc(sizeof(*icode), GFP_KERNEL);
2338                 if (icode == NULL)
2339                         return -ENOMEM;
2340                 if (copy_from_user(icode, argp, sizeof(*icode))) {
2341                         kfree(icode);
2342                         return -EFAULT;
2343                 }
2344                 res = snd_emu10k1_icode_peek(emu, icode);
2345                 if (res == 0 && copy_to_user(argp, icode, sizeof(*icode))) {
2346                         kfree(icode);
2347                         return -EFAULT;
2348                 }
2349                 kfree(icode);
2350                 return res;
2351         case SNDRV_EMU10K1_IOCTL_PCM_POKE:
2352                 if (emu->audigy)
2353                         return -EINVAL;
2354                 ipcm = (emu10k1_fx8010_pcm_t *)kmalloc(sizeof(*ipcm), GFP_KERNEL);
2355                 if (ipcm == NULL)
2356                         return -ENOMEM;
2357                 if (copy_from_user(ipcm, argp, sizeof(*ipcm))) {
2358                         kfree(ipcm);
2359                         return -EFAULT;
2360                 }
2361                 res = snd_emu10k1_ipcm_poke(emu, ipcm);
2362                 kfree(ipcm);
2363                 return res;
2364         case SNDRV_EMU10K1_IOCTL_PCM_PEEK:
2365                 if (emu->audigy)
2366                         return -EINVAL;
2367                 ipcm = (emu10k1_fx8010_pcm_t *)snd_kcalloc(sizeof(*ipcm), GFP_KERNEL);
2368                 if (ipcm == NULL)
2369                         return -ENOMEM;
2370                 if (copy_from_user(ipcm, argp, sizeof(*ipcm))) {
2371                         kfree(ipcm);
2372                         return -EFAULT;
2373                 }
2374                 res = snd_emu10k1_ipcm_peek(emu, ipcm);
2375                 if (res == 0 && copy_to_user(argp, ipcm, sizeof(*ipcm))) {
2376                         kfree(ipcm);
2377                         return -EFAULT;
2378                 }
2379                 kfree(ipcm);
2380                 return res;
2381         case SNDRV_EMU10K1_IOCTL_TRAM_SETUP:
2382                 if (emu->audigy)
2383                         return -EINVAL;
2384                 if (!capable(CAP_SYS_ADMIN))
2385                         return -EPERM;
2386                 if (get_user(addr, (unsigned int __user *)argp))
2387                         return -EFAULT;
2388                 down(&emu->fx8010.lock);
2389                 res = snd_emu10k1_fx8010_tram_setup(emu, addr);
2390                 up(&emu->fx8010.lock);
2391                 return res;
2392         case SNDRV_EMU10K1_IOCTL_STOP:
2393                 if (!capable(CAP_SYS_ADMIN))
2394                         return -EPERM;
2395                 if (emu->audigy)
2396                         snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg |= A_DBG_SINGLE_STEP);
2397                 else
2398                         snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg |= EMU10K1_DBG_SINGLE_STEP);
2399                 return 0;
2400         case SNDRV_EMU10K1_IOCTL_CONTINUE:
2401                 if (!capable(CAP_SYS_ADMIN))
2402                         return -EPERM;
2403                 if (emu->audigy)
2404                         snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg = 0);
2405                 else
2406                         snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg = 0);
2407                 return 0;
2408         case SNDRV_EMU10K1_IOCTL_ZERO_TRAM_COUNTER:
2409                 if (!capable(CAP_SYS_ADMIN))
2410                         return -EPERM;
2411                 if (emu->audigy)
2412                         snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg | A_DBG_ZC);
2413                 else
2414                         snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg | EMU10K1_DBG_ZC);
2415                 udelay(10);
2416                 if (emu->audigy)
2417                         snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg);
2418                 else
2419                         snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg);
2420                 return 0;
2421         case SNDRV_EMU10K1_IOCTL_SINGLE_STEP:
2422                 if (!capable(CAP_SYS_ADMIN))
2423                         return -EPERM;
2424                 if (get_user(addr, (unsigned int __user *)argp))
2425                         return -EFAULT;
2426                 if (addr > 0x1ff)
2427                         return -EINVAL;
2428                 if (emu->audigy)
2429                         snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg |= A_DBG_SINGLE_STEP | addr);
2430                 else
2431                         snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg |= EMU10K1_DBG_SINGLE_STEP | addr);
2432                 udelay(10);
2433                 if (emu->audigy)
2434                         snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg |= A_DBG_SINGLE_STEP | A_DBG_STEP_ADDR | addr);
2435                 else
2436                         snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg |= EMU10K1_DBG_SINGLE_STEP | EMU10K1_DBG_STEP | addr);
2437                 return 0;
2438         case SNDRV_EMU10K1_IOCTL_DBG_READ:
2439                 if (emu->audigy)
2440                         addr = snd_emu10k1_ptr_read(emu, A_DBG, 0);
2441                 else
2442                         addr = snd_emu10k1_ptr_read(emu, DBG, 0);
2443                 if (put_user(addr, (unsigned int __user *)argp))
2444                         return -EFAULT;
2445                 return 0;
2446         }
2447         return -ENOTTY;
2448 }
2449
2450 static int snd_emu10k1_fx8010_release(snd_hwdep_t * hw, struct file *file)
2451 {
2452         return 0;
2453 }
2454
2455 int __devinit snd_emu10k1_fx8010_new(emu10k1_t *emu, int device, snd_hwdep_t ** rhwdep)
2456 {
2457         snd_hwdep_t *hw;
2458         int err;
2459         
2460         if (rhwdep)
2461                 *rhwdep = NULL;
2462         if ((err = snd_hwdep_new(emu->card, "FX8010", device, &hw)) < 0)
2463                 return err;
2464         strcpy(hw->name, "EMU10K1 (FX8010)");
2465         hw->iface = SNDRV_HWDEP_IFACE_EMU10K1;
2466         hw->ops.open = snd_emu10k1_fx8010_open;
2467         hw->ops.ioctl = snd_emu10k1_fx8010_ioctl;
2468         hw->ops.release = snd_emu10k1_fx8010_release;
2469         hw->private_data = emu;
2470         if (rhwdep)
2471                 *rhwdep = hw;
2472         return 0;
2473 }