2 * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
4 * Routines for effect processor FX8010
6 * Copyright (c) by James Courtier-Dutton <James@superbug.co.uk>
7 * Added EMU 1010 support.
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2 of the License, or
18 * (at your option) any later version.
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, write to the Free Software
27 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
31 #include <linux/pci.h>
32 #include <linux/capability.h>
33 #include <linux/delay.h>
34 #include <linux/slab.h>
35 #include <linux/vmalloc.h>
36 #include <linux/init.h>
37 #include <linux/mutex.h>
38 #include <linux/moduleparam.h>
39 #include <linux/nospec.h>
41 #include <sound/core.h>
42 #include <sound/tlv.h>
43 #include <sound/emu10k1.h>
45 #if 0 /* for testing purposes - digital out -> capture */
46 #define EMU10K1_CAPTURE_DIGITAL_OUT
48 #if 0 /* for testing purposes - set S/PDIF to AC3 output */
49 #define EMU10K1_SET_AC3_IEC958
51 #if 0 /* for testing purposes - feed the front signal to Center/LFE outputs */
52 #define EMU10K1_CENTER_LFE_FROM_FRONT
55 static bool high_res_gpr_volume;
56 module_param(high_res_gpr_volume, bool, 0444);
57 MODULE_PARM_DESC(high_res_gpr_volume, "GPR mixer controls use 31-bit range.");
63 static char *fxbuses[16] = {
64 /* 0x00 */ "PCM Left",
65 /* 0x01 */ "PCM Right",
66 /* 0x02 */ "PCM Surround Left",
67 /* 0x03 */ "PCM Surround Right",
68 /* 0x04 */ "MIDI Left",
69 /* 0x05 */ "MIDI Right",
76 /* 0x0c */ "MIDI Reverb",
77 /* 0x0d */ "MIDI Chorus",
82 static char *creative_ins[16] = {
83 /* 0x00 */ "AC97 Left",
84 /* 0x01 */ "AC97 Right",
85 /* 0x02 */ "TTL IEC958 Left",
86 /* 0x03 */ "TTL IEC958 Right",
87 /* 0x04 */ "Zoom Video Left",
88 /* 0x05 */ "Zoom Video Right",
89 /* 0x06 */ "Optical IEC958 Left",
90 /* 0x07 */ "Optical IEC958 Right",
91 /* 0x08 */ "Line/Mic 1 Left",
92 /* 0x09 */ "Line/Mic 1 Right",
93 /* 0x0a */ "Coaxial IEC958 Left",
94 /* 0x0b */ "Coaxial IEC958 Right",
95 /* 0x0c */ "Line/Mic 2 Left",
96 /* 0x0d */ "Line/Mic 2 Right",
101 static char *audigy_ins[16] = {
102 /* 0x00 */ "AC97 Left",
103 /* 0x01 */ "AC97 Right",
104 /* 0x02 */ "Audigy CD Left",
105 /* 0x03 */ "Audigy CD Right",
106 /* 0x04 */ "Optical IEC958 Left",
107 /* 0x05 */ "Optical IEC958 Right",
110 /* 0x08 */ "Line/Mic 2 Left",
111 /* 0x09 */ "Line/Mic 2 Right",
112 /* 0x0a */ "SPDIF Left",
113 /* 0x0b */ "SPDIF Right",
114 /* 0x0c */ "Aux2 Left",
115 /* 0x0d */ "Aux2 Right",
120 static char *creative_outs[32] = {
121 /* 0x00 */ "AC97 Left",
122 /* 0x01 */ "AC97 Right",
123 /* 0x02 */ "Optical IEC958 Left",
124 /* 0x03 */ "Optical IEC958 Right",
127 /* 0x06 */ "Headphone Left",
128 /* 0x07 */ "Headphone Right",
129 /* 0x08 */ "Surround Left",
130 /* 0x09 */ "Surround Right",
131 /* 0x0a */ "PCM Capture Left",
132 /* 0x0b */ "PCM Capture Right",
133 /* 0x0c */ "MIC Capture",
134 /* 0x0d */ "AC97 Surround Left",
135 /* 0x0e */ "AC97 Surround Right",
138 /* 0x11 */ "Analog Center",
139 /* 0x12 */ "Analog LFE",
155 static char *audigy_outs[32] = {
156 /* 0x00 */ "Digital Front Left",
157 /* 0x01 */ "Digital Front Right",
158 /* 0x02 */ "Digital Center",
159 /* 0x03 */ "Digital LEF",
160 /* 0x04 */ "Headphone Left",
161 /* 0x05 */ "Headphone Right",
162 /* 0x06 */ "Digital Rear Left",
163 /* 0x07 */ "Digital Rear Right",
164 /* 0x08 */ "Front Left",
165 /* 0x09 */ "Front Right",
170 /* 0x0e */ "Rear Left",
171 /* 0x0f */ "Rear Right",
172 /* 0x10 */ "AC97 Front Left",
173 /* 0x11 */ "AC97 Front Right",
174 /* 0x12 */ "ADC Caputre Left",
175 /* 0x13 */ "ADC Capture Right",
190 static const u32 bass_table[41][5] = {
191 { 0x3e4f844f, 0x84ed4cc3, 0x3cc69927, 0x7b03553a, 0xc4da8486 },
192 { 0x3e69a17a, 0x84c280fb, 0x3cd77cd4, 0x7b2f2a6f, 0xc4b08d1d },
193 { 0x3e82ff42, 0x849991d5, 0x3ce7466b, 0x7b5917c6, 0xc48863ee },
194 { 0x3e9bab3c, 0x847267f0, 0x3cf5ffe8, 0x7b813560, 0xc461f22c },
195 { 0x3eb3b275, 0x844ced29, 0x3d03b295, 0x7ba79a1c, 0xc43d223b },
196 { 0x3ecb2174, 0x84290c8b, 0x3d106714, 0x7bcc5ba3, 0xc419dfa5 },
197 { 0x3ee2044b, 0x8406b244, 0x3d1c2561, 0x7bef8e77, 0xc3f8170f },
198 { 0x3ef86698, 0x83e5cb96, 0x3d26f4d8, 0x7c114600, 0xc3d7b625 },
199 { 0x3f0e5390, 0x83c646c9, 0x3d30dc39, 0x7c319498, 0xc3b8ab97 },
200 { 0x3f23d60b, 0x83a81321, 0x3d39e1af, 0x7c508b9c, 0xc39ae704 },
201 { 0x3f38f884, 0x838b20d2, 0x3d420ad2, 0x7c6e3b75, 0xc37e58f1 },
202 { 0x3f4dc52c, 0x836f60ef, 0x3d495cab, 0x7c8ab3a6, 0xc362f2be },
203 { 0x3f6245e8, 0x8354c565, 0x3d4fdbb8, 0x7ca602d6, 0xc348a69b },
204 { 0x3f76845f, 0x833b40ec, 0x3d558bf0, 0x7cc036df, 0xc32f677c },
205 { 0x3f8a8a03, 0x8322c6fb, 0x3d5a70c4, 0x7cd95cd7, 0xc317290b },
206 { 0x3f9e6014, 0x830b4bc3, 0x3d5e8d25, 0x7cf1811a, 0xc2ffdfa5 },
207 { 0x3fb20fae, 0x82f4c420, 0x3d61e37f, 0x7d08af56, 0xc2e9804a },
208 { 0x3fc5a1cc, 0x82df2592, 0x3d6475c3, 0x7d1ef294, 0xc2d40096 },
209 { 0x3fd91f55, 0x82ca6632, 0x3d664564, 0x7d345541, 0xc2bf56b9 },
210 { 0x3fec9120, 0x82b67cac, 0x3d675356, 0x7d48e138, 0xc2ab796e },
211 { 0x40000000, 0x82a36037, 0x3d67a012, 0x7d5c9fc9, 0xc2985fee },
212 { 0x401374c7, 0x8291088a, 0x3d672b93, 0x7d6f99c3, 0xc28601f2 },
213 { 0x4026f857, 0x827f6dd7, 0x3d65f559, 0x7d81d77c, 0xc27457a3 },
214 { 0x403a939f, 0x826e88c5, 0x3d63fc63, 0x7d9360d4, 0xc2635996 },
215 { 0x404e4faf, 0x825e5266, 0x3d613f32, 0x7da43d42, 0xc25300c6 },
216 { 0x406235ba, 0x824ec434, 0x3d5dbbc3, 0x7db473d7, 0xc243468e },
217 { 0x40764f1f, 0x823fd80c, 0x3d596f8f, 0x7dc40b44, 0xc23424a2 },
218 { 0x408aa576, 0x82318824, 0x3d545787, 0x7dd309e2, 0xc2259509 },
219 { 0x409f4296, 0x8223cf0b, 0x3d4e7012, 0x7de175b5, 0xc2179218 },
220 { 0x40b430a0, 0x8216a7a1, 0x3d47b505, 0x7def5475, 0xc20a1670 },
221 { 0x40c97a0a, 0x820a0d12, 0x3d4021a1, 0x7dfcab8d, 0xc1fd1cf5 },
222 { 0x40df29a6, 0x81fdfad6, 0x3d37b08d, 0x7e098028, 0xc1f0a0ca },
223 { 0x40f54ab1, 0x81f26ca9, 0x3d2e5bd1, 0x7e15d72b, 0xc1e49d52 },
224 { 0x410be8da, 0x81e75e89, 0x3d241cce, 0x7e21b544, 0xc1d90e24 },
225 { 0x41231051, 0x81dcccb3, 0x3d18ec37, 0x7e2d1ee6, 0xc1cdef10 },
226 { 0x413acdd0, 0x81d2b39e, 0x3d0cc20a, 0x7e38184e, 0xc1c33c13 },
227 { 0x41532ea7, 0x81c90ffb, 0x3cff9585, 0x7e42a58b, 0xc1b8f15a },
228 { 0x416c40cd, 0x81bfdeb2, 0x3cf15d21, 0x7e4cca7c, 0xc1af0b3f },
229 { 0x418612ea, 0x81b71cdc, 0x3ce20e85, 0x7e568ad3, 0xc1a58640 },
230 { 0x41a0b465, 0x81aec7c5, 0x3cd19e7c, 0x7e5fea1e, 0xc19c5f03 },
231 { 0x41bc3573, 0x81a6dcea, 0x3cc000e9, 0x7e68ebc2, 0xc1939250 }
234 static const u32 treble_table[41][5] = {
235 { 0x0125cba9, 0xfed5debd, 0x00599b6c, 0x0d2506da, 0xfa85b354 },
236 { 0x0142f67e, 0xfeb03163, 0x0066cd0f, 0x0d14c69d, 0xfa914473 },
237 { 0x016328bd, 0xfe860158, 0x0075b7f2, 0x0d03eb27, 0xfa9d32d2 },
238 { 0x0186b438, 0xfe56c982, 0x00869234, 0x0cf27048, 0xfaa97fca },
239 { 0x01adf358, 0xfe21f5fe, 0x00999842, 0x0ce051c2, 0xfab62ca5 },
240 { 0x01d949fa, 0xfde6e287, 0x00af0d8d, 0x0ccd8b4a, 0xfac33aa7 },
241 { 0x02092669, 0xfda4d8bf, 0x00c73d4c, 0x0cba1884, 0xfad0ab07 },
242 { 0x023e0268, 0xfd5b0e4a, 0x00e27b54, 0x0ca5f509, 0xfade7ef2 },
243 { 0x0278645c, 0xfd08a2b0, 0x01012509, 0x0c911c63, 0xfaecb788 },
244 { 0x02b8e091, 0xfcac9d1a, 0x0123a262, 0x0c7b8a14, 0xfafb55df },
245 { 0x03001a9a, 0xfc45e9ce, 0x014a6709, 0x0c65398f, 0xfb0a5aff },
246 { 0x034ec6d7, 0xfbd3576b, 0x0175f397, 0x0c4e2643, 0xfb19c7e4 },
247 { 0x03a5ac15, 0xfb5393ee, 0x01a6d6ed, 0x0c364b94, 0xfb299d7c },
248 { 0x0405a562, 0xfac52968, 0x01ddafae, 0x0c1da4e2, 0xfb39dca5 },
249 { 0x046fa3fe, 0xfa267a66, 0x021b2ddd, 0x0c042d8d, 0xfb4a8631 },
250 { 0x04e4b17f, 0xf975be0f, 0x0260149f, 0x0be9e0f2, 0xfb5b9ae0 },
251 { 0x0565f220, 0xf8b0fbe5, 0x02ad3c29, 0x0bceba73, 0xfb6d1b60 },
252 { 0x05f4a745, 0xf7d60722, 0x030393d4, 0x0bb2b578, 0xfb7f084d },
253 { 0x06923236, 0xf6e279bd, 0x03642465, 0x0b95cd75, 0xfb916233 },
254 { 0x07401713, 0xf5d3aef9, 0x03d01283, 0x0b77fded, 0xfba42984 },
255 { 0x08000000, 0xf4a6bd88, 0x0448a161, 0x0b594278, 0xfbb75e9f },
256 { 0x08d3c097, 0xf3587131, 0x04cf35a4, 0x0b3996c9, 0xfbcb01cb },
257 { 0x09bd59a2, 0xf1e543f9, 0x05655880, 0x0b18f6b2, 0xfbdf1333 },
258 { 0x0abefd0f, 0xf04956ca, 0x060cbb12, 0x0af75e2c, 0xfbf392e8 },
259 { 0x0bdb123e, 0xee806984, 0x06c739fe, 0x0ad4c962, 0xfc0880dd },
260 { 0x0d143a94, 0xec85d287, 0x0796e150, 0x0ab134b0, 0xfc1ddce5 },
261 { 0x0e6d5664, 0xea547598, 0x087df0a0, 0x0a8c9cb6, 0xfc33a6ad },
262 { 0x0fe98a2a, 0xe7e6ba35, 0x097edf83, 0x0a66fe5b, 0xfc49ddc2 },
263 { 0x118c4421, 0xe536813a, 0x0a9c6248, 0x0a4056d7, 0xfc608185 },
264 { 0x1359422e, 0xe23d19eb, 0x0bd96efb, 0x0a18a3bf, 0xfc77912c },
265 { 0x1554982b, 0xdef33645, 0x0d3942bd, 0x09efe312, 0xfc8f0bc1 },
266 { 0x1782b68a, 0xdb50deb1, 0x0ebf676d, 0x09c6133f, 0xfca6f019 },
267 { 0x19e8715d, 0xd74d64fd, 0x106fb999, 0x099b3337, 0xfcbf3cd6 },
268 { 0x1c8b07b8, 0xd2df56ab, 0x124e6ec8, 0x096f4274, 0xfcd7f060 },
269 { 0x1f702b6d, 0xcdfc6e92, 0x14601c10, 0x0942410b, 0xfcf108e5 },
270 { 0x229e0933, 0xc89985cd, 0x16a9bcfa, 0x09142fb5, 0xfd0a8451 },
271 { 0x261b5118, 0xc2aa8409, 0x1930bab6, 0x08e50fdc, 0xfd24604d },
272 { 0x29ef3f5d, 0xbc224f28, 0x1bfaf396, 0x08b4e3aa, 0xfd3e9a3b },
273 { 0x2e21a59b, 0xb4f2ba46, 0x1f0ec2d6, 0x0883ae15, 0xfd592f33 },
274 { 0x32baf44b, 0xad0c7429, 0x227308a3, 0x085172eb, 0xfd741bfd },
275 { 0x37c4448b, 0xa45ef51d, 0x262f3267, 0x081e36dc, 0xfd8f5d14 }
278 /* dB gain = (float) 20 * log10( float(db_table_value) / 0x8000000 ) */
279 static const u32 db_table[101] = {
280 0x00000000, 0x01571f82, 0x01674b41, 0x01783a1b, 0x0189f540,
281 0x019c8651, 0x01aff763, 0x01c45306, 0x01d9a446, 0x01eff6b8,
282 0x0207567a, 0x021fd03d, 0x0239714c, 0x02544792, 0x027061a1,
283 0x028dcebb, 0x02ac9edc, 0x02cce2bf, 0x02eeabe8, 0x03120cb0,
284 0x0337184e, 0x035de2df, 0x03868173, 0x03b10a18, 0x03dd93e9,
285 0x040c3713, 0x043d0cea, 0x04702ff3, 0x04a5bbf2, 0x04ddcdfb,
286 0x0518847f, 0x0555ff62, 0x05966005, 0x05d9c95d, 0x06206005,
287 0x066a4a52, 0x06b7b067, 0x0708bc4c, 0x075d9a01, 0x07b6779d,
288 0x08138561, 0x0874f5d5, 0x08dafde1, 0x0945d4ed, 0x09b5b4fd,
289 0x0a2adad1, 0x0aa58605, 0x0b25f936, 0x0bac7a24, 0x0c3951d8,
290 0x0ccccccc, 0x0d673b17, 0x0e08f093, 0x0eb24510, 0x0f639481,
291 0x101d3f2d, 0x10dfa9e6, 0x11ab3e3f, 0x12806ac3, 0x135fa333,
292 0x144960c5, 0x153e2266, 0x163e6cfe, 0x174acbb7, 0x1863d04d,
293 0x198a1357, 0x1abe349f, 0x1c00db77, 0x1d52b712, 0x1eb47ee6,
294 0x2026f30f, 0x21aadcb6, 0x23410e7e, 0x24ea64f9, 0x26a7c71d,
295 0x287a26c4, 0x2a62812c, 0x2c61df84, 0x2e795779, 0x30aa0bcf,
296 0x32f52cfe, 0x355bf9d8, 0x37dfc033, 0x3a81dda4, 0x3d43c038,
297 0x4026e73c, 0x432ce40f, 0x46575af8, 0x49a8040f, 0x4d20ac2a,
298 0x50c335d3, 0x54919a57, 0x588dead1, 0x5cba514a, 0x611911ea,
299 0x65ac8c2f, 0x6a773c39, 0x6f7bbc23, 0x74bcc56c, 0x7a3d3272,
303 /* EMU10k1/EMU10k2 DSP control db gain */
304 static const DECLARE_TLV_DB_SCALE(snd_emu10k1_db_scale1, -4000, 40, 1);
305 static const DECLARE_TLV_DB_LINEAR(snd_emu10k1_db_linear, TLV_DB_GAIN_MUTE, 0);
307 /* EMU10K1 bass/treble db gain */
308 static const DECLARE_TLV_DB_SCALE(snd_emu10k1_bass_treble_db_scale, -1200, 60, 0);
310 static const u32 onoff_table[2] = {
311 0x00000000, 0x00000001
318 static int snd_emu10k1_gpr_ctl_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
320 struct snd_emu10k1_fx8010_ctl *ctl =
321 (struct snd_emu10k1_fx8010_ctl *) kcontrol->private_value;
323 if (ctl->min == 0 && ctl->max == 1)
324 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
326 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
327 uinfo->count = ctl->vcount;
328 uinfo->value.integer.min = ctl->min;
329 uinfo->value.integer.max = ctl->max;
333 static int snd_emu10k1_gpr_ctl_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
335 struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
336 struct snd_emu10k1_fx8010_ctl *ctl =
337 (struct snd_emu10k1_fx8010_ctl *) kcontrol->private_value;
341 spin_lock_irqsave(&emu->reg_lock, flags);
342 for (i = 0; i < ctl->vcount; i++)
343 ucontrol->value.integer.value[i] = ctl->value[i];
344 spin_unlock_irqrestore(&emu->reg_lock, flags);
348 static int snd_emu10k1_gpr_ctl_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
350 struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
351 struct snd_emu10k1_fx8010_ctl *ctl =
352 (struct snd_emu10k1_fx8010_ctl *) kcontrol->private_value;
354 unsigned int nval, val;
358 spin_lock_irqsave(&emu->reg_lock, flags);
359 for (i = 0; i < ctl->vcount; i++) {
360 nval = ucontrol->value.integer.value[i];
365 if (nval != ctl->value[i])
367 val = ctl->value[i] = nval;
368 switch (ctl->translation) {
369 case EMU10K1_GPR_TRANSLATION_NONE:
370 snd_emu10k1_ptr_write(emu, emu->gpr_base + ctl->gpr[i], 0, val);
372 case EMU10K1_GPR_TRANSLATION_TABLE100:
373 snd_emu10k1_ptr_write(emu, emu->gpr_base + ctl->gpr[i], 0, db_table[val]);
375 case EMU10K1_GPR_TRANSLATION_BASS:
376 if ((ctl->count % 5) != 0 || (ctl->count / 5) != ctl->vcount) {
380 for (j = 0; j < 5; j++)
381 snd_emu10k1_ptr_write(emu, emu->gpr_base + ctl->gpr[j * ctl->vcount + i], 0, bass_table[val][j]);
383 case EMU10K1_GPR_TRANSLATION_TREBLE:
384 if ((ctl->count % 5) != 0 || (ctl->count / 5) != ctl->vcount) {
388 for (j = 0; j < 5; j++)
389 snd_emu10k1_ptr_write(emu, emu->gpr_base + ctl->gpr[j * ctl->vcount + i], 0, treble_table[val][j]);
391 case EMU10K1_GPR_TRANSLATION_ONOFF:
392 snd_emu10k1_ptr_write(emu, emu->gpr_base + ctl->gpr[i], 0, onoff_table[val]);
397 spin_unlock_irqrestore(&emu->reg_lock, flags);
405 static void snd_emu10k1_fx8010_interrupt(struct snd_emu10k1 *emu)
407 struct snd_emu10k1_fx8010_irq *irq, *nirq;
409 irq = emu->fx8010.irq_handlers;
411 nirq = irq->next; /* irq ptr can be removed from list */
412 if (snd_emu10k1_ptr_read(emu, emu->gpr_base + irq->gpr_running, 0) & 0xffff0000) {
414 irq->handler(emu, irq->private_data);
415 snd_emu10k1_ptr_write(emu, emu->gpr_base + irq->gpr_running, 0, 1);
421 int snd_emu10k1_fx8010_register_irq_handler(struct snd_emu10k1 *emu,
422 snd_fx8010_irq_handler_t *handler,
423 unsigned char gpr_running,
425 struct snd_emu10k1_fx8010_irq **r_irq)
427 struct snd_emu10k1_fx8010_irq *irq;
430 irq = kmalloc(sizeof(*irq), GFP_ATOMIC);
433 irq->handler = handler;
434 irq->gpr_running = gpr_running;
435 irq->private_data = private_data;
437 spin_lock_irqsave(&emu->fx8010.irq_lock, flags);
438 if (emu->fx8010.irq_handlers == NULL) {
439 emu->fx8010.irq_handlers = irq;
440 emu->dsp_interrupt = snd_emu10k1_fx8010_interrupt;
441 snd_emu10k1_intr_enable(emu, INTE_FXDSPENABLE);
443 irq->next = emu->fx8010.irq_handlers;
444 emu->fx8010.irq_handlers = irq;
446 spin_unlock_irqrestore(&emu->fx8010.irq_lock, flags);
452 int snd_emu10k1_fx8010_unregister_irq_handler(struct snd_emu10k1 *emu,
453 struct snd_emu10k1_fx8010_irq *irq)
455 struct snd_emu10k1_fx8010_irq *tmp;
458 spin_lock_irqsave(&emu->fx8010.irq_lock, flags);
459 if ((tmp = emu->fx8010.irq_handlers) == irq) {
460 emu->fx8010.irq_handlers = tmp->next;
461 if (emu->fx8010.irq_handlers == NULL) {
462 snd_emu10k1_intr_disable(emu, INTE_FXDSPENABLE);
463 emu->dsp_interrupt = NULL;
466 while (tmp && tmp->next != irq)
469 tmp->next = tmp->next->next;
471 spin_unlock_irqrestore(&emu->fx8010.irq_lock, flags);
476 /*************************************************************************
477 * EMU10K1 effect manager
478 *************************************************************************/
480 static void snd_emu10k1_write_op(struct snd_emu10k1_fx8010_code *icode,
482 u32 op, u32 r, u32 a, u32 x, u32 y)
485 if (snd_BUG_ON(*ptr >= 512))
487 code = (u_int32_t __force *)icode->code + (*ptr) * 2;
488 set_bit(*ptr, icode->code_valid);
489 code[0] = ((x & 0x3ff) << 10) | (y & 0x3ff);
490 code[1] = ((op & 0x0f) << 20) | ((r & 0x3ff) << 10) | (a & 0x3ff);
494 #define OP(icode, ptr, op, r, a, x, y) \
495 snd_emu10k1_write_op(icode, ptr, op, r, a, x, y)
497 static void snd_emu10k1_audigy_write_op(struct snd_emu10k1_fx8010_code *icode,
499 u32 op, u32 r, u32 a, u32 x, u32 y)
502 if (snd_BUG_ON(*ptr >= 1024))
504 code = (u_int32_t __force *)icode->code + (*ptr) * 2;
505 set_bit(*ptr, icode->code_valid);
506 code[0] = ((x & 0x7ff) << 12) | (y & 0x7ff);
507 code[1] = ((op & 0x0f) << 24) | ((r & 0x7ff) << 12) | (a & 0x7ff);
511 #define A_OP(icode, ptr, op, r, a, x, y) \
512 snd_emu10k1_audigy_write_op(icode, ptr, op, r, a, x, y)
514 static void snd_emu10k1_efx_write(struct snd_emu10k1 *emu, unsigned int pc, unsigned int data)
516 pc += emu->audigy ? A_MICROCODEBASE : MICROCODEBASE;
517 snd_emu10k1_ptr_write(emu, pc, 0, data);
520 unsigned int snd_emu10k1_efx_read(struct snd_emu10k1 *emu, unsigned int pc)
522 pc += emu->audigy ? A_MICROCODEBASE : MICROCODEBASE;
523 return snd_emu10k1_ptr_read(emu, pc, 0);
526 static int snd_emu10k1_gpr_poke(struct snd_emu10k1 *emu,
527 struct snd_emu10k1_fx8010_code *icode,
533 for (gpr = 0; gpr < (emu->audigy ? 0x200 : 0x100); gpr++) {
534 if (!test_bit(gpr, icode->gpr_valid))
537 val = *(u32 *)&icode->gpr_map[gpr];
538 else if (get_user(val, &icode->gpr_map[gpr]))
540 snd_emu10k1_ptr_write(emu, emu->gpr_base + gpr, 0, val);
545 static int snd_emu10k1_gpr_peek(struct snd_emu10k1 *emu,
546 struct snd_emu10k1_fx8010_code *icode)
551 for (gpr = 0; gpr < (emu->audigy ? 0x200 : 0x100); gpr++) {
552 set_bit(gpr, icode->gpr_valid);
553 val = snd_emu10k1_ptr_read(emu, emu->gpr_base + gpr, 0);
554 if (put_user(val, &icode->gpr_map[gpr]))
560 static int snd_emu10k1_tram_poke(struct snd_emu10k1 *emu,
561 struct snd_emu10k1_fx8010_code *icode,
567 for (tram = 0; tram < (emu->audigy ? 0x100 : 0xa0); tram++) {
568 if (!test_bit(tram, icode->tram_valid))
571 val = *(u32 *)&icode->tram_data_map[tram];
572 addr = *(u32 *)&icode->tram_addr_map[tram];
574 if (get_user(val, &icode->tram_data_map[tram]) ||
575 get_user(addr, &icode->tram_addr_map[tram]))
578 snd_emu10k1_ptr_write(emu, TANKMEMDATAREGBASE + tram, 0, val);
580 snd_emu10k1_ptr_write(emu, TANKMEMADDRREGBASE + tram, 0, addr);
582 snd_emu10k1_ptr_write(emu, TANKMEMADDRREGBASE + tram, 0, addr << 12);
583 snd_emu10k1_ptr_write(emu, A_TANKMEMCTLREGBASE + tram, 0, addr >> 20);
589 static int snd_emu10k1_tram_peek(struct snd_emu10k1 *emu,
590 struct snd_emu10k1_fx8010_code *icode)
595 memset(icode->tram_valid, 0, sizeof(icode->tram_valid));
596 for (tram = 0; tram < (emu->audigy ? 0x100 : 0xa0); tram++) {
597 set_bit(tram, icode->tram_valid);
598 val = snd_emu10k1_ptr_read(emu, TANKMEMDATAREGBASE + tram, 0);
600 addr = snd_emu10k1_ptr_read(emu, TANKMEMADDRREGBASE + tram, 0);
602 addr = snd_emu10k1_ptr_read(emu, TANKMEMADDRREGBASE + tram, 0) >> 12;
603 addr |= snd_emu10k1_ptr_read(emu, A_TANKMEMCTLREGBASE + tram, 0) << 20;
605 if (put_user(val, &icode->tram_data_map[tram]) ||
606 put_user(addr, &icode->tram_addr_map[tram]))
612 static int snd_emu10k1_code_poke(struct snd_emu10k1 *emu,
613 struct snd_emu10k1_fx8010_code *icode,
618 for (pc = 0; pc < (emu->audigy ? 2*1024 : 2*512); pc += 2) {
619 if (!test_bit(pc / 2, icode->code_valid))
622 lo = *(u32 *)&icode->code[pc + 0];
623 hi = *(u32 *)&icode->code[pc + 1];
625 if (get_user(lo, &icode->code[pc + 0]) ||
626 get_user(hi, &icode->code[pc + 1]))
629 snd_emu10k1_efx_write(emu, pc + 0, lo);
630 snd_emu10k1_efx_write(emu, pc + 1, hi);
635 static int snd_emu10k1_code_peek(struct snd_emu10k1 *emu,
636 struct snd_emu10k1_fx8010_code *icode)
640 memset(icode->code_valid, 0, sizeof(icode->code_valid));
641 for (pc = 0; pc < (emu->audigy ? 2*1024 : 2*512); pc += 2) {
642 set_bit(pc / 2, icode->code_valid);
643 if (put_user(snd_emu10k1_efx_read(emu, pc + 0), &icode->code[pc + 0]))
645 if (put_user(snd_emu10k1_efx_read(emu, pc + 1), &icode->code[pc + 1]))
651 static struct snd_emu10k1_fx8010_ctl *
652 snd_emu10k1_look_for_ctl(struct snd_emu10k1 *emu, struct snd_ctl_elem_id *id)
654 struct snd_emu10k1_fx8010_ctl *ctl;
655 struct snd_kcontrol *kcontrol;
657 list_for_each_entry(ctl, &emu->fx8010.gpr_ctl, list) {
658 kcontrol = ctl->kcontrol;
659 if (kcontrol->id.iface == id->iface &&
660 !strcmp(kcontrol->id.name, id->name) &&
661 kcontrol->id.index == id->index)
667 #define MAX_TLV_SIZE 256
669 static unsigned int *copy_tlv(const unsigned int __user *_tlv, bool in_kernel)
671 unsigned int data[2];
677 memcpy(data, (void *)_tlv, sizeof(data));
678 else if (copy_from_user(data, _tlv, sizeof(data)))
680 if (data[1] >= MAX_TLV_SIZE)
682 tlv = kmalloc(data[1] + sizeof(data), GFP_KERNEL);
685 memcpy(tlv, data, sizeof(data));
687 memcpy(tlv + 2, (void *)(_tlv + 2), data[1]);
688 } else if (copy_from_user(tlv + 2, _tlv + 2, data[1])) {
695 static int copy_gctl(struct snd_emu10k1 *emu,
696 struct snd_emu10k1_fx8010_control_gpr *gctl,
697 struct snd_emu10k1_fx8010_control_gpr __user *_gctl,
698 int idx, bool in_kernel)
700 struct snd_emu10k1_fx8010_control_old_gpr __user *octl;
702 if (emu->support_tlv) {
704 memcpy(gctl, (void *)&_gctl[idx], sizeof(*gctl));
705 else if (copy_from_user(gctl, &_gctl[idx], sizeof(*gctl)))
710 octl = (struct snd_emu10k1_fx8010_control_old_gpr __user *)_gctl;
712 memcpy(gctl, (void *)&octl[idx], sizeof(*octl));
713 else if (copy_from_user(gctl, &octl[idx], sizeof(*octl)))
719 static int copy_gctl_to_user(struct snd_emu10k1 *emu,
720 struct snd_emu10k1_fx8010_control_gpr __user *_gctl,
721 struct snd_emu10k1_fx8010_control_gpr *gctl,
724 struct snd_emu10k1_fx8010_control_old_gpr __user *octl;
726 if (emu->support_tlv)
727 return copy_to_user(&_gctl[idx], gctl, sizeof(*gctl));
729 octl = (struct snd_emu10k1_fx8010_control_old_gpr __user *)_gctl;
730 return copy_to_user(&octl[idx], gctl, sizeof(*octl));
733 static int snd_emu10k1_verify_controls(struct snd_emu10k1 *emu,
734 struct snd_emu10k1_fx8010_code *icode,
738 struct snd_ctl_elem_id __user *_id;
739 struct snd_ctl_elem_id id;
740 struct snd_emu10k1_fx8010_control_gpr *gctl;
743 for (i = 0, _id = icode->gpr_del_controls;
744 i < icode->gpr_del_control_count; i++, _id++) {
746 id = *(struct snd_ctl_elem_id *)_id;
747 else if (copy_from_user(&id, _id, sizeof(id)))
749 if (snd_emu10k1_look_for_ctl(emu, &id) == NULL)
752 gctl = kmalloc(sizeof(*gctl), GFP_KERNEL);
756 for (i = 0; i < icode->gpr_add_control_count; i++) {
757 if (copy_gctl(emu, gctl, icode->gpr_add_controls, i,
762 if (snd_emu10k1_look_for_ctl(emu, &gctl->id))
764 down_read(&emu->card->controls_rwsem);
765 if (snd_ctl_find_id(emu->card, &gctl->id) != NULL) {
766 up_read(&emu->card->controls_rwsem);
770 up_read(&emu->card->controls_rwsem);
771 if (gctl->id.iface != SNDRV_CTL_ELEM_IFACE_MIXER &&
772 gctl->id.iface != SNDRV_CTL_ELEM_IFACE_PCM) {
777 for (i = 0; i < icode->gpr_list_control_count; i++) {
778 /* FIXME: we need to check the WRITE access */
779 if (copy_gctl(emu, gctl, icode->gpr_list_controls, i,
790 static void snd_emu10k1_ctl_private_free(struct snd_kcontrol *kctl)
792 struct snd_emu10k1_fx8010_ctl *ctl;
794 ctl = (struct snd_emu10k1_fx8010_ctl *) kctl->private_value;
795 kctl->private_value = 0;
796 list_del(&ctl->list);
801 static int snd_emu10k1_add_controls(struct snd_emu10k1 *emu,
802 struct snd_emu10k1_fx8010_code *icode,
806 struct snd_emu10k1_fx8010_control_gpr *gctl;
807 struct snd_emu10k1_fx8010_ctl *ctl, *nctl;
808 struct snd_kcontrol_new knew;
809 struct snd_kcontrol *kctl;
810 struct snd_ctl_elem_value *val;
813 val = kmalloc(sizeof(*val), GFP_KERNEL);
814 gctl = kmalloc(sizeof(*gctl), GFP_KERNEL);
815 nctl = kmalloc(sizeof(*nctl), GFP_KERNEL);
816 if (!val || !gctl || !nctl) {
821 for (i = 0; i < icode->gpr_add_control_count; i++) {
822 if (copy_gctl(emu, gctl, icode->gpr_add_controls, i,
827 if (gctl->id.iface != SNDRV_CTL_ELEM_IFACE_MIXER &&
828 gctl->id.iface != SNDRV_CTL_ELEM_IFACE_PCM) {
832 if (! gctl->id.name[0]) {
836 ctl = snd_emu10k1_look_for_ctl(emu, &gctl->id);
837 memset(&knew, 0, sizeof(knew));
838 knew.iface = gctl->id.iface;
839 knew.name = gctl->id.name;
840 knew.index = gctl->id.index;
841 knew.device = gctl->id.device;
842 knew.subdevice = gctl->id.subdevice;
843 knew.info = snd_emu10k1_gpr_ctl_info;
844 knew.tlv.p = copy_tlv(gctl->tlv, in_kernel);
846 knew.access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
847 SNDRV_CTL_ELEM_ACCESS_TLV_READ;
848 knew.get = snd_emu10k1_gpr_ctl_get;
849 knew.put = snd_emu10k1_gpr_ctl_put;
850 memset(nctl, 0, sizeof(*nctl));
851 nctl->vcount = gctl->vcount;
852 nctl->count = gctl->count;
853 for (j = 0; j < 32; j++) {
854 nctl->gpr[j] = gctl->gpr[j];
855 nctl->value[j] = ~gctl->value[j]; /* inverted, we want to write new value in gpr_ctl_put() */
856 val->value.integer.value[j] = gctl->value[j];
858 nctl->min = gctl->min;
859 nctl->max = gctl->max;
860 nctl->translation = gctl->translation;
862 ctl = kmalloc(sizeof(*ctl), GFP_KERNEL);
868 knew.private_value = (unsigned long)ctl;
870 if ((err = snd_ctl_add(emu->card, kctl = snd_ctl_new1(&knew, emu))) < 0) {
875 kctl->private_free = snd_emu10k1_ctl_private_free;
876 ctl->kcontrol = kctl;
877 list_add_tail(&ctl->list, &emu->fx8010.gpr_ctl);
880 nctl->list = ctl->list;
881 nctl->kcontrol = ctl->kcontrol;
883 snd_ctl_notify(emu->card, SNDRV_CTL_EVENT_MASK_VALUE |
884 SNDRV_CTL_EVENT_MASK_INFO, &ctl->kcontrol->id);
886 snd_emu10k1_gpr_ctl_put(ctl->kcontrol, val);
895 static int snd_emu10k1_del_controls(struct snd_emu10k1 *emu,
896 struct snd_emu10k1_fx8010_code *icode,
900 struct snd_ctl_elem_id id;
901 struct snd_ctl_elem_id __user *_id;
902 struct snd_emu10k1_fx8010_ctl *ctl;
903 struct snd_card *card = emu->card;
905 for (i = 0, _id = icode->gpr_del_controls;
906 i < icode->gpr_del_control_count; i++, _id++) {
908 id = *(struct snd_ctl_elem_id *)_id;
909 else if (copy_from_user(&id, _id, sizeof(id)))
911 down_write(&card->controls_rwsem);
912 ctl = snd_emu10k1_look_for_ctl(emu, &id);
914 snd_ctl_remove(card, ctl->kcontrol);
915 up_write(&card->controls_rwsem);
920 static int snd_emu10k1_list_controls(struct snd_emu10k1 *emu,
921 struct snd_emu10k1_fx8010_code *icode)
923 unsigned int i = 0, j;
924 unsigned int total = 0;
925 struct snd_emu10k1_fx8010_control_gpr *gctl;
926 struct snd_emu10k1_fx8010_ctl *ctl;
927 struct snd_ctl_elem_id *id;
929 gctl = kmalloc(sizeof(*gctl), GFP_KERNEL);
933 list_for_each_entry(ctl, &emu->fx8010.gpr_ctl, list) {
935 if (icode->gpr_list_controls &&
936 i < icode->gpr_list_control_count) {
937 memset(gctl, 0, sizeof(*gctl));
938 id = &ctl->kcontrol->id;
939 gctl->id.iface = id->iface;
940 strlcpy(gctl->id.name, id->name, sizeof(gctl->id.name));
941 gctl->id.index = id->index;
942 gctl->id.device = id->device;
943 gctl->id.subdevice = id->subdevice;
944 gctl->vcount = ctl->vcount;
945 gctl->count = ctl->count;
946 for (j = 0; j < 32; j++) {
947 gctl->gpr[j] = ctl->gpr[j];
948 gctl->value[j] = ctl->value[j];
950 gctl->min = ctl->min;
951 gctl->max = ctl->max;
952 gctl->translation = ctl->translation;
953 if (copy_gctl_to_user(emu, icode->gpr_list_controls,
961 icode->gpr_list_control_total = total;
966 static int snd_emu10k1_icode_poke(struct snd_emu10k1 *emu,
967 struct snd_emu10k1_fx8010_code *icode,
972 mutex_lock(&emu->fx8010.lock);
973 err = snd_emu10k1_verify_controls(emu, icode, in_kernel);
976 strlcpy(emu->fx8010.name, icode->name, sizeof(emu->fx8010.name));
977 /* stop FX processor - this may be dangerous, but it's better to miss
978 some samples than generate wrong ones - [jk] */
980 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg | A_DBG_SINGLE_STEP);
982 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg | EMU10K1_DBG_SINGLE_STEP);
983 /* ok, do the main job */
984 err = snd_emu10k1_del_controls(emu, icode, in_kernel);
987 err = snd_emu10k1_gpr_poke(emu, icode, in_kernel);
990 err = snd_emu10k1_tram_poke(emu, icode, in_kernel);
993 err = snd_emu10k1_code_poke(emu, icode, in_kernel);
996 err = snd_emu10k1_add_controls(emu, icode, in_kernel);
999 /* start FX processor when the DSP code is updated */
1001 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg);
1003 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg);
1005 mutex_unlock(&emu->fx8010.lock);
1009 static int snd_emu10k1_icode_peek(struct snd_emu10k1 *emu,
1010 struct snd_emu10k1_fx8010_code *icode)
1014 mutex_lock(&emu->fx8010.lock);
1015 strlcpy(icode->name, emu->fx8010.name, sizeof(icode->name));
1016 /* ok, do the main job */
1017 err = snd_emu10k1_gpr_peek(emu, icode);
1019 err = snd_emu10k1_tram_peek(emu, icode);
1021 err = snd_emu10k1_code_peek(emu, icode);
1023 err = snd_emu10k1_list_controls(emu, icode);
1024 mutex_unlock(&emu->fx8010.lock);
1028 static int snd_emu10k1_ipcm_poke(struct snd_emu10k1 *emu,
1029 struct snd_emu10k1_fx8010_pcm_rec *ipcm)
1033 struct snd_emu10k1_fx8010_pcm *pcm;
1035 if (ipcm->substream >= EMU10K1_FX8010_PCM_COUNT)
1037 ipcm->substream = array_index_nospec(ipcm->substream,
1038 EMU10K1_FX8010_PCM_COUNT);
1039 if (ipcm->channels > 32)
1041 pcm = &emu->fx8010.pcm[ipcm->substream];
1042 mutex_lock(&emu->fx8010.lock);
1043 spin_lock_irq(&emu->reg_lock);
1048 if (ipcm->channels == 0) { /* remove */
1051 /* FIXME: we need to add universal code to the PCM transfer routine */
1052 if (ipcm->channels != 2) {
1058 pcm->channels = ipcm->channels;
1059 pcm->tram_start = ipcm->tram_start;
1060 pcm->buffer_size = ipcm->buffer_size;
1061 pcm->gpr_size = ipcm->gpr_size;
1062 pcm->gpr_count = ipcm->gpr_count;
1063 pcm->gpr_tmpcount = ipcm->gpr_tmpcount;
1064 pcm->gpr_ptr = ipcm->gpr_ptr;
1065 pcm->gpr_trigger = ipcm->gpr_trigger;
1066 pcm->gpr_running = ipcm->gpr_running;
1067 for (i = 0; i < pcm->channels; i++)
1068 pcm->etram[i] = ipcm->etram[i];
1071 spin_unlock_irq(&emu->reg_lock);
1072 mutex_unlock(&emu->fx8010.lock);
1076 static int snd_emu10k1_ipcm_peek(struct snd_emu10k1 *emu,
1077 struct snd_emu10k1_fx8010_pcm_rec *ipcm)
1081 struct snd_emu10k1_fx8010_pcm *pcm;
1083 if (ipcm->substream >= EMU10K1_FX8010_PCM_COUNT)
1085 ipcm->substream = array_index_nospec(ipcm->substream,
1086 EMU10K1_FX8010_PCM_COUNT);
1087 pcm = &emu->fx8010.pcm[ipcm->substream];
1088 mutex_lock(&emu->fx8010.lock);
1089 spin_lock_irq(&emu->reg_lock);
1090 ipcm->channels = pcm->channels;
1091 ipcm->tram_start = pcm->tram_start;
1092 ipcm->buffer_size = pcm->buffer_size;
1093 ipcm->gpr_size = pcm->gpr_size;
1094 ipcm->gpr_ptr = pcm->gpr_ptr;
1095 ipcm->gpr_count = pcm->gpr_count;
1096 ipcm->gpr_tmpcount = pcm->gpr_tmpcount;
1097 ipcm->gpr_trigger = pcm->gpr_trigger;
1098 ipcm->gpr_running = pcm->gpr_running;
1099 for (i = 0; i < pcm->channels; i++)
1100 ipcm->etram[i] = pcm->etram[i];
1101 ipcm->res1 = ipcm->res2 = 0;
1103 spin_unlock_irq(&emu->reg_lock);
1104 mutex_unlock(&emu->fx8010.lock);
1108 #define SND_EMU10K1_GPR_CONTROLS 44
1109 #define SND_EMU10K1_INPUTS 12
1110 #define SND_EMU10K1_PLAYBACK_CHANNELS 8
1111 #define SND_EMU10K1_CAPTURE_CHANNELS 4
1114 snd_emu10k1_init_mono_control(struct snd_emu10k1_fx8010_control_gpr *ctl,
1115 const char *name, int gpr, int defval)
1117 ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1118 strcpy(ctl->id.name, name);
1119 ctl->vcount = ctl->count = 1;
1120 ctl->gpr[0] = gpr + 0; ctl->value[0] = defval;
1121 if (high_res_gpr_volume) {
1123 ctl->max = 0x7fffffff;
1124 ctl->tlv = snd_emu10k1_db_linear;
1125 ctl->translation = EMU10K1_GPR_TRANSLATION_NONE;
1129 ctl->tlv = snd_emu10k1_db_scale1;
1130 ctl->translation = EMU10K1_GPR_TRANSLATION_TABLE100;
1135 snd_emu10k1_init_stereo_control(struct snd_emu10k1_fx8010_control_gpr *ctl,
1136 const char *name, int gpr, int defval)
1138 ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1139 strcpy(ctl->id.name, name);
1140 ctl->vcount = ctl->count = 2;
1141 ctl->gpr[0] = gpr + 0; ctl->value[0] = defval;
1142 ctl->gpr[1] = gpr + 1; ctl->value[1] = defval;
1143 if (high_res_gpr_volume) {
1145 ctl->max = 0x7fffffff;
1146 ctl->tlv = snd_emu10k1_db_linear;
1147 ctl->translation = EMU10K1_GPR_TRANSLATION_NONE;
1151 ctl->tlv = snd_emu10k1_db_scale1;
1152 ctl->translation = EMU10K1_GPR_TRANSLATION_TABLE100;
1157 snd_emu10k1_init_mono_onoff_control(struct snd_emu10k1_fx8010_control_gpr *ctl,
1158 const char *name, int gpr, int defval)
1160 ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1161 strcpy(ctl->id.name, name);
1162 ctl->vcount = ctl->count = 1;
1163 ctl->gpr[0] = gpr + 0; ctl->value[0] = defval;
1166 ctl->translation = EMU10K1_GPR_TRANSLATION_ONOFF;
1170 snd_emu10k1_init_stereo_onoff_control(struct snd_emu10k1_fx8010_control_gpr *ctl,
1171 const char *name, int gpr, int defval)
1173 ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1174 strcpy(ctl->id.name, name);
1175 ctl->vcount = ctl->count = 2;
1176 ctl->gpr[0] = gpr + 0; ctl->value[0] = defval;
1177 ctl->gpr[1] = gpr + 1; ctl->value[1] = defval;
1180 ctl->translation = EMU10K1_GPR_TRANSLATION_ONOFF;
1184 * Used for emu1010 - conversion from 32-bit capture inputs from HANA
1185 * to 2 x 16-bit registers in audigy - their values are read via DMA.
1186 * Conversion is performed by Audigy DSP instructions of FX8010.
1188 static int snd_emu10k1_audigy_dsp_convert_32_to_2x16(
1189 struct snd_emu10k1_fx8010_code *icode,
1190 u32 *ptr, int tmp, int bit_shifter16,
1191 int reg_in, int reg_out)
1193 A_OP(icode, ptr, iACC3, A_GPR(tmp + 1), reg_in, A_C_00000000, A_C_00000000);
1194 A_OP(icode, ptr, iANDXOR, A_GPR(tmp), A_GPR(tmp + 1), A_GPR(bit_shifter16 - 1), A_C_00000000);
1195 A_OP(icode, ptr, iTSTNEG, A_GPR(tmp + 2), A_GPR(tmp), A_C_80000000, A_GPR(bit_shifter16 - 2));
1196 A_OP(icode, ptr, iANDXOR, A_GPR(tmp + 2), A_GPR(tmp + 2), A_C_80000000, A_C_00000000);
1197 A_OP(icode, ptr, iANDXOR, A_GPR(tmp), A_GPR(tmp), A_GPR(bit_shifter16 - 3), A_C_00000000);
1198 A_OP(icode, ptr, iMACINT0, A_GPR(tmp), A_C_00000000, A_GPR(tmp), A_C_00010000);
1199 A_OP(icode, ptr, iANDXOR, reg_out, A_GPR(tmp), A_C_ffffffff, A_GPR(tmp + 2));
1200 A_OP(icode, ptr, iACC3, reg_out + 1, A_GPR(tmp + 1), A_C_00000000, A_C_00000000);
1205 * initial DSP configuration for Audigy
1208 static int _snd_emu10k1_audigy_init_efx(struct snd_emu10k1 *emu)
1210 int err, i, z, gpr, nctl;
1212 const int playback = 10;
1213 const int capture = playback + (SND_EMU10K1_PLAYBACK_CHANNELS * 2); /* we reserve 10 voices */
1214 const int stereo_mix = capture + 2;
1215 const int tmp = 0x88;
1217 struct snd_emu10k1_fx8010_code *icode = NULL;
1218 struct snd_emu10k1_fx8010_control_gpr *controls = NULL, *ctl;
1222 icode = kzalloc(sizeof(*icode), GFP_KERNEL);
1226 icode->gpr_map = (u_int32_t __user *) kcalloc(512 + 256 + 256 + 2 * 1024,
1227 sizeof(u_int32_t), GFP_KERNEL);
1228 if (!icode->gpr_map)
1230 controls = kcalloc(SND_EMU10K1_GPR_CONTROLS,
1231 sizeof(*controls), GFP_KERNEL);
1235 gpr_map = (u32 __force *)icode->gpr_map;
1237 icode->tram_data_map = icode->gpr_map + 512;
1238 icode->tram_addr_map = icode->tram_data_map + 256;
1239 icode->code = icode->tram_addr_map + 256;
1241 /* clear free GPRs */
1242 for (i = 0; i < 512; i++)
1243 set_bit(i, icode->gpr_valid);
1245 /* clear TRAM data & address lines */
1246 for (i = 0; i < 256; i++)
1247 set_bit(i, icode->tram_valid);
1249 strcpy(icode->name, "Audigy DSP code for ALSA");
1252 gpr = stereo_mix + 10;
1253 gpr_map[gpr++] = 0x00007fff;
1254 gpr_map[gpr++] = 0x00008000;
1255 gpr_map[gpr++] = 0x0000ffff;
1256 bit_shifter16 = gpr;
1258 /* stop FX processor */
1259 snd_emu10k1_ptr_write(emu, A_DBG, 0, (emu->fx8010.dbg = 0) | A_DBG_SINGLE_STEP);
1262 /* PCM front Playback Volume (independent from stereo mix)
1263 * playback = 0 + ( gpr * FXBUS_PCM_LEFT_FRONT >> 31)
1264 * where gpr contains attenuation from corresponding mixer control
1265 * (snd_emu10k1_init_stereo_control)
1267 A_OP(icode, &ptr, iMAC0, A_GPR(playback), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LEFT_FRONT));
1268 A_OP(icode, &ptr, iMAC0, A_GPR(playback+1), A_C_00000000, A_GPR(gpr+1), A_FXBUS(FXBUS_PCM_RIGHT_FRONT));
1269 snd_emu10k1_init_stereo_control(&controls[nctl++], "PCM Front Playback Volume", gpr, 100);
1272 /* PCM Surround Playback (independent from stereo mix) */
1273 A_OP(icode, &ptr, iMAC0, A_GPR(playback+2), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LEFT_REAR));
1274 A_OP(icode, &ptr, iMAC0, A_GPR(playback+3), A_C_00000000, A_GPR(gpr+1), A_FXBUS(FXBUS_PCM_RIGHT_REAR));
1275 snd_emu10k1_init_stereo_control(&controls[nctl++], "PCM Surround Playback Volume", gpr, 100);
1278 /* PCM Side Playback (independent from stereo mix) */
1279 if (emu->card_capabilities->spk71) {
1280 A_OP(icode, &ptr, iMAC0, A_GPR(playback+6), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LEFT_SIDE));
1281 A_OP(icode, &ptr, iMAC0, A_GPR(playback+7), A_C_00000000, A_GPR(gpr+1), A_FXBUS(FXBUS_PCM_RIGHT_SIDE));
1282 snd_emu10k1_init_stereo_control(&controls[nctl++], "PCM Side Playback Volume", gpr, 100);
1286 /* PCM Center Playback (independent from stereo mix) */
1287 A_OP(icode, &ptr, iMAC0, A_GPR(playback+4), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_CENTER));
1288 snd_emu10k1_init_mono_control(&controls[nctl++], "PCM Center Playback Volume", gpr, 100);
1291 /* PCM LFE Playback (independent from stereo mix) */
1292 A_OP(icode, &ptr, iMAC0, A_GPR(playback+5), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LFE));
1293 snd_emu10k1_init_mono_control(&controls[nctl++], "PCM LFE Playback Volume", gpr, 100);
1299 /* Wave (PCM) Playback Volume (will be renamed later) */
1300 A_OP(icode, &ptr, iMAC0, A_GPR(stereo_mix), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LEFT));
1301 A_OP(icode, &ptr, iMAC0, A_GPR(stereo_mix+1), A_C_00000000, A_GPR(gpr+1), A_FXBUS(FXBUS_PCM_RIGHT));
1302 snd_emu10k1_init_stereo_control(&controls[nctl++], "Wave Playback Volume", gpr, 100);
1305 /* Synth Playback */
1306 A_OP(icode, &ptr, iMAC0, A_GPR(stereo_mix+0), A_GPR(stereo_mix+0), A_GPR(gpr), A_FXBUS(FXBUS_MIDI_LEFT));
1307 A_OP(icode, &ptr, iMAC0, A_GPR(stereo_mix+1), A_GPR(stereo_mix+1), A_GPR(gpr+1), A_FXBUS(FXBUS_MIDI_RIGHT));
1308 snd_emu10k1_init_stereo_control(&controls[nctl++], "Synth Playback Volume", gpr, 100);
1311 /* Wave (PCM) Capture */
1312 A_OP(icode, &ptr, iMAC0, A_GPR(capture+0), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LEFT));
1313 A_OP(icode, &ptr, iMAC0, A_GPR(capture+1), A_C_00000000, A_GPR(gpr+1), A_FXBUS(FXBUS_PCM_RIGHT));
1314 snd_emu10k1_init_stereo_control(&controls[nctl++], "PCM Capture Volume", gpr, 0);
1318 A_OP(icode, &ptr, iMAC0, A_GPR(capture+0), A_GPR(capture+0), A_GPR(gpr), A_FXBUS(FXBUS_MIDI_LEFT));
1319 A_OP(icode, &ptr, iMAC0, A_GPR(capture+1), A_GPR(capture+1), A_GPR(gpr+1), A_FXBUS(FXBUS_MIDI_RIGHT));
1320 snd_emu10k1_init_stereo_control(&controls[nctl++], "Synth Capture Volume", gpr, 0);
1326 #define A_ADD_VOLUME_IN(var,vol,input) \
1327 A_OP(icode, &ptr, iMAC0, A_GPR(var), A_GPR(var), A_GPR(vol), A_EXTIN(input))
1329 /* emu1212 DSP 0 and DSP 1 Capture */
1330 if (emu->card_capabilities->emu_model) {
1331 if (emu->card_capabilities->ca0108_chip) {
1332 /* Note:JCD:No longer bit shift lower 16bits to upper 16bits of 32bit value. */
1333 A_OP(icode, &ptr, iMACINT0, A_GPR(tmp), A_C_00000000, A3_EMU32IN(0x0), A_C_00000001);
1334 A_OP(icode, &ptr, iMAC0, A_GPR(capture+0), A_GPR(capture+0), A_GPR(gpr), A_GPR(tmp));
1335 A_OP(icode, &ptr, iMACINT0, A_GPR(tmp), A_C_00000000, A3_EMU32IN(0x1), A_C_00000001);
1336 A_OP(icode, &ptr, iMAC0, A_GPR(capture+1), A_GPR(capture+1), A_GPR(gpr), A_GPR(tmp));
1338 A_OP(icode, &ptr, iMAC0, A_GPR(capture+0), A_GPR(capture+0), A_GPR(gpr), A_P16VIN(0x0));
1339 A_OP(icode, &ptr, iMAC0, A_GPR(capture+1), A_GPR(capture+1), A_GPR(gpr+1), A_P16VIN(0x1));
1341 snd_emu10k1_init_stereo_control(&controls[nctl++], "EMU Capture Volume", gpr, 0);
1344 /* AC'97 Playback Volume - used only for mic (renamed later) */
1345 A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_AC97_L);
1346 A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_AC97_R);
1347 snd_emu10k1_init_stereo_control(&controls[nctl++], "AMic Playback Volume", gpr, 0);
1349 /* AC'97 Capture Volume - used only for mic */
1350 A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_AC97_L);
1351 A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_AC97_R);
1352 snd_emu10k1_init_stereo_control(&controls[nctl++], "Mic Capture Volume", gpr, 0);
1355 /* mic capture buffer */
1356 A_OP(icode, &ptr, iINTERP, A_EXTOUT(A_EXTOUT_MIC_CAP), A_EXTIN(A_EXTIN_AC97_L), 0xcd, A_EXTIN(A_EXTIN_AC97_R));
1358 /* Audigy CD Playback Volume */
1359 A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_SPDIF_CD_L);
1360 A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_SPDIF_CD_R);
1361 snd_emu10k1_init_stereo_control(&controls[nctl++],
1362 emu->card_capabilities->ac97_chip ? "Audigy CD Playback Volume" : "CD Playback Volume",
1365 /* Audigy CD Capture Volume */
1366 A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_SPDIF_CD_L);
1367 A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_SPDIF_CD_R);
1368 snd_emu10k1_init_stereo_control(&controls[nctl++],
1369 emu->card_capabilities->ac97_chip ? "Audigy CD Capture Volume" : "CD Capture Volume",
1373 /* Optical SPDIF Playback Volume */
1374 A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_OPT_SPDIF_L);
1375 A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_OPT_SPDIF_R);
1376 snd_emu10k1_init_stereo_control(&controls[nctl++], SNDRV_CTL_NAME_IEC958("Optical ",PLAYBACK,VOLUME), gpr, 0);
1378 /* Optical SPDIF Capture Volume */
1379 A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_OPT_SPDIF_L);
1380 A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_OPT_SPDIF_R);
1381 snd_emu10k1_init_stereo_control(&controls[nctl++], SNDRV_CTL_NAME_IEC958("Optical ",CAPTURE,VOLUME), gpr, 0);
1384 /* Line2 Playback Volume */
1385 A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_LINE2_L);
1386 A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_LINE2_R);
1387 snd_emu10k1_init_stereo_control(&controls[nctl++],
1388 emu->card_capabilities->ac97_chip ? "Line2 Playback Volume" : "Line Playback Volume",
1391 /* Line2 Capture Volume */
1392 A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_LINE2_L);
1393 A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_LINE2_R);
1394 snd_emu10k1_init_stereo_control(&controls[nctl++],
1395 emu->card_capabilities->ac97_chip ? "Line2 Capture Volume" : "Line Capture Volume",
1399 /* Philips ADC Playback Volume */
1400 A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_ADC_L);
1401 A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_ADC_R);
1402 snd_emu10k1_init_stereo_control(&controls[nctl++], "Analog Mix Playback Volume", gpr, 0);
1404 /* Philips ADC Capture Volume */
1405 A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_ADC_L);
1406 A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_ADC_R);
1407 snd_emu10k1_init_stereo_control(&controls[nctl++], "Analog Mix Capture Volume", gpr, 0);
1410 /* Aux2 Playback Volume */
1411 A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_AUX2_L);
1412 A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_AUX2_R);
1413 snd_emu10k1_init_stereo_control(&controls[nctl++],
1414 emu->card_capabilities->ac97_chip ? "Aux2 Playback Volume" : "Aux Playback Volume",
1417 /* Aux2 Capture Volume */
1418 A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_AUX2_L);
1419 A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_AUX2_R);
1420 snd_emu10k1_init_stereo_control(&controls[nctl++],
1421 emu->card_capabilities->ac97_chip ? "Aux2 Capture Volume" : "Aux Capture Volume",
1425 /* Stereo Mix Front Playback Volume */
1426 A_OP(icode, &ptr, iMAC0, A_GPR(playback), A_GPR(playback), A_GPR(gpr), A_GPR(stereo_mix));
1427 A_OP(icode, &ptr, iMAC0, A_GPR(playback+1), A_GPR(playback+1), A_GPR(gpr+1), A_GPR(stereo_mix+1));
1428 snd_emu10k1_init_stereo_control(&controls[nctl++], "Front Playback Volume", gpr, 100);
1431 /* Stereo Mix Surround Playback */
1432 A_OP(icode, &ptr, iMAC0, A_GPR(playback+2), A_GPR(playback+2), A_GPR(gpr), A_GPR(stereo_mix));
1433 A_OP(icode, &ptr, iMAC0, A_GPR(playback+3), A_GPR(playback+3), A_GPR(gpr+1), A_GPR(stereo_mix+1));
1434 snd_emu10k1_init_stereo_control(&controls[nctl++], "Surround Playback Volume", gpr, 0);
1437 /* Stereo Mix Center Playback */
1438 /* Center = sub = Left/2 + Right/2 */
1439 A_OP(icode, &ptr, iINTERP, A_GPR(tmp), A_GPR(stereo_mix), 0xcd, A_GPR(stereo_mix+1));
1440 A_OP(icode, &ptr, iMAC0, A_GPR(playback+4), A_GPR(playback+4), A_GPR(gpr), A_GPR(tmp));
1441 snd_emu10k1_init_mono_control(&controls[nctl++], "Center Playback Volume", gpr, 0);
1444 /* Stereo Mix LFE Playback */
1445 A_OP(icode, &ptr, iMAC0, A_GPR(playback+5), A_GPR(playback+5), A_GPR(gpr), A_GPR(tmp));
1446 snd_emu10k1_init_mono_control(&controls[nctl++], "LFE Playback Volume", gpr, 0);
1449 if (emu->card_capabilities->spk71) {
1450 /* Stereo Mix Side Playback */
1451 A_OP(icode, &ptr, iMAC0, A_GPR(playback+6), A_GPR(playback+6), A_GPR(gpr), A_GPR(stereo_mix));
1452 A_OP(icode, &ptr, iMAC0, A_GPR(playback+7), A_GPR(playback+7), A_GPR(gpr+1), A_GPR(stereo_mix+1));
1453 snd_emu10k1_init_stereo_control(&controls[nctl++], "Side Playback Volume", gpr, 0);
1460 #define A_PUT_OUTPUT(out,src) A_OP(icode, &ptr, iACC3, A_EXTOUT(out), A_C_00000000, A_C_00000000, A_GPR(src))
1461 #define A_PUT_STEREO_OUTPUT(out1,out2,src) \
1462 {A_PUT_OUTPUT(out1,src); A_PUT_OUTPUT(out2,src+1);}
1464 #define _A_SWITCH(icode, ptr, dst, src, sw) \
1465 A_OP((icode), ptr, iMACINT0, dst, A_C_00000000, src, sw);
1466 #define A_SWITCH(icode, ptr, dst, src, sw) \
1467 _A_SWITCH(icode, ptr, A_GPR(dst), A_GPR(src), A_GPR(sw))
1468 #define _A_SWITCH_NEG(icode, ptr, dst, src) \
1469 A_OP((icode), ptr, iANDXOR, dst, src, A_C_00000001, A_C_00000001);
1470 #define A_SWITCH_NEG(icode, ptr, dst, src) \
1471 _A_SWITCH_NEG(icode, ptr, A_GPR(dst), A_GPR(src))
1475 * Process tone control
1477 A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 0), A_GPR(playback + 0), A_C_00000000, A_C_00000000); /* left */
1478 A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 1), A_GPR(playback + 1), A_C_00000000, A_C_00000000); /* right */
1479 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 */
1480 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 */
1481 A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 4), A_GPR(playback + 4), A_C_00000000, A_C_00000000); /* center */
1482 A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 5), A_GPR(playback + 5), A_C_00000000, A_C_00000000); /* LFE */
1483 if (emu->card_capabilities->spk71) {
1484 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 */
1485 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 */
1489 ctl = &controls[nctl + 0];
1490 ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1491 strcpy(ctl->id.name, "Tone Control - Bass");
1496 ctl->value[0] = ctl->value[1] = 20;
1497 ctl->translation = EMU10K1_GPR_TRANSLATION_BASS;
1498 ctl = &controls[nctl + 1];
1499 ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1500 strcpy(ctl->id.name, "Tone Control - Treble");
1505 ctl->value[0] = ctl->value[1] = 20;
1506 ctl->translation = EMU10K1_GPR_TRANSLATION_TREBLE;
1508 #define BASS_GPR 0x8c
1509 #define TREBLE_GPR 0x96
1511 for (z = 0; z < 5; z++) {
1513 for (j = 0; j < 2; j++) {
1514 controls[nctl + 0].gpr[z * 2 + j] = BASS_GPR + z * 2 + j;
1515 controls[nctl + 1].gpr[z * 2 + j] = TREBLE_GPR + z * 2 + j;
1518 for (z = 0; z < 4; z++) { /* front/rear/center-lfe/side */
1520 for (j = 0; j < 2; j++) { /* left/right */
1521 k = 0xb0 + (z * 8) + (j * 4);
1522 l = 0xe0 + (z * 8) + (j * 4);
1523 d = playback + SND_EMU10K1_PLAYBACK_CHANNELS + z * 2 + j;
1525 A_OP(icode, &ptr, iMAC0, A_C_00000000, A_C_00000000, A_GPR(d), A_GPR(BASS_GPR + 0 + j));
1526 A_OP(icode, &ptr, iMACMV, A_GPR(k+1), A_GPR(k), A_GPR(k+1), A_GPR(BASS_GPR + 4 + j));
1527 A_OP(icode, &ptr, iMACMV, A_GPR(k), A_GPR(d), A_GPR(k), A_GPR(BASS_GPR + 2 + j));
1528 A_OP(icode, &ptr, iMACMV, A_GPR(k+3), A_GPR(k+2), A_GPR(k+3), A_GPR(BASS_GPR + 8 + j));
1529 A_OP(icode, &ptr, iMAC0, A_GPR(k+2), A_GPR_ACCU, A_GPR(k+2), A_GPR(BASS_GPR + 6 + j));
1530 A_OP(icode, &ptr, iACC3, A_GPR(k+2), A_GPR(k+2), A_GPR(k+2), A_C_00000000);
1532 A_OP(icode, &ptr, iMAC0, A_C_00000000, A_C_00000000, A_GPR(k+2), A_GPR(TREBLE_GPR + 0 + j));
1533 A_OP(icode, &ptr, iMACMV, A_GPR(l+1), A_GPR(l), A_GPR(l+1), A_GPR(TREBLE_GPR + 4 + j));
1534 A_OP(icode, &ptr, iMACMV, A_GPR(l), A_GPR(k+2), A_GPR(l), A_GPR(TREBLE_GPR + 2 + j));
1535 A_OP(icode, &ptr, iMACMV, A_GPR(l+3), A_GPR(l+2), A_GPR(l+3), A_GPR(TREBLE_GPR + 8 + j));
1536 A_OP(icode, &ptr, iMAC0, A_GPR(l+2), A_GPR_ACCU, A_GPR(l+2), A_GPR(TREBLE_GPR + 6 + j));
1537 A_OP(icode, &ptr, iMACINT0, A_GPR(l+2), A_C_00000000, A_GPR(l+2), A_C_00000010);
1539 A_OP(icode, &ptr, iACC3, A_GPR(d), A_GPR(l+2), A_C_00000000, A_C_00000000);
1541 if (z == 2) /* center */
1550 for (z = 0; z < 8; z++) {
1551 A_SWITCH(icode, &ptr, tmp + 0, playback + SND_EMU10K1_PLAYBACK_CHANNELS + z, gpr + 0);
1552 A_SWITCH_NEG(icode, &ptr, tmp + 1, gpr + 0);
1553 A_SWITCH(icode, &ptr, tmp + 1, playback + z, tmp + 1);
1554 A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + z), A_GPR(tmp + 0), A_GPR(tmp + 1), A_C_00000000);
1556 snd_emu10k1_init_stereo_onoff_control(controls + nctl++, "Tone Control - Switch", gpr, 0);
1559 /* Master volume (will be renamed later) */
1560 for (z = 0; z < 8; z++)
1561 A_OP(icode, &ptr, iMAC0, A_GPR(playback+z+SND_EMU10K1_PLAYBACK_CHANNELS), A_C_00000000, A_GPR(gpr), A_GPR(playback+z+SND_EMU10K1_PLAYBACK_CHANNELS));
1562 snd_emu10k1_init_mono_control(&controls[nctl++], "Wave Master Playback Volume", gpr, 0);
1565 /* analog speakers */
1566 A_PUT_STEREO_OUTPUT(A_EXTOUT_AFRONT_L, A_EXTOUT_AFRONT_R, playback + SND_EMU10K1_PLAYBACK_CHANNELS);
1567 A_PUT_STEREO_OUTPUT(A_EXTOUT_AREAR_L, A_EXTOUT_AREAR_R, playback+2 + SND_EMU10K1_PLAYBACK_CHANNELS);
1568 A_PUT_OUTPUT(A_EXTOUT_ACENTER, playback+4 + SND_EMU10K1_PLAYBACK_CHANNELS);
1569 A_PUT_OUTPUT(A_EXTOUT_ALFE, playback+5 + SND_EMU10K1_PLAYBACK_CHANNELS);
1570 if (emu->card_capabilities->spk71)
1571 A_PUT_STEREO_OUTPUT(A_EXTOUT_ASIDE_L, A_EXTOUT_ASIDE_R, playback+6 + SND_EMU10K1_PLAYBACK_CHANNELS);
1574 A_PUT_STEREO_OUTPUT(A_EXTOUT_HEADPHONE_L, A_EXTOUT_HEADPHONE_R, playback + SND_EMU10K1_PLAYBACK_CHANNELS);
1576 /* digital outputs */
1577 /* A_PUT_STEREO_OUTPUT(A_EXTOUT_FRONT_L, A_EXTOUT_FRONT_R, playback + SND_EMU10K1_PLAYBACK_CHANNELS); */
1578 if (emu->card_capabilities->emu_model) {
1579 /* EMU1010 Outputs from PCM Front, Rear, Center, LFE, Side */
1580 dev_info(emu->card->dev, "EMU outputs on\n");
1581 for (z = 0; z < 8; z++) {
1582 if (emu->card_capabilities->ca0108_chip) {
1583 A_OP(icode, &ptr, iACC3, A3_EMU32OUT(z), A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + z), A_C_00000000, A_C_00000000);
1585 A_OP(icode, &ptr, iACC3, A_EMU32OUTL(z), A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + z), A_C_00000000, A_C_00000000);
1590 /* IEC958 Optical Raw Playback Switch */
1592 gpr_map[gpr++] = 0x1008;
1593 gpr_map[gpr++] = 0xffff0000;
1594 for (z = 0; z < 2; z++) {
1595 A_OP(icode, &ptr, iMAC0, A_GPR(tmp + 2), A_FXBUS(FXBUS_PT_LEFT + z), A_C_00000000, A_C_00000000);
1596 A_OP(icode, &ptr, iSKIP, A_GPR_COND, A_GPR_COND, A_GPR(gpr - 2), A_C_00000001);
1597 A_OP(icode, &ptr, iACC3, A_GPR(tmp + 2), A_C_00000000, A_C_00010000, A_GPR(tmp + 2));
1598 A_OP(icode, &ptr, iANDXOR, A_GPR(tmp + 2), A_GPR(tmp + 2), A_GPR(gpr - 1), A_C_00000000);
1599 A_SWITCH(icode, &ptr, tmp + 0, tmp + 2, gpr + z);
1600 A_SWITCH_NEG(icode, &ptr, tmp + 1, gpr + z);
1601 A_SWITCH(icode, &ptr, tmp + 1, playback + SND_EMU10K1_PLAYBACK_CHANNELS + z, tmp + 1);
1602 if ((z==1) && (emu->card_capabilities->spdif_bug)) {
1603 /* Due to a SPDIF output bug on some Audigy cards, this code delays the Right channel by 1 sample */
1604 dev_info(emu->card->dev,
1605 "Installing spdif_bug patch: %s\n",
1606 emu->card_capabilities->name);
1607 A_OP(icode, &ptr, iACC3, A_EXTOUT(A_EXTOUT_FRONT_L + z), A_GPR(gpr - 3), A_C_00000000, A_C_00000000);
1608 A_OP(icode, &ptr, iACC3, A_GPR(gpr - 3), A_GPR(tmp + 0), A_GPR(tmp + 1), A_C_00000000);
1610 A_OP(icode, &ptr, iACC3, A_EXTOUT(A_EXTOUT_FRONT_L + z), A_GPR(tmp + 0), A_GPR(tmp + 1), A_C_00000000);
1613 snd_emu10k1_init_stereo_onoff_control(controls + nctl++, SNDRV_CTL_NAME_IEC958("Optical Raw ",PLAYBACK,SWITCH), gpr, 0);
1616 A_PUT_STEREO_OUTPUT(A_EXTOUT_REAR_L, A_EXTOUT_REAR_R, playback+2 + SND_EMU10K1_PLAYBACK_CHANNELS);
1617 A_PUT_OUTPUT(A_EXTOUT_CENTER, playback+4 + SND_EMU10K1_PLAYBACK_CHANNELS);
1618 A_PUT_OUTPUT(A_EXTOUT_LFE, playback+5 + SND_EMU10K1_PLAYBACK_CHANNELS);
1621 #ifdef EMU10K1_CAPTURE_DIGITAL_OUT
1622 A_PUT_STEREO_OUTPUT(A_EXTOUT_ADC_CAP_L, A_EXTOUT_ADC_CAP_R, playback + SND_EMU10K1_PLAYBACK_CHANNELS);
1624 A_PUT_OUTPUT(A_EXTOUT_ADC_CAP_L, capture);
1625 A_PUT_OUTPUT(A_EXTOUT_ADC_CAP_R, capture+1);
1628 if (emu->card_capabilities->emu_model) {
1629 if (emu->card_capabilities->ca0108_chip) {
1630 dev_info(emu->card->dev, "EMU2 inputs on\n");
1631 for (z = 0; z < 0x10; z++) {
1632 snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp,
1638 dev_info(emu->card->dev, "EMU inputs on\n");
1639 /* Capture 16 (originally 8) channels of S32_LE sound */
1642 dev_dbg(emu->card->dev, "emufx.c: gpr=0x%x, tmp=0x%x\n",
1645 snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_P16VIN(0x0), A_FXBUS2(0) );
1646 /* A_P16VIN(0) is delayed by one sample, so all other A_P16VIN channels
1647 * will need to also be delayed; we use an auxiliary register for that. */
1648 for (z = 1; z < 0x10; z++) {
1649 snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_GPR(gpr), A_FXBUS2(z * 2) );
1650 A_OP(icode, &ptr, iACC3, A_GPR(gpr), A_P16VIN(z), A_C_00000000, A_C_00000000);
1651 gpr_map[gpr++] = 0x00000000;
1656 for (z = 4; z < 8; z++) {
1657 A_OP(icode, &ptr, iACC3, A_FXBUS2(z), A_C_00000000, A_C_00000000, A_C_00000000);
1659 for (z = 0xc; z < 0x10; z++) {
1660 A_OP(icode, &ptr, iACC3, A_FXBUS2(z), A_C_00000000, A_C_00000000, A_C_00000000);
1664 /* EFX capture - capture the 16 EXTINs */
1665 /* Capture 16 channels of S16_LE sound */
1666 for (z = 0; z < 16; z++) {
1667 A_OP(icode, &ptr, iACC3, A_FXBUS2(z), A_C_00000000, A_C_00000000, A_EXTIN(z));
1671 #endif /* JCD test */
1681 /* clear remaining instruction memory */
1683 A_OP(icode, &ptr, 0x0f, 0xc0, 0xc0, 0xcf, 0xc0);
1685 icode->gpr_add_control_count = nctl;
1686 icode->gpr_add_controls = (struct snd_emu10k1_fx8010_control_gpr __user *)controls;
1687 emu->support_tlv = 1; /* support TLV */
1688 err = snd_emu10k1_icode_poke(emu, icode, true);
1689 emu->support_tlv = 0; /* clear again */
1694 kfree((void __force *)icode->gpr_map);
1702 * initial DSP configuration for Emu10k1
1705 /* when volume = max, then copy only to avoid volume modification */
1706 /* with iMAC0 (negative values) */
1707 static void _volume(struct snd_emu10k1_fx8010_code *icode, u32 *ptr, u32 dst, u32 src, u32 vol)
1709 OP(icode, ptr, iMAC0, dst, C_00000000, src, vol);
1710 OP(icode, ptr, iANDXOR, C_00000000, vol, C_ffffffff, C_7fffffff);
1711 OP(icode, ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, C_00000001);
1712 OP(icode, ptr, iACC3, dst, src, C_00000000, C_00000000);
1714 static void _volume_add(struct snd_emu10k1_fx8010_code *icode, u32 *ptr, u32 dst, u32 src, u32 vol)
1716 OP(icode, ptr, iANDXOR, C_00000000, vol, C_ffffffff, C_7fffffff);
1717 OP(icode, ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, C_00000002);
1718 OP(icode, ptr, iMACINT0, dst, dst, src, C_00000001);
1719 OP(icode, ptr, iSKIP, C_00000000, C_7fffffff, C_7fffffff, C_00000001);
1720 OP(icode, ptr, iMAC0, dst, dst, src, vol);
1722 static void _volume_out(struct snd_emu10k1_fx8010_code *icode, u32 *ptr, u32 dst, u32 src, u32 vol)
1724 OP(icode, ptr, iANDXOR, C_00000000, vol, C_ffffffff, C_7fffffff);
1725 OP(icode, ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, C_00000002);
1726 OP(icode, ptr, iACC3, dst, src, C_00000000, C_00000000);
1727 OP(icode, ptr, iSKIP, C_00000000, C_7fffffff, C_7fffffff, C_00000001);
1728 OP(icode, ptr, iMAC0, dst, C_00000000, src, vol);
1731 #define VOLUME(icode, ptr, dst, src, vol) \
1732 _volume(icode, ptr, GPR(dst), GPR(src), GPR(vol))
1733 #define VOLUME_IN(icode, ptr, dst, src, vol) \
1734 _volume(icode, ptr, GPR(dst), EXTIN(src), GPR(vol))
1735 #define VOLUME_ADD(icode, ptr, dst, src, vol) \
1736 _volume_add(icode, ptr, GPR(dst), GPR(src), GPR(vol))
1737 #define VOLUME_ADDIN(icode, ptr, dst, src, vol) \
1738 _volume_add(icode, ptr, GPR(dst), EXTIN(src), GPR(vol))
1739 #define VOLUME_OUT(icode, ptr, dst, src, vol) \
1740 _volume_out(icode, ptr, EXTOUT(dst), GPR(src), GPR(vol))
1741 #define _SWITCH(icode, ptr, dst, src, sw) \
1742 OP((icode), ptr, iMACINT0, dst, C_00000000, src, sw);
1743 #define SWITCH(icode, ptr, dst, src, sw) \
1744 _SWITCH(icode, ptr, GPR(dst), GPR(src), GPR(sw))
1745 #define SWITCH_IN(icode, ptr, dst, src, sw) \
1746 _SWITCH(icode, ptr, GPR(dst), EXTIN(src), GPR(sw))
1747 #define _SWITCH_NEG(icode, ptr, dst, src) \
1748 OP((icode), ptr, iANDXOR, dst, src, C_00000001, C_00000001);
1749 #define SWITCH_NEG(icode, ptr, dst, src) \
1750 _SWITCH_NEG(icode, ptr, GPR(dst), GPR(src))
1753 static int _snd_emu10k1_init_efx(struct snd_emu10k1 *emu)
1755 int err, i, z, gpr, tmp, playback, capture;
1757 struct snd_emu10k1_fx8010_code *icode;
1758 struct snd_emu10k1_fx8010_pcm_rec *ipcm = NULL;
1759 struct snd_emu10k1_fx8010_control_gpr *controls = NULL, *ctl;
1763 icode = kzalloc(sizeof(*icode), GFP_KERNEL);
1767 icode->gpr_map = (u_int32_t __user *) kcalloc(256 + 160 + 160 + 2 * 512,
1768 sizeof(u_int32_t), GFP_KERNEL);
1769 if (!icode->gpr_map)
1772 controls = kcalloc(SND_EMU10K1_GPR_CONTROLS,
1773 sizeof(struct snd_emu10k1_fx8010_control_gpr),
1778 ipcm = kzalloc(sizeof(*ipcm), GFP_KERNEL);
1782 gpr_map = (u32 __force *)icode->gpr_map;
1784 icode->tram_data_map = icode->gpr_map + 256;
1785 icode->tram_addr_map = icode->tram_data_map + 160;
1786 icode->code = icode->tram_addr_map + 160;
1788 /* clear free GPRs */
1789 for (i = 0; i < 256; i++)
1790 set_bit(i, icode->gpr_valid);
1792 /* clear TRAM data & address lines */
1793 for (i = 0; i < 160; i++)
1794 set_bit(i, icode->tram_valid);
1796 strcpy(icode->name, "SB Live! FX8010 code for ALSA v1.2 by Jaroslav Kysela");
1798 /* we have 12 inputs */
1799 playback = SND_EMU10K1_INPUTS;
1800 /* we have 6 playback channels and tone control doubles */
1801 capture = playback + (SND_EMU10K1_PLAYBACK_CHANNELS * 2);
1802 gpr = capture + SND_EMU10K1_CAPTURE_CHANNELS;
1803 tmp = 0x88; /* we need 4 temporary GPR */
1804 /* from 0x8c to 0xff is the area for tone control */
1806 /* stop FX processor */
1807 snd_emu10k1_ptr_write(emu, DBG, 0, (emu->fx8010.dbg = 0) | EMU10K1_DBG_SINGLE_STEP);
1812 OP(icode, &ptr, iMACINT0, GPR(0), C_00000000, FXBUS(FXBUS_PCM_LEFT), C_00000004);
1813 OP(icode, &ptr, iMACINT0, GPR(1), C_00000000, FXBUS(FXBUS_PCM_RIGHT), C_00000004);
1814 OP(icode, &ptr, iMACINT0, GPR(2), C_00000000, FXBUS(FXBUS_MIDI_LEFT), C_00000004);
1815 OP(icode, &ptr, iMACINT0, GPR(3), C_00000000, FXBUS(FXBUS_MIDI_RIGHT), C_00000004);
1816 OP(icode, &ptr, iMACINT0, GPR(4), C_00000000, FXBUS(FXBUS_PCM_LEFT_REAR), C_00000004);
1817 OP(icode, &ptr, iMACINT0, GPR(5), C_00000000, FXBUS(FXBUS_PCM_RIGHT_REAR), C_00000004);
1818 OP(icode, &ptr, iMACINT0, GPR(6), C_00000000, FXBUS(FXBUS_PCM_CENTER), C_00000004);
1819 OP(icode, &ptr, iMACINT0, GPR(7), C_00000000, FXBUS(FXBUS_PCM_LFE), C_00000004);
1820 OP(icode, &ptr, iMACINT0, GPR(8), C_00000000, C_00000000, C_00000000); /* S/PDIF left */
1821 OP(icode, &ptr, iMACINT0, GPR(9), C_00000000, C_00000000, C_00000000); /* S/PDIF right */
1822 OP(icode, &ptr, iMACINT0, GPR(10), C_00000000, FXBUS(FXBUS_PCM_LEFT_FRONT), C_00000004);
1823 OP(icode, &ptr, iMACINT0, GPR(11), C_00000000, FXBUS(FXBUS_PCM_RIGHT_FRONT), C_00000004);
1825 /* Raw S/PDIF PCM */
1826 ipcm->substream = 0;
1828 ipcm->tram_start = 0;
1829 ipcm->buffer_size = (64 * 1024) / 2;
1830 ipcm->gpr_size = gpr++;
1831 ipcm->gpr_ptr = gpr++;
1832 ipcm->gpr_count = gpr++;
1833 ipcm->gpr_tmpcount = gpr++;
1834 ipcm->gpr_trigger = gpr++;
1835 ipcm->gpr_running = gpr++;
1839 gpr_map[gpr + 0] = 0xfffff000;
1840 gpr_map[gpr + 1] = 0xffff0000;
1841 gpr_map[gpr + 2] = 0x70000000;
1842 gpr_map[gpr + 3] = 0x00000007;
1843 gpr_map[gpr + 4] = 0x001f << 11;
1844 gpr_map[gpr + 5] = 0x001c << 11;
1845 gpr_map[gpr + 6] = (0x22 - 0x01) - 1; /* skip at 01 to 22 */
1846 gpr_map[gpr + 7] = (0x22 - 0x06) - 1; /* skip at 06 to 22 */
1847 gpr_map[gpr + 8] = 0x2000000 + (2<<11);
1848 gpr_map[gpr + 9] = 0x4000000 + (2<<11);
1849 gpr_map[gpr + 10] = 1<<11;
1850 gpr_map[gpr + 11] = (0x24 - 0x0a) - 1; /* skip at 0a to 24 */
1851 gpr_map[gpr + 12] = 0;
1853 /* if the trigger flag is not set, skip */
1854 /* 00: */ OP(icode, &ptr, iMAC0, C_00000000, GPR(ipcm->gpr_trigger), C_00000000, C_00000000);
1855 /* 01: */ OP(icode, &ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_ZERO, GPR(gpr + 6));
1856 /* if the running flag is set, we're running */
1857 /* 02: */ OP(icode, &ptr, iMAC0, C_00000000, GPR(ipcm->gpr_running), C_00000000, C_00000000);
1858 /* 03: */ OP(icode, &ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, C_00000004);
1859 /* wait until ((GPR_DBAC>>11) & 0x1f) == 0x1c) */
1860 /* 04: */ OP(icode, &ptr, iANDXOR, GPR(tmp + 0), GPR_DBAC, GPR(gpr + 4), C_00000000);
1861 /* 05: */ OP(icode, &ptr, iMACINT0, C_00000000, GPR(tmp + 0), C_ffffffff, GPR(gpr + 5));
1862 /* 06: */ OP(icode, &ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, GPR(gpr + 7));
1863 /* 07: */ OP(icode, &ptr, iACC3, GPR(gpr + 12), C_00000010, C_00000001, C_00000000);
1865 /* 08: */ OP(icode, &ptr, iANDXOR, GPR(ipcm->gpr_running), GPR(ipcm->gpr_running), C_00000000, C_00000001);
1866 /* 09: */ OP(icode, &ptr, iACC3, GPR(gpr + 12), GPR(gpr + 12), C_ffffffff, C_00000000);
1867 /* 0a: */ OP(icode, &ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, GPR(gpr + 11));
1868 /* 0b: */ OP(icode, &ptr, iACC3, GPR(gpr + 12), C_00000001, C_00000000, C_00000000);
1870 /* 0c: */ OP(icode, &ptr, iANDXOR, GPR(tmp + 0), ETRAM_DATA(ipcm->etram[0]), GPR(gpr + 0), C_00000000);
1871 /* 0d: */ OP(icode, &ptr, iLOG, GPR(tmp + 0), GPR(tmp + 0), GPR(gpr + 3), C_00000000);
1872 /* 0e: */ OP(icode, &ptr, iANDXOR, GPR(8), GPR(tmp + 0), GPR(gpr + 1), GPR(gpr + 2));
1873 /* 0f: */ OP(icode, &ptr, iSKIP, C_00000000, GPR_COND, CC_REG_MINUS, C_00000001);
1874 /* 10: */ OP(icode, &ptr, iANDXOR, GPR(8), GPR(8), GPR(gpr + 1), GPR(gpr + 2));
1876 /* 11: */ OP(icode, &ptr, iANDXOR, GPR(tmp + 0), ETRAM_DATA(ipcm->etram[1]), GPR(gpr + 0), C_00000000);
1877 /* 12: */ OP(icode, &ptr, iLOG, GPR(tmp + 0), GPR(tmp + 0), GPR(gpr + 3), C_00000000);
1878 /* 13: */ OP(icode, &ptr, iANDXOR, GPR(9), GPR(tmp + 0), GPR(gpr + 1), GPR(gpr + 2));
1879 /* 14: */ OP(icode, &ptr, iSKIP, C_00000000, GPR_COND, CC_REG_MINUS, C_00000001);
1880 /* 15: */ OP(icode, &ptr, iANDXOR, GPR(9), GPR(9), GPR(gpr + 1), GPR(gpr + 2));
1882 /* 16: */ OP(icode, &ptr, iACC3, GPR(tmp + 0), GPR(ipcm->gpr_ptr), C_00000001, C_00000000);
1883 /* 17: */ OP(icode, &ptr, iMACINT0, C_00000000, GPR(tmp + 0), C_ffffffff, GPR(ipcm->gpr_size));
1884 /* 18: */ OP(icode, &ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_MINUS, C_00000001);
1885 /* 19: */ OP(icode, &ptr, iACC3, GPR(tmp + 0), C_00000000, C_00000000, C_00000000);
1886 /* 1a: */ OP(icode, &ptr, iACC3, GPR(ipcm->gpr_ptr), GPR(tmp + 0), C_00000000, C_00000000);
1888 /* 1b: */ OP(icode, &ptr, iACC3, GPR(ipcm->gpr_tmpcount), GPR(ipcm->gpr_tmpcount), C_ffffffff, C_00000000);
1889 /* 1c: */ OP(icode, &ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, C_00000002);
1890 /* 1d: */ OP(icode, &ptr, iACC3, GPR(ipcm->gpr_tmpcount), GPR(ipcm->gpr_count), C_00000000, C_00000000);
1891 /* 1e: */ OP(icode, &ptr, iACC3, GPR_IRQ, C_80000000, C_00000000, C_00000000);
1892 /* 1f: */ OP(icode, &ptr, iANDXOR, GPR(ipcm->gpr_running), GPR(ipcm->gpr_running), C_00000001, C_00010000);
1894 /* 20: */ OP(icode, &ptr, iANDXOR, GPR(ipcm->gpr_running), GPR(ipcm->gpr_running), C_00010000, C_00000001);
1895 /* 21: */ OP(icode, &ptr, iSKIP, C_00000000, C_7fffffff, C_7fffffff, C_00000002);
1897 /* 22: */ OP(icode, &ptr, iMACINT1, ETRAM_ADDR(ipcm->etram[0]), GPR(gpr + 8), GPR_DBAC, C_ffffffff);
1898 /* 23: */ OP(icode, &ptr, iMACINT1, ETRAM_ADDR(ipcm->etram[1]), GPR(gpr + 9), GPR_DBAC, C_ffffffff);
1903 /* Wave Playback Volume */
1904 for (z = 0; z < 2; z++)
1905 VOLUME(icode, &ptr, playback + z, z, gpr + z);
1906 snd_emu10k1_init_stereo_control(controls + i++, "Wave Playback Volume", gpr, 100);
1909 /* Wave Surround Playback Volume */
1910 for (z = 0; z < 2; z++)
1911 VOLUME(icode, &ptr, playback + 2 + z, z, gpr + z);
1912 snd_emu10k1_init_stereo_control(controls + i++, "Wave Surround Playback Volume", gpr, 0);
1915 /* Wave Center/LFE Playback Volume */
1916 OP(icode, &ptr, iACC3, GPR(tmp + 0), FXBUS(FXBUS_PCM_LEFT), FXBUS(FXBUS_PCM_RIGHT), C_00000000);
1917 OP(icode, &ptr, iMACINT0, GPR(tmp + 0), C_00000000, GPR(tmp + 0), C_00000002);
1918 VOLUME(icode, &ptr, playback + 4, tmp + 0, gpr);
1919 snd_emu10k1_init_mono_control(controls + i++, "Wave Center Playback Volume", gpr++, 0);
1920 VOLUME(icode, &ptr, playback + 5, tmp + 0, gpr);
1921 snd_emu10k1_init_mono_control(controls + i++, "Wave LFE Playback Volume", gpr++, 0);
1923 /* Wave Capture Volume + Switch */
1924 for (z = 0; z < 2; z++) {
1925 SWITCH(icode, &ptr, tmp + 0, z, gpr + 2 + z);
1926 VOLUME(icode, &ptr, capture + z, tmp + 0, gpr + z);
1928 snd_emu10k1_init_stereo_control(controls + i++, "Wave Capture Volume", gpr, 0);
1929 snd_emu10k1_init_stereo_onoff_control(controls + i++, "Wave Capture Switch", gpr + 2, 0);
1932 /* Synth Playback Volume */
1933 for (z = 0; z < 2; z++)
1934 VOLUME_ADD(icode, &ptr, playback + z, 2 + z, gpr + z);
1935 snd_emu10k1_init_stereo_control(controls + i++, "Synth Playback Volume", gpr, 100);
1938 /* Synth Capture Volume + Switch */
1939 for (z = 0; z < 2; z++) {
1940 SWITCH(icode, &ptr, tmp + 0, 2 + z, gpr + 2 + z);
1941 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
1943 snd_emu10k1_init_stereo_control(controls + i++, "Synth Capture Volume", gpr, 0);
1944 snd_emu10k1_init_stereo_onoff_control(controls + i++, "Synth Capture Switch", gpr + 2, 0);
1947 /* Surround Digital Playback Volume (renamed later without Digital) */
1948 for (z = 0; z < 2; z++)
1949 VOLUME_ADD(icode, &ptr, playback + 2 + z, 4 + z, gpr + z);
1950 snd_emu10k1_init_stereo_control(controls + i++, "Surround Digital Playback Volume", gpr, 100);
1953 /* Surround Capture Volume + Switch */
1954 for (z = 0; z < 2; z++) {
1955 SWITCH(icode, &ptr, tmp + 0, 4 + z, gpr + 2 + z);
1956 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
1958 snd_emu10k1_init_stereo_control(controls + i++, "Surround Capture Volume", gpr, 0);
1959 snd_emu10k1_init_stereo_onoff_control(controls + i++, "Surround Capture Switch", gpr + 2, 0);
1962 /* Center Playback Volume (renamed later without Digital) */
1963 VOLUME_ADD(icode, &ptr, playback + 4, 6, gpr);
1964 snd_emu10k1_init_mono_control(controls + i++, "Center Digital Playback Volume", gpr++, 100);
1966 /* LFE Playback Volume + Switch (renamed later without Digital) */
1967 VOLUME_ADD(icode, &ptr, playback + 5, 7, gpr);
1968 snd_emu10k1_init_mono_control(controls + i++, "LFE Digital Playback Volume", gpr++, 100);
1970 /* Front Playback Volume */
1971 for (z = 0; z < 2; z++)
1972 VOLUME_ADD(icode, &ptr, playback + z, 10 + z, gpr + z);
1973 snd_emu10k1_init_stereo_control(controls + i++, "Front Playback Volume", gpr, 100);
1976 /* Front Capture Volume + Switch */
1977 for (z = 0; z < 2; z++) {
1978 SWITCH(icode, &ptr, tmp + 0, 10 + z, gpr + 2);
1979 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
1981 snd_emu10k1_init_stereo_control(controls + i++, "Front Capture Volume", gpr, 0);
1982 snd_emu10k1_init_mono_onoff_control(controls + i++, "Front Capture Switch", gpr + 2, 0);
1989 if (emu->fx8010.extin_mask & ((1<<EXTIN_AC97_L)|(1<<EXTIN_AC97_R))) {
1990 /* AC'97 Playback Volume */
1991 VOLUME_ADDIN(icode, &ptr, playback + 0, EXTIN_AC97_L, gpr); gpr++;
1992 VOLUME_ADDIN(icode, &ptr, playback + 1, EXTIN_AC97_R, gpr); gpr++;
1993 snd_emu10k1_init_stereo_control(controls + i++, "AC97 Playback Volume", gpr-2, 0);
1994 /* AC'97 Capture Volume */
1995 VOLUME_ADDIN(icode, &ptr, capture + 0, EXTIN_AC97_L, gpr); gpr++;
1996 VOLUME_ADDIN(icode, &ptr, capture + 1, EXTIN_AC97_R, gpr); gpr++;
1997 snd_emu10k1_init_stereo_control(controls + i++, "AC97 Capture Volume", gpr-2, 100);
2000 if (emu->fx8010.extin_mask & ((1<<EXTIN_SPDIF_CD_L)|(1<<EXTIN_SPDIF_CD_R))) {
2001 /* IEC958 TTL Playback Volume */
2002 for (z = 0; z < 2; z++)
2003 VOLUME_ADDIN(icode, &ptr, playback + z, EXTIN_SPDIF_CD_L + z, gpr + z);
2004 snd_emu10k1_init_stereo_control(controls + i++, SNDRV_CTL_NAME_IEC958("TTL ",PLAYBACK,VOLUME), gpr, 0);
2007 /* IEC958 TTL Capture Volume + Switch */
2008 for (z = 0; z < 2; z++) {
2009 SWITCH_IN(icode, &ptr, tmp + 0, EXTIN_SPDIF_CD_L + z, gpr + 2 + z);
2010 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
2012 snd_emu10k1_init_stereo_control(controls + i++, SNDRV_CTL_NAME_IEC958("TTL ",CAPTURE,VOLUME), gpr, 0);
2013 snd_emu10k1_init_stereo_onoff_control(controls + i++, SNDRV_CTL_NAME_IEC958("TTL ",CAPTURE,SWITCH), gpr + 2, 0);
2017 if (emu->fx8010.extin_mask & ((1<<EXTIN_ZOOM_L)|(1<<EXTIN_ZOOM_R))) {
2018 /* Zoom Video Playback Volume */
2019 for (z = 0; z < 2; z++)
2020 VOLUME_ADDIN(icode, &ptr, playback + z, EXTIN_ZOOM_L + z, gpr + z);
2021 snd_emu10k1_init_stereo_control(controls + i++, "Zoom Video Playback Volume", gpr, 0);
2024 /* Zoom Video Capture Volume + Switch */
2025 for (z = 0; z < 2; z++) {
2026 SWITCH_IN(icode, &ptr, tmp + 0, EXTIN_ZOOM_L + z, gpr + 2 + z);
2027 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
2029 snd_emu10k1_init_stereo_control(controls + i++, "Zoom Video Capture Volume", gpr, 0);
2030 snd_emu10k1_init_stereo_onoff_control(controls + i++, "Zoom Video Capture Switch", gpr + 2, 0);
2034 if (emu->fx8010.extin_mask & ((1<<EXTIN_TOSLINK_L)|(1<<EXTIN_TOSLINK_R))) {
2035 /* IEC958 Optical Playback Volume */
2036 for (z = 0; z < 2; z++)
2037 VOLUME_ADDIN(icode, &ptr, playback + z, EXTIN_TOSLINK_L + z, gpr + z);
2038 snd_emu10k1_init_stereo_control(controls + i++, SNDRV_CTL_NAME_IEC958("LiveDrive ",PLAYBACK,VOLUME), gpr, 0);
2041 /* IEC958 Optical Capture Volume */
2042 for (z = 0; z < 2; z++) {
2043 SWITCH_IN(icode, &ptr, tmp + 0, EXTIN_TOSLINK_L + z, gpr + 2 + z);
2044 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
2046 snd_emu10k1_init_stereo_control(controls + i++, SNDRV_CTL_NAME_IEC958("LiveDrive ",CAPTURE,VOLUME), gpr, 0);
2047 snd_emu10k1_init_stereo_onoff_control(controls + i++, SNDRV_CTL_NAME_IEC958("LiveDrive ",CAPTURE,SWITCH), gpr + 2, 0);
2051 if (emu->fx8010.extin_mask & ((1<<EXTIN_LINE1_L)|(1<<EXTIN_LINE1_R))) {
2052 /* Line LiveDrive Playback Volume */
2053 for (z = 0; z < 2; z++)
2054 VOLUME_ADDIN(icode, &ptr, playback + z, EXTIN_LINE1_L + z, gpr + z);
2055 snd_emu10k1_init_stereo_control(controls + i++, "Line LiveDrive Playback Volume", gpr, 0);
2058 /* Line LiveDrive Capture Volume + Switch */
2059 for (z = 0; z < 2; z++) {
2060 SWITCH_IN(icode, &ptr, tmp + 0, EXTIN_LINE1_L + z, gpr + 2 + z);
2061 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
2063 snd_emu10k1_init_stereo_control(controls + i++, "Line LiveDrive Capture Volume", gpr, 0);
2064 snd_emu10k1_init_stereo_onoff_control(controls + i++, "Line LiveDrive Capture Switch", gpr + 2, 0);
2068 if (emu->fx8010.extin_mask & ((1<<EXTIN_COAX_SPDIF_L)|(1<<EXTIN_COAX_SPDIF_R))) {
2069 /* IEC958 Coax Playback Volume */
2070 for (z = 0; z < 2; z++)
2071 VOLUME_ADDIN(icode, &ptr, playback + z, EXTIN_COAX_SPDIF_L + z, gpr + z);
2072 snd_emu10k1_init_stereo_control(controls + i++, SNDRV_CTL_NAME_IEC958("Coaxial ",PLAYBACK,VOLUME), gpr, 0);
2075 /* IEC958 Coax Capture Volume + Switch */
2076 for (z = 0; z < 2; z++) {
2077 SWITCH_IN(icode, &ptr, tmp + 0, EXTIN_COAX_SPDIF_L + z, gpr + 2 + z);
2078 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
2080 snd_emu10k1_init_stereo_control(controls + i++, SNDRV_CTL_NAME_IEC958("Coaxial ",CAPTURE,VOLUME), gpr, 0);
2081 snd_emu10k1_init_stereo_onoff_control(controls + i++, SNDRV_CTL_NAME_IEC958("Coaxial ",CAPTURE,SWITCH), gpr + 2, 0);
2085 if (emu->fx8010.extin_mask & ((1<<EXTIN_LINE2_L)|(1<<EXTIN_LINE2_R))) {
2086 /* Line LiveDrive Playback Volume */
2087 for (z = 0; z < 2; z++)
2088 VOLUME_ADDIN(icode, &ptr, playback + z, EXTIN_LINE2_L + z, gpr + z);
2089 snd_emu10k1_init_stereo_control(controls + i++, "Line2 LiveDrive Playback Volume", gpr, 0);
2090 controls[i-1].id.index = 1;
2093 /* Line LiveDrive Capture Volume */
2094 for (z = 0; z < 2; z++) {
2095 SWITCH_IN(icode, &ptr, tmp + 0, EXTIN_LINE2_L + z, gpr + 2 + z);
2096 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
2098 snd_emu10k1_init_stereo_control(controls + i++, "Line2 LiveDrive Capture Volume", gpr, 0);
2099 controls[i-1].id.index = 1;
2100 snd_emu10k1_init_stereo_onoff_control(controls + i++, "Line2 LiveDrive Capture Switch", gpr + 2, 0);
2101 controls[i-1].id.index = 1;
2106 * Process tone control
2108 OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 0), GPR(playback + 0), C_00000000, C_00000000); /* left */
2109 OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 1), GPR(playback + 1), C_00000000, C_00000000); /* right */
2110 OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 2), GPR(playback + 2), C_00000000, C_00000000); /* rear left */
2111 OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 3), GPR(playback + 3), C_00000000, C_00000000); /* rear right */
2112 OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 4), GPR(playback + 4), C_00000000, C_00000000); /* center */
2113 OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 5), GPR(playback + 5), C_00000000, C_00000000); /* LFE */
2115 ctl = &controls[i + 0];
2116 ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
2117 strcpy(ctl->id.name, "Tone Control - Bass");
2122 ctl->value[0] = ctl->value[1] = 20;
2123 ctl->tlv = snd_emu10k1_bass_treble_db_scale;
2124 ctl->translation = EMU10K1_GPR_TRANSLATION_BASS;
2125 ctl = &controls[i + 1];
2126 ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
2127 strcpy(ctl->id.name, "Tone Control - Treble");
2132 ctl->value[0] = ctl->value[1] = 20;
2133 ctl->tlv = snd_emu10k1_bass_treble_db_scale;
2134 ctl->translation = EMU10K1_GPR_TRANSLATION_TREBLE;
2136 #define BASS_GPR 0x8c
2137 #define TREBLE_GPR 0x96
2139 for (z = 0; z < 5; z++) {
2141 for (j = 0; j < 2; j++) {
2142 controls[i + 0].gpr[z * 2 + j] = BASS_GPR + z * 2 + j;
2143 controls[i + 1].gpr[z * 2 + j] = TREBLE_GPR + z * 2 + j;
2146 for (z = 0; z < 3; z++) { /* front/rear/center-lfe */
2148 for (j = 0; j < 2; j++) { /* left/right */
2149 k = 0xa0 + (z * 8) + (j * 4);
2150 l = 0xd0 + (z * 8) + (j * 4);
2151 d = playback + SND_EMU10K1_PLAYBACK_CHANNELS + z * 2 + j;
2153 OP(icode, &ptr, iMAC0, C_00000000, C_00000000, GPR(d), GPR(BASS_GPR + 0 + j));
2154 OP(icode, &ptr, iMACMV, GPR(k+1), GPR(k), GPR(k+1), GPR(BASS_GPR + 4 + j));
2155 OP(icode, &ptr, iMACMV, GPR(k), GPR(d), GPR(k), GPR(BASS_GPR + 2 + j));
2156 OP(icode, &ptr, iMACMV, GPR(k+3), GPR(k+2), GPR(k+3), GPR(BASS_GPR + 8 + j));
2157 OP(icode, &ptr, iMAC0, GPR(k+2), GPR_ACCU, GPR(k+2), GPR(BASS_GPR + 6 + j));
2158 OP(icode, &ptr, iACC3, GPR(k+2), GPR(k+2), GPR(k+2), C_00000000);
2160 OP(icode, &ptr, iMAC0, C_00000000, C_00000000, GPR(k+2), GPR(TREBLE_GPR + 0 + j));
2161 OP(icode, &ptr, iMACMV, GPR(l+1), GPR(l), GPR(l+1), GPR(TREBLE_GPR + 4 + j));
2162 OP(icode, &ptr, iMACMV, GPR(l), GPR(k+2), GPR(l), GPR(TREBLE_GPR + 2 + j));
2163 OP(icode, &ptr, iMACMV, GPR(l+3), GPR(l+2), GPR(l+3), GPR(TREBLE_GPR + 8 + j));
2164 OP(icode, &ptr, iMAC0, GPR(l+2), GPR_ACCU, GPR(l+2), GPR(TREBLE_GPR + 6 + j));
2165 OP(icode, &ptr, iMACINT0, GPR(l+2), C_00000000, GPR(l+2), C_00000010);
2167 OP(icode, &ptr, iACC3, GPR(d), GPR(l+2), C_00000000, C_00000000);
2169 if (z == 2) /* center */
2178 for (z = 0; z < 6; z++) {
2179 SWITCH(icode, &ptr, tmp + 0, playback + SND_EMU10K1_PLAYBACK_CHANNELS + z, gpr + 0);
2180 SWITCH_NEG(icode, &ptr, tmp + 1, gpr + 0);
2181 SWITCH(icode, &ptr, tmp + 1, playback + z, tmp + 1);
2182 OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + z), GPR(tmp + 0), GPR(tmp + 1), C_00000000);
2184 snd_emu10k1_init_stereo_onoff_control(controls + i++, "Tone Control - Switch", gpr, 0);
2190 if (emu->fx8010.extout_mask & ((1<<EXTOUT_AC97_L)|(1<<EXTOUT_AC97_R))) {
2191 /* AC'97 Playback Volume */
2193 for (z = 0; z < 2; z++)
2194 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_AC97_L + z), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + z), C_00000000, C_00000000);
2197 if (emu->fx8010.extout_mask & ((1<<EXTOUT_TOSLINK_L)|(1<<EXTOUT_TOSLINK_R))) {
2198 /* IEC958 Optical Raw Playback Switch */
2200 for (z = 0; z < 2; z++) {
2201 SWITCH(icode, &ptr, tmp + 0, 8 + z, gpr + z);
2202 SWITCH_NEG(icode, &ptr, tmp + 1, gpr + z);
2203 SWITCH(icode, &ptr, tmp + 1, playback + SND_EMU10K1_PLAYBACK_CHANNELS + z, tmp + 1);
2204 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_TOSLINK_L + z), GPR(tmp + 0), GPR(tmp + 1), C_00000000);
2205 #ifdef EMU10K1_CAPTURE_DIGITAL_OUT
2206 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_ADC_CAP_L + z), GPR(tmp + 0), GPR(tmp + 1), C_00000000);
2210 snd_emu10k1_init_stereo_onoff_control(controls + i++, SNDRV_CTL_NAME_IEC958("Optical Raw ",PLAYBACK,SWITCH), gpr, 0);
2214 if (emu->fx8010.extout_mask & ((1<<EXTOUT_HEADPHONE_L)|(1<<EXTOUT_HEADPHONE_R))) {
2215 /* Headphone Playback Volume */
2217 for (z = 0; z < 2; z++) {
2218 SWITCH(icode, &ptr, tmp + 0, playback + SND_EMU10K1_PLAYBACK_CHANNELS + 4 + z, gpr + 2 + z);
2219 SWITCH_NEG(icode, &ptr, tmp + 1, gpr + 2 + z);
2220 SWITCH(icode, &ptr, tmp + 1, playback + SND_EMU10K1_PLAYBACK_CHANNELS + z, tmp + 1);
2221 OP(icode, &ptr, iACC3, GPR(tmp + 0), GPR(tmp + 0), GPR(tmp + 1), C_00000000);
2222 VOLUME_OUT(icode, &ptr, EXTOUT_HEADPHONE_L + z, tmp + 0, gpr + z);
2225 snd_emu10k1_init_stereo_control(controls + i++, "Headphone Playback Volume", gpr + 0, 0);
2226 controls[i-1].id.index = 1; /* AC'97 can have also Headphone control */
2227 snd_emu10k1_init_mono_onoff_control(controls + i++, "Headphone Center Playback Switch", gpr + 2, 0);
2228 controls[i-1].id.index = 1;
2229 snd_emu10k1_init_mono_onoff_control(controls + i++, "Headphone LFE Playback Switch", gpr + 3, 0);
2230 controls[i-1].id.index = 1;
2235 if (emu->fx8010.extout_mask & ((1<<EXTOUT_REAR_L)|(1<<EXTOUT_REAR_R)))
2236 for (z = 0; z < 2; z++)
2237 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_REAR_L + z), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 2 + z), C_00000000, C_00000000);
2239 if (emu->fx8010.extout_mask & ((1<<EXTOUT_AC97_REAR_L)|(1<<EXTOUT_AC97_REAR_R)))
2240 for (z = 0; z < 2; z++)
2241 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_AC97_REAR_L + z), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 2 + z), C_00000000, C_00000000);
2243 if (emu->fx8010.extout_mask & (1<<EXTOUT_AC97_CENTER)) {
2244 #ifndef EMU10K1_CENTER_LFE_FROM_FRONT
2245 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_AC97_CENTER), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 4), C_00000000, C_00000000);
2246 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_ACENTER), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 4), C_00000000, C_00000000);
2248 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_AC97_CENTER), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 0), C_00000000, C_00000000);
2249 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_ACENTER), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 0), C_00000000, C_00000000);
2253 if (emu->fx8010.extout_mask & (1<<EXTOUT_AC97_LFE)) {
2254 #ifndef EMU10K1_CENTER_LFE_FROM_FRONT
2255 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_AC97_LFE), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 5), C_00000000, C_00000000);
2256 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_ALFE), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 5), C_00000000, C_00000000);
2258 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_AC97_LFE), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 1), C_00000000, C_00000000);
2259 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_ALFE), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 1), C_00000000, C_00000000);
2263 #ifndef EMU10K1_CAPTURE_DIGITAL_OUT
2264 for (z = 0; z < 2; z++)
2265 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_ADC_CAP_L + z), GPR(capture + z), C_00000000, C_00000000);
2268 if (emu->fx8010.extout_mask & (1<<EXTOUT_MIC_CAP))
2269 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_MIC_CAP), GPR(capture + 2), C_00000000, C_00000000);
2271 /* EFX capture - capture the 16 EXTINS */
2272 if (emu->card_capabilities->sblive51) {
2273 /* On the Live! 5.1, FXBUS2(1) and FXBUS(2) are shared with EXTOUT_ACENTER
2274 * and EXTOUT_ALFE, so we can't connect inputs to them for multitrack recording.
2276 * Since only 14 of the 16 EXTINs are used, this is not a big problem.
2277 * We route AC97L and R to FX capture 14 and 15, SPDIF CD in to FX capture
2278 * 0 and 3, then the rest of the EXTINs to the corresponding FX capture
2279 * channel. Multitrack recorders will still see the center/lfe output signal
2280 * on the second and third channels.
2282 OP(icode, &ptr, iACC3, FXBUS2(14), C_00000000, C_00000000, EXTIN(0));
2283 OP(icode, &ptr, iACC3, FXBUS2(15), C_00000000, C_00000000, EXTIN(1));
2284 OP(icode, &ptr, iACC3, FXBUS2(0), C_00000000, C_00000000, EXTIN(2));
2285 OP(icode, &ptr, iACC3, FXBUS2(3), C_00000000, C_00000000, EXTIN(3));
2286 for (z = 4; z < 14; z++)
2287 OP(icode, &ptr, iACC3, FXBUS2(z), C_00000000, C_00000000, EXTIN(z));
2289 for (z = 0; z < 16; z++)
2290 OP(icode, &ptr, iACC3, FXBUS2(z), C_00000000, C_00000000, EXTIN(z));
2299 if (i > SND_EMU10K1_GPR_CONTROLS) {
2305 /* clear remaining instruction memory */
2307 OP(icode, &ptr, iACC3, C_00000000, C_00000000, C_00000000, C_00000000);
2309 if ((err = snd_emu10k1_fx8010_tram_setup(emu, ipcm->buffer_size)) < 0)
2311 icode->gpr_add_control_count = i;
2312 icode->gpr_add_controls = (struct snd_emu10k1_fx8010_control_gpr __user *)controls;
2313 emu->support_tlv = 1; /* support TLV */
2314 err = snd_emu10k1_icode_poke(emu, icode, true);
2315 emu->support_tlv = 0; /* clear again */
2317 err = snd_emu10k1_ipcm_poke(emu, ipcm);
2323 kfree((void __force *)icode->gpr_map);
2329 int snd_emu10k1_init_efx(struct snd_emu10k1 *emu)
2331 spin_lock_init(&emu->fx8010.irq_lock);
2332 INIT_LIST_HEAD(&emu->fx8010.gpr_ctl);
2334 return _snd_emu10k1_audigy_init_efx(emu);
2336 return _snd_emu10k1_init_efx(emu);
2339 void snd_emu10k1_free_efx(struct snd_emu10k1 *emu)
2341 /* stop processor */
2343 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg = A_DBG_SINGLE_STEP);
2345 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg = EMU10K1_DBG_SINGLE_STEP);
2348 #if 0 /* FIXME: who use them? */
2349 int snd_emu10k1_fx8010_tone_control_activate(struct snd_emu10k1 *emu, int output)
2351 if (output < 0 || output >= 6)
2353 snd_emu10k1_ptr_write(emu, emu->gpr_base + 0x94 + output, 0, 1);
2357 int snd_emu10k1_fx8010_tone_control_deactivate(struct snd_emu10k1 *emu, int output)
2359 if (output < 0 || output >= 6)
2361 snd_emu10k1_ptr_write(emu, emu->gpr_base + 0x94 + output, 0, 0);
2366 int snd_emu10k1_fx8010_tram_setup(struct snd_emu10k1 *emu, u32 size)
2370 /* size is in samples */
2372 size = (size - 1) >> 13;
2378 size = 0x2000 << size_reg;
2380 if ((emu->fx8010.etram_pages.bytes / 2) == size)
2382 spin_lock_irq(&emu->emu_lock);
2383 outl(HCFG_LOCKTANKCACHE_MASK | inl(emu->port + HCFG), emu->port + HCFG);
2384 spin_unlock_irq(&emu->emu_lock);
2385 snd_emu10k1_ptr_write(emu, TCB, 0, 0);
2386 snd_emu10k1_ptr_write(emu, TCBS, 0, 0);
2387 if (emu->fx8010.etram_pages.area != NULL) {
2388 snd_dma_free_pages(&emu->fx8010.etram_pages);
2389 emu->fx8010.etram_pages.area = NULL;
2390 emu->fx8010.etram_pages.bytes = 0;
2394 if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(emu->pci),
2395 size * 2, &emu->fx8010.etram_pages) < 0)
2397 memset(emu->fx8010.etram_pages.area, 0, size * 2);
2398 snd_emu10k1_ptr_write(emu, TCB, 0, emu->fx8010.etram_pages.addr);
2399 snd_emu10k1_ptr_write(emu, TCBS, 0, size_reg);
2400 spin_lock_irq(&emu->emu_lock);
2401 outl(inl(emu->port + HCFG) & ~HCFG_LOCKTANKCACHE_MASK, emu->port + HCFG);
2402 spin_unlock_irq(&emu->emu_lock);
2408 static int snd_emu10k1_fx8010_open(struct snd_hwdep * hw, struct file *file)
2413 static void copy_string(char *dst, char *src, char *null, int idx)
2416 sprintf(dst, "%s %02X", null, idx);
2421 static void snd_emu10k1_fx8010_info(struct snd_emu10k1 *emu,
2422 struct snd_emu10k1_fx8010_info *info)
2424 char **fxbus, **extin, **extout;
2425 unsigned short fxbus_mask, extin_mask, extout_mask;
2428 info->internal_tram_size = emu->fx8010.itram_size;
2429 info->external_tram_size = emu->fx8010.etram_pages.bytes / 2;
2431 extin = emu->audigy ? audigy_ins : creative_ins;
2432 extout = emu->audigy ? audigy_outs : creative_outs;
2433 fxbus_mask = emu->fx8010.fxbus_mask;
2434 extin_mask = emu->fx8010.extin_mask;
2435 extout_mask = emu->fx8010.extout_mask;
2436 for (res = 0; res < 16; res++, fxbus++, extin++, extout++) {
2437 copy_string(info->fxbus_names[res], fxbus_mask & (1 << res) ? *fxbus : NULL, "FXBUS", res);
2438 copy_string(info->extin_names[res], extin_mask & (1 << res) ? *extin : NULL, "Unused", res);
2439 copy_string(info->extout_names[res], extout_mask & (1 << res) ? *extout : NULL, "Unused", res);
2441 for (res = 16; res < 32; res++, extout++)
2442 copy_string(info->extout_names[res], extout_mask & (1 << res) ? *extout : NULL, "Unused", res);
2443 info->gpr_controls = emu->fx8010.gpr_count;
2446 static int snd_emu10k1_fx8010_ioctl(struct snd_hwdep * hw, struct file *file, unsigned int cmd, unsigned long arg)
2448 struct snd_emu10k1 *emu = hw->private_data;
2449 struct snd_emu10k1_fx8010_info *info;
2450 struct snd_emu10k1_fx8010_code *icode;
2451 struct snd_emu10k1_fx8010_pcm_rec *ipcm;
2453 void __user *argp = (void __user *)arg;
2457 case SNDRV_EMU10K1_IOCTL_PVERSION:
2458 emu->support_tlv = 1;
2459 return put_user(SNDRV_EMU10K1_VERSION, (int __user *)argp);
2460 case SNDRV_EMU10K1_IOCTL_INFO:
2461 info = kzalloc(sizeof(*info), GFP_KERNEL);
2464 snd_emu10k1_fx8010_info(emu, info);
2465 if (copy_to_user(argp, info, sizeof(*info))) {
2471 case SNDRV_EMU10K1_IOCTL_CODE_POKE:
2472 if (!capable(CAP_SYS_ADMIN))
2475 icode = memdup_user(argp, sizeof(*icode));
2477 return PTR_ERR(icode);
2478 res = snd_emu10k1_icode_poke(emu, icode, false);
2481 case SNDRV_EMU10K1_IOCTL_CODE_PEEK:
2482 icode = memdup_user(argp, sizeof(*icode));
2484 return PTR_ERR(icode);
2485 res = snd_emu10k1_icode_peek(emu, icode);
2486 if (res == 0 && copy_to_user(argp, icode, sizeof(*icode))) {
2492 case SNDRV_EMU10K1_IOCTL_PCM_POKE:
2493 ipcm = memdup_user(argp, sizeof(*ipcm));
2495 return PTR_ERR(ipcm);
2496 res = snd_emu10k1_ipcm_poke(emu, ipcm);
2499 case SNDRV_EMU10K1_IOCTL_PCM_PEEK:
2500 ipcm = memdup_user(argp, sizeof(*ipcm));
2502 return PTR_ERR(ipcm);
2503 res = snd_emu10k1_ipcm_peek(emu, ipcm);
2504 if (res == 0 && copy_to_user(argp, ipcm, sizeof(*ipcm))) {
2510 case SNDRV_EMU10K1_IOCTL_TRAM_SETUP:
2511 if (!capable(CAP_SYS_ADMIN))
2513 if (get_user(addr, (unsigned int __user *)argp))
2515 mutex_lock(&emu->fx8010.lock);
2516 res = snd_emu10k1_fx8010_tram_setup(emu, addr);
2517 mutex_unlock(&emu->fx8010.lock);
2519 case SNDRV_EMU10K1_IOCTL_STOP:
2520 if (!capable(CAP_SYS_ADMIN))
2523 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg |= A_DBG_SINGLE_STEP);
2525 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg |= EMU10K1_DBG_SINGLE_STEP);
2527 case SNDRV_EMU10K1_IOCTL_CONTINUE:
2528 if (!capable(CAP_SYS_ADMIN))
2531 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg = 0);
2533 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg = 0);
2535 case SNDRV_EMU10K1_IOCTL_ZERO_TRAM_COUNTER:
2536 if (!capable(CAP_SYS_ADMIN))
2539 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg | A_DBG_ZC);
2541 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg | EMU10K1_DBG_ZC);
2544 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg);
2546 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg);
2548 case SNDRV_EMU10K1_IOCTL_SINGLE_STEP:
2549 if (!capable(CAP_SYS_ADMIN))
2551 if (get_user(addr, (unsigned int __user *)argp))
2556 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg |= A_DBG_SINGLE_STEP | addr);
2558 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg |= EMU10K1_DBG_SINGLE_STEP | addr);
2561 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg |= A_DBG_SINGLE_STEP | A_DBG_STEP_ADDR | addr);
2563 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg |= EMU10K1_DBG_SINGLE_STEP | EMU10K1_DBG_STEP | addr);
2565 case SNDRV_EMU10K1_IOCTL_DBG_READ:
2567 addr = snd_emu10k1_ptr_read(emu, A_DBG, 0);
2569 addr = snd_emu10k1_ptr_read(emu, DBG, 0);
2570 if (put_user(addr, (unsigned int __user *)argp))
2577 static int snd_emu10k1_fx8010_release(struct snd_hwdep * hw, struct file *file)
2582 int snd_emu10k1_fx8010_new(struct snd_emu10k1 *emu, int device)
2584 struct snd_hwdep *hw;
2587 if ((err = snd_hwdep_new(emu->card, "FX8010", device, &hw)) < 0)
2589 strcpy(hw->name, "EMU10K1 (FX8010)");
2590 hw->iface = SNDRV_HWDEP_IFACE_EMU10K1;
2591 hw->ops.open = snd_emu10k1_fx8010_open;
2592 hw->ops.ioctl = snd_emu10k1_fx8010_ioctl;
2593 hw->ops.release = snd_emu10k1_fx8010_release;
2594 hw->private_data = emu;
2598 #ifdef CONFIG_PM_SLEEP
2599 int snd_emu10k1_efx_alloc_pm_buffer(struct snd_emu10k1 *emu)
2603 len = emu->audigy ? 0x200 : 0x100;
2604 emu->saved_gpr = kmalloc(len * 4, GFP_KERNEL);
2605 if (! emu->saved_gpr)
2607 len = emu->audigy ? 0x100 : 0xa0;
2608 emu->tram_val_saved = kmalloc(len * 4, GFP_KERNEL);
2609 emu->tram_addr_saved = kmalloc(len * 4, GFP_KERNEL);
2610 if (! emu->tram_val_saved || ! emu->tram_addr_saved)
2612 len = emu->audigy ? 2 * 1024 : 2 * 512;
2613 emu->saved_icode = vmalloc(len * 4);
2614 if (! emu->saved_icode)
2619 void snd_emu10k1_efx_free_pm_buffer(struct snd_emu10k1 *emu)
2621 kfree(emu->saved_gpr);
2622 kfree(emu->tram_val_saved);
2623 kfree(emu->tram_addr_saved);
2624 vfree(emu->saved_icode);
2628 * save/restore GPR, TRAM and codes
2630 void snd_emu10k1_efx_suspend(struct snd_emu10k1 *emu)
2634 len = emu->audigy ? 0x200 : 0x100;
2635 for (i = 0; i < len; i++)
2636 emu->saved_gpr[i] = snd_emu10k1_ptr_read(emu, emu->gpr_base + i, 0);
2638 len = emu->audigy ? 0x100 : 0xa0;
2639 for (i = 0; i < len; i++) {
2640 emu->tram_val_saved[i] = snd_emu10k1_ptr_read(emu, TANKMEMDATAREGBASE + i, 0);
2641 emu->tram_addr_saved[i] = snd_emu10k1_ptr_read(emu, TANKMEMADDRREGBASE + i, 0);
2643 emu->tram_addr_saved[i] >>= 12;
2644 emu->tram_addr_saved[i] |=
2645 snd_emu10k1_ptr_read(emu, A_TANKMEMCTLREGBASE + i, 0) << 20;
2649 len = emu->audigy ? 2 * 1024 : 2 * 512;
2650 for (i = 0; i < len; i++)
2651 emu->saved_icode[i] = snd_emu10k1_efx_read(emu, i);
2654 void snd_emu10k1_efx_resume(struct snd_emu10k1 *emu)
2659 if (emu->fx8010.etram_pages.bytes > 0) {
2660 unsigned size, size_reg = 0;
2661 size = emu->fx8010.etram_pages.bytes / 2;
2662 size = (size - 1) >> 13;
2667 outl(HCFG_LOCKTANKCACHE_MASK | inl(emu->port + HCFG), emu->port + HCFG);
2668 snd_emu10k1_ptr_write(emu, TCB, 0, emu->fx8010.etram_pages.addr);
2669 snd_emu10k1_ptr_write(emu, TCBS, 0, size_reg);
2670 outl(inl(emu->port + HCFG) & ~HCFG_LOCKTANKCACHE_MASK, emu->port + HCFG);
2674 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg | A_DBG_SINGLE_STEP);
2676 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg | EMU10K1_DBG_SINGLE_STEP);
2678 len = emu->audigy ? 0x200 : 0x100;
2679 for (i = 0; i < len; i++)
2680 snd_emu10k1_ptr_write(emu, emu->gpr_base + i, 0, emu->saved_gpr[i]);
2682 len = emu->audigy ? 0x100 : 0xa0;
2683 for (i = 0; i < len; i++) {
2684 snd_emu10k1_ptr_write(emu, TANKMEMDATAREGBASE + i, 0,
2685 emu->tram_val_saved[i]);
2687 snd_emu10k1_ptr_write(emu, TANKMEMADDRREGBASE + i, 0,
2688 emu->tram_addr_saved[i]);
2690 snd_emu10k1_ptr_write(emu, TANKMEMADDRREGBASE + i, 0,
2691 emu->tram_addr_saved[i] << 12);
2692 snd_emu10k1_ptr_write(emu, TANKMEMADDRREGBASE + i, 0,
2693 emu->tram_addr_saved[i] >> 20);
2697 len = emu->audigy ? 2 * 1024 : 2 * 512;
2698 for (i = 0; i < len; i++)
2699 snd_emu10k1_efx_write(emu, i, emu->saved_icode[i]);
2701 /* start FX processor when the DSP code is updated */
2703 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg);
2705 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg);