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 #define chip_t emu10k1_t
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",
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(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
316 snd_emu10k1_fx8010_ctl_t *ctl = (snd_emu10k1_fx8010_ctl_t *)kcontrol->private_value;
318 if (ctl->min == 0 && ctl->max == 1)
319 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
321 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
322 uinfo->count = ctl->vcount;
323 uinfo->value.integer.min = ctl->min;
324 uinfo->value.integer.max = ctl->max;
328 static int snd_emu10k1_gpr_ctl_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
330 emu10k1_t *emu = snd_kcontrol_chip(kcontrol);
331 snd_emu10k1_fx8010_ctl_t *ctl = (snd_emu10k1_fx8010_ctl_t *)kcontrol->private_value;
335 spin_lock_irqsave(&emu->reg_lock, flags);
336 for (i = 0; i < ctl->vcount; i++)
337 ucontrol->value.integer.value[i] = ctl->value[i];
338 spin_unlock_irqrestore(&emu->reg_lock, flags);
342 static int snd_emu10k1_gpr_ctl_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
344 emu10k1_t *emu = snd_kcontrol_chip(kcontrol);
345 snd_emu10k1_fx8010_ctl_t *ctl = (snd_emu10k1_fx8010_ctl_t *)kcontrol->private_value;
347 unsigned int nval, val;
351 spin_lock_irqsave(&emu->reg_lock, flags);
352 for (i = 0; i < ctl->vcount; i++) {
353 nval = ucontrol->value.integer.value[i];
358 if (nval != ctl->value[i])
360 val = ctl->value[i] = nval;
361 switch (ctl->translation) {
362 case EMU10K1_GPR_TRANSLATION_NONE:
363 snd_emu10k1_ptr_write(emu, emu->gpr_base + ctl->gpr[i], 0, val);
365 case EMU10K1_GPR_TRANSLATION_TABLE100:
366 snd_emu10k1_ptr_write(emu, emu->gpr_base + ctl->gpr[i], 0, db_table[val]);
368 case EMU10K1_GPR_TRANSLATION_BASS:
369 snd_runtime_check((ctl->count % 5) == 0 && (ctl->count / 5) == ctl->vcount, change = -EIO; goto __error);
370 for (j = 0; j < 5; j++)
371 snd_emu10k1_ptr_write(emu, emu->gpr_base + ctl->gpr[j * ctl->vcount + i], 0, bass_table[val][j]);
373 case EMU10K1_GPR_TRANSLATION_TREBLE:
374 snd_runtime_check((ctl->count % 5) == 0 && (ctl->count / 5) == ctl->vcount, change = -EIO; goto __error);
375 for (j = 0; j < 5; j++)
376 snd_emu10k1_ptr_write(emu, emu->gpr_base + ctl->gpr[j * ctl->vcount + i], 0, treble_table[val][j]);
378 case EMU10K1_GPR_TRANSLATION_ONOFF:
379 snd_emu10k1_ptr_write(emu, emu->gpr_base + ctl->gpr[i], 0, onoff_table[val]);
384 spin_unlock_irqrestore(&emu->reg_lock, flags);
392 static void snd_emu10k1_fx8010_interrupt(emu10k1_t *emu)
394 snd_emu10k1_fx8010_irq_t *irq, *nirq;
396 irq = emu->fx8010.irq_handlers;
398 nirq = irq->next; /* irq ptr can be removed from list */
399 if (snd_emu10k1_ptr_read(emu, emu->gpr_base + irq->gpr_running, 0) & 0xffff0000) {
401 irq->handler(emu, irq->private_data);
402 snd_emu10k1_ptr_write(emu, emu->gpr_base + irq->gpr_running, 0, 1);
408 static int snd_emu10k1_fx8010_register_irq_handler(emu10k1_t *emu,
409 snd_fx8010_irq_handler_t *handler,
410 unsigned char gpr_running,
412 snd_emu10k1_fx8010_irq_t **r_irq)
414 snd_emu10k1_fx8010_irq_t *irq;
417 snd_runtime_check(emu, return -EINVAL);
418 snd_runtime_check(handler, return -EINVAL);
419 irq = kmalloc(sizeof(*irq), GFP_ATOMIC);
422 irq->handler = handler;
423 irq->gpr_running = gpr_running;
424 irq->private_data = private_data;
426 spin_lock_irqsave(&emu->fx8010.irq_lock, flags);
427 if (emu->fx8010.irq_handlers == NULL) {
428 emu->fx8010.irq_handlers = irq;
429 emu->dsp_interrupt = snd_emu10k1_fx8010_interrupt;
430 snd_emu10k1_intr_enable(emu, INTE_FXDSPENABLE);
432 irq->next = emu->fx8010.irq_handlers;
433 emu->fx8010.irq_handlers = irq;
435 spin_unlock_irqrestore(&emu->fx8010.irq_lock, flags);
441 static int snd_emu10k1_fx8010_unregister_irq_handler(emu10k1_t *emu,
442 snd_emu10k1_fx8010_irq_t *irq)
444 snd_emu10k1_fx8010_irq_t *tmp;
447 snd_runtime_check(irq, return -EINVAL);
448 spin_lock_irqsave(&emu->fx8010.irq_lock, flags);
449 if ((tmp = emu->fx8010.irq_handlers) == irq) {
450 emu->fx8010.irq_handlers = tmp->next;
451 if (emu->fx8010.irq_handlers == NULL) {
452 snd_emu10k1_intr_disable(emu, INTE_FXDSPENABLE);
453 emu->dsp_interrupt = NULL;
456 while (tmp && tmp->next != irq)
459 tmp->next = tmp->next->next;
461 spin_unlock_irqrestore(&emu->fx8010.irq_lock, flags);
470 #define INITIAL_TRAM_SHIFT 14
471 #define INITIAL_TRAM_POS(size) ((((size) / 2) - INITIAL_TRAM_SHIFT) - 1)
473 static void snd_emu10k1_fx8010_playback_irq(emu10k1_t *emu, void *private_data)
475 snd_pcm_substream_t *substream = snd_magic_cast(snd_pcm_substream_t, private_data, return);
476 snd_pcm_period_elapsed(substream);
479 static void snd_emu10k1_fx8010_playback_tram_poke1(unsigned short *dst_left,
480 unsigned short *dst_right,
483 unsigned int tram_shift)
485 // printk("tram_poke1: dst_left = 0x%p, dst_right = 0x%p, src = 0x%p, count = 0x%x\n", dst_left, dst_right, src, count);
486 if ((tram_shift & 1) == 0) {
488 *dst_left-- = *src++;
489 *dst_right-- = *src++;
493 *dst_right-- = *src++;
494 *dst_left-- = *src++;
499 static void snd_emu10k1_fx8010_playback_tram_poke(emu10k1_t *emu,
500 unsigned int *tram_pos,
501 unsigned int *tram_shift,
502 unsigned int tram_size,
508 while (frames > *tram_pos) {
509 count = *tram_pos + 1;
510 snd_emu10k1_fx8010_playback_tram_poke1((unsigned short *)emu->fx8010.etram_pages.area + *tram_pos,
511 (unsigned short *)emu->fx8010.etram_pages.area + *tram_pos + tram_size / 2,
512 src, count, *tram_shift);
515 *tram_pos = (tram_size / 2) - 1;
518 snd_emu10k1_fx8010_playback_tram_poke1((unsigned short *)emu->fx8010.etram_pages.area + *tram_pos,
519 (unsigned short *)emu->fx8010.etram_pages.area + *tram_pos + tram_size / 2,
520 src, frames, *tram_shift++);
524 static int snd_emu10k1_fx8010_playback_transfer(snd_pcm_substream_t *substream)
526 emu10k1_t *emu = snd_pcm_substream_chip(substream);
527 snd_pcm_runtime_t *runtime = substream->runtime;
528 snd_emu10k1_fx8010_pcm_t *pcm = &emu->fx8010.pcm[substream->number];
529 snd_pcm_uframes_t appl_ptr = runtime->control->appl_ptr;
530 snd_pcm_sframes_t diff = appl_ptr - pcm->appl_ptr;
531 snd_pcm_uframes_t buffer_size = pcm->buffer_size / 2;
534 if (diff < -(snd_pcm_sframes_t) (runtime->boundary / 2))
535 diff += runtime->boundary;
536 pcm->sw_ready += diff;
537 pcm->appl_ptr = appl_ptr;
539 while (pcm->hw_ready < buffer_size &&
541 size_t hw_to_end = buffer_size - pcm->hw_data;
542 size_t sw_to_end = (runtime->buffer_size << 2) - pcm->sw_data;
543 size_t tframes = buffer_size - pcm->hw_ready;
544 if (pcm->sw_ready < tframes)
545 tframes = pcm->sw_ready;
546 if (hw_to_end < tframes)
548 if (sw_to_end < tframes)
550 snd_emu10k1_fx8010_playback_tram_poke(emu, &pcm->tram_pos, &pcm->tram_shift,
552 (unsigned short *)(runtime->dma_area + (pcm->sw_data << 2)),
554 pcm->hw_data += tframes;
555 if (pcm->hw_data == buffer_size)
557 pcm->sw_data += tframes;
558 if (pcm->sw_data == runtime->buffer_size)
560 pcm->hw_ready += tframes;
561 pcm->sw_ready -= tframes;
566 static int snd_emu10k1_fx8010_playback_hw_params(snd_pcm_substream_t * substream,
567 snd_pcm_hw_params_t * hw_params)
569 return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
572 static int snd_emu10k1_fx8010_playback_hw_free(snd_pcm_substream_t * substream)
574 emu10k1_t *emu = snd_pcm_substream_chip(substream);
575 snd_emu10k1_fx8010_pcm_t *pcm = &emu->fx8010.pcm[substream->number];
578 for (i = 0; i < pcm->channels; i++)
579 snd_emu10k1_ptr_write(emu, TANKMEMADDRREGBASE + 0x80 + pcm->etram[i], 0, 0);
580 snd_pcm_lib_free_pages(substream);
584 static int snd_emu10k1_fx8010_playback_prepare(snd_pcm_substream_t * substream)
586 emu10k1_t *emu = snd_pcm_substream_chip(substream);
587 snd_pcm_runtime_t *runtime = substream->runtime;
588 snd_emu10k1_fx8010_pcm_t *pcm = &emu->fx8010.pcm[substream->number];
591 // printk("prepare: etram_pages = 0x%p, dma_area = 0x%x, buffer_size = 0x%x (0x%x)\n", emu->fx8010.etram_pages, runtime->dma_area, runtime->buffer_size, runtime->buffer_size << 2);
592 pcm->sw_data = pcm->sw_io = pcm->sw_ready = 0;
593 pcm->hw_data = pcm->hw_io = pcm->hw_ready = 0;
594 pcm->tram_pos = INITIAL_TRAM_POS(pcm->buffer_size);
597 snd_emu10k1_ptr_write(emu, emu->gpr_base + pcm->gpr_running, 0, 0); /* reset */
598 snd_emu10k1_ptr_write(emu, emu->gpr_base + pcm->gpr_trigger, 0, 0); /* reset */
599 snd_emu10k1_ptr_write(emu, emu->gpr_base + pcm->gpr_size, 0, runtime->buffer_size);
600 snd_emu10k1_ptr_write(emu, emu->gpr_base + pcm->gpr_ptr, 0, 0); /* reset ptr number */
601 snd_emu10k1_ptr_write(emu, emu->gpr_base + pcm->gpr_count, 0, runtime->period_size);
602 snd_emu10k1_ptr_write(emu, emu->gpr_base + pcm->gpr_tmpcount, 0, runtime->period_size);
603 for (i = 0; i < pcm->channels; i++)
604 snd_emu10k1_ptr_write(emu, TANKMEMADDRREGBASE + 0x80 + pcm->etram[i], 0, (TANKMEMADDRREG_READ|TANKMEMADDRREG_ALIGN) + i * (runtime->buffer_size / pcm->channels));
608 static int snd_emu10k1_fx8010_playback_trigger(snd_pcm_substream_t * substream, int cmd)
610 emu10k1_t *emu = snd_pcm_substream_chip(substream);
611 snd_emu10k1_fx8010_pcm_t *pcm = &emu->fx8010.pcm[substream->number];
615 spin_lock_irqsave(&emu->reg_lock, flags);
617 case SNDRV_PCM_TRIGGER_START:
619 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
620 #ifdef EMU10K1_SET_AC3_IEC958
623 for (i = 0; i < 3; i++) {
625 bits = SPCS_CLKACCY_1000PPM | SPCS_SAMPLERATE_48 |
626 SPCS_CHANNELNUM_LEFT | SPCS_SOURCENUM_UNSPEC | SPCS_GENERATIONSTATUS |
627 0x00001200 | SPCS_EMPHASIS_NONE | SPCS_COPYRIGHT | SPCS_NOTAUDIODATA;
628 snd_emu10k1_ptr_write(emu, SPCS0 + i, 0, bits);
632 result = snd_emu10k1_fx8010_register_irq_handler(emu, snd_emu10k1_fx8010_playback_irq, pcm->gpr_running, substream, &pcm->irq);
635 snd_emu10k1_fx8010_playback_transfer(substream); /* roll the ball */
636 snd_emu10k1_ptr_write(emu, emu->gpr_base + pcm->gpr_trigger, 0, 1);
638 case SNDRV_PCM_TRIGGER_STOP:
639 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
640 snd_emu10k1_fx8010_unregister_irq_handler(emu, pcm->irq); pcm->irq = NULL;
641 snd_emu10k1_ptr_write(emu, emu->gpr_base + pcm->gpr_trigger, 0, 0);
642 pcm->tram_pos = INITIAL_TRAM_POS(pcm->buffer_size);
650 spin_unlock_irqrestore(&emu->reg_lock, flags);
654 static snd_pcm_uframes_t snd_emu10k1_fx8010_playback_pointer(snd_pcm_substream_t * substream)
656 emu10k1_t *emu = snd_pcm_substream_chip(substream);
657 snd_pcm_runtime_t *runtime = substream->runtime;
658 snd_emu10k1_fx8010_pcm_t *pcm = &emu->fx8010.pcm[substream->number];
660 snd_pcm_sframes_t frames;
662 if (!snd_emu10k1_ptr_read(emu, emu->gpr_base + pcm->gpr_trigger, 0))
664 ptr = snd_emu10k1_ptr_read(emu, emu->gpr_base + pcm->gpr_ptr, 0);
665 frames = ptr - pcm->hw_io;
667 frames += runtime->buffer_size;
669 pcm->hw_ready -= frames;
670 pcm->sw_io += frames;
671 if (pcm->sw_io >= runtime->buffer_size)
672 pcm->sw_io -= runtime->buffer_size;
673 snd_emu10k1_fx8010_playback_transfer(substream);
677 static snd_pcm_hardware_t snd_emu10k1_fx8010_playback =
679 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
680 /* SNDRV_PCM_INFO_MMAP_VALID | */ SNDRV_PCM_INFO_PAUSE),
681 .formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE,
682 .rates = SNDRV_PCM_RATE_48000,
687 .buffer_bytes_max = (128*1024),
688 .period_bytes_min = 1024,
689 .period_bytes_max = (128*1024),
695 static int snd_emu10k1_fx8010_playback_open(snd_pcm_substream_t * substream)
697 emu10k1_t *emu = snd_pcm_substream_chip(substream);
698 snd_pcm_runtime_t *runtime = substream->runtime;
699 snd_emu10k1_fx8010_pcm_t *pcm = &emu->fx8010.pcm[substream->number];
701 runtime->hw = snd_emu10k1_fx8010_playback;
702 runtime->hw.channels_min = runtime->hw.channels_max = pcm->channels;
703 runtime->hw.period_bytes_max = (pcm->buffer_size * 2) / 2;
704 spin_lock(&emu->reg_lock);
705 if (pcm->valid == 0) {
706 spin_unlock(&emu->reg_lock);
710 spin_unlock(&emu->reg_lock);
714 static int snd_emu10k1_fx8010_playback_close(snd_pcm_substream_t * substream)
716 emu10k1_t *emu = snd_pcm_substream_chip(substream);
717 snd_emu10k1_fx8010_pcm_t *pcm = &emu->fx8010.pcm[substream->number];
719 spin_lock(&emu->reg_lock);
721 spin_unlock(&emu->reg_lock);
725 static snd_pcm_ops_t snd_emu10k1_fx8010_playback_ops = {
726 .open = snd_emu10k1_fx8010_playback_open,
727 .close = snd_emu10k1_fx8010_playback_close,
728 .ioctl = snd_pcm_lib_ioctl,
729 .hw_params = snd_emu10k1_fx8010_playback_hw_params,
730 .hw_free = snd_emu10k1_fx8010_playback_hw_free,
731 .prepare = snd_emu10k1_fx8010_playback_prepare,
732 .trigger = snd_emu10k1_fx8010_playback_trigger,
733 .pointer = snd_emu10k1_fx8010_playback_pointer,
734 .ack = snd_emu10k1_fx8010_playback_transfer,
737 static void snd_emu10k1_fx8010_pcm_free(snd_pcm_t *pcm)
739 emu10k1_t *emu = snd_magic_cast(emu10k1_t, pcm->private_data, return);
740 emu->pcm_fx8010 = NULL;
741 snd_pcm_lib_preallocate_free_for_all(pcm);
744 int snd_emu10k1_fx8010_pcm(emu10k1_t * emu, int device, snd_pcm_t ** rpcm)
752 if ((err = snd_pcm_new(emu->card, "emu10k1", device, 8, 0, &pcm)) < 0)
755 pcm->private_data = emu;
756 pcm->private_free = snd_emu10k1_fx8010_pcm_free;
758 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_emu10k1_fx8010_playback_ops);
761 strcpy(pcm->name, "EMU10K1 FX8010");
762 emu->pcm_fx8010 = pcm;
764 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(emu->pci), 64*1024, 0);
772 /*************************************************************************
773 * EMU10K1 effect manager
774 *************************************************************************/
776 static void snd_emu10k1_write_op(emu10k1_fx8010_code_t *icode, unsigned int *ptr,
777 u32 op, u32 r, u32 a, u32 x, u32 y)
779 snd_assert(*ptr < 512, return);
780 set_bit(*ptr, icode->code_valid);
781 icode->code[*ptr ][0] = ((x & 0x3ff) << 10) | (y & 0x3ff);
782 icode->code[(*ptr)++][1] = ((op & 0x0f) << 20) | ((r & 0x3ff) << 10) | (a & 0x3ff);
785 #define OP(icode, ptr, op, r, a, x, y) \
786 snd_emu10k1_write_op(icode, ptr, op, r, a, x, y)
788 static void snd_emu10k1_audigy_write_op(emu10k1_fx8010_code_t *icode, unsigned int *ptr,
789 u32 op, u32 r, u32 a, u32 x, u32 y)
791 snd_assert(*ptr < 512, return);
792 set_bit(*ptr, icode->code_valid);
793 icode->code[*ptr ][0] = ((x & 0x7ff) << 12) | (y & 0x7ff);
794 icode->code[(*ptr)++][1] = ((op & 0x0f) << 24) | ((r & 0x7ff) << 12) | (a & 0x7ff);
797 #define A_OP(icode, ptr, op, r, a, x, y) \
798 snd_emu10k1_audigy_write_op(icode, ptr, op, r, a, x, y)
800 void snd_emu10k1_efx_write(emu10k1_t *emu, unsigned int pc, unsigned int data)
802 pc += emu->audigy ? A_MICROCODEBASE : MICROCODEBASE;
803 snd_emu10k1_ptr_write(emu, pc, 0, data);
806 unsigned int snd_emu10k1_efx_read(emu10k1_t *emu, unsigned int pc)
808 pc += emu->audigy ? A_MICROCODEBASE : MICROCODEBASE;
809 return snd_emu10k1_ptr_read(emu, pc, 0);
812 static void snd_emu10k1_gpr_poke(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
816 for (gpr = 0; gpr < 0x100; gpr++) {
817 if (!test_bit(gpr, icode->gpr_valid))
819 snd_emu10k1_ptr_write(emu, emu->gpr_base + gpr, 0, icode->gpr_map[gpr]);
823 static void snd_emu10k1_gpr_peek(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
827 for (gpr = 0; gpr < 0x100; gpr++) {
828 set_bit(gpr, icode->gpr_valid);
829 icode->gpr_map[gpr] = snd_emu10k1_ptr_read(emu, emu->gpr_base + gpr, 0);
833 static void snd_emu10k1_tram_poke(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
837 for (tram = 0; tram < 0xa0; tram++) {
838 if (!test_bit(tram, icode->tram_valid))
840 snd_emu10k1_ptr_write(emu, TANKMEMDATAREGBASE + tram, 0, icode->tram_data_map[tram]);
841 snd_emu10k1_ptr_write(emu, TANKMEMADDRREGBASE + tram, 0, icode->tram_addr_map[tram]);
845 static void snd_emu10k1_tram_peek(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
849 memset(icode->tram_valid, 0, sizeof(icode->tram_valid));
850 for (tram = 0; tram < 0xa0; tram++) {
851 set_bit(tram, icode->tram_valid);
852 icode->tram_data_map[tram] = snd_emu10k1_ptr_read(emu, TANKMEMDATAREGBASE + tram, 0);
853 icode->tram_addr_map[tram] = snd_emu10k1_ptr_read(emu, TANKMEMADDRREGBASE + tram, 0);
857 static void snd_emu10k1_code_poke(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
861 for (pc = 0; pc < 512; pc++) {
862 if (!test_bit(pc, icode->code_valid))
864 snd_emu10k1_efx_write(emu, pc * 2, icode->code[pc][0]);
865 snd_emu10k1_efx_write(emu, pc * 2 + 1, icode->code[pc][1]);
869 static void snd_emu10k1_code_peek(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
873 memset(icode->code_valid, 0, sizeof(icode->code_valid));
874 for (pc = 0; pc < 512; pc++) {
875 set_bit(pc, icode->code_valid);
876 icode->code[pc][0] = snd_emu10k1_efx_read(emu, pc * 2);
877 icode->code[pc][1] = snd_emu10k1_efx_read(emu, pc * 2 + 1);
881 static snd_emu10k1_fx8010_ctl_t *snd_emu10k1_look_for_ctl(emu10k1_t *emu, snd_ctl_elem_id_t *id)
883 snd_emu10k1_fx8010_ctl_t *ctl;
884 snd_kcontrol_t *kcontrol;
885 struct list_head *list;
887 list_for_each(list, &emu->fx8010.gpr_ctl) {
888 ctl = emu10k1_gpr_ctl(list);
889 kcontrol = ctl->kcontrol;
890 if (kcontrol->id.iface == id->iface &&
891 !strcmp(kcontrol->id.name, id->name) &&
892 kcontrol->id.index == id->index)
898 static int snd_emu10k1_verify_controls(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
901 snd_ctl_elem_id_t *_id, id;
902 emu10k1_fx8010_control_gpr_t *_gctl, gctl;
904 for (i = 0, _id = icode->gpr_del_controls;
905 i < icode->gpr_del_control_count; i++, _id++) {
906 if (copy_from_user(&id, _id, sizeof(id)))
908 if (snd_emu10k1_look_for_ctl(emu, &id) == NULL)
911 for (i = 0, _gctl = icode->gpr_add_controls;
912 i < icode->gpr_add_control_count; i++, _gctl++) {
913 if (copy_from_user(&gctl, _gctl, sizeof(gctl)))
915 if (snd_emu10k1_look_for_ctl(emu, &gctl.id))
917 down_read(&emu->card->controls_rwsem);
918 if (snd_ctl_find_id(emu->card, &gctl.id) != NULL) {
919 up_read(&emu->card->controls_rwsem);
922 up_read(&emu->card->controls_rwsem);
923 if (gctl.id.iface != SNDRV_CTL_ELEM_IFACE_MIXER &&
924 gctl.id.iface != SNDRV_CTL_ELEM_IFACE_PCM)
927 for (i = 0, _gctl = icode->gpr_list_controls;
928 i < icode->gpr_list_control_count; i++, _gctl++) {
929 /* FIXME: we need to check the WRITE access */
930 if (copy_from_user(&gctl, _gctl, sizeof(gctl)))
936 static void snd_emu10k1_ctl_private_free(snd_kcontrol_t *kctl)
938 snd_emu10k1_fx8010_ctl_t *ctl;
940 ctl = (snd_emu10k1_fx8010_ctl_t *)kctl->private_value;
941 kctl->private_value = 0;
942 list_del(&ctl->list);
946 static void snd_emu10k1_add_controls(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
949 emu10k1_fx8010_control_gpr_t *_gctl, gctl;
950 snd_emu10k1_fx8010_ctl_t *ctl, nctl;
951 snd_kcontrol_new_t knew;
952 snd_kcontrol_t *kctl;
953 snd_ctl_elem_value_t *val;
955 val = (snd_ctl_elem_value_t *)kmalloc(sizeof(*val), GFP_KERNEL);
958 for (i = 0, _gctl = icode->gpr_add_controls;
959 i < icode->gpr_add_control_count; i++, _gctl++) {
960 if (copy_from_user(&gctl, _gctl, sizeof(gctl)))
962 snd_runtime_check(gctl.id.iface == SNDRV_CTL_ELEM_IFACE_MIXER ||
963 gctl.id.iface == SNDRV_CTL_ELEM_IFACE_PCM, continue);
964 snd_runtime_check(gctl.id.name[0] != '\0', continue);
965 ctl = snd_emu10k1_look_for_ctl(emu, &gctl.id);
966 memset(&knew, 0, sizeof(knew));
967 knew.iface = gctl.id.iface;
968 knew.name = gctl.id.name;
969 knew.index = gctl.id.index;
970 knew.device = gctl.id.device;
971 knew.subdevice = gctl.id.subdevice;
972 knew.info = snd_emu10k1_gpr_ctl_info;
973 knew.get = snd_emu10k1_gpr_ctl_get;
974 knew.put = snd_emu10k1_gpr_ctl_put;
975 memset(&nctl, 0, sizeof(nctl));
976 nctl.vcount = gctl.vcount;
977 nctl.count = gctl.count;
978 for (j = 0; j < 32; j++) {
979 nctl.gpr[j] = gctl.gpr[j];
980 nctl.value[j] = ~gctl.value[j]; /* inverted, we want to write new value in gpr_ctl_put() */
981 val->value.integer.value[j] = gctl.value[j];
985 nctl.translation = gctl.translation;
987 ctl = (snd_emu10k1_fx8010_ctl_t *)kmalloc(sizeof(*ctl), GFP_KERNEL);
990 knew.private_value = (unsigned long)ctl;
991 memcpy(ctl, &nctl, sizeof(nctl));
992 if (snd_ctl_add(emu->card, kctl = snd_ctl_new1(&knew, emu)) < 0) {
996 kctl->private_free = snd_emu10k1_ctl_private_free;
997 ctl->kcontrol = kctl;
998 list_add_tail(&ctl->list, &emu->fx8010.gpr_ctl);
1001 nctl.list = ctl->list;
1002 nctl.kcontrol = ctl->kcontrol;
1003 memcpy(ctl, &nctl, sizeof(nctl));
1004 snd_ctl_notify(emu->card, SNDRV_CTL_EVENT_MASK_VALUE |
1005 SNDRV_CTL_EVENT_MASK_INFO, &ctl->kcontrol->id);
1007 snd_emu10k1_gpr_ctl_put(ctl->kcontrol, val);
1012 static void snd_emu10k1_del_controls(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
1015 snd_ctl_elem_id_t *_id, id;
1016 snd_emu10k1_fx8010_ctl_t *ctl;
1017 snd_card_t *card = emu->card;
1019 for (i = 0, _id = icode->gpr_del_controls;
1020 i < icode->gpr_del_control_count; i++, _id++) {
1021 snd_runtime_check(copy_from_user(&id, _id, sizeof(id)) == 0, continue);
1022 down_write(&card->controls_rwsem);
1023 ctl = snd_emu10k1_look_for_ctl(emu, &id);
1025 snd_ctl_remove(card, ctl->kcontrol);
1026 up_write(&card->controls_rwsem);
1030 static int snd_emu10k1_list_controls(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
1032 unsigned int i = 0, j;
1033 unsigned int total = 0;
1034 emu10k1_fx8010_control_gpr_t *_gctl, gctl;
1035 snd_emu10k1_fx8010_ctl_t *ctl;
1036 snd_ctl_elem_id_t *id;
1037 struct list_head *list;
1039 _gctl = icode->gpr_list_controls;
1040 list_for_each(list, &emu->fx8010.gpr_ctl) {
1041 ctl = emu10k1_gpr_ctl(list);
1043 if (_gctl && i < icode->gpr_list_control_count) {
1044 memset(&gctl, 0, sizeof(gctl));
1045 id = &ctl->kcontrol->id;
1046 gctl.id.iface = id->iface;
1047 strlcpy(gctl.id.name, id->name, sizeof(gctl.id.name));
1048 gctl.id.index = id->index;
1049 gctl.id.device = id->device;
1050 gctl.id.subdevice = id->subdevice;
1051 gctl.vcount = ctl->vcount;
1052 gctl.count = ctl->count;
1053 for (j = 0; j < 32; j++) {
1054 gctl.gpr[j] = ctl->gpr[j];
1055 gctl.value[j] = ctl->value[j];
1057 gctl.min = ctl->min;
1058 gctl.max = ctl->max;
1059 gctl.translation = ctl->translation;
1060 if (copy_to_user(_gctl, &gctl, sizeof(gctl)))
1066 icode->gpr_list_control_total = total;
1070 static int snd_emu10k1_icode_poke(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
1074 down(&emu->fx8010.lock);
1075 if ((err = snd_emu10k1_verify_controls(emu, icode)) < 0)
1077 strlcpy(emu->fx8010.name, icode->name, sizeof(emu->fx8010.name));
1078 /* stop FX processor - this may be dangerous, but it's better to miss
1079 some samples than generate wrong ones - [jk] */
1081 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg | A_DBG_SINGLE_STEP);
1083 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg | EMU10K1_DBG_SINGLE_STEP);
1084 /* ok, do the main job */
1085 snd_emu10k1_del_controls(emu, icode);
1086 snd_emu10k1_gpr_poke(emu, icode);
1087 snd_emu10k1_tram_poke(emu, icode);
1088 snd_emu10k1_code_poke(emu, icode);
1089 snd_emu10k1_add_controls(emu, icode);
1090 /* start FX processor when the DSP code is updated */
1092 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg);
1094 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg);
1096 up(&emu->fx8010.lock);
1100 static int snd_emu10k1_icode_peek(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
1104 down(&emu->fx8010.lock);
1105 strlcpy(icode->name, emu->fx8010.name, sizeof(icode->name));
1106 /* ok, do the main job */
1107 snd_emu10k1_gpr_peek(emu, icode);
1108 snd_emu10k1_tram_peek(emu, icode);
1109 snd_emu10k1_code_peek(emu, icode);
1110 err = snd_emu10k1_list_controls(emu, icode);
1111 up(&emu->fx8010.lock);
1115 static int snd_emu10k1_ipcm_poke(emu10k1_t *emu, emu10k1_fx8010_pcm_t *ipcm)
1119 snd_emu10k1_fx8010_pcm_t *pcm;
1121 if (ipcm->substream >= EMU10K1_FX8010_PCM_COUNT)
1123 if (ipcm->channels > 32)
1125 pcm = &emu->fx8010.pcm[ipcm->substream];
1126 down(&emu->fx8010.lock);
1127 spin_lock_irq(&emu->reg_lock);
1132 if (ipcm->channels == 0) { /* remove */
1135 /* FIXME: we need to add universal code to the PCM transfer routine */
1136 if (ipcm->channels != 2) {
1142 pcm->channels = ipcm->channels;
1143 pcm->tram_start = ipcm->tram_start;
1144 pcm->buffer_size = ipcm->buffer_size;
1145 pcm->gpr_size = ipcm->gpr_size;
1146 pcm->gpr_count = ipcm->gpr_count;
1147 pcm->gpr_tmpcount = ipcm->gpr_tmpcount;
1148 pcm->gpr_ptr = ipcm->gpr_ptr;
1149 pcm->gpr_trigger = ipcm->gpr_trigger;
1150 pcm->gpr_running = ipcm->gpr_running;
1151 for (i = 0; i < pcm->channels; i++)
1152 pcm->etram[i] = ipcm->etram[i];
1155 spin_unlock_irq(&emu->reg_lock);
1156 up(&emu->fx8010.lock);
1160 static int snd_emu10k1_ipcm_peek(emu10k1_t *emu, emu10k1_fx8010_pcm_t *ipcm)
1164 snd_emu10k1_fx8010_pcm_t *pcm;
1166 if (ipcm->substream >= EMU10K1_FX8010_PCM_COUNT)
1168 pcm = &emu->fx8010.pcm[ipcm->substream];
1169 down(&emu->fx8010.lock);
1170 spin_lock_irq(&emu->reg_lock);
1171 ipcm->channels = pcm->channels;
1172 ipcm->tram_start = pcm->tram_start;
1173 ipcm->buffer_size = pcm->buffer_size;
1174 ipcm->gpr_size = pcm->gpr_size;
1175 ipcm->gpr_ptr = pcm->gpr_ptr;
1176 ipcm->gpr_count = pcm->gpr_count;
1177 ipcm->gpr_tmpcount = pcm->gpr_tmpcount;
1178 ipcm->gpr_trigger = pcm->gpr_trigger;
1179 ipcm->gpr_running = pcm->gpr_running;
1180 for (i = 0; i < pcm->channels; i++)
1181 ipcm->etram[i] = pcm->etram[i];
1182 ipcm->res1 = ipcm->res2 = 0;
1184 spin_unlock_irq(&emu->reg_lock);
1185 up(&emu->fx8010.lock);
1189 #define SND_EMU10K1_GPR_CONTROLS 41
1190 #define SND_EMU10K1_INPUTS 10
1191 #define SND_EMU10K1_PLAYBACK_CHANNELS 6
1192 #define SND_EMU10K1_CAPTURE_CHANNELS 4
1194 static void __devinit snd_emu10k1_init_mono_control(emu10k1_fx8010_control_gpr_t *ctl, const char *name, int gpr, int defval)
1196 ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1197 strcpy(ctl->id.name, name);
1198 ctl->vcount = ctl->count = 1;
1199 ctl->gpr[0] = gpr + 0; ctl->value[0] = defval;
1202 ctl->translation = EMU10K1_GPR_TRANSLATION_TABLE100;
1205 static void __devinit snd_emu10k1_init_stereo_control(emu10k1_fx8010_control_gpr_t *ctl, const char *name, int gpr, int defval)
1207 ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1208 strcpy(ctl->id.name, name);
1209 ctl->vcount = ctl->count = 2;
1210 ctl->gpr[0] = gpr + 0; ctl->value[0] = defval;
1211 ctl->gpr[1] = gpr + 1; ctl->value[1] = defval;
1214 ctl->translation = EMU10K1_GPR_TRANSLATION_TABLE100;
1217 static void __devinit snd_emu10k1_init_mono_onoff_control(emu10k1_fx8010_control_gpr_t *ctl, const char *name, int gpr, int defval)
1219 ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1220 strcpy(ctl->id.name, name);
1221 ctl->vcount = ctl->count = 1;
1222 ctl->gpr[0] = gpr + 0; ctl->value[0] = defval;
1225 ctl->translation = EMU10K1_GPR_TRANSLATION_ONOFF;
1228 static void __devinit snd_emu10k1_init_stereo_onoff_control(emu10k1_fx8010_control_gpr_t *ctl, const char *name, int gpr, int defval)
1230 ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1231 strcpy(ctl->id.name, name);
1232 ctl->vcount = ctl->count = 2;
1233 ctl->gpr[0] = gpr + 0; ctl->value[0] = defval;
1234 ctl->gpr[1] = gpr + 1; ctl->value[1] = defval;
1237 ctl->translation = EMU10K1_GPR_TRANSLATION_ONOFF;
1242 * initial DSP configuration for Audigy
1245 static int __devinit _snd_emu10k1_audigy_init_efx(emu10k1_t *emu)
1247 int err, i, z, gpr, nctl;
1248 const int playback = 10;
1249 const int capture = playback + (SND_EMU10K1_PLAYBACK_CHANNELS * 2); /* we reserve 10 voices */
1250 const int stereo_mix = capture + 2;
1251 const int tmp = 0x88;
1253 emu10k1_fx8010_code_t *icode;
1254 emu10k1_fx8010_control_gpr_t *controls, *ctl;
1257 spin_lock_init(&emu->fx8010.irq_lock);
1258 INIT_LIST_HEAD(&emu->fx8010.gpr_ctl);
1260 if ((icode = snd_kcalloc(sizeof(emu10k1_fx8010_code_t), GFP_KERNEL)) == NULL)
1262 if ((controls = snd_kcalloc(sizeof(emu10k1_fx8010_control_gpr_t) * SND_EMU10K1_GPR_CONTROLS, GFP_KERNEL)) == NULL) {
1267 /* clear free GPRs */
1268 for (i = 0; i < 256; i++)
1269 set_bit(i, icode->gpr_valid);
1271 strcpy(icode->name, "Audigy DSP code for ALSA");
1274 gpr = stereo_mix + 10;
1276 /* stop FX processor */
1277 snd_emu10k1_ptr_write(emu, A_DBG, 0, (emu->fx8010.dbg = 0) | A_DBG_SINGLE_STEP);
1279 /* PCM front Playback Volume (independent from stereo mix) */
1280 A_OP(icode, &ptr, iMAC0, A_GPR(playback), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LEFT_FRONT));
1281 A_OP(icode, &ptr, iMAC0, A_GPR(playback+1), A_C_00000000, A_GPR(gpr+1), A_FXBUS(FXBUS_PCM_RIGHT_FRONT));
1282 snd_emu10k1_init_stereo_control(&controls[nctl++], "PCM Front Playback Volume", gpr, 100);
1285 /* PCM Surround Playback (independent from stereo mix) */
1286 A_OP(icode, &ptr, iMAC0, A_GPR(playback+2), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LEFT_REAR));
1287 A_OP(icode, &ptr, iMAC0, A_GPR(playback+3), A_C_00000000, A_GPR(gpr+1), A_FXBUS(FXBUS_PCM_RIGHT_REAR));
1288 snd_emu10k1_init_stereo_control(&controls[nctl++], "PCM Surround Playback Volume", gpr, 100);
1291 /* PCM Center Playback (independent from stereo mix) */
1292 A_OP(icode, &ptr, iMAC0, A_GPR(playback+4), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_CENTER));
1293 snd_emu10k1_init_mono_control(&controls[nctl++], "PCM Center Playback Volume", gpr, 100);
1296 /* PCM LFE Playback (independent from stereo mix) */
1297 A_OP(icode, &ptr, iMAC0, A_GPR(playback+5), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LFE));
1298 snd_emu10k1_init_mono_control(&controls[nctl++], "PCM LFE Playback Volume", gpr, 100);
1304 /* Wave (PCM) Playback Volume (will be renamed later) */
1305 A_OP(icode, &ptr, iMAC0, A_GPR(stereo_mix), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LEFT));
1306 A_OP(icode, &ptr, iMAC0, A_GPR(stereo_mix+1), A_C_00000000, A_GPR(gpr+1), A_FXBUS(FXBUS_PCM_RIGHT));
1307 snd_emu10k1_init_stereo_control(&controls[nctl++], "Wave Playback Volume", gpr, 100);
1310 /* Music Playback */
1311 A_OP(icode, &ptr, iMAC0, A_GPR(stereo_mix+0), A_GPR(stereo_mix+0), A_GPR(gpr), A_FXBUS(FXBUS_MIDI_LEFT));
1312 A_OP(icode, &ptr, iMAC0, A_GPR(stereo_mix+1), A_GPR(stereo_mix+1), A_GPR(gpr+1), A_FXBUS(FXBUS_MIDI_RIGHT));
1313 snd_emu10k1_init_stereo_control(&controls[nctl++], "Music Playback Volume", gpr, 100);
1316 /* Wave (PCM) Capture */
1317 A_OP(icode, &ptr, iMAC0, A_GPR(capture+0), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LEFT));
1318 A_OP(icode, &ptr, iMAC0, A_GPR(capture+1), A_C_00000000, A_GPR(gpr+1), A_FXBUS(FXBUS_PCM_RIGHT));
1319 snd_emu10k1_init_stereo_control(&controls[nctl++], "PCM Capture Volume", gpr, 0);
1323 A_OP(icode, &ptr, iMAC0, A_GPR(capture+0), A_GPR(capture+0), A_GPR(gpr), A_FXBUS(FXBUS_MIDI_LEFT));
1324 A_OP(icode, &ptr, iMAC0, A_GPR(capture+1), A_GPR(capture+1), A_GPR(gpr+1), A_FXBUS(FXBUS_MIDI_RIGHT));
1325 snd_emu10k1_init_stereo_control(&controls[nctl++], "Music Capture Volume", gpr, 0);
1331 #define A_ADD_VOLUME_IN(var,vol,input) \
1332 A_OP(icode, &ptr, iMAC0, A_GPR(var), A_GPR(var), A_GPR(vol), A_EXTIN(input))
1334 /* AC'97 Playback Volume - used only for mic (renamed later) */
1335 A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_AC97_L);
1336 A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_AC97_R);
1337 snd_emu10k1_init_stereo_control(&controls[nctl++], "AMic Playback Volume", gpr, 0);
1339 /* AC'97 Capture Volume - used only for mic */
1340 A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_AC97_L);
1341 A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_AC97_R);
1342 snd_emu10k1_init_stereo_control(&controls[nctl++], "Mic Capture Volume", gpr, 0);
1345 /* mic capture buffer */
1346 A_OP(icode, &ptr, iINTERP, A_EXTOUT(A_EXTOUT_MIC_CAP), A_EXTIN(A_EXTIN_AC97_L), 0xcd, A_EXTIN(A_EXTIN_AC97_R));
1348 /* Audigy CD Playback Volume */
1349 A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_SPDIF_CD_L);
1350 A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_SPDIF_CD_R);
1351 snd_emu10k1_init_stereo_control(&controls[nctl++],
1352 emu->no_ac97 ? "CD Playback Volume" : "Audigy CD Playback Volume",
1355 /* Audigy CD Capture Volume */
1356 A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_SPDIF_CD_L);
1357 A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_SPDIF_CD_R);
1358 snd_emu10k1_init_stereo_control(&controls[nctl++],
1359 emu->no_ac97 ? "CD Capture Volume" : "Audigy CD Capture Volume",
1363 /* Optical SPDIF Playback Volume */
1364 A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_OPT_SPDIF_L);
1365 A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_OPT_SPDIF_R);
1366 snd_emu10k1_init_stereo_control(&controls[nctl++], "IEC958 Optical Playback Volume", gpr, 0);
1368 /* Optical SPDIF Capture Volume */
1369 A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_OPT_SPDIF_L);
1370 A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_OPT_SPDIF_R);
1371 snd_emu10k1_init_stereo_control(&controls[nctl++], "IEC958 Optical Capture Volume", gpr, 0);
1374 /* Line2 Playback Volume */
1375 A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_LINE2_L);
1376 A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_LINE2_R);
1377 snd_emu10k1_init_stereo_control(&controls[nctl++],
1378 emu->no_ac97 ? "Line Playback Volume" : "Line2 Playback Volume",
1381 /* Line2 Capture Volume */
1382 A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_LINE2_L);
1383 A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_LINE2_R);
1384 snd_emu10k1_init_stereo_control(&controls[nctl++],
1385 emu->no_ac97 ? "Line Capture Volume" : "Line2 Capture Volume",
1389 /* Philips ADC Playback Volume */
1390 A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_ADC_L);
1391 A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_ADC_R);
1392 snd_emu10k1_init_stereo_control(&controls[nctl++], "Analog Mix Playback Volume", gpr, 0);
1394 /* Philips ADC Capture Volume */
1395 A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_ADC_L);
1396 A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_ADC_R);
1397 snd_emu10k1_init_stereo_control(&controls[nctl++], "Analog Mix Capture Volume", gpr, 0);
1400 /* Aux2 Playback Volume */
1401 A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_AUX2_L);
1402 A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_AUX2_R);
1403 snd_emu10k1_init_stereo_control(&controls[nctl++],
1404 emu->no_ac97 ? "Aux Playback Volume" : "Aux2 Playback Volume",
1407 /* Aux2 Capture Volume */
1408 A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_AUX2_L);
1409 A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_AUX2_R);
1410 snd_emu10k1_init_stereo_control(&controls[nctl++],
1411 emu->no_ac97 ? "Aux Capture Volume" : "Aux2 Capture Volume",
1415 /* Stereo Mix Front Playback Volume */
1416 A_OP(icode, &ptr, iMAC0, A_GPR(playback), A_GPR(playback), A_GPR(gpr), A_GPR(stereo_mix));
1417 A_OP(icode, &ptr, iMAC0, A_GPR(playback+1), A_GPR(playback+1), A_GPR(gpr+1), A_GPR(stereo_mix+1));
1418 snd_emu10k1_init_stereo_control(&controls[nctl++], "Front Playback Volume", gpr, 100);
1421 /* Stereo Mix Surround Playback */
1422 A_OP(icode, &ptr, iMAC0, A_GPR(playback+2), A_GPR(playback+2), A_GPR(gpr), A_GPR(stereo_mix));
1423 A_OP(icode, &ptr, iMAC0, A_GPR(playback+3), A_GPR(playback+3), A_GPR(gpr+1), A_GPR(stereo_mix+1));
1424 snd_emu10k1_init_stereo_control(&controls[nctl++], "Surround Playback Volume", gpr, 0);
1427 /* Stereo Mix Center Playback */
1428 /* Center = sub = Left/2 + Right/2 */
1429 A_OP(icode, &ptr, iINTERP, A_GPR(tmp), A_GPR(stereo_mix), 0xcd, A_GPR(stereo_mix+1));
1430 A_OP(icode, &ptr, iMAC0, A_GPR(playback+4), A_GPR(playback+4), A_GPR(gpr), A_GPR(tmp));
1431 snd_emu10k1_init_mono_control(&controls[nctl++], "Center Playback Volume", gpr, 0);
1434 /* Stereo Mix LFE Playback */
1435 A_OP(icode, &ptr, iMAC0, A_GPR(playback+5), A_GPR(playback+5), A_GPR(gpr), A_GPR(tmp));
1436 snd_emu10k1_init_mono_control(&controls[nctl++], "LFE Playback Volume", gpr, 0);
1442 #define A_PUT_OUTPUT(out,src) A_OP(icode, &ptr, iACC3, A_EXTOUT(out), A_C_00000000, A_C_00000000, A_GPR(src))
1443 #define A_PUT_STEREO_OUTPUT(out1,out2,src) \
1444 {A_PUT_OUTPUT(out1,src); A_PUT_OUTPUT(out2,src+1);}
1446 #define _A_SWITCH(icode, ptr, dst, src, sw) \
1447 A_OP((icode), ptr, iMACINT0, dst, A_C_00000000, src, sw);
1448 #define A_SWITCH(icode, ptr, dst, src, sw) \
1449 _A_SWITCH(icode, ptr, A_GPR(dst), A_GPR(src), A_GPR(sw))
1450 #define _A_SWITCH_NEG(icode, ptr, dst, src) \
1451 A_OP((icode), ptr, iANDXOR, dst, src, A_C_00000001, A_C_00000001);
1452 #define A_SWITCH_NEG(icode, ptr, dst, src) \
1453 _A_SWITCH_NEG(icode, ptr, A_GPR(dst), A_GPR(src))
1457 * Process tone control
1459 A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 0), A_GPR(playback + 0), A_C_00000000, A_C_00000000); /* left */
1460 A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 1), A_GPR(playback + 1), A_C_00000000, A_C_00000000); /* right */
1461 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 */
1462 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 */
1463 A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 4), A_GPR(playback + 4), A_C_00000000, A_C_00000000); /* center */
1464 A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 5), A_GPR(playback + 5), A_C_00000000, A_C_00000000); /* LFE */
1466 ctl = &controls[nctl + 0];
1467 ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1468 strcpy(ctl->id.name, "Tone Control - Bass");
1473 ctl->value[0] = ctl->value[1] = 20;
1474 ctl->translation = EMU10K1_GPR_TRANSLATION_BASS;
1475 ctl = &controls[nctl + 1];
1476 ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1477 strcpy(ctl->id.name, "Tone Control - Treble");
1482 ctl->value[0] = ctl->value[1] = 20;
1483 ctl->translation = EMU10K1_GPR_TRANSLATION_TREBLE;
1485 #define BASS_GPR 0x8c
1486 #define TREBLE_GPR 0x96
1488 for (z = 0; z < 5; z++) {
1490 for (j = 0; j < 2; j++) {
1491 controls[nctl + 0].gpr[z * 2 + j] = BASS_GPR + z * 2 + j;
1492 controls[nctl + 1].gpr[z * 2 + j] = TREBLE_GPR + z * 2 + j;
1495 for (z = 0; z < 3; z++) { /* front/rear/center-lfe */
1497 for (j = 0; j < 2; j++) { /* left/right */
1498 k = 0xb0 + (z * 8) + (j * 4);
1499 l = 0xe0 + (z * 8) + (j * 4);
1500 d = playback + SND_EMU10K1_PLAYBACK_CHANNELS + z * 2 + j;
1502 A_OP(icode, &ptr, iMAC0, A_C_00000000, A_C_00000000, A_GPR(d), A_GPR(BASS_GPR + 0 + j));
1503 A_OP(icode, &ptr, iMACMV, A_GPR(k+1), A_GPR(k), A_GPR(k+1), A_GPR(BASS_GPR + 4 + j));
1504 A_OP(icode, &ptr, iMACMV, A_GPR(k), A_GPR(d), A_GPR(k), A_GPR(BASS_GPR + 2 + j));
1505 A_OP(icode, &ptr, iMACMV, A_GPR(k+3), A_GPR(k+2), A_GPR(k+3), A_GPR(BASS_GPR + 8 + j));
1506 A_OP(icode, &ptr, iMAC0, A_GPR(k+2), A_GPR_ACCU, A_GPR(k+2), A_GPR(BASS_GPR + 6 + j));
1507 A_OP(icode, &ptr, iACC3, A_GPR(k+2), A_GPR(k+2), A_GPR(k+2), A_C_00000000);
1509 A_OP(icode, &ptr, iMAC0, A_C_00000000, A_C_00000000, A_GPR(k+2), A_GPR(TREBLE_GPR + 0 + j));
1510 A_OP(icode, &ptr, iMACMV, A_GPR(l+1), A_GPR(l), A_GPR(l+1), A_GPR(TREBLE_GPR + 4 + j));
1511 A_OP(icode, &ptr, iMACMV, A_GPR(l), A_GPR(k+2), A_GPR(l), A_GPR(TREBLE_GPR + 2 + j));
1512 A_OP(icode, &ptr, iMACMV, A_GPR(l+3), A_GPR(l+2), A_GPR(l+3), A_GPR(TREBLE_GPR + 8 + j));
1513 A_OP(icode, &ptr, iMAC0, A_GPR(l+2), A_GPR_ACCU, A_GPR(l+2), A_GPR(TREBLE_GPR + 6 + j));
1514 A_OP(icode, &ptr, iMACINT0, A_GPR(l+2), A_C_00000000, A_GPR(l+2), A_C_00000010);
1516 A_OP(icode, &ptr, iACC3, A_GPR(d), A_GPR(l+2), A_C_00000000, A_C_00000000);
1518 if (z == 2) /* center */
1527 for (z = 0; z < 6; z++) {
1528 A_SWITCH(icode, &ptr, tmp + 0, playback + SND_EMU10K1_PLAYBACK_CHANNELS + z, gpr + 0);
1529 A_SWITCH_NEG(icode, &ptr, tmp + 1, gpr + 0);
1530 A_SWITCH(icode, &ptr, tmp + 1, playback + z, tmp + 1);
1531 A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + z), A_GPR(tmp + 0), A_GPR(tmp + 1), A_C_00000000);
1533 snd_emu10k1_init_stereo_onoff_control(controls + nctl++, "Tone Control - Switch", gpr, 0);
1536 /* Master volume (will be renamed later) */
1537 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));
1538 A_OP(icode, &ptr, iMAC0, A_GPR(playback+1+SND_EMU10K1_PLAYBACK_CHANNELS), A_C_00000000, A_GPR(gpr+1), A_GPR(playback+1+SND_EMU10K1_PLAYBACK_CHANNELS));
1539 A_OP(icode, &ptr, iMAC0, A_GPR(playback+2+SND_EMU10K1_PLAYBACK_CHANNELS), A_C_00000000, A_GPR(gpr+1), A_GPR(playback+2+SND_EMU10K1_PLAYBACK_CHANNELS));
1540 A_OP(icode, &ptr, iMAC0, A_GPR(playback+3+SND_EMU10K1_PLAYBACK_CHANNELS), A_C_00000000, A_GPR(gpr+1), A_GPR(playback+3+SND_EMU10K1_PLAYBACK_CHANNELS));
1541 A_OP(icode, &ptr, iMAC0, A_GPR(playback+4+SND_EMU10K1_PLAYBACK_CHANNELS), A_C_00000000, A_GPR(gpr+1), A_GPR(playback+4+SND_EMU10K1_PLAYBACK_CHANNELS));
1542 A_OP(icode, &ptr, iMAC0, A_GPR(playback+5+SND_EMU10K1_PLAYBACK_CHANNELS), A_C_00000000, A_GPR(gpr+1), A_GPR(playback+5+SND_EMU10K1_PLAYBACK_CHANNELS));
1543 snd_emu10k1_init_stereo_control(&controls[nctl++], "Wave Master Playback Volume", gpr, 0);
1546 /* analog speakers */
1547 A_PUT_STEREO_OUTPUT(A_EXTOUT_AFRONT_L, A_EXTOUT_AFRONT_R, playback + SND_EMU10K1_PLAYBACK_CHANNELS);
1548 A_PUT_STEREO_OUTPUT(A_EXTOUT_AREAR_L, A_EXTOUT_AREAR_R, playback+2 + SND_EMU10K1_PLAYBACK_CHANNELS);
1549 A_PUT_OUTPUT(A_EXTOUT_ACENTER, playback+4 + SND_EMU10K1_PLAYBACK_CHANNELS);
1550 A_PUT_OUTPUT(A_EXTOUT_ALFE, playback+5 + SND_EMU10K1_PLAYBACK_CHANNELS);
1553 A_PUT_STEREO_OUTPUT(A_EXTOUT_HEADPHONE_L, A_EXTOUT_HEADPHONE_R, playback + SND_EMU10K1_PLAYBACK_CHANNELS);
1555 /* digital outputs */
1556 /* A_PUT_STEREO_OUTPUT(A_EXTOUT_FRONT_L, A_EXTOUT_FRONT_R, playback + SND_EMU10K1_PLAYBACK_CHANNELS); */
1558 /* IEC958 Optical Raw Playback Switch */
1559 icode->gpr_map[gpr++] = 0x1008;
1560 icode->gpr_map[gpr++] = 0xffff0000;
1561 for (z = 0; z < 2; z++) {
1562 A_OP(icode, &ptr, iMAC0, A_GPR(tmp + 2), A_FXBUS(FXBUS_PT_LEFT + z), A_C_00000000, A_C_00000000);
1563 A_OP(icode, &ptr, iSKIP, A_GPR_COND, A_GPR_COND, A_GPR(gpr - 2), A_C_00000001);
1564 A_OP(icode, &ptr, iACC3, A_GPR(tmp + 2), A_C_00000000, A_C_00010000, A_GPR(tmp + 2));
1565 A_OP(icode, &ptr, iANDXOR, A_GPR(tmp + 2), A_GPR(tmp + 2), A_GPR(gpr - 1), A_C_00000000);
1566 A_SWITCH(icode, &ptr, tmp + 0, tmp + 2, gpr + z);
1567 A_SWITCH_NEG(icode, &ptr, tmp + 1, gpr + z);
1568 A_SWITCH(icode, &ptr, tmp + 1, playback + SND_EMU10K1_PLAYBACK_CHANNELS + z, tmp + 1);
1569 A_OP(icode, &ptr, iACC3, A_EXTOUT(A_EXTOUT_FRONT_L + z), A_GPR(tmp + 0), A_GPR(tmp + 1), A_C_00000000);
1571 snd_emu10k1_init_stereo_onoff_control(controls + nctl++, "IEC958 Optical Raw Playback Switch", gpr, 0);
1574 A_PUT_STEREO_OUTPUT(A_EXTOUT_REAR_L, A_EXTOUT_REAR_R, playback+2 + SND_EMU10K1_PLAYBACK_CHANNELS);
1575 A_PUT_OUTPUT(A_EXTOUT_CENTER, playback+4 + SND_EMU10K1_PLAYBACK_CHANNELS);
1576 A_PUT_OUTPUT(A_EXTOUT_LFE, playback+5 + SND_EMU10K1_PLAYBACK_CHANNELS);
1579 A_PUT_OUTPUT(A_EXTOUT_ADC_CAP_L, capture);
1580 A_PUT_OUTPUT(A_EXTOUT_ADC_CAP_R, capture+1);
1591 /* clear remaining instruction memory */
1593 A_OP(icode, &ptr, 0x0f, 0xc0, 0xc0, 0xcf, 0xc0);
1595 seg = snd_enter_user();
1596 icode->gpr_add_control_count = nctl;
1597 icode->gpr_add_controls = controls;
1598 err = snd_emu10k1_icode_poke(emu, icode);
1599 snd_leave_user(seg);
1609 * initial DSP configuration for Emu10k1
1612 /* when volume = max, then copy only to avoid volume modification */
1613 /* with iMAC0 (negative values) */
1614 static void __devinit _volume(emu10k1_fx8010_code_t *icode, u32 *ptr, u32 dst, u32 src, u32 vol)
1616 OP(icode, ptr, iMAC0, dst, C_00000000, src, vol);
1617 OP(icode, ptr, iANDXOR, C_00000000, vol, C_ffffffff, C_7fffffff);
1618 OP(icode, ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, C_00000001);
1619 OP(icode, ptr, iACC3, dst, src, C_00000000, C_00000000);
1621 static void __devinit _volume_add(emu10k1_fx8010_code_t *icode, u32 *ptr, u32 dst, u32 src, u32 vol)
1623 OP(icode, ptr, iANDXOR, C_00000000, vol, C_ffffffff, C_7fffffff);
1624 OP(icode, ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, C_00000002);
1625 OP(icode, ptr, iMACINT0, dst, dst, src, C_00000001);
1626 OP(icode, ptr, iSKIP, C_00000000, C_7fffffff, C_7fffffff, C_00000001);
1627 OP(icode, ptr, iMAC0, dst, dst, src, vol);
1629 static void __devinit _volume_out(emu10k1_fx8010_code_t *icode, u32 *ptr, u32 dst, u32 src, u32 vol)
1631 OP(icode, ptr, iANDXOR, C_00000000, vol, C_ffffffff, C_7fffffff);
1632 OP(icode, ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, C_00000002);
1633 OP(icode, ptr, iACC3, dst, src, C_00000000, C_00000000);
1634 OP(icode, ptr, iSKIP, C_00000000, C_7fffffff, C_7fffffff, C_00000001);
1635 OP(icode, ptr, iMAC0, dst, C_00000000, src, vol);
1638 #define VOLUME(icode, ptr, dst, src, vol) \
1639 _volume(icode, ptr, GPR(dst), GPR(src), GPR(vol))
1640 #define VOLUME_IN(icode, ptr, dst, src, vol) \
1641 _volume(icode, ptr, GPR(dst), EXTIN(src), GPR(vol))
1642 #define VOLUME_ADD(icode, ptr, dst, src, vol) \
1643 _volume_add(icode, ptr, GPR(dst), GPR(src), GPR(vol))
1644 #define VOLUME_ADDIN(icode, ptr, dst, src, vol) \
1645 _volume_add(icode, ptr, GPR(dst), EXTIN(src), GPR(vol))
1646 #define VOLUME_OUT(icode, ptr, dst, src, vol) \
1647 _volume_out(icode, ptr, EXTOUT(dst), GPR(src), GPR(vol))
1648 #define _SWITCH(icode, ptr, dst, src, sw) \
1649 OP((icode), ptr, iMACINT0, dst, C_00000000, src, sw);
1650 #define SWITCH(icode, ptr, dst, src, sw) \
1651 _SWITCH(icode, ptr, GPR(dst), GPR(src), GPR(sw))
1652 #define SWITCH_IN(icode, ptr, dst, src, sw) \
1653 _SWITCH(icode, ptr, GPR(dst), EXTIN(src), GPR(sw))
1654 #define _SWITCH_NEG(icode, ptr, dst, src) \
1655 OP((icode), ptr, iANDXOR, dst, src, C_00000001, C_00000001);
1656 #define SWITCH_NEG(icode, ptr, dst, src) \
1657 _SWITCH_NEG(icode, ptr, GPR(dst), GPR(src))
1660 static int __devinit _snd_emu10k1_init_efx(emu10k1_t *emu)
1662 int err, i, z, gpr, tmp, playback, capture;
1664 emu10k1_fx8010_code_t *icode;
1665 emu10k1_fx8010_pcm_t *ipcm;
1666 emu10k1_fx8010_control_gpr_t *controls, *ctl;
1669 spin_lock_init(&emu->fx8010.irq_lock);
1670 INIT_LIST_HEAD(&emu->fx8010.gpr_ctl);
1672 if ((icode = snd_kcalloc(sizeof(emu10k1_fx8010_code_t), GFP_KERNEL)) == NULL)
1674 if ((controls = snd_kcalloc(sizeof(emu10k1_fx8010_control_gpr_t) * SND_EMU10K1_GPR_CONTROLS, GFP_KERNEL)) == NULL) {
1678 if ((ipcm = snd_kcalloc(sizeof(emu10k1_fx8010_pcm_t), GFP_KERNEL)) == NULL) {
1684 /* clear free GPRs */
1685 for (i = 0; i < 256; i++)
1686 set_bit(i, icode->gpr_valid);
1688 /* clear TRAM data & address lines */
1689 for (i = 0; i < 160; i++)
1690 set_bit(i, icode->tram_valid);
1692 strcpy(icode->name, "SB Live! FX8010 code for ALSA v1.2 by Jaroslav Kysela");
1694 /* we have 10 inputs */
1695 playback = SND_EMU10K1_INPUTS;
1696 /* we have 6 playback channels and tone control doubles */
1697 capture = playback + (SND_EMU10K1_PLAYBACK_CHANNELS * 2);
1698 gpr = capture + SND_EMU10K1_CAPTURE_CHANNELS;
1699 tmp = 0x88; /* we need 4 temporary GPR */
1700 /* from 0x8c to 0xff is the area for tone control */
1702 /* stop FX processor */
1703 snd_emu10k1_ptr_write(emu, DBG, 0, (emu->fx8010.dbg = 0) | EMU10K1_DBG_SINGLE_STEP);
1708 OP(icode, &ptr, iMACINT0, GPR(0), C_00000000, FXBUS(FXBUS_PCM_LEFT), C_00000004);
1709 OP(icode, &ptr, iMACINT0, GPR(1), C_00000000, FXBUS(FXBUS_PCM_RIGHT), C_00000004);
1710 OP(icode, &ptr, iMACINT0, GPR(2), C_00000000, FXBUS(FXBUS_MIDI_LEFT), C_00000004);
1711 OP(icode, &ptr, iMACINT0, GPR(3), C_00000000, FXBUS(FXBUS_MIDI_RIGHT), C_00000004);
1712 OP(icode, &ptr, iMACINT0, GPR(4), C_00000000, FXBUS(FXBUS_PCM_LEFT_REAR), C_00000004);
1713 OP(icode, &ptr, iMACINT0, GPR(5), C_00000000, FXBUS(FXBUS_PCM_RIGHT_REAR), C_00000004);
1714 OP(icode, &ptr, iMACINT0, GPR(6), C_00000000, FXBUS(FXBUS_PCM_CENTER), C_00000004);
1715 OP(icode, &ptr, iMACINT0, GPR(7), C_00000000, FXBUS(FXBUS_PCM_LFE), C_00000004);
1716 OP(icode, &ptr, iMACINT0, GPR(8), C_00000000, C_00000000, C_00000000); /* S/PDIF left */
1717 OP(icode, &ptr, iMACINT0, GPR(9), C_00000000, C_00000000, C_00000000); /* S/PDIF right */
1719 /* Raw S/PDIF PCM */
1720 ipcm->substream = 0;
1722 ipcm->tram_start = 0;
1723 ipcm->buffer_size = (64 * 1024) / 2;
1724 ipcm->gpr_size = gpr++;
1725 ipcm->gpr_ptr = gpr++;
1726 ipcm->gpr_count = gpr++;
1727 ipcm->gpr_tmpcount = gpr++;
1728 ipcm->gpr_trigger = gpr++;
1729 ipcm->gpr_running = gpr++;
1733 icode->gpr_map[gpr + 0] = 0xfffff000;
1734 icode->gpr_map[gpr + 1] = 0xffff0000;
1735 icode->gpr_map[gpr + 2] = 0x70000000;
1736 icode->gpr_map[gpr + 3] = 0x00000007;
1737 icode->gpr_map[gpr + 4] = 0x001f << 11;
1738 icode->gpr_map[gpr + 5] = 0x001c << 11;
1739 icode->gpr_map[gpr + 6] = (0x22 - 0x01) - 1; /* skip at 01 to 22 */
1740 icode->gpr_map[gpr + 7] = (0x22 - 0x06) - 1; /* skip at 06 to 22 */
1741 icode->gpr_map[gpr + 8] = 0x2000000 + (2<<11);
1742 icode->gpr_map[gpr + 9] = 0x4000000 + (2<<11);
1743 icode->gpr_map[gpr + 10] = 1<<11;
1744 icode->gpr_map[gpr + 11] = (0x24 - 0x0a) - 1; /* skip at 0a to 24 */
1745 icode->gpr_map[gpr + 12] = 0;
1747 /* if the trigger flag is not set, skip */
1748 /* 00: */ OP(icode, &ptr, iMAC0, C_00000000, GPR(ipcm->gpr_trigger), C_00000000, C_00000000);
1749 /* 01: */ OP(icode, &ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_ZERO, GPR(gpr + 6));
1750 /* if the running flag is set, we're running */
1751 /* 02: */ OP(icode, &ptr, iMAC0, C_00000000, GPR(ipcm->gpr_running), C_00000000, C_00000000);
1752 /* 03: */ OP(icode, &ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, C_00000004);
1753 /* wait until ((GPR_DBAC>>11) & 0x1f) == 0x1c) */
1754 /* 04: */ OP(icode, &ptr, iANDXOR, GPR(tmp + 0), GPR_DBAC, GPR(gpr + 4), C_00000000);
1755 /* 05: */ OP(icode, &ptr, iMACINT0, C_00000000, GPR(tmp + 0), C_ffffffff, GPR(gpr + 5));
1756 /* 06: */ OP(icode, &ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, GPR(gpr + 7));
1757 /* 07: */ OP(icode, &ptr, iACC3, GPR(gpr + 12), C_00000010, C_00000001, C_00000000);
1759 /* 08: */ OP(icode, &ptr, iANDXOR, GPR(ipcm->gpr_running), GPR(ipcm->gpr_running), C_00000000, C_00000001);
1760 /* 09: */ OP(icode, &ptr, iACC3, GPR(gpr + 12), GPR(gpr + 12), C_ffffffff, C_00000000);
1761 /* 0a: */ OP(icode, &ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, GPR(gpr + 11));
1762 /* 0b: */ OP(icode, &ptr, iACC3, GPR(gpr + 12), C_00000001, C_00000000, C_00000000);
1764 /* 0c: */ OP(icode, &ptr, iANDXOR, GPR(tmp + 0), ETRAM_DATA(ipcm->etram[0]), GPR(gpr + 0), C_00000000);
1765 /* 0d: */ OP(icode, &ptr, iLOG, GPR(tmp + 0), GPR(tmp + 0), GPR(gpr + 3), C_00000000);
1766 /* 0e: */ OP(icode, &ptr, iANDXOR, GPR(8), GPR(tmp + 0), GPR(gpr + 1), GPR(gpr + 2));
1767 /* 0f: */ OP(icode, &ptr, iSKIP, C_00000000, GPR_COND, CC_REG_MINUS, C_00000001);
1768 /* 10: */ OP(icode, &ptr, iANDXOR, GPR(8), GPR(8), GPR(gpr + 1), GPR(gpr + 2));
1770 /* 11: */ OP(icode, &ptr, iANDXOR, GPR(tmp + 0), ETRAM_DATA(ipcm->etram[1]), GPR(gpr + 0), C_00000000);
1771 /* 12: */ OP(icode, &ptr, iLOG, GPR(tmp + 0), GPR(tmp + 0), GPR(gpr + 3), C_00000000);
1772 /* 13: */ OP(icode, &ptr, iANDXOR, GPR(9), GPR(tmp + 0), GPR(gpr + 1), GPR(gpr + 2));
1773 /* 14: */ OP(icode, &ptr, iSKIP, C_00000000, GPR_COND, CC_REG_MINUS, C_00000001);
1774 /* 15: */ OP(icode, &ptr, iANDXOR, GPR(9), GPR(9), GPR(gpr + 1), GPR(gpr + 2));
1776 /* 16: */ OP(icode, &ptr, iACC3, GPR(tmp + 0), GPR(ipcm->gpr_ptr), C_00000001, C_00000000);
1777 /* 17: */ OP(icode, &ptr, iMACINT0, C_00000000, GPR(tmp + 0), C_ffffffff, GPR(ipcm->gpr_size));
1778 /* 18: */ OP(icode, &ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_MINUS, C_00000001);
1779 /* 19: */ OP(icode, &ptr, iACC3, GPR(tmp + 0), C_00000000, C_00000000, C_00000000);
1780 /* 1a: */ OP(icode, &ptr, iACC3, GPR(ipcm->gpr_ptr), GPR(tmp + 0), C_00000000, C_00000000);
1782 /* 1b: */ OP(icode, &ptr, iACC3, GPR(ipcm->gpr_tmpcount), GPR(ipcm->gpr_tmpcount), C_ffffffff, C_00000000);
1783 /* 1c: */ OP(icode, &ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, C_00000002);
1784 /* 1d: */ OP(icode, &ptr, iACC3, GPR(ipcm->gpr_tmpcount), GPR(ipcm->gpr_count), C_00000000, C_00000000);
1785 /* 1e: */ OP(icode, &ptr, iACC3, GPR_IRQ, C_80000000, C_00000000, C_00000000);
1786 /* 1f: */ OP(icode, &ptr, iANDXOR, GPR(ipcm->gpr_running), GPR(ipcm->gpr_running), C_00000001, C_00010000);
1788 /* 20: */ OP(icode, &ptr, iANDXOR, GPR(ipcm->gpr_running), GPR(ipcm->gpr_running), C_00010000, C_00000001);
1789 /* 21: */ OP(icode, &ptr, iSKIP, C_00000000, C_7fffffff, C_7fffffff, C_00000002);
1791 /* 22: */ OP(icode, &ptr, iMACINT1, ETRAM_ADDR(ipcm->etram[0]), GPR(gpr + 8), GPR_DBAC, C_ffffffff);
1792 /* 23: */ OP(icode, &ptr, iMACINT1, ETRAM_ADDR(ipcm->etram[1]), GPR(gpr + 9), GPR_DBAC, C_ffffffff);
1797 /* Wave Playback Volume */
1798 for (z = 0; z < 2; z++)
1799 VOLUME(icode, &ptr, playback + z, z, gpr + z);
1800 snd_emu10k1_init_stereo_control(controls + i++, "Wave Playback Volume", gpr, 100);
1803 /* Wave Surround Playback Volume */
1804 for (z = 0; z < 2; z++)
1805 VOLUME(icode, &ptr, playback + 2 + z, z, gpr + z);
1806 snd_emu10k1_init_stereo_control(controls + i++, "Wave Surround Playback Volume", gpr, 0);
1809 /* Wave Center/LFE Playback Volume */
1810 OP(icode, &ptr, iACC3, GPR(tmp + 0), FXBUS(FXBUS_PCM_LEFT), FXBUS(FXBUS_PCM_RIGHT), C_00000000);
1811 OP(icode, &ptr, iMACINT0, GPR(tmp + 0), C_00000000, GPR(tmp + 0), C_00000002);
1812 VOLUME(icode, &ptr, playback + 4, tmp + 0, gpr);
1813 snd_emu10k1_init_mono_control(controls + i++, "Wave Center Playback Volume", gpr++, 0);
1814 VOLUME(icode, &ptr, playback + 5, tmp + 0, gpr);
1815 snd_emu10k1_init_mono_control(controls + i++, "Wave LFE Playback Volume", gpr++, 0);
1817 /* Wave Capture Volume + Switch */
1818 for (z = 0; z < 2; z++) {
1819 SWITCH(icode, &ptr, tmp + 0, z, gpr + 2 + z);
1820 VOLUME(icode, &ptr, capture + z, tmp + 0, gpr + z);
1822 snd_emu10k1_init_stereo_control(controls + i++, "Wave Capture Volume", gpr, 0);
1823 snd_emu10k1_init_stereo_onoff_control(controls + i++, "Wave Capture Switch", gpr + 2, 0);
1826 /* Music Playback Volume */
1827 for (z = 0; z < 2; z++)
1828 VOLUME_ADD(icode, &ptr, playback + z, 2 + z, gpr + z);
1829 snd_emu10k1_init_stereo_control(controls + i++, "Music Playback Volume", gpr, 100);
1832 /* Music Capture Volume + Switch */
1833 for (z = 0; z < 2; z++) {
1834 SWITCH(icode, &ptr, tmp + 0, 2 + z, gpr + 2 + z);
1835 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
1837 snd_emu10k1_init_stereo_control(controls + i++, "Music Capture Volume", gpr, 0);
1838 snd_emu10k1_init_stereo_onoff_control(controls + i++, "Music Capture Switch", gpr + 2, 0);
1841 /* Surround Digital Playback Volume (renamed later without Digital) */
1842 for (z = 0; z < 2; z++)
1843 VOLUME_ADD(icode, &ptr, playback + 2 + z, 4 + z, gpr + z);
1844 snd_emu10k1_init_stereo_control(controls + i++, "Surround Digital Playback Volume", gpr, 100);
1847 /* Surround Capture Volume + Switch */
1848 for (z = 0; z < 2; z++) {
1849 SWITCH(icode, &ptr, tmp + 0, 4 + z, gpr + 2 + z);
1850 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
1852 snd_emu10k1_init_stereo_control(controls + i++, "Surround Capture Volume", gpr, 0);
1853 snd_emu10k1_init_stereo_onoff_control(controls + i++, "Surround Capture Switch", gpr + 2, 0);
1856 /* Center Playback Volume (renamed later without Digital) */
1857 VOLUME_ADD(icode, &ptr, playback + 4, 6, gpr);
1858 snd_emu10k1_init_mono_control(controls + i++, "Center Digital Playback Volume", gpr++, 100);
1860 /* LFE Playback Volume + Switch (renamed later without Digital) */
1861 VOLUME_ADD(icode, &ptr, playback + 5, 7, gpr);
1862 snd_emu10k1_init_mono_control(controls + i++, "LFE Digital Playback Volume", gpr++, 100);
1868 if (emu->fx8010.extin_mask & ((1<<EXTIN_AC97_L)|(1<<EXTIN_AC97_R))) {
1869 /* AC'97 Playback Volume */
1870 VOLUME_ADDIN(icode, &ptr, playback + 0, EXTIN_AC97_L, gpr); gpr++;
1871 VOLUME_ADDIN(icode, &ptr, playback + 1, EXTIN_AC97_R, gpr); gpr++;
1872 snd_emu10k1_init_stereo_control(controls + i++, "AC97 Playback Volume", gpr-2, 0);
1873 /* AC'97 Capture Volume */
1874 VOLUME_ADDIN(icode, &ptr, capture + 0, EXTIN_AC97_L, gpr); gpr++;
1875 VOLUME_ADDIN(icode, &ptr, capture + 1, EXTIN_AC97_R, gpr); gpr++;
1876 snd_emu10k1_init_stereo_control(controls + i++, "AC97 Capture Volume", gpr-2, 100);
1879 if (emu->fx8010.extin_mask & ((1<<EXTIN_SPDIF_CD_L)|(1<<EXTIN_SPDIF_CD_R))) {
1880 /* IEC958 TTL Playback Volume */
1881 for (z = 0; z < 2; z++)
1882 VOLUME_ADDIN(icode, &ptr, playback + z, EXTIN_SPDIF_CD_L + z, gpr + z);
1883 snd_emu10k1_init_stereo_control(controls + i++, "IEC958 TTL Playback Volume", gpr, 0);
1886 /* IEC958 TTL Capture Volume + Switch */
1887 for (z = 0; z < 2; z++) {
1888 SWITCH_IN(icode, &ptr, tmp + 0, EXTIN_SPDIF_CD_L + z, gpr + 2 + z);
1889 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
1891 snd_emu10k1_init_stereo_control(controls + i++, "IEC958 TTL Capture Volume", gpr, 0);
1892 snd_emu10k1_init_stereo_onoff_control(controls + i++, "IEC958 TTL Capture Switch", gpr + 2, 0);
1896 if (emu->fx8010.extin_mask & ((1<<EXTIN_ZOOM_L)|(1<<EXTIN_ZOOM_R))) {
1897 /* Zoom Video Playback Volume */
1898 for (z = 0; z < 2; z++)
1899 VOLUME_ADDIN(icode, &ptr, playback + z, EXTIN_ZOOM_L + z, gpr + z);
1900 snd_emu10k1_init_stereo_control(controls + i++, "Zoom Video Playback Volume", gpr, 0);
1903 /* Zoom Video Capture Volume + Switch */
1904 for (z = 0; z < 2; z++) {
1905 SWITCH_IN(icode, &ptr, tmp + 0, EXTIN_ZOOM_L + z, gpr + 2 + z);
1906 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
1908 snd_emu10k1_init_stereo_control(controls + i++, "Zoom Video Capture Volume", gpr, 0);
1909 snd_emu10k1_init_stereo_onoff_control(controls + i++, "Zoom Video Capture Switch", gpr + 2, 0);
1913 if (emu->fx8010.extin_mask & ((1<<EXTIN_TOSLINK_L)|(1<<EXTIN_TOSLINK_R))) {
1914 /* IEC958 Optical Playback Volume */
1915 for (z = 0; z < 2; z++)
1916 VOLUME_ADDIN(icode, &ptr, playback + z, EXTIN_TOSLINK_L + z, gpr + z);
1917 snd_emu10k1_init_stereo_control(controls + i++, "IEC958 LiveDrive Playback Volume", gpr, 0);
1920 /* IEC958 Optical Capture Volume */
1921 for (z = 0; z < 2; z++) {
1922 SWITCH_IN(icode, &ptr, tmp + 0, EXTIN_TOSLINK_L + z, gpr + 2 + z);
1923 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
1925 snd_emu10k1_init_stereo_control(controls + i++, "IEC958 LiveDrive Capture Volume", gpr, 0);
1926 snd_emu10k1_init_stereo_onoff_control(controls + i++, "IEC958 LiveDrive Capture Switch", gpr + 2, 0);
1930 if (emu->fx8010.extin_mask & ((1<<EXTIN_LINE1_L)|(1<<EXTIN_LINE1_R))) {
1931 /* Line LiveDrive Playback Volume */
1932 for (z = 0; z < 2; z++)
1933 VOLUME_ADDIN(icode, &ptr, playback + z, EXTIN_LINE1_L + z, gpr + z);
1934 snd_emu10k1_init_stereo_control(controls + i++, "Line LiveDrive Playback Volume", gpr, 0);
1937 /* Line LiveDrive Capture Volume + Switch */
1938 for (z = 0; z < 2; z++) {
1939 SWITCH_IN(icode, &ptr, tmp + 0, EXTIN_LINE1_L + z, gpr + 2 + z);
1940 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
1942 snd_emu10k1_init_stereo_control(controls + i++, "Line LiveDrive Capture Volume", gpr, 0);
1943 snd_emu10k1_init_stereo_onoff_control(controls + i++, "Line LiveDrive Capture Switch", gpr + 2, 0);
1947 if (emu->fx8010.extin_mask & ((1<<EXTIN_COAX_SPDIF_L)|(1<<EXTIN_COAX_SPDIF_R))) {
1948 /* IEC958 Coax Playback Volume */
1949 for (z = 0; z < 2; z++)
1950 VOLUME_ADDIN(icode, &ptr, playback + z, EXTIN_COAX_SPDIF_L + z, gpr + z);
1951 snd_emu10k1_init_stereo_control(controls + i++, "IEC958 Coaxial Playback Volume", gpr, 0);
1954 /* IEC958 Coax Capture Volume + Switch */
1955 for (z = 0; z < 2; z++) {
1956 SWITCH_IN(icode, &ptr, tmp + 0, EXTIN_COAX_SPDIF_L + z, gpr + 2 + z);
1957 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
1959 snd_emu10k1_init_stereo_control(controls + i++, "IEC958 Coaxial Capture Volume", gpr, 0);
1960 snd_emu10k1_init_stereo_onoff_control(controls + i++, "IEC958 Coaxial Capture Switch", gpr + 2, 0);
1964 if (emu->fx8010.extin_mask & ((1<<EXTIN_LINE2_L)|(1<<EXTIN_LINE2_R))) {
1965 /* Line LiveDrive Playback Volume */
1966 for (z = 0; z < 2; z++)
1967 VOLUME_ADDIN(icode, &ptr, playback + z, EXTIN_LINE2_L + z, gpr + z);
1968 snd_emu10k1_init_stereo_control(controls + i++, "Line2 LiveDrive Playback Volume", gpr, 0);
1969 controls[i-1].id.index = 1;
1972 /* Line LiveDrive Capture Volume */
1973 for (z = 0; z < 2; z++) {
1974 SWITCH_IN(icode, &ptr, tmp + 0, EXTIN_LINE2_L + z, gpr + 2 + z);
1975 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
1977 snd_emu10k1_init_stereo_control(controls + i++, "Line2 LiveDrive Capture Volume", gpr, 0);
1978 controls[i-1].id.index = 1;
1979 snd_emu10k1_init_stereo_onoff_control(controls + i++, "Line2 LiveDrive Capture Switch", gpr + 2, 0);
1980 controls[i-1].id.index = 1;
1985 * Process tone control
1987 OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 0), GPR(playback + 0), C_00000000, C_00000000); /* left */
1988 OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 1), GPR(playback + 1), C_00000000, C_00000000); /* right */
1989 OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 2), GPR(playback + 2), C_00000000, C_00000000); /* rear left */
1990 OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 3), GPR(playback + 3), C_00000000, C_00000000); /* rear right */
1991 OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 4), GPR(playback + 4), C_00000000, C_00000000); /* center */
1992 OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 5), GPR(playback + 5), C_00000000, C_00000000); /* LFE */
1994 ctl = &controls[i + 0];
1995 ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1996 strcpy(ctl->id.name, "Tone Control - Bass");
2001 ctl->value[0] = ctl->value[1] = 20;
2002 ctl->translation = EMU10K1_GPR_TRANSLATION_BASS;
2003 ctl = &controls[i + 1];
2004 ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
2005 strcpy(ctl->id.name, "Tone Control - Treble");
2010 ctl->value[0] = ctl->value[1] = 20;
2011 ctl->translation = EMU10K1_GPR_TRANSLATION_TREBLE;
2013 #define BASS_GPR 0x8c
2014 #define TREBLE_GPR 0x96
2016 for (z = 0; z < 5; z++) {
2018 for (j = 0; j < 2; j++) {
2019 controls[i + 0].gpr[z * 2 + j] = BASS_GPR + z * 2 + j;
2020 controls[i + 1].gpr[z * 2 + j] = TREBLE_GPR + z * 2 + j;
2023 for (z = 0; z < 3; z++) { /* front/rear/center-lfe */
2025 for (j = 0; j < 2; j++) { /* left/right */
2026 k = 0xa0 + (z * 8) + (j * 4);
2027 l = 0xd0 + (z * 8) + (j * 4);
2028 d = playback + SND_EMU10K1_PLAYBACK_CHANNELS + z * 2 + j;
2030 OP(icode, &ptr, iMAC0, C_00000000, C_00000000, GPR(d), GPR(BASS_GPR + 0 + j));
2031 OP(icode, &ptr, iMACMV, GPR(k+1), GPR(k), GPR(k+1), GPR(BASS_GPR + 4 + j));
2032 OP(icode, &ptr, iMACMV, GPR(k), GPR(d), GPR(k), GPR(BASS_GPR + 2 + j));
2033 OP(icode, &ptr, iMACMV, GPR(k+3), GPR(k+2), GPR(k+3), GPR(BASS_GPR + 8 + j));
2034 OP(icode, &ptr, iMAC0, GPR(k+2), GPR_ACCU, GPR(k+2), GPR(BASS_GPR + 6 + j));
2035 OP(icode, &ptr, iACC3, GPR(k+2), GPR(k+2), GPR(k+2), C_00000000);
2037 OP(icode, &ptr, iMAC0, C_00000000, C_00000000, GPR(k+2), GPR(TREBLE_GPR + 0 + j));
2038 OP(icode, &ptr, iMACMV, GPR(l+1), GPR(l), GPR(l+1), GPR(TREBLE_GPR + 4 + j));
2039 OP(icode, &ptr, iMACMV, GPR(l), GPR(k+2), GPR(l), GPR(TREBLE_GPR + 2 + j));
2040 OP(icode, &ptr, iMACMV, GPR(l+3), GPR(l+2), GPR(l+3), GPR(TREBLE_GPR + 8 + j));
2041 OP(icode, &ptr, iMAC0, GPR(l+2), GPR_ACCU, GPR(l+2), GPR(TREBLE_GPR + 6 + j));
2042 OP(icode, &ptr, iMACINT0, GPR(l+2), C_00000000, GPR(l+2), C_00000010);
2044 OP(icode, &ptr, iACC3, GPR(d), GPR(l+2), C_00000000, C_00000000);
2046 if (z == 2) /* center */
2055 for (z = 0; z < 6; z++) {
2056 SWITCH(icode, &ptr, tmp + 0, playback + SND_EMU10K1_PLAYBACK_CHANNELS + z, gpr + 0);
2057 SWITCH_NEG(icode, &ptr, tmp + 1, gpr + 0);
2058 SWITCH(icode, &ptr, tmp + 1, playback + z, tmp + 1);
2059 OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + z), GPR(tmp + 0), GPR(tmp + 1), C_00000000);
2061 snd_emu10k1_init_stereo_onoff_control(controls + i++, "Tone Control - Switch", gpr, 0);
2067 if (emu->fx8010.extout_mask & ((1<<EXTOUT_AC97_L)|(1<<EXTOUT_AC97_R))) {
2068 /* AC'97 Playback Volume */
2070 for (z = 0; z < 2; z++)
2071 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_AC97_L + z), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + z), C_00000000, C_00000000);
2074 if (emu->fx8010.extout_mask & ((1<<EXTOUT_TOSLINK_L)|(1<<EXTOUT_TOSLINK_R))) {
2075 /* IEC958 Optical Raw Playback Switch */
2077 for (z = 0; z < 2; z++) {
2078 SWITCH(icode, &ptr, tmp + 0, 8 + z, gpr + z);
2079 SWITCH_NEG(icode, &ptr, tmp + 1, gpr + z);
2080 SWITCH(icode, &ptr, tmp + 1, playback + SND_EMU10K1_PLAYBACK_CHANNELS + z, tmp + 1);
2081 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_TOSLINK_L + z), GPR(tmp + 0), GPR(tmp + 1), C_00000000);
2082 #ifdef EMU10K1_CAPTURE_DIGITAL_OUT
2083 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_ADC_CAP_L + z), GPR(tmp + 0), GPR(tmp + 1), C_00000000);
2087 snd_emu10k1_init_stereo_onoff_control(controls + i++, "IEC958 Optical Raw Playback Switch", gpr, 0);
2091 if (emu->fx8010.extout_mask & ((1<<EXTOUT_HEADPHONE_L)|(1<<EXTOUT_HEADPHONE_R))) {
2092 /* Headphone Playback Volume */
2094 for (z = 0; z < 2; z++) {
2095 SWITCH(icode, &ptr, tmp + 0, playback + SND_EMU10K1_PLAYBACK_CHANNELS + 4 + z, gpr + 2 + z);
2096 SWITCH_NEG(icode, &ptr, tmp + 1, gpr + 2 + z);
2097 SWITCH(icode, &ptr, tmp + 1, playback + SND_EMU10K1_PLAYBACK_CHANNELS + z, tmp + 1);
2098 OP(icode, &ptr, iACC3, GPR(tmp + 0), GPR(tmp + 0), GPR(tmp + 1), C_00000000);
2099 VOLUME_OUT(icode, &ptr, EXTOUT_HEADPHONE_L + z, tmp + 0, gpr + z);
2102 snd_emu10k1_init_stereo_control(controls + i++, "Headphone Playback Volume", gpr + 0, 0);
2103 controls[i-1].id.index = 1; /* AC'97 can have also Headphone control */
2104 snd_emu10k1_init_mono_onoff_control(controls + i++, "Headphone Center Playback Switch", gpr + 2, 0);
2105 controls[i-1].id.index = 1;
2106 snd_emu10k1_init_mono_onoff_control(controls + i++, "Headphone LFE Playback Switch", gpr + 3, 0);
2107 controls[i-1].id.index = 1;
2112 if (emu->fx8010.extout_mask & ((1<<EXTOUT_REAR_L)|(1<<EXTOUT_REAR_R)))
2113 for (z = 0; z < 2; z++)
2114 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_REAR_L + z), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 2 + z), C_00000000, C_00000000);
2116 if (emu->fx8010.extout_mask & (1<<EXTOUT_CENTER)) {
2117 #ifndef EMU10K1_CENTER_LFE_FROM_FRONT
2118 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_CENTER), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 4), C_00000000, C_00000000);
2119 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_ACENTER), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 4), C_00000000, C_00000000);
2121 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_CENTER), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 0), C_00000000, C_00000000);
2122 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_ACENTER), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 0), C_00000000, C_00000000);
2126 if (emu->fx8010.extout_mask & (1<<EXTOUT_LFE)) {
2127 #ifndef EMU10K1_CENTER_LFE_FROM_FRONT
2128 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_LFE), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 5), C_00000000, C_00000000);
2129 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_ALFE), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 5), C_00000000, C_00000000);
2131 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_LFE), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 1), C_00000000, C_00000000);
2132 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_ALFE), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 1), C_00000000, C_00000000);
2136 #ifndef EMU10K1_CAPTURE_DIGITAL_OUT
2137 for (z = 0; z < 2; z++)
2138 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_ADC_CAP_L + z), GPR(capture + z), C_00000000, C_00000000);
2141 if (emu->fx8010.extout_mask & (1<<EXTOUT_MIC_CAP))
2142 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_MIC_CAP), GPR(capture + 2), C_00000000, C_00000000);
2149 if (i > SND_EMU10K1_GPR_CONTROLS) {
2155 /* clear remaining instruction memory */
2157 OP(icode, &ptr, iACC3, C_00000000, C_00000000, C_00000000, C_00000000);
2159 if ((err = snd_emu10k1_fx8010_tram_setup(emu, ipcm->buffer_size)) < 0)
2161 seg = snd_enter_user();
2162 icode->gpr_add_control_count = i;
2163 icode->gpr_add_controls = controls;
2164 err = snd_emu10k1_icode_poke(emu, icode);
2165 snd_leave_user(seg);
2167 err = snd_emu10k1_ipcm_poke(emu, ipcm);
2175 int __devinit snd_emu10k1_init_efx(emu10k1_t *emu)
2178 return _snd_emu10k1_audigy_init_efx(emu);
2180 return _snd_emu10k1_init_efx(emu);
2183 void snd_emu10k1_free_efx(emu10k1_t *emu)
2185 /* stop processor */
2187 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg = A_DBG_SINGLE_STEP);
2189 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg = EMU10K1_DBG_SINGLE_STEP);
2192 #if 0 // FIXME: who use them?
2193 int snd_emu10k1_fx8010_tone_control_activate(emu10k1_t *emu, int output)
2195 snd_runtime_check(output >= 0 && output < 6, return -EINVAL);
2196 snd_emu10k1_ptr_write(emu, emu->gpr_base + 0x94 + output, 0, 1);
2200 int snd_emu10k1_fx8010_tone_control_deactivate(emu10k1_t *emu, int output)
2202 snd_runtime_check(output >= 0 && output < 6, return -EINVAL);
2203 snd_emu10k1_ptr_write(emu, emu->gpr_base + 0x94 + output, 0, 0);
2208 int snd_emu10k1_fx8010_tram_setup(emu10k1_t *emu, u32 size)
2212 /* size is in samples */
2214 size = (size - 1) >> 13;
2220 size = 0x2000 << size_reg;
2222 if (emu->fx8010.etram_pages.bytes == size)
2224 spin_lock_irq(&emu->emu_lock);
2225 outl(HCFG_LOCKTANKCACHE_MASK | inl(emu->port + HCFG), emu->port + HCFG);
2226 spin_unlock_irq(&emu->emu_lock);
2227 snd_emu10k1_ptr_write(emu, TCB, 0, 0);
2228 snd_emu10k1_ptr_write(emu, TCBS, 0, 0);
2229 if (emu->fx8010.etram_pages.area != NULL) {
2230 snd_dma_free_pages(&emu->dma_dev, &emu->fx8010.etram_pages);
2231 emu->fx8010.etram_pages.area = NULL;
2232 emu->fx8010.etram_pages.bytes = 0;
2236 if (snd_dma_alloc_pages(&emu->dma_dev, size * 2, &emu->fx8010.etram_pages) < 0)
2238 memset(emu->fx8010.etram_pages.area, 0, size * 2);
2239 snd_emu10k1_ptr_write(emu, TCB, 0, emu->fx8010.etram_pages.addr);
2240 snd_emu10k1_ptr_write(emu, TCBS, 0, size_reg);
2241 spin_lock_irq(&emu->emu_lock);
2242 outl(inl(emu->port + HCFG) & ~HCFG_LOCKTANKCACHE_MASK, emu->port + HCFG);
2243 spin_unlock_irq(&emu->emu_lock);
2249 static int snd_emu10k1_fx8010_open(snd_hwdep_t * hw, struct file *file)
2254 static void copy_string(char *dst, char *src, char *null, int idx)
2257 sprintf(dst, "%s %02X", null, idx);
2262 static int snd_emu10k1_fx8010_info(emu10k1_t *emu, emu10k1_fx8010_info_t *info)
2264 char **fxbus, **extin, **extout;
2265 unsigned short fxbus_mask, extin_mask, extout_mask;
2268 memset(info, 0, sizeof(info));
2269 info->card = emu->card_type;
2270 info->internal_tram_size = emu->fx8010.itram_size;
2271 info->external_tram_size = emu->fx8010.etram_pages.bytes;
2273 extin = emu->audigy ? audigy_ins : creative_ins;
2274 extout = emu->audigy ? audigy_outs : creative_outs;
2275 fxbus_mask = emu->fx8010.fxbus_mask;
2276 extin_mask = emu->fx8010.extin_mask;
2277 extout_mask = emu->fx8010.extout_mask;
2278 for (res = 0; res < 16; res++, fxbus++, extin++, extout++) {
2279 copy_string(info->fxbus_names[res], fxbus_mask & (1 << res) ? *fxbus : NULL, "FXBUS", res);
2280 copy_string(info->extin_names[res], extin_mask & (1 << res) ? *extin : NULL, "Unused", res);
2281 copy_string(info->extout_names[res], extout_mask & (1 << res) ? *extout : NULL, "Unused", res);
2283 for (res = 16; res < 32; res++, extout++)
2284 copy_string(info->extout_names[res], extout_mask & (1 << res) ? *extout : NULL, "Unused", res);
2285 info->gpr_controls = emu->fx8010.gpr_count;
2289 static int snd_emu10k1_fx8010_ioctl(snd_hwdep_t * hw, struct file *file, unsigned int cmd, unsigned long arg)
2291 emu10k1_t *emu = snd_magic_cast(emu10k1_t, hw->private_data, return -ENXIO);
2292 emu10k1_fx8010_info_t *info;
2293 emu10k1_fx8010_code_t *icode;
2294 emu10k1_fx8010_pcm_t *ipcm;
2299 case SNDRV_EMU10K1_IOCTL_INFO:
2300 info = (emu10k1_fx8010_info_t *)kmalloc(sizeof(*info), GFP_KERNEL);
2303 if ((res = snd_emu10k1_fx8010_info(emu, info)) < 0) {
2307 if (copy_to_user((void *)arg, info, sizeof(*info))) {
2313 case SNDRV_EMU10K1_IOCTL_CODE_POKE:
2314 if (!capable(CAP_SYS_ADMIN))
2316 icode = (emu10k1_fx8010_code_t *)kmalloc(sizeof(*icode), GFP_KERNEL);
2319 if (copy_from_user(icode, (void *)arg, sizeof(*icode))) {
2323 res = snd_emu10k1_icode_poke(emu, icode);
2326 case SNDRV_EMU10K1_IOCTL_CODE_PEEK:
2327 icode = (emu10k1_fx8010_code_t *)kmalloc(sizeof(*icode), GFP_KERNEL);
2330 if (copy_from_user(icode, (void *)arg, sizeof(*icode))) {
2334 res = snd_emu10k1_icode_peek(emu, icode);
2335 if (res == 0 && copy_to_user((void *)arg, icode, sizeof(*icode))) {
2341 case SNDRV_EMU10K1_IOCTL_PCM_POKE:
2344 ipcm = (emu10k1_fx8010_pcm_t *)kmalloc(sizeof(*ipcm), GFP_KERNEL);
2347 if (copy_from_user(ipcm, (void *)arg, sizeof(*ipcm))) {
2351 res = snd_emu10k1_ipcm_poke(emu, ipcm);
2354 case SNDRV_EMU10K1_IOCTL_PCM_PEEK:
2357 ipcm = (emu10k1_fx8010_pcm_t *)snd_kcalloc(sizeof(*ipcm), GFP_KERNEL);
2360 if (copy_from_user(ipcm, (void *)arg, sizeof(*ipcm))) {
2364 res = snd_emu10k1_ipcm_peek(emu, ipcm);
2365 if (res == 0 && copy_to_user((void *)arg, ipcm, sizeof(*ipcm))) {
2371 case SNDRV_EMU10K1_IOCTL_TRAM_SETUP:
2374 if (!capable(CAP_SYS_ADMIN))
2376 if (get_user(addr, (unsigned int *)arg))
2378 down(&emu->fx8010.lock);
2379 res = snd_emu10k1_fx8010_tram_setup(emu, addr);
2380 up(&emu->fx8010.lock);
2382 case SNDRV_EMU10K1_IOCTL_STOP:
2383 if (!capable(CAP_SYS_ADMIN))
2386 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg |= A_DBG_SINGLE_STEP);
2388 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg |= EMU10K1_DBG_SINGLE_STEP);
2390 case SNDRV_EMU10K1_IOCTL_CONTINUE:
2391 if (!capable(CAP_SYS_ADMIN))
2394 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg = 0);
2396 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg = 0);
2398 case SNDRV_EMU10K1_IOCTL_ZERO_TRAM_COUNTER:
2399 if (!capable(CAP_SYS_ADMIN))
2402 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg | A_DBG_ZC);
2404 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg | EMU10K1_DBG_ZC);
2407 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg);
2409 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg);
2411 case SNDRV_EMU10K1_IOCTL_SINGLE_STEP:
2412 if (!capable(CAP_SYS_ADMIN))
2414 if (get_user(addr, (unsigned int *)arg))
2419 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg |= A_DBG_SINGLE_STEP | addr);
2421 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg |= EMU10K1_DBG_SINGLE_STEP | addr);
2424 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg |= A_DBG_SINGLE_STEP | A_DBG_STEP_ADDR | addr);
2426 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg |= EMU10K1_DBG_SINGLE_STEP | EMU10K1_DBG_STEP | addr);
2428 case SNDRV_EMU10K1_IOCTL_DBG_READ:
2430 addr = snd_emu10k1_ptr_read(emu, A_DBG, 0);
2432 addr = snd_emu10k1_ptr_read(emu, DBG, 0);
2433 if (put_user(addr, (unsigned int *)arg))
2440 static int snd_emu10k1_fx8010_release(snd_hwdep_t * hw, struct file *file)
2445 int __devinit snd_emu10k1_fx8010_new(emu10k1_t *emu, int device, snd_hwdep_t ** rhwdep)
2452 if ((err = snd_hwdep_new(emu->card, "FX8010", device, &hw)) < 0)
2454 strcpy(hw->name, "EMU10K1 (FX8010)");
2455 hw->iface = SNDRV_HWDEP_IFACE_EMU10K1;
2456 hw->ops.open = snd_emu10k1_fx8010_open;
2457 hw->ops.ioctl = snd_emu10k1_fx8010_ioctl;
2458 hw->ops.release = snd_emu10k1_fx8010_release;
2459 hw->private_data = emu;