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 < 1024, 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 < (emu->audigy ? 0x200 : 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 < (emu->audigy ? 0x200 : 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 < (emu->audigy ? 0x100 : 0xa0); tram++) {
530 if (!test_bit(tram, icode->tram_valid))
532 snd_emu10k1_ptr_write(emu, TANKMEMDATAREGBASE + tram, 0, icode->tram_data_map[tram]);
534 snd_emu10k1_ptr_write(emu, TANKMEMADDRREGBASE + tram, 0, icode->tram_addr_map[tram]);
536 snd_emu10k1_ptr_write(emu, TANKMEMADDRREGBASE + tram, 0, icode->tram_addr_map[tram] << 12);
537 snd_emu10k1_ptr_write(emu, A_TANKMEMCTLREGBASE + tram, 0, icode->tram_addr_map[tram] >> 20);
542 static void snd_emu10k1_tram_peek(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
546 memset(icode->tram_valid, 0, sizeof(icode->tram_valid));
547 for (tram = 0; tram < (emu->audigy ? 0x100 : 0xa0); tram++) {
548 set_bit(tram, icode->tram_valid);
549 icode->tram_data_map[tram] = snd_emu10k1_ptr_read(emu, TANKMEMDATAREGBASE + tram, 0);
551 icode->tram_addr_map[tram] = snd_emu10k1_ptr_read(emu, TANKMEMADDRREGBASE + tram, 0);
553 icode->tram_addr_map[tram] = snd_emu10k1_ptr_read(emu, TANKMEMADDRREGBASE + tram, 0) >> 12;
554 icode->tram_addr_map[tram] |= snd_emu10k1_ptr_read(emu, A_TANKMEMCTLREGBASE + tram, 0) << 20;
559 static void snd_emu10k1_code_poke(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
563 for (pc = 0; pc < (emu->audigy ? 1024 : 512); pc++) {
564 if (!test_bit(pc, icode->code_valid))
566 snd_emu10k1_efx_write(emu, pc * 2, icode->code[pc][0]);
567 snd_emu10k1_efx_write(emu, pc * 2 + 1, icode->code[pc][1]);
571 static void snd_emu10k1_code_peek(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
575 memset(icode->code_valid, 0, sizeof(icode->code_valid));
576 for (pc = 0; pc < (emu->audigy ? 1024 : 512); pc++) {
577 set_bit(pc, icode->code_valid);
578 icode->code[pc][0] = snd_emu10k1_efx_read(emu, pc * 2);
579 icode->code[pc][1] = snd_emu10k1_efx_read(emu, pc * 2 + 1);
583 static snd_emu10k1_fx8010_ctl_t *snd_emu10k1_look_for_ctl(emu10k1_t *emu, snd_ctl_elem_id_t *id)
585 snd_emu10k1_fx8010_ctl_t *ctl;
586 snd_kcontrol_t *kcontrol;
587 struct list_head *list;
589 list_for_each(list, &emu->fx8010.gpr_ctl) {
590 ctl = emu10k1_gpr_ctl(list);
591 kcontrol = ctl->kcontrol;
592 if (kcontrol->id.iface == id->iface &&
593 !strcmp(kcontrol->id.name, id->name) &&
594 kcontrol->id.index == id->index)
600 static int snd_emu10k1_verify_controls(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
603 snd_ctl_elem_id_t __user *_id;
604 snd_ctl_elem_id_t id;
605 emu10k1_fx8010_control_gpr_t __user *_gctl;
606 emu10k1_fx8010_control_gpr_t gctl;
608 for (i = 0, _id = icode->gpr_del_controls;
609 i < icode->gpr_del_control_count; i++, _id++) {
610 if (copy_from_user(&id, _id, sizeof(id)))
612 if (snd_emu10k1_look_for_ctl(emu, &id) == NULL)
615 for (i = 0, _gctl = icode->gpr_add_controls;
616 i < icode->gpr_add_control_count; i++, _gctl++) {
617 if (copy_from_user(&gctl, _gctl, sizeof(gctl)))
619 if (snd_emu10k1_look_for_ctl(emu, &gctl.id))
621 down_read(&emu->card->controls_rwsem);
622 if (snd_ctl_find_id(emu->card, &gctl.id) != NULL) {
623 up_read(&emu->card->controls_rwsem);
626 up_read(&emu->card->controls_rwsem);
627 if (gctl.id.iface != SNDRV_CTL_ELEM_IFACE_MIXER &&
628 gctl.id.iface != SNDRV_CTL_ELEM_IFACE_PCM)
631 for (i = 0, _gctl = icode->gpr_list_controls;
632 i < icode->gpr_list_control_count; i++, _gctl++) {
633 /* FIXME: we need to check the WRITE access */
634 if (copy_from_user(&gctl, _gctl, sizeof(gctl)))
640 static void snd_emu10k1_ctl_private_free(snd_kcontrol_t *kctl)
642 snd_emu10k1_fx8010_ctl_t *ctl;
644 ctl = (snd_emu10k1_fx8010_ctl_t *)kctl->private_value;
645 kctl->private_value = 0;
646 list_del(&ctl->list);
650 static void snd_emu10k1_add_controls(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
653 emu10k1_fx8010_control_gpr_t __user *_gctl;
654 emu10k1_fx8010_control_gpr_t gctl;
655 snd_emu10k1_fx8010_ctl_t *ctl, nctl;
656 snd_kcontrol_new_t knew;
657 snd_kcontrol_t *kctl;
658 snd_ctl_elem_value_t *val;
660 val = (snd_ctl_elem_value_t *)kmalloc(sizeof(*val), GFP_KERNEL);
663 for (i = 0, _gctl = icode->gpr_add_controls;
664 i < icode->gpr_add_control_count; i++, _gctl++) {
665 if (copy_from_user(&gctl, _gctl, sizeof(gctl)))
667 snd_runtime_check(gctl.id.iface == SNDRV_CTL_ELEM_IFACE_MIXER ||
668 gctl.id.iface == SNDRV_CTL_ELEM_IFACE_PCM, continue);
669 snd_runtime_check(gctl.id.name[0] != '\0', continue);
670 ctl = snd_emu10k1_look_for_ctl(emu, &gctl.id);
671 memset(&knew, 0, sizeof(knew));
672 knew.iface = gctl.id.iface;
673 knew.name = gctl.id.name;
674 knew.index = gctl.id.index;
675 knew.device = gctl.id.device;
676 knew.subdevice = gctl.id.subdevice;
677 knew.info = snd_emu10k1_gpr_ctl_info;
678 knew.get = snd_emu10k1_gpr_ctl_get;
679 knew.put = snd_emu10k1_gpr_ctl_put;
680 memset(&nctl, 0, sizeof(nctl));
681 nctl.vcount = gctl.vcount;
682 nctl.count = gctl.count;
683 for (j = 0; j < 32; j++) {
684 nctl.gpr[j] = gctl.gpr[j];
685 nctl.value[j] = ~gctl.value[j]; /* inverted, we want to write new value in gpr_ctl_put() */
686 val->value.integer.value[j] = gctl.value[j];
690 nctl.translation = gctl.translation;
692 ctl = (snd_emu10k1_fx8010_ctl_t *)kmalloc(sizeof(*ctl), GFP_KERNEL);
695 knew.private_value = (unsigned long)ctl;
696 memcpy(ctl, &nctl, sizeof(nctl));
697 if (snd_ctl_add(emu->card, kctl = snd_ctl_new1(&knew, emu)) < 0) {
701 kctl->private_free = snd_emu10k1_ctl_private_free;
702 ctl->kcontrol = kctl;
703 list_add_tail(&ctl->list, &emu->fx8010.gpr_ctl);
706 nctl.list = ctl->list;
707 nctl.kcontrol = ctl->kcontrol;
708 memcpy(ctl, &nctl, sizeof(nctl));
709 snd_ctl_notify(emu->card, SNDRV_CTL_EVENT_MASK_VALUE |
710 SNDRV_CTL_EVENT_MASK_INFO, &ctl->kcontrol->id);
712 snd_emu10k1_gpr_ctl_put(ctl->kcontrol, val);
717 static void snd_emu10k1_del_controls(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
720 snd_ctl_elem_id_t id;
721 snd_ctl_elem_id_t __user *_id;
722 snd_emu10k1_fx8010_ctl_t *ctl;
723 snd_card_t *card = emu->card;
725 for (i = 0, _id = icode->gpr_del_controls;
726 i < icode->gpr_del_control_count; i++, _id++) {
727 snd_runtime_check(copy_from_user(&id, _id, sizeof(id)) == 0, continue);
728 down_write(&card->controls_rwsem);
729 ctl = snd_emu10k1_look_for_ctl(emu, &id);
731 snd_ctl_remove(card, ctl->kcontrol);
732 up_write(&card->controls_rwsem);
736 static int snd_emu10k1_list_controls(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
738 unsigned int i = 0, j;
739 unsigned int total = 0;
740 emu10k1_fx8010_control_gpr_t gctl;
741 emu10k1_fx8010_control_gpr_t __user *_gctl;
742 snd_emu10k1_fx8010_ctl_t *ctl;
743 snd_ctl_elem_id_t *id;
744 struct list_head *list;
746 _gctl = icode->gpr_list_controls;
747 list_for_each(list, &emu->fx8010.gpr_ctl) {
748 ctl = emu10k1_gpr_ctl(list);
750 if (_gctl && i < icode->gpr_list_control_count) {
751 memset(&gctl, 0, sizeof(gctl));
752 id = &ctl->kcontrol->id;
753 gctl.id.iface = id->iface;
754 strlcpy(gctl.id.name, id->name, sizeof(gctl.id.name));
755 gctl.id.index = id->index;
756 gctl.id.device = id->device;
757 gctl.id.subdevice = id->subdevice;
758 gctl.vcount = ctl->vcount;
759 gctl.count = ctl->count;
760 for (j = 0; j < 32; j++) {
761 gctl.gpr[j] = ctl->gpr[j];
762 gctl.value[j] = ctl->value[j];
766 gctl.translation = ctl->translation;
767 if (copy_to_user(_gctl, &gctl, sizeof(gctl)))
773 icode->gpr_list_control_total = total;
777 static int snd_emu10k1_icode_poke(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
781 down(&emu->fx8010.lock);
782 if ((err = snd_emu10k1_verify_controls(emu, icode)) < 0)
784 strlcpy(emu->fx8010.name, icode->name, sizeof(emu->fx8010.name));
785 /* stop FX processor - this may be dangerous, but it's better to miss
786 some samples than generate wrong ones - [jk] */
788 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg | A_DBG_SINGLE_STEP);
790 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg | EMU10K1_DBG_SINGLE_STEP);
791 /* ok, do the main job */
792 snd_emu10k1_del_controls(emu, icode);
793 snd_emu10k1_gpr_poke(emu, icode);
794 snd_emu10k1_tram_poke(emu, icode);
795 snd_emu10k1_code_poke(emu, icode);
796 snd_emu10k1_add_controls(emu, icode);
797 /* start FX processor when the DSP code is updated */
799 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg);
801 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg);
803 up(&emu->fx8010.lock);
807 static int snd_emu10k1_icode_peek(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
811 down(&emu->fx8010.lock);
812 strlcpy(icode->name, emu->fx8010.name, sizeof(icode->name));
813 /* ok, do the main job */
814 snd_emu10k1_gpr_peek(emu, icode);
815 snd_emu10k1_tram_peek(emu, icode);
816 snd_emu10k1_code_peek(emu, icode);
817 err = snd_emu10k1_list_controls(emu, icode);
818 up(&emu->fx8010.lock);
822 static int snd_emu10k1_ipcm_poke(emu10k1_t *emu, emu10k1_fx8010_pcm_t *ipcm)
826 snd_emu10k1_fx8010_pcm_t *pcm;
828 if (ipcm->substream >= EMU10K1_FX8010_PCM_COUNT)
830 if (ipcm->channels > 32)
832 pcm = &emu->fx8010.pcm[ipcm->substream];
833 down(&emu->fx8010.lock);
834 spin_lock_irq(&emu->reg_lock);
839 if (ipcm->channels == 0) { /* remove */
842 /* FIXME: we need to add universal code to the PCM transfer routine */
843 if (ipcm->channels != 2) {
849 pcm->channels = ipcm->channels;
850 pcm->tram_start = ipcm->tram_start;
851 pcm->buffer_size = ipcm->buffer_size;
852 pcm->gpr_size = ipcm->gpr_size;
853 pcm->gpr_count = ipcm->gpr_count;
854 pcm->gpr_tmpcount = ipcm->gpr_tmpcount;
855 pcm->gpr_ptr = ipcm->gpr_ptr;
856 pcm->gpr_trigger = ipcm->gpr_trigger;
857 pcm->gpr_running = ipcm->gpr_running;
858 for (i = 0; i < pcm->channels; i++)
859 pcm->etram[i] = ipcm->etram[i];
862 spin_unlock_irq(&emu->reg_lock);
863 up(&emu->fx8010.lock);
867 static int snd_emu10k1_ipcm_peek(emu10k1_t *emu, emu10k1_fx8010_pcm_t *ipcm)
871 snd_emu10k1_fx8010_pcm_t *pcm;
873 if (ipcm->substream >= EMU10K1_FX8010_PCM_COUNT)
875 pcm = &emu->fx8010.pcm[ipcm->substream];
876 down(&emu->fx8010.lock);
877 spin_lock_irq(&emu->reg_lock);
878 ipcm->channels = pcm->channels;
879 ipcm->tram_start = pcm->tram_start;
880 ipcm->buffer_size = pcm->buffer_size;
881 ipcm->gpr_size = pcm->gpr_size;
882 ipcm->gpr_ptr = pcm->gpr_ptr;
883 ipcm->gpr_count = pcm->gpr_count;
884 ipcm->gpr_tmpcount = pcm->gpr_tmpcount;
885 ipcm->gpr_trigger = pcm->gpr_trigger;
886 ipcm->gpr_running = pcm->gpr_running;
887 for (i = 0; i < pcm->channels; i++)
888 ipcm->etram[i] = pcm->etram[i];
889 ipcm->res1 = ipcm->res2 = 0;
891 spin_unlock_irq(&emu->reg_lock);
892 up(&emu->fx8010.lock);
896 #define SND_EMU10K1_GPR_CONTROLS 41
897 #define SND_EMU10K1_INPUTS 10
898 #define SND_EMU10K1_PLAYBACK_CHANNELS 8
899 #define SND_EMU10K1_CAPTURE_CHANNELS 4
901 static void __devinit snd_emu10k1_init_mono_control(emu10k1_fx8010_control_gpr_t *ctl, const char *name, int gpr, int defval)
903 ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
904 strcpy(ctl->id.name, name);
905 ctl->vcount = ctl->count = 1;
906 ctl->gpr[0] = gpr + 0; ctl->value[0] = defval;
909 ctl->translation = EMU10K1_GPR_TRANSLATION_TABLE100;
912 static void __devinit snd_emu10k1_init_stereo_control(emu10k1_fx8010_control_gpr_t *ctl, const char *name, int gpr, int defval)
914 ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
915 strcpy(ctl->id.name, name);
916 ctl->vcount = ctl->count = 2;
917 ctl->gpr[0] = gpr + 0; ctl->value[0] = defval;
918 ctl->gpr[1] = gpr + 1; ctl->value[1] = defval;
921 ctl->translation = EMU10K1_GPR_TRANSLATION_TABLE100;
924 static void __devinit snd_emu10k1_init_mono_onoff_control(emu10k1_fx8010_control_gpr_t *ctl, const char *name, int gpr, int defval)
926 ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
927 strcpy(ctl->id.name, name);
928 ctl->vcount = ctl->count = 1;
929 ctl->gpr[0] = gpr + 0; ctl->value[0] = defval;
932 ctl->translation = EMU10K1_GPR_TRANSLATION_ONOFF;
935 static void __devinit snd_emu10k1_init_stereo_onoff_control(emu10k1_fx8010_control_gpr_t *ctl, const char *name, int gpr, int defval)
937 ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
938 strcpy(ctl->id.name, name);
939 ctl->vcount = ctl->count = 2;
940 ctl->gpr[0] = gpr + 0; ctl->value[0] = defval;
941 ctl->gpr[1] = gpr + 1; ctl->value[1] = defval;
944 ctl->translation = EMU10K1_GPR_TRANSLATION_ONOFF;
949 * initial DSP configuration for Audigy
952 static int __devinit _snd_emu10k1_audigy_init_efx(emu10k1_t *emu)
954 int err, i, z, gpr, nctl;
955 const int playback = 10;
956 const int capture = playback + (SND_EMU10K1_PLAYBACK_CHANNELS * 2); /* we reserve 10 voices */
957 const int stereo_mix = capture + 2;
958 const int tmp = 0x88;
960 emu10k1_fx8010_code_t *icode;
961 emu10k1_fx8010_control_gpr_t *controls, *ctl;
964 spin_lock_init(&emu->fx8010.irq_lock);
965 INIT_LIST_HEAD(&emu->fx8010.gpr_ctl);
967 if ((icode = kcalloc(1, sizeof(*icode), GFP_KERNEL)) == NULL)
969 if ((controls = kcalloc(SND_EMU10K1_GPR_CONTROLS, sizeof(*controls), GFP_KERNEL)) == NULL) {
974 /* clear free GPRs */
975 for (i = 0; i < 512; i++)
976 set_bit(i, icode->gpr_valid);
978 /* clear TRAM data & address lines */
979 for (i = 0; i < 256; i++)
980 set_bit(i, icode->tram_valid);
982 strcpy(icode->name, "Audigy DSP code for ALSA");
985 gpr = stereo_mix + 10;
987 /* stop FX processor */
988 snd_emu10k1_ptr_write(emu, A_DBG, 0, (emu->fx8010.dbg = 0) | A_DBG_SINGLE_STEP);
990 /* PCM front Playback Volume (independent from stereo mix) */
991 A_OP(icode, &ptr, iMAC0, A_GPR(playback), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LEFT_FRONT));
992 A_OP(icode, &ptr, iMAC0, A_GPR(playback+1), A_C_00000000, A_GPR(gpr+1), A_FXBUS(FXBUS_PCM_RIGHT_FRONT));
993 snd_emu10k1_init_stereo_control(&controls[nctl++], "PCM Front Playback Volume", gpr, 100);
996 /* PCM Surround Playback (independent from stereo mix) */
997 A_OP(icode, &ptr, iMAC0, A_GPR(playback+2), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LEFT_REAR));
998 A_OP(icode, &ptr, iMAC0, A_GPR(playback+3), A_C_00000000, A_GPR(gpr+1), A_FXBUS(FXBUS_PCM_RIGHT_REAR));
999 snd_emu10k1_init_stereo_control(&controls[nctl++], "PCM Surround Playback Volume", gpr, 100);
1002 /* PCM Side Playback (independent from stereo mix) */
1004 A_OP(icode, &ptr, iMAC0, A_GPR(playback+6), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LEFT_SIDE));
1005 A_OP(icode, &ptr, iMAC0, A_GPR(playback+7), A_C_00000000, A_GPR(gpr+1), A_FXBUS(FXBUS_PCM_RIGHT_SIDE));
1006 snd_emu10k1_init_stereo_control(&controls[nctl++], "PCM Side Playback Volume", gpr, 100);
1010 /* PCM Center Playback (independent from stereo mix) */
1011 A_OP(icode, &ptr, iMAC0, A_GPR(playback+4), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_CENTER));
1012 snd_emu10k1_init_mono_control(&controls[nctl++], "PCM Center Playback Volume", gpr, 100);
1015 /* PCM LFE Playback (independent from stereo mix) */
1016 A_OP(icode, &ptr, iMAC0, A_GPR(playback+5), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LFE));
1017 snd_emu10k1_init_mono_control(&controls[nctl++], "PCM LFE Playback Volume", gpr, 100);
1023 /* Wave (PCM) Playback Volume (will be renamed later) */
1024 A_OP(icode, &ptr, iMAC0, A_GPR(stereo_mix), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LEFT));
1025 A_OP(icode, &ptr, iMAC0, A_GPR(stereo_mix+1), A_C_00000000, A_GPR(gpr+1), A_FXBUS(FXBUS_PCM_RIGHT));
1026 snd_emu10k1_init_stereo_control(&controls[nctl++], "Wave Playback Volume", gpr, 100);
1029 /* Music Playback */
1030 A_OP(icode, &ptr, iMAC0, A_GPR(stereo_mix+0), A_GPR(stereo_mix+0), A_GPR(gpr), A_FXBUS(FXBUS_MIDI_LEFT));
1031 A_OP(icode, &ptr, iMAC0, A_GPR(stereo_mix+1), A_GPR(stereo_mix+1), A_GPR(gpr+1), A_FXBUS(FXBUS_MIDI_RIGHT));
1032 snd_emu10k1_init_stereo_control(&controls[nctl++], "Music Playback Volume", gpr, 100);
1035 /* Wave (PCM) Capture */
1036 A_OP(icode, &ptr, iMAC0, A_GPR(capture+0), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LEFT));
1037 A_OP(icode, &ptr, iMAC0, A_GPR(capture+1), A_C_00000000, A_GPR(gpr+1), A_FXBUS(FXBUS_PCM_RIGHT));
1038 snd_emu10k1_init_stereo_control(&controls[nctl++], "PCM Capture Volume", gpr, 0);
1042 A_OP(icode, &ptr, iMAC0, A_GPR(capture+0), A_GPR(capture+0), A_GPR(gpr), A_FXBUS(FXBUS_MIDI_LEFT));
1043 A_OP(icode, &ptr, iMAC0, A_GPR(capture+1), A_GPR(capture+1), A_GPR(gpr+1), A_FXBUS(FXBUS_MIDI_RIGHT));
1044 snd_emu10k1_init_stereo_control(&controls[nctl++], "Music Capture Volume", gpr, 0);
1050 #define A_ADD_VOLUME_IN(var,vol,input) \
1051 A_OP(icode, &ptr, iMAC0, A_GPR(var), A_GPR(var), A_GPR(vol), A_EXTIN(input))
1053 /* AC'97 Playback Volume - used only for mic (renamed later) */
1054 A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_AC97_L);
1055 A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_AC97_R);
1056 snd_emu10k1_init_stereo_control(&controls[nctl++], "AMic Playback Volume", gpr, 0);
1058 /* AC'97 Capture Volume - used only for mic */
1059 A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_AC97_L);
1060 A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_AC97_R);
1061 snd_emu10k1_init_stereo_control(&controls[nctl++], "Mic Capture Volume", gpr, 0);
1064 /* mic capture buffer */
1065 A_OP(icode, &ptr, iINTERP, A_EXTOUT(A_EXTOUT_MIC_CAP), A_EXTIN(A_EXTIN_AC97_L), 0xcd, A_EXTIN(A_EXTIN_AC97_R));
1067 /* Audigy CD Playback Volume */
1068 A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_SPDIF_CD_L);
1069 A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_SPDIF_CD_R);
1070 snd_emu10k1_init_stereo_control(&controls[nctl++],
1071 emu->no_ac97 ? "CD Playback Volume" : "Audigy CD Playback Volume",
1074 /* Audigy CD Capture Volume */
1075 A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_SPDIF_CD_L);
1076 A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_SPDIF_CD_R);
1077 snd_emu10k1_init_stereo_control(&controls[nctl++],
1078 emu->no_ac97 ? "CD Capture Volume" : "Audigy CD Capture Volume",
1082 /* Optical SPDIF Playback Volume */
1083 A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_OPT_SPDIF_L);
1084 A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_OPT_SPDIF_R);
1085 snd_emu10k1_init_stereo_control(&controls[nctl++], "IEC958 Optical Playback Volume", gpr, 0);
1087 /* Optical SPDIF Capture Volume */
1088 A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_OPT_SPDIF_L);
1089 A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_OPT_SPDIF_R);
1090 snd_emu10k1_init_stereo_control(&controls[nctl++], "IEC958 Optical Capture Volume", gpr, 0);
1093 /* Line2 Playback Volume */
1094 A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_LINE2_L);
1095 A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_LINE2_R);
1096 snd_emu10k1_init_stereo_control(&controls[nctl++],
1097 emu->no_ac97 ? "Line Playback Volume" : "Line2 Playback Volume",
1100 /* Line2 Capture Volume */
1101 A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_LINE2_L);
1102 A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_LINE2_R);
1103 snd_emu10k1_init_stereo_control(&controls[nctl++],
1104 emu->no_ac97 ? "Line Capture Volume" : "Line2 Capture Volume",
1108 /* Philips ADC Playback Volume */
1109 A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_ADC_L);
1110 A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_ADC_R);
1111 snd_emu10k1_init_stereo_control(&controls[nctl++], "Analog Mix Playback Volume", gpr, 0);
1113 /* Philips ADC Capture Volume */
1114 A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_ADC_L);
1115 A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_ADC_R);
1116 snd_emu10k1_init_stereo_control(&controls[nctl++], "Analog Mix Capture Volume", gpr, 0);
1119 /* Aux2 Playback Volume */
1120 A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_AUX2_L);
1121 A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_AUX2_R);
1122 snd_emu10k1_init_stereo_control(&controls[nctl++],
1123 emu->no_ac97 ? "Aux Playback Volume" : "Aux2 Playback Volume",
1126 /* Aux2 Capture Volume */
1127 A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_AUX2_L);
1128 A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_AUX2_R);
1129 snd_emu10k1_init_stereo_control(&controls[nctl++],
1130 emu->no_ac97 ? "Aux Capture Volume" : "Aux2 Capture Volume",
1134 /* Stereo Mix Front Playback Volume */
1135 A_OP(icode, &ptr, iMAC0, A_GPR(playback), A_GPR(playback), A_GPR(gpr), A_GPR(stereo_mix));
1136 A_OP(icode, &ptr, iMAC0, A_GPR(playback+1), A_GPR(playback+1), A_GPR(gpr+1), A_GPR(stereo_mix+1));
1137 snd_emu10k1_init_stereo_control(&controls[nctl++], "Front Playback Volume", gpr, 100);
1140 /* Stereo Mix Surround Playback */
1141 A_OP(icode, &ptr, iMAC0, A_GPR(playback+2), A_GPR(playback+2), A_GPR(gpr), A_GPR(stereo_mix));
1142 A_OP(icode, &ptr, iMAC0, A_GPR(playback+3), A_GPR(playback+3), A_GPR(gpr+1), A_GPR(stereo_mix+1));
1143 snd_emu10k1_init_stereo_control(&controls[nctl++], "Surround Playback Volume", gpr, 0);
1146 /* Stereo Mix Center Playback */
1147 /* Center = sub = Left/2 + Right/2 */
1148 A_OP(icode, &ptr, iINTERP, A_GPR(tmp), A_GPR(stereo_mix), 0xcd, A_GPR(stereo_mix+1));
1149 A_OP(icode, &ptr, iMAC0, A_GPR(playback+4), A_GPR(playback+4), A_GPR(gpr), A_GPR(tmp));
1150 snd_emu10k1_init_mono_control(&controls[nctl++], "Center Playback Volume", gpr, 0);
1153 /* Stereo Mix LFE Playback */
1154 A_OP(icode, &ptr, iMAC0, A_GPR(playback+5), A_GPR(playback+5), A_GPR(gpr), A_GPR(tmp));
1155 snd_emu10k1_init_mono_control(&controls[nctl++], "LFE Playback Volume", gpr, 0);
1159 /* Stereo Mix Side Playback */
1160 A_OP(icode, &ptr, iMAC0, A_GPR(playback+6), A_GPR(playback+6), A_GPR(gpr), A_GPR(stereo_mix));
1161 A_OP(icode, &ptr, iMAC0, A_GPR(playback+7), A_GPR(playback+7), A_GPR(gpr+1), A_GPR(stereo_mix+1));
1162 snd_emu10k1_init_stereo_control(&controls[nctl++], "Side Playback Volume", gpr, 0);
1169 #define A_PUT_OUTPUT(out,src) A_OP(icode, &ptr, iACC3, A_EXTOUT(out), A_C_00000000, A_C_00000000, A_GPR(src))
1170 #define A_PUT_STEREO_OUTPUT(out1,out2,src) \
1171 {A_PUT_OUTPUT(out1,src); A_PUT_OUTPUT(out2,src+1);}
1173 #define _A_SWITCH(icode, ptr, dst, src, sw) \
1174 A_OP((icode), ptr, iMACINT0, dst, A_C_00000000, src, sw);
1175 #define A_SWITCH(icode, ptr, dst, src, sw) \
1176 _A_SWITCH(icode, ptr, A_GPR(dst), A_GPR(src), A_GPR(sw))
1177 #define _A_SWITCH_NEG(icode, ptr, dst, src) \
1178 A_OP((icode), ptr, iANDXOR, dst, src, A_C_00000001, A_C_00000001);
1179 #define A_SWITCH_NEG(icode, ptr, dst, src) \
1180 _A_SWITCH_NEG(icode, ptr, A_GPR(dst), A_GPR(src))
1184 * Process tone control
1186 A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 0), A_GPR(playback + 0), A_C_00000000, A_C_00000000); /* left */
1187 A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 1), A_GPR(playback + 1), A_C_00000000, A_C_00000000); /* right */
1188 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 */
1189 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 */
1190 A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 4), A_GPR(playback + 4), A_C_00000000, A_C_00000000); /* center */
1191 A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 5), A_GPR(playback + 5), A_C_00000000, A_C_00000000); /* LFE */
1193 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 */
1194 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 */
1198 ctl = &controls[nctl + 0];
1199 ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1200 strcpy(ctl->id.name, "Tone Control - Bass");
1205 ctl->value[0] = ctl->value[1] = 20;
1206 ctl->translation = EMU10K1_GPR_TRANSLATION_BASS;
1207 ctl = &controls[nctl + 1];
1208 ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1209 strcpy(ctl->id.name, "Tone Control - Treble");
1214 ctl->value[0] = ctl->value[1] = 20;
1215 ctl->translation = EMU10K1_GPR_TRANSLATION_TREBLE;
1217 #define BASS_GPR 0x8c
1218 #define TREBLE_GPR 0x96
1220 for (z = 0; z < 5; z++) {
1222 for (j = 0; j < 2; j++) {
1223 controls[nctl + 0].gpr[z * 2 + j] = BASS_GPR + z * 2 + j;
1224 controls[nctl + 1].gpr[z * 2 + j] = TREBLE_GPR + z * 2 + j;
1227 for (z = 0; z < 4; z++) { /* front/rear/center-lfe/side */
1229 for (j = 0; j < 2; j++) { /* left/right */
1230 k = 0xb0 + (z * 8) + (j * 4);
1231 l = 0xe0 + (z * 8) + (j * 4);
1232 d = playback + SND_EMU10K1_PLAYBACK_CHANNELS + z * 2 + j;
1234 A_OP(icode, &ptr, iMAC0, A_C_00000000, A_C_00000000, A_GPR(d), A_GPR(BASS_GPR + 0 + j));
1235 A_OP(icode, &ptr, iMACMV, A_GPR(k+1), A_GPR(k), A_GPR(k+1), A_GPR(BASS_GPR + 4 + j));
1236 A_OP(icode, &ptr, iMACMV, A_GPR(k), A_GPR(d), A_GPR(k), A_GPR(BASS_GPR + 2 + j));
1237 A_OP(icode, &ptr, iMACMV, A_GPR(k+3), A_GPR(k+2), A_GPR(k+3), A_GPR(BASS_GPR + 8 + j));
1238 A_OP(icode, &ptr, iMAC0, A_GPR(k+2), A_GPR_ACCU, A_GPR(k+2), A_GPR(BASS_GPR + 6 + j));
1239 A_OP(icode, &ptr, iACC3, A_GPR(k+2), A_GPR(k+2), A_GPR(k+2), A_C_00000000);
1241 A_OP(icode, &ptr, iMAC0, A_C_00000000, A_C_00000000, A_GPR(k+2), A_GPR(TREBLE_GPR + 0 + j));
1242 A_OP(icode, &ptr, iMACMV, A_GPR(l+1), A_GPR(l), A_GPR(l+1), A_GPR(TREBLE_GPR + 4 + j));
1243 A_OP(icode, &ptr, iMACMV, A_GPR(l), A_GPR(k+2), A_GPR(l), A_GPR(TREBLE_GPR + 2 + j));
1244 A_OP(icode, &ptr, iMACMV, A_GPR(l+3), A_GPR(l+2), A_GPR(l+3), A_GPR(TREBLE_GPR + 8 + j));
1245 A_OP(icode, &ptr, iMAC0, A_GPR(l+2), A_GPR_ACCU, A_GPR(l+2), A_GPR(TREBLE_GPR + 6 + j));
1246 A_OP(icode, &ptr, iMACINT0, A_GPR(l+2), A_C_00000000, A_GPR(l+2), A_C_00000010);
1248 A_OP(icode, &ptr, iACC3, A_GPR(d), A_GPR(l+2), A_C_00000000, A_C_00000000);
1250 if (z == 2) /* center */
1259 for (z = 0; z < 8; z++) {
1260 A_SWITCH(icode, &ptr, tmp + 0, playback + SND_EMU10K1_PLAYBACK_CHANNELS + z, gpr + 0);
1261 A_SWITCH_NEG(icode, &ptr, tmp + 1, gpr + 0);
1262 A_SWITCH(icode, &ptr, tmp + 1, playback + z, tmp + 1);
1263 A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + z), A_GPR(tmp + 0), A_GPR(tmp + 1), A_C_00000000);
1265 snd_emu10k1_init_stereo_onoff_control(controls + nctl++, "Tone Control - Switch", gpr, 0);
1268 /* Master volume (will be renamed later) */
1269 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));
1270 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));
1271 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));
1272 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));
1273 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));
1274 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));
1275 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));
1276 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));
1277 snd_emu10k1_init_mono_control(&controls[nctl++], "Wave Master Playback Volume", gpr, 0);
1280 /* analog speakers */
1281 A_PUT_STEREO_OUTPUT(A_EXTOUT_AFRONT_L, A_EXTOUT_AFRONT_R, playback + SND_EMU10K1_PLAYBACK_CHANNELS);
1282 A_PUT_STEREO_OUTPUT(A_EXTOUT_AREAR_L, A_EXTOUT_AREAR_R, playback+2 + SND_EMU10K1_PLAYBACK_CHANNELS);
1283 A_PUT_OUTPUT(A_EXTOUT_ACENTER, playback+4 + SND_EMU10K1_PLAYBACK_CHANNELS);
1284 A_PUT_OUTPUT(A_EXTOUT_ALFE, playback+5 + SND_EMU10K1_PLAYBACK_CHANNELS);
1286 A_PUT_STEREO_OUTPUT(A_EXTOUT_ASIDE_L, A_EXTOUT_ASIDE_R, playback+6 + SND_EMU10K1_PLAYBACK_CHANNELS);
1289 A_PUT_STEREO_OUTPUT(A_EXTOUT_HEADPHONE_L, A_EXTOUT_HEADPHONE_R, playback + SND_EMU10K1_PLAYBACK_CHANNELS);
1291 /* digital outputs */
1292 /* A_PUT_STEREO_OUTPUT(A_EXTOUT_FRONT_L, A_EXTOUT_FRONT_R, playback + SND_EMU10K1_PLAYBACK_CHANNELS); */
1294 /* IEC958 Optical Raw Playback Switch */
1295 icode->gpr_map[gpr++] = 0x1008;
1296 icode->gpr_map[gpr++] = 0xffff0000;
1297 for (z = 0; z < 2; z++) {
1298 A_OP(icode, &ptr, iMAC0, A_GPR(tmp + 2), A_FXBUS(FXBUS_PT_LEFT + z), A_C_00000000, A_C_00000000);
1299 A_OP(icode, &ptr, iSKIP, A_GPR_COND, A_GPR_COND, A_GPR(gpr - 2), A_C_00000001);
1300 A_OP(icode, &ptr, iACC3, A_GPR(tmp + 2), A_C_00000000, A_C_00010000, A_GPR(tmp + 2));
1301 A_OP(icode, &ptr, iANDXOR, A_GPR(tmp + 2), A_GPR(tmp + 2), A_GPR(gpr - 1), A_C_00000000);
1302 A_SWITCH(icode, &ptr, tmp + 0, tmp + 2, gpr + z);
1303 A_SWITCH_NEG(icode, &ptr, tmp + 1, gpr + z);
1304 A_SWITCH(icode, &ptr, tmp + 1, playback + SND_EMU10K1_PLAYBACK_CHANNELS + z, tmp + 1);
1305 A_OP(icode, &ptr, iACC3, A_EXTOUT(A_EXTOUT_FRONT_L + z), A_GPR(tmp + 0), A_GPR(tmp + 1), A_C_00000000);
1307 snd_emu10k1_init_stereo_onoff_control(controls + nctl++, "IEC958 Optical Raw Playback Switch", gpr, 0);
1310 A_PUT_STEREO_OUTPUT(A_EXTOUT_REAR_L, A_EXTOUT_REAR_R, playback+2 + SND_EMU10K1_PLAYBACK_CHANNELS);
1311 A_PUT_OUTPUT(A_EXTOUT_CENTER, playback+4 + SND_EMU10K1_PLAYBACK_CHANNELS);
1312 A_PUT_OUTPUT(A_EXTOUT_LFE, playback+5 + SND_EMU10K1_PLAYBACK_CHANNELS);
1315 A_PUT_OUTPUT(A_EXTOUT_ADC_CAP_L, capture);
1316 A_PUT_OUTPUT(A_EXTOUT_ADC_CAP_R, capture+1);
1327 /* clear remaining instruction memory */
1329 A_OP(icode, &ptr, 0x0f, 0xc0, 0xc0, 0xcf, 0xc0);
1331 seg = snd_enter_user();
1332 icode->gpr_add_control_count = nctl;
1333 icode->gpr_add_controls = controls;
1334 err = snd_emu10k1_icode_poke(emu, icode);
1335 snd_leave_user(seg);
1345 * initial DSP configuration for Emu10k1
1348 /* when volume = max, then copy only to avoid volume modification */
1349 /* with iMAC0 (negative values) */
1350 static void __devinit _volume(emu10k1_fx8010_code_t *icode, u32 *ptr, u32 dst, u32 src, u32 vol)
1352 OP(icode, ptr, iMAC0, dst, C_00000000, src, 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_00000001);
1355 OP(icode, ptr, iACC3, dst, src, C_00000000, C_00000000);
1357 static void __devinit _volume_add(emu10k1_fx8010_code_t *icode, u32 *ptr, u32 dst, u32 src, u32 vol)
1359 OP(icode, ptr, iANDXOR, C_00000000, vol, C_ffffffff, C_7fffffff);
1360 OP(icode, ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, C_00000002);
1361 OP(icode, ptr, iMACINT0, dst, dst, src, C_00000001);
1362 OP(icode, ptr, iSKIP, C_00000000, C_7fffffff, C_7fffffff, C_00000001);
1363 OP(icode, ptr, iMAC0, dst, dst, src, vol);
1365 static void __devinit _volume_out(emu10k1_fx8010_code_t *icode, u32 *ptr, u32 dst, u32 src, u32 vol)
1367 OP(icode, ptr, iANDXOR, C_00000000, vol, C_ffffffff, C_7fffffff);
1368 OP(icode, ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, C_00000002);
1369 OP(icode, ptr, iACC3, dst, src, C_00000000, C_00000000);
1370 OP(icode, ptr, iSKIP, C_00000000, C_7fffffff, C_7fffffff, C_00000001);
1371 OP(icode, ptr, iMAC0, dst, C_00000000, src, vol);
1374 #define VOLUME(icode, ptr, dst, src, vol) \
1375 _volume(icode, ptr, GPR(dst), GPR(src), GPR(vol))
1376 #define VOLUME_IN(icode, ptr, dst, src, vol) \
1377 _volume(icode, ptr, GPR(dst), EXTIN(src), GPR(vol))
1378 #define VOLUME_ADD(icode, ptr, dst, src, vol) \
1379 _volume_add(icode, ptr, GPR(dst), GPR(src), GPR(vol))
1380 #define VOLUME_ADDIN(icode, ptr, dst, src, vol) \
1381 _volume_add(icode, ptr, GPR(dst), EXTIN(src), GPR(vol))
1382 #define VOLUME_OUT(icode, ptr, dst, src, vol) \
1383 _volume_out(icode, ptr, EXTOUT(dst), GPR(src), GPR(vol))
1384 #define _SWITCH(icode, ptr, dst, src, sw) \
1385 OP((icode), ptr, iMACINT0, dst, C_00000000, src, sw);
1386 #define SWITCH(icode, ptr, dst, src, sw) \
1387 _SWITCH(icode, ptr, GPR(dst), GPR(src), GPR(sw))
1388 #define SWITCH_IN(icode, ptr, dst, src, sw) \
1389 _SWITCH(icode, ptr, GPR(dst), EXTIN(src), GPR(sw))
1390 #define _SWITCH_NEG(icode, ptr, dst, src) \
1391 OP((icode), ptr, iANDXOR, dst, src, C_00000001, C_00000001);
1392 #define SWITCH_NEG(icode, ptr, dst, src) \
1393 _SWITCH_NEG(icode, ptr, GPR(dst), GPR(src))
1396 static int __devinit _snd_emu10k1_init_efx(emu10k1_t *emu)
1398 int err, i, z, gpr, tmp, playback, capture;
1400 emu10k1_fx8010_code_t *icode;
1401 emu10k1_fx8010_pcm_t *ipcm;
1402 emu10k1_fx8010_control_gpr_t *controls, *ctl;
1405 spin_lock_init(&emu->fx8010.irq_lock);
1406 INIT_LIST_HEAD(&emu->fx8010.gpr_ctl);
1408 if ((icode = kcalloc(1, sizeof(*icode), GFP_KERNEL)) == NULL)
1410 if ((controls = kcalloc(SND_EMU10K1_GPR_CONTROLS, sizeof(emu10k1_fx8010_control_gpr_t), GFP_KERNEL)) == NULL) {
1414 if ((ipcm = kcalloc(1, sizeof(*ipcm), GFP_KERNEL)) == NULL) {
1420 /* clear free GPRs */
1421 for (i = 0; i < 256; i++)
1422 set_bit(i, icode->gpr_valid);
1424 /* clear TRAM data & address lines */
1425 for (i = 0; i < 160; i++)
1426 set_bit(i, icode->tram_valid);
1428 strcpy(icode->name, "SB Live! FX8010 code for ALSA v1.2 by Jaroslav Kysela");
1430 /* we have 10 inputs */
1431 playback = SND_EMU10K1_INPUTS;
1432 /* we have 6 playback channels and tone control doubles */
1433 capture = playback + (SND_EMU10K1_PLAYBACK_CHANNELS * 2);
1434 gpr = capture + SND_EMU10K1_CAPTURE_CHANNELS;
1435 tmp = 0x88; /* we need 4 temporary GPR */
1436 /* from 0x8c to 0xff is the area for tone control */
1438 /* stop FX processor */
1439 snd_emu10k1_ptr_write(emu, DBG, 0, (emu->fx8010.dbg = 0) | EMU10K1_DBG_SINGLE_STEP);
1444 OP(icode, &ptr, iMACINT0, GPR(0), C_00000000, FXBUS(FXBUS_PCM_LEFT), C_00000004);
1445 OP(icode, &ptr, iMACINT0, GPR(1), C_00000000, FXBUS(FXBUS_PCM_RIGHT), C_00000004);
1446 OP(icode, &ptr, iMACINT0, GPR(2), C_00000000, FXBUS(FXBUS_MIDI_LEFT), C_00000004);
1447 OP(icode, &ptr, iMACINT0, GPR(3), C_00000000, FXBUS(FXBUS_MIDI_RIGHT), C_00000004);
1448 OP(icode, &ptr, iMACINT0, GPR(4), C_00000000, FXBUS(FXBUS_PCM_LEFT_REAR), C_00000004);
1449 OP(icode, &ptr, iMACINT0, GPR(5), C_00000000, FXBUS(FXBUS_PCM_RIGHT_REAR), C_00000004);
1450 OP(icode, &ptr, iMACINT0, GPR(6), C_00000000, FXBUS(FXBUS_PCM_CENTER), C_00000004);
1451 OP(icode, &ptr, iMACINT0, GPR(7), C_00000000, FXBUS(FXBUS_PCM_LFE), C_00000004);
1452 OP(icode, &ptr, iMACINT0, GPR(8), C_00000000, C_00000000, C_00000000); /* S/PDIF left */
1453 OP(icode, &ptr, iMACINT0, GPR(9), C_00000000, C_00000000, C_00000000); /* S/PDIF right */
1455 /* Raw S/PDIF PCM */
1456 ipcm->substream = 0;
1458 ipcm->tram_start = 0;
1459 ipcm->buffer_size = (64 * 1024) / 2;
1460 ipcm->gpr_size = gpr++;
1461 ipcm->gpr_ptr = gpr++;
1462 ipcm->gpr_count = gpr++;
1463 ipcm->gpr_tmpcount = gpr++;
1464 ipcm->gpr_trigger = gpr++;
1465 ipcm->gpr_running = gpr++;
1469 icode->gpr_map[gpr + 0] = 0xfffff000;
1470 icode->gpr_map[gpr + 1] = 0xffff0000;
1471 icode->gpr_map[gpr + 2] = 0x70000000;
1472 icode->gpr_map[gpr + 3] = 0x00000007;
1473 icode->gpr_map[gpr + 4] = 0x001f << 11;
1474 icode->gpr_map[gpr + 5] = 0x001c << 11;
1475 icode->gpr_map[gpr + 6] = (0x22 - 0x01) - 1; /* skip at 01 to 22 */
1476 icode->gpr_map[gpr + 7] = (0x22 - 0x06) - 1; /* skip at 06 to 22 */
1477 icode->gpr_map[gpr + 8] = 0x2000000 + (2<<11);
1478 icode->gpr_map[gpr + 9] = 0x4000000 + (2<<11);
1479 icode->gpr_map[gpr + 10] = 1<<11;
1480 icode->gpr_map[gpr + 11] = (0x24 - 0x0a) - 1; /* skip at 0a to 24 */
1481 icode->gpr_map[gpr + 12] = 0;
1483 /* if the trigger flag is not set, skip */
1484 /* 00: */ OP(icode, &ptr, iMAC0, C_00000000, GPR(ipcm->gpr_trigger), C_00000000, C_00000000);
1485 /* 01: */ OP(icode, &ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_ZERO, GPR(gpr + 6));
1486 /* if the running flag is set, we're running */
1487 /* 02: */ OP(icode, &ptr, iMAC0, C_00000000, GPR(ipcm->gpr_running), C_00000000, C_00000000);
1488 /* 03: */ OP(icode, &ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, C_00000004);
1489 /* wait until ((GPR_DBAC>>11) & 0x1f) == 0x1c) */
1490 /* 04: */ OP(icode, &ptr, iANDXOR, GPR(tmp + 0), GPR_DBAC, GPR(gpr + 4), C_00000000);
1491 /* 05: */ OP(icode, &ptr, iMACINT0, C_00000000, GPR(tmp + 0), C_ffffffff, GPR(gpr + 5));
1492 /* 06: */ OP(icode, &ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, GPR(gpr + 7));
1493 /* 07: */ OP(icode, &ptr, iACC3, GPR(gpr + 12), C_00000010, C_00000001, C_00000000);
1495 /* 08: */ OP(icode, &ptr, iANDXOR, GPR(ipcm->gpr_running), GPR(ipcm->gpr_running), C_00000000, C_00000001);
1496 /* 09: */ OP(icode, &ptr, iACC3, GPR(gpr + 12), GPR(gpr + 12), C_ffffffff, C_00000000);
1497 /* 0a: */ OP(icode, &ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, GPR(gpr + 11));
1498 /* 0b: */ OP(icode, &ptr, iACC3, GPR(gpr + 12), C_00000001, C_00000000, C_00000000);
1500 /* 0c: */ OP(icode, &ptr, iANDXOR, GPR(tmp + 0), ETRAM_DATA(ipcm->etram[0]), GPR(gpr + 0), C_00000000);
1501 /* 0d: */ OP(icode, &ptr, iLOG, GPR(tmp + 0), GPR(tmp + 0), GPR(gpr + 3), C_00000000);
1502 /* 0e: */ OP(icode, &ptr, iANDXOR, GPR(8), GPR(tmp + 0), GPR(gpr + 1), GPR(gpr + 2));
1503 /* 0f: */ OP(icode, &ptr, iSKIP, C_00000000, GPR_COND, CC_REG_MINUS, C_00000001);
1504 /* 10: */ OP(icode, &ptr, iANDXOR, GPR(8), GPR(8), GPR(gpr + 1), GPR(gpr + 2));
1506 /* 11: */ OP(icode, &ptr, iANDXOR, GPR(tmp + 0), ETRAM_DATA(ipcm->etram[1]), GPR(gpr + 0), C_00000000);
1507 /* 12: */ OP(icode, &ptr, iLOG, GPR(tmp + 0), GPR(tmp + 0), GPR(gpr + 3), C_00000000);
1508 /* 13: */ OP(icode, &ptr, iANDXOR, GPR(9), GPR(tmp + 0), GPR(gpr + 1), GPR(gpr + 2));
1509 /* 14: */ OP(icode, &ptr, iSKIP, C_00000000, GPR_COND, CC_REG_MINUS, C_00000001);
1510 /* 15: */ OP(icode, &ptr, iANDXOR, GPR(9), GPR(9), GPR(gpr + 1), GPR(gpr + 2));
1512 /* 16: */ OP(icode, &ptr, iACC3, GPR(tmp + 0), GPR(ipcm->gpr_ptr), C_00000001, C_00000000);
1513 /* 17: */ OP(icode, &ptr, iMACINT0, C_00000000, GPR(tmp + 0), C_ffffffff, GPR(ipcm->gpr_size));
1514 /* 18: */ OP(icode, &ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_MINUS, C_00000001);
1515 /* 19: */ OP(icode, &ptr, iACC3, GPR(tmp + 0), C_00000000, C_00000000, C_00000000);
1516 /* 1a: */ OP(icode, &ptr, iACC3, GPR(ipcm->gpr_ptr), GPR(tmp + 0), C_00000000, C_00000000);
1518 /* 1b: */ OP(icode, &ptr, iACC3, GPR(ipcm->gpr_tmpcount), GPR(ipcm->gpr_tmpcount), C_ffffffff, C_00000000);
1519 /* 1c: */ OP(icode, &ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, C_00000002);
1520 /* 1d: */ OP(icode, &ptr, iACC3, GPR(ipcm->gpr_tmpcount), GPR(ipcm->gpr_count), C_00000000, C_00000000);
1521 /* 1e: */ OP(icode, &ptr, iACC3, GPR_IRQ, C_80000000, C_00000000, C_00000000);
1522 /* 1f: */ OP(icode, &ptr, iANDXOR, GPR(ipcm->gpr_running), GPR(ipcm->gpr_running), C_00000001, C_00010000);
1524 /* 20: */ OP(icode, &ptr, iANDXOR, GPR(ipcm->gpr_running), GPR(ipcm->gpr_running), C_00010000, C_00000001);
1525 /* 21: */ OP(icode, &ptr, iSKIP, C_00000000, C_7fffffff, C_7fffffff, C_00000002);
1527 /* 22: */ OP(icode, &ptr, iMACINT1, ETRAM_ADDR(ipcm->etram[0]), GPR(gpr + 8), GPR_DBAC, C_ffffffff);
1528 /* 23: */ OP(icode, &ptr, iMACINT1, ETRAM_ADDR(ipcm->etram[1]), GPR(gpr + 9), GPR_DBAC, C_ffffffff);
1533 /* Wave Playback Volume */
1534 for (z = 0; z < 2; z++)
1535 VOLUME(icode, &ptr, playback + z, z, gpr + z);
1536 snd_emu10k1_init_stereo_control(controls + i++, "Wave Playback Volume", gpr, 100);
1539 /* Wave Surround Playback Volume */
1540 for (z = 0; z < 2; z++)
1541 VOLUME(icode, &ptr, playback + 2 + z, z, gpr + z);
1542 snd_emu10k1_init_stereo_control(controls + i++, "Wave Surround Playback Volume", gpr, 0);
1545 /* Wave Center/LFE Playback Volume */
1546 OP(icode, &ptr, iACC3, GPR(tmp + 0), FXBUS(FXBUS_PCM_LEFT), FXBUS(FXBUS_PCM_RIGHT), C_00000000);
1547 OP(icode, &ptr, iMACINT0, GPR(tmp + 0), C_00000000, GPR(tmp + 0), C_00000002);
1548 VOLUME(icode, &ptr, playback + 4, tmp + 0, gpr);
1549 snd_emu10k1_init_mono_control(controls + i++, "Wave Center Playback Volume", gpr++, 0);
1550 VOLUME(icode, &ptr, playback + 5, tmp + 0, gpr);
1551 snd_emu10k1_init_mono_control(controls + i++, "Wave LFE Playback Volume", gpr++, 0);
1553 /* Wave Capture Volume + Switch */
1554 for (z = 0; z < 2; z++) {
1555 SWITCH(icode, &ptr, tmp + 0, z, gpr + 2 + z);
1556 VOLUME(icode, &ptr, capture + z, tmp + 0, gpr + z);
1558 snd_emu10k1_init_stereo_control(controls + i++, "Wave Capture Volume", gpr, 0);
1559 snd_emu10k1_init_stereo_onoff_control(controls + i++, "Wave Capture Switch", gpr + 2, 0);
1562 /* Music Playback Volume */
1563 for (z = 0; z < 2; z++)
1564 VOLUME_ADD(icode, &ptr, playback + z, 2 + z, gpr + z);
1565 snd_emu10k1_init_stereo_control(controls + i++, "Music Playback Volume", gpr, 100);
1568 /* Music Capture Volume + Switch */
1569 for (z = 0; z < 2; z++) {
1570 SWITCH(icode, &ptr, tmp + 0, 2 + z, gpr + 2 + z);
1571 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
1573 snd_emu10k1_init_stereo_control(controls + i++, "Music Capture Volume", gpr, 0);
1574 snd_emu10k1_init_stereo_onoff_control(controls + i++, "Music Capture Switch", gpr + 2, 0);
1577 /* Surround Digital Playback Volume (renamed later without Digital) */
1578 for (z = 0; z < 2; z++)
1579 VOLUME_ADD(icode, &ptr, playback + 2 + z, 4 + z, gpr + z);
1580 snd_emu10k1_init_stereo_control(controls + i++, "Surround Digital Playback Volume", gpr, 100);
1583 /* Surround Capture Volume + Switch */
1584 for (z = 0; z < 2; z++) {
1585 SWITCH(icode, &ptr, tmp + 0, 4 + z, gpr + 2 + z);
1586 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
1588 snd_emu10k1_init_stereo_control(controls + i++, "Surround Capture Volume", gpr, 0);
1589 snd_emu10k1_init_stereo_onoff_control(controls + i++, "Surround Capture Switch", gpr + 2, 0);
1592 /* Center Playback Volume (renamed later without Digital) */
1593 VOLUME_ADD(icode, &ptr, playback + 4, 6, gpr);
1594 snd_emu10k1_init_mono_control(controls + i++, "Center Digital Playback Volume", gpr++, 100);
1596 /* LFE Playback Volume + Switch (renamed later without Digital) */
1597 VOLUME_ADD(icode, &ptr, playback + 5, 7, gpr);
1598 snd_emu10k1_init_mono_control(controls + i++, "LFE Digital Playback Volume", gpr++, 100);
1604 if (emu->fx8010.extin_mask & ((1<<EXTIN_AC97_L)|(1<<EXTIN_AC97_R))) {
1605 /* AC'97 Playback Volume */
1606 VOLUME_ADDIN(icode, &ptr, playback + 0, EXTIN_AC97_L, gpr); gpr++;
1607 VOLUME_ADDIN(icode, &ptr, playback + 1, EXTIN_AC97_R, gpr); gpr++;
1608 snd_emu10k1_init_stereo_control(controls + i++, "AC97 Playback Volume", gpr-2, 0);
1609 /* AC'97 Capture Volume */
1610 VOLUME_ADDIN(icode, &ptr, capture + 0, EXTIN_AC97_L, gpr); gpr++;
1611 VOLUME_ADDIN(icode, &ptr, capture + 1, EXTIN_AC97_R, gpr); gpr++;
1612 snd_emu10k1_init_stereo_control(controls + i++, "AC97 Capture Volume", gpr-2, 100);
1615 if (emu->fx8010.extin_mask & ((1<<EXTIN_SPDIF_CD_L)|(1<<EXTIN_SPDIF_CD_R))) {
1616 /* IEC958 TTL Playback Volume */
1617 for (z = 0; z < 2; z++)
1618 VOLUME_ADDIN(icode, &ptr, playback + z, EXTIN_SPDIF_CD_L + z, gpr + z);
1619 snd_emu10k1_init_stereo_control(controls + i++, "IEC958 TTL Playback Volume", gpr, 0);
1622 /* IEC958 TTL Capture Volume + Switch */
1623 for (z = 0; z < 2; z++) {
1624 SWITCH_IN(icode, &ptr, tmp + 0, EXTIN_SPDIF_CD_L + z, gpr + 2 + z);
1625 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
1627 snd_emu10k1_init_stereo_control(controls + i++, "IEC958 TTL Capture Volume", gpr, 0);
1628 snd_emu10k1_init_stereo_onoff_control(controls + i++, "IEC958 TTL Capture Switch", gpr + 2, 0);
1632 if (emu->fx8010.extin_mask & ((1<<EXTIN_ZOOM_L)|(1<<EXTIN_ZOOM_R))) {
1633 /* Zoom Video Playback Volume */
1634 for (z = 0; z < 2; z++)
1635 VOLUME_ADDIN(icode, &ptr, playback + z, EXTIN_ZOOM_L + z, gpr + z);
1636 snd_emu10k1_init_stereo_control(controls + i++, "Zoom Video Playback Volume", gpr, 0);
1639 /* Zoom Video Capture Volume + Switch */
1640 for (z = 0; z < 2; z++) {
1641 SWITCH_IN(icode, &ptr, tmp + 0, EXTIN_ZOOM_L + z, gpr + 2 + z);
1642 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
1644 snd_emu10k1_init_stereo_control(controls + i++, "Zoom Video Capture Volume", gpr, 0);
1645 snd_emu10k1_init_stereo_onoff_control(controls + i++, "Zoom Video Capture Switch", gpr + 2, 0);
1649 if (emu->fx8010.extin_mask & ((1<<EXTIN_TOSLINK_L)|(1<<EXTIN_TOSLINK_R))) {
1650 /* IEC958 Optical Playback Volume */
1651 for (z = 0; z < 2; z++)
1652 VOLUME_ADDIN(icode, &ptr, playback + z, EXTIN_TOSLINK_L + z, gpr + z);
1653 snd_emu10k1_init_stereo_control(controls + i++, "IEC958 LiveDrive Playback Volume", gpr, 0);
1656 /* IEC958 Optical Capture Volume */
1657 for (z = 0; z < 2; z++) {
1658 SWITCH_IN(icode, &ptr, tmp + 0, EXTIN_TOSLINK_L + z, gpr + 2 + z);
1659 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
1661 snd_emu10k1_init_stereo_control(controls + i++, "IEC958 LiveDrive Capture Volume", gpr, 0);
1662 snd_emu10k1_init_stereo_onoff_control(controls + i++, "IEC958 LiveDrive Capture Switch", gpr + 2, 0);
1666 if (emu->fx8010.extin_mask & ((1<<EXTIN_LINE1_L)|(1<<EXTIN_LINE1_R))) {
1667 /* Line LiveDrive Playback Volume */
1668 for (z = 0; z < 2; z++)
1669 VOLUME_ADDIN(icode, &ptr, playback + z, EXTIN_LINE1_L + z, gpr + z);
1670 snd_emu10k1_init_stereo_control(controls + i++, "Line LiveDrive Playback Volume", gpr, 0);
1673 /* Line LiveDrive Capture Volume + Switch */
1674 for (z = 0; z < 2; z++) {
1675 SWITCH_IN(icode, &ptr, tmp + 0, EXTIN_LINE1_L + z, gpr + 2 + z);
1676 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
1678 snd_emu10k1_init_stereo_control(controls + i++, "Line LiveDrive Capture Volume", gpr, 0);
1679 snd_emu10k1_init_stereo_onoff_control(controls + i++, "Line LiveDrive Capture Switch", gpr + 2, 0);
1683 if (emu->fx8010.extin_mask & ((1<<EXTIN_COAX_SPDIF_L)|(1<<EXTIN_COAX_SPDIF_R))) {
1684 /* IEC958 Coax Playback Volume */
1685 for (z = 0; z < 2; z++)
1686 VOLUME_ADDIN(icode, &ptr, playback + z, EXTIN_COAX_SPDIF_L + z, gpr + z);
1687 snd_emu10k1_init_stereo_control(controls + i++, "IEC958 Coaxial Playback Volume", gpr, 0);
1690 /* IEC958 Coax Capture Volume + Switch */
1691 for (z = 0; z < 2; z++) {
1692 SWITCH_IN(icode, &ptr, tmp + 0, EXTIN_COAX_SPDIF_L + z, gpr + 2 + z);
1693 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
1695 snd_emu10k1_init_stereo_control(controls + i++, "IEC958 Coaxial Capture Volume", gpr, 0);
1696 snd_emu10k1_init_stereo_onoff_control(controls + i++, "IEC958 Coaxial Capture Switch", gpr + 2, 0);
1700 if (emu->fx8010.extin_mask & ((1<<EXTIN_LINE2_L)|(1<<EXTIN_LINE2_R))) {
1701 /* Line LiveDrive Playback Volume */
1702 for (z = 0; z < 2; z++)
1703 VOLUME_ADDIN(icode, &ptr, playback + z, EXTIN_LINE2_L + z, gpr + z);
1704 snd_emu10k1_init_stereo_control(controls + i++, "Line2 LiveDrive Playback Volume", gpr, 0);
1705 controls[i-1].id.index = 1;
1708 /* Line LiveDrive Capture Volume */
1709 for (z = 0; z < 2; z++) {
1710 SWITCH_IN(icode, &ptr, tmp + 0, EXTIN_LINE2_L + z, gpr + 2 + z);
1711 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
1713 snd_emu10k1_init_stereo_control(controls + i++, "Line2 LiveDrive Capture Volume", gpr, 0);
1714 controls[i-1].id.index = 1;
1715 snd_emu10k1_init_stereo_onoff_control(controls + i++, "Line2 LiveDrive Capture Switch", gpr + 2, 0);
1716 controls[i-1].id.index = 1;
1721 * Process tone control
1723 OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 0), GPR(playback + 0), C_00000000, C_00000000); /* left */
1724 OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 1), GPR(playback + 1), C_00000000, C_00000000); /* right */
1725 OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 2), GPR(playback + 2), C_00000000, C_00000000); /* rear left */
1726 OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 3), GPR(playback + 3), C_00000000, C_00000000); /* rear right */
1727 OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 4), GPR(playback + 4), C_00000000, C_00000000); /* center */
1728 OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 5), GPR(playback + 5), C_00000000, C_00000000); /* LFE */
1730 ctl = &controls[i + 0];
1731 ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1732 strcpy(ctl->id.name, "Tone Control - Bass");
1737 ctl->value[0] = ctl->value[1] = 20;
1738 ctl->translation = EMU10K1_GPR_TRANSLATION_BASS;
1739 ctl = &controls[i + 1];
1740 ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1741 strcpy(ctl->id.name, "Tone Control - Treble");
1746 ctl->value[0] = ctl->value[1] = 20;
1747 ctl->translation = EMU10K1_GPR_TRANSLATION_TREBLE;
1749 #define BASS_GPR 0x8c
1750 #define TREBLE_GPR 0x96
1752 for (z = 0; z < 5; z++) {
1754 for (j = 0; j < 2; j++) {
1755 controls[i + 0].gpr[z * 2 + j] = BASS_GPR + z * 2 + j;
1756 controls[i + 1].gpr[z * 2 + j] = TREBLE_GPR + z * 2 + j;
1759 for (z = 0; z < 3; z++) { /* front/rear/center-lfe */
1761 for (j = 0; j < 2; j++) { /* left/right */
1762 k = 0xa0 + (z * 8) + (j * 4);
1763 l = 0xd0 + (z * 8) + (j * 4);
1764 d = playback + SND_EMU10K1_PLAYBACK_CHANNELS + z * 2 + j;
1766 OP(icode, &ptr, iMAC0, C_00000000, C_00000000, GPR(d), GPR(BASS_GPR + 0 + j));
1767 OP(icode, &ptr, iMACMV, GPR(k+1), GPR(k), GPR(k+1), GPR(BASS_GPR + 4 + j));
1768 OP(icode, &ptr, iMACMV, GPR(k), GPR(d), GPR(k), GPR(BASS_GPR + 2 + j));
1769 OP(icode, &ptr, iMACMV, GPR(k+3), GPR(k+2), GPR(k+3), GPR(BASS_GPR + 8 + j));
1770 OP(icode, &ptr, iMAC0, GPR(k+2), GPR_ACCU, GPR(k+2), GPR(BASS_GPR + 6 + j));
1771 OP(icode, &ptr, iACC3, GPR(k+2), GPR(k+2), GPR(k+2), C_00000000);
1773 OP(icode, &ptr, iMAC0, C_00000000, C_00000000, GPR(k+2), GPR(TREBLE_GPR + 0 + j));
1774 OP(icode, &ptr, iMACMV, GPR(l+1), GPR(l), GPR(l+1), GPR(TREBLE_GPR + 4 + j));
1775 OP(icode, &ptr, iMACMV, GPR(l), GPR(k+2), GPR(l), GPR(TREBLE_GPR + 2 + j));
1776 OP(icode, &ptr, iMACMV, GPR(l+3), GPR(l+2), GPR(l+3), GPR(TREBLE_GPR + 8 + j));
1777 OP(icode, &ptr, iMAC0, GPR(l+2), GPR_ACCU, GPR(l+2), GPR(TREBLE_GPR + 6 + j));
1778 OP(icode, &ptr, iMACINT0, GPR(l+2), C_00000000, GPR(l+2), C_00000010);
1780 OP(icode, &ptr, iACC3, GPR(d), GPR(l+2), C_00000000, C_00000000);
1782 if (z == 2) /* center */
1791 for (z = 0; z < 6; z++) {
1792 SWITCH(icode, &ptr, tmp + 0, playback + SND_EMU10K1_PLAYBACK_CHANNELS + z, gpr + 0);
1793 SWITCH_NEG(icode, &ptr, tmp + 1, gpr + 0);
1794 SWITCH(icode, &ptr, tmp + 1, playback + z, tmp + 1);
1795 OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + z), GPR(tmp + 0), GPR(tmp + 1), C_00000000);
1797 snd_emu10k1_init_stereo_onoff_control(controls + i++, "Tone Control - Switch", gpr, 0);
1803 if (emu->fx8010.extout_mask & ((1<<EXTOUT_AC97_L)|(1<<EXTOUT_AC97_R))) {
1804 /* AC'97 Playback Volume */
1806 for (z = 0; z < 2; z++)
1807 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_AC97_L + z), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + z), C_00000000, C_00000000);
1810 if (emu->fx8010.extout_mask & ((1<<EXTOUT_TOSLINK_L)|(1<<EXTOUT_TOSLINK_R))) {
1811 /* IEC958 Optical Raw Playback Switch */
1813 for (z = 0; z < 2; z++) {
1814 SWITCH(icode, &ptr, tmp + 0, 8 + z, gpr + z);
1815 SWITCH_NEG(icode, &ptr, tmp + 1, gpr + z);
1816 SWITCH(icode, &ptr, tmp + 1, playback + SND_EMU10K1_PLAYBACK_CHANNELS + z, tmp + 1);
1817 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_TOSLINK_L + z), GPR(tmp + 0), GPR(tmp + 1), C_00000000);
1818 #ifdef EMU10K1_CAPTURE_DIGITAL_OUT
1819 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_ADC_CAP_L + z), GPR(tmp + 0), GPR(tmp + 1), C_00000000);
1823 snd_emu10k1_init_stereo_onoff_control(controls + i++, "IEC958 Optical Raw Playback Switch", gpr, 0);
1827 if (emu->fx8010.extout_mask & ((1<<EXTOUT_HEADPHONE_L)|(1<<EXTOUT_HEADPHONE_R))) {
1828 /* Headphone Playback Volume */
1830 for (z = 0; z < 2; z++) {
1831 SWITCH(icode, &ptr, tmp + 0, playback + SND_EMU10K1_PLAYBACK_CHANNELS + 4 + z, gpr + 2 + z);
1832 SWITCH_NEG(icode, &ptr, tmp + 1, gpr + 2 + z);
1833 SWITCH(icode, &ptr, tmp + 1, playback + SND_EMU10K1_PLAYBACK_CHANNELS + z, tmp + 1);
1834 OP(icode, &ptr, iACC3, GPR(tmp + 0), GPR(tmp + 0), GPR(tmp + 1), C_00000000);
1835 VOLUME_OUT(icode, &ptr, EXTOUT_HEADPHONE_L + z, tmp + 0, gpr + z);
1838 snd_emu10k1_init_stereo_control(controls + i++, "Headphone Playback Volume", gpr + 0, 0);
1839 controls[i-1].id.index = 1; /* AC'97 can have also Headphone control */
1840 snd_emu10k1_init_mono_onoff_control(controls + i++, "Headphone Center Playback Switch", gpr + 2, 0);
1841 controls[i-1].id.index = 1;
1842 snd_emu10k1_init_mono_onoff_control(controls + i++, "Headphone LFE Playback Switch", gpr + 3, 0);
1843 controls[i-1].id.index = 1;
1848 if (emu->fx8010.extout_mask & ((1<<EXTOUT_REAR_L)|(1<<EXTOUT_REAR_R)))
1849 for (z = 0; z < 2; z++)
1850 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_REAR_L + z), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 2 + z), C_00000000, C_00000000);
1852 if (emu->fx8010.extout_mask & ((1<<EXTOUT_AC97_REAR_L)|(1<<EXTOUT_AC97_REAR_R)))
1853 for (z = 0; z < 2; z++)
1854 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_AC97_REAR_L + z), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 2 + z), C_00000000, C_00000000);
1856 if (emu->fx8010.extout_mask & (1<<EXTOUT_AC97_CENTER)) {
1857 #ifndef EMU10K1_CENTER_LFE_FROM_FRONT
1858 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_AC97_CENTER), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 4), C_00000000, C_00000000);
1859 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_ACENTER), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 4), C_00000000, C_00000000);
1861 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_AC97_CENTER), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 0), C_00000000, C_00000000);
1862 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_ACENTER), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 0), C_00000000, C_00000000);
1866 if (emu->fx8010.extout_mask & (1<<EXTOUT_AC97_LFE)) {
1867 #ifndef EMU10K1_CENTER_LFE_FROM_FRONT
1868 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_AC97_LFE), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 5), C_00000000, C_00000000);
1869 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_ALFE), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 5), C_00000000, C_00000000);
1871 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_AC97_LFE), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 1), C_00000000, C_00000000);
1872 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_ALFE), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 1), C_00000000, C_00000000);
1876 #ifndef EMU10K1_CAPTURE_DIGITAL_OUT
1877 for (z = 0; z < 2; z++)
1878 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_ADC_CAP_L + z), GPR(capture + z), C_00000000, C_00000000);
1881 if (emu->fx8010.extout_mask & (1<<EXTOUT_MIC_CAP))
1882 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_MIC_CAP), GPR(capture + 2), C_00000000, C_00000000);
1889 if (i > SND_EMU10K1_GPR_CONTROLS) {
1895 /* clear remaining instruction memory */
1897 OP(icode, &ptr, iACC3, C_00000000, C_00000000, C_00000000, C_00000000);
1899 if ((err = snd_emu10k1_fx8010_tram_setup(emu, ipcm->buffer_size)) < 0)
1901 seg = snd_enter_user();
1902 icode->gpr_add_control_count = i;
1903 icode->gpr_add_controls = controls;
1904 err = snd_emu10k1_icode_poke(emu, icode);
1905 snd_leave_user(seg);
1907 err = snd_emu10k1_ipcm_poke(emu, ipcm);
1915 int __devinit snd_emu10k1_init_efx(emu10k1_t *emu)
1918 return _snd_emu10k1_audigy_init_efx(emu);
1920 return _snd_emu10k1_init_efx(emu);
1923 void snd_emu10k1_free_efx(emu10k1_t *emu)
1925 /* stop processor */
1927 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg = A_DBG_SINGLE_STEP);
1929 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg = EMU10K1_DBG_SINGLE_STEP);
1932 #if 0 // FIXME: who use them?
1933 int snd_emu10k1_fx8010_tone_control_activate(emu10k1_t *emu, int output)
1935 snd_runtime_check(output >= 0 && output < 6, return -EINVAL);
1936 snd_emu10k1_ptr_write(emu, emu->gpr_base + 0x94 + output, 0, 1);
1940 int snd_emu10k1_fx8010_tone_control_deactivate(emu10k1_t *emu, int output)
1942 snd_runtime_check(output >= 0 && output < 6, return -EINVAL);
1943 snd_emu10k1_ptr_write(emu, emu->gpr_base + 0x94 + output, 0, 0);
1948 int snd_emu10k1_fx8010_tram_setup(emu10k1_t *emu, u32 size)
1952 /* size is in samples */
1954 size = (size - 1) >> 13;
1960 size = 0x2000 << size_reg;
1962 if (emu->fx8010.etram_pages.bytes == size)
1964 spin_lock_irq(&emu->emu_lock);
1965 outl(HCFG_LOCKTANKCACHE_MASK | inl(emu->port + HCFG), emu->port + HCFG);
1966 spin_unlock_irq(&emu->emu_lock);
1967 snd_emu10k1_ptr_write(emu, TCB, 0, 0);
1968 snd_emu10k1_ptr_write(emu, TCBS, 0, 0);
1969 if (emu->fx8010.etram_pages.area != NULL) {
1970 snd_dma_free_pages(&emu->fx8010.etram_pages);
1971 emu->fx8010.etram_pages.area = NULL;
1972 emu->fx8010.etram_pages.bytes = 0;
1976 if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(emu->pci),
1977 size * 2, &emu->fx8010.etram_pages) < 0)
1979 memset(emu->fx8010.etram_pages.area, 0, size * 2);
1980 snd_emu10k1_ptr_write(emu, TCB, 0, emu->fx8010.etram_pages.addr);
1981 snd_emu10k1_ptr_write(emu, TCBS, 0, size_reg);
1982 spin_lock_irq(&emu->emu_lock);
1983 outl(inl(emu->port + HCFG) & ~HCFG_LOCKTANKCACHE_MASK, emu->port + HCFG);
1984 spin_unlock_irq(&emu->emu_lock);
1990 static int snd_emu10k1_fx8010_open(snd_hwdep_t * hw, struct file *file)
1995 static void copy_string(char *dst, char *src, char *null, int idx)
1998 sprintf(dst, "%s %02X", null, idx);
2003 static int snd_emu10k1_fx8010_info(emu10k1_t *emu, emu10k1_fx8010_info_t *info)
2005 char **fxbus, **extin, **extout;
2006 unsigned short fxbus_mask, extin_mask, extout_mask;
2009 memset(info, 0, sizeof(info));
2010 info->card = emu->card_type;
2011 info->internal_tram_size = emu->fx8010.itram_size;
2012 info->external_tram_size = emu->fx8010.etram_pages.bytes;
2014 extin = emu->audigy ? audigy_ins : creative_ins;
2015 extout = emu->audigy ? audigy_outs : creative_outs;
2016 fxbus_mask = emu->fx8010.fxbus_mask;
2017 extin_mask = emu->fx8010.extin_mask;
2018 extout_mask = emu->fx8010.extout_mask;
2019 for (res = 0; res < 16; res++, fxbus++, extin++, extout++) {
2020 copy_string(info->fxbus_names[res], fxbus_mask & (1 << res) ? *fxbus : NULL, "FXBUS", res);
2021 copy_string(info->extin_names[res], extin_mask & (1 << res) ? *extin : NULL, "Unused", res);
2022 copy_string(info->extout_names[res], extout_mask & (1 << res) ? *extout : NULL, "Unused", res);
2024 for (res = 16; res < 32; res++, extout++)
2025 copy_string(info->extout_names[res], extout_mask & (1 << res) ? *extout : NULL, "Unused", res);
2026 info->gpr_controls = emu->fx8010.gpr_count;
2030 static int snd_emu10k1_fx8010_ioctl(snd_hwdep_t * hw, struct file *file, unsigned int cmd, unsigned long arg)
2032 emu10k1_t *emu = hw->private_data;
2033 emu10k1_fx8010_info_t *info;
2034 emu10k1_fx8010_code_t *icode;
2035 emu10k1_fx8010_pcm_t *ipcm;
2037 void __user *argp = (void __user *)arg;
2041 case SNDRV_EMU10K1_IOCTL_INFO:
2042 info = (emu10k1_fx8010_info_t *)kmalloc(sizeof(*info), GFP_KERNEL);
2045 if ((res = snd_emu10k1_fx8010_info(emu, info)) < 0) {
2049 if (copy_to_user(argp, info, sizeof(*info))) {
2055 case SNDRV_EMU10K1_IOCTL_CODE_POKE:
2056 if (!capable(CAP_SYS_ADMIN))
2058 icode = (emu10k1_fx8010_code_t *)kmalloc(sizeof(*icode), GFP_KERNEL);
2061 if (copy_from_user(icode, argp, sizeof(*icode))) {
2065 res = snd_emu10k1_icode_poke(emu, icode);
2068 case SNDRV_EMU10K1_IOCTL_CODE_PEEK:
2069 icode = (emu10k1_fx8010_code_t *)kmalloc(sizeof(*icode), GFP_KERNEL);
2072 if (copy_from_user(icode, argp, sizeof(*icode))) {
2076 res = snd_emu10k1_icode_peek(emu, icode);
2077 if (res == 0 && copy_to_user(argp, icode, sizeof(*icode))) {
2083 case SNDRV_EMU10K1_IOCTL_PCM_POKE:
2084 ipcm = (emu10k1_fx8010_pcm_t *)kmalloc(sizeof(*ipcm), GFP_KERNEL);
2087 if (copy_from_user(ipcm, argp, sizeof(*ipcm))) {
2091 res = snd_emu10k1_ipcm_poke(emu, ipcm);
2094 case SNDRV_EMU10K1_IOCTL_PCM_PEEK:
2095 ipcm = kcalloc(1, sizeof(*ipcm), GFP_KERNEL);
2098 if (copy_from_user(ipcm, argp, sizeof(*ipcm))) {
2102 res = snd_emu10k1_ipcm_peek(emu, ipcm);
2103 if (res == 0 && copy_to_user(argp, ipcm, sizeof(*ipcm))) {
2109 case SNDRV_EMU10K1_IOCTL_TRAM_SETUP:
2110 if (!capable(CAP_SYS_ADMIN))
2112 if (get_user(addr, (unsigned int __user *)argp))
2114 down(&emu->fx8010.lock);
2115 res = snd_emu10k1_fx8010_tram_setup(emu, addr);
2116 up(&emu->fx8010.lock);
2118 case SNDRV_EMU10K1_IOCTL_STOP:
2119 if (!capable(CAP_SYS_ADMIN))
2122 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg |= A_DBG_SINGLE_STEP);
2124 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg |= EMU10K1_DBG_SINGLE_STEP);
2126 case SNDRV_EMU10K1_IOCTL_CONTINUE:
2127 if (!capable(CAP_SYS_ADMIN))
2130 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg = 0);
2132 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg = 0);
2134 case SNDRV_EMU10K1_IOCTL_ZERO_TRAM_COUNTER:
2135 if (!capable(CAP_SYS_ADMIN))
2138 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg | A_DBG_ZC);
2140 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg | EMU10K1_DBG_ZC);
2143 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg);
2145 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg);
2147 case SNDRV_EMU10K1_IOCTL_SINGLE_STEP:
2148 if (!capable(CAP_SYS_ADMIN))
2150 if (get_user(addr, (unsigned int __user *)argp))
2155 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg |= A_DBG_SINGLE_STEP | addr);
2157 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg |= EMU10K1_DBG_SINGLE_STEP | addr);
2160 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg |= A_DBG_SINGLE_STEP | A_DBG_STEP_ADDR | addr);
2162 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg |= EMU10K1_DBG_SINGLE_STEP | EMU10K1_DBG_STEP | addr);
2164 case SNDRV_EMU10K1_IOCTL_DBG_READ:
2166 addr = snd_emu10k1_ptr_read(emu, A_DBG, 0);
2168 addr = snd_emu10k1_ptr_read(emu, DBG, 0);
2169 if (put_user(addr, (unsigned int __user *)argp))
2176 static int snd_emu10k1_fx8010_release(snd_hwdep_t * hw, struct file *file)
2181 int __devinit snd_emu10k1_fx8010_new(emu10k1_t *emu, int device, snd_hwdep_t ** rhwdep)
2188 if ((err = snd_hwdep_new(emu->card, "FX8010", device, &hw)) < 0)
2190 strcpy(hw->name, "EMU10K1 (FX8010)");
2191 hw->iface = SNDRV_HWDEP_IFACE_EMU10K1;
2192 hw->ops.open = snd_emu10k1_fx8010_open;
2193 hw->ops.ioctl = snd_emu10k1_fx8010_ioctl;
2194 hw->ops.release = snd_emu10k1_fx8010_release;
2195 hw->private_data = emu;