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 ][0] = ((x & 0x3ff) << 10) | (y & 0x3ff);
474 icode->code[(*ptr)++][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 < 512, return);
484 set_bit(*ptr, icode->code_valid);
485 icode->code[*ptr ][0] = ((x & 0x7ff) << 12) | (y & 0x7ff);
486 icode->code[(*ptr)++][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 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 void snd_emu10k1_gpr_poke(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
508 for (gpr = 0; gpr < 0x100; gpr++) {
509 if (!test_bit(gpr, icode->gpr_valid))
511 snd_emu10k1_ptr_write(emu, emu->gpr_base + gpr, 0, icode->gpr_map[gpr]);
515 static void snd_emu10k1_gpr_peek(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
519 for (gpr = 0; gpr < 0x100; gpr++) {
520 set_bit(gpr, icode->gpr_valid);
521 icode->gpr_map[gpr] = snd_emu10k1_ptr_read(emu, emu->gpr_base + gpr, 0);
525 static void snd_emu10k1_tram_poke(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
529 for (tram = 0; tram < 0xa0; tram++) {
530 if (!test_bit(tram, icode->tram_valid))
532 snd_emu10k1_ptr_write(emu, TANKMEMDATAREGBASE + tram, 0, icode->tram_data_map[tram]);
533 snd_emu10k1_ptr_write(emu, TANKMEMADDRREGBASE + tram, 0, icode->tram_addr_map[tram]);
537 static void snd_emu10k1_tram_peek(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
541 memset(icode->tram_valid, 0, sizeof(icode->tram_valid));
542 for (tram = 0; tram < 0xa0; tram++) {
543 set_bit(tram, icode->tram_valid);
544 icode->tram_data_map[tram] = snd_emu10k1_ptr_read(emu, TANKMEMDATAREGBASE + tram, 0);
545 icode->tram_addr_map[tram] = snd_emu10k1_ptr_read(emu, TANKMEMADDRREGBASE + tram, 0);
549 static void snd_emu10k1_code_poke(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
553 for (pc = 0; pc < 512; pc++) {
554 if (!test_bit(pc, icode->code_valid))
556 snd_emu10k1_efx_write(emu, pc * 2, icode->code[pc][0]);
557 snd_emu10k1_efx_write(emu, pc * 2 + 1, icode->code[pc][1]);
561 static void snd_emu10k1_code_peek(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
565 memset(icode->code_valid, 0, sizeof(icode->code_valid));
566 for (pc = 0; pc < 512; pc++) {
567 set_bit(pc, icode->code_valid);
568 icode->code[pc][0] = snd_emu10k1_efx_read(emu, pc * 2);
569 icode->code[pc][1] = snd_emu10k1_efx_read(emu, pc * 2 + 1);
573 static snd_emu10k1_fx8010_ctl_t *snd_emu10k1_look_for_ctl(emu10k1_t *emu, snd_ctl_elem_id_t *id)
575 snd_emu10k1_fx8010_ctl_t *ctl;
576 snd_kcontrol_t *kcontrol;
577 struct list_head *list;
579 list_for_each(list, &emu->fx8010.gpr_ctl) {
580 ctl = emu10k1_gpr_ctl(list);
581 kcontrol = ctl->kcontrol;
582 if (kcontrol->id.iface == id->iface &&
583 !strcmp(kcontrol->id.name, id->name) &&
584 kcontrol->id.index == id->index)
590 static int snd_emu10k1_verify_controls(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
593 snd_ctl_elem_id_t __user *_id;
594 snd_ctl_elem_id_t id;
595 emu10k1_fx8010_control_gpr_t __user *_gctl;
596 emu10k1_fx8010_control_gpr_t gctl;
598 for (i = 0, _id = icode->gpr_del_controls;
599 i < icode->gpr_del_control_count; i++, _id++) {
600 if (copy_from_user(&id, _id, sizeof(id)))
602 if (snd_emu10k1_look_for_ctl(emu, &id) == NULL)
605 for (i = 0, _gctl = icode->gpr_add_controls;
606 i < icode->gpr_add_control_count; i++, _gctl++) {
607 if (copy_from_user(&gctl, _gctl, sizeof(gctl)))
609 if (snd_emu10k1_look_for_ctl(emu, &gctl.id))
611 down_read(&emu->card->controls_rwsem);
612 if (snd_ctl_find_id(emu->card, &gctl.id) != NULL) {
613 up_read(&emu->card->controls_rwsem);
616 up_read(&emu->card->controls_rwsem);
617 if (gctl.id.iface != SNDRV_CTL_ELEM_IFACE_MIXER &&
618 gctl.id.iface != SNDRV_CTL_ELEM_IFACE_PCM)
621 for (i = 0, _gctl = icode->gpr_list_controls;
622 i < icode->gpr_list_control_count; i++, _gctl++) {
623 /* FIXME: we need to check the WRITE access */
624 if (copy_from_user(&gctl, _gctl, sizeof(gctl)))
630 static void snd_emu10k1_ctl_private_free(snd_kcontrol_t *kctl)
632 snd_emu10k1_fx8010_ctl_t *ctl;
634 ctl = (snd_emu10k1_fx8010_ctl_t *)kctl->private_value;
635 kctl->private_value = 0;
636 list_del(&ctl->list);
640 static void snd_emu10k1_add_controls(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
643 emu10k1_fx8010_control_gpr_t __user *_gctl;
644 emu10k1_fx8010_control_gpr_t gctl;
645 snd_emu10k1_fx8010_ctl_t *ctl, nctl;
646 snd_kcontrol_new_t knew;
647 snd_kcontrol_t *kctl;
648 snd_ctl_elem_value_t *val;
650 val = (snd_ctl_elem_value_t *)kmalloc(sizeof(*val), GFP_KERNEL);
653 for (i = 0, _gctl = icode->gpr_add_controls;
654 i < icode->gpr_add_control_count; i++, _gctl++) {
655 if (copy_from_user(&gctl, _gctl, sizeof(gctl)))
657 snd_runtime_check(gctl.id.iface == SNDRV_CTL_ELEM_IFACE_MIXER ||
658 gctl.id.iface == SNDRV_CTL_ELEM_IFACE_PCM, continue);
659 snd_runtime_check(gctl.id.name[0] != '\0', continue);
660 ctl = snd_emu10k1_look_for_ctl(emu, &gctl.id);
661 memset(&knew, 0, sizeof(knew));
662 knew.iface = gctl.id.iface;
663 knew.name = gctl.id.name;
664 knew.index = gctl.id.index;
665 knew.device = gctl.id.device;
666 knew.subdevice = gctl.id.subdevice;
667 knew.info = snd_emu10k1_gpr_ctl_info;
668 knew.get = snd_emu10k1_gpr_ctl_get;
669 knew.put = snd_emu10k1_gpr_ctl_put;
670 memset(&nctl, 0, sizeof(nctl));
671 nctl.vcount = gctl.vcount;
672 nctl.count = gctl.count;
673 for (j = 0; j < 32; j++) {
674 nctl.gpr[j] = gctl.gpr[j];
675 nctl.value[j] = ~gctl.value[j]; /* inverted, we want to write new value in gpr_ctl_put() */
676 val->value.integer.value[j] = gctl.value[j];
680 nctl.translation = gctl.translation;
682 ctl = (snd_emu10k1_fx8010_ctl_t *)kmalloc(sizeof(*ctl), GFP_KERNEL);
685 knew.private_value = (unsigned long)ctl;
686 memcpy(ctl, &nctl, sizeof(nctl));
687 if (snd_ctl_add(emu->card, kctl = snd_ctl_new1(&knew, emu)) < 0) {
691 kctl->private_free = snd_emu10k1_ctl_private_free;
692 ctl->kcontrol = kctl;
693 list_add_tail(&ctl->list, &emu->fx8010.gpr_ctl);
696 nctl.list = ctl->list;
697 nctl.kcontrol = ctl->kcontrol;
698 memcpy(ctl, &nctl, sizeof(nctl));
699 snd_ctl_notify(emu->card, SNDRV_CTL_EVENT_MASK_VALUE |
700 SNDRV_CTL_EVENT_MASK_INFO, &ctl->kcontrol->id);
702 snd_emu10k1_gpr_ctl_put(ctl->kcontrol, val);
707 static void snd_emu10k1_del_controls(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
710 snd_ctl_elem_id_t id;
711 snd_ctl_elem_id_t __user *_id;
712 snd_emu10k1_fx8010_ctl_t *ctl;
713 snd_card_t *card = emu->card;
715 for (i = 0, _id = icode->gpr_del_controls;
716 i < icode->gpr_del_control_count; i++, _id++) {
717 snd_runtime_check(copy_from_user(&id, _id, sizeof(id)) == 0, continue);
718 down_write(&card->controls_rwsem);
719 ctl = snd_emu10k1_look_for_ctl(emu, &id);
721 snd_ctl_remove(card, ctl->kcontrol);
722 up_write(&card->controls_rwsem);
726 static int snd_emu10k1_list_controls(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
728 unsigned int i = 0, j;
729 unsigned int total = 0;
730 emu10k1_fx8010_control_gpr_t gctl;
731 emu10k1_fx8010_control_gpr_t __user *_gctl;
732 snd_emu10k1_fx8010_ctl_t *ctl;
733 snd_ctl_elem_id_t *id;
734 struct list_head *list;
736 _gctl = icode->gpr_list_controls;
737 list_for_each(list, &emu->fx8010.gpr_ctl) {
738 ctl = emu10k1_gpr_ctl(list);
740 if (_gctl && i < icode->gpr_list_control_count) {
741 memset(&gctl, 0, sizeof(gctl));
742 id = &ctl->kcontrol->id;
743 gctl.id.iface = id->iface;
744 strlcpy(gctl.id.name, id->name, sizeof(gctl.id.name));
745 gctl.id.index = id->index;
746 gctl.id.device = id->device;
747 gctl.id.subdevice = id->subdevice;
748 gctl.vcount = ctl->vcount;
749 gctl.count = ctl->count;
750 for (j = 0; j < 32; j++) {
751 gctl.gpr[j] = ctl->gpr[j];
752 gctl.value[j] = ctl->value[j];
756 gctl.translation = ctl->translation;
757 if (copy_to_user(_gctl, &gctl, sizeof(gctl)))
763 icode->gpr_list_control_total = total;
767 static int snd_emu10k1_icode_poke(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
771 down(&emu->fx8010.lock);
772 if ((err = snd_emu10k1_verify_controls(emu, icode)) < 0)
774 strlcpy(emu->fx8010.name, icode->name, sizeof(emu->fx8010.name));
775 /* stop FX processor - this may be dangerous, but it's better to miss
776 some samples than generate wrong ones - [jk] */
778 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg | A_DBG_SINGLE_STEP);
780 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg | EMU10K1_DBG_SINGLE_STEP);
781 /* ok, do the main job */
782 snd_emu10k1_del_controls(emu, icode);
783 snd_emu10k1_gpr_poke(emu, icode);
784 snd_emu10k1_tram_poke(emu, icode);
785 snd_emu10k1_code_poke(emu, icode);
786 snd_emu10k1_add_controls(emu, icode);
787 /* start FX processor when the DSP code is updated */
789 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg);
791 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg);
793 up(&emu->fx8010.lock);
797 static int snd_emu10k1_icode_peek(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
801 down(&emu->fx8010.lock);
802 strlcpy(icode->name, emu->fx8010.name, sizeof(icode->name));
803 /* ok, do the main job */
804 snd_emu10k1_gpr_peek(emu, icode);
805 snd_emu10k1_tram_peek(emu, icode);
806 snd_emu10k1_code_peek(emu, icode);
807 err = snd_emu10k1_list_controls(emu, icode);
808 up(&emu->fx8010.lock);
812 static int snd_emu10k1_ipcm_poke(emu10k1_t *emu, emu10k1_fx8010_pcm_t *ipcm)
816 snd_emu10k1_fx8010_pcm_t *pcm;
818 if (ipcm->substream >= EMU10K1_FX8010_PCM_COUNT)
820 if (ipcm->channels > 32)
822 pcm = &emu->fx8010.pcm[ipcm->substream];
823 down(&emu->fx8010.lock);
824 spin_lock_irq(&emu->reg_lock);
829 if (ipcm->channels == 0) { /* remove */
832 /* FIXME: we need to add universal code to the PCM transfer routine */
833 if (ipcm->channels != 2) {
839 pcm->channels = ipcm->channels;
840 pcm->tram_start = ipcm->tram_start;
841 pcm->buffer_size = ipcm->buffer_size;
842 pcm->gpr_size = ipcm->gpr_size;
843 pcm->gpr_count = ipcm->gpr_count;
844 pcm->gpr_tmpcount = ipcm->gpr_tmpcount;
845 pcm->gpr_ptr = ipcm->gpr_ptr;
846 pcm->gpr_trigger = ipcm->gpr_trigger;
847 pcm->gpr_running = ipcm->gpr_running;
848 for (i = 0; i < pcm->channels; i++)
849 pcm->etram[i] = ipcm->etram[i];
852 spin_unlock_irq(&emu->reg_lock);
853 up(&emu->fx8010.lock);
857 static int snd_emu10k1_ipcm_peek(emu10k1_t *emu, emu10k1_fx8010_pcm_t *ipcm)
861 snd_emu10k1_fx8010_pcm_t *pcm;
863 if (ipcm->substream >= EMU10K1_FX8010_PCM_COUNT)
865 pcm = &emu->fx8010.pcm[ipcm->substream];
866 down(&emu->fx8010.lock);
867 spin_lock_irq(&emu->reg_lock);
868 ipcm->channels = pcm->channels;
869 ipcm->tram_start = pcm->tram_start;
870 ipcm->buffer_size = pcm->buffer_size;
871 ipcm->gpr_size = pcm->gpr_size;
872 ipcm->gpr_ptr = pcm->gpr_ptr;
873 ipcm->gpr_count = pcm->gpr_count;
874 ipcm->gpr_tmpcount = pcm->gpr_tmpcount;
875 ipcm->gpr_trigger = pcm->gpr_trigger;
876 ipcm->gpr_running = pcm->gpr_running;
877 for (i = 0; i < pcm->channels; i++)
878 ipcm->etram[i] = pcm->etram[i];
879 ipcm->res1 = ipcm->res2 = 0;
881 spin_unlock_irq(&emu->reg_lock);
882 up(&emu->fx8010.lock);
886 #define SND_EMU10K1_GPR_CONTROLS 41
887 #define SND_EMU10K1_INPUTS 10
888 #define SND_EMU10K1_PLAYBACK_CHANNELS 8
889 #define SND_EMU10K1_CAPTURE_CHANNELS 4
891 static void __devinit snd_emu10k1_init_mono_control(emu10k1_fx8010_control_gpr_t *ctl, const char *name, int gpr, int defval)
893 ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
894 strcpy(ctl->id.name, name);
895 ctl->vcount = ctl->count = 1;
896 ctl->gpr[0] = gpr + 0; ctl->value[0] = defval;
899 ctl->translation = EMU10K1_GPR_TRANSLATION_TABLE100;
902 static void __devinit snd_emu10k1_init_stereo_control(emu10k1_fx8010_control_gpr_t *ctl, const char *name, int gpr, int defval)
904 ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
905 strcpy(ctl->id.name, name);
906 ctl->vcount = ctl->count = 2;
907 ctl->gpr[0] = gpr + 0; ctl->value[0] = defval;
908 ctl->gpr[1] = gpr + 1; ctl->value[1] = defval;
911 ctl->translation = EMU10K1_GPR_TRANSLATION_TABLE100;
914 static void __devinit snd_emu10k1_init_mono_onoff_control(emu10k1_fx8010_control_gpr_t *ctl, const char *name, int gpr, int defval)
916 ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
917 strcpy(ctl->id.name, name);
918 ctl->vcount = ctl->count = 1;
919 ctl->gpr[0] = gpr + 0; ctl->value[0] = defval;
922 ctl->translation = EMU10K1_GPR_TRANSLATION_ONOFF;
925 static void __devinit snd_emu10k1_init_stereo_onoff_control(emu10k1_fx8010_control_gpr_t *ctl, const char *name, int gpr, int defval)
927 ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
928 strcpy(ctl->id.name, name);
929 ctl->vcount = ctl->count = 2;
930 ctl->gpr[0] = gpr + 0; ctl->value[0] = defval;
931 ctl->gpr[1] = gpr + 1; ctl->value[1] = defval;
934 ctl->translation = EMU10K1_GPR_TRANSLATION_ONOFF;
939 * initial DSP configuration for Audigy
942 static int __devinit _snd_emu10k1_audigy_init_efx(emu10k1_t *emu)
944 int err, i, z, gpr, nctl;
945 const int playback = 10;
946 const int capture = playback + (SND_EMU10K1_PLAYBACK_CHANNELS * 2); /* we reserve 10 voices */
947 const int stereo_mix = capture + 2;
948 const int tmp = 0x88;
950 emu10k1_fx8010_code_t *icode;
951 emu10k1_fx8010_control_gpr_t *controls, *ctl;
954 spin_lock_init(&emu->fx8010.irq_lock);
955 INIT_LIST_HEAD(&emu->fx8010.gpr_ctl);
957 if ((icode = kcalloc(1, sizeof(*icode), GFP_KERNEL)) == NULL)
959 if ((controls = kcalloc(SND_EMU10K1_GPR_CONTROLS, sizeof(*controls), GFP_KERNEL)) == NULL) {
964 /* clear free GPRs */
965 for (i = 0; i < 256; i++)
966 set_bit(i, icode->gpr_valid);
968 strcpy(icode->name, "Audigy DSP code for ALSA");
971 gpr = stereo_mix + 10;
973 /* stop FX processor */
974 snd_emu10k1_ptr_write(emu, A_DBG, 0, (emu->fx8010.dbg = 0) | A_DBG_SINGLE_STEP);
976 /* PCM front Playback Volume (independent from stereo mix) */
977 A_OP(icode, &ptr, iMAC0, A_GPR(playback), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LEFT_FRONT));
978 A_OP(icode, &ptr, iMAC0, A_GPR(playback+1), A_C_00000000, A_GPR(gpr+1), A_FXBUS(FXBUS_PCM_RIGHT_FRONT));
979 snd_emu10k1_init_stereo_control(&controls[nctl++], "PCM Front Playback Volume", gpr, 100);
982 /* PCM Surround Playback (independent from stereo mix) */
983 A_OP(icode, &ptr, iMAC0, A_GPR(playback+2), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LEFT_REAR));
984 A_OP(icode, &ptr, iMAC0, A_GPR(playback+3), A_C_00000000, A_GPR(gpr+1), A_FXBUS(FXBUS_PCM_RIGHT_REAR));
985 snd_emu10k1_init_stereo_control(&controls[nctl++], "PCM Surround Playback Volume", gpr, 100);
988 /* PCM Side Playback (independent from stereo mix) */
990 A_OP(icode, &ptr, iMAC0, A_GPR(playback+6), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LEFT_SIDE));
991 A_OP(icode, &ptr, iMAC0, A_GPR(playback+7), A_C_00000000, A_GPR(gpr+1), A_FXBUS(FXBUS_PCM_RIGHT_SIDE));
992 snd_emu10k1_init_stereo_control(&controls[nctl++], "PCM Side Playback Volume", gpr, 100);
996 /* PCM Center Playback (independent from stereo mix) */
997 A_OP(icode, &ptr, iMAC0, A_GPR(playback+4), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_CENTER));
998 snd_emu10k1_init_mono_control(&controls[nctl++], "PCM Center Playback Volume", gpr, 100);
1001 /* PCM LFE Playback (independent from stereo mix) */
1002 A_OP(icode, &ptr, iMAC0, A_GPR(playback+5), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LFE));
1003 snd_emu10k1_init_mono_control(&controls[nctl++], "PCM LFE Playback Volume", gpr, 100);
1009 /* Wave (PCM) Playback Volume (will be renamed later) */
1010 A_OP(icode, &ptr, iMAC0, A_GPR(stereo_mix), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LEFT));
1011 A_OP(icode, &ptr, iMAC0, A_GPR(stereo_mix+1), A_C_00000000, A_GPR(gpr+1), A_FXBUS(FXBUS_PCM_RIGHT));
1012 snd_emu10k1_init_stereo_control(&controls[nctl++], "Wave Playback Volume", gpr, 100);
1015 /* Music Playback */
1016 A_OP(icode, &ptr, iMAC0, A_GPR(stereo_mix+0), A_GPR(stereo_mix+0), A_GPR(gpr), A_FXBUS(FXBUS_MIDI_LEFT));
1017 A_OP(icode, &ptr, iMAC0, A_GPR(stereo_mix+1), A_GPR(stereo_mix+1), A_GPR(gpr+1), A_FXBUS(FXBUS_MIDI_RIGHT));
1018 snd_emu10k1_init_stereo_control(&controls[nctl++], "Music Playback Volume", gpr, 100);
1021 /* Wave (PCM) Capture */
1022 A_OP(icode, &ptr, iMAC0, A_GPR(capture+0), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LEFT));
1023 A_OP(icode, &ptr, iMAC0, A_GPR(capture+1), A_C_00000000, A_GPR(gpr+1), A_FXBUS(FXBUS_PCM_RIGHT));
1024 snd_emu10k1_init_stereo_control(&controls[nctl++], "PCM Capture Volume", gpr, 0);
1028 A_OP(icode, &ptr, iMAC0, A_GPR(capture+0), A_GPR(capture+0), A_GPR(gpr), A_FXBUS(FXBUS_MIDI_LEFT));
1029 A_OP(icode, &ptr, iMAC0, A_GPR(capture+1), A_GPR(capture+1), A_GPR(gpr+1), A_FXBUS(FXBUS_MIDI_RIGHT));
1030 snd_emu10k1_init_stereo_control(&controls[nctl++], "Music Capture Volume", gpr, 0);
1036 #define A_ADD_VOLUME_IN(var,vol,input) \
1037 A_OP(icode, &ptr, iMAC0, A_GPR(var), A_GPR(var), A_GPR(vol), A_EXTIN(input))
1039 /* AC'97 Playback Volume - used only for mic (renamed later) */
1040 A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_AC97_L);
1041 A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_AC97_R);
1042 snd_emu10k1_init_stereo_control(&controls[nctl++], "AMic Playback Volume", gpr, 0);
1044 /* AC'97 Capture Volume - used only for mic */
1045 A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_AC97_L);
1046 A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_AC97_R);
1047 snd_emu10k1_init_stereo_control(&controls[nctl++], "Mic Capture Volume", gpr, 0);
1050 /* mic capture buffer */
1051 A_OP(icode, &ptr, iINTERP, A_EXTOUT(A_EXTOUT_MIC_CAP), A_EXTIN(A_EXTIN_AC97_L), 0xcd, A_EXTIN(A_EXTIN_AC97_R));
1053 /* Audigy CD Playback Volume */
1054 A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_SPDIF_CD_L);
1055 A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_SPDIF_CD_R);
1056 snd_emu10k1_init_stereo_control(&controls[nctl++],
1057 emu->no_ac97 ? "CD Playback Volume" : "Audigy CD Playback Volume",
1060 /* Audigy CD Capture Volume */
1061 A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_SPDIF_CD_L);
1062 A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_SPDIF_CD_R);
1063 snd_emu10k1_init_stereo_control(&controls[nctl++],
1064 emu->no_ac97 ? "CD Capture Volume" : "Audigy CD Capture Volume",
1068 /* Optical SPDIF Playback Volume */
1069 A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_OPT_SPDIF_L);
1070 A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_OPT_SPDIF_R);
1071 snd_emu10k1_init_stereo_control(&controls[nctl++], "IEC958 Optical Playback Volume", gpr, 0);
1073 /* Optical SPDIF Capture Volume */
1074 A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_OPT_SPDIF_L);
1075 A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_OPT_SPDIF_R);
1076 snd_emu10k1_init_stereo_control(&controls[nctl++], "IEC958 Optical Capture Volume", gpr, 0);
1079 /* Line2 Playback Volume */
1080 A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_LINE2_L);
1081 A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_LINE2_R);
1082 snd_emu10k1_init_stereo_control(&controls[nctl++],
1083 emu->no_ac97 ? "Line Playback Volume" : "Line2 Playback Volume",
1086 /* Line2 Capture Volume */
1087 A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_LINE2_L);
1088 A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_LINE2_R);
1089 snd_emu10k1_init_stereo_control(&controls[nctl++],
1090 emu->no_ac97 ? "Line Capture Volume" : "Line2 Capture Volume",
1094 /* Philips ADC Playback Volume */
1095 A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_ADC_L);
1096 A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_ADC_R);
1097 snd_emu10k1_init_stereo_control(&controls[nctl++], "Analog Mix Playback Volume", gpr, 0);
1099 /* Philips ADC Capture Volume */
1100 A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_ADC_L);
1101 A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_ADC_R);
1102 snd_emu10k1_init_stereo_control(&controls[nctl++], "Analog Mix Capture Volume", gpr, 0);
1105 /* Aux2 Playback Volume */
1106 A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_AUX2_L);
1107 A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_AUX2_R);
1108 snd_emu10k1_init_stereo_control(&controls[nctl++],
1109 emu->no_ac97 ? "Aux Playback Volume" : "Aux2 Playback Volume",
1112 /* Aux2 Capture Volume */
1113 A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_AUX2_L);
1114 A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_AUX2_R);
1115 snd_emu10k1_init_stereo_control(&controls[nctl++],
1116 emu->no_ac97 ? "Aux Capture Volume" : "Aux2 Capture Volume",
1120 /* Stereo Mix Front Playback Volume */
1121 A_OP(icode, &ptr, iMAC0, A_GPR(playback), A_GPR(playback), A_GPR(gpr), A_GPR(stereo_mix));
1122 A_OP(icode, &ptr, iMAC0, A_GPR(playback+1), A_GPR(playback+1), A_GPR(gpr+1), A_GPR(stereo_mix+1));
1123 snd_emu10k1_init_stereo_control(&controls[nctl++], "Front Playback Volume", gpr, 100);
1126 /* Stereo Mix Surround Playback */
1127 A_OP(icode, &ptr, iMAC0, A_GPR(playback+2), A_GPR(playback+2), A_GPR(gpr), A_GPR(stereo_mix));
1128 A_OP(icode, &ptr, iMAC0, A_GPR(playback+3), A_GPR(playback+3), A_GPR(gpr+1), A_GPR(stereo_mix+1));
1129 snd_emu10k1_init_stereo_control(&controls[nctl++], "Surround Playback Volume", gpr, 0);
1132 /* Stereo Mix Center Playback */
1133 /* Center = sub = Left/2 + Right/2 */
1134 A_OP(icode, &ptr, iINTERP, A_GPR(tmp), A_GPR(stereo_mix), 0xcd, A_GPR(stereo_mix+1));
1135 A_OP(icode, &ptr, iMAC0, A_GPR(playback+4), A_GPR(playback+4), A_GPR(gpr), A_GPR(tmp));
1136 snd_emu10k1_init_mono_control(&controls[nctl++], "Center Playback Volume", gpr, 0);
1139 /* Stereo Mix LFE Playback */
1140 A_OP(icode, &ptr, iMAC0, A_GPR(playback+5), A_GPR(playback+5), A_GPR(gpr), A_GPR(tmp));
1141 snd_emu10k1_init_mono_control(&controls[nctl++], "LFE Playback Volume", gpr, 0);
1145 /* Stereo Mix Side Playback */
1146 A_OP(icode, &ptr, iMAC0, A_GPR(playback+6), A_GPR(playback+6), A_GPR(gpr), A_GPR(stereo_mix));
1147 A_OP(icode, &ptr, iMAC0, A_GPR(playback+7), A_GPR(playback+7), A_GPR(gpr+1), A_GPR(stereo_mix+1));
1148 snd_emu10k1_init_stereo_control(&controls[nctl++], "Side Playback Volume", gpr, 0);
1155 #define A_PUT_OUTPUT(out,src) A_OP(icode, &ptr, iACC3, A_EXTOUT(out), A_C_00000000, A_C_00000000, A_GPR(src))
1156 #define A_PUT_STEREO_OUTPUT(out1,out2,src) \
1157 {A_PUT_OUTPUT(out1,src); A_PUT_OUTPUT(out2,src+1);}
1159 #define _A_SWITCH(icode, ptr, dst, src, sw) \
1160 A_OP((icode), ptr, iMACINT0, dst, A_C_00000000, src, sw);
1161 #define A_SWITCH(icode, ptr, dst, src, sw) \
1162 _A_SWITCH(icode, ptr, A_GPR(dst), A_GPR(src), A_GPR(sw))
1163 #define _A_SWITCH_NEG(icode, ptr, dst, src) \
1164 A_OP((icode), ptr, iANDXOR, dst, src, A_C_00000001, A_C_00000001);
1165 #define A_SWITCH_NEG(icode, ptr, dst, src) \
1166 _A_SWITCH_NEG(icode, ptr, A_GPR(dst), A_GPR(src))
1170 * Process tone control
1172 A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 0), A_GPR(playback + 0), A_C_00000000, A_C_00000000); /* left */
1173 A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 1), A_GPR(playback + 1), A_C_00000000, A_C_00000000); /* right */
1174 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 */
1175 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 */
1176 A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 4), A_GPR(playback + 4), A_C_00000000, A_C_00000000); /* center */
1177 A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 5), A_GPR(playback + 5), A_C_00000000, A_C_00000000); /* LFE */
1179 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 */
1180 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 */
1184 ctl = &controls[nctl + 0];
1185 ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1186 strcpy(ctl->id.name, "Tone Control - Bass");
1191 ctl->value[0] = ctl->value[1] = 20;
1192 ctl->translation = EMU10K1_GPR_TRANSLATION_BASS;
1193 ctl = &controls[nctl + 1];
1194 ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1195 strcpy(ctl->id.name, "Tone Control - Treble");
1200 ctl->value[0] = ctl->value[1] = 20;
1201 ctl->translation = EMU10K1_GPR_TRANSLATION_TREBLE;
1203 #define BASS_GPR 0x8c
1204 #define TREBLE_GPR 0x96
1206 for (z = 0; z < 5; z++) {
1208 for (j = 0; j < 2; j++) {
1209 controls[nctl + 0].gpr[z * 2 + j] = BASS_GPR + z * 2 + j;
1210 controls[nctl + 1].gpr[z * 2 + j] = TREBLE_GPR + z * 2 + j;
1213 for (z = 0; z < 4; z++) { /* front/rear/center-lfe/side */
1215 for (j = 0; j < 2; j++) { /* left/right */
1216 k = 0xb0 + (z * 8) + (j * 4);
1217 l = 0xe0 + (z * 8) + (j * 4);
1218 d = playback + SND_EMU10K1_PLAYBACK_CHANNELS + z * 2 + j;
1220 A_OP(icode, &ptr, iMAC0, A_C_00000000, A_C_00000000, A_GPR(d), A_GPR(BASS_GPR + 0 + j));
1221 A_OP(icode, &ptr, iMACMV, A_GPR(k+1), A_GPR(k), A_GPR(k+1), A_GPR(BASS_GPR + 4 + j));
1222 A_OP(icode, &ptr, iMACMV, A_GPR(k), A_GPR(d), A_GPR(k), A_GPR(BASS_GPR + 2 + j));
1223 A_OP(icode, &ptr, iMACMV, A_GPR(k+3), A_GPR(k+2), A_GPR(k+3), A_GPR(BASS_GPR + 8 + j));
1224 A_OP(icode, &ptr, iMAC0, A_GPR(k+2), A_GPR_ACCU, A_GPR(k+2), A_GPR(BASS_GPR + 6 + j));
1225 A_OP(icode, &ptr, iACC3, A_GPR(k+2), A_GPR(k+2), A_GPR(k+2), A_C_00000000);
1227 A_OP(icode, &ptr, iMAC0, A_C_00000000, A_C_00000000, A_GPR(k+2), A_GPR(TREBLE_GPR + 0 + j));
1228 A_OP(icode, &ptr, iMACMV, A_GPR(l+1), A_GPR(l), A_GPR(l+1), A_GPR(TREBLE_GPR + 4 + j));
1229 A_OP(icode, &ptr, iMACMV, A_GPR(l), A_GPR(k+2), A_GPR(l), A_GPR(TREBLE_GPR + 2 + j));
1230 A_OP(icode, &ptr, iMACMV, A_GPR(l+3), A_GPR(l+2), A_GPR(l+3), A_GPR(TREBLE_GPR + 8 + j));
1231 A_OP(icode, &ptr, iMAC0, A_GPR(l+2), A_GPR_ACCU, A_GPR(l+2), A_GPR(TREBLE_GPR + 6 + j));
1232 A_OP(icode, &ptr, iMACINT0, A_GPR(l+2), A_C_00000000, A_GPR(l+2), A_C_00000010);
1234 A_OP(icode, &ptr, iACC3, A_GPR(d), A_GPR(l+2), A_C_00000000, A_C_00000000);
1236 if (z == 2) /* center */
1245 for (z = 0; z < 8; z++) {
1246 A_SWITCH(icode, &ptr, tmp + 0, playback + SND_EMU10K1_PLAYBACK_CHANNELS + z, gpr + 0);
1247 A_SWITCH_NEG(icode, &ptr, tmp + 1, gpr + 0);
1248 A_SWITCH(icode, &ptr, tmp + 1, playback + z, tmp + 1);
1249 A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + z), A_GPR(tmp + 0), A_GPR(tmp + 1), A_C_00000000);
1251 snd_emu10k1_init_stereo_onoff_control(controls + nctl++, "Tone Control - Switch", gpr, 0);
1254 /* Master volume (will be renamed later) */
1255 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));
1256 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));
1257 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));
1258 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));
1259 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));
1260 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));
1261 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));
1262 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));
1263 snd_emu10k1_init_mono_control(&controls[nctl++], "Wave Master Playback Volume", gpr, 0);
1266 /* analog speakers */
1267 A_PUT_STEREO_OUTPUT(A_EXTOUT_AFRONT_L, A_EXTOUT_AFRONT_R, playback + SND_EMU10K1_PLAYBACK_CHANNELS);
1268 A_PUT_STEREO_OUTPUT(A_EXTOUT_AREAR_L, A_EXTOUT_AREAR_R, playback+2 + SND_EMU10K1_PLAYBACK_CHANNELS);
1269 A_PUT_OUTPUT(A_EXTOUT_ACENTER, playback+4 + SND_EMU10K1_PLAYBACK_CHANNELS);
1270 A_PUT_OUTPUT(A_EXTOUT_ALFE, playback+5 + SND_EMU10K1_PLAYBACK_CHANNELS);
1272 A_PUT_STEREO_OUTPUT(A_EXTOUT_ASIDE_L, A_EXTOUT_ASIDE_R, playback+6 + SND_EMU10K1_PLAYBACK_CHANNELS);
1275 A_PUT_STEREO_OUTPUT(A_EXTOUT_HEADPHONE_L, A_EXTOUT_HEADPHONE_R, playback + SND_EMU10K1_PLAYBACK_CHANNELS);
1277 /* digital outputs */
1278 /* A_PUT_STEREO_OUTPUT(A_EXTOUT_FRONT_L, A_EXTOUT_FRONT_R, playback + SND_EMU10K1_PLAYBACK_CHANNELS); */
1280 /* IEC958 Optical Raw Playback Switch */
1281 icode->gpr_map[gpr++] = 0x1008;
1282 icode->gpr_map[gpr++] = 0xffff0000;
1283 for (z = 0; z < 2; z++) {
1284 A_OP(icode, &ptr, iMAC0, A_GPR(tmp + 2), A_FXBUS(FXBUS_PT_LEFT + z), A_C_00000000, A_C_00000000);
1285 A_OP(icode, &ptr, iSKIP, A_GPR_COND, A_GPR_COND, A_GPR(gpr - 2), A_C_00000001);
1286 A_OP(icode, &ptr, iACC3, A_GPR(tmp + 2), A_C_00000000, A_C_00010000, A_GPR(tmp + 2));
1287 A_OP(icode, &ptr, iANDXOR, A_GPR(tmp + 2), A_GPR(tmp + 2), A_GPR(gpr - 1), A_C_00000000);
1288 A_SWITCH(icode, &ptr, tmp + 0, tmp + 2, gpr + z);
1289 A_SWITCH_NEG(icode, &ptr, tmp + 1, gpr + z);
1290 A_SWITCH(icode, &ptr, tmp + 1, playback + SND_EMU10K1_PLAYBACK_CHANNELS + z, tmp + 1);
1291 A_OP(icode, &ptr, iACC3, A_EXTOUT(A_EXTOUT_FRONT_L + z), A_GPR(tmp + 0), A_GPR(tmp + 1), A_C_00000000);
1293 snd_emu10k1_init_stereo_onoff_control(controls + nctl++, "IEC958 Optical Raw Playback Switch", gpr, 0);
1296 A_PUT_STEREO_OUTPUT(A_EXTOUT_REAR_L, A_EXTOUT_REAR_R, playback+2 + SND_EMU10K1_PLAYBACK_CHANNELS);
1297 A_PUT_OUTPUT(A_EXTOUT_CENTER, playback+4 + SND_EMU10K1_PLAYBACK_CHANNELS);
1298 A_PUT_OUTPUT(A_EXTOUT_LFE, playback+5 + SND_EMU10K1_PLAYBACK_CHANNELS);
1301 A_PUT_OUTPUT(A_EXTOUT_ADC_CAP_L, capture);
1302 A_PUT_OUTPUT(A_EXTOUT_ADC_CAP_R, capture+1);
1313 /* clear remaining instruction memory */
1315 A_OP(icode, &ptr, 0x0f, 0xc0, 0xc0, 0xcf, 0xc0);
1317 seg = snd_enter_user();
1318 icode->gpr_add_control_count = nctl;
1319 icode->gpr_add_controls = controls;
1320 err = snd_emu10k1_icode_poke(emu, icode);
1321 snd_leave_user(seg);
1331 * initial DSP configuration for Emu10k1
1334 /* when volume = max, then copy only to avoid volume modification */
1335 /* with iMAC0 (negative values) */
1336 static void __devinit _volume(emu10k1_fx8010_code_t *icode, u32 *ptr, u32 dst, u32 src, u32 vol)
1338 OP(icode, ptr, iMAC0, dst, C_00000000, src, vol);
1339 OP(icode, ptr, iANDXOR, C_00000000, vol, C_ffffffff, C_7fffffff);
1340 OP(icode, ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, C_00000001);
1341 OP(icode, ptr, iACC3, dst, src, C_00000000, C_00000000);
1343 static void __devinit _volume_add(emu10k1_fx8010_code_t *icode, u32 *ptr, u32 dst, u32 src, u32 vol)
1345 OP(icode, ptr, iANDXOR, C_00000000, vol, C_ffffffff, C_7fffffff);
1346 OP(icode, ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, C_00000002);
1347 OP(icode, ptr, iMACINT0, dst, dst, src, C_00000001);
1348 OP(icode, ptr, iSKIP, C_00000000, C_7fffffff, C_7fffffff, C_00000001);
1349 OP(icode, ptr, iMAC0, dst, dst, src, vol);
1351 static void __devinit _volume_out(emu10k1_fx8010_code_t *icode, u32 *ptr, u32 dst, u32 src, u32 vol)
1353 OP(icode, ptr, iANDXOR, C_00000000, vol, C_ffffffff, C_7fffffff);
1354 OP(icode, ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, C_00000002);
1355 OP(icode, ptr, iACC3, dst, src, C_00000000, C_00000000);
1356 OP(icode, ptr, iSKIP, C_00000000, C_7fffffff, C_7fffffff, C_00000001);
1357 OP(icode, ptr, iMAC0, dst, C_00000000, src, vol);
1360 #define VOLUME(icode, ptr, dst, src, vol) \
1361 _volume(icode, ptr, GPR(dst), GPR(src), GPR(vol))
1362 #define VOLUME_IN(icode, ptr, dst, src, vol) \
1363 _volume(icode, ptr, GPR(dst), EXTIN(src), GPR(vol))
1364 #define VOLUME_ADD(icode, ptr, dst, src, vol) \
1365 _volume_add(icode, ptr, GPR(dst), GPR(src), GPR(vol))
1366 #define VOLUME_ADDIN(icode, ptr, dst, src, vol) \
1367 _volume_add(icode, ptr, GPR(dst), EXTIN(src), GPR(vol))
1368 #define VOLUME_OUT(icode, ptr, dst, src, vol) \
1369 _volume_out(icode, ptr, EXTOUT(dst), GPR(src), GPR(vol))
1370 #define _SWITCH(icode, ptr, dst, src, sw) \
1371 OP((icode), ptr, iMACINT0, dst, C_00000000, src, sw);
1372 #define SWITCH(icode, ptr, dst, src, sw) \
1373 _SWITCH(icode, ptr, GPR(dst), GPR(src), GPR(sw))
1374 #define SWITCH_IN(icode, ptr, dst, src, sw) \
1375 _SWITCH(icode, ptr, GPR(dst), EXTIN(src), GPR(sw))
1376 #define _SWITCH_NEG(icode, ptr, dst, src) \
1377 OP((icode), ptr, iANDXOR, dst, src, C_00000001, C_00000001);
1378 #define SWITCH_NEG(icode, ptr, dst, src) \
1379 _SWITCH_NEG(icode, ptr, GPR(dst), GPR(src))
1382 static int __devinit _snd_emu10k1_init_efx(emu10k1_t *emu)
1384 int err, i, z, gpr, tmp, playback, capture;
1386 emu10k1_fx8010_code_t *icode;
1387 emu10k1_fx8010_pcm_t *ipcm;
1388 emu10k1_fx8010_control_gpr_t *controls, *ctl;
1391 spin_lock_init(&emu->fx8010.irq_lock);
1392 INIT_LIST_HEAD(&emu->fx8010.gpr_ctl);
1394 if ((icode = kcalloc(1, sizeof(*icode), GFP_KERNEL)) == NULL)
1396 if ((controls = kcalloc(SND_EMU10K1_GPR_CONTROLS, sizeof(emu10k1_fx8010_control_gpr_t), GFP_KERNEL)) == NULL) {
1400 if ((ipcm = kcalloc(1, sizeof(*ipcm), GFP_KERNEL)) == NULL) {
1406 /* clear free GPRs */
1407 for (i = 0; i < 256; i++)
1408 set_bit(i, icode->gpr_valid);
1410 /* clear TRAM data & address lines */
1411 for (i = 0; i < 160; i++)
1412 set_bit(i, icode->tram_valid);
1414 strcpy(icode->name, "SB Live! FX8010 code for ALSA v1.2 by Jaroslav Kysela");
1416 /* we have 10 inputs */
1417 playback = SND_EMU10K1_INPUTS;
1418 /* we have 6 playback channels and tone control doubles */
1419 capture = playback + (SND_EMU10K1_PLAYBACK_CHANNELS * 2);
1420 gpr = capture + SND_EMU10K1_CAPTURE_CHANNELS;
1421 tmp = 0x88; /* we need 4 temporary GPR */
1422 /* from 0x8c to 0xff is the area for tone control */
1424 /* stop FX processor */
1425 snd_emu10k1_ptr_write(emu, DBG, 0, (emu->fx8010.dbg = 0) | EMU10K1_DBG_SINGLE_STEP);
1430 OP(icode, &ptr, iMACINT0, GPR(0), C_00000000, FXBUS(FXBUS_PCM_LEFT), C_00000004);
1431 OP(icode, &ptr, iMACINT0, GPR(1), C_00000000, FXBUS(FXBUS_PCM_RIGHT), C_00000004);
1432 OP(icode, &ptr, iMACINT0, GPR(2), C_00000000, FXBUS(FXBUS_MIDI_LEFT), C_00000004);
1433 OP(icode, &ptr, iMACINT0, GPR(3), C_00000000, FXBUS(FXBUS_MIDI_RIGHT), C_00000004);
1434 OP(icode, &ptr, iMACINT0, GPR(4), C_00000000, FXBUS(FXBUS_PCM_LEFT_REAR), C_00000004);
1435 OP(icode, &ptr, iMACINT0, GPR(5), C_00000000, FXBUS(FXBUS_PCM_RIGHT_REAR), C_00000004);
1436 OP(icode, &ptr, iMACINT0, GPR(6), C_00000000, FXBUS(FXBUS_PCM_CENTER), C_00000004);
1437 OP(icode, &ptr, iMACINT0, GPR(7), C_00000000, FXBUS(FXBUS_PCM_LFE), C_00000004);
1438 OP(icode, &ptr, iMACINT0, GPR(8), C_00000000, C_00000000, C_00000000); /* S/PDIF left */
1439 OP(icode, &ptr, iMACINT0, GPR(9), C_00000000, C_00000000, C_00000000); /* S/PDIF right */
1441 /* Raw S/PDIF PCM */
1442 ipcm->substream = 0;
1444 ipcm->tram_start = 0;
1445 ipcm->buffer_size = (64 * 1024) / 2;
1446 ipcm->gpr_size = gpr++;
1447 ipcm->gpr_ptr = gpr++;
1448 ipcm->gpr_count = gpr++;
1449 ipcm->gpr_tmpcount = gpr++;
1450 ipcm->gpr_trigger = gpr++;
1451 ipcm->gpr_running = gpr++;
1455 icode->gpr_map[gpr + 0] = 0xfffff000;
1456 icode->gpr_map[gpr + 1] = 0xffff0000;
1457 icode->gpr_map[gpr + 2] = 0x70000000;
1458 icode->gpr_map[gpr + 3] = 0x00000007;
1459 icode->gpr_map[gpr + 4] = 0x001f << 11;
1460 icode->gpr_map[gpr + 5] = 0x001c << 11;
1461 icode->gpr_map[gpr + 6] = (0x22 - 0x01) - 1; /* skip at 01 to 22 */
1462 icode->gpr_map[gpr + 7] = (0x22 - 0x06) - 1; /* skip at 06 to 22 */
1463 icode->gpr_map[gpr + 8] = 0x2000000 + (2<<11);
1464 icode->gpr_map[gpr + 9] = 0x4000000 + (2<<11);
1465 icode->gpr_map[gpr + 10] = 1<<11;
1466 icode->gpr_map[gpr + 11] = (0x24 - 0x0a) - 1; /* skip at 0a to 24 */
1467 icode->gpr_map[gpr + 12] = 0;
1469 /* if the trigger flag is not set, skip */
1470 /* 00: */ OP(icode, &ptr, iMAC0, C_00000000, GPR(ipcm->gpr_trigger), C_00000000, C_00000000);
1471 /* 01: */ OP(icode, &ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_ZERO, GPR(gpr + 6));
1472 /* if the running flag is set, we're running */
1473 /* 02: */ OP(icode, &ptr, iMAC0, C_00000000, GPR(ipcm->gpr_running), C_00000000, C_00000000);
1474 /* 03: */ OP(icode, &ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, C_00000004);
1475 /* wait until ((GPR_DBAC>>11) & 0x1f) == 0x1c) */
1476 /* 04: */ OP(icode, &ptr, iANDXOR, GPR(tmp + 0), GPR_DBAC, GPR(gpr + 4), C_00000000);
1477 /* 05: */ OP(icode, &ptr, iMACINT0, C_00000000, GPR(tmp + 0), C_ffffffff, GPR(gpr + 5));
1478 /* 06: */ OP(icode, &ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, GPR(gpr + 7));
1479 /* 07: */ OP(icode, &ptr, iACC3, GPR(gpr + 12), C_00000010, C_00000001, C_00000000);
1481 /* 08: */ OP(icode, &ptr, iANDXOR, GPR(ipcm->gpr_running), GPR(ipcm->gpr_running), C_00000000, C_00000001);
1482 /* 09: */ OP(icode, &ptr, iACC3, GPR(gpr + 12), GPR(gpr + 12), C_ffffffff, C_00000000);
1483 /* 0a: */ OP(icode, &ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, GPR(gpr + 11));
1484 /* 0b: */ OP(icode, &ptr, iACC3, GPR(gpr + 12), C_00000001, C_00000000, C_00000000);
1486 /* 0c: */ OP(icode, &ptr, iANDXOR, GPR(tmp + 0), ETRAM_DATA(ipcm->etram[0]), GPR(gpr + 0), C_00000000);
1487 /* 0d: */ OP(icode, &ptr, iLOG, GPR(tmp + 0), GPR(tmp + 0), GPR(gpr + 3), C_00000000);
1488 /* 0e: */ OP(icode, &ptr, iANDXOR, GPR(8), GPR(tmp + 0), GPR(gpr + 1), GPR(gpr + 2));
1489 /* 0f: */ OP(icode, &ptr, iSKIP, C_00000000, GPR_COND, CC_REG_MINUS, C_00000001);
1490 /* 10: */ OP(icode, &ptr, iANDXOR, GPR(8), GPR(8), GPR(gpr + 1), GPR(gpr + 2));
1492 /* 11: */ OP(icode, &ptr, iANDXOR, GPR(tmp + 0), ETRAM_DATA(ipcm->etram[1]), GPR(gpr + 0), C_00000000);
1493 /* 12: */ OP(icode, &ptr, iLOG, GPR(tmp + 0), GPR(tmp + 0), GPR(gpr + 3), C_00000000);
1494 /* 13: */ OP(icode, &ptr, iANDXOR, GPR(9), GPR(tmp + 0), GPR(gpr + 1), GPR(gpr + 2));
1495 /* 14: */ OP(icode, &ptr, iSKIP, C_00000000, GPR_COND, CC_REG_MINUS, C_00000001);
1496 /* 15: */ OP(icode, &ptr, iANDXOR, GPR(9), GPR(9), GPR(gpr + 1), GPR(gpr + 2));
1498 /* 16: */ OP(icode, &ptr, iACC3, GPR(tmp + 0), GPR(ipcm->gpr_ptr), C_00000001, C_00000000);
1499 /* 17: */ OP(icode, &ptr, iMACINT0, C_00000000, GPR(tmp + 0), C_ffffffff, GPR(ipcm->gpr_size));
1500 /* 18: */ OP(icode, &ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_MINUS, C_00000001);
1501 /* 19: */ OP(icode, &ptr, iACC3, GPR(tmp + 0), C_00000000, C_00000000, C_00000000);
1502 /* 1a: */ OP(icode, &ptr, iACC3, GPR(ipcm->gpr_ptr), GPR(tmp + 0), C_00000000, C_00000000);
1504 /* 1b: */ OP(icode, &ptr, iACC3, GPR(ipcm->gpr_tmpcount), GPR(ipcm->gpr_tmpcount), C_ffffffff, C_00000000);
1505 /* 1c: */ OP(icode, &ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, C_00000002);
1506 /* 1d: */ OP(icode, &ptr, iACC3, GPR(ipcm->gpr_tmpcount), GPR(ipcm->gpr_count), C_00000000, C_00000000);
1507 /* 1e: */ OP(icode, &ptr, iACC3, GPR_IRQ, C_80000000, C_00000000, C_00000000);
1508 /* 1f: */ OP(icode, &ptr, iANDXOR, GPR(ipcm->gpr_running), GPR(ipcm->gpr_running), C_00000001, C_00010000);
1510 /* 20: */ OP(icode, &ptr, iANDXOR, GPR(ipcm->gpr_running), GPR(ipcm->gpr_running), C_00010000, C_00000001);
1511 /* 21: */ OP(icode, &ptr, iSKIP, C_00000000, C_7fffffff, C_7fffffff, C_00000002);
1513 /* 22: */ OP(icode, &ptr, iMACINT1, ETRAM_ADDR(ipcm->etram[0]), GPR(gpr + 8), GPR_DBAC, C_ffffffff);
1514 /* 23: */ OP(icode, &ptr, iMACINT1, ETRAM_ADDR(ipcm->etram[1]), GPR(gpr + 9), GPR_DBAC, C_ffffffff);
1519 /* Wave Playback Volume */
1520 for (z = 0; z < 2; z++)
1521 VOLUME(icode, &ptr, playback + z, z, gpr + z);
1522 snd_emu10k1_init_stereo_control(controls + i++, "Wave Playback Volume", gpr, 100);
1525 /* Wave Surround Playback Volume */
1526 for (z = 0; z < 2; z++)
1527 VOLUME(icode, &ptr, playback + 2 + z, z, gpr + z);
1528 snd_emu10k1_init_stereo_control(controls + i++, "Wave Surround Playback Volume", gpr, 0);
1531 /* Wave Center/LFE Playback Volume */
1532 OP(icode, &ptr, iACC3, GPR(tmp + 0), FXBUS(FXBUS_PCM_LEFT), FXBUS(FXBUS_PCM_RIGHT), C_00000000);
1533 OP(icode, &ptr, iMACINT0, GPR(tmp + 0), C_00000000, GPR(tmp + 0), C_00000002);
1534 VOLUME(icode, &ptr, playback + 4, tmp + 0, gpr);
1535 snd_emu10k1_init_mono_control(controls + i++, "Wave Center Playback Volume", gpr++, 0);
1536 VOLUME(icode, &ptr, playback + 5, tmp + 0, gpr);
1537 snd_emu10k1_init_mono_control(controls + i++, "Wave LFE Playback Volume", gpr++, 0);
1539 /* Wave Capture Volume + Switch */
1540 for (z = 0; z < 2; z++) {
1541 SWITCH(icode, &ptr, tmp + 0, z, gpr + 2 + z);
1542 VOLUME(icode, &ptr, capture + z, tmp + 0, gpr + z);
1544 snd_emu10k1_init_stereo_control(controls + i++, "Wave Capture Volume", gpr, 0);
1545 snd_emu10k1_init_stereo_onoff_control(controls + i++, "Wave Capture Switch", gpr + 2, 0);
1548 /* Music Playback Volume */
1549 for (z = 0; z < 2; z++)
1550 VOLUME_ADD(icode, &ptr, playback + z, 2 + z, gpr + z);
1551 snd_emu10k1_init_stereo_control(controls + i++, "Music Playback Volume", gpr, 100);
1554 /* Music Capture Volume + Switch */
1555 for (z = 0; z < 2; z++) {
1556 SWITCH(icode, &ptr, tmp + 0, 2 + z, gpr + 2 + z);
1557 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
1559 snd_emu10k1_init_stereo_control(controls + i++, "Music Capture Volume", gpr, 0);
1560 snd_emu10k1_init_stereo_onoff_control(controls + i++, "Music Capture Switch", gpr + 2, 0);
1563 /* Surround Digital Playback Volume (renamed later without Digital) */
1564 for (z = 0; z < 2; z++)
1565 VOLUME_ADD(icode, &ptr, playback + 2 + z, 4 + z, gpr + z);
1566 snd_emu10k1_init_stereo_control(controls + i++, "Surround Digital Playback Volume", gpr, 100);
1569 /* Surround Capture Volume + Switch */
1570 for (z = 0; z < 2; z++) {
1571 SWITCH(icode, &ptr, tmp + 0, 4 + z, gpr + 2 + z);
1572 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
1574 snd_emu10k1_init_stereo_control(controls + i++, "Surround Capture Volume", gpr, 0);
1575 snd_emu10k1_init_stereo_onoff_control(controls + i++, "Surround Capture Switch", gpr + 2, 0);
1578 /* Center Playback Volume (renamed later without Digital) */
1579 VOLUME_ADD(icode, &ptr, playback + 4, 6, gpr);
1580 snd_emu10k1_init_mono_control(controls + i++, "Center Digital Playback Volume", gpr++, 100);
1582 /* LFE Playback Volume + Switch (renamed later without Digital) */
1583 VOLUME_ADD(icode, &ptr, playback + 5, 7, gpr);
1584 snd_emu10k1_init_mono_control(controls + i++, "LFE Digital Playback Volume", gpr++, 100);
1590 if (emu->fx8010.extin_mask & ((1<<EXTIN_AC97_L)|(1<<EXTIN_AC97_R))) {
1591 /* AC'97 Playback Volume */
1592 VOLUME_ADDIN(icode, &ptr, playback + 0, EXTIN_AC97_L, gpr); gpr++;
1593 VOLUME_ADDIN(icode, &ptr, playback + 1, EXTIN_AC97_R, gpr); gpr++;
1594 snd_emu10k1_init_stereo_control(controls + i++, "AC97 Playback Volume", gpr-2, 0);
1595 /* AC'97 Capture Volume */
1596 VOLUME_ADDIN(icode, &ptr, capture + 0, EXTIN_AC97_L, gpr); gpr++;
1597 VOLUME_ADDIN(icode, &ptr, capture + 1, EXTIN_AC97_R, gpr); gpr++;
1598 snd_emu10k1_init_stereo_control(controls + i++, "AC97 Capture Volume", gpr-2, 100);
1601 if (emu->fx8010.extin_mask & ((1<<EXTIN_SPDIF_CD_L)|(1<<EXTIN_SPDIF_CD_R))) {
1602 /* IEC958 TTL Playback Volume */
1603 for (z = 0; z < 2; z++)
1604 VOLUME_ADDIN(icode, &ptr, playback + z, EXTIN_SPDIF_CD_L + z, gpr + z);
1605 snd_emu10k1_init_stereo_control(controls + i++, "IEC958 TTL Playback Volume", gpr, 0);
1608 /* IEC958 TTL Capture Volume + Switch */
1609 for (z = 0; z < 2; z++) {
1610 SWITCH_IN(icode, &ptr, tmp + 0, EXTIN_SPDIF_CD_L + z, gpr + 2 + z);
1611 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
1613 snd_emu10k1_init_stereo_control(controls + i++, "IEC958 TTL Capture Volume", gpr, 0);
1614 snd_emu10k1_init_stereo_onoff_control(controls + i++, "IEC958 TTL Capture Switch", gpr + 2, 0);
1618 if (emu->fx8010.extin_mask & ((1<<EXTIN_ZOOM_L)|(1<<EXTIN_ZOOM_R))) {
1619 /* Zoom Video Playback Volume */
1620 for (z = 0; z < 2; z++)
1621 VOLUME_ADDIN(icode, &ptr, playback + z, EXTIN_ZOOM_L + z, gpr + z);
1622 snd_emu10k1_init_stereo_control(controls + i++, "Zoom Video Playback Volume", gpr, 0);
1625 /* Zoom Video Capture Volume + Switch */
1626 for (z = 0; z < 2; z++) {
1627 SWITCH_IN(icode, &ptr, tmp + 0, EXTIN_ZOOM_L + z, gpr + 2 + z);
1628 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
1630 snd_emu10k1_init_stereo_control(controls + i++, "Zoom Video Capture Volume", gpr, 0);
1631 snd_emu10k1_init_stereo_onoff_control(controls + i++, "Zoom Video Capture Switch", gpr + 2, 0);
1635 if (emu->fx8010.extin_mask & ((1<<EXTIN_TOSLINK_L)|(1<<EXTIN_TOSLINK_R))) {
1636 /* IEC958 Optical Playback Volume */
1637 for (z = 0; z < 2; z++)
1638 VOLUME_ADDIN(icode, &ptr, playback + z, EXTIN_TOSLINK_L + z, gpr + z);
1639 snd_emu10k1_init_stereo_control(controls + i++, "IEC958 LiveDrive Playback Volume", gpr, 0);
1642 /* IEC958 Optical Capture Volume */
1643 for (z = 0; z < 2; z++) {
1644 SWITCH_IN(icode, &ptr, tmp + 0, EXTIN_TOSLINK_L + z, gpr + 2 + z);
1645 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
1647 snd_emu10k1_init_stereo_control(controls + i++, "IEC958 LiveDrive Capture Volume", gpr, 0);
1648 snd_emu10k1_init_stereo_onoff_control(controls + i++, "IEC958 LiveDrive Capture Switch", gpr + 2, 0);
1652 if (emu->fx8010.extin_mask & ((1<<EXTIN_LINE1_L)|(1<<EXTIN_LINE1_R))) {
1653 /* Line LiveDrive Playback Volume */
1654 for (z = 0; z < 2; z++)
1655 VOLUME_ADDIN(icode, &ptr, playback + z, EXTIN_LINE1_L + z, gpr + z);
1656 snd_emu10k1_init_stereo_control(controls + i++, "Line LiveDrive Playback Volume", gpr, 0);
1659 /* Line LiveDrive Capture Volume + Switch */
1660 for (z = 0; z < 2; z++) {
1661 SWITCH_IN(icode, &ptr, tmp + 0, EXTIN_LINE1_L + z, gpr + 2 + z);
1662 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
1664 snd_emu10k1_init_stereo_control(controls + i++, "Line LiveDrive Capture Volume", gpr, 0);
1665 snd_emu10k1_init_stereo_onoff_control(controls + i++, "Line LiveDrive Capture Switch", gpr + 2, 0);
1669 if (emu->fx8010.extin_mask & ((1<<EXTIN_COAX_SPDIF_L)|(1<<EXTIN_COAX_SPDIF_R))) {
1670 /* IEC958 Coax Playback Volume */
1671 for (z = 0; z < 2; z++)
1672 VOLUME_ADDIN(icode, &ptr, playback + z, EXTIN_COAX_SPDIF_L + z, gpr + z);
1673 snd_emu10k1_init_stereo_control(controls + i++, "IEC958 Coaxial Playback Volume", gpr, 0);
1676 /* IEC958 Coax Capture Volume + Switch */
1677 for (z = 0; z < 2; z++) {
1678 SWITCH_IN(icode, &ptr, tmp + 0, EXTIN_COAX_SPDIF_L + z, gpr + 2 + z);
1679 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
1681 snd_emu10k1_init_stereo_control(controls + i++, "IEC958 Coaxial Capture Volume", gpr, 0);
1682 snd_emu10k1_init_stereo_onoff_control(controls + i++, "IEC958 Coaxial Capture Switch", gpr + 2, 0);
1686 if (emu->fx8010.extin_mask & ((1<<EXTIN_LINE2_L)|(1<<EXTIN_LINE2_R))) {
1687 /* Line LiveDrive Playback Volume */
1688 for (z = 0; z < 2; z++)
1689 VOLUME_ADDIN(icode, &ptr, playback + z, EXTIN_LINE2_L + z, gpr + z);
1690 snd_emu10k1_init_stereo_control(controls + i++, "Line2 LiveDrive Playback Volume", gpr, 0);
1691 controls[i-1].id.index = 1;
1694 /* Line LiveDrive Capture Volume */
1695 for (z = 0; z < 2; z++) {
1696 SWITCH_IN(icode, &ptr, tmp + 0, EXTIN_LINE2_L + z, gpr + 2 + z);
1697 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
1699 snd_emu10k1_init_stereo_control(controls + i++, "Line2 LiveDrive Capture Volume", gpr, 0);
1700 controls[i-1].id.index = 1;
1701 snd_emu10k1_init_stereo_onoff_control(controls + i++, "Line2 LiveDrive Capture Switch", gpr + 2, 0);
1702 controls[i-1].id.index = 1;
1707 * Process tone control
1709 OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 0), GPR(playback + 0), C_00000000, C_00000000); /* left */
1710 OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 1), GPR(playback + 1), C_00000000, C_00000000); /* right */
1711 OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 2), GPR(playback + 2), C_00000000, C_00000000); /* rear left */
1712 OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 3), GPR(playback + 3), C_00000000, C_00000000); /* rear right */
1713 OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 4), GPR(playback + 4), C_00000000, C_00000000); /* center */
1714 OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 5), GPR(playback + 5), C_00000000, C_00000000); /* LFE */
1716 ctl = &controls[i + 0];
1717 ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1718 strcpy(ctl->id.name, "Tone Control - Bass");
1723 ctl->value[0] = ctl->value[1] = 20;
1724 ctl->translation = EMU10K1_GPR_TRANSLATION_BASS;
1725 ctl = &controls[i + 1];
1726 ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1727 strcpy(ctl->id.name, "Tone Control - Treble");
1732 ctl->value[0] = ctl->value[1] = 20;
1733 ctl->translation = EMU10K1_GPR_TRANSLATION_TREBLE;
1735 #define BASS_GPR 0x8c
1736 #define TREBLE_GPR 0x96
1738 for (z = 0; z < 5; z++) {
1740 for (j = 0; j < 2; j++) {
1741 controls[i + 0].gpr[z * 2 + j] = BASS_GPR + z * 2 + j;
1742 controls[i + 1].gpr[z * 2 + j] = TREBLE_GPR + z * 2 + j;
1745 for (z = 0; z < 3; z++) { /* front/rear/center-lfe */
1747 for (j = 0; j < 2; j++) { /* left/right */
1748 k = 0xa0 + (z * 8) + (j * 4);
1749 l = 0xd0 + (z * 8) + (j * 4);
1750 d = playback + SND_EMU10K1_PLAYBACK_CHANNELS + z * 2 + j;
1752 OP(icode, &ptr, iMAC0, C_00000000, C_00000000, GPR(d), GPR(BASS_GPR + 0 + j));
1753 OP(icode, &ptr, iMACMV, GPR(k+1), GPR(k), GPR(k+1), GPR(BASS_GPR + 4 + j));
1754 OP(icode, &ptr, iMACMV, GPR(k), GPR(d), GPR(k), GPR(BASS_GPR + 2 + j));
1755 OP(icode, &ptr, iMACMV, GPR(k+3), GPR(k+2), GPR(k+3), GPR(BASS_GPR + 8 + j));
1756 OP(icode, &ptr, iMAC0, GPR(k+2), GPR_ACCU, GPR(k+2), GPR(BASS_GPR + 6 + j));
1757 OP(icode, &ptr, iACC3, GPR(k+2), GPR(k+2), GPR(k+2), C_00000000);
1759 OP(icode, &ptr, iMAC0, C_00000000, C_00000000, GPR(k+2), GPR(TREBLE_GPR + 0 + j));
1760 OP(icode, &ptr, iMACMV, GPR(l+1), GPR(l), GPR(l+1), GPR(TREBLE_GPR + 4 + j));
1761 OP(icode, &ptr, iMACMV, GPR(l), GPR(k+2), GPR(l), GPR(TREBLE_GPR + 2 + j));
1762 OP(icode, &ptr, iMACMV, GPR(l+3), GPR(l+2), GPR(l+3), GPR(TREBLE_GPR + 8 + j));
1763 OP(icode, &ptr, iMAC0, GPR(l+2), GPR_ACCU, GPR(l+2), GPR(TREBLE_GPR + 6 + j));
1764 OP(icode, &ptr, iMACINT0, GPR(l+2), C_00000000, GPR(l+2), C_00000010);
1766 OP(icode, &ptr, iACC3, GPR(d), GPR(l+2), C_00000000, C_00000000);
1768 if (z == 2) /* center */
1777 for (z = 0; z < 6; z++) {
1778 SWITCH(icode, &ptr, tmp + 0, playback + SND_EMU10K1_PLAYBACK_CHANNELS + z, gpr + 0);
1779 SWITCH_NEG(icode, &ptr, tmp + 1, gpr + 0);
1780 SWITCH(icode, &ptr, tmp + 1, playback + z, tmp + 1);
1781 OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + z), GPR(tmp + 0), GPR(tmp + 1), C_00000000);
1783 snd_emu10k1_init_stereo_onoff_control(controls + i++, "Tone Control - Switch", gpr, 0);
1789 if (emu->fx8010.extout_mask & ((1<<EXTOUT_AC97_L)|(1<<EXTOUT_AC97_R))) {
1790 /* AC'97 Playback Volume */
1792 for (z = 0; z < 2; z++)
1793 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_AC97_L + z), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + z), C_00000000, C_00000000);
1796 if (emu->fx8010.extout_mask & ((1<<EXTOUT_TOSLINK_L)|(1<<EXTOUT_TOSLINK_R))) {
1797 /* IEC958 Optical Raw Playback Switch */
1799 for (z = 0; z < 2; z++) {
1800 SWITCH(icode, &ptr, tmp + 0, 8 + z, gpr + z);
1801 SWITCH_NEG(icode, &ptr, tmp + 1, gpr + z);
1802 SWITCH(icode, &ptr, tmp + 1, playback + SND_EMU10K1_PLAYBACK_CHANNELS + z, tmp + 1);
1803 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_TOSLINK_L + z), GPR(tmp + 0), GPR(tmp + 1), C_00000000);
1804 #ifdef EMU10K1_CAPTURE_DIGITAL_OUT
1805 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_ADC_CAP_L + z), GPR(tmp + 0), GPR(tmp + 1), C_00000000);
1809 snd_emu10k1_init_stereo_onoff_control(controls + i++, "IEC958 Optical Raw Playback Switch", gpr, 0);
1813 if (emu->fx8010.extout_mask & ((1<<EXTOUT_HEADPHONE_L)|(1<<EXTOUT_HEADPHONE_R))) {
1814 /* Headphone Playback Volume */
1816 for (z = 0; z < 2; z++) {
1817 SWITCH(icode, &ptr, tmp + 0, playback + SND_EMU10K1_PLAYBACK_CHANNELS + 4 + z, gpr + 2 + z);
1818 SWITCH_NEG(icode, &ptr, tmp + 1, gpr + 2 + z);
1819 SWITCH(icode, &ptr, tmp + 1, playback + SND_EMU10K1_PLAYBACK_CHANNELS + z, tmp + 1);
1820 OP(icode, &ptr, iACC3, GPR(tmp + 0), GPR(tmp + 0), GPR(tmp + 1), C_00000000);
1821 VOLUME_OUT(icode, &ptr, EXTOUT_HEADPHONE_L + z, tmp + 0, gpr + z);
1824 snd_emu10k1_init_stereo_control(controls + i++, "Headphone Playback Volume", gpr + 0, 0);
1825 controls[i-1].id.index = 1; /* AC'97 can have also Headphone control */
1826 snd_emu10k1_init_mono_onoff_control(controls + i++, "Headphone Center Playback Switch", gpr + 2, 0);
1827 controls[i-1].id.index = 1;
1828 snd_emu10k1_init_mono_onoff_control(controls + i++, "Headphone LFE Playback Switch", gpr + 3, 0);
1829 controls[i-1].id.index = 1;
1834 if (emu->fx8010.extout_mask & ((1<<EXTOUT_REAR_L)|(1<<EXTOUT_REAR_R)))
1835 for (z = 0; z < 2; z++)
1836 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_REAR_L + z), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 2 + z), C_00000000, C_00000000);
1838 if (emu->fx8010.extout_mask & ((1<<EXTOUT_AC97_REAR_L)|(1<<EXTOUT_AC97_REAR_R)))
1839 for (z = 0; z < 2; z++)
1840 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_AC97_REAR_L + z), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 2 + z), C_00000000, C_00000000);
1842 if (emu->fx8010.extout_mask & (1<<EXTOUT_AC97_CENTER)) {
1843 #ifndef EMU10K1_CENTER_LFE_FROM_FRONT
1844 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_AC97_CENTER), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 4), C_00000000, C_00000000);
1845 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_ACENTER), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 4), C_00000000, C_00000000);
1847 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_AC97_CENTER), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 0), C_00000000, C_00000000);
1848 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_ACENTER), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 0), C_00000000, C_00000000);
1852 if (emu->fx8010.extout_mask & (1<<EXTOUT_AC97_LFE)) {
1853 #ifndef EMU10K1_CENTER_LFE_FROM_FRONT
1854 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_AC97_LFE), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 5), C_00000000, C_00000000);
1855 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_ALFE), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 5), C_00000000, C_00000000);
1857 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_AC97_LFE), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 1), C_00000000, C_00000000);
1858 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_ALFE), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 1), C_00000000, C_00000000);
1862 #ifndef EMU10K1_CAPTURE_DIGITAL_OUT
1863 for (z = 0; z < 2; z++)
1864 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_ADC_CAP_L + z), GPR(capture + z), C_00000000, C_00000000);
1867 if (emu->fx8010.extout_mask & (1<<EXTOUT_MIC_CAP))
1868 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_MIC_CAP), GPR(capture + 2), C_00000000, C_00000000);
1875 if (i > SND_EMU10K1_GPR_CONTROLS) {
1881 /* clear remaining instruction memory */
1883 OP(icode, &ptr, iACC3, C_00000000, C_00000000, C_00000000, C_00000000);
1885 if ((err = snd_emu10k1_fx8010_tram_setup(emu, ipcm->buffer_size)) < 0)
1887 seg = snd_enter_user();
1888 icode->gpr_add_control_count = i;
1889 icode->gpr_add_controls = controls;
1890 err = snd_emu10k1_icode_poke(emu, icode);
1891 snd_leave_user(seg);
1893 err = snd_emu10k1_ipcm_poke(emu, ipcm);
1901 int __devinit snd_emu10k1_init_efx(emu10k1_t *emu)
1904 return _snd_emu10k1_audigy_init_efx(emu);
1906 return _snd_emu10k1_init_efx(emu);
1909 void snd_emu10k1_free_efx(emu10k1_t *emu)
1911 /* stop processor */
1913 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg = A_DBG_SINGLE_STEP);
1915 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg = EMU10K1_DBG_SINGLE_STEP);
1918 #if 0 // FIXME: who use them?
1919 int snd_emu10k1_fx8010_tone_control_activate(emu10k1_t *emu, int output)
1921 snd_runtime_check(output >= 0 && output < 6, return -EINVAL);
1922 snd_emu10k1_ptr_write(emu, emu->gpr_base + 0x94 + output, 0, 1);
1926 int snd_emu10k1_fx8010_tone_control_deactivate(emu10k1_t *emu, int output)
1928 snd_runtime_check(output >= 0 && output < 6, return -EINVAL);
1929 snd_emu10k1_ptr_write(emu, emu->gpr_base + 0x94 + output, 0, 0);
1934 int snd_emu10k1_fx8010_tram_setup(emu10k1_t *emu, u32 size)
1938 /* size is in samples */
1940 size = (size - 1) >> 13;
1946 size = 0x2000 << size_reg;
1948 if (emu->fx8010.etram_pages.bytes == size)
1950 spin_lock_irq(&emu->emu_lock);
1951 outl(HCFG_LOCKTANKCACHE_MASK | inl(emu->port + HCFG), emu->port + HCFG);
1952 spin_unlock_irq(&emu->emu_lock);
1953 snd_emu10k1_ptr_write(emu, TCB, 0, 0);
1954 snd_emu10k1_ptr_write(emu, TCBS, 0, 0);
1955 if (emu->fx8010.etram_pages.area != NULL) {
1956 snd_dma_free_pages(&emu->fx8010.etram_pages);
1957 emu->fx8010.etram_pages.area = NULL;
1958 emu->fx8010.etram_pages.bytes = 0;
1962 if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(emu->pci),
1963 size * 2, &emu->fx8010.etram_pages) < 0)
1965 memset(emu->fx8010.etram_pages.area, 0, size * 2);
1966 snd_emu10k1_ptr_write(emu, TCB, 0, emu->fx8010.etram_pages.addr);
1967 snd_emu10k1_ptr_write(emu, TCBS, 0, size_reg);
1968 spin_lock_irq(&emu->emu_lock);
1969 outl(inl(emu->port + HCFG) & ~HCFG_LOCKTANKCACHE_MASK, emu->port + HCFG);
1970 spin_unlock_irq(&emu->emu_lock);
1976 static int snd_emu10k1_fx8010_open(snd_hwdep_t * hw, struct file *file)
1981 static void copy_string(char *dst, char *src, char *null, int idx)
1984 sprintf(dst, "%s %02X", null, idx);
1989 static int snd_emu10k1_fx8010_info(emu10k1_t *emu, emu10k1_fx8010_info_t *info)
1991 char **fxbus, **extin, **extout;
1992 unsigned short fxbus_mask, extin_mask, extout_mask;
1995 memset(info, 0, sizeof(info));
1996 info->card = emu->card_type;
1997 info->internal_tram_size = emu->fx8010.itram_size;
1998 info->external_tram_size = emu->fx8010.etram_pages.bytes;
2000 extin = emu->audigy ? audigy_ins : creative_ins;
2001 extout = emu->audigy ? audigy_outs : creative_outs;
2002 fxbus_mask = emu->fx8010.fxbus_mask;
2003 extin_mask = emu->fx8010.extin_mask;
2004 extout_mask = emu->fx8010.extout_mask;
2005 for (res = 0; res < 16; res++, fxbus++, extin++, extout++) {
2006 copy_string(info->fxbus_names[res], fxbus_mask & (1 << res) ? *fxbus : NULL, "FXBUS", res);
2007 copy_string(info->extin_names[res], extin_mask & (1 << res) ? *extin : NULL, "Unused", res);
2008 copy_string(info->extout_names[res], extout_mask & (1 << res) ? *extout : NULL, "Unused", res);
2010 for (res = 16; res < 32; res++, extout++)
2011 copy_string(info->extout_names[res], extout_mask & (1 << res) ? *extout : NULL, "Unused", res);
2012 info->gpr_controls = emu->fx8010.gpr_count;
2016 static int snd_emu10k1_fx8010_ioctl(snd_hwdep_t * hw, struct file *file, unsigned int cmd, unsigned long arg)
2018 emu10k1_t *emu = hw->private_data;
2019 emu10k1_fx8010_info_t *info;
2020 emu10k1_fx8010_code_t *icode;
2021 emu10k1_fx8010_pcm_t *ipcm;
2023 void __user *argp = (void __user *)arg;
2027 case SNDRV_EMU10K1_IOCTL_INFO:
2028 info = (emu10k1_fx8010_info_t *)kmalloc(sizeof(*info), GFP_KERNEL);
2031 if ((res = snd_emu10k1_fx8010_info(emu, info)) < 0) {
2035 if (copy_to_user(argp, info, sizeof(*info))) {
2041 case SNDRV_EMU10K1_IOCTL_CODE_POKE:
2042 if (!capable(CAP_SYS_ADMIN))
2044 icode = (emu10k1_fx8010_code_t *)kmalloc(sizeof(*icode), GFP_KERNEL);
2047 if (copy_from_user(icode, argp, sizeof(*icode))) {
2051 res = snd_emu10k1_icode_poke(emu, icode);
2054 case SNDRV_EMU10K1_IOCTL_CODE_PEEK:
2055 icode = (emu10k1_fx8010_code_t *)kmalloc(sizeof(*icode), GFP_KERNEL);
2058 if (copy_from_user(icode, argp, sizeof(*icode))) {
2062 res = snd_emu10k1_icode_peek(emu, icode);
2063 if (res == 0 && copy_to_user(argp, icode, sizeof(*icode))) {
2069 case SNDRV_EMU10K1_IOCTL_PCM_POKE:
2072 ipcm = (emu10k1_fx8010_pcm_t *)kmalloc(sizeof(*ipcm), GFP_KERNEL);
2075 if (copy_from_user(ipcm, argp, sizeof(*ipcm))) {
2079 res = snd_emu10k1_ipcm_poke(emu, ipcm);
2082 case SNDRV_EMU10K1_IOCTL_PCM_PEEK:
2085 ipcm = kcalloc(1, sizeof(*ipcm), GFP_KERNEL);
2088 if (copy_from_user(ipcm, argp, sizeof(*ipcm))) {
2092 res = snd_emu10k1_ipcm_peek(emu, ipcm);
2093 if (res == 0 && copy_to_user(argp, ipcm, sizeof(*ipcm))) {
2099 case SNDRV_EMU10K1_IOCTL_TRAM_SETUP:
2102 if (!capable(CAP_SYS_ADMIN))
2104 if (get_user(addr, (unsigned int __user *)argp))
2106 down(&emu->fx8010.lock);
2107 res = snd_emu10k1_fx8010_tram_setup(emu, addr);
2108 up(&emu->fx8010.lock);
2110 case SNDRV_EMU10K1_IOCTL_STOP:
2111 if (!capable(CAP_SYS_ADMIN))
2114 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg |= A_DBG_SINGLE_STEP);
2116 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg |= EMU10K1_DBG_SINGLE_STEP);
2118 case SNDRV_EMU10K1_IOCTL_CONTINUE:
2119 if (!capable(CAP_SYS_ADMIN))
2122 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg = 0);
2124 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg = 0);
2126 case SNDRV_EMU10K1_IOCTL_ZERO_TRAM_COUNTER:
2127 if (!capable(CAP_SYS_ADMIN))
2130 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg | A_DBG_ZC);
2132 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg | EMU10K1_DBG_ZC);
2135 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg);
2137 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg);
2139 case SNDRV_EMU10K1_IOCTL_SINGLE_STEP:
2140 if (!capable(CAP_SYS_ADMIN))
2142 if (get_user(addr, (unsigned int __user *)argp))
2147 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg |= A_DBG_SINGLE_STEP | addr);
2149 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg |= EMU10K1_DBG_SINGLE_STEP | addr);
2152 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg |= A_DBG_SINGLE_STEP | A_DBG_STEP_ADDR | addr);
2154 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg |= EMU10K1_DBG_SINGLE_STEP | EMU10K1_DBG_STEP | addr);
2156 case SNDRV_EMU10K1_IOCTL_DBG_READ:
2158 addr = snd_emu10k1_ptr_read(emu, A_DBG, 0);
2160 addr = snd_emu10k1_ptr_read(emu, DBG, 0);
2161 if (put_user(addr, (unsigned int __user *)argp))
2168 static int snd_emu10k1_fx8010_release(snd_hwdep_t * hw, struct file *file)
2173 int __devinit snd_emu10k1_fx8010_new(emu10k1_t *emu, int device, snd_hwdep_t ** rhwdep)
2180 if ((err = snd_hwdep_new(emu->card, "FX8010", device, &hw)) < 0)
2182 strcpy(hw->name, "EMU10K1 (FX8010)");
2183 hw->iface = SNDRV_HWDEP_IFACE_EMU10K1;
2184 hw->ops.open = snd_emu10k1_fx8010_open;
2185 hw->ops.ioctl = snd_emu10k1_fx8010_ioctl;
2186 hw->ops.release = snd_emu10k1_fx8010_release;
2187 hw->private_data = emu;