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/capability.h>
31 #include <linux/delay.h>
32 #include <linux/slab.h>
33 #include <linux/vmalloc.h>
34 #include <linux/init.h>
35 #include <linux/mutex.h>
37 #include <sound/core.h>
38 #include <sound/emu10k1.h>
40 #if 0 /* for testing purposes - digital out -> capture */
41 #define EMU10K1_CAPTURE_DIGITAL_OUT
43 #if 0 /* for testing purposes - set S/PDIF to AC3 output */
44 #define EMU10K1_SET_AC3_IEC958
46 #if 0 /* for testing purposes - feed the front signal to Center/LFE outputs */
47 #define EMU10K1_CENTER_LFE_FROM_FRONT
54 static char *fxbuses[16] = {
55 /* 0x00 */ "PCM Left",
56 /* 0x01 */ "PCM Right",
57 /* 0x02 */ "PCM Surround Left",
58 /* 0x03 */ "PCM Surround Right",
59 /* 0x04 */ "MIDI Left",
60 /* 0x05 */ "MIDI Right",
67 /* 0x0c */ "MIDI Reverb",
68 /* 0x0d */ "MIDI Chorus",
73 static char *creative_ins[16] = {
74 /* 0x00 */ "AC97 Left",
75 /* 0x01 */ "AC97 Right",
76 /* 0x02 */ "TTL IEC958 Left",
77 /* 0x03 */ "TTL IEC958 Right",
78 /* 0x04 */ "Zoom Video Left",
79 /* 0x05 */ "Zoom Video Right",
80 /* 0x06 */ "Optical IEC958 Left",
81 /* 0x07 */ "Optical IEC958 Right",
82 /* 0x08 */ "Line/Mic 1 Left",
83 /* 0x09 */ "Line/Mic 1 Right",
84 /* 0x0a */ "Coaxial IEC958 Left",
85 /* 0x0b */ "Coaxial IEC958 Right",
86 /* 0x0c */ "Line/Mic 2 Left",
87 /* 0x0d */ "Line/Mic 2 Right",
92 static char *audigy_ins[16] = {
93 /* 0x00 */ "AC97 Left",
94 /* 0x01 */ "AC97 Right",
95 /* 0x02 */ "Audigy CD Left",
96 /* 0x03 */ "Audigy CD Right",
97 /* 0x04 */ "Optical IEC958 Left",
98 /* 0x05 */ "Optical IEC958 Right",
101 /* 0x08 */ "Line/Mic 2 Left",
102 /* 0x09 */ "Line/Mic 2 Right",
103 /* 0x0a */ "SPDIF Left",
104 /* 0x0b */ "SPDIF Right",
105 /* 0x0c */ "Aux2 Left",
106 /* 0x0d */ "Aux2 Right",
111 static char *creative_outs[32] = {
112 /* 0x00 */ "AC97 Left",
113 /* 0x01 */ "AC97 Right",
114 /* 0x02 */ "Optical IEC958 Left",
115 /* 0x03 */ "Optical IEC958 Right",
118 /* 0x06 */ "Headphone Left",
119 /* 0x07 */ "Headphone Right",
120 /* 0x08 */ "Surround Left",
121 /* 0x09 */ "Surround Right",
122 /* 0x0a */ "PCM Capture Left",
123 /* 0x0b */ "PCM Capture Right",
124 /* 0x0c */ "MIC Capture",
125 /* 0x0d */ "AC97 Surround Left",
126 /* 0x0e */ "AC97 Surround Right",
129 /* 0x11 */ "Analog Center",
130 /* 0x12 */ "Analog LFE",
146 static char *audigy_outs[32] = {
147 /* 0x00 */ "Digital Front Left",
148 /* 0x01 */ "Digital Front Right",
149 /* 0x02 */ "Digital Center",
150 /* 0x03 */ "Digital LEF",
151 /* 0x04 */ "Headphone Left",
152 /* 0x05 */ "Headphone Right",
153 /* 0x06 */ "Digital Rear Left",
154 /* 0x07 */ "Digital Rear Right",
155 /* 0x08 */ "Front Left",
156 /* 0x09 */ "Front Right",
161 /* 0x0e */ "Rear Left",
162 /* 0x0f */ "Rear Right",
163 /* 0x10 */ "AC97 Front Left",
164 /* 0x11 */ "AC97 Front Right",
165 /* 0x12 */ "ADC Caputre Left",
166 /* 0x13 */ "ADC Capture Right",
181 static const u32 bass_table[41][5] = {
182 { 0x3e4f844f, 0x84ed4cc3, 0x3cc69927, 0x7b03553a, 0xc4da8486 },
183 { 0x3e69a17a, 0x84c280fb, 0x3cd77cd4, 0x7b2f2a6f, 0xc4b08d1d },
184 { 0x3e82ff42, 0x849991d5, 0x3ce7466b, 0x7b5917c6, 0xc48863ee },
185 { 0x3e9bab3c, 0x847267f0, 0x3cf5ffe8, 0x7b813560, 0xc461f22c },
186 { 0x3eb3b275, 0x844ced29, 0x3d03b295, 0x7ba79a1c, 0xc43d223b },
187 { 0x3ecb2174, 0x84290c8b, 0x3d106714, 0x7bcc5ba3, 0xc419dfa5 },
188 { 0x3ee2044b, 0x8406b244, 0x3d1c2561, 0x7bef8e77, 0xc3f8170f },
189 { 0x3ef86698, 0x83e5cb96, 0x3d26f4d8, 0x7c114600, 0xc3d7b625 },
190 { 0x3f0e5390, 0x83c646c9, 0x3d30dc39, 0x7c319498, 0xc3b8ab97 },
191 { 0x3f23d60b, 0x83a81321, 0x3d39e1af, 0x7c508b9c, 0xc39ae704 },
192 { 0x3f38f884, 0x838b20d2, 0x3d420ad2, 0x7c6e3b75, 0xc37e58f1 },
193 { 0x3f4dc52c, 0x836f60ef, 0x3d495cab, 0x7c8ab3a6, 0xc362f2be },
194 { 0x3f6245e8, 0x8354c565, 0x3d4fdbb8, 0x7ca602d6, 0xc348a69b },
195 { 0x3f76845f, 0x833b40ec, 0x3d558bf0, 0x7cc036df, 0xc32f677c },
196 { 0x3f8a8a03, 0x8322c6fb, 0x3d5a70c4, 0x7cd95cd7, 0xc317290b },
197 { 0x3f9e6014, 0x830b4bc3, 0x3d5e8d25, 0x7cf1811a, 0xc2ffdfa5 },
198 { 0x3fb20fae, 0x82f4c420, 0x3d61e37f, 0x7d08af56, 0xc2e9804a },
199 { 0x3fc5a1cc, 0x82df2592, 0x3d6475c3, 0x7d1ef294, 0xc2d40096 },
200 { 0x3fd91f55, 0x82ca6632, 0x3d664564, 0x7d345541, 0xc2bf56b9 },
201 { 0x3fec9120, 0x82b67cac, 0x3d675356, 0x7d48e138, 0xc2ab796e },
202 { 0x40000000, 0x82a36037, 0x3d67a012, 0x7d5c9fc9, 0xc2985fee },
203 { 0x401374c7, 0x8291088a, 0x3d672b93, 0x7d6f99c3, 0xc28601f2 },
204 { 0x4026f857, 0x827f6dd7, 0x3d65f559, 0x7d81d77c, 0xc27457a3 },
205 { 0x403a939f, 0x826e88c5, 0x3d63fc63, 0x7d9360d4, 0xc2635996 },
206 { 0x404e4faf, 0x825e5266, 0x3d613f32, 0x7da43d42, 0xc25300c6 },
207 { 0x406235ba, 0x824ec434, 0x3d5dbbc3, 0x7db473d7, 0xc243468e },
208 { 0x40764f1f, 0x823fd80c, 0x3d596f8f, 0x7dc40b44, 0xc23424a2 },
209 { 0x408aa576, 0x82318824, 0x3d545787, 0x7dd309e2, 0xc2259509 },
210 { 0x409f4296, 0x8223cf0b, 0x3d4e7012, 0x7de175b5, 0xc2179218 },
211 { 0x40b430a0, 0x8216a7a1, 0x3d47b505, 0x7def5475, 0xc20a1670 },
212 { 0x40c97a0a, 0x820a0d12, 0x3d4021a1, 0x7dfcab8d, 0xc1fd1cf5 },
213 { 0x40df29a6, 0x81fdfad6, 0x3d37b08d, 0x7e098028, 0xc1f0a0ca },
214 { 0x40f54ab1, 0x81f26ca9, 0x3d2e5bd1, 0x7e15d72b, 0xc1e49d52 },
215 { 0x410be8da, 0x81e75e89, 0x3d241cce, 0x7e21b544, 0xc1d90e24 },
216 { 0x41231051, 0x81dcccb3, 0x3d18ec37, 0x7e2d1ee6, 0xc1cdef10 },
217 { 0x413acdd0, 0x81d2b39e, 0x3d0cc20a, 0x7e38184e, 0xc1c33c13 },
218 { 0x41532ea7, 0x81c90ffb, 0x3cff9585, 0x7e42a58b, 0xc1b8f15a },
219 { 0x416c40cd, 0x81bfdeb2, 0x3cf15d21, 0x7e4cca7c, 0xc1af0b3f },
220 { 0x418612ea, 0x81b71cdc, 0x3ce20e85, 0x7e568ad3, 0xc1a58640 },
221 { 0x41a0b465, 0x81aec7c5, 0x3cd19e7c, 0x7e5fea1e, 0xc19c5f03 },
222 { 0x41bc3573, 0x81a6dcea, 0x3cc000e9, 0x7e68ebc2, 0xc1939250 }
225 static const u32 treble_table[41][5] = {
226 { 0x0125cba9, 0xfed5debd, 0x00599b6c, 0x0d2506da, 0xfa85b354 },
227 { 0x0142f67e, 0xfeb03163, 0x0066cd0f, 0x0d14c69d, 0xfa914473 },
228 { 0x016328bd, 0xfe860158, 0x0075b7f2, 0x0d03eb27, 0xfa9d32d2 },
229 { 0x0186b438, 0xfe56c982, 0x00869234, 0x0cf27048, 0xfaa97fca },
230 { 0x01adf358, 0xfe21f5fe, 0x00999842, 0x0ce051c2, 0xfab62ca5 },
231 { 0x01d949fa, 0xfde6e287, 0x00af0d8d, 0x0ccd8b4a, 0xfac33aa7 },
232 { 0x02092669, 0xfda4d8bf, 0x00c73d4c, 0x0cba1884, 0xfad0ab07 },
233 { 0x023e0268, 0xfd5b0e4a, 0x00e27b54, 0x0ca5f509, 0xfade7ef2 },
234 { 0x0278645c, 0xfd08a2b0, 0x01012509, 0x0c911c63, 0xfaecb788 },
235 { 0x02b8e091, 0xfcac9d1a, 0x0123a262, 0x0c7b8a14, 0xfafb55df },
236 { 0x03001a9a, 0xfc45e9ce, 0x014a6709, 0x0c65398f, 0xfb0a5aff },
237 { 0x034ec6d7, 0xfbd3576b, 0x0175f397, 0x0c4e2643, 0xfb19c7e4 },
238 { 0x03a5ac15, 0xfb5393ee, 0x01a6d6ed, 0x0c364b94, 0xfb299d7c },
239 { 0x0405a562, 0xfac52968, 0x01ddafae, 0x0c1da4e2, 0xfb39dca5 },
240 { 0x046fa3fe, 0xfa267a66, 0x021b2ddd, 0x0c042d8d, 0xfb4a8631 },
241 { 0x04e4b17f, 0xf975be0f, 0x0260149f, 0x0be9e0f2, 0xfb5b9ae0 },
242 { 0x0565f220, 0xf8b0fbe5, 0x02ad3c29, 0x0bceba73, 0xfb6d1b60 },
243 { 0x05f4a745, 0xf7d60722, 0x030393d4, 0x0bb2b578, 0xfb7f084d },
244 { 0x06923236, 0xf6e279bd, 0x03642465, 0x0b95cd75, 0xfb916233 },
245 { 0x07401713, 0xf5d3aef9, 0x03d01283, 0x0b77fded, 0xfba42984 },
246 { 0x08000000, 0xf4a6bd88, 0x0448a161, 0x0b594278, 0xfbb75e9f },
247 { 0x08d3c097, 0xf3587131, 0x04cf35a4, 0x0b3996c9, 0xfbcb01cb },
248 { 0x09bd59a2, 0xf1e543f9, 0x05655880, 0x0b18f6b2, 0xfbdf1333 },
249 { 0x0abefd0f, 0xf04956ca, 0x060cbb12, 0x0af75e2c, 0xfbf392e8 },
250 { 0x0bdb123e, 0xee806984, 0x06c739fe, 0x0ad4c962, 0xfc0880dd },
251 { 0x0d143a94, 0xec85d287, 0x0796e150, 0x0ab134b0, 0xfc1ddce5 },
252 { 0x0e6d5664, 0xea547598, 0x087df0a0, 0x0a8c9cb6, 0xfc33a6ad },
253 { 0x0fe98a2a, 0xe7e6ba35, 0x097edf83, 0x0a66fe5b, 0xfc49ddc2 },
254 { 0x118c4421, 0xe536813a, 0x0a9c6248, 0x0a4056d7, 0xfc608185 },
255 { 0x1359422e, 0xe23d19eb, 0x0bd96efb, 0x0a18a3bf, 0xfc77912c },
256 { 0x1554982b, 0xdef33645, 0x0d3942bd, 0x09efe312, 0xfc8f0bc1 },
257 { 0x1782b68a, 0xdb50deb1, 0x0ebf676d, 0x09c6133f, 0xfca6f019 },
258 { 0x19e8715d, 0xd74d64fd, 0x106fb999, 0x099b3337, 0xfcbf3cd6 },
259 { 0x1c8b07b8, 0xd2df56ab, 0x124e6ec8, 0x096f4274, 0xfcd7f060 },
260 { 0x1f702b6d, 0xcdfc6e92, 0x14601c10, 0x0942410b, 0xfcf108e5 },
261 { 0x229e0933, 0xc89985cd, 0x16a9bcfa, 0x09142fb5, 0xfd0a8451 },
262 { 0x261b5118, 0xc2aa8409, 0x1930bab6, 0x08e50fdc, 0xfd24604d },
263 { 0x29ef3f5d, 0xbc224f28, 0x1bfaf396, 0x08b4e3aa, 0xfd3e9a3b },
264 { 0x2e21a59b, 0xb4f2ba46, 0x1f0ec2d6, 0x0883ae15, 0xfd592f33 },
265 { 0x32baf44b, 0xad0c7429, 0x227308a3, 0x085172eb, 0xfd741bfd },
266 { 0x37c4448b, 0xa45ef51d, 0x262f3267, 0x081e36dc, 0xfd8f5d14 }
269 static const u32 db_table[101] = {
270 0x00000000, 0x01571f82, 0x01674b41, 0x01783a1b, 0x0189f540,
271 0x019c8651, 0x01aff763, 0x01c45306, 0x01d9a446, 0x01eff6b8,
272 0x0207567a, 0x021fd03d, 0x0239714c, 0x02544792, 0x027061a1,
273 0x028dcebb, 0x02ac9edc, 0x02cce2bf, 0x02eeabe8, 0x03120cb0,
274 0x0337184e, 0x035de2df, 0x03868173, 0x03b10a18, 0x03dd93e9,
275 0x040c3713, 0x043d0cea, 0x04702ff3, 0x04a5bbf2, 0x04ddcdfb,
276 0x0518847f, 0x0555ff62, 0x05966005, 0x05d9c95d, 0x06206005,
277 0x066a4a52, 0x06b7b067, 0x0708bc4c, 0x075d9a01, 0x07b6779d,
278 0x08138561, 0x0874f5d5, 0x08dafde1, 0x0945d4ed, 0x09b5b4fd,
279 0x0a2adad1, 0x0aa58605, 0x0b25f936, 0x0bac7a24, 0x0c3951d8,
280 0x0ccccccc, 0x0d673b17, 0x0e08f093, 0x0eb24510, 0x0f639481,
281 0x101d3f2d, 0x10dfa9e6, 0x11ab3e3f, 0x12806ac3, 0x135fa333,
282 0x144960c5, 0x153e2266, 0x163e6cfe, 0x174acbb7, 0x1863d04d,
283 0x198a1357, 0x1abe349f, 0x1c00db77, 0x1d52b712, 0x1eb47ee6,
284 0x2026f30f, 0x21aadcb6, 0x23410e7e, 0x24ea64f9, 0x26a7c71d,
285 0x287a26c4, 0x2a62812c, 0x2c61df84, 0x2e795779, 0x30aa0bcf,
286 0x32f52cfe, 0x355bf9d8, 0x37dfc033, 0x3a81dda4, 0x3d43c038,
287 0x4026e73c, 0x432ce40f, 0x46575af8, 0x49a8040f, 0x4d20ac2a,
288 0x50c335d3, 0x54919a57, 0x588dead1, 0x5cba514a, 0x611911ea,
289 0x65ac8c2f, 0x6a773c39, 0x6f7bbc23, 0x74bcc56c, 0x7a3d3272,
293 static const u32 onoff_table[2] = {
294 0x00000000, 0x00000001
300 static inline mm_segment_t snd_enter_user(void)
302 mm_segment_t fs = get_fs();
307 static inline void snd_leave_user(mm_segment_t fs)
316 static int snd_emu10k1_gpr_ctl_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
318 struct snd_emu10k1_fx8010_ctl *ctl =
319 (struct snd_emu10k1_fx8010_ctl *) kcontrol->private_value;
321 if (ctl->min == 0 && ctl->max == 1)
322 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
324 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
325 uinfo->count = ctl->vcount;
326 uinfo->value.integer.min = ctl->min;
327 uinfo->value.integer.max = ctl->max;
331 static int snd_emu10k1_gpr_ctl_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
333 struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
334 struct snd_emu10k1_fx8010_ctl *ctl =
335 (struct snd_emu10k1_fx8010_ctl *) kcontrol->private_value;
339 spin_lock_irqsave(&emu->reg_lock, flags);
340 for (i = 0; i < ctl->vcount; i++)
341 ucontrol->value.integer.value[i] = ctl->value[i];
342 spin_unlock_irqrestore(&emu->reg_lock, flags);
346 static int snd_emu10k1_gpr_ctl_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
348 struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
349 struct snd_emu10k1_fx8010_ctl *ctl =
350 (struct snd_emu10k1_fx8010_ctl *) kcontrol->private_value;
352 unsigned int nval, val;
356 spin_lock_irqsave(&emu->reg_lock, flags);
357 for (i = 0; i < ctl->vcount; i++) {
358 nval = ucontrol->value.integer.value[i];
363 if (nval != ctl->value[i])
365 val = ctl->value[i] = nval;
366 switch (ctl->translation) {
367 case EMU10K1_GPR_TRANSLATION_NONE:
368 snd_emu10k1_ptr_write(emu, emu->gpr_base + ctl->gpr[i], 0, val);
370 case EMU10K1_GPR_TRANSLATION_TABLE100:
371 snd_emu10k1_ptr_write(emu, emu->gpr_base + ctl->gpr[i], 0, db_table[val]);
373 case EMU10K1_GPR_TRANSLATION_BASS:
374 if ((ctl->count % 5) != 0 || (ctl->count / 5) != ctl->vcount) {
378 for (j = 0; j < 5; j++)
379 snd_emu10k1_ptr_write(emu, emu->gpr_base + ctl->gpr[j * ctl->vcount + i], 0, bass_table[val][j]);
381 case EMU10K1_GPR_TRANSLATION_TREBLE:
382 if ((ctl->count % 5) != 0 || (ctl->count / 5) != ctl->vcount) {
386 for (j = 0; j < 5; j++)
387 snd_emu10k1_ptr_write(emu, emu->gpr_base + ctl->gpr[j * ctl->vcount + i], 0, treble_table[val][j]);
389 case EMU10K1_GPR_TRANSLATION_ONOFF:
390 snd_emu10k1_ptr_write(emu, emu->gpr_base + ctl->gpr[i], 0, onoff_table[val]);
395 spin_unlock_irqrestore(&emu->reg_lock, flags);
403 static void snd_emu10k1_fx8010_interrupt(struct snd_emu10k1 *emu)
405 struct snd_emu10k1_fx8010_irq *irq, *nirq;
407 irq = emu->fx8010.irq_handlers;
409 nirq = irq->next; /* irq ptr can be removed from list */
410 if (snd_emu10k1_ptr_read(emu, emu->gpr_base + irq->gpr_running, 0) & 0xffff0000) {
412 irq->handler(emu, irq->private_data);
413 snd_emu10k1_ptr_write(emu, emu->gpr_base + irq->gpr_running, 0, 1);
419 int snd_emu10k1_fx8010_register_irq_handler(struct snd_emu10k1 *emu,
420 snd_fx8010_irq_handler_t *handler,
421 unsigned char gpr_running,
423 struct snd_emu10k1_fx8010_irq **r_irq)
425 struct snd_emu10k1_fx8010_irq *irq;
428 irq = kmalloc(sizeof(*irq), GFP_ATOMIC);
431 irq->handler = handler;
432 irq->gpr_running = gpr_running;
433 irq->private_data = private_data;
435 spin_lock_irqsave(&emu->fx8010.irq_lock, flags);
436 if (emu->fx8010.irq_handlers == NULL) {
437 emu->fx8010.irq_handlers = irq;
438 emu->dsp_interrupt = snd_emu10k1_fx8010_interrupt;
439 snd_emu10k1_intr_enable(emu, INTE_FXDSPENABLE);
441 irq->next = emu->fx8010.irq_handlers;
442 emu->fx8010.irq_handlers = irq;
444 spin_unlock_irqrestore(&emu->fx8010.irq_lock, flags);
450 int snd_emu10k1_fx8010_unregister_irq_handler(struct snd_emu10k1 *emu,
451 struct snd_emu10k1_fx8010_irq *irq)
453 struct snd_emu10k1_fx8010_irq *tmp;
456 spin_lock_irqsave(&emu->fx8010.irq_lock, flags);
457 if ((tmp = emu->fx8010.irq_handlers) == irq) {
458 emu->fx8010.irq_handlers = tmp->next;
459 if (emu->fx8010.irq_handlers == NULL) {
460 snd_emu10k1_intr_disable(emu, INTE_FXDSPENABLE);
461 emu->dsp_interrupt = NULL;
464 while (tmp && tmp->next != irq)
467 tmp->next = tmp->next->next;
469 spin_unlock_irqrestore(&emu->fx8010.irq_lock, flags);
474 /*************************************************************************
475 * EMU10K1 effect manager
476 *************************************************************************/
478 static void snd_emu10k1_write_op(struct snd_emu10k1_fx8010_code *icode,
480 u32 op, u32 r, u32 a, u32 x, u32 y)
483 snd_assert(*ptr < 512, return);
484 code = (u_int32_t __force *)icode->code + (*ptr) * 2;
485 set_bit(*ptr, icode->code_valid);
486 code[0] = ((x & 0x3ff) << 10) | (y & 0x3ff);
487 code[1] = ((op & 0x0f) << 20) | ((r & 0x3ff) << 10) | (a & 0x3ff);
491 #define OP(icode, ptr, op, r, a, x, y) \
492 snd_emu10k1_write_op(icode, ptr, op, r, a, x, y)
494 static void snd_emu10k1_audigy_write_op(struct snd_emu10k1_fx8010_code *icode,
496 u32 op, u32 r, u32 a, u32 x, u32 y)
499 snd_assert(*ptr < 1024, return);
500 code = (u_int32_t __force *)icode->code + (*ptr) * 2;
501 set_bit(*ptr, icode->code_valid);
502 code[0] = ((x & 0x7ff) << 12) | (y & 0x7ff);
503 code[1] = ((op & 0x0f) << 24) | ((r & 0x7ff) << 12) | (a & 0x7ff);
507 #define A_OP(icode, ptr, op, r, a, x, y) \
508 snd_emu10k1_audigy_write_op(icode, ptr, op, r, a, x, y)
510 static void snd_emu10k1_efx_write(struct snd_emu10k1 *emu, unsigned int pc, unsigned int data)
512 pc += emu->audigy ? A_MICROCODEBASE : MICROCODEBASE;
513 snd_emu10k1_ptr_write(emu, pc, 0, data);
516 unsigned int snd_emu10k1_efx_read(struct snd_emu10k1 *emu, unsigned int pc)
518 pc += emu->audigy ? A_MICROCODEBASE : MICROCODEBASE;
519 return snd_emu10k1_ptr_read(emu, pc, 0);
522 static int snd_emu10k1_gpr_poke(struct snd_emu10k1 *emu,
523 struct snd_emu10k1_fx8010_code *icode)
528 for (gpr = 0; gpr < (emu->audigy ? 0x200 : 0x100); gpr++) {
529 if (!test_bit(gpr, icode->gpr_valid))
531 if (get_user(val, &icode->gpr_map[gpr]))
533 snd_emu10k1_ptr_write(emu, emu->gpr_base + gpr, 0, val);
538 static int snd_emu10k1_gpr_peek(struct snd_emu10k1 *emu,
539 struct snd_emu10k1_fx8010_code *icode)
544 for (gpr = 0; gpr < (emu->audigy ? 0x200 : 0x100); gpr++) {
545 set_bit(gpr, icode->gpr_valid);
546 val = snd_emu10k1_ptr_read(emu, emu->gpr_base + gpr, 0);
547 if (put_user(val, &icode->gpr_map[gpr]))
553 static int snd_emu10k1_tram_poke(struct snd_emu10k1 *emu,
554 struct snd_emu10k1_fx8010_code *icode)
559 for (tram = 0; tram < (emu->audigy ? 0x100 : 0xa0); tram++) {
560 if (!test_bit(tram, icode->tram_valid))
562 if (get_user(val, &icode->tram_data_map[tram]) ||
563 get_user(addr, &icode->tram_addr_map[tram]))
565 snd_emu10k1_ptr_write(emu, TANKMEMDATAREGBASE + tram, 0, val);
567 snd_emu10k1_ptr_write(emu, TANKMEMADDRREGBASE + tram, 0, addr);
569 snd_emu10k1_ptr_write(emu, TANKMEMADDRREGBASE + tram, 0, addr << 12);
570 snd_emu10k1_ptr_write(emu, A_TANKMEMCTLREGBASE + tram, 0, addr >> 20);
576 static int snd_emu10k1_tram_peek(struct snd_emu10k1 *emu,
577 struct snd_emu10k1_fx8010_code *icode)
582 memset(icode->tram_valid, 0, sizeof(icode->tram_valid));
583 for (tram = 0; tram < (emu->audigy ? 0x100 : 0xa0); tram++) {
584 set_bit(tram, icode->tram_valid);
585 val = snd_emu10k1_ptr_read(emu, TANKMEMDATAREGBASE + tram, 0);
587 addr = snd_emu10k1_ptr_read(emu, TANKMEMADDRREGBASE + tram, 0);
589 addr = snd_emu10k1_ptr_read(emu, TANKMEMADDRREGBASE + tram, 0) >> 12;
590 addr |= snd_emu10k1_ptr_read(emu, A_TANKMEMCTLREGBASE + tram, 0) << 20;
592 if (put_user(val, &icode->tram_data_map[tram]) ||
593 put_user(addr, &icode->tram_addr_map[tram]))
599 static int snd_emu10k1_code_poke(struct snd_emu10k1 *emu,
600 struct snd_emu10k1_fx8010_code *icode)
604 for (pc = 0; pc < (emu->audigy ? 2*1024 : 2*512); pc += 2) {
605 if (!test_bit(pc / 2, icode->code_valid))
607 if (get_user(lo, &icode->code[pc + 0]) ||
608 get_user(hi, &icode->code[pc + 1]))
610 snd_emu10k1_efx_write(emu, pc + 0, lo);
611 snd_emu10k1_efx_write(emu, pc + 1, hi);
616 static int snd_emu10k1_code_peek(struct snd_emu10k1 *emu,
617 struct snd_emu10k1_fx8010_code *icode)
621 memset(icode->code_valid, 0, sizeof(icode->code_valid));
622 for (pc = 0; pc < (emu->audigy ? 2*1024 : 2*512); pc += 2) {
623 set_bit(pc / 2, icode->code_valid);
624 if (put_user(snd_emu10k1_efx_read(emu, pc + 0), &icode->code[pc + 0]))
626 if (put_user(snd_emu10k1_efx_read(emu, pc + 1), &icode->code[pc + 1]))
632 static struct snd_emu10k1_fx8010_ctl *
633 snd_emu10k1_look_for_ctl(struct snd_emu10k1 *emu, struct snd_ctl_elem_id *id)
635 struct snd_emu10k1_fx8010_ctl *ctl;
636 struct snd_kcontrol *kcontrol;
637 struct list_head *list;
639 list_for_each(list, &emu->fx8010.gpr_ctl) {
640 ctl = emu10k1_gpr_ctl(list);
641 kcontrol = ctl->kcontrol;
642 if (kcontrol->id.iface == id->iface &&
643 !strcmp(kcontrol->id.name, id->name) &&
644 kcontrol->id.index == id->index)
650 static int snd_emu10k1_verify_controls(struct snd_emu10k1 *emu,
651 struct snd_emu10k1_fx8010_code *icode)
654 struct snd_ctl_elem_id __user *_id;
655 struct snd_ctl_elem_id id;
656 struct snd_emu10k1_fx8010_control_gpr __user *_gctl;
657 struct snd_emu10k1_fx8010_control_gpr *gctl;
660 for (i = 0, _id = icode->gpr_del_controls;
661 i < icode->gpr_del_control_count; i++, _id++) {
662 if (copy_from_user(&id, _id, sizeof(id)))
664 if (snd_emu10k1_look_for_ctl(emu, &id) == NULL)
667 gctl = kmalloc(sizeof(*gctl), GFP_KERNEL);
671 for (i = 0, _gctl = icode->gpr_add_controls;
672 i < icode->gpr_add_control_count; i++, _gctl++) {
673 if (copy_from_user(gctl, _gctl, sizeof(*gctl))) {
677 if (snd_emu10k1_look_for_ctl(emu, &gctl->id))
679 down_read(&emu->card->controls_rwsem);
680 if (snd_ctl_find_id(emu->card, &gctl->id) != NULL) {
681 up_read(&emu->card->controls_rwsem);
685 up_read(&emu->card->controls_rwsem);
686 if (gctl->id.iface != SNDRV_CTL_ELEM_IFACE_MIXER &&
687 gctl->id.iface != SNDRV_CTL_ELEM_IFACE_PCM) {
692 for (i = 0, _gctl = icode->gpr_list_controls;
693 i < icode->gpr_list_control_count; i++, _gctl++) {
694 /* FIXME: we need to check the WRITE access */
695 if (copy_from_user(gctl, _gctl, sizeof(*gctl))) {
705 static void snd_emu10k1_ctl_private_free(struct snd_kcontrol *kctl)
707 struct snd_emu10k1_fx8010_ctl *ctl;
709 ctl = (struct snd_emu10k1_fx8010_ctl *) kctl->private_value;
710 kctl->private_value = 0;
711 list_del(&ctl->list);
715 static int snd_emu10k1_add_controls(struct snd_emu10k1 *emu,
716 struct snd_emu10k1_fx8010_code *icode)
719 struct snd_emu10k1_fx8010_control_gpr __user *_gctl;
720 struct snd_emu10k1_fx8010_control_gpr *gctl;
721 struct snd_emu10k1_fx8010_ctl *ctl, *nctl;
722 struct snd_kcontrol_new knew;
723 struct snd_kcontrol *kctl;
724 struct snd_ctl_elem_value *val;
727 val = kmalloc(sizeof(*val), GFP_KERNEL);
728 gctl = kmalloc(sizeof(*gctl), GFP_KERNEL);
729 nctl = kmalloc(sizeof(*nctl), GFP_KERNEL);
730 if (!val || !gctl || !nctl) {
735 for (i = 0, _gctl = icode->gpr_add_controls;
736 i < icode->gpr_add_control_count; i++, _gctl++) {
737 if (copy_from_user(gctl, _gctl, sizeof(*gctl))) {
741 if (gctl->id.iface != SNDRV_CTL_ELEM_IFACE_MIXER &&
742 gctl->id.iface != SNDRV_CTL_ELEM_IFACE_PCM) {
746 if (! gctl->id.name[0]) {
750 ctl = snd_emu10k1_look_for_ctl(emu, &gctl->id);
751 memset(&knew, 0, sizeof(knew));
752 knew.iface = gctl->id.iface;
753 knew.name = gctl->id.name;
754 knew.index = gctl->id.index;
755 knew.device = gctl->id.device;
756 knew.subdevice = gctl->id.subdevice;
757 knew.info = snd_emu10k1_gpr_ctl_info;
758 knew.get = snd_emu10k1_gpr_ctl_get;
759 knew.put = snd_emu10k1_gpr_ctl_put;
760 memset(nctl, 0, sizeof(*nctl));
761 nctl->vcount = gctl->vcount;
762 nctl->count = gctl->count;
763 for (j = 0; j < 32; j++) {
764 nctl->gpr[j] = gctl->gpr[j];
765 nctl->value[j] = ~gctl->value[j]; /* inverted, we want to write new value in gpr_ctl_put() */
766 val->value.integer.value[j] = gctl->value[j];
768 nctl->min = gctl->min;
769 nctl->max = gctl->max;
770 nctl->translation = gctl->translation;
772 ctl = kmalloc(sizeof(*ctl), GFP_KERNEL);
777 knew.private_value = (unsigned long)ctl;
779 if ((err = snd_ctl_add(emu->card, kctl = snd_ctl_new1(&knew, emu))) < 0) {
783 kctl->private_free = snd_emu10k1_ctl_private_free;
784 ctl->kcontrol = kctl;
785 list_add_tail(&ctl->list, &emu->fx8010.gpr_ctl);
788 nctl->list = ctl->list;
789 nctl->kcontrol = ctl->kcontrol;
791 snd_ctl_notify(emu->card, SNDRV_CTL_EVENT_MASK_VALUE |
792 SNDRV_CTL_EVENT_MASK_INFO, &ctl->kcontrol->id);
794 snd_emu10k1_gpr_ctl_put(ctl->kcontrol, val);
803 static int snd_emu10k1_del_controls(struct snd_emu10k1 *emu,
804 struct snd_emu10k1_fx8010_code *icode)
807 struct snd_ctl_elem_id id;
808 struct snd_ctl_elem_id __user *_id;
809 struct snd_emu10k1_fx8010_ctl *ctl;
810 struct snd_card *card = emu->card;
812 for (i = 0, _id = icode->gpr_del_controls;
813 i < icode->gpr_del_control_count; i++, _id++) {
814 if (copy_from_user(&id, _id, sizeof(id)))
816 down_write(&card->controls_rwsem);
817 ctl = snd_emu10k1_look_for_ctl(emu, &id);
819 snd_ctl_remove(card, ctl->kcontrol);
820 up_write(&card->controls_rwsem);
825 static int snd_emu10k1_list_controls(struct snd_emu10k1 *emu,
826 struct snd_emu10k1_fx8010_code *icode)
828 unsigned int i = 0, j;
829 unsigned int total = 0;
830 struct snd_emu10k1_fx8010_control_gpr *gctl;
831 struct snd_emu10k1_fx8010_control_gpr __user *_gctl;
832 struct snd_emu10k1_fx8010_ctl *ctl;
833 struct snd_ctl_elem_id *id;
834 struct list_head *list;
836 gctl = kmalloc(sizeof(*gctl), GFP_KERNEL);
840 _gctl = icode->gpr_list_controls;
841 list_for_each(list, &emu->fx8010.gpr_ctl) {
842 ctl = emu10k1_gpr_ctl(list);
844 if (_gctl && i < icode->gpr_list_control_count) {
845 memset(gctl, 0, sizeof(*gctl));
846 id = &ctl->kcontrol->id;
847 gctl->id.iface = id->iface;
848 strlcpy(gctl->id.name, id->name, sizeof(gctl->id.name));
849 gctl->id.index = id->index;
850 gctl->id.device = id->device;
851 gctl->id.subdevice = id->subdevice;
852 gctl->vcount = ctl->vcount;
853 gctl->count = ctl->count;
854 for (j = 0; j < 32; j++) {
855 gctl->gpr[j] = ctl->gpr[j];
856 gctl->value[j] = ctl->value[j];
858 gctl->min = ctl->min;
859 gctl->max = ctl->max;
860 gctl->translation = ctl->translation;
861 if (copy_to_user(_gctl, gctl, sizeof(*gctl))) {
869 icode->gpr_list_control_total = total;
874 static int snd_emu10k1_icode_poke(struct snd_emu10k1 *emu,
875 struct snd_emu10k1_fx8010_code *icode)
879 mutex_lock(&emu->fx8010.lock);
880 if ((err = snd_emu10k1_verify_controls(emu, icode)) < 0)
882 strlcpy(emu->fx8010.name, icode->name, sizeof(emu->fx8010.name));
883 /* stop FX processor - this may be dangerous, but it's better to miss
884 some samples than generate wrong ones - [jk] */
886 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg | A_DBG_SINGLE_STEP);
888 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg | EMU10K1_DBG_SINGLE_STEP);
889 /* ok, do the main job */
890 if ((err = snd_emu10k1_del_controls(emu, icode)) < 0 ||
891 (err = snd_emu10k1_gpr_poke(emu, icode)) < 0 ||
892 (err = snd_emu10k1_tram_poke(emu, icode)) < 0 ||
893 (err = snd_emu10k1_code_poke(emu, icode)) < 0 ||
894 (err = snd_emu10k1_add_controls(emu, icode)) < 0)
896 /* start FX processor when the DSP code is updated */
898 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg);
900 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg);
902 mutex_unlock(&emu->fx8010.lock);
906 static int snd_emu10k1_icode_peek(struct snd_emu10k1 *emu,
907 struct snd_emu10k1_fx8010_code *icode)
911 mutex_lock(&emu->fx8010.lock);
912 strlcpy(icode->name, emu->fx8010.name, sizeof(icode->name));
913 /* ok, do the main job */
914 err = snd_emu10k1_gpr_peek(emu, icode);
916 err = snd_emu10k1_tram_peek(emu, icode);
918 err = snd_emu10k1_code_peek(emu, icode);
920 err = snd_emu10k1_list_controls(emu, icode);
921 mutex_unlock(&emu->fx8010.lock);
925 static int snd_emu10k1_ipcm_poke(struct snd_emu10k1 *emu,
926 struct snd_emu10k1_fx8010_pcm_rec *ipcm)
930 struct snd_emu10k1_fx8010_pcm *pcm;
932 if (ipcm->substream >= EMU10K1_FX8010_PCM_COUNT)
934 if (ipcm->channels > 32)
936 pcm = &emu->fx8010.pcm[ipcm->substream];
937 mutex_lock(&emu->fx8010.lock);
938 spin_lock_irq(&emu->reg_lock);
943 if (ipcm->channels == 0) { /* remove */
946 /* FIXME: we need to add universal code to the PCM transfer routine */
947 if (ipcm->channels != 2) {
953 pcm->channels = ipcm->channels;
954 pcm->tram_start = ipcm->tram_start;
955 pcm->buffer_size = ipcm->buffer_size;
956 pcm->gpr_size = ipcm->gpr_size;
957 pcm->gpr_count = ipcm->gpr_count;
958 pcm->gpr_tmpcount = ipcm->gpr_tmpcount;
959 pcm->gpr_ptr = ipcm->gpr_ptr;
960 pcm->gpr_trigger = ipcm->gpr_trigger;
961 pcm->gpr_running = ipcm->gpr_running;
962 for (i = 0; i < pcm->channels; i++)
963 pcm->etram[i] = ipcm->etram[i];
966 spin_unlock_irq(&emu->reg_lock);
967 mutex_unlock(&emu->fx8010.lock);
971 static int snd_emu10k1_ipcm_peek(struct snd_emu10k1 *emu,
972 struct snd_emu10k1_fx8010_pcm_rec *ipcm)
976 struct snd_emu10k1_fx8010_pcm *pcm;
978 if (ipcm->substream >= EMU10K1_FX8010_PCM_COUNT)
980 pcm = &emu->fx8010.pcm[ipcm->substream];
981 mutex_lock(&emu->fx8010.lock);
982 spin_lock_irq(&emu->reg_lock);
983 ipcm->channels = pcm->channels;
984 ipcm->tram_start = pcm->tram_start;
985 ipcm->buffer_size = pcm->buffer_size;
986 ipcm->gpr_size = pcm->gpr_size;
987 ipcm->gpr_ptr = pcm->gpr_ptr;
988 ipcm->gpr_count = pcm->gpr_count;
989 ipcm->gpr_tmpcount = pcm->gpr_tmpcount;
990 ipcm->gpr_trigger = pcm->gpr_trigger;
991 ipcm->gpr_running = pcm->gpr_running;
992 for (i = 0; i < pcm->channels; i++)
993 ipcm->etram[i] = pcm->etram[i];
994 ipcm->res1 = ipcm->res2 = 0;
996 spin_unlock_irq(&emu->reg_lock);
997 mutex_unlock(&emu->fx8010.lock);
1001 #define SND_EMU10K1_GPR_CONTROLS 44
1002 #define SND_EMU10K1_INPUTS 12
1003 #define SND_EMU10K1_PLAYBACK_CHANNELS 8
1004 #define SND_EMU10K1_CAPTURE_CHANNELS 4
1006 static void __devinit
1007 snd_emu10k1_init_mono_control(struct snd_emu10k1_fx8010_control_gpr *ctl,
1008 const char *name, int gpr, int defval)
1010 ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1011 strcpy(ctl->id.name, name);
1012 ctl->vcount = ctl->count = 1;
1013 ctl->gpr[0] = gpr + 0; ctl->value[0] = defval;
1016 ctl->translation = EMU10K1_GPR_TRANSLATION_TABLE100;
1019 static void __devinit
1020 snd_emu10k1_init_stereo_control(struct snd_emu10k1_fx8010_control_gpr *ctl,
1021 const char *name, int gpr, int defval)
1023 ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1024 strcpy(ctl->id.name, name);
1025 ctl->vcount = ctl->count = 2;
1026 ctl->gpr[0] = gpr + 0; ctl->value[0] = defval;
1027 ctl->gpr[1] = gpr + 1; ctl->value[1] = defval;
1030 ctl->translation = EMU10K1_GPR_TRANSLATION_TABLE100;
1033 static void __devinit
1034 snd_emu10k1_init_mono_onoff_control(struct snd_emu10k1_fx8010_control_gpr *ctl,
1035 const char *name, int gpr, int defval)
1037 ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1038 strcpy(ctl->id.name, name);
1039 ctl->vcount = ctl->count = 1;
1040 ctl->gpr[0] = gpr + 0; ctl->value[0] = defval;
1043 ctl->translation = EMU10K1_GPR_TRANSLATION_ONOFF;
1046 static void __devinit
1047 snd_emu10k1_init_stereo_onoff_control(struct snd_emu10k1_fx8010_control_gpr *ctl,
1048 const char *name, int gpr, int defval)
1050 ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1051 strcpy(ctl->id.name, name);
1052 ctl->vcount = ctl->count = 2;
1053 ctl->gpr[0] = gpr + 0; ctl->value[0] = defval;
1054 ctl->gpr[1] = gpr + 1; ctl->value[1] = defval;
1057 ctl->translation = EMU10K1_GPR_TRANSLATION_ONOFF;
1062 * initial DSP configuration for Audigy
1065 static int __devinit _snd_emu10k1_audigy_init_efx(struct snd_emu10k1 *emu)
1067 int err, i, z, gpr, nctl;
1068 const int playback = 10;
1069 const int capture = playback + (SND_EMU10K1_PLAYBACK_CHANNELS * 2); /* we reserve 10 voices */
1070 const int stereo_mix = capture + 2;
1071 const int tmp = 0x88;
1073 struct snd_emu10k1_fx8010_code *icode = NULL;
1074 struct snd_emu10k1_fx8010_control_gpr *controls = NULL, *ctl;
1078 if ((icode = kzalloc(sizeof(*icode), GFP_KERNEL)) == NULL ||
1079 (icode->gpr_map = (u_int32_t __user *)
1080 kcalloc(512 + 256 + 256 + 2 * 1024, sizeof(u_int32_t),
1081 GFP_KERNEL)) == NULL ||
1082 (controls = kcalloc(SND_EMU10K1_GPR_CONTROLS,
1083 sizeof(*controls), GFP_KERNEL)) == NULL) {
1087 gpr_map = (u32 __force *)icode->gpr_map;
1089 icode->tram_data_map = icode->gpr_map + 512;
1090 icode->tram_addr_map = icode->tram_data_map + 256;
1091 icode->code = icode->tram_addr_map + 256;
1093 /* clear free GPRs */
1094 for (i = 0; i < 512; i++)
1095 set_bit(i, icode->gpr_valid);
1097 /* clear TRAM data & address lines */
1098 for (i = 0; i < 256; i++)
1099 set_bit(i, icode->tram_valid);
1101 strcpy(icode->name, "Audigy DSP code for ALSA");
1104 gpr = stereo_mix + 10;
1106 /* stop FX processor */
1107 snd_emu10k1_ptr_write(emu, A_DBG, 0, (emu->fx8010.dbg = 0) | A_DBG_SINGLE_STEP);
1111 for (z = 0; z < 80; z=z+2) {
1112 A_OP(icode, &ptr, iACC3, A_EXTOUT(z), A_FXBUS(FXBUS_PCM_LEFT_FRONT), A_C_00000000, A_C_00000000); /* left */
1113 A_OP(icode, &ptr, iACC3, A_EXTOUT(z+1), A_FXBUS(FXBUS_PCM_RIGHT_FRONT), A_C_00000000, A_C_00000000); /* right */
1115 #endif /* jcd test */
1117 /* PCM front Playback Volume (independent from stereo mix) */
1118 A_OP(icode, &ptr, iMAC0, A_GPR(playback), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LEFT_FRONT));
1119 A_OP(icode, &ptr, iMAC0, A_GPR(playback+1), A_C_00000000, A_GPR(gpr+1), A_FXBUS(FXBUS_PCM_RIGHT_FRONT));
1120 snd_emu10k1_init_stereo_control(&controls[nctl++], "PCM Front Playback Volume", gpr, 100);
1123 /* PCM Surround Playback (independent from stereo mix) */
1124 A_OP(icode, &ptr, iMAC0, A_GPR(playback+2), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LEFT_REAR));
1125 A_OP(icode, &ptr, iMAC0, A_GPR(playback+3), A_C_00000000, A_GPR(gpr+1), A_FXBUS(FXBUS_PCM_RIGHT_REAR));
1126 snd_emu10k1_init_stereo_control(&controls[nctl++], "PCM Surround Playback Volume", gpr, 100);
1129 /* PCM Side Playback (independent from stereo mix) */
1130 if (emu->card_capabilities->spk71) {
1131 A_OP(icode, &ptr, iMAC0, A_GPR(playback+6), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LEFT_SIDE));
1132 A_OP(icode, &ptr, iMAC0, A_GPR(playback+7), A_C_00000000, A_GPR(gpr+1), A_FXBUS(FXBUS_PCM_RIGHT_SIDE));
1133 snd_emu10k1_init_stereo_control(&controls[nctl++], "PCM Side Playback Volume", gpr, 100);
1137 /* PCM Center Playback (independent from stereo mix) */
1138 A_OP(icode, &ptr, iMAC0, A_GPR(playback+4), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_CENTER));
1139 snd_emu10k1_init_mono_control(&controls[nctl++], "PCM Center Playback Volume", gpr, 100);
1142 /* PCM LFE Playback (independent from stereo mix) */
1143 A_OP(icode, &ptr, iMAC0, A_GPR(playback+5), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LFE));
1144 snd_emu10k1_init_mono_control(&controls[nctl++], "PCM LFE Playback Volume", gpr, 100);
1150 /* Wave (PCM) Playback Volume (will be renamed later) */
1151 A_OP(icode, &ptr, iMAC0, A_GPR(stereo_mix), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LEFT));
1152 A_OP(icode, &ptr, iMAC0, A_GPR(stereo_mix+1), A_C_00000000, A_GPR(gpr+1), A_FXBUS(FXBUS_PCM_RIGHT));
1153 snd_emu10k1_init_stereo_control(&controls[nctl++], "Wave Playback Volume", gpr, 100);
1156 /* Synth Playback */
1157 A_OP(icode, &ptr, iMAC0, A_GPR(stereo_mix+0), A_GPR(stereo_mix+0), A_GPR(gpr), A_FXBUS(FXBUS_MIDI_LEFT));
1158 A_OP(icode, &ptr, iMAC0, A_GPR(stereo_mix+1), A_GPR(stereo_mix+1), A_GPR(gpr+1), A_FXBUS(FXBUS_MIDI_RIGHT));
1159 snd_emu10k1_init_stereo_control(&controls[nctl++], "Synth Playback Volume", gpr, 100);
1162 /* Wave (PCM) Capture */
1163 A_OP(icode, &ptr, iMAC0, A_GPR(capture+0), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LEFT));
1164 A_OP(icode, &ptr, iMAC0, A_GPR(capture+1), A_C_00000000, A_GPR(gpr+1), A_FXBUS(FXBUS_PCM_RIGHT));
1165 snd_emu10k1_init_stereo_control(&controls[nctl++], "PCM Capture Volume", gpr, 0);
1169 A_OP(icode, &ptr, iMAC0, A_GPR(capture+0), A_GPR(capture+0), A_GPR(gpr), A_FXBUS(FXBUS_MIDI_LEFT));
1170 A_OP(icode, &ptr, iMAC0, A_GPR(capture+1), A_GPR(capture+1), A_GPR(gpr+1), A_FXBUS(FXBUS_MIDI_RIGHT));
1171 snd_emu10k1_init_stereo_control(&controls[nctl++], "Synth Capture Volume", gpr, 0);
1177 #define A_ADD_VOLUME_IN(var,vol,input) \
1178 A_OP(icode, &ptr, iMAC0, A_GPR(var), A_GPR(var), A_GPR(vol), A_EXTIN(input))
1180 /* AC'97 Playback Volume - used only for mic (renamed later) */
1181 A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_AC97_L);
1182 A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_AC97_R);
1183 snd_emu10k1_init_stereo_control(&controls[nctl++], "AMic Playback Volume", gpr, 0);
1185 /* AC'97 Capture Volume - used only for mic */
1186 A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_AC97_L);
1187 A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_AC97_R);
1188 snd_emu10k1_init_stereo_control(&controls[nctl++], "Mic Capture Volume", gpr, 0);
1191 /* mic capture buffer */
1192 A_OP(icode, &ptr, iINTERP, A_EXTOUT(A_EXTOUT_MIC_CAP), A_EXTIN(A_EXTIN_AC97_L), 0xcd, A_EXTIN(A_EXTIN_AC97_R));
1194 /* Audigy CD Playback Volume */
1195 A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_SPDIF_CD_L);
1196 A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_SPDIF_CD_R);
1197 snd_emu10k1_init_stereo_control(&controls[nctl++],
1198 emu->card_capabilities->ac97_chip ? "Audigy CD Playback Volume" : "CD Playback Volume",
1201 /* Audigy CD Capture Volume */
1202 A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_SPDIF_CD_L);
1203 A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_SPDIF_CD_R);
1204 snd_emu10k1_init_stereo_control(&controls[nctl++],
1205 emu->card_capabilities->ac97_chip ? "Audigy CD Capture Volume" : "CD Capture Volume",
1209 /* Optical SPDIF Playback Volume */
1210 A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_OPT_SPDIF_L);
1211 A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_OPT_SPDIF_R);
1212 snd_emu10k1_init_stereo_control(&controls[nctl++], SNDRV_CTL_NAME_IEC958("Optical ",PLAYBACK,VOLUME), gpr, 0);
1214 /* Optical SPDIF Capture Volume */
1215 A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_OPT_SPDIF_L);
1216 A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_OPT_SPDIF_R);
1217 snd_emu10k1_init_stereo_control(&controls[nctl++], SNDRV_CTL_NAME_IEC958("Optical ",CAPTURE,VOLUME), gpr, 0);
1220 /* Line2 Playback Volume */
1221 A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_LINE2_L);
1222 A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_LINE2_R);
1223 snd_emu10k1_init_stereo_control(&controls[nctl++],
1224 emu->card_capabilities->ac97_chip ? "Line2 Playback Volume" : "Line Playback Volume",
1227 /* Line2 Capture Volume */
1228 A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_LINE2_L);
1229 A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_LINE2_R);
1230 snd_emu10k1_init_stereo_control(&controls[nctl++],
1231 emu->card_capabilities->ac97_chip ? "Line2 Capture Volume" : "Line Capture Volume",
1235 /* Philips ADC Playback Volume */
1236 A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_ADC_L);
1237 A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_ADC_R);
1238 snd_emu10k1_init_stereo_control(&controls[nctl++], "Analog Mix Playback Volume", gpr, 0);
1240 /* Philips ADC Capture Volume */
1241 A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_ADC_L);
1242 A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_ADC_R);
1243 snd_emu10k1_init_stereo_control(&controls[nctl++], "Analog Mix Capture Volume", gpr, 0);
1246 /* Aux2 Playback Volume */
1247 A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_AUX2_L);
1248 A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_AUX2_R);
1249 snd_emu10k1_init_stereo_control(&controls[nctl++],
1250 emu->card_capabilities->ac97_chip ? "Aux2 Playback Volume" : "Aux Playback Volume",
1253 /* Aux2 Capture Volume */
1254 A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_AUX2_L);
1255 A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_AUX2_R);
1256 snd_emu10k1_init_stereo_control(&controls[nctl++],
1257 emu->card_capabilities->ac97_chip ? "Aux2 Capture Volume" : "Aux Capture Volume",
1261 /* Stereo Mix Front Playback Volume */
1262 A_OP(icode, &ptr, iMAC0, A_GPR(playback), A_GPR(playback), A_GPR(gpr), A_GPR(stereo_mix));
1263 A_OP(icode, &ptr, iMAC0, A_GPR(playback+1), A_GPR(playback+1), A_GPR(gpr+1), A_GPR(stereo_mix+1));
1264 snd_emu10k1_init_stereo_control(&controls[nctl++], "Front Playback Volume", gpr, 100);
1267 /* Stereo Mix Surround Playback */
1268 A_OP(icode, &ptr, iMAC0, A_GPR(playback+2), A_GPR(playback+2), A_GPR(gpr), A_GPR(stereo_mix));
1269 A_OP(icode, &ptr, iMAC0, A_GPR(playback+3), A_GPR(playback+3), A_GPR(gpr+1), A_GPR(stereo_mix+1));
1270 snd_emu10k1_init_stereo_control(&controls[nctl++], "Surround Playback Volume", gpr, 0);
1273 /* Stereo Mix Center Playback */
1274 /* Center = sub = Left/2 + Right/2 */
1275 A_OP(icode, &ptr, iINTERP, A_GPR(tmp), A_GPR(stereo_mix), 0xcd, A_GPR(stereo_mix+1));
1276 A_OP(icode, &ptr, iMAC0, A_GPR(playback+4), A_GPR(playback+4), A_GPR(gpr), A_GPR(tmp));
1277 snd_emu10k1_init_mono_control(&controls[nctl++], "Center Playback Volume", gpr, 0);
1280 /* Stereo Mix LFE Playback */
1281 A_OP(icode, &ptr, iMAC0, A_GPR(playback+5), A_GPR(playback+5), A_GPR(gpr), A_GPR(tmp));
1282 snd_emu10k1_init_mono_control(&controls[nctl++], "LFE Playback Volume", gpr, 0);
1285 if (emu->card_capabilities->spk71) {
1286 /* Stereo Mix Side Playback */
1287 A_OP(icode, &ptr, iMAC0, A_GPR(playback+6), A_GPR(playback+6), A_GPR(gpr), A_GPR(stereo_mix));
1288 A_OP(icode, &ptr, iMAC0, A_GPR(playback+7), A_GPR(playback+7), A_GPR(gpr+1), A_GPR(stereo_mix+1));
1289 snd_emu10k1_init_stereo_control(&controls[nctl++], "Side Playback Volume", gpr, 0);
1296 #define A_PUT_OUTPUT(out,src) A_OP(icode, &ptr, iACC3, A_EXTOUT(out), A_C_00000000, A_C_00000000, A_GPR(src))
1297 #define A_PUT_STEREO_OUTPUT(out1,out2,src) \
1298 {A_PUT_OUTPUT(out1,src); A_PUT_OUTPUT(out2,src+1);}
1300 #define _A_SWITCH(icode, ptr, dst, src, sw) \
1301 A_OP((icode), ptr, iMACINT0, dst, A_C_00000000, src, sw);
1302 #define A_SWITCH(icode, ptr, dst, src, sw) \
1303 _A_SWITCH(icode, ptr, A_GPR(dst), A_GPR(src), A_GPR(sw))
1304 #define _A_SWITCH_NEG(icode, ptr, dst, src) \
1305 A_OP((icode), ptr, iANDXOR, dst, src, A_C_00000001, A_C_00000001);
1306 #define A_SWITCH_NEG(icode, ptr, dst, src) \
1307 _A_SWITCH_NEG(icode, ptr, A_GPR(dst), A_GPR(src))
1311 * Process tone control
1313 A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 0), A_GPR(playback + 0), A_C_00000000, A_C_00000000); /* left */
1314 A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 1), A_GPR(playback + 1), A_C_00000000, A_C_00000000); /* right */
1315 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 */
1316 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 */
1317 A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 4), A_GPR(playback + 4), A_C_00000000, A_C_00000000); /* center */
1318 A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 5), A_GPR(playback + 5), A_C_00000000, A_C_00000000); /* LFE */
1319 if (emu->card_capabilities->spk71) {
1320 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 */
1321 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 */
1325 ctl = &controls[nctl + 0];
1326 ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1327 strcpy(ctl->id.name, "Tone Control - Bass");
1332 ctl->value[0] = ctl->value[1] = 20;
1333 ctl->translation = EMU10K1_GPR_TRANSLATION_BASS;
1334 ctl = &controls[nctl + 1];
1335 ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1336 strcpy(ctl->id.name, "Tone Control - Treble");
1341 ctl->value[0] = ctl->value[1] = 20;
1342 ctl->translation = EMU10K1_GPR_TRANSLATION_TREBLE;
1344 #define BASS_GPR 0x8c
1345 #define TREBLE_GPR 0x96
1347 for (z = 0; z < 5; z++) {
1349 for (j = 0; j < 2; j++) {
1350 controls[nctl + 0].gpr[z * 2 + j] = BASS_GPR + z * 2 + j;
1351 controls[nctl + 1].gpr[z * 2 + j] = TREBLE_GPR + z * 2 + j;
1354 for (z = 0; z < 4; z++) { /* front/rear/center-lfe/side */
1356 for (j = 0; j < 2; j++) { /* left/right */
1357 k = 0xb0 + (z * 8) + (j * 4);
1358 l = 0xe0 + (z * 8) + (j * 4);
1359 d = playback + SND_EMU10K1_PLAYBACK_CHANNELS + z * 2 + j;
1361 A_OP(icode, &ptr, iMAC0, A_C_00000000, A_C_00000000, A_GPR(d), A_GPR(BASS_GPR + 0 + j));
1362 A_OP(icode, &ptr, iMACMV, A_GPR(k+1), A_GPR(k), A_GPR(k+1), A_GPR(BASS_GPR + 4 + j));
1363 A_OP(icode, &ptr, iMACMV, A_GPR(k), A_GPR(d), A_GPR(k), A_GPR(BASS_GPR + 2 + j));
1364 A_OP(icode, &ptr, iMACMV, A_GPR(k+3), A_GPR(k+2), A_GPR(k+3), A_GPR(BASS_GPR + 8 + j));
1365 A_OP(icode, &ptr, iMAC0, A_GPR(k+2), A_GPR_ACCU, A_GPR(k+2), A_GPR(BASS_GPR + 6 + j));
1366 A_OP(icode, &ptr, iACC3, A_GPR(k+2), A_GPR(k+2), A_GPR(k+2), A_C_00000000);
1368 A_OP(icode, &ptr, iMAC0, A_C_00000000, A_C_00000000, A_GPR(k+2), A_GPR(TREBLE_GPR + 0 + j));
1369 A_OP(icode, &ptr, iMACMV, A_GPR(l+1), A_GPR(l), A_GPR(l+1), A_GPR(TREBLE_GPR + 4 + j));
1370 A_OP(icode, &ptr, iMACMV, A_GPR(l), A_GPR(k+2), A_GPR(l), A_GPR(TREBLE_GPR + 2 + j));
1371 A_OP(icode, &ptr, iMACMV, A_GPR(l+3), A_GPR(l+2), A_GPR(l+3), A_GPR(TREBLE_GPR + 8 + j));
1372 A_OP(icode, &ptr, iMAC0, A_GPR(l+2), A_GPR_ACCU, A_GPR(l+2), A_GPR(TREBLE_GPR + 6 + j));
1373 A_OP(icode, &ptr, iMACINT0, A_GPR(l+2), A_C_00000000, A_GPR(l+2), A_C_00000010);
1375 A_OP(icode, &ptr, iACC3, A_GPR(d), A_GPR(l+2), A_C_00000000, A_C_00000000);
1377 if (z == 2) /* center */
1386 for (z = 0; z < 8; z++) {
1387 A_SWITCH(icode, &ptr, tmp + 0, playback + SND_EMU10K1_PLAYBACK_CHANNELS + z, gpr + 0);
1388 A_SWITCH_NEG(icode, &ptr, tmp + 1, gpr + 0);
1389 A_SWITCH(icode, &ptr, tmp + 1, playback + z, tmp + 1);
1390 A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + z), A_GPR(tmp + 0), A_GPR(tmp + 1), A_C_00000000);
1392 snd_emu10k1_init_stereo_onoff_control(controls + nctl++, "Tone Control - Switch", gpr, 0);
1395 /* Master volume (will be renamed later) */
1396 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));
1397 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));
1398 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));
1399 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));
1400 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));
1401 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));
1402 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));
1403 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));
1404 snd_emu10k1_init_mono_control(&controls[nctl++], "Wave Master Playback Volume", gpr, 0);
1407 /* analog speakers */
1408 A_PUT_STEREO_OUTPUT(A_EXTOUT_AFRONT_L, A_EXTOUT_AFRONT_R, playback + SND_EMU10K1_PLAYBACK_CHANNELS);
1409 A_PUT_STEREO_OUTPUT(A_EXTOUT_AREAR_L, A_EXTOUT_AREAR_R, playback+2 + SND_EMU10K1_PLAYBACK_CHANNELS);
1410 A_PUT_OUTPUT(A_EXTOUT_ACENTER, playback+4 + SND_EMU10K1_PLAYBACK_CHANNELS);
1411 A_PUT_OUTPUT(A_EXTOUT_ALFE, playback+5 + SND_EMU10K1_PLAYBACK_CHANNELS);
1412 if (emu->card_capabilities->spk71)
1413 A_PUT_STEREO_OUTPUT(A_EXTOUT_ASIDE_L, A_EXTOUT_ASIDE_R, playback+6 + SND_EMU10K1_PLAYBACK_CHANNELS);
1416 A_PUT_STEREO_OUTPUT(A_EXTOUT_HEADPHONE_L, A_EXTOUT_HEADPHONE_R, playback + SND_EMU10K1_PLAYBACK_CHANNELS);
1418 /* digital outputs */
1419 /* A_PUT_STEREO_OUTPUT(A_EXTOUT_FRONT_L, A_EXTOUT_FRONT_R, playback + SND_EMU10K1_PLAYBACK_CHANNELS); */
1421 /* IEC958 Optical Raw Playback Switch */
1423 gpr_map[gpr++] = 0x1008;
1424 gpr_map[gpr++] = 0xffff0000;
1425 for (z = 0; z < 2; z++) {
1426 A_OP(icode, &ptr, iMAC0, A_GPR(tmp + 2), A_FXBUS(FXBUS_PT_LEFT + z), A_C_00000000, A_C_00000000);
1427 A_OP(icode, &ptr, iSKIP, A_GPR_COND, A_GPR_COND, A_GPR(gpr - 2), A_C_00000001);
1428 A_OP(icode, &ptr, iACC3, A_GPR(tmp + 2), A_C_00000000, A_C_00010000, A_GPR(tmp + 2));
1429 A_OP(icode, &ptr, iANDXOR, A_GPR(tmp + 2), A_GPR(tmp + 2), A_GPR(gpr - 1), A_C_00000000);
1430 A_SWITCH(icode, &ptr, tmp + 0, tmp + 2, gpr + z);
1431 A_SWITCH_NEG(icode, &ptr, tmp + 1, gpr + z);
1432 A_SWITCH(icode, &ptr, tmp + 1, playback + SND_EMU10K1_PLAYBACK_CHANNELS + z, tmp + 1);
1433 if ((z==1) && (emu->card_capabilities->spdif_bug)) {
1434 /* Due to a SPDIF output bug on some Audigy cards, this code delays the Right channel by 1 sample */
1435 snd_printk(KERN_INFO "Installing spdif_bug patch: %s\n", emu->card_capabilities->name);
1436 A_OP(icode, &ptr, iACC3, A_EXTOUT(A_EXTOUT_FRONT_L + z), A_GPR(gpr - 3), A_C_00000000, A_C_00000000);
1437 A_OP(icode, &ptr, iACC3, A_GPR(gpr - 3), A_GPR(tmp + 0), A_GPR(tmp + 1), A_C_00000000);
1439 A_OP(icode, &ptr, iACC3, A_EXTOUT(A_EXTOUT_FRONT_L + z), A_GPR(tmp + 0), A_GPR(tmp + 1), A_C_00000000);
1442 snd_emu10k1_init_stereo_onoff_control(controls + nctl++, SNDRV_CTL_NAME_IEC958("Optical Raw ",PLAYBACK,SWITCH), gpr, 0);
1445 A_PUT_STEREO_OUTPUT(A_EXTOUT_REAR_L, A_EXTOUT_REAR_R, playback+2 + SND_EMU10K1_PLAYBACK_CHANNELS);
1446 A_PUT_OUTPUT(A_EXTOUT_CENTER, playback+4 + SND_EMU10K1_PLAYBACK_CHANNELS);
1447 A_PUT_OUTPUT(A_EXTOUT_LFE, playback+5 + SND_EMU10K1_PLAYBACK_CHANNELS);
1450 #ifdef EMU10K1_CAPTURE_DIGITAL_OUT
1451 A_PUT_STEREO_OUTPUT(A_EXTOUT_ADC_CAP_L, A_EXTOUT_ADC_CAP_R, playback + SND_EMU10K1_PLAYBACK_CHANNELS);
1453 A_PUT_OUTPUT(A_EXTOUT_ADC_CAP_L, capture);
1454 A_PUT_OUTPUT(A_EXTOUT_ADC_CAP_R, capture+1);
1457 /* EFX capture - capture the 16 EXTINs */
1458 for (z = 0; z < 16; z++) {
1459 A_OP(icode, &ptr, iACC3, A_FXBUS2(z), A_C_00000000, A_C_00000000, A_EXTIN(z));
1462 #endif /* JCD test */
1472 /* clear remaining instruction memory */
1474 A_OP(icode, &ptr, 0x0f, 0xc0, 0xc0, 0xcf, 0xc0);
1476 seg = snd_enter_user();
1477 icode->gpr_add_control_count = nctl;
1478 icode->gpr_add_controls = (struct snd_emu10k1_fx8010_control_gpr __user *)controls;
1479 err = snd_emu10k1_icode_poke(emu, icode);
1480 snd_leave_user(seg);
1484 if (icode != NULL) {
1485 kfree((void __force *)icode->gpr_map);
1493 * initial DSP configuration for Emu10k1
1496 /* when volume = max, then copy only to avoid volume modification */
1497 /* with iMAC0 (negative values) */
1498 static void __devinit _volume(struct snd_emu10k1_fx8010_code *icode, u32 *ptr, u32 dst, u32 src, u32 vol)
1500 OP(icode, ptr, iMAC0, dst, C_00000000, src, vol);
1501 OP(icode, ptr, iANDXOR, C_00000000, vol, C_ffffffff, C_7fffffff);
1502 OP(icode, ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, C_00000001);
1503 OP(icode, ptr, iACC3, dst, src, C_00000000, C_00000000);
1505 static void __devinit _volume_add(struct snd_emu10k1_fx8010_code *icode, u32 *ptr, u32 dst, u32 src, u32 vol)
1507 OP(icode, ptr, iANDXOR, C_00000000, vol, C_ffffffff, C_7fffffff);
1508 OP(icode, ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, C_00000002);
1509 OP(icode, ptr, iMACINT0, dst, dst, src, C_00000001);
1510 OP(icode, ptr, iSKIP, C_00000000, C_7fffffff, C_7fffffff, C_00000001);
1511 OP(icode, ptr, iMAC0, dst, dst, src, vol);
1513 static void __devinit _volume_out(struct snd_emu10k1_fx8010_code *icode, u32 *ptr, u32 dst, u32 src, u32 vol)
1515 OP(icode, ptr, iANDXOR, C_00000000, vol, C_ffffffff, C_7fffffff);
1516 OP(icode, ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, C_00000002);
1517 OP(icode, ptr, iACC3, dst, src, C_00000000, C_00000000);
1518 OP(icode, ptr, iSKIP, C_00000000, C_7fffffff, C_7fffffff, C_00000001);
1519 OP(icode, ptr, iMAC0, dst, C_00000000, src, vol);
1522 #define VOLUME(icode, ptr, dst, src, vol) \
1523 _volume(icode, ptr, GPR(dst), GPR(src), GPR(vol))
1524 #define VOLUME_IN(icode, ptr, dst, src, vol) \
1525 _volume(icode, ptr, GPR(dst), EXTIN(src), GPR(vol))
1526 #define VOLUME_ADD(icode, ptr, dst, src, vol) \
1527 _volume_add(icode, ptr, GPR(dst), GPR(src), GPR(vol))
1528 #define VOLUME_ADDIN(icode, ptr, dst, src, vol) \
1529 _volume_add(icode, ptr, GPR(dst), EXTIN(src), GPR(vol))
1530 #define VOLUME_OUT(icode, ptr, dst, src, vol) \
1531 _volume_out(icode, ptr, EXTOUT(dst), GPR(src), GPR(vol))
1532 #define _SWITCH(icode, ptr, dst, src, sw) \
1533 OP((icode), ptr, iMACINT0, dst, C_00000000, src, sw);
1534 #define SWITCH(icode, ptr, dst, src, sw) \
1535 _SWITCH(icode, ptr, GPR(dst), GPR(src), GPR(sw))
1536 #define SWITCH_IN(icode, ptr, dst, src, sw) \
1537 _SWITCH(icode, ptr, GPR(dst), EXTIN(src), GPR(sw))
1538 #define _SWITCH_NEG(icode, ptr, dst, src) \
1539 OP((icode), ptr, iANDXOR, dst, src, C_00000001, C_00000001);
1540 #define SWITCH_NEG(icode, ptr, dst, src) \
1541 _SWITCH_NEG(icode, ptr, GPR(dst), GPR(src))
1544 static int __devinit _snd_emu10k1_init_efx(struct snd_emu10k1 *emu)
1546 int err, i, z, gpr, tmp, playback, capture;
1548 struct snd_emu10k1_fx8010_code *icode;
1549 struct snd_emu10k1_fx8010_pcm_rec *ipcm = NULL;
1550 struct snd_emu10k1_fx8010_control_gpr *controls = NULL, *ctl;
1554 if ((icode = kzalloc(sizeof(*icode), GFP_KERNEL)) == NULL)
1556 if ((icode->gpr_map = (u_int32_t __user *)
1557 kcalloc(256 + 160 + 160 + 2 * 512, sizeof(u_int32_t),
1558 GFP_KERNEL)) == NULL ||
1559 (controls = kcalloc(SND_EMU10K1_GPR_CONTROLS,
1560 sizeof(struct snd_emu10k1_fx8010_control_gpr),
1561 GFP_KERNEL)) == NULL ||
1562 (ipcm = kzalloc(sizeof(*ipcm), GFP_KERNEL)) == NULL) {
1566 gpr_map = (u32 __force *)icode->gpr_map;
1568 icode->tram_data_map = icode->gpr_map + 256;
1569 icode->tram_addr_map = icode->tram_data_map + 160;
1570 icode->code = icode->tram_addr_map + 160;
1572 /* clear free GPRs */
1573 for (i = 0; i < 256; i++)
1574 set_bit(i, icode->gpr_valid);
1576 /* clear TRAM data & address lines */
1577 for (i = 0; i < 160; i++)
1578 set_bit(i, icode->tram_valid);
1580 strcpy(icode->name, "SB Live! FX8010 code for ALSA v1.2 by Jaroslav Kysela");
1582 /* we have 12 inputs */
1583 playback = SND_EMU10K1_INPUTS;
1584 /* we have 6 playback channels and tone control doubles */
1585 capture = playback + (SND_EMU10K1_PLAYBACK_CHANNELS * 2);
1586 gpr = capture + SND_EMU10K1_CAPTURE_CHANNELS;
1587 tmp = 0x88; /* we need 4 temporary GPR */
1588 /* from 0x8c to 0xff is the area for tone control */
1590 /* stop FX processor */
1591 snd_emu10k1_ptr_write(emu, DBG, 0, (emu->fx8010.dbg = 0) | EMU10K1_DBG_SINGLE_STEP);
1596 OP(icode, &ptr, iMACINT0, GPR(0), C_00000000, FXBUS(FXBUS_PCM_LEFT), C_00000004);
1597 OP(icode, &ptr, iMACINT0, GPR(1), C_00000000, FXBUS(FXBUS_PCM_RIGHT), C_00000004);
1598 OP(icode, &ptr, iMACINT0, GPR(2), C_00000000, FXBUS(FXBUS_MIDI_LEFT), C_00000004);
1599 OP(icode, &ptr, iMACINT0, GPR(3), C_00000000, FXBUS(FXBUS_MIDI_RIGHT), C_00000004);
1600 OP(icode, &ptr, iMACINT0, GPR(4), C_00000000, FXBUS(FXBUS_PCM_LEFT_REAR), C_00000004);
1601 OP(icode, &ptr, iMACINT0, GPR(5), C_00000000, FXBUS(FXBUS_PCM_RIGHT_REAR), C_00000004);
1602 OP(icode, &ptr, iMACINT0, GPR(6), C_00000000, FXBUS(FXBUS_PCM_CENTER), C_00000004);
1603 OP(icode, &ptr, iMACINT0, GPR(7), C_00000000, FXBUS(FXBUS_PCM_LFE), C_00000004);
1604 OP(icode, &ptr, iMACINT0, GPR(8), C_00000000, C_00000000, C_00000000); /* S/PDIF left */
1605 OP(icode, &ptr, iMACINT0, GPR(9), C_00000000, C_00000000, C_00000000); /* S/PDIF right */
1606 OP(icode, &ptr, iMACINT0, GPR(10), C_00000000, FXBUS(FXBUS_PCM_LEFT_FRONT), C_00000004);
1607 OP(icode, &ptr, iMACINT0, GPR(11), C_00000000, FXBUS(FXBUS_PCM_RIGHT_FRONT), C_00000004);
1609 /* Raw S/PDIF PCM */
1610 ipcm->substream = 0;
1612 ipcm->tram_start = 0;
1613 ipcm->buffer_size = (64 * 1024) / 2;
1614 ipcm->gpr_size = gpr++;
1615 ipcm->gpr_ptr = gpr++;
1616 ipcm->gpr_count = gpr++;
1617 ipcm->gpr_tmpcount = gpr++;
1618 ipcm->gpr_trigger = gpr++;
1619 ipcm->gpr_running = gpr++;
1623 gpr_map[gpr + 0] = 0xfffff000;
1624 gpr_map[gpr + 1] = 0xffff0000;
1625 gpr_map[gpr + 2] = 0x70000000;
1626 gpr_map[gpr + 3] = 0x00000007;
1627 gpr_map[gpr + 4] = 0x001f << 11;
1628 gpr_map[gpr + 5] = 0x001c << 11;
1629 gpr_map[gpr + 6] = (0x22 - 0x01) - 1; /* skip at 01 to 22 */
1630 gpr_map[gpr + 7] = (0x22 - 0x06) - 1; /* skip at 06 to 22 */
1631 gpr_map[gpr + 8] = 0x2000000 + (2<<11);
1632 gpr_map[gpr + 9] = 0x4000000 + (2<<11);
1633 gpr_map[gpr + 10] = 1<<11;
1634 gpr_map[gpr + 11] = (0x24 - 0x0a) - 1; /* skip at 0a to 24 */
1635 gpr_map[gpr + 12] = 0;
1637 /* if the trigger flag is not set, skip */
1638 /* 00: */ OP(icode, &ptr, iMAC0, C_00000000, GPR(ipcm->gpr_trigger), C_00000000, C_00000000);
1639 /* 01: */ OP(icode, &ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_ZERO, GPR(gpr + 6));
1640 /* if the running flag is set, we're running */
1641 /* 02: */ OP(icode, &ptr, iMAC0, C_00000000, GPR(ipcm->gpr_running), C_00000000, C_00000000);
1642 /* 03: */ OP(icode, &ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, C_00000004);
1643 /* wait until ((GPR_DBAC>>11) & 0x1f) == 0x1c) */
1644 /* 04: */ OP(icode, &ptr, iANDXOR, GPR(tmp + 0), GPR_DBAC, GPR(gpr + 4), C_00000000);
1645 /* 05: */ OP(icode, &ptr, iMACINT0, C_00000000, GPR(tmp + 0), C_ffffffff, GPR(gpr + 5));
1646 /* 06: */ OP(icode, &ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, GPR(gpr + 7));
1647 /* 07: */ OP(icode, &ptr, iACC3, GPR(gpr + 12), C_00000010, C_00000001, C_00000000);
1649 /* 08: */ OP(icode, &ptr, iANDXOR, GPR(ipcm->gpr_running), GPR(ipcm->gpr_running), C_00000000, C_00000001);
1650 /* 09: */ OP(icode, &ptr, iACC3, GPR(gpr + 12), GPR(gpr + 12), C_ffffffff, C_00000000);
1651 /* 0a: */ OP(icode, &ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, GPR(gpr + 11));
1652 /* 0b: */ OP(icode, &ptr, iACC3, GPR(gpr + 12), C_00000001, C_00000000, C_00000000);
1654 /* 0c: */ OP(icode, &ptr, iANDXOR, GPR(tmp + 0), ETRAM_DATA(ipcm->etram[0]), GPR(gpr + 0), C_00000000);
1655 /* 0d: */ OP(icode, &ptr, iLOG, GPR(tmp + 0), GPR(tmp + 0), GPR(gpr + 3), C_00000000);
1656 /* 0e: */ OP(icode, &ptr, iANDXOR, GPR(8), GPR(tmp + 0), GPR(gpr + 1), GPR(gpr + 2));
1657 /* 0f: */ OP(icode, &ptr, iSKIP, C_00000000, GPR_COND, CC_REG_MINUS, C_00000001);
1658 /* 10: */ OP(icode, &ptr, iANDXOR, GPR(8), GPR(8), GPR(gpr + 1), GPR(gpr + 2));
1660 /* 11: */ OP(icode, &ptr, iANDXOR, GPR(tmp + 0), ETRAM_DATA(ipcm->etram[1]), GPR(gpr + 0), C_00000000);
1661 /* 12: */ OP(icode, &ptr, iLOG, GPR(tmp + 0), GPR(tmp + 0), GPR(gpr + 3), C_00000000);
1662 /* 13: */ OP(icode, &ptr, iANDXOR, GPR(9), GPR(tmp + 0), GPR(gpr + 1), GPR(gpr + 2));
1663 /* 14: */ OP(icode, &ptr, iSKIP, C_00000000, GPR_COND, CC_REG_MINUS, C_00000001);
1664 /* 15: */ OP(icode, &ptr, iANDXOR, GPR(9), GPR(9), GPR(gpr + 1), GPR(gpr + 2));
1666 /* 16: */ OP(icode, &ptr, iACC3, GPR(tmp + 0), GPR(ipcm->gpr_ptr), C_00000001, C_00000000);
1667 /* 17: */ OP(icode, &ptr, iMACINT0, C_00000000, GPR(tmp + 0), C_ffffffff, GPR(ipcm->gpr_size));
1668 /* 18: */ OP(icode, &ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_MINUS, C_00000001);
1669 /* 19: */ OP(icode, &ptr, iACC3, GPR(tmp + 0), C_00000000, C_00000000, C_00000000);
1670 /* 1a: */ OP(icode, &ptr, iACC3, GPR(ipcm->gpr_ptr), GPR(tmp + 0), C_00000000, C_00000000);
1672 /* 1b: */ OP(icode, &ptr, iACC3, GPR(ipcm->gpr_tmpcount), GPR(ipcm->gpr_tmpcount), C_ffffffff, C_00000000);
1673 /* 1c: */ OP(icode, &ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, C_00000002);
1674 /* 1d: */ OP(icode, &ptr, iACC3, GPR(ipcm->gpr_tmpcount), GPR(ipcm->gpr_count), C_00000000, C_00000000);
1675 /* 1e: */ OP(icode, &ptr, iACC3, GPR_IRQ, C_80000000, C_00000000, C_00000000);
1676 /* 1f: */ OP(icode, &ptr, iANDXOR, GPR(ipcm->gpr_running), GPR(ipcm->gpr_running), C_00000001, C_00010000);
1678 /* 20: */ OP(icode, &ptr, iANDXOR, GPR(ipcm->gpr_running), GPR(ipcm->gpr_running), C_00010000, C_00000001);
1679 /* 21: */ OP(icode, &ptr, iSKIP, C_00000000, C_7fffffff, C_7fffffff, C_00000002);
1681 /* 22: */ OP(icode, &ptr, iMACINT1, ETRAM_ADDR(ipcm->etram[0]), GPR(gpr + 8), GPR_DBAC, C_ffffffff);
1682 /* 23: */ OP(icode, &ptr, iMACINT1, ETRAM_ADDR(ipcm->etram[1]), GPR(gpr + 9), GPR_DBAC, C_ffffffff);
1687 /* Wave Playback Volume */
1688 for (z = 0; z < 2; z++)
1689 VOLUME(icode, &ptr, playback + z, z, gpr + z);
1690 snd_emu10k1_init_stereo_control(controls + i++, "Wave Playback Volume", gpr, 100);
1693 /* Wave Surround Playback Volume */
1694 for (z = 0; z < 2; z++)
1695 VOLUME(icode, &ptr, playback + 2 + z, z, gpr + z);
1696 snd_emu10k1_init_stereo_control(controls + i++, "Wave Surround Playback Volume", gpr, 0);
1699 /* Wave Center/LFE Playback Volume */
1700 OP(icode, &ptr, iACC3, GPR(tmp + 0), FXBUS(FXBUS_PCM_LEFT), FXBUS(FXBUS_PCM_RIGHT), C_00000000);
1701 OP(icode, &ptr, iMACINT0, GPR(tmp + 0), C_00000000, GPR(tmp + 0), C_00000002);
1702 VOLUME(icode, &ptr, playback + 4, tmp + 0, gpr);
1703 snd_emu10k1_init_mono_control(controls + i++, "Wave Center Playback Volume", gpr++, 0);
1704 VOLUME(icode, &ptr, playback + 5, tmp + 0, gpr);
1705 snd_emu10k1_init_mono_control(controls + i++, "Wave LFE Playback Volume", gpr++, 0);
1707 /* Wave Capture Volume + Switch */
1708 for (z = 0; z < 2; z++) {
1709 SWITCH(icode, &ptr, tmp + 0, z, gpr + 2 + z);
1710 VOLUME(icode, &ptr, capture + z, tmp + 0, gpr + z);
1712 snd_emu10k1_init_stereo_control(controls + i++, "Wave Capture Volume", gpr, 0);
1713 snd_emu10k1_init_stereo_onoff_control(controls + i++, "Wave Capture Switch", gpr + 2, 0);
1716 /* Synth Playback Volume */
1717 for (z = 0; z < 2; z++)
1718 VOLUME_ADD(icode, &ptr, playback + z, 2 + z, gpr + z);
1719 snd_emu10k1_init_stereo_control(controls + i++, "Synth Playback Volume", gpr, 100);
1722 /* Synth Capture Volume + Switch */
1723 for (z = 0; z < 2; z++) {
1724 SWITCH(icode, &ptr, tmp + 0, 2 + z, gpr + 2 + z);
1725 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
1727 snd_emu10k1_init_stereo_control(controls + i++, "Synth Capture Volume", gpr, 0);
1728 snd_emu10k1_init_stereo_onoff_control(controls + i++, "Synth Capture Switch", gpr + 2, 0);
1731 /* Surround Digital Playback Volume (renamed later without Digital) */
1732 for (z = 0; z < 2; z++)
1733 VOLUME_ADD(icode, &ptr, playback + 2 + z, 4 + z, gpr + z);
1734 snd_emu10k1_init_stereo_control(controls + i++, "Surround Digital Playback Volume", gpr, 100);
1737 /* Surround Capture Volume + Switch */
1738 for (z = 0; z < 2; z++) {
1739 SWITCH(icode, &ptr, tmp + 0, 4 + z, gpr + 2 + z);
1740 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
1742 snd_emu10k1_init_stereo_control(controls + i++, "Surround Capture Volume", gpr, 0);
1743 snd_emu10k1_init_stereo_onoff_control(controls + i++, "Surround Capture Switch", gpr + 2, 0);
1746 /* Center Playback Volume (renamed later without Digital) */
1747 VOLUME_ADD(icode, &ptr, playback + 4, 6, gpr);
1748 snd_emu10k1_init_mono_control(controls + i++, "Center Digital Playback Volume", gpr++, 100);
1750 /* LFE Playback Volume + Switch (renamed later without Digital) */
1751 VOLUME_ADD(icode, &ptr, playback + 5, 7, gpr);
1752 snd_emu10k1_init_mono_control(controls + i++, "LFE Digital Playback Volume", gpr++, 100);
1754 /* Front Playback Volume */
1755 for (z = 0; z < 2; z++)
1756 VOLUME_ADD(icode, &ptr, playback + z, 10 + z, gpr + z);
1757 snd_emu10k1_init_stereo_control(controls + i++, "Front Playback Volume", gpr, 100);
1760 /* Front Capture Volume + Switch */
1761 for (z = 0; z < 2; z++) {
1762 SWITCH(icode, &ptr, tmp + 0, 10 + z, gpr + 2);
1763 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
1765 snd_emu10k1_init_stereo_control(controls + i++, "Front Capture Volume", gpr, 0);
1766 snd_emu10k1_init_mono_onoff_control(controls + i++, "Front Capture Switch", gpr + 2, 0);
1773 if (emu->fx8010.extin_mask & ((1<<EXTIN_AC97_L)|(1<<EXTIN_AC97_R))) {
1774 /* AC'97 Playback Volume */
1775 VOLUME_ADDIN(icode, &ptr, playback + 0, EXTIN_AC97_L, gpr); gpr++;
1776 VOLUME_ADDIN(icode, &ptr, playback + 1, EXTIN_AC97_R, gpr); gpr++;
1777 snd_emu10k1_init_stereo_control(controls + i++, "AC97 Playback Volume", gpr-2, 0);
1778 /* AC'97 Capture Volume */
1779 VOLUME_ADDIN(icode, &ptr, capture + 0, EXTIN_AC97_L, gpr); gpr++;
1780 VOLUME_ADDIN(icode, &ptr, capture + 1, EXTIN_AC97_R, gpr); gpr++;
1781 snd_emu10k1_init_stereo_control(controls + i++, "AC97 Capture Volume", gpr-2, 100);
1784 if (emu->fx8010.extin_mask & ((1<<EXTIN_SPDIF_CD_L)|(1<<EXTIN_SPDIF_CD_R))) {
1785 /* IEC958 TTL Playback Volume */
1786 for (z = 0; z < 2; z++)
1787 VOLUME_ADDIN(icode, &ptr, playback + z, EXTIN_SPDIF_CD_L + z, gpr + z);
1788 snd_emu10k1_init_stereo_control(controls + i++, SNDRV_CTL_NAME_IEC958("TTL ",PLAYBACK,VOLUME), gpr, 0);
1791 /* IEC958 TTL Capture Volume + Switch */
1792 for (z = 0; z < 2; z++) {
1793 SWITCH_IN(icode, &ptr, tmp + 0, EXTIN_SPDIF_CD_L + z, gpr + 2 + z);
1794 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
1796 snd_emu10k1_init_stereo_control(controls + i++, SNDRV_CTL_NAME_IEC958("TTL ",CAPTURE,VOLUME), gpr, 0);
1797 snd_emu10k1_init_stereo_onoff_control(controls + i++, SNDRV_CTL_NAME_IEC958("TTL ",CAPTURE,SWITCH), gpr + 2, 0);
1801 if (emu->fx8010.extin_mask & ((1<<EXTIN_ZOOM_L)|(1<<EXTIN_ZOOM_R))) {
1802 /* Zoom Video Playback Volume */
1803 for (z = 0; z < 2; z++)
1804 VOLUME_ADDIN(icode, &ptr, playback + z, EXTIN_ZOOM_L + z, gpr + z);
1805 snd_emu10k1_init_stereo_control(controls + i++, "Zoom Video Playback Volume", gpr, 0);
1808 /* Zoom Video Capture Volume + Switch */
1809 for (z = 0; z < 2; z++) {
1810 SWITCH_IN(icode, &ptr, tmp + 0, EXTIN_ZOOM_L + z, gpr + 2 + z);
1811 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
1813 snd_emu10k1_init_stereo_control(controls + i++, "Zoom Video Capture Volume", gpr, 0);
1814 snd_emu10k1_init_stereo_onoff_control(controls + i++, "Zoom Video Capture Switch", gpr + 2, 0);
1818 if (emu->fx8010.extin_mask & ((1<<EXTIN_TOSLINK_L)|(1<<EXTIN_TOSLINK_R))) {
1819 /* IEC958 Optical Playback Volume */
1820 for (z = 0; z < 2; z++)
1821 VOLUME_ADDIN(icode, &ptr, playback + z, EXTIN_TOSLINK_L + z, gpr + z);
1822 snd_emu10k1_init_stereo_control(controls + i++, SNDRV_CTL_NAME_IEC958("LiveDrive ",PLAYBACK,VOLUME), gpr, 0);
1825 /* IEC958 Optical Capture Volume */
1826 for (z = 0; z < 2; z++) {
1827 SWITCH_IN(icode, &ptr, tmp + 0, EXTIN_TOSLINK_L + z, gpr + 2 + z);
1828 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
1830 snd_emu10k1_init_stereo_control(controls + i++, SNDRV_CTL_NAME_IEC958("LiveDrive ",CAPTURE,VOLUME), gpr, 0);
1831 snd_emu10k1_init_stereo_onoff_control(controls + i++, SNDRV_CTL_NAME_IEC958("LiveDrive ",CAPTURE,SWITCH), gpr + 2, 0);
1835 if (emu->fx8010.extin_mask & ((1<<EXTIN_LINE1_L)|(1<<EXTIN_LINE1_R))) {
1836 /* Line LiveDrive Playback Volume */
1837 for (z = 0; z < 2; z++)
1838 VOLUME_ADDIN(icode, &ptr, playback + z, EXTIN_LINE1_L + z, gpr + z);
1839 snd_emu10k1_init_stereo_control(controls + i++, "Line LiveDrive Playback Volume", gpr, 0);
1842 /* Line LiveDrive Capture Volume + Switch */
1843 for (z = 0; z < 2; z++) {
1844 SWITCH_IN(icode, &ptr, tmp + 0, EXTIN_LINE1_L + z, gpr + 2 + z);
1845 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
1847 snd_emu10k1_init_stereo_control(controls + i++, "Line LiveDrive Capture Volume", gpr, 0);
1848 snd_emu10k1_init_stereo_onoff_control(controls + i++, "Line LiveDrive Capture Switch", gpr + 2, 0);
1852 if (emu->fx8010.extin_mask & ((1<<EXTIN_COAX_SPDIF_L)|(1<<EXTIN_COAX_SPDIF_R))) {
1853 /* IEC958 Coax Playback Volume */
1854 for (z = 0; z < 2; z++)
1855 VOLUME_ADDIN(icode, &ptr, playback + z, EXTIN_COAX_SPDIF_L + z, gpr + z);
1856 snd_emu10k1_init_stereo_control(controls + i++, SNDRV_CTL_NAME_IEC958("Coaxial ",PLAYBACK,VOLUME), gpr, 0);
1859 /* IEC958 Coax Capture Volume + Switch */
1860 for (z = 0; z < 2; z++) {
1861 SWITCH_IN(icode, &ptr, tmp + 0, EXTIN_COAX_SPDIF_L + z, gpr + 2 + z);
1862 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
1864 snd_emu10k1_init_stereo_control(controls + i++, SNDRV_CTL_NAME_IEC958("Coaxial ",CAPTURE,VOLUME), gpr, 0);
1865 snd_emu10k1_init_stereo_onoff_control(controls + i++, SNDRV_CTL_NAME_IEC958("Coaxial ",CAPTURE,SWITCH), gpr + 2, 0);
1869 if (emu->fx8010.extin_mask & ((1<<EXTIN_LINE2_L)|(1<<EXTIN_LINE2_R))) {
1870 /* Line LiveDrive Playback Volume */
1871 for (z = 0; z < 2; z++)
1872 VOLUME_ADDIN(icode, &ptr, playback + z, EXTIN_LINE2_L + z, gpr + z);
1873 snd_emu10k1_init_stereo_control(controls + i++, "Line2 LiveDrive Playback Volume", gpr, 0);
1874 controls[i-1].id.index = 1;
1877 /* Line LiveDrive Capture Volume */
1878 for (z = 0; z < 2; z++) {
1879 SWITCH_IN(icode, &ptr, tmp + 0, EXTIN_LINE2_L + z, gpr + 2 + z);
1880 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
1882 snd_emu10k1_init_stereo_control(controls + i++, "Line2 LiveDrive Capture Volume", gpr, 0);
1883 controls[i-1].id.index = 1;
1884 snd_emu10k1_init_stereo_onoff_control(controls + i++, "Line2 LiveDrive Capture Switch", gpr + 2, 0);
1885 controls[i-1].id.index = 1;
1890 * Process tone control
1892 OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 0), GPR(playback + 0), C_00000000, C_00000000); /* left */
1893 OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 1), GPR(playback + 1), C_00000000, C_00000000); /* right */
1894 OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 2), GPR(playback + 2), C_00000000, C_00000000); /* rear left */
1895 OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 3), GPR(playback + 3), C_00000000, C_00000000); /* rear right */
1896 OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 4), GPR(playback + 4), C_00000000, C_00000000); /* center */
1897 OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 5), GPR(playback + 5), C_00000000, C_00000000); /* LFE */
1899 ctl = &controls[i + 0];
1900 ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1901 strcpy(ctl->id.name, "Tone Control - Bass");
1906 ctl->value[0] = ctl->value[1] = 20;
1907 ctl->translation = EMU10K1_GPR_TRANSLATION_BASS;
1908 ctl = &controls[i + 1];
1909 ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1910 strcpy(ctl->id.name, "Tone Control - Treble");
1915 ctl->value[0] = ctl->value[1] = 20;
1916 ctl->translation = EMU10K1_GPR_TRANSLATION_TREBLE;
1918 #define BASS_GPR 0x8c
1919 #define TREBLE_GPR 0x96
1921 for (z = 0; z < 5; z++) {
1923 for (j = 0; j < 2; j++) {
1924 controls[i + 0].gpr[z * 2 + j] = BASS_GPR + z * 2 + j;
1925 controls[i + 1].gpr[z * 2 + j] = TREBLE_GPR + z * 2 + j;
1928 for (z = 0; z < 3; z++) { /* front/rear/center-lfe */
1930 for (j = 0; j < 2; j++) { /* left/right */
1931 k = 0xa0 + (z * 8) + (j * 4);
1932 l = 0xd0 + (z * 8) + (j * 4);
1933 d = playback + SND_EMU10K1_PLAYBACK_CHANNELS + z * 2 + j;
1935 OP(icode, &ptr, iMAC0, C_00000000, C_00000000, GPR(d), GPR(BASS_GPR + 0 + j));
1936 OP(icode, &ptr, iMACMV, GPR(k+1), GPR(k), GPR(k+1), GPR(BASS_GPR + 4 + j));
1937 OP(icode, &ptr, iMACMV, GPR(k), GPR(d), GPR(k), GPR(BASS_GPR + 2 + j));
1938 OP(icode, &ptr, iMACMV, GPR(k+3), GPR(k+2), GPR(k+3), GPR(BASS_GPR + 8 + j));
1939 OP(icode, &ptr, iMAC0, GPR(k+2), GPR_ACCU, GPR(k+2), GPR(BASS_GPR + 6 + j));
1940 OP(icode, &ptr, iACC3, GPR(k+2), GPR(k+2), GPR(k+2), C_00000000);
1942 OP(icode, &ptr, iMAC0, C_00000000, C_00000000, GPR(k+2), GPR(TREBLE_GPR + 0 + j));
1943 OP(icode, &ptr, iMACMV, GPR(l+1), GPR(l), GPR(l+1), GPR(TREBLE_GPR + 4 + j));
1944 OP(icode, &ptr, iMACMV, GPR(l), GPR(k+2), GPR(l), GPR(TREBLE_GPR + 2 + j));
1945 OP(icode, &ptr, iMACMV, GPR(l+3), GPR(l+2), GPR(l+3), GPR(TREBLE_GPR + 8 + j));
1946 OP(icode, &ptr, iMAC0, GPR(l+2), GPR_ACCU, GPR(l+2), GPR(TREBLE_GPR + 6 + j));
1947 OP(icode, &ptr, iMACINT0, GPR(l+2), C_00000000, GPR(l+2), C_00000010);
1949 OP(icode, &ptr, iACC3, GPR(d), GPR(l+2), C_00000000, C_00000000);
1951 if (z == 2) /* center */
1960 for (z = 0; z < 6; z++) {
1961 SWITCH(icode, &ptr, tmp + 0, playback + SND_EMU10K1_PLAYBACK_CHANNELS + z, gpr + 0);
1962 SWITCH_NEG(icode, &ptr, tmp + 1, gpr + 0);
1963 SWITCH(icode, &ptr, tmp + 1, playback + z, tmp + 1);
1964 OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + z), GPR(tmp + 0), GPR(tmp + 1), C_00000000);
1966 snd_emu10k1_init_stereo_onoff_control(controls + i++, "Tone Control - Switch", gpr, 0);
1972 if (emu->fx8010.extout_mask & ((1<<EXTOUT_AC97_L)|(1<<EXTOUT_AC97_R))) {
1973 /* AC'97 Playback Volume */
1975 for (z = 0; z < 2; z++)
1976 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_AC97_L + z), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + z), C_00000000, C_00000000);
1979 if (emu->fx8010.extout_mask & ((1<<EXTOUT_TOSLINK_L)|(1<<EXTOUT_TOSLINK_R))) {
1980 /* IEC958 Optical Raw Playback Switch */
1982 for (z = 0; z < 2; z++) {
1983 SWITCH(icode, &ptr, tmp + 0, 8 + z, gpr + z);
1984 SWITCH_NEG(icode, &ptr, tmp + 1, gpr + z);
1985 SWITCH(icode, &ptr, tmp + 1, playback + SND_EMU10K1_PLAYBACK_CHANNELS + z, tmp + 1);
1986 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_TOSLINK_L + z), GPR(tmp + 0), GPR(tmp + 1), C_00000000);
1987 #ifdef EMU10K1_CAPTURE_DIGITAL_OUT
1988 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_ADC_CAP_L + z), GPR(tmp + 0), GPR(tmp + 1), C_00000000);
1992 snd_emu10k1_init_stereo_onoff_control(controls + i++, SNDRV_CTL_NAME_IEC958("Optical Raw ",PLAYBACK,SWITCH), gpr, 0);
1996 if (emu->fx8010.extout_mask & ((1<<EXTOUT_HEADPHONE_L)|(1<<EXTOUT_HEADPHONE_R))) {
1997 /* Headphone Playback Volume */
1999 for (z = 0; z < 2; z++) {
2000 SWITCH(icode, &ptr, tmp + 0, playback + SND_EMU10K1_PLAYBACK_CHANNELS + 4 + z, gpr + 2 + z);
2001 SWITCH_NEG(icode, &ptr, tmp + 1, gpr + 2 + z);
2002 SWITCH(icode, &ptr, tmp + 1, playback + SND_EMU10K1_PLAYBACK_CHANNELS + z, tmp + 1);
2003 OP(icode, &ptr, iACC3, GPR(tmp + 0), GPR(tmp + 0), GPR(tmp + 1), C_00000000);
2004 VOLUME_OUT(icode, &ptr, EXTOUT_HEADPHONE_L + z, tmp + 0, gpr + z);
2007 snd_emu10k1_init_stereo_control(controls + i++, "Headphone Playback Volume", gpr + 0, 0);
2008 controls[i-1].id.index = 1; /* AC'97 can have also Headphone control */
2009 snd_emu10k1_init_mono_onoff_control(controls + i++, "Headphone Center Playback Switch", gpr + 2, 0);
2010 controls[i-1].id.index = 1;
2011 snd_emu10k1_init_mono_onoff_control(controls + i++, "Headphone LFE Playback Switch", gpr + 3, 0);
2012 controls[i-1].id.index = 1;
2017 if (emu->fx8010.extout_mask & ((1<<EXTOUT_REAR_L)|(1<<EXTOUT_REAR_R)))
2018 for (z = 0; z < 2; z++)
2019 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_REAR_L + z), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 2 + z), C_00000000, C_00000000);
2021 if (emu->fx8010.extout_mask & ((1<<EXTOUT_AC97_REAR_L)|(1<<EXTOUT_AC97_REAR_R)))
2022 for (z = 0; z < 2; z++)
2023 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_AC97_REAR_L + z), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 2 + z), C_00000000, C_00000000);
2025 if (emu->fx8010.extout_mask & (1<<EXTOUT_AC97_CENTER)) {
2026 #ifndef EMU10K1_CENTER_LFE_FROM_FRONT
2027 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_AC97_CENTER), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 4), C_00000000, C_00000000);
2028 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_ACENTER), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 4), C_00000000, C_00000000);
2030 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_AC97_CENTER), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 0), C_00000000, C_00000000);
2031 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_ACENTER), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 0), C_00000000, C_00000000);
2035 if (emu->fx8010.extout_mask & (1<<EXTOUT_AC97_LFE)) {
2036 #ifndef EMU10K1_CENTER_LFE_FROM_FRONT
2037 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_AC97_LFE), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 5), C_00000000, C_00000000);
2038 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_ALFE), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 5), C_00000000, C_00000000);
2040 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_AC97_LFE), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 1), C_00000000, C_00000000);
2041 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_ALFE), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 1), C_00000000, C_00000000);
2045 #ifndef EMU10K1_CAPTURE_DIGITAL_OUT
2046 for (z = 0; z < 2; z++)
2047 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_ADC_CAP_L + z), GPR(capture + z), C_00000000, C_00000000);
2050 if (emu->fx8010.extout_mask & (1<<EXTOUT_MIC_CAP))
2051 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_MIC_CAP), GPR(capture + 2), C_00000000, C_00000000);
2053 /* EFX capture - capture the 16 EXTINS */
2054 if (emu->card_capabilities->sblive51) {
2055 /* On the Live! 5.1, FXBUS2(1) and FXBUS(2) are shared with EXTOUT_ACENTER
2056 * and EXTOUT_ALFE, so we can't connect inputs to them for multitrack recording.
2058 * Since only 14 of the 16 EXTINs are used, this is not a big problem.
2059 * We route AC97L and R to FX capture 14 and 15, SPDIF CD in to FX capture
2060 * 0 and 3, then the rest of the EXTINs to the corresponding FX capture
2061 * channel. Multitrack recorders will still see the center/lfe output signal
2062 * on the second and third channels.
2064 OP(icode, &ptr, iACC3, FXBUS2(14), C_00000000, C_00000000, EXTIN(0));
2065 OP(icode, &ptr, iACC3, FXBUS2(15), C_00000000, C_00000000, EXTIN(1));
2066 OP(icode, &ptr, iACC3, FXBUS2(0), C_00000000, C_00000000, EXTIN(2));
2067 OP(icode, &ptr, iACC3, FXBUS2(3), C_00000000, C_00000000, EXTIN(3));
2068 for (z = 4; z < 14; z++)
2069 OP(icode, &ptr, iACC3, FXBUS2(z), C_00000000, C_00000000, EXTIN(z));
2071 for (z = 0; z < 16; z++)
2072 OP(icode, &ptr, iACC3, FXBUS2(z), C_00000000, C_00000000, EXTIN(z));
2081 if (i > SND_EMU10K1_GPR_CONTROLS) {
2087 /* clear remaining instruction memory */
2089 OP(icode, &ptr, iACC3, C_00000000, C_00000000, C_00000000, C_00000000);
2091 if ((err = snd_emu10k1_fx8010_tram_setup(emu, ipcm->buffer_size)) < 0)
2093 seg = snd_enter_user();
2094 icode->gpr_add_control_count = i;
2095 icode->gpr_add_controls = (struct snd_emu10k1_fx8010_control_gpr __user *)controls;
2096 err = snd_emu10k1_icode_poke(emu, icode);
2097 snd_leave_user(seg);
2099 err = snd_emu10k1_ipcm_poke(emu, ipcm);
2103 if (icode != NULL) {
2104 kfree((void __force *)icode->gpr_map);
2110 int __devinit snd_emu10k1_init_efx(struct snd_emu10k1 *emu)
2112 spin_lock_init(&emu->fx8010.irq_lock);
2113 INIT_LIST_HEAD(&emu->fx8010.gpr_ctl);
2115 return _snd_emu10k1_audigy_init_efx(emu);
2117 return _snd_emu10k1_init_efx(emu);
2120 void snd_emu10k1_free_efx(struct snd_emu10k1 *emu)
2122 /* stop processor */
2124 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg = A_DBG_SINGLE_STEP);
2126 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg = EMU10K1_DBG_SINGLE_STEP);
2129 #if 0 // FIXME: who use them?
2130 int snd_emu10k1_fx8010_tone_control_activate(struct snd_emu10k1 *emu, int output)
2132 if (output < 0 || output >= 6)
2134 snd_emu10k1_ptr_write(emu, emu->gpr_base + 0x94 + output, 0, 1);
2138 int snd_emu10k1_fx8010_tone_control_deactivate(struct snd_emu10k1 *emu, int output)
2140 if (output < 0 || output >= 6)
2142 snd_emu10k1_ptr_write(emu, emu->gpr_base + 0x94 + output, 0, 0);
2147 int snd_emu10k1_fx8010_tram_setup(struct snd_emu10k1 *emu, u32 size)
2151 /* size is in samples */
2153 size = (size - 1) >> 13;
2159 size = 0x2000 << size_reg;
2161 if ((emu->fx8010.etram_pages.bytes / 2) == size)
2163 spin_lock_irq(&emu->emu_lock);
2164 outl(HCFG_LOCKTANKCACHE_MASK | inl(emu->port + HCFG), emu->port + HCFG);
2165 spin_unlock_irq(&emu->emu_lock);
2166 snd_emu10k1_ptr_write(emu, TCB, 0, 0);
2167 snd_emu10k1_ptr_write(emu, TCBS, 0, 0);
2168 if (emu->fx8010.etram_pages.area != NULL) {
2169 snd_dma_free_pages(&emu->fx8010.etram_pages);
2170 emu->fx8010.etram_pages.area = NULL;
2171 emu->fx8010.etram_pages.bytes = 0;
2175 if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(emu->pci),
2176 size * 2, &emu->fx8010.etram_pages) < 0)
2178 memset(emu->fx8010.etram_pages.area, 0, size * 2);
2179 snd_emu10k1_ptr_write(emu, TCB, 0, emu->fx8010.etram_pages.addr);
2180 snd_emu10k1_ptr_write(emu, TCBS, 0, size_reg);
2181 spin_lock_irq(&emu->emu_lock);
2182 outl(inl(emu->port + HCFG) & ~HCFG_LOCKTANKCACHE_MASK, emu->port + HCFG);
2183 spin_unlock_irq(&emu->emu_lock);
2189 static int snd_emu10k1_fx8010_open(struct snd_hwdep * hw, struct file *file)
2194 static void copy_string(char *dst, char *src, char *null, int idx)
2197 sprintf(dst, "%s %02X", null, idx);
2202 static int snd_emu10k1_fx8010_info(struct snd_emu10k1 *emu,
2203 struct snd_emu10k1_fx8010_info *info)
2205 char **fxbus, **extin, **extout;
2206 unsigned short fxbus_mask, extin_mask, extout_mask;
2209 memset(info, 0, sizeof(info));
2210 info->internal_tram_size = emu->fx8010.itram_size;
2211 info->external_tram_size = emu->fx8010.etram_pages.bytes / 2;
2213 extin = emu->audigy ? audigy_ins : creative_ins;
2214 extout = emu->audigy ? audigy_outs : creative_outs;
2215 fxbus_mask = emu->fx8010.fxbus_mask;
2216 extin_mask = emu->fx8010.extin_mask;
2217 extout_mask = emu->fx8010.extout_mask;
2218 for (res = 0; res < 16; res++, fxbus++, extin++, extout++) {
2219 copy_string(info->fxbus_names[res], fxbus_mask & (1 << res) ? *fxbus : NULL, "FXBUS", res);
2220 copy_string(info->extin_names[res], extin_mask & (1 << res) ? *extin : NULL, "Unused", res);
2221 copy_string(info->extout_names[res], extout_mask & (1 << res) ? *extout : NULL, "Unused", res);
2223 for (res = 16; res < 32; res++, extout++)
2224 copy_string(info->extout_names[res], extout_mask & (1 << res) ? *extout : NULL, "Unused", res);
2225 info->gpr_controls = emu->fx8010.gpr_count;
2229 static int snd_emu10k1_fx8010_ioctl(struct snd_hwdep * hw, struct file *file, unsigned int cmd, unsigned long arg)
2231 struct snd_emu10k1 *emu = hw->private_data;
2232 struct snd_emu10k1_fx8010_info *info;
2233 struct snd_emu10k1_fx8010_code *icode;
2234 struct snd_emu10k1_fx8010_pcm_rec *ipcm;
2236 void __user *argp = (void __user *)arg;
2240 case SNDRV_EMU10K1_IOCTL_INFO:
2241 info = kmalloc(sizeof(*info), GFP_KERNEL);
2244 if ((res = snd_emu10k1_fx8010_info(emu, info)) < 0) {
2248 if (copy_to_user(argp, info, sizeof(*info))) {
2254 case SNDRV_EMU10K1_IOCTL_CODE_POKE:
2255 if (!capable(CAP_SYS_ADMIN))
2257 icode = kmalloc(sizeof(*icode), GFP_KERNEL);
2260 if (copy_from_user(icode, argp, sizeof(*icode))) {
2264 res = snd_emu10k1_icode_poke(emu, icode);
2267 case SNDRV_EMU10K1_IOCTL_CODE_PEEK:
2268 icode = kmalloc(sizeof(*icode), GFP_KERNEL);
2271 if (copy_from_user(icode, argp, sizeof(*icode))) {
2275 res = snd_emu10k1_icode_peek(emu, icode);
2276 if (res == 0 && copy_to_user(argp, icode, sizeof(*icode))) {
2282 case SNDRV_EMU10K1_IOCTL_PCM_POKE:
2283 ipcm = kmalloc(sizeof(*ipcm), GFP_KERNEL);
2286 if (copy_from_user(ipcm, argp, sizeof(*ipcm))) {
2290 res = snd_emu10k1_ipcm_poke(emu, ipcm);
2293 case SNDRV_EMU10K1_IOCTL_PCM_PEEK:
2294 ipcm = kzalloc(sizeof(*ipcm), GFP_KERNEL);
2297 if (copy_from_user(ipcm, argp, sizeof(*ipcm))) {
2301 res = snd_emu10k1_ipcm_peek(emu, ipcm);
2302 if (res == 0 && copy_to_user(argp, ipcm, sizeof(*ipcm))) {
2308 case SNDRV_EMU10K1_IOCTL_TRAM_SETUP:
2309 if (!capable(CAP_SYS_ADMIN))
2311 if (get_user(addr, (unsigned int __user *)argp))
2313 mutex_lock(&emu->fx8010.lock);
2314 res = snd_emu10k1_fx8010_tram_setup(emu, addr);
2315 mutex_unlock(&emu->fx8010.lock);
2317 case SNDRV_EMU10K1_IOCTL_STOP:
2318 if (!capable(CAP_SYS_ADMIN))
2321 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg |= A_DBG_SINGLE_STEP);
2323 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg |= EMU10K1_DBG_SINGLE_STEP);
2325 case SNDRV_EMU10K1_IOCTL_CONTINUE:
2326 if (!capable(CAP_SYS_ADMIN))
2329 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg = 0);
2331 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg = 0);
2333 case SNDRV_EMU10K1_IOCTL_ZERO_TRAM_COUNTER:
2334 if (!capable(CAP_SYS_ADMIN))
2337 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg | A_DBG_ZC);
2339 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg | EMU10K1_DBG_ZC);
2342 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg);
2344 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg);
2346 case SNDRV_EMU10K1_IOCTL_SINGLE_STEP:
2347 if (!capable(CAP_SYS_ADMIN))
2349 if (get_user(addr, (unsigned int __user *)argp))
2354 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg |= A_DBG_SINGLE_STEP | addr);
2356 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg |= EMU10K1_DBG_SINGLE_STEP | addr);
2359 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg |= A_DBG_SINGLE_STEP | A_DBG_STEP_ADDR | addr);
2361 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg |= EMU10K1_DBG_SINGLE_STEP | EMU10K1_DBG_STEP | addr);
2363 case SNDRV_EMU10K1_IOCTL_DBG_READ:
2365 addr = snd_emu10k1_ptr_read(emu, A_DBG, 0);
2367 addr = snd_emu10k1_ptr_read(emu, DBG, 0);
2368 if (put_user(addr, (unsigned int __user *)argp))
2375 static int snd_emu10k1_fx8010_release(struct snd_hwdep * hw, struct file *file)
2380 int __devinit snd_emu10k1_fx8010_new(struct snd_emu10k1 *emu, int device, struct snd_hwdep ** rhwdep)
2382 struct snd_hwdep *hw;
2387 if ((err = snd_hwdep_new(emu->card, "FX8010", device, &hw)) < 0)
2389 strcpy(hw->name, "EMU10K1 (FX8010)");
2390 hw->iface = SNDRV_HWDEP_IFACE_EMU10K1;
2391 hw->ops.open = snd_emu10k1_fx8010_open;
2392 hw->ops.ioctl = snd_emu10k1_fx8010_ioctl;
2393 hw->ops.release = snd_emu10k1_fx8010_release;
2394 hw->private_data = emu;
2401 int __devinit snd_emu10k1_efx_alloc_pm_buffer(struct snd_emu10k1 *emu)
2405 len = emu->audigy ? 0x200 : 0x100;
2406 emu->saved_gpr = kmalloc(len * 4, GFP_KERNEL);
2407 if (! emu->saved_gpr)
2409 len = emu->audigy ? 0x100 : 0xa0;
2410 emu->tram_val_saved = kmalloc(len * 4, GFP_KERNEL);
2411 emu->tram_addr_saved = kmalloc(len * 4, GFP_KERNEL);
2412 if (! emu->tram_val_saved || ! emu->tram_addr_saved)
2414 len = emu->audigy ? 2 * 1024 : 2 * 512;
2415 emu->saved_icode = vmalloc(len * 4);
2416 if (! emu->saved_icode)
2421 void snd_emu10k1_efx_free_pm_buffer(struct snd_emu10k1 *emu)
2423 kfree(emu->saved_gpr);
2424 kfree(emu->tram_val_saved);
2425 kfree(emu->tram_addr_saved);
2426 vfree(emu->saved_icode);
2430 * save/restore GPR, TRAM and codes
2432 void snd_emu10k1_efx_suspend(struct snd_emu10k1 *emu)
2436 len = emu->audigy ? 0x200 : 0x100;
2437 for (i = 0; i < len; i++)
2438 emu->saved_gpr[i] = snd_emu10k1_ptr_read(emu, emu->gpr_base + i, 0);
2440 len = emu->audigy ? 0x100 : 0xa0;
2441 for (i = 0; i < len; i++) {
2442 emu->tram_val_saved[i] = snd_emu10k1_ptr_read(emu, TANKMEMDATAREGBASE + i, 0);
2443 emu->tram_addr_saved[i] = snd_emu10k1_ptr_read(emu, TANKMEMADDRREGBASE + i, 0);
2445 emu->tram_addr_saved[i] >>= 12;
2446 emu->tram_addr_saved[i] |=
2447 snd_emu10k1_ptr_read(emu, A_TANKMEMCTLREGBASE + i, 0) << 20;
2451 len = emu->audigy ? 2 * 1024 : 2 * 512;
2452 for (i = 0; i < len; i++)
2453 emu->saved_icode[i] = snd_emu10k1_efx_read(emu, i);
2456 void snd_emu10k1_efx_resume(struct snd_emu10k1 *emu)
2461 if (emu->fx8010.etram_pages.bytes > 0) {
2462 unsigned size, size_reg = 0;
2463 size = emu->fx8010.etram_pages.bytes / 2;
2464 size = (size - 1) >> 13;
2469 outl(HCFG_LOCKTANKCACHE_MASK | inl(emu->port + HCFG), emu->port + HCFG);
2470 snd_emu10k1_ptr_write(emu, TCB, 0, emu->fx8010.etram_pages.addr);
2471 snd_emu10k1_ptr_write(emu, TCBS, 0, size_reg);
2472 outl(inl(emu->port + HCFG) & ~HCFG_LOCKTANKCACHE_MASK, emu->port + HCFG);
2476 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg | A_DBG_SINGLE_STEP);
2478 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg | EMU10K1_DBG_SINGLE_STEP);
2480 len = emu->audigy ? 0x200 : 0x100;
2481 for (i = 0; i < len; i++)
2482 snd_emu10k1_ptr_write(emu, emu->gpr_base + i, 0, emu->saved_gpr[i]);
2484 len = emu->audigy ? 0x100 : 0xa0;
2485 for (i = 0; i < len; i++) {
2486 snd_emu10k1_ptr_write(emu, TANKMEMDATAREGBASE + i, 0,
2487 emu->tram_val_saved[i]);
2489 snd_emu10k1_ptr_write(emu, TANKMEMADDRREGBASE + i, 0,
2490 emu->tram_addr_saved[i]);
2492 snd_emu10k1_ptr_write(emu, TANKMEMADDRREGBASE + i, 0,
2493 emu->tram_addr_saved[i] << 12);
2494 snd_emu10k1_ptr_write(emu, TANKMEMADDRREGBASE + i, 0,
2495 emu->tram_addr_saved[i] >> 20);
2499 len = emu->audigy ? 2 * 1024 : 2 * 512;
2500 for (i = 0; i < len; i++)
2501 snd_emu10k1_efx_write(emu, i, emu->saved_icode[i]);
2503 /* start FX processor when the DSP code is updated */
2505 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg);
2507 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg);