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