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