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