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);
1105 /* PCM front Playback Volume (independent from stereo mix) */
1106 A_OP(icode, &ptr, iMAC0, A_GPR(playback), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LEFT_FRONT));
1107 A_OP(icode, &ptr, iMAC0, A_GPR(playback+1), A_C_00000000, A_GPR(gpr+1), A_FXBUS(FXBUS_PCM_RIGHT_FRONT));
1108 snd_emu10k1_init_stereo_control(&controls[nctl++], "PCM Front Playback Volume", gpr, 100);
1111 /* PCM Surround Playback (independent from stereo mix) */
1112 A_OP(icode, &ptr, iMAC0, A_GPR(playback+2), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LEFT_REAR));
1113 A_OP(icode, &ptr, iMAC0, A_GPR(playback+3), A_C_00000000, A_GPR(gpr+1), A_FXBUS(FXBUS_PCM_RIGHT_REAR));
1114 snd_emu10k1_init_stereo_control(&controls[nctl++], "PCM Surround Playback Volume", gpr, 100);
1117 /* PCM Side Playback (independent from stereo mix) */
1118 if (emu->card_capabilities->spk71) {
1119 A_OP(icode, &ptr, iMAC0, A_GPR(playback+6), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LEFT_SIDE));
1120 A_OP(icode, &ptr, iMAC0, A_GPR(playback+7), A_C_00000000, A_GPR(gpr+1), A_FXBUS(FXBUS_PCM_RIGHT_SIDE));
1121 snd_emu10k1_init_stereo_control(&controls[nctl++], "PCM Side Playback Volume", gpr, 100);
1125 /* PCM Center Playback (independent from stereo mix) */
1126 A_OP(icode, &ptr, iMAC0, A_GPR(playback+4), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_CENTER));
1127 snd_emu10k1_init_mono_control(&controls[nctl++], "PCM Center Playback Volume", gpr, 100);
1130 /* PCM LFE Playback (independent from stereo mix) */
1131 A_OP(icode, &ptr, iMAC0, A_GPR(playback+5), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LFE));
1132 snd_emu10k1_init_mono_control(&controls[nctl++], "PCM LFE Playback Volume", gpr, 100);
1138 /* Wave (PCM) Playback Volume (will be renamed later) */
1139 A_OP(icode, &ptr, iMAC0, A_GPR(stereo_mix), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LEFT));
1140 A_OP(icode, &ptr, iMAC0, A_GPR(stereo_mix+1), A_C_00000000, A_GPR(gpr+1), A_FXBUS(FXBUS_PCM_RIGHT));
1141 snd_emu10k1_init_stereo_control(&controls[nctl++], "Wave Playback Volume", gpr, 100);
1144 /* Synth Playback */
1145 A_OP(icode, &ptr, iMAC0, A_GPR(stereo_mix+0), A_GPR(stereo_mix+0), A_GPR(gpr), A_FXBUS(FXBUS_MIDI_LEFT));
1146 A_OP(icode, &ptr, iMAC0, A_GPR(stereo_mix+1), A_GPR(stereo_mix+1), A_GPR(gpr+1), A_FXBUS(FXBUS_MIDI_RIGHT));
1147 snd_emu10k1_init_stereo_control(&controls[nctl++], "Synth Playback Volume", gpr, 100);
1150 /* Wave (PCM) Capture */
1151 A_OP(icode, &ptr, iMAC0, A_GPR(capture+0), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LEFT));
1152 A_OP(icode, &ptr, iMAC0, A_GPR(capture+1), A_C_00000000, A_GPR(gpr+1), A_FXBUS(FXBUS_PCM_RIGHT));
1153 snd_emu10k1_init_stereo_control(&controls[nctl++], "PCM Capture Volume", gpr, 0);
1157 A_OP(icode, &ptr, iMAC0, A_GPR(capture+0), A_GPR(capture+0), A_GPR(gpr), A_FXBUS(FXBUS_MIDI_LEFT));
1158 A_OP(icode, &ptr, iMAC0, A_GPR(capture+1), A_GPR(capture+1), A_GPR(gpr+1), A_FXBUS(FXBUS_MIDI_RIGHT));
1159 snd_emu10k1_init_stereo_control(&controls[nctl++], "Synth Capture Volume", gpr, 0);
1165 #define A_ADD_VOLUME_IN(var,vol,input) \
1166 A_OP(icode, &ptr, iMAC0, A_GPR(var), A_GPR(var), A_GPR(vol), A_EXTIN(input))
1168 /* AC'97 Playback Volume - used only for mic (renamed later) */
1169 A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_AC97_L);
1170 A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_AC97_R);
1171 snd_emu10k1_init_stereo_control(&controls[nctl++], "AMic Playback Volume", gpr, 0);
1173 /* AC'97 Capture Volume - used only for mic */
1174 A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_AC97_L);
1175 A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_AC97_R);
1176 snd_emu10k1_init_stereo_control(&controls[nctl++], "Mic Capture Volume", gpr, 0);
1179 /* mic capture buffer */
1180 A_OP(icode, &ptr, iINTERP, A_EXTOUT(A_EXTOUT_MIC_CAP), A_EXTIN(A_EXTIN_AC97_L), 0xcd, A_EXTIN(A_EXTIN_AC97_R));
1182 /* Audigy CD Playback Volume */
1183 A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_SPDIF_CD_L);
1184 A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_SPDIF_CD_R);
1185 snd_emu10k1_init_stereo_control(&controls[nctl++],
1186 emu->card_capabilities->ac97_chip ? "Audigy CD Playback Volume" : "CD Playback Volume",
1189 /* Audigy CD Capture Volume */
1190 A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_SPDIF_CD_L);
1191 A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_SPDIF_CD_R);
1192 snd_emu10k1_init_stereo_control(&controls[nctl++],
1193 emu->card_capabilities->ac97_chip ? "Audigy CD Capture Volume" : "CD Capture Volume",
1197 /* Optical SPDIF Playback Volume */
1198 A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_OPT_SPDIF_L);
1199 A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_OPT_SPDIF_R);
1200 snd_emu10k1_init_stereo_control(&controls[nctl++], SNDRV_CTL_NAME_IEC958("Optical ",PLAYBACK,VOLUME), gpr, 0);
1202 /* Optical SPDIF Capture Volume */
1203 A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_OPT_SPDIF_L);
1204 A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_OPT_SPDIF_R);
1205 snd_emu10k1_init_stereo_control(&controls[nctl++], SNDRV_CTL_NAME_IEC958("Optical ",CAPTURE,VOLUME), gpr, 0);
1208 /* Line2 Playback Volume */
1209 A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_LINE2_L);
1210 A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_LINE2_R);
1211 snd_emu10k1_init_stereo_control(&controls[nctl++],
1212 emu->card_capabilities->ac97_chip ? "Line2 Playback Volume" : "Line Playback Volume",
1215 /* Line2 Capture Volume */
1216 A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_LINE2_L);
1217 A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_LINE2_R);
1218 snd_emu10k1_init_stereo_control(&controls[nctl++],
1219 emu->card_capabilities->ac97_chip ? "Line2 Capture Volume" : "Line Capture Volume",
1223 /* Philips ADC Playback Volume */
1224 A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_ADC_L);
1225 A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_ADC_R);
1226 snd_emu10k1_init_stereo_control(&controls[nctl++], "Analog Mix Playback Volume", gpr, 0);
1228 /* Philips ADC Capture Volume */
1229 A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_ADC_L);
1230 A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_ADC_R);
1231 snd_emu10k1_init_stereo_control(&controls[nctl++], "Analog Mix Capture Volume", gpr, 0);
1234 /* Aux2 Playback Volume */
1235 A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_AUX2_L);
1236 A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_AUX2_R);
1237 snd_emu10k1_init_stereo_control(&controls[nctl++],
1238 emu->card_capabilities->ac97_chip ? "Aux2 Playback Volume" : "Aux Playback Volume",
1241 /* Aux2 Capture Volume */
1242 A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_AUX2_L);
1243 A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_AUX2_R);
1244 snd_emu10k1_init_stereo_control(&controls[nctl++],
1245 emu->card_capabilities->ac97_chip ? "Aux2 Capture Volume" : "Aux Capture Volume",
1249 /* Stereo Mix Front Playback Volume */
1250 A_OP(icode, &ptr, iMAC0, A_GPR(playback), A_GPR(playback), A_GPR(gpr), A_GPR(stereo_mix));
1251 A_OP(icode, &ptr, iMAC0, A_GPR(playback+1), A_GPR(playback+1), A_GPR(gpr+1), A_GPR(stereo_mix+1));
1252 snd_emu10k1_init_stereo_control(&controls[nctl++], "Front Playback Volume", gpr, 100);
1255 /* Stereo Mix Surround Playback */
1256 A_OP(icode, &ptr, iMAC0, A_GPR(playback+2), A_GPR(playback+2), A_GPR(gpr), A_GPR(stereo_mix));
1257 A_OP(icode, &ptr, iMAC0, A_GPR(playback+3), A_GPR(playback+3), A_GPR(gpr+1), A_GPR(stereo_mix+1));
1258 snd_emu10k1_init_stereo_control(&controls[nctl++], "Surround Playback Volume", gpr, 0);
1261 /* Stereo Mix Center Playback */
1262 /* Center = sub = Left/2 + Right/2 */
1263 A_OP(icode, &ptr, iINTERP, A_GPR(tmp), A_GPR(stereo_mix), 0xcd, A_GPR(stereo_mix+1));
1264 A_OP(icode, &ptr, iMAC0, A_GPR(playback+4), A_GPR(playback+4), A_GPR(gpr), A_GPR(tmp));
1265 snd_emu10k1_init_mono_control(&controls[nctl++], "Center Playback Volume", gpr, 0);
1268 /* Stereo Mix LFE Playback */
1269 A_OP(icode, &ptr, iMAC0, A_GPR(playback+5), A_GPR(playback+5), A_GPR(gpr), A_GPR(tmp));
1270 snd_emu10k1_init_mono_control(&controls[nctl++], "LFE Playback Volume", gpr, 0);
1273 if (emu->card_capabilities->spk71) {
1274 /* Stereo Mix Side Playback */
1275 A_OP(icode, &ptr, iMAC0, A_GPR(playback+6), A_GPR(playback+6), A_GPR(gpr), A_GPR(stereo_mix));
1276 A_OP(icode, &ptr, iMAC0, A_GPR(playback+7), A_GPR(playback+7), A_GPR(gpr+1), A_GPR(stereo_mix+1));
1277 snd_emu10k1_init_stereo_control(&controls[nctl++], "Side Playback Volume", gpr, 0);
1284 #define A_PUT_OUTPUT(out,src) A_OP(icode, &ptr, iACC3, A_EXTOUT(out), A_C_00000000, A_C_00000000, A_GPR(src))
1285 #define A_PUT_STEREO_OUTPUT(out1,out2,src) \
1286 {A_PUT_OUTPUT(out1,src); A_PUT_OUTPUT(out2,src+1);}
1288 #define _A_SWITCH(icode, ptr, dst, src, sw) \
1289 A_OP((icode), ptr, iMACINT0, dst, A_C_00000000, src, sw);
1290 #define A_SWITCH(icode, ptr, dst, src, sw) \
1291 _A_SWITCH(icode, ptr, A_GPR(dst), A_GPR(src), A_GPR(sw))
1292 #define _A_SWITCH_NEG(icode, ptr, dst, src) \
1293 A_OP((icode), ptr, iANDXOR, dst, src, A_C_00000001, A_C_00000001);
1294 #define A_SWITCH_NEG(icode, ptr, dst, src) \
1295 _A_SWITCH_NEG(icode, ptr, A_GPR(dst), A_GPR(src))
1299 * Process tone control
1301 A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 0), A_GPR(playback + 0), A_C_00000000, A_C_00000000); /* left */
1302 A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 1), A_GPR(playback + 1), A_C_00000000, A_C_00000000); /* right */
1303 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 */
1304 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 */
1305 A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 4), A_GPR(playback + 4), A_C_00000000, A_C_00000000); /* center */
1306 A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 5), A_GPR(playback + 5), A_C_00000000, A_C_00000000); /* LFE */
1307 if (emu->card_capabilities->spk71) {
1308 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 */
1309 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 */
1313 ctl = &controls[nctl + 0];
1314 ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1315 strcpy(ctl->id.name, "Tone Control - Bass");
1320 ctl->value[0] = ctl->value[1] = 20;
1321 ctl->translation = EMU10K1_GPR_TRANSLATION_BASS;
1322 ctl = &controls[nctl + 1];
1323 ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1324 strcpy(ctl->id.name, "Tone Control - Treble");
1329 ctl->value[0] = ctl->value[1] = 20;
1330 ctl->translation = EMU10K1_GPR_TRANSLATION_TREBLE;
1332 #define BASS_GPR 0x8c
1333 #define TREBLE_GPR 0x96
1335 for (z = 0; z < 5; z++) {
1337 for (j = 0; j < 2; j++) {
1338 controls[nctl + 0].gpr[z * 2 + j] = BASS_GPR + z * 2 + j;
1339 controls[nctl + 1].gpr[z * 2 + j] = TREBLE_GPR + z * 2 + j;
1342 for (z = 0; z < 4; z++) { /* front/rear/center-lfe/side */
1344 for (j = 0; j < 2; j++) { /* left/right */
1345 k = 0xb0 + (z * 8) + (j * 4);
1346 l = 0xe0 + (z * 8) + (j * 4);
1347 d = playback + SND_EMU10K1_PLAYBACK_CHANNELS + z * 2 + j;
1349 A_OP(icode, &ptr, iMAC0, A_C_00000000, A_C_00000000, A_GPR(d), A_GPR(BASS_GPR + 0 + j));
1350 A_OP(icode, &ptr, iMACMV, A_GPR(k+1), A_GPR(k), A_GPR(k+1), A_GPR(BASS_GPR + 4 + j));
1351 A_OP(icode, &ptr, iMACMV, A_GPR(k), A_GPR(d), A_GPR(k), A_GPR(BASS_GPR + 2 + j));
1352 A_OP(icode, &ptr, iMACMV, A_GPR(k+3), A_GPR(k+2), A_GPR(k+3), A_GPR(BASS_GPR + 8 + j));
1353 A_OP(icode, &ptr, iMAC0, A_GPR(k+2), A_GPR_ACCU, A_GPR(k+2), A_GPR(BASS_GPR + 6 + j));
1354 A_OP(icode, &ptr, iACC3, A_GPR(k+2), A_GPR(k+2), A_GPR(k+2), A_C_00000000);
1356 A_OP(icode, &ptr, iMAC0, A_C_00000000, A_C_00000000, A_GPR(k+2), A_GPR(TREBLE_GPR + 0 + j));
1357 A_OP(icode, &ptr, iMACMV, A_GPR(l+1), A_GPR(l), A_GPR(l+1), A_GPR(TREBLE_GPR + 4 + j));
1358 A_OP(icode, &ptr, iMACMV, A_GPR(l), A_GPR(k+2), A_GPR(l), A_GPR(TREBLE_GPR + 2 + j));
1359 A_OP(icode, &ptr, iMACMV, A_GPR(l+3), A_GPR(l+2), A_GPR(l+3), A_GPR(TREBLE_GPR + 8 + j));
1360 A_OP(icode, &ptr, iMAC0, A_GPR(l+2), A_GPR_ACCU, A_GPR(l+2), A_GPR(TREBLE_GPR + 6 + j));
1361 A_OP(icode, &ptr, iMACINT0, A_GPR(l+2), A_C_00000000, A_GPR(l+2), A_C_00000010);
1363 A_OP(icode, &ptr, iACC3, A_GPR(d), A_GPR(l+2), A_C_00000000, A_C_00000000);
1365 if (z == 2) /* center */
1374 for (z = 0; z < 8; z++) {
1375 A_SWITCH(icode, &ptr, tmp + 0, playback + SND_EMU10K1_PLAYBACK_CHANNELS + z, gpr + 0);
1376 A_SWITCH_NEG(icode, &ptr, tmp + 1, gpr + 0);
1377 A_SWITCH(icode, &ptr, tmp + 1, playback + z, tmp + 1);
1378 A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + z), A_GPR(tmp + 0), A_GPR(tmp + 1), A_C_00000000);
1380 snd_emu10k1_init_stereo_onoff_control(controls + nctl++, "Tone Control - Switch", gpr, 0);
1383 /* Master volume (will be renamed later) */
1384 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));
1385 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));
1386 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));
1387 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));
1388 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));
1389 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));
1390 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));
1391 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));
1392 snd_emu10k1_init_mono_control(&controls[nctl++], "Wave Master Playback Volume", gpr, 0);
1395 /* analog speakers */
1396 A_PUT_STEREO_OUTPUT(A_EXTOUT_AFRONT_L, A_EXTOUT_AFRONT_R, playback + SND_EMU10K1_PLAYBACK_CHANNELS);
1397 A_PUT_STEREO_OUTPUT(A_EXTOUT_AREAR_L, A_EXTOUT_AREAR_R, playback+2 + SND_EMU10K1_PLAYBACK_CHANNELS);
1398 A_PUT_OUTPUT(A_EXTOUT_ACENTER, playback+4 + SND_EMU10K1_PLAYBACK_CHANNELS);
1399 A_PUT_OUTPUT(A_EXTOUT_ALFE, playback+5 + SND_EMU10K1_PLAYBACK_CHANNELS);
1400 if (emu->card_capabilities->spk71)
1401 A_PUT_STEREO_OUTPUT(A_EXTOUT_ASIDE_L, A_EXTOUT_ASIDE_R, playback+6 + SND_EMU10K1_PLAYBACK_CHANNELS);
1404 A_PUT_STEREO_OUTPUT(A_EXTOUT_HEADPHONE_L, A_EXTOUT_HEADPHONE_R, playback + SND_EMU10K1_PLAYBACK_CHANNELS);
1406 /* digital outputs */
1407 /* A_PUT_STEREO_OUTPUT(A_EXTOUT_FRONT_L, A_EXTOUT_FRONT_R, playback + SND_EMU10K1_PLAYBACK_CHANNELS); */
1409 /* IEC958 Optical Raw Playback Switch */
1411 gpr_map[gpr++] = 0x1008;
1412 gpr_map[gpr++] = 0xffff0000;
1413 for (z = 0; z < 2; z++) {
1414 A_OP(icode, &ptr, iMAC0, A_GPR(tmp + 2), A_FXBUS(FXBUS_PT_LEFT + z), A_C_00000000, A_C_00000000);
1415 A_OP(icode, &ptr, iSKIP, A_GPR_COND, A_GPR_COND, A_GPR(gpr - 2), A_C_00000001);
1416 A_OP(icode, &ptr, iACC3, A_GPR(tmp + 2), A_C_00000000, A_C_00010000, A_GPR(tmp + 2));
1417 A_OP(icode, &ptr, iANDXOR, A_GPR(tmp + 2), A_GPR(tmp + 2), A_GPR(gpr - 1), A_C_00000000);
1418 A_SWITCH(icode, &ptr, tmp + 0, tmp + 2, gpr + z);
1419 A_SWITCH_NEG(icode, &ptr, tmp + 1, gpr + z);
1420 A_SWITCH(icode, &ptr, tmp + 1, playback + SND_EMU10K1_PLAYBACK_CHANNELS + z, tmp + 1);
1421 if ((z==1) && (emu->card_capabilities->spdif_bug)) {
1422 /* Due to a SPDIF output bug on some Audigy cards, this code delays the Right channel by 1 sample */
1423 snd_printk(KERN_INFO "Installing spdif_bug patch: %s\n", emu->card_capabilities->name);
1424 A_OP(icode, &ptr, iACC3, A_EXTOUT(A_EXTOUT_FRONT_L + z), A_GPR(gpr - 3), A_C_00000000, A_C_00000000);
1425 A_OP(icode, &ptr, iACC3, A_GPR(gpr - 3), A_GPR(tmp + 0), A_GPR(tmp + 1), A_C_00000000);
1427 A_OP(icode, &ptr, iACC3, A_EXTOUT(A_EXTOUT_FRONT_L + z), A_GPR(tmp + 0), A_GPR(tmp + 1), A_C_00000000);
1430 snd_emu10k1_init_stereo_onoff_control(controls + nctl++, SNDRV_CTL_NAME_IEC958("Optical Raw ",PLAYBACK,SWITCH), gpr, 0);
1433 A_PUT_STEREO_OUTPUT(A_EXTOUT_REAR_L, A_EXTOUT_REAR_R, playback+2 + SND_EMU10K1_PLAYBACK_CHANNELS);
1434 A_PUT_OUTPUT(A_EXTOUT_CENTER, playback+4 + SND_EMU10K1_PLAYBACK_CHANNELS);
1435 A_PUT_OUTPUT(A_EXTOUT_LFE, playback+5 + SND_EMU10K1_PLAYBACK_CHANNELS);
1438 #ifdef EMU10K1_CAPTURE_DIGITAL_OUT
1439 A_PUT_STEREO_OUTPUT(A_EXTOUT_ADC_CAP_L, A_EXTOUT_ADC_CAP_R, playback + SND_EMU10K1_PLAYBACK_CHANNELS);
1441 A_PUT_OUTPUT(A_EXTOUT_ADC_CAP_L, capture);
1442 A_PUT_OUTPUT(A_EXTOUT_ADC_CAP_R, capture+1);
1445 /* EFX capture - capture the 16 EXTINs */
1446 for (z = 0; z < 16; z++) {
1447 A_OP(icode, &ptr, iACC3, A_FXBUS2(z), A_C_00000000, A_C_00000000, A_EXTIN(z));
1459 /* clear remaining instruction memory */
1461 A_OP(icode, &ptr, 0x0f, 0xc0, 0xc0, 0xcf, 0xc0);
1463 seg = snd_enter_user();
1464 icode->gpr_add_control_count = nctl;
1465 icode->gpr_add_controls = (struct snd_emu10k1_fx8010_control_gpr __user *)controls;
1466 err = snd_emu10k1_icode_poke(emu, icode);
1467 snd_leave_user(seg);
1471 if (icode != NULL) {
1472 kfree((void __force *)icode->gpr_map);
1480 * initial DSP configuration for Emu10k1
1483 /* when volume = max, then copy only to avoid volume modification */
1484 /* with iMAC0 (negative values) */
1485 static void __devinit _volume(struct snd_emu10k1_fx8010_code *icode, u32 *ptr, u32 dst, u32 src, u32 vol)
1487 OP(icode, ptr, iMAC0, dst, C_00000000, src, vol);
1488 OP(icode, ptr, iANDXOR, C_00000000, vol, C_ffffffff, C_7fffffff);
1489 OP(icode, ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, C_00000001);
1490 OP(icode, ptr, iACC3, dst, src, C_00000000, C_00000000);
1492 static void __devinit _volume_add(struct snd_emu10k1_fx8010_code *icode, u32 *ptr, u32 dst, u32 src, u32 vol)
1494 OP(icode, ptr, iANDXOR, C_00000000, vol, C_ffffffff, C_7fffffff);
1495 OP(icode, ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, C_00000002);
1496 OP(icode, ptr, iMACINT0, dst, dst, src, C_00000001);
1497 OP(icode, ptr, iSKIP, C_00000000, C_7fffffff, C_7fffffff, C_00000001);
1498 OP(icode, ptr, iMAC0, dst, dst, src, vol);
1500 static void __devinit _volume_out(struct snd_emu10k1_fx8010_code *icode, u32 *ptr, u32 dst, u32 src, u32 vol)
1502 OP(icode, ptr, iANDXOR, C_00000000, vol, C_ffffffff, C_7fffffff);
1503 OP(icode, ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, C_00000002);
1504 OP(icode, ptr, iACC3, dst, src, C_00000000, C_00000000);
1505 OP(icode, ptr, iSKIP, C_00000000, C_7fffffff, C_7fffffff, C_00000001);
1506 OP(icode, ptr, iMAC0, dst, C_00000000, src, vol);
1509 #define VOLUME(icode, ptr, dst, src, vol) \
1510 _volume(icode, ptr, GPR(dst), GPR(src), GPR(vol))
1511 #define VOLUME_IN(icode, ptr, dst, src, vol) \
1512 _volume(icode, ptr, GPR(dst), EXTIN(src), GPR(vol))
1513 #define VOLUME_ADD(icode, ptr, dst, src, vol) \
1514 _volume_add(icode, ptr, GPR(dst), GPR(src), GPR(vol))
1515 #define VOLUME_ADDIN(icode, ptr, dst, src, vol) \
1516 _volume_add(icode, ptr, GPR(dst), EXTIN(src), GPR(vol))
1517 #define VOLUME_OUT(icode, ptr, dst, src, vol) \
1518 _volume_out(icode, ptr, EXTOUT(dst), GPR(src), GPR(vol))
1519 #define _SWITCH(icode, ptr, dst, src, sw) \
1520 OP((icode), ptr, iMACINT0, dst, C_00000000, src, sw);
1521 #define SWITCH(icode, ptr, dst, src, sw) \
1522 _SWITCH(icode, ptr, GPR(dst), GPR(src), GPR(sw))
1523 #define SWITCH_IN(icode, ptr, dst, src, sw) \
1524 _SWITCH(icode, ptr, GPR(dst), EXTIN(src), GPR(sw))
1525 #define _SWITCH_NEG(icode, ptr, dst, src) \
1526 OP((icode), ptr, iANDXOR, dst, src, C_00000001, C_00000001);
1527 #define SWITCH_NEG(icode, ptr, dst, src) \
1528 _SWITCH_NEG(icode, ptr, GPR(dst), GPR(src))
1531 static int __devinit _snd_emu10k1_init_efx(struct snd_emu10k1 *emu)
1533 int err, i, z, gpr, tmp, playback, capture;
1535 struct snd_emu10k1_fx8010_code *icode;
1536 struct snd_emu10k1_fx8010_pcm_rec *ipcm = NULL;
1537 struct snd_emu10k1_fx8010_control_gpr *controls = NULL, *ctl;
1541 if ((icode = kzalloc(sizeof(*icode), GFP_KERNEL)) == NULL)
1543 if ((icode->gpr_map = (u_int32_t __user *)
1544 kcalloc(256 + 160 + 160 + 2 * 512, sizeof(u_int32_t),
1545 GFP_KERNEL)) == NULL ||
1546 (controls = kcalloc(SND_EMU10K1_GPR_CONTROLS,
1547 sizeof(struct snd_emu10k1_fx8010_control_gpr),
1548 GFP_KERNEL)) == NULL ||
1549 (ipcm = kzalloc(sizeof(*ipcm), GFP_KERNEL)) == NULL) {
1553 gpr_map = (u32 __force *)icode->gpr_map;
1555 icode->tram_data_map = icode->gpr_map + 256;
1556 icode->tram_addr_map = icode->tram_data_map + 160;
1557 icode->code = icode->tram_addr_map + 160;
1559 /* clear free GPRs */
1560 for (i = 0; i < 256; i++)
1561 set_bit(i, icode->gpr_valid);
1563 /* clear TRAM data & address lines */
1564 for (i = 0; i < 160; i++)
1565 set_bit(i, icode->tram_valid);
1567 strcpy(icode->name, "SB Live! FX8010 code for ALSA v1.2 by Jaroslav Kysela");
1569 /* we have 12 inputs */
1570 playback = SND_EMU10K1_INPUTS;
1571 /* we have 6 playback channels and tone control doubles */
1572 capture = playback + (SND_EMU10K1_PLAYBACK_CHANNELS * 2);
1573 gpr = capture + SND_EMU10K1_CAPTURE_CHANNELS;
1574 tmp = 0x88; /* we need 4 temporary GPR */
1575 /* from 0x8c to 0xff is the area for tone control */
1577 /* stop FX processor */
1578 snd_emu10k1_ptr_write(emu, DBG, 0, (emu->fx8010.dbg = 0) | EMU10K1_DBG_SINGLE_STEP);
1583 OP(icode, &ptr, iMACINT0, GPR(0), C_00000000, FXBUS(FXBUS_PCM_LEFT), C_00000004);
1584 OP(icode, &ptr, iMACINT0, GPR(1), C_00000000, FXBUS(FXBUS_PCM_RIGHT), C_00000004);
1585 OP(icode, &ptr, iMACINT0, GPR(2), C_00000000, FXBUS(FXBUS_MIDI_LEFT), C_00000004);
1586 OP(icode, &ptr, iMACINT0, GPR(3), C_00000000, FXBUS(FXBUS_MIDI_RIGHT), C_00000004);
1587 OP(icode, &ptr, iMACINT0, GPR(4), C_00000000, FXBUS(FXBUS_PCM_LEFT_REAR), C_00000004);
1588 OP(icode, &ptr, iMACINT0, GPR(5), C_00000000, FXBUS(FXBUS_PCM_RIGHT_REAR), C_00000004);
1589 OP(icode, &ptr, iMACINT0, GPR(6), C_00000000, FXBUS(FXBUS_PCM_CENTER), C_00000004);
1590 OP(icode, &ptr, iMACINT0, GPR(7), C_00000000, FXBUS(FXBUS_PCM_LFE), C_00000004);
1591 OP(icode, &ptr, iMACINT0, GPR(8), C_00000000, C_00000000, C_00000000); /* S/PDIF left */
1592 OP(icode, &ptr, iMACINT0, GPR(9), C_00000000, C_00000000, C_00000000); /* S/PDIF right */
1593 OP(icode, &ptr, iMACINT0, GPR(10), C_00000000, FXBUS(FXBUS_PCM_LEFT_FRONT), C_00000004);
1594 OP(icode, &ptr, iMACINT0, GPR(11), C_00000000, FXBUS(FXBUS_PCM_RIGHT_FRONT), C_00000004);
1596 /* Raw S/PDIF PCM */
1597 ipcm->substream = 0;
1599 ipcm->tram_start = 0;
1600 ipcm->buffer_size = (64 * 1024) / 2;
1601 ipcm->gpr_size = gpr++;
1602 ipcm->gpr_ptr = gpr++;
1603 ipcm->gpr_count = gpr++;
1604 ipcm->gpr_tmpcount = gpr++;
1605 ipcm->gpr_trigger = gpr++;
1606 ipcm->gpr_running = gpr++;
1610 gpr_map[gpr + 0] = 0xfffff000;
1611 gpr_map[gpr + 1] = 0xffff0000;
1612 gpr_map[gpr + 2] = 0x70000000;
1613 gpr_map[gpr + 3] = 0x00000007;
1614 gpr_map[gpr + 4] = 0x001f << 11;
1615 gpr_map[gpr + 5] = 0x001c << 11;
1616 gpr_map[gpr + 6] = (0x22 - 0x01) - 1; /* skip at 01 to 22 */
1617 gpr_map[gpr + 7] = (0x22 - 0x06) - 1; /* skip at 06 to 22 */
1618 gpr_map[gpr + 8] = 0x2000000 + (2<<11);
1619 gpr_map[gpr + 9] = 0x4000000 + (2<<11);
1620 gpr_map[gpr + 10] = 1<<11;
1621 gpr_map[gpr + 11] = (0x24 - 0x0a) - 1; /* skip at 0a to 24 */
1622 gpr_map[gpr + 12] = 0;
1624 /* if the trigger flag is not set, skip */
1625 /* 00: */ OP(icode, &ptr, iMAC0, C_00000000, GPR(ipcm->gpr_trigger), C_00000000, C_00000000);
1626 /* 01: */ OP(icode, &ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_ZERO, GPR(gpr + 6));
1627 /* if the running flag is set, we're running */
1628 /* 02: */ OP(icode, &ptr, iMAC0, C_00000000, GPR(ipcm->gpr_running), C_00000000, C_00000000);
1629 /* 03: */ OP(icode, &ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, C_00000004);
1630 /* wait until ((GPR_DBAC>>11) & 0x1f) == 0x1c) */
1631 /* 04: */ OP(icode, &ptr, iANDXOR, GPR(tmp + 0), GPR_DBAC, GPR(gpr + 4), C_00000000);
1632 /* 05: */ OP(icode, &ptr, iMACINT0, C_00000000, GPR(tmp + 0), C_ffffffff, GPR(gpr + 5));
1633 /* 06: */ OP(icode, &ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, GPR(gpr + 7));
1634 /* 07: */ OP(icode, &ptr, iACC3, GPR(gpr + 12), C_00000010, C_00000001, C_00000000);
1636 /* 08: */ OP(icode, &ptr, iANDXOR, GPR(ipcm->gpr_running), GPR(ipcm->gpr_running), C_00000000, C_00000001);
1637 /* 09: */ OP(icode, &ptr, iACC3, GPR(gpr + 12), GPR(gpr + 12), C_ffffffff, C_00000000);
1638 /* 0a: */ OP(icode, &ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, GPR(gpr + 11));
1639 /* 0b: */ OP(icode, &ptr, iACC3, GPR(gpr + 12), C_00000001, C_00000000, C_00000000);
1641 /* 0c: */ OP(icode, &ptr, iANDXOR, GPR(tmp + 0), ETRAM_DATA(ipcm->etram[0]), GPR(gpr + 0), C_00000000);
1642 /* 0d: */ OP(icode, &ptr, iLOG, GPR(tmp + 0), GPR(tmp + 0), GPR(gpr + 3), C_00000000);
1643 /* 0e: */ OP(icode, &ptr, iANDXOR, GPR(8), GPR(tmp + 0), GPR(gpr + 1), GPR(gpr + 2));
1644 /* 0f: */ OP(icode, &ptr, iSKIP, C_00000000, GPR_COND, CC_REG_MINUS, C_00000001);
1645 /* 10: */ OP(icode, &ptr, iANDXOR, GPR(8), GPR(8), GPR(gpr + 1), GPR(gpr + 2));
1647 /* 11: */ OP(icode, &ptr, iANDXOR, GPR(tmp + 0), ETRAM_DATA(ipcm->etram[1]), GPR(gpr + 0), C_00000000);
1648 /* 12: */ OP(icode, &ptr, iLOG, GPR(tmp + 0), GPR(tmp + 0), GPR(gpr + 3), C_00000000);
1649 /* 13: */ OP(icode, &ptr, iANDXOR, GPR(9), GPR(tmp + 0), GPR(gpr + 1), GPR(gpr + 2));
1650 /* 14: */ OP(icode, &ptr, iSKIP, C_00000000, GPR_COND, CC_REG_MINUS, C_00000001);
1651 /* 15: */ OP(icode, &ptr, iANDXOR, GPR(9), GPR(9), GPR(gpr + 1), GPR(gpr + 2));
1653 /* 16: */ OP(icode, &ptr, iACC3, GPR(tmp + 0), GPR(ipcm->gpr_ptr), C_00000001, C_00000000);
1654 /* 17: */ OP(icode, &ptr, iMACINT0, C_00000000, GPR(tmp + 0), C_ffffffff, GPR(ipcm->gpr_size));
1655 /* 18: */ OP(icode, &ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_MINUS, C_00000001);
1656 /* 19: */ OP(icode, &ptr, iACC3, GPR(tmp + 0), C_00000000, C_00000000, C_00000000);
1657 /* 1a: */ OP(icode, &ptr, iACC3, GPR(ipcm->gpr_ptr), GPR(tmp + 0), C_00000000, C_00000000);
1659 /* 1b: */ OP(icode, &ptr, iACC3, GPR(ipcm->gpr_tmpcount), GPR(ipcm->gpr_tmpcount), C_ffffffff, C_00000000);
1660 /* 1c: */ OP(icode, &ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, C_00000002);
1661 /* 1d: */ OP(icode, &ptr, iACC3, GPR(ipcm->gpr_tmpcount), GPR(ipcm->gpr_count), C_00000000, C_00000000);
1662 /* 1e: */ OP(icode, &ptr, iACC3, GPR_IRQ, C_80000000, C_00000000, C_00000000);
1663 /* 1f: */ OP(icode, &ptr, iANDXOR, GPR(ipcm->gpr_running), GPR(ipcm->gpr_running), C_00000001, C_00010000);
1665 /* 20: */ OP(icode, &ptr, iANDXOR, GPR(ipcm->gpr_running), GPR(ipcm->gpr_running), C_00010000, C_00000001);
1666 /* 21: */ OP(icode, &ptr, iSKIP, C_00000000, C_7fffffff, C_7fffffff, C_00000002);
1668 /* 22: */ OP(icode, &ptr, iMACINT1, ETRAM_ADDR(ipcm->etram[0]), GPR(gpr + 8), GPR_DBAC, C_ffffffff);
1669 /* 23: */ OP(icode, &ptr, iMACINT1, ETRAM_ADDR(ipcm->etram[1]), GPR(gpr + 9), GPR_DBAC, C_ffffffff);
1674 /* Wave Playback Volume */
1675 for (z = 0; z < 2; z++)
1676 VOLUME(icode, &ptr, playback + z, z, gpr + z);
1677 snd_emu10k1_init_stereo_control(controls + i++, "Wave Playback Volume", gpr, 100);
1680 /* Wave Surround Playback Volume */
1681 for (z = 0; z < 2; z++)
1682 VOLUME(icode, &ptr, playback + 2 + z, z, gpr + z);
1683 snd_emu10k1_init_stereo_control(controls + i++, "Wave Surround Playback Volume", gpr, 0);
1686 /* Wave Center/LFE Playback Volume */
1687 OP(icode, &ptr, iACC3, GPR(tmp + 0), FXBUS(FXBUS_PCM_LEFT), FXBUS(FXBUS_PCM_RIGHT), C_00000000);
1688 OP(icode, &ptr, iMACINT0, GPR(tmp + 0), C_00000000, GPR(tmp + 0), C_00000002);
1689 VOLUME(icode, &ptr, playback + 4, tmp + 0, gpr);
1690 snd_emu10k1_init_mono_control(controls + i++, "Wave Center Playback Volume", gpr++, 0);
1691 VOLUME(icode, &ptr, playback + 5, tmp + 0, gpr);
1692 snd_emu10k1_init_mono_control(controls + i++, "Wave LFE Playback Volume", gpr++, 0);
1694 /* Wave Capture Volume + Switch */
1695 for (z = 0; z < 2; z++) {
1696 SWITCH(icode, &ptr, tmp + 0, z, gpr + 2 + z);
1697 VOLUME(icode, &ptr, capture + z, tmp + 0, gpr + z);
1699 snd_emu10k1_init_stereo_control(controls + i++, "Wave Capture Volume", gpr, 0);
1700 snd_emu10k1_init_stereo_onoff_control(controls + i++, "Wave Capture Switch", gpr + 2, 0);
1703 /* Synth Playback Volume */
1704 for (z = 0; z < 2; z++)
1705 VOLUME_ADD(icode, &ptr, playback + z, 2 + z, gpr + z);
1706 snd_emu10k1_init_stereo_control(controls + i++, "Synth Playback Volume", gpr, 100);
1709 /* Synth Capture Volume + Switch */
1710 for (z = 0; z < 2; z++) {
1711 SWITCH(icode, &ptr, tmp + 0, 2 + z, gpr + 2 + z);
1712 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
1714 snd_emu10k1_init_stereo_control(controls + i++, "Synth Capture Volume", gpr, 0);
1715 snd_emu10k1_init_stereo_onoff_control(controls + i++, "Synth Capture Switch", gpr + 2, 0);
1718 /* Surround Digital Playback Volume (renamed later without Digital) */
1719 for (z = 0; z < 2; z++)
1720 VOLUME_ADD(icode, &ptr, playback + 2 + z, 4 + z, gpr + z);
1721 snd_emu10k1_init_stereo_control(controls + i++, "Surround Digital Playback Volume", gpr, 100);
1724 /* Surround Capture Volume + Switch */
1725 for (z = 0; z < 2; z++) {
1726 SWITCH(icode, &ptr, tmp + 0, 4 + z, gpr + 2 + z);
1727 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
1729 snd_emu10k1_init_stereo_control(controls + i++, "Surround Capture Volume", gpr, 0);
1730 snd_emu10k1_init_stereo_onoff_control(controls + i++, "Surround Capture Switch", gpr + 2, 0);
1733 /* Center Playback Volume (renamed later without Digital) */
1734 VOLUME_ADD(icode, &ptr, playback + 4, 6, gpr);
1735 snd_emu10k1_init_mono_control(controls + i++, "Center Digital Playback Volume", gpr++, 100);
1737 /* LFE Playback Volume + Switch (renamed later without Digital) */
1738 VOLUME_ADD(icode, &ptr, playback + 5, 7, gpr);
1739 snd_emu10k1_init_mono_control(controls + i++, "LFE Digital Playback Volume", gpr++, 100);
1741 /* Front Playback Volume */
1742 for (z = 0; z < 2; z++)
1743 VOLUME_ADD(icode, &ptr, playback + z, 10 + z, gpr + z);
1744 snd_emu10k1_init_stereo_control(controls + i++, "Front Playback Volume", gpr, 100);
1747 /* Front Capture Volume + Switch */
1748 for (z = 0; z < 2; z++) {
1749 SWITCH(icode, &ptr, tmp + 0, 10 + z, gpr + 2);
1750 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
1752 snd_emu10k1_init_stereo_control(controls + i++, "Front Capture Volume", gpr, 0);
1753 snd_emu10k1_init_mono_onoff_control(controls + i++, "Front Capture Switch", gpr + 2, 0);
1760 if (emu->fx8010.extin_mask & ((1<<EXTIN_AC97_L)|(1<<EXTIN_AC97_R))) {
1761 /* AC'97 Playback Volume */
1762 VOLUME_ADDIN(icode, &ptr, playback + 0, EXTIN_AC97_L, gpr); gpr++;
1763 VOLUME_ADDIN(icode, &ptr, playback + 1, EXTIN_AC97_R, gpr); gpr++;
1764 snd_emu10k1_init_stereo_control(controls + i++, "AC97 Playback Volume", gpr-2, 0);
1765 /* AC'97 Capture Volume */
1766 VOLUME_ADDIN(icode, &ptr, capture + 0, EXTIN_AC97_L, gpr); gpr++;
1767 VOLUME_ADDIN(icode, &ptr, capture + 1, EXTIN_AC97_R, gpr); gpr++;
1768 snd_emu10k1_init_stereo_control(controls + i++, "AC97 Capture Volume", gpr-2, 100);
1771 if (emu->fx8010.extin_mask & ((1<<EXTIN_SPDIF_CD_L)|(1<<EXTIN_SPDIF_CD_R))) {
1772 /* IEC958 TTL Playback Volume */
1773 for (z = 0; z < 2; z++)
1774 VOLUME_ADDIN(icode, &ptr, playback + z, EXTIN_SPDIF_CD_L + z, gpr + z);
1775 snd_emu10k1_init_stereo_control(controls + i++, SNDRV_CTL_NAME_IEC958("TTL ",PLAYBACK,VOLUME), gpr, 0);
1778 /* IEC958 TTL Capture Volume + Switch */
1779 for (z = 0; z < 2; z++) {
1780 SWITCH_IN(icode, &ptr, tmp + 0, EXTIN_SPDIF_CD_L + z, gpr + 2 + z);
1781 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
1783 snd_emu10k1_init_stereo_control(controls + i++, SNDRV_CTL_NAME_IEC958("TTL ",CAPTURE,VOLUME), gpr, 0);
1784 snd_emu10k1_init_stereo_onoff_control(controls + i++, SNDRV_CTL_NAME_IEC958("TTL ",CAPTURE,SWITCH), gpr + 2, 0);
1788 if (emu->fx8010.extin_mask & ((1<<EXTIN_ZOOM_L)|(1<<EXTIN_ZOOM_R))) {
1789 /* Zoom Video Playback Volume */
1790 for (z = 0; z < 2; z++)
1791 VOLUME_ADDIN(icode, &ptr, playback + z, EXTIN_ZOOM_L + z, gpr + z);
1792 snd_emu10k1_init_stereo_control(controls + i++, "Zoom Video Playback Volume", gpr, 0);
1795 /* Zoom Video Capture Volume + Switch */
1796 for (z = 0; z < 2; z++) {
1797 SWITCH_IN(icode, &ptr, tmp + 0, EXTIN_ZOOM_L + z, gpr + 2 + z);
1798 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
1800 snd_emu10k1_init_stereo_control(controls + i++, "Zoom Video Capture Volume", gpr, 0);
1801 snd_emu10k1_init_stereo_onoff_control(controls + i++, "Zoom Video Capture Switch", gpr + 2, 0);
1805 if (emu->fx8010.extin_mask & ((1<<EXTIN_TOSLINK_L)|(1<<EXTIN_TOSLINK_R))) {
1806 /* IEC958 Optical Playback Volume */
1807 for (z = 0; z < 2; z++)
1808 VOLUME_ADDIN(icode, &ptr, playback + z, EXTIN_TOSLINK_L + z, gpr + z);
1809 snd_emu10k1_init_stereo_control(controls + i++, SNDRV_CTL_NAME_IEC958("LiveDrive ",PLAYBACK,VOLUME), gpr, 0);
1812 /* IEC958 Optical Capture Volume */
1813 for (z = 0; z < 2; z++) {
1814 SWITCH_IN(icode, &ptr, tmp + 0, EXTIN_TOSLINK_L + z, gpr + 2 + z);
1815 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
1817 snd_emu10k1_init_stereo_control(controls + i++, SNDRV_CTL_NAME_IEC958("LiveDrive ",CAPTURE,VOLUME), gpr, 0);
1818 snd_emu10k1_init_stereo_onoff_control(controls + i++, SNDRV_CTL_NAME_IEC958("LiveDrive ",CAPTURE,SWITCH), gpr + 2, 0);
1822 if (emu->fx8010.extin_mask & ((1<<EXTIN_LINE1_L)|(1<<EXTIN_LINE1_R))) {
1823 /* Line LiveDrive Playback Volume */
1824 for (z = 0; z < 2; z++)
1825 VOLUME_ADDIN(icode, &ptr, playback + z, EXTIN_LINE1_L + z, gpr + z);
1826 snd_emu10k1_init_stereo_control(controls + i++, "Line LiveDrive Playback Volume", gpr, 0);
1829 /* Line LiveDrive Capture Volume + Switch */
1830 for (z = 0; z < 2; z++) {
1831 SWITCH_IN(icode, &ptr, tmp + 0, EXTIN_LINE1_L + z, gpr + 2 + z);
1832 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
1834 snd_emu10k1_init_stereo_control(controls + i++, "Line LiveDrive Capture Volume", gpr, 0);
1835 snd_emu10k1_init_stereo_onoff_control(controls + i++, "Line LiveDrive Capture Switch", gpr + 2, 0);
1839 if (emu->fx8010.extin_mask & ((1<<EXTIN_COAX_SPDIF_L)|(1<<EXTIN_COAX_SPDIF_R))) {
1840 /* IEC958 Coax Playback Volume */
1841 for (z = 0; z < 2; z++)
1842 VOLUME_ADDIN(icode, &ptr, playback + z, EXTIN_COAX_SPDIF_L + z, gpr + z);
1843 snd_emu10k1_init_stereo_control(controls + i++, SNDRV_CTL_NAME_IEC958("Coaxial ",PLAYBACK,VOLUME), gpr, 0);
1846 /* IEC958 Coax Capture Volume + Switch */
1847 for (z = 0; z < 2; z++) {
1848 SWITCH_IN(icode, &ptr, tmp + 0, EXTIN_COAX_SPDIF_L + z, gpr + 2 + z);
1849 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
1851 snd_emu10k1_init_stereo_control(controls + i++, SNDRV_CTL_NAME_IEC958("Coaxial ",CAPTURE,VOLUME), gpr, 0);
1852 snd_emu10k1_init_stereo_onoff_control(controls + i++, SNDRV_CTL_NAME_IEC958("Coaxial ",CAPTURE,SWITCH), gpr + 2, 0);
1856 if (emu->fx8010.extin_mask & ((1<<EXTIN_LINE2_L)|(1<<EXTIN_LINE2_R))) {
1857 /* Line LiveDrive Playback Volume */
1858 for (z = 0; z < 2; z++)
1859 VOLUME_ADDIN(icode, &ptr, playback + z, EXTIN_LINE2_L + z, gpr + z);
1860 snd_emu10k1_init_stereo_control(controls + i++, "Line2 LiveDrive Playback Volume", gpr, 0);
1861 controls[i-1].id.index = 1;
1864 /* Line LiveDrive Capture Volume */
1865 for (z = 0; z < 2; z++) {
1866 SWITCH_IN(icode, &ptr, tmp + 0, EXTIN_LINE2_L + z, gpr + 2 + z);
1867 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
1869 snd_emu10k1_init_stereo_control(controls + i++, "Line2 LiveDrive Capture Volume", gpr, 0);
1870 controls[i-1].id.index = 1;
1871 snd_emu10k1_init_stereo_onoff_control(controls + i++, "Line2 LiveDrive Capture Switch", gpr + 2, 0);
1872 controls[i-1].id.index = 1;
1877 * Process tone control
1879 OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 0), GPR(playback + 0), C_00000000, C_00000000); /* left */
1880 OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 1), GPR(playback + 1), C_00000000, C_00000000); /* right */
1881 OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 2), GPR(playback + 2), C_00000000, C_00000000); /* rear left */
1882 OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 3), GPR(playback + 3), C_00000000, C_00000000); /* rear right */
1883 OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 4), GPR(playback + 4), C_00000000, C_00000000); /* center */
1884 OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 5), GPR(playback + 5), C_00000000, C_00000000); /* LFE */
1886 ctl = &controls[i + 0];
1887 ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1888 strcpy(ctl->id.name, "Tone Control - Bass");
1893 ctl->value[0] = ctl->value[1] = 20;
1894 ctl->translation = EMU10K1_GPR_TRANSLATION_BASS;
1895 ctl = &controls[i + 1];
1896 ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1897 strcpy(ctl->id.name, "Tone Control - Treble");
1902 ctl->value[0] = ctl->value[1] = 20;
1903 ctl->translation = EMU10K1_GPR_TRANSLATION_TREBLE;
1905 #define BASS_GPR 0x8c
1906 #define TREBLE_GPR 0x96
1908 for (z = 0; z < 5; z++) {
1910 for (j = 0; j < 2; j++) {
1911 controls[i + 0].gpr[z * 2 + j] = BASS_GPR + z * 2 + j;
1912 controls[i + 1].gpr[z * 2 + j] = TREBLE_GPR + z * 2 + j;
1915 for (z = 0; z < 3; z++) { /* front/rear/center-lfe */
1917 for (j = 0; j < 2; j++) { /* left/right */
1918 k = 0xa0 + (z * 8) + (j * 4);
1919 l = 0xd0 + (z * 8) + (j * 4);
1920 d = playback + SND_EMU10K1_PLAYBACK_CHANNELS + z * 2 + j;
1922 OP(icode, &ptr, iMAC0, C_00000000, C_00000000, GPR(d), GPR(BASS_GPR + 0 + j));
1923 OP(icode, &ptr, iMACMV, GPR(k+1), GPR(k), GPR(k+1), GPR(BASS_GPR + 4 + j));
1924 OP(icode, &ptr, iMACMV, GPR(k), GPR(d), GPR(k), GPR(BASS_GPR + 2 + j));
1925 OP(icode, &ptr, iMACMV, GPR(k+3), GPR(k+2), GPR(k+3), GPR(BASS_GPR + 8 + j));
1926 OP(icode, &ptr, iMAC0, GPR(k+2), GPR_ACCU, GPR(k+2), GPR(BASS_GPR + 6 + j));
1927 OP(icode, &ptr, iACC3, GPR(k+2), GPR(k+2), GPR(k+2), C_00000000);
1929 OP(icode, &ptr, iMAC0, C_00000000, C_00000000, GPR(k+2), GPR(TREBLE_GPR + 0 + j));
1930 OP(icode, &ptr, iMACMV, GPR(l+1), GPR(l), GPR(l+1), GPR(TREBLE_GPR + 4 + j));
1931 OP(icode, &ptr, iMACMV, GPR(l), GPR(k+2), GPR(l), GPR(TREBLE_GPR + 2 + j));
1932 OP(icode, &ptr, iMACMV, GPR(l+3), GPR(l+2), GPR(l+3), GPR(TREBLE_GPR + 8 + j));
1933 OP(icode, &ptr, iMAC0, GPR(l+2), GPR_ACCU, GPR(l+2), GPR(TREBLE_GPR + 6 + j));
1934 OP(icode, &ptr, iMACINT0, GPR(l+2), C_00000000, GPR(l+2), C_00000010);
1936 OP(icode, &ptr, iACC3, GPR(d), GPR(l+2), C_00000000, C_00000000);
1938 if (z == 2) /* center */
1947 for (z = 0; z < 6; z++) {
1948 SWITCH(icode, &ptr, tmp + 0, playback + SND_EMU10K1_PLAYBACK_CHANNELS + z, gpr + 0);
1949 SWITCH_NEG(icode, &ptr, tmp + 1, gpr + 0);
1950 SWITCH(icode, &ptr, tmp + 1, playback + z, tmp + 1);
1951 OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + z), GPR(tmp + 0), GPR(tmp + 1), C_00000000);
1953 snd_emu10k1_init_stereo_onoff_control(controls + i++, "Tone Control - Switch", gpr, 0);
1959 if (emu->fx8010.extout_mask & ((1<<EXTOUT_AC97_L)|(1<<EXTOUT_AC97_R))) {
1960 /* AC'97 Playback Volume */
1962 for (z = 0; z < 2; z++)
1963 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_AC97_L + z), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + z), C_00000000, C_00000000);
1966 if (emu->fx8010.extout_mask & ((1<<EXTOUT_TOSLINK_L)|(1<<EXTOUT_TOSLINK_R))) {
1967 /* IEC958 Optical Raw Playback Switch */
1969 for (z = 0; z < 2; z++) {
1970 SWITCH(icode, &ptr, tmp + 0, 8 + z, gpr + z);
1971 SWITCH_NEG(icode, &ptr, tmp + 1, gpr + z);
1972 SWITCH(icode, &ptr, tmp + 1, playback + SND_EMU10K1_PLAYBACK_CHANNELS + z, tmp + 1);
1973 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_TOSLINK_L + z), GPR(tmp + 0), GPR(tmp + 1), C_00000000);
1974 #ifdef EMU10K1_CAPTURE_DIGITAL_OUT
1975 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_ADC_CAP_L + z), GPR(tmp + 0), GPR(tmp + 1), C_00000000);
1979 snd_emu10k1_init_stereo_onoff_control(controls + i++, SNDRV_CTL_NAME_IEC958("Optical Raw ",PLAYBACK,SWITCH), gpr, 0);
1983 if (emu->fx8010.extout_mask & ((1<<EXTOUT_HEADPHONE_L)|(1<<EXTOUT_HEADPHONE_R))) {
1984 /* Headphone Playback Volume */
1986 for (z = 0; z < 2; z++) {
1987 SWITCH(icode, &ptr, tmp + 0, playback + SND_EMU10K1_PLAYBACK_CHANNELS + 4 + z, gpr + 2 + z);
1988 SWITCH_NEG(icode, &ptr, tmp + 1, gpr + 2 + z);
1989 SWITCH(icode, &ptr, tmp + 1, playback + SND_EMU10K1_PLAYBACK_CHANNELS + z, tmp + 1);
1990 OP(icode, &ptr, iACC3, GPR(tmp + 0), GPR(tmp + 0), GPR(tmp + 1), C_00000000);
1991 VOLUME_OUT(icode, &ptr, EXTOUT_HEADPHONE_L + z, tmp + 0, gpr + z);
1994 snd_emu10k1_init_stereo_control(controls + i++, "Headphone Playback Volume", gpr + 0, 0);
1995 controls[i-1].id.index = 1; /* AC'97 can have also Headphone control */
1996 snd_emu10k1_init_mono_onoff_control(controls + i++, "Headphone Center Playback Switch", gpr + 2, 0);
1997 controls[i-1].id.index = 1;
1998 snd_emu10k1_init_mono_onoff_control(controls + i++, "Headphone LFE Playback Switch", gpr + 3, 0);
1999 controls[i-1].id.index = 1;
2004 if (emu->fx8010.extout_mask & ((1<<EXTOUT_REAR_L)|(1<<EXTOUT_REAR_R)))
2005 for (z = 0; z < 2; z++)
2006 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_REAR_L + z), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 2 + z), C_00000000, C_00000000);
2008 if (emu->fx8010.extout_mask & ((1<<EXTOUT_AC97_REAR_L)|(1<<EXTOUT_AC97_REAR_R)))
2009 for (z = 0; z < 2; z++)
2010 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_AC97_REAR_L + z), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 2 + z), C_00000000, C_00000000);
2012 if (emu->fx8010.extout_mask & (1<<EXTOUT_AC97_CENTER)) {
2013 #ifndef EMU10K1_CENTER_LFE_FROM_FRONT
2014 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_AC97_CENTER), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 4), C_00000000, C_00000000);
2015 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_ACENTER), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 4), C_00000000, C_00000000);
2017 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_AC97_CENTER), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 0), C_00000000, C_00000000);
2018 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_ACENTER), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 0), C_00000000, C_00000000);
2022 if (emu->fx8010.extout_mask & (1<<EXTOUT_AC97_LFE)) {
2023 #ifndef EMU10K1_CENTER_LFE_FROM_FRONT
2024 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_AC97_LFE), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 5), C_00000000, C_00000000);
2025 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_ALFE), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 5), C_00000000, C_00000000);
2027 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_AC97_LFE), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 1), C_00000000, C_00000000);
2028 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_ALFE), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 1), C_00000000, C_00000000);
2032 #ifndef EMU10K1_CAPTURE_DIGITAL_OUT
2033 for (z = 0; z < 2; z++)
2034 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_ADC_CAP_L + z), GPR(capture + z), C_00000000, C_00000000);
2037 if (emu->fx8010.extout_mask & (1<<EXTOUT_MIC_CAP))
2038 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_MIC_CAP), GPR(capture + 2), C_00000000, C_00000000);
2040 /* EFX capture - capture the 16 EXTINS */
2041 if (emu->card_capabilities->sblive51) {
2042 /* On the Live! 5.1, FXBUS2(1) and FXBUS(2) are shared with EXTOUT_ACENTER
2043 * and EXTOUT_ALFE, so we can't connect inputs to them for multitrack recording.
2045 * Since only 14 of the 16 EXTINs are used, this is not a big problem.
2046 * We route AC97L and R to FX capture 14 and 15, SPDIF CD in to FX capture
2047 * 0 and 3, then the rest of the EXTINs to the corresponding FX capture
2048 * channel. Multitrack recorders will still see the center/lfe output signal
2049 * on the second and third channels.
2051 OP(icode, &ptr, iACC3, FXBUS2(14), C_00000000, C_00000000, EXTIN(0));
2052 OP(icode, &ptr, iACC3, FXBUS2(15), C_00000000, C_00000000, EXTIN(1));
2053 OP(icode, &ptr, iACC3, FXBUS2(0), C_00000000, C_00000000, EXTIN(2));
2054 OP(icode, &ptr, iACC3, FXBUS2(3), C_00000000, C_00000000, EXTIN(3));
2055 for (z = 4; z < 14; z++)
2056 OP(icode, &ptr, iACC3, FXBUS2(z), C_00000000, C_00000000, EXTIN(z));
2058 for (z = 0; z < 16; z++)
2059 OP(icode, &ptr, iACC3, FXBUS2(z), C_00000000, C_00000000, EXTIN(z));
2068 if (i > SND_EMU10K1_GPR_CONTROLS) {
2074 /* clear remaining instruction memory */
2076 OP(icode, &ptr, iACC3, C_00000000, C_00000000, C_00000000, C_00000000);
2078 if ((err = snd_emu10k1_fx8010_tram_setup(emu, ipcm->buffer_size)) < 0)
2080 seg = snd_enter_user();
2081 icode->gpr_add_control_count = i;
2082 icode->gpr_add_controls = (struct snd_emu10k1_fx8010_control_gpr __user *)controls;
2083 err = snd_emu10k1_icode_poke(emu, icode);
2084 snd_leave_user(seg);
2086 err = snd_emu10k1_ipcm_poke(emu, ipcm);
2090 if (icode != NULL) {
2091 kfree((void __force *)icode->gpr_map);
2097 int __devinit snd_emu10k1_init_efx(struct snd_emu10k1 *emu)
2099 spin_lock_init(&emu->fx8010.irq_lock);
2100 INIT_LIST_HEAD(&emu->fx8010.gpr_ctl);
2102 return _snd_emu10k1_audigy_init_efx(emu);
2104 return _snd_emu10k1_init_efx(emu);
2107 void snd_emu10k1_free_efx(struct snd_emu10k1 *emu)
2109 /* stop processor */
2111 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg = A_DBG_SINGLE_STEP);
2113 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg = EMU10K1_DBG_SINGLE_STEP);
2116 #if 0 // FIXME: who use them?
2117 int snd_emu10k1_fx8010_tone_control_activate(struct snd_emu10k1 *emu, int output)
2119 if (output < 0 || output >= 6)
2121 snd_emu10k1_ptr_write(emu, emu->gpr_base + 0x94 + output, 0, 1);
2125 int snd_emu10k1_fx8010_tone_control_deactivate(struct snd_emu10k1 *emu, int output)
2127 if (output < 0 || output >= 6)
2129 snd_emu10k1_ptr_write(emu, emu->gpr_base + 0x94 + output, 0, 0);
2134 int snd_emu10k1_fx8010_tram_setup(struct snd_emu10k1 *emu, u32 size)
2138 /* size is in samples */
2140 size = (size - 1) >> 13;
2146 size = 0x2000 << size_reg;
2148 if ((emu->fx8010.etram_pages.bytes / 2) == size)
2150 spin_lock_irq(&emu->emu_lock);
2151 outl(HCFG_LOCKTANKCACHE_MASK | inl(emu->port + HCFG), emu->port + HCFG);
2152 spin_unlock_irq(&emu->emu_lock);
2153 snd_emu10k1_ptr_write(emu, TCB, 0, 0);
2154 snd_emu10k1_ptr_write(emu, TCBS, 0, 0);
2155 if (emu->fx8010.etram_pages.area != NULL) {
2156 snd_dma_free_pages(&emu->fx8010.etram_pages);
2157 emu->fx8010.etram_pages.area = NULL;
2158 emu->fx8010.etram_pages.bytes = 0;
2162 if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(emu->pci),
2163 size * 2, &emu->fx8010.etram_pages) < 0)
2165 memset(emu->fx8010.etram_pages.area, 0, size * 2);
2166 snd_emu10k1_ptr_write(emu, TCB, 0, emu->fx8010.etram_pages.addr);
2167 snd_emu10k1_ptr_write(emu, TCBS, 0, size_reg);
2168 spin_lock_irq(&emu->emu_lock);
2169 outl(inl(emu->port + HCFG) & ~HCFG_LOCKTANKCACHE_MASK, emu->port + HCFG);
2170 spin_unlock_irq(&emu->emu_lock);
2176 static int snd_emu10k1_fx8010_open(struct snd_hwdep * hw, struct file *file)
2181 static void copy_string(char *dst, char *src, char *null, int idx)
2184 sprintf(dst, "%s %02X", null, idx);
2189 static int snd_emu10k1_fx8010_info(struct snd_emu10k1 *emu,
2190 struct snd_emu10k1_fx8010_info *info)
2192 char **fxbus, **extin, **extout;
2193 unsigned short fxbus_mask, extin_mask, extout_mask;
2196 memset(info, 0, sizeof(info));
2197 info->internal_tram_size = emu->fx8010.itram_size;
2198 info->external_tram_size = emu->fx8010.etram_pages.bytes / 2;
2200 extin = emu->audigy ? audigy_ins : creative_ins;
2201 extout = emu->audigy ? audigy_outs : creative_outs;
2202 fxbus_mask = emu->fx8010.fxbus_mask;
2203 extin_mask = emu->fx8010.extin_mask;
2204 extout_mask = emu->fx8010.extout_mask;
2205 for (res = 0; res < 16; res++, fxbus++, extin++, extout++) {
2206 copy_string(info->fxbus_names[res], fxbus_mask & (1 << res) ? *fxbus : NULL, "FXBUS", res);
2207 copy_string(info->extin_names[res], extin_mask & (1 << res) ? *extin : NULL, "Unused", res);
2208 copy_string(info->extout_names[res], extout_mask & (1 << res) ? *extout : NULL, "Unused", res);
2210 for (res = 16; res < 32; res++, extout++)
2211 copy_string(info->extout_names[res], extout_mask & (1 << res) ? *extout : NULL, "Unused", res);
2212 info->gpr_controls = emu->fx8010.gpr_count;
2216 static int snd_emu10k1_fx8010_ioctl(struct snd_hwdep * hw, struct file *file, unsigned int cmd, unsigned long arg)
2218 struct snd_emu10k1 *emu = hw->private_data;
2219 struct snd_emu10k1_fx8010_info *info;
2220 struct snd_emu10k1_fx8010_code *icode;
2221 struct snd_emu10k1_fx8010_pcm_rec *ipcm;
2223 void __user *argp = (void __user *)arg;
2227 case SNDRV_EMU10K1_IOCTL_INFO:
2228 info = kmalloc(sizeof(*info), GFP_KERNEL);
2231 if ((res = snd_emu10k1_fx8010_info(emu, info)) < 0) {
2235 if (copy_to_user(argp, info, sizeof(*info))) {
2241 case SNDRV_EMU10K1_IOCTL_CODE_POKE:
2242 if (!capable(CAP_SYS_ADMIN))
2244 icode = kmalloc(sizeof(*icode), GFP_KERNEL);
2247 if (copy_from_user(icode, argp, sizeof(*icode))) {
2251 res = snd_emu10k1_icode_poke(emu, icode);
2254 case SNDRV_EMU10K1_IOCTL_CODE_PEEK:
2255 icode = kmalloc(sizeof(*icode), GFP_KERNEL);
2258 if (copy_from_user(icode, argp, sizeof(*icode))) {
2262 res = snd_emu10k1_icode_peek(emu, icode);
2263 if (res == 0 && copy_to_user(argp, icode, sizeof(*icode))) {
2269 case SNDRV_EMU10K1_IOCTL_PCM_POKE:
2270 ipcm = kmalloc(sizeof(*ipcm), GFP_KERNEL);
2273 if (copy_from_user(ipcm, argp, sizeof(*ipcm))) {
2277 res = snd_emu10k1_ipcm_poke(emu, ipcm);
2280 case SNDRV_EMU10K1_IOCTL_PCM_PEEK:
2281 ipcm = kzalloc(sizeof(*ipcm), GFP_KERNEL);
2284 if (copy_from_user(ipcm, argp, sizeof(*ipcm))) {
2288 res = snd_emu10k1_ipcm_peek(emu, ipcm);
2289 if (res == 0 && copy_to_user(argp, ipcm, sizeof(*ipcm))) {
2295 case SNDRV_EMU10K1_IOCTL_TRAM_SETUP:
2296 if (!capable(CAP_SYS_ADMIN))
2298 if (get_user(addr, (unsigned int __user *)argp))
2300 down(&emu->fx8010.lock);
2301 res = snd_emu10k1_fx8010_tram_setup(emu, addr);
2302 up(&emu->fx8010.lock);
2304 case SNDRV_EMU10K1_IOCTL_STOP:
2305 if (!capable(CAP_SYS_ADMIN))
2308 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg |= A_DBG_SINGLE_STEP);
2310 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg |= EMU10K1_DBG_SINGLE_STEP);
2312 case SNDRV_EMU10K1_IOCTL_CONTINUE:
2313 if (!capable(CAP_SYS_ADMIN))
2316 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg = 0);
2318 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg = 0);
2320 case SNDRV_EMU10K1_IOCTL_ZERO_TRAM_COUNTER:
2321 if (!capable(CAP_SYS_ADMIN))
2324 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg | A_DBG_ZC);
2326 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg | EMU10K1_DBG_ZC);
2329 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg);
2331 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg);
2333 case SNDRV_EMU10K1_IOCTL_SINGLE_STEP:
2334 if (!capable(CAP_SYS_ADMIN))
2336 if (get_user(addr, (unsigned int __user *)argp))
2341 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg |= A_DBG_SINGLE_STEP | addr);
2343 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg |= EMU10K1_DBG_SINGLE_STEP | addr);
2346 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg |= A_DBG_SINGLE_STEP | A_DBG_STEP_ADDR | addr);
2348 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg |= EMU10K1_DBG_SINGLE_STEP | EMU10K1_DBG_STEP | addr);
2350 case SNDRV_EMU10K1_IOCTL_DBG_READ:
2352 addr = snd_emu10k1_ptr_read(emu, A_DBG, 0);
2354 addr = snd_emu10k1_ptr_read(emu, DBG, 0);
2355 if (put_user(addr, (unsigned int __user *)argp))
2362 static int snd_emu10k1_fx8010_release(struct snd_hwdep * hw, struct file *file)
2367 int __devinit snd_emu10k1_fx8010_new(struct snd_emu10k1 *emu, int device, struct snd_hwdep ** rhwdep)
2369 struct snd_hwdep *hw;
2374 if ((err = snd_hwdep_new(emu->card, "FX8010", device, &hw)) < 0)
2376 strcpy(hw->name, "EMU10K1 (FX8010)");
2377 hw->iface = SNDRV_HWDEP_IFACE_EMU10K1;
2378 hw->ops.open = snd_emu10k1_fx8010_open;
2379 hw->ops.ioctl = snd_emu10k1_fx8010_ioctl;
2380 hw->ops.release = snd_emu10k1_fx8010_release;
2381 hw->private_data = emu;
2388 int __devinit snd_emu10k1_efx_alloc_pm_buffer(struct snd_emu10k1 *emu)
2392 len = emu->audigy ? 0x200 : 0x100;
2393 emu->saved_gpr = kmalloc(len * 4, GFP_KERNEL);
2394 if (! emu->saved_gpr)
2396 len = emu->audigy ? 0x100 : 0xa0;
2397 emu->tram_val_saved = kmalloc(len * 4, GFP_KERNEL);
2398 emu->tram_addr_saved = kmalloc(len * 4, GFP_KERNEL);
2399 if (! emu->tram_val_saved || ! emu->tram_addr_saved)
2401 len = emu->audigy ? 2 * 1024 : 2 * 512;
2402 emu->saved_icode = vmalloc(len * 4);
2403 if (! emu->saved_icode)
2408 void snd_emu10k1_efx_free_pm_buffer(struct snd_emu10k1 *emu)
2410 kfree(emu->saved_gpr);
2411 kfree(emu->tram_val_saved);
2412 kfree(emu->tram_addr_saved);
2413 vfree(emu->saved_icode);
2417 * save/restore GPR, TRAM and codes
2419 void snd_emu10k1_efx_suspend(struct snd_emu10k1 *emu)
2423 len = emu->audigy ? 0x200 : 0x100;
2424 for (i = 0; i < len; i++)
2425 emu->saved_gpr[i] = snd_emu10k1_ptr_read(emu, emu->gpr_base + i, 0);
2427 len = emu->audigy ? 0x100 : 0xa0;
2428 for (i = 0; i < len; i++) {
2429 emu->tram_val_saved[i] = snd_emu10k1_ptr_read(emu, TANKMEMDATAREGBASE + i, 0);
2430 emu->tram_addr_saved[i] = snd_emu10k1_ptr_read(emu, TANKMEMADDRREGBASE + i, 0);
2432 emu->tram_addr_saved[i] >>= 12;
2433 emu->tram_addr_saved[i] |=
2434 snd_emu10k1_ptr_read(emu, A_TANKMEMCTLREGBASE + i, 0) << 20;
2438 len = emu->audigy ? 2 * 1024 : 2 * 512;
2439 for (i = 0; i < len; i++)
2440 emu->saved_icode[i] = snd_emu10k1_efx_read(emu, i);
2443 void snd_emu10k1_efx_resume(struct snd_emu10k1 *emu)
2448 if (emu->fx8010.etram_pages.bytes > 0) {
2449 unsigned size, size_reg = 0;
2450 size = emu->fx8010.etram_pages.bytes / 2;
2451 size = (size - 1) >> 13;
2456 outl(HCFG_LOCKTANKCACHE_MASK | inl(emu->port + HCFG), emu->port + HCFG);
2457 snd_emu10k1_ptr_write(emu, TCB, 0, emu->fx8010.etram_pages.addr);
2458 snd_emu10k1_ptr_write(emu, TCBS, 0, size_reg);
2459 outl(inl(emu->port + HCFG) & ~HCFG_LOCKTANKCACHE_MASK, emu->port + HCFG);
2463 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg | A_DBG_SINGLE_STEP);
2465 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg | EMU10K1_DBG_SINGLE_STEP);
2467 len = emu->audigy ? 0x200 : 0x100;
2468 for (i = 0; i < len; i++)
2469 snd_emu10k1_ptr_write(emu, emu->gpr_base + i, 0, emu->saved_gpr[i]);
2471 len = emu->audigy ? 0x100 : 0xa0;
2472 for (i = 0; i < len; i++) {
2473 snd_emu10k1_ptr_write(emu, TANKMEMDATAREGBASE + i, 0,
2474 emu->tram_val_saved[i]);
2476 snd_emu10k1_ptr_write(emu, TANKMEMADDRREGBASE + i, 0,
2477 emu->tram_addr_saved[i]);
2479 snd_emu10k1_ptr_write(emu, TANKMEMADDRREGBASE + i, 0,
2480 emu->tram_addr_saved[i] << 12);
2481 snd_emu10k1_ptr_write(emu, TANKMEMADDRREGBASE + i, 0,
2482 emu->tram_addr_saved[i] >> 20);
2486 len = emu->audigy ? 2 * 1024 : 2 * 512;
2487 for (i = 0; i < len; i++)
2488 snd_emu10k1_efx_write(emu, i, emu->saved_icode[i]);
2490 /* start FX processor when the DSP code is updated */
2492 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg);
2494 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg);