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/capability.h>
31 #include <linux/delay.h>
32 #include <linux/slab.h>
33 #include <linux/vmalloc.h>
34 #include <linux/init.h>
35 #include <sound/core.h>
36 #include <sound/emu10k1.h>
38 #if 0 /* for testing purposes - digital out -> capture */
39 #define EMU10K1_CAPTURE_DIGITAL_OUT
41 #if 0 /* for testing purposes - set S/PDIF to AC3 output */
42 #define EMU10K1_SET_AC3_IEC958
44 #if 0 /* for testing purposes - feed the front signal to Center/LFE outputs */
45 #define EMU10K1_CENTER_LFE_FROM_FRONT
52 static char *fxbuses[16] = {
53 /* 0x00 */ "PCM Left",
54 /* 0x01 */ "PCM Right",
55 /* 0x02 */ "PCM Surround Left",
56 /* 0x03 */ "PCM Surround Right",
57 /* 0x04 */ "MIDI Left",
58 /* 0x05 */ "MIDI Right",
65 /* 0x0c */ "MIDI Reverb",
66 /* 0x0d */ "MIDI Chorus",
71 static char *creative_ins[16] = {
72 /* 0x00 */ "AC97 Left",
73 /* 0x01 */ "AC97 Right",
74 /* 0x02 */ "TTL IEC958 Left",
75 /* 0x03 */ "TTL IEC958 Right",
76 /* 0x04 */ "Zoom Video Left",
77 /* 0x05 */ "Zoom Video Right",
78 /* 0x06 */ "Optical IEC958 Left",
79 /* 0x07 */ "Optical IEC958 Right",
80 /* 0x08 */ "Line/Mic 1 Left",
81 /* 0x09 */ "Line/Mic 1 Right",
82 /* 0x0a */ "Coaxial IEC958 Left",
83 /* 0x0b */ "Coaxial IEC958 Right",
84 /* 0x0c */ "Line/Mic 2 Left",
85 /* 0x0d */ "Line/Mic 2 Right",
90 static char *audigy_ins[16] = {
91 /* 0x00 */ "AC97 Left",
92 /* 0x01 */ "AC97 Right",
93 /* 0x02 */ "Audigy CD Left",
94 /* 0x03 */ "Audigy CD Right",
95 /* 0x04 */ "Optical IEC958 Left",
96 /* 0x05 */ "Optical IEC958 Right",
99 /* 0x08 */ "Line/Mic 2 Left",
100 /* 0x09 */ "Line/Mic 2 Right",
101 /* 0x0a */ "SPDIF Left",
102 /* 0x0b */ "SPDIF Right",
103 /* 0x0c */ "Aux2 Left",
104 /* 0x0d */ "Aux2 Right",
109 static char *creative_outs[32] = {
110 /* 0x00 */ "AC97 Left",
111 /* 0x01 */ "AC97 Right",
112 /* 0x02 */ "Optical IEC958 Left",
113 /* 0x03 */ "Optical IEC958 Right",
116 /* 0x06 */ "Headphone Left",
117 /* 0x07 */ "Headphone Right",
118 /* 0x08 */ "Surround Left",
119 /* 0x09 */ "Surround Right",
120 /* 0x0a */ "PCM Capture Left",
121 /* 0x0b */ "PCM Capture Right",
122 /* 0x0c */ "MIC Capture",
123 /* 0x0d */ "AC97 Surround Left",
124 /* 0x0e */ "AC97 Surround Right",
127 /* 0x11 */ "Analog Center",
128 /* 0x12 */ "Analog LFE",
144 static char *audigy_outs[32] = {
145 /* 0x00 */ "Digital Front Left",
146 /* 0x01 */ "Digital Front Right",
147 /* 0x02 */ "Digital Center",
148 /* 0x03 */ "Digital LEF",
149 /* 0x04 */ "Headphone Left",
150 /* 0x05 */ "Headphone Right",
151 /* 0x06 */ "Digital Rear Left",
152 /* 0x07 */ "Digital Rear Right",
153 /* 0x08 */ "Front Left",
154 /* 0x09 */ "Front Right",
159 /* 0x0e */ "Rear Left",
160 /* 0x0f */ "Rear Right",
161 /* 0x10 */ "AC97 Front Left",
162 /* 0x11 */ "AC97 Front Right",
163 /* 0x12 */ "ADC Caputre Left",
164 /* 0x13 */ "ADC Capture Right",
179 static const u32 bass_table[41][5] = {
180 { 0x3e4f844f, 0x84ed4cc3, 0x3cc69927, 0x7b03553a, 0xc4da8486 },
181 { 0x3e69a17a, 0x84c280fb, 0x3cd77cd4, 0x7b2f2a6f, 0xc4b08d1d },
182 { 0x3e82ff42, 0x849991d5, 0x3ce7466b, 0x7b5917c6, 0xc48863ee },
183 { 0x3e9bab3c, 0x847267f0, 0x3cf5ffe8, 0x7b813560, 0xc461f22c },
184 { 0x3eb3b275, 0x844ced29, 0x3d03b295, 0x7ba79a1c, 0xc43d223b },
185 { 0x3ecb2174, 0x84290c8b, 0x3d106714, 0x7bcc5ba3, 0xc419dfa5 },
186 { 0x3ee2044b, 0x8406b244, 0x3d1c2561, 0x7bef8e77, 0xc3f8170f },
187 { 0x3ef86698, 0x83e5cb96, 0x3d26f4d8, 0x7c114600, 0xc3d7b625 },
188 { 0x3f0e5390, 0x83c646c9, 0x3d30dc39, 0x7c319498, 0xc3b8ab97 },
189 { 0x3f23d60b, 0x83a81321, 0x3d39e1af, 0x7c508b9c, 0xc39ae704 },
190 { 0x3f38f884, 0x838b20d2, 0x3d420ad2, 0x7c6e3b75, 0xc37e58f1 },
191 { 0x3f4dc52c, 0x836f60ef, 0x3d495cab, 0x7c8ab3a6, 0xc362f2be },
192 { 0x3f6245e8, 0x8354c565, 0x3d4fdbb8, 0x7ca602d6, 0xc348a69b },
193 { 0x3f76845f, 0x833b40ec, 0x3d558bf0, 0x7cc036df, 0xc32f677c },
194 { 0x3f8a8a03, 0x8322c6fb, 0x3d5a70c4, 0x7cd95cd7, 0xc317290b },
195 { 0x3f9e6014, 0x830b4bc3, 0x3d5e8d25, 0x7cf1811a, 0xc2ffdfa5 },
196 { 0x3fb20fae, 0x82f4c420, 0x3d61e37f, 0x7d08af56, 0xc2e9804a },
197 { 0x3fc5a1cc, 0x82df2592, 0x3d6475c3, 0x7d1ef294, 0xc2d40096 },
198 { 0x3fd91f55, 0x82ca6632, 0x3d664564, 0x7d345541, 0xc2bf56b9 },
199 { 0x3fec9120, 0x82b67cac, 0x3d675356, 0x7d48e138, 0xc2ab796e },
200 { 0x40000000, 0x82a36037, 0x3d67a012, 0x7d5c9fc9, 0xc2985fee },
201 { 0x401374c7, 0x8291088a, 0x3d672b93, 0x7d6f99c3, 0xc28601f2 },
202 { 0x4026f857, 0x827f6dd7, 0x3d65f559, 0x7d81d77c, 0xc27457a3 },
203 { 0x403a939f, 0x826e88c5, 0x3d63fc63, 0x7d9360d4, 0xc2635996 },
204 { 0x404e4faf, 0x825e5266, 0x3d613f32, 0x7da43d42, 0xc25300c6 },
205 { 0x406235ba, 0x824ec434, 0x3d5dbbc3, 0x7db473d7, 0xc243468e },
206 { 0x40764f1f, 0x823fd80c, 0x3d596f8f, 0x7dc40b44, 0xc23424a2 },
207 { 0x408aa576, 0x82318824, 0x3d545787, 0x7dd309e2, 0xc2259509 },
208 { 0x409f4296, 0x8223cf0b, 0x3d4e7012, 0x7de175b5, 0xc2179218 },
209 { 0x40b430a0, 0x8216a7a1, 0x3d47b505, 0x7def5475, 0xc20a1670 },
210 { 0x40c97a0a, 0x820a0d12, 0x3d4021a1, 0x7dfcab8d, 0xc1fd1cf5 },
211 { 0x40df29a6, 0x81fdfad6, 0x3d37b08d, 0x7e098028, 0xc1f0a0ca },
212 { 0x40f54ab1, 0x81f26ca9, 0x3d2e5bd1, 0x7e15d72b, 0xc1e49d52 },
213 { 0x410be8da, 0x81e75e89, 0x3d241cce, 0x7e21b544, 0xc1d90e24 },
214 { 0x41231051, 0x81dcccb3, 0x3d18ec37, 0x7e2d1ee6, 0xc1cdef10 },
215 { 0x413acdd0, 0x81d2b39e, 0x3d0cc20a, 0x7e38184e, 0xc1c33c13 },
216 { 0x41532ea7, 0x81c90ffb, 0x3cff9585, 0x7e42a58b, 0xc1b8f15a },
217 { 0x416c40cd, 0x81bfdeb2, 0x3cf15d21, 0x7e4cca7c, 0xc1af0b3f },
218 { 0x418612ea, 0x81b71cdc, 0x3ce20e85, 0x7e568ad3, 0xc1a58640 },
219 { 0x41a0b465, 0x81aec7c5, 0x3cd19e7c, 0x7e5fea1e, 0xc19c5f03 },
220 { 0x41bc3573, 0x81a6dcea, 0x3cc000e9, 0x7e68ebc2, 0xc1939250 }
223 static const u32 treble_table[41][5] = {
224 { 0x0125cba9, 0xfed5debd, 0x00599b6c, 0x0d2506da, 0xfa85b354 },
225 { 0x0142f67e, 0xfeb03163, 0x0066cd0f, 0x0d14c69d, 0xfa914473 },
226 { 0x016328bd, 0xfe860158, 0x0075b7f2, 0x0d03eb27, 0xfa9d32d2 },
227 { 0x0186b438, 0xfe56c982, 0x00869234, 0x0cf27048, 0xfaa97fca },
228 { 0x01adf358, 0xfe21f5fe, 0x00999842, 0x0ce051c2, 0xfab62ca5 },
229 { 0x01d949fa, 0xfde6e287, 0x00af0d8d, 0x0ccd8b4a, 0xfac33aa7 },
230 { 0x02092669, 0xfda4d8bf, 0x00c73d4c, 0x0cba1884, 0xfad0ab07 },
231 { 0x023e0268, 0xfd5b0e4a, 0x00e27b54, 0x0ca5f509, 0xfade7ef2 },
232 { 0x0278645c, 0xfd08a2b0, 0x01012509, 0x0c911c63, 0xfaecb788 },
233 { 0x02b8e091, 0xfcac9d1a, 0x0123a262, 0x0c7b8a14, 0xfafb55df },
234 { 0x03001a9a, 0xfc45e9ce, 0x014a6709, 0x0c65398f, 0xfb0a5aff },
235 { 0x034ec6d7, 0xfbd3576b, 0x0175f397, 0x0c4e2643, 0xfb19c7e4 },
236 { 0x03a5ac15, 0xfb5393ee, 0x01a6d6ed, 0x0c364b94, 0xfb299d7c },
237 { 0x0405a562, 0xfac52968, 0x01ddafae, 0x0c1da4e2, 0xfb39dca5 },
238 { 0x046fa3fe, 0xfa267a66, 0x021b2ddd, 0x0c042d8d, 0xfb4a8631 },
239 { 0x04e4b17f, 0xf975be0f, 0x0260149f, 0x0be9e0f2, 0xfb5b9ae0 },
240 { 0x0565f220, 0xf8b0fbe5, 0x02ad3c29, 0x0bceba73, 0xfb6d1b60 },
241 { 0x05f4a745, 0xf7d60722, 0x030393d4, 0x0bb2b578, 0xfb7f084d },
242 { 0x06923236, 0xf6e279bd, 0x03642465, 0x0b95cd75, 0xfb916233 },
243 { 0x07401713, 0xf5d3aef9, 0x03d01283, 0x0b77fded, 0xfba42984 },
244 { 0x08000000, 0xf4a6bd88, 0x0448a161, 0x0b594278, 0xfbb75e9f },
245 { 0x08d3c097, 0xf3587131, 0x04cf35a4, 0x0b3996c9, 0xfbcb01cb },
246 { 0x09bd59a2, 0xf1e543f9, 0x05655880, 0x0b18f6b2, 0xfbdf1333 },
247 { 0x0abefd0f, 0xf04956ca, 0x060cbb12, 0x0af75e2c, 0xfbf392e8 },
248 { 0x0bdb123e, 0xee806984, 0x06c739fe, 0x0ad4c962, 0xfc0880dd },
249 { 0x0d143a94, 0xec85d287, 0x0796e150, 0x0ab134b0, 0xfc1ddce5 },
250 { 0x0e6d5664, 0xea547598, 0x087df0a0, 0x0a8c9cb6, 0xfc33a6ad },
251 { 0x0fe98a2a, 0xe7e6ba35, 0x097edf83, 0x0a66fe5b, 0xfc49ddc2 },
252 { 0x118c4421, 0xe536813a, 0x0a9c6248, 0x0a4056d7, 0xfc608185 },
253 { 0x1359422e, 0xe23d19eb, 0x0bd96efb, 0x0a18a3bf, 0xfc77912c },
254 { 0x1554982b, 0xdef33645, 0x0d3942bd, 0x09efe312, 0xfc8f0bc1 },
255 { 0x1782b68a, 0xdb50deb1, 0x0ebf676d, 0x09c6133f, 0xfca6f019 },
256 { 0x19e8715d, 0xd74d64fd, 0x106fb999, 0x099b3337, 0xfcbf3cd6 },
257 { 0x1c8b07b8, 0xd2df56ab, 0x124e6ec8, 0x096f4274, 0xfcd7f060 },
258 { 0x1f702b6d, 0xcdfc6e92, 0x14601c10, 0x0942410b, 0xfcf108e5 },
259 { 0x229e0933, 0xc89985cd, 0x16a9bcfa, 0x09142fb5, 0xfd0a8451 },
260 { 0x261b5118, 0xc2aa8409, 0x1930bab6, 0x08e50fdc, 0xfd24604d },
261 { 0x29ef3f5d, 0xbc224f28, 0x1bfaf396, 0x08b4e3aa, 0xfd3e9a3b },
262 { 0x2e21a59b, 0xb4f2ba46, 0x1f0ec2d6, 0x0883ae15, 0xfd592f33 },
263 { 0x32baf44b, 0xad0c7429, 0x227308a3, 0x085172eb, 0xfd741bfd },
264 { 0x37c4448b, 0xa45ef51d, 0x262f3267, 0x081e36dc, 0xfd8f5d14 }
267 static const u32 db_table[101] = {
268 0x00000000, 0x01571f82, 0x01674b41, 0x01783a1b, 0x0189f540,
269 0x019c8651, 0x01aff763, 0x01c45306, 0x01d9a446, 0x01eff6b8,
270 0x0207567a, 0x021fd03d, 0x0239714c, 0x02544792, 0x027061a1,
271 0x028dcebb, 0x02ac9edc, 0x02cce2bf, 0x02eeabe8, 0x03120cb0,
272 0x0337184e, 0x035de2df, 0x03868173, 0x03b10a18, 0x03dd93e9,
273 0x040c3713, 0x043d0cea, 0x04702ff3, 0x04a5bbf2, 0x04ddcdfb,
274 0x0518847f, 0x0555ff62, 0x05966005, 0x05d9c95d, 0x06206005,
275 0x066a4a52, 0x06b7b067, 0x0708bc4c, 0x075d9a01, 0x07b6779d,
276 0x08138561, 0x0874f5d5, 0x08dafde1, 0x0945d4ed, 0x09b5b4fd,
277 0x0a2adad1, 0x0aa58605, 0x0b25f936, 0x0bac7a24, 0x0c3951d8,
278 0x0ccccccc, 0x0d673b17, 0x0e08f093, 0x0eb24510, 0x0f639481,
279 0x101d3f2d, 0x10dfa9e6, 0x11ab3e3f, 0x12806ac3, 0x135fa333,
280 0x144960c5, 0x153e2266, 0x163e6cfe, 0x174acbb7, 0x1863d04d,
281 0x198a1357, 0x1abe349f, 0x1c00db77, 0x1d52b712, 0x1eb47ee6,
282 0x2026f30f, 0x21aadcb6, 0x23410e7e, 0x24ea64f9, 0x26a7c71d,
283 0x287a26c4, 0x2a62812c, 0x2c61df84, 0x2e795779, 0x30aa0bcf,
284 0x32f52cfe, 0x355bf9d8, 0x37dfc033, 0x3a81dda4, 0x3d43c038,
285 0x4026e73c, 0x432ce40f, 0x46575af8, 0x49a8040f, 0x4d20ac2a,
286 0x50c335d3, 0x54919a57, 0x588dead1, 0x5cba514a, 0x611911ea,
287 0x65ac8c2f, 0x6a773c39, 0x6f7bbc23, 0x74bcc56c, 0x7a3d3272,
291 static const u32 onoff_table[2] = {
292 0x00000000, 0x00000001
298 static inline mm_segment_t snd_enter_user(void)
300 mm_segment_t fs = get_fs();
305 static inline void snd_leave_user(mm_segment_t fs)
314 static int snd_emu10k1_gpr_ctl_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
316 struct snd_emu10k1_fx8010_ctl *ctl =
317 (struct snd_emu10k1_fx8010_ctl *) kcontrol->private_value;
319 if (ctl->min == 0 && ctl->max == 1)
320 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
322 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
323 uinfo->count = ctl->vcount;
324 uinfo->value.integer.min = ctl->min;
325 uinfo->value.integer.max = ctl->max;
329 static int snd_emu10k1_gpr_ctl_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
331 struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
332 struct snd_emu10k1_fx8010_ctl *ctl =
333 (struct snd_emu10k1_fx8010_ctl *) kcontrol->private_value;
337 spin_lock_irqsave(&emu->reg_lock, flags);
338 for (i = 0; i < ctl->vcount; i++)
339 ucontrol->value.integer.value[i] = ctl->value[i];
340 spin_unlock_irqrestore(&emu->reg_lock, flags);
344 static int snd_emu10k1_gpr_ctl_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
346 struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
347 struct snd_emu10k1_fx8010_ctl *ctl =
348 (struct snd_emu10k1_fx8010_ctl *) kcontrol->private_value;
350 unsigned int nval, val;
354 spin_lock_irqsave(&emu->reg_lock, flags);
355 for (i = 0; i < ctl->vcount; i++) {
356 nval = ucontrol->value.integer.value[i];
361 if (nval != ctl->value[i])
363 val = ctl->value[i] = nval;
364 switch (ctl->translation) {
365 case EMU10K1_GPR_TRANSLATION_NONE:
366 snd_emu10k1_ptr_write(emu, emu->gpr_base + ctl->gpr[i], 0, val);
368 case EMU10K1_GPR_TRANSLATION_TABLE100:
369 snd_emu10k1_ptr_write(emu, emu->gpr_base + ctl->gpr[i], 0, db_table[val]);
371 case EMU10K1_GPR_TRANSLATION_BASS:
372 if ((ctl->count % 5) != 0 || (ctl->count / 5) != ctl->vcount) {
376 for (j = 0; j < 5; j++)
377 snd_emu10k1_ptr_write(emu, emu->gpr_base + ctl->gpr[j * ctl->vcount + i], 0, bass_table[val][j]);
379 case EMU10K1_GPR_TRANSLATION_TREBLE:
380 if ((ctl->count % 5) != 0 || (ctl->count / 5) != ctl->vcount) {
384 for (j = 0; j < 5; j++)
385 snd_emu10k1_ptr_write(emu, emu->gpr_base + ctl->gpr[j * ctl->vcount + i], 0, treble_table[val][j]);
387 case EMU10K1_GPR_TRANSLATION_ONOFF:
388 snd_emu10k1_ptr_write(emu, emu->gpr_base + ctl->gpr[i], 0, onoff_table[val]);
393 spin_unlock_irqrestore(&emu->reg_lock, flags);
401 static void snd_emu10k1_fx8010_interrupt(struct snd_emu10k1 *emu)
403 struct snd_emu10k1_fx8010_irq *irq, *nirq;
405 irq = emu->fx8010.irq_handlers;
407 nirq = irq->next; /* irq ptr can be removed from list */
408 if (snd_emu10k1_ptr_read(emu, emu->gpr_base + irq->gpr_running, 0) & 0xffff0000) {
410 irq->handler(emu, irq->private_data);
411 snd_emu10k1_ptr_write(emu, emu->gpr_base + irq->gpr_running, 0, 1);
417 int snd_emu10k1_fx8010_register_irq_handler(struct snd_emu10k1 *emu,
418 snd_fx8010_irq_handler_t *handler,
419 unsigned char gpr_running,
421 struct snd_emu10k1_fx8010_irq **r_irq)
423 struct snd_emu10k1_fx8010_irq *irq;
426 irq = kmalloc(sizeof(*irq), GFP_ATOMIC);
429 irq->handler = handler;
430 irq->gpr_running = gpr_running;
431 irq->private_data = private_data;
433 spin_lock_irqsave(&emu->fx8010.irq_lock, flags);
434 if (emu->fx8010.irq_handlers == NULL) {
435 emu->fx8010.irq_handlers = irq;
436 emu->dsp_interrupt = snd_emu10k1_fx8010_interrupt;
437 snd_emu10k1_intr_enable(emu, INTE_FXDSPENABLE);
439 irq->next = emu->fx8010.irq_handlers;
440 emu->fx8010.irq_handlers = irq;
442 spin_unlock_irqrestore(&emu->fx8010.irq_lock, flags);
448 int snd_emu10k1_fx8010_unregister_irq_handler(struct snd_emu10k1 *emu,
449 struct snd_emu10k1_fx8010_irq *irq)
451 struct snd_emu10k1_fx8010_irq *tmp;
454 spin_lock_irqsave(&emu->fx8010.irq_lock, flags);
455 if ((tmp = emu->fx8010.irq_handlers) == irq) {
456 emu->fx8010.irq_handlers = tmp->next;
457 if (emu->fx8010.irq_handlers == NULL) {
458 snd_emu10k1_intr_disable(emu, INTE_FXDSPENABLE);
459 emu->dsp_interrupt = NULL;
462 while (tmp && tmp->next != irq)
465 tmp->next = tmp->next->next;
467 spin_unlock_irqrestore(&emu->fx8010.irq_lock, flags);
472 /*************************************************************************
473 * EMU10K1 effect manager
474 *************************************************************************/
476 static void snd_emu10k1_write_op(struct snd_emu10k1_fx8010_code *icode,
478 u32 op, u32 r, u32 a, u32 x, u32 y)
481 snd_assert(*ptr < 512, return);
482 code = (u_int32_t __force *)icode->code + (*ptr) * 2;
483 set_bit(*ptr, icode->code_valid);
484 code[0] = ((x & 0x3ff) << 10) | (y & 0x3ff);
485 code[1] = ((op & 0x0f) << 20) | ((r & 0x3ff) << 10) | (a & 0x3ff);
489 #define OP(icode, ptr, op, r, a, x, y) \
490 snd_emu10k1_write_op(icode, ptr, op, r, a, x, y)
492 static void snd_emu10k1_audigy_write_op(struct snd_emu10k1_fx8010_code *icode,
494 u32 op, u32 r, u32 a, u32 x, u32 y)
497 snd_assert(*ptr < 1024, return);
498 code = (u_int32_t __force *)icode->code + (*ptr) * 2;
499 set_bit(*ptr, icode->code_valid);
500 code[0] = ((x & 0x7ff) << 12) | (y & 0x7ff);
501 code[1] = ((op & 0x0f) << 24) | ((r & 0x7ff) << 12) | (a & 0x7ff);
505 #define A_OP(icode, ptr, op, r, a, x, y) \
506 snd_emu10k1_audigy_write_op(icode, ptr, op, r, a, x, y)
508 static void snd_emu10k1_efx_write(struct snd_emu10k1 *emu, unsigned int pc, unsigned int data)
510 pc += emu->audigy ? A_MICROCODEBASE : MICROCODEBASE;
511 snd_emu10k1_ptr_write(emu, pc, 0, data);
514 unsigned int snd_emu10k1_efx_read(struct snd_emu10k1 *emu, unsigned int pc)
516 pc += emu->audigy ? A_MICROCODEBASE : MICROCODEBASE;
517 return snd_emu10k1_ptr_read(emu, pc, 0);
520 static int snd_emu10k1_gpr_poke(struct snd_emu10k1 *emu,
521 struct snd_emu10k1_fx8010_code *icode)
526 for (gpr = 0; gpr < (emu->audigy ? 0x200 : 0x100); gpr++) {
527 if (!test_bit(gpr, icode->gpr_valid))
529 if (get_user(val, &icode->gpr_map[gpr]))
531 snd_emu10k1_ptr_write(emu, emu->gpr_base + gpr, 0, val);
536 static int snd_emu10k1_gpr_peek(struct snd_emu10k1 *emu,
537 struct snd_emu10k1_fx8010_code *icode)
542 for (gpr = 0; gpr < (emu->audigy ? 0x200 : 0x100); gpr++) {
543 set_bit(gpr, icode->gpr_valid);
544 val = snd_emu10k1_ptr_read(emu, emu->gpr_base + gpr, 0);
545 if (put_user(val, &icode->gpr_map[gpr]))
551 static int snd_emu10k1_tram_poke(struct snd_emu10k1 *emu,
552 struct snd_emu10k1_fx8010_code *icode)
557 for (tram = 0; tram < (emu->audigy ? 0x100 : 0xa0); tram++) {
558 if (!test_bit(tram, icode->tram_valid))
560 if (get_user(val, &icode->tram_data_map[tram]) ||
561 get_user(addr, &icode->tram_addr_map[tram]))
563 snd_emu10k1_ptr_write(emu, TANKMEMDATAREGBASE + tram, 0, val);
565 snd_emu10k1_ptr_write(emu, TANKMEMADDRREGBASE + tram, 0, addr);
567 snd_emu10k1_ptr_write(emu, TANKMEMADDRREGBASE + tram, 0, addr << 12);
568 snd_emu10k1_ptr_write(emu, A_TANKMEMCTLREGBASE + tram, 0, addr >> 20);
574 static int snd_emu10k1_tram_peek(struct snd_emu10k1 *emu,
575 struct snd_emu10k1_fx8010_code *icode)
580 memset(icode->tram_valid, 0, sizeof(icode->tram_valid));
581 for (tram = 0; tram < (emu->audigy ? 0x100 : 0xa0); tram++) {
582 set_bit(tram, icode->tram_valid);
583 val = snd_emu10k1_ptr_read(emu, TANKMEMDATAREGBASE + tram, 0);
585 addr = snd_emu10k1_ptr_read(emu, TANKMEMADDRREGBASE + tram, 0);
587 addr = snd_emu10k1_ptr_read(emu, TANKMEMADDRREGBASE + tram, 0) >> 12;
588 addr |= snd_emu10k1_ptr_read(emu, A_TANKMEMCTLREGBASE + tram, 0) << 20;
590 if (put_user(val, &icode->tram_data_map[tram]) ||
591 put_user(addr, &icode->tram_addr_map[tram]))
597 static int snd_emu10k1_code_poke(struct snd_emu10k1 *emu,
598 struct snd_emu10k1_fx8010_code *icode)
602 for (pc = 0; pc < (emu->audigy ? 2*1024 : 2*512); pc += 2) {
603 if (!test_bit(pc / 2, icode->code_valid))
605 if (get_user(lo, &icode->code[pc + 0]) ||
606 get_user(hi, &icode->code[pc + 1]))
608 snd_emu10k1_efx_write(emu, pc + 0, lo);
609 snd_emu10k1_efx_write(emu, pc + 1, hi);
614 static int snd_emu10k1_code_peek(struct snd_emu10k1 *emu,
615 struct snd_emu10k1_fx8010_code *icode)
619 memset(icode->code_valid, 0, sizeof(icode->code_valid));
620 for (pc = 0; pc < (emu->audigy ? 2*1024 : 2*512); pc += 2) {
621 set_bit(pc / 2, icode->code_valid);
622 if (put_user(snd_emu10k1_efx_read(emu, pc + 0), &icode->code[pc + 0]))
624 if (put_user(snd_emu10k1_efx_read(emu, pc + 1), &icode->code[pc + 1]))
630 static struct snd_emu10k1_fx8010_ctl *
631 snd_emu10k1_look_for_ctl(struct snd_emu10k1 *emu, struct snd_ctl_elem_id *id)
633 struct snd_emu10k1_fx8010_ctl *ctl;
634 struct snd_kcontrol *kcontrol;
635 struct list_head *list;
637 list_for_each(list, &emu->fx8010.gpr_ctl) {
638 ctl = emu10k1_gpr_ctl(list);
639 kcontrol = ctl->kcontrol;
640 if (kcontrol->id.iface == id->iface &&
641 !strcmp(kcontrol->id.name, id->name) &&
642 kcontrol->id.index == id->index)
648 static int snd_emu10k1_verify_controls(struct snd_emu10k1 *emu,
649 struct snd_emu10k1_fx8010_code *icode)
652 struct snd_ctl_elem_id __user *_id;
653 struct snd_ctl_elem_id id;
654 struct snd_emu10k1_fx8010_control_gpr __user *_gctl;
655 struct snd_emu10k1_fx8010_control_gpr *gctl;
658 for (i = 0, _id = icode->gpr_del_controls;
659 i < icode->gpr_del_control_count; i++, _id++) {
660 if (copy_from_user(&id, _id, sizeof(id)))
662 if (snd_emu10k1_look_for_ctl(emu, &id) == NULL)
665 gctl = kmalloc(sizeof(*gctl), GFP_KERNEL);
669 for (i = 0, _gctl = icode->gpr_add_controls;
670 i < icode->gpr_add_control_count; i++, _gctl++) {
671 if (copy_from_user(gctl, _gctl, sizeof(*gctl))) {
675 if (snd_emu10k1_look_for_ctl(emu, &gctl->id))
677 down_read(&emu->card->controls_rwsem);
678 if (snd_ctl_find_id(emu->card, &gctl->id) != NULL) {
679 up_read(&emu->card->controls_rwsem);
683 up_read(&emu->card->controls_rwsem);
684 if (gctl->id.iface != SNDRV_CTL_ELEM_IFACE_MIXER &&
685 gctl->id.iface != SNDRV_CTL_ELEM_IFACE_PCM) {
690 for (i = 0, _gctl = icode->gpr_list_controls;
691 i < icode->gpr_list_control_count; i++, _gctl++) {
692 /* FIXME: we need to check the WRITE access */
693 if (copy_from_user(gctl, _gctl, sizeof(*gctl))) {
703 static void snd_emu10k1_ctl_private_free(struct snd_kcontrol *kctl)
705 struct snd_emu10k1_fx8010_ctl *ctl;
707 ctl = (struct snd_emu10k1_fx8010_ctl *) kctl->private_value;
708 kctl->private_value = 0;
709 list_del(&ctl->list);
713 static int snd_emu10k1_add_controls(struct snd_emu10k1 *emu,
714 struct snd_emu10k1_fx8010_code *icode)
717 struct snd_emu10k1_fx8010_control_gpr __user *_gctl;
718 struct snd_emu10k1_fx8010_control_gpr *gctl;
719 struct snd_emu10k1_fx8010_ctl *ctl, *nctl;
720 struct snd_kcontrol_new knew;
721 struct snd_kcontrol *kctl;
722 struct snd_ctl_elem_value *val;
725 val = kmalloc(sizeof(*val), GFP_KERNEL);
726 gctl = kmalloc(sizeof(*gctl), GFP_KERNEL);
727 nctl = kmalloc(sizeof(*nctl), GFP_KERNEL);
728 if (!val || !gctl || !nctl) {
733 for (i = 0, _gctl = icode->gpr_add_controls;
734 i < icode->gpr_add_control_count; i++, _gctl++) {
735 if (copy_from_user(gctl, _gctl, sizeof(*gctl))) {
739 if (gctl->id.iface != SNDRV_CTL_ELEM_IFACE_MIXER &&
740 gctl->id.iface != SNDRV_CTL_ELEM_IFACE_PCM) {
744 if (! gctl->id.name[0]) {
748 ctl = snd_emu10k1_look_for_ctl(emu, &gctl->id);
749 memset(&knew, 0, sizeof(knew));
750 knew.iface = gctl->id.iface;
751 knew.name = gctl->id.name;
752 knew.index = gctl->id.index;
753 knew.device = gctl->id.device;
754 knew.subdevice = gctl->id.subdevice;
755 knew.info = snd_emu10k1_gpr_ctl_info;
756 knew.get = snd_emu10k1_gpr_ctl_get;
757 knew.put = snd_emu10k1_gpr_ctl_put;
758 memset(nctl, 0, sizeof(*nctl));
759 nctl->vcount = gctl->vcount;
760 nctl->count = gctl->count;
761 for (j = 0; j < 32; j++) {
762 nctl->gpr[j] = gctl->gpr[j];
763 nctl->value[j] = ~gctl->value[j]; /* inverted, we want to write new value in gpr_ctl_put() */
764 val->value.integer.value[j] = gctl->value[j];
766 nctl->min = gctl->min;
767 nctl->max = gctl->max;
768 nctl->translation = gctl->translation;
770 ctl = kmalloc(sizeof(*ctl), GFP_KERNEL);
775 knew.private_value = (unsigned long)ctl;
777 if ((err = snd_ctl_add(emu->card, kctl = snd_ctl_new1(&knew, emu))) < 0) {
781 kctl->private_free = snd_emu10k1_ctl_private_free;
782 ctl->kcontrol = kctl;
783 list_add_tail(&ctl->list, &emu->fx8010.gpr_ctl);
786 nctl->list = ctl->list;
787 nctl->kcontrol = ctl->kcontrol;
789 snd_ctl_notify(emu->card, SNDRV_CTL_EVENT_MASK_VALUE |
790 SNDRV_CTL_EVENT_MASK_INFO, &ctl->kcontrol->id);
792 snd_emu10k1_gpr_ctl_put(ctl->kcontrol, val);
801 static int snd_emu10k1_del_controls(struct snd_emu10k1 *emu,
802 struct snd_emu10k1_fx8010_code *icode)
805 struct snd_ctl_elem_id id;
806 struct snd_ctl_elem_id __user *_id;
807 struct snd_emu10k1_fx8010_ctl *ctl;
808 struct snd_card *card = emu->card;
810 for (i = 0, _id = icode->gpr_del_controls;
811 i < icode->gpr_del_control_count; i++, _id++) {
812 if (copy_from_user(&id, _id, sizeof(id)))
814 down_write(&card->controls_rwsem);
815 ctl = snd_emu10k1_look_for_ctl(emu, &id);
817 snd_ctl_remove(card, ctl->kcontrol);
818 up_write(&card->controls_rwsem);
823 static int snd_emu10k1_list_controls(struct snd_emu10k1 *emu,
824 struct snd_emu10k1_fx8010_code *icode)
826 unsigned int i = 0, j;
827 unsigned int total = 0;
828 struct snd_emu10k1_fx8010_control_gpr *gctl;
829 struct snd_emu10k1_fx8010_control_gpr __user *_gctl;
830 struct snd_emu10k1_fx8010_ctl *ctl;
831 struct snd_ctl_elem_id *id;
832 struct list_head *list;
834 gctl = kmalloc(sizeof(*gctl), GFP_KERNEL);
838 _gctl = icode->gpr_list_controls;
839 list_for_each(list, &emu->fx8010.gpr_ctl) {
840 ctl = emu10k1_gpr_ctl(list);
842 if (_gctl && i < icode->gpr_list_control_count) {
843 memset(gctl, 0, sizeof(*gctl));
844 id = &ctl->kcontrol->id;
845 gctl->id.iface = id->iface;
846 strlcpy(gctl->id.name, id->name, sizeof(gctl->id.name));
847 gctl->id.index = id->index;
848 gctl->id.device = id->device;
849 gctl->id.subdevice = id->subdevice;
850 gctl->vcount = ctl->vcount;
851 gctl->count = ctl->count;
852 for (j = 0; j < 32; j++) {
853 gctl->gpr[j] = ctl->gpr[j];
854 gctl->value[j] = ctl->value[j];
856 gctl->min = ctl->min;
857 gctl->max = ctl->max;
858 gctl->translation = ctl->translation;
859 if (copy_to_user(_gctl, gctl, sizeof(*gctl))) {
867 icode->gpr_list_control_total = total;
872 static int snd_emu10k1_icode_poke(struct snd_emu10k1 *emu,
873 struct snd_emu10k1_fx8010_code *icode)
877 down(&emu->fx8010.lock);
878 if ((err = snd_emu10k1_verify_controls(emu, icode)) < 0)
880 strlcpy(emu->fx8010.name, icode->name, sizeof(emu->fx8010.name));
881 /* stop FX processor - this may be dangerous, but it's better to miss
882 some samples than generate wrong ones - [jk] */
884 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg | A_DBG_SINGLE_STEP);
886 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg | EMU10K1_DBG_SINGLE_STEP);
887 /* ok, do the main job */
888 if ((err = snd_emu10k1_del_controls(emu, icode)) < 0 ||
889 (err = snd_emu10k1_gpr_poke(emu, icode)) < 0 ||
890 (err = snd_emu10k1_tram_poke(emu, icode)) < 0 ||
891 (err = snd_emu10k1_code_poke(emu, icode)) < 0 ||
892 (err = snd_emu10k1_add_controls(emu, icode)) < 0)
894 /* start FX processor when the DSP code is updated */
896 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg);
898 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg);
900 up(&emu->fx8010.lock);
904 static int snd_emu10k1_icode_peek(struct snd_emu10k1 *emu,
905 struct snd_emu10k1_fx8010_code *icode)
909 down(&emu->fx8010.lock);
910 strlcpy(icode->name, emu->fx8010.name, sizeof(icode->name));
911 /* ok, do the main job */
912 err = snd_emu10k1_gpr_peek(emu, icode);
914 err = snd_emu10k1_tram_peek(emu, icode);
916 err = snd_emu10k1_code_peek(emu, icode);
918 err = snd_emu10k1_list_controls(emu, icode);
919 up(&emu->fx8010.lock);
923 static int snd_emu10k1_ipcm_poke(struct snd_emu10k1 *emu,
924 struct snd_emu10k1_fx8010_pcm_rec *ipcm)
928 struct snd_emu10k1_fx8010_pcm *pcm;
930 if (ipcm->substream >= EMU10K1_FX8010_PCM_COUNT)
932 if (ipcm->channels > 32)
934 pcm = &emu->fx8010.pcm[ipcm->substream];
935 down(&emu->fx8010.lock);
936 spin_lock_irq(&emu->reg_lock);
941 if (ipcm->channels == 0) { /* remove */
944 /* FIXME: we need to add universal code to the PCM transfer routine */
945 if (ipcm->channels != 2) {
951 pcm->channels = ipcm->channels;
952 pcm->tram_start = ipcm->tram_start;
953 pcm->buffer_size = ipcm->buffer_size;
954 pcm->gpr_size = ipcm->gpr_size;
955 pcm->gpr_count = ipcm->gpr_count;
956 pcm->gpr_tmpcount = ipcm->gpr_tmpcount;
957 pcm->gpr_ptr = ipcm->gpr_ptr;
958 pcm->gpr_trigger = ipcm->gpr_trigger;
959 pcm->gpr_running = ipcm->gpr_running;
960 for (i = 0; i < pcm->channels; i++)
961 pcm->etram[i] = ipcm->etram[i];
964 spin_unlock_irq(&emu->reg_lock);
965 up(&emu->fx8010.lock);
969 static int snd_emu10k1_ipcm_peek(struct snd_emu10k1 *emu,
970 struct snd_emu10k1_fx8010_pcm_rec *ipcm)
974 struct snd_emu10k1_fx8010_pcm *pcm;
976 if (ipcm->substream >= EMU10K1_FX8010_PCM_COUNT)
978 pcm = &emu->fx8010.pcm[ipcm->substream];
979 down(&emu->fx8010.lock);
980 spin_lock_irq(&emu->reg_lock);
981 ipcm->channels = pcm->channels;
982 ipcm->tram_start = pcm->tram_start;
983 ipcm->buffer_size = pcm->buffer_size;
984 ipcm->gpr_size = pcm->gpr_size;
985 ipcm->gpr_ptr = pcm->gpr_ptr;
986 ipcm->gpr_count = pcm->gpr_count;
987 ipcm->gpr_tmpcount = pcm->gpr_tmpcount;
988 ipcm->gpr_trigger = pcm->gpr_trigger;
989 ipcm->gpr_running = pcm->gpr_running;
990 for (i = 0; i < pcm->channels; i++)
991 ipcm->etram[i] = pcm->etram[i];
992 ipcm->res1 = ipcm->res2 = 0;
994 spin_unlock_irq(&emu->reg_lock);
995 up(&emu->fx8010.lock);
999 #define SND_EMU10K1_GPR_CONTROLS 44
1000 #define SND_EMU10K1_INPUTS 12
1001 #define SND_EMU10K1_PLAYBACK_CHANNELS 8
1002 #define SND_EMU10K1_CAPTURE_CHANNELS 4
1004 static void __devinit
1005 snd_emu10k1_init_mono_control(struct snd_emu10k1_fx8010_control_gpr *ctl,
1006 const char *name, int gpr, int defval)
1008 ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1009 strcpy(ctl->id.name, name);
1010 ctl->vcount = ctl->count = 1;
1011 ctl->gpr[0] = gpr + 0; ctl->value[0] = defval;
1014 ctl->translation = EMU10K1_GPR_TRANSLATION_TABLE100;
1017 static void __devinit
1018 snd_emu10k1_init_stereo_control(struct snd_emu10k1_fx8010_control_gpr *ctl,
1019 const char *name, int gpr, int defval)
1021 ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1022 strcpy(ctl->id.name, name);
1023 ctl->vcount = ctl->count = 2;
1024 ctl->gpr[0] = gpr + 0; ctl->value[0] = defval;
1025 ctl->gpr[1] = gpr + 1; ctl->value[1] = defval;
1028 ctl->translation = EMU10K1_GPR_TRANSLATION_TABLE100;
1031 static void __devinit
1032 snd_emu10k1_init_mono_onoff_control(struct snd_emu10k1_fx8010_control_gpr *ctl,
1033 const char *name, int gpr, int defval)
1035 ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1036 strcpy(ctl->id.name, name);
1037 ctl->vcount = ctl->count = 1;
1038 ctl->gpr[0] = gpr + 0; ctl->value[0] = defval;
1041 ctl->translation = EMU10K1_GPR_TRANSLATION_ONOFF;
1044 static void __devinit
1045 snd_emu10k1_init_stereo_onoff_control(struct snd_emu10k1_fx8010_control_gpr *ctl,
1046 const char *name, int gpr, int defval)
1048 ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1049 strcpy(ctl->id.name, name);
1050 ctl->vcount = ctl->count = 2;
1051 ctl->gpr[0] = gpr + 0; ctl->value[0] = defval;
1052 ctl->gpr[1] = gpr + 1; ctl->value[1] = defval;
1055 ctl->translation = EMU10K1_GPR_TRANSLATION_ONOFF;
1060 * initial DSP configuration for Audigy
1063 static int __devinit _snd_emu10k1_audigy_init_efx(struct snd_emu10k1 *emu)
1065 int err, i, z, gpr, nctl;
1066 const int playback = 10;
1067 const int capture = playback + (SND_EMU10K1_PLAYBACK_CHANNELS * 2); /* we reserve 10 voices */
1068 const int stereo_mix = capture + 2;
1069 const int tmp = 0x88;
1071 struct snd_emu10k1_fx8010_code *icode = NULL;
1072 struct snd_emu10k1_fx8010_control_gpr *controls = NULL, *ctl;
1076 if ((icode = kzalloc(sizeof(*icode), GFP_KERNEL)) == NULL ||
1077 (icode->gpr_map = (u_int32_t __user *)
1078 kcalloc(512 + 256 + 256 + 2 * 1024, sizeof(u_int32_t),
1079 GFP_KERNEL)) == NULL ||
1080 (controls = kcalloc(SND_EMU10K1_GPR_CONTROLS,
1081 sizeof(*controls), GFP_KERNEL)) == NULL) {
1085 gpr_map = (u32 __force *)icode->gpr_map;
1087 icode->tram_data_map = icode->gpr_map + 512;
1088 icode->tram_addr_map = icode->tram_data_map + 256;
1089 icode->code = icode->tram_addr_map + 256;
1091 /* clear free GPRs */
1092 for (i = 0; i < 512; i++)
1093 set_bit(i, icode->gpr_valid);
1095 /* clear TRAM data & address lines */
1096 for (i = 0; i < 256; i++)
1097 set_bit(i, icode->tram_valid);
1099 strcpy(icode->name, "Audigy DSP code for ALSA");
1102 gpr = stereo_mix + 10;
1104 /* stop FX processor */
1105 snd_emu10k1_ptr_write(emu, A_DBG, 0, (emu->fx8010.dbg = 0) | A_DBG_SINGLE_STEP);
1109 for (z = 0; z < 80; z=z+2) {
1110 A_OP(icode, &ptr, iACC3, A_EXTOUT(z), A_FXBUS(FXBUS_PCM_LEFT_FRONT), A_C_00000000, A_C_00000000); /* left */
1111 A_OP(icode, &ptr, iACC3, A_EXTOUT(z+1), A_FXBUS(FXBUS_PCM_RIGHT_FRONT), A_C_00000000, A_C_00000000); /* right */
1113 #endif /* jcd test */
1115 /* PCM front Playback Volume (independent from stereo mix) */
1116 A_OP(icode, &ptr, iMAC0, A_GPR(playback), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LEFT_FRONT));
1117 A_OP(icode, &ptr, iMAC0, A_GPR(playback+1), A_C_00000000, A_GPR(gpr+1), A_FXBUS(FXBUS_PCM_RIGHT_FRONT));
1118 snd_emu10k1_init_stereo_control(&controls[nctl++], "PCM Front Playback Volume", gpr, 100);
1121 /* PCM Surround Playback (independent from stereo mix) */
1122 A_OP(icode, &ptr, iMAC0, A_GPR(playback+2), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LEFT_REAR));
1123 A_OP(icode, &ptr, iMAC0, A_GPR(playback+3), A_C_00000000, A_GPR(gpr+1), A_FXBUS(FXBUS_PCM_RIGHT_REAR));
1124 snd_emu10k1_init_stereo_control(&controls[nctl++], "PCM Surround Playback Volume", gpr, 100);
1127 /* PCM Side Playback (independent from stereo mix) */
1128 if (emu->card_capabilities->spk71) {
1129 A_OP(icode, &ptr, iMAC0, A_GPR(playback+6), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LEFT_SIDE));
1130 A_OP(icode, &ptr, iMAC0, A_GPR(playback+7), A_C_00000000, A_GPR(gpr+1), A_FXBUS(FXBUS_PCM_RIGHT_SIDE));
1131 snd_emu10k1_init_stereo_control(&controls[nctl++], "PCM Side Playback Volume", gpr, 100);
1135 /* PCM Center Playback (independent from stereo mix) */
1136 A_OP(icode, &ptr, iMAC0, A_GPR(playback+4), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_CENTER));
1137 snd_emu10k1_init_mono_control(&controls[nctl++], "PCM Center Playback Volume", gpr, 100);
1140 /* PCM LFE Playback (independent from stereo mix) */
1141 A_OP(icode, &ptr, iMAC0, A_GPR(playback+5), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LFE));
1142 snd_emu10k1_init_mono_control(&controls[nctl++], "PCM LFE Playback Volume", gpr, 100);
1148 /* Wave (PCM) Playback Volume (will be renamed later) */
1149 A_OP(icode, &ptr, iMAC0, A_GPR(stereo_mix), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LEFT));
1150 A_OP(icode, &ptr, iMAC0, A_GPR(stereo_mix+1), A_C_00000000, A_GPR(gpr+1), A_FXBUS(FXBUS_PCM_RIGHT));
1151 snd_emu10k1_init_stereo_control(&controls[nctl++], "Wave Playback Volume", gpr, 100);
1154 /* Synth Playback */
1155 A_OP(icode, &ptr, iMAC0, A_GPR(stereo_mix+0), A_GPR(stereo_mix+0), A_GPR(gpr), A_FXBUS(FXBUS_MIDI_LEFT));
1156 A_OP(icode, &ptr, iMAC0, A_GPR(stereo_mix+1), A_GPR(stereo_mix+1), A_GPR(gpr+1), A_FXBUS(FXBUS_MIDI_RIGHT));
1157 snd_emu10k1_init_stereo_control(&controls[nctl++], "Synth Playback Volume", gpr, 100);
1160 /* Wave (PCM) Capture */
1161 A_OP(icode, &ptr, iMAC0, A_GPR(capture+0), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LEFT));
1162 A_OP(icode, &ptr, iMAC0, A_GPR(capture+1), A_C_00000000, A_GPR(gpr+1), A_FXBUS(FXBUS_PCM_RIGHT));
1163 snd_emu10k1_init_stereo_control(&controls[nctl++], "PCM Capture Volume", gpr, 0);
1167 A_OP(icode, &ptr, iMAC0, A_GPR(capture+0), A_GPR(capture+0), A_GPR(gpr), A_FXBUS(FXBUS_MIDI_LEFT));
1168 A_OP(icode, &ptr, iMAC0, A_GPR(capture+1), A_GPR(capture+1), A_GPR(gpr+1), A_FXBUS(FXBUS_MIDI_RIGHT));
1169 snd_emu10k1_init_stereo_control(&controls[nctl++], "Synth Capture Volume", gpr, 0);
1175 #define A_ADD_VOLUME_IN(var,vol,input) \
1176 A_OP(icode, &ptr, iMAC0, A_GPR(var), A_GPR(var), A_GPR(vol), A_EXTIN(input))
1178 /* AC'97 Playback Volume - used only for mic (renamed later) */
1179 A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_AC97_L);
1180 A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_AC97_R);
1181 snd_emu10k1_init_stereo_control(&controls[nctl++], "AMic Playback Volume", gpr, 0);
1183 /* AC'97 Capture Volume - used only for mic */
1184 A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_AC97_L);
1185 A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_AC97_R);
1186 snd_emu10k1_init_stereo_control(&controls[nctl++], "Mic Capture Volume", gpr, 0);
1189 /* mic capture buffer */
1190 A_OP(icode, &ptr, iINTERP, A_EXTOUT(A_EXTOUT_MIC_CAP), A_EXTIN(A_EXTIN_AC97_L), 0xcd, A_EXTIN(A_EXTIN_AC97_R));
1192 /* Audigy CD Playback Volume */
1193 A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_SPDIF_CD_L);
1194 A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_SPDIF_CD_R);
1195 snd_emu10k1_init_stereo_control(&controls[nctl++],
1196 emu->card_capabilities->ac97_chip ? "Audigy CD Playback Volume" : "CD Playback Volume",
1199 /* Audigy CD Capture Volume */
1200 A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_SPDIF_CD_L);
1201 A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_SPDIF_CD_R);
1202 snd_emu10k1_init_stereo_control(&controls[nctl++],
1203 emu->card_capabilities->ac97_chip ? "Audigy CD Capture Volume" : "CD Capture Volume",
1207 /* Optical SPDIF Playback Volume */
1208 A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_OPT_SPDIF_L);
1209 A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_OPT_SPDIF_R);
1210 snd_emu10k1_init_stereo_control(&controls[nctl++], SNDRV_CTL_NAME_IEC958("Optical ",PLAYBACK,VOLUME), gpr, 0);
1212 /* Optical SPDIF Capture Volume */
1213 A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_OPT_SPDIF_L);
1214 A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_OPT_SPDIF_R);
1215 snd_emu10k1_init_stereo_control(&controls[nctl++], SNDRV_CTL_NAME_IEC958("Optical ",CAPTURE,VOLUME), gpr, 0);
1218 /* Line2 Playback Volume */
1219 A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_LINE2_L);
1220 A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_LINE2_R);
1221 snd_emu10k1_init_stereo_control(&controls[nctl++],
1222 emu->card_capabilities->ac97_chip ? "Line2 Playback Volume" : "Line Playback Volume",
1225 /* Line2 Capture Volume */
1226 A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_LINE2_L);
1227 A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_LINE2_R);
1228 snd_emu10k1_init_stereo_control(&controls[nctl++],
1229 emu->card_capabilities->ac97_chip ? "Line2 Capture Volume" : "Line Capture Volume",
1233 /* Philips ADC Playback Volume */
1234 A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_ADC_L);
1235 A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_ADC_R);
1236 snd_emu10k1_init_stereo_control(&controls[nctl++], "Analog Mix Playback Volume", gpr, 0);
1238 /* Philips ADC Capture Volume */
1239 A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_ADC_L);
1240 A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_ADC_R);
1241 snd_emu10k1_init_stereo_control(&controls[nctl++], "Analog Mix Capture Volume", gpr, 0);
1244 /* Aux2 Playback Volume */
1245 A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_AUX2_L);
1246 A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_AUX2_R);
1247 snd_emu10k1_init_stereo_control(&controls[nctl++],
1248 emu->card_capabilities->ac97_chip ? "Aux2 Playback Volume" : "Aux Playback Volume",
1251 /* Aux2 Capture Volume */
1252 A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_AUX2_L);
1253 A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_AUX2_R);
1254 snd_emu10k1_init_stereo_control(&controls[nctl++],
1255 emu->card_capabilities->ac97_chip ? "Aux2 Capture Volume" : "Aux Capture Volume",
1259 /* Stereo Mix Front Playback Volume */
1260 A_OP(icode, &ptr, iMAC0, A_GPR(playback), A_GPR(playback), A_GPR(gpr), A_GPR(stereo_mix));
1261 A_OP(icode, &ptr, iMAC0, A_GPR(playback+1), A_GPR(playback+1), A_GPR(gpr+1), A_GPR(stereo_mix+1));
1262 snd_emu10k1_init_stereo_control(&controls[nctl++], "Front Playback Volume", gpr, 100);
1265 /* Stereo Mix Surround Playback */
1266 A_OP(icode, &ptr, iMAC0, A_GPR(playback+2), A_GPR(playback+2), A_GPR(gpr), A_GPR(stereo_mix));
1267 A_OP(icode, &ptr, iMAC0, A_GPR(playback+3), A_GPR(playback+3), A_GPR(gpr+1), A_GPR(stereo_mix+1));
1268 snd_emu10k1_init_stereo_control(&controls[nctl++], "Surround Playback Volume", gpr, 0);
1271 /* Stereo Mix Center Playback */
1272 /* Center = sub = Left/2 + Right/2 */
1273 A_OP(icode, &ptr, iINTERP, A_GPR(tmp), A_GPR(stereo_mix), 0xcd, A_GPR(stereo_mix+1));
1274 A_OP(icode, &ptr, iMAC0, A_GPR(playback+4), A_GPR(playback+4), A_GPR(gpr), A_GPR(tmp));
1275 snd_emu10k1_init_mono_control(&controls[nctl++], "Center Playback Volume", gpr, 0);
1278 /* Stereo Mix LFE Playback */
1279 A_OP(icode, &ptr, iMAC0, A_GPR(playback+5), A_GPR(playback+5), A_GPR(gpr), A_GPR(tmp));
1280 snd_emu10k1_init_mono_control(&controls[nctl++], "LFE Playback Volume", gpr, 0);
1283 if (emu->card_capabilities->spk71) {
1284 /* Stereo Mix Side Playback */
1285 A_OP(icode, &ptr, iMAC0, A_GPR(playback+6), A_GPR(playback+6), A_GPR(gpr), A_GPR(stereo_mix));
1286 A_OP(icode, &ptr, iMAC0, A_GPR(playback+7), A_GPR(playback+7), A_GPR(gpr+1), A_GPR(stereo_mix+1));
1287 snd_emu10k1_init_stereo_control(&controls[nctl++], "Side Playback Volume", gpr, 0);
1294 #define A_PUT_OUTPUT(out,src) A_OP(icode, &ptr, iACC3, A_EXTOUT(out), A_C_00000000, A_C_00000000, A_GPR(src))
1295 #define A_PUT_STEREO_OUTPUT(out1,out2,src) \
1296 {A_PUT_OUTPUT(out1,src); A_PUT_OUTPUT(out2,src+1);}
1298 #define _A_SWITCH(icode, ptr, dst, src, sw) \
1299 A_OP((icode), ptr, iMACINT0, dst, A_C_00000000, src, sw);
1300 #define A_SWITCH(icode, ptr, dst, src, sw) \
1301 _A_SWITCH(icode, ptr, A_GPR(dst), A_GPR(src), A_GPR(sw))
1302 #define _A_SWITCH_NEG(icode, ptr, dst, src) \
1303 A_OP((icode), ptr, iANDXOR, dst, src, A_C_00000001, A_C_00000001);
1304 #define A_SWITCH_NEG(icode, ptr, dst, src) \
1305 _A_SWITCH_NEG(icode, ptr, A_GPR(dst), A_GPR(src))
1309 * Process tone control
1311 A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 0), A_GPR(playback + 0), A_C_00000000, A_C_00000000); /* left */
1312 A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 1), A_GPR(playback + 1), A_C_00000000, A_C_00000000); /* right */
1313 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 */
1314 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 */
1315 A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 4), A_GPR(playback + 4), A_C_00000000, A_C_00000000); /* center */
1316 A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 5), A_GPR(playback + 5), A_C_00000000, A_C_00000000); /* LFE */
1317 if (emu->card_capabilities->spk71) {
1318 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 */
1319 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 */
1323 ctl = &controls[nctl + 0];
1324 ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1325 strcpy(ctl->id.name, "Tone Control - Bass");
1330 ctl->value[0] = ctl->value[1] = 20;
1331 ctl->translation = EMU10K1_GPR_TRANSLATION_BASS;
1332 ctl = &controls[nctl + 1];
1333 ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1334 strcpy(ctl->id.name, "Tone Control - Treble");
1339 ctl->value[0] = ctl->value[1] = 20;
1340 ctl->translation = EMU10K1_GPR_TRANSLATION_TREBLE;
1342 #define BASS_GPR 0x8c
1343 #define TREBLE_GPR 0x96
1345 for (z = 0; z < 5; z++) {
1347 for (j = 0; j < 2; j++) {
1348 controls[nctl + 0].gpr[z * 2 + j] = BASS_GPR + z * 2 + j;
1349 controls[nctl + 1].gpr[z * 2 + j] = TREBLE_GPR + z * 2 + j;
1352 for (z = 0; z < 4; z++) { /* front/rear/center-lfe/side */
1354 for (j = 0; j < 2; j++) { /* left/right */
1355 k = 0xb0 + (z * 8) + (j * 4);
1356 l = 0xe0 + (z * 8) + (j * 4);
1357 d = playback + SND_EMU10K1_PLAYBACK_CHANNELS + z * 2 + j;
1359 A_OP(icode, &ptr, iMAC0, A_C_00000000, A_C_00000000, A_GPR(d), A_GPR(BASS_GPR + 0 + j));
1360 A_OP(icode, &ptr, iMACMV, A_GPR(k+1), A_GPR(k), A_GPR(k+1), A_GPR(BASS_GPR + 4 + j));
1361 A_OP(icode, &ptr, iMACMV, A_GPR(k), A_GPR(d), A_GPR(k), A_GPR(BASS_GPR + 2 + j));
1362 A_OP(icode, &ptr, iMACMV, A_GPR(k+3), A_GPR(k+2), A_GPR(k+3), A_GPR(BASS_GPR + 8 + j));
1363 A_OP(icode, &ptr, iMAC0, A_GPR(k+2), A_GPR_ACCU, A_GPR(k+2), A_GPR(BASS_GPR + 6 + j));
1364 A_OP(icode, &ptr, iACC3, A_GPR(k+2), A_GPR(k+2), A_GPR(k+2), A_C_00000000);
1366 A_OP(icode, &ptr, iMAC0, A_C_00000000, A_C_00000000, A_GPR(k+2), A_GPR(TREBLE_GPR + 0 + j));
1367 A_OP(icode, &ptr, iMACMV, A_GPR(l+1), A_GPR(l), A_GPR(l+1), A_GPR(TREBLE_GPR + 4 + j));
1368 A_OP(icode, &ptr, iMACMV, A_GPR(l), A_GPR(k+2), A_GPR(l), A_GPR(TREBLE_GPR + 2 + j));
1369 A_OP(icode, &ptr, iMACMV, A_GPR(l+3), A_GPR(l+2), A_GPR(l+3), A_GPR(TREBLE_GPR + 8 + j));
1370 A_OP(icode, &ptr, iMAC0, A_GPR(l+2), A_GPR_ACCU, A_GPR(l+2), A_GPR(TREBLE_GPR + 6 + j));
1371 A_OP(icode, &ptr, iMACINT0, A_GPR(l+2), A_C_00000000, A_GPR(l+2), A_C_00000010);
1373 A_OP(icode, &ptr, iACC3, A_GPR(d), A_GPR(l+2), A_C_00000000, A_C_00000000);
1375 if (z == 2) /* center */
1384 for (z = 0; z < 8; z++) {
1385 A_SWITCH(icode, &ptr, tmp + 0, playback + SND_EMU10K1_PLAYBACK_CHANNELS + z, gpr + 0);
1386 A_SWITCH_NEG(icode, &ptr, tmp + 1, gpr + 0);
1387 A_SWITCH(icode, &ptr, tmp + 1, playback + z, tmp + 1);
1388 A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + z), A_GPR(tmp + 0), A_GPR(tmp + 1), A_C_00000000);
1390 snd_emu10k1_init_stereo_onoff_control(controls + nctl++, "Tone Control - Switch", gpr, 0);
1393 /* Master volume (will be renamed later) */
1394 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));
1395 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));
1396 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));
1397 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));
1398 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));
1399 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));
1400 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));
1401 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));
1402 snd_emu10k1_init_mono_control(&controls[nctl++], "Wave Master Playback Volume", gpr, 0);
1405 /* analog speakers */
1406 A_PUT_STEREO_OUTPUT(A_EXTOUT_AFRONT_L, A_EXTOUT_AFRONT_R, playback + SND_EMU10K1_PLAYBACK_CHANNELS);
1407 A_PUT_STEREO_OUTPUT(A_EXTOUT_AREAR_L, A_EXTOUT_AREAR_R, playback+2 + SND_EMU10K1_PLAYBACK_CHANNELS);
1408 A_PUT_OUTPUT(A_EXTOUT_ACENTER, playback+4 + SND_EMU10K1_PLAYBACK_CHANNELS);
1409 A_PUT_OUTPUT(A_EXTOUT_ALFE, playback+5 + SND_EMU10K1_PLAYBACK_CHANNELS);
1410 if (emu->card_capabilities->spk71)
1411 A_PUT_STEREO_OUTPUT(A_EXTOUT_ASIDE_L, A_EXTOUT_ASIDE_R, playback+6 + SND_EMU10K1_PLAYBACK_CHANNELS);
1414 A_PUT_STEREO_OUTPUT(A_EXTOUT_HEADPHONE_L, A_EXTOUT_HEADPHONE_R, playback + SND_EMU10K1_PLAYBACK_CHANNELS);
1416 /* digital outputs */
1417 /* A_PUT_STEREO_OUTPUT(A_EXTOUT_FRONT_L, A_EXTOUT_FRONT_R, playback + SND_EMU10K1_PLAYBACK_CHANNELS); */
1419 /* IEC958 Optical Raw Playback Switch */
1421 gpr_map[gpr++] = 0x1008;
1422 gpr_map[gpr++] = 0xffff0000;
1423 for (z = 0; z < 2; z++) {
1424 A_OP(icode, &ptr, iMAC0, A_GPR(tmp + 2), A_FXBUS(FXBUS_PT_LEFT + z), A_C_00000000, A_C_00000000);
1425 A_OP(icode, &ptr, iSKIP, A_GPR_COND, A_GPR_COND, A_GPR(gpr - 2), A_C_00000001);
1426 A_OP(icode, &ptr, iACC3, A_GPR(tmp + 2), A_C_00000000, A_C_00010000, A_GPR(tmp + 2));
1427 A_OP(icode, &ptr, iANDXOR, A_GPR(tmp + 2), A_GPR(tmp + 2), A_GPR(gpr - 1), A_C_00000000);
1428 A_SWITCH(icode, &ptr, tmp + 0, tmp + 2, gpr + z);
1429 A_SWITCH_NEG(icode, &ptr, tmp + 1, gpr + z);
1430 A_SWITCH(icode, &ptr, tmp + 1, playback + SND_EMU10K1_PLAYBACK_CHANNELS + z, tmp + 1);
1431 if ((z==1) && (emu->card_capabilities->spdif_bug)) {
1432 /* Due to a SPDIF output bug on some Audigy cards, this code delays the Right channel by 1 sample */
1433 snd_printk(KERN_INFO "Installing spdif_bug patch: %s\n", emu->card_capabilities->name);
1434 A_OP(icode, &ptr, iACC3, A_EXTOUT(A_EXTOUT_FRONT_L + z), A_GPR(gpr - 3), A_C_00000000, A_C_00000000);
1435 A_OP(icode, &ptr, iACC3, A_GPR(gpr - 3), A_GPR(tmp + 0), A_GPR(tmp + 1), A_C_00000000);
1437 A_OP(icode, &ptr, iACC3, A_EXTOUT(A_EXTOUT_FRONT_L + z), A_GPR(tmp + 0), A_GPR(tmp + 1), A_C_00000000);
1440 snd_emu10k1_init_stereo_onoff_control(controls + nctl++, SNDRV_CTL_NAME_IEC958("Optical Raw ",PLAYBACK,SWITCH), gpr, 0);
1443 A_PUT_STEREO_OUTPUT(A_EXTOUT_REAR_L, A_EXTOUT_REAR_R, playback+2 + SND_EMU10K1_PLAYBACK_CHANNELS);
1444 A_PUT_OUTPUT(A_EXTOUT_CENTER, playback+4 + SND_EMU10K1_PLAYBACK_CHANNELS);
1445 A_PUT_OUTPUT(A_EXTOUT_LFE, playback+5 + SND_EMU10K1_PLAYBACK_CHANNELS);
1448 #ifdef EMU10K1_CAPTURE_DIGITAL_OUT
1449 A_PUT_STEREO_OUTPUT(A_EXTOUT_ADC_CAP_L, A_EXTOUT_ADC_CAP_R, playback + SND_EMU10K1_PLAYBACK_CHANNELS);
1451 A_PUT_OUTPUT(A_EXTOUT_ADC_CAP_L, capture);
1452 A_PUT_OUTPUT(A_EXTOUT_ADC_CAP_R, capture+1);
1455 /* EFX capture - capture the 16 EXTINs */
1456 for (z = 0; z < 16; z++) {
1457 A_OP(icode, &ptr, iACC3, A_FXBUS2(z), A_C_00000000, A_C_00000000, A_EXTIN(z));
1460 #endif /* JCD test */
1470 /* clear remaining instruction memory */
1472 A_OP(icode, &ptr, 0x0f, 0xc0, 0xc0, 0xcf, 0xc0);
1474 seg = snd_enter_user();
1475 icode->gpr_add_control_count = nctl;
1476 icode->gpr_add_controls = (struct snd_emu10k1_fx8010_control_gpr __user *)controls;
1477 err = snd_emu10k1_icode_poke(emu, icode);
1478 snd_leave_user(seg);
1482 if (icode != NULL) {
1483 kfree((void __force *)icode->gpr_map);
1491 * initial DSP configuration for Emu10k1
1494 /* when volume = max, then copy only to avoid volume modification */
1495 /* with iMAC0 (negative values) */
1496 static void __devinit _volume(struct snd_emu10k1_fx8010_code *icode, u32 *ptr, u32 dst, u32 src, u32 vol)
1498 OP(icode, ptr, iMAC0, dst, C_00000000, src, vol);
1499 OP(icode, ptr, iANDXOR, C_00000000, vol, C_ffffffff, C_7fffffff);
1500 OP(icode, ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, C_00000001);
1501 OP(icode, ptr, iACC3, dst, src, C_00000000, C_00000000);
1503 static void __devinit _volume_add(struct snd_emu10k1_fx8010_code *icode, u32 *ptr, u32 dst, u32 src, u32 vol)
1505 OP(icode, ptr, iANDXOR, C_00000000, vol, C_ffffffff, C_7fffffff);
1506 OP(icode, ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, C_00000002);
1507 OP(icode, ptr, iMACINT0, dst, dst, src, C_00000001);
1508 OP(icode, ptr, iSKIP, C_00000000, C_7fffffff, C_7fffffff, C_00000001);
1509 OP(icode, ptr, iMAC0, dst, dst, src, vol);
1511 static void __devinit _volume_out(struct snd_emu10k1_fx8010_code *icode, u32 *ptr, u32 dst, u32 src, u32 vol)
1513 OP(icode, ptr, iANDXOR, C_00000000, vol, C_ffffffff, C_7fffffff);
1514 OP(icode, ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, C_00000002);
1515 OP(icode, ptr, iACC3, dst, src, C_00000000, C_00000000);
1516 OP(icode, ptr, iSKIP, C_00000000, C_7fffffff, C_7fffffff, C_00000001);
1517 OP(icode, ptr, iMAC0, dst, C_00000000, src, vol);
1520 #define VOLUME(icode, ptr, dst, src, vol) \
1521 _volume(icode, ptr, GPR(dst), GPR(src), GPR(vol))
1522 #define VOLUME_IN(icode, ptr, dst, src, vol) \
1523 _volume(icode, ptr, GPR(dst), EXTIN(src), GPR(vol))
1524 #define VOLUME_ADD(icode, ptr, dst, src, vol) \
1525 _volume_add(icode, ptr, GPR(dst), GPR(src), GPR(vol))
1526 #define VOLUME_ADDIN(icode, ptr, dst, src, vol) \
1527 _volume_add(icode, ptr, GPR(dst), EXTIN(src), GPR(vol))
1528 #define VOLUME_OUT(icode, ptr, dst, src, vol) \
1529 _volume_out(icode, ptr, EXTOUT(dst), GPR(src), GPR(vol))
1530 #define _SWITCH(icode, ptr, dst, src, sw) \
1531 OP((icode), ptr, iMACINT0, dst, C_00000000, src, sw);
1532 #define SWITCH(icode, ptr, dst, src, sw) \
1533 _SWITCH(icode, ptr, GPR(dst), GPR(src), GPR(sw))
1534 #define SWITCH_IN(icode, ptr, dst, src, sw) \
1535 _SWITCH(icode, ptr, GPR(dst), EXTIN(src), GPR(sw))
1536 #define _SWITCH_NEG(icode, ptr, dst, src) \
1537 OP((icode), ptr, iANDXOR, dst, src, C_00000001, C_00000001);
1538 #define SWITCH_NEG(icode, ptr, dst, src) \
1539 _SWITCH_NEG(icode, ptr, GPR(dst), GPR(src))
1542 static int __devinit _snd_emu10k1_init_efx(struct snd_emu10k1 *emu)
1544 int err, i, z, gpr, tmp, playback, capture;
1546 struct snd_emu10k1_fx8010_code *icode;
1547 struct snd_emu10k1_fx8010_pcm_rec *ipcm = NULL;
1548 struct snd_emu10k1_fx8010_control_gpr *controls = NULL, *ctl;
1552 if ((icode = kzalloc(sizeof(*icode), GFP_KERNEL)) == NULL)
1554 if ((icode->gpr_map = (u_int32_t __user *)
1555 kcalloc(256 + 160 + 160 + 2 * 512, sizeof(u_int32_t),
1556 GFP_KERNEL)) == NULL ||
1557 (controls = kcalloc(SND_EMU10K1_GPR_CONTROLS,
1558 sizeof(struct snd_emu10k1_fx8010_control_gpr),
1559 GFP_KERNEL)) == NULL ||
1560 (ipcm = kzalloc(sizeof(*ipcm), GFP_KERNEL)) == NULL) {
1564 gpr_map = (u32 __force *)icode->gpr_map;
1566 icode->tram_data_map = icode->gpr_map + 256;
1567 icode->tram_addr_map = icode->tram_data_map + 160;
1568 icode->code = icode->tram_addr_map + 160;
1570 /* clear free GPRs */
1571 for (i = 0; i < 256; i++)
1572 set_bit(i, icode->gpr_valid);
1574 /* clear TRAM data & address lines */
1575 for (i = 0; i < 160; i++)
1576 set_bit(i, icode->tram_valid);
1578 strcpy(icode->name, "SB Live! FX8010 code for ALSA v1.2 by Jaroslav Kysela");
1580 /* we have 12 inputs */
1581 playback = SND_EMU10K1_INPUTS;
1582 /* we have 6 playback channels and tone control doubles */
1583 capture = playback + (SND_EMU10K1_PLAYBACK_CHANNELS * 2);
1584 gpr = capture + SND_EMU10K1_CAPTURE_CHANNELS;
1585 tmp = 0x88; /* we need 4 temporary GPR */
1586 /* from 0x8c to 0xff is the area for tone control */
1588 /* stop FX processor */
1589 snd_emu10k1_ptr_write(emu, DBG, 0, (emu->fx8010.dbg = 0) | EMU10K1_DBG_SINGLE_STEP);
1594 OP(icode, &ptr, iMACINT0, GPR(0), C_00000000, FXBUS(FXBUS_PCM_LEFT), C_00000004);
1595 OP(icode, &ptr, iMACINT0, GPR(1), C_00000000, FXBUS(FXBUS_PCM_RIGHT), C_00000004);
1596 OP(icode, &ptr, iMACINT0, GPR(2), C_00000000, FXBUS(FXBUS_MIDI_LEFT), C_00000004);
1597 OP(icode, &ptr, iMACINT0, GPR(3), C_00000000, FXBUS(FXBUS_MIDI_RIGHT), C_00000004);
1598 OP(icode, &ptr, iMACINT0, GPR(4), C_00000000, FXBUS(FXBUS_PCM_LEFT_REAR), C_00000004);
1599 OP(icode, &ptr, iMACINT0, GPR(5), C_00000000, FXBUS(FXBUS_PCM_RIGHT_REAR), C_00000004);
1600 OP(icode, &ptr, iMACINT0, GPR(6), C_00000000, FXBUS(FXBUS_PCM_CENTER), C_00000004);
1601 OP(icode, &ptr, iMACINT0, GPR(7), C_00000000, FXBUS(FXBUS_PCM_LFE), C_00000004);
1602 OP(icode, &ptr, iMACINT0, GPR(8), C_00000000, C_00000000, C_00000000); /* S/PDIF left */
1603 OP(icode, &ptr, iMACINT0, GPR(9), C_00000000, C_00000000, C_00000000); /* S/PDIF right */
1604 OP(icode, &ptr, iMACINT0, GPR(10), C_00000000, FXBUS(FXBUS_PCM_LEFT_FRONT), C_00000004);
1605 OP(icode, &ptr, iMACINT0, GPR(11), C_00000000, FXBUS(FXBUS_PCM_RIGHT_FRONT), C_00000004);
1607 /* Raw S/PDIF PCM */
1608 ipcm->substream = 0;
1610 ipcm->tram_start = 0;
1611 ipcm->buffer_size = (64 * 1024) / 2;
1612 ipcm->gpr_size = gpr++;
1613 ipcm->gpr_ptr = gpr++;
1614 ipcm->gpr_count = gpr++;
1615 ipcm->gpr_tmpcount = gpr++;
1616 ipcm->gpr_trigger = gpr++;
1617 ipcm->gpr_running = gpr++;
1621 gpr_map[gpr + 0] = 0xfffff000;
1622 gpr_map[gpr + 1] = 0xffff0000;
1623 gpr_map[gpr + 2] = 0x70000000;
1624 gpr_map[gpr + 3] = 0x00000007;
1625 gpr_map[gpr + 4] = 0x001f << 11;
1626 gpr_map[gpr + 5] = 0x001c << 11;
1627 gpr_map[gpr + 6] = (0x22 - 0x01) - 1; /* skip at 01 to 22 */
1628 gpr_map[gpr + 7] = (0x22 - 0x06) - 1; /* skip at 06 to 22 */
1629 gpr_map[gpr + 8] = 0x2000000 + (2<<11);
1630 gpr_map[gpr + 9] = 0x4000000 + (2<<11);
1631 gpr_map[gpr + 10] = 1<<11;
1632 gpr_map[gpr + 11] = (0x24 - 0x0a) - 1; /* skip at 0a to 24 */
1633 gpr_map[gpr + 12] = 0;
1635 /* if the trigger flag is not set, skip */
1636 /* 00: */ OP(icode, &ptr, iMAC0, C_00000000, GPR(ipcm->gpr_trigger), C_00000000, C_00000000);
1637 /* 01: */ OP(icode, &ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_ZERO, GPR(gpr + 6));
1638 /* if the running flag is set, we're running */
1639 /* 02: */ OP(icode, &ptr, iMAC0, C_00000000, GPR(ipcm->gpr_running), C_00000000, C_00000000);
1640 /* 03: */ OP(icode, &ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, C_00000004);
1641 /* wait until ((GPR_DBAC>>11) & 0x1f) == 0x1c) */
1642 /* 04: */ OP(icode, &ptr, iANDXOR, GPR(tmp + 0), GPR_DBAC, GPR(gpr + 4), C_00000000);
1643 /* 05: */ OP(icode, &ptr, iMACINT0, C_00000000, GPR(tmp + 0), C_ffffffff, GPR(gpr + 5));
1644 /* 06: */ OP(icode, &ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, GPR(gpr + 7));
1645 /* 07: */ OP(icode, &ptr, iACC3, GPR(gpr + 12), C_00000010, C_00000001, C_00000000);
1647 /* 08: */ OP(icode, &ptr, iANDXOR, GPR(ipcm->gpr_running), GPR(ipcm->gpr_running), C_00000000, C_00000001);
1648 /* 09: */ OP(icode, &ptr, iACC3, GPR(gpr + 12), GPR(gpr + 12), C_ffffffff, C_00000000);
1649 /* 0a: */ OP(icode, &ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, GPR(gpr + 11));
1650 /* 0b: */ OP(icode, &ptr, iACC3, GPR(gpr + 12), C_00000001, C_00000000, C_00000000);
1652 /* 0c: */ OP(icode, &ptr, iANDXOR, GPR(tmp + 0), ETRAM_DATA(ipcm->etram[0]), GPR(gpr + 0), C_00000000);
1653 /* 0d: */ OP(icode, &ptr, iLOG, GPR(tmp + 0), GPR(tmp + 0), GPR(gpr + 3), C_00000000);
1654 /* 0e: */ OP(icode, &ptr, iANDXOR, GPR(8), GPR(tmp + 0), GPR(gpr + 1), GPR(gpr + 2));
1655 /* 0f: */ OP(icode, &ptr, iSKIP, C_00000000, GPR_COND, CC_REG_MINUS, C_00000001);
1656 /* 10: */ OP(icode, &ptr, iANDXOR, GPR(8), GPR(8), GPR(gpr + 1), GPR(gpr + 2));
1658 /* 11: */ OP(icode, &ptr, iANDXOR, GPR(tmp + 0), ETRAM_DATA(ipcm->etram[1]), GPR(gpr + 0), C_00000000);
1659 /* 12: */ OP(icode, &ptr, iLOG, GPR(tmp + 0), GPR(tmp + 0), GPR(gpr + 3), C_00000000);
1660 /* 13: */ OP(icode, &ptr, iANDXOR, GPR(9), GPR(tmp + 0), GPR(gpr + 1), GPR(gpr + 2));
1661 /* 14: */ OP(icode, &ptr, iSKIP, C_00000000, GPR_COND, CC_REG_MINUS, C_00000001);
1662 /* 15: */ OP(icode, &ptr, iANDXOR, GPR(9), GPR(9), GPR(gpr + 1), GPR(gpr + 2));
1664 /* 16: */ OP(icode, &ptr, iACC3, GPR(tmp + 0), GPR(ipcm->gpr_ptr), C_00000001, C_00000000);
1665 /* 17: */ OP(icode, &ptr, iMACINT0, C_00000000, GPR(tmp + 0), C_ffffffff, GPR(ipcm->gpr_size));
1666 /* 18: */ OP(icode, &ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_MINUS, C_00000001);
1667 /* 19: */ OP(icode, &ptr, iACC3, GPR(tmp + 0), C_00000000, C_00000000, C_00000000);
1668 /* 1a: */ OP(icode, &ptr, iACC3, GPR(ipcm->gpr_ptr), GPR(tmp + 0), C_00000000, C_00000000);
1670 /* 1b: */ OP(icode, &ptr, iACC3, GPR(ipcm->gpr_tmpcount), GPR(ipcm->gpr_tmpcount), C_ffffffff, C_00000000);
1671 /* 1c: */ OP(icode, &ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, C_00000002);
1672 /* 1d: */ OP(icode, &ptr, iACC3, GPR(ipcm->gpr_tmpcount), GPR(ipcm->gpr_count), C_00000000, C_00000000);
1673 /* 1e: */ OP(icode, &ptr, iACC3, GPR_IRQ, C_80000000, C_00000000, C_00000000);
1674 /* 1f: */ OP(icode, &ptr, iANDXOR, GPR(ipcm->gpr_running), GPR(ipcm->gpr_running), C_00000001, C_00010000);
1676 /* 20: */ OP(icode, &ptr, iANDXOR, GPR(ipcm->gpr_running), GPR(ipcm->gpr_running), C_00010000, C_00000001);
1677 /* 21: */ OP(icode, &ptr, iSKIP, C_00000000, C_7fffffff, C_7fffffff, C_00000002);
1679 /* 22: */ OP(icode, &ptr, iMACINT1, ETRAM_ADDR(ipcm->etram[0]), GPR(gpr + 8), GPR_DBAC, C_ffffffff);
1680 /* 23: */ OP(icode, &ptr, iMACINT1, ETRAM_ADDR(ipcm->etram[1]), GPR(gpr + 9), GPR_DBAC, C_ffffffff);
1685 /* Wave Playback Volume */
1686 for (z = 0; z < 2; z++)
1687 VOLUME(icode, &ptr, playback + z, z, gpr + z);
1688 snd_emu10k1_init_stereo_control(controls + i++, "Wave Playback Volume", gpr, 100);
1691 /* Wave Surround Playback Volume */
1692 for (z = 0; z < 2; z++)
1693 VOLUME(icode, &ptr, playback + 2 + z, z, gpr + z);
1694 snd_emu10k1_init_stereo_control(controls + i++, "Wave Surround Playback Volume", gpr, 0);
1697 /* Wave Center/LFE Playback Volume */
1698 OP(icode, &ptr, iACC3, GPR(tmp + 0), FXBUS(FXBUS_PCM_LEFT), FXBUS(FXBUS_PCM_RIGHT), C_00000000);
1699 OP(icode, &ptr, iMACINT0, GPR(tmp + 0), C_00000000, GPR(tmp + 0), C_00000002);
1700 VOLUME(icode, &ptr, playback + 4, tmp + 0, gpr);
1701 snd_emu10k1_init_mono_control(controls + i++, "Wave Center Playback Volume", gpr++, 0);
1702 VOLUME(icode, &ptr, playback + 5, tmp + 0, gpr);
1703 snd_emu10k1_init_mono_control(controls + i++, "Wave LFE Playback Volume", gpr++, 0);
1705 /* Wave Capture Volume + Switch */
1706 for (z = 0; z < 2; z++) {
1707 SWITCH(icode, &ptr, tmp + 0, z, gpr + 2 + z);
1708 VOLUME(icode, &ptr, capture + z, tmp + 0, gpr + z);
1710 snd_emu10k1_init_stereo_control(controls + i++, "Wave Capture Volume", gpr, 0);
1711 snd_emu10k1_init_stereo_onoff_control(controls + i++, "Wave Capture Switch", gpr + 2, 0);
1714 /* Synth Playback Volume */
1715 for (z = 0; z < 2; z++)
1716 VOLUME_ADD(icode, &ptr, playback + z, 2 + z, gpr + z);
1717 snd_emu10k1_init_stereo_control(controls + i++, "Synth Playback Volume", gpr, 100);
1720 /* Synth Capture Volume + Switch */
1721 for (z = 0; z < 2; z++) {
1722 SWITCH(icode, &ptr, tmp + 0, 2 + z, gpr + 2 + z);
1723 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
1725 snd_emu10k1_init_stereo_control(controls + i++, "Synth Capture Volume", gpr, 0);
1726 snd_emu10k1_init_stereo_onoff_control(controls + i++, "Synth Capture Switch", gpr + 2, 0);
1729 /* Surround Digital Playback Volume (renamed later without Digital) */
1730 for (z = 0; z < 2; z++)
1731 VOLUME_ADD(icode, &ptr, playback + 2 + z, 4 + z, gpr + z);
1732 snd_emu10k1_init_stereo_control(controls + i++, "Surround Digital Playback Volume", gpr, 100);
1735 /* Surround Capture Volume + Switch */
1736 for (z = 0; z < 2; z++) {
1737 SWITCH(icode, &ptr, tmp + 0, 4 + z, gpr + 2 + z);
1738 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
1740 snd_emu10k1_init_stereo_control(controls + i++, "Surround Capture Volume", gpr, 0);
1741 snd_emu10k1_init_stereo_onoff_control(controls + i++, "Surround Capture Switch", gpr + 2, 0);
1744 /* Center Playback Volume (renamed later without Digital) */
1745 VOLUME_ADD(icode, &ptr, playback + 4, 6, gpr);
1746 snd_emu10k1_init_mono_control(controls + i++, "Center Digital Playback Volume", gpr++, 100);
1748 /* LFE Playback Volume + Switch (renamed later without Digital) */
1749 VOLUME_ADD(icode, &ptr, playback + 5, 7, gpr);
1750 snd_emu10k1_init_mono_control(controls + i++, "LFE Digital Playback Volume", gpr++, 100);
1752 /* Front Playback Volume */
1753 for (z = 0; z < 2; z++)
1754 VOLUME_ADD(icode, &ptr, playback + z, 10 + z, gpr + z);
1755 snd_emu10k1_init_stereo_control(controls + i++, "Front Playback Volume", gpr, 100);
1758 /* Front Capture Volume + Switch */
1759 for (z = 0; z < 2; z++) {
1760 SWITCH(icode, &ptr, tmp + 0, 10 + z, gpr + 2);
1761 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
1763 snd_emu10k1_init_stereo_control(controls + i++, "Front Capture Volume", gpr, 0);
1764 snd_emu10k1_init_mono_onoff_control(controls + i++, "Front Capture Switch", gpr + 2, 0);
1771 if (emu->fx8010.extin_mask & ((1<<EXTIN_AC97_L)|(1<<EXTIN_AC97_R))) {
1772 /* AC'97 Playback Volume */
1773 VOLUME_ADDIN(icode, &ptr, playback + 0, EXTIN_AC97_L, gpr); gpr++;
1774 VOLUME_ADDIN(icode, &ptr, playback + 1, EXTIN_AC97_R, gpr); gpr++;
1775 snd_emu10k1_init_stereo_control(controls + i++, "AC97 Playback Volume", gpr-2, 0);
1776 /* AC'97 Capture Volume */
1777 VOLUME_ADDIN(icode, &ptr, capture + 0, EXTIN_AC97_L, gpr); gpr++;
1778 VOLUME_ADDIN(icode, &ptr, capture + 1, EXTIN_AC97_R, gpr); gpr++;
1779 snd_emu10k1_init_stereo_control(controls + i++, "AC97 Capture Volume", gpr-2, 100);
1782 if (emu->fx8010.extin_mask & ((1<<EXTIN_SPDIF_CD_L)|(1<<EXTIN_SPDIF_CD_R))) {
1783 /* IEC958 TTL Playback Volume */
1784 for (z = 0; z < 2; z++)
1785 VOLUME_ADDIN(icode, &ptr, playback + z, EXTIN_SPDIF_CD_L + z, gpr + z);
1786 snd_emu10k1_init_stereo_control(controls + i++, SNDRV_CTL_NAME_IEC958("TTL ",PLAYBACK,VOLUME), gpr, 0);
1789 /* IEC958 TTL Capture Volume + Switch */
1790 for (z = 0; z < 2; z++) {
1791 SWITCH_IN(icode, &ptr, tmp + 0, EXTIN_SPDIF_CD_L + z, gpr + 2 + z);
1792 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
1794 snd_emu10k1_init_stereo_control(controls + i++, SNDRV_CTL_NAME_IEC958("TTL ",CAPTURE,VOLUME), gpr, 0);
1795 snd_emu10k1_init_stereo_onoff_control(controls + i++, SNDRV_CTL_NAME_IEC958("TTL ",CAPTURE,SWITCH), gpr + 2, 0);
1799 if (emu->fx8010.extin_mask & ((1<<EXTIN_ZOOM_L)|(1<<EXTIN_ZOOM_R))) {
1800 /* Zoom Video Playback Volume */
1801 for (z = 0; z < 2; z++)
1802 VOLUME_ADDIN(icode, &ptr, playback + z, EXTIN_ZOOM_L + z, gpr + z);
1803 snd_emu10k1_init_stereo_control(controls + i++, "Zoom Video Playback Volume", gpr, 0);
1806 /* Zoom Video Capture Volume + Switch */
1807 for (z = 0; z < 2; z++) {
1808 SWITCH_IN(icode, &ptr, tmp + 0, EXTIN_ZOOM_L + z, gpr + 2 + z);
1809 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
1811 snd_emu10k1_init_stereo_control(controls + i++, "Zoom Video Capture Volume", gpr, 0);
1812 snd_emu10k1_init_stereo_onoff_control(controls + i++, "Zoom Video Capture Switch", gpr + 2, 0);
1816 if (emu->fx8010.extin_mask & ((1<<EXTIN_TOSLINK_L)|(1<<EXTIN_TOSLINK_R))) {
1817 /* IEC958 Optical Playback Volume */
1818 for (z = 0; z < 2; z++)
1819 VOLUME_ADDIN(icode, &ptr, playback + z, EXTIN_TOSLINK_L + z, gpr + z);
1820 snd_emu10k1_init_stereo_control(controls + i++, SNDRV_CTL_NAME_IEC958("LiveDrive ",PLAYBACK,VOLUME), gpr, 0);
1823 /* IEC958 Optical Capture Volume */
1824 for (z = 0; z < 2; z++) {
1825 SWITCH_IN(icode, &ptr, tmp + 0, EXTIN_TOSLINK_L + z, gpr + 2 + z);
1826 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
1828 snd_emu10k1_init_stereo_control(controls + i++, SNDRV_CTL_NAME_IEC958("LiveDrive ",CAPTURE,VOLUME), gpr, 0);
1829 snd_emu10k1_init_stereo_onoff_control(controls + i++, SNDRV_CTL_NAME_IEC958("LiveDrive ",CAPTURE,SWITCH), gpr + 2, 0);
1833 if (emu->fx8010.extin_mask & ((1<<EXTIN_LINE1_L)|(1<<EXTIN_LINE1_R))) {
1834 /* Line LiveDrive Playback Volume */
1835 for (z = 0; z < 2; z++)
1836 VOLUME_ADDIN(icode, &ptr, playback + z, EXTIN_LINE1_L + z, gpr + z);
1837 snd_emu10k1_init_stereo_control(controls + i++, "Line LiveDrive Playback Volume", gpr, 0);
1840 /* Line LiveDrive Capture Volume + Switch */
1841 for (z = 0; z < 2; z++) {
1842 SWITCH_IN(icode, &ptr, tmp + 0, EXTIN_LINE1_L + z, gpr + 2 + z);
1843 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
1845 snd_emu10k1_init_stereo_control(controls + i++, "Line LiveDrive Capture Volume", gpr, 0);
1846 snd_emu10k1_init_stereo_onoff_control(controls + i++, "Line LiveDrive Capture Switch", gpr + 2, 0);
1850 if (emu->fx8010.extin_mask & ((1<<EXTIN_COAX_SPDIF_L)|(1<<EXTIN_COAX_SPDIF_R))) {
1851 /* IEC958 Coax Playback Volume */
1852 for (z = 0; z < 2; z++)
1853 VOLUME_ADDIN(icode, &ptr, playback + z, EXTIN_COAX_SPDIF_L + z, gpr + z);
1854 snd_emu10k1_init_stereo_control(controls + i++, SNDRV_CTL_NAME_IEC958("Coaxial ",PLAYBACK,VOLUME), gpr, 0);
1857 /* IEC958 Coax Capture Volume + Switch */
1858 for (z = 0; z < 2; z++) {
1859 SWITCH_IN(icode, &ptr, tmp + 0, EXTIN_COAX_SPDIF_L + z, gpr + 2 + z);
1860 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
1862 snd_emu10k1_init_stereo_control(controls + i++, SNDRV_CTL_NAME_IEC958("Coaxial ",CAPTURE,VOLUME), gpr, 0);
1863 snd_emu10k1_init_stereo_onoff_control(controls + i++, SNDRV_CTL_NAME_IEC958("Coaxial ",CAPTURE,SWITCH), gpr + 2, 0);
1867 if (emu->fx8010.extin_mask & ((1<<EXTIN_LINE2_L)|(1<<EXTIN_LINE2_R))) {
1868 /* Line LiveDrive Playback Volume */
1869 for (z = 0; z < 2; z++)
1870 VOLUME_ADDIN(icode, &ptr, playback + z, EXTIN_LINE2_L + z, gpr + z);
1871 snd_emu10k1_init_stereo_control(controls + i++, "Line2 LiveDrive Playback Volume", gpr, 0);
1872 controls[i-1].id.index = 1;
1875 /* Line LiveDrive Capture Volume */
1876 for (z = 0; z < 2; z++) {
1877 SWITCH_IN(icode, &ptr, tmp + 0, EXTIN_LINE2_L + z, gpr + 2 + z);
1878 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
1880 snd_emu10k1_init_stereo_control(controls + i++, "Line2 LiveDrive Capture Volume", gpr, 0);
1881 controls[i-1].id.index = 1;
1882 snd_emu10k1_init_stereo_onoff_control(controls + i++, "Line2 LiveDrive Capture Switch", gpr + 2, 0);
1883 controls[i-1].id.index = 1;
1888 * Process tone control
1890 OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 0), GPR(playback + 0), C_00000000, C_00000000); /* left */
1891 OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 1), GPR(playback + 1), C_00000000, C_00000000); /* right */
1892 OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 2), GPR(playback + 2), C_00000000, C_00000000); /* rear left */
1893 OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 3), GPR(playback + 3), C_00000000, C_00000000); /* rear right */
1894 OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 4), GPR(playback + 4), C_00000000, C_00000000); /* center */
1895 OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 5), GPR(playback + 5), C_00000000, C_00000000); /* LFE */
1897 ctl = &controls[i + 0];
1898 ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1899 strcpy(ctl->id.name, "Tone Control - Bass");
1904 ctl->value[0] = ctl->value[1] = 20;
1905 ctl->translation = EMU10K1_GPR_TRANSLATION_BASS;
1906 ctl = &controls[i + 1];
1907 ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1908 strcpy(ctl->id.name, "Tone Control - Treble");
1913 ctl->value[0] = ctl->value[1] = 20;
1914 ctl->translation = EMU10K1_GPR_TRANSLATION_TREBLE;
1916 #define BASS_GPR 0x8c
1917 #define TREBLE_GPR 0x96
1919 for (z = 0; z < 5; z++) {
1921 for (j = 0; j < 2; j++) {
1922 controls[i + 0].gpr[z * 2 + j] = BASS_GPR + z * 2 + j;
1923 controls[i + 1].gpr[z * 2 + j] = TREBLE_GPR + z * 2 + j;
1926 for (z = 0; z < 3; z++) { /* front/rear/center-lfe */
1928 for (j = 0; j < 2; j++) { /* left/right */
1929 k = 0xa0 + (z * 8) + (j * 4);
1930 l = 0xd0 + (z * 8) + (j * 4);
1931 d = playback + SND_EMU10K1_PLAYBACK_CHANNELS + z * 2 + j;
1933 OP(icode, &ptr, iMAC0, C_00000000, C_00000000, GPR(d), GPR(BASS_GPR + 0 + j));
1934 OP(icode, &ptr, iMACMV, GPR(k+1), GPR(k), GPR(k+1), GPR(BASS_GPR + 4 + j));
1935 OP(icode, &ptr, iMACMV, GPR(k), GPR(d), GPR(k), GPR(BASS_GPR + 2 + j));
1936 OP(icode, &ptr, iMACMV, GPR(k+3), GPR(k+2), GPR(k+3), GPR(BASS_GPR + 8 + j));
1937 OP(icode, &ptr, iMAC0, GPR(k+2), GPR_ACCU, GPR(k+2), GPR(BASS_GPR + 6 + j));
1938 OP(icode, &ptr, iACC3, GPR(k+2), GPR(k+2), GPR(k+2), C_00000000);
1940 OP(icode, &ptr, iMAC0, C_00000000, C_00000000, GPR(k+2), GPR(TREBLE_GPR + 0 + j));
1941 OP(icode, &ptr, iMACMV, GPR(l+1), GPR(l), GPR(l+1), GPR(TREBLE_GPR + 4 + j));
1942 OP(icode, &ptr, iMACMV, GPR(l), GPR(k+2), GPR(l), GPR(TREBLE_GPR + 2 + j));
1943 OP(icode, &ptr, iMACMV, GPR(l+3), GPR(l+2), GPR(l+3), GPR(TREBLE_GPR + 8 + j));
1944 OP(icode, &ptr, iMAC0, GPR(l+2), GPR_ACCU, GPR(l+2), GPR(TREBLE_GPR + 6 + j));
1945 OP(icode, &ptr, iMACINT0, GPR(l+2), C_00000000, GPR(l+2), C_00000010);
1947 OP(icode, &ptr, iACC3, GPR(d), GPR(l+2), C_00000000, C_00000000);
1949 if (z == 2) /* center */
1958 for (z = 0; z < 6; z++) {
1959 SWITCH(icode, &ptr, tmp + 0, playback + SND_EMU10K1_PLAYBACK_CHANNELS + z, gpr + 0);
1960 SWITCH_NEG(icode, &ptr, tmp + 1, gpr + 0);
1961 SWITCH(icode, &ptr, tmp + 1, playback + z, tmp + 1);
1962 OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + z), GPR(tmp + 0), GPR(tmp + 1), C_00000000);
1964 snd_emu10k1_init_stereo_onoff_control(controls + i++, "Tone Control - Switch", gpr, 0);
1970 if (emu->fx8010.extout_mask & ((1<<EXTOUT_AC97_L)|(1<<EXTOUT_AC97_R))) {
1971 /* AC'97 Playback Volume */
1973 for (z = 0; z < 2; z++)
1974 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_AC97_L + z), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + z), C_00000000, C_00000000);
1977 if (emu->fx8010.extout_mask & ((1<<EXTOUT_TOSLINK_L)|(1<<EXTOUT_TOSLINK_R))) {
1978 /* IEC958 Optical Raw Playback Switch */
1980 for (z = 0; z < 2; z++) {
1981 SWITCH(icode, &ptr, tmp + 0, 8 + z, gpr + z);
1982 SWITCH_NEG(icode, &ptr, tmp + 1, gpr + z);
1983 SWITCH(icode, &ptr, tmp + 1, playback + SND_EMU10K1_PLAYBACK_CHANNELS + z, tmp + 1);
1984 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_TOSLINK_L + z), GPR(tmp + 0), GPR(tmp + 1), C_00000000);
1985 #ifdef EMU10K1_CAPTURE_DIGITAL_OUT
1986 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_ADC_CAP_L + z), GPR(tmp + 0), GPR(tmp + 1), C_00000000);
1990 snd_emu10k1_init_stereo_onoff_control(controls + i++, SNDRV_CTL_NAME_IEC958("Optical Raw ",PLAYBACK,SWITCH), gpr, 0);
1994 if (emu->fx8010.extout_mask & ((1<<EXTOUT_HEADPHONE_L)|(1<<EXTOUT_HEADPHONE_R))) {
1995 /* Headphone Playback Volume */
1997 for (z = 0; z < 2; z++) {
1998 SWITCH(icode, &ptr, tmp + 0, playback + SND_EMU10K1_PLAYBACK_CHANNELS + 4 + z, gpr + 2 + z);
1999 SWITCH_NEG(icode, &ptr, tmp + 1, gpr + 2 + z);
2000 SWITCH(icode, &ptr, tmp + 1, playback + SND_EMU10K1_PLAYBACK_CHANNELS + z, tmp + 1);
2001 OP(icode, &ptr, iACC3, GPR(tmp + 0), GPR(tmp + 0), GPR(tmp + 1), C_00000000);
2002 VOLUME_OUT(icode, &ptr, EXTOUT_HEADPHONE_L + z, tmp + 0, gpr + z);
2005 snd_emu10k1_init_stereo_control(controls + i++, "Headphone Playback Volume", gpr + 0, 0);
2006 controls[i-1].id.index = 1; /* AC'97 can have also Headphone control */
2007 snd_emu10k1_init_mono_onoff_control(controls + i++, "Headphone Center Playback Switch", gpr + 2, 0);
2008 controls[i-1].id.index = 1;
2009 snd_emu10k1_init_mono_onoff_control(controls + i++, "Headphone LFE Playback Switch", gpr + 3, 0);
2010 controls[i-1].id.index = 1;
2015 if (emu->fx8010.extout_mask & ((1<<EXTOUT_REAR_L)|(1<<EXTOUT_REAR_R)))
2016 for (z = 0; z < 2; z++)
2017 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_REAR_L + z), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 2 + z), C_00000000, C_00000000);
2019 if (emu->fx8010.extout_mask & ((1<<EXTOUT_AC97_REAR_L)|(1<<EXTOUT_AC97_REAR_R)))
2020 for (z = 0; z < 2; z++)
2021 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_AC97_REAR_L + z), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 2 + z), C_00000000, C_00000000);
2023 if (emu->fx8010.extout_mask & (1<<EXTOUT_AC97_CENTER)) {
2024 #ifndef EMU10K1_CENTER_LFE_FROM_FRONT
2025 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_AC97_CENTER), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 4), C_00000000, C_00000000);
2026 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_ACENTER), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 4), C_00000000, C_00000000);
2028 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_AC97_CENTER), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 0), C_00000000, C_00000000);
2029 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_ACENTER), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 0), C_00000000, C_00000000);
2033 if (emu->fx8010.extout_mask & (1<<EXTOUT_AC97_LFE)) {
2034 #ifndef EMU10K1_CENTER_LFE_FROM_FRONT
2035 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_AC97_LFE), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 5), C_00000000, C_00000000);
2036 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_ALFE), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 5), C_00000000, C_00000000);
2038 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_AC97_LFE), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 1), C_00000000, C_00000000);
2039 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_ALFE), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 1), C_00000000, C_00000000);
2043 #ifndef EMU10K1_CAPTURE_DIGITAL_OUT
2044 for (z = 0; z < 2; z++)
2045 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_ADC_CAP_L + z), GPR(capture + z), C_00000000, C_00000000);
2048 if (emu->fx8010.extout_mask & (1<<EXTOUT_MIC_CAP))
2049 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_MIC_CAP), GPR(capture + 2), C_00000000, C_00000000);
2051 /* EFX capture - capture the 16 EXTINS */
2052 if (emu->card_capabilities->sblive51) {
2053 /* On the Live! 5.1, FXBUS2(1) and FXBUS(2) are shared with EXTOUT_ACENTER
2054 * and EXTOUT_ALFE, so we can't connect inputs to them for multitrack recording.
2056 * Since only 14 of the 16 EXTINs are used, this is not a big problem.
2057 * We route AC97L and R to FX capture 14 and 15, SPDIF CD in to FX capture
2058 * 0 and 3, then the rest of the EXTINs to the corresponding FX capture
2059 * channel. Multitrack recorders will still see the center/lfe output signal
2060 * on the second and third channels.
2062 OP(icode, &ptr, iACC3, FXBUS2(14), C_00000000, C_00000000, EXTIN(0));
2063 OP(icode, &ptr, iACC3, FXBUS2(15), C_00000000, C_00000000, EXTIN(1));
2064 OP(icode, &ptr, iACC3, FXBUS2(0), C_00000000, C_00000000, EXTIN(2));
2065 OP(icode, &ptr, iACC3, FXBUS2(3), C_00000000, C_00000000, EXTIN(3));
2066 for (z = 4; z < 14; z++)
2067 OP(icode, &ptr, iACC3, FXBUS2(z), C_00000000, C_00000000, EXTIN(z));
2069 for (z = 0; z < 16; z++)
2070 OP(icode, &ptr, iACC3, FXBUS2(z), C_00000000, C_00000000, EXTIN(z));
2079 if (i > SND_EMU10K1_GPR_CONTROLS) {
2085 /* clear remaining instruction memory */
2087 OP(icode, &ptr, iACC3, C_00000000, C_00000000, C_00000000, C_00000000);
2089 if ((err = snd_emu10k1_fx8010_tram_setup(emu, ipcm->buffer_size)) < 0)
2091 seg = snd_enter_user();
2092 icode->gpr_add_control_count = i;
2093 icode->gpr_add_controls = (struct snd_emu10k1_fx8010_control_gpr __user *)controls;
2094 err = snd_emu10k1_icode_poke(emu, icode);
2095 snd_leave_user(seg);
2097 err = snd_emu10k1_ipcm_poke(emu, ipcm);
2101 if (icode != NULL) {
2102 kfree((void __force *)icode->gpr_map);
2108 int __devinit snd_emu10k1_init_efx(struct snd_emu10k1 *emu)
2110 spin_lock_init(&emu->fx8010.irq_lock);
2111 INIT_LIST_HEAD(&emu->fx8010.gpr_ctl);
2113 return _snd_emu10k1_audigy_init_efx(emu);
2115 return _snd_emu10k1_init_efx(emu);
2118 void snd_emu10k1_free_efx(struct snd_emu10k1 *emu)
2120 /* stop processor */
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);
2127 #if 0 // FIXME: who use them?
2128 int snd_emu10k1_fx8010_tone_control_activate(struct snd_emu10k1 *emu, int output)
2130 if (output < 0 || output >= 6)
2132 snd_emu10k1_ptr_write(emu, emu->gpr_base + 0x94 + output, 0, 1);
2136 int snd_emu10k1_fx8010_tone_control_deactivate(struct snd_emu10k1 *emu, int output)
2138 if (output < 0 || output >= 6)
2140 snd_emu10k1_ptr_write(emu, emu->gpr_base + 0x94 + output, 0, 0);
2145 int snd_emu10k1_fx8010_tram_setup(struct snd_emu10k1 *emu, u32 size)
2149 /* size is in samples */
2151 size = (size - 1) >> 13;
2157 size = 0x2000 << size_reg;
2159 if ((emu->fx8010.etram_pages.bytes / 2) == size)
2161 spin_lock_irq(&emu->emu_lock);
2162 outl(HCFG_LOCKTANKCACHE_MASK | inl(emu->port + HCFG), emu->port + HCFG);
2163 spin_unlock_irq(&emu->emu_lock);
2164 snd_emu10k1_ptr_write(emu, TCB, 0, 0);
2165 snd_emu10k1_ptr_write(emu, TCBS, 0, 0);
2166 if (emu->fx8010.etram_pages.area != NULL) {
2167 snd_dma_free_pages(&emu->fx8010.etram_pages);
2168 emu->fx8010.etram_pages.area = NULL;
2169 emu->fx8010.etram_pages.bytes = 0;
2173 if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(emu->pci),
2174 size * 2, &emu->fx8010.etram_pages) < 0)
2176 memset(emu->fx8010.etram_pages.area, 0, size * 2);
2177 snd_emu10k1_ptr_write(emu, TCB, 0, emu->fx8010.etram_pages.addr);
2178 snd_emu10k1_ptr_write(emu, TCBS, 0, size_reg);
2179 spin_lock_irq(&emu->emu_lock);
2180 outl(inl(emu->port + HCFG) & ~HCFG_LOCKTANKCACHE_MASK, emu->port + HCFG);
2181 spin_unlock_irq(&emu->emu_lock);
2187 static int snd_emu10k1_fx8010_open(struct snd_hwdep * hw, struct file *file)
2192 static void copy_string(char *dst, char *src, char *null, int idx)
2195 sprintf(dst, "%s %02X", null, idx);
2200 static int snd_emu10k1_fx8010_info(struct snd_emu10k1 *emu,
2201 struct snd_emu10k1_fx8010_info *info)
2203 char **fxbus, **extin, **extout;
2204 unsigned short fxbus_mask, extin_mask, extout_mask;
2207 memset(info, 0, sizeof(info));
2208 info->internal_tram_size = emu->fx8010.itram_size;
2209 info->external_tram_size = emu->fx8010.etram_pages.bytes / 2;
2211 extin = emu->audigy ? audigy_ins : creative_ins;
2212 extout = emu->audigy ? audigy_outs : creative_outs;
2213 fxbus_mask = emu->fx8010.fxbus_mask;
2214 extin_mask = emu->fx8010.extin_mask;
2215 extout_mask = emu->fx8010.extout_mask;
2216 for (res = 0; res < 16; res++, fxbus++, extin++, extout++) {
2217 copy_string(info->fxbus_names[res], fxbus_mask & (1 << res) ? *fxbus : NULL, "FXBUS", res);
2218 copy_string(info->extin_names[res], extin_mask & (1 << res) ? *extin : NULL, "Unused", res);
2219 copy_string(info->extout_names[res], extout_mask & (1 << res) ? *extout : NULL, "Unused", res);
2221 for (res = 16; res < 32; res++, extout++)
2222 copy_string(info->extout_names[res], extout_mask & (1 << res) ? *extout : NULL, "Unused", res);
2223 info->gpr_controls = emu->fx8010.gpr_count;
2227 static int snd_emu10k1_fx8010_ioctl(struct snd_hwdep * hw, struct file *file, unsigned int cmd, unsigned long arg)
2229 struct snd_emu10k1 *emu = hw->private_data;
2230 struct snd_emu10k1_fx8010_info *info;
2231 struct snd_emu10k1_fx8010_code *icode;
2232 struct snd_emu10k1_fx8010_pcm_rec *ipcm;
2234 void __user *argp = (void __user *)arg;
2238 case SNDRV_EMU10K1_IOCTL_INFO:
2239 info = kmalloc(sizeof(*info), GFP_KERNEL);
2242 if ((res = snd_emu10k1_fx8010_info(emu, info)) < 0) {
2246 if (copy_to_user(argp, info, sizeof(*info))) {
2252 case SNDRV_EMU10K1_IOCTL_CODE_POKE:
2253 if (!capable(CAP_SYS_ADMIN))
2255 icode = kmalloc(sizeof(*icode), GFP_KERNEL);
2258 if (copy_from_user(icode, argp, sizeof(*icode))) {
2262 res = snd_emu10k1_icode_poke(emu, icode);
2265 case SNDRV_EMU10K1_IOCTL_CODE_PEEK:
2266 icode = kmalloc(sizeof(*icode), GFP_KERNEL);
2269 if (copy_from_user(icode, argp, sizeof(*icode))) {
2273 res = snd_emu10k1_icode_peek(emu, icode);
2274 if (res == 0 && copy_to_user(argp, icode, sizeof(*icode))) {
2280 case SNDRV_EMU10K1_IOCTL_PCM_POKE:
2281 ipcm = kmalloc(sizeof(*ipcm), GFP_KERNEL);
2284 if (copy_from_user(ipcm, argp, sizeof(*ipcm))) {
2288 res = snd_emu10k1_ipcm_poke(emu, ipcm);
2291 case SNDRV_EMU10K1_IOCTL_PCM_PEEK:
2292 ipcm = kzalloc(sizeof(*ipcm), GFP_KERNEL);
2295 if (copy_from_user(ipcm, argp, sizeof(*ipcm))) {
2299 res = snd_emu10k1_ipcm_peek(emu, ipcm);
2300 if (res == 0 && copy_to_user(argp, ipcm, sizeof(*ipcm))) {
2306 case SNDRV_EMU10K1_IOCTL_TRAM_SETUP:
2307 if (!capable(CAP_SYS_ADMIN))
2309 if (get_user(addr, (unsigned int __user *)argp))
2311 down(&emu->fx8010.lock);
2312 res = snd_emu10k1_fx8010_tram_setup(emu, addr);
2313 up(&emu->fx8010.lock);
2315 case SNDRV_EMU10K1_IOCTL_STOP:
2316 if (!capable(CAP_SYS_ADMIN))
2319 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg |= A_DBG_SINGLE_STEP);
2321 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg |= EMU10K1_DBG_SINGLE_STEP);
2323 case SNDRV_EMU10K1_IOCTL_CONTINUE:
2324 if (!capable(CAP_SYS_ADMIN))
2327 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg = 0);
2329 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg = 0);
2331 case SNDRV_EMU10K1_IOCTL_ZERO_TRAM_COUNTER:
2332 if (!capable(CAP_SYS_ADMIN))
2335 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg | A_DBG_ZC);
2337 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg | EMU10K1_DBG_ZC);
2340 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg);
2342 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg);
2344 case SNDRV_EMU10K1_IOCTL_SINGLE_STEP:
2345 if (!capable(CAP_SYS_ADMIN))
2347 if (get_user(addr, (unsigned int __user *)argp))
2352 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg |= A_DBG_SINGLE_STEP | addr);
2354 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg |= EMU10K1_DBG_SINGLE_STEP | addr);
2357 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg |= A_DBG_SINGLE_STEP | A_DBG_STEP_ADDR | addr);
2359 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg |= EMU10K1_DBG_SINGLE_STEP | EMU10K1_DBG_STEP | addr);
2361 case SNDRV_EMU10K1_IOCTL_DBG_READ:
2363 addr = snd_emu10k1_ptr_read(emu, A_DBG, 0);
2365 addr = snd_emu10k1_ptr_read(emu, DBG, 0);
2366 if (put_user(addr, (unsigned int __user *)argp))
2373 static int snd_emu10k1_fx8010_release(struct snd_hwdep * hw, struct file *file)
2378 int __devinit snd_emu10k1_fx8010_new(struct snd_emu10k1 *emu, int device, struct snd_hwdep ** rhwdep)
2380 struct snd_hwdep *hw;
2385 if ((err = snd_hwdep_new(emu->card, "FX8010", device, &hw)) < 0)
2387 strcpy(hw->name, "EMU10K1 (FX8010)");
2388 hw->iface = SNDRV_HWDEP_IFACE_EMU10K1;
2389 hw->ops.open = snd_emu10k1_fx8010_open;
2390 hw->ops.ioctl = snd_emu10k1_fx8010_ioctl;
2391 hw->ops.release = snd_emu10k1_fx8010_release;
2392 hw->private_data = emu;
2399 int __devinit snd_emu10k1_efx_alloc_pm_buffer(struct snd_emu10k1 *emu)
2403 len = emu->audigy ? 0x200 : 0x100;
2404 emu->saved_gpr = kmalloc(len * 4, GFP_KERNEL);
2405 if (! emu->saved_gpr)
2407 len = emu->audigy ? 0x100 : 0xa0;
2408 emu->tram_val_saved = kmalloc(len * 4, GFP_KERNEL);
2409 emu->tram_addr_saved = kmalloc(len * 4, GFP_KERNEL);
2410 if (! emu->tram_val_saved || ! emu->tram_addr_saved)
2412 len = emu->audigy ? 2 * 1024 : 2 * 512;
2413 emu->saved_icode = vmalloc(len * 4);
2414 if (! emu->saved_icode)
2419 void snd_emu10k1_efx_free_pm_buffer(struct snd_emu10k1 *emu)
2421 kfree(emu->saved_gpr);
2422 kfree(emu->tram_val_saved);
2423 kfree(emu->tram_addr_saved);
2424 vfree(emu->saved_icode);
2428 * save/restore GPR, TRAM and codes
2430 void snd_emu10k1_efx_suspend(struct snd_emu10k1 *emu)
2434 len = emu->audigy ? 0x200 : 0x100;
2435 for (i = 0; i < len; i++)
2436 emu->saved_gpr[i] = snd_emu10k1_ptr_read(emu, emu->gpr_base + i, 0);
2438 len = emu->audigy ? 0x100 : 0xa0;
2439 for (i = 0; i < len; i++) {
2440 emu->tram_val_saved[i] = snd_emu10k1_ptr_read(emu, TANKMEMDATAREGBASE + i, 0);
2441 emu->tram_addr_saved[i] = snd_emu10k1_ptr_read(emu, TANKMEMADDRREGBASE + i, 0);
2443 emu->tram_addr_saved[i] >>= 12;
2444 emu->tram_addr_saved[i] |=
2445 snd_emu10k1_ptr_read(emu, A_TANKMEMCTLREGBASE + i, 0) << 20;
2449 len = emu->audigy ? 2 * 1024 : 2 * 512;
2450 for (i = 0; i < len; i++)
2451 emu->saved_icode[i] = snd_emu10k1_efx_read(emu, i);
2454 void snd_emu10k1_efx_resume(struct snd_emu10k1 *emu)
2459 if (emu->fx8010.etram_pages.bytes > 0) {
2460 unsigned size, size_reg = 0;
2461 size = emu->fx8010.etram_pages.bytes / 2;
2462 size = (size - 1) >> 13;
2467 outl(HCFG_LOCKTANKCACHE_MASK | inl(emu->port + HCFG), emu->port + HCFG);
2468 snd_emu10k1_ptr_write(emu, TCB, 0, emu->fx8010.etram_pages.addr);
2469 snd_emu10k1_ptr_write(emu, TCBS, 0, size_reg);
2470 outl(inl(emu->port + HCFG) & ~HCFG_LOCKTANKCACHE_MASK, emu->port + HCFG);
2474 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg | A_DBG_SINGLE_STEP);
2476 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg | EMU10K1_DBG_SINGLE_STEP);
2478 len = emu->audigy ? 0x200 : 0x100;
2479 for (i = 0; i < len; i++)
2480 snd_emu10k1_ptr_write(emu, emu->gpr_base + i, 0, emu->saved_gpr[i]);
2482 len = emu->audigy ? 0x100 : 0xa0;
2483 for (i = 0; i < len; i++) {
2484 snd_emu10k1_ptr_write(emu, TANKMEMDATAREGBASE + i, 0,
2485 emu->tram_val_saved[i]);
2487 snd_emu10k1_ptr_write(emu, TANKMEMADDRREGBASE + i, 0,
2488 emu->tram_addr_saved[i]);
2490 snd_emu10k1_ptr_write(emu, TANKMEMADDRREGBASE + i, 0,
2491 emu->tram_addr_saved[i] << 12);
2492 snd_emu10k1_ptr_write(emu, TANKMEMADDRREGBASE + i, 0,
2493 emu->tram_addr_saved[i] >> 20);
2497 len = emu->audigy ? 2 * 1024 : 2 * 512;
2498 for (i = 0; i < len; i++)
2499 snd_emu10k1_efx_write(emu, i, emu->saved_icode[i]);
2501 /* start FX processor when the DSP code is updated */
2503 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg);
2505 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg);