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(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
314 struct snd_emu10k1_fx8010_ctl *ctl =
315 (struct snd_emu10k1_fx8010_ctl *) kcontrol->private_value;
317 if (ctl->min == 0 && ctl->max == 1)
318 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
320 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
321 uinfo->count = ctl->vcount;
322 uinfo->value.integer.min = ctl->min;
323 uinfo->value.integer.max = ctl->max;
327 static int snd_emu10k1_gpr_ctl_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
329 struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
330 struct snd_emu10k1_fx8010_ctl *ctl =
331 (struct snd_emu10k1_fx8010_ctl *) kcontrol->private_value;
335 spin_lock_irqsave(&emu->reg_lock, flags);
336 for (i = 0; i < ctl->vcount; i++)
337 ucontrol->value.integer.value[i] = ctl->value[i];
338 spin_unlock_irqrestore(&emu->reg_lock, flags);
342 static int snd_emu10k1_gpr_ctl_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
344 struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
345 struct snd_emu10k1_fx8010_ctl *ctl =
346 (struct snd_emu10k1_fx8010_ctl *) kcontrol->private_value;
348 unsigned int nval, val;
352 spin_lock_irqsave(&emu->reg_lock, flags);
353 for (i = 0; i < ctl->vcount; i++) {
354 nval = ucontrol->value.integer.value[i];
359 if (nval != ctl->value[i])
361 val = ctl->value[i] = nval;
362 switch (ctl->translation) {
363 case EMU10K1_GPR_TRANSLATION_NONE:
364 snd_emu10k1_ptr_write(emu, emu->gpr_base + ctl->gpr[i], 0, val);
366 case EMU10K1_GPR_TRANSLATION_TABLE100:
367 snd_emu10k1_ptr_write(emu, emu->gpr_base + ctl->gpr[i], 0, db_table[val]);
369 case EMU10K1_GPR_TRANSLATION_BASS:
370 if ((ctl->count % 5) != 0 || (ctl->count / 5) != ctl->vcount) {
374 for (j = 0; j < 5; j++)
375 snd_emu10k1_ptr_write(emu, emu->gpr_base + ctl->gpr[j * ctl->vcount + i], 0, bass_table[val][j]);
377 case EMU10K1_GPR_TRANSLATION_TREBLE:
378 if ((ctl->count % 5) != 0 || (ctl->count / 5) != ctl->vcount) {
382 for (j = 0; j < 5; j++)
383 snd_emu10k1_ptr_write(emu, emu->gpr_base + ctl->gpr[j * ctl->vcount + i], 0, treble_table[val][j]);
385 case EMU10K1_GPR_TRANSLATION_ONOFF:
386 snd_emu10k1_ptr_write(emu, emu->gpr_base + ctl->gpr[i], 0, onoff_table[val]);
391 spin_unlock_irqrestore(&emu->reg_lock, flags);
399 static void snd_emu10k1_fx8010_interrupt(struct snd_emu10k1 *emu)
401 struct snd_emu10k1_fx8010_irq *irq, *nirq;
403 irq = emu->fx8010.irq_handlers;
405 nirq = irq->next; /* irq ptr can be removed from list */
406 if (snd_emu10k1_ptr_read(emu, emu->gpr_base + irq->gpr_running, 0) & 0xffff0000) {
408 irq->handler(emu, irq->private_data);
409 snd_emu10k1_ptr_write(emu, emu->gpr_base + irq->gpr_running, 0, 1);
415 int snd_emu10k1_fx8010_register_irq_handler(struct snd_emu10k1 *emu,
416 snd_fx8010_irq_handler_t *handler,
417 unsigned char gpr_running,
419 struct snd_emu10k1_fx8010_irq **r_irq)
421 struct snd_emu10k1_fx8010_irq *irq;
424 irq = kmalloc(sizeof(*irq), GFP_ATOMIC);
427 irq->handler = handler;
428 irq->gpr_running = gpr_running;
429 irq->private_data = private_data;
431 spin_lock_irqsave(&emu->fx8010.irq_lock, flags);
432 if (emu->fx8010.irq_handlers == NULL) {
433 emu->fx8010.irq_handlers = irq;
434 emu->dsp_interrupt = snd_emu10k1_fx8010_interrupt;
435 snd_emu10k1_intr_enable(emu, INTE_FXDSPENABLE);
437 irq->next = emu->fx8010.irq_handlers;
438 emu->fx8010.irq_handlers = irq;
440 spin_unlock_irqrestore(&emu->fx8010.irq_lock, flags);
446 int snd_emu10k1_fx8010_unregister_irq_handler(struct snd_emu10k1 *emu,
447 struct snd_emu10k1_fx8010_irq *irq)
449 struct snd_emu10k1_fx8010_irq *tmp;
452 spin_lock_irqsave(&emu->fx8010.irq_lock, flags);
453 if ((tmp = emu->fx8010.irq_handlers) == irq) {
454 emu->fx8010.irq_handlers = tmp->next;
455 if (emu->fx8010.irq_handlers == NULL) {
456 snd_emu10k1_intr_disable(emu, INTE_FXDSPENABLE);
457 emu->dsp_interrupt = NULL;
460 while (tmp && tmp->next != irq)
463 tmp->next = tmp->next->next;
465 spin_unlock_irqrestore(&emu->fx8010.irq_lock, flags);
470 /*************************************************************************
471 * EMU10K1 effect manager
472 *************************************************************************/
474 static void snd_emu10k1_write_op(struct snd_emu10k1_fx8010_code *icode,
476 u32 op, u32 r, u32 a, u32 x, u32 y)
479 snd_assert(*ptr < 512, return);
480 code = (u_int32_t __force *)icode->code + (*ptr) * 2;
481 set_bit(*ptr, icode->code_valid);
482 code[0] = ((x & 0x3ff) << 10) | (y & 0x3ff);
483 code[1] = ((op & 0x0f) << 20) | ((r & 0x3ff) << 10) | (a & 0x3ff);
487 #define OP(icode, ptr, op, r, a, x, y) \
488 snd_emu10k1_write_op(icode, ptr, op, r, a, x, y)
490 static void snd_emu10k1_audigy_write_op(struct snd_emu10k1_fx8010_code *icode,
492 u32 op, u32 r, u32 a, u32 x, u32 y)
495 snd_assert(*ptr < 1024, return);
496 code = (u_int32_t __force *)icode->code + (*ptr) * 2;
497 set_bit(*ptr, icode->code_valid);
498 code[0] = ((x & 0x7ff) << 12) | (y & 0x7ff);
499 code[1] = ((op & 0x0f) << 24) | ((r & 0x7ff) << 12) | (a & 0x7ff);
503 #define A_OP(icode, ptr, op, r, a, x, y) \
504 snd_emu10k1_audigy_write_op(icode, ptr, op, r, a, x, y)
506 static void snd_emu10k1_efx_write(struct snd_emu10k1 *emu, unsigned int pc, unsigned int data)
508 pc += emu->audigy ? A_MICROCODEBASE : MICROCODEBASE;
509 snd_emu10k1_ptr_write(emu, pc, 0, data);
512 unsigned int snd_emu10k1_efx_read(struct snd_emu10k1 *emu, unsigned int pc)
514 pc += emu->audigy ? A_MICROCODEBASE : MICROCODEBASE;
515 return snd_emu10k1_ptr_read(emu, pc, 0);
518 static int snd_emu10k1_gpr_poke(struct snd_emu10k1 *emu,
519 struct snd_emu10k1_fx8010_code *icode)
524 for (gpr = 0; gpr < (emu->audigy ? 0x200 : 0x100); gpr++) {
525 if (!test_bit(gpr, icode->gpr_valid))
527 if (get_user(val, &icode->gpr_map[gpr]))
529 snd_emu10k1_ptr_write(emu, emu->gpr_base + gpr, 0, val);
534 static int snd_emu10k1_gpr_peek(struct snd_emu10k1 *emu,
535 struct snd_emu10k1_fx8010_code *icode)
540 for (gpr = 0; gpr < (emu->audigy ? 0x200 : 0x100); gpr++) {
541 set_bit(gpr, icode->gpr_valid);
542 val = snd_emu10k1_ptr_read(emu, emu->gpr_base + gpr, 0);
543 if (put_user(val, &icode->gpr_map[gpr]))
549 static int snd_emu10k1_tram_poke(struct snd_emu10k1 *emu,
550 struct snd_emu10k1_fx8010_code *icode)
555 for (tram = 0; tram < (emu->audigy ? 0x100 : 0xa0); tram++) {
556 if (!test_bit(tram, icode->tram_valid))
558 if (get_user(val, &icode->tram_data_map[tram]) ||
559 get_user(addr, &icode->tram_addr_map[tram]))
561 snd_emu10k1_ptr_write(emu, TANKMEMDATAREGBASE + tram, 0, val);
563 snd_emu10k1_ptr_write(emu, TANKMEMADDRREGBASE + tram, 0, addr);
565 snd_emu10k1_ptr_write(emu, TANKMEMADDRREGBASE + tram, 0, addr << 12);
566 snd_emu10k1_ptr_write(emu, A_TANKMEMCTLREGBASE + tram, 0, addr >> 20);
572 static int snd_emu10k1_tram_peek(struct snd_emu10k1 *emu,
573 struct snd_emu10k1_fx8010_code *icode)
578 memset(icode->tram_valid, 0, sizeof(icode->tram_valid));
579 for (tram = 0; tram < (emu->audigy ? 0x100 : 0xa0); tram++) {
580 set_bit(tram, icode->tram_valid);
581 val = snd_emu10k1_ptr_read(emu, TANKMEMDATAREGBASE + tram, 0);
583 addr = snd_emu10k1_ptr_read(emu, TANKMEMADDRREGBASE + tram, 0);
585 addr = snd_emu10k1_ptr_read(emu, TANKMEMADDRREGBASE + tram, 0) >> 12;
586 addr |= snd_emu10k1_ptr_read(emu, A_TANKMEMCTLREGBASE + tram, 0) << 20;
588 if (put_user(val, &icode->tram_data_map[tram]) ||
589 put_user(addr, &icode->tram_addr_map[tram]))
595 static int snd_emu10k1_code_poke(struct snd_emu10k1 *emu,
596 struct snd_emu10k1_fx8010_code *icode)
600 for (pc = 0; pc < (emu->audigy ? 2*1024 : 2*512); pc += 2) {
601 if (!test_bit(pc / 2, icode->code_valid))
603 if (get_user(lo, &icode->code[pc + 0]) ||
604 get_user(hi, &icode->code[pc + 1]))
606 snd_emu10k1_efx_write(emu, pc + 0, lo);
607 snd_emu10k1_efx_write(emu, pc + 1, hi);
612 static int snd_emu10k1_code_peek(struct snd_emu10k1 *emu,
613 struct snd_emu10k1_fx8010_code *icode)
617 memset(icode->code_valid, 0, sizeof(icode->code_valid));
618 for (pc = 0; pc < (emu->audigy ? 2*1024 : 2*512); pc += 2) {
619 set_bit(pc / 2, icode->code_valid);
620 if (put_user(snd_emu10k1_efx_read(emu, pc + 0), &icode->code[pc + 0]))
622 if (put_user(snd_emu10k1_efx_read(emu, pc + 1), &icode->code[pc + 1]))
628 static struct snd_emu10k1_fx8010_ctl *
629 snd_emu10k1_look_for_ctl(struct snd_emu10k1 *emu, struct snd_ctl_elem_id *id)
631 struct snd_emu10k1_fx8010_ctl *ctl;
632 struct snd_kcontrol *kcontrol;
633 struct list_head *list;
635 list_for_each(list, &emu->fx8010.gpr_ctl) {
636 ctl = emu10k1_gpr_ctl(list);
637 kcontrol = ctl->kcontrol;
638 if (kcontrol->id.iface == id->iface &&
639 !strcmp(kcontrol->id.name, id->name) &&
640 kcontrol->id.index == id->index)
646 static int snd_emu10k1_verify_controls(struct snd_emu10k1 *emu,
647 struct snd_emu10k1_fx8010_code *icode)
650 struct snd_ctl_elem_id __user *_id;
651 struct snd_ctl_elem_id id;
652 struct snd_emu10k1_fx8010_control_gpr __user *_gctl;
653 struct snd_emu10k1_fx8010_control_gpr *gctl;
656 for (i = 0, _id = icode->gpr_del_controls;
657 i < icode->gpr_del_control_count; i++, _id++) {
658 if (copy_from_user(&id, _id, sizeof(id)))
660 if (snd_emu10k1_look_for_ctl(emu, &id) == NULL)
663 gctl = kmalloc(sizeof(*gctl), GFP_KERNEL);
667 for (i = 0, _gctl = icode->gpr_add_controls;
668 i < icode->gpr_add_control_count; i++, _gctl++) {
669 if (copy_from_user(gctl, _gctl, sizeof(*gctl))) {
673 if (snd_emu10k1_look_for_ctl(emu, &gctl->id))
675 down_read(&emu->card->controls_rwsem);
676 if (snd_ctl_find_id(emu->card, &gctl->id) != NULL) {
677 up_read(&emu->card->controls_rwsem);
681 up_read(&emu->card->controls_rwsem);
682 if (gctl->id.iface != SNDRV_CTL_ELEM_IFACE_MIXER &&
683 gctl->id.iface != SNDRV_CTL_ELEM_IFACE_PCM) {
688 for (i = 0, _gctl = icode->gpr_list_controls;
689 i < icode->gpr_list_control_count; i++, _gctl++) {
690 /* FIXME: we need to check the WRITE access */
691 if (copy_from_user(gctl, _gctl, sizeof(*gctl))) {
701 static void snd_emu10k1_ctl_private_free(struct snd_kcontrol *kctl)
703 struct snd_emu10k1_fx8010_ctl *ctl;
705 ctl = (struct snd_emu10k1_fx8010_ctl *) kctl->private_value;
706 kctl->private_value = 0;
707 list_del(&ctl->list);
711 static int snd_emu10k1_add_controls(struct snd_emu10k1 *emu,
712 struct snd_emu10k1_fx8010_code *icode)
715 struct snd_emu10k1_fx8010_control_gpr __user *_gctl;
716 struct snd_emu10k1_fx8010_control_gpr *gctl;
717 struct snd_emu10k1_fx8010_ctl *ctl, *nctl;
718 struct snd_kcontrol_new knew;
719 struct snd_kcontrol *kctl;
720 struct snd_ctl_elem_value *val;
723 val = kmalloc(sizeof(*val), GFP_KERNEL);
724 gctl = kmalloc(sizeof(*gctl), GFP_KERNEL);
725 nctl = kmalloc(sizeof(*nctl), GFP_KERNEL);
726 if (!val || !gctl || !nctl) {
731 for (i = 0, _gctl = icode->gpr_add_controls;
732 i < icode->gpr_add_control_count; i++, _gctl++) {
733 if (copy_from_user(gctl, _gctl, sizeof(*gctl))) {
737 if (gctl->id.iface != SNDRV_CTL_ELEM_IFACE_MIXER &&
738 gctl->id.iface != SNDRV_CTL_ELEM_IFACE_PCM) {
742 if (! gctl->id.name[0]) {
746 ctl = snd_emu10k1_look_for_ctl(emu, &gctl->id);
747 memset(&knew, 0, sizeof(knew));
748 knew.iface = gctl->id.iface;
749 knew.name = gctl->id.name;
750 knew.index = gctl->id.index;
751 knew.device = gctl->id.device;
752 knew.subdevice = gctl->id.subdevice;
753 knew.info = snd_emu10k1_gpr_ctl_info;
754 knew.get = snd_emu10k1_gpr_ctl_get;
755 knew.put = snd_emu10k1_gpr_ctl_put;
756 memset(nctl, 0, sizeof(*nctl));
757 nctl->vcount = gctl->vcount;
758 nctl->count = gctl->count;
759 for (j = 0; j < 32; j++) {
760 nctl->gpr[j] = gctl->gpr[j];
761 nctl->value[j] = ~gctl->value[j]; /* inverted, we want to write new value in gpr_ctl_put() */
762 val->value.integer.value[j] = gctl->value[j];
764 nctl->min = gctl->min;
765 nctl->max = gctl->max;
766 nctl->translation = gctl->translation;
768 ctl = kmalloc(sizeof(*ctl), GFP_KERNEL);
773 knew.private_value = (unsigned long)ctl;
775 if ((err = snd_ctl_add(emu->card, kctl = snd_ctl_new1(&knew, emu))) < 0) {
779 kctl->private_free = snd_emu10k1_ctl_private_free;
780 ctl->kcontrol = kctl;
781 list_add_tail(&ctl->list, &emu->fx8010.gpr_ctl);
784 nctl->list = ctl->list;
785 nctl->kcontrol = ctl->kcontrol;
787 snd_ctl_notify(emu->card, SNDRV_CTL_EVENT_MASK_VALUE |
788 SNDRV_CTL_EVENT_MASK_INFO, &ctl->kcontrol->id);
790 snd_emu10k1_gpr_ctl_put(ctl->kcontrol, val);
799 static int snd_emu10k1_del_controls(struct snd_emu10k1 *emu,
800 struct snd_emu10k1_fx8010_code *icode)
803 struct snd_ctl_elem_id id;
804 struct snd_ctl_elem_id __user *_id;
805 struct snd_emu10k1_fx8010_ctl *ctl;
806 struct snd_card *card = emu->card;
808 for (i = 0, _id = icode->gpr_del_controls;
809 i < icode->gpr_del_control_count; i++, _id++) {
810 if (copy_from_user(&id, _id, sizeof(id)))
812 down_write(&card->controls_rwsem);
813 ctl = snd_emu10k1_look_for_ctl(emu, &id);
815 snd_ctl_remove(card, ctl->kcontrol);
816 up_write(&card->controls_rwsem);
821 static int snd_emu10k1_list_controls(struct snd_emu10k1 *emu,
822 struct snd_emu10k1_fx8010_code *icode)
824 unsigned int i = 0, j;
825 unsigned int total = 0;
826 struct snd_emu10k1_fx8010_control_gpr *gctl;
827 struct snd_emu10k1_fx8010_control_gpr __user *_gctl;
828 struct snd_emu10k1_fx8010_ctl *ctl;
829 struct snd_ctl_elem_id *id;
830 struct list_head *list;
832 gctl = kmalloc(sizeof(*gctl), GFP_KERNEL);
836 _gctl = icode->gpr_list_controls;
837 list_for_each(list, &emu->fx8010.gpr_ctl) {
838 ctl = emu10k1_gpr_ctl(list);
840 if (_gctl && i < icode->gpr_list_control_count) {
841 memset(gctl, 0, sizeof(*gctl));
842 id = &ctl->kcontrol->id;
843 gctl->id.iface = id->iface;
844 strlcpy(gctl->id.name, id->name, sizeof(gctl->id.name));
845 gctl->id.index = id->index;
846 gctl->id.device = id->device;
847 gctl->id.subdevice = id->subdevice;
848 gctl->vcount = ctl->vcount;
849 gctl->count = ctl->count;
850 for (j = 0; j < 32; j++) {
851 gctl->gpr[j] = ctl->gpr[j];
852 gctl->value[j] = ctl->value[j];
854 gctl->min = ctl->min;
855 gctl->max = ctl->max;
856 gctl->translation = ctl->translation;
857 if (copy_to_user(_gctl, gctl, sizeof(*gctl))) {
865 icode->gpr_list_control_total = total;
870 static int snd_emu10k1_icode_poke(struct snd_emu10k1 *emu,
871 struct snd_emu10k1_fx8010_code *icode)
875 down(&emu->fx8010.lock);
876 if ((err = snd_emu10k1_verify_controls(emu, icode)) < 0)
878 strlcpy(emu->fx8010.name, icode->name, sizeof(emu->fx8010.name));
879 /* stop FX processor - this may be dangerous, but it's better to miss
880 some samples than generate wrong ones - [jk] */
882 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg | A_DBG_SINGLE_STEP);
884 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg | EMU10K1_DBG_SINGLE_STEP);
885 /* ok, do the main job */
886 if ((err = snd_emu10k1_del_controls(emu, icode)) < 0 ||
887 (err = snd_emu10k1_gpr_poke(emu, icode)) < 0 ||
888 (err = snd_emu10k1_tram_poke(emu, icode)) < 0 ||
889 (err = snd_emu10k1_code_poke(emu, icode)) < 0 ||
890 (err = snd_emu10k1_add_controls(emu, icode)) < 0)
892 /* start FX processor when the DSP code is updated */
894 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg);
896 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg);
898 up(&emu->fx8010.lock);
902 static int snd_emu10k1_icode_peek(struct snd_emu10k1 *emu,
903 struct snd_emu10k1_fx8010_code *icode)
907 down(&emu->fx8010.lock);
908 strlcpy(icode->name, emu->fx8010.name, sizeof(icode->name));
909 /* ok, do the main job */
910 err = snd_emu10k1_gpr_peek(emu, icode);
912 err = snd_emu10k1_tram_peek(emu, icode);
914 err = snd_emu10k1_code_peek(emu, icode);
916 err = snd_emu10k1_list_controls(emu, icode);
917 up(&emu->fx8010.lock);
921 static int snd_emu10k1_ipcm_poke(struct snd_emu10k1 *emu,
922 struct snd_emu10k1_fx8010_pcm_rec *ipcm)
926 struct snd_emu10k1_fx8010_pcm *pcm;
928 if (ipcm->substream >= EMU10K1_FX8010_PCM_COUNT)
930 if (ipcm->channels > 32)
932 pcm = &emu->fx8010.pcm[ipcm->substream];
933 down(&emu->fx8010.lock);
934 spin_lock_irq(&emu->reg_lock);
939 if (ipcm->channels == 0) { /* remove */
942 /* FIXME: we need to add universal code to the PCM transfer routine */
943 if (ipcm->channels != 2) {
949 pcm->channels = ipcm->channels;
950 pcm->tram_start = ipcm->tram_start;
951 pcm->buffer_size = ipcm->buffer_size;
952 pcm->gpr_size = ipcm->gpr_size;
953 pcm->gpr_count = ipcm->gpr_count;
954 pcm->gpr_tmpcount = ipcm->gpr_tmpcount;
955 pcm->gpr_ptr = ipcm->gpr_ptr;
956 pcm->gpr_trigger = ipcm->gpr_trigger;
957 pcm->gpr_running = ipcm->gpr_running;
958 for (i = 0; i < pcm->channels; i++)
959 pcm->etram[i] = ipcm->etram[i];
962 spin_unlock_irq(&emu->reg_lock);
963 up(&emu->fx8010.lock);
967 static int snd_emu10k1_ipcm_peek(struct snd_emu10k1 *emu,
968 struct snd_emu10k1_fx8010_pcm_rec *ipcm)
972 struct snd_emu10k1_fx8010_pcm *pcm;
974 if (ipcm->substream >= EMU10K1_FX8010_PCM_COUNT)
976 pcm = &emu->fx8010.pcm[ipcm->substream];
977 down(&emu->fx8010.lock);
978 spin_lock_irq(&emu->reg_lock);
979 ipcm->channels = pcm->channels;
980 ipcm->tram_start = pcm->tram_start;
981 ipcm->buffer_size = pcm->buffer_size;
982 ipcm->gpr_size = pcm->gpr_size;
983 ipcm->gpr_ptr = pcm->gpr_ptr;
984 ipcm->gpr_count = pcm->gpr_count;
985 ipcm->gpr_tmpcount = pcm->gpr_tmpcount;
986 ipcm->gpr_trigger = pcm->gpr_trigger;
987 ipcm->gpr_running = pcm->gpr_running;
988 for (i = 0; i < pcm->channels; i++)
989 ipcm->etram[i] = pcm->etram[i];
990 ipcm->res1 = ipcm->res2 = 0;
992 spin_unlock_irq(&emu->reg_lock);
993 up(&emu->fx8010.lock);
997 #define SND_EMU10K1_GPR_CONTROLS 44
998 #define SND_EMU10K1_INPUTS 12
999 #define SND_EMU10K1_PLAYBACK_CHANNELS 8
1000 #define SND_EMU10K1_CAPTURE_CHANNELS 4
1002 static void __devinit
1003 snd_emu10k1_init_mono_control(struct snd_emu10k1_fx8010_control_gpr *ctl,
1004 const char *name, int gpr, int defval)
1006 ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1007 strcpy(ctl->id.name, name);
1008 ctl->vcount = ctl->count = 1;
1009 ctl->gpr[0] = gpr + 0; ctl->value[0] = defval;
1012 ctl->translation = EMU10K1_GPR_TRANSLATION_TABLE100;
1015 static void __devinit
1016 snd_emu10k1_init_stereo_control(struct snd_emu10k1_fx8010_control_gpr *ctl,
1017 const char *name, int gpr, int defval)
1019 ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1020 strcpy(ctl->id.name, name);
1021 ctl->vcount = ctl->count = 2;
1022 ctl->gpr[0] = gpr + 0; ctl->value[0] = defval;
1023 ctl->gpr[1] = gpr + 1; ctl->value[1] = defval;
1026 ctl->translation = EMU10K1_GPR_TRANSLATION_TABLE100;
1029 static void __devinit
1030 snd_emu10k1_init_mono_onoff_control(struct snd_emu10k1_fx8010_control_gpr *ctl,
1031 const char *name, int gpr, int defval)
1033 ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1034 strcpy(ctl->id.name, name);
1035 ctl->vcount = ctl->count = 1;
1036 ctl->gpr[0] = gpr + 0; ctl->value[0] = defval;
1039 ctl->translation = EMU10K1_GPR_TRANSLATION_ONOFF;
1042 static void __devinit
1043 snd_emu10k1_init_stereo_onoff_control(struct snd_emu10k1_fx8010_control_gpr *ctl,
1044 const char *name, int gpr, int defval)
1046 ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1047 strcpy(ctl->id.name, name);
1048 ctl->vcount = ctl->count = 2;
1049 ctl->gpr[0] = gpr + 0; ctl->value[0] = defval;
1050 ctl->gpr[1] = gpr + 1; ctl->value[1] = defval;
1053 ctl->translation = EMU10K1_GPR_TRANSLATION_ONOFF;
1058 * initial DSP configuration for Audigy
1061 static int __devinit _snd_emu10k1_audigy_init_efx(struct snd_emu10k1 *emu)
1063 int err, i, z, gpr, nctl;
1064 const int playback = 10;
1065 const int capture = playback + (SND_EMU10K1_PLAYBACK_CHANNELS * 2); /* we reserve 10 voices */
1066 const int stereo_mix = capture + 2;
1067 const int tmp = 0x88;
1069 struct snd_emu10k1_fx8010_code *icode = NULL;
1070 struct snd_emu10k1_fx8010_control_gpr *controls = NULL, *ctl;
1074 spin_lock_init(&emu->fx8010.irq_lock);
1075 INIT_LIST_HEAD(&emu->fx8010.gpr_ctl);
1077 if ((icode = kzalloc(sizeof(*icode), GFP_KERNEL)) == NULL ||
1078 (icode->gpr_map = (u_int32_t __user *)
1079 kcalloc(512 + 256 + 256 + 2 * 1024, sizeof(u_int32_t),
1080 GFP_KERNEL)) == NULL ||
1081 (controls = kcalloc(SND_EMU10K1_GPR_CONTROLS,
1082 sizeof(*controls), GFP_KERNEL)) == NULL) {
1086 gpr_map = (u32 __force *)icode->gpr_map;
1088 icode->tram_data_map = icode->gpr_map + 512;
1089 icode->tram_addr_map = icode->tram_data_map + 256;
1090 icode->code = icode->tram_addr_map + 256;
1092 /* clear free GPRs */
1093 for (i = 0; i < 512; i++)
1094 set_bit(i, icode->gpr_valid);
1096 /* clear TRAM data & address lines */
1097 for (i = 0; i < 256; i++)
1098 set_bit(i, icode->tram_valid);
1100 strcpy(icode->name, "Audigy DSP code for ALSA");
1103 gpr = stereo_mix + 10;
1105 /* stop FX processor */
1106 snd_emu10k1_ptr_write(emu, A_DBG, 0, (emu->fx8010.dbg = 0) | A_DBG_SINGLE_STEP);
1108 /* PCM front Playback Volume (independent from stereo mix) */
1109 A_OP(icode, &ptr, iMAC0, A_GPR(playback), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LEFT_FRONT));
1110 A_OP(icode, &ptr, iMAC0, A_GPR(playback+1), A_C_00000000, A_GPR(gpr+1), A_FXBUS(FXBUS_PCM_RIGHT_FRONT));
1111 snd_emu10k1_init_stereo_control(&controls[nctl++], "PCM Front Playback Volume", gpr, 100);
1114 /* PCM Surround Playback (independent from stereo mix) */
1115 A_OP(icode, &ptr, iMAC0, A_GPR(playback+2), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LEFT_REAR));
1116 A_OP(icode, &ptr, iMAC0, A_GPR(playback+3), A_C_00000000, A_GPR(gpr+1), A_FXBUS(FXBUS_PCM_RIGHT_REAR));
1117 snd_emu10k1_init_stereo_control(&controls[nctl++], "PCM Surround Playback Volume", gpr, 100);
1120 /* PCM Side Playback (independent from stereo mix) */
1121 if (emu->card_capabilities->spk71) {
1122 A_OP(icode, &ptr, iMAC0, A_GPR(playback+6), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LEFT_SIDE));
1123 A_OP(icode, &ptr, iMAC0, A_GPR(playback+7), A_C_00000000, A_GPR(gpr+1), A_FXBUS(FXBUS_PCM_RIGHT_SIDE));
1124 snd_emu10k1_init_stereo_control(&controls[nctl++], "PCM Side Playback Volume", gpr, 100);
1128 /* PCM Center Playback (independent from stereo mix) */
1129 A_OP(icode, &ptr, iMAC0, A_GPR(playback+4), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_CENTER));
1130 snd_emu10k1_init_mono_control(&controls[nctl++], "PCM Center Playback Volume", gpr, 100);
1133 /* PCM LFE Playback (independent from stereo mix) */
1134 A_OP(icode, &ptr, iMAC0, A_GPR(playback+5), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LFE));
1135 snd_emu10k1_init_mono_control(&controls[nctl++], "PCM LFE Playback Volume", gpr, 100);
1141 /* Wave (PCM) Playback Volume (will be renamed later) */
1142 A_OP(icode, &ptr, iMAC0, A_GPR(stereo_mix), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LEFT));
1143 A_OP(icode, &ptr, iMAC0, A_GPR(stereo_mix+1), A_C_00000000, A_GPR(gpr+1), A_FXBUS(FXBUS_PCM_RIGHT));
1144 snd_emu10k1_init_stereo_control(&controls[nctl++], "Wave Playback Volume", gpr, 100);
1147 /* Synth Playback */
1148 A_OP(icode, &ptr, iMAC0, A_GPR(stereo_mix+0), A_GPR(stereo_mix+0), A_GPR(gpr), A_FXBUS(FXBUS_MIDI_LEFT));
1149 A_OP(icode, &ptr, iMAC0, A_GPR(stereo_mix+1), A_GPR(stereo_mix+1), A_GPR(gpr+1), A_FXBUS(FXBUS_MIDI_RIGHT));
1150 snd_emu10k1_init_stereo_control(&controls[nctl++], "Synth Playback Volume", gpr, 100);
1153 /* Wave (PCM) Capture */
1154 A_OP(icode, &ptr, iMAC0, A_GPR(capture+0), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LEFT));
1155 A_OP(icode, &ptr, iMAC0, A_GPR(capture+1), A_C_00000000, A_GPR(gpr+1), A_FXBUS(FXBUS_PCM_RIGHT));
1156 snd_emu10k1_init_stereo_control(&controls[nctl++], "PCM Capture Volume", gpr, 0);
1160 A_OP(icode, &ptr, iMAC0, A_GPR(capture+0), A_GPR(capture+0), A_GPR(gpr), A_FXBUS(FXBUS_MIDI_LEFT));
1161 A_OP(icode, &ptr, iMAC0, A_GPR(capture+1), A_GPR(capture+1), A_GPR(gpr+1), A_FXBUS(FXBUS_MIDI_RIGHT));
1162 snd_emu10k1_init_stereo_control(&controls[nctl++], "Synth Capture Volume", gpr, 0);
1168 #define A_ADD_VOLUME_IN(var,vol,input) \
1169 A_OP(icode, &ptr, iMAC0, A_GPR(var), A_GPR(var), A_GPR(vol), A_EXTIN(input))
1171 /* AC'97 Playback Volume - used only for mic (renamed later) */
1172 A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_AC97_L);
1173 A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_AC97_R);
1174 snd_emu10k1_init_stereo_control(&controls[nctl++], "AMic Playback Volume", gpr, 0);
1176 /* AC'97 Capture Volume - used only for mic */
1177 A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_AC97_L);
1178 A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_AC97_R);
1179 snd_emu10k1_init_stereo_control(&controls[nctl++], "Mic Capture Volume", gpr, 0);
1182 /* mic capture buffer */
1183 A_OP(icode, &ptr, iINTERP, A_EXTOUT(A_EXTOUT_MIC_CAP), A_EXTIN(A_EXTIN_AC97_L), 0xcd, A_EXTIN(A_EXTIN_AC97_R));
1185 /* Audigy CD Playback Volume */
1186 A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_SPDIF_CD_L);
1187 A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_SPDIF_CD_R);
1188 snd_emu10k1_init_stereo_control(&controls[nctl++],
1189 emu->card_capabilities->ac97_chip ? "Audigy CD Playback Volume" : "CD Playback Volume",
1192 /* Audigy CD Capture Volume */
1193 A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_SPDIF_CD_L);
1194 A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_SPDIF_CD_R);
1195 snd_emu10k1_init_stereo_control(&controls[nctl++],
1196 emu->card_capabilities->ac97_chip ? "Audigy CD Capture Volume" : "CD Capture Volume",
1200 /* Optical SPDIF Playback Volume */
1201 A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_OPT_SPDIF_L);
1202 A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_OPT_SPDIF_R);
1203 snd_emu10k1_init_stereo_control(&controls[nctl++], SNDRV_CTL_NAME_IEC958("Optical ",PLAYBACK,VOLUME), gpr, 0);
1205 /* Optical SPDIF Capture Volume */
1206 A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_OPT_SPDIF_L);
1207 A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_OPT_SPDIF_R);
1208 snd_emu10k1_init_stereo_control(&controls[nctl++], SNDRV_CTL_NAME_IEC958("Optical ",CAPTURE,VOLUME), gpr, 0);
1211 /* Line2 Playback Volume */
1212 A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_LINE2_L);
1213 A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_LINE2_R);
1214 snd_emu10k1_init_stereo_control(&controls[nctl++],
1215 emu->card_capabilities->ac97_chip ? "Line2 Playback Volume" : "Line Playback Volume",
1218 /* Line2 Capture Volume */
1219 A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_LINE2_L);
1220 A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_LINE2_R);
1221 snd_emu10k1_init_stereo_control(&controls[nctl++],
1222 emu->card_capabilities->ac97_chip ? "Line2 Capture Volume" : "Line Capture Volume",
1226 /* Philips ADC Playback Volume */
1227 A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_ADC_L);
1228 A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_ADC_R);
1229 snd_emu10k1_init_stereo_control(&controls[nctl++], "Analog Mix Playback Volume", gpr, 0);
1231 /* Philips ADC Capture Volume */
1232 A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_ADC_L);
1233 A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_ADC_R);
1234 snd_emu10k1_init_stereo_control(&controls[nctl++], "Analog Mix Capture Volume", gpr, 0);
1237 /* Aux2 Playback Volume */
1238 A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_AUX2_L);
1239 A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_AUX2_R);
1240 snd_emu10k1_init_stereo_control(&controls[nctl++],
1241 emu->card_capabilities->ac97_chip ? "Aux2 Playback Volume" : "Aux Playback Volume",
1244 /* Aux2 Capture Volume */
1245 A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_AUX2_L);
1246 A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_AUX2_R);
1247 snd_emu10k1_init_stereo_control(&controls[nctl++],
1248 emu->card_capabilities->ac97_chip ? "Aux2 Capture Volume" : "Aux Capture Volume",
1252 /* Stereo Mix Front Playback Volume */
1253 A_OP(icode, &ptr, iMAC0, A_GPR(playback), A_GPR(playback), A_GPR(gpr), A_GPR(stereo_mix));
1254 A_OP(icode, &ptr, iMAC0, A_GPR(playback+1), A_GPR(playback+1), A_GPR(gpr+1), A_GPR(stereo_mix+1));
1255 snd_emu10k1_init_stereo_control(&controls[nctl++], "Front Playback Volume", gpr, 100);
1258 /* Stereo Mix Surround Playback */
1259 A_OP(icode, &ptr, iMAC0, A_GPR(playback+2), A_GPR(playback+2), A_GPR(gpr), A_GPR(stereo_mix));
1260 A_OP(icode, &ptr, iMAC0, A_GPR(playback+3), A_GPR(playback+3), A_GPR(gpr+1), A_GPR(stereo_mix+1));
1261 snd_emu10k1_init_stereo_control(&controls[nctl++], "Surround Playback Volume", gpr, 0);
1264 /* Stereo Mix Center Playback */
1265 /* Center = sub = Left/2 + Right/2 */
1266 A_OP(icode, &ptr, iINTERP, A_GPR(tmp), A_GPR(stereo_mix), 0xcd, A_GPR(stereo_mix+1));
1267 A_OP(icode, &ptr, iMAC0, A_GPR(playback+4), A_GPR(playback+4), A_GPR(gpr), A_GPR(tmp));
1268 snd_emu10k1_init_mono_control(&controls[nctl++], "Center Playback Volume", gpr, 0);
1271 /* Stereo Mix LFE Playback */
1272 A_OP(icode, &ptr, iMAC0, A_GPR(playback+5), A_GPR(playback+5), A_GPR(gpr), A_GPR(tmp));
1273 snd_emu10k1_init_mono_control(&controls[nctl++], "LFE Playback Volume", gpr, 0);
1276 if (emu->card_capabilities->spk71) {
1277 /* Stereo Mix Side Playback */
1278 A_OP(icode, &ptr, iMAC0, A_GPR(playback+6), A_GPR(playback+6), A_GPR(gpr), A_GPR(stereo_mix));
1279 A_OP(icode, &ptr, iMAC0, A_GPR(playback+7), A_GPR(playback+7), A_GPR(gpr+1), A_GPR(stereo_mix+1));
1280 snd_emu10k1_init_stereo_control(&controls[nctl++], "Side Playback Volume", gpr, 0);
1287 #define A_PUT_OUTPUT(out,src) A_OP(icode, &ptr, iACC3, A_EXTOUT(out), A_C_00000000, A_C_00000000, A_GPR(src))
1288 #define A_PUT_STEREO_OUTPUT(out1,out2,src) \
1289 {A_PUT_OUTPUT(out1,src); A_PUT_OUTPUT(out2,src+1);}
1291 #define _A_SWITCH(icode, ptr, dst, src, sw) \
1292 A_OP((icode), ptr, iMACINT0, dst, A_C_00000000, src, sw);
1293 #define A_SWITCH(icode, ptr, dst, src, sw) \
1294 _A_SWITCH(icode, ptr, A_GPR(dst), A_GPR(src), A_GPR(sw))
1295 #define _A_SWITCH_NEG(icode, ptr, dst, src) \
1296 A_OP((icode), ptr, iANDXOR, dst, src, A_C_00000001, A_C_00000001);
1297 #define A_SWITCH_NEG(icode, ptr, dst, src) \
1298 _A_SWITCH_NEG(icode, ptr, A_GPR(dst), A_GPR(src))
1302 * Process tone control
1304 A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 0), A_GPR(playback + 0), A_C_00000000, A_C_00000000); /* left */
1305 A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 1), A_GPR(playback + 1), A_C_00000000, A_C_00000000); /* right */
1306 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 */
1307 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 */
1308 A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 4), A_GPR(playback + 4), A_C_00000000, A_C_00000000); /* center */
1309 A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 5), A_GPR(playback + 5), A_C_00000000, A_C_00000000); /* LFE */
1310 if (emu->card_capabilities->spk71) {
1311 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 */
1312 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 */
1316 ctl = &controls[nctl + 0];
1317 ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1318 strcpy(ctl->id.name, "Tone Control - Bass");
1323 ctl->value[0] = ctl->value[1] = 20;
1324 ctl->translation = EMU10K1_GPR_TRANSLATION_BASS;
1325 ctl = &controls[nctl + 1];
1326 ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1327 strcpy(ctl->id.name, "Tone Control - Treble");
1332 ctl->value[0] = ctl->value[1] = 20;
1333 ctl->translation = EMU10K1_GPR_TRANSLATION_TREBLE;
1335 #define BASS_GPR 0x8c
1336 #define TREBLE_GPR 0x96
1338 for (z = 0; z < 5; z++) {
1340 for (j = 0; j < 2; j++) {
1341 controls[nctl + 0].gpr[z * 2 + j] = BASS_GPR + z * 2 + j;
1342 controls[nctl + 1].gpr[z * 2 + j] = TREBLE_GPR + z * 2 + j;
1345 for (z = 0; z < 4; z++) { /* front/rear/center-lfe/side */
1347 for (j = 0; j < 2; j++) { /* left/right */
1348 k = 0xb0 + (z * 8) + (j * 4);
1349 l = 0xe0 + (z * 8) + (j * 4);
1350 d = playback + SND_EMU10K1_PLAYBACK_CHANNELS + z * 2 + j;
1352 A_OP(icode, &ptr, iMAC0, A_C_00000000, A_C_00000000, A_GPR(d), A_GPR(BASS_GPR + 0 + j));
1353 A_OP(icode, &ptr, iMACMV, A_GPR(k+1), A_GPR(k), A_GPR(k+1), A_GPR(BASS_GPR + 4 + j));
1354 A_OP(icode, &ptr, iMACMV, A_GPR(k), A_GPR(d), A_GPR(k), A_GPR(BASS_GPR + 2 + j));
1355 A_OP(icode, &ptr, iMACMV, A_GPR(k+3), A_GPR(k+2), A_GPR(k+3), A_GPR(BASS_GPR + 8 + j));
1356 A_OP(icode, &ptr, iMAC0, A_GPR(k+2), A_GPR_ACCU, A_GPR(k+2), A_GPR(BASS_GPR + 6 + j));
1357 A_OP(icode, &ptr, iACC3, A_GPR(k+2), A_GPR(k+2), A_GPR(k+2), A_C_00000000);
1359 A_OP(icode, &ptr, iMAC0, A_C_00000000, A_C_00000000, A_GPR(k+2), A_GPR(TREBLE_GPR + 0 + j));
1360 A_OP(icode, &ptr, iMACMV, A_GPR(l+1), A_GPR(l), A_GPR(l+1), A_GPR(TREBLE_GPR + 4 + j));
1361 A_OP(icode, &ptr, iMACMV, A_GPR(l), A_GPR(k+2), A_GPR(l), A_GPR(TREBLE_GPR + 2 + j));
1362 A_OP(icode, &ptr, iMACMV, A_GPR(l+3), A_GPR(l+2), A_GPR(l+3), A_GPR(TREBLE_GPR + 8 + j));
1363 A_OP(icode, &ptr, iMAC0, A_GPR(l+2), A_GPR_ACCU, A_GPR(l+2), A_GPR(TREBLE_GPR + 6 + j));
1364 A_OP(icode, &ptr, iMACINT0, A_GPR(l+2), A_C_00000000, A_GPR(l+2), A_C_00000010);
1366 A_OP(icode, &ptr, iACC3, A_GPR(d), A_GPR(l+2), A_C_00000000, A_C_00000000);
1368 if (z == 2) /* center */
1377 for (z = 0; z < 8; z++) {
1378 A_SWITCH(icode, &ptr, tmp + 0, playback + SND_EMU10K1_PLAYBACK_CHANNELS + z, gpr + 0);
1379 A_SWITCH_NEG(icode, &ptr, tmp + 1, gpr + 0);
1380 A_SWITCH(icode, &ptr, tmp + 1, playback + z, tmp + 1);
1381 A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + z), A_GPR(tmp + 0), A_GPR(tmp + 1), A_C_00000000);
1383 snd_emu10k1_init_stereo_onoff_control(controls + nctl++, "Tone Control - Switch", gpr, 0);
1386 /* Master volume (will be renamed later) */
1387 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));
1388 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));
1389 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));
1390 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));
1391 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));
1392 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));
1393 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));
1394 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));
1395 snd_emu10k1_init_mono_control(&controls[nctl++], "Wave Master Playback Volume", gpr, 0);
1398 /* analog speakers */
1399 A_PUT_STEREO_OUTPUT(A_EXTOUT_AFRONT_L, A_EXTOUT_AFRONT_R, playback + SND_EMU10K1_PLAYBACK_CHANNELS);
1400 A_PUT_STEREO_OUTPUT(A_EXTOUT_AREAR_L, A_EXTOUT_AREAR_R, playback+2 + SND_EMU10K1_PLAYBACK_CHANNELS);
1401 A_PUT_OUTPUT(A_EXTOUT_ACENTER, playback+4 + SND_EMU10K1_PLAYBACK_CHANNELS);
1402 A_PUT_OUTPUT(A_EXTOUT_ALFE, playback+5 + SND_EMU10K1_PLAYBACK_CHANNELS);
1403 if (emu->card_capabilities->spk71)
1404 A_PUT_STEREO_OUTPUT(A_EXTOUT_ASIDE_L, A_EXTOUT_ASIDE_R, playback+6 + SND_EMU10K1_PLAYBACK_CHANNELS);
1407 A_PUT_STEREO_OUTPUT(A_EXTOUT_HEADPHONE_L, A_EXTOUT_HEADPHONE_R, playback + SND_EMU10K1_PLAYBACK_CHANNELS);
1409 /* digital outputs */
1410 /* A_PUT_STEREO_OUTPUT(A_EXTOUT_FRONT_L, A_EXTOUT_FRONT_R, playback + SND_EMU10K1_PLAYBACK_CHANNELS); */
1412 /* IEC958 Optical Raw Playback Switch */
1414 gpr_map[gpr++] = 0x1008;
1415 gpr_map[gpr++] = 0xffff0000;
1416 for (z = 0; z < 2; z++) {
1417 A_OP(icode, &ptr, iMAC0, A_GPR(tmp + 2), A_FXBUS(FXBUS_PT_LEFT + z), A_C_00000000, A_C_00000000);
1418 A_OP(icode, &ptr, iSKIP, A_GPR_COND, A_GPR_COND, A_GPR(gpr - 2), A_C_00000001);
1419 A_OP(icode, &ptr, iACC3, A_GPR(tmp + 2), A_C_00000000, A_C_00010000, A_GPR(tmp + 2));
1420 A_OP(icode, &ptr, iANDXOR, A_GPR(tmp + 2), A_GPR(tmp + 2), A_GPR(gpr - 1), A_C_00000000);
1421 A_SWITCH(icode, &ptr, tmp + 0, tmp + 2, gpr + z);
1422 A_SWITCH_NEG(icode, &ptr, tmp + 1, gpr + z);
1423 A_SWITCH(icode, &ptr, tmp + 1, playback + SND_EMU10K1_PLAYBACK_CHANNELS + z, tmp + 1);
1424 if ((z==1) && (emu->card_capabilities->spdif_bug)) {
1425 /* Due to a SPDIF output bug on some Audigy cards, this code delays the Right channel by 1 sample */
1426 snd_printk(KERN_INFO "Installing spdif_bug patch: %s\n", emu->card_capabilities->name);
1427 A_OP(icode, &ptr, iACC3, A_EXTOUT(A_EXTOUT_FRONT_L + z), A_GPR(gpr - 3), A_C_00000000, A_C_00000000);
1428 A_OP(icode, &ptr, iACC3, A_GPR(gpr - 3), A_GPR(tmp + 0), A_GPR(tmp + 1), A_C_00000000);
1430 A_OP(icode, &ptr, iACC3, A_EXTOUT(A_EXTOUT_FRONT_L + z), A_GPR(tmp + 0), A_GPR(tmp + 1), A_C_00000000);
1433 snd_emu10k1_init_stereo_onoff_control(controls + nctl++, SNDRV_CTL_NAME_IEC958("Optical Raw ",PLAYBACK,SWITCH), gpr, 0);
1436 A_PUT_STEREO_OUTPUT(A_EXTOUT_REAR_L, A_EXTOUT_REAR_R, playback+2 + SND_EMU10K1_PLAYBACK_CHANNELS);
1437 A_PUT_OUTPUT(A_EXTOUT_CENTER, playback+4 + SND_EMU10K1_PLAYBACK_CHANNELS);
1438 A_PUT_OUTPUT(A_EXTOUT_LFE, playback+5 + SND_EMU10K1_PLAYBACK_CHANNELS);
1441 #ifdef EMU10K1_CAPTURE_DIGITAL_OUT
1442 A_PUT_STEREO_OUTPUT(A_EXTOUT_ADC_CAP_L, A_EXTOUT_ADC_CAP_R, playback + SND_EMU10K1_PLAYBACK_CHANNELS);
1444 A_PUT_OUTPUT(A_EXTOUT_ADC_CAP_L, capture);
1445 A_PUT_OUTPUT(A_EXTOUT_ADC_CAP_R, capture+1);
1448 /* EFX capture - capture the 16 EXTINs */
1449 for (z = 0; z < 16; z++) {
1450 A_OP(icode, &ptr, iACC3, A_FXBUS2(z), A_C_00000000, A_C_00000000, A_EXTIN(z));
1462 /* clear remaining instruction memory */
1464 A_OP(icode, &ptr, 0x0f, 0xc0, 0xc0, 0xcf, 0xc0);
1466 seg = snd_enter_user();
1467 icode->gpr_add_control_count = nctl;
1468 icode->gpr_add_controls = (struct snd_emu10k1_fx8010_control_gpr __user *)controls;
1469 err = snd_emu10k1_icode_poke(emu, icode);
1470 snd_leave_user(seg);
1474 if (icode != NULL) {
1475 kfree((void __force *)icode->gpr_map);
1483 * initial DSP configuration for Emu10k1
1486 /* when volume = max, then copy only to avoid volume modification */
1487 /* with iMAC0 (negative values) */
1488 static void __devinit _volume(struct snd_emu10k1_fx8010_code *icode, u32 *ptr, u32 dst, u32 src, u32 vol)
1490 OP(icode, ptr, iMAC0, dst, C_00000000, src, vol);
1491 OP(icode, ptr, iANDXOR, C_00000000, vol, C_ffffffff, C_7fffffff);
1492 OP(icode, ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, C_00000001);
1493 OP(icode, ptr, iACC3, dst, src, C_00000000, C_00000000);
1495 static void __devinit _volume_add(struct snd_emu10k1_fx8010_code *icode, u32 *ptr, u32 dst, u32 src, u32 vol)
1497 OP(icode, ptr, iANDXOR, C_00000000, vol, C_ffffffff, C_7fffffff);
1498 OP(icode, ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, C_00000002);
1499 OP(icode, ptr, iMACINT0, dst, dst, src, C_00000001);
1500 OP(icode, ptr, iSKIP, C_00000000, C_7fffffff, C_7fffffff, C_00000001);
1501 OP(icode, ptr, iMAC0, dst, dst, src, vol);
1503 static void __devinit _volume_out(struct snd_emu10k1_fx8010_code *icode, u32 *ptr, u32 dst, u32 src, u32 vol)
1505 OP(icode, ptr, iANDXOR, C_00000000, vol, C_ffffffff, C_7fffffff);
1506 OP(icode, ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, C_00000002);
1507 OP(icode, ptr, iACC3, dst, src, C_00000000, C_00000000);
1508 OP(icode, ptr, iSKIP, C_00000000, C_7fffffff, C_7fffffff, C_00000001);
1509 OP(icode, ptr, iMAC0, dst, C_00000000, src, vol);
1512 #define VOLUME(icode, ptr, dst, src, vol) \
1513 _volume(icode, ptr, GPR(dst), GPR(src), GPR(vol))
1514 #define VOLUME_IN(icode, ptr, dst, src, vol) \
1515 _volume(icode, ptr, GPR(dst), EXTIN(src), GPR(vol))
1516 #define VOLUME_ADD(icode, ptr, dst, src, vol) \
1517 _volume_add(icode, ptr, GPR(dst), GPR(src), GPR(vol))
1518 #define VOLUME_ADDIN(icode, ptr, dst, src, vol) \
1519 _volume_add(icode, ptr, GPR(dst), EXTIN(src), GPR(vol))
1520 #define VOLUME_OUT(icode, ptr, dst, src, vol) \
1521 _volume_out(icode, ptr, EXTOUT(dst), GPR(src), GPR(vol))
1522 #define _SWITCH(icode, ptr, dst, src, sw) \
1523 OP((icode), ptr, iMACINT0, dst, C_00000000, src, sw);
1524 #define SWITCH(icode, ptr, dst, src, sw) \
1525 _SWITCH(icode, ptr, GPR(dst), GPR(src), GPR(sw))
1526 #define SWITCH_IN(icode, ptr, dst, src, sw) \
1527 _SWITCH(icode, ptr, GPR(dst), EXTIN(src), GPR(sw))
1528 #define _SWITCH_NEG(icode, ptr, dst, src) \
1529 OP((icode), ptr, iANDXOR, dst, src, C_00000001, C_00000001);
1530 #define SWITCH_NEG(icode, ptr, dst, src) \
1531 _SWITCH_NEG(icode, ptr, GPR(dst), GPR(src))
1534 static int __devinit _snd_emu10k1_init_efx(struct snd_emu10k1 *emu)
1536 int err, i, z, gpr, tmp, playback, capture;
1538 struct snd_emu10k1_fx8010_code *icode;
1539 struct snd_emu10k1_fx8010_pcm_rec *ipcm = NULL;
1540 struct snd_emu10k1_fx8010_control_gpr *controls = NULL, *ctl;
1544 spin_lock_init(&emu->fx8010.irq_lock);
1545 INIT_LIST_HEAD(&emu->fx8010.gpr_ctl);
1547 if ((icode = kzalloc(sizeof(*icode), GFP_KERNEL)) == NULL)
1549 if ((icode->gpr_map = (u_int32_t __user *)
1550 kcalloc(256 + 160 + 160 + 2 * 512, sizeof(u_int32_t),
1551 GFP_KERNEL)) == NULL ||
1552 (controls = kcalloc(SND_EMU10K1_GPR_CONTROLS,
1553 sizeof(struct snd_emu10k1_fx8010_control_gpr),
1554 GFP_KERNEL)) == NULL ||
1555 (ipcm = kzalloc(sizeof(*ipcm), GFP_KERNEL)) == NULL) {
1559 gpr_map = (u32 __force *)icode->gpr_map;
1561 icode->tram_data_map = icode->gpr_map + 256;
1562 icode->tram_addr_map = icode->tram_data_map + 160;
1563 icode->code = icode->tram_addr_map + 160;
1565 /* clear free GPRs */
1566 for (i = 0; i < 256; i++)
1567 set_bit(i, icode->gpr_valid);
1569 /* clear TRAM data & address lines */
1570 for (i = 0; i < 160; i++)
1571 set_bit(i, icode->tram_valid);
1573 strcpy(icode->name, "SB Live! FX8010 code for ALSA v1.2 by Jaroslav Kysela");
1575 /* we have 12 inputs */
1576 playback = SND_EMU10K1_INPUTS;
1577 /* we have 6 playback channels and tone control doubles */
1578 capture = playback + (SND_EMU10K1_PLAYBACK_CHANNELS * 2);
1579 gpr = capture + SND_EMU10K1_CAPTURE_CHANNELS;
1580 tmp = 0x88; /* we need 4 temporary GPR */
1581 /* from 0x8c to 0xff is the area for tone control */
1583 /* stop FX processor */
1584 snd_emu10k1_ptr_write(emu, DBG, 0, (emu->fx8010.dbg = 0) | EMU10K1_DBG_SINGLE_STEP);
1589 OP(icode, &ptr, iMACINT0, GPR(0), C_00000000, FXBUS(FXBUS_PCM_LEFT), C_00000004);
1590 OP(icode, &ptr, iMACINT0, GPR(1), C_00000000, FXBUS(FXBUS_PCM_RIGHT), C_00000004);
1591 OP(icode, &ptr, iMACINT0, GPR(2), C_00000000, FXBUS(FXBUS_MIDI_LEFT), C_00000004);
1592 OP(icode, &ptr, iMACINT0, GPR(3), C_00000000, FXBUS(FXBUS_MIDI_RIGHT), C_00000004);
1593 OP(icode, &ptr, iMACINT0, GPR(4), C_00000000, FXBUS(FXBUS_PCM_LEFT_REAR), C_00000004);
1594 OP(icode, &ptr, iMACINT0, GPR(5), C_00000000, FXBUS(FXBUS_PCM_RIGHT_REAR), C_00000004);
1595 OP(icode, &ptr, iMACINT0, GPR(6), C_00000000, FXBUS(FXBUS_PCM_CENTER), C_00000004);
1596 OP(icode, &ptr, iMACINT0, GPR(7), C_00000000, FXBUS(FXBUS_PCM_LFE), C_00000004);
1597 OP(icode, &ptr, iMACINT0, GPR(8), C_00000000, C_00000000, C_00000000); /* S/PDIF left */
1598 OP(icode, &ptr, iMACINT0, GPR(9), C_00000000, C_00000000, C_00000000); /* S/PDIF right */
1599 OP(icode, &ptr, iMACINT0, GPR(10), C_00000000, FXBUS(FXBUS_PCM_LEFT_FRONT), C_00000004);
1600 OP(icode, &ptr, iMACINT0, GPR(11), C_00000000, FXBUS(FXBUS_PCM_RIGHT_FRONT), C_00000004);
1602 /* Raw S/PDIF PCM */
1603 ipcm->substream = 0;
1605 ipcm->tram_start = 0;
1606 ipcm->buffer_size = (64 * 1024) / 2;
1607 ipcm->gpr_size = gpr++;
1608 ipcm->gpr_ptr = gpr++;
1609 ipcm->gpr_count = gpr++;
1610 ipcm->gpr_tmpcount = gpr++;
1611 ipcm->gpr_trigger = gpr++;
1612 ipcm->gpr_running = gpr++;
1616 gpr_map[gpr + 0] = 0xfffff000;
1617 gpr_map[gpr + 1] = 0xffff0000;
1618 gpr_map[gpr + 2] = 0x70000000;
1619 gpr_map[gpr + 3] = 0x00000007;
1620 gpr_map[gpr + 4] = 0x001f << 11;
1621 gpr_map[gpr + 5] = 0x001c << 11;
1622 gpr_map[gpr + 6] = (0x22 - 0x01) - 1; /* skip at 01 to 22 */
1623 gpr_map[gpr + 7] = (0x22 - 0x06) - 1; /* skip at 06 to 22 */
1624 gpr_map[gpr + 8] = 0x2000000 + (2<<11);
1625 gpr_map[gpr + 9] = 0x4000000 + (2<<11);
1626 gpr_map[gpr + 10] = 1<<11;
1627 gpr_map[gpr + 11] = (0x24 - 0x0a) - 1; /* skip at 0a to 24 */
1628 gpr_map[gpr + 12] = 0;
1630 /* if the trigger flag is not set, skip */
1631 /* 00: */ OP(icode, &ptr, iMAC0, C_00000000, GPR(ipcm->gpr_trigger), C_00000000, C_00000000);
1632 /* 01: */ OP(icode, &ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_ZERO, GPR(gpr + 6));
1633 /* if the running flag is set, we're running */
1634 /* 02: */ OP(icode, &ptr, iMAC0, C_00000000, GPR(ipcm->gpr_running), C_00000000, C_00000000);
1635 /* 03: */ OP(icode, &ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, C_00000004);
1636 /* wait until ((GPR_DBAC>>11) & 0x1f) == 0x1c) */
1637 /* 04: */ OP(icode, &ptr, iANDXOR, GPR(tmp + 0), GPR_DBAC, GPR(gpr + 4), C_00000000);
1638 /* 05: */ OP(icode, &ptr, iMACINT0, C_00000000, GPR(tmp + 0), C_ffffffff, GPR(gpr + 5));
1639 /* 06: */ OP(icode, &ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, GPR(gpr + 7));
1640 /* 07: */ OP(icode, &ptr, iACC3, GPR(gpr + 12), C_00000010, C_00000001, C_00000000);
1642 /* 08: */ OP(icode, &ptr, iANDXOR, GPR(ipcm->gpr_running), GPR(ipcm->gpr_running), C_00000000, C_00000001);
1643 /* 09: */ OP(icode, &ptr, iACC3, GPR(gpr + 12), GPR(gpr + 12), C_ffffffff, C_00000000);
1644 /* 0a: */ OP(icode, &ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, GPR(gpr + 11));
1645 /* 0b: */ OP(icode, &ptr, iACC3, GPR(gpr + 12), C_00000001, C_00000000, C_00000000);
1647 /* 0c: */ OP(icode, &ptr, iANDXOR, GPR(tmp + 0), ETRAM_DATA(ipcm->etram[0]), GPR(gpr + 0), C_00000000);
1648 /* 0d: */ OP(icode, &ptr, iLOG, GPR(tmp + 0), GPR(tmp + 0), GPR(gpr + 3), C_00000000);
1649 /* 0e: */ OP(icode, &ptr, iANDXOR, GPR(8), GPR(tmp + 0), GPR(gpr + 1), GPR(gpr + 2));
1650 /* 0f: */ OP(icode, &ptr, iSKIP, C_00000000, GPR_COND, CC_REG_MINUS, C_00000001);
1651 /* 10: */ OP(icode, &ptr, iANDXOR, GPR(8), GPR(8), GPR(gpr + 1), GPR(gpr + 2));
1653 /* 11: */ OP(icode, &ptr, iANDXOR, GPR(tmp + 0), ETRAM_DATA(ipcm->etram[1]), GPR(gpr + 0), C_00000000);
1654 /* 12: */ OP(icode, &ptr, iLOG, GPR(tmp + 0), GPR(tmp + 0), GPR(gpr + 3), C_00000000);
1655 /* 13: */ OP(icode, &ptr, iANDXOR, GPR(9), GPR(tmp + 0), GPR(gpr + 1), GPR(gpr + 2));
1656 /* 14: */ OP(icode, &ptr, iSKIP, C_00000000, GPR_COND, CC_REG_MINUS, C_00000001);
1657 /* 15: */ OP(icode, &ptr, iANDXOR, GPR(9), GPR(9), GPR(gpr + 1), GPR(gpr + 2));
1659 /* 16: */ OP(icode, &ptr, iACC3, GPR(tmp + 0), GPR(ipcm->gpr_ptr), C_00000001, C_00000000);
1660 /* 17: */ OP(icode, &ptr, iMACINT0, C_00000000, GPR(tmp + 0), C_ffffffff, GPR(ipcm->gpr_size));
1661 /* 18: */ OP(icode, &ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_MINUS, C_00000001);
1662 /* 19: */ OP(icode, &ptr, iACC3, GPR(tmp + 0), C_00000000, C_00000000, C_00000000);
1663 /* 1a: */ OP(icode, &ptr, iACC3, GPR(ipcm->gpr_ptr), GPR(tmp + 0), C_00000000, C_00000000);
1665 /* 1b: */ OP(icode, &ptr, iACC3, GPR(ipcm->gpr_tmpcount), GPR(ipcm->gpr_tmpcount), C_ffffffff, C_00000000);
1666 /* 1c: */ OP(icode, &ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, C_00000002);
1667 /* 1d: */ OP(icode, &ptr, iACC3, GPR(ipcm->gpr_tmpcount), GPR(ipcm->gpr_count), C_00000000, C_00000000);
1668 /* 1e: */ OP(icode, &ptr, iACC3, GPR_IRQ, C_80000000, C_00000000, C_00000000);
1669 /* 1f: */ OP(icode, &ptr, iANDXOR, GPR(ipcm->gpr_running), GPR(ipcm->gpr_running), C_00000001, C_00010000);
1671 /* 20: */ OP(icode, &ptr, iANDXOR, GPR(ipcm->gpr_running), GPR(ipcm->gpr_running), C_00010000, C_00000001);
1672 /* 21: */ OP(icode, &ptr, iSKIP, C_00000000, C_7fffffff, C_7fffffff, C_00000002);
1674 /* 22: */ OP(icode, &ptr, iMACINT1, ETRAM_ADDR(ipcm->etram[0]), GPR(gpr + 8), GPR_DBAC, C_ffffffff);
1675 /* 23: */ OP(icode, &ptr, iMACINT1, ETRAM_ADDR(ipcm->etram[1]), GPR(gpr + 9), GPR_DBAC, C_ffffffff);
1680 /* Wave Playback Volume */
1681 for (z = 0; z < 2; z++)
1682 VOLUME(icode, &ptr, playback + z, z, gpr + z);
1683 snd_emu10k1_init_stereo_control(controls + i++, "Wave Playback Volume", gpr, 100);
1686 /* Wave Surround Playback Volume */
1687 for (z = 0; z < 2; z++)
1688 VOLUME(icode, &ptr, playback + 2 + z, z, gpr + z);
1689 snd_emu10k1_init_stereo_control(controls + i++, "Wave Surround Playback Volume", gpr, 0);
1692 /* Wave Center/LFE Playback Volume */
1693 OP(icode, &ptr, iACC3, GPR(tmp + 0), FXBUS(FXBUS_PCM_LEFT), FXBUS(FXBUS_PCM_RIGHT), C_00000000);
1694 OP(icode, &ptr, iMACINT0, GPR(tmp + 0), C_00000000, GPR(tmp + 0), C_00000002);
1695 VOLUME(icode, &ptr, playback + 4, tmp + 0, gpr);
1696 snd_emu10k1_init_mono_control(controls + i++, "Wave Center Playback Volume", gpr++, 0);
1697 VOLUME(icode, &ptr, playback + 5, tmp + 0, gpr);
1698 snd_emu10k1_init_mono_control(controls + i++, "Wave LFE Playback Volume", gpr++, 0);
1700 /* Wave Capture Volume + Switch */
1701 for (z = 0; z < 2; z++) {
1702 SWITCH(icode, &ptr, tmp + 0, z, gpr + 2 + z);
1703 VOLUME(icode, &ptr, capture + z, tmp + 0, gpr + z);
1705 snd_emu10k1_init_stereo_control(controls + i++, "Wave Capture Volume", gpr, 0);
1706 snd_emu10k1_init_stereo_onoff_control(controls + i++, "Wave Capture Switch", gpr + 2, 0);
1709 /* Synth Playback Volume */
1710 for (z = 0; z < 2; z++)
1711 VOLUME_ADD(icode, &ptr, playback + z, 2 + z, gpr + z);
1712 snd_emu10k1_init_stereo_control(controls + i++, "Synth Playback Volume", gpr, 100);
1715 /* Synth Capture Volume + Switch */
1716 for (z = 0; z < 2; z++) {
1717 SWITCH(icode, &ptr, tmp + 0, 2 + z, gpr + 2 + z);
1718 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
1720 snd_emu10k1_init_stereo_control(controls + i++, "Synth Capture Volume", gpr, 0);
1721 snd_emu10k1_init_stereo_onoff_control(controls + i++, "Synth Capture Switch", gpr + 2, 0);
1724 /* Surround Digital Playback Volume (renamed later without Digital) */
1725 for (z = 0; z < 2; z++)
1726 VOLUME_ADD(icode, &ptr, playback + 2 + z, 4 + z, gpr + z);
1727 snd_emu10k1_init_stereo_control(controls + i++, "Surround Digital Playback Volume", gpr, 100);
1730 /* Surround Capture Volume + Switch */
1731 for (z = 0; z < 2; z++) {
1732 SWITCH(icode, &ptr, tmp + 0, 4 + z, gpr + 2 + z);
1733 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
1735 snd_emu10k1_init_stereo_control(controls + i++, "Surround Capture Volume", gpr, 0);
1736 snd_emu10k1_init_stereo_onoff_control(controls + i++, "Surround Capture Switch", gpr + 2, 0);
1739 /* Center Playback Volume (renamed later without Digital) */
1740 VOLUME_ADD(icode, &ptr, playback + 4, 6, gpr);
1741 snd_emu10k1_init_mono_control(controls + i++, "Center Digital Playback Volume", gpr++, 100);
1743 /* LFE Playback Volume + Switch (renamed later without Digital) */
1744 VOLUME_ADD(icode, &ptr, playback + 5, 7, gpr);
1745 snd_emu10k1_init_mono_control(controls + i++, "LFE Digital Playback Volume", gpr++, 100);
1747 /* Front Playback Volume */
1748 for (z = 0; z < 2; z++)
1749 VOLUME_ADD(icode, &ptr, playback + z, 10 + z, gpr + z);
1750 snd_emu10k1_init_stereo_control(controls + i++, "Front Playback Volume", gpr, 100);
1753 /* Front Capture Volume + Switch */
1754 for (z = 0; z < 2; z++) {
1755 SWITCH(icode, &ptr, tmp + 0, 10 + z, gpr + 2);
1756 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
1758 snd_emu10k1_init_stereo_control(controls + i++, "Front Capture Volume", gpr, 0);
1759 snd_emu10k1_init_mono_onoff_control(controls + i++, "Front Capture Switch", gpr + 2, 0);
1766 if (emu->fx8010.extin_mask & ((1<<EXTIN_AC97_L)|(1<<EXTIN_AC97_R))) {
1767 /* AC'97 Playback Volume */
1768 VOLUME_ADDIN(icode, &ptr, playback + 0, EXTIN_AC97_L, gpr); gpr++;
1769 VOLUME_ADDIN(icode, &ptr, playback + 1, EXTIN_AC97_R, gpr); gpr++;
1770 snd_emu10k1_init_stereo_control(controls + i++, "AC97 Playback Volume", gpr-2, 0);
1771 /* AC'97 Capture Volume */
1772 VOLUME_ADDIN(icode, &ptr, capture + 0, EXTIN_AC97_L, gpr); gpr++;
1773 VOLUME_ADDIN(icode, &ptr, capture + 1, EXTIN_AC97_R, gpr); gpr++;
1774 snd_emu10k1_init_stereo_control(controls + i++, "AC97 Capture Volume", gpr-2, 100);
1777 if (emu->fx8010.extin_mask & ((1<<EXTIN_SPDIF_CD_L)|(1<<EXTIN_SPDIF_CD_R))) {
1778 /* IEC958 TTL Playback Volume */
1779 for (z = 0; z < 2; z++)
1780 VOLUME_ADDIN(icode, &ptr, playback + z, EXTIN_SPDIF_CD_L + z, gpr + z);
1781 snd_emu10k1_init_stereo_control(controls + i++, SNDRV_CTL_NAME_IEC958("TTL ",PLAYBACK,VOLUME), gpr, 0);
1784 /* IEC958 TTL Capture Volume + Switch */
1785 for (z = 0; z < 2; z++) {
1786 SWITCH_IN(icode, &ptr, tmp + 0, EXTIN_SPDIF_CD_L + z, gpr + 2 + z);
1787 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
1789 snd_emu10k1_init_stereo_control(controls + i++, SNDRV_CTL_NAME_IEC958("TTL ",CAPTURE,VOLUME), gpr, 0);
1790 snd_emu10k1_init_stereo_onoff_control(controls + i++, SNDRV_CTL_NAME_IEC958("TTL ",CAPTURE,SWITCH), gpr + 2, 0);
1794 if (emu->fx8010.extin_mask & ((1<<EXTIN_ZOOM_L)|(1<<EXTIN_ZOOM_R))) {
1795 /* Zoom Video Playback Volume */
1796 for (z = 0; z < 2; z++)
1797 VOLUME_ADDIN(icode, &ptr, playback + z, EXTIN_ZOOM_L + z, gpr + z);
1798 snd_emu10k1_init_stereo_control(controls + i++, "Zoom Video Playback Volume", gpr, 0);
1801 /* Zoom Video Capture Volume + Switch */
1802 for (z = 0; z < 2; z++) {
1803 SWITCH_IN(icode, &ptr, tmp + 0, EXTIN_ZOOM_L + z, gpr + 2 + z);
1804 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
1806 snd_emu10k1_init_stereo_control(controls + i++, "Zoom Video Capture Volume", gpr, 0);
1807 snd_emu10k1_init_stereo_onoff_control(controls + i++, "Zoom Video Capture Switch", gpr + 2, 0);
1811 if (emu->fx8010.extin_mask & ((1<<EXTIN_TOSLINK_L)|(1<<EXTIN_TOSLINK_R))) {
1812 /* IEC958 Optical Playback Volume */
1813 for (z = 0; z < 2; z++)
1814 VOLUME_ADDIN(icode, &ptr, playback + z, EXTIN_TOSLINK_L + z, gpr + z);
1815 snd_emu10k1_init_stereo_control(controls + i++, SNDRV_CTL_NAME_IEC958("LiveDrive ",PLAYBACK,VOLUME), gpr, 0);
1818 /* IEC958 Optical Capture Volume */
1819 for (z = 0; z < 2; z++) {
1820 SWITCH_IN(icode, &ptr, tmp + 0, EXTIN_TOSLINK_L + z, gpr + 2 + z);
1821 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
1823 snd_emu10k1_init_stereo_control(controls + i++, SNDRV_CTL_NAME_IEC958("LiveDrive ",CAPTURE,VOLUME), gpr, 0);
1824 snd_emu10k1_init_stereo_onoff_control(controls + i++, SNDRV_CTL_NAME_IEC958("LiveDrive ",CAPTURE,SWITCH), gpr + 2, 0);
1828 if (emu->fx8010.extin_mask & ((1<<EXTIN_LINE1_L)|(1<<EXTIN_LINE1_R))) {
1829 /* Line LiveDrive Playback Volume */
1830 for (z = 0; z < 2; z++)
1831 VOLUME_ADDIN(icode, &ptr, playback + z, EXTIN_LINE1_L + z, gpr + z);
1832 snd_emu10k1_init_stereo_control(controls + i++, "Line LiveDrive Playback Volume", gpr, 0);
1835 /* Line LiveDrive Capture Volume + Switch */
1836 for (z = 0; z < 2; z++) {
1837 SWITCH_IN(icode, &ptr, tmp + 0, EXTIN_LINE1_L + z, gpr + 2 + z);
1838 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
1840 snd_emu10k1_init_stereo_control(controls + i++, "Line LiveDrive Capture Volume", gpr, 0);
1841 snd_emu10k1_init_stereo_onoff_control(controls + i++, "Line LiveDrive Capture Switch", gpr + 2, 0);
1845 if (emu->fx8010.extin_mask & ((1<<EXTIN_COAX_SPDIF_L)|(1<<EXTIN_COAX_SPDIF_R))) {
1846 /* IEC958 Coax Playback Volume */
1847 for (z = 0; z < 2; z++)
1848 VOLUME_ADDIN(icode, &ptr, playback + z, EXTIN_COAX_SPDIF_L + z, gpr + z);
1849 snd_emu10k1_init_stereo_control(controls + i++, SNDRV_CTL_NAME_IEC958("Coaxial ",PLAYBACK,VOLUME), gpr, 0);
1852 /* IEC958 Coax Capture Volume + Switch */
1853 for (z = 0; z < 2; z++) {
1854 SWITCH_IN(icode, &ptr, tmp + 0, EXTIN_COAX_SPDIF_L + z, gpr + 2 + z);
1855 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
1857 snd_emu10k1_init_stereo_control(controls + i++, SNDRV_CTL_NAME_IEC958("Coaxial ",CAPTURE,VOLUME), gpr, 0);
1858 snd_emu10k1_init_stereo_onoff_control(controls + i++, SNDRV_CTL_NAME_IEC958("Coaxial ",CAPTURE,SWITCH), gpr + 2, 0);
1862 if (emu->fx8010.extin_mask & ((1<<EXTIN_LINE2_L)|(1<<EXTIN_LINE2_R))) {
1863 /* Line LiveDrive Playback Volume */
1864 for (z = 0; z < 2; z++)
1865 VOLUME_ADDIN(icode, &ptr, playback + z, EXTIN_LINE2_L + z, gpr + z);
1866 snd_emu10k1_init_stereo_control(controls + i++, "Line2 LiveDrive Playback Volume", gpr, 0);
1867 controls[i-1].id.index = 1;
1870 /* Line LiveDrive Capture Volume */
1871 for (z = 0; z < 2; z++) {
1872 SWITCH_IN(icode, &ptr, tmp + 0, EXTIN_LINE2_L + z, gpr + 2 + z);
1873 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
1875 snd_emu10k1_init_stereo_control(controls + i++, "Line2 LiveDrive Capture Volume", gpr, 0);
1876 controls[i-1].id.index = 1;
1877 snd_emu10k1_init_stereo_onoff_control(controls + i++, "Line2 LiveDrive Capture Switch", gpr + 2, 0);
1878 controls[i-1].id.index = 1;
1883 * Process tone control
1885 OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 0), GPR(playback + 0), C_00000000, C_00000000); /* left */
1886 OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 1), GPR(playback + 1), C_00000000, C_00000000); /* right */
1887 OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 2), GPR(playback + 2), C_00000000, C_00000000); /* rear left */
1888 OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 3), GPR(playback + 3), C_00000000, C_00000000); /* rear right */
1889 OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 4), GPR(playback + 4), C_00000000, C_00000000); /* center */
1890 OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 5), GPR(playback + 5), C_00000000, C_00000000); /* LFE */
1892 ctl = &controls[i + 0];
1893 ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1894 strcpy(ctl->id.name, "Tone Control - Bass");
1899 ctl->value[0] = ctl->value[1] = 20;
1900 ctl->translation = EMU10K1_GPR_TRANSLATION_BASS;
1901 ctl = &controls[i + 1];
1902 ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1903 strcpy(ctl->id.name, "Tone Control - Treble");
1908 ctl->value[0] = ctl->value[1] = 20;
1909 ctl->translation = EMU10K1_GPR_TRANSLATION_TREBLE;
1911 #define BASS_GPR 0x8c
1912 #define TREBLE_GPR 0x96
1914 for (z = 0; z < 5; z++) {
1916 for (j = 0; j < 2; j++) {
1917 controls[i + 0].gpr[z * 2 + j] = BASS_GPR + z * 2 + j;
1918 controls[i + 1].gpr[z * 2 + j] = TREBLE_GPR + z * 2 + j;
1921 for (z = 0; z < 3; z++) { /* front/rear/center-lfe */
1923 for (j = 0; j < 2; j++) { /* left/right */
1924 k = 0xa0 + (z * 8) + (j * 4);
1925 l = 0xd0 + (z * 8) + (j * 4);
1926 d = playback + SND_EMU10K1_PLAYBACK_CHANNELS + z * 2 + j;
1928 OP(icode, &ptr, iMAC0, C_00000000, C_00000000, GPR(d), GPR(BASS_GPR + 0 + j));
1929 OP(icode, &ptr, iMACMV, GPR(k+1), GPR(k), GPR(k+1), GPR(BASS_GPR + 4 + j));
1930 OP(icode, &ptr, iMACMV, GPR(k), GPR(d), GPR(k), GPR(BASS_GPR + 2 + j));
1931 OP(icode, &ptr, iMACMV, GPR(k+3), GPR(k+2), GPR(k+3), GPR(BASS_GPR + 8 + j));
1932 OP(icode, &ptr, iMAC0, GPR(k+2), GPR_ACCU, GPR(k+2), GPR(BASS_GPR + 6 + j));
1933 OP(icode, &ptr, iACC3, GPR(k+2), GPR(k+2), GPR(k+2), C_00000000);
1935 OP(icode, &ptr, iMAC0, C_00000000, C_00000000, GPR(k+2), GPR(TREBLE_GPR + 0 + j));
1936 OP(icode, &ptr, iMACMV, GPR(l+1), GPR(l), GPR(l+1), GPR(TREBLE_GPR + 4 + j));
1937 OP(icode, &ptr, iMACMV, GPR(l), GPR(k+2), GPR(l), GPR(TREBLE_GPR + 2 + j));
1938 OP(icode, &ptr, iMACMV, GPR(l+3), GPR(l+2), GPR(l+3), GPR(TREBLE_GPR + 8 + j));
1939 OP(icode, &ptr, iMAC0, GPR(l+2), GPR_ACCU, GPR(l+2), GPR(TREBLE_GPR + 6 + j));
1940 OP(icode, &ptr, iMACINT0, GPR(l+2), C_00000000, GPR(l+2), C_00000010);
1942 OP(icode, &ptr, iACC3, GPR(d), GPR(l+2), C_00000000, C_00000000);
1944 if (z == 2) /* center */
1953 for (z = 0; z < 6; z++) {
1954 SWITCH(icode, &ptr, tmp + 0, playback + SND_EMU10K1_PLAYBACK_CHANNELS + z, gpr + 0);
1955 SWITCH_NEG(icode, &ptr, tmp + 1, gpr + 0);
1956 SWITCH(icode, &ptr, tmp + 1, playback + z, tmp + 1);
1957 OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + z), GPR(tmp + 0), GPR(tmp + 1), C_00000000);
1959 snd_emu10k1_init_stereo_onoff_control(controls + i++, "Tone Control - Switch", gpr, 0);
1965 if (emu->fx8010.extout_mask & ((1<<EXTOUT_AC97_L)|(1<<EXTOUT_AC97_R))) {
1966 /* AC'97 Playback Volume */
1968 for (z = 0; z < 2; z++)
1969 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_AC97_L + z), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + z), C_00000000, C_00000000);
1972 if (emu->fx8010.extout_mask & ((1<<EXTOUT_TOSLINK_L)|(1<<EXTOUT_TOSLINK_R))) {
1973 /* IEC958 Optical Raw Playback Switch */
1975 for (z = 0; z < 2; z++) {
1976 SWITCH(icode, &ptr, tmp + 0, 8 + z, gpr + z);
1977 SWITCH_NEG(icode, &ptr, tmp + 1, gpr + z);
1978 SWITCH(icode, &ptr, tmp + 1, playback + SND_EMU10K1_PLAYBACK_CHANNELS + z, tmp + 1);
1979 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_TOSLINK_L + z), GPR(tmp + 0), GPR(tmp + 1), C_00000000);
1980 #ifdef EMU10K1_CAPTURE_DIGITAL_OUT
1981 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_ADC_CAP_L + z), GPR(tmp + 0), GPR(tmp + 1), C_00000000);
1985 snd_emu10k1_init_stereo_onoff_control(controls + i++, SNDRV_CTL_NAME_IEC958("Optical Raw ",PLAYBACK,SWITCH), gpr, 0);
1989 if (emu->fx8010.extout_mask & ((1<<EXTOUT_HEADPHONE_L)|(1<<EXTOUT_HEADPHONE_R))) {
1990 /* Headphone Playback Volume */
1992 for (z = 0; z < 2; z++) {
1993 SWITCH(icode, &ptr, tmp + 0, playback + SND_EMU10K1_PLAYBACK_CHANNELS + 4 + z, gpr + 2 + z);
1994 SWITCH_NEG(icode, &ptr, tmp + 1, gpr + 2 + z);
1995 SWITCH(icode, &ptr, tmp + 1, playback + SND_EMU10K1_PLAYBACK_CHANNELS + z, tmp + 1);
1996 OP(icode, &ptr, iACC3, GPR(tmp + 0), GPR(tmp + 0), GPR(tmp + 1), C_00000000);
1997 VOLUME_OUT(icode, &ptr, EXTOUT_HEADPHONE_L + z, tmp + 0, gpr + z);
2000 snd_emu10k1_init_stereo_control(controls + i++, "Headphone Playback Volume", gpr + 0, 0);
2001 controls[i-1].id.index = 1; /* AC'97 can have also Headphone control */
2002 snd_emu10k1_init_mono_onoff_control(controls + i++, "Headphone Center Playback Switch", gpr + 2, 0);
2003 controls[i-1].id.index = 1;
2004 snd_emu10k1_init_mono_onoff_control(controls + i++, "Headphone LFE Playback Switch", gpr + 3, 0);
2005 controls[i-1].id.index = 1;
2010 if (emu->fx8010.extout_mask & ((1<<EXTOUT_REAR_L)|(1<<EXTOUT_REAR_R)))
2011 for (z = 0; z < 2; z++)
2012 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_REAR_L + z), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 2 + z), C_00000000, C_00000000);
2014 if (emu->fx8010.extout_mask & ((1<<EXTOUT_AC97_REAR_L)|(1<<EXTOUT_AC97_REAR_R)))
2015 for (z = 0; z < 2; z++)
2016 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_AC97_REAR_L + z), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 2 + z), C_00000000, C_00000000);
2018 if (emu->fx8010.extout_mask & (1<<EXTOUT_AC97_CENTER)) {
2019 #ifndef EMU10K1_CENTER_LFE_FROM_FRONT
2020 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_AC97_CENTER), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 4), C_00000000, C_00000000);
2021 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_ACENTER), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 4), C_00000000, C_00000000);
2023 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_AC97_CENTER), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 0), C_00000000, C_00000000);
2024 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_ACENTER), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 0), C_00000000, C_00000000);
2028 if (emu->fx8010.extout_mask & (1<<EXTOUT_AC97_LFE)) {
2029 #ifndef EMU10K1_CENTER_LFE_FROM_FRONT
2030 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_AC97_LFE), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 5), C_00000000, C_00000000);
2031 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_ALFE), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 5), C_00000000, C_00000000);
2033 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_AC97_LFE), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 1), C_00000000, C_00000000);
2034 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_ALFE), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 1), C_00000000, C_00000000);
2038 #ifndef EMU10K1_CAPTURE_DIGITAL_OUT
2039 for (z = 0; z < 2; z++)
2040 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_ADC_CAP_L + z), GPR(capture + z), C_00000000, C_00000000);
2043 if (emu->fx8010.extout_mask & (1<<EXTOUT_MIC_CAP))
2044 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_MIC_CAP), GPR(capture + 2), C_00000000, C_00000000);
2046 /* EFX capture - capture the 16 EXTINS */
2047 if (emu->card_capabilities->sblive51) {
2048 /* On the Live! 5.1, FXBUS2(1) and FXBUS(2) are shared with EXTOUT_ACENTER
2049 * and EXTOUT_ALFE, so we can't connect inputs to them for multitrack recording.
2051 * Since only 14 of the 16 EXTINs are used, this is not a big problem.
2052 * We route AC97L and R to FX capture 14 and 15, SPDIF CD in to FX capture
2053 * 0 and 3, then the rest of the EXTINs to the corresponding FX capture
2054 * channel. Multitrack recorders will still see the center/lfe output signal
2055 * on the second and third channels.
2057 OP(icode, &ptr, iACC3, FXBUS2(14), C_00000000, C_00000000, EXTIN(0));
2058 OP(icode, &ptr, iACC3, FXBUS2(15), C_00000000, C_00000000, EXTIN(1));
2059 OP(icode, &ptr, iACC3, FXBUS2(0), C_00000000, C_00000000, EXTIN(2));
2060 OP(icode, &ptr, iACC3, FXBUS2(3), C_00000000, C_00000000, EXTIN(3));
2061 for (z = 4; z < 14; z++)
2062 OP(icode, &ptr, iACC3, FXBUS2(z), C_00000000, C_00000000, EXTIN(z));
2064 for (z = 0; z < 16; z++)
2065 OP(icode, &ptr, iACC3, FXBUS2(z), C_00000000, C_00000000, EXTIN(z));
2074 if (i > SND_EMU10K1_GPR_CONTROLS) {
2080 /* clear remaining instruction memory */
2082 OP(icode, &ptr, iACC3, C_00000000, C_00000000, C_00000000, C_00000000);
2084 if ((err = snd_emu10k1_fx8010_tram_setup(emu, ipcm->buffer_size)) < 0)
2086 seg = snd_enter_user();
2087 icode->gpr_add_control_count = i;
2088 icode->gpr_add_controls = (struct snd_emu10k1_fx8010_control_gpr __user *)controls;
2089 err = snd_emu10k1_icode_poke(emu, icode);
2090 snd_leave_user(seg);
2092 err = snd_emu10k1_ipcm_poke(emu, ipcm);
2096 if (icode != NULL) {
2097 kfree((void __force *)icode->gpr_map);
2103 int __devinit snd_emu10k1_init_efx(struct snd_emu10k1 *emu)
2106 return _snd_emu10k1_audigy_init_efx(emu);
2108 return _snd_emu10k1_init_efx(emu);
2111 void snd_emu10k1_free_efx(struct snd_emu10k1 *emu)
2113 /* stop processor */
2115 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg = A_DBG_SINGLE_STEP);
2117 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg = EMU10K1_DBG_SINGLE_STEP);
2120 #if 0 // FIXME: who use them?
2121 int snd_emu10k1_fx8010_tone_control_activate(struct snd_emu10k1 *emu, int output)
2123 if (output < 0 || output >= 6)
2125 snd_emu10k1_ptr_write(emu, emu->gpr_base + 0x94 + output, 0, 1);
2129 int snd_emu10k1_fx8010_tone_control_deactivate(struct snd_emu10k1 *emu, int output)
2131 if (output < 0 || output >= 6)
2133 snd_emu10k1_ptr_write(emu, emu->gpr_base + 0x94 + output, 0, 0);
2138 int snd_emu10k1_fx8010_tram_setup(struct snd_emu10k1 *emu, u32 size)
2142 /* size is in samples */
2144 size = (size - 1) >> 13;
2150 size = 0x2000 << size_reg;
2152 if ((emu->fx8010.etram_pages.bytes / 2) == size)
2154 spin_lock_irq(&emu->emu_lock);
2155 outl(HCFG_LOCKTANKCACHE_MASK | inl(emu->port + HCFG), emu->port + HCFG);
2156 spin_unlock_irq(&emu->emu_lock);
2157 snd_emu10k1_ptr_write(emu, TCB, 0, 0);
2158 snd_emu10k1_ptr_write(emu, TCBS, 0, 0);
2159 if (emu->fx8010.etram_pages.area != NULL) {
2160 snd_dma_free_pages(&emu->fx8010.etram_pages);
2161 emu->fx8010.etram_pages.area = NULL;
2162 emu->fx8010.etram_pages.bytes = 0;
2166 if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(emu->pci),
2167 size * 2, &emu->fx8010.etram_pages) < 0)
2169 memset(emu->fx8010.etram_pages.area, 0, size * 2);
2170 snd_emu10k1_ptr_write(emu, TCB, 0, emu->fx8010.etram_pages.addr);
2171 snd_emu10k1_ptr_write(emu, TCBS, 0, size_reg);
2172 spin_lock_irq(&emu->emu_lock);
2173 outl(inl(emu->port + HCFG) & ~HCFG_LOCKTANKCACHE_MASK, emu->port + HCFG);
2174 spin_unlock_irq(&emu->emu_lock);
2180 static int snd_emu10k1_fx8010_open(struct snd_hwdep * hw, struct file *file)
2185 static void copy_string(char *dst, char *src, char *null, int idx)
2188 sprintf(dst, "%s %02X", null, idx);
2193 static int snd_emu10k1_fx8010_info(struct snd_emu10k1 *emu,
2194 struct snd_emu10k1_fx8010_info *info)
2196 char **fxbus, **extin, **extout;
2197 unsigned short fxbus_mask, extin_mask, extout_mask;
2200 memset(info, 0, sizeof(info));
2201 info->internal_tram_size = emu->fx8010.itram_size;
2202 info->external_tram_size = emu->fx8010.etram_pages.bytes / 2;
2204 extin = emu->audigy ? audigy_ins : creative_ins;
2205 extout = emu->audigy ? audigy_outs : creative_outs;
2206 fxbus_mask = emu->fx8010.fxbus_mask;
2207 extin_mask = emu->fx8010.extin_mask;
2208 extout_mask = emu->fx8010.extout_mask;
2209 for (res = 0; res < 16; res++, fxbus++, extin++, extout++) {
2210 copy_string(info->fxbus_names[res], fxbus_mask & (1 << res) ? *fxbus : NULL, "FXBUS", res);
2211 copy_string(info->extin_names[res], extin_mask & (1 << res) ? *extin : NULL, "Unused", res);
2212 copy_string(info->extout_names[res], extout_mask & (1 << res) ? *extout : NULL, "Unused", res);
2214 for (res = 16; res < 32; res++, extout++)
2215 copy_string(info->extout_names[res], extout_mask & (1 << res) ? *extout : NULL, "Unused", res);
2216 info->gpr_controls = emu->fx8010.gpr_count;
2220 static int snd_emu10k1_fx8010_ioctl(struct snd_hwdep * hw, struct file *file, unsigned int cmd, unsigned long arg)
2222 struct snd_emu10k1 *emu = hw->private_data;
2223 struct snd_emu10k1_fx8010_info *info;
2224 struct snd_emu10k1_fx8010_code *icode;
2225 struct snd_emu10k1_fx8010_pcm_rec *ipcm;
2227 void __user *argp = (void __user *)arg;
2231 case SNDRV_EMU10K1_IOCTL_INFO:
2232 info = kmalloc(sizeof(*info), GFP_KERNEL);
2235 if ((res = snd_emu10k1_fx8010_info(emu, info)) < 0) {
2239 if (copy_to_user(argp, info, sizeof(*info))) {
2245 case SNDRV_EMU10K1_IOCTL_CODE_POKE:
2246 if (!capable(CAP_SYS_ADMIN))
2248 icode = kmalloc(sizeof(*icode), GFP_KERNEL);
2251 if (copy_from_user(icode, argp, sizeof(*icode))) {
2255 res = snd_emu10k1_icode_poke(emu, icode);
2258 case SNDRV_EMU10K1_IOCTL_CODE_PEEK:
2259 icode = kmalloc(sizeof(*icode), GFP_KERNEL);
2262 if (copy_from_user(icode, argp, sizeof(*icode))) {
2266 res = snd_emu10k1_icode_peek(emu, icode);
2267 if (res == 0 && copy_to_user(argp, icode, sizeof(*icode))) {
2273 case SNDRV_EMU10K1_IOCTL_PCM_POKE:
2274 ipcm = kmalloc(sizeof(*ipcm), GFP_KERNEL);
2277 if (copy_from_user(ipcm, argp, sizeof(*ipcm))) {
2281 res = snd_emu10k1_ipcm_poke(emu, ipcm);
2284 case SNDRV_EMU10K1_IOCTL_PCM_PEEK:
2285 ipcm = kzalloc(sizeof(*ipcm), GFP_KERNEL);
2288 if (copy_from_user(ipcm, argp, sizeof(*ipcm))) {
2292 res = snd_emu10k1_ipcm_peek(emu, ipcm);
2293 if (res == 0 && copy_to_user(argp, ipcm, sizeof(*ipcm))) {
2299 case SNDRV_EMU10K1_IOCTL_TRAM_SETUP:
2300 if (!capable(CAP_SYS_ADMIN))
2302 if (get_user(addr, (unsigned int __user *)argp))
2304 down(&emu->fx8010.lock);
2305 res = snd_emu10k1_fx8010_tram_setup(emu, addr);
2306 up(&emu->fx8010.lock);
2308 case SNDRV_EMU10K1_IOCTL_STOP:
2309 if (!capable(CAP_SYS_ADMIN))
2312 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg |= A_DBG_SINGLE_STEP);
2314 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg |= EMU10K1_DBG_SINGLE_STEP);
2316 case SNDRV_EMU10K1_IOCTL_CONTINUE:
2317 if (!capable(CAP_SYS_ADMIN))
2320 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg = 0);
2322 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg = 0);
2324 case SNDRV_EMU10K1_IOCTL_ZERO_TRAM_COUNTER:
2325 if (!capable(CAP_SYS_ADMIN))
2328 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg | A_DBG_ZC);
2330 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg | EMU10K1_DBG_ZC);
2333 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg);
2335 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg);
2337 case SNDRV_EMU10K1_IOCTL_SINGLE_STEP:
2338 if (!capable(CAP_SYS_ADMIN))
2340 if (get_user(addr, (unsigned int __user *)argp))
2345 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg |= A_DBG_SINGLE_STEP | addr);
2347 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg |= EMU10K1_DBG_SINGLE_STEP | addr);
2350 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg |= A_DBG_SINGLE_STEP | A_DBG_STEP_ADDR | addr);
2352 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg |= EMU10K1_DBG_SINGLE_STEP | EMU10K1_DBG_STEP | addr);
2354 case SNDRV_EMU10K1_IOCTL_DBG_READ:
2356 addr = snd_emu10k1_ptr_read(emu, A_DBG, 0);
2358 addr = snd_emu10k1_ptr_read(emu, DBG, 0);
2359 if (put_user(addr, (unsigned int __user *)argp))
2366 static int snd_emu10k1_fx8010_release(struct snd_hwdep * hw, struct file *file)
2371 int __devinit snd_emu10k1_fx8010_new(struct snd_emu10k1 *emu, int device, struct snd_hwdep ** rhwdep)
2373 struct snd_hwdep *hw;
2378 if ((err = snd_hwdep_new(emu->card, "FX8010", device, &hw)) < 0)
2380 strcpy(hw->name, "EMU10K1 (FX8010)");
2381 hw->iface = SNDRV_HWDEP_IFACE_EMU10K1;
2382 hw->ops.open = snd_emu10k1_fx8010_open;
2383 hw->ops.ioctl = snd_emu10k1_fx8010_ioctl;
2384 hw->ops.release = snd_emu10k1_fx8010_release;
2385 hw->private_data = emu;