2 * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
4 * Routines for effect processor FX8010
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.
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.
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
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>
36 #if 0 /* for testing purposes - digital out -> capture */
37 #define EMU10K1_CAPTURE_DIGITAL_OUT
39 #if 0 /* for testing purposes - set S/PDIF to AC3 output */
40 #define EMU10K1_SET_AC3_IEC958
42 #if 0 /* for testing purposes - feed the front signal to Center/LFE outputs */
43 #define EMU10K1_CENTER_LFE_FROM_FRONT
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",
63 /* 0x0c */ "MIDI Reverb",
64 /* 0x0d */ "MIDI Chorus",
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",
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",
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",
107 static char *creative_outs[32] = {
108 /* 0x00 */ "AC97 Left",
109 /* 0x01 */ "AC97 Right",
110 /* 0x02 */ "Optical IEC958 Left",
111 /* 0x03 */ "Optical IEC958 Right",
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",
125 /* 0x11 */ "Analog Center",
126 /* 0x12 */ "Analog LFE",
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",
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",
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 }
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 }
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,
289 static const u32 onoff_table[2] = {
290 0x00000000, 0x00000001
296 static inline mm_segment_t snd_enter_user(void)
298 mm_segment_t fs = get_fs();
303 static inline void snd_leave_user(mm_segment_t fs)
312 static int snd_emu10k1_gpr_ctl_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
314 snd_emu10k1_fx8010_ctl_t *ctl = (snd_emu10k1_fx8010_ctl_t *)kcontrol->private_value;
316 if (ctl->min == 0 && ctl->max == 1)
317 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
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;
326 static int snd_emu10k1_gpr_ctl_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
328 emu10k1_t *emu = snd_kcontrol_chip(kcontrol);
329 snd_emu10k1_fx8010_ctl_t *ctl = (snd_emu10k1_fx8010_ctl_t *)kcontrol->private_value;
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);
340 static int snd_emu10k1_gpr_ctl_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
342 emu10k1_t *emu = snd_kcontrol_chip(kcontrol);
343 snd_emu10k1_fx8010_ctl_t *ctl = (snd_emu10k1_fx8010_ctl_t *)kcontrol->private_value;
345 unsigned int nval, val;
349 spin_lock_irqsave(&emu->reg_lock, flags);
350 for (i = 0; i < ctl->vcount; i++) {
351 nval = ucontrol->value.integer.value[i];
356 if (nval != ctl->value[i])
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);
363 case EMU10K1_GPR_TRANSLATION_TABLE100:
364 snd_emu10k1_ptr_write(emu, emu->gpr_base + ctl->gpr[i], 0, db_table[val]);
366 case EMU10K1_GPR_TRANSLATION_BASS:
367 if ((ctl->count % 5) != 0 || (ctl->count / 5) != ctl->vcount) {
371 for (j = 0; j < 5; j++)
372 snd_emu10k1_ptr_write(emu, emu->gpr_base + ctl->gpr[j * ctl->vcount + i], 0, bass_table[val][j]);
374 case EMU10K1_GPR_TRANSLATION_TREBLE:
375 if ((ctl->count % 5) != 0 || (ctl->count / 5) != ctl->vcount) {
379 for (j = 0; j < 5; j++)
380 snd_emu10k1_ptr_write(emu, emu->gpr_base + ctl->gpr[j * ctl->vcount + i], 0, treble_table[val][j]);
382 case EMU10K1_GPR_TRANSLATION_ONOFF:
383 snd_emu10k1_ptr_write(emu, emu->gpr_base + ctl->gpr[i], 0, onoff_table[val]);
388 spin_unlock_irqrestore(&emu->reg_lock, flags);
396 static void snd_emu10k1_fx8010_interrupt(emu10k1_t *emu)
398 snd_emu10k1_fx8010_irq_t *irq, *nirq;
400 irq = emu->fx8010.irq_handlers;
402 nirq = irq->next; /* irq ptr can be removed from list */
403 if (snd_emu10k1_ptr_read(emu, emu->gpr_base + irq->gpr_running, 0) & 0xffff0000) {
405 irq->handler(emu, irq->private_data);
406 snd_emu10k1_ptr_write(emu, emu->gpr_base + irq->gpr_running, 0, 1);
412 int snd_emu10k1_fx8010_register_irq_handler(emu10k1_t *emu,
413 snd_fx8010_irq_handler_t *handler,
414 unsigned char gpr_running,
416 snd_emu10k1_fx8010_irq_t **r_irq)
418 snd_emu10k1_fx8010_irq_t *irq;
421 irq = kmalloc(sizeof(*irq), GFP_ATOMIC);
424 irq->handler = handler;
425 irq->gpr_running = gpr_running;
426 irq->private_data = private_data;
428 spin_lock_irqsave(&emu->fx8010.irq_lock, flags);
429 if (emu->fx8010.irq_handlers == NULL) {
430 emu->fx8010.irq_handlers = irq;
431 emu->dsp_interrupt = snd_emu10k1_fx8010_interrupt;
432 snd_emu10k1_intr_enable(emu, INTE_FXDSPENABLE);
434 irq->next = emu->fx8010.irq_handlers;
435 emu->fx8010.irq_handlers = irq;
437 spin_unlock_irqrestore(&emu->fx8010.irq_lock, flags);
443 int snd_emu10k1_fx8010_unregister_irq_handler(emu10k1_t *emu,
444 snd_emu10k1_fx8010_irq_t *irq)
446 snd_emu10k1_fx8010_irq_t *tmp;
449 spin_lock_irqsave(&emu->fx8010.irq_lock, flags);
450 if ((tmp = emu->fx8010.irq_handlers) == irq) {
451 emu->fx8010.irq_handlers = tmp->next;
452 if (emu->fx8010.irq_handlers == NULL) {
453 snd_emu10k1_intr_disable(emu, INTE_FXDSPENABLE);
454 emu->dsp_interrupt = NULL;
457 while (tmp && tmp->next != irq)
460 tmp->next = tmp->next->next;
462 spin_unlock_irqrestore(&emu->fx8010.irq_lock, flags);
467 /*************************************************************************
468 * EMU10K1 effect manager
469 *************************************************************************/
471 static void snd_emu10k1_write_op(emu10k1_fx8010_code_t *icode, unsigned int *ptr,
472 u32 op, u32 r, u32 a, u32 x, u32 y)
475 snd_assert(*ptr < 512, return);
476 code = (u_int32_t __force *)icode->code + (*ptr) * 2;
477 set_bit(*ptr, icode->code_valid);
478 code[0] = ((x & 0x3ff) << 10) | (y & 0x3ff);
479 code[1] = ((op & 0x0f) << 20) | ((r & 0x3ff) << 10) | (a & 0x3ff);
483 #define OP(icode, ptr, op, r, a, x, y) \
484 snd_emu10k1_write_op(icode, ptr, op, r, a, x, y)
486 static void snd_emu10k1_audigy_write_op(emu10k1_fx8010_code_t *icode, unsigned int *ptr,
487 u32 op, u32 r, u32 a, u32 x, u32 y)
490 snd_assert(*ptr < 1024, return);
491 code = (u_int32_t __force *)icode->code + (*ptr) * 2;
492 set_bit(*ptr, icode->code_valid);
493 code[0] = ((x & 0x7ff) << 12) | (y & 0x7ff);
494 code[1] = ((op & 0x0f) << 24) | ((r & 0x7ff) << 12) | (a & 0x7ff);
498 #define A_OP(icode, ptr, op, r, a, x, y) \
499 snd_emu10k1_audigy_write_op(icode, ptr, op, r, a, x, y)
501 static void snd_emu10k1_efx_write(emu10k1_t *emu, unsigned int pc, unsigned int data)
503 pc += emu->audigy ? A_MICROCODEBASE : MICROCODEBASE;
504 snd_emu10k1_ptr_write(emu, pc, 0, data);
507 unsigned int snd_emu10k1_efx_read(emu10k1_t *emu, unsigned int pc)
509 pc += emu->audigy ? A_MICROCODEBASE : MICROCODEBASE;
510 return snd_emu10k1_ptr_read(emu, pc, 0);
513 static int snd_emu10k1_gpr_poke(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
518 for (gpr = 0; gpr < (emu->audigy ? 0x200 : 0x100); gpr++) {
519 if (!test_bit(gpr, icode->gpr_valid))
521 if (get_user(val, &icode->gpr_map[gpr]))
523 snd_emu10k1_ptr_write(emu, emu->gpr_base + gpr, 0, val);
528 static int snd_emu10k1_gpr_peek(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
533 for (gpr = 0; gpr < (emu->audigy ? 0x200 : 0x100); gpr++) {
534 set_bit(gpr, icode->gpr_valid);
535 val = snd_emu10k1_ptr_read(emu, emu->gpr_base + gpr, 0);
536 if (put_user(val, &icode->gpr_map[gpr]))
542 static int snd_emu10k1_tram_poke(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
547 for (tram = 0; tram < (emu->audigy ? 0x100 : 0xa0); tram++) {
548 if (!test_bit(tram, icode->tram_valid))
550 if (get_user(val, &icode->tram_data_map[tram]) ||
551 get_user(addr, &icode->tram_addr_map[tram]))
553 snd_emu10k1_ptr_write(emu, TANKMEMDATAREGBASE + tram, 0, val);
555 snd_emu10k1_ptr_write(emu, TANKMEMADDRREGBASE + tram, 0, addr);
557 snd_emu10k1_ptr_write(emu, TANKMEMADDRREGBASE + tram, 0, addr << 12);
558 snd_emu10k1_ptr_write(emu, A_TANKMEMCTLREGBASE + tram, 0, addr >> 20);
564 static int snd_emu10k1_tram_peek(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
569 memset(icode->tram_valid, 0, sizeof(icode->tram_valid));
570 for (tram = 0; tram < (emu->audigy ? 0x100 : 0xa0); tram++) {
571 set_bit(tram, icode->tram_valid);
572 val = snd_emu10k1_ptr_read(emu, TANKMEMDATAREGBASE + tram, 0);
574 addr = snd_emu10k1_ptr_read(emu, TANKMEMADDRREGBASE + tram, 0);
576 addr = snd_emu10k1_ptr_read(emu, TANKMEMADDRREGBASE + tram, 0) >> 12;
577 addr |= snd_emu10k1_ptr_read(emu, A_TANKMEMCTLREGBASE + tram, 0) << 20;
579 if (put_user(val, &icode->tram_data_map[tram]) ||
580 put_user(addr, &icode->tram_addr_map[tram]))
586 static int snd_emu10k1_code_poke(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
590 for (pc = 0; pc < (emu->audigy ? 2*1024 : 2*512); pc += 2) {
591 if (!test_bit(pc / 2, icode->code_valid))
593 if (get_user(lo, &icode->code[pc + 0]) ||
594 get_user(hi, &icode->code[pc + 1]))
596 snd_emu10k1_efx_write(emu, pc + 0, lo);
597 snd_emu10k1_efx_write(emu, pc + 1, hi);
602 static int snd_emu10k1_code_peek(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
606 memset(icode->code_valid, 0, sizeof(icode->code_valid));
607 for (pc = 0; pc < (emu->audigy ? 2*1024 : 2*512); pc += 2) {
608 set_bit(pc / 2, icode->code_valid);
609 if (put_user(snd_emu10k1_efx_read(emu, pc + 0), &icode->code[pc + 0]))
611 if (put_user(snd_emu10k1_efx_read(emu, pc + 1), &icode->code[pc + 1]))
617 static snd_emu10k1_fx8010_ctl_t *snd_emu10k1_look_for_ctl(emu10k1_t *emu, snd_ctl_elem_id_t *id)
619 snd_emu10k1_fx8010_ctl_t *ctl;
620 snd_kcontrol_t *kcontrol;
621 struct list_head *list;
623 list_for_each(list, &emu->fx8010.gpr_ctl) {
624 ctl = emu10k1_gpr_ctl(list);
625 kcontrol = ctl->kcontrol;
626 if (kcontrol->id.iface == id->iface &&
627 !strcmp(kcontrol->id.name, id->name) &&
628 kcontrol->id.index == id->index)
634 static int snd_emu10k1_verify_controls(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
637 snd_ctl_elem_id_t __user *_id;
638 snd_ctl_elem_id_t id;
639 emu10k1_fx8010_control_gpr_t __user *_gctl;
640 emu10k1_fx8010_control_gpr_t *gctl;
643 for (i = 0, _id = icode->gpr_del_controls;
644 i < icode->gpr_del_control_count; i++, _id++) {
645 if (copy_from_user(&id, _id, sizeof(id)))
647 if (snd_emu10k1_look_for_ctl(emu, &id) == NULL)
650 gctl = kmalloc(sizeof(*gctl), GFP_KERNEL);
654 for (i = 0, _gctl = icode->gpr_add_controls;
655 i < icode->gpr_add_control_count; i++, _gctl++) {
656 if (copy_from_user(gctl, _gctl, sizeof(*gctl))) {
660 if (snd_emu10k1_look_for_ctl(emu, &gctl->id))
662 down_read(&emu->card->controls_rwsem);
663 if (snd_ctl_find_id(emu->card, &gctl->id) != NULL) {
664 up_read(&emu->card->controls_rwsem);
668 up_read(&emu->card->controls_rwsem);
669 if (gctl->id.iface != SNDRV_CTL_ELEM_IFACE_MIXER &&
670 gctl->id.iface != SNDRV_CTL_ELEM_IFACE_PCM) {
675 for (i = 0, _gctl = icode->gpr_list_controls;
676 i < icode->gpr_list_control_count; i++, _gctl++) {
677 /* FIXME: we need to check the WRITE access */
678 if (copy_from_user(gctl, _gctl, sizeof(*gctl))) {
688 static void snd_emu10k1_ctl_private_free(snd_kcontrol_t *kctl)
690 snd_emu10k1_fx8010_ctl_t *ctl;
692 ctl = (snd_emu10k1_fx8010_ctl_t *)kctl->private_value;
693 kctl->private_value = 0;
694 list_del(&ctl->list);
698 static int snd_emu10k1_add_controls(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
701 emu10k1_fx8010_control_gpr_t __user *_gctl;
702 emu10k1_fx8010_control_gpr_t *gctl;
703 snd_emu10k1_fx8010_ctl_t *ctl, *nctl;
704 snd_kcontrol_new_t knew;
705 snd_kcontrol_t *kctl;
706 snd_ctl_elem_value_t *val;
709 val = (snd_ctl_elem_value_t *)kmalloc(sizeof(*val), GFP_KERNEL);
710 gctl = kmalloc(sizeof(*gctl), GFP_KERNEL);
711 nctl = kmalloc(sizeof(*nctl), GFP_KERNEL);
712 if (!val || !gctl || !nctl) {
717 for (i = 0, _gctl = icode->gpr_add_controls;
718 i < icode->gpr_add_control_count; i++, _gctl++) {
719 if (copy_from_user(gctl, _gctl, sizeof(*gctl))) {
723 if (gctl->id.iface != SNDRV_CTL_ELEM_IFACE_MIXER &&
724 gctl->id.iface != SNDRV_CTL_ELEM_IFACE_PCM) {
728 if (! gctl->id.name[0]) {
732 ctl = snd_emu10k1_look_for_ctl(emu, &gctl->id);
733 memset(&knew, 0, sizeof(knew));
734 knew.iface = gctl->id.iface;
735 knew.name = gctl->id.name;
736 knew.index = gctl->id.index;
737 knew.device = gctl->id.device;
738 knew.subdevice = gctl->id.subdevice;
739 knew.info = snd_emu10k1_gpr_ctl_info;
740 knew.get = snd_emu10k1_gpr_ctl_get;
741 knew.put = snd_emu10k1_gpr_ctl_put;
742 memset(nctl, 0, sizeof(*nctl));
743 nctl->vcount = gctl->vcount;
744 nctl->count = gctl->count;
745 for (j = 0; j < 32; j++) {
746 nctl->gpr[j] = gctl->gpr[j];
747 nctl->value[j] = ~gctl->value[j]; /* inverted, we want to write new value in gpr_ctl_put() */
748 val->value.integer.value[j] = gctl->value[j];
750 nctl->min = gctl->min;
751 nctl->max = gctl->max;
752 nctl->translation = gctl->translation;
754 ctl = (snd_emu10k1_fx8010_ctl_t *)kmalloc(sizeof(*ctl), GFP_KERNEL);
759 knew.private_value = (unsigned long)ctl;
761 if ((err = snd_ctl_add(emu->card, kctl = snd_ctl_new1(&knew, emu))) < 0) {
765 kctl->private_free = snd_emu10k1_ctl_private_free;
766 ctl->kcontrol = kctl;
767 list_add_tail(&ctl->list, &emu->fx8010.gpr_ctl);
770 nctl->list = ctl->list;
771 nctl->kcontrol = ctl->kcontrol;
773 snd_ctl_notify(emu->card, SNDRV_CTL_EVENT_MASK_VALUE |
774 SNDRV_CTL_EVENT_MASK_INFO, &ctl->kcontrol->id);
776 snd_emu10k1_gpr_ctl_put(ctl->kcontrol, val);
785 static int snd_emu10k1_del_controls(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
788 snd_ctl_elem_id_t id;
789 snd_ctl_elem_id_t __user *_id;
790 snd_emu10k1_fx8010_ctl_t *ctl;
791 snd_card_t *card = emu->card;
793 for (i = 0, _id = icode->gpr_del_controls;
794 i < icode->gpr_del_control_count; i++, _id++) {
795 if (copy_from_user(&id, _id, sizeof(id)))
797 down_write(&card->controls_rwsem);
798 ctl = snd_emu10k1_look_for_ctl(emu, &id);
800 snd_ctl_remove(card, ctl->kcontrol);
801 up_write(&card->controls_rwsem);
806 static int snd_emu10k1_list_controls(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
808 unsigned int i = 0, j;
809 unsigned int total = 0;
810 emu10k1_fx8010_control_gpr_t *gctl;
811 emu10k1_fx8010_control_gpr_t __user *_gctl;
812 snd_emu10k1_fx8010_ctl_t *ctl;
813 snd_ctl_elem_id_t *id;
814 struct list_head *list;
816 gctl = kmalloc(sizeof(*gctl), GFP_KERNEL);
820 _gctl = icode->gpr_list_controls;
821 list_for_each(list, &emu->fx8010.gpr_ctl) {
822 ctl = emu10k1_gpr_ctl(list);
824 if (_gctl && i < icode->gpr_list_control_count) {
825 memset(gctl, 0, sizeof(*gctl));
826 id = &ctl->kcontrol->id;
827 gctl->id.iface = id->iface;
828 strlcpy(gctl->id.name, id->name, sizeof(gctl->id.name));
829 gctl->id.index = id->index;
830 gctl->id.device = id->device;
831 gctl->id.subdevice = id->subdevice;
832 gctl->vcount = ctl->vcount;
833 gctl->count = ctl->count;
834 for (j = 0; j < 32; j++) {
835 gctl->gpr[j] = ctl->gpr[j];
836 gctl->value[j] = ctl->value[j];
838 gctl->min = ctl->min;
839 gctl->max = ctl->max;
840 gctl->translation = ctl->translation;
841 if (copy_to_user(_gctl, gctl, sizeof(*gctl))) {
849 icode->gpr_list_control_total = total;
854 static int snd_emu10k1_icode_poke(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
858 down(&emu->fx8010.lock);
859 if ((err = snd_emu10k1_verify_controls(emu, icode)) < 0)
861 strlcpy(emu->fx8010.name, icode->name, sizeof(emu->fx8010.name));
862 /* stop FX processor - this may be dangerous, but it's better to miss
863 some samples than generate wrong ones - [jk] */
865 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg | A_DBG_SINGLE_STEP);
867 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg | EMU10K1_DBG_SINGLE_STEP);
868 /* ok, do the main job */
869 if ((err = snd_emu10k1_del_controls(emu, icode)) < 0 ||
870 (err = snd_emu10k1_gpr_poke(emu, icode)) < 0 ||
871 (err = snd_emu10k1_tram_poke(emu, icode)) < 0 ||
872 (err = snd_emu10k1_code_poke(emu, icode)) < 0 ||
873 (err = snd_emu10k1_add_controls(emu, icode)) < 0)
875 /* start FX processor when the DSP code is updated */
877 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg);
879 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg);
881 up(&emu->fx8010.lock);
885 static int snd_emu10k1_icode_peek(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
889 down(&emu->fx8010.lock);
890 strlcpy(icode->name, emu->fx8010.name, sizeof(icode->name));
891 /* ok, do the main job */
892 err = snd_emu10k1_gpr_peek(emu, icode);
894 err = snd_emu10k1_tram_peek(emu, icode);
896 err = snd_emu10k1_code_peek(emu, icode);
898 err = snd_emu10k1_list_controls(emu, icode);
899 up(&emu->fx8010.lock);
903 static int snd_emu10k1_ipcm_poke(emu10k1_t *emu, emu10k1_fx8010_pcm_t *ipcm)
907 snd_emu10k1_fx8010_pcm_t *pcm;
909 if (ipcm->substream >= EMU10K1_FX8010_PCM_COUNT)
911 if (ipcm->channels > 32)
913 pcm = &emu->fx8010.pcm[ipcm->substream];
914 down(&emu->fx8010.lock);
915 spin_lock_irq(&emu->reg_lock);
920 if (ipcm->channels == 0) { /* remove */
923 /* FIXME: we need to add universal code to the PCM transfer routine */
924 if (ipcm->channels != 2) {
930 pcm->channels = ipcm->channels;
931 pcm->tram_start = ipcm->tram_start;
932 pcm->buffer_size = ipcm->buffer_size;
933 pcm->gpr_size = ipcm->gpr_size;
934 pcm->gpr_count = ipcm->gpr_count;
935 pcm->gpr_tmpcount = ipcm->gpr_tmpcount;
936 pcm->gpr_ptr = ipcm->gpr_ptr;
937 pcm->gpr_trigger = ipcm->gpr_trigger;
938 pcm->gpr_running = ipcm->gpr_running;
939 for (i = 0; i < pcm->channels; i++)
940 pcm->etram[i] = ipcm->etram[i];
943 spin_unlock_irq(&emu->reg_lock);
944 up(&emu->fx8010.lock);
948 static int snd_emu10k1_ipcm_peek(emu10k1_t *emu, emu10k1_fx8010_pcm_t *ipcm)
952 snd_emu10k1_fx8010_pcm_t *pcm;
954 if (ipcm->substream >= EMU10K1_FX8010_PCM_COUNT)
956 pcm = &emu->fx8010.pcm[ipcm->substream];
957 down(&emu->fx8010.lock);
958 spin_lock_irq(&emu->reg_lock);
959 ipcm->channels = pcm->channels;
960 ipcm->tram_start = pcm->tram_start;
961 ipcm->buffer_size = pcm->buffer_size;
962 ipcm->gpr_size = pcm->gpr_size;
963 ipcm->gpr_ptr = pcm->gpr_ptr;
964 ipcm->gpr_count = pcm->gpr_count;
965 ipcm->gpr_tmpcount = pcm->gpr_tmpcount;
966 ipcm->gpr_trigger = pcm->gpr_trigger;
967 ipcm->gpr_running = pcm->gpr_running;
968 for (i = 0; i < pcm->channels; i++)
969 ipcm->etram[i] = pcm->etram[i];
970 ipcm->res1 = ipcm->res2 = 0;
972 spin_unlock_irq(&emu->reg_lock);
973 up(&emu->fx8010.lock);
977 #define SND_EMU10K1_GPR_CONTROLS 44
978 #define SND_EMU10K1_INPUTS 12
979 #define SND_EMU10K1_PLAYBACK_CHANNELS 8
980 #define SND_EMU10K1_CAPTURE_CHANNELS 4
982 static void __devinit snd_emu10k1_init_mono_control(emu10k1_fx8010_control_gpr_t *ctl, const char *name, int gpr, int defval)
984 ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
985 strcpy(ctl->id.name, name);
986 ctl->vcount = ctl->count = 1;
987 ctl->gpr[0] = gpr + 0; ctl->value[0] = defval;
990 ctl->translation = EMU10K1_GPR_TRANSLATION_TABLE100;
993 static void __devinit snd_emu10k1_init_stereo_control(emu10k1_fx8010_control_gpr_t *ctl, const char *name, int gpr, int defval)
995 ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
996 strcpy(ctl->id.name, name);
997 ctl->vcount = ctl->count = 2;
998 ctl->gpr[0] = gpr + 0; ctl->value[0] = defval;
999 ctl->gpr[1] = gpr + 1; ctl->value[1] = defval;
1002 ctl->translation = EMU10K1_GPR_TRANSLATION_TABLE100;
1005 static void __devinit snd_emu10k1_init_mono_onoff_control(emu10k1_fx8010_control_gpr_t *ctl, const char *name, int gpr, int defval)
1007 ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1008 strcpy(ctl->id.name, name);
1009 ctl->vcount = ctl->count = 1;
1010 ctl->gpr[0] = gpr + 0; ctl->value[0] = defval;
1013 ctl->translation = EMU10K1_GPR_TRANSLATION_ONOFF;
1016 static void __devinit snd_emu10k1_init_stereo_onoff_control(emu10k1_fx8010_control_gpr_t *ctl, const char *name, int gpr, int defval)
1018 ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1019 strcpy(ctl->id.name, name);
1020 ctl->vcount = ctl->count = 2;
1021 ctl->gpr[0] = gpr + 0; ctl->value[0] = defval;
1022 ctl->gpr[1] = gpr + 1; ctl->value[1] = defval;
1025 ctl->translation = EMU10K1_GPR_TRANSLATION_ONOFF;
1030 * initial DSP configuration for Audigy
1033 static int __devinit _snd_emu10k1_audigy_init_efx(emu10k1_t *emu)
1035 int err, i, z, gpr, nctl;
1036 const int playback = 10;
1037 const int capture = playback + (SND_EMU10K1_PLAYBACK_CHANNELS * 2); /* we reserve 10 voices */
1038 const int stereo_mix = capture + 2;
1039 const int tmp = 0x88;
1041 emu10k1_fx8010_code_t *icode = NULL;
1042 emu10k1_fx8010_control_gpr_t *controls = NULL, *ctl;
1046 spin_lock_init(&emu->fx8010.irq_lock);
1047 INIT_LIST_HEAD(&emu->fx8010.gpr_ctl);
1049 if ((icode = kzalloc(sizeof(*icode), GFP_KERNEL)) == NULL ||
1050 (icode->gpr_map = (u_int32_t __user *)kcalloc(512 + 256 + 256 + 2 * 1024, sizeof(u_int32_t), GFP_KERNEL)) == NULL ||
1051 (controls = kcalloc(SND_EMU10K1_GPR_CONTROLS, sizeof(*controls), GFP_KERNEL)) == NULL) {
1055 gpr_map = (u32 __force *)icode->gpr_map;
1057 icode->tram_data_map = icode->gpr_map + 512;
1058 icode->tram_addr_map = icode->tram_data_map + 256;
1059 icode->code = icode->tram_addr_map + 256;
1061 /* clear free GPRs */
1062 for (i = 0; i < 512; i++)
1063 set_bit(i, icode->gpr_valid);
1065 /* clear TRAM data & address lines */
1066 for (i = 0; i < 256; i++)
1067 set_bit(i, icode->tram_valid);
1069 strcpy(icode->name, "Audigy DSP code for ALSA");
1072 gpr = stereo_mix + 10;
1074 /* stop FX processor */
1075 snd_emu10k1_ptr_write(emu, A_DBG, 0, (emu->fx8010.dbg = 0) | A_DBG_SINGLE_STEP);
1077 /* PCM front Playback Volume (independent from stereo mix) */
1078 A_OP(icode, &ptr, iMAC0, A_GPR(playback), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LEFT_FRONT));
1079 A_OP(icode, &ptr, iMAC0, A_GPR(playback+1), A_C_00000000, A_GPR(gpr+1), A_FXBUS(FXBUS_PCM_RIGHT_FRONT));
1080 snd_emu10k1_init_stereo_control(&controls[nctl++], "PCM Front Playback Volume", gpr, 100);
1083 /* PCM Surround Playback (independent from stereo mix) */
1084 A_OP(icode, &ptr, iMAC0, A_GPR(playback+2), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LEFT_REAR));
1085 A_OP(icode, &ptr, iMAC0, A_GPR(playback+3), A_C_00000000, A_GPR(gpr+1), A_FXBUS(FXBUS_PCM_RIGHT_REAR));
1086 snd_emu10k1_init_stereo_control(&controls[nctl++], "PCM Surround Playback Volume", gpr, 100);
1089 /* PCM Side Playback (independent from stereo mix) */
1090 if (emu->card_capabilities->spk71) {
1091 A_OP(icode, &ptr, iMAC0, A_GPR(playback+6), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LEFT_SIDE));
1092 A_OP(icode, &ptr, iMAC0, A_GPR(playback+7), A_C_00000000, A_GPR(gpr+1), A_FXBUS(FXBUS_PCM_RIGHT_SIDE));
1093 snd_emu10k1_init_stereo_control(&controls[nctl++], "PCM Side Playback Volume", gpr, 100);
1097 /* PCM Center Playback (independent from stereo mix) */
1098 A_OP(icode, &ptr, iMAC0, A_GPR(playback+4), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_CENTER));
1099 snd_emu10k1_init_mono_control(&controls[nctl++], "PCM Center Playback Volume", gpr, 100);
1102 /* PCM LFE Playback (independent from stereo mix) */
1103 A_OP(icode, &ptr, iMAC0, A_GPR(playback+5), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LFE));
1104 snd_emu10k1_init_mono_control(&controls[nctl++], "PCM LFE Playback Volume", gpr, 100);
1110 /* Wave (PCM) Playback Volume (will be renamed later) */
1111 A_OP(icode, &ptr, iMAC0, A_GPR(stereo_mix), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LEFT));
1112 A_OP(icode, &ptr, iMAC0, A_GPR(stereo_mix+1), A_C_00000000, A_GPR(gpr+1), A_FXBUS(FXBUS_PCM_RIGHT));
1113 snd_emu10k1_init_stereo_control(&controls[nctl++], "Wave Playback Volume", gpr, 100);
1116 /* Synth Playback */
1117 A_OP(icode, &ptr, iMAC0, A_GPR(stereo_mix+0), A_GPR(stereo_mix+0), A_GPR(gpr), A_FXBUS(FXBUS_MIDI_LEFT));
1118 A_OP(icode, &ptr, iMAC0, A_GPR(stereo_mix+1), A_GPR(stereo_mix+1), A_GPR(gpr+1), A_FXBUS(FXBUS_MIDI_RIGHT));
1119 snd_emu10k1_init_stereo_control(&controls[nctl++], "Synth Playback Volume", gpr, 100);
1122 /* Wave (PCM) Capture */
1123 A_OP(icode, &ptr, iMAC0, A_GPR(capture+0), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LEFT));
1124 A_OP(icode, &ptr, iMAC0, A_GPR(capture+1), A_C_00000000, A_GPR(gpr+1), A_FXBUS(FXBUS_PCM_RIGHT));
1125 snd_emu10k1_init_stereo_control(&controls[nctl++], "PCM Capture Volume", gpr, 0);
1129 A_OP(icode, &ptr, iMAC0, A_GPR(capture+0), A_GPR(capture+0), A_GPR(gpr), A_FXBUS(FXBUS_MIDI_LEFT));
1130 A_OP(icode, &ptr, iMAC0, A_GPR(capture+1), A_GPR(capture+1), A_GPR(gpr+1), A_FXBUS(FXBUS_MIDI_RIGHT));
1131 snd_emu10k1_init_stereo_control(&controls[nctl++], "Synth Capture Volume", gpr, 0);
1137 #define A_ADD_VOLUME_IN(var,vol,input) \
1138 A_OP(icode, &ptr, iMAC0, A_GPR(var), A_GPR(var), A_GPR(vol), A_EXTIN(input))
1140 /* AC'97 Playback Volume - used only for mic (renamed later) */
1141 A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_AC97_L);
1142 A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_AC97_R);
1143 snd_emu10k1_init_stereo_control(&controls[nctl++], "AMic Playback Volume", gpr, 0);
1145 /* AC'97 Capture Volume - used only for mic */
1146 A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_AC97_L);
1147 A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_AC97_R);
1148 snd_emu10k1_init_stereo_control(&controls[nctl++], "Mic Capture Volume", gpr, 0);
1151 /* mic capture buffer */
1152 A_OP(icode, &ptr, iINTERP, A_EXTOUT(A_EXTOUT_MIC_CAP), A_EXTIN(A_EXTIN_AC97_L), 0xcd, A_EXTIN(A_EXTIN_AC97_R));
1154 /* Audigy CD Playback Volume */
1155 A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_SPDIF_CD_L);
1156 A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_SPDIF_CD_R);
1157 snd_emu10k1_init_stereo_control(&controls[nctl++],
1158 emu->card_capabilities->ac97_chip ? "Audigy CD Playback Volume" : "CD Playback Volume",
1161 /* Audigy CD Capture Volume */
1162 A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_SPDIF_CD_L);
1163 A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_SPDIF_CD_R);
1164 snd_emu10k1_init_stereo_control(&controls[nctl++],
1165 emu->card_capabilities->ac97_chip ? "Audigy CD Capture Volume" : "CD Capture Volume",
1169 /* Optical SPDIF Playback Volume */
1170 A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_OPT_SPDIF_L);
1171 A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_OPT_SPDIF_R);
1172 snd_emu10k1_init_stereo_control(&controls[nctl++], SNDRV_CTL_NAME_IEC958("Optical ",PLAYBACK,VOLUME), gpr, 0);
1174 /* Optical SPDIF Capture Volume */
1175 A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_OPT_SPDIF_L);
1176 A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_OPT_SPDIF_R);
1177 snd_emu10k1_init_stereo_control(&controls[nctl++], SNDRV_CTL_NAME_IEC958("Optical ",CAPTURE,VOLUME), gpr, 0);
1180 /* Line2 Playback Volume */
1181 A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_LINE2_L);
1182 A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_LINE2_R);
1183 snd_emu10k1_init_stereo_control(&controls[nctl++],
1184 emu->card_capabilities->ac97_chip ? "Line2 Playback Volume" : "Line Playback Volume",
1187 /* Line2 Capture Volume */
1188 A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_LINE2_L);
1189 A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_LINE2_R);
1190 snd_emu10k1_init_stereo_control(&controls[nctl++],
1191 emu->card_capabilities->ac97_chip ? "Line2 Capture Volume" : "Line Capture Volume",
1195 /* Philips ADC Playback Volume */
1196 A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_ADC_L);
1197 A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_ADC_R);
1198 snd_emu10k1_init_stereo_control(&controls[nctl++], "Analog Mix Playback Volume", gpr, 0);
1200 /* Philips ADC Capture Volume */
1201 A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_ADC_L);
1202 A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_ADC_R);
1203 snd_emu10k1_init_stereo_control(&controls[nctl++], "Analog Mix Capture Volume", gpr, 0);
1206 /* Aux2 Playback Volume */
1207 A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_AUX2_L);
1208 A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_AUX2_R);
1209 snd_emu10k1_init_stereo_control(&controls[nctl++],
1210 emu->card_capabilities->ac97_chip ? "Aux2 Playback Volume" : "Aux Playback Volume",
1213 /* Aux2 Capture Volume */
1214 A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_AUX2_L);
1215 A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_AUX2_R);
1216 snd_emu10k1_init_stereo_control(&controls[nctl++],
1217 emu->card_capabilities->ac97_chip ? "Aux2 Capture Volume" : "Aux Capture Volume",
1221 /* Stereo Mix Front Playback Volume */
1222 A_OP(icode, &ptr, iMAC0, A_GPR(playback), A_GPR(playback), A_GPR(gpr), A_GPR(stereo_mix));
1223 A_OP(icode, &ptr, iMAC0, A_GPR(playback+1), A_GPR(playback+1), A_GPR(gpr+1), A_GPR(stereo_mix+1));
1224 snd_emu10k1_init_stereo_control(&controls[nctl++], "Front Playback Volume", gpr, 100);
1227 /* Stereo Mix Surround Playback */
1228 A_OP(icode, &ptr, iMAC0, A_GPR(playback+2), A_GPR(playback+2), A_GPR(gpr), A_GPR(stereo_mix));
1229 A_OP(icode, &ptr, iMAC0, A_GPR(playback+3), A_GPR(playback+3), A_GPR(gpr+1), A_GPR(stereo_mix+1));
1230 snd_emu10k1_init_stereo_control(&controls[nctl++], "Surround Playback Volume", gpr, 0);
1233 /* Stereo Mix Center Playback */
1234 /* Center = sub = Left/2 + Right/2 */
1235 A_OP(icode, &ptr, iINTERP, A_GPR(tmp), A_GPR(stereo_mix), 0xcd, A_GPR(stereo_mix+1));
1236 A_OP(icode, &ptr, iMAC0, A_GPR(playback+4), A_GPR(playback+4), A_GPR(gpr), A_GPR(tmp));
1237 snd_emu10k1_init_mono_control(&controls[nctl++], "Center Playback Volume", gpr, 0);
1240 /* Stereo Mix LFE Playback */
1241 A_OP(icode, &ptr, iMAC0, A_GPR(playback+5), A_GPR(playback+5), A_GPR(gpr), A_GPR(tmp));
1242 snd_emu10k1_init_mono_control(&controls[nctl++], "LFE Playback Volume", gpr, 0);
1245 if (emu->card_capabilities->spk71) {
1246 /* Stereo Mix Side Playback */
1247 A_OP(icode, &ptr, iMAC0, A_GPR(playback+6), A_GPR(playback+6), A_GPR(gpr), A_GPR(stereo_mix));
1248 A_OP(icode, &ptr, iMAC0, A_GPR(playback+7), A_GPR(playback+7), A_GPR(gpr+1), A_GPR(stereo_mix+1));
1249 snd_emu10k1_init_stereo_control(&controls[nctl++], "Side Playback Volume", gpr, 0);
1256 #define A_PUT_OUTPUT(out,src) A_OP(icode, &ptr, iACC3, A_EXTOUT(out), A_C_00000000, A_C_00000000, A_GPR(src))
1257 #define A_PUT_STEREO_OUTPUT(out1,out2,src) \
1258 {A_PUT_OUTPUT(out1,src); A_PUT_OUTPUT(out2,src+1);}
1260 #define _A_SWITCH(icode, ptr, dst, src, sw) \
1261 A_OP((icode), ptr, iMACINT0, dst, A_C_00000000, src, sw);
1262 #define A_SWITCH(icode, ptr, dst, src, sw) \
1263 _A_SWITCH(icode, ptr, A_GPR(dst), A_GPR(src), A_GPR(sw))
1264 #define _A_SWITCH_NEG(icode, ptr, dst, src) \
1265 A_OP((icode), ptr, iANDXOR, dst, src, A_C_00000001, A_C_00000001);
1266 #define A_SWITCH_NEG(icode, ptr, dst, src) \
1267 _A_SWITCH_NEG(icode, ptr, A_GPR(dst), A_GPR(src))
1271 * Process tone control
1273 A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 0), A_GPR(playback + 0), A_C_00000000, A_C_00000000); /* left */
1274 A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 1), A_GPR(playback + 1), A_C_00000000, A_C_00000000); /* right */
1275 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 */
1276 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 */
1277 A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 4), A_GPR(playback + 4), A_C_00000000, A_C_00000000); /* center */
1278 A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 5), A_GPR(playback + 5), A_C_00000000, A_C_00000000); /* LFE */
1279 if (emu->card_capabilities->spk71) {
1280 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 */
1281 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 */
1285 ctl = &controls[nctl + 0];
1286 ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1287 strcpy(ctl->id.name, "Tone Control - Bass");
1292 ctl->value[0] = ctl->value[1] = 20;
1293 ctl->translation = EMU10K1_GPR_TRANSLATION_BASS;
1294 ctl = &controls[nctl + 1];
1295 ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1296 strcpy(ctl->id.name, "Tone Control - Treble");
1301 ctl->value[0] = ctl->value[1] = 20;
1302 ctl->translation = EMU10K1_GPR_TRANSLATION_TREBLE;
1304 #define BASS_GPR 0x8c
1305 #define TREBLE_GPR 0x96
1307 for (z = 0; z < 5; z++) {
1309 for (j = 0; j < 2; j++) {
1310 controls[nctl + 0].gpr[z * 2 + j] = BASS_GPR + z * 2 + j;
1311 controls[nctl + 1].gpr[z * 2 + j] = TREBLE_GPR + z * 2 + j;
1314 for (z = 0; z < 4; z++) { /* front/rear/center-lfe/side */
1316 for (j = 0; j < 2; j++) { /* left/right */
1317 k = 0xb0 + (z * 8) + (j * 4);
1318 l = 0xe0 + (z * 8) + (j * 4);
1319 d = playback + SND_EMU10K1_PLAYBACK_CHANNELS + z * 2 + j;
1321 A_OP(icode, &ptr, iMAC0, A_C_00000000, A_C_00000000, A_GPR(d), A_GPR(BASS_GPR + 0 + j));
1322 A_OP(icode, &ptr, iMACMV, A_GPR(k+1), A_GPR(k), A_GPR(k+1), A_GPR(BASS_GPR + 4 + j));
1323 A_OP(icode, &ptr, iMACMV, A_GPR(k), A_GPR(d), A_GPR(k), A_GPR(BASS_GPR + 2 + j));
1324 A_OP(icode, &ptr, iMACMV, A_GPR(k+3), A_GPR(k+2), A_GPR(k+3), A_GPR(BASS_GPR + 8 + j));
1325 A_OP(icode, &ptr, iMAC0, A_GPR(k+2), A_GPR_ACCU, A_GPR(k+2), A_GPR(BASS_GPR + 6 + j));
1326 A_OP(icode, &ptr, iACC3, A_GPR(k+2), A_GPR(k+2), A_GPR(k+2), A_C_00000000);
1328 A_OP(icode, &ptr, iMAC0, A_C_00000000, A_C_00000000, A_GPR(k+2), A_GPR(TREBLE_GPR + 0 + j));
1329 A_OP(icode, &ptr, iMACMV, A_GPR(l+1), A_GPR(l), A_GPR(l+1), A_GPR(TREBLE_GPR + 4 + j));
1330 A_OP(icode, &ptr, iMACMV, A_GPR(l), A_GPR(k+2), A_GPR(l), A_GPR(TREBLE_GPR + 2 + j));
1331 A_OP(icode, &ptr, iMACMV, A_GPR(l+3), A_GPR(l+2), A_GPR(l+3), A_GPR(TREBLE_GPR + 8 + j));
1332 A_OP(icode, &ptr, iMAC0, A_GPR(l+2), A_GPR_ACCU, A_GPR(l+2), A_GPR(TREBLE_GPR + 6 + j));
1333 A_OP(icode, &ptr, iMACINT0, A_GPR(l+2), A_C_00000000, A_GPR(l+2), A_C_00000010);
1335 A_OP(icode, &ptr, iACC3, A_GPR(d), A_GPR(l+2), A_C_00000000, A_C_00000000);
1337 if (z == 2) /* center */
1346 for (z = 0; z < 8; z++) {
1347 A_SWITCH(icode, &ptr, tmp + 0, playback + SND_EMU10K1_PLAYBACK_CHANNELS + z, gpr + 0);
1348 A_SWITCH_NEG(icode, &ptr, tmp + 1, gpr + 0);
1349 A_SWITCH(icode, &ptr, tmp + 1, playback + z, tmp + 1);
1350 A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + z), A_GPR(tmp + 0), A_GPR(tmp + 1), A_C_00000000);
1352 snd_emu10k1_init_stereo_onoff_control(controls + nctl++, "Tone Control - Switch", gpr, 0);
1355 /* Master volume (will be renamed later) */
1356 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));
1357 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));
1358 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));
1359 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));
1360 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));
1361 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));
1362 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));
1363 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));
1364 snd_emu10k1_init_mono_control(&controls[nctl++], "Wave Master Playback Volume", gpr, 0);
1367 /* analog speakers */
1368 A_PUT_STEREO_OUTPUT(A_EXTOUT_AFRONT_L, A_EXTOUT_AFRONT_R, playback + SND_EMU10K1_PLAYBACK_CHANNELS);
1369 A_PUT_STEREO_OUTPUT(A_EXTOUT_AREAR_L, A_EXTOUT_AREAR_R, playback+2 + SND_EMU10K1_PLAYBACK_CHANNELS);
1370 A_PUT_OUTPUT(A_EXTOUT_ACENTER, playback+4 + SND_EMU10K1_PLAYBACK_CHANNELS);
1371 A_PUT_OUTPUT(A_EXTOUT_ALFE, playback+5 + SND_EMU10K1_PLAYBACK_CHANNELS);
1372 if (emu->card_capabilities->spk71)
1373 A_PUT_STEREO_OUTPUT(A_EXTOUT_ASIDE_L, A_EXTOUT_ASIDE_R, playback+6 + SND_EMU10K1_PLAYBACK_CHANNELS);
1376 A_PUT_STEREO_OUTPUT(A_EXTOUT_HEADPHONE_L, A_EXTOUT_HEADPHONE_R, playback + SND_EMU10K1_PLAYBACK_CHANNELS);
1378 /* digital outputs */
1379 /* A_PUT_STEREO_OUTPUT(A_EXTOUT_FRONT_L, A_EXTOUT_FRONT_R, playback + SND_EMU10K1_PLAYBACK_CHANNELS); */
1381 /* IEC958 Optical Raw Playback Switch */
1383 gpr_map[gpr++] = 0x1008;
1384 gpr_map[gpr++] = 0xffff0000;
1385 for (z = 0; z < 2; z++) {
1386 A_OP(icode, &ptr, iMAC0, A_GPR(tmp + 2), A_FXBUS(FXBUS_PT_LEFT + z), A_C_00000000, A_C_00000000);
1387 A_OP(icode, &ptr, iSKIP, A_GPR_COND, A_GPR_COND, A_GPR(gpr - 2), A_C_00000001);
1388 A_OP(icode, &ptr, iACC3, A_GPR(tmp + 2), A_C_00000000, A_C_00010000, A_GPR(tmp + 2));
1389 A_OP(icode, &ptr, iANDXOR, A_GPR(tmp + 2), A_GPR(tmp + 2), A_GPR(gpr - 1), A_C_00000000);
1390 A_SWITCH(icode, &ptr, tmp + 0, tmp + 2, gpr + z);
1391 A_SWITCH_NEG(icode, &ptr, tmp + 1, gpr + z);
1392 A_SWITCH(icode, &ptr, tmp + 1, playback + SND_EMU10K1_PLAYBACK_CHANNELS + z, tmp + 1);
1393 if ((z==1) && (emu->card_capabilities->spdif_bug)) {
1394 /* Due to a SPDIF output bug on some Audigy cards, this code delays the Right channel by 1 sample */
1395 snd_printk(KERN_INFO "Installing spdif_bug patch: %s\n", emu->card_capabilities->name);
1396 A_OP(icode, &ptr, iACC3, A_EXTOUT(A_EXTOUT_FRONT_L + z), A_GPR(gpr - 3), A_C_00000000, A_C_00000000);
1397 A_OP(icode, &ptr, iACC3, A_GPR(gpr - 3), A_GPR(tmp + 0), A_GPR(tmp + 1), A_C_00000000);
1399 A_OP(icode, &ptr, iACC3, A_EXTOUT(A_EXTOUT_FRONT_L + z), A_GPR(tmp + 0), A_GPR(tmp + 1), A_C_00000000);
1402 snd_emu10k1_init_stereo_onoff_control(controls + nctl++, SNDRV_CTL_NAME_IEC958("Optical Raw ",PLAYBACK,SWITCH), gpr, 0);
1405 A_PUT_STEREO_OUTPUT(A_EXTOUT_REAR_L, A_EXTOUT_REAR_R, playback+2 + SND_EMU10K1_PLAYBACK_CHANNELS);
1406 A_PUT_OUTPUT(A_EXTOUT_CENTER, playback+4 + SND_EMU10K1_PLAYBACK_CHANNELS);
1407 A_PUT_OUTPUT(A_EXTOUT_LFE, playback+5 + SND_EMU10K1_PLAYBACK_CHANNELS);
1410 #ifdef EMU10K1_CAPTURE_DIGITAL_OUT
1411 A_PUT_STEREO_OUTPUT(A_EXTOUT_ADC_CAP_L, A_EXTOUT_ADC_CAP_R, playback + SND_EMU10K1_PLAYBACK_CHANNELS);
1413 A_PUT_OUTPUT(A_EXTOUT_ADC_CAP_L, capture);
1414 A_PUT_OUTPUT(A_EXTOUT_ADC_CAP_R, capture+1);
1417 /* EFX capture - capture the 16 EXTINs */
1418 for (z = 0; z < 16; z++) {
1419 A_OP(icode, &ptr, iACC3, A_FXBUS2(z), A_C_00000000, A_C_00000000, A_EXTIN(z));
1431 /* clear remaining instruction memory */
1433 A_OP(icode, &ptr, 0x0f, 0xc0, 0xc0, 0xcf, 0xc0);
1435 seg = snd_enter_user();
1436 icode->gpr_add_control_count = nctl;
1437 icode->gpr_add_controls = (emu10k1_fx8010_control_gpr_t __user *)controls;
1438 err = snd_emu10k1_icode_poke(emu, icode);
1439 snd_leave_user(seg);
1443 if (icode != NULL) {
1444 kfree((void __force *)icode->gpr_map);
1452 * initial DSP configuration for Emu10k1
1455 /* when volume = max, then copy only to avoid volume modification */
1456 /* with iMAC0 (negative values) */
1457 static void __devinit _volume(emu10k1_fx8010_code_t *icode, u32 *ptr, u32 dst, u32 src, u32 vol)
1459 OP(icode, ptr, iMAC0, dst, C_00000000, src, vol);
1460 OP(icode, ptr, iANDXOR, C_00000000, vol, C_ffffffff, C_7fffffff);
1461 OP(icode, ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, C_00000001);
1462 OP(icode, ptr, iACC3, dst, src, C_00000000, C_00000000);
1464 static void __devinit _volume_add(emu10k1_fx8010_code_t *icode, u32 *ptr, u32 dst, u32 src, u32 vol)
1466 OP(icode, ptr, iANDXOR, C_00000000, vol, C_ffffffff, C_7fffffff);
1467 OP(icode, ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, C_00000002);
1468 OP(icode, ptr, iMACINT0, dst, dst, src, C_00000001);
1469 OP(icode, ptr, iSKIP, C_00000000, C_7fffffff, C_7fffffff, C_00000001);
1470 OP(icode, ptr, iMAC0, dst, dst, src, vol);
1472 static void __devinit _volume_out(emu10k1_fx8010_code_t *icode, u32 *ptr, u32 dst, u32 src, u32 vol)
1474 OP(icode, ptr, iANDXOR, C_00000000, vol, C_ffffffff, C_7fffffff);
1475 OP(icode, ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, C_00000002);
1476 OP(icode, ptr, iACC3, dst, src, C_00000000, C_00000000);
1477 OP(icode, ptr, iSKIP, C_00000000, C_7fffffff, C_7fffffff, C_00000001);
1478 OP(icode, ptr, iMAC0, dst, C_00000000, src, vol);
1481 #define VOLUME(icode, ptr, dst, src, vol) \
1482 _volume(icode, ptr, GPR(dst), GPR(src), GPR(vol))
1483 #define VOLUME_IN(icode, ptr, dst, src, vol) \
1484 _volume(icode, ptr, GPR(dst), EXTIN(src), GPR(vol))
1485 #define VOLUME_ADD(icode, ptr, dst, src, vol) \
1486 _volume_add(icode, ptr, GPR(dst), GPR(src), GPR(vol))
1487 #define VOLUME_ADDIN(icode, ptr, dst, src, vol) \
1488 _volume_add(icode, ptr, GPR(dst), EXTIN(src), GPR(vol))
1489 #define VOLUME_OUT(icode, ptr, dst, src, vol) \
1490 _volume_out(icode, ptr, EXTOUT(dst), GPR(src), GPR(vol))
1491 #define _SWITCH(icode, ptr, dst, src, sw) \
1492 OP((icode), ptr, iMACINT0, dst, C_00000000, src, sw);
1493 #define SWITCH(icode, ptr, dst, src, sw) \
1494 _SWITCH(icode, ptr, GPR(dst), GPR(src), GPR(sw))
1495 #define SWITCH_IN(icode, ptr, dst, src, sw) \
1496 _SWITCH(icode, ptr, GPR(dst), EXTIN(src), GPR(sw))
1497 #define _SWITCH_NEG(icode, ptr, dst, src) \
1498 OP((icode), ptr, iANDXOR, dst, src, C_00000001, C_00000001);
1499 #define SWITCH_NEG(icode, ptr, dst, src) \
1500 _SWITCH_NEG(icode, ptr, GPR(dst), GPR(src))
1503 static int __devinit _snd_emu10k1_init_efx(emu10k1_t *emu)
1505 int err, i, z, gpr, tmp, playback, capture;
1507 emu10k1_fx8010_code_t *icode;
1508 emu10k1_fx8010_pcm_t *ipcm = NULL;
1509 emu10k1_fx8010_control_gpr_t *controls = NULL, *ctl;
1513 spin_lock_init(&emu->fx8010.irq_lock);
1514 INIT_LIST_HEAD(&emu->fx8010.gpr_ctl);
1516 if ((icode = kzalloc(sizeof(*icode), GFP_KERNEL)) == NULL)
1518 if ((icode->gpr_map = (u_int32_t __user *)kcalloc(256 + 160 + 160 + 2 * 512, sizeof(u_int32_t), GFP_KERNEL)) == NULL ||
1519 (controls = kcalloc(SND_EMU10K1_GPR_CONTROLS, sizeof(emu10k1_fx8010_control_gpr_t), GFP_KERNEL)) == NULL ||
1520 (ipcm = kzalloc(sizeof(*ipcm), GFP_KERNEL)) == NULL) {
1524 gpr_map = (u32 __force *)icode->gpr_map;
1526 icode->tram_data_map = icode->gpr_map + 256;
1527 icode->tram_addr_map = icode->tram_data_map + 160;
1528 icode->code = icode->tram_addr_map + 160;
1530 /* clear free GPRs */
1531 for (i = 0; i < 256; i++)
1532 set_bit(i, icode->gpr_valid);
1534 /* clear TRAM data & address lines */
1535 for (i = 0; i < 160; i++)
1536 set_bit(i, icode->tram_valid);
1538 strcpy(icode->name, "SB Live! FX8010 code for ALSA v1.2 by Jaroslav Kysela");
1540 /* we have 12 inputs */
1541 playback = SND_EMU10K1_INPUTS;
1542 /* we have 6 playback channels and tone control doubles */
1543 capture = playback + (SND_EMU10K1_PLAYBACK_CHANNELS * 2);
1544 gpr = capture + SND_EMU10K1_CAPTURE_CHANNELS;
1545 tmp = 0x88; /* we need 4 temporary GPR */
1546 /* from 0x8c to 0xff is the area for tone control */
1548 /* stop FX processor */
1549 snd_emu10k1_ptr_write(emu, DBG, 0, (emu->fx8010.dbg = 0) | EMU10K1_DBG_SINGLE_STEP);
1554 OP(icode, &ptr, iMACINT0, GPR(0), C_00000000, FXBUS(FXBUS_PCM_LEFT), C_00000004);
1555 OP(icode, &ptr, iMACINT0, GPR(1), C_00000000, FXBUS(FXBUS_PCM_RIGHT), C_00000004);
1556 OP(icode, &ptr, iMACINT0, GPR(2), C_00000000, FXBUS(FXBUS_MIDI_LEFT), C_00000004);
1557 OP(icode, &ptr, iMACINT0, GPR(3), C_00000000, FXBUS(FXBUS_MIDI_RIGHT), C_00000004);
1558 OP(icode, &ptr, iMACINT0, GPR(4), C_00000000, FXBUS(FXBUS_PCM_LEFT_REAR), C_00000004);
1559 OP(icode, &ptr, iMACINT0, GPR(5), C_00000000, FXBUS(FXBUS_PCM_RIGHT_REAR), C_00000004);
1560 OP(icode, &ptr, iMACINT0, GPR(6), C_00000000, FXBUS(FXBUS_PCM_CENTER), C_00000004);
1561 OP(icode, &ptr, iMACINT0, GPR(7), C_00000000, FXBUS(FXBUS_PCM_LFE), C_00000004);
1562 OP(icode, &ptr, iMACINT0, GPR(8), C_00000000, C_00000000, C_00000000); /* S/PDIF left */
1563 OP(icode, &ptr, iMACINT0, GPR(9), C_00000000, C_00000000, C_00000000); /* S/PDIF right */
1564 OP(icode, &ptr, iMACINT0, GPR(10), C_00000000, FXBUS(FXBUS_PCM_LEFT_FRONT), C_00000004);
1565 OP(icode, &ptr, iMACINT0, GPR(11), C_00000000, FXBUS(FXBUS_PCM_RIGHT_FRONT), C_00000004);
1567 /* Raw S/PDIF PCM */
1568 ipcm->substream = 0;
1570 ipcm->tram_start = 0;
1571 ipcm->buffer_size = (64 * 1024) / 2;
1572 ipcm->gpr_size = gpr++;
1573 ipcm->gpr_ptr = gpr++;
1574 ipcm->gpr_count = gpr++;
1575 ipcm->gpr_tmpcount = gpr++;
1576 ipcm->gpr_trigger = gpr++;
1577 ipcm->gpr_running = gpr++;
1581 gpr_map[gpr + 0] = 0xfffff000;
1582 gpr_map[gpr + 1] = 0xffff0000;
1583 gpr_map[gpr + 2] = 0x70000000;
1584 gpr_map[gpr + 3] = 0x00000007;
1585 gpr_map[gpr + 4] = 0x001f << 11;
1586 gpr_map[gpr + 5] = 0x001c << 11;
1587 gpr_map[gpr + 6] = (0x22 - 0x01) - 1; /* skip at 01 to 22 */
1588 gpr_map[gpr + 7] = (0x22 - 0x06) - 1; /* skip at 06 to 22 */
1589 gpr_map[gpr + 8] = 0x2000000 + (2<<11);
1590 gpr_map[gpr + 9] = 0x4000000 + (2<<11);
1591 gpr_map[gpr + 10] = 1<<11;
1592 gpr_map[gpr + 11] = (0x24 - 0x0a) - 1; /* skip at 0a to 24 */
1593 gpr_map[gpr + 12] = 0;
1595 /* if the trigger flag is not set, skip */
1596 /* 00: */ OP(icode, &ptr, iMAC0, C_00000000, GPR(ipcm->gpr_trigger), C_00000000, C_00000000);
1597 /* 01: */ OP(icode, &ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_ZERO, GPR(gpr + 6));
1598 /* if the running flag is set, we're running */
1599 /* 02: */ OP(icode, &ptr, iMAC0, C_00000000, GPR(ipcm->gpr_running), C_00000000, C_00000000);
1600 /* 03: */ OP(icode, &ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, C_00000004);
1601 /* wait until ((GPR_DBAC>>11) & 0x1f) == 0x1c) */
1602 /* 04: */ OP(icode, &ptr, iANDXOR, GPR(tmp + 0), GPR_DBAC, GPR(gpr + 4), C_00000000);
1603 /* 05: */ OP(icode, &ptr, iMACINT0, C_00000000, GPR(tmp + 0), C_ffffffff, GPR(gpr + 5));
1604 /* 06: */ OP(icode, &ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, GPR(gpr + 7));
1605 /* 07: */ OP(icode, &ptr, iACC3, GPR(gpr + 12), C_00000010, C_00000001, C_00000000);
1607 /* 08: */ OP(icode, &ptr, iANDXOR, GPR(ipcm->gpr_running), GPR(ipcm->gpr_running), C_00000000, C_00000001);
1608 /* 09: */ OP(icode, &ptr, iACC3, GPR(gpr + 12), GPR(gpr + 12), C_ffffffff, C_00000000);
1609 /* 0a: */ OP(icode, &ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, GPR(gpr + 11));
1610 /* 0b: */ OP(icode, &ptr, iACC3, GPR(gpr + 12), C_00000001, C_00000000, C_00000000);
1612 /* 0c: */ OP(icode, &ptr, iANDXOR, GPR(tmp + 0), ETRAM_DATA(ipcm->etram[0]), GPR(gpr + 0), C_00000000);
1613 /* 0d: */ OP(icode, &ptr, iLOG, GPR(tmp + 0), GPR(tmp + 0), GPR(gpr + 3), C_00000000);
1614 /* 0e: */ OP(icode, &ptr, iANDXOR, GPR(8), GPR(tmp + 0), GPR(gpr + 1), GPR(gpr + 2));
1615 /* 0f: */ OP(icode, &ptr, iSKIP, C_00000000, GPR_COND, CC_REG_MINUS, C_00000001);
1616 /* 10: */ OP(icode, &ptr, iANDXOR, GPR(8), GPR(8), GPR(gpr + 1), GPR(gpr + 2));
1618 /* 11: */ OP(icode, &ptr, iANDXOR, GPR(tmp + 0), ETRAM_DATA(ipcm->etram[1]), GPR(gpr + 0), C_00000000);
1619 /* 12: */ OP(icode, &ptr, iLOG, GPR(tmp + 0), GPR(tmp + 0), GPR(gpr + 3), C_00000000);
1620 /* 13: */ OP(icode, &ptr, iANDXOR, GPR(9), GPR(tmp + 0), GPR(gpr + 1), GPR(gpr + 2));
1621 /* 14: */ OP(icode, &ptr, iSKIP, C_00000000, GPR_COND, CC_REG_MINUS, C_00000001);
1622 /* 15: */ OP(icode, &ptr, iANDXOR, GPR(9), GPR(9), GPR(gpr + 1), GPR(gpr + 2));
1624 /* 16: */ OP(icode, &ptr, iACC3, GPR(tmp + 0), GPR(ipcm->gpr_ptr), C_00000001, C_00000000);
1625 /* 17: */ OP(icode, &ptr, iMACINT0, C_00000000, GPR(tmp + 0), C_ffffffff, GPR(ipcm->gpr_size));
1626 /* 18: */ OP(icode, &ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_MINUS, C_00000001);
1627 /* 19: */ OP(icode, &ptr, iACC3, GPR(tmp + 0), C_00000000, C_00000000, C_00000000);
1628 /* 1a: */ OP(icode, &ptr, iACC3, GPR(ipcm->gpr_ptr), GPR(tmp + 0), C_00000000, C_00000000);
1630 /* 1b: */ OP(icode, &ptr, iACC3, GPR(ipcm->gpr_tmpcount), GPR(ipcm->gpr_tmpcount), C_ffffffff, C_00000000);
1631 /* 1c: */ OP(icode, &ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, C_00000002);
1632 /* 1d: */ OP(icode, &ptr, iACC3, GPR(ipcm->gpr_tmpcount), GPR(ipcm->gpr_count), C_00000000, C_00000000);
1633 /* 1e: */ OP(icode, &ptr, iACC3, GPR_IRQ, C_80000000, C_00000000, C_00000000);
1634 /* 1f: */ OP(icode, &ptr, iANDXOR, GPR(ipcm->gpr_running), GPR(ipcm->gpr_running), C_00000001, C_00010000);
1636 /* 20: */ OP(icode, &ptr, iANDXOR, GPR(ipcm->gpr_running), GPR(ipcm->gpr_running), C_00010000, C_00000001);
1637 /* 21: */ OP(icode, &ptr, iSKIP, C_00000000, C_7fffffff, C_7fffffff, C_00000002);
1639 /* 22: */ OP(icode, &ptr, iMACINT1, ETRAM_ADDR(ipcm->etram[0]), GPR(gpr + 8), GPR_DBAC, C_ffffffff);
1640 /* 23: */ OP(icode, &ptr, iMACINT1, ETRAM_ADDR(ipcm->etram[1]), GPR(gpr + 9), GPR_DBAC, C_ffffffff);
1645 /* Wave Playback Volume */
1646 for (z = 0; z < 2; z++)
1647 VOLUME(icode, &ptr, playback + z, z, gpr + z);
1648 snd_emu10k1_init_stereo_control(controls + i++, "Wave Playback Volume", gpr, 100);
1651 /* Wave Surround Playback Volume */
1652 for (z = 0; z < 2; z++)
1653 VOLUME(icode, &ptr, playback + 2 + z, z, gpr + z);
1654 snd_emu10k1_init_stereo_control(controls + i++, "Wave Surround Playback Volume", gpr, 0);
1657 /* Wave Center/LFE Playback Volume */
1658 OP(icode, &ptr, iACC3, GPR(tmp + 0), FXBUS(FXBUS_PCM_LEFT), FXBUS(FXBUS_PCM_RIGHT), C_00000000);
1659 OP(icode, &ptr, iMACINT0, GPR(tmp + 0), C_00000000, GPR(tmp + 0), C_00000002);
1660 VOLUME(icode, &ptr, playback + 4, tmp + 0, gpr);
1661 snd_emu10k1_init_mono_control(controls + i++, "Wave Center Playback Volume", gpr++, 0);
1662 VOLUME(icode, &ptr, playback + 5, tmp + 0, gpr);
1663 snd_emu10k1_init_mono_control(controls + i++, "Wave LFE Playback Volume", gpr++, 0);
1665 /* Wave Capture Volume + Switch */
1666 for (z = 0; z < 2; z++) {
1667 SWITCH(icode, &ptr, tmp + 0, z, gpr + 2 + z);
1668 VOLUME(icode, &ptr, capture + z, tmp + 0, gpr + z);
1670 snd_emu10k1_init_stereo_control(controls + i++, "Wave Capture Volume", gpr, 0);
1671 snd_emu10k1_init_stereo_onoff_control(controls + i++, "Wave Capture Switch", gpr + 2, 0);
1674 /* Synth Playback Volume */
1675 for (z = 0; z < 2; z++)
1676 VOLUME_ADD(icode, &ptr, playback + z, 2 + z, gpr + z);
1677 snd_emu10k1_init_stereo_control(controls + i++, "Synth Playback Volume", gpr, 100);
1680 /* Synth Capture Volume + Switch */
1681 for (z = 0; z < 2; z++) {
1682 SWITCH(icode, &ptr, tmp + 0, 2 + z, gpr + 2 + z);
1683 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
1685 snd_emu10k1_init_stereo_control(controls + i++, "Synth Capture Volume", gpr, 0);
1686 snd_emu10k1_init_stereo_onoff_control(controls + i++, "Synth Capture Switch", gpr + 2, 0);
1689 /* Surround Digital Playback Volume (renamed later without Digital) */
1690 for (z = 0; z < 2; z++)
1691 VOLUME_ADD(icode, &ptr, playback + 2 + z, 4 + z, gpr + z);
1692 snd_emu10k1_init_stereo_control(controls + i++, "Surround Digital Playback Volume", gpr, 100);
1695 /* Surround Capture Volume + Switch */
1696 for (z = 0; z < 2; z++) {
1697 SWITCH(icode, &ptr, tmp + 0, 4 + z, gpr + 2 + z);
1698 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
1700 snd_emu10k1_init_stereo_control(controls + i++, "Surround Capture Volume", gpr, 0);
1701 snd_emu10k1_init_stereo_onoff_control(controls + i++, "Surround Capture Switch", gpr + 2, 0);
1704 /* Center Playback Volume (renamed later without Digital) */
1705 VOLUME_ADD(icode, &ptr, playback + 4, 6, gpr);
1706 snd_emu10k1_init_mono_control(controls + i++, "Center Digital Playback Volume", gpr++, 100);
1708 /* LFE Playback Volume + Switch (renamed later without Digital) */
1709 VOLUME_ADD(icode, &ptr, playback + 5, 7, gpr);
1710 snd_emu10k1_init_mono_control(controls + i++, "LFE Digital Playback Volume", gpr++, 100);
1712 /* Front Playback Volume */
1713 for (z = 0; z < 2; z++)
1714 VOLUME_ADD(icode, &ptr, playback + z, 10 + z, gpr + z);
1715 snd_emu10k1_init_stereo_control(controls + i++, "Front Playback Volume", gpr, 100);
1718 /* Front Capture Volume + Switch */
1719 for (z = 0; z < 2; z++) {
1720 SWITCH(icode, &ptr, tmp + 0, 10 + z, gpr + 2);
1721 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
1723 snd_emu10k1_init_stereo_control(controls + i++, "Front Capture Volume", gpr, 0);
1724 snd_emu10k1_init_mono_onoff_control(controls + i++, "Front Capture Switch", gpr + 2, 0);
1731 if (emu->fx8010.extin_mask & ((1<<EXTIN_AC97_L)|(1<<EXTIN_AC97_R))) {
1732 /* AC'97 Playback Volume */
1733 VOLUME_ADDIN(icode, &ptr, playback + 0, EXTIN_AC97_L, gpr); gpr++;
1734 VOLUME_ADDIN(icode, &ptr, playback + 1, EXTIN_AC97_R, gpr); gpr++;
1735 snd_emu10k1_init_stereo_control(controls + i++, "AC97 Playback Volume", gpr-2, 0);
1736 /* AC'97 Capture Volume */
1737 VOLUME_ADDIN(icode, &ptr, capture + 0, EXTIN_AC97_L, gpr); gpr++;
1738 VOLUME_ADDIN(icode, &ptr, capture + 1, EXTIN_AC97_R, gpr); gpr++;
1739 snd_emu10k1_init_stereo_control(controls + i++, "AC97 Capture Volume", gpr-2, 100);
1742 if (emu->fx8010.extin_mask & ((1<<EXTIN_SPDIF_CD_L)|(1<<EXTIN_SPDIF_CD_R))) {
1743 /* IEC958 TTL Playback Volume */
1744 for (z = 0; z < 2; z++)
1745 VOLUME_ADDIN(icode, &ptr, playback + z, EXTIN_SPDIF_CD_L + z, gpr + z);
1746 snd_emu10k1_init_stereo_control(controls + i++, SNDRV_CTL_NAME_IEC958("TTL ",PLAYBACK,VOLUME), gpr, 0);
1749 /* IEC958 TTL Capture Volume + Switch */
1750 for (z = 0; z < 2; z++) {
1751 SWITCH_IN(icode, &ptr, tmp + 0, EXTIN_SPDIF_CD_L + z, gpr + 2 + z);
1752 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
1754 snd_emu10k1_init_stereo_control(controls + i++, SNDRV_CTL_NAME_IEC958("TTL ",CAPTURE,VOLUME), gpr, 0);
1755 snd_emu10k1_init_stereo_onoff_control(controls + i++, SNDRV_CTL_NAME_IEC958("TTL ",CAPTURE,SWITCH), gpr + 2, 0);
1759 if (emu->fx8010.extin_mask & ((1<<EXTIN_ZOOM_L)|(1<<EXTIN_ZOOM_R))) {
1760 /* Zoom Video Playback Volume */
1761 for (z = 0; z < 2; z++)
1762 VOLUME_ADDIN(icode, &ptr, playback + z, EXTIN_ZOOM_L + z, gpr + z);
1763 snd_emu10k1_init_stereo_control(controls + i++, "Zoom Video Playback Volume", gpr, 0);
1766 /* Zoom Video Capture Volume + Switch */
1767 for (z = 0; z < 2; z++) {
1768 SWITCH_IN(icode, &ptr, tmp + 0, EXTIN_ZOOM_L + z, gpr + 2 + z);
1769 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
1771 snd_emu10k1_init_stereo_control(controls + i++, "Zoom Video Capture Volume", gpr, 0);
1772 snd_emu10k1_init_stereo_onoff_control(controls + i++, "Zoom Video Capture Switch", gpr + 2, 0);
1776 if (emu->fx8010.extin_mask & ((1<<EXTIN_TOSLINK_L)|(1<<EXTIN_TOSLINK_R))) {
1777 /* IEC958 Optical Playback Volume */
1778 for (z = 0; z < 2; z++)
1779 VOLUME_ADDIN(icode, &ptr, playback + z, EXTIN_TOSLINK_L + z, gpr + z);
1780 snd_emu10k1_init_stereo_control(controls + i++, SNDRV_CTL_NAME_IEC958("LiveDrive ",PLAYBACK,VOLUME), gpr, 0);
1783 /* IEC958 Optical Capture Volume */
1784 for (z = 0; z < 2; z++) {
1785 SWITCH_IN(icode, &ptr, tmp + 0, EXTIN_TOSLINK_L + z, gpr + 2 + z);
1786 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
1788 snd_emu10k1_init_stereo_control(controls + i++, SNDRV_CTL_NAME_IEC958("LiveDrive ",CAPTURE,VOLUME), gpr, 0);
1789 snd_emu10k1_init_stereo_onoff_control(controls + i++, SNDRV_CTL_NAME_IEC958("LiveDrive ",CAPTURE,SWITCH), gpr + 2, 0);
1793 if (emu->fx8010.extin_mask & ((1<<EXTIN_LINE1_L)|(1<<EXTIN_LINE1_R))) {
1794 /* Line LiveDrive Playback Volume */
1795 for (z = 0; z < 2; z++)
1796 VOLUME_ADDIN(icode, &ptr, playback + z, EXTIN_LINE1_L + z, gpr + z);
1797 snd_emu10k1_init_stereo_control(controls + i++, "Line LiveDrive Playback Volume", gpr, 0);
1800 /* Line LiveDrive Capture Volume + Switch */
1801 for (z = 0; z < 2; z++) {
1802 SWITCH_IN(icode, &ptr, tmp + 0, EXTIN_LINE1_L + z, gpr + 2 + z);
1803 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
1805 snd_emu10k1_init_stereo_control(controls + i++, "Line LiveDrive Capture Volume", gpr, 0);
1806 snd_emu10k1_init_stereo_onoff_control(controls + i++, "Line LiveDrive Capture Switch", gpr + 2, 0);
1810 if (emu->fx8010.extin_mask & ((1<<EXTIN_COAX_SPDIF_L)|(1<<EXTIN_COAX_SPDIF_R))) {
1811 /* IEC958 Coax Playback Volume */
1812 for (z = 0; z < 2; z++)
1813 VOLUME_ADDIN(icode, &ptr, playback + z, EXTIN_COAX_SPDIF_L + z, gpr + z);
1814 snd_emu10k1_init_stereo_control(controls + i++, SNDRV_CTL_NAME_IEC958("Coaxial ",PLAYBACK,VOLUME), gpr, 0);
1817 /* IEC958 Coax Capture Volume + Switch */
1818 for (z = 0; z < 2; z++) {
1819 SWITCH_IN(icode, &ptr, tmp + 0, EXTIN_COAX_SPDIF_L + z, gpr + 2 + z);
1820 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
1822 snd_emu10k1_init_stereo_control(controls + i++, SNDRV_CTL_NAME_IEC958("Coaxial ",CAPTURE,VOLUME), gpr, 0);
1823 snd_emu10k1_init_stereo_onoff_control(controls + i++, SNDRV_CTL_NAME_IEC958("Coaxial ",CAPTURE,SWITCH), gpr + 2, 0);
1827 if (emu->fx8010.extin_mask & ((1<<EXTIN_LINE2_L)|(1<<EXTIN_LINE2_R))) {
1828 /* Line LiveDrive Playback Volume */
1829 for (z = 0; z < 2; z++)
1830 VOLUME_ADDIN(icode, &ptr, playback + z, EXTIN_LINE2_L + z, gpr + z);
1831 snd_emu10k1_init_stereo_control(controls + i++, "Line2 LiveDrive Playback Volume", gpr, 0);
1832 controls[i-1].id.index = 1;
1835 /* Line LiveDrive Capture Volume */
1836 for (z = 0; z < 2; z++) {
1837 SWITCH_IN(icode, &ptr, tmp + 0, EXTIN_LINE2_L + z, gpr + 2 + z);
1838 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
1840 snd_emu10k1_init_stereo_control(controls + i++, "Line2 LiveDrive Capture Volume", gpr, 0);
1841 controls[i-1].id.index = 1;
1842 snd_emu10k1_init_stereo_onoff_control(controls + i++, "Line2 LiveDrive Capture Switch", gpr + 2, 0);
1843 controls[i-1].id.index = 1;
1848 * Process tone control
1850 OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 0), GPR(playback + 0), C_00000000, C_00000000); /* left */
1851 OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 1), GPR(playback + 1), C_00000000, C_00000000); /* right */
1852 OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 2), GPR(playback + 2), C_00000000, C_00000000); /* rear left */
1853 OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 3), GPR(playback + 3), C_00000000, C_00000000); /* rear right */
1854 OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 4), GPR(playback + 4), C_00000000, C_00000000); /* center */
1855 OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 5), GPR(playback + 5), C_00000000, C_00000000); /* LFE */
1857 ctl = &controls[i + 0];
1858 ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1859 strcpy(ctl->id.name, "Tone Control - Bass");
1864 ctl->value[0] = ctl->value[1] = 20;
1865 ctl->translation = EMU10K1_GPR_TRANSLATION_BASS;
1866 ctl = &controls[i + 1];
1867 ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1868 strcpy(ctl->id.name, "Tone Control - Treble");
1873 ctl->value[0] = ctl->value[1] = 20;
1874 ctl->translation = EMU10K1_GPR_TRANSLATION_TREBLE;
1876 #define BASS_GPR 0x8c
1877 #define TREBLE_GPR 0x96
1879 for (z = 0; z < 5; z++) {
1881 for (j = 0; j < 2; j++) {
1882 controls[i + 0].gpr[z * 2 + j] = BASS_GPR + z * 2 + j;
1883 controls[i + 1].gpr[z * 2 + j] = TREBLE_GPR + z * 2 + j;
1886 for (z = 0; z < 3; z++) { /* front/rear/center-lfe */
1888 for (j = 0; j < 2; j++) { /* left/right */
1889 k = 0xa0 + (z * 8) + (j * 4);
1890 l = 0xd0 + (z * 8) + (j * 4);
1891 d = playback + SND_EMU10K1_PLAYBACK_CHANNELS + z * 2 + j;
1893 OP(icode, &ptr, iMAC0, C_00000000, C_00000000, GPR(d), GPR(BASS_GPR + 0 + j));
1894 OP(icode, &ptr, iMACMV, GPR(k+1), GPR(k), GPR(k+1), GPR(BASS_GPR + 4 + j));
1895 OP(icode, &ptr, iMACMV, GPR(k), GPR(d), GPR(k), GPR(BASS_GPR + 2 + j));
1896 OP(icode, &ptr, iMACMV, GPR(k+3), GPR(k+2), GPR(k+3), GPR(BASS_GPR + 8 + j));
1897 OP(icode, &ptr, iMAC0, GPR(k+2), GPR_ACCU, GPR(k+2), GPR(BASS_GPR + 6 + j));
1898 OP(icode, &ptr, iACC3, GPR(k+2), GPR(k+2), GPR(k+2), C_00000000);
1900 OP(icode, &ptr, iMAC0, C_00000000, C_00000000, GPR(k+2), GPR(TREBLE_GPR + 0 + j));
1901 OP(icode, &ptr, iMACMV, GPR(l+1), GPR(l), GPR(l+1), GPR(TREBLE_GPR + 4 + j));
1902 OP(icode, &ptr, iMACMV, GPR(l), GPR(k+2), GPR(l), GPR(TREBLE_GPR + 2 + j));
1903 OP(icode, &ptr, iMACMV, GPR(l+3), GPR(l+2), GPR(l+3), GPR(TREBLE_GPR + 8 + j));
1904 OP(icode, &ptr, iMAC0, GPR(l+2), GPR_ACCU, GPR(l+2), GPR(TREBLE_GPR + 6 + j));
1905 OP(icode, &ptr, iMACINT0, GPR(l+2), C_00000000, GPR(l+2), C_00000010);
1907 OP(icode, &ptr, iACC3, GPR(d), GPR(l+2), C_00000000, C_00000000);
1909 if (z == 2) /* center */
1918 for (z = 0; z < 6; z++) {
1919 SWITCH(icode, &ptr, tmp + 0, playback + SND_EMU10K1_PLAYBACK_CHANNELS + z, gpr + 0);
1920 SWITCH_NEG(icode, &ptr, tmp + 1, gpr + 0);
1921 SWITCH(icode, &ptr, tmp + 1, playback + z, tmp + 1);
1922 OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + z), GPR(tmp + 0), GPR(tmp + 1), C_00000000);
1924 snd_emu10k1_init_stereo_onoff_control(controls + i++, "Tone Control - Switch", gpr, 0);
1930 if (emu->fx8010.extout_mask & ((1<<EXTOUT_AC97_L)|(1<<EXTOUT_AC97_R))) {
1931 /* AC'97 Playback Volume */
1933 for (z = 0; z < 2; z++)
1934 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_AC97_L + z), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + z), C_00000000, C_00000000);
1937 if (emu->fx8010.extout_mask & ((1<<EXTOUT_TOSLINK_L)|(1<<EXTOUT_TOSLINK_R))) {
1938 /* IEC958 Optical Raw Playback Switch */
1940 for (z = 0; z < 2; z++) {
1941 SWITCH(icode, &ptr, tmp + 0, 8 + z, gpr + z);
1942 SWITCH_NEG(icode, &ptr, tmp + 1, gpr + z);
1943 SWITCH(icode, &ptr, tmp + 1, playback + SND_EMU10K1_PLAYBACK_CHANNELS + z, tmp + 1);
1944 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_TOSLINK_L + z), GPR(tmp + 0), GPR(tmp + 1), C_00000000);
1945 #ifdef EMU10K1_CAPTURE_DIGITAL_OUT
1946 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_ADC_CAP_L + z), GPR(tmp + 0), GPR(tmp + 1), C_00000000);
1950 snd_emu10k1_init_stereo_onoff_control(controls + i++, SNDRV_CTL_NAME_IEC958("Optical Raw ",PLAYBACK,SWITCH), gpr, 0);
1954 if (emu->fx8010.extout_mask & ((1<<EXTOUT_HEADPHONE_L)|(1<<EXTOUT_HEADPHONE_R))) {
1955 /* Headphone Playback Volume */
1957 for (z = 0; z < 2; z++) {
1958 SWITCH(icode, &ptr, tmp + 0, playback + SND_EMU10K1_PLAYBACK_CHANNELS + 4 + z, gpr + 2 + z);
1959 SWITCH_NEG(icode, &ptr, tmp + 1, gpr + 2 + z);
1960 SWITCH(icode, &ptr, tmp + 1, playback + SND_EMU10K1_PLAYBACK_CHANNELS + z, tmp + 1);
1961 OP(icode, &ptr, iACC3, GPR(tmp + 0), GPR(tmp + 0), GPR(tmp + 1), C_00000000);
1962 VOLUME_OUT(icode, &ptr, EXTOUT_HEADPHONE_L + z, tmp + 0, gpr + z);
1965 snd_emu10k1_init_stereo_control(controls + i++, "Headphone Playback Volume", gpr + 0, 0);
1966 controls[i-1].id.index = 1; /* AC'97 can have also Headphone control */
1967 snd_emu10k1_init_mono_onoff_control(controls + i++, "Headphone Center Playback Switch", gpr + 2, 0);
1968 controls[i-1].id.index = 1;
1969 snd_emu10k1_init_mono_onoff_control(controls + i++, "Headphone LFE Playback Switch", gpr + 3, 0);
1970 controls[i-1].id.index = 1;
1975 if (emu->fx8010.extout_mask & ((1<<EXTOUT_REAR_L)|(1<<EXTOUT_REAR_R)))
1976 for (z = 0; z < 2; z++)
1977 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_REAR_L + z), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 2 + z), C_00000000, C_00000000);
1979 if (emu->fx8010.extout_mask & ((1<<EXTOUT_AC97_REAR_L)|(1<<EXTOUT_AC97_REAR_R)))
1980 for (z = 0; z < 2; z++)
1981 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_AC97_REAR_L + z), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 2 + z), C_00000000, C_00000000);
1983 if (emu->fx8010.extout_mask & (1<<EXTOUT_AC97_CENTER)) {
1984 #ifndef EMU10K1_CENTER_LFE_FROM_FRONT
1985 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_AC97_CENTER), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 4), C_00000000, C_00000000);
1986 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_ACENTER), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 4), C_00000000, C_00000000);
1988 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_AC97_CENTER), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 0), C_00000000, C_00000000);
1989 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_ACENTER), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 0), C_00000000, C_00000000);
1993 if (emu->fx8010.extout_mask & (1<<EXTOUT_AC97_LFE)) {
1994 #ifndef EMU10K1_CENTER_LFE_FROM_FRONT
1995 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_AC97_LFE), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 5), C_00000000, C_00000000);
1996 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_ALFE), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 5), C_00000000, C_00000000);
1998 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_AC97_LFE), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 1), C_00000000, C_00000000);
1999 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_ALFE), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 1), C_00000000, C_00000000);
2003 #ifndef EMU10K1_CAPTURE_DIGITAL_OUT
2004 for (z = 0; z < 2; z++)
2005 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_ADC_CAP_L + z), GPR(capture + z), C_00000000, C_00000000);
2008 if (emu->fx8010.extout_mask & (1<<EXTOUT_MIC_CAP))
2009 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_MIC_CAP), GPR(capture + 2), C_00000000, C_00000000);
2011 /* EFX capture - capture the 16 EXTINS */
2012 if (emu->card_capabilities->sblive51) {
2013 /* On the Live! 5.1, FXBUS2(1) and FXBUS(2) are shared with EXTOUT_ACENTER
2014 * and EXTOUT_ALFE, so we can't connect inputs to them for multitrack recording.
2016 * Since only 14 of the 16 EXTINs are used, this is not a big problem.
2017 * We route AC97L and R to FX capture 14 and 15, SPDIF CD in to FX capture
2018 * 0 and 3, then the rest of the EXTINs to the corresponding FX capture
2019 * channel. Multitrack recorders will still see the center/lfe output signal
2020 * on the second and third channels.
2022 OP(icode, &ptr, iACC3, FXBUS2(14), C_00000000, C_00000000, EXTIN(0));
2023 OP(icode, &ptr, iACC3, FXBUS2(15), C_00000000, C_00000000, EXTIN(1));
2024 OP(icode, &ptr, iACC3, FXBUS2(0), C_00000000, C_00000000, EXTIN(2));
2025 OP(icode, &ptr, iACC3, FXBUS2(3), C_00000000, C_00000000, EXTIN(3));
2026 for (z = 4; z < 14; z++)
2027 OP(icode, &ptr, iACC3, FXBUS2(z), C_00000000, C_00000000, EXTIN(z));
2029 for (z = 0; z < 16; z++)
2030 OP(icode, &ptr, iACC3, FXBUS2(z), C_00000000, C_00000000, EXTIN(z));
2039 if (i > SND_EMU10K1_GPR_CONTROLS) {
2045 /* clear remaining instruction memory */
2047 OP(icode, &ptr, iACC3, C_00000000, C_00000000, C_00000000, C_00000000);
2049 if ((err = snd_emu10k1_fx8010_tram_setup(emu, ipcm->buffer_size)) < 0)
2051 seg = snd_enter_user();
2052 icode->gpr_add_control_count = i;
2053 icode->gpr_add_controls = (emu10k1_fx8010_control_gpr_t __user *)controls;
2054 err = snd_emu10k1_icode_poke(emu, icode);
2055 snd_leave_user(seg);
2057 err = snd_emu10k1_ipcm_poke(emu, ipcm);
2061 if (icode != NULL) {
2062 kfree((void __force *)icode->gpr_map);
2068 int __devinit snd_emu10k1_init_efx(emu10k1_t *emu)
2071 return _snd_emu10k1_audigy_init_efx(emu);
2073 return _snd_emu10k1_init_efx(emu);
2076 void snd_emu10k1_free_efx(emu10k1_t *emu)
2078 /* stop processor */
2080 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg = A_DBG_SINGLE_STEP);
2082 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg = EMU10K1_DBG_SINGLE_STEP);
2085 #if 0 // FIXME: who use them?
2086 int snd_emu10k1_fx8010_tone_control_activate(emu10k1_t *emu, int output)
2088 if (output < 0 || output >= 6)
2090 snd_emu10k1_ptr_write(emu, emu->gpr_base + 0x94 + output, 0, 1);
2094 int snd_emu10k1_fx8010_tone_control_deactivate(emu10k1_t *emu, int output)
2096 if (output < 0 || output >= 6)
2098 snd_emu10k1_ptr_write(emu, emu->gpr_base + 0x94 + output, 0, 0);
2103 int snd_emu10k1_fx8010_tram_setup(emu10k1_t *emu, u32 size)
2107 /* size is in samples */
2109 size = (size - 1) >> 13;
2115 size = 0x2000 << size_reg;
2117 if ((emu->fx8010.etram_pages.bytes / 2) == size)
2119 spin_lock_irq(&emu->emu_lock);
2120 outl(HCFG_LOCKTANKCACHE_MASK | inl(emu->port + HCFG), emu->port + HCFG);
2121 spin_unlock_irq(&emu->emu_lock);
2122 snd_emu10k1_ptr_write(emu, TCB, 0, 0);
2123 snd_emu10k1_ptr_write(emu, TCBS, 0, 0);
2124 if (emu->fx8010.etram_pages.area != NULL) {
2125 snd_dma_free_pages(&emu->fx8010.etram_pages);
2126 emu->fx8010.etram_pages.area = NULL;
2127 emu->fx8010.etram_pages.bytes = 0;
2131 if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(emu->pci),
2132 size * 2, &emu->fx8010.etram_pages) < 0)
2134 memset(emu->fx8010.etram_pages.area, 0, size * 2);
2135 snd_emu10k1_ptr_write(emu, TCB, 0, emu->fx8010.etram_pages.addr);
2136 snd_emu10k1_ptr_write(emu, TCBS, 0, size_reg);
2137 spin_lock_irq(&emu->emu_lock);
2138 outl(inl(emu->port + HCFG) & ~HCFG_LOCKTANKCACHE_MASK, emu->port + HCFG);
2139 spin_unlock_irq(&emu->emu_lock);
2145 static int snd_emu10k1_fx8010_open(snd_hwdep_t * hw, struct file *file)
2150 static void copy_string(char *dst, char *src, char *null, int idx)
2153 sprintf(dst, "%s %02X", null, idx);
2158 static int snd_emu10k1_fx8010_info(emu10k1_t *emu, emu10k1_fx8010_info_t *info)
2160 char **fxbus, **extin, **extout;
2161 unsigned short fxbus_mask, extin_mask, extout_mask;
2164 memset(info, 0, sizeof(info));
2165 info->internal_tram_size = emu->fx8010.itram_size;
2166 info->external_tram_size = emu->fx8010.etram_pages.bytes / 2;
2168 extin = emu->audigy ? audigy_ins : creative_ins;
2169 extout = emu->audigy ? audigy_outs : creative_outs;
2170 fxbus_mask = emu->fx8010.fxbus_mask;
2171 extin_mask = emu->fx8010.extin_mask;
2172 extout_mask = emu->fx8010.extout_mask;
2173 for (res = 0; res < 16; res++, fxbus++, extin++, extout++) {
2174 copy_string(info->fxbus_names[res], fxbus_mask & (1 << res) ? *fxbus : NULL, "FXBUS", res);
2175 copy_string(info->extin_names[res], extin_mask & (1 << res) ? *extin : NULL, "Unused", res);
2176 copy_string(info->extout_names[res], extout_mask & (1 << res) ? *extout : NULL, "Unused", res);
2178 for (res = 16; res < 32; res++, extout++)
2179 copy_string(info->extout_names[res], extout_mask & (1 << res) ? *extout : NULL, "Unused", res);
2180 info->gpr_controls = emu->fx8010.gpr_count;
2184 static int snd_emu10k1_fx8010_ioctl(snd_hwdep_t * hw, struct file *file, unsigned int cmd, unsigned long arg)
2186 emu10k1_t *emu = hw->private_data;
2187 emu10k1_fx8010_info_t *info;
2188 emu10k1_fx8010_code_t *icode;
2189 emu10k1_fx8010_pcm_t *ipcm;
2191 void __user *argp = (void __user *)arg;
2195 case SNDRV_EMU10K1_IOCTL_INFO:
2196 info = (emu10k1_fx8010_info_t *)kmalloc(sizeof(*info), GFP_KERNEL);
2199 if ((res = snd_emu10k1_fx8010_info(emu, info)) < 0) {
2203 if (copy_to_user(argp, info, sizeof(*info))) {
2209 case SNDRV_EMU10K1_IOCTL_CODE_POKE:
2210 if (!capable(CAP_SYS_ADMIN))
2212 icode = (emu10k1_fx8010_code_t *)kmalloc(sizeof(*icode), GFP_KERNEL);
2215 if (copy_from_user(icode, argp, sizeof(*icode))) {
2219 res = snd_emu10k1_icode_poke(emu, icode);
2222 case SNDRV_EMU10K1_IOCTL_CODE_PEEK:
2223 icode = (emu10k1_fx8010_code_t *)kmalloc(sizeof(*icode), GFP_KERNEL);
2226 if (copy_from_user(icode, argp, sizeof(*icode))) {
2230 res = snd_emu10k1_icode_peek(emu, icode);
2231 if (res == 0 && copy_to_user(argp, icode, sizeof(*icode))) {
2237 case SNDRV_EMU10K1_IOCTL_PCM_POKE:
2238 ipcm = (emu10k1_fx8010_pcm_t *)kmalloc(sizeof(*ipcm), GFP_KERNEL);
2241 if (copy_from_user(ipcm, argp, sizeof(*ipcm))) {
2245 res = snd_emu10k1_ipcm_poke(emu, ipcm);
2248 case SNDRV_EMU10K1_IOCTL_PCM_PEEK:
2249 ipcm = kzalloc(sizeof(*ipcm), GFP_KERNEL);
2252 if (copy_from_user(ipcm, argp, sizeof(*ipcm))) {
2256 res = snd_emu10k1_ipcm_peek(emu, ipcm);
2257 if (res == 0 && copy_to_user(argp, ipcm, sizeof(*ipcm))) {
2263 case SNDRV_EMU10K1_IOCTL_TRAM_SETUP:
2264 if (!capable(CAP_SYS_ADMIN))
2266 if (get_user(addr, (unsigned int __user *)argp))
2268 down(&emu->fx8010.lock);
2269 res = snd_emu10k1_fx8010_tram_setup(emu, addr);
2270 up(&emu->fx8010.lock);
2272 case SNDRV_EMU10K1_IOCTL_STOP:
2273 if (!capable(CAP_SYS_ADMIN))
2276 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg |= A_DBG_SINGLE_STEP);
2278 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg |= EMU10K1_DBG_SINGLE_STEP);
2280 case SNDRV_EMU10K1_IOCTL_CONTINUE:
2281 if (!capable(CAP_SYS_ADMIN))
2284 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg = 0);
2286 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg = 0);
2288 case SNDRV_EMU10K1_IOCTL_ZERO_TRAM_COUNTER:
2289 if (!capable(CAP_SYS_ADMIN))
2292 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg | A_DBG_ZC);
2294 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg | EMU10K1_DBG_ZC);
2297 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg);
2299 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg);
2301 case SNDRV_EMU10K1_IOCTL_SINGLE_STEP:
2302 if (!capable(CAP_SYS_ADMIN))
2304 if (get_user(addr, (unsigned int __user *)argp))
2309 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg |= A_DBG_SINGLE_STEP | addr);
2311 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg |= EMU10K1_DBG_SINGLE_STEP | addr);
2314 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg |= A_DBG_SINGLE_STEP | A_DBG_STEP_ADDR | addr);
2316 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg |= EMU10K1_DBG_SINGLE_STEP | EMU10K1_DBG_STEP | addr);
2318 case SNDRV_EMU10K1_IOCTL_DBG_READ:
2320 addr = snd_emu10k1_ptr_read(emu, A_DBG, 0);
2322 addr = snd_emu10k1_ptr_read(emu, DBG, 0);
2323 if (put_user(addr, (unsigned int __user *)argp))
2330 static int snd_emu10k1_fx8010_release(snd_hwdep_t * hw, struct file *file)
2335 int __devinit snd_emu10k1_fx8010_new(emu10k1_t *emu, int device, snd_hwdep_t ** rhwdep)
2342 if ((err = snd_hwdep_new(emu->card, "FX8010", device, &hw)) < 0)
2344 strcpy(hw->name, "EMU10K1 (FX8010)");
2345 hw->iface = SNDRV_HWDEP_IFACE_EMU10K1;
2346 hw->ops.open = snd_emu10k1_fx8010_open;
2347 hw->ops.ioctl = snd_emu10k1_fx8010_ioctl;
2348 hw->ops.release = snd_emu10k1_fx8010_release;
2349 hw->private_data = emu;