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/vmalloc.h>
33 #include <linux/init.h>
34 #include <sound/core.h>
35 #include <sound/emu10k1.h>
37 #if 0 /* for testing purposes - digital out -> capture */
38 #define EMU10K1_CAPTURE_DIGITAL_OUT
40 #if 0 /* for testing purposes - set S/PDIF to AC3 output */
41 #define EMU10K1_SET_AC3_IEC958
43 #if 0 /* for testing purposes - feed the front signal to Center/LFE outputs */
44 #define EMU10K1_CENTER_LFE_FROM_FRONT
51 static char *fxbuses[16] = {
52 /* 0x00 */ "PCM Left",
53 /* 0x01 */ "PCM Right",
54 /* 0x02 */ "PCM Surround Left",
55 /* 0x03 */ "PCM Surround Right",
56 /* 0x04 */ "MIDI Left",
57 /* 0x05 */ "MIDI Right",
64 /* 0x0c */ "MIDI Reverb",
65 /* 0x0d */ "MIDI Chorus",
70 static char *creative_ins[16] = {
71 /* 0x00 */ "AC97 Left",
72 /* 0x01 */ "AC97 Right",
73 /* 0x02 */ "TTL IEC958 Left",
74 /* 0x03 */ "TTL IEC958 Right",
75 /* 0x04 */ "Zoom Video Left",
76 /* 0x05 */ "Zoom Video Right",
77 /* 0x06 */ "Optical IEC958 Left",
78 /* 0x07 */ "Optical IEC958 Right",
79 /* 0x08 */ "Line/Mic 1 Left",
80 /* 0x09 */ "Line/Mic 1 Right",
81 /* 0x0a */ "Coaxial IEC958 Left",
82 /* 0x0b */ "Coaxial IEC958 Right",
83 /* 0x0c */ "Line/Mic 2 Left",
84 /* 0x0d */ "Line/Mic 2 Right",
89 static char *audigy_ins[16] = {
90 /* 0x00 */ "AC97 Left",
91 /* 0x01 */ "AC97 Right",
92 /* 0x02 */ "Audigy CD Left",
93 /* 0x03 */ "Audigy CD Right",
94 /* 0x04 */ "Optical IEC958 Left",
95 /* 0x05 */ "Optical IEC958 Right",
98 /* 0x08 */ "Line/Mic 2 Left",
99 /* 0x09 */ "Line/Mic 2 Right",
100 /* 0x0a */ "SPDIF Left",
101 /* 0x0b */ "SPDIF Right",
102 /* 0x0c */ "Aux2 Left",
103 /* 0x0d */ "Aux2 Right",
108 static char *creative_outs[32] = {
109 /* 0x00 */ "AC97 Left",
110 /* 0x01 */ "AC97 Right",
111 /* 0x02 */ "Optical IEC958 Left",
112 /* 0x03 */ "Optical IEC958 Right",
115 /* 0x06 */ "Headphone Left",
116 /* 0x07 */ "Headphone Right",
117 /* 0x08 */ "Surround Left",
118 /* 0x09 */ "Surround Right",
119 /* 0x0a */ "PCM Capture Left",
120 /* 0x0b */ "PCM Capture Right",
121 /* 0x0c */ "MIC Capture",
122 /* 0x0d */ "AC97 Surround Left",
123 /* 0x0e */ "AC97 Surround Right",
126 /* 0x11 */ "Analog Center",
127 /* 0x12 */ "Analog LFE",
143 static char *audigy_outs[32] = {
144 /* 0x00 */ "Digital Front Left",
145 /* 0x01 */ "Digital Front Right",
146 /* 0x02 */ "Digital Center",
147 /* 0x03 */ "Digital LEF",
148 /* 0x04 */ "Headphone Left",
149 /* 0x05 */ "Headphone Right",
150 /* 0x06 */ "Digital Rear Left",
151 /* 0x07 */ "Digital Rear Right",
152 /* 0x08 */ "Front Left",
153 /* 0x09 */ "Front Right",
158 /* 0x0e */ "Rear Left",
159 /* 0x0f */ "Rear Right",
160 /* 0x10 */ "AC97 Front Left",
161 /* 0x11 */ "AC97 Front Right",
162 /* 0x12 */ "ADC Caputre Left",
163 /* 0x13 */ "ADC Capture Right",
178 static const u32 bass_table[41][5] = {
179 { 0x3e4f844f, 0x84ed4cc3, 0x3cc69927, 0x7b03553a, 0xc4da8486 },
180 { 0x3e69a17a, 0x84c280fb, 0x3cd77cd4, 0x7b2f2a6f, 0xc4b08d1d },
181 { 0x3e82ff42, 0x849991d5, 0x3ce7466b, 0x7b5917c6, 0xc48863ee },
182 { 0x3e9bab3c, 0x847267f0, 0x3cf5ffe8, 0x7b813560, 0xc461f22c },
183 { 0x3eb3b275, 0x844ced29, 0x3d03b295, 0x7ba79a1c, 0xc43d223b },
184 { 0x3ecb2174, 0x84290c8b, 0x3d106714, 0x7bcc5ba3, 0xc419dfa5 },
185 { 0x3ee2044b, 0x8406b244, 0x3d1c2561, 0x7bef8e77, 0xc3f8170f },
186 { 0x3ef86698, 0x83e5cb96, 0x3d26f4d8, 0x7c114600, 0xc3d7b625 },
187 { 0x3f0e5390, 0x83c646c9, 0x3d30dc39, 0x7c319498, 0xc3b8ab97 },
188 { 0x3f23d60b, 0x83a81321, 0x3d39e1af, 0x7c508b9c, 0xc39ae704 },
189 { 0x3f38f884, 0x838b20d2, 0x3d420ad2, 0x7c6e3b75, 0xc37e58f1 },
190 { 0x3f4dc52c, 0x836f60ef, 0x3d495cab, 0x7c8ab3a6, 0xc362f2be },
191 { 0x3f6245e8, 0x8354c565, 0x3d4fdbb8, 0x7ca602d6, 0xc348a69b },
192 { 0x3f76845f, 0x833b40ec, 0x3d558bf0, 0x7cc036df, 0xc32f677c },
193 { 0x3f8a8a03, 0x8322c6fb, 0x3d5a70c4, 0x7cd95cd7, 0xc317290b },
194 { 0x3f9e6014, 0x830b4bc3, 0x3d5e8d25, 0x7cf1811a, 0xc2ffdfa5 },
195 { 0x3fb20fae, 0x82f4c420, 0x3d61e37f, 0x7d08af56, 0xc2e9804a },
196 { 0x3fc5a1cc, 0x82df2592, 0x3d6475c3, 0x7d1ef294, 0xc2d40096 },
197 { 0x3fd91f55, 0x82ca6632, 0x3d664564, 0x7d345541, 0xc2bf56b9 },
198 { 0x3fec9120, 0x82b67cac, 0x3d675356, 0x7d48e138, 0xc2ab796e },
199 { 0x40000000, 0x82a36037, 0x3d67a012, 0x7d5c9fc9, 0xc2985fee },
200 { 0x401374c7, 0x8291088a, 0x3d672b93, 0x7d6f99c3, 0xc28601f2 },
201 { 0x4026f857, 0x827f6dd7, 0x3d65f559, 0x7d81d77c, 0xc27457a3 },
202 { 0x403a939f, 0x826e88c5, 0x3d63fc63, 0x7d9360d4, 0xc2635996 },
203 { 0x404e4faf, 0x825e5266, 0x3d613f32, 0x7da43d42, 0xc25300c6 },
204 { 0x406235ba, 0x824ec434, 0x3d5dbbc3, 0x7db473d7, 0xc243468e },
205 { 0x40764f1f, 0x823fd80c, 0x3d596f8f, 0x7dc40b44, 0xc23424a2 },
206 { 0x408aa576, 0x82318824, 0x3d545787, 0x7dd309e2, 0xc2259509 },
207 { 0x409f4296, 0x8223cf0b, 0x3d4e7012, 0x7de175b5, 0xc2179218 },
208 { 0x40b430a0, 0x8216a7a1, 0x3d47b505, 0x7def5475, 0xc20a1670 },
209 { 0x40c97a0a, 0x820a0d12, 0x3d4021a1, 0x7dfcab8d, 0xc1fd1cf5 },
210 { 0x40df29a6, 0x81fdfad6, 0x3d37b08d, 0x7e098028, 0xc1f0a0ca },
211 { 0x40f54ab1, 0x81f26ca9, 0x3d2e5bd1, 0x7e15d72b, 0xc1e49d52 },
212 { 0x410be8da, 0x81e75e89, 0x3d241cce, 0x7e21b544, 0xc1d90e24 },
213 { 0x41231051, 0x81dcccb3, 0x3d18ec37, 0x7e2d1ee6, 0xc1cdef10 },
214 { 0x413acdd0, 0x81d2b39e, 0x3d0cc20a, 0x7e38184e, 0xc1c33c13 },
215 { 0x41532ea7, 0x81c90ffb, 0x3cff9585, 0x7e42a58b, 0xc1b8f15a },
216 { 0x416c40cd, 0x81bfdeb2, 0x3cf15d21, 0x7e4cca7c, 0xc1af0b3f },
217 { 0x418612ea, 0x81b71cdc, 0x3ce20e85, 0x7e568ad3, 0xc1a58640 },
218 { 0x41a0b465, 0x81aec7c5, 0x3cd19e7c, 0x7e5fea1e, 0xc19c5f03 },
219 { 0x41bc3573, 0x81a6dcea, 0x3cc000e9, 0x7e68ebc2, 0xc1939250 }
222 static const u32 treble_table[41][5] = {
223 { 0x0125cba9, 0xfed5debd, 0x00599b6c, 0x0d2506da, 0xfa85b354 },
224 { 0x0142f67e, 0xfeb03163, 0x0066cd0f, 0x0d14c69d, 0xfa914473 },
225 { 0x016328bd, 0xfe860158, 0x0075b7f2, 0x0d03eb27, 0xfa9d32d2 },
226 { 0x0186b438, 0xfe56c982, 0x00869234, 0x0cf27048, 0xfaa97fca },
227 { 0x01adf358, 0xfe21f5fe, 0x00999842, 0x0ce051c2, 0xfab62ca5 },
228 { 0x01d949fa, 0xfde6e287, 0x00af0d8d, 0x0ccd8b4a, 0xfac33aa7 },
229 { 0x02092669, 0xfda4d8bf, 0x00c73d4c, 0x0cba1884, 0xfad0ab07 },
230 { 0x023e0268, 0xfd5b0e4a, 0x00e27b54, 0x0ca5f509, 0xfade7ef2 },
231 { 0x0278645c, 0xfd08a2b0, 0x01012509, 0x0c911c63, 0xfaecb788 },
232 { 0x02b8e091, 0xfcac9d1a, 0x0123a262, 0x0c7b8a14, 0xfafb55df },
233 { 0x03001a9a, 0xfc45e9ce, 0x014a6709, 0x0c65398f, 0xfb0a5aff },
234 { 0x034ec6d7, 0xfbd3576b, 0x0175f397, 0x0c4e2643, 0xfb19c7e4 },
235 { 0x03a5ac15, 0xfb5393ee, 0x01a6d6ed, 0x0c364b94, 0xfb299d7c },
236 { 0x0405a562, 0xfac52968, 0x01ddafae, 0x0c1da4e2, 0xfb39dca5 },
237 { 0x046fa3fe, 0xfa267a66, 0x021b2ddd, 0x0c042d8d, 0xfb4a8631 },
238 { 0x04e4b17f, 0xf975be0f, 0x0260149f, 0x0be9e0f2, 0xfb5b9ae0 },
239 { 0x0565f220, 0xf8b0fbe5, 0x02ad3c29, 0x0bceba73, 0xfb6d1b60 },
240 { 0x05f4a745, 0xf7d60722, 0x030393d4, 0x0bb2b578, 0xfb7f084d },
241 { 0x06923236, 0xf6e279bd, 0x03642465, 0x0b95cd75, 0xfb916233 },
242 { 0x07401713, 0xf5d3aef9, 0x03d01283, 0x0b77fded, 0xfba42984 },
243 { 0x08000000, 0xf4a6bd88, 0x0448a161, 0x0b594278, 0xfbb75e9f },
244 { 0x08d3c097, 0xf3587131, 0x04cf35a4, 0x0b3996c9, 0xfbcb01cb },
245 { 0x09bd59a2, 0xf1e543f9, 0x05655880, 0x0b18f6b2, 0xfbdf1333 },
246 { 0x0abefd0f, 0xf04956ca, 0x060cbb12, 0x0af75e2c, 0xfbf392e8 },
247 { 0x0bdb123e, 0xee806984, 0x06c739fe, 0x0ad4c962, 0xfc0880dd },
248 { 0x0d143a94, 0xec85d287, 0x0796e150, 0x0ab134b0, 0xfc1ddce5 },
249 { 0x0e6d5664, 0xea547598, 0x087df0a0, 0x0a8c9cb6, 0xfc33a6ad },
250 { 0x0fe98a2a, 0xe7e6ba35, 0x097edf83, 0x0a66fe5b, 0xfc49ddc2 },
251 { 0x118c4421, 0xe536813a, 0x0a9c6248, 0x0a4056d7, 0xfc608185 },
252 { 0x1359422e, 0xe23d19eb, 0x0bd96efb, 0x0a18a3bf, 0xfc77912c },
253 { 0x1554982b, 0xdef33645, 0x0d3942bd, 0x09efe312, 0xfc8f0bc1 },
254 { 0x1782b68a, 0xdb50deb1, 0x0ebf676d, 0x09c6133f, 0xfca6f019 },
255 { 0x19e8715d, 0xd74d64fd, 0x106fb999, 0x099b3337, 0xfcbf3cd6 },
256 { 0x1c8b07b8, 0xd2df56ab, 0x124e6ec8, 0x096f4274, 0xfcd7f060 },
257 { 0x1f702b6d, 0xcdfc6e92, 0x14601c10, 0x0942410b, 0xfcf108e5 },
258 { 0x229e0933, 0xc89985cd, 0x16a9bcfa, 0x09142fb5, 0xfd0a8451 },
259 { 0x261b5118, 0xc2aa8409, 0x1930bab6, 0x08e50fdc, 0xfd24604d },
260 { 0x29ef3f5d, 0xbc224f28, 0x1bfaf396, 0x08b4e3aa, 0xfd3e9a3b },
261 { 0x2e21a59b, 0xb4f2ba46, 0x1f0ec2d6, 0x0883ae15, 0xfd592f33 },
262 { 0x32baf44b, 0xad0c7429, 0x227308a3, 0x085172eb, 0xfd741bfd },
263 { 0x37c4448b, 0xa45ef51d, 0x262f3267, 0x081e36dc, 0xfd8f5d14 }
266 static const u32 db_table[101] = {
267 0x00000000, 0x01571f82, 0x01674b41, 0x01783a1b, 0x0189f540,
268 0x019c8651, 0x01aff763, 0x01c45306, 0x01d9a446, 0x01eff6b8,
269 0x0207567a, 0x021fd03d, 0x0239714c, 0x02544792, 0x027061a1,
270 0x028dcebb, 0x02ac9edc, 0x02cce2bf, 0x02eeabe8, 0x03120cb0,
271 0x0337184e, 0x035de2df, 0x03868173, 0x03b10a18, 0x03dd93e9,
272 0x040c3713, 0x043d0cea, 0x04702ff3, 0x04a5bbf2, 0x04ddcdfb,
273 0x0518847f, 0x0555ff62, 0x05966005, 0x05d9c95d, 0x06206005,
274 0x066a4a52, 0x06b7b067, 0x0708bc4c, 0x075d9a01, 0x07b6779d,
275 0x08138561, 0x0874f5d5, 0x08dafde1, 0x0945d4ed, 0x09b5b4fd,
276 0x0a2adad1, 0x0aa58605, 0x0b25f936, 0x0bac7a24, 0x0c3951d8,
277 0x0ccccccc, 0x0d673b17, 0x0e08f093, 0x0eb24510, 0x0f639481,
278 0x101d3f2d, 0x10dfa9e6, 0x11ab3e3f, 0x12806ac3, 0x135fa333,
279 0x144960c5, 0x153e2266, 0x163e6cfe, 0x174acbb7, 0x1863d04d,
280 0x198a1357, 0x1abe349f, 0x1c00db77, 0x1d52b712, 0x1eb47ee6,
281 0x2026f30f, 0x21aadcb6, 0x23410e7e, 0x24ea64f9, 0x26a7c71d,
282 0x287a26c4, 0x2a62812c, 0x2c61df84, 0x2e795779, 0x30aa0bcf,
283 0x32f52cfe, 0x355bf9d8, 0x37dfc033, 0x3a81dda4, 0x3d43c038,
284 0x4026e73c, 0x432ce40f, 0x46575af8, 0x49a8040f, 0x4d20ac2a,
285 0x50c335d3, 0x54919a57, 0x588dead1, 0x5cba514a, 0x611911ea,
286 0x65ac8c2f, 0x6a773c39, 0x6f7bbc23, 0x74bcc56c, 0x7a3d3272,
290 static const u32 onoff_table[2] = {
291 0x00000000, 0x00000001
297 static inline mm_segment_t snd_enter_user(void)
299 mm_segment_t fs = get_fs();
304 static inline void snd_leave_user(mm_segment_t fs)
313 static int snd_emu10k1_gpr_ctl_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
315 struct snd_emu10k1_fx8010_ctl *ctl =
316 (struct snd_emu10k1_fx8010_ctl *) kcontrol->private_value;
318 if (ctl->min == 0 && ctl->max == 1)
319 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
321 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
322 uinfo->count = ctl->vcount;
323 uinfo->value.integer.min = ctl->min;
324 uinfo->value.integer.max = ctl->max;
328 static int snd_emu10k1_gpr_ctl_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
330 struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
331 struct snd_emu10k1_fx8010_ctl *ctl =
332 (struct snd_emu10k1_fx8010_ctl *) kcontrol->private_value;
336 spin_lock_irqsave(&emu->reg_lock, flags);
337 for (i = 0; i < ctl->vcount; i++)
338 ucontrol->value.integer.value[i] = ctl->value[i];
339 spin_unlock_irqrestore(&emu->reg_lock, flags);
343 static int snd_emu10k1_gpr_ctl_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
345 struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
346 struct snd_emu10k1_fx8010_ctl *ctl =
347 (struct snd_emu10k1_fx8010_ctl *) kcontrol->private_value;
349 unsigned int nval, val;
353 spin_lock_irqsave(&emu->reg_lock, flags);
354 for (i = 0; i < ctl->vcount; i++) {
355 nval = ucontrol->value.integer.value[i];
360 if (nval != ctl->value[i])
362 val = ctl->value[i] = nval;
363 switch (ctl->translation) {
364 case EMU10K1_GPR_TRANSLATION_NONE:
365 snd_emu10k1_ptr_write(emu, emu->gpr_base + ctl->gpr[i], 0, val);
367 case EMU10K1_GPR_TRANSLATION_TABLE100:
368 snd_emu10k1_ptr_write(emu, emu->gpr_base + ctl->gpr[i], 0, db_table[val]);
370 case EMU10K1_GPR_TRANSLATION_BASS:
371 if ((ctl->count % 5) != 0 || (ctl->count / 5) != ctl->vcount) {
375 for (j = 0; j < 5; j++)
376 snd_emu10k1_ptr_write(emu, emu->gpr_base + ctl->gpr[j * ctl->vcount + i], 0, bass_table[val][j]);
378 case EMU10K1_GPR_TRANSLATION_TREBLE:
379 if ((ctl->count % 5) != 0 || (ctl->count / 5) != ctl->vcount) {
383 for (j = 0; j < 5; j++)
384 snd_emu10k1_ptr_write(emu, emu->gpr_base + ctl->gpr[j * ctl->vcount + i], 0, treble_table[val][j]);
386 case EMU10K1_GPR_TRANSLATION_ONOFF:
387 snd_emu10k1_ptr_write(emu, emu->gpr_base + ctl->gpr[i], 0, onoff_table[val]);
392 spin_unlock_irqrestore(&emu->reg_lock, flags);
400 static void snd_emu10k1_fx8010_interrupt(struct snd_emu10k1 *emu)
402 struct snd_emu10k1_fx8010_irq *irq, *nirq;
404 irq = emu->fx8010.irq_handlers;
406 nirq = irq->next; /* irq ptr can be removed from list */
407 if (snd_emu10k1_ptr_read(emu, emu->gpr_base + irq->gpr_running, 0) & 0xffff0000) {
409 irq->handler(emu, irq->private_data);
410 snd_emu10k1_ptr_write(emu, emu->gpr_base + irq->gpr_running, 0, 1);
416 int snd_emu10k1_fx8010_register_irq_handler(struct snd_emu10k1 *emu,
417 snd_fx8010_irq_handler_t *handler,
418 unsigned char gpr_running,
420 struct snd_emu10k1_fx8010_irq **r_irq)
422 struct snd_emu10k1_fx8010_irq *irq;
425 irq = kmalloc(sizeof(*irq), GFP_ATOMIC);
428 irq->handler = handler;
429 irq->gpr_running = gpr_running;
430 irq->private_data = private_data;
432 spin_lock_irqsave(&emu->fx8010.irq_lock, flags);
433 if (emu->fx8010.irq_handlers == NULL) {
434 emu->fx8010.irq_handlers = irq;
435 emu->dsp_interrupt = snd_emu10k1_fx8010_interrupt;
436 snd_emu10k1_intr_enable(emu, INTE_FXDSPENABLE);
438 irq->next = emu->fx8010.irq_handlers;
439 emu->fx8010.irq_handlers = irq;
441 spin_unlock_irqrestore(&emu->fx8010.irq_lock, flags);
447 int snd_emu10k1_fx8010_unregister_irq_handler(struct snd_emu10k1 *emu,
448 struct snd_emu10k1_fx8010_irq *irq)
450 struct snd_emu10k1_fx8010_irq *tmp;
453 spin_lock_irqsave(&emu->fx8010.irq_lock, flags);
454 if ((tmp = emu->fx8010.irq_handlers) == irq) {
455 emu->fx8010.irq_handlers = tmp->next;
456 if (emu->fx8010.irq_handlers == NULL) {
457 snd_emu10k1_intr_disable(emu, INTE_FXDSPENABLE);
458 emu->dsp_interrupt = NULL;
461 while (tmp && tmp->next != irq)
464 tmp->next = tmp->next->next;
466 spin_unlock_irqrestore(&emu->fx8010.irq_lock, flags);
471 /*************************************************************************
472 * EMU10K1 effect manager
473 *************************************************************************/
475 static void snd_emu10k1_write_op(struct snd_emu10k1_fx8010_code *icode,
477 u32 op, u32 r, u32 a, u32 x, u32 y)
480 snd_assert(*ptr < 512, return);
481 code = (u_int32_t __force *)icode->code + (*ptr) * 2;
482 set_bit(*ptr, icode->code_valid);
483 code[0] = ((x & 0x3ff) << 10) | (y & 0x3ff);
484 code[1] = ((op & 0x0f) << 20) | ((r & 0x3ff) << 10) | (a & 0x3ff);
488 #define OP(icode, ptr, op, r, a, x, y) \
489 snd_emu10k1_write_op(icode, ptr, op, r, a, x, y)
491 static void snd_emu10k1_audigy_write_op(struct snd_emu10k1_fx8010_code *icode,
493 u32 op, u32 r, u32 a, u32 x, u32 y)
496 snd_assert(*ptr < 1024, return);
497 code = (u_int32_t __force *)icode->code + (*ptr) * 2;
498 set_bit(*ptr, icode->code_valid);
499 code[0] = ((x & 0x7ff) << 12) | (y & 0x7ff);
500 code[1] = ((op & 0x0f) << 24) | ((r & 0x7ff) << 12) | (a & 0x7ff);
504 #define A_OP(icode, ptr, op, r, a, x, y) \
505 snd_emu10k1_audigy_write_op(icode, ptr, op, r, a, x, y)
507 static void snd_emu10k1_efx_write(struct snd_emu10k1 *emu, unsigned int pc, unsigned int data)
509 pc += emu->audigy ? A_MICROCODEBASE : MICROCODEBASE;
510 snd_emu10k1_ptr_write(emu, pc, 0, data);
513 unsigned int snd_emu10k1_efx_read(struct snd_emu10k1 *emu, unsigned int pc)
515 pc += emu->audigy ? A_MICROCODEBASE : MICROCODEBASE;
516 return snd_emu10k1_ptr_read(emu, pc, 0);
519 static int snd_emu10k1_gpr_poke(struct snd_emu10k1 *emu,
520 struct snd_emu10k1_fx8010_code *icode)
525 for (gpr = 0; gpr < (emu->audigy ? 0x200 : 0x100); gpr++) {
526 if (!test_bit(gpr, icode->gpr_valid))
528 if (get_user(val, &icode->gpr_map[gpr]))
530 snd_emu10k1_ptr_write(emu, emu->gpr_base + gpr, 0, val);
535 static int snd_emu10k1_gpr_peek(struct snd_emu10k1 *emu,
536 struct snd_emu10k1_fx8010_code *icode)
541 for (gpr = 0; gpr < (emu->audigy ? 0x200 : 0x100); gpr++) {
542 set_bit(gpr, icode->gpr_valid);
543 val = snd_emu10k1_ptr_read(emu, emu->gpr_base + gpr, 0);
544 if (put_user(val, &icode->gpr_map[gpr]))
550 static int snd_emu10k1_tram_poke(struct snd_emu10k1 *emu,
551 struct snd_emu10k1_fx8010_code *icode)
556 for (tram = 0; tram < (emu->audigy ? 0x100 : 0xa0); tram++) {
557 if (!test_bit(tram, icode->tram_valid))
559 if (get_user(val, &icode->tram_data_map[tram]) ||
560 get_user(addr, &icode->tram_addr_map[tram]))
562 snd_emu10k1_ptr_write(emu, TANKMEMDATAREGBASE + tram, 0, val);
564 snd_emu10k1_ptr_write(emu, TANKMEMADDRREGBASE + tram, 0, addr);
566 snd_emu10k1_ptr_write(emu, TANKMEMADDRREGBASE + tram, 0, addr << 12);
567 snd_emu10k1_ptr_write(emu, A_TANKMEMCTLREGBASE + tram, 0, addr >> 20);
573 static int snd_emu10k1_tram_peek(struct snd_emu10k1 *emu,
574 struct snd_emu10k1_fx8010_code *icode)
579 memset(icode->tram_valid, 0, sizeof(icode->tram_valid));
580 for (tram = 0; tram < (emu->audigy ? 0x100 : 0xa0); tram++) {
581 set_bit(tram, icode->tram_valid);
582 val = snd_emu10k1_ptr_read(emu, TANKMEMDATAREGBASE + tram, 0);
584 addr = snd_emu10k1_ptr_read(emu, TANKMEMADDRREGBASE + tram, 0);
586 addr = snd_emu10k1_ptr_read(emu, TANKMEMADDRREGBASE + tram, 0) >> 12;
587 addr |= snd_emu10k1_ptr_read(emu, A_TANKMEMCTLREGBASE + tram, 0) << 20;
589 if (put_user(val, &icode->tram_data_map[tram]) ||
590 put_user(addr, &icode->tram_addr_map[tram]))
596 static int snd_emu10k1_code_poke(struct snd_emu10k1 *emu,
597 struct snd_emu10k1_fx8010_code *icode)
601 for (pc = 0; pc < (emu->audigy ? 2*1024 : 2*512); pc += 2) {
602 if (!test_bit(pc / 2, icode->code_valid))
604 if (get_user(lo, &icode->code[pc + 0]) ||
605 get_user(hi, &icode->code[pc + 1]))
607 snd_emu10k1_efx_write(emu, pc + 0, lo);
608 snd_emu10k1_efx_write(emu, pc + 1, hi);
613 static int snd_emu10k1_code_peek(struct snd_emu10k1 *emu,
614 struct snd_emu10k1_fx8010_code *icode)
618 memset(icode->code_valid, 0, sizeof(icode->code_valid));
619 for (pc = 0; pc < (emu->audigy ? 2*1024 : 2*512); pc += 2) {
620 set_bit(pc / 2, icode->code_valid);
621 if (put_user(snd_emu10k1_efx_read(emu, pc + 0), &icode->code[pc + 0]))
623 if (put_user(snd_emu10k1_efx_read(emu, pc + 1), &icode->code[pc + 1]))
629 static struct snd_emu10k1_fx8010_ctl *
630 snd_emu10k1_look_for_ctl(struct snd_emu10k1 *emu, struct snd_ctl_elem_id *id)
632 struct snd_emu10k1_fx8010_ctl *ctl;
633 struct snd_kcontrol *kcontrol;
634 struct list_head *list;
636 list_for_each(list, &emu->fx8010.gpr_ctl) {
637 ctl = emu10k1_gpr_ctl(list);
638 kcontrol = ctl->kcontrol;
639 if (kcontrol->id.iface == id->iface &&
640 !strcmp(kcontrol->id.name, id->name) &&
641 kcontrol->id.index == id->index)
647 static int snd_emu10k1_verify_controls(struct snd_emu10k1 *emu,
648 struct snd_emu10k1_fx8010_code *icode)
651 struct snd_ctl_elem_id __user *_id;
652 struct snd_ctl_elem_id id;
653 struct snd_emu10k1_fx8010_control_gpr __user *_gctl;
654 struct snd_emu10k1_fx8010_control_gpr *gctl;
657 for (i = 0, _id = icode->gpr_del_controls;
658 i < icode->gpr_del_control_count; i++, _id++) {
659 if (copy_from_user(&id, _id, sizeof(id)))
661 if (snd_emu10k1_look_for_ctl(emu, &id) == NULL)
664 gctl = kmalloc(sizeof(*gctl), GFP_KERNEL);
668 for (i = 0, _gctl = icode->gpr_add_controls;
669 i < icode->gpr_add_control_count; i++, _gctl++) {
670 if (copy_from_user(gctl, _gctl, sizeof(*gctl))) {
674 if (snd_emu10k1_look_for_ctl(emu, &gctl->id))
676 down_read(&emu->card->controls_rwsem);
677 if (snd_ctl_find_id(emu->card, &gctl->id) != NULL) {
678 up_read(&emu->card->controls_rwsem);
682 up_read(&emu->card->controls_rwsem);
683 if (gctl->id.iface != SNDRV_CTL_ELEM_IFACE_MIXER &&
684 gctl->id.iface != SNDRV_CTL_ELEM_IFACE_PCM) {
689 for (i = 0, _gctl = icode->gpr_list_controls;
690 i < icode->gpr_list_control_count; i++, _gctl++) {
691 /* FIXME: we need to check the WRITE access */
692 if (copy_from_user(gctl, _gctl, sizeof(*gctl))) {
702 static void snd_emu10k1_ctl_private_free(struct snd_kcontrol *kctl)
704 struct snd_emu10k1_fx8010_ctl *ctl;
706 ctl = (struct snd_emu10k1_fx8010_ctl *) kctl->private_value;
707 kctl->private_value = 0;
708 list_del(&ctl->list);
712 static int snd_emu10k1_add_controls(struct snd_emu10k1 *emu,
713 struct snd_emu10k1_fx8010_code *icode)
716 struct snd_emu10k1_fx8010_control_gpr __user *_gctl;
717 struct snd_emu10k1_fx8010_control_gpr *gctl;
718 struct snd_emu10k1_fx8010_ctl *ctl, *nctl;
719 struct snd_kcontrol_new knew;
720 struct snd_kcontrol *kctl;
721 struct snd_ctl_elem_value *val;
724 val = kmalloc(sizeof(*val), GFP_KERNEL);
725 gctl = kmalloc(sizeof(*gctl), GFP_KERNEL);
726 nctl = kmalloc(sizeof(*nctl), GFP_KERNEL);
727 if (!val || !gctl || !nctl) {
732 for (i = 0, _gctl = icode->gpr_add_controls;
733 i < icode->gpr_add_control_count; i++, _gctl++) {
734 if (copy_from_user(gctl, _gctl, sizeof(*gctl))) {
738 if (gctl->id.iface != SNDRV_CTL_ELEM_IFACE_MIXER &&
739 gctl->id.iface != SNDRV_CTL_ELEM_IFACE_PCM) {
743 if (! gctl->id.name[0]) {
747 ctl = snd_emu10k1_look_for_ctl(emu, &gctl->id);
748 memset(&knew, 0, sizeof(knew));
749 knew.iface = gctl->id.iface;
750 knew.name = gctl->id.name;
751 knew.index = gctl->id.index;
752 knew.device = gctl->id.device;
753 knew.subdevice = gctl->id.subdevice;
754 knew.info = snd_emu10k1_gpr_ctl_info;
755 knew.get = snd_emu10k1_gpr_ctl_get;
756 knew.put = snd_emu10k1_gpr_ctl_put;
757 memset(nctl, 0, sizeof(*nctl));
758 nctl->vcount = gctl->vcount;
759 nctl->count = gctl->count;
760 for (j = 0; j < 32; j++) {
761 nctl->gpr[j] = gctl->gpr[j];
762 nctl->value[j] = ~gctl->value[j]; /* inverted, we want to write new value in gpr_ctl_put() */
763 val->value.integer.value[j] = gctl->value[j];
765 nctl->min = gctl->min;
766 nctl->max = gctl->max;
767 nctl->translation = gctl->translation;
769 ctl = kmalloc(sizeof(*ctl), GFP_KERNEL);
774 knew.private_value = (unsigned long)ctl;
776 if ((err = snd_ctl_add(emu->card, kctl = snd_ctl_new1(&knew, emu))) < 0) {
780 kctl->private_free = snd_emu10k1_ctl_private_free;
781 ctl->kcontrol = kctl;
782 list_add_tail(&ctl->list, &emu->fx8010.gpr_ctl);
785 nctl->list = ctl->list;
786 nctl->kcontrol = ctl->kcontrol;
788 snd_ctl_notify(emu->card, SNDRV_CTL_EVENT_MASK_VALUE |
789 SNDRV_CTL_EVENT_MASK_INFO, &ctl->kcontrol->id);
791 snd_emu10k1_gpr_ctl_put(ctl->kcontrol, val);
800 static int snd_emu10k1_del_controls(struct snd_emu10k1 *emu,
801 struct snd_emu10k1_fx8010_code *icode)
804 struct snd_ctl_elem_id id;
805 struct snd_ctl_elem_id __user *_id;
806 struct snd_emu10k1_fx8010_ctl *ctl;
807 struct snd_card *card = emu->card;
809 for (i = 0, _id = icode->gpr_del_controls;
810 i < icode->gpr_del_control_count; i++, _id++) {
811 if (copy_from_user(&id, _id, sizeof(id)))
813 down_write(&card->controls_rwsem);
814 ctl = snd_emu10k1_look_for_ctl(emu, &id);
816 snd_ctl_remove(card, ctl->kcontrol);
817 up_write(&card->controls_rwsem);
822 static int snd_emu10k1_list_controls(struct snd_emu10k1 *emu,
823 struct snd_emu10k1_fx8010_code *icode)
825 unsigned int i = 0, j;
826 unsigned int total = 0;
827 struct snd_emu10k1_fx8010_control_gpr *gctl;
828 struct snd_emu10k1_fx8010_control_gpr __user *_gctl;
829 struct snd_emu10k1_fx8010_ctl *ctl;
830 struct snd_ctl_elem_id *id;
831 struct list_head *list;
833 gctl = kmalloc(sizeof(*gctl), GFP_KERNEL);
837 _gctl = icode->gpr_list_controls;
838 list_for_each(list, &emu->fx8010.gpr_ctl) {
839 ctl = emu10k1_gpr_ctl(list);
841 if (_gctl && i < icode->gpr_list_control_count) {
842 memset(gctl, 0, sizeof(*gctl));
843 id = &ctl->kcontrol->id;
844 gctl->id.iface = id->iface;
845 strlcpy(gctl->id.name, id->name, sizeof(gctl->id.name));
846 gctl->id.index = id->index;
847 gctl->id.device = id->device;
848 gctl->id.subdevice = id->subdevice;
849 gctl->vcount = ctl->vcount;
850 gctl->count = ctl->count;
851 for (j = 0; j < 32; j++) {
852 gctl->gpr[j] = ctl->gpr[j];
853 gctl->value[j] = ctl->value[j];
855 gctl->min = ctl->min;
856 gctl->max = ctl->max;
857 gctl->translation = ctl->translation;
858 if (copy_to_user(_gctl, gctl, sizeof(*gctl))) {
866 icode->gpr_list_control_total = total;
871 static int snd_emu10k1_icode_poke(struct snd_emu10k1 *emu,
872 struct snd_emu10k1_fx8010_code *icode)
876 down(&emu->fx8010.lock);
877 if ((err = snd_emu10k1_verify_controls(emu, icode)) < 0)
879 strlcpy(emu->fx8010.name, icode->name, sizeof(emu->fx8010.name));
880 /* stop FX processor - this may be dangerous, but it's better to miss
881 some samples than generate wrong ones - [jk] */
883 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg | A_DBG_SINGLE_STEP);
885 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg | EMU10K1_DBG_SINGLE_STEP);
886 /* ok, do the main job */
887 if ((err = snd_emu10k1_del_controls(emu, icode)) < 0 ||
888 (err = snd_emu10k1_gpr_poke(emu, icode)) < 0 ||
889 (err = snd_emu10k1_tram_poke(emu, icode)) < 0 ||
890 (err = snd_emu10k1_code_poke(emu, icode)) < 0 ||
891 (err = snd_emu10k1_add_controls(emu, icode)) < 0)
893 /* start FX processor when the DSP code is updated */
895 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg);
897 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg);
899 up(&emu->fx8010.lock);
903 static int snd_emu10k1_icode_peek(struct snd_emu10k1 *emu,
904 struct snd_emu10k1_fx8010_code *icode)
908 down(&emu->fx8010.lock);
909 strlcpy(icode->name, emu->fx8010.name, sizeof(icode->name));
910 /* ok, do the main job */
911 err = snd_emu10k1_gpr_peek(emu, icode);
913 err = snd_emu10k1_tram_peek(emu, icode);
915 err = snd_emu10k1_code_peek(emu, icode);
917 err = snd_emu10k1_list_controls(emu, icode);
918 up(&emu->fx8010.lock);
922 static int snd_emu10k1_ipcm_poke(struct snd_emu10k1 *emu,
923 struct snd_emu10k1_fx8010_pcm_rec *ipcm)
927 struct snd_emu10k1_fx8010_pcm *pcm;
929 if (ipcm->substream >= EMU10K1_FX8010_PCM_COUNT)
931 if (ipcm->channels > 32)
933 pcm = &emu->fx8010.pcm[ipcm->substream];
934 down(&emu->fx8010.lock);
935 spin_lock_irq(&emu->reg_lock);
940 if (ipcm->channels == 0) { /* remove */
943 /* FIXME: we need to add universal code to the PCM transfer routine */
944 if (ipcm->channels != 2) {
950 pcm->channels = ipcm->channels;
951 pcm->tram_start = ipcm->tram_start;
952 pcm->buffer_size = ipcm->buffer_size;
953 pcm->gpr_size = ipcm->gpr_size;
954 pcm->gpr_count = ipcm->gpr_count;
955 pcm->gpr_tmpcount = ipcm->gpr_tmpcount;
956 pcm->gpr_ptr = ipcm->gpr_ptr;
957 pcm->gpr_trigger = ipcm->gpr_trigger;
958 pcm->gpr_running = ipcm->gpr_running;
959 for (i = 0; i < pcm->channels; i++)
960 pcm->etram[i] = ipcm->etram[i];
963 spin_unlock_irq(&emu->reg_lock);
964 up(&emu->fx8010.lock);
968 static int snd_emu10k1_ipcm_peek(struct snd_emu10k1 *emu,
969 struct snd_emu10k1_fx8010_pcm_rec *ipcm)
973 struct snd_emu10k1_fx8010_pcm *pcm;
975 if (ipcm->substream >= EMU10K1_FX8010_PCM_COUNT)
977 pcm = &emu->fx8010.pcm[ipcm->substream];
978 down(&emu->fx8010.lock);
979 spin_lock_irq(&emu->reg_lock);
980 ipcm->channels = pcm->channels;
981 ipcm->tram_start = pcm->tram_start;
982 ipcm->buffer_size = pcm->buffer_size;
983 ipcm->gpr_size = pcm->gpr_size;
984 ipcm->gpr_ptr = pcm->gpr_ptr;
985 ipcm->gpr_count = pcm->gpr_count;
986 ipcm->gpr_tmpcount = pcm->gpr_tmpcount;
987 ipcm->gpr_trigger = pcm->gpr_trigger;
988 ipcm->gpr_running = pcm->gpr_running;
989 for (i = 0; i < pcm->channels; i++)
990 ipcm->etram[i] = pcm->etram[i];
991 ipcm->res1 = ipcm->res2 = 0;
993 spin_unlock_irq(&emu->reg_lock);
994 up(&emu->fx8010.lock);
998 #define SND_EMU10K1_GPR_CONTROLS 44
999 #define SND_EMU10K1_INPUTS 12
1000 #define SND_EMU10K1_PLAYBACK_CHANNELS 8
1001 #define SND_EMU10K1_CAPTURE_CHANNELS 4
1003 static void __devinit
1004 snd_emu10k1_init_mono_control(struct snd_emu10k1_fx8010_control_gpr *ctl,
1005 const char *name, int gpr, int defval)
1007 ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1008 strcpy(ctl->id.name, name);
1009 ctl->vcount = ctl->count = 1;
1010 ctl->gpr[0] = gpr + 0; ctl->value[0] = defval;
1013 ctl->translation = EMU10K1_GPR_TRANSLATION_TABLE100;
1016 static void __devinit
1017 snd_emu10k1_init_stereo_control(struct snd_emu10k1_fx8010_control_gpr *ctl,
1018 const char *name, int gpr, int defval)
1020 ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1021 strcpy(ctl->id.name, name);
1022 ctl->vcount = ctl->count = 2;
1023 ctl->gpr[0] = gpr + 0; ctl->value[0] = defval;
1024 ctl->gpr[1] = gpr + 1; ctl->value[1] = defval;
1027 ctl->translation = EMU10K1_GPR_TRANSLATION_TABLE100;
1030 static void __devinit
1031 snd_emu10k1_init_mono_onoff_control(struct snd_emu10k1_fx8010_control_gpr *ctl,
1032 const char *name, int gpr, int defval)
1034 ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1035 strcpy(ctl->id.name, name);
1036 ctl->vcount = ctl->count = 1;
1037 ctl->gpr[0] = gpr + 0; ctl->value[0] = defval;
1040 ctl->translation = EMU10K1_GPR_TRANSLATION_ONOFF;
1043 static void __devinit
1044 snd_emu10k1_init_stereo_onoff_control(struct snd_emu10k1_fx8010_control_gpr *ctl,
1045 const char *name, int gpr, int defval)
1047 ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1048 strcpy(ctl->id.name, name);
1049 ctl->vcount = ctl->count = 2;
1050 ctl->gpr[0] = gpr + 0; ctl->value[0] = defval;
1051 ctl->gpr[1] = gpr + 1; ctl->value[1] = defval;
1054 ctl->translation = EMU10K1_GPR_TRANSLATION_ONOFF;
1059 * initial DSP configuration for Audigy
1062 static int __devinit _snd_emu10k1_audigy_init_efx(struct snd_emu10k1 *emu)
1064 int err, i, z, gpr, nctl;
1065 const int playback = 10;
1066 const int capture = playback + (SND_EMU10K1_PLAYBACK_CHANNELS * 2); /* we reserve 10 voices */
1067 const int stereo_mix = capture + 2;
1068 const int tmp = 0x88;
1070 struct snd_emu10k1_fx8010_code *icode = NULL;
1071 struct snd_emu10k1_fx8010_control_gpr *controls = NULL, *ctl;
1075 if ((icode = kzalloc(sizeof(*icode), GFP_KERNEL)) == NULL ||
1076 (icode->gpr_map = (u_int32_t __user *)
1077 kcalloc(512 + 256 + 256 + 2 * 1024, sizeof(u_int32_t),
1078 GFP_KERNEL)) == NULL ||
1079 (controls = kcalloc(SND_EMU10K1_GPR_CONTROLS,
1080 sizeof(*controls), GFP_KERNEL)) == NULL) {
1084 gpr_map = (u32 __force *)icode->gpr_map;
1086 icode->tram_data_map = icode->gpr_map + 512;
1087 icode->tram_addr_map = icode->tram_data_map + 256;
1088 icode->code = icode->tram_addr_map + 256;
1090 /* clear free GPRs */
1091 for (i = 0; i < 512; i++)
1092 set_bit(i, icode->gpr_valid);
1094 /* clear TRAM data & address lines */
1095 for (i = 0; i < 256; i++)
1096 set_bit(i, icode->tram_valid);
1098 strcpy(icode->name, "Audigy DSP code for ALSA");
1101 gpr = stereo_mix + 10;
1103 /* stop FX processor */
1104 snd_emu10k1_ptr_write(emu, A_DBG, 0, (emu->fx8010.dbg = 0) | A_DBG_SINGLE_STEP);
1108 for (z = 0; z < 80; z=z+2) {
1109 A_OP(icode, &ptr, iACC3, A_EXTOUT(z), A_FXBUS(FXBUS_PCM_LEFT_FRONT), A_C_00000000, A_C_00000000); /* left */
1110 A_OP(icode, &ptr, iACC3, A_EXTOUT(z+1), A_FXBUS(FXBUS_PCM_RIGHT_FRONT), A_C_00000000, A_C_00000000); /* right */
1112 #endif /* jcd test */
1114 /* PCM front Playback Volume (independent from stereo mix) */
1115 A_OP(icode, &ptr, iMAC0, A_GPR(playback), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LEFT_FRONT));
1116 A_OP(icode, &ptr, iMAC0, A_GPR(playback+1), A_C_00000000, A_GPR(gpr+1), A_FXBUS(FXBUS_PCM_RIGHT_FRONT));
1117 snd_emu10k1_init_stereo_control(&controls[nctl++], "PCM Front Playback Volume", gpr, 100);
1120 /* PCM Surround Playback (independent from stereo mix) */
1121 A_OP(icode, &ptr, iMAC0, A_GPR(playback+2), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LEFT_REAR));
1122 A_OP(icode, &ptr, iMAC0, A_GPR(playback+3), A_C_00000000, A_GPR(gpr+1), A_FXBUS(FXBUS_PCM_RIGHT_REAR));
1123 snd_emu10k1_init_stereo_control(&controls[nctl++], "PCM Surround Playback Volume", gpr, 100);
1126 /* PCM Side Playback (independent from stereo mix) */
1127 if (emu->card_capabilities->spk71) {
1128 A_OP(icode, &ptr, iMAC0, A_GPR(playback+6), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LEFT_SIDE));
1129 A_OP(icode, &ptr, iMAC0, A_GPR(playback+7), A_C_00000000, A_GPR(gpr+1), A_FXBUS(FXBUS_PCM_RIGHT_SIDE));
1130 snd_emu10k1_init_stereo_control(&controls[nctl++], "PCM Side Playback Volume", gpr, 100);
1134 /* PCM Center Playback (independent from stereo mix) */
1135 A_OP(icode, &ptr, iMAC0, A_GPR(playback+4), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_CENTER));
1136 snd_emu10k1_init_mono_control(&controls[nctl++], "PCM Center Playback Volume", gpr, 100);
1139 /* PCM LFE Playback (independent from stereo mix) */
1140 A_OP(icode, &ptr, iMAC0, A_GPR(playback+5), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LFE));
1141 snd_emu10k1_init_mono_control(&controls[nctl++], "PCM LFE Playback Volume", gpr, 100);
1147 /* Wave (PCM) Playback Volume (will be renamed later) */
1148 A_OP(icode, &ptr, iMAC0, A_GPR(stereo_mix), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LEFT));
1149 A_OP(icode, &ptr, iMAC0, A_GPR(stereo_mix+1), A_C_00000000, A_GPR(gpr+1), A_FXBUS(FXBUS_PCM_RIGHT));
1150 snd_emu10k1_init_stereo_control(&controls[nctl++], "Wave Playback Volume", gpr, 100);
1153 /* Synth Playback */
1154 A_OP(icode, &ptr, iMAC0, A_GPR(stereo_mix+0), A_GPR(stereo_mix+0), A_GPR(gpr), A_FXBUS(FXBUS_MIDI_LEFT));
1155 A_OP(icode, &ptr, iMAC0, A_GPR(stereo_mix+1), A_GPR(stereo_mix+1), A_GPR(gpr+1), A_FXBUS(FXBUS_MIDI_RIGHT));
1156 snd_emu10k1_init_stereo_control(&controls[nctl++], "Synth Playback Volume", gpr, 100);
1159 /* Wave (PCM) Capture */
1160 A_OP(icode, &ptr, iMAC0, A_GPR(capture+0), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LEFT));
1161 A_OP(icode, &ptr, iMAC0, A_GPR(capture+1), A_C_00000000, A_GPR(gpr+1), A_FXBUS(FXBUS_PCM_RIGHT));
1162 snd_emu10k1_init_stereo_control(&controls[nctl++], "PCM Capture Volume", gpr, 0);
1166 A_OP(icode, &ptr, iMAC0, A_GPR(capture+0), A_GPR(capture+0), A_GPR(gpr), A_FXBUS(FXBUS_MIDI_LEFT));
1167 A_OP(icode, &ptr, iMAC0, A_GPR(capture+1), A_GPR(capture+1), A_GPR(gpr+1), A_FXBUS(FXBUS_MIDI_RIGHT));
1168 snd_emu10k1_init_stereo_control(&controls[nctl++], "Synth Capture Volume", gpr, 0);
1174 #define A_ADD_VOLUME_IN(var,vol,input) \
1175 A_OP(icode, &ptr, iMAC0, A_GPR(var), A_GPR(var), A_GPR(vol), A_EXTIN(input))
1177 /* AC'97 Playback Volume - used only for mic (renamed later) */
1178 A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_AC97_L);
1179 A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_AC97_R);
1180 snd_emu10k1_init_stereo_control(&controls[nctl++], "AMic Playback Volume", gpr, 0);
1182 /* AC'97 Capture Volume - used only for mic */
1183 A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_AC97_L);
1184 A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_AC97_R);
1185 snd_emu10k1_init_stereo_control(&controls[nctl++], "Mic Capture Volume", gpr, 0);
1188 /* mic capture buffer */
1189 A_OP(icode, &ptr, iINTERP, A_EXTOUT(A_EXTOUT_MIC_CAP), A_EXTIN(A_EXTIN_AC97_L), 0xcd, A_EXTIN(A_EXTIN_AC97_R));
1191 /* Audigy CD Playback Volume */
1192 A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_SPDIF_CD_L);
1193 A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_SPDIF_CD_R);
1194 snd_emu10k1_init_stereo_control(&controls[nctl++],
1195 emu->card_capabilities->ac97_chip ? "Audigy CD Playback Volume" : "CD Playback Volume",
1198 /* Audigy CD Capture Volume */
1199 A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_SPDIF_CD_L);
1200 A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_SPDIF_CD_R);
1201 snd_emu10k1_init_stereo_control(&controls[nctl++],
1202 emu->card_capabilities->ac97_chip ? "Audigy CD Capture Volume" : "CD Capture Volume",
1206 /* Optical SPDIF Playback Volume */
1207 A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_OPT_SPDIF_L);
1208 A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_OPT_SPDIF_R);
1209 snd_emu10k1_init_stereo_control(&controls[nctl++], SNDRV_CTL_NAME_IEC958("Optical ",PLAYBACK,VOLUME), gpr, 0);
1211 /* Optical SPDIF Capture Volume */
1212 A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_OPT_SPDIF_L);
1213 A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_OPT_SPDIF_R);
1214 snd_emu10k1_init_stereo_control(&controls[nctl++], SNDRV_CTL_NAME_IEC958("Optical ",CAPTURE,VOLUME), gpr, 0);
1217 /* Line2 Playback Volume */
1218 A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_LINE2_L);
1219 A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_LINE2_R);
1220 snd_emu10k1_init_stereo_control(&controls[nctl++],
1221 emu->card_capabilities->ac97_chip ? "Line2 Playback Volume" : "Line Playback Volume",
1224 /* Line2 Capture Volume */
1225 A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_LINE2_L);
1226 A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_LINE2_R);
1227 snd_emu10k1_init_stereo_control(&controls[nctl++],
1228 emu->card_capabilities->ac97_chip ? "Line2 Capture Volume" : "Line Capture Volume",
1232 /* Philips ADC Playback Volume */
1233 A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_ADC_L);
1234 A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_ADC_R);
1235 snd_emu10k1_init_stereo_control(&controls[nctl++], "Analog Mix Playback Volume", gpr, 0);
1237 /* Philips ADC Capture Volume */
1238 A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_ADC_L);
1239 A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_ADC_R);
1240 snd_emu10k1_init_stereo_control(&controls[nctl++], "Analog Mix Capture Volume", gpr, 0);
1243 /* Aux2 Playback Volume */
1244 A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_AUX2_L);
1245 A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_AUX2_R);
1246 snd_emu10k1_init_stereo_control(&controls[nctl++],
1247 emu->card_capabilities->ac97_chip ? "Aux2 Playback Volume" : "Aux Playback Volume",
1250 /* Aux2 Capture Volume */
1251 A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_AUX2_L);
1252 A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_AUX2_R);
1253 snd_emu10k1_init_stereo_control(&controls[nctl++],
1254 emu->card_capabilities->ac97_chip ? "Aux2 Capture Volume" : "Aux Capture Volume",
1258 /* Stereo Mix Front Playback Volume */
1259 A_OP(icode, &ptr, iMAC0, A_GPR(playback), A_GPR(playback), A_GPR(gpr), A_GPR(stereo_mix));
1260 A_OP(icode, &ptr, iMAC0, A_GPR(playback+1), A_GPR(playback+1), A_GPR(gpr+1), A_GPR(stereo_mix+1));
1261 snd_emu10k1_init_stereo_control(&controls[nctl++], "Front Playback Volume", gpr, 100);
1264 /* Stereo Mix Surround Playback */
1265 A_OP(icode, &ptr, iMAC0, A_GPR(playback+2), A_GPR(playback+2), A_GPR(gpr), A_GPR(stereo_mix));
1266 A_OP(icode, &ptr, iMAC0, A_GPR(playback+3), A_GPR(playback+3), A_GPR(gpr+1), A_GPR(stereo_mix+1));
1267 snd_emu10k1_init_stereo_control(&controls[nctl++], "Surround Playback Volume", gpr, 0);
1270 /* Stereo Mix Center Playback */
1271 /* Center = sub = Left/2 + Right/2 */
1272 A_OP(icode, &ptr, iINTERP, A_GPR(tmp), A_GPR(stereo_mix), 0xcd, A_GPR(stereo_mix+1));
1273 A_OP(icode, &ptr, iMAC0, A_GPR(playback+4), A_GPR(playback+4), A_GPR(gpr), A_GPR(tmp));
1274 snd_emu10k1_init_mono_control(&controls[nctl++], "Center Playback Volume", gpr, 0);
1277 /* Stereo Mix LFE Playback */
1278 A_OP(icode, &ptr, iMAC0, A_GPR(playback+5), A_GPR(playback+5), A_GPR(gpr), A_GPR(tmp));
1279 snd_emu10k1_init_mono_control(&controls[nctl++], "LFE Playback Volume", gpr, 0);
1282 if (emu->card_capabilities->spk71) {
1283 /* Stereo Mix Side Playback */
1284 A_OP(icode, &ptr, iMAC0, A_GPR(playback+6), A_GPR(playback+6), A_GPR(gpr), A_GPR(stereo_mix));
1285 A_OP(icode, &ptr, iMAC0, A_GPR(playback+7), A_GPR(playback+7), A_GPR(gpr+1), A_GPR(stereo_mix+1));
1286 snd_emu10k1_init_stereo_control(&controls[nctl++], "Side Playback Volume", gpr, 0);
1293 #define A_PUT_OUTPUT(out,src) A_OP(icode, &ptr, iACC3, A_EXTOUT(out), A_C_00000000, A_C_00000000, A_GPR(src))
1294 #define A_PUT_STEREO_OUTPUT(out1,out2,src) \
1295 {A_PUT_OUTPUT(out1,src); A_PUT_OUTPUT(out2,src+1);}
1297 #define _A_SWITCH(icode, ptr, dst, src, sw) \
1298 A_OP((icode), ptr, iMACINT0, dst, A_C_00000000, src, sw);
1299 #define A_SWITCH(icode, ptr, dst, src, sw) \
1300 _A_SWITCH(icode, ptr, A_GPR(dst), A_GPR(src), A_GPR(sw))
1301 #define _A_SWITCH_NEG(icode, ptr, dst, src) \
1302 A_OP((icode), ptr, iANDXOR, dst, src, A_C_00000001, A_C_00000001);
1303 #define A_SWITCH_NEG(icode, ptr, dst, src) \
1304 _A_SWITCH_NEG(icode, ptr, A_GPR(dst), A_GPR(src))
1308 * Process tone control
1310 A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 0), A_GPR(playback + 0), A_C_00000000, A_C_00000000); /* left */
1311 A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 1), A_GPR(playback + 1), A_C_00000000, A_C_00000000); /* right */
1312 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 */
1313 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 */
1314 A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 4), A_GPR(playback + 4), A_C_00000000, A_C_00000000); /* center */
1315 A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 5), A_GPR(playback + 5), A_C_00000000, A_C_00000000); /* LFE */
1316 if (emu->card_capabilities->spk71) {
1317 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 */
1318 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 */
1322 ctl = &controls[nctl + 0];
1323 ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1324 strcpy(ctl->id.name, "Tone Control - Bass");
1329 ctl->value[0] = ctl->value[1] = 20;
1330 ctl->translation = EMU10K1_GPR_TRANSLATION_BASS;
1331 ctl = &controls[nctl + 1];
1332 ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1333 strcpy(ctl->id.name, "Tone Control - Treble");
1338 ctl->value[0] = ctl->value[1] = 20;
1339 ctl->translation = EMU10K1_GPR_TRANSLATION_TREBLE;
1341 #define BASS_GPR 0x8c
1342 #define TREBLE_GPR 0x96
1344 for (z = 0; z < 5; z++) {
1346 for (j = 0; j < 2; j++) {
1347 controls[nctl + 0].gpr[z * 2 + j] = BASS_GPR + z * 2 + j;
1348 controls[nctl + 1].gpr[z * 2 + j] = TREBLE_GPR + z * 2 + j;
1351 for (z = 0; z < 4; z++) { /* front/rear/center-lfe/side */
1353 for (j = 0; j < 2; j++) { /* left/right */
1354 k = 0xb0 + (z * 8) + (j * 4);
1355 l = 0xe0 + (z * 8) + (j * 4);
1356 d = playback + SND_EMU10K1_PLAYBACK_CHANNELS + z * 2 + j;
1358 A_OP(icode, &ptr, iMAC0, A_C_00000000, A_C_00000000, A_GPR(d), A_GPR(BASS_GPR + 0 + j));
1359 A_OP(icode, &ptr, iMACMV, A_GPR(k+1), A_GPR(k), A_GPR(k+1), A_GPR(BASS_GPR + 4 + j));
1360 A_OP(icode, &ptr, iMACMV, A_GPR(k), A_GPR(d), A_GPR(k), A_GPR(BASS_GPR + 2 + j));
1361 A_OP(icode, &ptr, iMACMV, A_GPR(k+3), A_GPR(k+2), A_GPR(k+3), A_GPR(BASS_GPR + 8 + j));
1362 A_OP(icode, &ptr, iMAC0, A_GPR(k+2), A_GPR_ACCU, A_GPR(k+2), A_GPR(BASS_GPR + 6 + j));
1363 A_OP(icode, &ptr, iACC3, A_GPR(k+2), A_GPR(k+2), A_GPR(k+2), A_C_00000000);
1365 A_OP(icode, &ptr, iMAC0, A_C_00000000, A_C_00000000, A_GPR(k+2), A_GPR(TREBLE_GPR + 0 + j));
1366 A_OP(icode, &ptr, iMACMV, A_GPR(l+1), A_GPR(l), A_GPR(l+1), A_GPR(TREBLE_GPR + 4 + j));
1367 A_OP(icode, &ptr, iMACMV, A_GPR(l), A_GPR(k+2), A_GPR(l), A_GPR(TREBLE_GPR + 2 + j));
1368 A_OP(icode, &ptr, iMACMV, A_GPR(l+3), A_GPR(l+2), A_GPR(l+3), A_GPR(TREBLE_GPR + 8 + j));
1369 A_OP(icode, &ptr, iMAC0, A_GPR(l+2), A_GPR_ACCU, A_GPR(l+2), A_GPR(TREBLE_GPR + 6 + j));
1370 A_OP(icode, &ptr, iMACINT0, A_GPR(l+2), A_C_00000000, A_GPR(l+2), A_C_00000010);
1372 A_OP(icode, &ptr, iACC3, A_GPR(d), A_GPR(l+2), A_C_00000000, A_C_00000000);
1374 if (z == 2) /* center */
1383 for (z = 0; z < 8; z++) {
1384 A_SWITCH(icode, &ptr, tmp + 0, playback + SND_EMU10K1_PLAYBACK_CHANNELS + z, gpr + 0);
1385 A_SWITCH_NEG(icode, &ptr, tmp + 1, gpr + 0);
1386 A_SWITCH(icode, &ptr, tmp + 1, playback + z, tmp + 1);
1387 A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + z), A_GPR(tmp + 0), A_GPR(tmp + 1), A_C_00000000);
1389 snd_emu10k1_init_stereo_onoff_control(controls + nctl++, "Tone Control - Switch", gpr, 0);
1392 /* Master volume (will be renamed later) */
1393 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));
1394 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));
1395 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));
1396 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));
1397 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));
1398 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));
1399 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));
1400 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));
1401 snd_emu10k1_init_mono_control(&controls[nctl++], "Wave Master Playback Volume", gpr, 0);
1404 /* analog speakers */
1405 A_PUT_STEREO_OUTPUT(A_EXTOUT_AFRONT_L, A_EXTOUT_AFRONT_R, playback + SND_EMU10K1_PLAYBACK_CHANNELS);
1406 A_PUT_STEREO_OUTPUT(A_EXTOUT_AREAR_L, A_EXTOUT_AREAR_R, playback+2 + SND_EMU10K1_PLAYBACK_CHANNELS);
1407 A_PUT_OUTPUT(A_EXTOUT_ACENTER, playback+4 + SND_EMU10K1_PLAYBACK_CHANNELS);
1408 A_PUT_OUTPUT(A_EXTOUT_ALFE, playback+5 + SND_EMU10K1_PLAYBACK_CHANNELS);
1409 if (emu->card_capabilities->spk71)
1410 A_PUT_STEREO_OUTPUT(A_EXTOUT_ASIDE_L, A_EXTOUT_ASIDE_R, playback+6 + SND_EMU10K1_PLAYBACK_CHANNELS);
1413 A_PUT_STEREO_OUTPUT(A_EXTOUT_HEADPHONE_L, A_EXTOUT_HEADPHONE_R, playback + SND_EMU10K1_PLAYBACK_CHANNELS);
1415 /* digital outputs */
1416 /* A_PUT_STEREO_OUTPUT(A_EXTOUT_FRONT_L, A_EXTOUT_FRONT_R, playback + SND_EMU10K1_PLAYBACK_CHANNELS); */
1418 /* IEC958 Optical Raw Playback Switch */
1420 gpr_map[gpr++] = 0x1008;
1421 gpr_map[gpr++] = 0xffff0000;
1422 for (z = 0; z < 2; z++) {
1423 A_OP(icode, &ptr, iMAC0, A_GPR(tmp + 2), A_FXBUS(FXBUS_PT_LEFT + z), A_C_00000000, A_C_00000000);
1424 A_OP(icode, &ptr, iSKIP, A_GPR_COND, A_GPR_COND, A_GPR(gpr - 2), A_C_00000001);
1425 A_OP(icode, &ptr, iACC3, A_GPR(tmp + 2), A_C_00000000, A_C_00010000, A_GPR(tmp + 2));
1426 A_OP(icode, &ptr, iANDXOR, A_GPR(tmp + 2), A_GPR(tmp + 2), A_GPR(gpr - 1), A_C_00000000);
1427 A_SWITCH(icode, &ptr, tmp + 0, tmp + 2, gpr + z);
1428 A_SWITCH_NEG(icode, &ptr, tmp + 1, gpr + z);
1429 A_SWITCH(icode, &ptr, tmp + 1, playback + SND_EMU10K1_PLAYBACK_CHANNELS + z, tmp + 1);
1430 if ((z==1) && (emu->card_capabilities->spdif_bug)) {
1431 /* Due to a SPDIF output bug on some Audigy cards, this code delays the Right channel by 1 sample */
1432 snd_printk(KERN_INFO "Installing spdif_bug patch: %s\n", emu->card_capabilities->name);
1433 A_OP(icode, &ptr, iACC3, A_EXTOUT(A_EXTOUT_FRONT_L + z), A_GPR(gpr - 3), A_C_00000000, A_C_00000000);
1434 A_OP(icode, &ptr, iACC3, A_GPR(gpr - 3), A_GPR(tmp + 0), A_GPR(tmp + 1), A_C_00000000);
1436 A_OP(icode, &ptr, iACC3, A_EXTOUT(A_EXTOUT_FRONT_L + z), A_GPR(tmp + 0), A_GPR(tmp + 1), A_C_00000000);
1439 snd_emu10k1_init_stereo_onoff_control(controls + nctl++, SNDRV_CTL_NAME_IEC958("Optical Raw ",PLAYBACK,SWITCH), gpr, 0);
1442 A_PUT_STEREO_OUTPUT(A_EXTOUT_REAR_L, A_EXTOUT_REAR_R, playback+2 + SND_EMU10K1_PLAYBACK_CHANNELS);
1443 A_PUT_OUTPUT(A_EXTOUT_CENTER, playback+4 + SND_EMU10K1_PLAYBACK_CHANNELS);
1444 A_PUT_OUTPUT(A_EXTOUT_LFE, playback+5 + SND_EMU10K1_PLAYBACK_CHANNELS);
1447 #ifdef EMU10K1_CAPTURE_DIGITAL_OUT
1448 A_PUT_STEREO_OUTPUT(A_EXTOUT_ADC_CAP_L, A_EXTOUT_ADC_CAP_R, playback + SND_EMU10K1_PLAYBACK_CHANNELS);
1450 A_PUT_OUTPUT(A_EXTOUT_ADC_CAP_L, capture);
1451 A_PUT_OUTPUT(A_EXTOUT_ADC_CAP_R, capture+1);
1454 /* EFX capture - capture the 16 EXTINs */
1455 for (z = 0; z < 16; z++) {
1456 A_OP(icode, &ptr, iACC3, A_FXBUS2(z), A_C_00000000, A_C_00000000, A_EXTIN(z));
1459 #endif /* JCD test */
1469 /* clear remaining instruction memory */
1471 A_OP(icode, &ptr, 0x0f, 0xc0, 0xc0, 0xcf, 0xc0);
1473 seg = snd_enter_user();
1474 icode->gpr_add_control_count = nctl;
1475 icode->gpr_add_controls = (struct snd_emu10k1_fx8010_control_gpr __user *)controls;
1476 err = snd_emu10k1_icode_poke(emu, icode);
1477 snd_leave_user(seg);
1481 if (icode != NULL) {
1482 kfree((void __force *)icode->gpr_map);
1490 * initial DSP configuration for Emu10k1
1493 /* when volume = max, then copy only to avoid volume modification */
1494 /* with iMAC0 (negative values) */
1495 static void __devinit _volume(struct snd_emu10k1_fx8010_code *icode, u32 *ptr, u32 dst, u32 src, u32 vol)
1497 OP(icode, ptr, iMAC0, dst, C_00000000, src, vol);
1498 OP(icode, ptr, iANDXOR, C_00000000, vol, C_ffffffff, C_7fffffff);
1499 OP(icode, ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, C_00000001);
1500 OP(icode, ptr, iACC3, dst, src, C_00000000, C_00000000);
1502 static void __devinit _volume_add(struct snd_emu10k1_fx8010_code *icode, u32 *ptr, u32 dst, u32 src, u32 vol)
1504 OP(icode, ptr, iANDXOR, C_00000000, vol, C_ffffffff, C_7fffffff);
1505 OP(icode, ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, C_00000002);
1506 OP(icode, ptr, iMACINT0, dst, dst, src, C_00000001);
1507 OP(icode, ptr, iSKIP, C_00000000, C_7fffffff, C_7fffffff, C_00000001);
1508 OP(icode, ptr, iMAC0, dst, dst, src, vol);
1510 static void __devinit _volume_out(struct snd_emu10k1_fx8010_code *icode, u32 *ptr, u32 dst, u32 src, u32 vol)
1512 OP(icode, ptr, iANDXOR, C_00000000, vol, C_ffffffff, C_7fffffff);
1513 OP(icode, ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, C_00000002);
1514 OP(icode, ptr, iACC3, dst, src, C_00000000, C_00000000);
1515 OP(icode, ptr, iSKIP, C_00000000, C_7fffffff, C_7fffffff, C_00000001);
1516 OP(icode, ptr, iMAC0, dst, C_00000000, src, vol);
1519 #define VOLUME(icode, ptr, dst, src, vol) \
1520 _volume(icode, ptr, GPR(dst), GPR(src), GPR(vol))
1521 #define VOLUME_IN(icode, ptr, dst, src, vol) \
1522 _volume(icode, ptr, GPR(dst), EXTIN(src), GPR(vol))
1523 #define VOLUME_ADD(icode, ptr, dst, src, vol) \
1524 _volume_add(icode, ptr, GPR(dst), GPR(src), GPR(vol))
1525 #define VOLUME_ADDIN(icode, ptr, dst, src, vol) \
1526 _volume_add(icode, ptr, GPR(dst), EXTIN(src), GPR(vol))
1527 #define VOLUME_OUT(icode, ptr, dst, src, vol) \
1528 _volume_out(icode, ptr, EXTOUT(dst), GPR(src), GPR(vol))
1529 #define _SWITCH(icode, ptr, dst, src, sw) \
1530 OP((icode), ptr, iMACINT0, dst, C_00000000, src, sw);
1531 #define SWITCH(icode, ptr, dst, src, sw) \
1532 _SWITCH(icode, ptr, GPR(dst), GPR(src), GPR(sw))
1533 #define SWITCH_IN(icode, ptr, dst, src, sw) \
1534 _SWITCH(icode, ptr, GPR(dst), EXTIN(src), GPR(sw))
1535 #define _SWITCH_NEG(icode, ptr, dst, src) \
1536 OP((icode), ptr, iANDXOR, dst, src, C_00000001, C_00000001);
1537 #define SWITCH_NEG(icode, ptr, dst, src) \
1538 _SWITCH_NEG(icode, ptr, GPR(dst), GPR(src))
1541 static int __devinit _snd_emu10k1_init_efx(struct snd_emu10k1 *emu)
1543 int err, i, z, gpr, tmp, playback, capture;
1545 struct snd_emu10k1_fx8010_code *icode;
1546 struct snd_emu10k1_fx8010_pcm_rec *ipcm = NULL;
1547 struct snd_emu10k1_fx8010_control_gpr *controls = NULL, *ctl;
1551 if ((icode = kzalloc(sizeof(*icode), GFP_KERNEL)) == NULL)
1553 if ((icode->gpr_map = (u_int32_t __user *)
1554 kcalloc(256 + 160 + 160 + 2 * 512, sizeof(u_int32_t),
1555 GFP_KERNEL)) == NULL ||
1556 (controls = kcalloc(SND_EMU10K1_GPR_CONTROLS,
1557 sizeof(struct snd_emu10k1_fx8010_control_gpr),
1558 GFP_KERNEL)) == NULL ||
1559 (ipcm = kzalloc(sizeof(*ipcm), GFP_KERNEL)) == NULL) {
1563 gpr_map = (u32 __force *)icode->gpr_map;
1565 icode->tram_data_map = icode->gpr_map + 256;
1566 icode->tram_addr_map = icode->tram_data_map + 160;
1567 icode->code = icode->tram_addr_map + 160;
1569 /* clear free GPRs */
1570 for (i = 0; i < 256; i++)
1571 set_bit(i, icode->gpr_valid);
1573 /* clear TRAM data & address lines */
1574 for (i = 0; i < 160; i++)
1575 set_bit(i, icode->tram_valid);
1577 strcpy(icode->name, "SB Live! FX8010 code for ALSA v1.2 by Jaroslav Kysela");
1579 /* we have 12 inputs */
1580 playback = SND_EMU10K1_INPUTS;
1581 /* we have 6 playback channels and tone control doubles */
1582 capture = playback + (SND_EMU10K1_PLAYBACK_CHANNELS * 2);
1583 gpr = capture + SND_EMU10K1_CAPTURE_CHANNELS;
1584 tmp = 0x88; /* we need 4 temporary GPR */
1585 /* from 0x8c to 0xff is the area for tone control */
1587 /* stop FX processor */
1588 snd_emu10k1_ptr_write(emu, DBG, 0, (emu->fx8010.dbg = 0) | EMU10K1_DBG_SINGLE_STEP);
1593 OP(icode, &ptr, iMACINT0, GPR(0), C_00000000, FXBUS(FXBUS_PCM_LEFT), C_00000004);
1594 OP(icode, &ptr, iMACINT0, GPR(1), C_00000000, FXBUS(FXBUS_PCM_RIGHT), C_00000004);
1595 OP(icode, &ptr, iMACINT0, GPR(2), C_00000000, FXBUS(FXBUS_MIDI_LEFT), C_00000004);
1596 OP(icode, &ptr, iMACINT0, GPR(3), C_00000000, FXBUS(FXBUS_MIDI_RIGHT), C_00000004);
1597 OP(icode, &ptr, iMACINT0, GPR(4), C_00000000, FXBUS(FXBUS_PCM_LEFT_REAR), C_00000004);
1598 OP(icode, &ptr, iMACINT0, GPR(5), C_00000000, FXBUS(FXBUS_PCM_RIGHT_REAR), C_00000004);
1599 OP(icode, &ptr, iMACINT0, GPR(6), C_00000000, FXBUS(FXBUS_PCM_CENTER), C_00000004);
1600 OP(icode, &ptr, iMACINT0, GPR(7), C_00000000, FXBUS(FXBUS_PCM_LFE), C_00000004);
1601 OP(icode, &ptr, iMACINT0, GPR(8), C_00000000, C_00000000, C_00000000); /* S/PDIF left */
1602 OP(icode, &ptr, iMACINT0, GPR(9), C_00000000, C_00000000, C_00000000); /* S/PDIF right */
1603 OP(icode, &ptr, iMACINT0, GPR(10), C_00000000, FXBUS(FXBUS_PCM_LEFT_FRONT), C_00000004);
1604 OP(icode, &ptr, iMACINT0, GPR(11), C_00000000, FXBUS(FXBUS_PCM_RIGHT_FRONT), C_00000004);
1606 /* Raw S/PDIF PCM */
1607 ipcm->substream = 0;
1609 ipcm->tram_start = 0;
1610 ipcm->buffer_size = (64 * 1024) / 2;
1611 ipcm->gpr_size = gpr++;
1612 ipcm->gpr_ptr = gpr++;
1613 ipcm->gpr_count = gpr++;
1614 ipcm->gpr_tmpcount = gpr++;
1615 ipcm->gpr_trigger = gpr++;
1616 ipcm->gpr_running = gpr++;
1620 gpr_map[gpr + 0] = 0xfffff000;
1621 gpr_map[gpr + 1] = 0xffff0000;
1622 gpr_map[gpr + 2] = 0x70000000;
1623 gpr_map[gpr + 3] = 0x00000007;
1624 gpr_map[gpr + 4] = 0x001f << 11;
1625 gpr_map[gpr + 5] = 0x001c << 11;
1626 gpr_map[gpr + 6] = (0x22 - 0x01) - 1; /* skip at 01 to 22 */
1627 gpr_map[gpr + 7] = (0x22 - 0x06) - 1; /* skip at 06 to 22 */
1628 gpr_map[gpr + 8] = 0x2000000 + (2<<11);
1629 gpr_map[gpr + 9] = 0x4000000 + (2<<11);
1630 gpr_map[gpr + 10] = 1<<11;
1631 gpr_map[gpr + 11] = (0x24 - 0x0a) - 1; /* skip at 0a to 24 */
1632 gpr_map[gpr + 12] = 0;
1634 /* if the trigger flag is not set, skip */
1635 /* 00: */ OP(icode, &ptr, iMAC0, C_00000000, GPR(ipcm->gpr_trigger), C_00000000, C_00000000);
1636 /* 01: */ OP(icode, &ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_ZERO, GPR(gpr + 6));
1637 /* if the running flag is set, we're running */
1638 /* 02: */ OP(icode, &ptr, iMAC0, C_00000000, GPR(ipcm->gpr_running), C_00000000, C_00000000);
1639 /* 03: */ OP(icode, &ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, C_00000004);
1640 /* wait until ((GPR_DBAC>>11) & 0x1f) == 0x1c) */
1641 /* 04: */ OP(icode, &ptr, iANDXOR, GPR(tmp + 0), GPR_DBAC, GPR(gpr + 4), C_00000000);
1642 /* 05: */ OP(icode, &ptr, iMACINT0, C_00000000, GPR(tmp + 0), C_ffffffff, GPR(gpr + 5));
1643 /* 06: */ OP(icode, &ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, GPR(gpr + 7));
1644 /* 07: */ OP(icode, &ptr, iACC3, GPR(gpr + 12), C_00000010, C_00000001, C_00000000);
1646 /* 08: */ OP(icode, &ptr, iANDXOR, GPR(ipcm->gpr_running), GPR(ipcm->gpr_running), C_00000000, C_00000001);
1647 /* 09: */ OP(icode, &ptr, iACC3, GPR(gpr + 12), GPR(gpr + 12), C_ffffffff, C_00000000);
1648 /* 0a: */ OP(icode, &ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, GPR(gpr + 11));
1649 /* 0b: */ OP(icode, &ptr, iACC3, GPR(gpr + 12), C_00000001, C_00000000, C_00000000);
1651 /* 0c: */ OP(icode, &ptr, iANDXOR, GPR(tmp + 0), ETRAM_DATA(ipcm->etram[0]), GPR(gpr + 0), C_00000000);
1652 /* 0d: */ OP(icode, &ptr, iLOG, GPR(tmp + 0), GPR(tmp + 0), GPR(gpr + 3), C_00000000);
1653 /* 0e: */ OP(icode, &ptr, iANDXOR, GPR(8), GPR(tmp + 0), GPR(gpr + 1), GPR(gpr + 2));
1654 /* 0f: */ OP(icode, &ptr, iSKIP, C_00000000, GPR_COND, CC_REG_MINUS, C_00000001);
1655 /* 10: */ OP(icode, &ptr, iANDXOR, GPR(8), GPR(8), GPR(gpr + 1), GPR(gpr + 2));
1657 /* 11: */ OP(icode, &ptr, iANDXOR, GPR(tmp + 0), ETRAM_DATA(ipcm->etram[1]), GPR(gpr + 0), C_00000000);
1658 /* 12: */ OP(icode, &ptr, iLOG, GPR(tmp + 0), GPR(tmp + 0), GPR(gpr + 3), C_00000000);
1659 /* 13: */ OP(icode, &ptr, iANDXOR, GPR(9), GPR(tmp + 0), GPR(gpr + 1), GPR(gpr + 2));
1660 /* 14: */ OP(icode, &ptr, iSKIP, C_00000000, GPR_COND, CC_REG_MINUS, C_00000001);
1661 /* 15: */ OP(icode, &ptr, iANDXOR, GPR(9), GPR(9), GPR(gpr + 1), GPR(gpr + 2));
1663 /* 16: */ OP(icode, &ptr, iACC3, GPR(tmp + 0), GPR(ipcm->gpr_ptr), C_00000001, C_00000000);
1664 /* 17: */ OP(icode, &ptr, iMACINT0, C_00000000, GPR(tmp + 0), C_ffffffff, GPR(ipcm->gpr_size));
1665 /* 18: */ OP(icode, &ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_MINUS, C_00000001);
1666 /* 19: */ OP(icode, &ptr, iACC3, GPR(tmp + 0), C_00000000, C_00000000, C_00000000);
1667 /* 1a: */ OP(icode, &ptr, iACC3, GPR(ipcm->gpr_ptr), GPR(tmp + 0), C_00000000, C_00000000);
1669 /* 1b: */ OP(icode, &ptr, iACC3, GPR(ipcm->gpr_tmpcount), GPR(ipcm->gpr_tmpcount), C_ffffffff, C_00000000);
1670 /* 1c: */ OP(icode, &ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, C_00000002);
1671 /* 1d: */ OP(icode, &ptr, iACC3, GPR(ipcm->gpr_tmpcount), GPR(ipcm->gpr_count), C_00000000, C_00000000);
1672 /* 1e: */ OP(icode, &ptr, iACC3, GPR_IRQ, C_80000000, C_00000000, C_00000000);
1673 /* 1f: */ OP(icode, &ptr, iANDXOR, GPR(ipcm->gpr_running), GPR(ipcm->gpr_running), C_00000001, C_00010000);
1675 /* 20: */ OP(icode, &ptr, iANDXOR, GPR(ipcm->gpr_running), GPR(ipcm->gpr_running), C_00010000, C_00000001);
1676 /* 21: */ OP(icode, &ptr, iSKIP, C_00000000, C_7fffffff, C_7fffffff, C_00000002);
1678 /* 22: */ OP(icode, &ptr, iMACINT1, ETRAM_ADDR(ipcm->etram[0]), GPR(gpr + 8), GPR_DBAC, C_ffffffff);
1679 /* 23: */ OP(icode, &ptr, iMACINT1, ETRAM_ADDR(ipcm->etram[1]), GPR(gpr + 9), GPR_DBAC, C_ffffffff);
1684 /* Wave Playback Volume */
1685 for (z = 0; z < 2; z++)
1686 VOLUME(icode, &ptr, playback + z, z, gpr + z);
1687 snd_emu10k1_init_stereo_control(controls + i++, "Wave Playback Volume", gpr, 100);
1690 /* Wave Surround Playback Volume */
1691 for (z = 0; z < 2; z++)
1692 VOLUME(icode, &ptr, playback + 2 + z, z, gpr + z);
1693 snd_emu10k1_init_stereo_control(controls + i++, "Wave Surround Playback Volume", gpr, 0);
1696 /* Wave Center/LFE Playback Volume */
1697 OP(icode, &ptr, iACC3, GPR(tmp + 0), FXBUS(FXBUS_PCM_LEFT), FXBUS(FXBUS_PCM_RIGHT), C_00000000);
1698 OP(icode, &ptr, iMACINT0, GPR(tmp + 0), C_00000000, GPR(tmp + 0), C_00000002);
1699 VOLUME(icode, &ptr, playback + 4, tmp + 0, gpr);
1700 snd_emu10k1_init_mono_control(controls + i++, "Wave Center Playback Volume", gpr++, 0);
1701 VOLUME(icode, &ptr, playback + 5, tmp + 0, gpr);
1702 snd_emu10k1_init_mono_control(controls + i++, "Wave LFE Playback Volume", gpr++, 0);
1704 /* Wave Capture Volume + Switch */
1705 for (z = 0; z < 2; z++) {
1706 SWITCH(icode, &ptr, tmp + 0, z, gpr + 2 + z);
1707 VOLUME(icode, &ptr, capture + z, tmp + 0, gpr + z);
1709 snd_emu10k1_init_stereo_control(controls + i++, "Wave Capture Volume", gpr, 0);
1710 snd_emu10k1_init_stereo_onoff_control(controls + i++, "Wave Capture Switch", gpr + 2, 0);
1713 /* Synth Playback Volume */
1714 for (z = 0; z < 2; z++)
1715 VOLUME_ADD(icode, &ptr, playback + z, 2 + z, gpr + z);
1716 snd_emu10k1_init_stereo_control(controls + i++, "Synth Playback Volume", gpr, 100);
1719 /* Synth Capture Volume + Switch */
1720 for (z = 0; z < 2; z++) {
1721 SWITCH(icode, &ptr, tmp + 0, 2 + z, gpr + 2 + z);
1722 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
1724 snd_emu10k1_init_stereo_control(controls + i++, "Synth Capture Volume", gpr, 0);
1725 snd_emu10k1_init_stereo_onoff_control(controls + i++, "Synth Capture Switch", gpr + 2, 0);
1728 /* Surround Digital Playback Volume (renamed later without Digital) */
1729 for (z = 0; z < 2; z++)
1730 VOLUME_ADD(icode, &ptr, playback + 2 + z, 4 + z, gpr + z);
1731 snd_emu10k1_init_stereo_control(controls + i++, "Surround Digital Playback Volume", gpr, 100);
1734 /* Surround Capture Volume + Switch */
1735 for (z = 0; z < 2; z++) {
1736 SWITCH(icode, &ptr, tmp + 0, 4 + z, gpr + 2 + z);
1737 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
1739 snd_emu10k1_init_stereo_control(controls + i++, "Surround Capture Volume", gpr, 0);
1740 snd_emu10k1_init_stereo_onoff_control(controls + i++, "Surround Capture Switch", gpr + 2, 0);
1743 /* Center Playback Volume (renamed later without Digital) */
1744 VOLUME_ADD(icode, &ptr, playback + 4, 6, gpr);
1745 snd_emu10k1_init_mono_control(controls + i++, "Center Digital Playback Volume", gpr++, 100);
1747 /* LFE Playback Volume + Switch (renamed later without Digital) */
1748 VOLUME_ADD(icode, &ptr, playback + 5, 7, gpr);
1749 snd_emu10k1_init_mono_control(controls + i++, "LFE Digital Playback Volume", gpr++, 100);
1751 /* Front Playback Volume */
1752 for (z = 0; z < 2; z++)
1753 VOLUME_ADD(icode, &ptr, playback + z, 10 + z, gpr + z);
1754 snd_emu10k1_init_stereo_control(controls + i++, "Front Playback Volume", gpr, 100);
1757 /* Front Capture Volume + Switch */
1758 for (z = 0; z < 2; z++) {
1759 SWITCH(icode, &ptr, tmp + 0, 10 + z, gpr + 2);
1760 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
1762 snd_emu10k1_init_stereo_control(controls + i++, "Front Capture Volume", gpr, 0);
1763 snd_emu10k1_init_mono_onoff_control(controls + i++, "Front Capture Switch", gpr + 2, 0);
1770 if (emu->fx8010.extin_mask & ((1<<EXTIN_AC97_L)|(1<<EXTIN_AC97_R))) {
1771 /* AC'97 Playback Volume */
1772 VOLUME_ADDIN(icode, &ptr, playback + 0, EXTIN_AC97_L, gpr); gpr++;
1773 VOLUME_ADDIN(icode, &ptr, playback + 1, EXTIN_AC97_R, gpr); gpr++;
1774 snd_emu10k1_init_stereo_control(controls + i++, "AC97 Playback Volume", gpr-2, 0);
1775 /* AC'97 Capture Volume */
1776 VOLUME_ADDIN(icode, &ptr, capture + 0, EXTIN_AC97_L, gpr); gpr++;
1777 VOLUME_ADDIN(icode, &ptr, capture + 1, EXTIN_AC97_R, gpr); gpr++;
1778 snd_emu10k1_init_stereo_control(controls + i++, "AC97 Capture Volume", gpr-2, 100);
1781 if (emu->fx8010.extin_mask & ((1<<EXTIN_SPDIF_CD_L)|(1<<EXTIN_SPDIF_CD_R))) {
1782 /* IEC958 TTL Playback Volume */
1783 for (z = 0; z < 2; z++)
1784 VOLUME_ADDIN(icode, &ptr, playback + z, EXTIN_SPDIF_CD_L + z, gpr + z);
1785 snd_emu10k1_init_stereo_control(controls + i++, SNDRV_CTL_NAME_IEC958("TTL ",PLAYBACK,VOLUME), gpr, 0);
1788 /* IEC958 TTL Capture Volume + Switch */
1789 for (z = 0; z < 2; z++) {
1790 SWITCH_IN(icode, &ptr, tmp + 0, EXTIN_SPDIF_CD_L + z, gpr + 2 + z);
1791 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
1793 snd_emu10k1_init_stereo_control(controls + i++, SNDRV_CTL_NAME_IEC958("TTL ",CAPTURE,VOLUME), gpr, 0);
1794 snd_emu10k1_init_stereo_onoff_control(controls + i++, SNDRV_CTL_NAME_IEC958("TTL ",CAPTURE,SWITCH), gpr + 2, 0);
1798 if (emu->fx8010.extin_mask & ((1<<EXTIN_ZOOM_L)|(1<<EXTIN_ZOOM_R))) {
1799 /* Zoom Video Playback Volume */
1800 for (z = 0; z < 2; z++)
1801 VOLUME_ADDIN(icode, &ptr, playback + z, EXTIN_ZOOM_L + z, gpr + z);
1802 snd_emu10k1_init_stereo_control(controls + i++, "Zoom Video Playback Volume", gpr, 0);
1805 /* Zoom Video Capture Volume + Switch */
1806 for (z = 0; z < 2; z++) {
1807 SWITCH_IN(icode, &ptr, tmp + 0, EXTIN_ZOOM_L + z, gpr + 2 + z);
1808 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
1810 snd_emu10k1_init_stereo_control(controls + i++, "Zoom Video Capture Volume", gpr, 0);
1811 snd_emu10k1_init_stereo_onoff_control(controls + i++, "Zoom Video Capture Switch", gpr + 2, 0);
1815 if (emu->fx8010.extin_mask & ((1<<EXTIN_TOSLINK_L)|(1<<EXTIN_TOSLINK_R))) {
1816 /* IEC958 Optical Playback Volume */
1817 for (z = 0; z < 2; z++)
1818 VOLUME_ADDIN(icode, &ptr, playback + z, EXTIN_TOSLINK_L + z, gpr + z);
1819 snd_emu10k1_init_stereo_control(controls + i++, SNDRV_CTL_NAME_IEC958("LiveDrive ",PLAYBACK,VOLUME), gpr, 0);
1822 /* IEC958 Optical Capture Volume */
1823 for (z = 0; z < 2; z++) {
1824 SWITCH_IN(icode, &ptr, tmp + 0, EXTIN_TOSLINK_L + z, gpr + 2 + z);
1825 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
1827 snd_emu10k1_init_stereo_control(controls + i++, SNDRV_CTL_NAME_IEC958("LiveDrive ",CAPTURE,VOLUME), gpr, 0);
1828 snd_emu10k1_init_stereo_onoff_control(controls + i++, SNDRV_CTL_NAME_IEC958("LiveDrive ",CAPTURE,SWITCH), gpr + 2, 0);
1832 if (emu->fx8010.extin_mask & ((1<<EXTIN_LINE1_L)|(1<<EXTIN_LINE1_R))) {
1833 /* Line LiveDrive Playback Volume */
1834 for (z = 0; z < 2; z++)
1835 VOLUME_ADDIN(icode, &ptr, playback + z, EXTIN_LINE1_L + z, gpr + z);
1836 snd_emu10k1_init_stereo_control(controls + i++, "Line LiveDrive Playback Volume", gpr, 0);
1839 /* Line LiveDrive Capture Volume + Switch */
1840 for (z = 0; z < 2; z++) {
1841 SWITCH_IN(icode, &ptr, tmp + 0, EXTIN_LINE1_L + z, gpr + 2 + z);
1842 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
1844 snd_emu10k1_init_stereo_control(controls + i++, "Line LiveDrive Capture Volume", gpr, 0);
1845 snd_emu10k1_init_stereo_onoff_control(controls + i++, "Line LiveDrive Capture Switch", gpr + 2, 0);
1849 if (emu->fx8010.extin_mask & ((1<<EXTIN_COAX_SPDIF_L)|(1<<EXTIN_COAX_SPDIF_R))) {
1850 /* IEC958 Coax Playback Volume */
1851 for (z = 0; z < 2; z++)
1852 VOLUME_ADDIN(icode, &ptr, playback + z, EXTIN_COAX_SPDIF_L + z, gpr + z);
1853 snd_emu10k1_init_stereo_control(controls + i++, SNDRV_CTL_NAME_IEC958("Coaxial ",PLAYBACK,VOLUME), gpr, 0);
1856 /* IEC958 Coax Capture Volume + Switch */
1857 for (z = 0; z < 2; z++) {
1858 SWITCH_IN(icode, &ptr, tmp + 0, EXTIN_COAX_SPDIF_L + z, gpr + 2 + z);
1859 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
1861 snd_emu10k1_init_stereo_control(controls + i++, SNDRV_CTL_NAME_IEC958("Coaxial ",CAPTURE,VOLUME), gpr, 0);
1862 snd_emu10k1_init_stereo_onoff_control(controls + i++, SNDRV_CTL_NAME_IEC958("Coaxial ",CAPTURE,SWITCH), gpr + 2, 0);
1866 if (emu->fx8010.extin_mask & ((1<<EXTIN_LINE2_L)|(1<<EXTIN_LINE2_R))) {
1867 /* Line LiveDrive Playback Volume */
1868 for (z = 0; z < 2; z++)
1869 VOLUME_ADDIN(icode, &ptr, playback + z, EXTIN_LINE2_L + z, gpr + z);
1870 snd_emu10k1_init_stereo_control(controls + i++, "Line2 LiveDrive Playback Volume", gpr, 0);
1871 controls[i-1].id.index = 1;
1874 /* Line LiveDrive Capture Volume */
1875 for (z = 0; z < 2; z++) {
1876 SWITCH_IN(icode, &ptr, tmp + 0, EXTIN_LINE2_L + z, gpr + 2 + z);
1877 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
1879 snd_emu10k1_init_stereo_control(controls + i++, "Line2 LiveDrive Capture Volume", gpr, 0);
1880 controls[i-1].id.index = 1;
1881 snd_emu10k1_init_stereo_onoff_control(controls + i++, "Line2 LiveDrive Capture Switch", gpr + 2, 0);
1882 controls[i-1].id.index = 1;
1887 * Process tone control
1889 OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 0), GPR(playback + 0), C_00000000, C_00000000); /* left */
1890 OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 1), GPR(playback + 1), C_00000000, C_00000000); /* right */
1891 OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 2), GPR(playback + 2), C_00000000, C_00000000); /* rear left */
1892 OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 3), GPR(playback + 3), C_00000000, C_00000000); /* rear right */
1893 OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 4), GPR(playback + 4), C_00000000, C_00000000); /* center */
1894 OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 5), GPR(playback + 5), C_00000000, C_00000000); /* LFE */
1896 ctl = &controls[i + 0];
1897 ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1898 strcpy(ctl->id.name, "Tone Control - Bass");
1903 ctl->value[0] = ctl->value[1] = 20;
1904 ctl->translation = EMU10K1_GPR_TRANSLATION_BASS;
1905 ctl = &controls[i + 1];
1906 ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1907 strcpy(ctl->id.name, "Tone Control - Treble");
1912 ctl->value[0] = ctl->value[1] = 20;
1913 ctl->translation = EMU10K1_GPR_TRANSLATION_TREBLE;
1915 #define BASS_GPR 0x8c
1916 #define TREBLE_GPR 0x96
1918 for (z = 0; z < 5; z++) {
1920 for (j = 0; j < 2; j++) {
1921 controls[i + 0].gpr[z * 2 + j] = BASS_GPR + z * 2 + j;
1922 controls[i + 1].gpr[z * 2 + j] = TREBLE_GPR + z * 2 + j;
1925 for (z = 0; z < 3; z++) { /* front/rear/center-lfe */
1927 for (j = 0; j < 2; j++) { /* left/right */
1928 k = 0xa0 + (z * 8) + (j * 4);
1929 l = 0xd0 + (z * 8) + (j * 4);
1930 d = playback + SND_EMU10K1_PLAYBACK_CHANNELS + z * 2 + j;
1932 OP(icode, &ptr, iMAC0, C_00000000, C_00000000, GPR(d), GPR(BASS_GPR + 0 + j));
1933 OP(icode, &ptr, iMACMV, GPR(k+1), GPR(k), GPR(k+1), GPR(BASS_GPR + 4 + j));
1934 OP(icode, &ptr, iMACMV, GPR(k), GPR(d), GPR(k), GPR(BASS_GPR + 2 + j));
1935 OP(icode, &ptr, iMACMV, GPR(k+3), GPR(k+2), GPR(k+3), GPR(BASS_GPR + 8 + j));
1936 OP(icode, &ptr, iMAC0, GPR(k+2), GPR_ACCU, GPR(k+2), GPR(BASS_GPR + 6 + j));
1937 OP(icode, &ptr, iACC3, GPR(k+2), GPR(k+2), GPR(k+2), C_00000000);
1939 OP(icode, &ptr, iMAC0, C_00000000, C_00000000, GPR(k+2), GPR(TREBLE_GPR + 0 + j));
1940 OP(icode, &ptr, iMACMV, GPR(l+1), GPR(l), GPR(l+1), GPR(TREBLE_GPR + 4 + j));
1941 OP(icode, &ptr, iMACMV, GPR(l), GPR(k+2), GPR(l), GPR(TREBLE_GPR + 2 + j));
1942 OP(icode, &ptr, iMACMV, GPR(l+3), GPR(l+2), GPR(l+3), GPR(TREBLE_GPR + 8 + j));
1943 OP(icode, &ptr, iMAC0, GPR(l+2), GPR_ACCU, GPR(l+2), GPR(TREBLE_GPR + 6 + j));
1944 OP(icode, &ptr, iMACINT0, GPR(l+2), C_00000000, GPR(l+2), C_00000010);
1946 OP(icode, &ptr, iACC3, GPR(d), GPR(l+2), C_00000000, C_00000000);
1948 if (z == 2) /* center */
1957 for (z = 0; z < 6; z++) {
1958 SWITCH(icode, &ptr, tmp + 0, playback + SND_EMU10K1_PLAYBACK_CHANNELS + z, gpr + 0);
1959 SWITCH_NEG(icode, &ptr, tmp + 1, gpr + 0);
1960 SWITCH(icode, &ptr, tmp + 1, playback + z, tmp + 1);
1961 OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + z), GPR(tmp + 0), GPR(tmp + 1), C_00000000);
1963 snd_emu10k1_init_stereo_onoff_control(controls + i++, "Tone Control - Switch", gpr, 0);
1969 if (emu->fx8010.extout_mask & ((1<<EXTOUT_AC97_L)|(1<<EXTOUT_AC97_R))) {
1970 /* AC'97 Playback Volume */
1972 for (z = 0; z < 2; z++)
1973 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_AC97_L + z), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + z), C_00000000, C_00000000);
1976 if (emu->fx8010.extout_mask & ((1<<EXTOUT_TOSLINK_L)|(1<<EXTOUT_TOSLINK_R))) {
1977 /* IEC958 Optical Raw Playback Switch */
1979 for (z = 0; z < 2; z++) {
1980 SWITCH(icode, &ptr, tmp + 0, 8 + z, gpr + z);
1981 SWITCH_NEG(icode, &ptr, tmp + 1, gpr + z);
1982 SWITCH(icode, &ptr, tmp + 1, playback + SND_EMU10K1_PLAYBACK_CHANNELS + z, tmp + 1);
1983 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_TOSLINK_L + z), GPR(tmp + 0), GPR(tmp + 1), C_00000000);
1984 #ifdef EMU10K1_CAPTURE_DIGITAL_OUT
1985 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_ADC_CAP_L + z), GPR(tmp + 0), GPR(tmp + 1), C_00000000);
1989 snd_emu10k1_init_stereo_onoff_control(controls + i++, SNDRV_CTL_NAME_IEC958("Optical Raw ",PLAYBACK,SWITCH), gpr, 0);
1993 if (emu->fx8010.extout_mask & ((1<<EXTOUT_HEADPHONE_L)|(1<<EXTOUT_HEADPHONE_R))) {
1994 /* Headphone Playback Volume */
1996 for (z = 0; z < 2; z++) {
1997 SWITCH(icode, &ptr, tmp + 0, playback + SND_EMU10K1_PLAYBACK_CHANNELS + 4 + z, gpr + 2 + z);
1998 SWITCH_NEG(icode, &ptr, tmp + 1, gpr + 2 + z);
1999 SWITCH(icode, &ptr, tmp + 1, playback + SND_EMU10K1_PLAYBACK_CHANNELS + z, tmp + 1);
2000 OP(icode, &ptr, iACC3, GPR(tmp + 0), GPR(tmp + 0), GPR(tmp + 1), C_00000000);
2001 VOLUME_OUT(icode, &ptr, EXTOUT_HEADPHONE_L + z, tmp + 0, gpr + z);
2004 snd_emu10k1_init_stereo_control(controls + i++, "Headphone Playback Volume", gpr + 0, 0);
2005 controls[i-1].id.index = 1; /* AC'97 can have also Headphone control */
2006 snd_emu10k1_init_mono_onoff_control(controls + i++, "Headphone Center Playback Switch", gpr + 2, 0);
2007 controls[i-1].id.index = 1;
2008 snd_emu10k1_init_mono_onoff_control(controls + i++, "Headphone LFE Playback Switch", gpr + 3, 0);
2009 controls[i-1].id.index = 1;
2014 if (emu->fx8010.extout_mask & ((1<<EXTOUT_REAR_L)|(1<<EXTOUT_REAR_R)))
2015 for (z = 0; z < 2; z++)
2016 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_REAR_L + z), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 2 + z), C_00000000, C_00000000);
2018 if (emu->fx8010.extout_mask & ((1<<EXTOUT_AC97_REAR_L)|(1<<EXTOUT_AC97_REAR_R)))
2019 for (z = 0; z < 2; z++)
2020 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_AC97_REAR_L + z), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 2 + z), C_00000000, C_00000000);
2022 if (emu->fx8010.extout_mask & (1<<EXTOUT_AC97_CENTER)) {
2023 #ifndef EMU10K1_CENTER_LFE_FROM_FRONT
2024 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_AC97_CENTER), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 4), C_00000000, C_00000000);
2025 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_ACENTER), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 4), C_00000000, C_00000000);
2027 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_AC97_CENTER), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 0), C_00000000, C_00000000);
2028 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_ACENTER), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 0), C_00000000, C_00000000);
2032 if (emu->fx8010.extout_mask & (1<<EXTOUT_AC97_LFE)) {
2033 #ifndef EMU10K1_CENTER_LFE_FROM_FRONT
2034 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_AC97_LFE), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 5), C_00000000, C_00000000);
2035 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_ALFE), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 5), C_00000000, C_00000000);
2037 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_AC97_LFE), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 1), C_00000000, C_00000000);
2038 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_ALFE), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 1), C_00000000, C_00000000);
2042 #ifndef EMU10K1_CAPTURE_DIGITAL_OUT
2043 for (z = 0; z < 2; z++)
2044 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_ADC_CAP_L + z), GPR(capture + z), C_00000000, C_00000000);
2047 if (emu->fx8010.extout_mask & (1<<EXTOUT_MIC_CAP))
2048 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_MIC_CAP), GPR(capture + 2), C_00000000, C_00000000);
2050 /* EFX capture - capture the 16 EXTINS */
2051 if (emu->card_capabilities->sblive51) {
2052 /* On the Live! 5.1, FXBUS2(1) and FXBUS(2) are shared with EXTOUT_ACENTER
2053 * and EXTOUT_ALFE, so we can't connect inputs to them for multitrack recording.
2055 * Since only 14 of the 16 EXTINs are used, this is not a big problem.
2056 * We route AC97L and R to FX capture 14 and 15, SPDIF CD in to FX capture
2057 * 0 and 3, then the rest of the EXTINs to the corresponding FX capture
2058 * channel. Multitrack recorders will still see the center/lfe output signal
2059 * on the second and third channels.
2061 OP(icode, &ptr, iACC3, FXBUS2(14), C_00000000, C_00000000, EXTIN(0));
2062 OP(icode, &ptr, iACC3, FXBUS2(15), C_00000000, C_00000000, EXTIN(1));
2063 OP(icode, &ptr, iACC3, FXBUS2(0), C_00000000, C_00000000, EXTIN(2));
2064 OP(icode, &ptr, iACC3, FXBUS2(3), C_00000000, C_00000000, EXTIN(3));
2065 for (z = 4; z < 14; z++)
2066 OP(icode, &ptr, iACC3, FXBUS2(z), C_00000000, C_00000000, EXTIN(z));
2068 for (z = 0; z < 16; z++)
2069 OP(icode, &ptr, iACC3, FXBUS2(z), C_00000000, C_00000000, EXTIN(z));
2078 if (i > SND_EMU10K1_GPR_CONTROLS) {
2084 /* clear remaining instruction memory */
2086 OP(icode, &ptr, iACC3, C_00000000, C_00000000, C_00000000, C_00000000);
2088 if ((err = snd_emu10k1_fx8010_tram_setup(emu, ipcm->buffer_size)) < 0)
2090 seg = snd_enter_user();
2091 icode->gpr_add_control_count = i;
2092 icode->gpr_add_controls = (struct snd_emu10k1_fx8010_control_gpr __user *)controls;
2093 err = snd_emu10k1_icode_poke(emu, icode);
2094 snd_leave_user(seg);
2096 err = snd_emu10k1_ipcm_poke(emu, ipcm);
2100 if (icode != NULL) {
2101 kfree((void __force *)icode->gpr_map);
2107 int __devinit snd_emu10k1_init_efx(struct snd_emu10k1 *emu)
2109 spin_lock_init(&emu->fx8010.irq_lock);
2110 INIT_LIST_HEAD(&emu->fx8010.gpr_ctl);
2112 return _snd_emu10k1_audigy_init_efx(emu);
2114 return _snd_emu10k1_init_efx(emu);
2117 void snd_emu10k1_free_efx(struct snd_emu10k1 *emu)
2119 /* stop processor */
2121 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg = A_DBG_SINGLE_STEP);
2123 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg = EMU10K1_DBG_SINGLE_STEP);
2126 #if 0 // FIXME: who use them?
2127 int snd_emu10k1_fx8010_tone_control_activate(struct snd_emu10k1 *emu, int output)
2129 if (output < 0 || output >= 6)
2131 snd_emu10k1_ptr_write(emu, emu->gpr_base + 0x94 + output, 0, 1);
2135 int snd_emu10k1_fx8010_tone_control_deactivate(struct snd_emu10k1 *emu, int output)
2137 if (output < 0 || output >= 6)
2139 snd_emu10k1_ptr_write(emu, emu->gpr_base + 0x94 + output, 0, 0);
2144 int snd_emu10k1_fx8010_tram_setup(struct snd_emu10k1 *emu, u32 size)
2148 /* size is in samples */
2150 size = (size - 1) >> 13;
2156 size = 0x2000 << size_reg;
2158 if ((emu->fx8010.etram_pages.bytes / 2) == size)
2160 spin_lock_irq(&emu->emu_lock);
2161 outl(HCFG_LOCKTANKCACHE_MASK | inl(emu->port + HCFG), emu->port + HCFG);
2162 spin_unlock_irq(&emu->emu_lock);
2163 snd_emu10k1_ptr_write(emu, TCB, 0, 0);
2164 snd_emu10k1_ptr_write(emu, TCBS, 0, 0);
2165 if (emu->fx8010.etram_pages.area != NULL) {
2166 snd_dma_free_pages(&emu->fx8010.etram_pages);
2167 emu->fx8010.etram_pages.area = NULL;
2168 emu->fx8010.etram_pages.bytes = 0;
2172 if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(emu->pci),
2173 size * 2, &emu->fx8010.etram_pages) < 0)
2175 memset(emu->fx8010.etram_pages.area, 0, size * 2);
2176 snd_emu10k1_ptr_write(emu, TCB, 0, emu->fx8010.etram_pages.addr);
2177 snd_emu10k1_ptr_write(emu, TCBS, 0, size_reg);
2178 spin_lock_irq(&emu->emu_lock);
2179 outl(inl(emu->port + HCFG) & ~HCFG_LOCKTANKCACHE_MASK, emu->port + HCFG);
2180 spin_unlock_irq(&emu->emu_lock);
2186 static int snd_emu10k1_fx8010_open(struct snd_hwdep * hw, struct file *file)
2191 static void copy_string(char *dst, char *src, char *null, int idx)
2194 sprintf(dst, "%s %02X", null, idx);
2199 static int snd_emu10k1_fx8010_info(struct snd_emu10k1 *emu,
2200 struct snd_emu10k1_fx8010_info *info)
2202 char **fxbus, **extin, **extout;
2203 unsigned short fxbus_mask, extin_mask, extout_mask;
2206 memset(info, 0, sizeof(info));
2207 info->internal_tram_size = emu->fx8010.itram_size;
2208 info->external_tram_size = emu->fx8010.etram_pages.bytes / 2;
2210 extin = emu->audigy ? audigy_ins : creative_ins;
2211 extout = emu->audigy ? audigy_outs : creative_outs;
2212 fxbus_mask = emu->fx8010.fxbus_mask;
2213 extin_mask = emu->fx8010.extin_mask;
2214 extout_mask = emu->fx8010.extout_mask;
2215 for (res = 0; res < 16; res++, fxbus++, extin++, extout++) {
2216 copy_string(info->fxbus_names[res], fxbus_mask & (1 << res) ? *fxbus : NULL, "FXBUS", res);
2217 copy_string(info->extin_names[res], extin_mask & (1 << res) ? *extin : NULL, "Unused", res);
2218 copy_string(info->extout_names[res], extout_mask & (1 << res) ? *extout : NULL, "Unused", res);
2220 for (res = 16; res < 32; res++, extout++)
2221 copy_string(info->extout_names[res], extout_mask & (1 << res) ? *extout : NULL, "Unused", res);
2222 info->gpr_controls = emu->fx8010.gpr_count;
2226 static int snd_emu10k1_fx8010_ioctl(struct snd_hwdep * hw, struct file *file, unsigned int cmd, unsigned long arg)
2228 struct snd_emu10k1 *emu = hw->private_data;
2229 struct snd_emu10k1_fx8010_info *info;
2230 struct snd_emu10k1_fx8010_code *icode;
2231 struct snd_emu10k1_fx8010_pcm_rec *ipcm;
2233 void __user *argp = (void __user *)arg;
2237 case SNDRV_EMU10K1_IOCTL_INFO:
2238 info = kmalloc(sizeof(*info), GFP_KERNEL);
2241 if ((res = snd_emu10k1_fx8010_info(emu, info)) < 0) {
2245 if (copy_to_user(argp, info, sizeof(*info))) {
2251 case SNDRV_EMU10K1_IOCTL_CODE_POKE:
2252 if (!capable(CAP_SYS_ADMIN))
2254 icode = kmalloc(sizeof(*icode), GFP_KERNEL);
2257 if (copy_from_user(icode, argp, sizeof(*icode))) {
2261 res = snd_emu10k1_icode_poke(emu, icode);
2264 case SNDRV_EMU10K1_IOCTL_CODE_PEEK:
2265 icode = kmalloc(sizeof(*icode), GFP_KERNEL);
2268 if (copy_from_user(icode, argp, sizeof(*icode))) {
2272 res = snd_emu10k1_icode_peek(emu, icode);
2273 if (res == 0 && copy_to_user(argp, icode, sizeof(*icode))) {
2279 case SNDRV_EMU10K1_IOCTL_PCM_POKE:
2280 ipcm = kmalloc(sizeof(*ipcm), GFP_KERNEL);
2283 if (copy_from_user(ipcm, argp, sizeof(*ipcm))) {
2287 res = snd_emu10k1_ipcm_poke(emu, ipcm);
2290 case SNDRV_EMU10K1_IOCTL_PCM_PEEK:
2291 ipcm = kzalloc(sizeof(*ipcm), GFP_KERNEL);
2294 if (copy_from_user(ipcm, argp, sizeof(*ipcm))) {
2298 res = snd_emu10k1_ipcm_peek(emu, ipcm);
2299 if (res == 0 && copy_to_user(argp, ipcm, sizeof(*ipcm))) {
2305 case SNDRV_EMU10K1_IOCTL_TRAM_SETUP:
2306 if (!capable(CAP_SYS_ADMIN))
2308 if (get_user(addr, (unsigned int __user *)argp))
2310 down(&emu->fx8010.lock);
2311 res = snd_emu10k1_fx8010_tram_setup(emu, addr);
2312 up(&emu->fx8010.lock);
2314 case SNDRV_EMU10K1_IOCTL_STOP:
2315 if (!capable(CAP_SYS_ADMIN))
2318 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg |= A_DBG_SINGLE_STEP);
2320 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg |= EMU10K1_DBG_SINGLE_STEP);
2322 case SNDRV_EMU10K1_IOCTL_CONTINUE:
2323 if (!capable(CAP_SYS_ADMIN))
2326 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg = 0);
2328 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg = 0);
2330 case SNDRV_EMU10K1_IOCTL_ZERO_TRAM_COUNTER:
2331 if (!capable(CAP_SYS_ADMIN))
2334 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg | A_DBG_ZC);
2336 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg | EMU10K1_DBG_ZC);
2339 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg);
2341 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg);
2343 case SNDRV_EMU10K1_IOCTL_SINGLE_STEP:
2344 if (!capable(CAP_SYS_ADMIN))
2346 if (get_user(addr, (unsigned int __user *)argp))
2351 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg |= A_DBG_SINGLE_STEP | addr);
2353 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg |= EMU10K1_DBG_SINGLE_STEP | addr);
2356 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg |= A_DBG_SINGLE_STEP | A_DBG_STEP_ADDR | addr);
2358 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg |= EMU10K1_DBG_SINGLE_STEP | EMU10K1_DBG_STEP | addr);
2360 case SNDRV_EMU10K1_IOCTL_DBG_READ:
2362 addr = snd_emu10k1_ptr_read(emu, A_DBG, 0);
2364 addr = snd_emu10k1_ptr_read(emu, DBG, 0);
2365 if (put_user(addr, (unsigned int __user *)argp))
2372 static int snd_emu10k1_fx8010_release(struct snd_hwdep * hw, struct file *file)
2377 int __devinit snd_emu10k1_fx8010_new(struct snd_emu10k1 *emu, int device, struct snd_hwdep ** rhwdep)
2379 struct snd_hwdep *hw;
2384 if ((err = snd_hwdep_new(emu->card, "FX8010", device, &hw)) < 0)
2386 strcpy(hw->name, "EMU10K1 (FX8010)");
2387 hw->iface = SNDRV_HWDEP_IFACE_EMU10K1;
2388 hw->ops.open = snd_emu10k1_fx8010_open;
2389 hw->ops.ioctl = snd_emu10k1_fx8010_ioctl;
2390 hw->ops.release = snd_emu10k1_fx8010_release;
2391 hw->private_data = emu;
2398 int __devinit snd_emu10k1_efx_alloc_pm_buffer(struct snd_emu10k1 *emu)
2402 len = emu->audigy ? 0x200 : 0x100;
2403 emu->saved_gpr = kmalloc(len * 4, GFP_KERNEL);
2404 if (! emu->saved_gpr)
2406 len = emu->audigy ? 0x100 : 0xa0;
2407 emu->tram_val_saved = kmalloc(len * 4, GFP_KERNEL);
2408 emu->tram_addr_saved = kmalloc(len * 4, GFP_KERNEL);
2409 if (! emu->tram_val_saved || ! emu->tram_addr_saved)
2411 len = emu->audigy ? 2 * 1024 : 2 * 512;
2412 emu->saved_icode = vmalloc(len * 4);
2413 if (! emu->saved_icode)
2418 void snd_emu10k1_efx_free_pm_buffer(struct snd_emu10k1 *emu)
2420 kfree(emu->saved_gpr);
2421 kfree(emu->tram_val_saved);
2422 kfree(emu->tram_addr_saved);
2423 vfree(emu->saved_icode);
2427 * save/restore GPR, TRAM and codes
2429 void snd_emu10k1_efx_suspend(struct snd_emu10k1 *emu)
2433 len = emu->audigy ? 0x200 : 0x100;
2434 for (i = 0; i < len; i++)
2435 emu->saved_gpr[i] = snd_emu10k1_ptr_read(emu, emu->gpr_base + i, 0);
2437 len = emu->audigy ? 0x100 : 0xa0;
2438 for (i = 0; i < len; i++) {
2439 emu->tram_val_saved[i] = snd_emu10k1_ptr_read(emu, TANKMEMDATAREGBASE + i, 0);
2440 emu->tram_addr_saved[i] = snd_emu10k1_ptr_read(emu, TANKMEMADDRREGBASE + i, 0);
2442 emu->tram_addr_saved[i] >>= 12;
2443 emu->tram_addr_saved[i] |=
2444 snd_emu10k1_ptr_read(emu, A_TANKMEMCTLREGBASE + i, 0) << 20;
2448 len = emu->audigy ? 2 * 1024 : 2 * 512;
2449 for (i = 0; i < len; i++)
2450 emu->saved_icode[i] = snd_emu10k1_efx_read(emu, i);
2453 void snd_emu10k1_efx_resume(struct snd_emu10k1 *emu)
2458 if (emu->fx8010.etram_pages.bytes > 0) {
2459 unsigned size, size_reg = 0;
2460 size = emu->fx8010.etram_pages.bytes / 2;
2461 size = (size - 1) >> 13;
2466 outl(HCFG_LOCKTANKCACHE_MASK | inl(emu->port + HCFG), emu->port + HCFG);
2467 snd_emu10k1_ptr_write(emu, TCB, 0, emu->fx8010.etram_pages.addr);
2468 snd_emu10k1_ptr_write(emu, TCBS, 0, size_reg);
2469 outl(inl(emu->port + HCFG) & ~HCFG_LOCKTANKCACHE_MASK, emu->port + HCFG);
2473 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg | A_DBG_SINGLE_STEP);
2475 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg | EMU10K1_DBG_SINGLE_STEP);
2477 len = emu->audigy ? 0x200 : 0x100;
2478 for (i = 0; i < len; i++)
2479 snd_emu10k1_ptr_write(emu, emu->gpr_base + i, 0, emu->saved_gpr[i]);
2481 len = emu->audigy ? 0x100 : 0xa0;
2482 for (i = 0; i < len; i++) {
2483 snd_emu10k1_ptr_write(emu, TANKMEMDATAREGBASE + i, 0,
2484 emu->tram_val_saved[i]);
2486 snd_emu10k1_ptr_write(emu, TANKMEMADDRREGBASE + i, 0,
2487 emu->tram_addr_saved[i]);
2489 snd_emu10k1_ptr_write(emu, TANKMEMADDRREGBASE + i, 0,
2490 emu->tram_addr_saved[i] << 12);
2491 snd_emu10k1_ptr_write(emu, TANKMEMADDRREGBASE + i, 0,
2492 emu->tram_addr_saved[i] >> 20);
2496 len = emu->audigy ? 2 * 1024 : 2 * 512;
2497 for (i = 0; i < len; i++)
2498 snd_emu10k1_efx_write(emu, i, emu->saved_icode[i]);
2500 /* start FX processor when the DSP code is updated */
2502 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg);
2504 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg);