vserver 1.9.5.x5
[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)   * 2 + 0] = ((x & 0x3ff) << 10) | (y & 0x3ff);
474         icode->code[(*ptr)++ * 2 + 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 < 1024, return);
484         set_bit(*ptr, icode->code_valid);
485         icode->code[(*ptr)   * 2 + 0] = ((x & 0x7ff) << 12) | (y & 0x7ff);
486         icode->code[(*ptr)++ * 2 + 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 static 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 int snd_emu10k1_gpr_poke(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
505 {
506         int gpr;
507         u32 val;
508
509         for (gpr = 0; gpr < (emu->audigy ? 0x200 : 0x100); gpr++) {
510                 if (!test_bit(gpr, icode->gpr_valid))
511                         continue;
512                 if (get_user(val, &icode->gpr_map[gpr]))
513                         return -EFAULT;
514                 snd_emu10k1_ptr_write(emu, emu->gpr_base + gpr, 0, val);
515         }
516         return 0;
517 }
518
519 static int snd_emu10k1_gpr_peek(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
520 {
521         int gpr;
522         u32 val;
523
524         for (gpr = 0; gpr < (emu->audigy ? 0x200 : 0x100); gpr++) {
525                 set_bit(gpr, icode->gpr_valid);
526                 val = snd_emu10k1_ptr_read(emu, emu->gpr_base + gpr, 0);
527                 if (put_user(val, &icode->gpr_map[gpr]))
528                         return -EFAULT;
529         }
530         return 0;
531 }
532
533 static int snd_emu10k1_tram_poke(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
534 {
535         int tram;
536         u32 addr, val;
537
538         for (tram = 0; tram < (emu->audigy ? 0x100 : 0xa0); tram++) {
539                 if (!test_bit(tram, icode->tram_valid))
540                         continue;
541                 if (get_user(val, &icode->tram_data_map[tram]) ||
542                     get_user(addr, &icode->tram_addr_map[tram]))
543                         return -EFAULT;
544                 snd_emu10k1_ptr_write(emu, TANKMEMDATAREGBASE + tram, 0, val);
545                 if (!emu->audigy) {
546                         snd_emu10k1_ptr_write(emu, TANKMEMADDRREGBASE + tram, 0, addr);
547                 } else {
548                         snd_emu10k1_ptr_write(emu, TANKMEMADDRREGBASE + tram, 0, addr << 12);
549                         snd_emu10k1_ptr_write(emu, A_TANKMEMCTLREGBASE + tram, 0, addr >> 20);
550                 }
551         }
552         return 0;
553 }
554
555 static int snd_emu10k1_tram_peek(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
556 {
557         int tram;
558         u32 val, addr;
559
560         memset(icode->tram_valid, 0, sizeof(icode->tram_valid));
561         for (tram = 0; tram < (emu->audigy ? 0x100 : 0xa0); tram++) {
562                 set_bit(tram, icode->tram_valid);
563                 val = snd_emu10k1_ptr_read(emu, TANKMEMDATAREGBASE + tram, 0);
564                 if (!emu->audigy) {
565                         addr = snd_emu10k1_ptr_read(emu, TANKMEMADDRREGBASE + tram, 0);
566                 } else {
567                         addr = snd_emu10k1_ptr_read(emu, TANKMEMADDRREGBASE + tram, 0) >> 12;
568                         addr |= snd_emu10k1_ptr_read(emu, A_TANKMEMCTLREGBASE + tram, 0) << 20;
569                 }
570                 if (put_user(val, &icode->tram_data_map[tram]) ||
571                     put_user(addr, &icode->tram_addr_map[tram]))
572                         return -EFAULT;
573         }
574         return 0;
575 }
576
577 static int snd_emu10k1_code_poke(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
578 {
579         u32 pc, lo, hi;
580
581         for (pc = 0; pc < (emu->audigy ? 2*1024 : 2*512); pc += 2) {
582                 if (!test_bit(pc / 2, icode->code_valid))
583                         continue;
584                 if (get_user(lo, &icode->code[pc + 0]) ||
585                     get_user(hi, &icode->code[pc + 1]))
586                         return -EFAULT;
587                 snd_emu10k1_efx_write(emu, pc + 0, lo);
588                 snd_emu10k1_efx_write(emu, pc + 1, hi);
589         }
590         return 0;
591 }
592
593 static int snd_emu10k1_code_peek(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
594 {
595         u32 pc;
596
597         memset(icode->code_valid, 0, sizeof(icode->code_valid));
598         for (pc = 0; pc < (emu->audigy ? 2*1024 : 2*512); pc += 2) {
599                 set_bit(pc / 2, icode->code_valid);
600                 if (put_user(snd_emu10k1_efx_read(emu, pc + 0), &icode->code[pc + 0]))
601                         return -EFAULT;
602                 if (put_user(snd_emu10k1_efx_read(emu, pc + 1), &icode->code[pc + 1]))
603                         return -EFAULT;
604         }
605         return 0;
606 }
607
608 static snd_emu10k1_fx8010_ctl_t *snd_emu10k1_look_for_ctl(emu10k1_t *emu, snd_ctl_elem_id_t *id)
609 {
610         snd_emu10k1_fx8010_ctl_t *ctl;
611         snd_kcontrol_t *kcontrol;
612         struct list_head *list;
613         
614         list_for_each(list, &emu->fx8010.gpr_ctl) {
615                 ctl = emu10k1_gpr_ctl(list);
616                 kcontrol = ctl->kcontrol;
617                 if (kcontrol->id.iface == id->iface &&
618                     !strcmp(kcontrol->id.name, id->name) &&
619                     kcontrol->id.index == id->index)
620                         return ctl;
621         }
622         return NULL;
623 }
624
625 static int snd_emu10k1_verify_controls(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
626 {
627         unsigned int i;
628         snd_ctl_elem_id_t __user *_id;
629         snd_ctl_elem_id_t id;
630         emu10k1_fx8010_control_gpr_t __user *_gctl;
631         emu10k1_fx8010_control_gpr_t gctl;
632         
633         for (i = 0, _id = icode->gpr_del_controls;
634              i < icode->gpr_del_control_count; i++, _id++) {
635                 if (copy_from_user(&id, _id, sizeof(id)))
636                         return -EFAULT;
637                 if (snd_emu10k1_look_for_ctl(emu, &id) == NULL)
638                         return -ENOENT;
639         }
640         for (i = 0, _gctl = icode->gpr_add_controls;
641              i < icode->gpr_add_control_count; i++, _gctl++) {
642                 if (copy_from_user(&gctl, _gctl, sizeof(gctl)))
643                         return -EFAULT;
644                 if (snd_emu10k1_look_for_ctl(emu, &gctl.id))
645                         continue;
646                 down_read(&emu->card->controls_rwsem);
647                 if (snd_ctl_find_id(emu->card, &gctl.id) != NULL) {
648                         up_read(&emu->card->controls_rwsem);
649                         return -EEXIST;
650                 }
651                 up_read(&emu->card->controls_rwsem);
652                 if (gctl.id.iface != SNDRV_CTL_ELEM_IFACE_MIXER &&
653                     gctl.id.iface != SNDRV_CTL_ELEM_IFACE_PCM)
654                         return -EINVAL;
655         }
656         for (i = 0, _gctl = icode->gpr_list_controls;
657              i < icode->gpr_list_control_count; i++, _gctl++) {
658                 /* FIXME: we need to check the WRITE access */
659                 if (copy_from_user(&gctl, _gctl, sizeof(gctl)))
660                         return -EFAULT;
661         }
662         return 0;
663 }
664
665 static void snd_emu10k1_ctl_private_free(snd_kcontrol_t *kctl)
666 {
667         snd_emu10k1_fx8010_ctl_t *ctl;
668         
669         ctl = (snd_emu10k1_fx8010_ctl_t *)kctl->private_value;
670         kctl->private_value = 0;
671         list_del(&ctl->list);
672         kfree(ctl);
673 }
674
675 static int snd_emu10k1_add_controls(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
676 {
677         unsigned int i, j;
678         emu10k1_fx8010_control_gpr_t __user *_gctl;
679         emu10k1_fx8010_control_gpr_t gctl;
680         snd_emu10k1_fx8010_ctl_t *ctl, nctl;
681         snd_kcontrol_new_t knew;
682         snd_kcontrol_t *kctl;
683         snd_ctl_elem_value_t *val;
684         int err = 0;
685
686         val = (snd_ctl_elem_value_t *)kmalloc(sizeof(*val), GFP_KERNEL);
687         if (!val)
688                 return -ENOMEM;
689         for (i = 0, _gctl = icode->gpr_add_controls;
690              i < icode->gpr_add_control_count; i++, _gctl++) {
691                 if (copy_from_user(&gctl, _gctl, sizeof(gctl))) {
692                         err = -EFAULT;
693                         goto __error;
694                 }
695                 snd_runtime_check(gctl.id.iface == SNDRV_CTL_ELEM_IFACE_MIXER ||
696                                   gctl.id.iface == SNDRV_CTL_ELEM_IFACE_PCM, err = -EINVAL; goto __error);
697                 snd_runtime_check(gctl.id.name[0] != '\0', err = -EINVAL; goto __error);
698                 ctl = snd_emu10k1_look_for_ctl(emu, &gctl.id);
699                 memset(&knew, 0, sizeof(knew));
700                 knew.iface = gctl.id.iface;
701                 knew.name = gctl.id.name;
702                 knew.index = gctl.id.index;
703                 knew.device = gctl.id.device;
704                 knew.subdevice = gctl.id.subdevice;
705                 knew.info = snd_emu10k1_gpr_ctl_info;
706                 knew.get = snd_emu10k1_gpr_ctl_get;
707                 knew.put = snd_emu10k1_gpr_ctl_put;
708                 memset(&nctl, 0, sizeof(nctl));
709                 nctl.vcount = gctl.vcount;
710                 nctl.count = gctl.count;
711                 for (j = 0; j < 32; j++) {
712                         nctl.gpr[j] = gctl.gpr[j];
713                         nctl.value[j] = ~gctl.value[j]; /* inverted, we want to write new value in gpr_ctl_put() */
714                         val->value.integer.value[j] = gctl.value[j];
715                 }
716                 nctl.min = gctl.min;
717                 nctl.max = gctl.max;
718                 nctl.translation = gctl.translation;
719                 if (ctl == NULL) {
720                         ctl = (snd_emu10k1_fx8010_ctl_t *)kmalloc(sizeof(*ctl), GFP_KERNEL);
721                         if (ctl == NULL)
722                                 continue;
723                         knew.private_value = (unsigned long)ctl;
724                         memcpy(ctl, &nctl, sizeof(nctl));
725                         if ((err = snd_ctl_add(emu->card, kctl = snd_ctl_new1(&knew, emu))) < 0) {
726                                 kfree(ctl);
727                                 goto __error;
728                         }
729                         kctl->private_free = snd_emu10k1_ctl_private_free;
730                         ctl->kcontrol = kctl;
731                         list_add_tail(&ctl->list, &emu->fx8010.gpr_ctl);
732                 } else {
733                         /* overwrite */
734                         nctl.list = ctl->list;
735                         nctl.kcontrol = ctl->kcontrol;
736                         memcpy(ctl, &nctl, sizeof(nctl));
737                         snd_ctl_notify(emu->card, SNDRV_CTL_EVENT_MASK_VALUE |
738                                                   SNDRV_CTL_EVENT_MASK_INFO, &ctl->kcontrol->id);
739                 }
740                 snd_emu10k1_gpr_ctl_put(ctl->kcontrol, val);
741         }
742       __error:
743         kfree(val);
744         return err;
745 }
746
747 static int snd_emu10k1_del_controls(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
748 {
749         unsigned int i;
750         snd_ctl_elem_id_t id;
751         snd_ctl_elem_id_t __user *_id;
752         snd_emu10k1_fx8010_ctl_t *ctl;
753         snd_card_t *card = emu->card;
754         
755         for (i = 0, _id = icode->gpr_del_controls;
756              i < icode->gpr_del_control_count; i++, _id++) {
757                 snd_runtime_check(copy_from_user(&id, _id, sizeof(id)) == 0, return -EFAULT);
758                 down_write(&card->controls_rwsem);
759                 ctl = snd_emu10k1_look_for_ctl(emu, &id);
760                 if (ctl)
761                         snd_ctl_remove(card, ctl->kcontrol);
762                 up_write(&card->controls_rwsem);
763         }
764         return 0;
765 }
766
767 static int snd_emu10k1_list_controls(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
768 {
769         unsigned int i = 0, j;
770         unsigned int total = 0;
771         emu10k1_fx8010_control_gpr_t gctl;
772         emu10k1_fx8010_control_gpr_t __user *_gctl;
773         snd_emu10k1_fx8010_ctl_t *ctl;
774         snd_ctl_elem_id_t *id;
775         struct list_head *list;
776
777         _gctl = icode->gpr_list_controls;       
778         list_for_each(list, &emu->fx8010.gpr_ctl) {
779                 ctl = emu10k1_gpr_ctl(list);
780                 total++;
781                 if (_gctl && i < icode->gpr_list_control_count) {
782                         memset(&gctl, 0, sizeof(gctl));
783                         id = &ctl->kcontrol->id;
784                         gctl.id.iface = id->iface;
785                         strlcpy(gctl.id.name, id->name, sizeof(gctl.id.name));
786                         gctl.id.index = id->index;
787                         gctl.id.device = id->device;
788                         gctl.id.subdevice = id->subdevice;
789                         gctl.vcount = ctl->vcount;
790                         gctl.count = ctl->count;
791                         for (j = 0; j < 32; j++) {
792                                 gctl.gpr[j] = ctl->gpr[j];
793                                 gctl.value[j] = ctl->value[j];
794                         }
795                         gctl.min = ctl->min;
796                         gctl.max = ctl->max;
797                         gctl.translation = ctl->translation;
798                         if (copy_to_user(_gctl, &gctl, sizeof(gctl)))
799                                 return -EFAULT;
800                         _gctl++;
801                         i++;
802                 }
803         }
804         icode->gpr_list_control_total = total;
805         return 0;
806 }
807
808 static int snd_emu10k1_icode_poke(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
809 {
810         int err = 0;
811
812         down(&emu->fx8010.lock);
813         if ((err = snd_emu10k1_verify_controls(emu, icode)) < 0)
814                 goto __error;
815         strlcpy(emu->fx8010.name, icode->name, sizeof(emu->fx8010.name));
816         /* stop FX processor - this may be dangerous, but it's better to miss
817            some samples than generate wrong ones - [jk] */
818         if (emu->audigy)
819                 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg | A_DBG_SINGLE_STEP);
820         else
821                 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg | EMU10K1_DBG_SINGLE_STEP);
822         /* ok, do the main job */
823         if ((err = snd_emu10k1_del_controls(emu, icode)) < 0 ||
824             (err = snd_emu10k1_gpr_poke(emu, icode)) < 0 ||
825             (err = snd_emu10k1_tram_poke(emu, icode)) < 0 ||
826             (err = snd_emu10k1_code_poke(emu, icode)) < 0 ||
827             (err = snd_emu10k1_add_controls(emu, icode)) < 0)
828                 goto __error;
829         /* start FX processor when the DSP code is updated */
830         if (emu->audigy)
831                 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg);
832         else
833                 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg);
834       __error:
835         up(&emu->fx8010.lock);
836         return err;
837 }
838
839 static int snd_emu10k1_icode_peek(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
840 {
841         int err;
842
843         down(&emu->fx8010.lock);
844         strlcpy(icode->name, emu->fx8010.name, sizeof(icode->name));
845         /* ok, do the main job */
846         err = snd_emu10k1_gpr_peek(emu, icode);
847         if (err >= 0)
848                 err = snd_emu10k1_tram_peek(emu, icode);
849         if (err >= 0)
850                 err = snd_emu10k1_code_peek(emu, icode);
851         if (err >= 0)
852                 err = snd_emu10k1_list_controls(emu, icode);
853         up(&emu->fx8010.lock);
854         return err;
855 }
856
857 static int snd_emu10k1_ipcm_poke(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         if (ipcm->channels > 32)
866                 return -EINVAL;
867         pcm = &emu->fx8010.pcm[ipcm->substream];
868         down(&emu->fx8010.lock);
869         spin_lock_irq(&emu->reg_lock);
870         if (pcm->opened) {
871                 err = -EBUSY;
872                 goto __error;
873         }
874         if (ipcm->channels == 0) {      /* remove */
875                 pcm->valid = 0;
876         } else {
877                 /* FIXME: we need to add universal code to the PCM transfer routine */
878                 if (ipcm->channels != 2) {
879                         err = -EINVAL;
880                         goto __error;
881                 }
882                 pcm->valid = 1;
883                 pcm->opened = 0;
884                 pcm->channels = ipcm->channels;
885                 pcm->tram_start = ipcm->tram_start;
886                 pcm->buffer_size = ipcm->buffer_size;
887                 pcm->gpr_size = ipcm->gpr_size;
888                 pcm->gpr_count = ipcm->gpr_count;
889                 pcm->gpr_tmpcount = ipcm->gpr_tmpcount;
890                 pcm->gpr_ptr = ipcm->gpr_ptr;
891                 pcm->gpr_trigger = ipcm->gpr_trigger;
892                 pcm->gpr_running = ipcm->gpr_running;
893                 for (i = 0; i < pcm->channels; i++)
894                         pcm->etram[i] = ipcm->etram[i];
895         }
896       __error:
897         spin_unlock_irq(&emu->reg_lock);
898         up(&emu->fx8010.lock);
899         return err;
900 }
901
902 static int snd_emu10k1_ipcm_peek(emu10k1_t *emu, emu10k1_fx8010_pcm_t *ipcm)
903 {
904         unsigned int i;
905         int err = 0;
906         snd_emu10k1_fx8010_pcm_t *pcm;
907
908         if (ipcm->substream >= EMU10K1_FX8010_PCM_COUNT)
909                 return -EINVAL;
910         pcm = &emu->fx8010.pcm[ipcm->substream];
911         down(&emu->fx8010.lock);
912         spin_lock_irq(&emu->reg_lock);
913         ipcm->channels = pcm->channels;
914         ipcm->tram_start = pcm->tram_start;
915         ipcm->buffer_size = pcm->buffer_size;
916         ipcm->gpr_size = pcm->gpr_size;
917         ipcm->gpr_ptr = pcm->gpr_ptr;
918         ipcm->gpr_count = pcm->gpr_count;
919         ipcm->gpr_tmpcount = pcm->gpr_tmpcount;
920         ipcm->gpr_trigger = pcm->gpr_trigger;
921         ipcm->gpr_running = pcm->gpr_running;
922         for (i = 0; i < pcm->channels; i++)
923                 ipcm->etram[i] = pcm->etram[i];
924         ipcm->res1 = ipcm->res2 = 0;
925         ipcm->pad = 0;
926         spin_unlock_irq(&emu->reg_lock);
927         up(&emu->fx8010.lock);
928         return err;
929 }
930
931 #define SND_EMU10K1_GPR_CONTROLS        41
932 #define SND_EMU10K1_INPUTS              10
933 #define SND_EMU10K1_PLAYBACK_CHANNELS   8
934 #define SND_EMU10K1_CAPTURE_CHANNELS    4
935
936 static void __devinit snd_emu10k1_init_mono_control(emu10k1_fx8010_control_gpr_t *ctl, const char *name, int gpr, int defval)
937 {
938         ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
939         strcpy(ctl->id.name, name);
940         ctl->vcount = ctl->count = 1;
941         ctl->gpr[0] = gpr + 0; ctl->value[0] = defval;
942         ctl->min = 0;
943         ctl->max = 100;
944         ctl->translation = EMU10K1_GPR_TRANSLATION_TABLE100;    
945 }
946
947 static void __devinit snd_emu10k1_init_stereo_control(emu10k1_fx8010_control_gpr_t *ctl, const char *name, int gpr, int defval)
948 {
949         ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
950         strcpy(ctl->id.name, name);
951         ctl->vcount = ctl->count = 2;
952         ctl->gpr[0] = gpr + 0; ctl->value[0] = defval;
953         ctl->gpr[1] = gpr + 1; ctl->value[1] = defval;
954         ctl->min = 0;
955         ctl->max = 100;
956         ctl->translation = EMU10K1_GPR_TRANSLATION_TABLE100;
957 }
958
959 static void __devinit snd_emu10k1_init_mono_onoff_control(emu10k1_fx8010_control_gpr_t *ctl, const char *name, int gpr, int defval)
960 {
961         ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
962         strcpy(ctl->id.name, name);
963         ctl->vcount = ctl->count = 1;
964         ctl->gpr[0] = gpr + 0; ctl->value[0] = defval;
965         ctl->min = 0;
966         ctl->max = 1;
967         ctl->translation = EMU10K1_GPR_TRANSLATION_ONOFF;
968 }
969
970 static void __devinit snd_emu10k1_init_stereo_onoff_control(emu10k1_fx8010_control_gpr_t *ctl, const char *name, int gpr, int defval)
971 {
972         ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
973         strcpy(ctl->id.name, name);
974         ctl->vcount = ctl->count = 2;
975         ctl->gpr[0] = gpr + 0; ctl->value[0] = defval;
976         ctl->gpr[1] = gpr + 1; ctl->value[1] = defval;
977         ctl->min = 0;
978         ctl->max = 1;
979         ctl->translation = EMU10K1_GPR_TRANSLATION_ONOFF;
980 }
981
982
983 /*
984  * initial DSP configuration for Audigy
985  */
986
987 static int __devinit _snd_emu10k1_audigy_init_efx(emu10k1_t *emu)
988 {
989         int err, i, z, gpr, nctl;
990         const int playback = 10;
991         const int capture = playback + (SND_EMU10K1_PLAYBACK_CHANNELS * 2); /* we reserve 10 voices */
992         const int stereo_mix = capture + 2;
993         const int tmp = 0x88;
994         u32 ptr;
995         emu10k1_fx8010_code_t *icode = NULL;
996         emu10k1_fx8010_control_gpr_t *controls = NULL, *ctl;
997         mm_segment_t seg;
998
999         spin_lock_init(&emu->fx8010.irq_lock);
1000         INIT_LIST_HEAD(&emu->fx8010.gpr_ctl);
1001
1002         if ((icode = kcalloc(1, sizeof(*icode), GFP_KERNEL)) == NULL ||
1003             (icode->gpr_map = kcalloc(512 + 256 + 256 + 2 * 1024, sizeof(u_int32_t), GFP_KERNEL)) == NULL ||
1004             (controls = kcalloc(SND_EMU10K1_GPR_CONTROLS, sizeof(*controls), GFP_KERNEL)) == NULL) {
1005                 err = -ENOMEM;
1006                 goto __err;
1007         }
1008
1009         icode->tram_data_map = icode->gpr_map + 512;
1010         icode->tram_addr_map = icode->tram_data_map + 256;
1011         icode->code = icode->tram_addr_map + 256;
1012
1013         /* clear free GPRs */
1014         for (i = 0; i < 512; i++)
1015                 set_bit(i, icode->gpr_valid);
1016                 
1017         /* clear TRAM data & address lines */
1018         for (i = 0; i < 256; i++)
1019                 set_bit(i, icode->tram_valid);
1020
1021         strcpy(icode->name, "Audigy DSP code for ALSA");
1022         ptr = 0;
1023         nctl = 0;
1024         gpr = stereo_mix + 10;
1025
1026         /* stop FX processor */
1027         snd_emu10k1_ptr_write(emu, A_DBG, 0, (emu->fx8010.dbg = 0) | A_DBG_SINGLE_STEP);
1028
1029         /* PCM front Playback Volume (independent from stereo mix) */
1030         A_OP(icode, &ptr, iMAC0, A_GPR(playback), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LEFT_FRONT));
1031         A_OP(icode, &ptr, iMAC0, A_GPR(playback+1), A_C_00000000, A_GPR(gpr+1), A_FXBUS(FXBUS_PCM_RIGHT_FRONT));
1032         snd_emu10k1_init_stereo_control(&controls[nctl++], "PCM Front Playback Volume", gpr, 100);
1033         gpr += 2;
1034         
1035         /* PCM Surround Playback (independent from stereo mix) */
1036         A_OP(icode, &ptr, iMAC0, A_GPR(playback+2), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LEFT_REAR));
1037         A_OP(icode, &ptr, iMAC0, A_GPR(playback+3), A_C_00000000, A_GPR(gpr+1), A_FXBUS(FXBUS_PCM_RIGHT_REAR));
1038         snd_emu10k1_init_stereo_control(&controls[nctl++], "PCM Surround Playback Volume", gpr, 100);
1039         gpr += 2;
1040         
1041         /* PCM Side Playback (independent from stereo mix) */
1042         if (emu->spk71) {
1043                 A_OP(icode, &ptr, iMAC0, A_GPR(playback+6), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LEFT_SIDE));
1044                 A_OP(icode, &ptr, iMAC0, A_GPR(playback+7), A_C_00000000, A_GPR(gpr+1), A_FXBUS(FXBUS_PCM_RIGHT_SIDE));
1045                 snd_emu10k1_init_stereo_control(&controls[nctl++], "PCM Side Playback Volume", gpr, 100);
1046                 gpr += 2;
1047         }
1048
1049         /* PCM Center Playback (independent from stereo mix) */
1050         A_OP(icode, &ptr, iMAC0, A_GPR(playback+4), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_CENTER));
1051         snd_emu10k1_init_mono_control(&controls[nctl++], "PCM Center Playback Volume", gpr, 100);
1052         gpr++;
1053
1054         /* PCM LFE Playback (independent from stereo mix) */
1055         A_OP(icode, &ptr, iMAC0, A_GPR(playback+5), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LFE));
1056         snd_emu10k1_init_mono_control(&controls[nctl++], "PCM LFE Playback Volume", gpr, 100);
1057         gpr++;
1058         
1059         /*
1060          * Stereo Mix
1061          */
1062         /* Wave (PCM) Playback Volume (will be renamed later) */
1063         A_OP(icode, &ptr, iMAC0, A_GPR(stereo_mix), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LEFT));
1064         A_OP(icode, &ptr, iMAC0, A_GPR(stereo_mix+1), A_C_00000000, A_GPR(gpr+1), A_FXBUS(FXBUS_PCM_RIGHT));
1065         snd_emu10k1_init_stereo_control(&controls[nctl++], "Wave Playback Volume", gpr, 100);
1066         gpr += 2;
1067
1068         /* Music Playback */
1069         A_OP(icode, &ptr, iMAC0, A_GPR(stereo_mix+0), A_GPR(stereo_mix+0), A_GPR(gpr), A_FXBUS(FXBUS_MIDI_LEFT));
1070         A_OP(icode, &ptr, iMAC0, A_GPR(stereo_mix+1), A_GPR(stereo_mix+1), A_GPR(gpr+1), A_FXBUS(FXBUS_MIDI_RIGHT));
1071         snd_emu10k1_init_stereo_control(&controls[nctl++], "Music Playback Volume", gpr, 100);
1072         gpr += 2;
1073
1074         /* Wave (PCM) Capture */
1075         A_OP(icode, &ptr, iMAC0, A_GPR(capture+0), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LEFT));
1076         A_OP(icode, &ptr, iMAC0, A_GPR(capture+1), A_C_00000000, A_GPR(gpr+1), A_FXBUS(FXBUS_PCM_RIGHT));
1077         snd_emu10k1_init_stereo_control(&controls[nctl++], "PCM Capture Volume", gpr, 0);
1078         gpr += 2;
1079
1080         /* Music Capture */
1081         A_OP(icode, &ptr, iMAC0, A_GPR(capture+0), A_GPR(capture+0), A_GPR(gpr), A_FXBUS(FXBUS_MIDI_LEFT));
1082         A_OP(icode, &ptr, iMAC0, A_GPR(capture+1), A_GPR(capture+1), A_GPR(gpr+1), A_FXBUS(FXBUS_MIDI_RIGHT));
1083         snd_emu10k1_init_stereo_control(&controls[nctl++], "Music Capture Volume", gpr, 0);
1084         gpr += 2;
1085
1086         /*
1087          * inputs
1088          */
1089 #define A_ADD_VOLUME_IN(var,vol,input) \
1090 A_OP(icode, &ptr, iMAC0, A_GPR(var), A_GPR(var), A_GPR(vol), A_EXTIN(input))
1091
1092         /* AC'97 Playback Volume - used only for mic (renamed later) */
1093         A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_AC97_L);
1094         A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_AC97_R);
1095         snd_emu10k1_init_stereo_control(&controls[nctl++], "AMic Playback Volume", gpr, 0);
1096         gpr += 2;
1097         /* AC'97 Capture Volume - used only for mic */
1098         A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_AC97_L);
1099         A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_AC97_R);
1100         snd_emu10k1_init_stereo_control(&controls[nctl++], "Mic Capture Volume", gpr, 0);
1101         gpr += 2;
1102
1103         /* mic capture buffer */        
1104         A_OP(icode, &ptr, iINTERP, A_EXTOUT(A_EXTOUT_MIC_CAP), A_EXTIN(A_EXTIN_AC97_L), 0xcd, A_EXTIN(A_EXTIN_AC97_R));
1105
1106         /* Audigy CD Playback Volume */
1107         A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_SPDIF_CD_L);
1108         A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_SPDIF_CD_R);
1109         snd_emu10k1_init_stereo_control(&controls[nctl++],
1110                                         emu->no_ac97 ? "CD Playback Volume" : "Audigy CD Playback Volume",
1111                                         gpr, 0);
1112         gpr += 2;
1113         /* Audigy CD Capture Volume */
1114         A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_SPDIF_CD_L);
1115         A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_SPDIF_CD_R);
1116         snd_emu10k1_init_stereo_control(&controls[nctl++],
1117                                         emu->no_ac97 ? "CD Capture Volume" : "Audigy CD Capture Volume",
1118                                         gpr, 0);
1119         gpr += 2;
1120
1121         /* Optical SPDIF Playback Volume */
1122         A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_OPT_SPDIF_L);
1123         A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_OPT_SPDIF_R);
1124         snd_emu10k1_init_stereo_control(&controls[nctl++], "IEC958 Optical Playback Volume", gpr, 0);
1125         gpr += 2;
1126         /* Optical SPDIF Capture Volume */
1127         A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_OPT_SPDIF_L);
1128         A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_OPT_SPDIF_R);
1129         snd_emu10k1_init_stereo_control(&controls[nctl++], "IEC958 Optical Capture Volume", gpr, 0);
1130         gpr += 2;
1131
1132         /* Line2 Playback Volume */
1133         A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_LINE2_L);
1134         A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_LINE2_R);
1135         snd_emu10k1_init_stereo_control(&controls[nctl++],
1136                                         emu->no_ac97 ? "Line Playback Volume" : "Line2 Playback Volume",
1137                                         gpr, 0);
1138         gpr += 2;
1139         /* Line2 Capture Volume */
1140         A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_LINE2_L);
1141         A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_LINE2_R);
1142         snd_emu10k1_init_stereo_control(&controls[nctl++],
1143                                         emu->no_ac97 ? "Line Capture Volume" : "Line2 Capture Volume",
1144                                         gpr, 0);
1145         gpr += 2;
1146         
1147         /* Philips ADC Playback Volume */
1148         A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_ADC_L);
1149         A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_ADC_R);
1150         snd_emu10k1_init_stereo_control(&controls[nctl++], "Analog Mix Playback Volume", gpr, 0);
1151         gpr += 2;
1152         /* Philips ADC Capture Volume */
1153         A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_ADC_L);
1154         A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_ADC_R);
1155         snd_emu10k1_init_stereo_control(&controls[nctl++], "Analog Mix Capture Volume", gpr, 0);
1156         gpr += 2;
1157
1158         /* Aux2 Playback Volume */
1159         A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_AUX2_L);
1160         A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_AUX2_R);
1161         snd_emu10k1_init_stereo_control(&controls[nctl++],
1162                                         emu->no_ac97 ? "Aux Playback Volume" : "Aux2 Playback Volume",
1163                                         gpr, 0);
1164         gpr += 2;
1165         /* Aux2 Capture Volume */
1166         A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_AUX2_L);
1167         A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_AUX2_R);
1168         snd_emu10k1_init_stereo_control(&controls[nctl++],
1169                                         emu->no_ac97 ? "Aux Capture Volume" : "Aux2 Capture Volume",
1170                                         gpr, 0);
1171         gpr += 2;
1172         
1173         /* Stereo Mix Front Playback Volume */
1174         A_OP(icode, &ptr, iMAC0, A_GPR(playback), A_GPR(playback), A_GPR(gpr), A_GPR(stereo_mix));
1175         A_OP(icode, &ptr, iMAC0, A_GPR(playback+1), A_GPR(playback+1), A_GPR(gpr+1), A_GPR(stereo_mix+1));
1176         snd_emu10k1_init_stereo_control(&controls[nctl++], "Front Playback Volume", gpr, 100);
1177         gpr += 2;
1178         
1179         /* Stereo Mix Surround Playback */
1180         A_OP(icode, &ptr, iMAC0, A_GPR(playback+2), A_GPR(playback+2), A_GPR(gpr), A_GPR(stereo_mix));
1181         A_OP(icode, &ptr, iMAC0, A_GPR(playback+3), A_GPR(playback+3), A_GPR(gpr+1), A_GPR(stereo_mix+1));
1182         snd_emu10k1_init_stereo_control(&controls[nctl++], "Surround Playback Volume", gpr, 0);
1183         gpr += 2;
1184
1185         /* Stereo Mix Center Playback */
1186         /* Center = sub = Left/2 + Right/2 */
1187         A_OP(icode, &ptr, iINTERP, A_GPR(tmp), A_GPR(stereo_mix), 0xcd, A_GPR(stereo_mix+1));
1188         A_OP(icode, &ptr, iMAC0, A_GPR(playback+4), A_GPR(playback+4), A_GPR(gpr), A_GPR(tmp));
1189         snd_emu10k1_init_mono_control(&controls[nctl++], "Center Playback Volume", gpr, 0);
1190         gpr++;
1191
1192         /* Stereo Mix LFE Playback */
1193         A_OP(icode, &ptr, iMAC0, A_GPR(playback+5), A_GPR(playback+5), A_GPR(gpr), A_GPR(tmp));
1194         snd_emu10k1_init_mono_control(&controls[nctl++], "LFE Playback Volume", gpr, 0);
1195         gpr++;
1196         
1197         if (emu->spk71) {
1198                 /* Stereo Mix Side Playback */
1199                 A_OP(icode, &ptr, iMAC0, A_GPR(playback+6), A_GPR(playback+6), A_GPR(gpr), A_GPR(stereo_mix));
1200                 A_OP(icode, &ptr, iMAC0, A_GPR(playback+7), A_GPR(playback+7), A_GPR(gpr+1), A_GPR(stereo_mix+1));
1201                 snd_emu10k1_init_stereo_control(&controls[nctl++], "Side Playback Volume", gpr, 0);
1202                 gpr += 2;
1203         }
1204
1205         /*
1206          * outputs
1207          */
1208 #define A_PUT_OUTPUT(out,src) A_OP(icode, &ptr, iACC3, A_EXTOUT(out), A_C_00000000, A_C_00000000, A_GPR(src))
1209 #define A_PUT_STEREO_OUTPUT(out1,out2,src) \
1210         {A_PUT_OUTPUT(out1,src); A_PUT_OUTPUT(out2,src+1);}
1211
1212 #define _A_SWITCH(icode, ptr, dst, src, sw) \
1213         A_OP((icode), ptr, iMACINT0, dst, A_C_00000000, src, sw);
1214 #define A_SWITCH(icode, ptr, dst, src, sw) \
1215                 _A_SWITCH(icode, ptr, A_GPR(dst), A_GPR(src), A_GPR(sw))
1216 #define _A_SWITCH_NEG(icode, ptr, dst, src) \
1217         A_OP((icode), ptr, iANDXOR, dst, src, A_C_00000001, A_C_00000001);
1218 #define A_SWITCH_NEG(icode, ptr, dst, src) \
1219                 _A_SWITCH_NEG(icode, ptr, A_GPR(dst), A_GPR(src))
1220
1221
1222         /*
1223          *  Process tone control
1224          */
1225         A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 0), A_GPR(playback + 0), A_C_00000000, A_C_00000000); /* left */
1226         A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 1), A_GPR(playback + 1), A_C_00000000, A_C_00000000); /* right */
1227         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 */
1228         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 */
1229         A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 4), A_GPR(playback + 4), A_C_00000000, A_C_00000000); /* center */
1230         A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 5), A_GPR(playback + 5), A_C_00000000, A_C_00000000); /* LFE */
1231         if (emu->spk71) {
1232                 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 */
1233                 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 */
1234         }
1235         
1236
1237         ctl = &controls[nctl + 0];
1238         ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1239         strcpy(ctl->id.name, "Tone Control - Bass");
1240         ctl->vcount = 2;
1241         ctl->count = 10;
1242         ctl->min = 0;
1243         ctl->max = 40;
1244         ctl->value[0] = ctl->value[1] = 20;
1245         ctl->translation = EMU10K1_GPR_TRANSLATION_BASS;
1246         ctl = &controls[nctl + 1];
1247         ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1248         strcpy(ctl->id.name, "Tone Control - Treble");
1249         ctl->vcount = 2;
1250         ctl->count = 10;
1251         ctl->min = 0;
1252         ctl->max = 40;
1253         ctl->value[0] = ctl->value[1] = 20;
1254         ctl->translation = EMU10K1_GPR_TRANSLATION_TREBLE;
1255
1256 #define BASS_GPR        0x8c
1257 #define TREBLE_GPR      0x96
1258
1259         for (z = 0; z < 5; z++) {
1260                 int j;
1261                 for (j = 0; j < 2; j++) {
1262                         controls[nctl + 0].gpr[z * 2 + j] = BASS_GPR + z * 2 + j;
1263                         controls[nctl + 1].gpr[z * 2 + j] = TREBLE_GPR + z * 2 + j;
1264                 }
1265         }
1266         for (z = 0; z < 4; z++) {               /* front/rear/center-lfe/side */
1267                 int j, k, l, d;
1268                 for (j = 0; j < 2; j++) {       /* left/right */
1269                         k = 0xb0 + (z * 8) + (j * 4);
1270                         l = 0xe0 + (z * 8) + (j * 4);
1271                         d = playback + SND_EMU10K1_PLAYBACK_CHANNELS + z * 2 + j;
1272
1273                         A_OP(icode, &ptr, iMAC0, A_C_00000000, A_C_00000000, A_GPR(d), A_GPR(BASS_GPR + 0 + j));
1274                         A_OP(icode, &ptr, iMACMV, A_GPR(k+1), A_GPR(k), A_GPR(k+1), A_GPR(BASS_GPR + 4 + j));
1275                         A_OP(icode, &ptr, iMACMV, A_GPR(k), A_GPR(d), A_GPR(k), A_GPR(BASS_GPR + 2 + j));
1276                         A_OP(icode, &ptr, iMACMV, A_GPR(k+3), A_GPR(k+2), A_GPR(k+3), A_GPR(BASS_GPR + 8 + j));
1277                         A_OP(icode, &ptr, iMAC0, A_GPR(k+2), A_GPR_ACCU, A_GPR(k+2), A_GPR(BASS_GPR + 6 + j));
1278                         A_OP(icode, &ptr, iACC3, A_GPR(k+2), A_GPR(k+2), A_GPR(k+2), A_C_00000000);
1279
1280                         A_OP(icode, &ptr, iMAC0, A_C_00000000, A_C_00000000, A_GPR(k+2), A_GPR(TREBLE_GPR + 0 + j));
1281                         A_OP(icode, &ptr, iMACMV, A_GPR(l+1), A_GPR(l), A_GPR(l+1), A_GPR(TREBLE_GPR + 4 + j));
1282                         A_OP(icode, &ptr, iMACMV, A_GPR(l), A_GPR(k+2), A_GPR(l), A_GPR(TREBLE_GPR + 2 + j));
1283                         A_OP(icode, &ptr, iMACMV, A_GPR(l+3), A_GPR(l+2), A_GPR(l+3), A_GPR(TREBLE_GPR + 8 + j));
1284                         A_OP(icode, &ptr, iMAC0, A_GPR(l+2), A_GPR_ACCU, A_GPR(l+2), A_GPR(TREBLE_GPR + 6 + j));
1285                         A_OP(icode, &ptr, iMACINT0, A_GPR(l+2), A_C_00000000, A_GPR(l+2), A_C_00000010);
1286
1287                         A_OP(icode, &ptr, iACC3, A_GPR(d), A_GPR(l+2), A_C_00000000, A_C_00000000);
1288
1289                         if (z == 2)     /* center */
1290                                 break;
1291                 }
1292         }
1293         nctl += 2;
1294
1295 #undef BASS_GPR
1296 #undef TREBLE_GPR
1297
1298         for (z = 0; z < 8; z++) {
1299                 A_SWITCH(icode, &ptr, tmp + 0, playback + SND_EMU10K1_PLAYBACK_CHANNELS + z, gpr + 0);
1300                 A_SWITCH_NEG(icode, &ptr, tmp + 1, gpr + 0);
1301                 A_SWITCH(icode, &ptr, tmp + 1, playback + z, tmp + 1);
1302                 A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + z), A_GPR(tmp + 0), A_GPR(tmp + 1), A_C_00000000);
1303         }
1304         snd_emu10k1_init_stereo_onoff_control(controls + nctl++, "Tone Control - Switch", gpr, 0);
1305         gpr += 2;
1306
1307         /* Master volume (will be renamed later) */
1308         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));
1309         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));
1310         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));
1311         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));
1312         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));
1313         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));
1314         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));
1315         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));
1316         snd_emu10k1_init_mono_control(&controls[nctl++], "Wave Master Playback Volume", gpr, 0);
1317         gpr += 2;
1318
1319         /* analog speakers */
1320         A_PUT_STEREO_OUTPUT(A_EXTOUT_AFRONT_L, A_EXTOUT_AFRONT_R, playback + SND_EMU10K1_PLAYBACK_CHANNELS);
1321         A_PUT_STEREO_OUTPUT(A_EXTOUT_AREAR_L, A_EXTOUT_AREAR_R, playback+2 + SND_EMU10K1_PLAYBACK_CHANNELS);
1322         A_PUT_OUTPUT(A_EXTOUT_ACENTER, playback+4 + SND_EMU10K1_PLAYBACK_CHANNELS);
1323         A_PUT_OUTPUT(A_EXTOUT_ALFE, playback+5 + SND_EMU10K1_PLAYBACK_CHANNELS);
1324         if (emu->spk71)
1325                 A_PUT_STEREO_OUTPUT(A_EXTOUT_ASIDE_L, A_EXTOUT_ASIDE_R, playback+6 + SND_EMU10K1_PLAYBACK_CHANNELS);
1326
1327         /* headphone */
1328         A_PUT_STEREO_OUTPUT(A_EXTOUT_HEADPHONE_L, A_EXTOUT_HEADPHONE_R, playback + SND_EMU10K1_PLAYBACK_CHANNELS);
1329
1330         /* digital outputs */
1331         /* A_PUT_STEREO_OUTPUT(A_EXTOUT_FRONT_L, A_EXTOUT_FRONT_R, playback + SND_EMU10K1_PLAYBACK_CHANNELS); */
1332
1333         /* IEC958 Optical Raw Playback Switch */ 
1334         icode->gpr_map[gpr++] = 0x1008;
1335         icode->gpr_map[gpr++] = 0xffff0000;
1336         for (z = 0; z < 2; z++) {
1337                 A_OP(icode, &ptr, iMAC0, A_GPR(tmp + 2), A_FXBUS(FXBUS_PT_LEFT + z), A_C_00000000, A_C_00000000);
1338                 A_OP(icode, &ptr, iSKIP, A_GPR_COND, A_GPR_COND, A_GPR(gpr - 2), A_C_00000001);
1339                 A_OP(icode, &ptr, iACC3, A_GPR(tmp + 2), A_C_00000000, A_C_00010000, A_GPR(tmp + 2));
1340                 A_OP(icode, &ptr, iANDXOR, A_GPR(tmp + 2), A_GPR(tmp + 2), A_GPR(gpr - 1), A_C_00000000);
1341                 A_SWITCH(icode, &ptr, tmp + 0, tmp + 2, gpr + z);
1342                 A_SWITCH_NEG(icode, &ptr, tmp + 1, gpr + z);
1343                 A_SWITCH(icode, &ptr, tmp + 1, playback + SND_EMU10K1_PLAYBACK_CHANNELS + z, tmp + 1);
1344                 A_OP(icode, &ptr, iACC3, A_EXTOUT(A_EXTOUT_FRONT_L + z), A_GPR(tmp + 0), A_GPR(tmp + 1), A_C_00000000);
1345         }
1346         snd_emu10k1_init_stereo_onoff_control(controls + nctl++, "IEC958 Optical Raw Playback Switch", gpr, 0);
1347         gpr += 2;
1348         
1349         A_PUT_STEREO_OUTPUT(A_EXTOUT_REAR_L, A_EXTOUT_REAR_R, playback+2 + SND_EMU10K1_PLAYBACK_CHANNELS);
1350         A_PUT_OUTPUT(A_EXTOUT_CENTER, playback+4 + SND_EMU10K1_PLAYBACK_CHANNELS);
1351         A_PUT_OUTPUT(A_EXTOUT_LFE, playback+5 + SND_EMU10K1_PLAYBACK_CHANNELS);
1352
1353         /* ADC buffer */
1354 #ifdef EMU10K1_CAPTURE_DIGITAL_OUT
1355         A_PUT_STEREO_OUTPUT(A_EXTOUT_ADC_CAP_L, A_EXTOUT_ADC_CAP_R, playback + SND_EMU10K1_PLAYBACK_CHANNELS);
1356 #else
1357         A_PUT_OUTPUT(A_EXTOUT_ADC_CAP_L, capture);
1358         A_PUT_OUTPUT(A_EXTOUT_ADC_CAP_R, capture+1);
1359 #endif
1360
1361         /*
1362          * ok, set up done..
1363          */
1364
1365         if (gpr > tmp) {
1366                 snd_BUG();
1367                 err = -EIO;
1368                 goto __err;
1369         }
1370         /* clear remaining instruction memory */
1371         while (ptr < 0x400)
1372                 A_OP(icode, &ptr, 0x0f, 0xc0, 0xc0, 0xcf, 0xc0);
1373
1374         seg = snd_enter_user();
1375         icode->gpr_add_control_count = nctl;
1376         icode->gpr_add_controls = controls;
1377         err = snd_emu10k1_icode_poke(emu, icode);
1378         snd_leave_user(seg);
1379
1380  __err:
1381         if (controls != NULL)
1382                 kfree(controls);
1383         if (icode != NULL) {
1384                 if (icode->gpr_map != NULL)
1385                         kfree(icode->gpr_map);
1386                 kfree(icode);
1387         }
1388         return err;
1389 }
1390
1391
1392 /*
1393  * initial DSP configuration for Emu10k1
1394  */
1395
1396 /* when volume = max, then copy only to avoid volume modification */
1397 /* with iMAC0 (negative values) */
1398 static void __devinit _volume(emu10k1_fx8010_code_t *icode, u32 *ptr, u32 dst, u32 src, u32 vol)
1399 {
1400         OP(icode, ptr, iMAC0, dst, C_00000000, src, vol);
1401         OP(icode, ptr, iANDXOR, C_00000000, vol, C_ffffffff, C_7fffffff);
1402         OP(icode, ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, C_00000001);
1403         OP(icode, ptr, iACC3, dst, src, C_00000000, C_00000000);
1404 }
1405 static void __devinit _volume_add(emu10k1_fx8010_code_t *icode, u32 *ptr, u32 dst, u32 src, u32 vol)
1406 {
1407         OP(icode, ptr, iANDXOR, C_00000000, vol, C_ffffffff, C_7fffffff);
1408         OP(icode, ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, C_00000002);
1409         OP(icode, ptr, iMACINT0, dst, dst, src, C_00000001);
1410         OP(icode, ptr, iSKIP, C_00000000, C_7fffffff, C_7fffffff, C_00000001);
1411         OP(icode, ptr, iMAC0, dst, dst, src, vol);
1412 }
1413 static void __devinit _volume_out(emu10k1_fx8010_code_t *icode, u32 *ptr, u32 dst, u32 src, u32 vol)
1414 {
1415         OP(icode, ptr, iANDXOR, C_00000000, vol, C_ffffffff, C_7fffffff);
1416         OP(icode, ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, C_00000002);
1417         OP(icode, ptr, iACC3, dst, src, C_00000000, C_00000000);
1418         OP(icode, ptr, iSKIP, C_00000000, C_7fffffff, C_7fffffff, C_00000001);
1419         OP(icode, ptr, iMAC0, dst, C_00000000, src, vol);
1420 }
1421
1422 #define VOLUME(icode, ptr, dst, src, vol) \
1423                 _volume(icode, ptr, GPR(dst), GPR(src), GPR(vol))
1424 #define VOLUME_IN(icode, ptr, dst, src, vol) \
1425                 _volume(icode, ptr, GPR(dst), EXTIN(src), GPR(vol))
1426 #define VOLUME_ADD(icode, ptr, dst, src, vol) \
1427                 _volume_add(icode, ptr, GPR(dst), GPR(src), GPR(vol))
1428 #define VOLUME_ADDIN(icode, ptr, dst, src, vol) \
1429                 _volume_add(icode, ptr, GPR(dst), EXTIN(src), GPR(vol))
1430 #define VOLUME_OUT(icode, ptr, dst, src, vol) \
1431                 _volume_out(icode, ptr, EXTOUT(dst), GPR(src), GPR(vol))
1432 #define _SWITCH(icode, ptr, dst, src, sw) \
1433         OP((icode), ptr, iMACINT0, dst, C_00000000, src, sw);
1434 #define SWITCH(icode, ptr, dst, src, sw) \
1435                 _SWITCH(icode, ptr, GPR(dst), GPR(src), GPR(sw))
1436 #define SWITCH_IN(icode, ptr, dst, src, sw) \
1437                 _SWITCH(icode, ptr, GPR(dst), EXTIN(src), GPR(sw))
1438 #define _SWITCH_NEG(icode, ptr, dst, src) \
1439         OP((icode), ptr, iANDXOR, dst, src, C_00000001, C_00000001);
1440 #define SWITCH_NEG(icode, ptr, dst, src) \
1441                 _SWITCH_NEG(icode, ptr, GPR(dst), GPR(src))
1442
1443
1444 static int __devinit _snd_emu10k1_init_efx(emu10k1_t *emu)
1445 {
1446         int err, i, z, gpr, tmp, playback, capture;
1447         u32 ptr;
1448         emu10k1_fx8010_code_t *icode;
1449         emu10k1_fx8010_pcm_t *ipcm = NULL;
1450         emu10k1_fx8010_control_gpr_t *controls = NULL, *ctl;
1451         mm_segment_t seg;
1452
1453         spin_lock_init(&emu->fx8010.irq_lock);
1454         INIT_LIST_HEAD(&emu->fx8010.gpr_ctl);
1455
1456         if ((icode = kcalloc(1, sizeof(*icode), GFP_KERNEL)) == NULL)
1457                 return -ENOMEM;
1458         if ((icode->gpr_map = kcalloc(256 + 160 + 160 + 2 * 512, sizeof(u_int32_t), GFP_KERNEL)) == NULL ||
1459             (controls = kcalloc(SND_EMU10K1_GPR_CONTROLS, sizeof(emu10k1_fx8010_control_gpr_t), GFP_KERNEL)) == NULL ||
1460             (ipcm = kcalloc(1, sizeof(*ipcm), GFP_KERNEL)) == NULL) {
1461                 err = -ENOMEM;
1462                 goto __err;
1463         }
1464
1465         icode->tram_data_map = icode->gpr_map + 256;
1466         icode->tram_addr_map = icode->tram_data_map + 160;
1467         icode->code = icode->tram_addr_map + 160;
1468         
1469         /* clear free GPRs */
1470         for (i = 0; i < 256; i++)
1471                 set_bit(i, icode->gpr_valid);
1472
1473         /* clear TRAM data & address lines */
1474         for (i = 0; i < 160; i++)
1475                 set_bit(i, icode->tram_valid);
1476
1477         strcpy(icode->name, "SB Live! FX8010 code for ALSA v1.2 by Jaroslav Kysela");
1478         ptr = 0; i = 0;
1479         /* we have 10 inputs */
1480         playback = SND_EMU10K1_INPUTS;
1481         /* we have 6 playback channels and tone control doubles */
1482         capture = playback + (SND_EMU10K1_PLAYBACK_CHANNELS * 2);
1483         gpr = capture + SND_EMU10K1_CAPTURE_CHANNELS;
1484         tmp = 0x88;     /* we need 4 temporary GPR */
1485         /* from 0x8c to 0xff is the area for tone control */
1486
1487         /* stop FX processor */
1488         snd_emu10k1_ptr_write(emu, DBG, 0, (emu->fx8010.dbg = 0) | EMU10K1_DBG_SINGLE_STEP);
1489
1490         /*
1491          *  Process FX Buses
1492          */
1493         OP(icode, &ptr, iMACINT0, GPR(0), C_00000000, FXBUS(FXBUS_PCM_LEFT), C_00000004);
1494         OP(icode, &ptr, iMACINT0, GPR(1), C_00000000, FXBUS(FXBUS_PCM_RIGHT), C_00000004);
1495         OP(icode, &ptr, iMACINT0, GPR(2), C_00000000, FXBUS(FXBUS_MIDI_LEFT), C_00000004);
1496         OP(icode, &ptr, iMACINT0, GPR(3), C_00000000, FXBUS(FXBUS_MIDI_RIGHT), C_00000004);
1497         OP(icode, &ptr, iMACINT0, GPR(4), C_00000000, FXBUS(FXBUS_PCM_LEFT_REAR), C_00000004);
1498         OP(icode, &ptr, iMACINT0, GPR(5), C_00000000, FXBUS(FXBUS_PCM_RIGHT_REAR), C_00000004);
1499         OP(icode, &ptr, iMACINT0, GPR(6), C_00000000, FXBUS(FXBUS_PCM_CENTER), C_00000004);
1500         OP(icode, &ptr, iMACINT0, GPR(7), C_00000000, FXBUS(FXBUS_PCM_LFE), C_00000004);
1501         OP(icode, &ptr, iMACINT0, GPR(8), C_00000000, C_00000000, C_00000000);  /* S/PDIF left */
1502         OP(icode, &ptr, iMACINT0, GPR(9), C_00000000, C_00000000, C_00000000);  /* S/PDIF right */
1503
1504         /* Raw S/PDIF PCM */
1505         ipcm->substream = 0;
1506         ipcm->channels = 2;
1507         ipcm->tram_start = 0;
1508         ipcm->buffer_size = (64 * 1024) / 2;
1509         ipcm->gpr_size = gpr++;
1510         ipcm->gpr_ptr = gpr++;
1511         ipcm->gpr_count = gpr++;
1512         ipcm->gpr_tmpcount = gpr++;
1513         ipcm->gpr_trigger = gpr++;
1514         ipcm->gpr_running = gpr++;
1515         ipcm->etram[0] = 0;
1516         ipcm->etram[1] = 1;
1517
1518         icode->gpr_map[gpr + 0] = 0xfffff000;
1519         icode->gpr_map[gpr + 1] = 0xffff0000;
1520         icode->gpr_map[gpr + 2] = 0x70000000;
1521         icode->gpr_map[gpr + 3] = 0x00000007;
1522         icode->gpr_map[gpr + 4] = 0x001f << 11;
1523         icode->gpr_map[gpr + 5] = 0x001c << 11;
1524         icode->gpr_map[gpr + 6] = (0x22  - 0x01) - 1;   /* skip at 01 to 22 */
1525         icode->gpr_map[gpr + 7] = (0x22  - 0x06) - 1;   /* skip at 06 to 22 */
1526         icode->gpr_map[gpr + 8] = 0x2000000 + (2<<11);
1527         icode->gpr_map[gpr + 9] = 0x4000000 + (2<<11);
1528         icode->gpr_map[gpr + 10] = 1<<11;
1529         icode->gpr_map[gpr + 11] = (0x24 - 0x0a) - 1;   /* skip at 0a to 24 */
1530         icode->gpr_map[gpr + 12] = 0;
1531
1532         /* if the trigger flag is not set, skip */
1533         /* 00: */ OP(icode, &ptr, iMAC0, C_00000000, GPR(ipcm->gpr_trigger), C_00000000, C_00000000);
1534         /* 01: */ OP(icode, &ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_ZERO, GPR(gpr + 6));
1535         /* if the running flag is set, we're running */
1536         /* 02: */ OP(icode, &ptr, iMAC0, C_00000000, GPR(ipcm->gpr_running), C_00000000, C_00000000);
1537         /* 03: */ OP(icode, &ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, C_00000004);
1538         /* wait until ((GPR_DBAC>>11) & 0x1f) == 0x1c) */
1539         /* 04: */ OP(icode, &ptr, iANDXOR, GPR(tmp + 0), GPR_DBAC, GPR(gpr + 4), C_00000000);
1540         /* 05: */ OP(icode, &ptr, iMACINT0, C_00000000, GPR(tmp + 0), C_ffffffff, GPR(gpr + 5));
1541         /* 06: */ OP(icode, &ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, GPR(gpr + 7));
1542         /* 07: */ OP(icode, &ptr, iACC3, GPR(gpr + 12), C_00000010, C_00000001, C_00000000);
1543
1544         /* 08: */ OP(icode, &ptr, iANDXOR, GPR(ipcm->gpr_running), GPR(ipcm->gpr_running), C_00000000, C_00000001);
1545         /* 09: */ OP(icode, &ptr, iACC3, GPR(gpr + 12), GPR(gpr + 12), C_ffffffff, C_00000000);
1546         /* 0a: */ OP(icode, &ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, GPR(gpr + 11));
1547         /* 0b: */ OP(icode, &ptr, iACC3, GPR(gpr + 12), C_00000001, C_00000000, C_00000000);
1548
1549         /* 0c: */ OP(icode, &ptr, iANDXOR, GPR(tmp + 0), ETRAM_DATA(ipcm->etram[0]), GPR(gpr + 0), C_00000000);
1550         /* 0d: */ OP(icode, &ptr, iLOG, GPR(tmp + 0), GPR(tmp + 0), GPR(gpr + 3), C_00000000);
1551         /* 0e: */ OP(icode, &ptr, iANDXOR, GPR(8), GPR(tmp + 0), GPR(gpr + 1), GPR(gpr + 2));
1552         /* 0f: */ OP(icode, &ptr, iSKIP, C_00000000, GPR_COND, CC_REG_MINUS, C_00000001);
1553         /* 10: */ OP(icode, &ptr, iANDXOR, GPR(8), GPR(8), GPR(gpr + 1), GPR(gpr + 2));
1554
1555         /* 11: */ OP(icode, &ptr, iANDXOR, GPR(tmp + 0), ETRAM_DATA(ipcm->etram[1]), GPR(gpr + 0), C_00000000);
1556         /* 12: */ OP(icode, &ptr, iLOG, GPR(tmp + 0), GPR(tmp + 0), GPR(gpr + 3), C_00000000);
1557         /* 13: */ OP(icode, &ptr, iANDXOR, GPR(9), GPR(tmp + 0), GPR(gpr + 1), GPR(gpr + 2));
1558         /* 14: */ OP(icode, &ptr, iSKIP, C_00000000, GPR_COND, CC_REG_MINUS, C_00000001);
1559         /* 15: */ OP(icode, &ptr, iANDXOR, GPR(9), GPR(9), GPR(gpr + 1), GPR(gpr + 2));
1560
1561         /* 16: */ OP(icode, &ptr, iACC3, GPR(tmp + 0), GPR(ipcm->gpr_ptr), C_00000001, C_00000000);
1562         /* 17: */ OP(icode, &ptr, iMACINT0, C_00000000, GPR(tmp + 0), C_ffffffff, GPR(ipcm->gpr_size));
1563         /* 18: */ OP(icode, &ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_MINUS, C_00000001);
1564         /* 19: */ OP(icode, &ptr, iACC3, GPR(tmp + 0), C_00000000, C_00000000, C_00000000);
1565         /* 1a: */ OP(icode, &ptr, iACC3, GPR(ipcm->gpr_ptr), GPR(tmp + 0), C_00000000, C_00000000);
1566         
1567         /* 1b: */ OP(icode, &ptr, iACC3, GPR(ipcm->gpr_tmpcount), GPR(ipcm->gpr_tmpcount), C_ffffffff, C_00000000);
1568         /* 1c: */ OP(icode, &ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, C_00000002);
1569         /* 1d: */ OP(icode, &ptr, iACC3, GPR(ipcm->gpr_tmpcount), GPR(ipcm->gpr_count), C_00000000, C_00000000);
1570         /* 1e: */ OP(icode, &ptr, iACC3, GPR_IRQ, C_80000000, C_00000000, C_00000000);
1571         /* 1f: */ OP(icode, &ptr, iANDXOR, GPR(ipcm->gpr_running), GPR(ipcm->gpr_running), C_00000001, C_00010000);
1572
1573         /* 20: */ OP(icode, &ptr, iANDXOR, GPR(ipcm->gpr_running), GPR(ipcm->gpr_running), C_00010000, C_00000001);
1574         /* 21: */ OP(icode, &ptr, iSKIP, C_00000000, C_7fffffff, C_7fffffff, C_00000002);
1575
1576         /* 22: */ OP(icode, &ptr, iMACINT1, ETRAM_ADDR(ipcm->etram[0]), GPR(gpr + 8), GPR_DBAC, C_ffffffff);
1577         /* 23: */ OP(icode, &ptr, iMACINT1, ETRAM_ADDR(ipcm->etram[1]), GPR(gpr + 9), GPR_DBAC, C_ffffffff);
1578
1579         /* 24: */
1580         gpr += 13;
1581
1582         /* Wave Playback Volume */
1583         for (z = 0; z < 2; z++)
1584                 VOLUME(icode, &ptr, playback + z, z, gpr + z);
1585         snd_emu10k1_init_stereo_control(controls + i++, "Wave Playback Volume", gpr, 100);
1586         gpr += 2;
1587
1588         /* Wave Surround Playback Volume */
1589         for (z = 0; z < 2; z++)
1590                 VOLUME(icode, &ptr, playback + 2 + z, z, gpr + z);
1591         snd_emu10k1_init_stereo_control(controls + i++, "Wave Surround Playback Volume", gpr, 0);
1592         gpr += 2;
1593         
1594         /* Wave Center/LFE Playback Volume */
1595         OP(icode, &ptr, iACC3, GPR(tmp + 0), FXBUS(FXBUS_PCM_LEFT), FXBUS(FXBUS_PCM_RIGHT), C_00000000);
1596         OP(icode, &ptr, iMACINT0, GPR(tmp + 0), C_00000000, GPR(tmp + 0), C_00000002);
1597         VOLUME(icode, &ptr, playback + 4, tmp + 0, gpr);
1598         snd_emu10k1_init_mono_control(controls + i++, "Wave Center Playback Volume", gpr++, 0);
1599         VOLUME(icode, &ptr, playback + 5, tmp + 0, gpr);
1600         snd_emu10k1_init_mono_control(controls + i++, "Wave LFE Playback Volume", gpr++, 0);
1601
1602         /* Wave Capture Volume + Switch */
1603         for (z = 0; z < 2; z++) {
1604                 SWITCH(icode, &ptr, tmp + 0, z, gpr + 2 + z);
1605                 VOLUME(icode, &ptr, capture + z, tmp + 0, gpr + z);
1606         }
1607         snd_emu10k1_init_stereo_control(controls + i++, "Wave Capture Volume", gpr, 0);
1608         snd_emu10k1_init_stereo_onoff_control(controls + i++, "Wave Capture Switch", gpr + 2, 0);
1609         gpr += 4;
1610
1611         /* Music Playback Volume */
1612         for (z = 0; z < 2; z++)
1613                 VOLUME_ADD(icode, &ptr, playback + z, 2 + z, gpr + z);
1614         snd_emu10k1_init_stereo_control(controls + i++, "Music Playback Volume", gpr, 100);
1615         gpr += 2;
1616
1617         /* Music Capture Volume + Switch */
1618         for (z = 0; z < 2; z++) {
1619                 SWITCH(icode, &ptr, tmp + 0, 2 + z, gpr + 2 + z);
1620                 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
1621         }
1622         snd_emu10k1_init_stereo_control(controls + i++, "Music Capture Volume", gpr, 0);
1623         snd_emu10k1_init_stereo_onoff_control(controls + i++, "Music Capture Switch", gpr + 2, 0);
1624         gpr += 4;
1625
1626         /* Surround Digital Playback Volume (renamed later without Digital) */
1627         for (z = 0; z < 2; z++)
1628                 VOLUME_ADD(icode, &ptr, playback + 2 + z, 4 + z, gpr + z);
1629         snd_emu10k1_init_stereo_control(controls + i++, "Surround Digital Playback Volume", gpr, 100);
1630         gpr += 2;
1631
1632         /* Surround Capture Volume + Switch */
1633         for (z = 0; z < 2; z++) {
1634                 SWITCH(icode, &ptr, tmp + 0, 4 + z, gpr + 2 + z);
1635                 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
1636         }
1637         snd_emu10k1_init_stereo_control(controls + i++, "Surround Capture Volume", gpr, 0);
1638         snd_emu10k1_init_stereo_onoff_control(controls + i++, "Surround Capture Switch", gpr + 2, 0);
1639         gpr += 4;
1640
1641         /* Center Playback Volume (renamed later without Digital) */
1642         VOLUME_ADD(icode, &ptr, playback + 4, 6, gpr);
1643         snd_emu10k1_init_mono_control(controls + i++, "Center Digital Playback Volume", gpr++, 100);
1644
1645         /* LFE Playback Volume + Switch (renamed later without Digital) */
1646         VOLUME_ADD(icode, &ptr, playback + 5, 7, gpr);
1647         snd_emu10k1_init_mono_control(controls + i++, "LFE Digital Playback Volume", gpr++, 100);
1648
1649         /*
1650          *  Process inputs
1651          */
1652
1653         if (emu->fx8010.extin_mask & ((1<<EXTIN_AC97_L)|(1<<EXTIN_AC97_R))) {
1654                 /* AC'97 Playback Volume */
1655                 VOLUME_ADDIN(icode, &ptr, playback + 0, EXTIN_AC97_L, gpr); gpr++;
1656                 VOLUME_ADDIN(icode, &ptr, playback + 1, EXTIN_AC97_R, gpr); gpr++;
1657                 snd_emu10k1_init_stereo_control(controls + i++, "AC97 Playback Volume", gpr-2, 0);
1658                 /* AC'97 Capture Volume */
1659                 VOLUME_ADDIN(icode, &ptr, capture + 0, EXTIN_AC97_L, gpr); gpr++;
1660                 VOLUME_ADDIN(icode, &ptr, capture + 1, EXTIN_AC97_R, gpr); gpr++;
1661                 snd_emu10k1_init_stereo_control(controls + i++, "AC97 Capture Volume", gpr-2, 100);
1662         }
1663         
1664         if (emu->fx8010.extin_mask & ((1<<EXTIN_SPDIF_CD_L)|(1<<EXTIN_SPDIF_CD_R))) {
1665                 /* IEC958 TTL Playback Volume */
1666                 for (z = 0; z < 2; z++)
1667                         VOLUME_ADDIN(icode, &ptr, playback + z, EXTIN_SPDIF_CD_L + z, gpr + z);
1668                 snd_emu10k1_init_stereo_control(controls + i++, "IEC958 TTL Playback Volume", gpr, 0);
1669                 gpr += 2;
1670         
1671                 /* IEC958 TTL Capture Volume + Switch */
1672                 for (z = 0; z < 2; z++) {
1673                         SWITCH_IN(icode, &ptr, tmp + 0, EXTIN_SPDIF_CD_L + z, gpr + 2 + z);
1674                         VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
1675                 }
1676                 snd_emu10k1_init_stereo_control(controls + i++, "IEC958 TTL Capture Volume", gpr, 0);
1677                 snd_emu10k1_init_stereo_onoff_control(controls + i++, "IEC958 TTL Capture Switch", gpr + 2, 0);
1678                 gpr += 4;
1679         }
1680         
1681         if (emu->fx8010.extin_mask & ((1<<EXTIN_ZOOM_L)|(1<<EXTIN_ZOOM_R))) {
1682                 /* Zoom Video Playback Volume */
1683                 for (z = 0; z < 2; z++)
1684                         VOLUME_ADDIN(icode, &ptr, playback + z, EXTIN_ZOOM_L + z, gpr + z);
1685                 snd_emu10k1_init_stereo_control(controls + i++, "Zoom Video Playback Volume", gpr, 0);
1686                 gpr += 2;
1687         
1688                 /* Zoom Video Capture Volume + Switch */
1689                 for (z = 0; z < 2; z++) {
1690                         SWITCH_IN(icode, &ptr, tmp + 0, EXTIN_ZOOM_L + z, gpr + 2 + z);
1691                         VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
1692                 }
1693                 snd_emu10k1_init_stereo_control(controls + i++, "Zoom Video Capture Volume", gpr, 0);
1694                 snd_emu10k1_init_stereo_onoff_control(controls + i++, "Zoom Video Capture Switch", gpr + 2, 0);
1695                 gpr += 4;
1696         }
1697         
1698         if (emu->fx8010.extin_mask & ((1<<EXTIN_TOSLINK_L)|(1<<EXTIN_TOSLINK_R))) {
1699                 /* IEC958 Optical Playback Volume */
1700                 for (z = 0; z < 2; z++)
1701                         VOLUME_ADDIN(icode, &ptr, playback + z, EXTIN_TOSLINK_L + z, gpr + z);
1702                 snd_emu10k1_init_stereo_control(controls + i++, "IEC958 LiveDrive Playback Volume", gpr, 0);
1703                 gpr += 2;
1704         
1705                 /* IEC958 Optical Capture Volume */
1706                 for (z = 0; z < 2; z++) {
1707                         SWITCH_IN(icode, &ptr, tmp + 0, EXTIN_TOSLINK_L + z, gpr + 2 + z);
1708                         VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
1709                 }
1710                 snd_emu10k1_init_stereo_control(controls + i++, "IEC958 LiveDrive Capture Volume", gpr, 0);
1711                 snd_emu10k1_init_stereo_onoff_control(controls + i++, "IEC958 LiveDrive Capture Switch", gpr + 2, 0);
1712                 gpr += 4;
1713         }
1714         
1715         if (emu->fx8010.extin_mask & ((1<<EXTIN_LINE1_L)|(1<<EXTIN_LINE1_R))) {
1716                 /* Line LiveDrive Playback Volume */
1717                 for (z = 0; z < 2; z++)
1718                         VOLUME_ADDIN(icode, &ptr, playback + z, EXTIN_LINE1_L + z, gpr + z);
1719                 snd_emu10k1_init_stereo_control(controls + i++, "Line LiveDrive Playback Volume", gpr, 0);
1720                 gpr += 2;
1721         
1722                 /* Line LiveDrive Capture Volume + Switch */
1723                 for (z = 0; z < 2; z++) {
1724                         SWITCH_IN(icode, &ptr, tmp + 0, EXTIN_LINE1_L + z, gpr + 2 + z);
1725                         VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
1726                 }
1727                 snd_emu10k1_init_stereo_control(controls + i++, "Line LiveDrive Capture Volume", gpr, 0);
1728                 snd_emu10k1_init_stereo_onoff_control(controls + i++, "Line LiveDrive Capture Switch", gpr + 2, 0);
1729                 gpr += 4;
1730         }
1731         
1732         if (emu->fx8010.extin_mask & ((1<<EXTIN_COAX_SPDIF_L)|(1<<EXTIN_COAX_SPDIF_R))) {
1733                 /* IEC958 Coax Playback Volume */
1734                 for (z = 0; z < 2; z++)
1735                         VOLUME_ADDIN(icode, &ptr, playback + z, EXTIN_COAX_SPDIF_L + z, gpr + z);
1736                 snd_emu10k1_init_stereo_control(controls + i++, "IEC958 Coaxial Playback Volume", gpr, 0);
1737                 gpr += 2;
1738         
1739                 /* IEC958 Coax Capture Volume + Switch */
1740                 for (z = 0; z < 2; z++) {
1741                         SWITCH_IN(icode, &ptr, tmp + 0, EXTIN_COAX_SPDIF_L + z, gpr + 2 + z);
1742                         VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
1743                 }
1744                 snd_emu10k1_init_stereo_control(controls + i++, "IEC958 Coaxial Capture Volume", gpr, 0);
1745                 snd_emu10k1_init_stereo_onoff_control(controls + i++, "IEC958 Coaxial Capture Switch", gpr + 2, 0);
1746                 gpr += 4;
1747         }
1748         
1749         if (emu->fx8010.extin_mask & ((1<<EXTIN_LINE2_L)|(1<<EXTIN_LINE2_R))) {
1750                 /* Line LiveDrive Playback Volume */
1751                 for (z = 0; z < 2; z++)
1752                         VOLUME_ADDIN(icode, &ptr, playback + z, EXTIN_LINE2_L + z, gpr + z);
1753                 snd_emu10k1_init_stereo_control(controls + i++, "Line2 LiveDrive Playback Volume", gpr, 0);
1754                 controls[i-1].id.index = 1;
1755                 gpr += 2;
1756         
1757                 /* Line LiveDrive Capture Volume */
1758                 for (z = 0; z < 2; z++) {
1759                         SWITCH_IN(icode, &ptr, tmp + 0, EXTIN_LINE2_L + z, gpr + 2 + z);
1760                         VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
1761                 }
1762                 snd_emu10k1_init_stereo_control(controls + i++, "Line2 LiveDrive Capture Volume", gpr, 0);
1763                 controls[i-1].id.index = 1;
1764                 snd_emu10k1_init_stereo_onoff_control(controls + i++, "Line2 LiveDrive Capture Switch", gpr + 2, 0);
1765                 controls[i-1].id.index = 1;
1766                 gpr += 4;
1767         }
1768
1769         /*
1770          *  Process tone control
1771          */
1772         OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 0), GPR(playback + 0), C_00000000, C_00000000); /* left */
1773         OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 1), GPR(playback + 1), C_00000000, C_00000000); /* right */
1774         OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 2), GPR(playback + 2), C_00000000, C_00000000); /* rear left */
1775         OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 3), GPR(playback + 3), C_00000000, C_00000000); /* rear right */
1776         OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 4), GPR(playback + 4), C_00000000, C_00000000); /* center */
1777         OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 5), GPR(playback + 5), C_00000000, C_00000000); /* LFE */
1778
1779         ctl = &controls[i + 0];
1780         ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1781         strcpy(ctl->id.name, "Tone Control - Bass");
1782         ctl->vcount = 2;
1783         ctl->count = 10;
1784         ctl->min = 0;
1785         ctl->max = 40;
1786         ctl->value[0] = ctl->value[1] = 20;
1787         ctl->translation = EMU10K1_GPR_TRANSLATION_BASS;
1788         ctl = &controls[i + 1];
1789         ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1790         strcpy(ctl->id.name, "Tone Control - Treble");
1791         ctl->vcount = 2;
1792         ctl->count = 10;
1793         ctl->min = 0;
1794         ctl->max = 40;
1795         ctl->value[0] = ctl->value[1] = 20;
1796         ctl->translation = EMU10K1_GPR_TRANSLATION_TREBLE;
1797
1798 #define BASS_GPR        0x8c
1799 #define TREBLE_GPR      0x96
1800
1801         for (z = 0; z < 5; z++) {
1802                 int j;
1803                 for (j = 0; j < 2; j++) {
1804                         controls[i + 0].gpr[z * 2 + j] = BASS_GPR + z * 2 + j;
1805                         controls[i + 1].gpr[z * 2 + j] = TREBLE_GPR + z * 2 + j;
1806                 }
1807         }
1808         for (z = 0; z < 3; z++) {               /* front/rear/center-lfe */
1809                 int j, k, l, d;
1810                 for (j = 0; j < 2; j++) {       /* left/right */
1811                         k = 0xa0 + (z * 8) + (j * 4);
1812                         l = 0xd0 + (z * 8) + (j * 4);
1813                         d = playback + SND_EMU10K1_PLAYBACK_CHANNELS + z * 2 + j;
1814
1815                         OP(icode, &ptr, iMAC0, C_00000000, C_00000000, GPR(d), GPR(BASS_GPR + 0 + j));
1816                         OP(icode, &ptr, iMACMV, GPR(k+1), GPR(k), GPR(k+1), GPR(BASS_GPR + 4 + j));
1817                         OP(icode, &ptr, iMACMV, GPR(k), GPR(d), GPR(k), GPR(BASS_GPR + 2 + j));
1818                         OP(icode, &ptr, iMACMV, GPR(k+3), GPR(k+2), GPR(k+3), GPR(BASS_GPR + 8 + j));
1819                         OP(icode, &ptr, iMAC0, GPR(k+2), GPR_ACCU, GPR(k+2), GPR(BASS_GPR + 6 + j));
1820                         OP(icode, &ptr, iACC3, GPR(k+2), GPR(k+2), GPR(k+2), C_00000000);
1821
1822                         OP(icode, &ptr, iMAC0, C_00000000, C_00000000, GPR(k+2), GPR(TREBLE_GPR + 0 + j));
1823                         OP(icode, &ptr, iMACMV, GPR(l+1), GPR(l), GPR(l+1), GPR(TREBLE_GPR + 4 + j));
1824                         OP(icode, &ptr, iMACMV, GPR(l), GPR(k+2), GPR(l), GPR(TREBLE_GPR + 2 + j));
1825                         OP(icode, &ptr, iMACMV, GPR(l+3), GPR(l+2), GPR(l+3), GPR(TREBLE_GPR + 8 + j));
1826                         OP(icode, &ptr, iMAC0, GPR(l+2), GPR_ACCU, GPR(l+2), GPR(TREBLE_GPR + 6 + j));
1827                         OP(icode, &ptr, iMACINT0, GPR(l+2), C_00000000, GPR(l+2), C_00000010);
1828
1829                         OP(icode, &ptr, iACC3, GPR(d), GPR(l+2), C_00000000, C_00000000);
1830
1831                         if (z == 2)     /* center */
1832                                 break;
1833                 }
1834         }
1835         i += 2;
1836
1837 #undef BASS_GPR
1838 #undef TREBLE_GPR
1839
1840         for (z = 0; z < 6; z++) {
1841                 SWITCH(icode, &ptr, tmp + 0, playback + SND_EMU10K1_PLAYBACK_CHANNELS + z, gpr + 0);
1842                 SWITCH_NEG(icode, &ptr, tmp + 1, gpr + 0);
1843                 SWITCH(icode, &ptr, tmp + 1, playback + z, tmp + 1);
1844                 OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + z), GPR(tmp + 0), GPR(tmp + 1), C_00000000);
1845         }
1846         snd_emu10k1_init_stereo_onoff_control(controls + i++, "Tone Control - Switch", gpr, 0);
1847         gpr += 2;
1848
1849         /*
1850          *  Process outputs
1851          */
1852         if (emu->fx8010.extout_mask & ((1<<EXTOUT_AC97_L)|(1<<EXTOUT_AC97_R))) {
1853                 /* AC'97 Playback Volume */
1854
1855                 for (z = 0; z < 2; z++)
1856                         OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_AC97_L + z), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + z), C_00000000, C_00000000);
1857         }
1858
1859         if (emu->fx8010.extout_mask & ((1<<EXTOUT_TOSLINK_L)|(1<<EXTOUT_TOSLINK_R))) {
1860                 /* IEC958 Optical Raw Playback Switch */
1861
1862                 for (z = 0; z < 2; z++) {
1863                         SWITCH(icode, &ptr, tmp + 0, 8 + z, gpr + z);
1864                         SWITCH_NEG(icode, &ptr, tmp + 1, gpr + z);
1865                         SWITCH(icode, &ptr, tmp + 1, playback + SND_EMU10K1_PLAYBACK_CHANNELS + z, tmp + 1);
1866                         OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_TOSLINK_L + z), GPR(tmp + 0), GPR(tmp + 1), C_00000000);
1867 #ifdef EMU10K1_CAPTURE_DIGITAL_OUT
1868                         OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_ADC_CAP_L + z), GPR(tmp + 0), GPR(tmp + 1), C_00000000);
1869 #endif
1870                 }
1871
1872                 snd_emu10k1_init_stereo_onoff_control(controls + i++, "IEC958 Optical Raw Playback Switch", gpr, 0);
1873                 gpr += 2;
1874         }
1875
1876         if (emu->fx8010.extout_mask & ((1<<EXTOUT_HEADPHONE_L)|(1<<EXTOUT_HEADPHONE_R))) {
1877                 /* Headphone Playback Volume */
1878
1879                 for (z = 0; z < 2; z++) {
1880                         SWITCH(icode, &ptr, tmp + 0, playback + SND_EMU10K1_PLAYBACK_CHANNELS + 4 + z, gpr + 2 + z);
1881                         SWITCH_NEG(icode, &ptr, tmp + 1, gpr + 2 + z);
1882                         SWITCH(icode, &ptr, tmp + 1, playback + SND_EMU10K1_PLAYBACK_CHANNELS + z, tmp + 1);
1883                         OP(icode, &ptr, iACC3, GPR(tmp + 0), GPR(tmp + 0), GPR(tmp + 1), C_00000000);
1884                         VOLUME_OUT(icode, &ptr, EXTOUT_HEADPHONE_L + z, tmp + 0, gpr + z);
1885                 }
1886
1887                 snd_emu10k1_init_stereo_control(controls + i++, "Headphone Playback Volume", gpr + 0, 0);
1888                 controls[i-1].id.index = 1;     /* AC'97 can have also Headphone control */
1889                 snd_emu10k1_init_mono_onoff_control(controls + i++, "Headphone Center Playback Switch", gpr + 2, 0);
1890                 controls[i-1].id.index = 1;
1891                 snd_emu10k1_init_mono_onoff_control(controls + i++, "Headphone LFE Playback Switch", gpr + 3, 0);
1892                 controls[i-1].id.index = 1;
1893
1894                 gpr += 4;
1895         }
1896         
1897         if (emu->fx8010.extout_mask & ((1<<EXTOUT_REAR_L)|(1<<EXTOUT_REAR_R)))
1898                 for (z = 0; z < 2; z++)
1899                         OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_REAR_L + z), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 2 + z), C_00000000, C_00000000);
1900
1901         if (emu->fx8010.extout_mask & ((1<<EXTOUT_AC97_REAR_L)|(1<<EXTOUT_AC97_REAR_R)))
1902                 for (z = 0; z < 2; z++)
1903                         OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_AC97_REAR_L + z), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 2 + z), C_00000000, C_00000000);
1904
1905         if (emu->fx8010.extout_mask & (1<<EXTOUT_AC97_CENTER)) {
1906 #ifndef EMU10K1_CENTER_LFE_FROM_FRONT
1907                 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_AC97_CENTER), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 4), C_00000000, C_00000000);
1908                 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_ACENTER), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 4), C_00000000, C_00000000);
1909 #else
1910                 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_AC97_CENTER), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 0), C_00000000, C_00000000);
1911                 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_ACENTER), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 0), C_00000000, C_00000000);
1912 #endif
1913         }
1914
1915         if (emu->fx8010.extout_mask & (1<<EXTOUT_AC97_LFE)) {
1916 #ifndef EMU10K1_CENTER_LFE_FROM_FRONT
1917                 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_AC97_LFE), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 5), C_00000000, C_00000000);
1918                 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_ALFE), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 5), C_00000000, C_00000000);
1919 #else
1920                 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_AC97_LFE), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 1), C_00000000, C_00000000);
1921                 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_ALFE), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 1), C_00000000, C_00000000);
1922 #endif
1923         }
1924         
1925 #ifndef EMU10K1_CAPTURE_DIGITAL_OUT
1926         for (z = 0; z < 2; z++)
1927                 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_ADC_CAP_L + z), GPR(capture + z), C_00000000, C_00000000);
1928 #endif
1929         
1930         if (emu->fx8010.extout_mask & (1<<EXTOUT_MIC_CAP))
1931                 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_MIC_CAP), GPR(capture + 2), C_00000000, C_00000000);
1932
1933         if (gpr > tmp) {
1934                 snd_BUG();
1935                 err = -EIO;
1936                 goto __err;
1937         }
1938         if (i > SND_EMU10K1_GPR_CONTROLS) {
1939                 snd_BUG();
1940                 err = -EIO;
1941                 goto __err;
1942         }
1943         
1944         /* clear remaining instruction memory */
1945         while (ptr < 0x200)
1946                 OP(icode, &ptr, iACC3, C_00000000, C_00000000, C_00000000, C_00000000);
1947
1948         if ((err = snd_emu10k1_fx8010_tram_setup(emu, ipcm->buffer_size)) < 0)
1949                 goto __err;
1950         seg = snd_enter_user();
1951         icode->gpr_add_control_count = i;
1952         icode->gpr_add_controls = controls;
1953         err = snd_emu10k1_icode_poke(emu, icode);
1954         snd_leave_user(seg);
1955         if (err >= 0)
1956                 err = snd_emu10k1_ipcm_poke(emu, ipcm);
1957       __err:
1958         if (ipcm != NULL)
1959                 kfree(ipcm);
1960         if (controls != NULL)
1961                 kfree(controls);
1962         if (icode != NULL) {
1963                 if (icode->gpr_map != NULL)
1964                         kfree(icode->gpr_map);
1965                 kfree(icode);
1966         }
1967         return err;
1968 }
1969
1970 int __devinit snd_emu10k1_init_efx(emu10k1_t *emu)
1971 {
1972         if (emu->audigy)
1973                 return _snd_emu10k1_audigy_init_efx(emu);
1974         else
1975                 return _snd_emu10k1_init_efx(emu);
1976 }
1977
1978 void snd_emu10k1_free_efx(emu10k1_t *emu)
1979 {
1980         /* stop processor */
1981         if (emu->audigy)
1982                 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg = A_DBG_SINGLE_STEP);
1983         else
1984                 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg = EMU10K1_DBG_SINGLE_STEP);
1985 }
1986
1987 #if 0 // FIXME: who use them?
1988 int snd_emu10k1_fx8010_tone_control_activate(emu10k1_t *emu, int output)
1989 {
1990         snd_runtime_check(output >= 0 && output < 6, return -EINVAL);
1991         snd_emu10k1_ptr_write(emu, emu->gpr_base + 0x94 + output, 0, 1);
1992         return 0;
1993 }
1994
1995 int snd_emu10k1_fx8010_tone_control_deactivate(emu10k1_t *emu, int output)
1996 {
1997         snd_runtime_check(output >= 0 && output < 6, return -EINVAL);
1998         snd_emu10k1_ptr_write(emu, emu->gpr_base + 0x94 + output, 0, 0);
1999         return 0;
2000 }
2001 #endif
2002
2003 int snd_emu10k1_fx8010_tram_setup(emu10k1_t *emu, u32 size)
2004 {
2005         u8 size_reg = 0;
2006
2007         /* size is in samples */
2008         if (size != 0) {
2009                 size = (size - 1) >> 13;
2010
2011                 while (size) {
2012                         size >>= 1;
2013                         size_reg++;
2014                 }
2015                 size = 0x2000 << size_reg;
2016         }
2017         if ((emu->fx8010.etram_pages.bytes / 2) == size)
2018                 return 0;
2019         spin_lock_irq(&emu->emu_lock);
2020         outl(HCFG_LOCKTANKCACHE_MASK | inl(emu->port + HCFG), emu->port + HCFG);
2021         spin_unlock_irq(&emu->emu_lock);
2022         snd_emu10k1_ptr_write(emu, TCB, 0, 0);
2023         snd_emu10k1_ptr_write(emu, TCBS, 0, 0);
2024         if (emu->fx8010.etram_pages.area != NULL) {
2025                 snd_dma_free_pages(&emu->fx8010.etram_pages);
2026                 emu->fx8010.etram_pages.area = NULL;
2027                 emu->fx8010.etram_pages.bytes = 0;
2028         }
2029
2030         if (size > 0) {
2031                 if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(emu->pci),
2032                                         size * 2, &emu->fx8010.etram_pages) < 0)
2033                         return -ENOMEM;
2034                 memset(emu->fx8010.etram_pages.area, 0, size * 2);
2035                 snd_emu10k1_ptr_write(emu, TCB, 0, emu->fx8010.etram_pages.addr);
2036                 snd_emu10k1_ptr_write(emu, TCBS, 0, size_reg);
2037                 spin_lock_irq(&emu->emu_lock);
2038                 outl(inl(emu->port + HCFG) & ~HCFG_LOCKTANKCACHE_MASK, emu->port + HCFG);
2039                 spin_unlock_irq(&emu->emu_lock);        
2040         }
2041
2042         return 0;
2043 }
2044
2045 static int snd_emu10k1_fx8010_open(snd_hwdep_t * hw, struct file *file)
2046 {
2047         return 0;
2048 }
2049
2050 static void copy_string(char *dst, char *src, char *null, int idx)
2051 {
2052         if (src == NULL)
2053                 sprintf(dst, "%s %02X", null, idx);
2054         else
2055                 strcpy(dst, src);
2056 }
2057
2058 static int snd_emu10k1_fx8010_info(emu10k1_t *emu, emu10k1_fx8010_info_t *info)
2059 {
2060         char **fxbus, **extin, **extout;
2061         unsigned short fxbus_mask, extin_mask, extout_mask;
2062         int res;
2063
2064         memset(info, 0, sizeof(info));
2065         info->card = emu->card_type;
2066         info->internal_tram_size = emu->fx8010.itram_size;
2067         info->external_tram_size = emu->fx8010.etram_pages.bytes;
2068         fxbus = fxbuses;
2069         extin = emu->audigy ? audigy_ins : creative_ins;
2070         extout = emu->audigy ? audigy_outs : creative_outs;
2071         fxbus_mask = emu->fx8010.fxbus_mask;
2072         extin_mask = emu->fx8010.extin_mask;
2073         extout_mask = emu->fx8010.extout_mask;
2074         for (res = 0; res < 16; res++, fxbus++, extin++, extout++) {
2075                 copy_string(info->fxbus_names[res], fxbus_mask & (1 << res) ? *fxbus : NULL, "FXBUS", res);
2076                 copy_string(info->extin_names[res], extin_mask & (1 << res) ? *extin : NULL, "Unused", res);
2077                 copy_string(info->extout_names[res], extout_mask & (1 << res) ? *extout : NULL, "Unused", res);
2078         }
2079         for (res = 16; res < 32; res++, extout++)
2080                 copy_string(info->extout_names[res], extout_mask & (1 << res) ? *extout : NULL, "Unused", res);
2081         info->gpr_controls = emu->fx8010.gpr_count;
2082         return 0;
2083 }
2084
2085 static int snd_emu10k1_fx8010_ioctl(snd_hwdep_t * hw, struct file *file, unsigned int cmd, unsigned long arg)
2086 {
2087         emu10k1_t *emu = hw->private_data;
2088         emu10k1_fx8010_info_t *info;
2089         emu10k1_fx8010_code_t *icode;
2090         emu10k1_fx8010_pcm_t *ipcm;
2091         unsigned int addr;
2092         void __user *argp = (void __user *)arg;
2093         int res;
2094         
2095         switch (cmd) {
2096         case SNDRV_EMU10K1_IOCTL_INFO:
2097                 info = (emu10k1_fx8010_info_t *)kmalloc(sizeof(*info), GFP_KERNEL);
2098                 if (!info)
2099                         return -ENOMEM;
2100                 if ((res = snd_emu10k1_fx8010_info(emu, info)) < 0) {
2101                         kfree(info);
2102                         return res;
2103                 }
2104                 if (copy_to_user(argp, info, sizeof(*info))) {
2105                         kfree(info);
2106                         return -EFAULT;
2107                 }
2108                 kfree(info);
2109                 return 0;
2110         case SNDRV_EMU10K1_IOCTL_CODE_POKE:
2111                 if (!capable(CAP_SYS_ADMIN))
2112                         return -EPERM;
2113                 icode = (emu10k1_fx8010_code_t *)kmalloc(sizeof(*icode), GFP_KERNEL);
2114                 if (icode == NULL)
2115                         return -ENOMEM;
2116                 if (copy_from_user(icode, argp, sizeof(*icode))) {
2117                         kfree(icode);
2118                         return -EFAULT;
2119                 }
2120                 res = snd_emu10k1_icode_poke(emu, icode);
2121                 kfree(icode);
2122                 return res;
2123         case SNDRV_EMU10K1_IOCTL_CODE_PEEK:
2124                 icode = (emu10k1_fx8010_code_t *)kmalloc(sizeof(*icode), GFP_KERNEL);
2125                 if (icode == NULL)
2126                         return -ENOMEM;
2127                 if (copy_from_user(icode, argp, sizeof(*icode))) {
2128                         kfree(icode);
2129                         return -EFAULT;
2130                 }
2131                 res = snd_emu10k1_icode_peek(emu, icode);
2132                 if (res == 0 && copy_to_user(argp, icode, sizeof(*icode))) {
2133                         kfree(icode);
2134                         return -EFAULT;
2135                 }
2136                 kfree(icode);
2137                 return res;
2138         case SNDRV_EMU10K1_IOCTL_PCM_POKE:
2139                 ipcm = (emu10k1_fx8010_pcm_t *)kmalloc(sizeof(*ipcm), GFP_KERNEL);
2140                 if (ipcm == NULL)
2141                         return -ENOMEM;
2142                 if (copy_from_user(ipcm, argp, sizeof(*ipcm))) {
2143                         kfree(ipcm);
2144                         return -EFAULT;
2145                 }
2146                 res = snd_emu10k1_ipcm_poke(emu, ipcm);
2147                 kfree(ipcm);
2148                 return res;
2149         case SNDRV_EMU10K1_IOCTL_PCM_PEEK:
2150                 ipcm = kcalloc(1, sizeof(*ipcm), GFP_KERNEL);
2151                 if (ipcm == NULL)
2152                         return -ENOMEM;
2153                 if (copy_from_user(ipcm, argp, sizeof(*ipcm))) {
2154                         kfree(ipcm);
2155                         return -EFAULT;
2156                 }
2157                 res = snd_emu10k1_ipcm_peek(emu, ipcm);
2158                 if (res == 0 && copy_to_user(argp, ipcm, sizeof(*ipcm))) {
2159                         kfree(ipcm);
2160                         return -EFAULT;
2161                 }
2162                 kfree(ipcm);
2163                 return res;
2164         case SNDRV_EMU10K1_IOCTL_TRAM_SETUP:
2165                 if (!capable(CAP_SYS_ADMIN))
2166                         return -EPERM;
2167                 if (get_user(addr, (unsigned int __user *)argp))
2168                         return -EFAULT;
2169                 down(&emu->fx8010.lock);
2170                 res = snd_emu10k1_fx8010_tram_setup(emu, addr);
2171                 up(&emu->fx8010.lock);
2172                 return res;
2173         case SNDRV_EMU10K1_IOCTL_STOP:
2174                 if (!capable(CAP_SYS_ADMIN))
2175                         return -EPERM;
2176                 if (emu->audigy)
2177                         snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg |= A_DBG_SINGLE_STEP);
2178                 else
2179                         snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg |= EMU10K1_DBG_SINGLE_STEP);
2180                 return 0;
2181         case SNDRV_EMU10K1_IOCTL_CONTINUE:
2182                 if (!capable(CAP_SYS_ADMIN))
2183                         return -EPERM;
2184                 if (emu->audigy)
2185                         snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg = 0);
2186                 else
2187                         snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg = 0);
2188                 return 0;
2189         case SNDRV_EMU10K1_IOCTL_ZERO_TRAM_COUNTER:
2190                 if (!capable(CAP_SYS_ADMIN))
2191                         return -EPERM;
2192                 if (emu->audigy)
2193                         snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg | A_DBG_ZC);
2194                 else
2195                         snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg | EMU10K1_DBG_ZC);
2196                 udelay(10);
2197                 if (emu->audigy)
2198                         snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg);
2199                 else
2200                         snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg);
2201                 return 0;
2202         case SNDRV_EMU10K1_IOCTL_SINGLE_STEP:
2203                 if (!capable(CAP_SYS_ADMIN))
2204                         return -EPERM;
2205                 if (get_user(addr, (unsigned int __user *)argp))
2206                         return -EFAULT;
2207                 if (addr > 0x1ff)
2208                         return -EINVAL;
2209                 if (emu->audigy)
2210                         snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg |= A_DBG_SINGLE_STEP | addr);
2211                 else
2212                         snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg |= EMU10K1_DBG_SINGLE_STEP | addr);
2213                 udelay(10);
2214                 if (emu->audigy)
2215                         snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg |= A_DBG_SINGLE_STEP | A_DBG_STEP_ADDR | addr);
2216                 else
2217                         snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg |= EMU10K1_DBG_SINGLE_STEP | EMU10K1_DBG_STEP | addr);
2218                 return 0;
2219         case SNDRV_EMU10K1_IOCTL_DBG_READ:
2220                 if (emu->audigy)
2221                         addr = snd_emu10k1_ptr_read(emu, A_DBG, 0);
2222                 else
2223                         addr = snd_emu10k1_ptr_read(emu, DBG, 0);
2224                 if (put_user(addr, (unsigned int __user *)argp))
2225                         return -EFAULT;
2226                 return 0;
2227         }
2228         return -ENOTTY;
2229 }
2230
2231 static int snd_emu10k1_fx8010_release(snd_hwdep_t * hw, struct file *file)
2232 {
2233         return 0;
2234 }
2235
2236 int __devinit snd_emu10k1_fx8010_new(emu10k1_t *emu, int device, snd_hwdep_t ** rhwdep)
2237 {
2238         snd_hwdep_t *hw;
2239         int err;
2240         
2241         if (rhwdep)
2242                 *rhwdep = NULL;
2243         if ((err = snd_hwdep_new(emu->card, "FX8010", device, &hw)) < 0)
2244                 return err;
2245         strcpy(hw->name, "EMU10K1 (FX8010)");
2246         hw->iface = SNDRV_HWDEP_IFACE_EMU10K1;
2247         hw->ops.open = snd_emu10k1_fx8010_open;
2248         hw->ops.ioctl = snd_emu10k1_fx8010_ioctl;
2249         hw->ops.release = snd_emu10k1_fx8010_release;
2250         hw->private_data = emu;
2251         if (rhwdep)
2252                 *rhwdep = hw;
2253         return 0;
2254 }