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",
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(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 __user *_id;
902 snd_ctl_elem_id_t id;
903 emu10k1_fx8010_control_gpr_t __user *_gctl;
904 emu10k1_fx8010_control_gpr_t gctl;
906 for (i = 0, _id = icode->gpr_del_controls;
907 i < icode->gpr_del_control_count; i++, _id++) {
908 if (copy_from_user(&id, _id, sizeof(id)))
910 if (snd_emu10k1_look_for_ctl(emu, &id) == NULL)
913 for (i = 0, _gctl = icode->gpr_add_controls;
914 i < icode->gpr_add_control_count; i++, _gctl++) {
915 if (copy_from_user(&gctl, _gctl, sizeof(gctl)))
917 if (snd_emu10k1_look_for_ctl(emu, &gctl.id))
919 down_read(&emu->card->controls_rwsem);
920 if (snd_ctl_find_id(emu->card, &gctl.id) != NULL) {
921 up_read(&emu->card->controls_rwsem);
924 up_read(&emu->card->controls_rwsem);
925 if (gctl.id.iface != SNDRV_CTL_ELEM_IFACE_MIXER &&
926 gctl.id.iface != SNDRV_CTL_ELEM_IFACE_PCM)
929 for (i = 0, _gctl = icode->gpr_list_controls;
930 i < icode->gpr_list_control_count; i++, _gctl++) {
931 /* FIXME: we need to check the WRITE access */
932 if (copy_from_user(&gctl, _gctl, sizeof(gctl)))
938 static void snd_emu10k1_ctl_private_free(snd_kcontrol_t *kctl)
940 snd_emu10k1_fx8010_ctl_t *ctl;
942 ctl = (snd_emu10k1_fx8010_ctl_t *)kctl->private_value;
943 kctl->private_value = 0;
944 list_del(&ctl->list);
948 static void snd_emu10k1_add_controls(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
951 emu10k1_fx8010_control_gpr_t __user *_gctl;
952 emu10k1_fx8010_control_gpr_t gctl;
953 snd_emu10k1_fx8010_ctl_t *ctl, nctl;
954 snd_kcontrol_new_t knew;
955 snd_kcontrol_t *kctl;
956 snd_ctl_elem_value_t *val;
958 val = (snd_ctl_elem_value_t *)kmalloc(sizeof(*val), GFP_KERNEL);
961 for (i = 0, _gctl = icode->gpr_add_controls;
962 i < icode->gpr_add_control_count; i++, _gctl++) {
963 if (copy_from_user(&gctl, _gctl, sizeof(gctl)))
965 snd_runtime_check(gctl.id.iface == SNDRV_CTL_ELEM_IFACE_MIXER ||
966 gctl.id.iface == SNDRV_CTL_ELEM_IFACE_PCM, continue);
967 snd_runtime_check(gctl.id.name[0] != '\0', continue);
968 ctl = snd_emu10k1_look_for_ctl(emu, &gctl.id);
969 memset(&knew, 0, sizeof(knew));
970 knew.iface = gctl.id.iface;
971 knew.name = gctl.id.name;
972 knew.index = gctl.id.index;
973 knew.device = gctl.id.device;
974 knew.subdevice = gctl.id.subdevice;
975 knew.info = snd_emu10k1_gpr_ctl_info;
976 knew.get = snd_emu10k1_gpr_ctl_get;
977 knew.put = snd_emu10k1_gpr_ctl_put;
978 memset(&nctl, 0, sizeof(nctl));
979 nctl.vcount = gctl.vcount;
980 nctl.count = gctl.count;
981 for (j = 0; j < 32; j++) {
982 nctl.gpr[j] = gctl.gpr[j];
983 nctl.value[j] = ~gctl.value[j]; /* inverted, we want to write new value in gpr_ctl_put() */
984 val->value.integer.value[j] = gctl.value[j];
988 nctl.translation = gctl.translation;
990 ctl = (snd_emu10k1_fx8010_ctl_t *)kmalloc(sizeof(*ctl), GFP_KERNEL);
993 knew.private_value = (unsigned long)ctl;
994 memcpy(ctl, &nctl, sizeof(nctl));
995 if (snd_ctl_add(emu->card, kctl = snd_ctl_new1(&knew, emu)) < 0) {
999 kctl->private_free = snd_emu10k1_ctl_private_free;
1000 ctl->kcontrol = kctl;
1001 list_add_tail(&ctl->list, &emu->fx8010.gpr_ctl);
1004 nctl.list = ctl->list;
1005 nctl.kcontrol = ctl->kcontrol;
1006 memcpy(ctl, &nctl, sizeof(nctl));
1007 snd_ctl_notify(emu->card, SNDRV_CTL_EVENT_MASK_VALUE |
1008 SNDRV_CTL_EVENT_MASK_INFO, &ctl->kcontrol->id);
1010 snd_emu10k1_gpr_ctl_put(ctl->kcontrol, val);
1015 static void snd_emu10k1_del_controls(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
1018 snd_ctl_elem_id_t id;
1019 snd_ctl_elem_id_t __user *_id;
1020 snd_emu10k1_fx8010_ctl_t *ctl;
1021 snd_card_t *card = emu->card;
1023 for (i = 0, _id = icode->gpr_del_controls;
1024 i < icode->gpr_del_control_count; i++, _id++) {
1025 snd_runtime_check(copy_from_user(&id, _id, sizeof(id)) == 0, continue);
1026 down_write(&card->controls_rwsem);
1027 ctl = snd_emu10k1_look_for_ctl(emu, &id);
1029 snd_ctl_remove(card, ctl->kcontrol);
1030 up_write(&card->controls_rwsem);
1034 static int snd_emu10k1_list_controls(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
1036 unsigned int i = 0, j;
1037 unsigned int total = 0;
1038 emu10k1_fx8010_control_gpr_t gctl;
1039 emu10k1_fx8010_control_gpr_t __user *_gctl;
1040 snd_emu10k1_fx8010_ctl_t *ctl;
1041 snd_ctl_elem_id_t *id;
1042 struct list_head *list;
1044 _gctl = icode->gpr_list_controls;
1045 list_for_each(list, &emu->fx8010.gpr_ctl) {
1046 ctl = emu10k1_gpr_ctl(list);
1048 if (_gctl && i < icode->gpr_list_control_count) {
1049 memset(&gctl, 0, sizeof(gctl));
1050 id = &ctl->kcontrol->id;
1051 gctl.id.iface = id->iface;
1052 strlcpy(gctl.id.name, id->name, sizeof(gctl.id.name));
1053 gctl.id.index = id->index;
1054 gctl.id.device = id->device;
1055 gctl.id.subdevice = id->subdevice;
1056 gctl.vcount = ctl->vcount;
1057 gctl.count = ctl->count;
1058 for (j = 0; j < 32; j++) {
1059 gctl.gpr[j] = ctl->gpr[j];
1060 gctl.value[j] = ctl->value[j];
1062 gctl.min = ctl->min;
1063 gctl.max = ctl->max;
1064 gctl.translation = ctl->translation;
1065 if (copy_to_user(_gctl, &gctl, sizeof(gctl)))
1071 icode->gpr_list_control_total = total;
1075 static int snd_emu10k1_icode_poke(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
1079 down(&emu->fx8010.lock);
1080 if ((err = snd_emu10k1_verify_controls(emu, icode)) < 0)
1082 strlcpy(emu->fx8010.name, icode->name, sizeof(emu->fx8010.name));
1083 /* stop FX processor - this may be dangerous, but it's better to miss
1084 some samples than generate wrong ones - [jk] */
1086 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg | A_DBG_SINGLE_STEP);
1088 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg | EMU10K1_DBG_SINGLE_STEP);
1089 /* ok, do the main job */
1090 snd_emu10k1_del_controls(emu, icode);
1091 snd_emu10k1_gpr_poke(emu, icode);
1092 snd_emu10k1_tram_poke(emu, icode);
1093 snd_emu10k1_code_poke(emu, icode);
1094 snd_emu10k1_add_controls(emu, icode);
1095 /* start FX processor when the DSP code is updated */
1097 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg);
1099 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg);
1101 up(&emu->fx8010.lock);
1105 static int snd_emu10k1_icode_peek(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
1109 down(&emu->fx8010.lock);
1110 strlcpy(icode->name, emu->fx8010.name, sizeof(icode->name));
1111 /* ok, do the main job */
1112 snd_emu10k1_gpr_peek(emu, icode);
1113 snd_emu10k1_tram_peek(emu, icode);
1114 snd_emu10k1_code_peek(emu, icode);
1115 err = snd_emu10k1_list_controls(emu, icode);
1116 up(&emu->fx8010.lock);
1120 static int snd_emu10k1_ipcm_poke(emu10k1_t *emu, emu10k1_fx8010_pcm_t *ipcm)
1124 snd_emu10k1_fx8010_pcm_t *pcm;
1126 if (ipcm->substream >= EMU10K1_FX8010_PCM_COUNT)
1128 if (ipcm->channels > 32)
1130 pcm = &emu->fx8010.pcm[ipcm->substream];
1131 down(&emu->fx8010.lock);
1132 spin_lock_irq(&emu->reg_lock);
1137 if (ipcm->channels == 0) { /* remove */
1140 /* FIXME: we need to add universal code to the PCM transfer routine */
1141 if (ipcm->channels != 2) {
1147 pcm->channels = ipcm->channels;
1148 pcm->tram_start = ipcm->tram_start;
1149 pcm->buffer_size = ipcm->buffer_size;
1150 pcm->gpr_size = ipcm->gpr_size;
1151 pcm->gpr_count = ipcm->gpr_count;
1152 pcm->gpr_tmpcount = ipcm->gpr_tmpcount;
1153 pcm->gpr_ptr = ipcm->gpr_ptr;
1154 pcm->gpr_trigger = ipcm->gpr_trigger;
1155 pcm->gpr_running = ipcm->gpr_running;
1156 for (i = 0; i < pcm->channels; i++)
1157 pcm->etram[i] = ipcm->etram[i];
1160 spin_unlock_irq(&emu->reg_lock);
1161 up(&emu->fx8010.lock);
1165 static int snd_emu10k1_ipcm_peek(emu10k1_t *emu, emu10k1_fx8010_pcm_t *ipcm)
1169 snd_emu10k1_fx8010_pcm_t *pcm;
1171 if (ipcm->substream >= EMU10K1_FX8010_PCM_COUNT)
1173 pcm = &emu->fx8010.pcm[ipcm->substream];
1174 down(&emu->fx8010.lock);
1175 spin_lock_irq(&emu->reg_lock);
1176 ipcm->channels = pcm->channels;
1177 ipcm->tram_start = pcm->tram_start;
1178 ipcm->buffer_size = pcm->buffer_size;
1179 ipcm->gpr_size = pcm->gpr_size;
1180 ipcm->gpr_ptr = pcm->gpr_ptr;
1181 ipcm->gpr_count = pcm->gpr_count;
1182 ipcm->gpr_tmpcount = pcm->gpr_tmpcount;
1183 ipcm->gpr_trigger = pcm->gpr_trigger;
1184 ipcm->gpr_running = pcm->gpr_running;
1185 for (i = 0; i < pcm->channels; i++)
1186 ipcm->etram[i] = pcm->etram[i];
1187 ipcm->res1 = ipcm->res2 = 0;
1189 spin_unlock_irq(&emu->reg_lock);
1190 up(&emu->fx8010.lock);
1194 #define SND_EMU10K1_GPR_CONTROLS 41
1195 #define SND_EMU10K1_INPUTS 10
1196 #define SND_EMU10K1_PLAYBACK_CHANNELS 6
1197 #define SND_EMU10K1_CAPTURE_CHANNELS 4
1199 static void __devinit snd_emu10k1_init_mono_control(emu10k1_fx8010_control_gpr_t *ctl, const char *name, int gpr, int defval)
1201 ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1202 strcpy(ctl->id.name, name);
1203 ctl->vcount = ctl->count = 1;
1204 ctl->gpr[0] = gpr + 0; ctl->value[0] = defval;
1207 ctl->translation = EMU10K1_GPR_TRANSLATION_TABLE100;
1210 static void __devinit snd_emu10k1_init_stereo_control(emu10k1_fx8010_control_gpr_t *ctl, const char *name, int gpr, int defval)
1212 ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1213 strcpy(ctl->id.name, name);
1214 ctl->vcount = ctl->count = 2;
1215 ctl->gpr[0] = gpr + 0; ctl->value[0] = defval;
1216 ctl->gpr[1] = gpr + 1; ctl->value[1] = defval;
1219 ctl->translation = EMU10K1_GPR_TRANSLATION_TABLE100;
1222 static void __devinit snd_emu10k1_init_mono_onoff_control(emu10k1_fx8010_control_gpr_t *ctl, const char *name, int gpr, int defval)
1224 ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1225 strcpy(ctl->id.name, name);
1226 ctl->vcount = ctl->count = 1;
1227 ctl->gpr[0] = gpr + 0; ctl->value[0] = defval;
1230 ctl->translation = EMU10K1_GPR_TRANSLATION_ONOFF;
1233 static void __devinit snd_emu10k1_init_stereo_onoff_control(emu10k1_fx8010_control_gpr_t *ctl, const char *name, int gpr, int defval)
1235 ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1236 strcpy(ctl->id.name, name);
1237 ctl->vcount = ctl->count = 2;
1238 ctl->gpr[0] = gpr + 0; ctl->value[0] = defval;
1239 ctl->gpr[1] = gpr + 1; ctl->value[1] = defval;
1242 ctl->translation = EMU10K1_GPR_TRANSLATION_ONOFF;
1247 * initial DSP configuration for Audigy
1250 static int __devinit _snd_emu10k1_audigy_init_efx(emu10k1_t *emu)
1252 int err, i, z, gpr, nctl;
1253 const int playback = 10;
1254 const int capture = playback + (SND_EMU10K1_PLAYBACK_CHANNELS * 2); /* we reserve 10 voices */
1255 const int stereo_mix = capture + 2;
1256 const int tmp = 0x88;
1258 emu10k1_fx8010_code_t *icode;
1259 emu10k1_fx8010_control_gpr_t *controls, *ctl;
1262 spin_lock_init(&emu->fx8010.irq_lock);
1263 INIT_LIST_HEAD(&emu->fx8010.gpr_ctl);
1265 if ((icode = snd_kcalloc(sizeof(emu10k1_fx8010_code_t), GFP_KERNEL)) == NULL)
1267 if ((controls = snd_kcalloc(sizeof(emu10k1_fx8010_control_gpr_t) * SND_EMU10K1_GPR_CONTROLS, GFP_KERNEL)) == NULL) {
1272 /* clear free GPRs */
1273 for (i = 0; i < 256; i++)
1274 set_bit(i, icode->gpr_valid);
1276 strcpy(icode->name, "Audigy DSP code for ALSA");
1279 gpr = stereo_mix + 10;
1281 /* stop FX processor */
1282 snd_emu10k1_ptr_write(emu, A_DBG, 0, (emu->fx8010.dbg = 0) | A_DBG_SINGLE_STEP);
1284 /* PCM front Playback Volume (independent from stereo mix) */
1285 A_OP(icode, &ptr, iMAC0, A_GPR(playback), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LEFT_FRONT));
1286 A_OP(icode, &ptr, iMAC0, A_GPR(playback+1), A_C_00000000, A_GPR(gpr+1), A_FXBUS(FXBUS_PCM_RIGHT_FRONT));
1287 snd_emu10k1_init_stereo_control(&controls[nctl++], "PCM Front Playback Volume", gpr, 100);
1290 /* PCM Surround Playback (independent from stereo mix) */
1291 A_OP(icode, &ptr, iMAC0, A_GPR(playback+2), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LEFT_REAR));
1292 A_OP(icode, &ptr, iMAC0, A_GPR(playback+3), A_C_00000000, A_GPR(gpr+1), A_FXBUS(FXBUS_PCM_RIGHT_REAR));
1293 snd_emu10k1_init_stereo_control(&controls[nctl++], "PCM Surround Playback Volume", gpr, 100);
1296 /* PCM Center Playback (independent from stereo mix) */
1297 A_OP(icode, &ptr, iMAC0, A_GPR(playback+4), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_CENTER));
1298 snd_emu10k1_init_mono_control(&controls[nctl++], "PCM Center Playback Volume", gpr, 100);
1301 /* PCM LFE Playback (independent from stereo mix) */
1302 A_OP(icode, &ptr, iMAC0, A_GPR(playback+5), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LFE));
1303 snd_emu10k1_init_mono_control(&controls[nctl++], "PCM LFE Playback Volume", gpr, 100);
1309 /* Wave (PCM) Playback Volume (will be renamed later) */
1310 A_OP(icode, &ptr, iMAC0, A_GPR(stereo_mix), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LEFT));
1311 A_OP(icode, &ptr, iMAC0, A_GPR(stereo_mix+1), A_C_00000000, A_GPR(gpr+1), A_FXBUS(FXBUS_PCM_RIGHT));
1312 snd_emu10k1_init_stereo_control(&controls[nctl++], "Wave Playback Volume", gpr, 100);
1315 /* Music Playback */
1316 A_OP(icode, &ptr, iMAC0, A_GPR(stereo_mix+0), A_GPR(stereo_mix+0), A_GPR(gpr), A_FXBUS(FXBUS_MIDI_LEFT));
1317 A_OP(icode, &ptr, iMAC0, A_GPR(stereo_mix+1), A_GPR(stereo_mix+1), A_GPR(gpr+1), A_FXBUS(FXBUS_MIDI_RIGHT));
1318 snd_emu10k1_init_stereo_control(&controls[nctl++], "Music Playback Volume", gpr, 100);
1321 /* Wave (PCM) Capture */
1322 A_OP(icode, &ptr, iMAC0, A_GPR(capture+0), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LEFT));
1323 A_OP(icode, &ptr, iMAC0, A_GPR(capture+1), A_C_00000000, A_GPR(gpr+1), A_FXBUS(FXBUS_PCM_RIGHT));
1324 snd_emu10k1_init_stereo_control(&controls[nctl++], "PCM Capture Volume", gpr, 0);
1328 A_OP(icode, &ptr, iMAC0, A_GPR(capture+0), A_GPR(capture+0), A_GPR(gpr), A_FXBUS(FXBUS_MIDI_LEFT));
1329 A_OP(icode, &ptr, iMAC0, A_GPR(capture+1), A_GPR(capture+1), A_GPR(gpr+1), A_FXBUS(FXBUS_MIDI_RIGHT));
1330 snd_emu10k1_init_stereo_control(&controls[nctl++], "Music Capture Volume", gpr, 0);
1336 #define A_ADD_VOLUME_IN(var,vol,input) \
1337 A_OP(icode, &ptr, iMAC0, A_GPR(var), A_GPR(var), A_GPR(vol), A_EXTIN(input))
1339 /* AC'97 Playback Volume - used only for mic (renamed later) */
1340 A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_AC97_L);
1341 A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_AC97_R);
1342 snd_emu10k1_init_stereo_control(&controls[nctl++], "AMic Playback Volume", gpr, 0);
1344 /* AC'97 Capture Volume - used only for mic */
1345 A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_AC97_L);
1346 A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_AC97_R);
1347 snd_emu10k1_init_stereo_control(&controls[nctl++], "Mic Capture Volume", gpr, 0);
1350 /* mic capture buffer */
1351 A_OP(icode, &ptr, iINTERP, A_EXTOUT(A_EXTOUT_MIC_CAP), A_EXTIN(A_EXTIN_AC97_L), 0xcd, A_EXTIN(A_EXTIN_AC97_R));
1353 /* Audigy CD Playback Volume */
1354 A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_SPDIF_CD_L);
1355 A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_SPDIF_CD_R);
1356 snd_emu10k1_init_stereo_control(&controls[nctl++],
1357 emu->no_ac97 ? "CD Playback Volume" : "Audigy CD Playback Volume",
1360 /* Audigy CD Capture Volume */
1361 A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_SPDIF_CD_L);
1362 A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_SPDIF_CD_R);
1363 snd_emu10k1_init_stereo_control(&controls[nctl++],
1364 emu->no_ac97 ? "CD Capture Volume" : "Audigy CD Capture Volume",
1368 /* Optical SPDIF Playback Volume */
1369 A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_OPT_SPDIF_L);
1370 A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_OPT_SPDIF_R);
1371 snd_emu10k1_init_stereo_control(&controls[nctl++], "IEC958 Optical Playback Volume", gpr, 0);
1373 /* Optical SPDIF Capture Volume */
1374 A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_OPT_SPDIF_L);
1375 A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_OPT_SPDIF_R);
1376 snd_emu10k1_init_stereo_control(&controls[nctl++], "IEC958 Optical Capture Volume", gpr, 0);
1379 /* Line2 Playback Volume */
1380 A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_LINE2_L);
1381 A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_LINE2_R);
1382 snd_emu10k1_init_stereo_control(&controls[nctl++],
1383 emu->no_ac97 ? "Line Playback Volume" : "Line2 Playback Volume",
1386 /* Line2 Capture Volume */
1387 A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_LINE2_L);
1388 A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_LINE2_R);
1389 snd_emu10k1_init_stereo_control(&controls[nctl++],
1390 emu->no_ac97 ? "Line Capture Volume" : "Line2 Capture Volume",
1394 /* Philips ADC Playback Volume */
1395 A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_ADC_L);
1396 A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_ADC_R);
1397 snd_emu10k1_init_stereo_control(&controls[nctl++], "Analog Mix Playback Volume", gpr, 0);
1399 /* Philips ADC Capture Volume */
1400 A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_ADC_L);
1401 A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_ADC_R);
1402 snd_emu10k1_init_stereo_control(&controls[nctl++], "Analog Mix Capture Volume", gpr, 0);
1405 /* Aux2 Playback Volume */
1406 A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_AUX2_L);
1407 A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_AUX2_R);
1408 snd_emu10k1_init_stereo_control(&controls[nctl++],
1409 emu->no_ac97 ? "Aux Playback Volume" : "Aux2 Playback Volume",
1412 /* Aux2 Capture Volume */
1413 A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_AUX2_L);
1414 A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_AUX2_R);
1415 snd_emu10k1_init_stereo_control(&controls[nctl++],
1416 emu->no_ac97 ? "Aux Capture Volume" : "Aux2 Capture Volume",
1420 /* Stereo Mix Front Playback Volume */
1421 A_OP(icode, &ptr, iMAC0, A_GPR(playback), A_GPR(playback), A_GPR(gpr), A_GPR(stereo_mix));
1422 A_OP(icode, &ptr, iMAC0, A_GPR(playback+1), A_GPR(playback+1), A_GPR(gpr+1), A_GPR(stereo_mix+1));
1423 snd_emu10k1_init_stereo_control(&controls[nctl++], "Front Playback Volume", gpr, 100);
1426 /* Stereo Mix Surround Playback */
1427 A_OP(icode, &ptr, iMAC0, A_GPR(playback+2), A_GPR(playback+2), A_GPR(gpr), A_GPR(stereo_mix));
1428 A_OP(icode, &ptr, iMAC0, A_GPR(playback+3), A_GPR(playback+3), A_GPR(gpr+1), A_GPR(stereo_mix+1));
1429 snd_emu10k1_init_stereo_control(&controls[nctl++], "Surround Playback Volume", gpr, 0);
1432 /* Stereo Mix Center Playback */
1433 /* Center = sub = Left/2 + Right/2 */
1434 A_OP(icode, &ptr, iINTERP, A_GPR(tmp), A_GPR(stereo_mix), 0xcd, A_GPR(stereo_mix+1));
1435 A_OP(icode, &ptr, iMAC0, A_GPR(playback+4), A_GPR(playback+4), A_GPR(gpr), A_GPR(tmp));
1436 snd_emu10k1_init_mono_control(&controls[nctl++], "Center Playback Volume", gpr, 0);
1439 /* Stereo Mix LFE Playback */
1440 A_OP(icode, &ptr, iMAC0, A_GPR(playback+5), A_GPR(playback+5), A_GPR(gpr), A_GPR(tmp));
1441 snd_emu10k1_init_mono_control(&controls[nctl++], "LFE Playback Volume", gpr, 0);
1447 #define A_PUT_OUTPUT(out,src) A_OP(icode, &ptr, iACC3, A_EXTOUT(out), A_C_00000000, A_C_00000000, A_GPR(src))
1448 #define A_PUT_STEREO_OUTPUT(out1,out2,src) \
1449 {A_PUT_OUTPUT(out1,src); A_PUT_OUTPUT(out2,src+1);}
1451 #define _A_SWITCH(icode, ptr, dst, src, sw) \
1452 A_OP((icode), ptr, iMACINT0, dst, A_C_00000000, src, sw);
1453 #define A_SWITCH(icode, ptr, dst, src, sw) \
1454 _A_SWITCH(icode, ptr, A_GPR(dst), A_GPR(src), A_GPR(sw))
1455 #define _A_SWITCH_NEG(icode, ptr, dst, src) \
1456 A_OP((icode), ptr, iANDXOR, dst, src, A_C_00000001, A_C_00000001);
1457 #define A_SWITCH_NEG(icode, ptr, dst, src) \
1458 _A_SWITCH_NEG(icode, ptr, A_GPR(dst), A_GPR(src))
1462 * Process tone control
1464 A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 0), A_GPR(playback + 0), A_C_00000000, A_C_00000000); /* left */
1465 A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 1), A_GPR(playback + 1), A_C_00000000, A_C_00000000); /* right */
1466 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 */
1467 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 */
1468 A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 4), A_GPR(playback + 4), A_C_00000000, A_C_00000000); /* center */
1469 A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 5), A_GPR(playback + 5), A_C_00000000, A_C_00000000); /* LFE */
1471 ctl = &controls[nctl + 0];
1472 ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1473 strcpy(ctl->id.name, "Tone Control - Bass");
1478 ctl->value[0] = ctl->value[1] = 20;
1479 ctl->translation = EMU10K1_GPR_TRANSLATION_BASS;
1480 ctl = &controls[nctl + 1];
1481 ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1482 strcpy(ctl->id.name, "Tone Control - Treble");
1487 ctl->value[0] = ctl->value[1] = 20;
1488 ctl->translation = EMU10K1_GPR_TRANSLATION_TREBLE;
1490 #define BASS_GPR 0x8c
1491 #define TREBLE_GPR 0x96
1493 for (z = 0; z < 5; z++) {
1495 for (j = 0; j < 2; j++) {
1496 controls[nctl + 0].gpr[z * 2 + j] = BASS_GPR + z * 2 + j;
1497 controls[nctl + 1].gpr[z * 2 + j] = TREBLE_GPR + z * 2 + j;
1500 for (z = 0; z < 3; z++) { /* front/rear/center-lfe */
1502 for (j = 0; j < 2; j++) { /* left/right */
1503 k = 0xb0 + (z * 8) + (j * 4);
1504 l = 0xe0 + (z * 8) + (j * 4);
1505 d = playback + SND_EMU10K1_PLAYBACK_CHANNELS + z * 2 + j;
1507 A_OP(icode, &ptr, iMAC0, A_C_00000000, A_C_00000000, A_GPR(d), A_GPR(BASS_GPR + 0 + j));
1508 A_OP(icode, &ptr, iMACMV, A_GPR(k+1), A_GPR(k), A_GPR(k+1), A_GPR(BASS_GPR + 4 + j));
1509 A_OP(icode, &ptr, iMACMV, A_GPR(k), A_GPR(d), A_GPR(k), A_GPR(BASS_GPR + 2 + j));
1510 A_OP(icode, &ptr, iMACMV, A_GPR(k+3), A_GPR(k+2), A_GPR(k+3), A_GPR(BASS_GPR + 8 + j));
1511 A_OP(icode, &ptr, iMAC0, A_GPR(k+2), A_GPR_ACCU, A_GPR(k+2), A_GPR(BASS_GPR + 6 + j));
1512 A_OP(icode, &ptr, iACC3, A_GPR(k+2), A_GPR(k+2), A_GPR(k+2), A_C_00000000);
1514 A_OP(icode, &ptr, iMAC0, A_C_00000000, A_C_00000000, A_GPR(k+2), A_GPR(TREBLE_GPR + 0 + j));
1515 A_OP(icode, &ptr, iMACMV, A_GPR(l+1), A_GPR(l), A_GPR(l+1), A_GPR(TREBLE_GPR + 4 + j));
1516 A_OP(icode, &ptr, iMACMV, A_GPR(l), A_GPR(k+2), A_GPR(l), A_GPR(TREBLE_GPR + 2 + j));
1517 A_OP(icode, &ptr, iMACMV, A_GPR(l+3), A_GPR(l+2), A_GPR(l+3), A_GPR(TREBLE_GPR + 8 + j));
1518 A_OP(icode, &ptr, iMAC0, A_GPR(l+2), A_GPR_ACCU, A_GPR(l+2), A_GPR(TREBLE_GPR + 6 + j));
1519 A_OP(icode, &ptr, iMACINT0, A_GPR(l+2), A_C_00000000, A_GPR(l+2), A_C_00000010);
1521 A_OP(icode, &ptr, iACC3, A_GPR(d), A_GPR(l+2), A_C_00000000, A_C_00000000);
1523 if (z == 2) /* center */
1532 for (z = 0; z < 6; z++) {
1533 A_SWITCH(icode, &ptr, tmp + 0, playback + SND_EMU10K1_PLAYBACK_CHANNELS + z, gpr + 0);
1534 A_SWITCH_NEG(icode, &ptr, tmp + 1, gpr + 0);
1535 A_SWITCH(icode, &ptr, tmp + 1, playback + z, tmp + 1);
1536 A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + z), A_GPR(tmp + 0), A_GPR(tmp + 1), A_C_00000000);
1538 snd_emu10k1_init_stereo_onoff_control(controls + nctl++, "Tone Control - Switch", gpr, 0);
1541 /* Master volume (will be renamed later) */
1542 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));
1543 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));
1544 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));
1545 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));
1546 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));
1547 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));
1548 snd_emu10k1_init_stereo_control(&controls[nctl++], "Wave Master Playback Volume", gpr, 0);
1551 /* analog speakers */
1552 A_PUT_STEREO_OUTPUT(A_EXTOUT_AFRONT_L, A_EXTOUT_AFRONT_R, playback + SND_EMU10K1_PLAYBACK_CHANNELS);
1553 A_PUT_STEREO_OUTPUT(A_EXTOUT_AREAR_L, A_EXTOUT_AREAR_R, playback+2 + SND_EMU10K1_PLAYBACK_CHANNELS);
1554 A_PUT_OUTPUT(A_EXTOUT_ACENTER, playback+4 + SND_EMU10K1_PLAYBACK_CHANNELS);
1555 A_PUT_OUTPUT(A_EXTOUT_ALFE, playback+5 + SND_EMU10K1_PLAYBACK_CHANNELS);
1558 A_PUT_STEREO_OUTPUT(A_EXTOUT_HEADPHONE_L, A_EXTOUT_HEADPHONE_R, playback + SND_EMU10K1_PLAYBACK_CHANNELS);
1560 /* digital outputs */
1561 /* A_PUT_STEREO_OUTPUT(A_EXTOUT_FRONT_L, A_EXTOUT_FRONT_R, playback + SND_EMU10K1_PLAYBACK_CHANNELS); */
1563 /* IEC958 Optical Raw Playback Switch */
1564 icode->gpr_map[gpr++] = 0x1008;
1565 icode->gpr_map[gpr++] = 0xffff0000;
1566 for (z = 0; z < 2; z++) {
1567 A_OP(icode, &ptr, iMAC0, A_GPR(tmp + 2), A_FXBUS(FXBUS_PT_LEFT + z), A_C_00000000, A_C_00000000);
1568 A_OP(icode, &ptr, iSKIP, A_GPR_COND, A_GPR_COND, A_GPR(gpr - 2), A_C_00000001);
1569 A_OP(icode, &ptr, iACC3, A_GPR(tmp + 2), A_C_00000000, A_C_00010000, A_GPR(tmp + 2));
1570 A_OP(icode, &ptr, iANDXOR, A_GPR(tmp + 2), A_GPR(tmp + 2), A_GPR(gpr - 1), A_C_00000000);
1571 A_SWITCH(icode, &ptr, tmp + 0, tmp + 2, gpr + z);
1572 A_SWITCH_NEG(icode, &ptr, tmp + 1, gpr + z);
1573 A_SWITCH(icode, &ptr, tmp + 1, playback + SND_EMU10K1_PLAYBACK_CHANNELS + z, tmp + 1);
1574 A_OP(icode, &ptr, iACC3, A_EXTOUT(A_EXTOUT_FRONT_L + z), A_GPR(tmp + 0), A_GPR(tmp + 1), A_C_00000000);
1576 snd_emu10k1_init_stereo_onoff_control(controls + nctl++, "IEC958 Optical Raw Playback Switch", gpr, 0);
1579 A_PUT_STEREO_OUTPUT(A_EXTOUT_REAR_L, A_EXTOUT_REAR_R, playback+2 + SND_EMU10K1_PLAYBACK_CHANNELS);
1580 A_PUT_OUTPUT(A_EXTOUT_CENTER, playback+4 + SND_EMU10K1_PLAYBACK_CHANNELS);
1581 A_PUT_OUTPUT(A_EXTOUT_LFE, playback+5 + SND_EMU10K1_PLAYBACK_CHANNELS);
1584 A_PUT_OUTPUT(A_EXTOUT_ADC_CAP_L, capture);
1585 A_PUT_OUTPUT(A_EXTOUT_ADC_CAP_R, capture+1);
1596 /* clear remaining instruction memory */
1598 A_OP(icode, &ptr, 0x0f, 0xc0, 0xc0, 0xcf, 0xc0);
1600 seg = snd_enter_user();
1601 icode->gpr_add_control_count = nctl;
1602 icode->gpr_add_controls = controls;
1603 err = snd_emu10k1_icode_poke(emu, icode);
1604 snd_leave_user(seg);
1614 * initial DSP configuration for Emu10k1
1617 /* when volume = max, then copy only to avoid volume modification */
1618 /* with iMAC0 (negative values) */
1619 static void __devinit _volume(emu10k1_fx8010_code_t *icode, u32 *ptr, u32 dst, u32 src, u32 vol)
1621 OP(icode, ptr, iMAC0, dst, C_00000000, src, vol);
1622 OP(icode, ptr, iANDXOR, C_00000000, vol, C_ffffffff, C_7fffffff);
1623 OP(icode, ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, C_00000001);
1624 OP(icode, ptr, iACC3, dst, src, C_00000000, C_00000000);
1626 static void __devinit _volume_add(emu10k1_fx8010_code_t *icode, u32 *ptr, u32 dst, u32 src, u32 vol)
1628 OP(icode, ptr, iANDXOR, C_00000000, vol, C_ffffffff, C_7fffffff);
1629 OP(icode, ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, C_00000002);
1630 OP(icode, ptr, iMACINT0, dst, dst, src, C_00000001);
1631 OP(icode, ptr, iSKIP, C_00000000, C_7fffffff, C_7fffffff, C_00000001);
1632 OP(icode, ptr, iMAC0, dst, dst, src, vol);
1634 static void __devinit _volume_out(emu10k1_fx8010_code_t *icode, u32 *ptr, u32 dst, u32 src, u32 vol)
1636 OP(icode, ptr, iANDXOR, C_00000000, vol, C_ffffffff, C_7fffffff);
1637 OP(icode, ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, C_00000002);
1638 OP(icode, ptr, iACC3, dst, src, C_00000000, C_00000000);
1639 OP(icode, ptr, iSKIP, C_00000000, C_7fffffff, C_7fffffff, C_00000001);
1640 OP(icode, ptr, iMAC0, dst, C_00000000, src, vol);
1643 #define VOLUME(icode, ptr, dst, src, vol) \
1644 _volume(icode, ptr, GPR(dst), GPR(src), GPR(vol))
1645 #define VOLUME_IN(icode, ptr, dst, src, vol) \
1646 _volume(icode, ptr, GPR(dst), EXTIN(src), GPR(vol))
1647 #define VOLUME_ADD(icode, ptr, dst, src, vol) \
1648 _volume_add(icode, ptr, GPR(dst), GPR(src), GPR(vol))
1649 #define VOLUME_ADDIN(icode, ptr, dst, src, vol) \
1650 _volume_add(icode, ptr, GPR(dst), EXTIN(src), GPR(vol))
1651 #define VOLUME_OUT(icode, ptr, dst, src, vol) \
1652 _volume_out(icode, ptr, EXTOUT(dst), GPR(src), GPR(vol))
1653 #define _SWITCH(icode, ptr, dst, src, sw) \
1654 OP((icode), ptr, iMACINT0, dst, C_00000000, src, sw);
1655 #define SWITCH(icode, ptr, dst, src, sw) \
1656 _SWITCH(icode, ptr, GPR(dst), GPR(src), GPR(sw))
1657 #define SWITCH_IN(icode, ptr, dst, src, sw) \
1658 _SWITCH(icode, ptr, GPR(dst), EXTIN(src), GPR(sw))
1659 #define _SWITCH_NEG(icode, ptr, dst, src) \
1660 OP((icode), ptr, iANDXOR, dst, src, C_00000001, C_00000001);
1661 #define SWITCH_NEG(icode, ptr, dst, src) \
1662 _SWITCH_NEG(icode, ptr, GPR(dst), GPR(src))
1665 static int __devinit _snd_emu10k1_init_efx(emu10k1_t *emu)
1667 int err, i, z, gpr, tmp, playback, capture;
1669 emu10k1_fx8010_code_t *icode;
1670 emu10k1_fx8010_pcm_t *ipcm;
1671 emu10k1_fx8010_control_gpr_t *controls, *ctl;
1674 spin_lock_init(&emu->fx8010.irq_lock);
1675 INIT_LIST_HEAD(&emu->fx8010.gpr_ctl);
1677 if ((icode = snd_kcalloc(sizeof(emu10k1_fx8010_code_t), GFP_KERNEL)) == NULL)
1679 if ((controls = snd_kcalloc(sizeof(emu10k1_fx8010_control_gpr_t) * SND_EMU10K1_GPR_CONTROLS, GFP_KERNEL)) == NULL) {
1683 if ((ipcm = snd_kcalloc(sizeof(emu10k1_fx8010_pcm_t), GFP_KERNEL)) == NULL) {
1689 /* clear free GPRs */
1690 for (i = 0; i < 256; i++)
1691 set_bit(i, icode->gpr_valid);
1693 /* clear TRAM data & address lines */
1694 for (i = 0; i < 160; i++)
1695 set_bit(i, icode->tram_valid);
1697 strcpy(icode->name, "SB Live! FX8010 code for ALSA v1.2 by Jaroslav Kysela");
1699 /* we have 10 inputs */
1700 playback = SND_EMU10K1_INPUTS;
1701 /* we have 6 playback channels and tone control doubles */
1702 capture = playback + (SND_EMU10K1_PLAYBACK_CHANNELS * 2);
1703 gpr = capture + SND_EMU10K1_CAPTURE_CHANNELS;
1704 tmp = 0x88; /* we need 4 temporary GPR */
1705 /* from 0x8c to 0xff is the area for tone control */
1707 /* stop FX processor */
1708 snd_emu10k1_ptr_write(emu, DBG, 0, (emu->fx8010.dbg = 0) | EMU10K1_DBG_SINGLE_STEP);
1713 OP(icode, &ptr, iMACINT0, GPR(0), C_00000000, FXBUS(FXBUS_PCM_LEFT), C_00000004);
1714 OP(icode, &ptr, iMACINT0, GPR(1), C_00000000, FXBUS(FXBUS_PCM_RIGHT), C_00000004);
1715 OP(icode, &ptr, iMACINT0, GPR(2), C_00000000, FXBUS(FXBUS_MIDI_LEFT), C_00000004);
1716 OP(icode, &ptr, iMACINT0, GPR(3), C_00000000, FXBUS(FXBUS_MIDI_RIGHT), C_00000004);
1717 OP(icode, &ptr, iMACINT0, GPR(4), C_00000000, FXBUS(FXBUS_PCM_LEFT_REAR), C_00000004);
1718 OP(icode, &ptr, iMACINT0, GPR(5), C_00000000, FXBUS(FXBUS_PCM_RIGHT_REAR), C_00000004);
1719 OP(icode, &ptr, iMACINT0, GPR(6), C_00000000, FXBUS(FXBUS_PCM_CENTER), C_00000004);
1720 OP(icode, &ptr, iMACINT0, GPR(7), C_00000000, FXBUS(FXBUS_PCM_LFE), C_00000004);
1721 OP(icode, &ptr, iMACINT0, GPR(8), C_00000000, C_00000000, C_00000000); /* S/PDIF left */
1722 OP(icode, &ptr, iMACINT0, GPR(9), C_00000000, C_00000000, C_00000000); /* S/PDIF right */
1724 /* Raw S/PDIF PCM */
1725 ipcm->substream = 0;
1727 ipcm->tram_start = 0;
1728 ipcm->buffer_size = (64 * 1024) / 2;
1729 ipcm->gpr_size = gpr++;
1730 ipcm->gpr_ptr = gpr++;
1731 ipcm->gpr_count = gpr++;
1732 ipcm->gpr_tmpcount = gpr++;
1733 ipcm->gpr_trigger = gpr++;
1734 ipcm->gpr_running = gpr++;
1738 icode->gpr_map[gpr + 0] = 0xfffff000;
1739 icode->gpr_map[gpr + 1] = 0xffff0000;
1740 icode->gpr_map[gpr + 2] = 0x70000000;
1741 icode->gpr_map[gpr + 3] = 0x00000007;
1742 icode->gpr_map[gpr + 4] = 0x001f << 11;
1743 icode->gpr_map[gpr + 5] = 0x001c << 11;
1744 icode->gpr_map[gpr + 6] = (0x22 - 0x01) - 1; /* skip at 01 to 22 */
1745 icode->gpr_map[gpr + 7] = (0x22 - 0x06) - 1; /* skip at 06 to 22 */
1746 icode->gpr_map[gpr + 8] = 0x2000000 + (2<<11);
1747 icode->gpr_map[gpr + 9] = 0x4000000 + (2<<11);
1748 icode->gpr_map[gpr + 10] = 1<<11;
1749 icode->gpr_map[gpr + 11] = (0x24 - 0x0a) - 1; /* skip at 0a to 24 */
1750 icode->gpr_map[gpr + 12] = 0;
1752 /* if the trigger flag is not set, skip */
1753 /* 00: */ OP(icode, &ptr, iMAC0, C_00000000, GPR(ipcm->gpr_trigger), C_00000000, C_00000000);
1754 /* 01: */ OP(icode, &ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_ZERO, GPR(gpr + 6));
1755 /* if the running flag is set, we're running */
1756 /* 02: */ OP(icode, &ptr, iMAC0, C_00000000, GPR(ipcm->gpr_running), C_00000000, C_00000000);
1757 /* 03: */ OP(icode, &ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, C_00000004);
1758 /* wait until ((GPR_DBAC>>11) & 0x1f) == 0x1c) */
1759 /* 04: */ OP(icode, &ptr, iANDXOR, GPR(tmp + 0), GPR_DBAC, GPR(gpr + 4), C_00000000);
1760 /* 05: */ OP(icode, &ptr, iMACINT0, C_00000000, GPR(tmp + 0), C_ffffffff, GPR(gpr + 5));
1761 /* 06: */ OP(icode, &ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, GPR(gpr + 7));
1762 /* 07: */ OP(icode, &ptr, iACC3, GPR(gpr + 12), C_00000010, C_00000001, C_00000000);
1764 /* 08: */ OP(icode, &ptr, iANDXOR, GPR(ipcm->gpr_running), GPR(ipcm->gpr_running), C_00000000, C_00000001);
1765 /* 09: */ OP(icode, &ptr, iACC3, GPR(gpr + 12), GPR(gpr + 12), C_ffffffff, C_00000000);
1766 /* 0a: */ OP(icode, &ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, GPR(gpr + 11));
1767 /* 0b: */ OP(icode, &ptr, iACC3, GPR(gpr + 12), C_00000001, C_00000000, C_00000000);
1769 /* 0c: */ OP(icode, &ptr, iANDXOR, GPR(tmp + 0), ETRAM_DATA(ipcm->etram[0]), GPR(gpr + 0), C_00000000);
1770 /* 0d: */ OP(icode, &ptr, iLOG, GPR(tmp + 0), GPR(tmp + 0), GPR(gpr + 3), C_00000000);
1771 /* 0e: */ OP(icode, &ptr, iANDXOR, GPR(8), GPR(tmp + 0), GPR(gpr + 1), GPR(gpr + 2));
1772 /* 0f: */ OP(icode, &ptr, iSKIP, C_00000000, GPR_COND, CC_REG_MINUS, C_00000001);
1773 /* 10: */ OP(icode, &ptr, iANDXOR, GPR(8), GPR(8), GPR(gpr + 1), GPR(gpr + 2));
1775 /* 11: */ OP(icode, &ptr, iANDXOR, GPR(tmp + 0), ETRAM_DATA(ipcm->etram[1]), GPR(gpr + 0), C_00000000);
1776 /* 12: */ OP(icode, &ptr, iLOG, GPR(tmp + 0), GPR(tmp + 0), GPR(gpr + 3), C_00000000);
1777 /* 13: */ OP(icode, &ptr, iANDXOR, GPR(9), GPR(tmp + 0), GPR(gpr + 1), GPR(gpr + 2));
1778 /* 14: */ OP(icode, &ptr, iSKIP, C_00000000, GPR_COND, CC_REG_MINUS, C_00000001);
1779 /* 15: */ OP(icode, &ptr, iANDXOR, GPR(9), GPR(9), GPR(gpr + 1), GPR(gpr + 2));
1781 /* 16: */ OP(icode, &ptr, iACC3, GPR(tmp + 0), GPR(ipcm->gpr_ptr), C_00000001, C_00000000);
1782 /* 17: */ OP(icode, &ptr, iMACINT0, C_00000000, GPR(tmp + 0), C_ffffffff, GPR(ipcm->gpr_size));
1783 /* 18: */ OP(icode, &ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_MINUS, C_00000001);
1784 /* 19: */ OP(icode, &ptr, iACC3, GPR(tmp + 0), C_00000000, C_00000000, C_00000000);
1785 /* 1a: */ OP(icode, &ptr, iACC3, GPR(ipcm->gpr_ptr), GPR(tmp + 0), C_00000000, C_00000000);
1787 /* 1b: */ OP(icode, &ptr, iACC3, GPR(ipcm->gpr_tmpcount), GPR(ipcm->gpr_tmpcount), C_ffffffff, C_00000000);
1788 /* 1c: */ OP(icode, &ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, C_00000002);
1789 /* 1d: */ OP(icode, &ptr, iACC3, GPR(ipcm->gpr_tmpcount), GPR(ipcm->gpr_count), C_00000000, C_00000000);
1790 /* 1e: */ OP(icode, &ptr, iACC3, GPR_IRQ, C_80000000, C_00000000, C_00000000);
1791 /* 1f: */ OP(icode, &ptr, iANDXOR, GPR(ipcm->gpr_running), GPR(ipcm->gpr_running), C_00000001, C_00010000);
1793 /* 20: */ OP(icode, &ptr, iANDXOR, GPR(ipcm->gpr_running), GPR(ipcm->gpr_running), C_00010000, C_00000001);
1794 /* 21: */ OP(icode, &ptr, iSKIP, C_00000000, C_7fffffff, C_7fffffff, C_00000002);
1796 /* 22: */ OP(icode, &ptr, iMACINT1, ETRAM_ADDR(ipcm->etram[0]), GPR(gpr + 8), GPR_DBAC, C_ffffffff);
1797 /* 23: */ OP(icode, &ptr, iMACINT1, ETRAM_ADDR(ipcm->etram[1]), GPR(gpr + 9), GPR_DBAC, C_ffffffff);
1802 /* Wave Playback Volume */
1803 for (z = 0; z < 2; z++)
1804 VOLUME(icode, &ptr, playback + z, z, gpr + z);
1805 snd_emu10k1_init_stereo_control(controls + i++, "Wave Playback Volume", gpr, 100);
1808 /* Wave Surround Playback Volume */
1809 for (z = 0; z < 2; z++)
1810 VOLUME(icode, &ptr, playback + 2 + z, z, gpr + z);
1811 snd_emu10k1_init_stereo_control(controls + i++, "Wave Surround Playback Volume", gpr, 0);
1814 /* Wave Center/LFE Playback Volume */
1815 OP(icode, &ptr, iACC3, GPR(tmp + 0), FXBUS(FXBUS_PCM_LEFT), FXBUS(FXBUS_PCM_RIGHT), C_00000000);
1816 OP(icode, &ptr, iMACINT0, GPR(tmp + 0), C_00000000, GPR(tmp + 0), C_00000002);
1817 VOLUME(icode, &ptr, playback + 4, tmp + 0, gpr);
1818 snd_emu10k1_init_mono_control(controls + i++, "Wave Center Playback Volume", gpr++, 0);
1819 VOLUME(icode, &ptr, playback + 5, tmp + 0, gpr);
1820 snd_emu10k1_init_mono_control(controls + i++, "Wave LFE Playback Volume", gpr++, 0);
1822 /* Wave Capture Volume + Switch */
1823 for (z = 0; z < 2; z++) {
1824 SWITCH(icode, &ptr, tmp + 0, z, gpr + 2 + z);
1825 VOLUME(icode, &ptr, capture + z, tmp + 0, gpr + z);
1827 snd_emu10k1_init_stereo_control(controls + i++, "Wave Capture Volume", gpr, 0);
1828 snd_emu10k1_init_stereo_onoff_control(controls + i++, "Wave Capture Switch", gpr + 2, 0);
1831 /* Music Playback Volume */
1832 for (z = 0; z < 2; z++)
1833 VOLUME_ADD(icode, &ptr, playback + z, 2 + z, gpr + z);
1834 snd_emu10k1_init_stereo_control(controls + i++, "Music Playback Volume", gpr, 100);
1837 /* Music Capture Volume + Switch */
1838 for (z = 0; z < 2; z++) {
1839 SWITCH(icode, &ptr, tmp + 0, 2 + z, gpr + 2 + z);
1840 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
1842 snd_emu10k1_init_stereo_control(controls + i++, "Music Capture Volume", gpr, 0);
1843 snd_emu10k1_init_stereo_onoff_control(controls + i++, "Music Capture Switch", gpr + 2, 0);
1846 /* Surround Digital Playback Volume (renamed later without Digital) */
1847 for (z = 0; z < 2; z++)
1848 VOLUME_ADD(icode, &ptr, playback + 2 + z, 4 + z, gpr + z);
1849 snd_emu10k1_init_stereo_control(controls + i++, "Surround Digital Playback Volume", gpr, 100);
1852 /* Surround Capture Volume + Switch */
1853 for (z = 0; z < 2; z++) {
1854 SWITCH(icode, &ptr, tmp + 0, 4 + z, gpr + 2 + z);
1855 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
1857 snd_emu10k1_init_stereo_control(controls + i++, "Surround Capture Volume", gpr, 0);
1858 snd_emu10k1_init_stereo_onoff_control(controls + i++, "Surround Capture Switch", gpr + 2, 0);
1861 /* Center Playback Volume (renamed later without Digital) */
1862 VOLUME_ADD(icode, &ptr, playback + 4, 6, gpr);
1863 snd_emu10k1_init_mono_control(controls + i++, "Center Digital Playback Volume", gpr++, 100);
1865 /* LFE Playback Volume + Switch (renamed later without Digital) */
1866 VOLUME_ADD(icode, &ptr, playback + 5, 7, gpr);
1867 snd_emu10k1_init_mono_control(controls + i++, "LFE Digital Playback Volume", gpr++, 100);
1873 if (emu->fx8010.extin_mask & ((1<<EXTIN_AC97_L)|(1<<EXTIN_AC97_R))) {
1874 /* AC'97 Playback Volume */
1875 VOLUME_ADDIN(icode, &ptr, playback + 0, EXTIN_AC97_L, gpr); gpr++;
1876 VOLUME_ADDIN(icode, &ptr, playback + 1, EXTIN_AC97_R, gpr); gpr++;
1877 snd_emu10k1_init_stereo_control(controls + i++, "AC97 Playback Volume", gpr-2, 0);
1878 /* AC'97 Capture Volume */
1879 VOLUME_ADDIN(icode, &ptr, capture + 0, EXTIN_AC97_L, gpr); gpr++;
1880 VOLUME_ADDIN(icode, &ptr, capture + 1, EXTIN_AC97_R, gpr); gpr++;
1881 snd_emu10k1_init_stereo_control(controls + i++, "AC97 Capture Volume", gpr-2, 100);
1884 if (emu->fx8010.extin_mask & ((1<<EXTIN_SPDIF_CD_L)|(1<<EXTIN_SPDIF_CD_R))) {
1885 /* IEC958 TTL Playback Volume */
1886 for (z = 0; z < 2; z++)
1887 VOLUME_ADDIN(icode, &ptr, playback + z, EXTIN_SPDIF_CD_L + z, gpr + z);
1888 snd_emu10k1_init_stereo_control(controls + i++, "IEC958 TTL Playback Volume", gpr, 0);
1891 /* IEC958 TTL Capture Volume + Switch */
1892 for (z = 0; z < 2; z++) {
1893 SWITCH_IN(icode, &ptr, tmp + 0, EXTIN_SPDIF_CD_L + z, gpr + 2 + z);
1894 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
1896 snd_emu10k1_init_stereo_control(controls + i++, "IEC958 TTL Capture Volume", gpr, 0);
1897 snd_emu10k1_init_stereo_onoff_control(controls + i++, "IEC958 TTL Capture Switch", gpr + 2, 0);
1901 if (emu->fx8010.extin_mask & ((1<<EXTIN_ZOOM_L)|(1<<EXTIN_ZOOM_R))) {
1902 /* Zoom Video Playback Volume */
1903 for (z = 0; z < 2; z++)
1904 VOLUME_ADDIN(icode, &ptr, playback + z, EXTIN_ZOOM_L + z, gpr + z);
1905 snd_emu10k1_init_stereo_control(controls + i++, "Zoom Video Playback Volume", gpr, 0);
1908 /* Zoom Video Capture Volume + Switch */
1909 for (z = 0; z < 2; z++) {
1910 SWITCH_IN(icode, &ptr, tmp + 0, EXTIN_ZOOM_L + z, gpr + 2 + z);
1911 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
1913 snd_emu10k1_init_stereo_control(controls + i++, "Zoom Video Capture Volume", gpr, 0);
1914 snd_emu10k1_init_stereo_onoff_control(controls + i++, "Zoom Video Capture Switch", gpr + 2, 0);
1918 if (emu->fx8010.extin_mask & ((1<<EXTIN_TOSLINK_L)|(1<<EXTIN_TOSLINK_R))) {
1919 /* IEC958 Optical Playback Volume */
1920 for (z = 0; z < 2; z++)
1921 VOLUME_ADDIN(icode, &ptr, playback + z, EXTIN_TOSLINK_L + z, gpr + z);
1922 snd_emu10k1_init_stereo_control(controls + i++, "IEC958 LiveDrive Playback Volume", gpr, 0);
1925 /* IEC958 Optical Capture Volume */
1926 for (z = 0; z < 2; z++) {
1927 SWITCH_IN(icode, &ptr, tmp + 0, EXTIN_TOSLINK_L + z, gpr + 2 + z);
1928 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
1930 snd_emu10k1_init_stereo_control(controls + i++, "IEC958 LiveDrive Capture Volume", gpr, 0);
1931 snd_emu10k1_init_stereo_onoff_control(controls + i++, "IEC958 LiveDrive Capture Switch", gpr + 2, 0);
1935 if (emu->fx8010.extin_mask & ((1<<EXTIN_LINE1_L)|(1<<EXTIN_LINE1_R))) {
1936 /* Line LiveDrive Playback Volume */
1937 for (z = 0; z < 2; z++)
1938 VOLUME_ADDIN(icode, &ptr, playback + z, EXTIN_LINE1_L + z, gpr + z);
1939 snd_emu10k1_init_stereo_control(controls + i++, "Line LiveDrive Playback Volume", gpr, 0);
1942 /* Line LiveDrive Capture Volume + Switch */
1943 for (z = 0; z < 2; z++) {
1944 SWITCH_IN(icode, &ptr, tmp + 0, EXTIN_LINE1_L + z, gpr + 2 + z);
1945 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
1947 snd_emu10k1_init_stereo_control(controls + i++, "Line LiveDrive Capture Volume", gpr, 0);
1948 snd_emu10k1_init_stereo_onoff_control(controls + i++, "Line LiveDrive Capture Switch", gpr + 2, 0);
1952 if (emu->fx8010.extin_mask & ((1<<EXTIN_COAX_SPDIF_L)|(1<<EXTIN_COAX_SPDIF_R))) {
1953 /* IEC958 Coax Playback Volume */
1954 for (z = 0; z < 2; z++)
1955 VOLUME_ADDIN(icode, &ptr, playback + z, EXTIN_COAX_SPDIF_L + z, gpr + z);
1956 snd_emu10k1_init_stereo_control(controls + i++, "IEC958 Coaxial Playback Volume", gpr, 0);
1959 /* IEC958 Coax Capture Volume + Switch */
1960 for (z = 0; z < 2; z++) {
1961 SWITCH_IN(icode, &ptr, tmp + 0, EXTIN_COAX_SPDIF_L + z, gpr + 2 + z);
1962 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
1964 snd_emu10k1_init_stereo_control(controls + i++, "IEC958 Coaxial Capture Volume", gpr, 0);
1965 snd_emu10k1_init_stereo_onoff_control(controls + i++, "IEC958 Coaxial Capture Switch", gpr + 2, 0);
1969 if (emu->fx8010.extin_mask & ((1<<EXTIN_LINE2_L)|(1<<EXTIN_LINE2_R))) {
1970 /* Line LiveDrive Playback Volume */
1971 for (z = 0; z < 2; z++)
1972 VOLUME_ADDIN(icode, &ptr, playback + z, EXTIN_LINE2_L + z, gpr + z);
1973 snd_emu10k1_init_stereo_control(controls + i++, "Line2 LiveDrive Playback Volume", gpr, 0);
1974 controls[i-1].id.index = 1;
1977 /* Line LiveDrive Capture Volume */
1978 for (z = 0; z < 2; z++) {
1979 SWITCH_IN(icode, &ptr, tmp + 0, EXTIN_LINE2_L + z, gpr + 2 + z);
1980 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
1982 snd_emu10k1_init_stereo_control(controls + i++, "Line2 LiveDrive Capture Volume", gpr, 0);
1983 controls[i-1].id.index = 1;
1984 snd_emu10k1_init_stereo_onoff_control(controls + i++, "Line2 LiveDrive Capture Switch", gpr + 2, 0);
1985 controls[i-1].id.index = 1;
1990 * Process tone control
1992 OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 0), GPR(playback + 0), C_00000000, C_00000000); /* left */
1993 OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 1), GPR(playback + 1), C_00000000, C_00000000); /* right */
1994 OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 2), GPR(playback + 2), C_00000000, C_00000000); /* rear left */
1995 OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 3), GPR(playback + 3), C_00000000, C_00000000); /* rear right */
1996 OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 4), GPR(playback + 4), C_00000000, C_00000000); /* center */
1997 OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 5), GPR(playback + 5), C_00000000, C_00000000); /* LFE */
1999 ctl = &controls[i + 0];
2000 ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
2001 strcpy(ctl->id.name, "Tone Control - Bass");
2006 ctl->value[0] = ctl->value[1] = 20;
2007 ctl->translation = EMU10K1_GPR_TRANSLATION_BASS;
2008 ctl = &controls[i + 1];
2009 ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
2010 strcpy(ctl->id.name, "Tone Control - Treble");
2015 ctl->value[0] = ctl->value[1] = 20;
2016 ctl->translation = EMU10K1_GPR_TRANSLATION_TREBLE;
2018 #define BASS_GPR 0x8c
2019 #define TREBLE_GPR 0x96
2021 for (z = 0; z < 5; z++) {
2023 for (j = 0; j < 2; j++) {
2024 controls[i + 0].gpr[z * 2 + j] = BASS_GPR + z * 2 + j;
2025 controls[i + 1].gpr[z * 2 + j] = TREBLE_GPR + z * 2 + j;
2028 for (z = 0; z < 3; z++) { /* front/rear/center-lfe */
2030 for (j = 0; j < 2; j++) { /* left/right */
2031 k = 0xa0 + (z * 8) + (j * 4);
2032 l = 0xd0 + (z * 8) + (j * 4);
2033 d = playback + SND_EMU10K1_PLAYBACK_CHANNELS + z * 2 + j;
2035 OP(icode, &ptr, iMAC0, C_00000000, C_00000000, GPR(d), GPR(BASS_GPR + 0 + j));
2036 OP(icode, &ptr, iMACMV, GPR(k+1), GPR(k), GPR(k+1), GPR(BASS_GPR + 4 + j));
2037 OP(icode, &ptr, iMACMV, GPR(k), GPR(d), GPR(k), GPR(BASS_GPR + 2 + j));
2038 OP(icode, &ptr, iMACMV, GPR(k+3), GPR(k+2), GPR(k+3), GPR(BASS_GPR + 8 + j));
2039 OP(icode, &ptr, iMAC0, GPR(k+2), GPR_ACCU, GPR(k+2), GPR(BASS_GPR + 6 + j));
2040 OP(icode, &ptr, iACC3, GPR(k+2), GPR(k+2), GPR(k+2), C_00000000);
2042 OP(icode, &ptr, iMAC0, C_00000000, C_00000000, GPR(k+2), GPR(TREBLE_GPR + 0 + j));
2043 OP(icode, &ptr, iMACMV, GPR(l+1), GPR(l), GPR(l+1), GPR(TREBLE_GPR + 4 + j));
2044 OP(icode, &ptr, iMACMV, GPR(l), GPR(k+2), GPR(l), GPR(TREBLE_GPR + 2 + j));
2045 OP(icode, &ptr, iMACMV, GPR(l+3), GPR(l+2), GPR(l+3), GPR(TREBLE_GPR + 8 + j));
2046 OP(icode, &ptr, iMAC0, GPR(l+2), GPR_ACCU, GPR(l+2), GPR(TREBLE_GPR + 6 + j));
2047 OP(icode, &ptr, iMACINT0, GPR(l+2), C_00000000, GPR(l+2), C_00000010);
2049 OP(icode, &ptr, iACC3, GPR(d), GPR(l+2), C_00000000, C_00000000);
2051 if (z == 2) /* center */
2060 for (z = 0; z < 6; z++) {
2061 SWITCH(icode, &ptr, tmp + 0, playback + SND_EMU10K1_PLAYBACK_CHANNELS + z, gpr + 0);
2062 SWITCH_NEG(icode, &ptr, tmp + 1, gpr + 0);
2063 SWITCH(icode, &ptr, tmp + 1, playback + z, tmp + 1);
2064 OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + z), GPR(tmp + 0), GPR(tmp + 1), C_00000000);
2066 snd_emu10k1_init_stereo_onoff_control(controls + i++, "Tone Control - Switch", gpr, 0);
2072 if (emu->fx8010.extout_mask & ((1<<EXTOUT_AC97_L)|(1<<EXTOUT_AC97_R))) {
2073 /* AC'97 Playback Volume */
2075 for (z = 0; z < 2; z++)
2076 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_AC97_L + z), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + z), C_00000000, C_00000000);
2079 if (emu->fx8010.extout_mask & ((1<<EXTOUT_TOSLINK_L)|(1<<EXTOUT_TOSLINK_R))) {
2080 /* IEC958 Optical Raw Playback Switch */
2082 for (z = 0; z < 2; z++) {
2083 SWITCH(icode, &ptr, tmp + 0, 8 + z, gpr + z);
2084 SWITCH_NEG(icode, &ptr, tmp + 1, gpr + z);
2085 SWITCH(icode, &ptr, tmp + 1, playback + SND_EMU10K1_PLAYBACK_CHANNELS + z, tmp + 1);
2086 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_TOSLINK_L + z), GPR(tmp + 0), GPR(tmp + 1), C_00000000);
2087 #ifdef EMU10K1_CAPTURE_DIGITAL_OUT
2088 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_ADC_CAP_L + z), GPR(tmp + 0), GPR(tmp + 1), C_00000000);
2092 snd_emu10k1_init_stereo_onoff_control(controls + i++, "IEC958 Optical Raw Playback Switch", gpr, 0);
2096 if (emu->fx8010.extout_mask & ((1<<EXTOUT_HEADPHONE_L)|(1<<EXTOUT_HEADPHONE_R))) {
2097 /* Headphone Playback Volume */
2099 for (z = 0; z < 2; z++) {
2100 SWITCH(icode, &ptr, tmp + 0, playback + SND_EMU10K1_PLAYBACK_CHANNELS + 4 + z, gpr + 2 + z);
2101 SWITCH_NEG(icode, &ptr, tmp + 1, gpr + 2 + z);
2102 SWITCH(icode, &ptr, tmp + 1, playback + SND_EMU10K1_PLAYBACK_CHANNELS + z, tmp + 1);
2103 OP(icode, &ptr, iACC3, GPR(tmp + 0), GPR(tmp + 0), GPR(tmp + 1), C_00000000);
2104 VOLUME_OUT(icode, &ptr, EXTOUT_HEADPHONE_L + z, tmp + 0, gpr + z);
2107 snd_emu10k1_init_stereo_control(controls + i++, "Headphone Playback Volume", gpr + 0, 0);
2108 controls[i-1].id.index = 1; /* AC'97 can have also Headphone control */
2109 snd_emu10k1_init_mono_onoff_control(controls + i++, "Headphone Center Playback Switch", gpr + 2, 0);
2110 controls[i-1].id.index = 1;
2111 snd_emu10k1_init_mono_onoff_control(controls + i++, "Headphone LFE Playback Switch", gpr + 3, 0);
2112 controls[i-1].id.index = 1;
2117 if (emu->fx8010.extout_mask & ((1<<EXTOUT_REAR_L)|(1<<EXTOUT_REAR_R)))
2118 for (z = 0; z < 2; z++)
2119 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_REAR_L + z), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 2 + z), C_00000000, C_00000000);
2121 if (emu->fx8010.extout_mask & ((1<<EXTOUT_AC97_REAR_L)|(1<<EXTOUT_AC97_REAR_R)))
2122 for (z = 0; z < 2; z++)
2123 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_AC97_REAR_L + z), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 2 + z), C_00000000, C_00000000);
2125 if (emu->fx8010.extout_mask & (1<<EXTOUT_AC97_CENTER)) {
2126 #ifndef EMU10K1_CENTER_LFE_FROM_FRONT
2127 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_AC97_CENTER), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 4), C_00000000, C_00000000);
2128 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_ACENTER), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 4), C_00000000, C_00000000);
2130 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_AC97_CENTER), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 0), C_00000000, C_00000000);
2131 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_ACENTER), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 0), C_00000000, C_00000000);
2135 if (emu->fx8010.extout_mask & (1<<EXTOUT_AC97_LFE)) {
2136 #ifndef EMU10K1_CENTER_LFE_FROM_FRONT
2137 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_AC97_LFE), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 5), C_00000000, C_00000000);
2138 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_ALFE), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 5), C_00000000, C_00000000);
2140 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_AC97_LFE), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 1), C_00000000, C_00000000);
2141 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_ALFE), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 1), C_00000000, C_00000000);
2145 #ifndef EMU10K1_CAPTURE_DIGITAL_OUT
2146 for (z = 0; z < 2; z++)
2147 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_ADC_CAP_L + z), GPR(capture + z), C_00000000, C_00000000);
2150 if (emu->fx8010.extout_mask & (1<<EXTOUT_MIC_CAP))
2151 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_MIC_CAP), GPR(capture + 2), C_00000000, C_00000000);
2158 if (i > SND_EMU10K1_GPR_CONTROLS) {
2164 /* clear remaining instruction memory */
2166 OP(icode, &ptr, iACC3, C_00000000, C_00000000, C_00000000, C_00000000);
2168 if ((err = snd_emu10k1_fx8010_tram_setup(emu, ipcm->buffer_size)) < 0)
2170 seg = snd_enter_user();
2171 icode->gpr_add_control_count = i;
2172 icode->gpr_add_controls = controls;
2173 err = snd_emu10k1_icode_poke(emu, icode);
2174 snd_leave_user(seg);
2176 err = snd_emu10k1_ipcm_poke(emu, ipcm);
2184 int __devinit snd_emu10k1_init_efx(emu10k1_t *emu)
2187 return _snd_emu10k1_audigy_init_efx(emu);
2189 return _snd_emu10k1_init_efx(emu);
2192 void snd_emu10k1_free_efx(emu10k1_t *emu)
2194 /* stop processor */
2196 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg = A_DBG_SINGLE_STEP);
2198 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg = EMU10K1_DBG_SINGLE_STEP);
2201 #if 0 // FIXME: who use them?
2202 int snd_emu10k1_fx8010_tone_control_activate(emu10k1_t *emu, int output)
2204 snd_runtime_check(output >= 0 && output < 6, return -EINVAL);
2205 snd_emu10k1_ptr_write(emu, emu->gpr_base + 0x94 + output, 0, 1);
2209 int snd_emu10k1_fx8010_tone_control_deactivate(emu10k1_t *emu, int output)
2211 snd_runtime_check(output >= 0 && output < 6, return -EINVAL);
2212 snd_emu10k1_ptr_write(emu, emu->gpr_base + 0x94 + output, 0, 0);
2217 int snd_emu10k1_fx8010_tram_setup(emu10k1_t *emu, u32 size)
2221 /* size is in samples */
2223 size = (size - 1) >> 13;
2229 size = 0x2000 << size_reg;
2231 if (emu->fx8010.etram_pages.bytes == size)
2233 spin_lock_irq(&emu->emu_lock);
2234 outl(HCFG_LOCKTANKCACHE_MASK | inl(emu->port + HCFG), emu->port + HCFG);
2235 spin_unlock_irq(&emu->emu_lock);
2236 snd_emu10k1_ptr_write(emu, TCB, 0, 0);
2237 snd_emu10k1_ptr_write(emu, TCBS, 0, 0);
2238 if (emu->fx8010.etram_pages.area != NULL) {
2239 snd_dma_free_pages(&emu->dma_dev, &emu->fx8010.etram_pages);
2240 emu->fx8010.etram_pages.area = NULL;
2241 emu->fx8010.etram_pages.bytes = 0;
2245 if (snd_dma_alloc_pages(&emu->dma_dev, size * 2, &emu->fx8010.etram_pages) < 0)
2247 memset(emu->fx8010.etram_pages.area, 0, size * 2);
2248 snd_emu10k1_ptr_write(emu, TCB, 0, emu->fx8010.etram_pages.addr);
2249 snd_emu10k1_ptr_write(emu, TCBS, 0, size_reg);
2250 spin_lock_irq(&emu->emu_lock);
2251 outl(inl(emu->port + HCFG) & ~HCFG_LOCKTANKCACHE_MASK, emu->port + HCFG);
2252 spin_unlock_irq(&emu->emu_lock);
2258 static int snd_emu10k1_fx8010_open(snd_hwdep_t * hw, struct file *file)
2263 static void copy_string(char *dst, char *src, char *null, int idx)
2266 sprintf(dst, "%s %02X", null, idx);
2271 static int snd_emu10k1_fx8010_info(emu10k1_t *emu, emu10k1_fx8010_info_t *info)
2273 char **fxbus, **extin, **extout;
2274 unsigned short fxbus_mask, extin_mask, extout_mask;
2277 memset(info, 0, sizeof(info));
2278 info->card = emu->card_type;
2279 info->internal_tram_size = emu->fx8010.itram_size;
2280 info->external_tram_size = emu->fx8010.etram_pages.bytes;
2282 extin = emu->audigy ? audigy_ins : creative_ins;
2283 extout = emu->audigy ? audigy_outs : creative_outs;
2284 fxbus_mask = emu->fx8010.fxbus_mask;
2285 extin_mask = emu->fx8010.extin_mask;
2286 extout_mask = emu->fx8010.extout_mask;
2287 for (res = 0; res < 16; res++, fxbus++, extin++, extout++) {
2288 copy_string(info->fxbus_names[res], fxbus_mask & (1 << res) ? *fxbus : NULL, "FXBUS", res);
2289 copy_string(info->extin_names[res], extin_mask & (1 << res) ? *extin : NULL, "Unused", res);
2290 copy_string(info->extout_names[res], extout_mask & (1 << res) ? *extout : NULL, "Unused", res);
2292 for (res = 16; res < 32; res++, extout++)
2293 copy_string(info->extout_names[res], extout_mask & (1 << res) ? *extout : NULL, "Unused", res);
2294 info->gpr_controls = emu->fx8010.gpr_count;
2298 static int snd_emu10k1_fx8010_ioctl(snd_hwdep_t * hw, struct file *file, unsigned int cmd, unsigned long arg)
2300 emu10k1_t *emu = snd_magic_cast(emu10k1_t, hw->private_data, return -ENXIO);
2301 emu10k1_fx8010_info_t *info;
2302 emu10k1_fx8010_code_t *icode;
2303 emu10k1_fx8010_pcm_t *ipcm;
2305 void __user *argp = (void __user *)arg;
2309 case SNDRV_EMU10K1_IOCTL_INFO:
2310 info = (emu10k1_fx8010_info_t *)kmalloc(sizeof(*info), GFP_KERNEL);
2313 if ((res = snd_emu10k1_fx8010_info(emu, info)) < 0) {
2317 if (copy_to_user(argp, info, sizeof(*info))) {
2323 case SNDRV_EMU10K1_IOCTL_CODE_POKE:
2324 if (!capable(CAP_SYS_ADMIN))
2326 icode = (emu10k1_fx8010_code_t *)kmalloc(sizeof(*icode), GFP_KERNEL);
2329 if (copy_from_user(icode, argp, sizeof(*icode))) {
2333 res = snd_emu10k1_icode_poke(emu, icode);
2336 case SNDRV_EMU10K1_IOCTL_CODE_PEEK:
2337 icode = (emu10k1_fx8010_code_t *)kmalloc(sizeof(*icode), GFP_KERNEL);
2340 if (copy_from_user(icode, argp, sizeof(*icode))) {
2344 res = snd_emu10k1_icode_peek(emu, icode);
2345 if (res == 0 && copy_to_user(argp, icode, sizeof(*icode))) {
2351 case SNDRV_EMU10K1_IOCTL_PCM_POKE:
2354 ipcm = (emu10k1_fx8010_pcm_t *)kmalloc(sizeof(*ipcm), GFP_KERNEL);
2357 if (copy_from_user(ipcm, argp, sizeof(*ipcm))) {
2361 res = snd_emu10k1_ipcm_poke(emu, ipcm);
2364 case SNDRV_EMU10K1_IOCTL_PCM_PEEK:
2367 ipcm = (emu10k1_fx8010_pcm_t *)snd_kcalloc(sizeof(*ipcm), GFP_KERNEL);
2370 if (copy_from_user(ipcm, argp, sizeof(*ipcm))) {
2374 res = snd_emu10k1_ipcm_peek(emu, ipcm);
2375 if (res == 0 && copy_to_user(argp, ipcm, sizeof(*ipcm))) {
2381 case SNDRV_EMU10K1_IOCTL_TRAM_SETUP:
2384 if (!capable(CAP_SYS_ADMIN))
2386 if (get_user(addr, (unsigned int __user *)argp))
2388 down(&emu->fx8010.lock);
2389 res = snd_emu10k1_fx8010_tram_setup(emu, addr);
2390 up(&emu->fx8010.lock);
2392 case SNDRV_EMU10K1_IOCTL_STOP:
2393 if (!capable(CAP_SYS_ADMIN))
2396 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg |= A_DBG_SINGLE_STEP);
2398 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg |= EMU10K1_DBG_SINGLE_STEP);
2400 case SNDRV_EMU10K1_IOCTL_CONTINUE:
2401 if (!capable(CAP_SYS_ADMIN))
2404 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg = 0);
2406 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg = 0);
2408 case SNDRV_EMU10K1_IOCTL_ZERO_TRAM_COUNTER:
2409 if (!capable(CAP_SYS_ADMIN))
2412 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg | A_DBG_ZC);
2414 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg | EMU10K1_DBG_ZC);
2417 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg);
2419 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg);
2421 case SNDRV_EMU10K1_IOCTL_SINGLE_STEP:
2422 if (!capable(CAP_SYS_ADMIN))
2424 if (get_user(addr, (unsigned int __user *)argp))
2429 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg |= A_DBG_SINGLE_STEP | addr);
2431 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg |= EMU10K1_DBG_SINGLE_STEP | addr);
2434 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg |= A_DBG_SINGLE_STEP | A_DBG_STEP_ADDR | addr);
2436 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg |= EMU10K1_DBG_SINGLE_STEP | EMU10K1_DBG_STEP | addr);
2438 case SNDRV_EMU10K1_IOCTL_DBG_READ:
2440 addr = snd_emu10k1_ptr_read(emu, A_DBG, 0);
2442 addr = snd_emu10k1_ptr_read(emu, DBG, 0);
2443 if (put_user(addr, (unsigned int __user *)argp))
2450 static int snd_emu10k1_fx8010_release(snd_hwdep_t * hw, struct file *file)
2455 int __devinit snd_emu10k1_fx8010_new(emu10k1_t *emu, int device, snd_hwdep_t ** rhwdep)
2462 if ((err = snd_hwdep_new(emu->card, "FX8010", device, &hw)) < 0)
2464 strcpy(hw->name, "EMU10K1 (FX8010)");
2465 hw->iface = SNDRV_HWDEP_IFACE_EMU10K1;
2466 hw->ops.open = snd_emu10k1_fx8010_open;
2467 hw->ops.ioctl = snd_emu10k1_fx8010_ioctl;
2468 hw->ops.release = snd_emu10k1_fx8010_release;
2469 hw->private_data = emu;