2 * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
4 * Routines for effect processor FX8010
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28 #include <sound/driver.h>
29 #include <linux/pci.h>
30 #include <linux/delay.h>
31 #include <linux/slab.h>
32 #include <linux/init.h>
33 #include <sound/core.h>
34 #include <sound/emu10k1.h>
36 #if 0 /* for testing purposes - digital out -> capture */
37 #define EMU10K1_CAPTURE_DIGITAL_OUT
39 #if 0 /* for testing purposes - set S/PDIF to AC3 output */
40 #define EMU10K1_SET_AC3_IEC958
42 #if 0 /* for testing purposes - feed the front signal to Center/LFE outputs */
43 #define EMU10K1_CENTER_LFE_FROM_FRONT
50 static char *fxbuses[16] = {
51 /* 0x00 */ "PCM Left",
52 /* 0x01 */ "PCM Right",
53 /* 0x02 */ "PCM Surround Left",
54 /* 0x03 */ "PCM Surround Right",
55 /* 0x04 */ "MIDI Left",
56 /* 0x05 */ "MIDI Right",
63 /* 0x0c */ "MIDI Reverb",
64 /* 0x0d */ "MIDI Chorus",
69 static char *creative_ins[16] = {
70 /* 0x00 */ "AC97 Left",
71 /* 0x01 */ "AC97 Right",
72 /* 0x02 */ "TTL IEC958 Left",
73 /* 0x03 */ "TTL IEC958 Right",
74 /* 0x04 */ "Zoom Video Left",
75 /* 0x05 */ "Zoom Video Right",
76 /* 0x06 */ "Optical IEC958 Left",
77 /* 0x07 */ "Optical IEC958 Right",
78 /* 0x08 */ "Line/Mic 1 Left",
79 /* 0x09 */ "Line/Mic 1 Right",
80 /* 0x0a */ "Coaxial IEC958 Left",
81 /* 0x0b */ "Coaxial IEC958 Right",
82 /* 0x0c */ "Line/Mic 2 Left",
83 /* 0x0d */ "Line/Mic 2 Right",
88 static char *audigy_ins[16] = {
89 /* 0x00 */ "AC97 Left",
90 /* 0x01 */ "AC97 Right",
91 /* 0x02 */ "Audigy CD Left",
92 /* 0x03 */ "Audigy CD Right",
93 /* 0x04 */ "Optical IEC958 Left",
94 /* 0x05 */ "Optical IEC958 Right",
97 /* 0x08 */ "Line/Mic 2 Left",
98 /* 0x09 */ "Line/Mic 2 Right",
99 /* 0x0a */ "SPDIF Left",
100 /* 0x0b */ "SPDIF Right",
101 /* 0x0c */ "Aux2 Left",
102 /* 0x0d */ "Aux2 Right",
107 static char *creative_outs[32] = {
108 /* 0x00 */ "AC97 Left",
109 /* 0x01 */ "AC97 Right",
110 /* 0x02 */ "Optical IEC958 Left",
111 /* 0x03 */ "Optical IEC958 Right",
114 /* 0x06 */ "Headphone Left",
115 /* 0x07 */ "Headphone Right",
116 /* 0x08 */ "Surround Left",
117 /* 0x09 */ "Surround Right",
118 /* 0x0a */ "PCM Capture Left",
119 /* 0x0b */ "PCM Capture Right",
120 /* 0x0c */ "MIC Capture",
121 /* 0x0d */ "AC97 Surround Left",
122 /* 0x0e */ "AC97 Surround Right",
125 /* 0x11 */ "Analog Center",
126 /* 0x12 */ "Analog LFE",
142 static char *audigy_outs[32] = {
143 /* 0x00 */ "Digital Front Left",
144 /* 0x01 */ "Digital Front Right",
145 /* 0x02 */ "Digital Center",
146 /* 0x03 */ "Digital LEF",
147 /* 0x04 */ "Headphone Left",
148 /* 0x05 */ "Headphone Right",
149 /* 0x06 */ "Digital Rear Left",
150 /* 0x07 */ "Digital Rear Right",
151 /* 0x08 */ "Front Left",
152 /* 0x09 */ "Front Right",
157 /* 0x0e */ "Rear Left",
158 /* 0x0f */ "Rear Right",
159 /* 0x10 */ "AC97 Front Left",
160 /* 0x11 */ "AC97 Front Right",
161 /* 0x12 */ "ADC Caputre Left",
162 /* 0x13 */ "ADC Capture Right",
177 static const u32 bass_table[41][5] = {
178 { 0x3e4f844f, 0x84ed4cc3, 0x3cc69927, 0x7b03553a, 0xc4da8486 },
179 { 0x3e69a17a, 0x84c280fb, 0x3cd77cd4, 0x7b2f2a6f, 0xc4b08d1d },
180 { 0x3e82ff42, 0x849991d5, 0x3ce7466b, 0x7b5917c6, 0xc48863ee },
181 { 0x3e9bab3c, 0x847267f0, 0x3cf5ffe8, 0x7b813560, 0xc461f22c },
182 { 0x3eb3b275, 0x844ced29, 0x3d03b295, 0x7ba79a1c, 0xc43d223b },
183 { 0x3ecb2174, 0x84290c8b, 0x3d106714, 0x7bcc5ba3, 0xc419dfa5 },
184 { 0x3ee2044b, 0x8406b244, 0x3d1c2561, 0x7bef8e77, 0xc3f8170f },
185 { 0x3ef86698, 0x83e5cb96, 0x3d26f4d8, 0x7c114600, 0xc3d7b625 },
186 { 0x3f0e5390, 0x83c646c9, 0x3d30dc39, 0x7c319498, 0xc3b8ab97 },
187 { 0x3f23d60b, 0x83a81321, 0x3d39e1af, 0x7c508b9c, 0xc39ae704 },
188 { 0x3f38f884, 0x838b20d2, 0x3d420ad2, 0x7c6e3b75, 0xc37e58f1 },
189 { 0x3f4dc52c, 0x836f60ef, 0x3d495cab, 0x7c8ab3a6, 0xc362f2be },
190 { 0x3f6245e8, 0x8354c565, 0x3d4fdbb8, 0x7ca602d6, 0xc348a69b },
191 { 0x3f76845f, 0x833b40ec, 0x3d558bf0, 0x7cc036df, 0xc32f677c },
192 { 0x3f8a8a03, 0x8322c6fb, 0x3d5a70c4, 0x7cd95cd7, 0xc317290b },
193 { 0x3f9e6014, 0x830b4bc3, 0x3d5e8d25, 0x7cf1811a, 0xc2ffdfa5 },
194 { 0x3fb20fae, 0x82f4c420, 0x3d61e37f, 0x7d08af56, 0xc2e9804a },
195 { 0x3fc5a1cc, 0x82df2592, 0x3d6475c3, 0x7d1ef294, 0xc2d40096 },
196 { 0x3fd91f55, 0x82ca6632, 0x3d664564, 0x7d345541, 0xc2bf56b9 },
197 { 0x3fec9120, 0x82b67cac, 0x3d675356, 0x7d48e138, 0xc2ab796e },
198 { 0x40000000, 0x82a36037, 0x3d67a012, 0x7d5c9fc9, 0xc2985fee },
199 { 0x401374c7, 0x8291088a, 0x3d672b93, 0x7d6f99c3, 0xc28601f2 },
200 { 0x4026f857, 0x827f6dd7, 0x3d65f559, 0x7d81d77c, 0xc27457a3 },
201 { 0x403a939f, 0x826e88c5, 0x3d63fc63, 0x7d9360d4, 0xc2635996 },
202 { 0x404e4faf, 0x825e5266, 0x3d613f32, 0x7da43d42, 0xc25300c6 },
203 { 0x406235ba, 0x824ec434, 0x3d5dbbc3, 0x7db473d7, 0xc243468e },
204 { 0x40764f1f, 0x823fd80c, 0x3d596f8f, 0x7dc40b44, 0xc23424a2 },
205 { 0x408aa576, 0x82318824, 0x3d545787, 0x7dd309e2, 0xc2259509 },
206 { 0x409f4296, 0x8223cf0b, 0x3d4e7012, 0x7de175b5, 0xc2179218 },
207 { 0x40b430a0, 0x8216a7a1, 0x3d47b505, 0x7def5475, 0xc20a1670 },
208 { 0x40c97a0a, 0x820a0d12, 0x3d4021a1, 0x7dfcab8d, 0xc1fd1cf5 },
209 { 0x40df29a6, 0x81fdfad6, 0x3d37b08d, 0x7e098028, 0xc1f0a0ca },
210 { 0x40f54ab1, 0x81f26ca9, 0x3d2e5bd1, 0x7e15d72b, 0xc1e49d52 },
211 { 0x410be8da, 0x81e75e89, 0x3d241cce, 0x7e21b544, 0xc1d90e24 },
212 { 0x41231051, 0x81dcccb3, 0x3d18ec37, 0x7e2d1ee6, 0xc1cdef10 },
213 { 0x413acdd0, 0x81d2b39e, 0x3d0cc20a, 0x7e38184e, 0xc1c33c13 },
214 { 0x41532ea7, 0x81c90ffb, 0x3cff9585, 0x7e42a58b, 0xc1b8f15a },
215 { 0x416c40cd, 0x81bfdeb2, 0x3cf15d21, 0x7e4cca7c, 0xc1af0b3f },
216 { 0x418612ea, 0x81b71cdc, 0x3ce20e85, 0x7e568ad3, 0xc1a58640 },
217 { 0x41a0b465, 0x81aec7c5, 0x3cd19e7c, 0x7e5fea1e, 0xc19c5f03 },
218 { 0x41bc3573, 0x81a6dcea, 0x3cc000e9, 0x7e68ebc2, 0xc1939250 }
221 static const u32 treble_table[41][5] = {
222 { 0x0125cba9, 0xfed5debd, 0x00599b6c, 0x0d2506da, 0xfa85b354 },
223 { 0x0142f67e, 0xfeb03163, 0x0066cd0f, 0x0d14c69d, 0xfa914473 },
224 { 0x016328bd, 0xfe860158, 0x0075b7f2, 0x0d03eb27, 0xfa9d32d2 },
225 { 0x0186b438, 0xfe56c982, 0x00869234, 0x0cf27048, 0xfaa97fca },
226 { 0x01adf358, 0xfe21f5fe, 0x00999842, 0x0ce051c2, 0xfab62ca5 },
227 { 0x01d949fa, 0xfde6e287, 0x00af0d8d, 0x0ccd8b4a, 0xfac33aa7 },
228 { 0x02092669, 0xfda4d8bf, 0x00c73d4c, 0x0cba1884, 0xfad0ab07 },
229 { 0x023e0268, 0xfd5b0e4a, 0x00e27b54, 0x0ca5f509, 0xfade7ef2 },
230 { 0x0278645c, 0xfd08a2b0, 0x01012509, 0x0c911c63, 0xfaecb788 },
231 { 0x02b8e091, 0xfcac9d1a, 0x0123a262, 0x0c7b8a14, 0xfafb55df },
232 { 0x03001a9a, 0xfc45e9ce, 0x014a6709, 0x0c65398f, 0xfb0a5aff },
233 { 0x034ec6d7, 0xfbd3576b, 0x0175f397, 0x0c4e2643, 0xfb19c7e4 },
234 { 0x03a5ac15, 0xfb5393ee, 0x01a6d6ed, 0x0c364b94, 0xfb299d7c },
235 { 0x0405a562, 0xfac52968, 0x01ddafae, 0x0c1da4e2, 0xfb39dca5 },
236 { 0x046fa3fe, 0xfa267a66, 0x021b2ddd, 0x0c042d8d, 0xfb4a8631 },
237 { 0x04e4b17f, 0xf975be0f, 0x0260149f, 0x0be9e0f2, 0xfb5b9ae0 },
238 { 0x0565f220, 0xf8b0fbe5, 0x02ad3c29, 0x0bceba73, 0xfb6d1b60 },
239 { 0x05f4a745, 0xf7d60722, 0x030393d4, 0x0bb2b578, 0xfb7f084d },
240 { 0x06923236, 0xf6e279bd, 0x03642465, 0x0b95cd75, 0xfb916233 },
241 { 0x07401713, 0xf5d3aef9, 0x03d01283, 0x0b77fded, 0xfba42984 },
242 { 0x08000000, 0xf4a6bd88, 0x0448a161, 0x0b594278, 0xfbb75e9f },
243 { 0x08d3c097, 0xf3587131, 0x04cf35a4, 0x0b3996c9, 0xfbcb01cb },
244 { 0x09bd59a2, 0xf1e543f9, 0x05655880, 0x0b18f6b2, 0xfbdf1333 },
245 { 0x0abefd0f, 0xf04956ca, 0x060cbb12, 0x0af75e2c, 0xfbf392e8 },
246 { 0x0bdb123e, 0xee806984, 0x06c739fe, 0x0ad4c962, 0xfc0880dd },
247 { 0x0d143a94, 0xec85d287, 0x0796e150, 0x0ab134b0, 0xfc1ddce5 },
248 { 0x0e6d5664, 0xea547598, 0x087df0a0, 0x0a8c9cb6, 0xfc33a6ad },
249 { 0x0fe98a2a, 0xe7e6ba35, 0x097edf83, 0x0a66fe5b, 0xfc49ddc2 },
250 { 0x118c4421, 0xe536813a, 0x0a9c6248, 0x0a4056d7, 0xfc608185 },
251 { 0x1359422e, 0xe23d19eb, 0x0bd96efb, 0x0a18a3bf, 0xfc77912c },
252 { 0x1554982b, 0xdef33645, 0x0d3942bd, 0x09efe312, 0xfc8f0bc1 },
253 { 0x1782b68a, 0xdb50deb1, 0x0ebf676d, 0x09c6133f, 0xfca6f019 },
254 { 0x19e8715d, 0xd74d64fd, 0x106fb999, 0x099b3337, 0xfcbf3cd6 },
255 { 0x1c8b07b8, 0xd2df56ab, 0x124e6ec8, 0x096f4274, 0xfcd7f060 },
256 { 0x1f702b6d, 0xcdfc6e92, 0x14601c10, 0x0942410b, 0xfcf108e5 },
257 { 0x229e0933, 0xc89985cd, 0x16a9bcfa, 0x09142fb5, 0xfd0a8451 },
258 { 0x261b5118, 0xc2aa8409, 0x1930bab6, 0x08e50fdc, 0xfd24604d },
259 { 0x29ef3f5d, 0xbc224f28, 0x1bfaf396, 0x08b4e3aa, 0xfd3e9a3b },
260 { 0x2e21a59b, 0xb4f2ba46, 0x1f0ec2d6, 0x0883ae15, 0xfd592f33 },
261 { 0x32baf44b, 0xad0c7429, 0x227308a3, 0x085172eb, 0xfd741bfd },
262 { 0x37c4448b, 0xa45ef51d, 0x262f3267, 0x081e36dc, 0xfd8f5d14 }
265 static const u32 db_table[101] = {
266 0x00000000, 0x01571f82, 0x01674b41, 0x01783a1b, 0x0189f540,
267 0x019c8651, 0x01aff763, 0x01c45306, 0x01d9a446, 0x01eff6b8,
268 0x0207567a, 0x021fd03d, 0x0239714c, 0x02544792, 0x027061a1,
269 0x028dcebb, 0x02ac9edc, 0x02cce2bf, 0x02eeabe8, 0x03120cb0,
270 0x0337184e, 0x035de2df, 0x03868173, 0x03b10a18, 0x03dd93e9,
271 0x040c3713, 0x043d0cea, 0x04702ff3, 0x04a5bbf2, 0x04ddcdfb,
272 0x0518847f, 0x0555ff62, 0x05966005, 0x05d9c95d, 0x06206005,
273 0x066a4a52, 0x06b7b067, 0x0708bc4c, 0x075d9a01, 0x07b6779d,
274 0x08138561, 0x0874f5d5, 0x08dafde1, 0x0945d4ed, 0x09b5b4fd,
275 0x0a2adad1, 0x0aa58605, 0x0b25f936, 0x0bac7a24, 0x0c3951d8,
276 0x0ccccccc, 0x0d673b17, 0x0e08f093, 0x0eb24510, 0x0f639481,
277 0x101d3f2d, 0x10dfa9e6, 0x11ab3e3f, 0x12806ac3, 0x135fa333,
278 0x144960c5, 0x153e2266, 0x163e6cfe, 0x174acbb7, 0x1863d04d,
279 0x198a1357, 0x1abe349f, 0x1c00db77, 0x1d52b712, 0x1eb47ee6,
280 0x2026f30f, 0x21aadcb6, 0x23410e7e, 0x24ea64f9, 0x26a7c71d,
281 0x287a26c4, 0x2a62812c, 0x2c61df84, 0x2e795779, 0x30aa0bcf,
282 0x32f52cfe, 0x355bf9d8, 0x37dfc033, 0x3a81dda4, 0x3d43c038,
283 0x4026e73c, 0x432ce40f, 0x46575af8, 0x49a8040f, 0x4d20ac2a,
284 0x50c335d3, 0x54919a57, 0x588dead1, 0x5cba514a, 0x611911ea,
285 0x65ac8c2f, 0x6a773c39, 0x6f7bbc23, 0x74bcc56c, 0x7a3d3272,
289 static const u32 onoff_table[2] = {
290 0x00000000, 0x00000001
296 static inline mm_segment_t snd_enter_user(void)
298 mm_segment_t fs = get_fs();
303 static inline void snd_leave_user(mm_segment_t fs)
312 static int snd_emu10k1_gpr_ctl_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
314 snd_emu10k1_fx8010_ctl_t *ctl = (snd_emu10k1_fx8010_ctl_t *)kcontrol->private_value;
316 if (ctl->min == 0 && ctl->max == 1)
317 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
319 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
320 uinfo->count = ctl->vcount;
321 uinfo->value.integer.min = ctl->min;
322 uinfo->value.integer.max = ctl->max;
326 static int snd_emu10k1_gpr_ctl_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
328 emu10k1_t *emu = snd_kcontrol_chip(kcontrol);
329 snd_emu10k1_fx8010_ctl_t *ctl = (snd_emu10k1_fx8010_ctl_t *)kcontrol->private_value;
333 spin_lock_irqsave(&emu->reg_lock, flags);
334 for (i = 0; i < ctl->vcount; i++)
335 ucontrol->value.integer.value[i] = ctl->value[i];
336 spin_unlock_irqrestore(&emu->reg_lock, flags);
340 static int snd_emu10k1_gpr_ctl_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
342 emu10k1_t *emu = snd_kcontrol_chip(kcontrol);
343 snd_emu10k1_fx8010_ctl_t *ctl = (snd_emu10k1_fx8010_ctl_t *)kcontrol->private_value;
345 unsigned int nval, val;
349 spin_lock_irqsave(&emu->reg_lock, flags);
350 for (i = 0; i < ctl->vcount; i++) {
351 nval = ucontrol->value.integer.value[i];
356 if (nval != ctl->value[i])
358 val = ctl->value[i] = nval;
359 switch (ctl->translation) {
360 case EMU10K1_GPR_TRANSLATION_NONE:
361 snd_emu10k1_ptr_write(emu, emu->gpr_base + ctl->gpr[i], 0, val);
363 case EMU10K1_GPR_TRANSLATION_TABLE100:
364 snd_emu10k1_ptr_write(emu, emu->gpr_base + ctl->gpr[i], 0, db_table[val]);
366 case EMU10K1_GPR_TRANSLATION_BASS:
367 snd_runtime_check((ctl->count % 5) == 0 && (ctl->count / 5) == ctl->vcount, change = -EIO; goto __error);
368 for (j = 0; j < 5; j++)
369 snd_emu10k1_ptr_write(emu, emu->gpr_base + ctl->gpr[j * ctl->vcount + i], 0, bass_table[val][j]);
371 case EMU10K1_GPR_TRANSLATION_TREBLE:
372 snd_runtime_check((ctl->count % 5) == 0 && (ctl->count / 5) == ctl->vcount, change = -EIO; goto __error);
373 for (j = 0; j < 5; j++)
374 snd_emu10k1_ptr_write(emu, emu->gpr_base + ctl->gpr[j * ctl->vcount + i], 0, treble_table[val][j]);
376 case EMU10K1_GPR_TRANSLATION_ONOFF:
377 snd_emu10k1_ptr_write(emu, emu->gpr_base + ctl->gpr[i], 0, onoff_table[val]);
382 spin_unlock_irqrestore(&emu->reg_lock, flags);
390 static void snd_emu10k1_fx8010_interrupt(emu10k1_t *emu)
392 snd_emu10k1_fx8010_irq_t *irq, *nirq;
394 irq = emu->fx8010.irq_handlers;
396 nirq = irq->next; /* irq ptr can be removed from list */
397 if (snd_emu10k1_ptr_read(emu, emu->gpr_base + irq->gpr_running, 0) & 0xffff0000) {
399 irq->handler(emu, irq->private_data);
400 snd_emu10k1_ptr_write(emu, emu->gpr_base + irq->gpr_running, 0, 1);
406 int snd_emu10k1_fx8010_register_irq_handler(emu10k1_t *emu,
407 snd_fx8010_irq_handler_t *handler,
408 unsigned char gpr_running,
410 snd_emu10k1_fx8010_irq_t **r_irq)
412 snd_emu10k1_fx8010_irq_t *irq;
415 snd_runtime_check(emu, return -EINVAL);
416 snd_runtime_check(handler, return -EINVAL);
417 irq = kmalloc(sizeof(*irq), GFP_ATOMIC);
420 irq->handler = handler;
421 irq->gpr_running = gpr_running;
422 irq->private_data = private_data;
424 spin_lock_irqsave(&emu->fx8010.irq_lock, flags);
425 if (emu->fx8010.irq_handlers == NULL) {
426 emu->fx8010.irq_handlers = irq;
427 emu->dsp_interrupt = snd_emu10k1_fx8010_interrupt;
428 snd_emu10k1_intr_enable(emu, INTE_FXDSPENABLE);
430 irq->next = emu->fx8010.irq_handlers;
431 emu->fx8010.irq_handlers = irq;
433 spin_unlock_irqrestore(&emu->fx8010.irq_lock, flags);
439 int snd_emu10k1_fx8010_unregister_irq_handler(emu10k1_t *emu,
440 snd_emu10k1_fx8010_irq_t *irq)
442 snd_emu10k1_fx8010_irq_t *tmp;
445 snd_runtime_check(irq, return -EINVAL);
446 spin_lock_irqsave(&emu->fx8010.irq_lock, flags);
447 if ((tmp = emu->fx8010.irq_handlers) == irq) {
448 emu->fx8010.irq_handlers = tmp->next;
449 if (emu->fx8010.irq_handlers == NULL) {
450 snd_emu10k1_intr_disable(emu, INTE_FXDSPENABLE);
451 emu->dsp_interrupt = NULL;
454 while (tmp && tmp->next != irq)
457 tmp->next = tmp->next->next;
459 spin_unlock_irqrestore(&emu->fx8010.irq_lock, flags);
464 /*************************************************************************
465 * EMU10K1 effect manager
466 *************************************************************************/
468 static void snd_emu10k1_write_op(emu10k1_fx8010_code_t *icode, unsigned int *ptr,
469 u32 op, u32 r, u32 a, u32 x, u32 y)
471 snd_assert(*ptr < 512, return);
472 set_bit(*ptr, icode->code_valid);
473 icode->code[(*ptr) * 2 + 0] = ((x & 0x3ff) << 10) | (y & 0x3ff);
474 icode->code[(*ptr)++ * 2 + 1] = ((op & 0x0f) << 20) | ((r & 0x3ff) << 10) | (a & 0x3ff);
477 #define OP(icode, ptr, op, r, a, x, y) \
478 snd_emu10k1_write_op(icode, ptr, op, r, a, x, y)
480 static void snd_emu10k1_audigy_write_op(emu10k1_fx8010_code_t *icode, unsigned int *ptr,
481 u32 op, u32 r, u32 a, u32 x, u32 y)
483 snd_assert(*ptr < 1024, return);
484 set_bit(*ptr, icode->code_valid);
485 icode->code[(*ptr) * 2 + 0] = ((x & 0x7ff) << 12) | (y & 0x7ff);
486 icode->code[(*ptr)++ * 2 + 1] = ((op & 0x0f) << 24) | ((r & 0x7ff) << 12) | (a & 0x7ff);
489 #define A_OP(icode, ptr, op, r, a, x, y) \
490 snd_emu10k1_audigy_write_op(icode, ptr, op, r, a, x, y)
492 static void snd_emu10k1_efx_write(emu10k1_t *emu, unsigned int pc, unsigned int data)
494 pc += emu->audigy ? A_MICROCODEBASE : MICROCODEBASE;
495 snd_emu10k1_ptr_write(emu, pc, 0, data);
498 unsigned int snd_emu10k1_efx_read(emu10k1_t *emu, unsigned int pc)
500 pc += emu->audigy ? A_MICROCODEBASE : MICROCODEBASE;
501 return snd_emu10k1_ptr_read(emu, pc, 0);
504 static int snd_emu10k1_gpr_poke(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
509 for (gpr = 0; gpr < (emu->audigy ? 0x200 : 0x100); gpr++) {
510 if (!test_bit(gpr, icode->gpr_valid))
512 if (get_user(val, &icode->gpr_map[gpr]))
514 snd_emu10k1_ptr_write(emu, emu->gpr_base + gpr, 0, val);
519 static int snd_emu10k1_gpr_peek(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
524 for (gpr = 0; gpr < (emu->audigy ? 0x200 : 0x100); gpr++) {
525 set_bit(gpr, icode->gpr_valid);
526 val = snd_emu10k1_ptr_read(emu, emu->gpr_base + gpr, 0);
527 if (put_user(val, &icode->gpr_map[gpr]))
533 static int snd_emu10k1_tram_poke(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
538 for (tram = 0; tram < (emu->audigy ? 0x100 : 0xa0); tram++) {
539 if (!test_bit(tram, icode->tram_valid))
541 if (get_user(val, &icode->tram_data_map[tram]) ||
542 get_user(addr, &icode->tram_addr_map[tram]))
544 snd_emu10k1_ptr_write(emu, TANKMEMDATAREGBASE + tram, 0, val);
546 snd_emu10k1_ptr_write(emu, TANKMEMADDRREGBASE + tram, 0, addr);
548 snd_emu10k1_ptr_write(emu, TANKMEMADDRREGBASE + tram, 0, addr << 12);
549 snd_emu10k1_ptr_write(emu, A_TANKMEMCTLREGBASE + tram, 0, addr >> 20);
555 static int snd_emu10k1_tram_peek(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
560 memset(icode->tram_valid, 0, sizeof(icode->tram_valid));
561 for (tram = 0; tram < (emu->audigy ? 0x100 : 0xa0); tram++) {
562 set_bit(tram, icode->tram_valid);
563 val = snd_emu10k1_ptr_read(emu, TANKMEMDATAREGBASE + tram, 0);
565 addr = snd_emu10k1_ptr_read(emu, TANKMEMADDRREGBASE + tram, 0);
567 addr = snd_emu10k1_ptr_read(emu, TANKMEMADDRREGBASE + tram, 0) >> 12;
568 addr |= snd_emu10k1_ptr_read(emu, A_TANKMEMCTLREGBASE + tram, 0) << 20;
570 if (put_user(val, &icode->tram_data_map[tram]) ||
571 put_user(addr, &icode->tram_addr_map[tram]))
577 static int snd_emu10k1_code_poke(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
581 for (pc = 0; pc < (emu->audigy ? 2*1024 : 2*512); pc += 2) {
582 if (!test_bit(pc / 2, icode->code_valid))
584 if (get_user(lo, &icode->code[pc + 0]) ||
585 get_user(hi, &icode->code[pc + 1]))
587 snd_emu10k1_efx_write(emu, pc + 0, lo);
588 snd_emu10k1_efx_write(emu, pc + 1, hi);
593 static int snd_emu10k1_code_peek(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
597 memset(icode->code_valid, 0, sizeof(icode->code_valid));
598 for (pc = 0; pc < (emu->audigy ? 2*1024 : 2*512); pc += 2) {
599 set_bit(pc / 2, icode->code_valid);
600 if (put_user(snd_emu10k1_efx_read(emu, pc + 0), &icode->code[pc + 0]))
602 if (put_user(snd_emu10k1_efx_read(emu, pc + 1), &icode->code[pc + 1]))
608 static snd_emu10k1_fx8010_ctl_t *snd_emu10k1_look_for_ctl(emu10k1_t *emu, snd_ctl_elem_id_t *id)
610 snd_emu10k1_fx8010_ctl_t *ctl;
611 snd_kcontrol_t *kcontrol;
612 struct list_head *list;
614 list_for_each(list, &emu->fx8010.gpr_ctl) {
615 ctl = emu10k1_gpr_ctl(list);
616 kcontrol = ctl->kcontrol;
617 if (kcontrol->id.iface == id->iface &&
618 !strcmp(kcontrol->id.name, id->name) &&
619 kcontrol->id.index == id->index)
625 static int snd_emu10k1_verify_controls(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
628 snd_ctl_elem_id_t __user *_id;
629 snd_ctl_elem_id_t id;
630 emu10k1_fx8010_control_gpr_t __user *_gctl;
631 emu10k1_fx8010_control_gpr_t gctl;
633 for (i = 0, _id = icode->gpr_del_controls;
634 i < icode->gpr_del_control_count; i++, _id++) {
635 if (copy_from_user(&id, _id, sizeof(id)))
637 if (snd_emu10k1_look_for_ctl(emu, &id) == NULL)
640 for (i = 0, _gctl = icode->gpr_add_controls;
641 i < icode->gpr_add_control_count; i++, _gctl++) {
642 if (copy_from_user(&gctl, _gctl, sizeof(gctl)))
644 if (snd_emu10k1_look_for_ctl(emu, &gctl.id))
646 down_read(&emu->card->controls_rwsem);
647 if (snd_ctl_find_id(emu->card, &gctl.id) != NULL) {
648 up_read(&emu->card->controls_rwsem);
651 up_read(&emu->card->controls_rwsem);
652 if (gctl.id.iface != SNDRV_CTL_ELEM_IFACE_MIXER &&
653 gctl.id.iface != SNDRV_CTL_ELEM_IFACE_PCM)
656 for (i = 0, _gctl = icode->gpr_list_controls;
657 i < icode->gpr_list_control_count; i++, _gctl++) {
658 /* FIXME: we need to check the WRITE access */
659 if (copy_from_user(&gctl, _gctl, sizeof(gctl)))
665 static void snd_emu10k1_ctl_private_free(snd_kcontrol_t *kctl)
667 snd_emu10k1_fx8010_ctl_t *ctl;
669 ctl = (snd_emu10k1_fx8010_ctl_t *)kctl->private_value;
670 kctl->private_value = 0;
671 list_del(&ctl->list);
675 static int snd_emu10k1_add_controls(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
678 emu10k1_fx8010_control_gpr_t __user *_gctl;
679 emu10k1_fx8010_control_gpr_t gctl;
680 snd_emu10k1_fx8010_ctl_t *ctl, nctl;
681 snd_kcontrol_new_t knew;
682 snd_kcontrol_t *kctl;
683 snd_ctl_elem_value_t *val;
686 val = (snd_ctl_elem_value_t *)kmalloc(sizeof(*val), GFP_KERNEL);
689 for (i = 0, _gctl = icode->gpr_add_controls;
690 i < icode->gpr_add_control_count; i++, _gctl++) {
691 if (copy_from_user(&gctl, _gctl, sizeof(gctl))) {
695 snd_runtime_check(gctl.id.iface == SNDRV_CTL_ELEM_IFACE_MIXER ||
696 gctl.id.iface == SNDRV_CTL_ELEM_IFACE_PCM, err = -EINVAL; goto __error);
697 snd_runtime_check(gctl.id.name[0] != '\0', err = -EINVAL; goto __error);
698 ctl = snd_emu10k1_look_for_ctl(emu, &gctl.id);
699 memset(&knew, 0, sizeof(knew));
700 knew.iface = gctl.id.iface;
701 knew.name = gctl.id.name;
702 knew.index = gctl.id.index;
703 knew.device = gctl.id.device;
704 knew.subdevice = gctl.id.subdevice;
705 knew.info = snd_emu10k1_gpr_ctl_info;
706 knew.get = snd_emu10k1_gpr_ctl_get;
707 knew.put = snd_emu10k1_gpr_ctl_put;
708 memset(&nctl, 0, sizeof(nctl));
709 nctl.vcount = gctl.vcount;
710 nctl.count = gctl.count;
711 for (j = 0; j < 32; j++) {
712 nctl.gpr[j] = gctl.gpr[j];
713 nctl.value[j] = ~gctl.value[j]; /* inverted, we want to write new value in gpr_ctl_put() */
714 val->value.integer.value[j] = gctl.value[j];
718 nctl.translation = gctl.translation;
720 ctl = (snd_emu10k1_fx8010_ctl_t *)kmalloc(sizeof(*ctl), GFP_KERNEL);
723 knew.private_value = (unsigned long)ctl;
724 memcpy(ctl, &nctl, sizeof(nctl));
725 if ((err = snd_ctl_add(emu->card, kctl = snd_ctl_new1(&knew, emu))) < 0) {
729 kctl->private_free = snd_emu10k1_ctl_private_free;
730 ctl->kcontrol = kctl;
731 list_add_tail(&ctl->list, &emu->fx8010.gpr_ctl);
734 nctl.list = ctl->list;
735 nctl.kcontrol = ctl->kcontrol;
736 memcpy(ctl, &nctl, sizeof(nctl));
737 snd_ctl_notify(emu->card, SNDRV_CTL_EVENT_MASK_VALUE |
738 SNDRV_CTL_EVENT_MASK_INFO, &ctl->kcontrol->id);
740 snd_emu10k1_gpr_ctl_put(ctl->kcontrol, val);
747 static int snd_emu10k1_del_controls(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
750 snd_ctl_elem_id_t id;
751 snd_ctl_elem_id_t __user *_id;
752 snd_emu10k1_fx8010_ctl_t *ctl;
753 snd_card_t *card = emu->card;
755 for (i = 0, _id = icode->gpr_del_controls;
756 i < icode->gpr_del_control_count; i++, _id++) {
757 snd_runtime_check(copy_from_user(&id, _id, sizeof(id)) == 0, return -EFAULT);
758 down_write(&card->controls_rwsem);
759 ctl = snd_emu10k1_look_for_ctl(emu, &id);
761 snd_ctl_remove(card, ctl->kcontrol);
762 up_write(&card->controls_rwsem);
767 static int snd_emu10k1_list_controls(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
769 unsigned int i = 0, j;
770 unsigned int total = 0;
771 emu10k1_fx8010_control_gpr_t gctl;
772 emu10k1_fx8010_control_gpr_t __user *_gctl;
773 snd_emu10k1_fx8010_ctl_t *ctl;
774 snd_ctl_elem_id_t *id;
775 struct list_head *list;
777 _gctl = icode->gpr_list_controls;
778 list_for_each(list, &emu->fx8010.gpr_ctl) {
779 ctl = emu10k1_gpr_ctl(list);
781 if (_gctl && i < icode->gpr_list_control_count) {
782 memset(&gctl, 0, sizeof(gctl));
783 id = &ctl->kcontrol->id;
784 gctl.id.iface = id->iface;
785 strlcpy(gctl.id.name, id->name, sizeof(gctl.id.name));
786 gctl.id.index = id->index;
787 gctl.id.device = id->device;
788 gctl.id.subdevice = id->subdevice;
789 gctl.vcount = ctl->vcount;
790 gctl.count = ctl->count;
791 for (j = 0; j < 32; j++) {
792 gctl.gpr[j] = ctl->gpr[j];
793 gctl.value[j] = ctl->value[j];
797 gctl.translation = ctl->translation;
798 if (copy_to_user(_gctl, &gctl, sizeof(gctl)))
804 icode->gpr_list_control_total = total;
808 static int snd_emu10k1_icode_poke(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
812 down(&emu->fx8010.lock);
813 if ((err = snd_emu10k1_verify_controls(emu, icode)) < 0)
815 strlcpy(emu->fx8010.name, icode->name, sizeof(emu->fx8010.name));
816 /* stop FX processor - this may be dangerous, but it's better to miss
817 some samples than generate wrong ones - [jk] */
819 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg | A_DBG_SINGLE_STEP);
821 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg | EMU10K1_DBG_SINGLE_STEP);
822 /* ok, do the main job */
823 if ((err = snd_emu10k1_del_controls(emu, icode)) < 0 ||
824 (err = snd_emu10k1_gpr_poke(emu, icode)) < 0 ||
825 (err = snd_emu10k1_tram_poke(emu, icode)) < 0 ||
826 (err = snd_emu10k1_code_poke(emu, icode)) < 0 ||
827 (err = snd_emu10k1_add_controls(emu, icode)) < 0)
829 /* start FX processor when the DSP code is updated */
831 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg);
833 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg);
835 up(&emu->fx8010.lock);
839 static int snd_emu10k1_icode_peek(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
843 down(&emu->fx8010.lock);
844 strlcpy(icode->name, emu->fx8010.name, sizeof(icode->name));
845 /* ok, do the main job */
846 err = snd_emu10k1_gpr_peek(emu, icode);
848 err = snd_emu10k1_tram_peek(emu, icode);
850 err = snd_emu10k1_code_peek(emu, icode);
852 err = snd_emu10k1_list_controls(emu, icode);
853 up(&emu->fx8010.lock);
857 static int snd_emu10k1_ipcm_poke(emu10k1_t *emu, emu10k1_fx8010_pcm_t *ipcm)
861 snd_emu10k1_fx8010_pcm_t *pcm;
863 if (ipcm->substream >= EMU10K1_FX8010_PCM_COUNT)
865 if (ipcm->channels > 32)
867 pcm = &emu->fx8010.pcm[ipcm->substream];
868 down(&emu->fx8010.lock);
869 spin_lock_irq(&emu->reg_lock);
874 if (ipcm->channels == 0) { /* remove */
877 /* FIXME: we need to add universal code to the PCM transfer routine */
878 if (ipcm->channels != 2) {
884 pcm->channels = ipcm->channels;
885 pcm->tram_start = ipcm->tram_start;
886 pcm->buffer_size = ipcm->buffer_size;
887 pcm->gpr_size = ipcm->gpr_size;
888 pcm->gpr_count = ipcm->gpr_count;
889 pcm->gpr_tmpcount = ipcm->gpr_tmpcount;
890 pcm->gpr_ptr = ipcm->gpr_ptr;
891 pcm->gpr_trigger = ipcm->gpr_trigger;
892 pcm->gpr_running = ipcm->gpr_running;
893 for (i = 0; i < pcm->channels; i++)
894 pcm->etram[i] = ipcm->etram[i];
897 spin_unlock_irq(&emu->reg_lock);
898 up(&emu->fx8010.lock);
902 static int snd_emu10k1_ipcm_peek(emu10k1_t *emu, emu10k1_fx8010_pcm_t *ipcm)
906 snd_emu10k1_fx8010_pcm_t *pcm;
908 if (ipcm->substream >= EMU10K1_FX8010_PCM_COUNT)
910 pcm = &emu->fx8010.pcm[ipcm->substream];
911 down(&emu->fx8010.lock);
912 spin_lock_irq(&emu->reg_lock);
913 ipcm->channels = pcm->channels;
914 ipcm->tram_start = pcm->tram_start;
915 ipcm->buffer_size = pcm->buffer_size;
916 ipcm->gpr_size = pcm->gpr_size;
917 ipcm->gpr_ptr = pcm->gpr_ptr;
918 ipcm->gpr_count = pcm->gpr_count;
919 ipcm->gpr_tmpcount = pcm->gpr_tmpcount;
920 ipcm->gpr_trigger = pcm->gpr_trigger;
921 ipcm->gpr_running = pcm->gpr_running;
922 for (i = 0; i < pcm->channels; i++)
923 ipcm->etram[i] = pcm->etram[i];
924 ipcm->res1 = ipcm->res2 = 0;
926 spin_unlock_irq(&emu->reg_lock);
927 up(&emu->fx8010.lock);
931 #define SND_EMU10K1_GPR_CONTROLS 41
932 #define SND_EMU10K1_INPUTS 10
933 #define SND_EMU10K1_PLAYBACK_CHANNELS 8
934 #define SND_EMU10K1_CAPTURE_CHANNELS 4
936 static void __devinit snd_emu10k1_init_mono_control(emu10k1_fx8010_control_gpr_t *ctl, const char *name, int gpr, int defval)
938 ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
939 strcpy(ctl->id.name, name);
940 ctl->vcount = ctl->count = 1;
941 ctl->gpr[0] = gpr + 0; ctl->value[0] = defval;
944 ctl->translation = EMU10K1_GPR_TRANSLATION_TABLE100;
947 static void __devinit snd_emu10k1_init_stereo_control(emu10k1_fx8010_control_gpr_t *ctl, const char *name, int gpr, int defval)
949 ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
950 strcpy(ctl->id.name, name);
951 ctl->vcount = ctl->count = 2;
952 ctl->gpr[0] = gpr + 0; ctl->value[0] = defval;
953 ctl->gpr[1] = gpr + 1; ctl->value[1] = defval;
956 ctl->translation = EMU10K1_GPR_TRANSLATION_TABLE100;
959 static void __devinit snd_emu10k1_init_mono_onoff_control(emu10k1_fx8010_control_gpr_t *ctl, const char *name, int gpr, int defval)
961 ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
962 strcpy(ctl->id.name, name);
963 ctl->vcount = ctl->count = 1;
964 ctl->gpr[0] = gpr + 0; ctl->value[0] = defval;
967 ctl->translation = EMU10K1_GPR_TRANSLATION_ONOFF;
970 static void __devinit snd_emu10k1_init_stereo_onoff_control(emu10k1_fx8010_control_gpr_t *ctl, const char *name, int gpr, int defval)
972 ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
973 strcpy(ctl->id.name, name);
974 ctl->vcount = ctl->count = 2;
975 ctl->gpr[0] = gpr + 0; ctl->value[0] = defval;
976 ctl->gpr[1] = gpr + 1; ctl->value[1] = defval;
979 ctl->translation = EMU10K1_GPR_TRANSLATION_ONOFF;
984 * initial DSP configuration for Audigy
987 static int __devinit _snd_emu10k1_audigy_init_efx(emu10k1_t *emu)
989 int err, i, z, gpr, nctl;
990 const int playback = 10;
991 const int capture = playback + (SND_EMU10K1_PLAYBACK_CHANNELS * 2); /* we reserve 10 voices */
992 const int stereo_mix = capture + 2;
993 const int tmp = 0x88;
995 emu10k1_fx8010_code_t *icode = NULL;
996 emu10k1_fx8010_control_gpr_t *controls = NULL, *ctl;
999 spin_lock_init(&emu->fx8010.irq_lock);
1000 INIT_LIST_HEAD(&emu->fx8010.gpr_ctl);
1002 if ((icode = kcalloc(1, sizeof(*icode), GFP_KERNEL)) == NULL ||
1003 (icode->gpr_map = kcalloc(512 + 256 + 256 + 2 * 1024, sizeof(u_int32_t), GFP_KERNEL)) == NULL ||
1004 (controls = kcalloc(SND_EMU10K1_GPR_CONTROLS, sizeof(*controls), GFP_KERNEL)) == NULL) {
1009 icode->tram_data_map = icode->gpr_map + 512;
1010 icode->tram_addr_map = icode->tram_data_map + 256;
1011 icode->code = icode->tram_addr_map + 256;
1013 /* clear free GPRs */
1014 for (i = 0; i < 512; i++)
1015 set_bit(i, icode->gpr_valid);
1017 /* clear TRAM data & address lines */
1018 for (i = 0; i < 256; i++)
1019 set_bit(i, icode->tram_valid);
1021 strcpy(icode->name, "Audigy DSP code for ALSA");
1024 gpr = stereo_mix + 10;
1026 /* stop FX processor */
1027 snd_emu10k1_ptr_write(emu, A_DBG, 0, (emu->fx8010.dbg = 0) | A_DBG_SINGLE_STEP);
1029 /* PCM front Playback Volume (independent from stereo mix) */
1030 A_OP(icode, &ptr, iMAC0, A_GPR(playback), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LEFT_FRONT));
1031 A_OP(icode, &ptr, iMAC0, A_GPR(playback+1), A_C_00000000, A_GPR(gpr+1), A_FXBUS(FXBUS_PCM_RIGHT_FRONT));
1032 snd_emu10k1_init_stereo_control(&controls[nctl++], "PCM Front Playback Volume", gpr, 100);
1035 /* PCM Surround Playback (independent from stereo mix) */
1036 A_OP(icode, &ptr, iMAC0, A_GPR(playback+2), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LEFT_REAR));
1037 A_OP(icode, &ptr, iMAC0, A_GPR(playback+3), A_C_00000000, A_GPR(gpr+1), A_FXBUS(FXBUS_PCM_RIGHT_REAR));
1038 snd_emu10k1_init_stereo_control(&controls[nctl++], "PCM Surround Playback Volume", gpr, 100);
1041 /* PCM Side Playback (independent from stereo mix) */
1043 A_OP(icode, &ptr, iMAC0, A_GPR(playback+6), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LEFT_SIDE));
1044 A_OP(icode, &ptr, iMAC0, A_GPR(playback+7), A_C_00000000, A_GPR(gpr+1), A_FXBUS(FXBUS_PCM_RIGHT_SIDE));
1045 snd_emu10k1_init_stereo_control(&controls[nctl++], "PCM Side Playback Volume", gpr, 100);
1049 /* PCM Center Playback (independent from stereo mix) */
1050 A_OP(icode, &ptr, iMAC0, A_GPR(playback+4), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_CENTER));
1051 snd_emu10k1_init_mono_control(&controls[nctl++], "PCM Center Playback Volume", gpr, 100);
1054 /* PCM LFE Playback (independent from stereo mix) */
1055 A_OP(icode, &ptr, iMAC0, A_GPR(playback+5), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LFE));
1056 snd_emu10k1_init_mono_control(&controls[nctl++], "PCM LFE Playback Volume", gpr, 100);
1062 /* Wave (PCM) Playback Volume (will be renamed later) */
1063 A_OP(icode, &ptr, iMAC0, A_GPR(stereo_mix), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LEFT));
1064 A_OP(icode, &ptr, iMAC0, A_GPR(stereo_mix+1), A_C_00000000, A_GPR(gpr+1), A_FXBUS(FXBUS_PCM_RIGHT));
1065 snd_emu10k1_init_stereo_control(&controls[nctl++], "Wave Playback Volume", gpr, 100);
1068 /* Music Playback */
1069 A_OP(icode, &ptr, iMAC0, A_GPR(stereo_mix+0), A_GPR(stereo_mix+0), A_GPR(gpr), A_FXBUS(FXBUS_MIDI_LEFT));
1070 A_OP(icode, &ptr, iMAC0, A_GPR(stereo_mix+1), A_GPR(stereo_mix+1), A_GPR(gpr+1), A_FXBUS(FXBUS_MIDI_RIGHT));
1071 snd_emu10k1_init_stereo_control(&controls[nctl++], "Music Playback Volume", gpr, 100);
1074 /* Wave (PCM) Capture */
1075 A_OP(icode, &ptr, iMAC0, A_GPR(capture+0), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LEFT));
1076 A_OP(icode, &ptr, iMAC0, A_GPR(capture+1), A_C_00000000, A_GPR(gpr+1), A_FXBUS(FXBUS_PCM_RIGHT));
1077 snd_emu10k1_init_stereo_control(&controls[nctl++], "PCM Capture Volume", gpr, 0);
1081 A_OP(icode, &ptr, iMAC0, A_GPR(capture+0), A_GPR(capture+0), A_GPR(gpr), A_FXBUS(FXBUS_MIDI_LEFT));
1082 A_OP(icode, &ptr, iMAC0, A_GPR(capture+1), A_GPR(capture+1), A_GPR(gpr+1), A_FXBUS(FXBUS_MIDI_RIGHT));
1083 snd_emu10k1_init_stereo_control(&controls[nctl++], "Music Capture Volume", gpr, 0);
1089 #define A_ADD_VOLUME_IN(var,vol,input) \
1090 A_OP(icode, &ptr, iMAC0, A_GPR(var), A_GPR(var), A_GPR(vol), A_EXTIN(input))
1092 /* AC'97 Playback Volume - used only for mic (renamed later) */
1093 A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_AC97_L);
1094 A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_AC97_R);
1095 snd_emu10k1_init_stereo_control(&controls[nctl++], "AMic Playback Volume", gpr, 0);
1097 /* AC'97 Capture Volume - used only for mic */
1098 A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_AC97_L);
1099 A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_AC97_R);
1100 snd_emu10k1_init_stereo_control(&controls[nctl++], "Mic Capture Volume", gpr, 0);
1103 /* mic capture buffer */
1104 A_OP(icode, &ptr, iINTERP, A_EXTOUT(A_EXTOUT_MIC_CAP), A_EXTIN(A_EXTIN_AC97_L), 0xcd, A_EXTIN(A_EXTIN_AC97_R));
1106 /* Audigy CD Playback Volume */
1107 A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_SPDIF_CD_L);
1108 A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_SPDIF_CD_R);
1109 snd_emu10k1_init_stereo_control(&controls[nctl++],
1110 emu->no_ac97 ? "CD Playback Volume" : "Audigy CD Playback Volume",
1113 /* Audigy CD Capture Volume */
1114 A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_SPDIF_CD_L);
1115 A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_SPDIF_CD_R);
1116 snd_emu10k1_init_stereo_control(&controls[nctl++],
1117 emu->no_ac97 ? "CD Capture Volume" : "Audigy CD Capture Volume",
1121 /* Optical SPDIF Playback Volume */
1122 A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_OPT_SPDIF_L);
1123 A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_OPT_SPDIF_R);
1124 snd_emu10k1_init_stereo_control(&controls[nctl++], "IEC958 Optical Playback Volume", gpr, 0);
1126 /* Optical SPDIF Capture Volume */
1127 A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_OPT_SPDIF_L);
1128 A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_OPT_SPDIF_R);
1129 snd_emu10k1_init_stereo_control(&controls[nctl++], "IEC958 Optical Capture Volume", gpr, 0);
1132 /* Line2 Playback Volume */
1133 A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_LINE2_L);
1134 A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_LINE2_R);
1135 snd_emu10k1_init_stereo_control(&controls[nctl++],
1136 emu->no_ac97 ? "Line Playback Volume" : "Line2 Playback Volume",
1139 /* Line2 Capture Volume */
1140 A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_LINE2_L);
1141 A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_LINE2_R);
1142 snd_emu10k1_init_stereo_control(&controls[nctl++],
1143 emu->no_ac97 ? "Line Capture Volume" : "Line2 Capture Volume",
1147 /* Philips ADC Playback Volume */
1148 A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_ADC_L);
1149 A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_ADC_R);
1150 snd_emu10k1_init_stereo_control(&controls[nctl++], "Analog Mix Playback Volume", gpr, 0);
1152 /* Philips ADC Capture Volume */
1153 A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_ADC_L);
1154 A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_ADC_R);
1155 snd_emu10k1_init_stereo_control(&controls[nctl++], "Analog Mix Capture Volume", gpr, 0);
1158 /* Aux2 Playback Volume */
1159 A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_AUX2_L);
1160 A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_AUX2_R);
1161 snd_emu10k1_init_stereo_control(&controls[nctl++],
1162 emu->no_ac97 ? "Aux Playback Volume" : "Aux2 Playback Volume",
1165 /* Aux2 Capture Volume */
1166 A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_AUX2_L);
1167 A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_AUX2_R);
1168 snd_emu10k1_init_stereo_control(&controls[nctl++],
1169 emu->no_ac97 ? "Aux Capture Volume" : "Aux2 Capture Volume",
1173 /* Stereo Mix Front Playback Volume */
1174 A_OP(icode, &ptr, iMAC0, A_GPR(playback), A_GPR(playback), A_GPR(gpr), A_GPR(stereo_mix));
1175 A_OP(icode, &ptr, iMAC0, A_GPR(playback+1), A_GPR(playback+1), A_GPR(gpr+1), A_GPR(stereo_mix+1));
1176 snd_emu10k1_init_stereo_control(&controls[nctl++], "Front Playback Volume", gpr, 100);
1179 /* Stereo Mix Surround Playback */
1180 A_OP(icode, &ptr, iMAC0, A_GPR(playback+2), A_GPR(playback+2), A_GPR(gpr), A_GPR(stereo_mix));
1181 A_OP(icode, &ptr, iMAC0, A_GPR(playback+3), A_GPR(playback+3), A_GPR(gpr+1), A_GPR(stereo_mix+1));
1182 snd_emu10k1_init_stereo_control(&controls[nctl++], "Surround Playback Volume", gpr, 0);
1185 /* Stereo Mix Center Playback */
1186 /* Center = sub = Left/2 + Right/2 */
1187 A_OP(icode, &ptr, iINTERP, A_GPR(tmp), A_GPR(stereo_mix), 0xcd, A_GPR(stereo_mix+1));
1188 A_OP(icode, &ptr, iMAC0, A_GPR(playback+4), A_GPR(playback+4), A_GPR(gpr), A_GPR(tmp));
1189 snd_emu10k1_init_mono_control(&controls[nctl++], "Center Playback Volume", gpr, 0);
1192 /* Stereo Mix LFE Playback */
1193 A_OP(icode, &ptr, iMAC0, A_GPR(playback+5), A_GPR(playback+5), A_GPR(gpr), A_GPR(tmp));
1194 snd_emu10k1_init_mono_control(&controls[nctl++], "LFE Playback Volume", gpr, 0);
1198 /* Stereo Mix Side Playback */
1199 A_OP(icode, &ptr, iMAC0, A_GPR(playback+6), A_GPR(playback+6), A_GPR(gpr), A_GPR(stereo_mix));
1200 A_OP(icode, &ptr, iMAC0, A_GPR(playback+7), A_GPR(playback+7), A_GPR(gpr+1), A_GPR(stereo_mix+1));
1201 snd_emu10k1_init_stereo_control(&controls[nctl++], "Side Playback Volume", gpr, 0);
1208 #define A_PUT_OUTPUT(out,src) A_OP(icode, &ptr, iACC3, A_EXTOUT(out), A_C_00000000, A_C_00000000, A_GPR(src))
1209 #define A_PUT_STEREO_OUTPUT(out1,out2,src) \
1210 {A_PUT_OUTPUT(out1,src); A_PUT_OUTPUT(out2,src+1);}
1212 #define _A_SWITCH(icode, ptr, dst, src, sw) \
1213 A_OP((icode), ptr, iMACINT0, dst, A_C_00000000, src, sw);
1214 #define A_SWITCH(icode, ptr, dst, src, sw) \
1215 _A_SWITCH(icode, ptr, A_GPR(dst), A_GPR(src), A_GPR(sw))
1216 #define _A_SWITCH_NEG(icode, ptr, dst, src) \
1217 A_OP((icode), ptr, iANDXOR, dst, src, A_C_00000001, A_C_00000001);
1218 #define A_SWITCH_NEG(icode, ptr, dst, src) \
1219 _A_SWITCH_NEG(icode, ptr, A_GPR(dst), A_GPR(src))
1223 * Process tone control
1225 A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 0), A_GPR(playback + 0), A_C_00000000, A_C_00000000); /* left */
1226 A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 1), A_GPR(playback + 1), A_C_00000000, A_C_00000000); /* right */
1227 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 */
1228 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 */
1229 A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 4), A_GPR(playback + 4), A_C_00000000, A_C_00000000); /* center */
1230 A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 5), A_GPR(playback + 5), A_C_00000000, A_C_00000000); /* LFE */
1232 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 */
1233 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 */
1237 ctl = &controls[nctl + 0];
1238 ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1239 strcpy(ctl->id.name, "Tone Control - Bass");
1244 ctl->value[0] = ctl->value[1] = 20;
1245 ctl->translation = EMU10K1_GPR_TRANSLATION_BASS;
1246 ctl = &controls[nctl + 1];
1247 ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1248 strcpy(ctl->id.name, "Tone Control - Treble");
1253 ctl->value[0] = ctl->value[1] = 20;
1254 ctl->translation = EMU10K1_GPR_TRANSLATION_TREBLE;
1256 #define BASS_GPR 0x8c
1257 #define TREBLE_GPR 0x96
1259 for (z = 0; z < 5; z++) {
1261 for (j = 0; j < 2; j++) {
1262 controls[nctl + 0].gpr[z * 2 + j] = BASS_GPR + z * 2 + j;
1263 controls[nctl + 1].gpr[z * 2 + j] = TREBLE_GPR + z * 2 + j;
1266 for (z = 0; z < 4; z++) { /* front/rear/center-lfe/side */
1268 for (j = 0; j < 2; j++) { /* left/right */
1269 k = 0xb0 + (z * 8) + (j * 4);
1270 l = 0xe0 + (z * 8) + (j * 4);
1271 d = playback + SND_EMU10K1_PLAYBACK_CHANNELS + z * 2 + j;
1273 A_OP(icode, &ptr, iMAC0, A_C_00000000, A_C_00000000, A_GPR(d), A_GPR(BASS_GPR + 0 + j));
1274 A_OP(icode, &ptr, iMACMV, A_GPR(k+1), A_GPR(k), A_GPR(k+1), A_GPR(BASS_GPR + 4 + j));
1275 A_OP(icode, &ptr, iMACMV, A_GPR(k), A_GPR(d), A_GPR(k), A_GPR(BASS_GPR + 2 + j));
1276 A_OP(icode, &ptr, iMACMV, A_GPR(k+3), A_GPR(k+2), A_GPR(k+3), A_GPR(BASS_GPR + 8 + j));
1277 A_OP(icode, &ptr, iMAC0, A_GPR(k+2), A_GPR_ACCU, A_GPR(k+2), A_GPR(BASS_GPR + 6 + j));
1278 A_OP(icode, &ptr, iACC3, A_GPR(k+2), A_GPR(k+2), A_GPR(k+2), A_C_00000000);
1280 A_OP(icode, &ptr, iMAC0, A_C_00000000, A_C_00000000, A_GPR(k+2), A_GPR(TREBLE_GPR + 0 + j));
1281 A_OP(icode, &ptr, iMACMV, A_GPR(l+1), A_GPR(l), A_GPR(l+1), A_GPR(TREBLE_GPR + 4 + j));
1282 A_OP(icode, &ptr, iMACMV, A_GPR(l), A_GPR(k+2), A_GPR(l), A_GPR(TREBLE_GPR + 2 + j));
1283 A_OP(icode, &ptr, iMACMV, A_GPR(l+3), A_GPR(l+2), A_GPR(l+3), A_GPR(TREBLE_GPR + 8 + j));
1284 A_OP(icode, &ptr, iMAC0, A_GPR(l+2), A_GPR_ACCU, A_GPR(l+2), A_GPR(TREBLE_GPR + 6 + j));
1285 A_OP(icode, &ptr, iMACINT0, A_GPR(l+2), A_C_00000000, A_GPR(l+2), A_C_00000010);
1287 A_OP(icode, &ptr, iACC3, A_GPR(d), A_GPR(l+2), A_C_00000000, A_C_00000000);
1289 if (z == 2) /* center */
1298 for (z = 0; z < 8; z++) {
1299 A_SWITCH(icode, &ptr, tmp + 0, playback + SND_EMU10K1_PLAYBACK_CHANNELS + z, gpr + 0);
1300 A_SWITCH_NEG(icode, &ptr, tmp + 1, gpr + 0);
1301 A_SWITCH(icode, &ptr, tmp + 1, playback + z, tmp + 1);
1302 A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + z), A_GPR(tmp + 0), A_GPR(tmp + 1), A_C_00000000);
1304 snd_emu10k1_init_stereo_onoff_control(controls + nctl++, "Tone Control - Switch", gpr, 0);
1307 /* Master volume (will be renamed later) */
1308 A_OP(icode, &ptr, iMAC0, A_GPR(playback+0+SND_EMU10K1_PLAYBACK_CHANNELS), A_C_00000000, A_GPR(gpr), A_GPR(playback+0+SND_EMU10K1_PLAYBACK_CHANNELS));
1309 A_OP(icode, &ptr, iMAC0, A_GPR(playback+1+SND_EMU10K1_PLAYBACK_CHANNELS), A_C_00000000, A_GPR(gpr), A_GPR(playback+1+SND_EMU10K1_PLAYBACK_CHANNELS));
1310 A_OP(icode, &ptr, iMAC0, A_GPR(playback+2+SND_EMU10K1_PLAYBACK_CHANNELS), A_C_00000000, A_GPR(gpr), A_GPR(playback+2+SND_EMU10K1_PLAYBACK_CHANNELS));
1311 A_OP(icode, &ptr, iMAC0, A_GPR(playback+3+SND_EMU10K1_PLAYBACK_CHANNELS), A_C_00000000, A_GPR(gpr), A_GPR(playback+3+SND_EMU10K1_PLAYBACK_CHANNELS));
1312 A_OP(icode, &ptr, iMAC0, A_GPR(playback+4+SND_EMU10K1_PLAYBACK_CHANNELS), A_C_00000000, A_GPR(gpr), A_GPR(playback+4+SND_EMU10K1_PLAYBACK_CHANNELS));
1313 A_OP(icode, &ptr, iMAC0, A_GPR(playback+5+SND_EMU10K1_PLAYBACK_CHANNELS), A_C_00000000, A_GPR(gpr), A_GPR(playback+5+SND_EMU10K1_PLAYBACK_CHANNELS));
1314 A_OP(icode, &ptr, iMAC0, A_GPR(playback+6+SND_EMU10K1_PLAYBACK_CHANNELS), A_C_00000000, A_GPR(gpr), A_GPR(playback+6+SND_EMU10K1_PLAYBACK_CHANNELS));
1315 A_OP(icode, &ptr, iMAC0, A_GPR(playback+7+SND_EMU10K1_PLAYBACK_CHANNELS), A_C_00000000, A_GPR(gpr), A_GPR(playback+7+SND_EMU10K1_PLAYBACK_CHANNELS));
1316 snd_emu10k1_init_mono_control(&controls[nctl++], "Wave Master Playback Volume", gpr, 0);
1319 /* analog speakers */
1320 A_PUT_STEREO_OUTPUT(A_EXTOUT_AFRONT_L, A_EXTOUT_AFRONT_R, playback + SND_EMU10K1_PLAYBACK_CHANNELS);
1321 A_PUT_STEREO_OUTPUT(A_EXTOUT_AREAR_L, A_EXTOUT_AREAR_R, playback+2 + SND_EMU10K1_PLAYBACK_CHANNELS);
1322 A_PUT_OUTPUT(A_EXTOUT_ACENTER, playback+4 + SND_EMU10K1_PLAYBACK_CHANNELS);
1323 A_PUT_OUTPUT(A_EXTOUT_ALFE, playback+5 + SND_EMU10K1_PLAYBACK_CHANNELS);
1325 A_PUT_STEREO_OUTPUT(A_EXTOUT_ASIDE_L, A_EXTOUT_ASIDE_R, playback+6 + SND_EMU10K1_PLAYBACK_CHANNELS);
1328 A_PUT_STEREO_OUTPUT(A_EXTOUT_HEADPHONE_L, A_EXTOUT_HEADPHONE_R, playback + SND_EMU10K1_PLAYBACK_CHANNELS);
1330 /* digital outputs */
1331 /* A_PUT_STEREO_OUTPUT(A_EXTOUT_FRONT_L, A_EXTOUT_FRONT_R, playback + SND_EMU10K1_PLAYBACK_CHANNELS); */
1333 /* IEC958 Optical Raw Playback Switch */
1334 icode->gpr_map[gpr++] = 0x1008;
1335 icode->gpr_map[gpr++] = 0xffff0000;
1336 for (z = 0; z < 2; z++) {
1337 A_OP(icode, &ptr, iMAC0, A_GPR(tmp + 2), A_FXBUS(FXBUS_PT_LEFT + z), A_C_00000000, A_C_00000000);
1338 A_OP(icode, &ptr, iSKIP, A_GPR_COND, A_GPR_COND, A_GPR(gpr - 2), A_C_00000001);
1339 A_OP(icode, &ptr, iACC3, A_GPR(tmp + 2), A_C_00000000, A_C_00010000, A_GPR(tmp + 2));
1340 A_OP(icode, &ptr, iANDXOR, A_GPR(tmp + 2), A_GPR(tmp + 2), A_GPR(gpr - 1), A_C_00000000);
1341 A_SWITCH(icode, &ptr, tmp + 0, tmp + 2, gpr + z);
1342 A_SWITCH_NEG(icode, &ptr, tmp + 1, gpr + z);
1343 A_SWITCH(icode, &ptr, tmp + 1, playback + SND_EMU10K1_PLAYBACK_CHANNELS + z, tmp + 1);
1344 A_OP(icode, &ptr, iACC3, A_EXTOUT(A_EXTOUT_FRONT_L + z), A_GPR(tmp + 0), A_GPR(tmp + 1), A_C_00000000);
1346 snd_emu10k1_init_stereo_onoff_control(controls + nctl++, "IEC958 Optical Raw Playback Switch", gpr, 0);
1349 A_PUT_STEREO_OUTPUT(A_EXTOUT_REAR_L, A_EXTOUT_REAR_R, playback+2 + SND_EMU10K1_PLAYBACK_CHANNELS);
1350 A_PUT_OUTPUT(A_EXTOUT_CENTER, playback+4 + SND_EMU10K1_PLAYBACK_CHANNELS);
1351 A_PUT_OUTPUT(A_EXTOUT_LFE, playback+5 + SND_EMU10K1_PLAYBACK_CHANNELS);
1354 #ifdef EMU10K1_CAPTURE_DIGITAL_OUT
1355 A_PUT_STEREO_OUTPUT(A_EXTOUT_ADC_CAP_L, A_EXTOUT_ADC_CAP_R, playback + SND_EMU10K1_PLAYBACK_CHANNELS);
1357 A_PUT_OUTPUT(A_EXTOUT_ADC_CAP_L, capture);
1358 A_PUT_OUTPUT(A_EXTOUT_ADC_CAP_R, capture+1);
1370 /* clear remaining instruction memory */
1372 A_OP(icode, &ptr, 0x0f, 0xc0, 0xc0, 0xcf, 0xc0);
1374 seg = snd_enter_user();
1375 icode->gpr_add_control_count = nctl;
1376 icode->gpr_add_controls = controls;
1377 err = snd_emu10k1_icode_poke(emu, icode);
1378 snd_leave_user(seg);
1381 if (controls != NULL)
1383 if (icode != NULL) {
1384 if (icode->gpr_map != NULL)
1385 kfree(icode->gpr_map);
1393 * initial DSP configuration for Emu10k1
1396 /* when volume = max, then copy only to avoid volume modification */
1397 /* with iMAC0 (negative values) */
1398 static void __devinit _volume(emu10k1_fx8010_code_t *icode, u32 *ptr, u32 dst, u32 src, u32 vol)
1400 OP(icode, ptr, iMAC0, dst, C_00000000, src, vol);
1401 OP(icode, ptr, iANDXOR, C_00000000, vol, C_ffffffff, C_7fffffff);
1402 OP(icode, ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, C_00000001);
1403 OP(icode, ptr, iACC3, dst, src, C_00000000, C_00000000);
1405 static void __devinit _volume_add(emu10k1_fx8010_code_t *icode, u32 *ptr, u32 dst, u32 src, u32 vol)
1407 OP(icode, ptr, iANDXOR, C_00000000, vol, C_ffffffff, C_7fffffff);
1408 OP(icode, ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, C_00000002);
1409 OP(icode, ptr, iMACINT0, dst, dst, src, C_00000001);
1410 OP(icode, ptr, iSKIP, C_00000000, C_7fffffff, C_7fffffff, C_00000001);
1411 OP(icode, ptr, iMAC0, dst, dst, src, vol);
1413 static void __devinit _volume_out(emu10k1_fx8010_code_t *icode, u32 *ptr, u32 dst, u32 src, u32 vol)
1415 OP(icode, ptr, iANDXOR, C_00000000, vol, C_ffffffff, C_7fffffff);
1416 OP(icode, ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, C_00000002);
1417 OP(icode, ptr, iACC3, dst, src, C_00000000, C_00000000);
1418 OP(icode, ptr, iSKIP, C_00000000, C_7fffffff, C_7fffffff, C_00000001);
1419 OP(icode, ptr, iMAC0, dst, C_00000000, src, vol);
1422 #define VOLUME(icode, ptr, dst, src, vol) \
1423 _volume(icode, ptr, GPR(dst), GPR(src), GPR(vol))
1424 #define VOLUME_IN(icode, ptr, dst, src, vol) \
1425 _volume(icode, ptr, GPR(dst), EXTIN(src), GPR(vol))
1426 #define VOLUME_ADD(icode, ptr, dst, src, vol) \
1427 _volume_add(icode, ptr, GPR(dst), GPR(src), GPR(vol))
1428 #define VOLUME_ADDIN(icode, ptr, dst, src, vol) \
1429 _volume_add(icode, ptr, GPR(dst), EXTIN(src), GPR(vol))
1430 #define VOLUME_OUT(icode, ptr, dst, src, vol) \
1431 _volume_out(icode, ptr, EXTOUT(dst), GPR(src), GPR(vol))
1432 #define _SWITCH(icode, ptr, dst, src, sw) \
1433 OP((icode), ptr, iMACINT0, dst, C_00000000, src, sw);
1434 #define SWITCH(icode, ptr, dst, src, sw) \
1435 _SWITCH(icode, ptr, GPR(dst), GPR(src), GPR(sw))
1436 #define SWITCH_IN(icode, ptr, dst, src, sw) \
1437 _SWITCH(icode, ptr, GPR(dst), EXTIN(src), GPR(sw))
1438 #define _SWITCH_NEG(icode, ptr, dst, src) \
1439 OP((icode), ptr, iANDXOR, dst, src, C_00000001, C_00000001);
1440 #define SWITCH_NEG(icode, ptr, dst, src) \
1441 _SWITCH_NEG(icode, ptr, GPR(dst), GPR(src))
1444 static int __devinit _snd_emu10k1_init_efx(emu10k1_t *emu)
1446 int err, i, z, gpr, tmp, playback, capture;
1448 emu10k1_fx8010_code_t *icode;
1449 emu10k1_fx8010_pcm_t *ipcm = NULL;
1450 emu10k1_fx8010_control_gpr_t *controls = NULL, *ctl;
1453 spin_lock_init(&emu->fx8010.irq_lock);
1454 INIT_LIST_HEAD(&emu->fx8010.gpr_ctl);
1456 if ((icode = kcalloc(1, sizeof(*icode), GFP_KERNEL)) == NULL)
1458 if ((icode->gpr_map = kcalloc(256 + 160 + 160 + 2 * 512, sizeof(u_int32_t), GFP_KERNEL)) == NULL ||
1459 (controls = kcalloc(SND_EMU10K1_GPR_CONTROLS, sizeof(emu10k1_fx8010_control_gpr_t), GFP_KERNEL)) == NULL ||
1460 (ipcm = kcalloc(1, sizeof(*ipcm), GFP_KERNEL)) == NULL) {
1465 icode->tram_data_map = icode->gpr_map + 256;
1466 icode->tram_addr_map = icode->tram_data_map + 160;
1467 icode->code = icode->tram_addr_map + 160;
1469 /* clear free GPRs */
1470 for (i = 0; i < 256; i++)
1471 set_bit(i, icode->gpr_valid);
1473 /* clear TRAM data & address lines */
1474 for (i = 0; i < 160; i++)
1475 set_bit(i, icode->tram_valid);
1477 strcpy(icode->name, "SB Live! FX8010 code for ALSA v1.2 by Jaroslav Kysela");
1479 /* we have 10 inputs */
1480 playback = SND_EMU10K1_INPUTS;
1481 /* we have 6 playback channels and tone control doubles */
1482 capture = playback + (SND_EMU10K1_PLAYBACK_CHANNELS * 2);
1483 gpr = capture + SND_EMU10K1_CAPTURE_CHANNELS;
1484 tmp = 0x88; /* we need 4 temporary GPR */
1485 /* from 0x8c to 0xff is the area for tone control */
1487 /* stop FX processor */
1488 snd_emu10k1_ptr_write(emu, DBG, 0, (emu->fx8010.dbg = 0) | EMU10K1_DBG_SINGLE_STEP);
1493 OP(icode, &ptr, iMACINT0, GPR(0), C_00000000, FXBUS(FXBUS_PCM_LEFT), C_00000004);
1494 OP(icode, &ptr, iMACINT0, GPR(1), C_00000000, FXBUS(FXBUS_PCM_RIGHT), C_00000004);
1495 OP(icode, &ptr, iMACINT0, GPR(2), C_00000000, FXBUS(FXBUS_MIDI_LEFT), C_00000004);
1496 OP(icode, &ptr, iMACINT0, GPR(3), C_00000000, FXBUS(FXBUS_MIDI_RIGHT), C_00000004);
1497 OP(icode, &ptr, iMACINT0, GPR(4), C_00000000, FXBUS(FXBUS_PCM_LEFT_REAR), C_00000004);
1498 OP(icode, &ptr, iMACINT0, GPR(5), C_00000000, FXBUS(FXBUS_PCM_RIGHT_REAR), C_00000004);
1499 OP(icode, &ptr, iMACINT0, GPR(6), C_00000000, FXBUS(FXBUS_PCM_CENTER), C_00000004);
1500 OP(icode, &ptr, iMACINT0, GPR(7), C_00000000, FXBUS(FXBUS_PCM_LFE), C_00000004);
1501 OP(icode, &ptr, iMACINT0, GPR(8), C_00000000, C_00000000, C_00000000); /* S/PDIF left */
1502 OP(icode, &ptr, iMACINT0, GPR(9), C_00000000, C_00000000, C_00000000); /* S/PDIF right */
1504 /* Raw S/PDIF PCM */
1505 ipcm->substream = 0;
1507 ipcm->tram_start = 0;
1508 ipcm->buffer_size = (64 * 1024) / 2;
1509 ipcm->gpr_size = gpr++;
1510 ipcm->gpr_ptr = gpr++;
1511 ipcm->gpr_count = gpr++;
1512 ipcm->gpr_tmpcount = gpr++;
1513 ipcm->gpr_trigger = gpr++;
1514 ipcm->gpr_running = gpr++;
1518 icode->gpr_map[gpr + 0] = 0xfffff000;
1519 icode->gpr_map[gpr + 1] = 0xffff0000;
1520 icode->gpr_map[gpr + 2] = 0x70000000;
1521 icode->gpr_map[gpr + 3] = 0x00000007;
1522 icode->gpr_map[gpr + 4] = 0x001f << 11;
1523 icode->gpr_map[gpr + 5] = 0x001c << 11;
1524 icode->gpr_map[gpr + 6] = (0x22 - 0x01) - 1; /* skip at 01 to 22 */
1525 icode->gpr_map[gpr + 7] = (0x22 - 0x06) - 1; /* skip at 06 to 22 */
1526 icode->gpr_map[gpr + 8] = 0x2000000 + (2<<11);
1527 icode->gpr_map[gpr + 9] = 0x4000000 + (2<<11);
1528 icode->gpr_map[gpr + 10] = 1<<11;
1529 icode->gpr_map[gpr + 11] = (0x24 - 0x0a) - 1; /* skip at 0a to 24 */
1530 icode->gpr_map[gpr + 12] = 0;
1532 /* if the trigger flag is not set, skip */
1533 /* 00: */ OP(icode, &ptr, iMAC0, C_00000000, GPR(ipcm->gpr_trigger), C_00000000, C_00000000);
1534 /* 01: */ OP(icode, &ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_ZERO, GPR(gpr + 6));
1535 /* if the running flag is set, we're running */
1536 /* 02: */ OP(icode, &ptr, iMAC0, C_00000000, GPR(ipcm->gpr_running), C_00000000, C_00000000);
1537 /* 03: */ OP(icode, &ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, C_00000004);
1538 /* wait until ((GPR_DBAC>>11) & 0x1f) == 0x1c) */
1539 /* 04: */ OP(icode, &ptr, iANDXOR, GPR(tmp + 0), GPR_DBAC, GPR(gpr + 4), C_00000000);
1540 /* 05: */ OP(icode, &ptr, iMACINT0, C_00000000, GPR(tmp + 0), C_ffffffff, GPR(gpr + 5));
1541 /* 06: */ OP(icode, &ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, GPR(gpr + 7));
1542 /* 07: */ OP(icode, &ptr, iACC3, GPR(gpr + 12), C_00000010, C_00000001, C_00000000);
1544 /* 08: */ OP(icode, &ptr, iANDXOR, GPR(ipcm->gpr_running), GPR(ipcm->gpr_running), C_00000000, C_00000001);
1545 /* 09: */ OP(icode, &ptr, iACC3, GPR(gpr + 12), GPR(gpr + 12), C_ffffffff, C_00000000);
1546 /* 0a: */ OP(icode, &ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, GPR(gpr + 11));
1547 /* 0b: */ OP(icode, &ptr, iACC3, GPR(gpr + 12), C_00000001, C_00000000, C_00000000);
1549 /* 0c: */ OP(icode, &ptr, iANDXOR, GPR(tmp + 0), ETRAM_DATA(ipcm->etram[0]), GPR(gpr + 0), C_00000000);
1550 /* 0d: */ OP(icode, &ptr, iLOG, GPR(tmp + 0), GPR(tmp + 0), GPR(gpr + 3), C_00000000);
1551 /* 0e: */ OP(icode, &ptr, iANDXOR, GPR(8), GPR(tmp + 0), GPR(gpr + 1), GPR(gpr + 2));
1552 /* 0f: */ OP(icode, &ptr, iSKIP, C_00000000, GPR_COND, CC_REG_MINUS, C_00000001);
1553 /* 10: */ OP(icode, &ptr, iANDXOR, GPR(8), GPR(8), GPR(gpr + 1), GPR(gpr + 2));
1555 /* 11: */ OP(icode, &ptr, iANDXOR, GPR(tmp + 0), ETRAM_DATA(ipcm->etram[1]), GPR(gpr + 0), C_00000000);
1556 /* 12: */ OP(icode, &ptr, iLOG, GPR(tmp + 0), GPR(tmp + 0), GPR(gpr + 3), C_00000000);
1557 /* 13: */ OP(icode, &ptr, iANDXOR, GPR(9), GPR(tmp + 0), GPR(gpr + 1), GPR(gpr + 2));
1558 /* 14: */ OP(icode, &ptr, iSKIP, C_00000000, GPR_COND, CC_REG_MINUS, C_00000001);
1559 /* 15: */ OP(icode, &ptr, iANDXOR, GPR(9), GPR(9), GPR(gpr + 1), GPR(gpr + 2));
1561 /* 16: */ OP(icode, &ptr, iACC3, GPR(tmp + 0), GPR(ipcm->gpr_ptr), C_00000001, C_00000000);
1562 /* 17: */ OP(icode, &ptr, iMACINT0, C_00000000, GPR(tmp + 0), C_ffffffff, GPR(ipcm->gpr_size));
1563 /* 18: */ OP(icode, &ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_MINUS, C_00000001);
1564 /* 19: */ OP(icode, &ptr, iACC3, GPR(tmp + 0), C_00000000, C_00000000, C_00000000);
1565 /* 1a: */ OP(icode, &ptr, iACC3, GPR(ipcm->gpr_ptr), GPR(tmp + 0), C_00000000, C_00000000);
1567 /* 1b: */ OP(icode, &ptr, iACC3, GPR(ipcm->gpr_tmpcount), GPR(ipcm->gpr_tmpcount), C_ffffffff, C_00000000);
1568 /* 1c: */ OP(icode, &ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, C_00000002);
1569 /* 1d: */ OP(icode, &ptr, iACC3, GPR(ipcm->gpr_tmpcount), GPR(ipcm->gpr_count), C_00000000, C_00000000);
1570 /* 1e: */ OP(icode, &ptr, iACC3, GPR_IRQ, C_80000000, C_00000000, C_00000000);
1571 /* 1f: */ OP(icode, &ptr, iANDXOR, GPR(ipcm->gpr_running), GPR(ipcm->gpr_running), C_00000001, C_00010000);
1573 /* 20: */ OP(icode, &ptr, iANDXOR, GPR(ipcm->gpr_running), GPR(ipcm->gpr_running), C_00010000, C_00000001);
1574 /* 21: */ OP(icode, &ptr, iSKIP, C_00000000, C_7fffffff, C_7fffffff, C_00000002);
1576 /* 22: */ OP(icode, &ptr, iMACINT1, ETRAM_ADDR(ipcm->etram[0]), GPR(gpr + 8), GPR_DBAC, C_ffffffff);
1577 /* 23: */ OP(icode, &ptr, iMACINT1, ETRAM_ADDR(ipcm->etram[1]), GPR(gpr + 9), GPR_DBAC, C_ffffffff);
1582 /* Wave Playback Volume */
1583 for (z = 0; z < 2; z++)
1584 VOLUME(icode, &ptr, playback + z, z, gpr + z);
1585 snd_emu10k1_init_stereo_control(controls + i++, "Wave Playback Volume", gpr, 100);
1588 /* Wave Surround Playback Volume */
1589 for (z = 0; z < 2; z++)
1590 VOLUME(icode, &ptr, playback + 2 + z, z, gpr + z);
1591 snd_emu10k1_init_stereo_control(controls + i++, "Wave Surround Playback Volume", gpr, 0);
1594 /* Wave Center/LFE Playback Volume */
1595 OP(icode, &ptr, iACC3, GPR(tmp + 0), FXBUS(FXBUS_PCM_LEFT), FXBUS(FXBUS_PCM_RIGHT), C_00000000);
1596 OP(icode, &ptr, iMACINT0, GPR(tmp + 0), C_00000000, GPR(tmp + 0), C_00000002);
1597 VOLUME(icode, &ptr, playback + 4, tmp + 0, gpr);
1598 snd_emu10k1_init_mono_control(controls + i++, "Wave Center Playback Volume", gpr++, 0);
1599 VOLUME(icode, &ptr, playback + 5, tmp + 0, gpr);
1600 snd_emu10k1_init_mono_control(controls + i++, "Wave LFE Playback Volume", gpr++, 0);
1602 /* Wave Capture Volume + Switch */
1603 for (z = 0; z < 2; z++) {
1604 SWITCH(icode, &ptr, tmp + 0, z, gpr + 2 + z);
1605 VOLUME(icode, &ptr, capture + z, tmp + 0, gpr + z);
1607 snd_emu10k1_init_stereo_control(controls + i++, "Wave Capture Volume", gpr, 0);
1608 snd_emu10k1_init_stereo_onoff_control(controls + i++, "Wave Capture Switch", gpr + 2, 0);
1611 /* Music Playback Volume */
1612 for (z = 0; z < 2; z++)
1613 VOLUME_ADD(icode, &ptr, playback + z, 2 + z, gpr + z);
1614 snd_emu10k1_init_stereo_control(controls + i++, "Music Playback Volume", gpr, 100);
1617 /* Music Capture Volume + Switch */
1618 for (z = 0; z < 2; z++) {
1619 SWITCH(icode, &ptr, tmp + 0, 2 + z, gpr + 2 + z);
1620 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
1622 snd_emu10k1_init_stereo_control(controls + i++, "Music Capture Volume", gpr, 0);
1623 snd_emu10k1_init_stereo_onoff_control(controls + i++, "Music Capture Switch", gpr + 2, 0);
1626 /* Surround Digital Playback Volume (renamed later without Digital) */
1627 for (z = 0; z < 2; z++)
1628 VOLUME_ADD(icode, &ptr, playback + 2 + z, 4 + z, gpr + z);
1629 snd_emu10k1_init_stereo_control(controls + i++, "Surround Digital Playback Volume", gpr, 100);
1632 /* Surround Capture Volume + Switch */
1633 for (z = 0; z < 2; z++) {
1634 SWITCH(icode, &ptr, tmp + 0, 4 + z, gpr + 2 + z);
1635 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
1637 snd_emu10k1_init_stereo_control(controls + i++, "Surround Capture Volume", gpr, 0);
1638 snd_emu10k1_init_stereo_onoff_control(controls + i++, "Surround Capture Switch", gpr + 2, 0);
1641 /* Center Playback Volume (renamed later without Digital) */
1642 VOLUME_ADD(icode, &ptr, playback + 4, 6, gpr);
1643 snd_emu10k1_init_mono_control(controls + i++, "Center Digital Playback Volume", gpr++, 100);
1645 /* LFE Playback Volume + Switch (renamed later without Digital) */
1646 VOLUME_ADD(icode, &ptr, playback + 5, 7, gpr);
1647 snd_emu10k1_init_mono_control(controls + i++, "LFE Digital Playback Volume", gpr++, 100);
1653 if (emu->fx8010.extin_mask & ((1<<EXTIN_AC97_L)|(1<<EXTIN_AC97_R))) {
1654 /* AC'97 Playback Volume */
1655 VOLUME_ADDIN(icode, &ptr, playback + 0, EXTIN_AC97_L, gpr); gpr++;
1656 VOLUME_ADDIN(icode, &ptr, playback + 1, EXTIN_AC97_R, gpr); gpr++;
1657 snd_emu10k1_init_stereo_control(controls + i++, "AC97 Playback Volume", gpr-2, 0);
1658 /* AC'97 Capture Volume */
1659 VOLUME_ADDIN(icode, &ptr, capture + 0, EXTIN_AC97_L, gpr); gpr++;
1660 VOLUME_ADDIN(icode, &ptr, capture + 1, EXTIN_AC97_R, gpr); gpr++;
1661 snd_emu10k1_init_stereo_control(controls + i++, "AC97 Capture Volume", gpr-2, 100);
1664 if (emu->fx8010.extin_mask & ((1<<EXTIN_SPDIF_CD_L)|(1<<EXTIN_SPDIF_CD_R))) {
1665 /* IEC958 TTL Playback Volume */
1666 for (z = 0; z < 2; z++)
1667 VOLUME_ADDIN(icode, &ptr, playback + z, EXTIN_SPDIF_CD_L + z, gpr + z);
1668 snd_emu10k1_init_stereo_control(controls + i++, "IEC958 TTL Playback Volume", gpr, 0);
1671 /* IEC958 TTL Capture Volume + Switch */
1672 for (z = 0; z < 2; z++) {
1673 SWITCH_IN(icode, &ptr, tmp + 0, EXTIN_SPDIF_CD_L + z, gpr + 2 + z);
1674 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
1676 snd_emu10k1_init_stereo_control(controls + i++, "IEC958 TTL Capture Volume", gpr, 0);
1677 snd_emu10k1_init_stereo_onoff_control(controls + i++, "IEC958 TTL Capture Switch", gpr + 2, 0);
1681 if (emu->fx8010.extin_mask & ((1<<EXTIN_ZOOM_L)|(1<<EXTIN_ZOOM_R))) {
1682 /* Zoom Video Playback Volume */
1683 for (z = 0; z < 2; z++)
1684 VOLUME_ADDIN(icode, &ptr, playback + z, EXTIN_ZOOM_L + z, gpr + z);
1685 snd_emu10k1_init_stereo_control(controls + i++, "Zoom Video Playback Volume", gpr, 0);
1688 /* Zoom Video Capture Volume + Switch */
1689 for (z = 0; z < 2; z++) {
1690 SWITCH_IN(icode, &ptr, tmp + 0, EXTIN_ZOOM_L + z, gpr + 2 + z);
1691 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
1693 snd_emu10k1_init_stereo_control(controls + i++, "Zoom Video Capture Volume", gpr, 0);
1694 snd_emu10k1_init_stereo_onoff_control(controls + i++, "Zoom Video Capture Switch", gpr + 2, 0);
1698 if (emu->fx8010.extin_mask & ((1<<EXTIN_TOSLINK_L)|(1<<EXTIN_TOSLINK_R))) {
1699 /* IEC958 Optical Playback Volume */
1700 for (z = 0; z < 2; z++)
1701 VOLUME_ADDIN(icode, &ptr, playback + z, EXTIN_TOSLINK_L + z, gpr + z);
1702 snd_emu10k1_init_stereo_control(controls + i++, "IEC958 LiveDrive Playback Volume", gpr, 0);
1705 /* IEC958 Optical Capture Volume */
1706 for (z = 0; z < 2; z++) {
1707 SWITCH_IN(icode, &ptr, tmp + 0, EXTIN_TOSLINK_L + z, gpr + 2 + z);
1708 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
1710 snd_emu10k1_init_stereo_control(controls + i++, "IEC958 LiveDrive Capture Volume", gpr, 0);
1711 snd_emu10k1_init_stereo_onoff_control(controls + i++, "IEC958 LiveDrive Capture Switch", gpr + 2, 0);
1715 if (emu->fx8010.extin_mask & ((1<<EXTIN_LINE1_L)|(1<<EXTIN_LINE1_R))) {
1716 /* Line LiveDrive Playback Volume */
1717 for (z = 0; z < 2; z++)
1718 VOLUME_ADDIN(icode, &ptr, playback + z, EXTIN_LINE1_L + z, gpr + z);
1719 snd_emu10k1_init_stereo_control(controls + i++, "Line LiveDrive Playback Volume", gpr, 0);
1722 /* Line LiveDrive Capture Volume + Switch */
1723 for (z = 0; z < 2; z++) {
1724 SWITCH_IN(icode, &ptr, tmp + 0, EXTIN_LINE1_L + z, gpr + 2 + z);
1725 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
1727 snd_emu10k1_init_stereo_control(controls + i++, "Line LiveDrive Capture Volume", gpr, 0);
1728 snd_emu10k1_init_stereo_onoff_control(controls + i++, "Line LiveDrive Capture Switch", gpr + 2, 0);
1732 if (emu->fx8010.extin_mask & ((1<<EXTIN_COAX_SPDIF_L)|(1<<EXTIN_COAX_SPDIF_R))) {
1733 /* IEC958 Coax Playback Volume */
1734 for (z = 0; z < 2; z++)
1735 VOLUME_ADDIN(icode, &ptr, playback + z, EXTIN_COAX_SPDIF_L + z, gpr + z);
1736 snd_emu10k1_init_stereo_control(controls + i++, "IEC958 Coaxial Playback Volume", gpr, 0);
1739 /* IEC958 Coax Capture Volume + Switch */
1740 for (z = 0; z < 2; z++) {
1741 SWITCH_IN(icode, &ptr, tmp + 0, EXTIN_COAX_SPDIF_L + z, gpr + 2 + z);
1742 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
1744 snd_emu10k1_init_stereo_control(controls + i++, "IEC958 Coaxial Capture Volume", gpr, 0);
1745 snd_emu10k1_init_stereo_onoff_control(controls + i++, "IEC958 Coaxial Capture Switch", gpr + 2, 0);
1749 if (emu->fx8010.extin_mask & ((1<<EXTIN_LINE2_L)|(1<<EXTIN_LINE2_R))) {
1750 /* Line LiveDrive Playback Volume */
1751 for (z = 0; z < 2; z++)
1752 VOLUME_ADDIN(icode, &ptr, playback + z, EXTIN_LINE2_L + z, gpr + z);
1753 snd_emu10k1_init_stereo_control(controls + i++, "Line2 LiveDrive Playback Volume", gpr, 0);
1754 controls[i-1].id.index = 1;
1757 /* Line LiveDrive Capture Volume */
1758 for (z = 0; z < 2; z++) {
1759 SWITCH_IN(icode, &ptr, tmp + 0, EXTIN_LINE2_L + z, gpr + 2 + z);
1760 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
1762 snd_emu10k1_init_stereo_control(controls + i++, "Line2 LiveDrive Capture Volume", gpr, 0);
1763 controls[i-1].id.index = 1;
1764 snd_emu10k1_init_stereo_onoff_control(controls + i++, "Line2 LiveDrive Capture Switch", gpr + 2, 0);
1765 controls[i-1].id.index = 1;
1770 * Process tone control
1772 OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 0), GPR(playback + 0), C_00000000, C_00000000); /* left */
1773 OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 1), GPR(playback + 1), C_00000000, C_00000000); /* right */
1774 OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 2), GPR(playback + 2), C_00000000, C_00000000); /* rear left */
1775 OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 3), GPR(playback + 3), C_00000000, C_00000000); /* rear right */
1776 OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 4), GPR(playback + 4), C_00000000, C_00000000); /* center */
1777 OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 5), GPR(playback + 5), C_00000000, C_00000000); /* LFE */
1779 ctl = &controls[i + 0];
1780 ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1781 strcpy(ctl->id.name, "Tone Control - Bass");
1786 ctl->value[0] = ctl->value[1] = 20;
1787 ctl->translation = EMU10K1_GPR_TRANSLATION_BASS;
1788 ctl = &controls[i + 1];
1789 ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1790 strcpy(ctl->id.name, "Tone Control - Treble");
1795 ctl->value[0] = ctl->value[1] = 20;
1796 ctl->translation = EMU10K1_GPR_TRANSLATION_TREBLE;
1798 #define BASS_GPR 0x8c
1799 #define TREBLE_GPR 0x96
1801 for (z = 0; z < 5; z++) {
1803 for (j = 0; j < 2; j++) {
1804 controls[i + 0].gpr[z * 2 + j] = BASS_GPR + z * 2 + j;
1805 controls[i + 1].gpr[z * 2 + j] = TREBLE_GPR + z * 2 + j;
1808 for (z = 0; z < 3; z++) { /* front/rear/center-lfe */
1810 for (j = 0; j < 2; j++) { /* left/right */
1811 k = 0xa0 + (z * 8) + (j * 4);
1812 l = 0xd0 + (z * 8) + (j * 4);
1813 d = playback + SND_EMU10K1_PLAYBACK_CHANNELS + z * 2 + j;
1815 OP(icode, &ptr, iMAC0, C_00000000, C_00000000, GPR(d), GPR(BASS_GPR + 0 + j));
1816 OP(icode, &ptr, iMACMV, GPR(k+1), GPR(k), GPR(k+1), GPR(BASS_GPR + 4 + j));
1817 OP(icode, &ptr, iMACMV, GPR(k), GPR(d), GPR(k), GPR(BASS_GPR + 2 + j));
1818 OP(icode, &ptr, iMACMV, GPR(k+3), GPR(k+2), GPR(k+3), GPR(BASS_GPR + 8 + j));
1819 OP(icode, &ptr, iMAC0, GPR(k+2), GPR_ACCU, GPR(k+2), GPR(BASS_GPR + 6 + j));
1820 OP(icode, &ptr, iACC3, GPR(k+2), GPR(k+2), GPR(k+2), C_00000000);
1822 OP(icode, &ptr, iMAC0, C_00000000, C_00000000, GPR(k+2), GPR(TREBLE_GPR + 0 + j));
1823 OP(icode, &ptr, iMACMV, GPR(l+1), GPR(l), GPR(l+1), GPR(TREBLE_GPR + 4 + j));
1824 OP(icode, &ptr, iMACMV, GPR(l), GPR(k+2), GPR(l), GPR(TREBLE_GPR + 2 + j));
1825 OP(icode, &ptr, iMACMV, GPR(l+3), GPR(l+2), GPR(l+3), GPR(TREBLE_GPR + 8 + j));
1826 OP(icode, &ptr, iMAC0, GPR(l+2), GPR_ACCU, GPR(l+2), GPR(TREBLE_GPR + 6 + j));
1827 OP(icode, &ptr, iMACINT0, GPR(l+2), C_00000000, GPR(l+2), C_00000010);
1829 OP(icode, &ptr, iACC3, GPR(d), GPR(l+2), C_00000000, C_00000000);
1831 if (z == 2) /* center */
1840 for (z = 0; z < 6; z++) {
1841 SWITCH(icode, &ptr, tmp + 0, playback + SND_EMU10K1_PLAYBACK_CHANNELS + z, gpr + 0);
1842 SWITCH_NEG(icode, &ptr, tmp + 1, gpr + 0);
1843 SWITCH(icode, &ptr, tmp + 1, playback + z, tmp + 1);
1844 OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + z), GPR(tmp + 0), GPR(tmp + 1), C_00000000);
1846 snd_emu10k1_init_stereo_onoff_control(controls + i++, "Tone Control - Switch", gpr, 0);
1852 if (emu->fx8010.extout_mask & ((1<<EXTOUT_AC97_L)|(1<<EXTOUT_AC97_R))) {
1853 /* AC'97 Playback Volume */
1855 for (z = 0; z < 2; z++)
1856 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_AC97_L + z), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + z), C_00000000, C_00000000);
1859 if (emu->fx8010.extout_mask & ((1<<EXTOUT_TOSLINK_L)|(1<<EXTOUT_TOSLINK_R))) {
1860 /* IEC958 Optical Raw Playback Switch */
1862 for (z = 0; z < 2; z++) {
1863 SWITCH(icode, &ptr, tmp + 0, 8 + z, gpr + z);
1864 SWITCH_NEG(icode, &ptr, tmp + 1, gpr + z);
1865 SWITCH(icode, &ptr, tmp + 1, playback + SND_EMU10K1_PLAYBACK_CHANNELS + z, tmp + 1);
1866 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_TOSLINK_L + z), GPR(tmp + 0), GPR(tmp + 1), C_00000000);
1867 #ifdef EMU10K1_CAPTURE_DIGITAL_OUT
1868 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_ADC_CAP_L + z), GPR(tmp + 0), GPR(tmp + 1), C_00000000);
1872 snd_emu10k1_init_stereo_onoff_control(controls + i++, "IEC958 Optical Raw Playback Switch", gpr, 0);
1876 if (emu->fx8010.extout_mask & ((1<<EXTOUT_HEADPHONE_L)|(1<<EXTOUT_HEADPHONE_R))) {
1877 /* Headphone Playback Volume */
1879 for (z = 0; z < 2; z++) {
1880 SWITCH(icode, &ptr, tmp + 0, playback + SND_EMU10K1_PLAYBACK_CHANNELS + 4 + z, gpr + 2 + z);
1881 SWITCH_NEG(icode, &ptr, tmp + 1, gpr + 2 + z);
1882 SWITCH(icode, &ptr, tmp + 1, playback + SND_EMU10K1_PLAYBACK_CHANNELS + z, tmp + 1);
1883 OP(icode, &ptr, iACC3, GPR(tmp + 0), GPR(tmp + 0), GPR(tmp + 1), C_00000000);
1884 VOLUME_OUT(icode, &ptr, EXTOUT_HEADPHONE_L + z, tmp + 0, gpr + z);
1887 snd_emu10k1_init_stereo_control(controls + i++, "Headphone Playback Volume", gpr + 0, 0);
1888 controls[i-1].id.index = 1; /* AC'97 can have also Headphone control */
1889 snd_emu10k1_init_mono_onoff_control(controls + i++, "Headphone Center Playback Switch", gpr + 2, 0);
1890 controls[i-1].id.index = 1;
1891 snd_emu10k1_init_mono_onoff_control(controls + i++, "Headphone LFE Playback Switch", gpr + 3, 0);
1892 controls[i-1].id.index = 1;
1897 if (emu->fx8010.extout_mask & ((1<<EXTOUT_REAR_L)|(1<<EXTOUT_REAR_R)))
1898 for (z = 0; z < 2; z++)
1899 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_REAR_L + z), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 2 + z), C_00000000, C_00000000);
1901 if (emu->fx8010.extout_mask & ((1<<EXTOUT_AC97_REAR_L)|(1<<EXTOUT_AC97_REAR_R)))
1902 for (z = 0; z < 2; z++)
1903 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_AC97_REAR_L + z), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 2 + z), C_00000000, C_00000000);
1905 if (emu->fx8010.extout_mask & (1<<EXTOUT_AC97_CENTER)) {
1906 #ifndef EMU10K1_CENTER_LFE_FROM_FRONT
1907 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_AC97_CENTER), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 4), C_00000000, C_00000000);
1908 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_ACENTER), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 4), C_00000000, C_00000000);
1910 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_AC97_CENTER), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 0), C_00000000, C_00000000);
1911 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_ACENTER), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 0), C_00000000, C_00000000);
1915 if (emu->fx8010.extout_mask & (1<<EXTOUT_AC97_LFE)) {
1916 #ifndef EMU10K1_CENTER_LFE_FROM_FRONT
1917 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_AC97_LFE), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 5), C_00000000, C_00000000);
1918 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_ALFE), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 5), C_00000000, C_00000000);
1920 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_AC97_LFE), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 1), C_00000000, C_00000000);
1921 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_ALFE), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 1), C_00000000, C_00000000);
1925 #ifndef EMU10K1_CAPTURE_DIGITAL_OUT
1926 for (z = 0; z < 2; z++)
1927 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_ADC_CAP_L + z), GPR(capture + z), C_00000000, C_00000000);
1930 if (emu->fx8010.extout_mask & (1<<EXTOUT_MIC_CAP))
1931 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_MIC_CAP), GPR(capture + 2), C_00000000, C_00000000);
1938 if (i > SND_EMU10K1_GPR_CONTROLS) {
1944 /* clear remaining instruction memory */
1946 OP(icode, &ptr, iACC3, C_00000000, C_00000000, C_00000000, C_00000000);
1948 if ((err = snd_emu10k1_fx8010_tram_setup(emu, ipcm->buffer_size)) < 0)
1950 seg = snd_enter_user();
1951 icode->gpr_add_control_count = i;
1952 icode->gpr_add_controls = controls;
1953 err = snd_emu10k1_icode_poke(emu, icode);
1954 snd_leave_user(seg);
1956 err = snd_emu10k1_ipcm_poke(emu, ipcm);
1960 if (controls != NULL)
1962 if (icode != NULL) {
1963 if (icode->gpr_map != NULL)
1964 kfree(icode->gpr_map);
1970 int __devinit snd_emu10k1_init_efx(emu10k1_t *emu)
1973 return _snd_emu10k1_audigy_init_efx(emu);
1975 return _snd_emu10k1_init_efx(emu);
1978 void snd_emu10k1_free_efx(emu10k1_t *emu)
1980 /* stop processor */
1982 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg = A_DBG_SINGLE_STEP);
1984 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg = EMU10K1_DBG_SINGLE_STEP);
1987 #if 0 // FIXME: who use them?
1988 int snd_emu10k1_fx8010_tone_control_activate(emu10k1_t *emu, int output)
1990 snd_runtime_check(output >= 0 && output < 6, return -EINVAL);
1991 snd_emu10k1_ptr_write(emu, emu->gpr_base + 0x94 + output, 0, 1);
1995 int snd_emu10k1_fx8010_tone_control_deactivate(emu10k1_t *emu, int output)
1997 snd_runtime_check(output >= 0 && output < 6, return -EINVAL);
1998 snd_emu10k1_ptr_write(emu, emu->gpr_base + 0x94 + output, 0, 0);
2003 int snd_emu10k1_fx8010_tram_setup(emu10k1_t *emu, u32 size)
2007 /* size is in samples */
2009 size = (size - 1) >> 13;
2015 size = 0x2000 << size_reg;
2017 if ((emu->fx8010.etram_pages.bytes / 2) == size)
2019 spin_lock_irq(&emu->emu_lock);
2020 outl(HCFG_LOCKTANKCACHE_MASK | inl(emu->port + HCFG), emu->port + HCFG);
2021 spin_unlock_irq(&emu->emu_lock);
2022 snd_emu10k1_ptr_write(emu, TCB, 0, 0);
2023 snd_emu10k1_ptr_write(emu, TCBS, 0, 0);
2024 if (emu->fx8010.etram_pages.area != NULL) {
2025 snd_dma_free_pages(&emu->fx8010.etram_pages);
2026 emu->fx8010.etram_pages.area = NULL;
2027 emu->fx8010.etram_pages.bytes = 0;
2031 if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(emu->pci),
2032 size * 2, &emu->fx8010.etram_pages) < 0)
2034 memset(emu->fx8010.etram_pages.area, 0, size * 2);
2035 snd_emu10k1_ptr_write(emu, TCB, 0, emu->fx8010.etram_pages.addr);
2036 snd_emu10k1_ptr_write(emu, TCBS, 0, size_reg);
2037 spin_lock_irq(&emu->emu_lock);
2038 outl(inl(emu->port + HCFG) & ~HCFG_LOCKTANKCACHE_MASK, emu->port + HCFG);
2039 spin_unlock_irq(&emu->emu_lock);
2045 static int snd_emu10k1_fx8010_open(snd_hwdep_t * hw, struct file *file)
2050 static void copy_string(char *dst, char *src, char *null, int idx)
2053 sprintf(dst, "%s %02X", null, idx);
2058 static int snd_emu10k1_fx8010_info(emu10k1_t *emu, emu10k1_fx8010_info_t *info)
2060 char **fxbus, **extin, **extout;
2061 unsigned short fxbus_mask, extin_mask, extout_mask;
2064 memset(info, 0, sizeof(info));
2065 info->card = emu->card_type;
2066 info->internal_tram_size = emu->fx8010.itram_size;
2067 info->external_tram_size = emu->fx8010.etram_pages.bytes;
2069 extin = emu->audigy ? audigy_ins : creative_ins;
2070 extout = emu->audigy ? audigy_outs : creative_outs;
2071 fxbus_mask = emu->fx8010.fxbus_mask;
2072 extin_mask = emu->fx8010.extin_mask;
2073 extout_mask = emu->fx8010.extout_mask;
2074 for (res = 0; res < 16; res++, fxbus++, extin++, extout++) {
2075 copy_string(info->fxbus_names[res], fxbus_mask & (1 << res) ? *fxbus : NULL, "FXBUS", res);
2076 copy_string(info->extin_names[res], extin_mask & (1 << res) ? *extin : NULL, "Unused", res);
2077 copy_string(info->extout_names[res], extout_mask & (1 << res) ? *extout : NULL, "Unused", res);
2079 for (res = 16; res < 32; res++, extout++)
2080 copy_string(info->extout_names[res], extout_mask & (1 << res) ? *extout : NULL, "Unused", res);
2081 info->gpr_controls = emu->fx8010.gpr_count;
2085 static int snd_emu10k1_fx8010_ioctl(snd_hwdep_t * hw, struct file *file, unsigned int cmd, unsigned long arg)
2087 emu10k1_t *emu = hw->private_data;
2088 emu10k1_fx8010_info_t *info;
2089 emu10k1_fx8010_code_t *icode;
2090 emu10k1_fx8010_pcm_t *ipcm;
2092 void __user *argp = (void __user *)arg;
2096 case SNDRV_EMU10K1_IOCTL_INFO:
2097 info = (emu10k1_fx8010_info_t *)kmalloc(sizeof(*info), GFP_KERNEL);
2100 if ((res = snd_emu10k1_fx8010_info(emu, info)) < 0) {
2104 if (copy_to_user(argp, info, sizeof(*info))) {
2110 case SNDRV_EMU10K1_IOCTL_CODE_POKE:
2111 if (!capable(CAP_SYS_ADMIN))
2113 icode = (emu10k1_fx8010_code_t *)kmalloc(sizeof(*icode), GFP_KERNEL);
2116 if (copy_from_user(icode, argp, sizeof(*icode))) {
2120 res = snd_emu10k1_icode_poke(emu, icode);
2123 case SNDRV_EMU10K1_IOCTL_CODE_PEEK:
2124 icode = (emu10k1_fx8010_code_t *)kmalloc(sizeof(*icode), GFP_KERNEL);
2127 if (copy_from_user(icode, argp, sizeof(*icode))) {
2131 res = snd_emu10k1_icode_peek(emu, icode);
2132 if (res == 0 && copy_to_user(argp, icode, sizeof(*icode))) {
2138 case SNDRV_EMU10K1_IOCTL_PCM_POKE:
2139 ipcm = (emu10k1_fx8010_pcm_t *)kmalloc(sizeof(*ipcm), GFP_KERNEL);
2142 if (copy_from_user(ipcm, argp, sizeof(*ipcm))) {
2146 res = snd_emu10k1_ipcm_poke(emu, ipcm);
2149 case SNDRV_EMU10K1_IOCTL_PCM_PEEK:
2150 ipcm = kcalloc(1, sizeof(*ipcm), GFP_KERNEL);
2153 if (copy_from_user(ipcm, argp, sizeof(*ipcm))) {
2157 res = snd_emu10k1_ipcm_peek(emu, ipcm);
2158 if (res == 0 && copy_to_user(argp, ipcm, sizeof(*ipcm))) {
2164 case SNDRV_EMU10K1_IOCTL_TRAM_SETUP:
2165 if (!capable(CAP_SYS_ADMIN))
2167 if (get_user(addr, (unsigned int __user *)argp))
2169 down(&emu->fx8010.lock);
2170 res = snd_emu10k1_fx8010_tram_setup(emu, addr);
2171 up(&emu->fx8010.lock);
2173 case SNDRV_EMU10K1_IOCTL_STOP:
2174 if (!capable(CAP_SYS_ADMIN))
2177 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg |= A_DBG_SINGLE_STEP);
2179 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg |= EMU10K1_DBG_SINGLE_STEP);
2181 case SNDRV_EMU10K1_IOCTL_CONTINUE:
2182 if (!capable(CAP_SYS_ADMIN))
2185 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg = 0);
2187 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg = 0);
2189 case SNDRV_EMU10K1_IOCTL_ZERO_TRAM_COUNTER:
2190 if (!capable(CAP_SYS_ADMIN))
2193 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg | A_DBG_ZC);
2195 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg | EMU10K1_DBG_ZC);
2198 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg);
2200 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg);
2202 case SNDRV_EMU10K1_IOCTL_SINGLE_STEP:
2203 if (!capable(CAP_SYS_ADMIN))
2205 if (get_user(addr, (unsigned int __user *)argp))
2210 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg |= A_DBG_SINGLE_STEP | addr);
2212 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg |= EMU10K1_DBG_SINGLE_STEP | addr);
2215 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg |= A_DBG_SINGLE_STEP | A_DBG_STEP_ADDR | addr);
2217 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg |= EMU10K1_DBG_SINGLE_STEP | EMU10K1_DBG_STEP | addr);
2219 case SNDRV_EMU10K1_IOCTL_DBG_READ:
2221 addr = snd_emu10k1_ptr_read(emu, A_DBG, 0);
2223 addr = snd_emu10k1_ptr_read(emu, DBG, 0);
2224 if (put_user(addr, (unsigned int __user *)argp))
2231 static int snd_emu10k1_fx8010_release(snd_hwdep_t * hw, struct file *file)
2236 int __devinit snd_emu10k1_fx8010_new(emu10k1_t *emu, int device, snd_hwdep_t ** rhwdep)
2243 if ((err = snd_hwdep_new(emu->card, "FX8010", device, &hw)) < 0)
2245 strcpy(hw->name, "EMU10K1 (FX8010)");
2246 hw->iface = SNDRV_HWDEP_IFACE_EMU10K1;
2247 hw->ops.open = snd_emu10k1_fx8010_open;
2248 hw->ops.ioctl = snd_emu10k1_fx8010_ioctl;
2249 hw->ops.release = snd_emu10k1_fx8010_release;
2250 hw->private_data = emu;