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