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 if ((icode = kzalloc(sizeof(*icode), GFP_KERNEL)) == NULL ||
1075 (icode->gpr_map = (u_int32_t __user *)
1076 kcalloc(512 + 256 + 256 + 2 * 1024, sizeof(u_int32_t),
1077 GFP_KERNEL)) == NULL ||
1078 (controls = kcalloc(SND_EMU10K1_GPR_CONTROLS,
1079 sizeof(*controls), GFP_KERNEL)) == NULL) {
1083 gpr_map = (u32 __force *)icode->gpr_map;
1085 icode->tram_data_map = icode->gpr_map + 512;
1086 icode->tram_addr_map = icode->tram_data_map + 256;
1087 icode->code = icode->tram_addr_map + 256;
1089 /* clear free GPRs */
1090 for (i = 0; i < 512; i++)
1091 set_bit(i, icode->gpr_valid);
1093 /* clear TRAM data & address lines */
1094 for (i = 0; i < 256; i++)
1095 set_bit(i, icode->tram_valid);
1097 strcpy(icode->name, "Audigy DSP code for ALSA");
1100 gpr = stereo_mix + 10;
1102 /* stop FX processor */
1103 snd_emu10k1_ptr_write(emu, A_DBG, 0, (emu->fx8010.dbg = 0) | A_DBG_SINGLE_STEP);
1107 for (z = 0; z < 80; z=z+2) {
1108 A_OP(icode, &ptr, iACC3, A_EXTOUT(z), A_FXBUS(FXBUS_PCM_LEFT_FRONT), A_C_00000000, A_C_00000000); /* left */
1109 A_OP(icode, &ptr, iACC3, A_EXTOUT(z+1), A_FXBUS(FXBUS_PCM_RIGHT_FRONT), A_C_00000000, A_C_00000000); /* right */
1111 #endif /* jcd test */
1113 /* PCM front Playback Volume (independent from stereo mix) */
1114 A_OP(icode, &ptr, iMAC0, A_GPR(playback), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LEFT_FRONT));
1115 A_OP(icode, &ptr, iMAC0, A_GPR(playback+1), A_C_00000000, A_GPR(gpr+1), A_FXBUS(FXBUS_PCM_RIGHT_FRONT));
1116 snd_emu10k1_init_stereo_control(&controls[nctl++], "PCM Front Playback Volume", gpr, 100);
1119 /* PCM Surround Playback (independent from stereo mix) */
1120 A_OP(icode, &ptr, iMAC0, A_GPR(playback+2), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LEFT_REAR));
1121 A_OP(icode, &ptr, iMAC0, A_GPR(playback+3), A_C_00000000, A_GPR(gpr+1), A_FXBUS(FXBUS_PCM_RIGHT_REAR));
1122 snd_emu10k1_init_stereo_control(&controls[nctl++], "PCM Surround Playback Volume", gpr, 100);
1125 /* PCM Side Playback (independent from stereo mix) */
1126 if (emu->card_capabilities->spk71) {
1127 A_OP(icode, &ptr, iMAC0, A_GPR(playback+6), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LEFT_SIDE));
1128 A_OP(icode, &ptr, iMAC0, A_GPR(playback+7), A_C_00000000, A_GPR(gpr+1), A_FXBUS(FXBUS_PCM_RIGHT_SIDE));
1129 snd_emu10k1_init_stereo_control(&controls[nctl++], "PCM Side Playback Volume", gpr, 100);
1133 /* PCM Center Playback (independent from stereo mix) */
1134 A_OP(icode, &ptr, iMAC0, A_GPR(playback+4), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_CENTER));
1135 snd_emu10k1_init_mono_control(&controls[nctl++], "PCM Center Playback Volume", gpr, 100);
1138 /* PCM LFE Playback (independent from stereo mix) */
1139 A_OP(icode, &ptr, iMAC0, A_GPR(playback+5), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LFE));
1140 snd_emu10k1_init_mono_control(&controls[nctl++], "PCM LFE Playback Volume", gpr, 100);
1146 /* Wave (PCM) Playback Volume (will be renamed later) */
1147 A_OP(icode, &ptr, iMAC0, A_GPR(stereo_mix), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LEFT));
1148 A_OP(icode, &ptr, iMAC0, A_GPR(stereo_mix+1), A_C_00000000, A_GPR(gpr+1), A_FXBUS(FXBUS_PCM_RIGHT));
1149 snd_emu10k1_init_stereo_control(&controls[nctl++], "Wave Playback Volume", gpr, 100);
1152 /* Synth Playback */
1153 A_OP(icode, &ptr, iMAC0, A_GPR(stereo_mix+0), A_GPR(stereo_mix+0), A_GPR(gpr), A_FXBUS(FXBUS_MIDI_LEFT));
1154 A_OP(icode, &ptr, iMAC0, A_GPR(stereo_mix+1), A_GPR(stereo_mix+1), A_GPR(gpr+1), A_FXBUS(FXBUS_MIDI_RIGHT));
1155 snd_emu10k1_init_stereo_control(&controls[nctl++], "Synth Playback Volume", gpr, 100);
1158 /* Wave (PCM) Capture */
1159 A_OP(icode, &ptr, iMAC0, A_GPR(capture+0), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LEFT));
1160 A_OP(icode, &ptr, iMAC0, A_GPR(capture+1), A_C_00000000, A_GPR(gpr+1), A_FXBUS(FXBUS_PCM_RIGHT));
1161 snd_emu10k1_init_stereo_control(&controls[nctl++], "PCM Capture Volume", gpr, 0);
1165 A_OP(icode, &ptr, iMAC0, A_GPR(capture+0), A_GPR(capture+0), A_GPR(gpr), A_FXBUS(FXBUS_MIDI_LEFT));
1166 A_OP(icode, &ptr, iMAC0, A_GPR(capture+1), A_GPR(capture+1), A_GPR(gpr+1), A_FXBUS(FXBUS_MIDI_RIGHT));
1167 snd_emu10k1_init_stereo_control(&controls[nctl++], "Synth Capture Volume", gpr, 0);
1173 #define A_ADD_VOLUME_IN(var,vol,input) \
1174 A_OP(icode, &ptr, iMAC0, A_GPR(var), A_GPR(var), A_GPR(vol), A_EXTIN(input))
1176 /* AC'97 Playback Volume - used only for mic (renamed later) */
1177 A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_AC97_L);
1178 A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_AC97_R);
1179 snd_emu10k1_init_stereo_control(&controls[nctl++], "AMic Playback Volume", gpr, 0);
1181 /* AC'97 Capture Volume - used only for mic */
1182 A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_AC97_L);
1183 A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_AC97_R);
1184 snd_emu10k1_init_stereo_control(&controls[nctl++], "Mic Capture Volume", gpr, 0);
1187 /* mic capture buffer */
1188 A_OP(icode, &ptr, iINTERP, A_EXTOUT(A_EXTOUT_MIC_CAP), A_EXTIN(A_EXTIN_AC97_L), 0xcd, A_EXTIN(A_EXTIN_AC97_R));
1190 /* Audigy CD Playback Volume */
1191 A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_SPDIF_CD_L);
1192 A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_SPDIF_CD_R);
1193 snd_emu10k1_init_stereo_control(&controls[nctl++],
1194 emu->card_capabilities->ac97_chip ? "Audigy CD Playback Volume" : "CD Playback Volume",
1197 /* Audigy CD Capture Volume */
1198 A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_SPDIF_CD_L);
1199 A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_SPDIF_CD_R);
1200 snd_emu10k1_init_stereo_control(&controls[nctl++],
1201 emu->card_capabilities->ac97_chip ? "Audigy CD Capture Volume" : "CD Capture Volume",
1205 /* Optical SPDIF Playback Volume */
1206 A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_OPT_SPDIF_L);
1207 A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_OPT_SPDIF_R);
1208 snd_emu10k1_init_stereo_control(&controls[nctl++], SNDRV_CTL_NAME_IEC958("Optical ",PLAYBACK,VOLUME), gpr, 0);
1210 /* Optical SPDIF Capture Volume */
1211 A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_OPT_SPDIF_L);
1212 A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_OPT_SPDIF_R);
1213 snd_emu10k1_init_stereo_control(&controls[nctl++], SNDRV_CTL_NAME_IEC958("Optical ",CAPTURE,VOLUME), gpr, 0);
1216 /* Line2 Playback Volume */
1217 A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_LINE2_L);
1218 A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_LINE2_R);
1219 snd_emu10k1_init_stereo_control(&controls[nctl++],
1220 emu->card_capabilities->ac97_chip ? "Line2 Playback Volume" : "Line Playback Volume",
1223 /* Line2 Capture Volume */
1224 A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_LINE2_L);
1225 A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_LINE2_R);
1226 snd_emu10k1_init_stereo_control(&controls[nctl++],
1227 emu->card_capabilities->ac97_chip ? "Line2 Capture Volume" : "Line Capture Volume",
1231 /* Philips ADC Playback Volume */
1232 A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_ADC_L);
1233 A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_ADC_R);
1234 snd_emu10k1_init_stereo_control(&controls[nctl++], "Analog Mix Playback Volume", gpr, 0);
1236 /* Philips ADC Capture Volume */
1237 A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_ADC_L);
1238 A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_ADC_R);
1239 snd_emu10k1_init_stereo_control(&controls[nctl++], "Analog Mix Capture Volume", gpr, 0);
1242 /* Aux2 Playback Volume */
1243 A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_AUX2_L);
1244 A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_AUX2_R);
1245 snd_emu10k1_init_stereo_control(&controls[nctl++],
1246 emu->card_capabilities->ac97_chip ? "Aux2 Playback Volume" : "Aux Playback Volume",
1249 /* Aux2 Capture Volume */
1250 A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_AUX2_L);
1251 A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_AUX2_R);
1252 snd_emu10k1_init_stereo_control(&controls[nctl++],
1253 emu->card_capabilities->ac97_chip ? "Aux2 Capture Volume" : "Aux Capture Volume",
1257 /* Stereo Mix Front Playback Volume */
1258 A_OP(icode, &ptr, iMAC0, A_GPR(playback), A_GPR(playback), A_GPR(gpr), A_GPR(stereo_mix));
1259 A_OP(icode, &ptr, iMAC0, A_GPR(playback+1), A_GPR(playback+1), A_GPR(gpr+1), A_GPR(stereo_mix+1));
1260 snd_emu10k1_init_stereo_control(&controls[nctl++], "Front Playback Volume", gpr, 100);
1263 /* Stereo Mix Surround Playback */
1264 A_OP(icode, &ptr, iMAC0, A_GPR(playback+2), A_GPR(playback+2), A_GPR(gpr), A_GPR(stereo_mix));
1265 A_OP(icode, &ptr, iMAC0, A_GPR(playback+3), A_GPR(playback+3), A_GPR(gpr+1), A_GPR(stereo_mix+1));
1266 snd_emu10k1_init_stereo_control(&controls[nctl++], "Surround Playback Volume", gpr, 0);
1269 /* Stereo Mix Center Playback */
1270 /* Center = sub = Left/2 + Right/2 */
1271 A_OP(icode, &ptr, iINTERP, A_GPR(tmp), A_GPR(stereo_mix), 0xcd, A_GPR(stereo_mix+1));
1272 A_OP(icode, &ptr, iMAC0, A_GPR(playback+4), A_GPR(playback+4), A_GPR(gpr), A_GPR(tmp));
1273 snd_emu10k1_init_mono_control(&controls[nctl++], "Center Playback Volume", gpr, 0);
1276 /* Stereo Mix LFE Playback */
1277 A_OP(icode, &ptr, iMAC0, A_GPR(playback+5), A_GPR(playback+5), A_GPR(gpr), A_GPR(tmp));
1278 snd_emu10k1_init_mono_control(&controls[nctl++], "LFE Playback Volume", gpr, 0);
1281 if (emu->card_capabilities->spk71) {
1282 /* Stereo Mix Side Playback */
1283 A_OP(icode, &ptr, iMAC0, A_GPR(playback+6), A_GPR(playback+6), A_GPR(gpr), A_GPR(stereo_mix));
1284 A_OP(icode, &ptr, iMAC0, A_GPR(playback+7), A_GPR(playback+7), A_GPR(gpr+1), A_GPR(stereo_mix+1));
1285 snd_emu10k1_init_stereo_control(&controls[nctl++], "Side Playback Volume", gpr, 0);
1292 #define A_PUT_OUTPUT(out,src) A_OP(icode, &ptr, iACC3, A_EXTOUT(out), A_C_00000000, A_C_00000000, A_GPR(src))
1293 #define A_PUT_STEREO_OUTPUT(out1,out2,src) \
1294 {A_PUT_OUTPUT(out1,src); A_PUT_OUTPUT(out2,src+1);}
1296 #define _A_SWITCH(icode, ptr, dst, src, sw) \
1297 A_OP((icode), ptr, iMACINT0, dst, A_C_00000000, src, sw);
1298 #define A_SWITCH(icode, ptr, dst, src, sw) \
1299 _A_SWITCH(icode, ptr, A_GPR(dst), A_GPR(src), A_GPR(sw))
1300 #define _A_SWITCH_NEG(icode, ptr, dst, src) \
1301 A_OP((icode), ptr, iANDXOR, dst, src, A_C_00000001, A_C_00000001);
1302 #define A_SWITCH_NEG(icode, ptr, dst, src) \
1303 _A_SWITCH_NEG(icode, ptr, A_GPR(dst), A_GPR(src))
1307 * Process tone control
1309 A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 0), A_GPR(playback + 0), A_C_00000000, A_C_00000000); /* left */
1310 A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 1), A_GPR(playback + 1), A_C_00000000, A_C_00000000); /* right */
1311 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 */
1312 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 */
1313 A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 4), A_GPR(playback + 4), A_C_00000000, A_C_00000000); /* center */
1314 A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 5), A_GPR(playback + 5), A_C_00000000, A_C_00000000); /* LFE */
1315 if (emu->card_capabilities->spk71) {
1316 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 */
1317 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 */
1321 ctl = &controls[nctl + 0];
1322 ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1323 strcpy(ctl->id.name, "Tone Control - Bass");
1328 ctl->value[0] = ctl->value[1] = 20;
1329 ctl->translation = EMU10K1_GPR_TRANSLATION_BASS;
1330 ctl = &controls[nctl + 1];
1331 ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1332 strcpy(ctl->id.name, "Tone Control - Treble");
1337 ctl->value[0] = ctl->value[1] = 20;
1338 ctl->translation = EMU10K1_GPR_TRANSLATION_TREBLE;
1340 #define BASS_GPR 0x8c
1341 #define TREBLE_GPR 0x96
1343 for (z = 0; z < 5; z++) {
1345 for (j = 0; j < 2; j++) {
1346 controls[nctl + 0].gpr[z * 2 + j] = BASS_GPR + z * 2 + j;
1347 controls[nctl + 1].gpr[z * 2 + j] = TREBLE_GPR + z * 2 + j;
1350 for (z = 0; z < 4; z++) { /* front/rear/center-lfe/side */
1352 for (j = 0; j < 2; j++) { /* left/right */
1353 k = 0xb0 + (z * 8) + (j * 4);
1354 l = 0xe0 + (z * 8) + (j * 4);
1355 d = playback + SND_EMU10K1_PLAYBACK_CHANNELS + z * 2 + j;
1357 A_OP(icode, &ptr, iMAC0, A_C_00000000, A_C_00000000, A_GPR(d), A_GPR(BASS_GPR + 0 + j));
1358 A_OP(icode, &ptr, iMACMV, A_GPR(k+1), A_GPR(k), A_GPR(k+1), A_GPR(BASS_GPR + 4 + j));
1359 A_OP(icode, &ptr, iMACMV, A_GPR(k), A_GPR(d), A_GPR(k), A_GPR(BASS_GPR + 2 + j));
1360 A_OP(icode, &ptr, iMACMV, A_GPR(k+3), A_GPR(k+2), A_GPR(k+3), A_GPR(BASS_GPR + 8 + j));
1361 A_OP(icode, &ptr, iMAC0, A_GPR(k+2), A_GPR_ACCU, A_GPR(k+2), A_GPR(BASS_GPR + 6 + j));
1362 A_OP(icode, &ptr, iACC3, A_GPR(k+2), A_GPR(k+2), A_GPR(k+2), A_C_00000000);
1364 A_OP(icode, &ptr, iMAC0, A_C_00000000, A_C_00000000, A_GPR(k+2), A_GPR(TREBLE_GPR + 0 + j));
1365 A_OP(icode, &ptr, iMACMV, A_GPR(l+1), A_GPR(l), A_GPR(l+1), A_GPR(TREBLE_GPR + 4 + j));
1366 A_OP(icode, &ptr, iMACMV, A_GPR(l), A_GPR(k+2), A_GPR(l), A_GPR(TREBLE_GPR + 2 + j));
1367 A_OP(icode, &ptr, iMACMV, A_GPR(l+3), A_GPR(l+2), A_GPR(l+3), A_GPR(TREBLE_GPR + 8 + j));
1368 A_OP(icode, &ptr, iMAC0, A_GPR(l+2), A_GPR_ACCU, A_GPR(l+2), A_GPR(TREBLE_GPR + 6 + j));
1369 A_OP(icode, &ptr, iMACINT0, A_GPR(l+2), A_C_00000000, A_GPR(l+2), A_C_00000010);
1371 A_OP(icode, &ptr, iACC3, A_GPR(d), A_GPR(l+2), A_C_00000000, A_C_00000000);
1373 if (z == 2) /* center */
1382 for (z = 0; z < 8; z++) {
1383 A_SWITCH(icode, &ptr, tmp + 0, playback + SND_EMU10K1_PLAYBACK_CHANNELS + z, gpr + 0);
1384 A_SWITCH_NEG(icode, &ptr, tmp + 1, gpr + 0);
1385 A_SWITCH(icode, &ptr, tmp + 1, playback + z, tmp + 1);
1386 A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + z), A_GPR(tmp + 0), A_GPR(tmp + 1), A_C_00000000);
1388 snd_emu10k1_init_stereo_onoff_control(controls + nctl++, "Tone Control - Switch", gpr, 0);
1391 /* Master volume (will be renamed later) */
1392 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));
1393 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));
1394 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));
1395 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));
1396 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));
1397 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));
1398 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));
1399 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));
1400 snd_emu10k1_init_mono_control(&controls[nctl++], "Wave Master Playback Volume", gpr, 0);
1403 /* analog speakers */
1404 A_PUT_STEREO_OUTPUT(A_EXTOUT_AFRONT_L, A_EXTOUT_AFRONT_R, playback + SND_EMU10K1_PLAYBACK_CHANNELS);
1405 A_PUT_STEREO_OUTPUT(A_EXTOUT_AREAR_L, A_EXTOUT_AREAR_R, playback+2 + SND_EMU10K1_PLAYBACK_CHANNELS);
1406 A_PUT_OUTPUT(A_EXTOUT_ACENTER, playback+4 + SND_EMU10K1_PLAYBACK_CHANNELS);
1407 A_PUT_OUTPUT(A_EXTOUT_ALFE, playback+5 + SND_EMU10K1_PLAYBACK_CHANNELS);
1408 if (emu->card_capabilities->spk71)
1409 A_PUT_STEREO_OUTPUT(A_EXTOUT_ASIDE_L, A_EXTOUT_ASIDE_R, playback+6 + SND_EMU10K1_PLAYBACK_CHANNELS);
1412 A_PUT_STEREO_OUTPUT(A_EXTOUT_HEADPHONE_L, A_EXTOUT_HEADPHONE_R, playback + SND_EMU10K1_PLAYBACK_CHANNELS);
1414 /* digital outputs */
1415 /* A_PUT_STEREO_OUTPUT(A_EXTOUT_FRONT_L, A_EXTOUT_FRONT_R, playback + SND_EMU10K1_PLAYBACK_CHANNELS); */
1417 /* IEC958 Optical Raw Playback Switch */
1419 gpr_map[gpr++] = 0x1008;
1420 gpr_map[gpr++] = 0xffff0000;
1421 for (z = 0; z < 2; z++) {
1422 A_OP(icode, &ptr, iMAC0, A_GPR(tmp + 2), A_FXBUS(FXBUS_PT_LEFT + z), A_C_00000000, A_C_00000000);
1423 A_OP(icode, &ptr, iSKIP, A_GPR_COND, A_GPR_COND, A_GPR(gpr - 2), A_C_00000001);
1424 A_OP(icode, &ptr, iACC3, A_GPR(tmp + 2), A_C_00000000, A_C_00010000, A_GPR(tmp + 2));
1425 A_OP(icode, &ptr, iANDXOR, A_GPR(tmp + 2), A_GPR(tmp + 2), A_GPR(gpr - 1), A_C_00000000);
1426 A_SWITCH(icode, &ptr, tmp + 0, tmp + 2, gpr + z);
1427 A_SWITCH_NEG(icode, &ptr, tmp + 1, gpr + z);
1428 A_SWITCH(icode, &ptr, tmp + 1, playback + SND_EMU10K1_PLAYBACK_CHANNELS + z, tmp + 1);
1429 if ((z==1) && (emu->card_capabilities->spdif_bug)) {
1430 /* Due to a SPDIF output bug on some Audigy cards, this code delays the Right channel by 1 sample */
1431 snd_printk(KERN_INFO "Installing spdif_bug patch: %s\n", emu->card_capabilities->name);
1432 A_OP(icode, &ptr, iACC3, A_EXTOUT(A_EXTOUT_FRONT_L + z), A_GPR(gpr - 3), A_C_00000000, A_C_00000000);
1433 A_OP(icode, &ptr, iACC3, A_GPR(gpr - 3), A_GPR(tmp + 0), A_GPR(tmp + 1), A_C_00000000);
1435 A_OP(icode, &ptr, iACC3, A_EXTOUT(A_EXTOUT_FRONT_L + z), A_GPR(tmp + 0), A_GPR(tmp + 1), A_C_00000000);
1438 snd_emu10k1_init_stereo_onoff_control(controls + nctl++, SNDRV_CTL_NAME_IEC958("Optical Raw ",PLAYBACK,SWITCH), gpr, 0);
1441 A_PUT_STEREO_OUTPUT(A_EXTOUT_REAR_L, A_EXTOUT_REAR_R, playback+2 + SND_EMU10K1_PLAYBACK_CHANNELS);
1442 A_PUT_OUTPUT(A_EXTOUT_CENTER, playback+4 + SND_EMU10K1_PLAYBACK_CHANNELS);
1443 A_PUT_OUTPUT(A_EXTOUT_LFE, playback+5 + SND_EMU10K1_PLAYBACK_CHANNELS);
1446 #ifdef EMU10K1_CAPTURE_DIGITAL_OUT
1447 A_PUT_STEREO_OUTPUT(A_EXTOUT_ADC_CAP_L, A_EXTOUT_ADC_CAP_R, playback + SND_EMU10K1_PLAYBACK_CHANNELS);
1449 A_PUT_OUTPUT(A_EXTOUT_ADC_CAP_L, capture);
1450 A_PUT_OUTPUT(A_EXTOUT_ADC_CAP_R, capture+1);
1453 /* EFX capture - capture the 16 EXTINs */
1454 for (z = 0; z < 16; z++) {
1455 A_OP(icode, &ptr, iACC3, A_FXBUS2(z), A_C_00000000, A_C_00000000, A_EXTIN(z));
1458 #endif /* JCD test */
1468 /* clear remaining instruction memory */
1470 A_OP(icode, &ptr, 0x0f, 0xc0, 0xc0, 0xcf, 0xc0);
1472 seg = snd_enter_user();
1473 icode->gpr_add_control_count = nctl;
1474 icode->gpr_add_controls = (struct snd_emu10k1_fx8010_control_gpr __user *)controls;
1475 err = snd_emu10k1_icode_poke(emu, icode);
1476 snd_leave_user(seg);
1480 if (icode != NULL) {
1481 kfree((void __force *)icode->gpr_map);
1489 * initial DSP configuration for Emu10k1
1492 /* when volume = max, then copy only to avoid volume modification */
1493 /* with iMAC0 (negative values) */
1494 static void __devinit _volume(struct snd_emu10k1_fx8010_code *icode, u32 *ptr, u32 dst, u32 src, u32 vol)
1496 OP(icode, ptr, iMAC0, dst, C_00000000, src, 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_00000001);
1499 OP(icode, ptr, iACC3, dst, src, C_00000000, C_00000000);
1501 static void __devinit _volume_add(struct snd_emu10k1_fx8010_code *icode, u32 *ptr, u32 dst, u32 src, u32 vol)
1503 OP(icode, ptr, iANDXOR, C_00000000, vol, C_ffffffff, C_7fffffff);
1504 OP(icode, ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, C_00000002);
1505 OP(icode, ptr, iMACINT0, dst, dst, src, C_00000001);
1506 OP(icode, ptr, iSKIP, C_00000000, C_7fffffff, C_7fffffff, C_00000001);
1507 OP(icode, ptr, iMAC0, dst, dst, src, vol);
1509 static void __devinit _volume_out(struct snd_emu10k1_fx8010_code *icode, u32 *ptr, u32 dst, u32 src, u32 vol)
1511 OP(icode, ptr, iANDXOR, C_00000000, vol, C_ffffffff, C_7fffffff);
1512 OP(icode, ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, C_00000002);
1513 OP(icode, ptr, iACC3, dst, src, C_00000000, C_00000000);
1514 OP(icode, ptr, iSKIP, C_00000000, C_7fffffff, C_7fffffff, C_00000001);
1515 OP(icode, ptr, iMAC0, dst, C_00000000, src, vol);
1518 #define VOLUME(icode, ptr, dst, src, vol) \
1519 _volume(icode, ptr, GPR(dst), GPR(src), GPR(vol))
1520 #define VOLUME_IN(icode, ptr, dst, src, vol) \
1521 _volume(icode, ptr, GPR(dst), EXTIN(src), GPR(vol))
1522 #define VOLUME_ADD(icode, ptr, dst, src, vol) \
1523 _volume_add(icode, ptr, GPR(dst), GPR(src), GPR(vol))
1524 #define VOLUME_ADDIN(icode, ptr, dst, src, vol) \
1525 _volume_add(icode, ptr, GPR(dst), EXTIN(src), GPR(vol))
1526 #define VOLUME_OUT(icode, ptr, dst, src, vol) \
1527 _volume_out(icode, ptr, EXTOUT(dst), GPR(src), GPR(vol))
1528 #define _SWITCH(icode, ptr, dst, src, sw) \
1529 OP((icode), ptr, iMACINT0, dst, C_00000000, src, sw);
1530 #define SWITCH(icode, ptr, dst, src, sw) \
1531 _SWITCH(icode, ptr, GPR(dst), GPR(src), GPR(sw))
1532 #define SWITCH_IN(icode, ptr, dst, src, sw) \
1533 _SWITCH(icode, ptr, GPR(dst), EXTIN(src), GPR(sw))
1534 #define _SWITCH_NEG(icode, ptr, dst, src) \
1535 OP((icode), ptr, iANDXOR, dst, src, C_00000001, C_00000001);
1536 #define SWITCH_NEG(icode, ptr, dst, src) \
1537 _SWITCH_NEG(icode, ptr, GPR(dst), GPR(src))
1540 static int __devinit _snd_emu10k1_init_efx(struct snd_emu10k1 *emu)
1542 int err, i, z, gpr, tmp, playback, capture;
1544 struct snd_emu10k1_fx8010_code *icode;
1545 struct snd_emu10k1_fx8010_pcm_rec *ipcm = NULL;
1546 struct snd_emu10k1_fx8010_control_gpr *controls = NULL, *ctl;
1550 if ((icode = kzalloc(sizeof(*icode), GFP_KERNEL)) == NULL)
1552 if ((icode->gpr_map = (u_int32_t __user *)
1553 kcalloc(256 + 160 + 160 + 2 * 512, sizeof(u_int32_t),
1554 GFP_KERNEL)) == NULL ||
1555 (controls = kcalloc(SND_EMU10K1_GPR_CONTROLS,
1556 sizeof(struct snd_emu10k1_fx8010_control_gpr),
1557 GFP_KERNEL)) == NULL ||
1558 (ipcm = kzalloc(sizeof(*ipcm), GFP_KERNEL)) == NULL) {
1562 gpr_map = (u32 __force *)icode->gpr_map;
1564 icode->tram_data_map = icode->gpr_map + 256;
1565 icode->tram_addr_map = icode->tram_data_map + 160;
1566 icode->code = icode->tram_addr_map + 160;
1568 /* clear free GPRs */
1569 for (i = 0; i < 256; i++)
1570 set_bit(i, icode->gpr_valid);
1572 /* clear TRAM data & address lines */
1573 for (i = 0; i < 160; i++)
1574 set_bit(i, icode->tram_valid);
1576 strcpy(icode->name, "SB Live! FX8010 code for ALSA v1.2 by Jaroslav Kysela");
1578 /* we have 12 inputs */
1579 playback = SND_EMU10K1_INPUTS;
1580 /* we have 6 playback channels and tone control doubles */
1581 capture = playback + (SND_EMU10K1_PLAYBACK_CHANNELS * 2);
1582 gpr = capture + SND_EMU10K1_CAPTURE_CHANNELS;
1583 tmp = 0x88; /* we need 4 temporary GPR */
1584 /* from 0x8c to 0xff is the area for tone control */
1586 /* stop FX processor */
1587 snd_emu10k1_ptr_write(emu, DBG, 0, (emu->fx8010.dbg = 0) | EMU10K1_DBG_SINGLE_STEP);
1592 OP(icode, &ptr, iMACINT0, GPR(0), C_00000000, FXBUS(FXBUS_PCM_LEFT), C_00000004);
1593 OP(icode, &ptr, iMACINT0, GPR(1), C_00000000, FXBUS(FXBUS_PCM_RIGHT), C_00000004);
1594 OP(icode, &ptr, iMACINT0, GPR(2), C_00000000, FXBUS(FXBUS_MIDI_LEFT), C_00000004);
1595 OP(icode, &ptr, iMACINT0, GPR(3), C_00000000, FXBUS(FXBUS_MIDI_RIGHT), C_00000004);
1596 OP(icode, &ptr, iMACINT0, GPR(4), C_00000000, FXBUS(FXBUS_PCM_LEFT_REAR), C_00000004);
1597 OP(icode, &ptr, iMACINT0, GPR(5), C_00000000, FXBUS(FXBUS_PCM_RIGHT_REAR), C_00000004);
1598 OP(icode, &ptr, iMACINT0, GPR(6), C_00000000, FXBUS(FXBUS_PCM_CENTER), C_00000004);
1599 OP(icode, &ptr, iMACINT0, GPR(7), C_00000000, FXBUS(FXBUS_PCM_LFE), C_00000004);
1600 OP(icode, &ptr, iMACINT0, GPR(8), C_00000000, C_00000000, C_00000000); /* S/PDIF left */
1601 OP(icode, &ptr, iMACINT0, GPR(9), C_00000000, C_00000000, C_00000000); /* S/PDIF right */
1602 OP(icode, &ptr, iMACINT0, GPR(10), C_00000000, FXBUS(FXBUS_PCM_LEFT_FRONT), C_00000004);
1603 OP(icode, &ptr, iMACINT0, GPR(11), C_00000000, FXBUS(FXBUS_PCM_RIGHT_FRONT), C_00000004);
1605 /* Raw S/PDIF PCM */
1606 ipcm->substream = 0;
1608 ipcm->tram_start = 0;
1609 ipcm->buffer_size = (64 * 1024) / 2;
1610 ipcm->gpr_size = gpr++;
1611 ipcm->gpr_ptr = gpr++;
1612 ipcm->gpr_count = gpr++;
1613 ipcm->gpr_tmpcount = gpr++;
1614 ipcm->gpr_trigger = gpr++;
1615 ipcm->gpr_running = gpr++;
1619 gpr_map[gpr + 0] = 0xfffff000;
1620 gpr_map[gpr + 1] = 0xffff0000;
1621 gpr_map[gpr + 2] = 0x70000000;
1622 gpr_map[gpr + 3] = 0x00000007;
1623 gpr_map[gpr + 4] = 0x001f << 11;
1624 gpr_map[gpr + 5] = 0x001c << 11;
1625 gpr_map[gpr + 6] = (0x22 - 0x01) - 1; /* skip at 01 to 22 */
1626 gpr_map[gpr + 7] = (0x22 - 0x06) - 1; /* skip at 06 to 22 */
1627 gpr_map[gpr + 8] = 0x2000000 + (2<<11);
1628 gpr_map[gpr + 9] = 0x4000000 + (2<<11);
1629 gpr_map[gpr + 10] = 1<<11;
1630 gpr_map[gpr + 11] = (0x24 - 0x0a) - 1; /* skip at 0a to 24 */
1631 gpr_map[gpr + 12] = 0;
1633 /* if the trigger flag is not set, skip */
1634 /* 00: */ OP(icode, &ptr, iMAC0, C_00000000, GPR(ipcm->gpr_trigger), C_00000000, C_00000000);
1635 /* 01: */ OP(icode, &ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_ZERO, GPR(gpr + 6));
1636 /* if the running flag is set, we're running */
1637 /* 02: */ OP(icode, &ptr, iMAC0, C_00000000, GPR(ipcm->gpr_running), C_00000000, C_00000000);
1638 /* 03: */ OP(icode, &ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, C_00000004);
1639 /* wait until ((GPR_DBAC>>11) & 0x1f) == 0x1c) */
1640 /* 04: */ OP(icode, &ptr, iANDXOR, GPR(tmp + 0), GPR_DBAC, GPR(gpr + 4), C_00000000);
1641 /* 05: */ OP(icode, &ptr, iMACINT0, C_00000000, GPR(tmp + 0), C_ffffffff, GPR(gpr + 5));
1642 /* 06: */ OP(icode, &ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, GPR(gpr + 7));
1643 /* 07: */ OP(icode, &ptr, iACC3, GPR(gpr + 12), C_00000010, C_00000001, C_00000000);
1645 /* 08: */ OP(icode, &ptr, iANDXOR, GPR(ipcm->gpr_running), GPR(ipcm->gpr_running), C_00000000, C_00000001);
1646 /* 09: */ OP(icode, &ptr, iACC3, GPR(gpr + 12), GPR(gpr + 12), C_ffffffff, C_00000000);
1647 /* 0a: */ OP(icode, &ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, GPR(gpr + 11));
1648 /* 0b: */ OP(icode, &ptr, iACC3, GPR(gpr + 12), C_00000001, C_00000000, C_00000000);
1650 /* 0c: */ OP(icode, &ptr, iANDXOR, GPR(tmp + 0), ETRAM_DATA(ipcm->etram[0]), GPR(gpr + 0), C_00000000);
1651 /* 0d: */ OP(icode, &ptr, iLOG, GPR(tmp + 0), GPR(tmp + 0), GPR(gpr + 3), C_00000000);
1652 /* 0e: */ OP(icode, &ptr, iANDXOR, GPR(8), GPR(tmp + 0), GPR(gpr + 1), GPR(gpr + 2));
1653 /* 0f: */ OP(icode, &ptr, iSKIP, C_00000000, GPR_COND, CC_REG_MINUS, C_00000001);
1654 /* 10: */ OP(icode, &ptr, iANDXOR, GPR(8), GPR(8), GPR(gpr + 1), GPR(gpr + 2));
1656 /* 11: */ OP(icode, &ptr, iANDXOR, GPR(tmp + 0), ETRAM_DATA(ipcm->etram[1]), GPR(gpr + 0), C_00000000);
1657 /* 12: */ OP(icode, &ptr, iLOG, GPR(tmp + 0), GPR(tmp + 0), GPR(gpr + 3), C_00000000);
1658 /* 13: */ OP(icode, &ptr, iANDXOR, GPR(9), GPR(tmp + 0), GPR(gpr + 1), GPR(gpr + 2));
1659 /* 14: */ OP(icode, &ptr, iSKIP, C_00000000, GPR_COND, CC_REG_MINUS, C_00000001);
1660 /* 15: */ OP(icode, &ptr, iANDXOR, GPR(9), GPR(9), GPR(gpr + 1), GPR(gpr + 2));
1662 /* 16: */ OP(icode, &ptr, iACC3, GPR(tmp + 0), GPR(ipcm->gpr_ptr), C_00000001, C_00000000);
1663 /* 17: */ OP(icode, &ptr, iMACINT0, C_00000000, GPR(tmp + 0), C_ffffffff, GPR(ipcm->gpr_size));
1664 /* 18: */ OP(icode, &ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_MINUS, C_00000001);
1665 /* 19: */ OP(icode, &ptr, iACC3, GPR(tmp + 0), C_00000000, C_00000000, C_00000000);
1666 /* 1a: */ OP(icode, &ptr, iACC3, GPR(ipcm->gpr_ptr), GPR(tmp + 0), C_00000000, C_00000000);
1668 /* 1b: */ OP(icode, &ptr, iACC3, GPR(ipcm->gpr_tmpcount), GPR(ipcm->gpr_tmpcount), C_ffffffff, C_00000000);
1669 /* 1c: */ OP(icode, &ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, C_00000002);
1670 /* 1d: */ OP(icode, &ptr, iACC3, GPR(ipcm->gpr_tmpcount), GPR(ipcm->gpr_count), C_00000000, C_00000000);
1671 /* 1e: */ OP(icode, &ptr, iACC3, GPR_IRQ, C_80000000, C_00000000, C_00000000);
1672 /* 1f: */ OP(icode, &ptr, iANDXOR, GPR(ipcm->gpr_running), GPR(ipcm->gpr_running), C_00000001, C_00010000);
1674 /* 20: */ OP(icode, &ptr, iANDXOR, GPR(ipcm->gpr_running), GPR(ipcm->gpr_running), C_00010000, C_00000001);
1675 /* 21: */ OP(icode, &ptr, iSKIP, C_00000000, C_7fffffff, C_7fffffff, C_00000002);
1677 /* 22: */ OP(icode, &ptr, iMACINT1, ETRAM_ADDR(ipcm->etram[0]), GPR(gpr + 8), GPR_DBAC, C_ffffffff);
1678 /* 23: */ OP(icode, &ptr, iMACINT1, ETRAM_ADDR(ipcm->etram[1]), GPR(gpr + 9), GPR_DBAC, C_ffffffff);
1683 /* Wave Playback Volume */
1684 for (z = 0; z < 2; z++)
1685 VOLUME(icode, &ptr, playback + z, z, gpr + z);
1686 snd_emu10k1_init_stereo_control(controls + i++, "Wave Playback Volume", gpr, 100);
1689 /* Wave Surround Playback Volume */
1690 for (z = 0; z < 2; z++)
1691 VOLUME(icode, &ptr, playback + 2 + z, z, gpr + z);
1692 snd_emu10k1_init_stereo_control(controls + i++, "Wave Surround Playback Volume", gpr, 0);
1695 /* Wave Center/LFE Playback Volume */
1696 OP(icode, &ptr, iACC3, GPR(tmp + 0), FXBUS(FXBUS_PCM_LEFT), FXBUS(FXBUS_PCM_RIGHT), C_00000000);
1697 OP(icode, &ptr, iMACINT0, GPR(tmp + 0), C_00000000, GPR(tmp + 0), C_00000002);
1698 VOLUME(icode, &ptr, playback + 4, tmp + 0, gpr);
1699 snd_emu10k1_init_mono_control(controls + i++, "Wave Center Playback Volume", gpr++, 0);
1700 VOLUME(icode, &ptr, playback + 5, tmp + 0, gpr);
1701 snd_emu10k1_init_mono_control(controls + i++, "Wave LFE Playback Volume", gpr++, 0);
1703 /* Wave Capture Volume + Switch */
1704 for (z = 0; z < 2; z++) {
1705 SWITCH(icode, &ptr, tmp + 0, z, gpr + 2 + z);
1706 VOLUME(icode, &ptr, capture + z, tmp + 0, gpr + z);
1708 snd_emu10k1_init_stereo_control(controls + i++, "Wave Capture Volume", gpr, 0);
1709 snd_emu10k1_init_stereo_onoff_control(controls + i++, "Wave Capture Switch", gpr + 2, 0);
1712 /* Synth Playback Volume */
1713 for (z = 0; z < 2; z++)
1714 VOLUME_ADD(icode, &ptr, playback + z, 2 + z, gpr + z);
1715 snd_emu10k1_init_stereo_control(controls + i++, "Synth Playback Volume", gpr, 100);
1718 /* Synth Capture Volume + Switch */
1719 for (z = 0; z < 2; z++) {
1720 SWITCH(icode, &ptr, tmp + 0, 2 + z, gpr + 2 + z);
1721 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
1723 snd_emu10k1_init_stereo_control(controls + i++, "Synth Capture Volume", gpr, 0);
1724 snd_emu10k1_init_stereo_onoff_control(controls + i++, "Synth Capture Switch", gpr + 2, 0);
1727 /* Surround Digital Playback Volume (renamed later without Digital) */
1728 for (z = 0; z < 2; z++)
1729 VOLUME_ADD(icode, &ptr, playback + 2 + z, 4 + z, gpr + z);
1730 snd_emu10k1_init_stereo_control(controls + i++, "Surround Digital Playback Volume", gpr, 100);
1733 /* Surround Capture Volume + Switch */
1734 for (z = 0; z < 2; z++) {
1735 SWITCH(icode, &ptr, tmp + 0, 4 + z, gpr + 2 + z);
1736 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
1738 snd_emu10k1_init_stereo_control(controls + i++, "Surround Capture Volume", gpr, 0);
1739 snd_emu10k1_init_stereo_onoff_control(controls + i++, "Surround Capture Switch", gpr + 2, 0);
1742 /* Center Playback Volume (renamed later without Digital) */
1743 VOLUME_ADD(icode, &ptr, playback + 4, 6, gpr);
1744 snd_emu10k1_init_mono_control(controls + i++, "Center Digital Playback Volume", gpr++, 100);
1746 /* LFE Playback Volume + Switch (renamed later without Digital) */
1747 VOLUME_ADD(icode, &ptr, playback + 5, 7, gpr);
1748 snd_emu10k1_init_mono_control(controls + i++, "LFE Digital Playback Volume", gpr++, 100);
1750 /* Front Playback Volume */
1751 for (z = 0; z < 2; z++)
1752 VOLUME_ADD(icode, &ptr, playback + z, 10 + z, gpr + z);
1753 snd_emu10k1_init_stereo_control(controls + i++, "Front Playback Volume", gpr, 100);
1756 /* Front Capture Volume + Switch */
1757 for (z = 0; z < 2; z++) {
1758 SWITCH(icode, &ptr, tmp + 0, 10 + z, gpr + 2);
1759 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
1761 snd_emu10k1_init_stereo_control(controls + i++, "Front Capture Volume", gpr, 0);
1762 snd_emu10k1_init_mono_onoff_control(controls + i++, "Front Capture Switch", gpr + 2, 0);
1769 if (emu->fx8010.extin_mask & ((1<<EXTIN_AC97_L)|(1<<EXTIN_AC97_R))) {
1770 /* AC'97 Playback Volume */
1771 VOLUME_ADDIN(icode, &ptr, playback + 0, EXTIN_AC97_L, gpr); gpr++;
1772 VOLUME_ADDIN(icode, &ptr, playback + 1, EXTIN_AC97_R, gpr); gpr++;
1773 snd_emu10k1_init_stereo_control(controls + i++, "AC97 Playback Volume", gpr-2, 0);
1774 /* AC'97 Capture Volume */
1775 VOLUME_ADDIN(icode, &ptr, capture + 0, EXTIN_AC97_L, gpr); gpr++;
1776 VOLUME_ADDIN(icode, &ptr, capture + 1, EXTIN_AC97_R, gpr); gpr++;
1777 snd_emu10k1_init_stereo_control(controls + i++, "AC97 Capture Volume", gpr-2, 100);
1780 if (emu->fx8010.extin_mask & ((1<<EXTIN_SPDIF_CD_L)|(1<<EXTIN_SPDIF_CD_R))) {
1781 /* IEC958 TTL Playback Volume */
1782 for (z = 0; z < 2; z++)
1783 VOLUME_ADDIN(icode, &ptr, playback + z, EXTIN_SPDIF_CD_L + z, gpr + z);
1784 snd_emu10k1_init_stereo_control(controls + i++, SNDRV_CTL_NAME_IEC958("TTL ",PLAYBACK,VOLUME), gpr, 0);
1787 /* IEC958 TTL Capture Volume + Switch */
1788 for (z = 0; z < 2; z++) {
1789 SWITCH_IN(icode, &ptr, tmp + 0, EXTIN_SPDIF_CD_L + z, gpr + 2 + z);
1790 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
1792 snd_emu10k1_init_stereo_control(controls + i++, SNDRV_CTL_NAME_IEC958("TTL ",CAPTURE,VOLUME), gpr, 0);
1793 snd_emu10k1_init_stereo_onoff_control(controls + i++, SNDRV_CTL_NAME_IEC958("TTL ",CAPTURE,SWITCH), gpr + 2, 0);
1797 if (emu->fx8010.extin_mask & ((1<<EXTIN_ZOOM_L)|(1<<EXTIN_ZOOM_R))) {
1798 /* Zoom Video Playback Volume */
1799 for (z = 0; z < 2; z++)
1800 VOLUME_ADDIN(icode, &ptr, playback + z, EXTIN_ZOOM_L + z, gpr + z);
1801 snd_emu10k1_init_stereo_control(controls + i++, "Zoom Video Playback Volume", gpr, 0);
1804 /* Zoom Video Capture Volume + Switch */
1805 for (z = 0; z < 2; z++) {
1806 SWITCH_IN(icode, &ptr, tmp + 0, EXTIN_ZOOM_L + z, gpr + 2 + z);
1807 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
1809 snd_emu10k1_init_stereo_control(controls + i++, "Zoom Video Capture Volume", gpr, 0);
1810 snd_emu10k1_init_stereo_onoff_control(controls + i++, "Zoom Video Capture Switch", gpr + 2, 0);
1814 if (emu->fx8010.extin_mask & ((1<<EXTIN_TOSLINK_L)|(1<<EXTIN_TOSLINK_R))) {
1815 /* IEC958 Optical Playback Volume */
1816 for (z = 0; z < 2; z++)
1817 VOLUME_ADDIN(icode, &ptr, playback + z, EXTIN_TOSLINK_L + z, gpr + z);
1818 snd_emu10k1_init_stereo_control(controls + i++, SNDRV_CTL_NAME_IEC958("LiveDrive ",PLAYBACK,VOLUME), gpr, 0);
1821 /* IEC958 Optical Capture Volume */
1822 for (z = 0; z < 2; z++) {
1823 SWITCH_IN(icode, &ptr, tmp + 0, EXTIN_TOSLINK_L + z, gpr + 2 + z);
1824 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
1826 snd_emu10k1_init_stereo_control(controls + i++, SNDRV_CTL_NAME_IEC958("LiveDrive ",CAPTURE,VOLUME), gpr, 0);
1827 snd_emu10k1_init_stereo_onoff_control(controls + i++, SNDRV_CTL_NAME_IEC958("LiveDrive ",CAPTURE,SWITCH), gpr + 2, 0);
1831 if (emu->fx8010.extin_mask & ((1<<EXTIN_LINE1_L)|(1<<EXTIN_LINE1_R))) {
1832 /* Line LiveDrive Playback Volume */
1833 for (z = 0; z < 2; z++)
1834 VOLUME_ADDIN(icode, &ptr, playback + z, EXTIN_LINE1_L + z, gpr + z);
1835 snd_emu10k1_init_stereo_control(controls + i++, "Line LiveDrive Playback Volume", gpr, 0);
1838 /* Line LiveDrive Capture Volume + Switch */
1839 for (z = 0; z < 2; z++) {
1840 SWITCH_IN(icode, &ptr, tmp + 0, EXTIN_LINE1_L + z, gpr + 2 + z);
1841 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
1843 snd_emu10k1_init_stereo_control(controls + i++, "Line LiveDrive Capture Volume", gpr, 0);
1844 snd_emu10k1_init_stereo_onoff_control(controls + i++, "Line LiveDrive Capture Switch", gpr + 2, 0);
1848 if (emu->fx8010.extin_mask & ((1<<EXTIN_COAX_SPDIF_L)|(1<<EXTIN_COAX_SPDIF_R))) {
1849 /* IEC958 Coax Playback Volume */
1850 for (z = 0; z < 2; z++)
1851 VOLUME_ADDIN(icode, &ptr, playback + z, EXTIN_COAX_SPDIF_L + z, gpr + z);
1852 snd_emu10k1_init_stereo_control(controls + i++, SNDRV_CTL_NAME_IEC958("Coaxial ",PLAYBACK,VOLUME), gpr, 0);
1855 /* IEC958 Coax Capture Volume + Switch */
1856 for (z = 0; z < 2; z++) {
1857 SWITCH_IN(icode, &ptr, tmp + 0, EXTIN_COAX_SPDIF_L + z, gpr + 2 + z);
1858 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
1860 snd_emu10k1_init_stereo_control(controls + i++, SNDRV_CTL_NAME_IEC958("Coaxial ",CAPTURE,VOLUME), gpr, 0);
1861 snd_emu10k1_init_stereo_onoff_control(controls + i++, SNDRV_CTL_NAME_IEC958("Coaxial ",CAPTURE,SWITCH), gpr + 2, 0);
1865 if (emu->fx8010.extin_mask & ((1<<EXTIN_LINE2_L)|(1<<EXTIN_LINE2_R))) {
1866 /* Line LiveDrive Playback Volume */
1867 for (z = 0; z < 2; z++)
1868 VOLUME_ADDIN(icode, &ptr, playback + z, EXTIN_LINE2_L + z, gpr + z);
1869 snd_emu10k1_init_stereo_control(controls + i++, "Line2 LiveDrive Playback Volume", gpr, 0);
1870 controls[i-1].id.index = 1;
1873 /* Line LiveDrive Capture Volume */
1874 for (z = 0; z < 2; z++) {
1875 SWITCH_IN(icode, &ptr, tmp + 0, EXTIN_LINE2_L + z, gpr + 2 + z);
1876 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
1878 snd_emu10k1_init_stereo_control(controls + i++, "Line2 LiveDrive Capture Volume", gpr, 0);
1879 controls[i-1].id.index = 1;
1880 snd_emu10k1_init_stereo_onoff_control(controls + i++, "Line2 LiveDrive Capture Switch", gpr + 2, 0);
1881 controls[i-1].id.index = 1;
1886 * Process tone control
1888 OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 0), GPR(playback + 0), C_00000000, C_00000000); /* left */
1889 OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 1), GPR(playback + 1), C_00000000, C_00000000); /* right */
1890 OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 2), GPR(playback + 2), C_00000000, C_00000000); /* rear left */
1891 OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 3), GPR(playback + 3), C_00000000, C_00000000); /* rear right */
1892 OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 4), GPR(playback + 4), C_00000000, C_00000000); /* center */
1893 OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 5), GPR(playback + 5), C_00000000, C_00000000); /* LFE */
1895 ctl = &controls[i + 0];
1896 ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1897 strcpy(ctl->id.name, "Tone Control - Bass");
1902 ctl->value[0] = ctl->value[1] = 20;
1903 ctl->translation = EMU10K1_GPR_TRANSLATION_BASS;
1904 ctl = &controls[i + 1];
1905 ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1906 strcpy(ctl->id.name, "Tone Control - Treble");
1911 ctl->value[0] = ctl->value[1] = 20;
1912 ctl->translation = EMU10K1_GPR_TRANSLATION_TREBLE;
1914 #define BASS_GPR 0x8c
1915 #define TREBLE_GPR 0x96
1917 for (z = 0; z < 5; z++) {
1919 for (j = 0; j < 2; j++) {
1920 controls[i + 0].gpr[z * 2 + j] = BASS_GPR + z * 2 + j;
1921 controls[i + 1].gpr[z * 2 + j] = TREBLE_GPR + z * 2 + j;
1924 for (z = 0; z < 3; z++) { /* front/rear/center-lfe */
1926 for (j = 0; j < 2; j++) { /* left/right */
1927 k = 0xa0 + (z * 8) + (j * 4);
1928 l = 0xd0 + (z * 8) + (j * 4);
1929 d = playback + SND_EMU10K1_PLAYBACK_CHANNELS + z * 2 + j;
1931 OP(icode, &ptr, iMAC0, C_00000000, C_00000000, GPR(d), GPR(BASS_GPR + 0 + j));
1932 OP(icode, &ptr, iMACMV, GPR(k+1), GPR(k), GPR(k+1), GPR(BASS_GPR + 4 + j));
1933 OP(icode, &ptr, iMACMV, GPR(k), GPR(d), GPR(k), GPR(BASS_GPR + 2 + j));
1934 OP(icode, &ptr, iMACMV, GPR(k+3), GPR(k+2), GPR(k+3), GPR(BASS_GPR + 8 + j));
1935 OP(icode, &ptr, iMAC0, GPR(k+2), GPR_ACCU, GPR(k+2), GPR(BASS_GPR + 6 + j));
1936 OP(icode, &ptr, iACC3, GPR(k+2), GPR(k+2), GPR(k+2), C_00000000);
1938 OP(icode, &ptr, iMAC0, C_00000000, C_00000000, GPR(k+2), GPR(TREBLE_GPR + 0 + j));
1939 OP(icode, &ptr, iMACMV, GPR(l+1), GPR(l), GPR(l+1), GPR(TREBLE_GPR + 4 + j));
1940 OP(icode, &ptr, iMACMV, GPR(l), GPR(k+2), GPR(l), GPR(TREBLE_GPR + 2 + j));
1941 OP(icode, &ptr, iMACMV, GPR(l+3), GPR(l+2), GPR(l+3), GPR(TREBLE_GPR + 8 + j));
1942 OP(icode, &ptr, iMAC0, GPR(l+2), GPR_ACCU, GPR(l+2), GPR(TREBLE_GPR + 6 + j));
1943 OP(icode, &ptr, iMACINT0, GPR(l+2), C_00000000, GPR(l+2), C_00000010);
1945 OP(icode, &ptr, iACC3, GPR(d), GPR(l+2), C_00000000, C_00000000);
1947 if (z == 2) /* center */
1956 for (z = 0; z < 6; z++) {
1957 SWITCH(icode, &ptr, tmp + 0, playback + SND_EMU10K1_PLAYBACK_CHANNELS + z, gpr + 0);
1958 SWITCH_NEG(icode, &ptr, tmp + 1, gpr + 0);
1959 SWITCH(icode, &ptr, tmp + 1, playback + z, tmp + 1);
1960 OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + z), GPR(tmp + 0), GPR(tmp + 1), C_00000000);
1962 snd_emu10k1_init_stereo_onoff_control(controls + i++, "Tone Control - Switch", gpr, 0);
1968 if (emu->fx8010.extout_mask & ((1<<EXTOUT_AC97_L)|(1<<EXTOUT_AC97_R))) {
1969 /* AC'97 Playback Volume */
1971 for (z = 0; z < 2; z++)
1972 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_AC97_L + z), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + z), C_00000000, C_00000000);
1975 if (emu->fx8010.extout_mask & ((1<<EXTOUT_TOSLINK_L)|(1<<EXTOUT_TOSLINK_R))) {
1976 /* IEC958 Optical Raw Playback Switch */
1978 for (z = 0; z < 2; z++) {
1979 SWITCH(icode, &ptr, tmp + 0, 8 + z, gpr + z);
1980 SWITCH_NEG(icode, &ptr, tmp + 1, gpr + z);
1981 SWITCH(icode, &ptr, tmp + 1, playback + SND_EMU10K1_PLAYBACK_CHANNELS + z, tmp + 1);
1982 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_TOSLINK_L + z), GPR(tmp + 0), GPR(tmp + 1), C_00000000);
1983 #ifdef EMU10K1_CAPTURE_DIGITAL_OUT
1984 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_ADC_CAP_L + z), GPR(tmp + 0), GPR(tmp + 1), C_00000000);
1988 snd_emu10k1_init_stereo_onoff_control(controls + i++, SNDRV_CTL_NAME_IEC958("Optical Raw ",PLAYBACK,SWITCH), gpr, 0);
1992 if (emu->fx8010.extout_mask & ((1<<EXTOUT_HEADPHONE_L)|(1<<EXTOUT_HEADPHONE_R))) {
1993 /* Headphone Playback Volume */
1995 for (z = 0; z < 2; z++) {
1996 SWITCH(icode, &ptr, tmp + 0, playback + SND_EMU10K1_PLAYBACK_CHANNELS + 4 + z, gpr + 2 + z);
1997 SWITCH_NEG(icode, &ptr, tmp + 1, gpr + 2 + z);
1998 SWITCH(icode, &ptr, tmp + 1, playback + SND_EMU10K1_PLAYBACK_CHANNELS + z, tmp + 1);
1999 OP(icode, &ptr, iACC3, GPR(tmp + 0), GPR(tmp + 0), GPR(tmp + 1), C_00000000);
2000 VOLUME_OUT(icode, &ptr, EXTOUT_HEADPHONE_L + z, tmp + 0, gpr + z);
2003 snd_emu10k1_init_stereo_control(controls + i++, "Headphone Playback Volume", gpr + 0, 0);
2004 controls[i-1].id.index = 1; /* AC'97 can have also Headphone control */
2005 snd_emu10k1_init_mono_onoff_control(controls + i++, "Headphone Center Playback Switch", gpr + 2, 0);
2006 controls[i-1].id.index = 1;
2007 snd_emu10k1_init_mono_onoff_control(controls + i++, "Headphone LFE Playback Switch", gpr + 3, 0);
2008 controls[i-1].id.index = 1;
2013 if (emu->fx8010.extout_mask & ((1<<EXTOUT_REAR_L)|(1<<EXTOUT_REAR_R)))
2014 for (z = 0; z < 2; z++)
2015 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_REAR_L + z), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 2 + z), C_00000000, C_00000000);
2017 if (emu->fx8010.extout_mask & ((1<<EXTOUT_AC97_REAR_L)|(1<<EXTOUT_AC97_REAR_R)))
2018 for (z = 0; z < 2; z++)
2019 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_AC97_REAR_L + z), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 2 + z), C_00000000, C_00000000);
2021 if (emu->fx8010.extout_mask & (1<<EXTOUT_AC97_CENTER)) {
2022 #ifndef EMU10K1_CENTER_LFE_FROM_FRONT
2023 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_AC97_CENTER), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 4), C_00000000, C_00000000);
2024 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_ACENTER), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 4), C_00000000, C_00000000);
2026 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_AC97_CENTER), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 0), C_00000000, C_00000000);
2027 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_ACENTER), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 0), C_00000000, C_00000000);
2031 if (emu->fx8010.extout_mask & (1<<EXTOUT_AC97_LFE)) {
2032 #ifndef EMU10K1_CENTER_LFE_FROM_FRONT
2033 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_AC97_LFE), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 5), C_00000000, C_00000000);
2034 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_ALFE), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 5), C_00000000, C_00000000);
2036 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_AC97_LFE), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 1), C_00000000, C_00000000);
2037 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_ALFE), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 1), C_00000000, C_00000000);
2041 #ifndef EMU10K1_CAPTURE_DIGITAL_OUT
2042 for (z = 0; z < 2; z++)
2043 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_ADC_CAP_L + z), GPR(capture + z), C_00000000, C_00000000);
2046 if (emu->fx8010.extout_mask & (1<<EXTOUT_MIC_CAP))
2047 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_MIC_CAP), GPR(capture + 2), C_00000000, C_00000000);
2049 /* EFX capture - capture the 16 EXTINS */
2050 if (emu->card_capabilities->sblive51) {
2051 /* On the Live! 5.1, FXBUS2(1) and FXBUS(2) are shared with EXTOUT_ACENTER
2052 * and EXTOUT_ALFE, so we can't connect inputs to them for multitrack recording.
2054 * Since only 14 of the 16 EXTINs are used, this is not a big problem.
2055 * We route AC97L and R to FX capture 14 and 15, SPDIF CD in to FX capture
2056 * 0 and 3, then the rest of the EXTINs to the corresponding FX capture
2057 * channel. Multitrack recorders will still see the center/lfe output signal
2058 * on the second and third channels.
2060 OP(icode, &ptr, iACC3, FXBUS2(14), C_00000000, C_00000000, EXTIN(0));
2061 OP(icode, &ptr, iACC3, FXBUS2(15), C_00000000, C_00000000, EXTIN(1));
2062 OP(icode, &ptr, iACC3, FXBUS2(0), C_00000000, C_00000000, EXTIN(2));
2063 OP(icode, &ptr, iACC3, FXBUS2(3), C_00000000, C_00000000, EXTIN(3));
2064 for (z = 4; z < 14; z++)
2065 OP(icode, &ptr, iACC3, FXBUS2(z), C_00000000, C_00000000, EXTIN(z));
2067 for (z = 0; z < 16; z++)
2068 OP(icode, &ptr, iACC3, FXBUS2(z), C_00000000, C_00000000, EXTIN(z));
2077 if (i > SND_EMU10K1_GPR_CONTROLS) {
2083 /* clear remaining instruction memory */
2085 OP(icode, &ptr, iACC3, C_00000000, C_00000000, C_00000000, C_00000000);
2087 if ((err = snd_emu10k1_fx8010_tram_setup(emu, ipcm->buffer_size)) < 0)
2089 seg = snd_enter_user();
2090 icode->gpr_add_control_count = i;
2091 icode->gpr_add_controls = (struct snd_emu10k1_fx8010_control_gpr __user *)controls;
2092 err = snd_emu10k1_icode_poke(emu, icode);
2093 snd_leave_user(seg);
2095 err = snd_emu10k1_ipcm_poke(emu, ipcm);
2099 if (icode != NULL) {
2100 kfree((void __force *)icode->gpr_map);
2106 int __devinit snd_emu10k1_init_efx(struct snd_emu10k1 *emu)
2108 spin_lock_init(&emu->fx8010.irq_lock);
2109 INIT_LIST_HEAD(&emu->fx8010.gpr_ctl);
2111 return _snd_emu10k1_audigy_init_efx(emu);
2113 return _snd_emu10k1_init_efx(emu);
2116 void snd_emu10k1_free_efx(struct snd_emu10k1 *emu)
2118 /* stop processor */
2120 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg = A_DBG_SINGLE_STEP);
2122 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg = EMU10K1_DBG_SINGLE_STEP);
2125 #if 0 // FIXME: who use them?
2126 int snd_emu10k1_fx8010_tone_control_activate(struct snd_emu10k1 *emu, int output)
2128 if (output < 0 || output >= 6)
2130 snd_emu10k1_ptr_write(emu, emu->gpr_base + 0x94 + output, 0, 1);
2134 int snd_emu10k1_fx8010_tone_control_deactivate(struct snd_emu10k1 *emu, int output)
2136 if (output < 0 || output >= 6)
2138 snd_emu10k1_ptr_write(emu, emu->gpr_base + 0x94 + output, 0, 0);
2143 int snd_emu10k1_fx8010_tram_setup(struct snd_emu10k1 *emu, u32 size)
2147 /* size is in samples */
2149 size = (size - 1) >> 13;
2155 size = 0x2000 << size_reg;
2157 if ((emu->fx8010.etram_pages.bytes / 2) == size)
2159 spin_lock_irq(&emu->emu_lock);
2160 outl(HCFG_LOCKTANKCACHE_MASK | inl(emu->port + HCFG), emu->port + HCFG);
2161 spin_unlock_irq(&emu->emu_lock);
2162 snd_emu10k1_ptr_write(emu, TCB, 0, 0);
2163 snd_emu10k1_ptr_write(emu, TCBS, 0, 0);
2164 if (emu->fx8010.etram_pages.area != NULL) {
2165 snd_dma_free_pages(&emu->fx8010.etram_pages);
2166 emu->fx8010.etram_pages.area = NULL;
2167 emu->fx8010.etram_pages.bytes = 0;
2171 if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(emu->pci),
2172 size * 2, &emu->fx8010.etram_pages) < 0)
2174 memset(emu->fx8010.etram_pages.area, 0, size * 2);
2175 snd_emu10k1_ptr_write(emu, TCB, 0, emu->fx8010.etram_pages.addr);
2176 snd_emu10k1_ptr_write(emu, TCBS, 0, size_reg);
2177 spin_lock_irq(&emu->emu_lock);
2178 outl(inl(emu->port + HCFG) & ~HCFG_LOCKTANKCACHE_MASK, emu->port + HCFG);
2179 spin_unlock_irq(&emu->emu_lock);
2185 static int snd_emu10k1_fx8010_open(struct snd_hwdep * hw, struct file *file)
2190 static void copy_string(char *dst, char *src, char *null, int idx)
2193 sprintf(dst, "%s %02X", null, idx);
2198 static int snd_emu10k1_fx8010_info(struct snd_emu10k1 *emu,
2199 struct snd_emu10k1_fx8010_info *info)
2201 char **fxbus, **extin, **extout;
2202 unsigned short fxbus_mask, extin_mask, extout_mask;
2205 memset(info, 0, sizeof(info));
2206 info->internal_tram_size = emu->fx8010.itram_size;
2207 info->external_tram_size = emu->fx8010.etram_pages.bytes / 2;
2209 extin = emu->audigy ? audigy_ins : creative_ins;
2210 extout = emu->audigy ? audigy_outs : creative_outs;
2211 fxbus_mask = emu->fx8010.fxbus_mask;
2212 extin_mask = emu->fx8010.extin_mask;
2213 extout_mask = emu->fx8010.extout_mask;
2214 for (res = 0; res < 16; res++, fxbus++, extin++, extout++) {
2215 copy_string(info->fxbus_names[res], fxbus_mask & (1 << res) ? *fxbus : NULL, "FXBUS", res);
2216 copy_string(info->extin_names[res], extin_mask & (1 << res) ? *extin : NULL, "Unused", res);
2217 copy_string(info->extout_names[res], extout_mask & (1 << res) ? *extout : NULL, "Unused", res);
2219 for (res = 16; res < 32; res++, extout++)
2220 copy_string(info->extout_names[res], extout_mask & (1 << res) ? *extout : NULL, "Unused", res);
2221 info->gpr_controls = emu->fx8010.gpr_count;
2225 static int snd_emu10k1_fx8010_ioctl(struct snd_hwdep * hw, struct file *file, unsigned int cmd, unsigned long arg)
2227 struct snd_emu10k1 *emu = hw->private_data;
2228 struct snd_emu10k1_fx8010_info *info;
2229 struct snd_emu10k1_fx8010_code *icode;
2230 struct snd_emu10k1_fx8010_pcm_rec *ipcm;
2232 void __user *argp = (void __user *)arg;
2236 case SNDRV_EMU10K1_IOCTL_INFO:
2237 info = kmalloc(sizeof(*info), GFP_KERNEL);
2240 if ((res = snd_emu10k1_fx8010_info(emu, info)) < 0) {
2244 if (copy_to_user(argp, info, sizeof(*info))) {
2250 case SNDRV_EMU10K1_IOCTL_CODE_POKE:
2251 if (!capable(CAP_SYS_ADMIN))
2253 icode = kmalloc(sizeof(*icode), GFP_KERNEL);
2256 if (copy_from_user(icode, argp, sizeof(*icode))) {
2260 res = snd_emu10k1_icode_poke(emu, icode);
2263 case SNDRV_EMU10K1_IOCTL_CODE_PEEK:
2264 icode = kmalloc(sizeof(*icode), GFP_KERNEL);
2267 if (copy_from_user(icode, argp, sizeof(*icode))) {
2271 res = snd_emu10k1_icode_peek(emu, icode);
2272 if (res == 0 && copy_to_user(argp, icode, sizeof(*icode))) {
2278 case SNDRV_EMU10K1_IOCTL_PCM_POKE:
2279 ipcm = kmalloc(sizeof(*ipcm), GFP_KERNEL);
2282 if (copy_from_user(ipcm, argp, sizeof(*ipcm))) {
2286 res = snd_emu10k1_ipcm_poke(emu, ipcm);
2289 case SNDRV_EMU10K1_IOCTL_PCM_PEEK:
2290 ipcm = kzalloc(sizeof(*ipcm), GFP_KERNEL);
2293 if (copy_from_user(ipcm, argp, sizeof(*ipcm))) {
2297 res = snd_emu10k1_ipcm_peek(emu, ipcm);
2298 if (res == 0 && copy_to_user(argp, ipcm, sizeof(*ipcm))) {
2304 case SNDRV_EMU10K1_IOCTL_TRAM_SETUP:
2305 if (!capable(CAP_SYS_ADMIN))
2307 if (get_user(addr, (unsigned int __user *)argp))
2309 down(&emu->fx8010.lock);
2310 res = snd_emu10k1_fx8010_tram_setup(emu, addr);
2311 up(&emu->fx8010.lock);
2313 case SNDRV_EMU10K1_IOCTL_STOP:
2314 if (!capable(CAP_SYS_ADMIN))
2317 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg |= A_DBG_SINGLE_STEP);
2319 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg |= EMU10K1_DBG_SINGLE_STEP);
2321 case SNDRV_EMU10K1_IOCTL_CONTINUE:
2322 if (!capable(CAP_SYS_ADMIN))
2325 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg = 0);
2327 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg = 0);
2329 case SNDRV_EMU10K1_IOCTL_ZERO_TRAM_COUNTER:
2330 if (!capable(CAP_SYS_ADMIN))
2333 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg | A_DBG_ZC);
2335 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg | EMU10K1_DBG_ZC);
2338 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg);
2340 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg);
2342 case SNDRV_EMU10K1_IOCTL_SINGLE_STEP:
2343 if (!capable(CAP_SYS_ADMIN))
2345 if (get_user(addr, (unsigned int __user *)argp))
2350 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg |= A_DBG_SINGLE_STEP | addr);
2352 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg |= EMU10K1_DBG_SINGLE_STEP | addr);
2355 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg |= A_DBG_SINGLE_STEP | A_DBG_STEP_ADDR | addr);
2357 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg |= EMU10K1_DBG_SINGLE_STEP | EMU10K1_DBG_STEP | addr);
2359 case SNDRV_EMU10K1_IOCTL_DBG_READ:
2361 addr = snd_emu10k1_ptr_read(emu, A_DBG, 0);
2363 addr = snd_emu10k1_ptr_read(emu, DBG, 0);
2364 if (put_user(addr, (unsigned int __user *)argp))
2371 static int snd_emu10k1_fx8010_release(struct snd_hwdep * hw, struct file *file)
2376 int __devinit snd_emu10k1_fx8010_new(struct snd_emu10k1 *emu, int device, struct snd_hwdep ** rhwdep)
2378 struct snd_hwdep *hw;
2383 if ((err = snd_hwdep_new(emu->card, "FX8010", device, &hw)) < 0)
2385 strcpy(hw->name, "EMU10K1 (FX8010)");
2386 hw->iface = SNDRV_HWDEP_IFACE_EMU10K1;
2387 hw->ops.open = snd_emu10k1_fx8010_open;
2388 hw->ops.ioctl = snd_emu10k1_fx8010_ioctl;
2389 hw->ops.release = snd_emu10k1_fx8010_release;
2390 hw->private_data = emu;
2397 int __devinit snd_emu10k1_efx_alloc_pm_buffer(struct snd_emu10k1 *emu)
2401 len = emu->audigy ? 0x200 : 0x100;
2402 emu->saved_gpr = kmalloc(len * 4, GFP_KERNEL);
2403 if (! emu->saved_gpr)
2405 len = emu->audigy ? 0x100 : 0xa0;
2406 emu->tram_val_saved = kmalloc(len * 4, GFP_KERNEL);
2407 emu->tram_addr_saved = kmalloc(len * 4, GFP_KERNEL);
2408 if (! emu->tram_val_saved || ! emu->tram_addr_saved)
2410 len = emu->audigy ? 2 * 1024 : 2 * 512;
2411 emu->saved_icode = vmalloc(len * 4);
2412 if (! emu->saved_icode)
2417 void snd_emu10k1_efx_free_pm_buffer(struct snd_emu10k1 *emu)
2419 kfree(emu->saved_gpr);
2420 kfree(emu->tram_val_saved);
2421 kfree(emu->tram_addr_saved);
2422 vfree(emu->saved_icode);
2426 * save/restore GPR, TRAM and codes
2428 void snd_emu10k1_efx_suspend(struct snd_emu10k1 *emu)
2432 len = emu->audigy ? 0x200 : 0x100;
2433 for (i = 0; i < len; i++)
2434 emu->saved_gpr[i] = snd_emu10k1_ptr_read(emu, emu->gpr_base + i, 0);
2436 len = emu->audigy ? 0x100 : 0xa0;
2437 for (i = 0; i < len; i++) {
2438 emu->tram_val_saved[i] = snd_emu10k1_ptr_read(emu, TANKMEMDATAREGBASE + i, 0);
2439 emu->tram_addr_saved[i] = snd_emu10k1_ptr_read(emu, TANKMEMADDRREGBASE + i, 0);
2441 emu->tram_addr_saved[i] >>= 12;
2442 emu->tram_addr_saved[i] |=
2443 snd_emu10k1_ptr_read(emu, A_TANKMEMCTLREGBASE + i, 0) << 20;
2447 len = emu->audigy ? 2 * 1024 : 2 * 512;
2448 for (i = 0; i < len; i++)
2449 emu->saved_icode[i] = snd_emu10k1_efx_read(emu, i);
2452 void snd_emu10k1_efx_resume(struct snd_emu10k1 *emu)
2457 if (emu->fx8010.etram_pages.bytes > 0) {
2458 unsigned size, size_reg = 0;
2459 size = emu->fx8010.etram_pages.bytes / 2;
2460 size = (size - 1) >> 13;
2465 outl(HCFG_LOCKTANKCACHE_MASK | inl(emu->port + HCFG), emu->port + HCFG);
2466 snd_emu10k1_ptr_write(emu, TCB, 0, emu->fx8010.etram_pages.addr);
2467 snd_emu10k1_ptr_write(emu, TCBS, 0, size_reg);
2468 outl(inl(emu->port + HCFG) & ~HCFG_LOCKTANKCACHE_MASK, emu->port + HCFG);
2472 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg | A_DBG_SINGLE_STEP);
2474 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg | EMU10K1_DBG_SINGLE_STEP);
2476 len = emu->audigy ? 0x200 : 0x100;
2477 for (i = 0; i < len; i++)
2478 snd_emu10k1_ptr_write(emu, emu->gpr_base + i, 0, emu->saved_gpr[i]);
2480 len = emu->audigy ? 0x100 : 0xa0;
2481 for (i = 0; i < len; i++) {
2482 snd_emu10k1_ptr_write(emu, TANKMEMDATAREGBASE + i, 0,
2483 emu->tram_val_saved[i]);
2485 snd_emu10k1_ptr_write(emu, TANKMEMADDRREGBASE + i, 0,
2486 emu->tram_addr_saved[i]);
2488 snd_emu10k1_ptr_write(emu, TANKMEMADDRREGBASE + i, 0,
2489 emu->tram_addr_saved[i] << 12);
2490 snd_emu10k1_ptr_write(emu, TANKMEMADDRREGBASE + i, 0,
2491 emu->tram_addr_saved[i] >> 20);
2495 len = emu->audigy ? 2 * 1024 : 2 * 512;
2496 for (i = 0; i < len; i++)
2497 snd_emu10k1_efx_write(emu, i, emu->saved_icode[i]);
2499 /* start FX processor when the DSP code is updated */
2501 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg);
2503 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg);