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