source: GPL/alsa-kernel/pci/emu10k1/emufx.c@ 18

Last change on this file since 18 was 18, checked in by vladest, 20 years ago

initial import

File size: 95.4 KB
Line 
1/*
2 * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
3 * Creative Labs, Inc.
4 * Routines for effect processor FX8010
5 *
6 * BUGS:
7 * --
8 *
9 * TODO:
10 * --
11 *
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.
16 *
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.
21 *
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
25 *
26 */
27
28#include <sound/driver.h>
29#include <linux/delay.h>
30#include <linux/slab.h>
31#include <sound/core.h>
32#include <sound/emu10k1.h>
33
34
35#if 0 /* for testing purposes - digital out -> capture */
36#define EMU10K1_CAPTURE_DIGITAL_OUT
37#endif
38#if 0 /* for testing purposes - set S/PDIF to AC3 output */
39#define EMU10K1_SET_AC3_IEC958
40#endif
41#if 0 /* for testing purposes - feed the front signal to Center/LFE outputs */
42#define EMU10K1_CENTER_LFE_FROM_FRONT
43#endif
44
45/*
46 * Tables
47 */
48
49static char *fxbuses[16] = {
50 /* 0x00 */ "PCM Left",
51 /* 0x01 */ "PCM Right",
52 /* 0x02 */ "PCM Surround Left",
53 /* 0x03 */ "PCM Surround Right",
54 /* 0x04 */ "MIDI Left",
55 /* 0x05 */ "MIDI Right",
56 /* 0x06 */ "Center",
57 /* 0x07 */ "LFE",
58 /* 0x08 */ NULL,
59 /* 0x09 */ NULL,
60 /* 0x0a */ NULL,
61 /* 0x0b */ NULL,
62 /* 0x0c */ "MIDI Reverb",
63 /* 0x0d */ "MIDI Chorus",
64 /* 0x0e */ NULL,
65 /* 0x0f */ NULL
66};
67
68static char *creative_ins[16] = {
69 /* 0x00 */ "AC97 Left",
70 /* 0x01 */ "AC97 Right",
71 /* 0x02 */ "TTL IEC958 Left",
72 /* 0x03 */ "TTL IEC958 Right",
73 /* 0x04 */ "Zoom Video Left",
74 /* 0x05 */ "Zoom Video Right",
75 /* 0x06 */ "Optical IEC958 Left",
76 /* 0x07 */ "Optical IEC958 Right",
77 /* 0x08 */ "Line/Mic 1 Left",
78 /* 0x09 */ "Line/Mic 1 Right",
79 /* 0x0a */ "Coaxial IEC958 Left",
80 /* 0x0b */ "Coaxial IEC958 Right",
81 /* 0x0c */ "Line/Mic 2 Left",
82 /* 0x0d */ "Line/Mic 2 Right",
83 /* 0x0e */ NULL,
84 /* 0x0f */ NULL
85};
86
87static char *audigy_ins[16] = {
88 /* 0x00 */ "AC97 Left",
89 /* 0x01 */ "AC97 Right",
90 /* 0x02 */ "Audigy CD Left",
91 /* 0x03 */ "Audigy CD Right",
92 /* 0x04 */ "Optical IEC958 Left",
93 /* 0x05 */ "Optical IEC958 Right",
94 /* 0x06 */ NULL,
95 /* 0x07 */ NULL,
96 /* 0x08 */ "Line/Mic 2 Left",
97 /* 0x09 */ "Line/Mic 2 Right",
98 /* 0x0a */ "SPDIF Left",
99 /* 0x0b */ "SPDIF Right",
100 /* 0x0c */ "Aux2 Left",
101 /* 0x0d */ "Aux2 Right",
102 /* 0x0e */ NULL,
103 /* 0x0f */ NULL
104};
105
106static char *creative_outs[32] = {
107 /* 0x00 */ "AC97 Left",
108 /* 0x01 */ "AC97 Right",
109 /* 0x02 */ "Optical IEC958 Left",
110 /* 0x03 */ "Optical IEC958 Right",
111 /* 0x04 */ "Center",
112 /* 0x05 */ "LFE",
113 /* 0x06 */ "Headphone Left",
114 /* 0x07 */ "Headphone Right",
115 /* 0x08 */ "Surround Left",
116 /* 0x09 */ "Surround Right",
117 /* 0x0a */ "PCM Capture Left",
118 /* 0x0b */ "PCM Capture Right",
119 /* 0x0c */ "MIC Capture",
120 /* 0x0d */ "AC97 Surround Left",
121 /* 0x0e */ "AC97 Surround Right",
122 /* 0x0f */ NULL,
123 /* 0x10 */ NULL,
124 /* 0x11 */ "Analog Center",
125 /* 0x12 */ "Analog LFE",
126 /* 0x13 */ NULL,
127 /* 0x14 */ NULL,
128 /* 0x15 */ NULL,
129 /* 0x16 */ NULL,
130 /* 0x17 */ NULL,
131 /* 0x18 */ NULL,
132 /* 0x19 */ NULL,
133 /* 0x1a */ NULL,
134 /* 0x1b */ NULL,
135 /* 0x1c */ NULL,
136 /* 0x1d */ NULL,
137 /* 0x1e */ NULL,
138 /* 0x1f */ NULL,
139};
140
141static char *audigy_outs[32] = {
142 /* 0x00 */ "Digital Front Left",
143 /* 0x01 */ "Digital Front Right",
144 /* 0x02 */ "Digital Center",
145 /* 0x03 */ "Digital LEF",
146 /* 0x04 */ "Headphone Left",
147 /* 0x05 */ "Headphone Right",
148 /* 0x06 */ "Digital Rear Left",
149 /* 0x07 */ "Digital Rear Right",
150 /* 0x08 */ "Front Left",
151 /* 0x09 */ "Front Right",
152 /* 0x0a */ "Center",
153 /* 0x0b */ "LFE",
154 /* 0x0c */ NULL,
155 /* 0x0d */ NULL,
156 /* 0x0e */ "Rear Left",
157 /* 0x0f */ "Rear Right",
158 /* 0x10 */ "AC97 Front Left",
159 /* 0x11 */ "AC97 Front Right",
160 /* 0x12 */ "ADC Caputre Left",
161 /* 0x13 */ "ADC Capture Right",
162 /* 0x14 */ NULL,
163 /* 0x15 */ NULL,
164 /* 0x16 */ NULL,
165 /* 0x17 */ NULL,
166 /* 0x18 */ NULL,
167 /* 0x19 */ NULL,
168 /* 0x1a */ NULL,
169 /* 0x1b */ NULL,
170 /* 0x1c */ NULL,
171 /* 0x1d */ NULL,
172 /* 0x1e */ NULL,
173 /* 0x1f */ NULL,
174};
175
176static const u32 bass_table[41][5] = {
177 { 0x3e4f844f, 0x84ed4cc3, 0x3cc69927, 0x7b03553a, 0xc4da8486 },
178 { 0x3e69a17a, 0x84c280fb, 0x3cd77cd4, 0x7b2f2a6f, 0xc4b08d1d },
179 { 0x3e82ff42, 0x849991d5, 0x3ce7466b, 0x7b5917c6, 0xc48863ee },
180 { 0x3e9bab3c, 0x847267f0, 0x3cf5ffe8, 0x7b813560, 0xc461f22c },
181 { 0x3eb3b275, 0x844ced29, 0x3d03b295, 0x7ba79a1c, 0xc43d223b },
182 { 0x3ecb2174, 0x84290c8b, 0x3d106714, 0x7bcc5ba3, 0xc419dfa5 },
183 { 0x3ee2044b, 0x8406b244, 0x3d1c2561, 0x7bef8e77, 0xc3f8170f },
184 { 0x3ef86698, 0x83e5cb96, 0x3d26f4d8, 0x7c114600, 0xc3d7b625 },
185 { 0x3f0e5390, 0x83c646c9, 0x3d30dc39, 0x7c319498, 0xc3b8ab97 },
186 { 0x3f23d60b, 0x83a81321, 0x3d39e1af, 0x7c508b9c, 0xc39ae704 },
187 { 0x3f38f884, 0x838b20d2, 0x3d420ad2, 0x7c6e3b75, 0xc37e58f1 },
188 { 0x3f4dc52c, 0x836f60ef, 0x3d495cab, 0x7c8ab3a6, 0xc362f2be },
189 { 0x3f6245e8, 0x8354c565, 0x3d4fdbb8, 0x7ca602d6, 0xc348a69b },
190 { 0x3f76845f, 0x833b40ec, 0x3d558bf0, 0x7cc036df, 0xc32f677c },
191 { 0x3f8a8a03, 0x8322c6fb, 0x3d5a70c4, 0x7cd95cd7, 0xc317290b },
192 { 0x3f9e6014, 0x830b4bc3, 0x3d5e8d25, 0x7cf1811a, 0xc2ffdfa5 },
193 { 0x3fb20fae, 0x82f4c420, 0x3d61e37f, 0x7d08af56, 0xc2e9804a },
194 { 0x3fc5a1cc, 0x82df2592, 0x3d6475c3, 0x7d1ef294, 0xc2d40096 },
195 { 0x3fd91f55, 0x82ca6632, 0x3d664564, 0x7d345541, 0xc2bf56b9 },
196 { 0x3fec9120, 0x82b67cac, 0x3d675356, 0x7d48e138, 0xc2ab796e },
197 { 0x40000000, 0x82a36037, 0x3d67a012, 0x7d5c9fc9, 0xc2985fee },
198 { 0x401374c7, 0x8291088a, 0x3d672b93, 0x7d6f99c3, 0xc28601f2 },
199 { 0x4026f857, 0x827f6dd7, 0x3d65f559, 0x7d81d77c, 0xc27457a3 },
200 { 0x403a939f, 0x826e88c5, 0x3d63fc63, 0x7d9360d4, 0xc2635996 },
201 { 0x404e4faf, 0x825e5266, 0x3d613f32, 0x7da43d42, 0xc25300c6 },
202 { 0x406235ba, 0x824ec434, 0x3d5dbbc3, 0x7db473d7, 0xc243468e },
203 { 0x40764f1f, 0x823fd80c, 0x3d596f8f, 0x7dc40b44, 0xc23424a2 },
204 { 0x408aa576, 0x82318824, 0x3d545787, 0x7dd309e2, 0xc2259509 },
205 { 0x409f4296, 0x8223cf0b, 0x3d4e7012, 0x7de175b5, 0xc2179218 },
206 { 0x40b430a0, 0x8216a7a1, 0x3d47b505, 0x7def5475, 0xc20a1670 },
207 { 0x40c97a0a, 0x820a0d12, 0x3d4021a1, 0x7dfcab8d, 0xc1fd1cf5 },
208 { 0x40df29a6, 0x81fdfad6, 0x3d37b08d, 0x7e098028, 0xc1f0a0ca },
209 { 0x40f54ab1, 0x81f26ca9, 0x3d2e5bd1, 0x7e15d72b, 0xc1e49d52 },
210 { 0x410be8da, 0x81e75e89, 0x3d241cce, 0x7e21b544, 0xc1d90e24 },
211 { 0x41231051, 0x81dcccb3, 0x3d18ec37, 0x7e2d1ee6, 0xc1cdef10 },
212 { 0x413acdd0, 0x81d2b39e, 0x3d0cc20a, 0x7e38184e, 0xc1c33c13 },
213 { 0x41532ea7, 0x81c90ffb, 0x3cff9585, 0x7e42a58b, 0xc1b8f15a },
214 { 0x416c40cd, 0x81bfdeb2, 0x3cf15d21, 0x7e4cca7c, 0xc1af0b3f },
215 { 0x418612ea, 0x81b71cdc, 0x3ce20e85, 0x7e568ad3, 0xc1a58640 },
216 { 0x41a0b465, 0x81aec7c5, 0x3cd19e7c, 0x7e5fea1e, 0xc19c5f03 },
217 { 0x41bc3573, 0x81a6dcea, 0x3cc000e9, 0x7e68ebc2, 0xc1939250 }
218};
219
220static const u32 treble_table[41][5] = {
221 { 0x0125cba9, 0xfed5debd, 0x00599b6c, 0x0d2506da, 0xfa85b354 },
222 { 0x0142f67e, 0xfeb03163, 0x0066cd0f, 0x0d14c69d, 0xfa914473 },
223 { 0x016328bd, 0xfe860158, 0x0075b7f2, 0x0d03eb27, 0xfa9d32d2 },
224 { 0x0186b438, 0xfe56c982, 0x00869234, 0x0cf27048, 0xfaa97fca },
225 { 0x01adf358, 0xfe21f5fe, 0x00999842, 0x0ce051c2, 0xfab62ca5 },
226 { 0x01d949fa, 0xfde6e287, 0x00af0d8d, 0x0ccd8b4a, 0xfac33aa7 },
227 { 0x02092669, 0xfda4d8bf, 0x00c73d4c, 0x0cba1884, 0xfad0ab07 },
228 { 0x023e0268, 0xfd5b0e4a, 0x00e27b54, 0x0ca5f509, 0xfade7ef2 },
229 { 0x0278645c, 0xfd08a2b0, 0x01012509, 0x0c911c63, 0xfaecb788 },
230 { 0x02b8e091, 0xfcac9d1a, 0x0123a262, 0x0c7b8a14, 0xfafb55df },
231 { 0x03001a9a, 0xfc45e9ce, 0x014a6709, 0x0c65398f, 0xfb0a5aff },
232 { 0x034ec6d7, 0xfbd3576b, 0x0175f397, 0x0c4e2643, 0xfb19c7e4 },
233 { 0x03a5ac15, 0xfb5393ee, 0x01a6d6ed, 0x0c364b94, 0xfb299d7c },
234 { 0x0405a562, 0xfac52968, 0x01ddafae, 0x0c1da4e2, 0xfb39dca5 },
235 { 0x046fa3fe, 0xfa267a66, 0x021b2ddd, 0x0c042d8d, 0xfb4a8631 },
236 { 0x04e4b17f, 0xf975be0f, 0x0260149f, 0x0be9e0f2, 0xfb5b9ae0 },
237 { 0x0565f220, 0xf8b0fbe5, 0x02ad3c29, 0x0bceba73, 0xfb6d1b60 },
238 { 0x05f4a745, 0xf7d60722, 0x030393d4, 0x0bb2b578, 0xfb7f084d },
239 { 0x06923236, 0xf6e279bd, 0x03642465, 0x0b95cd75, 0xfb916233 },
240 { 0x07401713, 0xf5d3aef9, 0x03d01283, 0x0b77fded, 0xfba42984 },
241 { 0x08000000, 0xf4a6bd88, 0x0448a161, 0x0b594278, 0xfbb75e9f },
242 { 0x08d3c097, 0xf3587131, 0x04cf35a4, 0x0b3996c9, 0xfbcb01cb },
243 { 0x09bd59a2, 0xf1e543f9, 0x05655880, 0x0b18f6b2, 0xfbdf1333 },
244 { 0x0abefd0f, 0xf04956ca, 0x060cbb12, 0x0af75e2c, 0xfbf392e8 },
245 { 0x0bdb123e, 0xee806984, 0x06c739fe, 0x0ad4c962, 0xfc0880dd },
246 { 0x0d143a94, 0xec85d287, 0x0796e150, 0x0ab134b0, 0xfc1ddce5 },
247 { 0x0e6d5664, 0xea547598, 0x087df0a0, 0x0a8c9cb6, 0xfc33a6ad },
248 { 0x0fe98a2a, 0xe7e6ba35, 0x097edf83, 0x0a66fe5b, 0xfc49ddc2 },
249 { 0x118c4421, 0xe536813a, 0x0a9c6248, 0x0a4056d7, 0xfc608185 },
250 { 0x1359422e, 0xe23d19eb, 0x0bd96efb, 0x0a18a3bf, 0xfc77912c },
251 { 0x1554982b, 0xdef33645, 0x0d3942bd, 0x09efe312, 0xfc8f0bc1 },
252 { 0x1782b68a, 0xdb50deb1, 0x0ebf676d, 0x09c6133f, 0xfca6f019 },
253 { 0x19e8715d, 0xd74d64fd, 0x106fb999, 0x099b3337, 0xfcbf3cd6 },
254 { 0x1c8b07b8, 0xd2df56ab, 0x124e6ec8, 0x096f4274, 0xfcd7f060 },
255 { 0x1f702b6d, 0xcdfc6e92, 0x14601c10, 0x0942410b, 0xfcf108e5 },
256 { 0x229e0933, 0xc89985cd, 0x16a9bcfa, 0x09142fb5, 0xfd0a8451 },
257 { 0x261b5118, 0xc2aa8409, 0x1930bab6, 0x08e50fdc, 0xfd24604d },
258 { 0x29ef3f5d, 0xbc224f28, 0x1bfaf396, 0x08b4e3aa, 0xfd3e9a3b },
259 { 0x2e21a59b, 0xb4f2ba46, 0x1f0ec2d6, 0x0883ae15, 0xfd592f33 },
260 { 0x32baf44b, 0xad0c7429, 0x227308a3, 0x085172eb, 0xfd741bfd },
261 { 0x37c4448b, 0xa45ef51d, 0x262f3267, 0x081e36dc, 0xfd8f5d14 }
262};
263
264static const u32 db_table[101] = {
265 0x00000000, 0x01571f82, 0x01674b41, 0x01783a1b, 0x0189f540,
266 0x019c8651, 0x01aff763, 0x01c45306, 0x01d9a446, 0x01eff6b8,
267 0x0207567a, 0x021fd03d, 0x0239714c, 0x02544792, 0x027061a1,
268 0x028dcebb, 0x02ac9edc, 0x02cce2bf, 0x02eeabe8, 0x03120cb0,
269 0x0337184e, 0x035de2df, 0x03868173, 0x03b10a18, 0x03dd93e9,
270 0x040c3713, 0x043d0cea, 0x04702ff3, 0x04a5bbf2, 0x04ddcdfb,
271 0x0518847f, 0x0555ff62, 0x05966005, 0x05d9c95d, 0x06206005,
272 0x066a4a52, 0x06b7b067, 0x0708bc4c, 0x075d9a01, 0x07b6779d,
273 0x08138561, 0x0874f5d5, 0x08dafde1, 0x0945d4ed, 0x09b5b4fd,
274 0x0a2adad1, 0x0aa58605, 0x0b25f936, 0x0bac7a24, 0x0c3951d8,
275 0x0ccccccc, 0x0d673b17, 0x0e08f093, 0x0eb24510, 0x0f639481,
276 0x101d3f2d, 0x10dfa9e6, 0x11ab3e3f, 0x12806ac3, 0x135fa333,
277 0x144960c5, 0x153e2266, 0x163e6cfe, 0x174acbb7, 0x1863d04d,
278 0x198a1357, 0x1abe349f, 0x1c00db77, 0x1d52b712, 0x1eb47ee6,
279 0x2026f30f, 0x21aadcb6, 0x23410e7e, 0x24ea64f9, 0x26a7c71d,
280 0x287a26c4, 0x2a62812c, 0x2c61df84, 0x2e795779, 0x30aa0bcf,
281 0x32f52cfe, 0x355bf9d8, 0x37dfc033, 0x3a81dda4, 0x3d43c038,
282 0x4026e73c, 0x432ce40f, 0x46575af8, 0x49a8040f, 0x4d20ac2a,
283 0x50c335d3, 0x54919a57, 0x588dead1, 0x5cba514a, 0x611911ea,
284 0x65ac8c2f, 0x6a773c39, 0x6f7bbc23, 0x74bcc56c, 0x7a3d3272,
285 0x7fffffff,
286};
287
288static const u32 onoff_table[2] = {
289 0x00000000, 0x00000001
290};
291
292/*
293 */
294
295#ifndef TARGET_OS2
296static inline mm_segment_t snd_enter_user(void)
297{
298 mm_segment_t fs = get_fs();
299 set_fs(get_ds());
300 return fs;
301}
302
303static inline void snd_leave_user(mm_segment_t fs)
304{
305 set_fs(fs);
306}
307#endif
308/*
309 * controls
310 */
311
312static int snd_emu10k1_gpr_ctl_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
313{
314 snd_emu10k1_fx8010_ctl_t *ctl = (snd_emu10k1_fx8010_ctl_t *)kcontrol->private_value;
315
316 if (ctl->min == 0 && ctl->max == 1)
317 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
318 else
319 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
320 uinfo->count = ctl->vcount;
321 uinfo->value.integer.min = ctl->min;
322 uinfo->value.integer.max = ctl->max;
323 return 0;
324}
325
326static int snd_emu10k1_gpr_ctl_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
327{
328 emu10k1_t *emu = snd_kcontrol_chip(kcontrol);
329 snd_emu10k1_fx8010_ctl_t *ctl = (snd_emu10k1_fx8010_ctl_t *)kcontrol->private_value;
330 unsigned long flags;
331 unsigned int i;
332
333 spin_lock_irqsave(&emu->reg_lock, flags);
334 for (i = 0; i < ctl->vcount; i++)
335 ucontrol->value.integer.value[i] = ctl->value[i];
336 spin_unlock_irqrestore(&emu->reg_lock, flags);
337 return 0;
338}
339
340static int snd_emu10k1_gpr_ctl_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
341{
342 emu10k1_t *emu = snd_kcontrol_chip(kcontrol);
343 snd_emu10k1_fx8010_ctl_t *ctl = (snd_emu10k1_fx8010_ctl_t *)kcontrol->private_value;
344 unsigned long flags;
345 unsigned int nval, val;
346 unsigned int i, j;
347 int change = 0;
348
349 spin_lock_irqsave(&emu->reg_lock, flags);
350 for (i = 0; i < ctl->vcount; i++) {
351 nval = ucontrol->value.integer.value[i];
352 if (nval < ctl->min)
353 nval = ctl->min;
354 if (nval > ctl->max)
355 nval = ctl->max;
356 if (nval != ctl->value[i])
357 change = 1;
358 val = ctl->value[i] = nval;
359 switch (ctl->translation) {
360 case EMU10K1_GPR_TRANSLATION_NONE:
361 snd_emu10k1_ptr_write(emu, emu->gpr_base + ctl->gpr[i], 0, val);
362 break;
363 case EMU10K1_GPR_TRANSLATION_TABLE100:
364 snd_emu10k1_ptr_write(emu, emu->gpr_base + ctl->gpr[i], 0, db_table[val]);
365 break;
366 case EMU10K1_GPR_TRANSLATION_BASS:
367 snd_runtime_check((ctl->count % 5) == 0 && (ctl->count / 5) == ctl->vcount, change = -EIO; goto __error);
368 for (j = 0; j < 5; j++)
369 snd_emu10k1_ptr_write(emu, emu->gpr_base + ctl->gpr[j * ctl->vcount + i], 0, bass_table[val][j]);
370 break;
371 case EMU10K1_GPR_TRANSLATION_TREBLE:
372 snd_runtime_check((ctl->count % 5) == 0 && (ctl->count / 5) == ctl->vcount, change = -EIO; goto __error);
373 for (j = 0; j < 5; j++)
374 snd_emu10k1_ptr_write(emu, emu->gpr_base + ctl->gpr[j * ctl->vcount + i], 0, treble_table[val][j]);
375 break;
376 case EMU10K1_GPR_TRANSLATION_ONOFF:
377 snd_emu10k1_ptr_write(emu, emu->gpr_base + ctl->gpr[i], 0, onoff_table[val]);
378 break;
379 }
380 }
381__error:
382 spin_unlock_irqrestore(&emu->reg_lock, flags);
383 return change;
384}
385
386/*
387 * Interrupt handler
388 */
389
390static void snd_emu10k1_fx8010_interrupt(emu10k1_t *emu)
391{
392 snd_emu10k1_fx8010_irq_t *irq, *nirq;
393
394 irq = emu->fx8010.irq_handlers;
395 while (irq) {
396 nirq = irq->next; /* irq ptr can be removed from list */
397 if (snd_emu10k1_ptr_read(emu, emu->gpr_base + irq->gpr_running, 0) & 0xffff0000) {
398 if (irq->handler)
399 irq->handler(emu, irq->private_data);
400 snd_emu10k1_ptr_write(emu, emu->gpr_base + irq->gpr_running, 0, 1);
401 }
402 irq = nirq;
403 }
404}
405
406int snd_emu10k1_fx8010_register_irq_handler(emu10k1_t *emu,
407 snd_fx8010_irq_handler_t *handler,
408 unsigned char gpr_running,
409 void *private_data,
410 snd_emu10k1_fx8010_irq_t **r_irq)
411{
412 snd_emu10k1_fx8010_irq_t *irq;
413 unsigned long flags;
414
415 snd_runtime_check(emu, return -EINVAL);
416 snd_runtime_check(handler, return -EINVAL);
417 irq = kmalloc(sizeof(*irq), GFP_ATOMIC);
418 if (irq == NULL)
419 return -ENOMEM;
420 irq->handler = handler;
421 irq->gpr_running = gpr_running;
422 irq->private_data = private_data;
423 irq->next = NULL;
424 spin_lock_irqsave(&emu->fx8010.irq_lock, flags);
425 if (emu->fx8010.irq_handlers == NULL) {
426 emu->fx8010.irq_handlers = irq;
427 emu->dsp_interrupt = snd_emu10k1_fx8010_interrupt;
428 snd_emu10k1_intr_enable(emu, INTE_FXDSPENABLE);
429 } else {
430 irq->next = emu->fx8010.irq_handlers;
431 emu->fx8010.irq_handlers = irq;
432 }
433 spin_unlock_irqrestore(&emu->fx8010.irq_lock, flags);
434 if (r_irq)
435 *r_irq = irq;
436 return 0;
437}
438
439int snd_emu10k1_fx8010_unregister_irq_handler(emu10k1_t *emu,
440 snd_emu10k1_fx8010_irq_t *irq)
441{
442 snd_emu10k1_fx8010_irq_t *tmp;
443 unsigned long flags;
444
445 snd_runtime_check(irq, return -EINVAL);
446 spin_lock_irqsave(&emu->fx8010.irq_lock, flags);
447 if ((tmp = emu->fx8010.irq_handlers) == irq) {
448 emu->fx8010.irq_handlers = tmp->next;
449 if (emu->fx8010.irq_handlers == NULL) {
450 snd_emu10k1_intr_disable(emu, INTE_FXDSPENABLE);
451 emu->dsp_interrupt = NULL;
452 }
453 } else {
454 while (tmp && tmp->next != irq)
455 tmp = tmp->next;
456 if (tmp)
457 tmp->next = tmp->next->next;
458 }
459 spin_unlock_irqrestore(&emu->fx8010.irq_lock, flags);
460 kfree(irq);
461 return 0;
462}
463
464/*************************************************************************
465 * EMU10K1 effect manager
466 *************************************************************************/
467
468static void snd_emu10k1_write_op(emu10k1_fx8010_code_t *icode, unsigned int *ptr,
469 u32 op, u32 r, u32 a, u32 x, u32 y)
470{
471 u_int32_t *code;
472 snd_assert(*ptr < 512, return);
473 code = (u_int32_t *)icode->code + (*ptr) * 2;
474 set_bit(*ptr, icode->code_valid);
475 code[0] = ((x & 0x3ff) << 10) | (y & 0x3ff);
476 code[1] = ((op & 0x0f) << 20) | ((r & 0x3ff) << 10) | (a & 0x3ff);
477 (*ptr)++;
478}
479
480#define OP(icode, ptr, op, r, a, x, y) \
481 snd_emu10k1_write_op(icode, ptr, op, r, a, x, y)
482
483static void snd_emu10k1_audigy_write_op(emu10k1_fx8010_code_t *icode, unsigned int *ptr,
484 u32 op, u32 r, u32 a, u32 x, u32 y)
485{
486 u_int32_t *code;
487 snd_assert(*ptr < 1024, return);
488 code = (u_int32_t *)icode->code + (*ptr) * 2;
489 set_bit(*ptr, icode->code_valid);
490 code[0] = ((x & 0x7ff) << 12) | (y & 0x7ff);
491 code[1] = ((op & 0x0f) << 24) | ((r & 0x7ff) << 12) | (a & 0x7ff);
492 (*ptr)++;
493}
494
495#define A_OP(icode, ptr, op, r, a, x, y) \
496 snd_emu10k1_audigy_write_op(icode, ptr, op, r, a, x, y)
497
498void snd_emu10k1_efx_write(emu10k1_t *emu, unsigned int pc, unsigned int data)
499{
500 pc += emu->audigy ? A_MICROCODEBASE : MICROCODEBASE;
501 snd_emu10k1_ptr_write(emu, pc, 0, data);
502}
503
504unsigned int snd_emu10k1_efx_read(emu10k1_t *emu, unsigned int pc)
505{
506 pc += emu->audigy ? A_MICROCODEBASE : MICROCODEBASE;
507 return snd_emu10k1_ptr_read(emu, pc, 0);
508}
509
510static int snd_emu10k1_gpr_poke(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
511{
512 int gpr;
513 u32 val;
514
515 for (gpr = 0; gpr < (emu->audigy ? 0x200 : 0x100); gpr++) {
516 if (!test_bit(gpr, icode->gpr_valid))
517 continue;
518 if (get_user(val, &icode->gpr_map[gpr]))
519 return -EFAULT;
520 snd_emu10k1_ptr_write(emu, emu->gpr_base + gpr, 0, val);
521 }
522 return 0;
523}
524
525static int snd_emu10k1_gpr_peek(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
526{
527 int gpr;
528 u32 val;
529
530 for (gpr = 0; gpr < (emu->audigy ? 0x200 : 0x100); gpr++) {
531 set_bit(gpr, icode->gpr_valid);
532 val = snd_emu10k1_ptr_read(emu, emu->gpr_base + gpr, 0);
533 if (put_user(val, &icode->gpr_map[gpr]))
534 return -EFAULT;
535 }
536 return 0;
537}
538
539static int snd_emu10k1_tram_poke(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
540{
541 int tram;
542 u32 addr, val;
543
544 for (tram = 0; tram < (emu->audigy ? 0x100 : 0xa0); tram++) {
545 if (!test_bit(tram, icode->tram_valid))
546 continue;
547 if (get_user(val, &icode->tram_data_map[tram]) ||
548 get_user(addr, &icode->tram_addr_map[tram]))
549 return -EFAULT;
550 snd_emu10k1_ptr_write(emu, TANKMEMDATAREGBASE + tram, 0, val);
551 if (!emu->audigy) {
552 snd_emu10k1_ptr_write(emu, TANKMEMADDRREGBASE + tram, 0, addr);
553 } else {
554 snd_emu10k1_ptr_write(emu, TANKMEMADDRREGBASE + tram, 0, addr << 12);
555 snd_emu10k1_ptr_write(emu, A_TANKMEMCTLREGBASE + tram, 0, addr >> 20);
556 }
557 }
558 return 0;
559}
560
561static int snd_emu10k1_tram_peek(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
562{
563 int tram;
564 u32 val, addr;
565
566 memset(icode->tram_valid, 0, sizeof(icode->tram_valid));
567 for (tram = 0; tram < (emu->audigy ? 0x100 : 0xa0); tram++) {
568 set_bit(tram, icode->tram_valid);
569 val = snd_emu10k1_ptr_read(emu, TANKMEMDATAREGBASE + tram, 0);
570 if (!emu->audigy) {
571 addr = snd_emu10k1_ptr_read(emu, TANKMEMADDRREGBASE + tram, 0);
572 } else {
573 addr = snd_emu10k1_ptr_read(emu, TANKMEMADDRREGBASE + tram, 0) >> 12;
574 addr |= snd_emu10k1_ptr_read(emu, A_TANKMEMCTLREGBASE + tram, 0) << 20;
575 }
576 if (put_user(val, &icode->tram_data_map[tram]) ||
577 put_user(addr, &icode->tram_addr_map[tram]))
578 return -EFAULT;
579 }
580 return 0;
581}
582
583static int snd_emu10k1_code_poke(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
584{
585 u32 pc, lo, hi;
586
587 for (pc = 0; pc < (emu->audigy ? 2*1024 : 2*512); pc += 2) {
588 if (!test_bit(pc / 2, icode->code_valid))
589 continue;
590 if (get_user(lo, &icode->code[pc + 0]) ||
591 get_user(hi, &icode->code[pc + 1]))
592 return -EFAULT;
593 snd_emu10k1_efx_write(emu, pc + 0, lo);
594 snd_emu10k1_efx_write(emu, pc + 1, hi);
595 }
596 return 0;
597}
598
599static int snd_emu10k1_code_peek(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
600{
601 u32 pc;
602
603 memset(icode->code_valid, 0, sizeof(icode->code_valid));
604 for (pc = 0; pc < (emu->audigy ? 2*1024 : 2*512); pc += 2) {
605 set_bit(pc / 2, icode->code_valid);
606 if (put_user(snd_emu10k1_efx_read(emu, pc + 0), &icode->code[pc + 0]))
607 return -EFAULT;
608 if (put_user(snd_emu10k1_efx_read(emu, pc + 1), &icode->code[pc + 1]))
609 return -EFAULT;
610 }
611 return 0;
612}
613
614static snd_emu10k1_fx8010_ctl_t *snd_emu10k1_look_for_ctl(emu10k1_t *emu, snd_ctl_elem_id_t *id)
615{
616 snd_emu10k1_fx8010_ctl_t *ctl;
617 snd_kcontrol_t *kcontrol;
618 struct list_head *list;
619
620 list_for_each(list, &emu->fx8010.gpr_ctl) {
621 ctl = emu10k1_gpr_ctl(list);
622 kcontrol = ctl->kcontrol;
623 if (kcontrol->id.iface == id->iface &&
624 !strcmp(kcontrol->id.name, id->name) &&
625 kcontrol->id.index == id->index)
626 return ctl;
627 }
628 return NULL;
629}
630
631static int snd_emu10k1_verify_controls(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
632{
633 unsigned int i;
634 snd_ctl_elem_id_t *_id, id;
635 emu10k1_fx8010_control_gpr_t *_gctl;
636 emu10k1_fx8010_control_gpr_t *gctl;
637 int err;
638
639 for (i = 0, _id = icode->gpr_del_controls;
640 i < icode->gpr_del_control_count; i++, _id++) {
641 if (copy_from_user(&id, _id, sizeof(id)))
642 return -EFAULT;
643 if (snd_emu10k1_look_for_ctl(emu, &id) == NULL)
644 return -ENOENT;
645 }
646 gctl = kmalloc(sizeof(*gctl), GFP_KERNEL);
647 if (! gctl)
648 return -ENOMEM;
649 err = 0;
650 for (i = 0, _gctl = icode->gpr_add_controls;
651 i < icode->gpr_add_control_count; i++, _gctl++) {
652 if (copy_from_user(gctl, _gctl, sizeof(*gctl))) {
653 err = -EFAULT;
654 goto __error;
655 }
656 if (snd_emu10k1_look_for_ctl(emu, &gctl->id))
657 continue;
658 down_read(&emu->card->controls_rwsem);
659 if (snd_ctl_find_id(emu->card, &gctl->id) != NULL) {
660 up_read(&emu->card->controls_rwsem);
661 err = -EEXIST;
662 goto __error;
663 }
664 up_read(&emu->card->controls_rwsem);
665 if (gctl->id.iface != SNDRV_CTL_ELEM_IFACE_MIXER &&
666 gctl->id.iface != SNDRV_CTL_ELEM_IFACE_PCM) {
667 err = -EINVAL;
668 goto __error;
669 }
670 }
671 for (i = 0, _gctl = icode->gpr_list_controls;
672 i < icode->gpr_list_control_count; i++, _gctl++) {
673 /* FIXME: we need to check the WRITE access */
674 if (copy_from_user(gctl, _gctl, sizeof(*gctl))) {
675 err = -EFAULT;
676 goto __error;
677 }
678 }
679__error:
680 kfree(gctl);
681 return err;
682}
683
684static void snd_emu10k1_ctl_private_free(snd_kcontrol_t *kctl)
685{
686 snd_emu10k1_fx8010_ctl_t *ctl;
687
688 ctl = (snd_emu10k1_fx8010_ctl_t *)kctl->private_value;
689 kctl->private_value = 0;
690 list_del(&ctl->list);
691 kfree(ctl);
692}
693
694static int snd_emu10k1_add_controls(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
695{
696 unsigned int i, j;
697 emu10k1_fx8010_control_gpr_t *_gctl;
698 emu10k1_fx8010_control_gpr_t *gctl;
699 snd_emu10k1_fx8010_ctl_t *ctl, *nctl;
700 snd_kcontrol_new_t knew;
701 snd_kcontrol_t *kctl;
702 snd_ctl_elem_value_t *val;
703 int err = 0;
704
705 val = (snd_ctl_elem_value_t *)kmalloc(sizeof(*val), GFP_KERNEL);
706 gctl = kmalloc(sizeof(*gctl), GFP_KERNEL);
707 nctl = kmalloc(sizeof(*nctl), GFP_KERNEL);
708 if (!val || !gctl || !nctl) {
709 err = -ENOMEM;
710 goto __error;
711 }
712
713 for (i = 0, _gctl = icode->gpr_add_controls;
714 i < icode->gpr_add_control_count; i++, _gctl++) {
715 if (copy_from_user(gctl, _gctl, sizeof(*gctl))) {
716 err = -EFAULT;
717 goto __error;
718 }
719 snd_runtime_check(gctl->id.iface == SNDRV_CTL_ELEM_IFACE_MIXER ||
720 gctl->id.iface == SNDRV_CTL_ELEM_IFACE_PCM, err = -EINVAL; goto __error);
721 snd_runtime_check(gctl->id.name[0] != '\0', err = -EINVAL; goto __error);
722 ctl = snd_emu10k1_look_for_ctl(emu, &gctl->id);
723 memset(&knew, 0, sizeof(knew));
724 knew.iface = gctl->id.iface;
725 knew.name = gctl->id.name;
726 knew.index = gctl->id.index;
727 knew.device = gctl->id.device;
728 knew.subdevice = gctl->id.subdevice;
729 knew.info = snd_emu10k1_gpr_ctl_info;
730 knew.get = snd_emu10k1_gpr_ctl_get;
731 knew.put = snd_emu10k1_gpr_ctl_put;
732 memset(nctl, 0, sizeof(*nctl));
733 nctl->vcount = gctl->vcount;
734 nctl->count = gctl->count;
735 for (j = 0; j < 32; j++) {
736 nctl->gpr[j] = gctl->gpr[j];
737 nctl->value[j] = ~gctl->value[j]; /* inverted, we want to write new value in gpr_ctl_put() */
738 val->value.integer.value[j] = gctl->value[j];
739 }
740 nctl->min = gctl->min;
741 nctl->max = gctl->max;
742 nctl->translation = gctl->translation;
743 if (ctl == NULL) {
744 ctl = (snd_emu10k1_fx8010_ctl_t *)kmalloc(sizeof(*ctl), GFP_KERNEL);
745 if (ctl == NULL) {
746 err = -ENOMEM;
747 goto __error;
748 }
749 knew.private_value = (unsigned long)ctl;
750 *ctl = *nctl;
751 if ((err = snd_ctl_add(emu->card, kctl = snd_ctl_new1(&knew, emu))) < 0) {
752 kfree(ctl);
753 goto __error;
754 }
755 kctl->private_free = snd_emu10k1_ctl_private_free;
756 ctl->kcontrol = kctl;
757 list_add_tail(&ctl->list, &emu->fx8010.gpr_ctl);
758 } else {
759 /* overwrite */
760 nctl->list = ctl->list;
761 nctl->kcontrol = ctl->kcontrol;
762 *ctl = *nctl;
763 snd_ctl_notify(emu->card, SNDRV_CTL_EVENT_MASK_VALUE |
764 SNDRV_CTL_EVENT_MASK_INFO, &ctl->kcontrol->id);
765 }
766 snd_emu10k1_gpr_ctl_put(ctl->kcontrol, val);
767 }
768__error:
769 kfree(nctl);
770 kfree(gctl);
771 kfree(val);
772 return err;
773}
774
775static int snd_emu10k1_del_controls(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
776{
777 unsigned int i;
778 snd_ctl_elem_id_t *_id, id;
779 snd_emu10k1_fx8010_ctl_t *ctl;
780 snd_card_t *card = emu->card;
781
782 for (i = 0, _id = icode->gpr_del_controls;
783 i < icode->gpr_del_control_count; i++, _id++) {
784 snd_runtime_check(copy_from_user(&id, _id, sizeof(id)) == 0, return -EFAULT);
785 down_write(&card->controls_rwsem);
786 ctl = snd_emu10k1_look_for_ctl(emu, &id);
787 if (ctl)
788 snd_ctl_remove(card, ctl->kcontrol);
789 up_write(&card->controls_rwsem);
790 }
791 return 0;
792}
793
794static int snd_emu10k1_list_controls(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
795{
796 unsigned int i = 0, j;
797 unsigned int total = 0;
798 emu10k1_fx8010_control_gpr_t *gctl;
799 emu10k1_fx8010_control_gpr_t *_gctl;
800 snd_emu10k1_fx8010_ctl_t *ctl;
801 snd_ctl_elem_id_t *id;
802 struct list_head *list;
803
804 gctl = kmalloc(sizeof(*gctl), GFP_KERNEL);
805 if (! gctl)
806 return -ENOMEM;
807
808 _gctl = icode->gpr_list_controls;
809 list_for_each(list, &emu->fx8010.gpr_ctl) {
810 ctl = emu10k1_gpr_ctl(list);
811 total++;
812 if (_gctl && i < icode->gpr_list_control_count) {
813 memset(gctl, 0, sizeof(*gctl));
814 id = &ctl->kcontrol->id;
815 gctl->id.iface = id->iface;
816 strlcpy(gctl->id.name, id->name, sizeof(gctl->id.name));
817 gctl->id.index = id->index;
818 gctl->id.device = id->device;
819 gctl->id.subdevice = id->subdevice;
820 gctl->vcount = ctl->vcount;
821 gctl->count = ctl->count;
822 for (j = 0; j < 32; j++) {
823 gctl->gpr[j] = ctl->gpr[j];
824 gctl->value[j] = ctl->value[j];
825 }
826 gctl->min = ctl->min;
827 gctl->max = ctl->max;
828 gctl->translation = ctl->translation;
829 if (copy_to_user(_gctl, gctl, sizeof(*gctl))) {
830 kfree(gctl);
831 return -EFAULT;
832 }
833 _gctl++;
834 i++;
835 }
836 }
837 icode->gpr_list_control_total = total;
838 kfree(gctl);
839 return 0;
840}
841
842static int snd_emu10k1_icode_poke(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
843{
844 int err = 0;
845
846 down(&emu->fx8010.lock);
847 if ((err = snd_emu10k1_verify_controls(emu, icode)) < 0)
848 goto __error;
849 strlcpy(emu->fx8010.name, icode->name, sizeof(emu->fx8010.name));
850 /* stop FX processor - this may be dangerous, but it's better to miss
851 some samples than generate wrong ones - [jk] */
852 if (emu->audigy)
853 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg | A_DBG_SINGLE_STEP);
854 else
855 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg | EMU10K1_DBG_SINGLE_STEP);
856 /* ok, do the main job */
857 if ((err = snd_emu10k1_del_controls(emu, icode)) < 0 ||
858 (err = snd_emu10k1_gpr_poke(emu, icode)) < 0 ||
859 (err = snd_emu10k1_tram_poke(emu, icode)) < 0 ||
860 (err = snd_emu10k1_code_poke(emu, icode)) < 0 ||
861 (err = snd_emu10k1_add_controls(emu, icode)) < 0)
862 goto __error;
863 /* start FX processor when the DSP code is updated */
864 if (emu->audigy)
865 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg);
866 else
867 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg);
868__error:
869 up(&emu->fx8010.lock);
870 return err;
871}
872
873static int snd_emu10k1_icode_peek(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
874{
875 int err;
876
877 down(&emu->fx8010.lock);
878 strlcpy(icode->name, emu->fx8010.name, sizeof(icode->name));
879 /* ok, do the main job */
880 err = snd_emu10k1_gpr_peek(emu, icode);
881 if (err >= 0)
882 err = snd_emu10k1_tram_peek(emu, icode);
883 if (err >= 0)
884 err = snd_emu10k1_code_peek(emu, icode);
885 if (err >= 0)
886 err = snd_emu10k1_list_controls(emu, icode);
887 up(&emu->fx8010.lock);
888 return err;
889}
890
891static int snd_emu10k1_ipcm_poke(emu10k1_t *emu, emu10k1_fx8010_pcm_t *ipcm)
892{
893 unsigned int i;
894 int err = 0;
895 snd_emu10k1_fx8010_pcm_t *pcm;
896
897 if (ipcm->substream >= EMU10K1_FX8010_PCM_COUNT)
898 return -EINVAL;
899 if (ipcm->channels > 32)
900 return -EINVAL;
901 pcm = &emu->fx8010.pcm[ipcm->substream];
902 down(&emu->fx8010.lock);
903 spin_lock_irq(&emu->reg_lock);
904 if (pcm->opened) {
905 err = -EBUSY;
906 goto __error;
907 }
908 if (ipcm->channels == 0) { /* remove */
909 pcm->valid = 0;
910 } else {
911 /* FIXME: we need to add universal code to the PCM transfer routine */
912 if (ipcm->channels != 2) {
913 err = -EINVAL;
914 goto __error;
915 }
916 pcm->valid = 1;
917 pcm->opened = 0;
918 pcm->channels = ipcm->channels;
919 pcm->tram_start = ipcm->tram_start;
920 pcm->buffer_size = ipcm->buffer_size;
921 pcm->gpr_size = ipcm->gpr_size;
922 pcm->gpr_count = ipcm->gpr_count;
923 pcm->gpr_tmpcount = ipcm->gpr_tmpcount;
924 pcm->gpr_ptr = ipcm->gpr_ptr;
925 pcm->gpr_trigger = ipcm->gpr_trigger;
926 pcm->gpr_running = ipcm->gpr_running;
927 for (i = 0; i < pcm->channels; i++)
928 pcm->etram[i] = ipcm->etram[i];
929 }
930__error:
931 spin_unlock_irq(&emu->reg_lock);
932 up(&emu->fx8010.lock);
933 return err;
934}
935
936static int snd_emu10k1_ipcm_peek(emu10k1_t *emu, emu10k1_fx8010_pcm_t *ipcm)
937{
938 unsigned int i;
939 int err = 0;
940 snd_emu10k1_fx8010_pcm_t *pcm;
941
942 if (ipcm->substream >= EMU10K1_FX8010_PCM_COUNT)
943 return -EINVAL;
944 pcm = &emu->fx8010.pcm[ipcm->substream];
945 down(&emu->fx8010.lock);
946 spin_lock_irq(&emu->reg_lock);
947 ipcm->channels = pcm->channels;
948 ipcm->tram_start = pcm->tram_start;
949 ipcm->buffer_size = pcm->buffer_size;
950 ipcm->gpr_size = pcm->gpr_size;
951 ipcm->gpr_ptr = pcm->gpr_ptr;
952 ipcm->gpr_count = pcm->gpr_count;
953 ipcm->gpr_tmpcount = pcm->gpr_tmpcount;
954 ipcm->gpr_trigger = pcm->gpr_trigger;
955 ipcm->gpr_running = pcm->gpr_running;
956 for (i = 0; i < pcm->channels; i++)
957 ipcm->etram[i] = pcm->etram[i];
958 ipcm->res1 = ipcm->res2 = 0;
959 ipcm->pad = 0;
960 spin_unlock_irq(&emu->reg_lock);
961 up(&emu->fx8010.lock);
962 return err;
963}
964
965#define SND_EMU10K1_GPR_CONTROLS 44
966#define SND_EMU10K1_INPUTS 12
967#define SND_EMU10K1_PLAYBACK_CHANNELS 8
968#define SND_EMU10K1_CAPTURE_CHANNELS 4
969
970static void __devinit snd_emu10k1_init_mono_control(emu10k1_fx8010_control_gpr_t *ctl, const char *name, int gpr, int defval)
971{
972 ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
973 strcpy(ctl->id.name, name);
974 ctl->vcount = ctl->count = 1;
975 ctl->gpr[0] = gpr + 0; ctl->value[0] = defval;
976 ctl->min = 0;
977 ctl->max = 100;
978 ctl->translation = EMU10K1_GPR_TRANSLATION_TABLE100;
979}
980
981static void __devinit snd_emu10k1_init_stereo_control(emu10k1_fx8010_control_gpr_t *ctl, const char *name, int gpr, int defval)
982{
983 ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
984 strcpy(ctl->id.name, name);
985 ctl->vcount = ctl->count = 2;
986 ctl->gpr[0] = gpr + 0; ctl->value[0] = defval;
987 ctl->gpr[1] = gpr + 1; ctl->value[1] = defval;
988 ctl->min = 0;
989 ctl->max = 100;
990 ctl->translation = EMU10K1_GPR_TRANSLATION_TABLE100;
991}
992
993static void __devinit snd_emu10k1_init_mono_onoff_control(emu10k1_fx8010_control_gpr_t *ctl, const char *name, int gpr, int defval)
994{
995 ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
996 strcpy(ctl->id.name, name);
997 ctl->vcount = ctl->count = 1;
998 ctl->gpr[0] = gpr + 0; ctl->value[0] = defval;
999 ctl->min = 0;
1000 ctl->max = 1;
1001 ctl->translation = EMU10K1_GPR_TRANSLATION_ONOFF;
1002}
1003
1004static void __devinit snd_emu10k1_init_stereo_onoff_control(emu10k1_fx8010_control_gpr_t *ctl, const char *name, int gpr, int defval)
1005{
1006 ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1007 strcpy(ctl->id.name, name);
1008 ctl->vcount = ctl->count = 2;
1009 ctl->gpr[0] = gpr + 0; ctl->value[0] = defval;
1010 ctl->gpr[1] = gpr + 1; ctl->value[1] = defval;
1011 ctl->min = 0;
1012 ctl->max = 1;
1013 ctl->translation = EMU10K1_GPR_TRANSLATION_ONOFF;
1014}
1015
1016
1017/*
1018 * initial DSP configuration for Audigy
1019 */
1020
1021static int __devinit _snd_emu10k1_audigy_init_efx(emu10k1_t *emu)
1022{
1023 int err, i, z, gpr, nctl;
1024 const int playback = 10;
1025 const int capture = playback + (SND_EMU10K1_PLAYBACK_CHANNELS * 2); /* we reserve 10 voices */
1026 const int stereo_mix = capture + 2;
1027 const int tmp = 0x88;
1028 u32 ptr;
1029 emu10k1_fx8010_code_t *icode = NULL;
1030 emu10k1_fx8010_control_gpr_t *controls = NULL, *ctl;
1031 u32 *gpr_map;
1032 mm_segment_t seg;
1033
1034 spin_lock_init(&emu->fx8010.irq_lock);
1035 INIT_LIST_HEAD(&emu->fx8010.gpr_ctl);
1036
1037 if ((icode = kzalloc(sizeof(*icode), GFP_KERNEL)) == NULL ||
1038 (icode->gpr_map = (u_int32_t __user *)kcalloc(512 + 256 + 256 + 2 * 1024, sizeof(u_int32_t), GFP_KERNEL)) == NULL ||
1039 (controls = kcalloc(SND_EMU10K1_GPR_CONTROLS, sizeof(*controls), GFP_KERNEL)) == NULL) {
1040 err = -ENOMEM;
1041 goto __err;
1042 }
1043 gpr_map = (u32 *)icode->gpr_map;
1044
1045 icode->tram_data_map = icode->gpr_map + 512;
1046 icode->tram_addr_map = icode->tram_data_map + 256;
1047 icode->code = icode->tram_addr_map + 256;
1048
1049 /* clear free GPRs */
1050 for (i = 0; i < 512; i++)
1051 set_bit(i, icode->gpr_valid);
1052
1053 /* clear TRAM data & address lines */
1054 for (i = 0; i < 256; i++)
1055 set_bit(i, icode->tram_valid);
1056
1057 strcpy(icode->name, "Audigy DSP code for ALSA");
1058 ptr = 0;
1059 nctl = 0;
1060 gpr = stereo_mix + 10;
1061
1062 /* stop FX processor */
1063 snd_emu10k1_ptr_write(emu, A_DBG, 0, (emu->fx8010.dbg = 0) | A_DBG_SINGLE_STEP);
1064
1065 /* PCM front Playback Volume (independent from stereo mix) */
1066 A_OP(icode, &ptr, iMAC0, A_GPR(playback), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LEFT_FRONT));
1067 A_OP(icode, &ptr, iMAC0, A_GPR(playback+1), A_C_00000000, A_GPR(gpr+1), A_FXBUS(FXBUS_PCM_RIGHT_FRONT));
1068 snd_emu10k1_init_stereo_control(&controls[nctl++], "PCM Front Playback Volume", gpr, 100);
1069 gpr += 2;
1070
1071 /* PCM Surround Playback (independent from stereo mix) */
1072 A_OP(icode, &ptr, iMAC0, A_GPR(playback+2), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LEFT_REAR));
1073 A_OP(icode, &ptr, iMAC0, A_GPR(playback+3), A_C_00000000, A_GPR(gpr+1), A_FXBUS(FXBUS_PCM_RIGHT_REAR));
1074 snd_emu10k1_init_stereo_control(&controls[nctl++], "PCM Surround Playback Volume", gpr, 100);
1075 gpr += 2;
1076
1077 /* PCM Side Playback (independent from stereo mix) */
1078 if (emu->card_capabilities->spk71) {
1079 A_OP(icode, &ptr, iMAC0, A_GPR(playback+6), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LEFT_SIDE));
1080 A_OP(icode, &ptr, iMAC0, A_GPR(playback+7), A_C_00000000, A_GPR(gpr+1), A_FXBUS(FXBUS_PCM_RIGHT_SIDE));
1081 snd_emu10k1_init_stereo_control(&controls[nctl++], "PCM Side Playback Volume", gpr, 100);
1082 gpr += 2;
1083 }
1084
1085 /* PCM Center Playback (independent from stereo mix) */
1086 A_OP(icode, &ptr, iMAC0, A_GPR(playback+4), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_CENTER));
1087 snd_emu10k1_init_mono_control(&controls[nctl++], "PCM Center Playback Volume", gpr, 100);
1088 gpr++;
1089
1090 /* PCM LFE Playback (independent from stereo mix) */
1091 A_OP(icode, &ptr, iMAC0, A_GPR(playback+5), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LFE));
1092 snd_emu10k1_init_mono_control(&controls[nctl++], "PCM LFE Playback Volume", gpr, 100);
1093 gpr++;
1094
1095 /*
1096 * Stereo Mix
1097 */
1098 /* Wave (PCM) Playback Volume (will be renamed later) */
1099 A_OP(icode, &ptr, iMAC0, A_GPR(stereo_mix), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LEFT));
1100 A_OP(icode, &ptr, iMAC0, A_GPR(stereo_mix+1), A_C_00000000, A_GPR(gpr+1), A_FXBUS(FXBUS_PCM_RIGHT));
1101 snd_emu10k1_init_stereo_control(&controls[nctl++], "Wave Playback Volume", gpr, 100);
1102 gpr += 2;
1103
1104 /* Music Playback */
1105 A_OP(icode, &ptr, iMAC0, A_GPR(stereo_mix+0), A_GPR(stereo_mix+0), A_GPR(gpr), A_FXBUS(FXBUS_MIDI_LEFT));
1106 A_OP(icode, &ptr, iMAC0, A_GPR(stereo_mix+1), A_GPR(stereo_mix+1), A_GPR(gpr+1), A_FXBUS(FXBUS_MIDI_RIGHT));
1107 snd_emu10k1_init_stereo_control(&controls[nctl++], "Music Playback Volume", gpr, 100);
1108 gpr += 2;
1109
1110 /* Wave (PCM) Capture */
1111 A_OP(icode, &ptr, iMAC0, A_GPR(capture+0), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LEFT));
1112 A_OP(icode, &ptr, iMAC0, A_GPR(capture+1), A_C_00000000, A_GPR(gpr+1), A_FXBUS(FXBUS_PCM_RIGHT));
1113 snd_emu10k1_init_stereo_control(&controls[nctl++], "PCM Capture Volume", gpr, 0);
1114 gpr += 2;
1115
1116 /* Music Capture */
1117 A_OP(icode, &ptr, iMAC0, A_GPR(capture+0), A_GPR(capture+0), A_GPR(gpr), A_FXBUS(FXBUS_MIDI_LEFT));
1118 A_OP(icode, &ptr, iMAC0, A_GPR(capture+1), A_GPR(capture+1), A_GPR(gpr+1), A_FXBUS(FXBUS_MIDI_RIGHT));
1119 snd_emu10k1_init_stereo_control(&controls[nctl++], "Music Capture Volume", gpr, 0);
1120 gpr += 2;
1121
1122 /*
1123 * inputs
1124 */
1125#define A_ADD_VOLUME_IN(var,vol,input) \
1126 A_OP(icode, &ptr, iMAC0, A_GPR(var), A_GPR(var), A_GPR(vol), A_EXTIN(input))
1127
1128 /* AC'97 Playback Volume - used only for mic */
1129 A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_AC97_L);
1130 A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_AC97_R);
1131 snd_emu10k1_init_stereo_control(&controls[nctl++], "AMic Playback Volume", gpr, 0);
1132 gpr += 2;
1133 /* AC'97 Capture Volume - used only for mic */
1134 A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_AC97_L);
1135 A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_AC97_R);
1136 snd_emu10k1_init_stereo_control(&controls[nctl++], "Mic Capture Volume", gpr, 0);
1137 gpr += 2;
1138
1139 /* mic capture buffer */
1140 A_OP(icode, &ptr, iINTERP, A_EXTOUT(A_EXTOUT_MIC_CAP), A_EXTIN(A_EXTIN_AC97_L), 0xcd, A_EXTIN(A_EXTIN_AC97_R));
1141
1142 /* Audigy CD Playback Volume */
1143 A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_SPDIF_CD_L);
1144 A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_SPDIF_CD_R);
1145 snd_emu10k1_init_stereo_control(&controls[nctl++],
1146 emu->card_capabilities->ac97_chip ? "Audigy CD Playback Volume" : "CD Playback Volume",
1147 gpr, 0);
1148 gpr += 2;
1149 /* Audigy CD Capture Volume */
1150 A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_SPDIF_CD_L);
1151 A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_SPDIF_CD_R);
1152 snd_emu10k1_init_stereo_control(&controls[nctl++],
1153 emu->card_capabilities->ac97_chip ? "Audigy CD Capture Volume" : "CD Capture Volume",
1154 gpr, 0);
1155 gpr += 2;
1156
1157 /* Optical SPDIF Playback Volume */
1158 A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_OPT_SPDIF_L);
1159 A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_OPT_SPDIF_R);
1160 snd_emu10k1_init_stereo_control(&controls[nctl++], "IEC958 Optical Playback Volume", gpr, 0);
1161 gpr += 2;
1162 /* Optical SPDIF Capture Volume */
1163 A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_OPT_SPDIF_L);
1164 A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_OPT_SPDIF_R);
1165 snd_emu10k1_init_stereo_control(&controls[nctl++], "IEC958 Optical Capture Volume", gpr, 0);
1166 gpr += 2;
1167
1168 /* Line2 Playback Volume */
1169 A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_LINE2_L);
1170 A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_LINE2_R);
1171 snd_emu10k1_init_stereo_control(&controls[nctl++],
1172 emu->card_capabilities->ac97_chip ? "Line2 Playback Volume" : "Line Playback Volume",
1173 gpr, 0);
1174 gpr += 2;
1175 /* Line2 Capture Volume */
1176 A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_LINE2_L);
1177 A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_LINE2_R);
1178 snd_emu10k1_init_stereo_control(&controls[nctl++],
1179 emu->card_capabilities->ac97_chip ? "Line2 Capture Volume" : "Line Capture Volume",
1180 gpr, 0);
1181 gpr += 2;
1182
1183 /* Philips ADC Playback Volume */
1184 A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_ADC_L);
1185 A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_ADC_R);
1186 snd_emu10k1_init_stereo_control(&controls[nctl++], "Analog Mix Playback Volume", gpr, 0);
1187 gpr += 2;
1188 /* Philips ADC Capture Volume */
1189 A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_ADC_L);
1190 A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_ADC_R);
1191 snd_emu10k1_init_stereo_control(&controls[nctl++], "Analog Mix Capture Volume", gpr, 0);
1192 gpr += 2;
1193
1194 /* Aux2 Playback Volume */
1195 A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_AUX2_L);
1196 A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_AUX2_R);
1197 snd_emu10k1_init_stereo_control(&controls[nctl++],
1198 emu->card_capabilities->ac97_chip ? "Aux2 Playback Volume" : "Aux Playback Volume",
1199 gpr, 0);
1200 gpr += 2;
1201 /* Aux2 Capture Volume */
1202 A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_AUX2_L);
1203 A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_AUX2_R);
1204 snd_emu10k1_init_stereo_control(&controls[nctl++],
1205 emu->card_capabilities->ac97_chip ? "Aux2 Capture Volume" : "Aux Capture Volume",
1206 gpr, 0);
1207 gpr += 2;
1208
1209 /* Stereo Mix Front Playback Volume */
1210 A_OP(icode, &ptr, iMAC0, A_GPR(playback), A_GPR(playback), A_GPR(gpr), A_GPR(stereo_mix));
1211 A_OP(icode, &ptr, iMAC0, A_GPR(playback+1), A_GPR(playback+1), A_GPR(gpr+1), A_GPR(stereo_mix+1));
1212 snd_emu10k1_init_stereo_control(&controls[nctl++], "Front Playback Volume", gpr, 100);
1213 gpr += 2;
1214
1215 /* Stereo Mix Surround Playback */
1216 A_OP(icode, &ptr, iMAC0, A_GPR(playback+2), A_GPR(playback+2), A_GPR(gpr), A_GPR(stereo_mix));
1217 A_OP(icode, &ptr, iMAC0, A_GPR(playback+3), A_GPR(playback+3), A_GPR(gpr+1), A_GPR(stereo_mix+1));
1218 snd_emu10k1_init_stereo_control(&controls[nctl++], "Surround Playback Volume", gpr, 0);
1219 gpr += 2;
1220
1221 /* Stereo Mix Center Playback */
1222 /* Center = sub = Left/2 + Right/2 */
1223 A_OP(icode, &ptr, iINTERP, A_GPR(tmp), A_GPR(stereo_mix), 0xcd, A_GPR(stereo_mix+1));
1224 A_OP(icode, &ptr, iMAC0, A_GPR(playback+4), A_GPR(playback+4), A_GPR(gpr), A_GPR(tmp));
1225 snd_emu10k1_init_mono_control(&controls[nctl++], "Center Playback Volume", gpr, 0);
1226 gpr++;
1227
1228 /* Stereo Mix LFE Playback */
1229 A_OP(icode, &ptr, iMAC0, A_GPR(playback+5), A_GPR(playback+5), A_GPR(gpr), A_GPR(tmp));
1230 snd_emu10k1_init_mono_control(&controls[nctl++], "LFE Playback Volume", gpr, 0);
1231 gpr++;
1232
1233 if (emu->card_capabilities->spk71) {
1234 /* Stereo Mix Side Playback */
1235 A_OP(icode, &ptr, iMAC0, A_GPR(playback+6), A_GPR(playback+6), A_GPR(gpr), A_GPR(stereo_mix));
1236 A_OP(icode, &ptr, iMAC0, A_GPR(playback+7), A_GPR(playback+7), A_GPR(gpr+1), A_GPR(stereo_mix+1));
1237 snd_emu10k1_init_stereo_control(&controls[nctl++], "Side Playback Volume", gpr, 0);
1238 gpr += 2;
1239 }
1240
1241 /*
1242 * outputs
1243 */
1244#define A_PUT_OUTPUT(out,src) A_OP(icode, &ptr, iACC3, A_EXTOUT(out), A_C_00000000, A_C_00000000, A_GPR(src))
1245#define A_PUT_STEREO_OUTPUT(out1,out2,src) \
1246 {A_PUT_OUTPUT(out1,src); A_PUT_OUTPUT(out2,src+1);}
1247
1248#define _A_SWITCH(icode, ptr, dst, src, sw) \
1249 A_OP((icode), ptr, iMACINT0, dst, A_C_00000000, src, sw);
1250#define A_SWITCH(icode, ptr, dst, src, sw) \
1251 _A_SWITCH(icode, ptr, A_GPR(dst), A_GPR(src), A_GPR(sw))
1252#define _A_SWITCH_NEG(icode, ptr, dst, src) \
1253 A_OP((icode), ptr, iANDXOR, dst, src, A_C_00000001, A_C_00000001);
1254#define A_SWITCH_NEG(icode, ptr, dst, src) \
1255 _A_SWITCH_NEG(icode, ptr, A_GPR(dst), A_GPR(src))
1256
1257
1258 /*
1259 * Process tone control
1260 */
1261 A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 0), A_GPR(playback + 0), A_C_00000000, A_C_00000000); /* left */
1262 A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 1), A_GPR(playback + 1), A_C_00000000, A_C_00000000); /* right */
1263 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 */
1264 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 */
1265 A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 4), A_GPR(playback + 4), A_C_00000000, A_C_00000000); /* center */
1266 A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 5), A_GPR(playback + 5), A_C_00000000, A_C_00000000); /* LFE */
1267
1268 if (emu->card_capabilities->spk71) {
1269 A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 6), A_GPR(playback + 6), A_C_00000000, A_C_00000000); /* side left */
1270 A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 7), A_GPR(playback + 7), A_C_00000000, A_C_00000000); /* side right */
1271 }
1272
1273 ctl = &controls[nctl + 0];
1274 ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1275 strcpy(ctl->id.name, "Tone Control - Bass");
1276 ctl->vcount = 2;
1277 ctl->count = 10;
1278 ctl->min = 0;
1279 ctl->max = 40;
1280 ctl->value[0] = ctl->value[1] = 20;
1281 ctl->translation = EMU10K1_GPR_TRANSLATION_BASS;
1282 ctl = &controls[nctl + 1];
1283 ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1284 strcpy(ctl->id.name, "Tone Control - Treble");
1285 ctl->vcount = 2;
1286 ctl->count = 10;
1287 ctl->min = 0;
1288 ctl->max = 40;
1289 ctl->value[0] = ctl->value[1] = 20;
1290 ctl->translation = EMU10K1_GPR_TRANSLATION_TREBLE;
1291
1292#define BASS_GPR 0x8c
1293#define TREBLE_GPR 0x96
1294
1295 for (z = 0; z < 5; z++) {
1296 int j;
1297 for (j = 0; j < 2; j++) {
1298 controls[nctl + 0].gpr[z * 2 + j] = BASS_GPR + z * 2 + j;
1299 controls[nctl + 1].gpr[z * 2 + j] = TREBLE_GPR + z * 2 + j;
1300 }
1301 }
1302 for (z = 0; z < 4; z++) { /* front/rear/center-lfe/side */
1303 int j, k, l, d;
1304 for (j = 0; j < 2; j++) { /* left/right */
1305 k = 0xb0 + (z * 8) + (j * 4);
1306 l = 0xe0 + (z * 8) + (j * 4);
1307 d = playback + SND_EMU10K1_PLAYBACK_CHANNELS + z * 2 + j;
1308
1309 A_OP(icode, &ptr, iMAC0, A_C_00000000, A_C_00000000, A_GPR(d), A_GPR(BASS_GPR + 0 + j));
1310 A_OP(icode, &ptr, iMACMV, A_GPR(k+1), A_GPR(k), A_GPR(k+1), A_GPR(BASS_GPR + 4 + j));
1311 A_OP(icode, &ptr, iMACMV, A_GPR(k), A_GPR(d), A_GPR(k), A_GPR(BASS_GPR + 2 + j));
1312 A_OP(icode, &ptr, iMACMV, A_GPR(k+3), A_GPR(k+2), A_GPR(k+3), A_GPR(BASS_GPR + 8 + j));
1313 A_OP(icode, &ptr, iMAC0, A_GPR(k+2), A_GPR_ACCU, A_GPR(k+2), A_GPR(BASS_GPR + 6 + j));
1314 A_OP(icode, &ptr, iACC3, A_GPR(k+2), A_GPR(k+2), A_GPR(k+2), A_C_00000000);
1315
1316 A_OP(icode, &ptr, iMAC0, A_C_00000000, A_C_00000000, A_GPR(k+2), A_GPR(TREBLE_GPR + 0 + j));
1317 A_OP(icode, &ptr, iMACMV, A_GPR(l+1), A_GPR(l), A_GPR(l+1), A_GPR(TREBLE_GPR + 4 + j));
1318 A_OP(icode, &ptr, iMACMV, A_GPR(l), A_GPR(k+2), A_GPR(l), A_GPR(TREBLE_GPR + 2 + j));
1319 A_OP(icode, &ptr, iMACMV, A_GPR(l+3), A_GPR(l+2), A_GPR(l+3), A_GPR(TREBLE_GPR + 8 + j));
1320 A_OP(icode, &ptr, iMAC0, A_GPR(l+2), A_GPR_ACCU, A_GPR(l+2), A_GPR(TREBLE_GPR + 6 + j));
1321 A_OP(icode, &ptr, iMACINT0, A_GPR(l+2), A_C_00000000, A_GPR(l+2), A_C_00000010);
1322
1323 A_OP(icode, &ptr, iACC3, A_GPR(d), A_GPR(l+2), A_C_00000000, A_C_00000000);
1324
1325 if (z == 2) /* center */
1326 break;
1327 }
1328 }
1329 nctl += 2;
1330
1331#undef BASS_GPR
1332#undef TREBLE_GPR
1333
1334 for (z = 0; z < 8; z++) {
1335 A_SWITCH(icode, &ptr, tmp + 0, playback + SND_EMU10K1_PLAYBACK_CHANNELS + z, gpr + 0);
1336 A_SWITCH_NEG(icode, &ptr, tmp + 1, gpr + 0);
1337 A_SWITCH(icode, &ptr, tmp + 1, playback + z, tmp + 1);
1338 A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + z), A_GPR(tmp + 0), A_GPR(tmp + 1), A_C_00000000);
1339 }
1340 snd_emu10k1_init_stereo_onoff_control(controls + nctl++, "Tone Control - Switch", gpr, 0);
1341 gpr += 2;
1342
1343 /* Master volume (will be renamed later) */
1344 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));
1345 A_OP(icode, &ptr, iMAC0, A_GPR(playback+1+SND_EMU10K1_PLAYBACK_CHANNELS), A_C_00000000, A_GPR(gpr), A_GPR(playback+1+SND_EMU10K1_PLAYBACK_CHANNELS));
1346 A_OP(icode, &ptr, iMAC0, A_GPR(playback+2+SND_EMU10K1_PLAYBACK_CHANNELS), A_C_00000000, A_GPR(gpr), A_GPR(playback+2+SND_EMU10K1_PLAYBACK_CHANNELS));
1347 A_OP(icode, &ptr, iMAC0, A_GPR(playback+3+SND_EMU10K1_PLAYBACK_CHANNELS), A_C_00000000, A_GPR(gpr), A_GPR(playback+3+SND_EMU10K1_PLAYBACK_CHANNELS));
1348 A_OP(icode, &ptr, iMAC0, A_GPR(playback+4+SND_EMU10K1_PLAYBACK_CHANNELS), A_C_00000000, A_GPR(gpr), A_GPR(playback+4+SND_EMU10K1_PLAYBACK_CHANNELS));
1349 A_OP(icode, &ptr, iMAC0, A_GPR(playback+5+SND_EMU10K1_PLAYBACK_CHANNELS), A_C_00000000, A_GPR(gpr), A_GPR(playback+5+SND_EMU10K1_PLAYBACK_CHANNELS));
1350 A_OP(icode, &ptr, iMAC0, A_GPR(playback+6+SND_EMU10K1_PLAYBACK_CHANNELS), A_C_00000000, A_GPR(gpr), A_GPR(playback+6+SND_EMU10K1_PLAYBACK_CHANNELS));
1351 A_OP(icode, &ptr, iMAC0, A_GPR(playback+7+SND_EMU10K1_PLAYBACK_CHANNELS), A_C_00000000, A_GPR(gpr), A_GPR(playback+7+SND_EMU10K1_PLAYBACK_CHANNELS));
1352 snd_emu10k1_init_stereo_control(&controls[nctl++], "Wave Master Playback Volume", gpr, 0);
1353 //snd_emu10k1_init_mono_control(&controls[nctl++], "Wave Master Playback Volume", gpr, 0);
1354 gpr += 2;
1355
1356 /* analog speakers */
1357 A_PUT_STEREO_OUTPUT(A_EXTOUT_AFRONT_L, A_EXTOUT_AFRONT_R, playback + SND_EMU10K1_PLAYBACK_CHANNELS);
1358 A_PUT_STEREO_OUTPUT(A_EXTOUT_AREAR_L, A_EXTOUT_AREAR_R, playback+2 + SND_EMU10K1_PLAYBACK_CHANNELS);
1359 A_PUT_OUTPUT(A_EXTOUT_ACENTER, playback+4 + SND_EMU10K1_PLAYBACK_CHANNELS);
1360 A_PUT_OUTPUT(A_EXTOUT_ALFE, playback+5 + SND_EMU10K1_PLAYBACK_CHANNELS);
1361
1362 if (emu->card_capabilities->spk71)
1363 A_PUT_STEREO_OUTPUT(A_EXTOUT_ASIDE_L, A_EXTOUT_ASIDE_R, playback+6 + SND_EMU10K1_PLAYBACK_CHANNELS);
1364
1365 /* headphone */
1366 A_PUT_STEREO_OUTPUT(A_EXTOUT_HEADPHONE_L, A_EXTOUT_HEADPHONE_R, playback + SND_EMU10K1_PLAYBACK_CHANNELS);
1367
1368 /* digital outputs */
1369 /* A_PUT_STEREO_OUTPUT(A_EXTOUT_FRONT_L, A_EXTOUT_FRONT_R, playback + SND_EMU10K1_PLAYBACK_CHANNELS); */
1370
1371 /* IEC958 Optical Raw Playback Switch */
1372 gpr_map[gpr++] = 0;
1373 gpr_map[gpr++] = 0x1008;
1374 gpr_map[gpr++] = 0xffff0000;
1375 for (z = 0; z < 2; z++) {
1376 A_OP(icode, &ptr, iMAC0, A_GPR(tmp + 2), A_FXBUS(FXBUS_PT_LEFT + z), A_C_00000000, A_C_00000000);
1377 A_OP(icode, &ptr, iSKIP, A_GPR_COND, A_GPR_COND, A_GPR(gpr - 2), A_C_00000001);
1378 A_OP(icode, &ptr, iACC3, A_GPR(tmp + 2), A_C_00000000, A_C_00010000, A_GPR(tmp + 2));
1379 A_OP(icode, &ptr, iANDXOR, A_GPR(tmp + 2), A_GPR(tmp + 2), A_GPR(gpr - 1), A_C_00000000);
1380 A_SWITCH(icode, &ptr, tmp + 0, tmp + 2, gpr + z);
1381 A_SWITCH_NEG(icode, &ptr, tmp + 1, gpr + z);
1382 A_SWITCH(icode, &ptr, tmp + 1, playback + SND_EMU10K1_PLAYBACK_CHANNELS + z, tmp + 1);
1383 if ((z==1) && (emu->card_capabilities->spdif_bug)) {
1384 /* Due to a SPDIF output bug on some Audigy cards, this code delays the Right channel by 1 sample */
1385 snd_printk("Installing spdif_bug patch: %s\n", emu->card_capabilities->name);
1386 A_OP(icode, &ptr, iACC3, A_EXTOUT(A_EXTOUT_FRONT_L + z), A_GPR(gpr - 3), A_C_00000000, A_C_00000000);
1387 A_OP(icode, &ptr, iACC3, A_GPR(gpr - 3), A_GPR(tmp + 0), A_GPR(tmp + 1), A_C_00000000);
1388 } else {
1389 A_OP(icode, &ptr, iACC3, A_EXTOUT(A_EXTOUT_FRONT_L + z), A_GPR(tmp + 0), A_GPR(tmp + 1), A_C_00000000);
1390 }
1391 }
1392 snd_emu10k1_init_stereo_onoff_control(controls + nctl++, "IEC958 Optical Raw Playback Switch", gpr, 0);
1393 gpr += 2;
1394
1395 A_PUT_STEREO_OUTPUT(A_EXTOUT_REAR_L, A_EXTOUT_REAR_R, playback+2 + SND_EMU10K1_PLAYBACK_CHANNELS);
1396 A_PUT_OUTPUT(A_EXTOUT_CENTER, playback+4 + SND_EMU10K1_PLAYBACK_CHANNELS);
1397 A_PUT_OUTPUT(A_EXTOUT_LFE, playback+5 + SND_EMU10K1_PLAYBACK_CHANNELS);
1398
1399 /* ADC buffer */
1400 A_PUT_OUTPUT(A_EXTOUT_ADC_CAP_L, capture);
1401 A_PUT_OUTPUT(A_EXTOUT_ADC_CAP_R, capture+1);
1402
1403 /* EFX capture - capture the 16 EXTINs */
1404 for (z = 0; z < 16; z++) {
1405 A_OP(icode, &ptr, iACC3, A_FXBUS2(z), A_C_00000000, A_C_00000000, A_EXTIN(z));
1406 }
1407
1408 /*
1409 * ok, set up done..
1410 */
1411
1412 if (gpr > tmp) {
1413 snd_BUG();
1414 err = -EIO;
1415 goto __err;
1416 }
1417 /* clear remaining instruction memory */
1418 while (ptr < 0x400)
1419 A_OP(icode, &ptr, 0x0f, 0xc0, 0xc0, 0xcf, 0xc0);
1420
1421 seg = snd_enter_user();
1422 icode->gpr_add_control_count = nctl;
1423 icode->gpr_add_controls = (emu10k1_fx8010_control_gpr_t __user *)controls;
1424 err = snd_emu10k1_icode_poke(emu, icode);
1425 snd_leave_user(seg);
1426
1427__err:
1428 kfree(controls);
1429 if (icode != NULL) {
1430 kfree((void *)icode->gpr_map);
1431 kfree(icode);
1432 }
1433 return err;
1434}
1435
1436
1437/*
1438 * initial DSP configuration for Emu10k1
1439 */
1440
1441/* when volume = max, then copy only to avoid volume modification */
1442/* with iMAC0 (negative values) */
1443static void __devinit _volume(emu10k1_fx8010_code_t *icode, u32 *ptr, u32 dst, u32 src, u32 vol)
1444{
1445 OP(icode, ptr, iMAC0, dst, C_00000000, src, vol);
1446 OP(icode, ptr, iANDXOR, C_00000000, vol, C_ffffffff, C_7fffffff);
1447 OP(icode, ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, C_00000001);
1448 OP(icode, ptr, iACC3, dst, src, C_00000000, C_00000000);
1449}
1450static void __devinit _volume_add(emu10k1_fx8010_code_t *icode, u32 *ptr, u32 dst, u32 src, u32 vol)
1451{
1452 OP(icode, ptr, iANDXOR, C_00000000, vol, C_ffffffff, C_7fffffff);
1453 OP(icode, ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, C_00000002);
1454 OP(icode, ptr, iMACINT0, dst, dst, src, C_00000001);
1455 OP(icode, ptr, iSKIP, C_00000000, C_7fffffff, C_7fffffff, C_00000001);
1456 OP(icode, ptr, iMAC0, dst, dst, src, vol);
1457}
1458static void __devinit _volume_out(emu10k1_fx8010_code_t *icode, u32 *ptr, u32 dst, u32 src, u32 vol)
1459{
1460 OP(icode, ptr, iANDXOR, C_00000000, vol, C_ffffffff, C_7fffffff);
1461 OP(icode, ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, C_00000002);
1462 OP(icode, ptr, iACC3, dst, src, C_00000000, C_00000000);
1463 OP(icode, ptr, iSKIP, C_00000000, C_7fffffff, C_7fffffff, C_00000001);
1464 OP(icode, ptr, iMAC0, dst, C_00000000, src, vol);
1465}
1466
1467#define VOLUME(icode, ptr, dst, src, vol) \
1468 _volume(icode, ptr, GPR(dst), GPR(src), GPR(vol))
1469#define VOLUME_IN(icode, ptr, dst, src, vol) \
1470 _volume(icode, ptr, GPR(dst), EXTIN(src), GPR(vol))
1471#define VOLUME_ADD(icode, ptr, dst, src, vol) \
1472 _volume_add(icode, ptr, GPR(dst), GPR(src), GPR(vol))
1473#define VOLUME_ADDIN(icode, ptr, dst, src, vol) \
1474 _volume_add(icode, ptr, GPR(dst), EXTIN(src), GPR(vol))
1475#define VOLUME_OUT(icode, ptr, dst, src, vol) \
1476 _volume_out(icode, ptr, EXTOUT(dst), GPR(src), GPR(vol))
1477#define _SWITCH(icode, ptr, dst, src, sw) \
1478 OP((icode), ptr, iMACINT0, dst, C_00000000, src, sw);
1479#define SWITCH(icode, ptr, dst, src, sw) \
1480 _SWITCH(icode, ptr, GPR(dst), GPR(src), GPR(sw))
1481#define SWITCH_IN(icode, ptr, dst, src, sw) \
1482 _SWITCH(icode, ptr, GPR(dst), EXTIN(src), GPR(sw))
1483#define _SWITCH_NEG(icode, ptr, dst, src) \
1484 OP((icode), ptr, iANDXOR, dst, src, C_00000001, C_00000001);
1485#define SWITCH_NEG(icode, ptr, dst, src) \
1486 _SWITCH_NEG(icode, ptr, GPR(dst), GPR(src))
1487
1488
1489static int __devinit _snd_emu10k1_init_efx(emu10k1_t *emu)
1490{
1491 int err, i, z, gpr, tmp, playback, capture;
1492 u32 ptr;
1493 emu10k1_fx8010_code_t *icode;
1494 emu10k1_fx8010_pcm_t *ipcm = NULL;
1495 emu10k1_fx8010_control_gpr_t *controls = NULL, *ctl;
1496 u32 *gpr_map;
1497 mm_segment_t seg;
1498
1499 spin_lock_init(&emu->fx8010.irq_lock);
1500 INIT_LIST_HEAD(&emu->fx8010.gpr_ctl);
1501
1502 if ((icode = kzalloc(sizeof(*icode), GFP_KERNEL)) == NULL)
1503 return -ENOMEM;
1504 if ((icode->gpr_map = (u_int32_t __user *)kcalloc(256 + 160 + 160 + 2 * 512, sizeof(u_int32_t), GFP_KERNEL)) == NULL ||
1505 (controls = kcalloc(SND_EMU10K1_GPR_CONTROLS, sizeof(emu10k1_fx8010_control_gpr_t), GFP_KERNEL)) == NULL ||
1506 (ipcm = kzalloc(sizeof(*ipcm), GFP_KERNEL)) == NULL) {
1507 err = -ENOMEM;
1508 goto __err;
1509 }
1510 gpr_map = (u32 *)icode->gpr_map;
1511
1512 icode->tram_data_map = icode->gpr_map + 256;
1513 icode->tram_addr_map = icode->tram_data_map + 160;
1514 icode->code = icode->tram_addr_map + 160;
1515
1516 /* clear free GPRs */
1517 for (i = 0; i < 256; i++)
1518 set_bit(i, icode->gpr_valid);
1519
1520 /* clear TRAM data & address lines */
1521 for (i = 0; i < 160; i++)
1522 set_bit(i, icode->tram_valid);
1523
1524 strcpy(icode->name, "SB Live! FX8010 code for ALSA v1.2 by Jaroslav Kysela");
1525 ptr = 0; i = 0;
1526 /* we have 12 inputs */
1527 playback = SND_EMU10K1_INPUTS;
1528 /* we have 6 playback channels and tone control doubles */
1529 capture = playback + (SND_EMU10K1_PLAYBACK_CHANNELS * 2);
1530 gpr = capture + SND_EMU10K1_CAPTURE_CHANNELS;
1531 tmp = 0x88; /* we need 4 temporary GPR */
1532 /* from 0x8c to 0xff is the area for tone control */
1533
1534 /* stop FX processor */
1535 snd_emu10k1_ptr_write(emu, DBG, 0, (emu->fx8010.dbg = 0) | EMU10K1_DBG_SINGLE_STEP);
1536
1537 /*
1538 * Process FX Buses
1539 */
1540 OP(icode, &ptr, iMACINT0, GPR(0), C_00000000, FXBUS(FXBUS_PCM_LEFT), C_00000004);
1541 OP(icode, &ptr, iMACINT0, GPR(1), C_00000000, FXBUS(FXBUS_PCM_RIGHT), C_00000004);
1542 OP(icode, &ptr, iMACINT0, GPR(2), C_00000000, FXBUS(FXBUS_MIDI_LEFT), C_00000004);
1543 OP(icode, &ptr, iMACINT0, GPR(3), C_00000000, FXBUS(FXBUS_MIDI_RIGHT), C_00000004);
1544 OP(icode, &ptr, iMACINT0, GPR(4), C_00000000, FXBUS(FXBUS_PCM_LEFT_REAR), C_00000004);
1545 OP(icode, &ptr, iMACINT0, GPR(5), C_00000000, FXBUS(FXBUS_PCM_RIGHT_REAR), C_00000004);
1546 OP(icode, &ptr, iMACINT0, GPR(6), C_00000000, FXBUS(FXBUS_PCM_CENTER), C_00000004);
1547 OP(icode, &ptr, iMACINT0, GPR(7), C_00000000, FXBUS(FXBUS_PCM_LFE), C_00000004);
1548 OP(icode, &ptr, iMACINT0, GPR(8), C_00000000, C_00000000, C_00000000); /* S/PDIF left */
1549 OP(icode, &ptr, iMACINT0, GPR(9), C_00000000, C_00000000, C_00000000); /* S/PDIF right */
1550 OP(icode, &ptr, iMACINT0, GPR(10), C_00000000, FXBUS(FXBUS_PCM_LEFT_FRONT), C_00000004);
1551 OP(icode, &ptr, iMACINT0, GPR(11), C_00000000, FXBUS(FXBUS_PCM_RIGHT_FRONT), C_00000004);
1552
1553 /* Raw S/PDIF PCM */
1554 ipcm->substream = 0;
1555 ipcm->channels = 2;
1556 ipcm->tram_start = 0;
1557 ipcm->buffer_size = (64 * 1024) / 2;
1558 ipcm->gpr_size = gpr++;
1559 ipcm->gpr_ptr = gpr++;
1560 ipcm->gpr_count = gpr++;
1561 ipcm->gpr_tmpcount = gpr++;
1562 ipcm->gpr_trigger = gpr++;
1563 ipcm->gpr_running = gpr++;
1564 ipcm->etram[0] = 0;
1565 ipcm->etram[1] = 1;
1566
1567 gpr_map[gpr + 0] = 0xfffff000;
1568 gpr_map[gpr + 1] = 0xffff0000;
1569 gpr_map[gpr + 2] = 0x70000000;
1570 gpr_map[gpr + 3] = 0x00000007;
1571 gpr_map[gpr + 4] = 0x001f << 11;
1572 gpr_map[gpr + 5] = 0x001c << 11;
1573 gpr_map[gpr + 6] = (0x22 - 0x01) - 1; /* skip at 01 to 22 */
1574 gpr_map[gpr + 7] = (0x22 - 0x06) - 1; /* skip at 06 to 22 */
1575 gpr_map[gpr + 8] = 0x2000000 + (2<<11);
1576 gpr_map[gpr + 9] = 0x4000000 + (2<<11);
1577 gpr_map[gpr + 10] = 1<<11;
1578 gpr_map[gpr + 11] = (0x24 - 0x0a) - 1; /* skip at 0a to 24 */
1579 gpr_map[gpr + 12] = 0;
1580
1581 /* if the trigger flag is not set, skip */
1582 /* 00: */ OP(icode, &ptr, iMAC0, C_00000000, GPR(ipcm->gpr_trigger), C_00000000, C_00000000);
1583 /* 01: */ OP(icode, &ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_ZERO, GPR(gpr + 6));
1584 /* if the running flag is set, we're running */
1585 /* 02: */ OP(icode, &ptr, iMAC0, C_00000000, GPR(ipcm->gpr_running), C_00000000, C_00000000);
1586 /* 03: */ OP(icode, &ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, C_00000004);
1587 /* wait until ((GPR_DBAC>>11) & 0x1f) == 0x1c) */
1588 /* 04: */ OP(icode, &ptr, iANDXOR, GPR(tmp + 0), GPR_DBAC, GPR(gpr + 4), C_00000000);
1589 /* 05: */ OP(icode, &ptr, iMACINT0, C_00000000, GPR(tmp + 0), C_ffffffff, GPR(gpr + 5));
1590 /* 06: */ OP(icode, &ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, GPR(gpr + 7));
1591 /* 07: */ OP(icode, &ptr, iACC3, GPR(gpr + 12), C_00000010, C_00000001, C_00000000);
1592
1593 /* 08: */ OP(icode, &ptr, iANDXOR, GPR(ipcm->gpr_running), GPR(ipcm->gpr_running), C_00000000, C_00000001);
1594 /* 09: */ OP(icode, &ptr, iACC3, GPR(gpr + 12), GPR(gpr + 12), C_ffffffff, C_00000000);
1595 /* 0a: */ OP(icode, &ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, GPR(gpr + 11));
1596 /* 0b: */ OP(icode, &ptr, iACC3, GPR(gpr + 12), C_00000001, C_00000000, C_00000000);
1597
1598 /* 0c: */ OP(icode, &ptr, iANDXOR, GPR(tmp + 0), ETRAM_DATA(ipcm->etram[0]), GPR(gpr + 0), C_00000000);
1599 /* 0d: */ OP(icode, &ptr, iLOG, GPR(tmp + 0), GPR(tmp + 0), GPR(gpr + 3), C_00000000);
1600 /* 0e: */ OP(icode, &ptr, iANDXOR, GPR(8), GPR(tmp + 0), GPR(gpr + 1), GPR(gpr + 2));
1601 /* 0f: */ OP(icode, &ptr, iSKIP, C_00000000, GPR_COND, CC_REG_MINUS, C_00000001);
1602 /* 10: */ OP(icode, &ptr, iANDXOR, GPR(8), GPR(8), GPR(gpr + 1), GPR(gpr + 2));
1603
1604 /* 11: */ OP(icode, &ptr, iANDXOR, GPR(tmp + 0), ETRAM_DATA(ipcm->etram[1]), GPR(gpr + 0), C_00000000);
1605 /* 12: */ OP(icode, &ptr, iLOG, GPR(tmp + 0), GPR(tmp + 0), GPR(gpr + 3), C_00000000);
1606 /* 13: */ OP(icode, &ptr, iANDXOR, GPR(9), GPR(tmp + 0), GPR(gpr + 1), GPR(gpr + 2));
1607 /* 14: */ OP(icode, &ptr, iSKIP, C_00000000, GPR_COND, CC_REG_MINUS, C_00000001);
1608 /* 15: */ OP(icode, &ptr, iANDXOR, GPR(9), GPR(9), GPR(gpr + 1), GPR(gpr + 2));
1609
1610 /* 16: */ OP(icode, &ptr, iACC3, GPR(tmp + 0), GPR(ipcm->gpr_ptr), C_00000001, C_00000000);
1611 /* 17: */ OP(icode, &ptr, iMACINT0, C_00000000, GPR(tmp + 0), C_ffffffff, GPR(ipcm->gpr_size));
1612 /* 18: */ OP(icode, &ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_MINUS, C_00000001);
1613 /* 19: */ OP(icode, &ptr, iACC3, GPR(tmp + 0), C_00000000, C_00000000, C_00000000);
1614 /* 1a: */ OP(icode, &ptr, iACC3, GPR(ipcm->gpr_ptr), GPR(tmp + 0), C_00000000, C_00000000);
1615
1616 /* 1b: */ OP(icode, &ptr, iACC3, GPR(ipcm->gpr_tmpcount), GPR(ipcm->gpr_tmpcount), C_ffffffff, C_00000000);
1617 /* 1c: */ OP(icode, &ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, C_00000002);
1618 /* 1d: */ OP(icode, &ptr, iACC3, GPR(ipcm->gpr_tmpcount), GPR(ipcm->gpr_count), C_00000000, C_00000000);
1619 /* 1e: */ OP(icode, &ptr, iACC3, GPR_IRQ, C_80000000, C_00000000, C_00000000);
1620 /* 1f: */ OP(icode, &ptr, iANDXOR, GPR(ipcm->gpr_running), GPR(ipcm->gpr_running), C_00000001, C_00010000);
1621
1622 /* 20: */ OP(icode, &ptr, iANDXOR, GPR(ipcm->gpr_running), GPR(ipcm->gpr_running), C_00010000, C_00000001);
1623 /* 21: */ OP(icode, &ptr, iSKIP, C_00000000, C_7fffffff, C_7fffffff, C_00000002);
1624
1625 /* 22: */ OP(icode, &ptr, iMACINT1, ETRAM_ADDR(ipcm->etram[0]), GPR(gpr + 8), GPR_DBAC, C_ffffffff);
1626 /* 23: */ OP(icode, &ptr, iMACINT1, ETRAM_ADDR(ipcm->etram[1]), GPR(gpr + 9), GPR_DBAC, C_ffffffff);
1627
1628 /* 24: */
1629 gpr += 13;
1630
1631 /* Wave Playback Volume */
1632 for (z = 0; z < 2; z++)
1633 VOLUME(icode, &ptr, playback + z, z, gpr + z);
1634 snd_emu10k1_init_stereo_control(controls + i++, "Wave Playback Volume", gpr, 100);
1635 gpr += 2;
1636
1637 /* Wave Surround Playback Volume */
1638 for (z = 0; z < 2; z++)
1639 VOLUME(icode, &ptr, playback + 2 + z, z, gpr + z);
1640 snd_emu10k1_init_stereo_control(controls + i++, "Wave Surround Playback Volume", gpr, 0);
1641 gpr += 2;
1642
1643 /* Wave Center/LFE Playback Volume */
1644 OP(icode, &ptr, iACC3, GPR(tmp + 0), FXBUS(FXBUS_PCM_LEFT), FXBUS(FXBUS_PCM_RIGHT), C_00000000);
1645 OP(icode, &ptr, iMACINT0, GPR(tmp + 0), C_00000000, GPR(tmp + 0), C_00000002);
1646 VOLUME(icode, &ptr, playback + 4, tmp + 0, gpr);
1647 snd_emu10k1_init_mono_control(controls + i++, "Wave Center Playback Volume", gpr++, 0);
1648 VOLUME(icode, &ptr, playback + 5, tmp + 0, gpr);
1649 snd_emu10k1_init_mono_control(controls + i++, "Wave LFE Playback Volume", gpr++, 0);
1650
1651 /* Wave Capture Volume + Switch */
1652 for (z = 0; z < 2; z++) {
1653 SWITCH(icode, &ptr, tmp + 0, z, gpr + 2 + z);
1654 VOLUME(icode, &ptr, capture + z, tmp + 0, gpr + z);
1655 }
1656 snd_emu10k1_init_stereo_control(controls + i++, "Wave Capture Volume", gpr, 0);
1657 snd_emu10k1_init_stereo_onoff_control(controls + i++, "Wave Capture Switch", gpr + 2, 0);
1658 gpr += 4;
1659
1660 /* Music Playback Volume */
1661 for (z = 0; z < 2; z++)
1662 VOLUME_ADD(icode, &ptr, playback + z, 2 + z, gpr + z);
1663 snd_emu10k1_init_stereo_control(controls + i++, "Music Playback Volume", gpr, 100);
1664 gpr += 2;
1665
1666 /* Music Capture Volume + Switch */
1667 for (z = 0; z < 2; z++) {
1668 SWITCH(icode, &ptr, tmp + 0, 2 + z, gpr + 2 + z);
1669 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
1670 }
1671 snd_emu10k1_init_stereo_control(controls + i++, "Music Capture Volume", gpr, 0);
1672 snd_emu10k1_init_stereo_onoff_control(controls + i++, "Music Capture Switch", gpr + 2, 0);
1673 gpr += 4;
1674
1675 /* Surround Digital Playback Volume (renamed later without Digital) */
1676 for (z = 0; z < 2; z++)
1677 VOLUME_ADD(icode, &ptr, playback + 2 + z, 4 + z, gpr + z);
1678 snd_emu10k1_init_stereo_control(controls + i++, "Surround Digital Playback Volume", gpr, 100);
1679 gpr += 2;
1680
1681 /* Surround Capture Volume + Switch */
1682 for (z = 0; z < 2; z++) {
1683 SWITCH(icode, &ptr, tmp + 0, 4 + z, gpr + 2 + z);
1684 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
1685 }
1686 snd_emu10k1_init_stereo_control(controls + i++, "Surround Capture Volume", gpr, 0);
1687 snd_emu10k1_init_stereo_onoff_control(controls + i++, "Surround Capture Switch", gpr + 2, 0);
1688 gpr += 4;
1689
1690 /* Center Playback Volume (renamed later without Digital) */
1691 VOLUME_ADD(icode, &ptr, playback + 4, 6, gpr);
1692 snd_emu10k1_init_mono_control(controls + i++, "Center Digital Playback Volume", gpr++, 100);
1693
1694 /* LFE Playback Volume + Switch (renamed later without Digital) */
1695 VOLUME_ADD(icode, &ptr, playback + 5, 7, gpr);
1696 snd_emu10k1_init_mono_control(controls + i++, "LFE Digital Playback Volume", gpr++, 100);
1697
1698 /* Front Playback Volume */
1699 for (z = 0; z < 2; z++)
1700 VOLUME_ADD(icode, &ptr, playback + z, 10 + z, gpr + z);
1701 snd_emu10k1_init_stereo_control(controls + i++, "Front Playback Volume", gpr, 100);
1702 gpr += 2;
1703
1704 /* Front Capture Volume + Switch */
1705 for (z = 0; z < 2; z++) {
1706 SWITCH(icode, &ptr, tmp + 0, 10 + z, gpr + 2);
1707 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
1708 }
1709 snd_emu10k1_init_stereo_control(controls + i++, "Front Capture Volume", gpr, 0);
1710 snd_emu10k1_init_mono_onoff_control(controls + i++, "Front Capture Switch", gpr + 2, 0);
1711 gpr += 3;
1712
1713 /*
1714 * Process inputs
1715 */
1716
1717 if (emu->fx8010.extin_mask & ((1<<EXTIN_AC97_L)|(1<<EXTIN_AC97_R))) {
1718 /* AC'97 Playback Volume */
1719 VOLUME_ADDIN(icode, &ptr, playback + 0, EXTIN_AC97_L, gpr); gpr++;
1720 VOLUME_ADDIN(icode, &ptr, playback + 1, EXTIN_AC97_R, gpr); gpr++;
1721 snd_emu10k1_init_stereo_control(controls + i++, "AC97 Playback Volume", gpr-2, 0);
1722 /* AC'97 Capture Volume */
1723 VOLUME_ADDIN(icode, &ptr, capture + 0, EXTIN_AC97_L, gpr); gpr++;
1724 VOLUME_ADDIN(icode, &ptr, capture + 1, EXTIN_AC97_R, gpr); gpr++;
1725 snd_emu10k1_init_stereo_control(controls + i++, "AC97 Capture Volume", gpr-2, 100);
1726 }
1727
1728 if (emu->fx8010.extin_mask & ((1<<EXTIN_SPDIF_CD_L)|(1<<EXTIN_SPDIF_CD_R))) {
1729 /* IEC958 TTL Playback Volume */
1730 for (z = 0; z < 2; z++)
1731 VOLUME_ADDIN(icode, &ptr, playback + z, EXTIN_SPDIF_CD_L + z, gpr + z);
1732 snd_emu10k1_init_stereo_control(controls + i++, "IEC958 TTL Playback Volume", gpr, 0);
1733 gpr += 2;
1734
1735 /* IEC958 TTL Capture Volume + Switch */
1736 for (z = 0; z < 2; z++) {
1737 SWITCH_IN(icode, &ptr, tmp + 0, EXTIN_SPDIF_CD_L + z, gpr + 2 + z);
1738 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
1739 }
1740 snd_emu10k1_init_stereo_control(controls + i++, "IEC958 TTL Capture Volume", gpr, 0);
1741 snd_emu10k1_init_stereo_onoff_control(controls + i++, "IEC958 TTL Capture Switch", gpr + 2, 0);
1742 gpr += 4;
1743 }
1744
1745 if (emu->fx8010.extin_mask & ((1<<EXTIN_ZOOM_L)|(1<<EXTIN_ZOOM_R))) {
1746 /* Zoom Video Playback Volume */
1747 for (z = 0; z < 2; z++)
1748 VOLUME_ADDIN(icode, &ptr, playback + z, EXTIN_ZOOM_L + z, gpr + z);
1749 snd_emu10k1_init_stereo_control(controls + i++, "Zoom Video Playback Volume", gpr, 0);
1750 gpr += 2;
1751
1752 /* Zoom Video Capture Volume + Switch */
1753 for (z = 0; z < 2; z++) {
1754 SWITCH_IN(icode, &ptr, tmp + 0, EXTIN_ZOOM_L + z, gpr + 2 + z);
1755 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
1756 }
1757 snd_emu10k1_init_stereo_control(controls + i++, "Zoom Video Capture Volume", gpr, 0);
1758 snd_emu10k1_init_stereo_onoff_control(controls + i++, "Zoom Video Capture Switch", gpr + 2, 0);
1759 gpr += 4;
1760 }
1761
1762 if (emu->fx8010.extin_mask & ((1<<EXTIN_TOSLINK_L)|(1<<EXTIN_TOSLINK_R))) {
1763 /* IEC958 Optical Playback Volume */
1764 for (z = 0; z < 2; z++)
1765 VOLUME_ADDIN(icode, &ptr, playback + z, EXTIN_TOSLINK_L + z, gpr + z);
1766 snd_emu10k1_init_stereo_control(controls + i++, "IEC958 LiveDrive Playback Volume", gpr, 0);
1767 gpr += 2;
1768
1769 /* IEC958 Optical Capture Volume */
1770 for (z = 0; z < 2; z++) {
1771 SWITCH_IN(icode, &ptr, tmp + 0, EXTIN_TOSLINK_L + z, gpr + 2 + z);
1772 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
1773 }
1774 snd_emu10k1_init_stereo_control(controls + i++, "IEC958 LiveDrive Capture Volume", gpr, 0);
1775 snd_emu10k1_init_stereo_onoff_control(controls + i++, "IEC958 LiveDrive Capture Switch", gpr + 2, 0);
1776 gpr += 4;
1777 }
1778
1779 if (emu->fx8010.extin_mask & ((1<<EXTIN_LINE1_L)|(1<<EXTIN_LINE1_R))) {
1780 /* Line LiveDrive Playback Volume */
1781 for (z = 0; z < 2; z++)
1782 VOLUME_ADDIN(icode, &ptr, playback + z, EXTIN_LINE1_L + z, gpr + z);
1783 snd_emu10k1_init_stereo_control(controls + i++, "Line LiveDrive Playback Volume", gpr, 0);
1784 gpr += 2;
1785
1786 /* Line LiveDrive Capture Volume + Switch */
1787 for (z = 0; z < 2; z++) {
1788 SWITCH_IN(icode, &ptr, tmp + 0, EXTIN_LINE1_L + z, gpr + 2 + z);
1789 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
1790 }
1791 snd_emu10k1_init_stereo_control(controls + i++, "Line LiveDrive Capture Volume", gpr, 0);
1792 snd_emu10k1_init_stereo_onoff_control(controls + i++, "Line LiveDrive Capture Switch", gpr + 2, 0);
1793 gpr += 4;
1794 }
1795
1796 if (emu->fx8010.extin_mask & ((1<<EXTIN_COAX_SPDIF_L)|(1<<EXTIN_COAX_SPDIF_R))) {
1797 /* IEC958 Coax Playback Volume */
1798 for (z = 0; z < 2; z++)
1799 VOLUME_ADDIN(icode, &ptr, playback + z, EXTIN_COAX_SPDIF_L + z, gpr + z);
1800 snd_emu10k1_init_stereo_control(controls + i++, "IEC958 Coaxial Playback Volume", gpr, 0);
1801 gpr += 2;
1802
1803 /* IEC958 Coax Capture Volume + Switch */
1804 for (z = 0; z < 2; z++) {
1805 SWITCH_IN(icode, &ptr, tmp + 0, EXTIN_COAX_SPDIF_L + z, gpr + 2 + z);
1806 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
1807 }
1808 snd_emu10k1_init_stereo_control(controls + i++, "IEC958 Coaxial Capture Volume", gpr, 0);
1809 snd_emu10k1_init_stereo_onoff_control(controls + i++, "IEC958 Coaxial Capture Switch", gpr + 2, 0);
1810 gpr += 4;
1811 }
1812
1813 if (emu->fx8010.extin_mask & ((1<<EXTIN_LINE2_L)|(1<<EXTIN_LINE2_R))) {
1814 /* Line LiveDrive Playback Volume */
1815 for (z = 0; z < 2; z++)
1816 VOLUME_ADDIN(icode, &ptr, playback + z, EXTIN_LINE2_L + z, gpr + z);
1817 snd_emu10k1_init_stereo_control(controls + i++, "Line2 LiveDrive Playback Volume", gpr, 0);
1818 controls[i-1].id.index = 1;
1819 gpr += 2;
1820
1821 /* Line LiveDrive Capture Volume */
1822 for (z = 0; z < 2; z++) {
1823 SWITCH_IN(icode, &ptr, tmp + 0, EXTIN_LINE2_L + z, gpr + 2 + z);
1824 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
1825 }
1826 snd_emu10k1_init_stereo_control(controls + i++, "Line2 LiveDrive Capture Volume", gpr, 0);
1827 controls[i-1].id.index = 1;
1828 snd_emu10k1_init_stereo_onoff_control(controls + i++, "Line2 LiveDrive Capture Switch", gpr + 2, 0);
1829 controls[i-1].id.index = 1;
1830 gpr += 4;
1831 }
1832
1833 /*
1834 * Process tone control
1835 */
1836 OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 0), GPR(playback + 0), C_00000000, C_00000000); /* left */
1837 OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 1), GPR(playback + 1), C_00000000, C_00000000); /* right */
1838 OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 2), GPR(playback + 2), C_00000000, C_00000000); /* rear left */
1839 OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 3), GPR(playback + 3), C_00000000, C_00000000); /* rear right */
1840 OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 4), GPR(playback + 4), C_00000000, C_00000000); /* center */
1841 OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 5), GPR(playback + 5), C_00000000, C_00000000); /* LFE */
1842
1843 ctl = &controls[i + 0];
1844 ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1845 strcpy(ctl->id.name, "Tone Control - Bass");
1846 ctl->vcount = 2;
1847 ctl->count = 10;
1848 ctl->min = 0;
1849 ctl->max = 40;
1850 ctl->value[0] = ctl->value[1] = 20;
1851 ctl->translation = EMU10K1_GPR_TRANSLATION_BASS;
1852 ctl = &controls[i + 1];
1853 ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1854 strcpy(ctl->id.name, "Tone Control - Treble");
1855 ctl->vcount = 2;
1856 ctl->count = 10;
1857 ctl->min = 0;
1858 ctl->max = 40;
1859 ctl->value[0] = ctl->value[1] = 20;
1860 ctl->translation = EMU10K1_GPR_TRANSLATION_TREBLE;
1861
1862#define BASS_GPR 0x8c
1863#define TREBLE_GPR 0x96
1864
1865 for (z = 0; z < 5; z++) {
1866 int j;
1867 for (j = 0; j < 2; j++) {
1868 controls[i + 0].gpr[z * 2 + j] = BASS_GPR + z * 2 + j;
1869 controls[i + 1].gpr[z * 2 + j] = TREBLE_GPR + z * 2 + j;
1870 }
1871 }
1872 for (z = 0; z < 3; z++) { /* front/rear/center-lfe */
1873 int j, k, l, d;
1874 for (j = 0; j < 2; j++) { /* left/right */
1875 k = 0xa0 + (z * 8) + (j * 4);
1876 l = 0xd0 + (z * 8) + (j * 4);
1877 d = playback + SND_EMU10K1_PLAYBACK_CHANNELS + z * 2 + j;
1878
1879 OP(icode, &ptr, iMAC0, C_00000000, C_00000000, GPR(d), GPR(BASS_GPR + 0 + j));
1880 OP(icode, &ptr, iMACMV, GPR(k+1), GPR(k), GPR(k+1), GPR(BASS_GPR + 4 + j));
1881 OP(icode, &ptr, iMACMV, GPR(k), GPR(d), GPR(k), GPR(BASS_GPR + 2 + j));
1882 OP(icode, &ptr, iMACMV, GPR(k+3), GPR(k+2), GPR(k+3), GPR(BASS_GPR + 8 + j));
1883 OP(icode, &ptr, iMAC0, GPR(k+2), GPR_ACCU, GPR(k+2), GPR(BASS_GPR + 6 + j));
1884 OP(icode, &ptr, iACC3, GPR(k+2), GPR(k+2), GPR(k+2), C_00000000);
1885
1886 OP(icode, &ptr, iMAC0, C_00000000, C_00000000, GPR(k+2), GPR(TREBLE_GPR + 0 + j));
1887 OP(icode, &ptr, iMACMV, GPR(l+1), GPR(l), GPR(l+1), GPR(TREBLE_GPR + 4 + j));
1888 OP(icode, &ptr, iMACMV, GPR(l), GPR(k+2), GPR(l), GPR(TREBLE_GPR + 2 + j));
1889 OP(icode, &ptr, iMACMV, GPR(l+3), GPR(l+2), GPR(l+3), GPR(TREBLE_GPR + 8 + j));
1890 OP(icode, &ptr, iMAC0, GPR(l+2), GPR_ACCU, GPR(l+2), GPR(TREBLE_GPR + 6 + j));
1891 OP(icode, &ptr, iMACINT0, GPR(l+2), C_00000000, GPR(l+2), C_00000010);
1892
1893 OP(icode, &ptr, iACC3, GPR(d), GPR(l+2), C_00000000, C_00000000);
1894
1895 if (z == 2) /* center */
1896 break;
1897 }
1898 }
1899 i += 2;
1900
1901#undef BASS_GPR
1902#undef TREBLE_GPR
1903
1904 for (z = 0; z < 6; z++) {
1905 SWITCH(icode, &ptr, tmp + 0, playback + SND_EMU10K1_PLAYBACK_CHANNELS + z, gpr + 0);
1906 SWITCH_NEG(icode, &ptr, tmp + 1, gpr + 0);
1907 SWITCH(icode, &ptr, tmp + 1, playback + z, tmp + 1);
1908 OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + z), GPR(tmp + 0), GPR(tmp + 1), C_00000000);
1909 }
1910 snd_emu10k1_init_stereo_onoff_control(controls + i++, "Tone Control - Switch", gpr, 0);
1911 gpr += 2;
1912
1913 /*
1914 * Process outputs
1915 */
1916 if (emu->fx8010.extout_mask & ((1<<EXTOUT_AC97_L)|(1<<EXTOUT_AC97_R))) {
1917 /* AC'97 Playback Volume */
1918
1919 for (z = 0; z < 2; z++)
1920 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_AC97_L + z), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + z), C_00000000, C_00000000);
1921 }
1922
1923 if (emu->fx8010.extout_mask & ((1<<EXTOUT_TOSLINK_L)|(1<<EXTOUT_TOSLINK_R))) {
1924 /* IEC958 Optical Raw Playback Switch */
1925
1926 for (z = 0; z < 2; z++) {
1927 SWITCH(icode, &ptr, tmp + 0, 8 + z, gpr + z);
1928 SWITCH_NEG(icode, &ptr, tmp + 1, gpr + z);
1929 SWITCH(icode, &ptr, tmp + 1, playback + SND_EMU10K1_PLAYBACK_CHANNELS + z, tmp + 1);
1930 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_TOSLINK_L + z), GPR(tmp + 0), GPR(tmp + 1), C_00000000);
1931#ifdef EMU10K1_CAPTURE_DIGITAL_OUT
1932 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_ADC_CAP_L + z), GPR(tmp + 0), GPR(tmp + 1), C_00000000);
1933#endif
1934 }
1935
1936 snd_emu10k1_init_stereo_onoff_control(controls + i++, "IEC958 Optical Raw Playback Switch", gpr, 0);
1937 gpr += 2;
1938 }
1939
1940 if (emu->fx8010.extout_mask & ((1<<EXTOUT_HEADPHONE_L)|(1<<EXTOUT_HEADPHONE_R))) {
1941 /* Headphone Playback Volume */
1942
1943 for (z = 0; z < 2; z++) {
1944 SWITCH(icode, &ptr, tmp + 0, playback + SND_EMU10K1_PLAYBACK_CHANNELS + 4 + z, gpr + 2 + z);
1945 SWITCH_NEG(icode, &ptr, tmp + 1, gpr + 2 + z);
1946 SWITCH(icode, &ptr, tmp + 1, playback + SND_EMU10K1_PLAYBACK_CHANNELS + z, tmp + 1);
1947 OP(icode, &ptr, iACC3, GPR(tmp + 0), GPR(tmp + 0), GPR(tmp + 1), C_00000000);
1948 VOLUME_OUT(icode, &ptr, EXTOUT_HEADPHONE_L + z, tmp + 0, gpr + z);
1949 }
1950
1951 snd_emu10k1_init_stereo_control(controls + i++, "Headphone Playback Volume", gpr + 0, 0);
1952 controls[i-1].id.index = 1; /* AC'97 can have also Headphone control */
1953 snd_emu10k1_init_mono_onoff_control(controls + i++, "Headphone Center Playback Switch", gpr + 2, 0);
1954 controls[i-1].id.index = 1;
1955 snd_emu10k1_init_mono_onoff_control(controls + i++, "Headphone LFE Playback Switch", gpr + 3, 0);
1956 controls[i-1].id.index = 1;
1957
1958 gpr += 4;
1959 }
1960
1961 if (emu->fx8010.extout_mask & ((1<<EXTOUT_REAR_L)|(1<<EXTOUT_REAR_R)))
1962 for (z = 0; z < 2; z++)
1963 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_REAR_L + z), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 2 + z), C_00000000, C_00000000);
1964
1965 if (emu->fx8010.extout_mask & ((1<<EXTOUT_AC97_REAR_L)|(1<<EXTOUT_AC97_REAR_R)))
1966 for (z = 0; z < 2; z++)
1967 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_AC97_REAR_L + z), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 2 + z), C_00000000, C_00000000);
1968 if (emu->fx8010.extout_mask & (1<<EXTOUT_AC97_CENTER)) {
1969#ifndef EMU10K1_CENTER_LFE_FROM_FRONT
1970 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_AC97_CENTER), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 4), C_00000000, C_00000000);
1971 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_ACENTER), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 4), C_00000000, C_00000000);
1972#else
1973 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_AC97_CENTER), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 0), C_00000000, C_00000000);
1974 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_ACENTER), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 0), C_00000000, C_00000000);
1975#endif
1976 }
1977
1978 if (emu->fx8010.extout_mask & (1<<EXTOUT_AC97_LFE)) {
1979#ifndef EMU10K1_CENTER_LFE_FROM_FRONT
1980 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_AC97_LFE), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 5), C_00000000, C_00000000);
1981 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_ALFE), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 5), C_00000000, C_00000000);
1982#else
1983 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_AC97_LFE), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 1), C_00000000, C_00000000);
1984 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_ALFE), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 1), C_00000000, C_00000000);
1985#endif
1986 }
1987
1988#ifndef EMU10K1_CAPTURE_DIGITAL_OUT
1989 for (z = 0; z < 2; z++)
1990 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_ADC_CAP_L + z), GPR(capture + z), C_00000000, C_00000000);
1991#endif
1992
1993 if (emu->fx8010.extout_mask & (1<<EXTOUT_MIC_CAP))
1994 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_MIC_CAP), GPR(capture + 2), C_00000000, C_00000000);
1995
1996 /* EFX capture - capture the 16 EXTINS */
1997 if (emu->card_capabilities->sblive51) {
1998 /* On the Live! 5.1, FXBUS2(1) and FXBUS(2) are shared with EXTOUT_ACENTER
1999 * and EXTOUT_ALFE, so we can't connect inputs to them for multitrack recording.
2000 *
2001 * Since only 14 of the 16 EXTINs are used, this is not a big problem.
2002 * We route AC97L and R to FX capture 14 and 15, SPDIF CD in to FX capture
2003 * 0 and 3, then the rest of the EXTINs to the corresponding FX capture
2004 * channel. Multitrack recorders will still see the center/lfe output signal
2005 * on the second and third channels.
2006 */
2007 OP(icode, &ptr, iACC3, FXBUS2(14), C_00000000, C_00000000, EXTIN(0));
2008 OP(icode, &ptr, iACC3, FXBUS2(15), C_00000000, C_00000000, EXTIN(1));
2009 OP(icode, &ptr, iACC3, FXBUS2(0), C_00000000, C_00000000, EXTIN(2));
2010 OP(icode, &ptr, iACC3, FXBUS2(3), C_00000000, C_00000000, EXTIN(3));
2011 for (z = 4; z < 14; z++)
2012 OP(icode, &ptr, iACC3, FXBUS2(z), C_00000000, C_00000000, EXTIN(z));
2013 } else {
2014 for (z = 0; z < 16; z++)
2015 OP(icode, &ptr, iACC3, FXBUS2(z), C_00000000, C_00000000, EXTIN(z));
2016 }
2017
2018 if (gpr > tmp) {
2019 snd_BUG();
2020 err = -EIO;
2021 goto __err;
2022 }
2023 if (i > SND_EMU10K1_GPR_CONTROLS) {
2024 snd_BUG();
2025 err = -EIO;
2026 goto __err;
2027 }
2028
2029 /* clear remaining instruction memory */
2030 while (ptr < 0x200)
2031 OP(icode, &ptr, iACC3, C_00000000, C_00000000, C_00000000, C_00000000);
2032
2033 if ((err = snd_emu10k1_fx8010_tram_setup(emu, ipcm->buffer_size)) < 0)
2034 goto __err;
2035 seg = snd_enter_user();
2036 icode->gpr_add_control_count = i;
2037 icode->gpr_add_controls = (emu10k1_fx8010_control_gpr_t __user *)controls;
2038 err = snd_emu10k1_icode_poke(emu, icode);
2039 snd_leave_user(seg);
2040 if (err >= 0)
2041 err = snd_emu10k1_ipcm_poke(emu, ipcm);
2042__err:
2043 kfree(ipcm);
2044 kfree(controls);
2045 if (icode != NULL) {
2046 kfree((void *)icode->gpr_map);
2047 kfree(icode);
2048 }
2049 return err;
2050}
2051
2052int __devinit snd_emu10k1_init_efx(emu10k1_t *emu)
2053{
2054 if (emu->audigy)
2055 return _snd_emu10k1_audigy_init_efx(emu);
2056 else
2057 return _snd_emu10k1_init_efx(emu);
2058}
2059
2060void snd_emu10k1_free_efx(emu10k1_t *emu)
2061{
2062 /* stop processor */
2063 if (emu->audigy)
2064 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg = A_DBG_SINGLE_STEP);
2065 else
2066 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg = EMU10K1_DBG_SINGLE_STEP);
2067}
2068
2069#if 0 // FIXME: who use them?
2070int snd_emu10k1_fx8010_tone_control_activate(emu10k1_t *emu, int output)
2071{
2072 snd_runtime_check(output >= 0 && output < 6, return -EINVAL);
2073 snd_emu10k1_ptr_write(emu, emu->gpr_base + 0x94 + output, 0, 1);
2074 return 0;
2075}
2076
2077int snd_emu10k1_fx8010_tone_control_deactivate(emu10k1_t *emu, int output)
2078{
2079 snd_runtime_check(output >= 0 && output < 6, return -EINVAL);
2080 snd_emu10k1_ptr_write(emu, emu->gpr_base + 0x94 + output, 0, 0);
2081 return 0;
2082}
2083#endif
2084
2085int snd_emu10k1_fx8010_tram_setup(emu10k1_t *emu, u32 size)
2086{
2087 u8 size_reg = 0;
2088
2089 /* size is in samples */
2090 if (size != 0) {
2091 size = (size - 1) >> 13;
2092
2093 while (size) {
2094 size >>= 1;
2095 size_reg++;
2096 }
2097 size = 0x2000 << size_reg;
2098 }
2099 if (emu->fx8010.etram_pages.bytes == size)
2100 return 0;
2101 spin_lock_irq(&emu->emu_lock);
2102 outl(HCFG_LOCKTANKCACHE_MASK | inl(emu->port + HCFG), emu->port + HCFG);
2103 spin_unlock_irq(&emu->emu_lock);
2104 snd_emu10k1_ptr_write(emu, TCB, 0, 0);
2105 snd_emu10k1_ptr_write(emu, TCBS, 0, 0);
2106 if (emu->fx8010.etram_pages.area != NULL) {
2107 snd_dma_free_pages(&emu->fx8010.etram_pages);
2108 emu->fx8010.etram_pages.area = NULL;
2109 emu->fx8010.etram_pages.bytes = 0;
2110 }
2111
2112 if (size > 0) {
2113 if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(emu->pci),
2114 size * 2, &emu->fx8010.etram_pages) < 0)
2115 return -ENOMEM;
2116 memset(emu->fx8010.etram_pages.area, 0, size * 2);
2117 snd_emu10k1_ptr_write(emu, TCB, 0, emu->fx8010.etram_pages.addr);
2118 snd_emu10k1_ptr_write(emu, TCBS, 0, size_reg);
2119 spin_lock_irq(&emu->emu_lock);
2120 outl(inl(emu->port + HCFG) & ~HCFG_LOCKTANKCACHE_MASK, emu->port + HCFG);
2121 spin_unlock_irq(&emu->emu_lock);
2122 }
2123
2124 return 0;
2125}
2126
2127static int snd_emu10k1_fx8010_open(snd_hwdep_t * hw, struct file *file)
2128{
2129 return 0;
2130}
2131
2132static void copy_string(char *dst, char *src, char *null, int idx)
2133{
2134 if (src == NULL)
2135 sprintf(dst, "%s %02X", null, idx);
2136 else
2137 strcpy(dst, src);
2138}
2139
2140static int snd_emu10k1_fx8010_info(emu10k1_t *emu, emu10k1_fx8010_info_t *info)
2141{
2142 char **fxbus, **extin, **extout;
2143 unsigned short fxbus_mask, extin_mask, extout_mask;
2144 int res;
2145
2146 memset(info, 0, sizeof(info));
2147 info->internal_tram_size = emu->fx8010.itram_size;
2148 info->external_tram_size = emu->fx8010.etram_pages.bytes / 2;
2149 fxbus = fxbuses;
2150 extin = emu->audigy ? audigy_ins : creative_ins;
2151 extout = emu->audigy ? audigy_outs : creative_outs;
2152 fxbus_mask = emu->fx8010.fxbus_mask;
2153 extin_mask = emu->fx8010.extin_mask;
2154 extout_mask = emu->fx8010.extout_mask;
2155 for (res = 0; res < 16; res++, fxbus++, extin++, extout++) {
2156 copy_string(info->fxbus_names[res], fxbus_mask & (1 << res) ? *fxbus : NULL, "FXBUS", res);
2157 copy_string(info->extin_names[res], extin_mask & (1 << res) ? *extin : NULL, "Unused", res);
2158 copy_string(info->extout_names[res], extout_mask & (1 << res) ? *extout : NULL, "Unused", res);
2159 }
2160 for (res = 16; res < 32; res++, extout++)
2161 copy_string(info->extout_names[res], extout_mask & (1 << res) ? *extout : NULL, "Unused", res);
2162 info->gpr_controls = emu->fx8010.gpr_count;
2163 return 0;
2164}
2165
2166static int snd_emu10k1_fx8010_ioctl(snd_hwdep_t * hw, struct file *file, unsigned int cmd, unsigned long arg)
2167{
2168 emu10k1_t *emu = hw->private_data;
2169 emu10k1_fx8010_info_t *info;
2170 emu10k1_fx8010_code_t *icode;
2171 emu10k1_fx8010_pcm_t *ipcm;
2172 unsigned int addr;
2173 int res;
2174
2175 switch (cmd) {
2176 case SNDRV_EMU10K1_IOCTL_INFO:
2177 info = (emu10k1_fx8010_info_t *)kmalloc(sizeof(*info), GFP_KERNEL);
2178 if (!info)
2179 return -ENOMEM;
2180 if ((res = snd_emu10k1_fx8010_info(emu, info)) < 0) {
2181 kfree(info);
2182 return res;
2183 }
2184 if (copy_to_user((void *)arg, info, sizeof(*info))) {
2185 kfree(info);
2186 return -EFAULT;
2187 }
2188 kfree(info);
2189 return 0;
2190 case SNDRV_EMU10K1_IOCTL_CODE_POKE:
2191 if (!capable(CAP_SYS_ADMIN))
2192 return -EPERM;
2193 icode = (emu10k1_fx8010_code_t *)kmalloc(sizeof(*icode), GFP_KERNEL);
2194 if (icode == NULL)
2195 return -ENOMEM;
2196 if (copy_from_user(icode, (void *)arg, sizeof(*icode))) {
2197 kfree(icode);
2198 return -EFAULT;
2199 }
2200 res = snd_emu10k1_icode_poke(emu, icode);
2201 kfree(icode);
2202 return res;
2203 case SNDRV_EMU10K1_IOCTL_CODE_PEEK:
2204 icode = (emu10k1_fx8010_code_t *)kmalloc(sizeof(*icode), GFP_KERNEL);
2205 if (icode == NULL)
2206 return -ENOMEM;
2207 if (copy_from_user(icode, (void *)arg, sizeof(*icode))) {
2208 kfree(icode);
2209 return -EFAULT;
2210 }
2211 res = snd_emu10k1_icode_peek(emu, icode);
2212 if (res == 0 && copy_to_user((void *)arg, icode, sizeof(*icode))) {
2213 kfree(icode);
2214 return -EFAULT;
2215 }
2216 kfree(icode);
2217 return res;
2218 case SNDRV_EMU10K1_IOCTL_PCM_POKE:
2219 ipcm = (emu10k1_fx8010_pcm_t *)kmalloc(sizeof(*ipcm), GFP_KERNEL);
2220 if (ipcm == NULL)
2221 return -ENOMEM;
2222 if (copy_from_user(ipcm, (void *)arg, sizeof(*ipcm))) {
2223 kfree(ipcm);
2224 return -EFAULT;
2225 }
2226 res = snd_emu10k1_ipcm_poke(emu, ipcm);
2227 kfree(ipcm);
2228 return res;
2229 case SNDRV_EMU10K1_IOCTL_PCM_PEEK:
2230 ipcm = kzalloc(sizeof(*ipcm), GFP_KERNEL);
2231 if (ipcm == NULL)
2232 return -ENOMEM;
2233 if (copy_from_user(ipcm, (void *)arg, sizeof(*ipcm))) {
2234 kfree(ipcm);
2235 return -EFAULT;
2236 }
2237 res = snd_emu10k1_ipcm_peek(emu, ipcm);
2238 if (res == 0 && copy_to_user((void *)arg, ipcm, sizeof(*ipcm))) {
2239 kfree(ipcm);
2240 return -EFAULT;
2241 }
2242 kfree(ipcm);
2243 return res;
2244 case SNDRV_EMU10K1_IOCTL_TRAM_SETUP:
2245 if (!capable(CAP_SYS_ADMIN))
2246 return -EPERM;
2247 if (get_user(addr, (unsigned int *)arg))
2248 return -EFAULT;
2249 down(&emu->fx8010.lock);
2250 res = snd_emu10k1_fx8010_tram_setup(emu, addr);
2251 up(&emu->fx8010.lock);
2252 return res;
2253 case SNDRV_EMU10K1_IOCTL_STOP:
2254 if (!capable(CAP_SYS_ADMIN))
2255 return -EPERM;
2256 if (emu->audigy)
2257 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg |= A_DBG_SINGLE_STEP);
2258 else
2259 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg |= EMU10K1_DBG_SINGLE_STEP);
2260 return 0;
2261 case SNDRV_EMU10K1_IOCTL_CONTINUE:
2262 if (!capable(CAP_SYS_ADMIN))
2263 return -EPERM;
2264 if (emu->audigy)
2265 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg = 0);
2266 else
2267 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg = 0);
2268 return 0;
2269 case SNDRV_EMU10K1_IOCTL_ZERO_TRAM_COUNTER:
2270 if (!capable(CAP_SYS_ADMIN))
2271 return -EPERM;
2272 if (emu->audigy)
2273 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg | A_DBG_ZC);
2274 else
2275 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg | EMU10K1_DBG_ZC);
2276 udelay(10);
2277 if (emu->audigy)
2278 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg);
2279 else
2280 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg);
2281 return 0;
2282 case SNDRV_EMU10K1_IOCTL_SINGLE_STEP:
2283 if (!capable(CAP_SYS_ADMIN))
2284 return -EPERM;
2285 if (get_user(addr, (unsigned int *)arg))
2286 return -EFAULT;
2287 if (addr > 0x1ff)
2288 return -EINVAL;
2289 if (emu->audigy)
2290 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg |= A_DBG_SINGLE_STEP | addr);
2291 else
2292 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg |= EMU10K1_DBG_SINGLE_STEP | addr);
2293 udelay(10);
2294 if (emu->audigy)
2295 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg |= A_DBG_SINGLE_STEP | A_DBG_STEP_ADDR | addr);
2296 else
2297 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg |= EMU10K1_DBG_SINGLE_STEP | EMU10K1_DBG_STEP | addr);
2298 return 0;
2299 case SNDRV_EMU10K1_IOCTL_DBG_READ:
2300 if (emu->audigy)
2301 addr = snd_emu10k1_ptr_read(emu, A_DBG, 0);
2302 else
2303 addr = snd_emu10k1_ptr_read(emu, DBG, 0);
2304 if (put_user(addr, (unsigned int *)arg))
2305 return -EFAULT;
2306 return 0;
2307 }
2308 return -ENOTTY;
2309}
2310
2311static int snd_emu10k1_fx8010_release(snd_hwdep_t * hw, struct file *file)
2312{
2313 return 0;
2314}
2315
2316int __devinit snd_emu10k1_fx8010_new(emu10k1_t *emu, int device, snd_hwdep_t ** rhwdep)
2317{
2318 snd_hwdep_t *hw;
2319 int err;
2320
2321 if (rhwdep)
2322 *rhwdep = NULL;
2323 if ((err = snd_hwdep_new(emu->card, "FX8010", device, &hw)) < 0)
2324 return err;
2325 strcpy(hw->name, "EMU10K1 (FX8010)");
2326 hw->iface = SNDRV_HWDEP_IFACE_EMU10K1;
2327 hw->ops.open = snd_emu10k1_fx8010_open;
2328 hw->ops.ioctl = snd_emu10k1_fx8010_ioctl;
2329 hw->ops.release = snd_emu10k1_fx8010_release;
2330 hw->private_data = emu;
2331 if (rhwdep)
2332 *rhwdep = hw;
2333 return 0;
2334}
Note: See TracBrowser for help on using the repository browser.