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