ASoC: fsi: use dmaengine_prep_dma_cyclic() for DMA transfer
[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
e23e7a14 1076static void
eb4698f3
TI
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
e23e7a14 1097static void
eb4698f3
TI
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
e23e7a14 1119static void
eb4698f3
TI
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
e23e7a14 1132static void
eb4698f3
TI
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
e23e7a14 1171static int _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
f1b4863a
GB
1185 err = -ENOMEM;
1186 icode = kzalloc(sizeof(*icode), GFP_KERNEL);
1187 if (!icode)
1188 return err;
1189
1190 icode->gpr_map = (u_int32_t __user *) kcalloc(512 + 256 + 256 + 2 * 1024,
1191 sizeof(u_int32_t), GFP_KERNEL);
1192 if (!icode->gpr_map)
1193 goto __err_gpr;
1194 controls = kcalloc(SND_EMU10K1_GPR_CONTROLS,
1195 sizeof(*controls), GFP_KERNEL);
1196 if (!controls)
1197 goto __err_ctrls;
1198
4d23359b 1199 gpr_map = (u32 __force *)icode->gpr_map;
1da177e4
LT
1200
1201 icode->tram_data_map = icode->gpr_map + 512;
1202 icode->tram_addr_map = icode->tram_data_map + 256;
1203 icode->code = icode->tram_addr_map + 256;
1204
1205 /* clear free GPRs */
1206 for (i = 0; i < 512; i++)
1207 set_bit(i, icode->gpr_valid);
1208
1209 /* clear TRAM data & address lines */
1210 for (i = 0; i < 256; i++)
1211 set_bit(i, icode->tram_valid);
1212
1213 strcpy(icode->name, "Audigy DSP code for ALSA");
1214 ptr = 0;
1215 nctl = 0;
1216 gpr = stereo_mix + 10;
9f4bd5dd
JCD
1217 gpr_map[gpr++] = 0x00007fff;
1218 gpr_map[gpr++] = 0x00008000;
1219 gpr_map[gpr++] = 0x0000ffff;
1220 bit_shifter16 = gpr;
1da177e4
LT
1221
1222 /* stop FX processor */
1223 snd_emu10k1_ptr_write(emu, A_DBG, 0, (emu->fx8010.dbg = 0) | A_DBG_SINGLE_STEP);
1224
19b99fba 1225#if 1
13d45709
PH
1226 /* PCM front Playback Volume (independent from stereo mix)
1227 * playback = 0 + ( gpr * FXBUS_PCM_LEFT_FRONT >> 31)
1228 * where gpr contains attenuation from corresponding mixer control
1229 * (snd_emu10k1_init_stereo_control)
1230 */
1da177e4
LT
1231 A_OP(icode, &ptr, iMAC0, A_GPR(playback), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LEFT_FRONT));
1232 A_OP(icode, &ptr, iMAC0, A_GPR(playback+1), A_C_00000000, A_GPR(gpr+1), A_FXBUS(FXBUS_PCM_RIGHT_FRONT));
1233 snd_emu10k1_init_stereo_control(&controls[nctl++], "PCM Front Playback Volume", gpr, 100);
1234 gpr += 2;
90fd5ce5 1235
1da177e4
LT
1236 /* PCM Surround Playback (independent from stereo mix) */
1237 A_OP(icode, &ptr, iMAC0, A_GPR(playback+2), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LEFT_REAR));
1238 A_OP(icode, &ptr, iMAC0, A_GPR(playback+3), A_C_00000000, A_GPR(gpr+1), A_FXBUS(FXBUS_PCM_RIGHT_REAR));
1239 snd_emu10k1_init_stereo_control(&controls[nctl++], "PCM Surround Playback Volume", gpr, 100);
1240 gpr += 2;
1241
1242 /* PCM Side Playback (independent from stereo mix) */
2b637da5 1243 if (emu->card_capabilities->spk71) {
1da177e4
LT
1244 A_OP(icode, &ptr, iMAC0, A_GPR(playback+6), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LEFT_SIDE));
1245 A_OP(icode, &ptr, iMAC0, A_GPR(playback+7), A_C_00000000, A_GPR(gpr+1), A_FXBUS(FXBUS_PCM_RIGHT_SIDE));
1246 snd_emu10k1_init_stereo_control(&controls[nctl++], "PCM Side Playback Volume", gpr, 100);
1247 gpr += 2;
1248 }
1249
1250 /* PCM Center Playback (independent from stereo mix) */
1251 A_OP(icode, &ptr, iMAC0, A_GPR(playback+4), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_CENTER));
1252 snd_emu10k1_init_mono_control(&controls[nctl++], "PCM Center Playback Volume", gpr, 100);
1253 gpr++;
1254
1255 /* PCM LFE Playback (independent from stereo mix) */
1256 A_OP(icode, &ptr, iMAC0, A_GPR(playback+5), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LFE));
1257 snd_emu10k1_init_mono_control(&controls[nctl++], "PCM LFE Playback Volume", gpr, 100);
1258 gpr++;
1259
1260 /*
1261 * Stereo Mix
1262 */
1263 /* Wave (PCM) Playback Volume (will be renamed later) */
1264 A_OP(icode, &ptr, iMAC0, A_GPR(stereo_mix), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LEFT));
1265 A_OP(icode, &ptr, iMAC0, A_GPR(stereo_mix+1), A_C_00000000, A_GPR(gpr+1), A_FXBUS(FXBUS_PCM_RIGHT));
1266 snd_emu10k1_init_stereo_control(&controls[nctl++], "Wave Playback Volume", gpr, 100);
1267 gpr += 2;
1268
1269 /* Synth Playback */
1270 A_OP(icode, &ptr, iMAC0, A_GPR(stereo_mix+0), A_GPR(stereo_mix+0), A_GPR(gpr), A_FXBUS(FXBUS_MIDI_LEFT));
1271 A_OP(icode, &ptr, iMAC0, A_GPR(stereo_mix+1), A_GPR(stereo_mix+1), A_GPR(gpr+1), A_FXBUS(FXBUS_MIDI_RIGHT));
1272 snd_emu10k1_init_stereo_control(&controls[nctl++], "Synth Playback Volume", gpr, 100);
1273 gpr += 2;
1274
1275 /* Wave (PCM) Capture */
1276 A_OP(icode, &ptr, iMAC0, A_GPR(capture+0), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LEFT));
1277 A_OP(icode, &ptr, iMAC0, A_GPR(capture+1), A_C_00000000, A_GPR(gpr+1), A_FXBUS(FXBUS_PCM_RIGHT));
1278 snd_emu10k1_init_stereo_control(&controls[nctl++], "PCM Capture Volume", gpr, 0);
1279 gpr += 2;
1280
1281 /* Synth Capture */
1282 A_OP(icode, &ptr, iMAC0, A_GPR(capture+0), A_GPR(capture+0), A_GPR(gpr), A_FXBUS(FXBUS_MIDI_LEFT));
1283 A_OP(icode, &ptr, iMAC0, A_GPR(capture+1), A_GPR(capture+1), A_GPR(gpr+1), A_FXBUS(FXBUS_MIDI_RIGHT));
1284 snd_emu10k1_init_stereo_control(&controls[nctl++], "Synth Capture Volume", gpr, 0);
1285 gpr += 2;
9f4bd5dd 1286
1da177e4
LT
1287 /*
1288 * inputs
1289 */
1290#define A_ADD_VOLUME_IN(var,vol,input) \
1291A_OP(icode, &ptr, iMAC0, A_GPR(var), A_GPR(var), A_GPR(vol), A_EXTIN(input))
1292
9f4bd5dd 1293 /* emu1212 DSP 0 and DSP 1 Capture */
190d2c46 1294 if (emu->card_capabilities->emu_model) {
90fd5ce5
JCD
1295 if (emu->card_capabilities->ca0108_chip) {
1296 /* Note:JCD:No longer bit shift lower 16bits to upper 16bits of 32bit value. */
1297 A_OP(icode, &ptr, iMACINT0, A_GPR(tmp), A_C_00000000, A3_EMU32IN(0x0), A_C_00000001);
1298 A_OP(icode, &ptr, iMAC0, A_GPR(capture+0), A_GPR(capture+0), A_GPR(gpr), A_GPR(tmp));
1299 A_OP(icode, &ptr, iMACINT0, A_GPR(tmp), A_C_00000000, A3_EMU32IN(0x1), A_C_00000001);
1300 A_OP(icode, &ptr, iMAC0, A_GPR(capture+1), A_GPR(capture+1), A_GPR(gpr), A_GPR(tmp));
1301 } else {
1302 A_OP(icode, &ptr, iMAC0, A_GPR(capture+0), A_GPR(capture+0), A_GPR(gpr), A_P16VIN(0x0));
1303 A_OP(icode, &ptr, iMAC0, A_GPR(capture+1), A_GPR(capture+1), A_GPR(gpr+1), A_P16VIN(0x1));
1304 }
9f4bd5dd
JCD
1305 snd_emu10k1_init_stereo_control(&controls[nctl++], "EMU Capture Volume", gpr, 0);
1306 gpr += 2;
1307 }
1da177e4
LT
1308 /* AC'97 Playback Volume - used only for mic (renamed later) */
1309 A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_AC97_L);
1310 A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_AC97_R);
1311 snd_emu10k1_init_stereo_control(&controls[nctl++], "AMic Playback Volume", gpr, 0);
1312 gpr += 2;
1313 /* AC'97 Capture Volume - used only for mic */
1314 A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_AC97_L);
1315 A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_AC97_R);
1316 snd_emu10k1_init_stereo_control(&controls[nctl++], "Mic Capture Volume", gpr, 0);
1317 gpr += 2;
1318
1319 /* mic capture buffer */
1320 A_OP(icode, &ptr, iINTERP, A_EXTOUT(A_EXTOUT_MIC_CAP), A_EXTIN(A_EXTIN_AC97_L), 0xcd, A_EXTIN(A_EXTIN_AC97_R));
1321
1322 /* Audigy CD Playback Volume */
1323 A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_SPDIF_CD_L);
1324 A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_SPDIF_CD_R);
1325 snd_emu10k1_init_stereo_control(&controls[nctl++],
2b637da5 1326 emu->card_capabilities->ac97_chip ? "Audigy CD Playback Volume" : "CD Playback Volume",
1da177e4
LT
1327 gpr, 0);
1328 gpr += 2;
1329 /* Audigy CD Capture Volume */
1330 A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_SPDIF_CD_L);
1331 A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_SPDIF_CD_R);
1332 snd_emu10k1_init_stereo_control(&controls[nctl++],
2b637da5 1333 emu->card_capabilities->ac97_chip ? "Audigy CD Capture Volume" : "CD Capture Volume",
1da177e4
LT
1334 gpr, 0);
1335 gpr += 2;
1336
1337 /* Optical SPDIF Playback Volume */
1338 A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_OPT_SPDIF_L);
1339 A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_OPT_SPDIF_R);
10e8d78a 1340 snd_emu10k1_init_stereo_control(&controls[nctl++], SNDRV_CTL_NAME_IEC958("Optical ",PLAYBACK,VOLUME), gpr, 0);
1da177e4
LT
1341 gpr += 2;
1342 /* Optical SPDIF Capture Volume */
1343 A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_OPT_SPDIF_L);
1344 A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_OPT_SPDIF_R);
10e8d78a 1345 snd_emu10k1_init_stereo_control(&controls[nctl++], SNDRV_CTL_NAME_IEC958("Optical ",CAPTURE,VOLUME), gpr, 0);
1da177e4
LT
1346 gpr += 2;
1347
1348 /* Line2 Playback Volume */
1349 A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_LINE2_L);
1350 A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_LINE2_R);
1351 snd_emu10k1_init_stereo_control(&controls[nctl++],
2b637da5 1352 emu->card_capabilities->ac97_chip ? "Line2 Playback Volume" : "Line Playback Volume",
1da177e4
LT
1353 gpr, 0);
1354 gpr += 2;
1355 /* Line2 Capture Volume */
1356 A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_LINE2_L);
1357 A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_LINE2_R);
1358 snd_emu10k1_init_stereo_control(&controls[nctl++],
2b637da5 1359 emu->card_capabilities->ac97_chip ? "Line2 Capture Volume" : "Line Capture Volume",
1da177e4
LT
1360 gpr, 0);
1361 gpr += 2;
1362
1363 /* Philips ADC Playback Volume */
1364 A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_ADC_L);
1365 A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_ADC_R);
1366 snd_emu10k1_init_stereo_control(&controls[nctl++], "Analog Mix Playback Volume", gpr, 0);
1367 gpr += 2;
1368 /* Philips ADC Capture Volume */
1369 A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_ADC_L);
1370 A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_ADC_R);
1371 snd_emu10k1_init_stereo_control(&controls[nctl++], "Analog Mix Capture Volume", gpr, 0);
1372 gpr += 2;
1373
1374 /* Aux2 Playback Volume */
1375 A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_AUX2_L);
1376 A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_AUX2_R);
1377 snd_emu10k1_init_stereo_control(&controls[nctl++],
2b637da5 1378 emu->card_capabilities->ac97_chip ? "Aux2 Playback Volume" : "Aux Playback Volume",
1da177e4
LT
1379 gpr, 0);
1380 gpr += 2;
1381 /* Aux2 Capture Volume */
1382 A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_AUX2_L);
1383 A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_AUX2_R);
1384 snd_emu10k1_init_stereo_control(&controls[nctl++],
2b637da5 1385 emu->card_capabilities->ac97_chip ? "Aux2 Capture Volume" : "Aux Capture Volume",
1da177e4
LT
1386 gpr, 0);
1387 gpr += 2;
1388
1389 /* Stereo Mix Front Playback Volume */
1390 A_OP(icode, &ptr, iMAC0, A_GPR(playback), A_GPR(playback), A_GPR(gpr), A_GPR(stereo_mix));
1391 A_OP(icode, &ptr, iMAC0, A_GPR(playback+1), A_GPR(playback+1), A_GPR(gpr+1), A_GPR(stereo_mix+1));
1392 snd_emu10k1_init_stereo_control(&controls[nctl++], "Front Playback Volume", gpr, 100);
1393 gpr += 2;
1394
1395 /* Stereo Mix Surround Playback */
1396 A_OP(icode, &ptr, iMAC0, A_GPR(playback+2), A_GPR(playback+2), A_GPR(gpr), A_GPR(stereo_mix));
1397 A_OP(icode, &ptr, iMAC0, A_GPR(playback+3), A_GPR(playback+3), A_GPR(gpr+1), A_GPR(stereo_mix+1));
1398 snd_emu10k1_init_stereo_control(&controls[nctl++], "Surround Playback Volume", gpr, 0);
1399 gpr += 2;
1400
1401 /* Stereo Mix Center Playback */
1402 /* Center = sub = Left/2 + Right/2 */
1403 A_OP(icode, &ptr, iINTERP, A_GPR(tmp), A_GPR(stereo_mix), 0xcd, A_GPR(stereo_mix+1));
1404 A_OP(icode, &ptr, iMAC0, A_GPR(playback+4), A_GPR(playback+4), A_GPR(gpr), A_GPR(tmp));
1405 snd_emu10k1_init_mono_control(&controls[nctl++], "Center Playback Volume", gpr, 0);
1406 gpr++;
1407
1408 /* Stereo Mix LFE Playback */
1409 A_OP(icode, &ptr, iMAC0, A_GPR(playback+5), A_GPR(playback+5), A_GPR(gpr), A_GPR(tmp));
1410 snd_emu10k1_init_mono_control(&controls[nctl++], "LFE Playback Volume", gpr, 0);
1411 gpr++;
1412
2b637da5 1413 if (emu->card_capabilities->spk71) {
1da177e4
LT
1414 /* Stereo Mix Side Playback */
1415 A_OP(icode, &ptr, iMAC0, A_GPR(playback+6), A_GPR(playback+6), A_GPR(gpr), A_GPR(stereo_mix));
1416 A_OP(icode, &ptr, iMAC0, A_GPR(playback+7), A_GPR(playback+7), A_GPR(gpr+1), A_GPR(stereo_mix+1));
1417 snd_emu10k1_init_stereo_control(&controls[nctl++], "Side Playback Volume", gpr, 0);
1418 gpr += 2;
1419 }
1420
1421 /*
1422 * outputs
1423 */
1424#define A_PUT_OUTPUT(out,src) A_OP(icode, &ptr, iACC3, A_EXTOUT(out), A_C_00000000, A_C_00000000, A_GPR(src))
1425#define A_PUT_STEREO_OUTPUT(out1,out2,src) \
1426 {A_PUT_OUTPUT(out1,src); A_PUT_OUTPUT(out2,src+1);}
1427
1428#define _A_SWITCH(icode, ptr, dst, src, sw) \
1429 A_OP((icode), ptr, iMACINT0, dst, A_C_00000000, src, sw);
1430#define A_SWITCH(icode, ptr, dst, src, sw) \
1431 _A_SWITCH(icode, ptr, A_GPR(dst), A_GPR(src), A_GPR(sw))
1432#define _A_SWITCH_NEG(icode, ptr, dst, src) \
1433 A_OP((icode), ptr, iANDXOR, dst, src, A_C_00000001, A_C_00000001);
1434#define A_SWITCH_NEG(icode, ptr, dst, src) \
1435 _A_SWITCH_NEG(icode, ptr, A_GPR(dst), A_GPR(src))
1436
1437
1438 /*
1439 * Process tone control
1440 */
1441 A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 0), A_GPR(playback + 0), A_C_00000000, A_C_00000000); /* left */
1442 A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 1), A_GPR(playback + 1), A_C_00000000, A_C_00000000); /* right */
1443 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 */
1444 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 */
1445 A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 4), A_GPR(playback + 4), A_C_00000000, A_C_00000000); /* center */
1446 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 1447 if (emu->card_capabilities->spk71) {
1da177e4
LT
1448 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 */
1449 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 */
1450 }
1451
1452
1453 ctl = &controls[nctl + 0];
1454 ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1455 strcpy(ctl->id.name, "Tone Control - Bass");
1456 ctl->vcount = 2;
1457 ctl->count = 10;
1458 ctl->min = 0;
1459 ctl->max = 40;
1460 ctl->value[0] = ctl->value[1] = 20;
1461 ctl->translation = EMU10K1_GPR_TRANSLATION_BASS;
1462 ctl = &controls[nctl + 1];
1463 ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1464 strcpy(ctl->id.name, "Tone Control - Treble");
1465 ctl->vcount = 2;
1466 ctl->count = 10;
1467 ctl->min = 0;
1468 ctl->max = 40;
1469 ctl->value[0] = ctl->value[1] = 20;
1470 ctl->translation = EMU10K1_GPR_TRANSLATION_TREBLE;
1471
1472#define BASS_GPR 0x8c
1473#define TREBLE_GPR 0x96
1474
1475 for (z = 0; z < 5; z++) {
1476 int j;
1477 for (j = 0; j < 2; j++) {
1478 controls[nctl + 0].gpr[z * 2 + j] = BASS_GPR + z * 2 + j;
1479 controls[nctl + 1].gpr[z * 2 + j] = TREBLE_GPR + z * 2 + j;
1480 }
1481 }
1482 for (z = 0; z < 4; z++) { /* front/rear/center-lfe/side */
1483 int j, k, l, d;
1484 for (j = 0; j < 2; j++) { /* left/right */
1485 k = 0xb0 + (z * 8) + (j * 4);
1486 l = 0xe0 + (z * 8) + (j * 4);
1487 d = playback + SND_EMU10K1_PLAYBACK_CHANNELS + z * 2 + j;
1488
1489 A_OP(icode, &ptr, iMAC0, A_C_00000000, A_C_00000000, A_GPR(d), A_GPR(BASS_GPR + 0 + j));
1490 A_OP(icode, &ptr, iMACMV, A_GPR(k+1), A_GPR(k), A_GPR(k+1), A_GPR(BASS_GPR + 4 + j));
1491 A_OP(icode, &ptr, iMACMV, A_GPR(k), A_GPR(d), A_GPR(k), A_GPR(BASS_GPR + 2 + j));
1492 A_OP(icode, &ptr, iMACMV, A_GPR(k+3), A_GPR(k+2), A_GPR(k+3), A_GPR(BASS_GPR + 8 + j));
1493 A_OP(icode, &ptr, iMAC0, A_GPR(k+2), A_GPR_ACCU, A_GPR(k+2), A_GPR(BASS_GPR + 6 + j));
1494 A_OP(icode, &ptr, iACC3, A_GPR(k+2), A_GPR(k+2), A_GPR(k+2), A_C_00000000);
1495
1496 A_OP(icode, &ptr, iMAC0, A_C_00000000, A_C_00000000, A_GPR(k+2), A_GPR(TREBLE_GPR + 0 + j));
1497 A_OP(icode, &ptr, iMACMV, A_GPR(l+1), A_GPR(l), A_GPR(l+1), A_GPR(TREBLE_GPR + 4 + j));
1498 A_OP(icode, &ptr, iMACMV, A_GPR(l), A_GPR(k+2), A_GPR(l), A_GPR(TREBLE_GPR + 2 + j));
1499 A_OP(icode, &ptr, iMACMV, A_GPR(l+3), A_GPR(l+2), A_GPR(l+3), A_GPR(TREBLE_GPR + 8 + j));
1500 A_OP(icode, &ptr, iMAC0, A_GPR(l+2), A_GPR_ACCU, A_GPR(l+2), A_GPR(TREBLE_GPR + 6 + j));
1501 A_OP(icode, &ptr, iMACINT0, A_GPR(l+2), A_C_00000000, A_GPR(l+2), A_C_00000010);
1502
1503 A_OP(icode, &ptr, iACC3, A_GPR(d), A_GPR(l+2), A_C_00000000, A_C_00000000);
1504
1505 if (z == 2) /* center */
1506 break;
1507 }
1508 }
1509 nctl += 2;
1510
1511#undef BASS_GPR
1512#undef TREBLE_GPR
1513
1514 for (z = 0; z < 8; z++) {
1515 A_SWITCH(icode, &ptr, tmp + 0, playback + SND_EMU10K1_PLAYBACK_CHANNELS + z, gpr + 0);
1516 A_SWITCH_NEG(icode, &ptr, tmp + 1, gpr + 0);
1517 A_SWITCH(icode, &ptr, tmp + 1, playback + z, tmp + 1);
1518 A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + z), A_GPR(tmp + 0), A_GPR(tmp + 1), A_C_00000000);
1519 }
1520 snd_emu10k1_init_stereo_onoff_control(controls + nctl++, "Tone Control - Switch", gpr, 0);
1521 gpr += 2;
1522
1523 /* Master volume (will be renamed later) */
1524 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));
1525 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));
1526 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));
1527 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));
1528 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));
1529 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));
1530 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));
1531 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));
1532 snd_emu10k1_init_mono_control(&controls[nctl++], "Wave Master Playback Volume", gpr, 0);
1533 gpr += 2;
1534
1535 /* analog speakers */
1536 A_PUT_STEREO_OUTPUT(A_EXTOUT_AFRONT_L, A_EXTOUT_AFRONT_R, playback + SND_EMU10K1_PLAYBACK_CHANNELS);
1537 A_PUT_STEREO_OUTPUT(A_EXTOUT_AREAR_L, A_EXTOUT_AREAR_R, playback+2 + SND_EMU10K1_PLAYBACK_CHANNELS);
1538 A_PUT_OUTPUT(A_EXTOUT_ACENTER, playback+4 + SND_EMU10K1_PLAYBACK_CHANNELS);
1539 A_PUT_OUTPUT(A_EXTOUT_ALFE, playback+5 + SND_EMU10K1_PLAYBACK_CHANNELS);
2b637da5 1540 if (emu->card_capabilities->spk71)
1da177e4
LT
1541 A_PUT_STEREO_OUTPUT(A_EXTOUT_ASIDE_L, A_EXTOUT_ASIDE_R, playback+6 + SND_EMU10K1_PLAYBACK_CHANNELS);
1542
1543 /* headphone */
1544 A_PUT_STEREO_OUTPUT(A_EXTOUT_HEADPHONE_L, A_EXTOUT_HEADPHONE_R, playback + SND_EMU10K1_PLAYBACK_CHANNELS);
1545
1546 /* digital outputs */
1547 /* A_PUT_STEREO_OUTPUT(A_EXTOUT_FRONT_L, A_EXTOUT_FRONT_R, playback + SND_EMU10K1_PLAYBACK_CHANNELS); */
190d2c46 1548 if (emu->card_capabilities->emu_model) {
9f4bd5dd 1549 /* EMU1010 Outputs from PCM Front, Rear, Center, LFE, Side */
6f002b02 1550 dev_info(emu->card->dev, "EMU outputs on\n");
9f4bd5dd 1551 for (z = 0; z < 8; z++) {
90fd5ce5
JCD
1552 if (emu->card_capabilities->ca0108_chip) {
1553 A_OP(icode, &ptr, iACC3, A3_EMU32OUT(z), A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + z), A_C_00000000, A_C_00000000);
1554 } else {
1555 A_OP(icode, &ptr, iACC3, A_EMU32OUTL(z), A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + z), A_C_00000000, A_C_00000000);
1556 }
9f4bd5dd
JCD
1557 }
1558 }
1da177e4
LT
1559
1560 /* IEC958 Optical Raw Playback Switch */
1561 gpr_map[gpr++] = 0;
1562 gpr_map[gpr++] = 0x1008;
1563 gpr_map[gpr++] = 0xffff0000;
1564 for (z = 0; z < 2; z++) {
1565 A_OP(icode, &ptr, iMAC0, A_GPR(tmp + 2), A_FXBUS(FXBUS_PT_LEFT + z), A_C_00000000, A_C_00000000);
1566 A_OP(icode, &ptr, iSKIP, A_GPR_COND, A_GPR_COND, A_GPR(gpr - 2), A_C_00000001);
1567 A_OP(icode, &ptr, iACC3, A_GPR(tmp + 2), A_C_00000000, A_C_00010000, A_GPR(tmp + 2));
1568 A_OP(icode, &ptr, iANDXOR, A_GPR(tmp + 2), A_GPR(tmp + 2), A_GPR(gpr - 1), A_C_00000000);
1569 A_SWITCH(icode, &ptr, tmp + 0, tmp + 2, gpr + z);
1570 A_SWITCH_NEG(icode, &ptr, tmp + 1, gpr + z);
1571 A_SWITCH(icode, &ptr, tmp + 1, playback + SND_EMU10K1_PLAYBACK_CHANNELS + z, tmp + 1);
1572 if ((z==1) && (emu->card_capabilities->spdif_bug)) {
1573 /* Due to a SPDIF output bug on some Audigy cards, this code delays the Right channel by 1 sample */
6f002b02
TI
1574 dev_info(emu->card->dev,
1575 "Installing spdif_bug patch: %s\n",
1576 emu->card_capabilities->name);
1da177e4
LT
1577 A_OP(icode, &ptr, iACC3, A_EXTOUT(A_EXTOUT_FRONT_L + z), A_GPR(gpr - 3), A_C_00000000, A_C_00000000);
1578 A_OP(icode, &ptr, iACC3, A_GPR(gpr - 3), A_GPR(tmp + 0), A_GPR(tmp + 1), A_C_00000000);
1579 } else {
1580 A_OP(icode, &ptr, iACC3, A_EXTOUT(A_EXTOUT_FRONT_L + z), A_GPR(tmp + 0), A_GPR(tmp + 1), A_C_00000000);
1581 }
1582 }
10e8d78a 1583 snd_emu10k1_init_stereo_onoff_control(controls + nctl++, SNDRV_CTL_NAME_IEC958("Optical Raw ",PLAYBACK,SWITCH), gpr, 0);
1da177e4
LT
1584 gpr += 2;
1585
1586 A_PUT_STEREO_OUTPUT(A_EXTOUT_REAR_L, A_EXTOUT_REAR_R, playback+2 + SND_EMU10K1_PLAYBACK_CHANNELS);
1587 A_PUT_OUTPUT(A_EXTOUT_CENTER, playback+4 + SND_EMU10K1_PLAYBACK_CHANNELS);
1588 A_PUT_OUTPUT(A_EXTOUT_LFE, playback+5 + SND_EMU10K1_PLAYBACK_CHANNELS);
1589
1590 /* ADC buffer */
1591#ifdef EMU10K1_CAPTURE_DIGITAL_OUT
1592 A_PUT_STEREO_OUTPUT(A_EXTOUT_ADC_CAP_L, A_EXTOUT_ADC_CAP_R, playback + SND_EMU10K1_PLAYBACK_CHANNELS);
1593#else
1594 A_PUT_OUTPUT(A_EXTOUT_ADC_CAP_L, capture);
1595 A_PUT_OUTPUT(A_EXTOUT_ADC_CAP_R, capture+1);
1596#endif
1597
190d2c46 1598 if (emu->card_capabilities->emu_model) {
90fd5ce5 1599 if (emu->card_capabilities->ca0108_chip) {
6f002b02 1600 dev_info(emu->card->dev, "EMU2 inputs on\n");
90fd5ce5
JCD
1601 for (z = 0; z < 0x10; z++) {
1602 snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp,
1603 bit_shifter16,
1604 A3_EMU32IN(z),
1605 A_FXBUS2(z*2) );
1606 }
1607 } else {
6f002b02 1608 dev_info(emu->card->dev, "EMU inputs on\n");
90fd5ce5
JCD
1609 /* Capture 16 (originally 8) channels of S32_LE sound */
1610
28a97c19 1611 /*
6f002b02 1612 dev_dbg(emu->card->dev, "emufx.c: gpr=0x%x, tmp=0x%x\n",
28a97c19
TI
1613 gpr, tmp);
1614 */
90fd5ce5
JCD
1615 /* For the EMU1010: How to get 32bit values from the DSP. High 16bits into L, low 16bits into R. */
1616 /* A_P16VIN(0) is delayed by one sample,
1617 * so all other A_P16VIN channels will need to also be delayed
1618 */
1619 /* Left ADC in. 1 of 2 */
1620 snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_P16VIN(0x0), A_FXBUS2(0) );
1621 /* Right ADC in 1 of 2 */
1622 gpr_map[gpr++] = 0x00000000;
1623 /* Delaying by one sample: instead of copying the input
1624 * value A_P16VIN to output A_FXBUS2 as in the first channel,
1625 * we use an auxiliary register, delaying the value by one
1626 * sample
1627 */
1628 snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_GPR(gpr - 1), A_FXBUS2(2) );
1629 A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x1), A_C_00000000, A_C_00000000);
1630 gpr_map[gpr++] = 0x00000000;
1631 snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_GPR(gpr - 1), A_FXBUS2(4) );
1632 A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x2), A_C_00000000, A_C_00000000);
1633 gpr_map[gpr++] = 0x00000000;
1634 snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_GPR(gpr - 1), A_FXBUS2(6) );
1635 A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x3), A_C_00000000, A_C_00000000);
1636 /* For 96kHz mode */
1637 /* Left ADC in. 2 of 2 */
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(0x8) );
1640 A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x4), A_C_00000000, A_C_00000000);
1641 /* Right ADC in 2 of 2 */
1642 gpr_map[gpr++] = 0x00000000;
1643 snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_GPR(gpr - 1), A_FXBUS2(0xa) );
1644 A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x5), A_C_00000000, A_C_00000000);
1645 gpr_map[gpr++] = 0x00000000;
1646 snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_GPR(gpr - 1), A_FXBUS2(0xc) );
1647 A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x6), A_C_00000000, A_C_00000000);
1648 gpr_map[gpr++] = 0x00000000;
1649 snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_GPR(gpr - 1), A_FXBUS2(0xe) );
1650 A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x7), A_C_00000000, A_C_00000000);
1651 /* Pavel Hofman - we still have voices, A_FXBUS2s, and
1652 * A_P16VINs available -
1653 * let's add 8 more capture channels - total of 16
1654 */
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(0x10));
1660 A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x8),
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(0x12));
1667 A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x9),
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(0x14));
1674 A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0xa),
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(0x16));
1681 A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0xb),
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(0x18));
1688 A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0xc),
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(0x1a));
1695 A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0xd),
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(0x1c));
1702 A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0xe),
1703 A_C_00000000, A_C_00000000);
1704 gpr_map[gpr++] = 0x00000000;
1705 snd_emu10k1_audigy_dsp_convert_32_to_2x16(icode, &ptr, tmp,
1706 bit_shifter16,
1707 A_GPR(gpr - 1),
1708 A_FXBUS2(0x1e));
1709 A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0xf),
1710 A_C_00000000, A_C_00000000);
1711 }
9f4bd5dd
JCD
1712
1713#if 0
1714 for (z = 4; z < 8; z++) {
1715 A_OP(icode, &ptr, iACC3, A_FXBUS2(z), A_C_00000000, A_C_00000000, A_C_00000000);
1716 }
1717 for (z = 0xc; z < 0x10; z++) {
1718 A_OP(icode, &ptr, iACC3, A_FXBUS2(z), A_C_00000000, A_C_00000000, A_C_00000000);
1719 }
1720#endif
1721 } else {
1722 /* EFX capture - capture the 16 EXTINs */
1723 /* Capture 16 channels of S16_LE sound */
1724 for (z = 0; z < 16; z++) {
1725 A_OP(icode, &ptr, iACC3, A_FXBUS2(z), A_C_00000000, A_C_00000000, A_EXTIN(z));
1726 }
1da177e4
LT
1727 }
1728
19b99fba 1729#endif /* JCD test */
1da177e4
LT
1730 /*
1731 * ok, set up done..
1732 */
1733
1734 if (gpr > tmp) {
1735 snd_BUG();
1736 err = -EIO;
1737 goto __err;
1738 }
1739 /* clear remaining instruction memory */
1740 while (ptr < 0x400)
1741 A_OP(icode, &ptr, 0x0f, 0xc0, 0xc0, 0xcf, 0xc0);
1742
1743 seg = snd_enter_user();
1744 icode->gpr_add_control_count = nctl;
eb4698f3 1745 icode->gpr_add_controls = (struct snd_emu10k1_fx8010_control_gpr __user *)controls;
f7ba7fc6 1746 emu->support_tlv = 1; /* support TLV */
1da177e4 1747 err = snd_emu10k1_icode_poke(emu, icode);
f7ba7fc6 1748 emu->support_tlv = 0; /* clear again */
1da177e4
LT
1749 snd_leave_user(seg);
1750
f1b4863a 1751__err:
1da177e4 1752 kfree(controls);
f1b4863a
GB
1753__err_ctrls:
1754 kfree((void __force *)icode->gpr_map);
1755__err_gpr:
1756 kfree(icode);
1da177e4
LT
1757 return err;
1758}
1759
1760
1761/*
1762 * initial DSP configuration for Emu10k1
1763 */
1764
1765/* when volume = max, then copy only to avoid volume modification */
1766/* with iMAC0 (negative values) */
e23e7a14 1767static void _volume(struct snd_emu10k1_fx8010_code *icode, u32 *ptr, u32 dst, u32 src, u32 vol)
1da177e4
LT
1768{
1769 OP(icode, ptr, iMAC0, dst, C_00000000, src, vol);
1770 OP(icode, ptr, iANDXOR, C_00000000, vol, C_ffffffff, C_7fffffff);
1771 OP(icode, ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, C_00000001);
1772 OP(icode, ptr, iACC3, dst, src, C_00000000, C_00000000);
1773}
e23e7a14 1774static void _volume_add(struct snd_emu10k1_fx8010_code *icode, u32 *ptr, u32 dst, u32 src, u32 vol)
1da177e4
LT
1775{
1776 OP(icode, ptr, iANDXOR, C_00000000, vol, C_ffffffff, C_7fffffff);
1777 OP(icode, ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, C_00000002);
1778 OP(icode, ptr, iMACINT0, dst, dst, src, C_00000001);
1779 OP(icode, ptr, iSKIP, C_00000000, C_7fffffff, C_7fffffff, C_00000001);
1780 OP(icode, ptr, iMAC0, dst, dst, src, vol);
1781}
e23e7a14 1782static void _volume_out(struct snd_emu10k1_fx8010_code *icode, u32 *ptr, u32 dst, u32 src, u32 vol)
1da177e4
LT
1783{
1784 OP(icode, ptr, iANDXOR, C_00000000, vol, C_ffffffff, C_7fffffff);
1785 OP(icode, ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, C_00000002);
1786 OP(icode, ptr, iACC3, dst, src, C_00000000, C_00000000);
1787 OP(icode, ptr, iSKIP, C_00000000, C_7fffffff, C_7fffffff, C_00000001);
1788 OP(icode, ptr, iMAC0, dst, C_00000000, src, vol);
1789}
1790
1791#define VOLUME(icode, ptr, dst, src, vol) \
1792 _volume(icode, ptr, GPR(dst), GPR(src), GPR(vol))
1793#define VOLUME_IN(icode, ptr, dst, src, vol) \
1794 _volume(icode, ptr, GPR(dst), EXTIN(src), GPR(vol))
1795#define VOLUME_ADD(icode, ptr, dst, src, vol) \
1796 _volume_add(icode, ptr, GPR(dst), GPR(src), GPR(vol))
1797#define VOLUME_ADDIN(icode, ptr, dst, src, vol) \
1798 _volume_add(icode, ptr, GPR(dst), EXTIN(src), GPR(vol))
1799#define VOLUME_OUT(icode, ptr, dst, src, vol) \
1800 _volume_out(icode, ptr, EXTOUT(dst), GPR(src), GPR(vol))
1801#define _SWITCH(icode, ptr, dst, src, sw) \
1802 OP((icode), ptr, iMACINT0, dst, C_00000000, src, sw);
1803#define SWITCH(icode, ptr, dst, src, sw) \
1804 _SWITCH(icode, ptr, GPR(dst), GPR(src), GPR(sw))
1805#define SWITCH_IN(icode, ptr, dst, src, sw) \
1806 _SWITCH(icode, ptr, GPR(dst), EXTIN(src), GPR(sw))
1807#define _SWITCH_NEG(icode, ptr, dst, src) \
1808 OP((icode), ptr, iANDXOR, dst, src, C_00000001, C_00000001);
1809#define SWITCH_NEG(icode, ptr, dst, src) \
1810 _SWITCH_NEG(icode, ptr, GPR(dst), GPR(src))
1811
1812
e23e7a14 1813static int _snd_emu10k1_init_efx(struct snd_emu10k1 *emu)
1da177e4
LT
1814{
1815 int err, i, z, gpr, tmp, playback, capture;
1816 u32 ptr;
eb4698f3
TI
1817 struct snd_emu10k1_fx8010_code *icode;
1818 struct snd_emu10k1_fx8010_pcm_rec *ipcm = NULL;
1819 struct snd_emu10k1_fx8010_control_gpr *controls = NULL, *ctl;
1da177e4
LT
1820 u32 *gpr_map;
1821 mm_segment_t seg;
1822
f1b4863a
GB
1823 err = -ENOMEM;
1824 icode = kzalloc(sizeof(*icode), GFP_KERNEL);
1825 if (!icode)
1826 return err;
1827
1828 icode->gpr_map = (u_int32_t __user *) kcalloc(256 + 160 + 160 + 2 * 512,
1829 sizeof(u_int32_t), GFP_KERNEL);
1830 if (!icode->gpr_map)
1831 goto __err_gpr;
1832
1833 controls = kcalloc(SND_EMU10K1_GPR_CONTROLS,
1834 sizeof(struct snd_emu10k1_fx8010_control_gpr),
1835 GFP_KERNEL);
1836 if (!controls)
1837 goto __err_ctrls;
1838
1839 ipcm = kzalloc(sizeof(*ipcm), GFP_KERNEL);
1840 if (!ipcm)
1841 goto __err_ipcm;
1842
4d23359b 1843 gpr_map = (u32 __force *)icode->gpr_map;
1da177e4
LT
1844
1845 icode->tram_data_map = icode->gpr_map + 256;
1846 icode->tram_addr_map = icode->tram_data_map + 160;
1847 icode->code = icode->tram_addr_map + 160;
1848
1849 /* clear free GPRs */
1850 for (i = 0; i < 256; i++)
1851 set_bit(i, icode->gpr_valid);
1852
1853 /* clear TRAM data & address lines */
1854 for (i = 0; i < 160; i++)
1855 set_bit(i, icode->tram_valid);
1856
1857 strcpy(icode->name, "SB Live! FX8010 code for ALSA v1.2 by Jaroslav Kysela");
1858 ptr = 0; i = 0;
edf8e456 1859 /* we have 12 inputs */
1da177e4
LT
1860 playback = SND_EMU10K1_INPUTS;
1861 /* we have 6 playback channels and tone control doubles */
1862 capture = playback + (SND_EMU10K1_PLAYBACK_CHANNELS * 2);
1863 gpr = capture + SND_EMU10K1_CAPTURE_CHANNELS;
1864 tmp = 0x88; /* we need 4 temporary GPR */
1865 /* from 0x8c to 0xff is the area for tone control */
1866
1867 /* stop FX processor */
1868 snd_emu10k1_ptr_write(emu, DBG, 0, (emu->fx8010.dbg = 0) | EMU10K1_DBG_SINGLE_STEP);
1869
1870 /*
1871 * Process FX Buses
1872 */
1873 OP(icode, &ptr, iMACINT0, GPR(0), C_00000000, FXBUS(FXBUS_PCM_LEFT), C_00000004);
1874 OP(icode, &ptr, iMACINT0, GPR(1), C_00000000, FXBUS(FXBUS_PCM_RIGHT), C_00000004);
1875 OP(icode, &ptr, iMACINT0, GPR(2), C_00000000, FXBUS(FXBUS_MIDI_LEFT), C_00000004);
1876 OP(icode, &ptr, iMACINT0, GPR(3), C_00000000, FXBUS(FXBUS_MIDI_RIGHT), C_00000004);
1877 OP(icode, &ptr, iMACINT0, GPR(4), C_00000000, FXBUS(FXBUS_PCM_LEFT_REAR), C_00000004);
1878 OP(icode, &ptr, iMACINT0, GPR(5), C_00000000, FXBUS(FXBUS_PCM_RIGHT_REAR), C_00000004);
1879 OP(icode, &ptr, iMACINT0, GPR(6), C_00000000, FXBUS(FXBUS_PCM_CENTER), C_00000004);
1880 OP(icode, &ptr, iMACINT0, GPR(7), C_00000000, FXBUS(FXBUS_PCM_LFE), C_00000004);
1881 OP(icode, &ptr, iMACINT0, GPR(8), C_00000000, C_00000000, C_00000000); /* S/PDIF left */
1882 OP(icode, &ptr, iMACINT0, GPR(9), C_00000000, C_00000000, C_00000000); /* S/PDIF right */
edf8e456
MM
1883 OP(icode, &ptr, iMACINT0, GPR(10), C_00000000, FXBUS(FXBUS_PCM_LEFT_FRONT), C_00000004);
1884 OP(icode, &ptr, iMACINT0, GPR(11), C_00000000, FXBUS(FXBUS_PCM_RIGHT_FRONT), C_00000004);
1da177e4
LT
1885
1886 /* Raw S/PDIF PCM */
1887 ipcm->substream = 0;
1888 ipcm->channels = 2;
1889 ipcm->tram_start = 0;
1890 ipcm->buffer_size = (64 * 1024) / 2;
1891 ipcm->gpr_size = gpr++;
1892 ipcm->gpr_ptr = gpr++;
1893 ipcm->gpr_count = gpr++;
1894 ipcm->gpr_tmpcount = gpr++;
1895 ipcm->gpr_trigger = gpr++;
1896 ipcm->gpr_running = gpr++;
1897 ipcm->etram[0] = 0;
1898 ipcm->etram[1] = 1;
1899
1900 gpr_map[gpr + 0] = 0xfffff000;
1901 gpr_map[gpr + 1] = 0xffff0000;
1902 gpr_map[gpr + 2] = 0x70000000;
1903 gpr_map[gpr + 3] = 0x00000007;
1904 gpr_map[gpr + 4] = 0x001f << 11;
1905 gpr_map[gpr + 5] = 0x001c << 11;
1906 gpr_map[gpr + 6] = (0x22 - 0x01) - 1; /* skip at 01 to 22 */
1907 gpr_map[gpr + 7] = (0x22 - 0x06) - 1; /* skip at 06 to 22 */
1908 gpr_map[gpr + 8] = 0x2000000 + (2<<11);
1909 gpr_map[gpr + 9] = 0x4000000 + (2<<11);
1910 gpr_map[gpr + 10] = 1<<11;
1911 gpr_map[gpr + 11] = (0x24 - 0x0a) - 1; /* skip at 0a to 24 */
1912 gpr_map[gpr + 12] = 0;
1913
1914 /* if the trigger flag is not set, skip */
1915 /* 00: */ OP(icode, &ptr, iMAC0, C_00000000, GPR(ipcm->gpr_trigger), C_00000000, C_00000000);
1916 /* 01: */ OP(icode, &ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_ZERO, GPR(gpr + 6));
1917 /* if the running flag is set, we're running */
1918 /* 02: */ OP(icode, &ptr, iMAC0, C_00000000, GPR(ipcm->gpr_running), C_00000000, C_00000000);
1919 /* 03: */ OP(icode, &ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, C_00000004);
1920 /* wait until ((GPR_DBAC>>11) & 0x1f) == 0x1c) */
1921 /* 04: */ OP(icode, &ptr, iANDXOR, GPR(tmp + 0), GPR_DBAC, GPR(gpr + 4), C_00000000);
1922 /* 05: */ OP(icode, &ptr, iMACINT0, C_00000000, GPR(tmp + 0), C_ffffffff, GPR(gpr + 5));
1923 /* 06: */ OP(icode, &ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, GPR(gpr + 7));
1924 /* 07: */ OP(icode, &ptr, iACC3, GPR(gpr + 12), C_00000010, C_00000001, C_00000000);
1925
1926 /* 08: */ OP(icode, &ptr, iANDXOR, GPR(ipcm->gpr_running), GPR(ipcm->gpr_running), C_00000000, C_00000001);
1927 /* 09: */ OP(icode, &ptr, iACC3, GPR(gpr + 12), GPR(gpr + 12), C_ffffffff, C_00000000);
1928 /* 0a: */ OP(icode, &ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, GPR(gpr + 11));
1929 /* 0b: */ OP(icode, &ptr, iACC3, GPR(gpr + 12), C_00000001, C_00000000, C_00000000);
1930
1931 /* 0c: */ OP(icode, &ptr, iANDXOR, GPR(tmp + 0), ETRAM_DATA(ipcm->etram[0]), GPR(gpr + 0), C_00000000);
1932 /* 0d: */ OP(icode, &ptr, iLOG, GPR(tmp + 0), GPR(tmp + 0), GPR(gpr + 3), C_00000000);
1933 /* 0e: */ OP(icode, &ptr, iANDXOR, GPR(8), GPR(tmp + 0), GPR(gpr + 1), GPR(gpr + 2));
1934 /* 0f: */ OP(icode, &ptr, iSKIP, C_00000000, GPR_COND, CC_REG_MINUS, C_00000001);
1935 /* 10: */ OP(icode, &ptr, iANDXOR, GPR(8), GPR(8), GPR(gpr + 1), GPR(gpr + 2));
1936
1937 /* 11: */ OP(icode, &ptr, iANDXOR, GPR(tmp + 0), ETRAM_DATA(ipcm->etram[1]), GPR(gpr + 0), C_00000000);
1938 /* 12: */ OP(icode, &ptr, iLOG, GPR(tmp + 0), GPR(tmp + 0), GPR(gpr + 3), C_00000000);
1939 /* 13: */ OP(icode, &ptr, iANDXOR, GPR(9), GPR(tmp + 0), GPR(gpr + 1), GPR(gpr + 2));
1940 /* 14: */ OP(icode, &ptr, iSKIP, C_00000000, GPR_COND, CC_REG_MINUS, C_00000001);
1941 /* 15: */ OP(icode, &ptr, iANDXOR, GPR(9), GPR(9), GPR(gpr + 1), GPR(gpr + 2));
1942
1943 /* 16: */ OP(icode, &ptr, iACC3, GPR(tmp + 0), GPR(ipcm->gpr_ptr), C_00000001, C_00000000);
1944 /* 17: */ OP(icode, &ptr, iMACINT0, C_00000000, GPR(tmp + 0), C_ffffffff, GPR(ipcm->gpr_size));
1945 /* 18: */ OP(icode, &ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_MINUS, C_00000001);
1946 /* 19: */ OP(icode, &ptr, iACC3, GPR(tmp + 0), C_00000000, C_00000000, C_00000000);
1947 /* 1a: */ OP(icode, &ptr, iACC3, GPR(ipcm->gpr_ptr), GPR(tmp + 0), C_00000000, C_00000000);
1948
1949 /* 1b: */ OP(icode, &ptr, iACC3, GPR(ipcm->gpr_tmpcount), GPR(ipcm->gpr_tmpcount), C_ffffffff, C_00000000);
1950 /* 1c: */ OP(icode, &ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, C_00000002);
1951 /* 1d: */ OP(icode, &ptr, iACC3, GPR(ipcm->gpr_tmpcount), GPR(ipcm->gpr_count), C_00000000, C_00000000);
1952 /* 1e: */ OP(icode, &ptr, iACC3, GPR_IRQ, C_80000000, C_00000000, C_00000000);
1953 /* 1f: */ OP(icode, &ptr, iANDXOR, GPR(ipcm->gpr_running), GPR(ipcm->gpr_running), C_00000001, C_00010000);
1954
1955 /* 20: */ OP(icode, &ptr, iANDXOR, GPR(ipcm->gpr_running), GPR(ipcm->gpr_running), C_00010000, C_00000001);
1956 /* 21: */ OP(icode, &ptr, iSKIP, C_00000000, C_7fffffff, C_7fffffff, C_00000002);
1957
1958 /* 22: */ OP(icode, &ptr, iMACINT1, ETRAM_ADDR(ipcm->etram[0]), GPR(gpr + 8), GPR_DBAC, C_ffffffff);
1959 /* 23: */ OP(icode, &ptr, iMACINT1, ETRAM_ADDR(ipcm->etram[1]), GPR(gpr + 9), GPR_DBAC, C_ffffffff);
1960
1961 /* 24: */
1962 gpr += 13;
1963
1964 /* Wave Playback Volume */
1965 for (z = 0; z < 2; z++)
1966 VOLUME(icode, &ptr, playback + z, z, gpr + z);
1967 snd_emu10k1_init_stereo_control(controls + i++, "Wave Playback Volume", gpr, 100);
1968 gpr += 2;
1969
1970 /* Wave Surround Playback Volume */
1971 for (z = 0; z < 2; z++)
1972 VOLUME(icode, &ptr, playback + 2 + z, z, gpr + z);
1973 snd_emu10k1_init_stereo_control(controls + i++, "Wave Surround Playback Volume", gpr, 0);
1974 gpr += 2;
1975
1976 /* Wave Center/LFE Playback Volume */
1977 OP(icode, &ptr, iACC3, GPR(tmp + 0), FXBUS(FXBUS_PCM_LEFT), FXBUS(FXBUS_PCM_RIGHT), C_00000000);
1978 OP(icode, &ptr, iMACINT0, GPR(tmp + 0), C_00000000, GPR(tmp + 0), C_00000002);
1979 VOLUME(icode, &ptr, playback + 4, tmp + 0, gpr);
1980 snd_emu10k1_init_mono_control(controls + i++, "Wave Center Playback Volume", gpr++, 0);
1981 VOLUME(icode, &ptr, playback + 5, tmp + 0, gpr);
1982 snd_emu10k1_init_mono_control(controls + i++, "Wave LFE Playback Volume", gpr++, 0);
1983
1984 /* Wave Capture Volume + Switch */
1985 for (z = 0; z < 2; z++) {
1986 SWITCH(icode, &ptr, tmp + 0, z, gpr + 2 + z);
1987 VOLUME(icode, &ptr, capture + z, tmp + 0, gpr + z);
1988 }
1989 snd_emu10k1_init_stereo_control(controls + i++, "Wave Capture Volume", gpr, 0);
1990 snd_emu10k1_init_stereo_onoff_control(controls + i++, "Wave Capture Switch", gpr + 2, 0);
1991 gpr += 4;
1992
1993 /* Synth Playback Volume */
1994 for (z = 0; z < 2; z++)
1995 VOLUME_ADD(icode, &ptr, playback + z, 2 + z, gpr + z);
1996 snd_emu10k1_init_stereo_control(controls + i++, "Synth Playback Volume", gpr, 100);
1997 gpr += 2;
1998
1999 /* Synth Capture Volume + Switch */
2000 for (z = 0; z < 2; z++) {
2001 SWITCH(icode, &ptr, tmp + 0, 2 + z, gpr + 2 + z);
2002 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
2003 }
2004 snd_emu10k1_init_stereo_control(controls + i++, "Synth Capture Volume", gpr, 0);
2005 snd_emu10k1_init_stereo_onoff_control(controls + i++, "Synth Capture Switch", gpr + 2, 0);
2006 gpr += 4;
2007
2008 /* Surround Digital Playback Volume (renamed later without Digital) */
2009 for (z = 0; z < 2; z++)
2010 VOLUME_ADD(icode, &ptr, playback + 2 + z, 4 + z, gpr + z);
2011 snd_emu10k1_init_stereo_control(controls + i++, "Surround Digital Playback Volume", gpr, 100);
2012 gpr += 2;
2013
2014 /* Surround Capture Volume + Switch */
2015 for (z = 0; z < 2; z++) {
2016 SWITCH(icode, &ptr, tmp + 0, 4 + z, gpr + 2 + z);
2017 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
2018 }
2019 snd_emu10k1_init_stereo_control(controls + i++, "Surround Capture Volume", gpr, 0);
2020 snd_emu10k1_init_stereo_onoff_control(controls + i++, "Surround Capture Switch", gpr + 2, 0);
2021 gpr += 4;
2022
2023 /* Center Playback Volume (renamed later without Digital) */
2024 VOLUME_ADD(icode, &ptr, playback + 4, 6, gpr);
2025 snd_emu10k1_init_mono_control(controls + i++, "Center Digital Playback Volume", gpr++, 100);
2026
2027 /* LFE Playback Volume + Switch (renamed later without Digital) */
2028 VOLUME_ADD(icode, &ptr, playback + 5, 7, gpr);
2029 snd_emu10k1_init_mono_control(controls + i++, "LFE Digital Playback Volume", gpr++, 100);
2030
edf8e456
MM
2031 /* Front Playback Volume */
2032 for (z = 0; z < 2; z++)
2033 VOLUME_ADD(icode, &ptr, playback + z, 10 + z, gpr + z);
2034 snd_emu10k1_init_stereo_control(controls + i++, "Front Playback Volume", gpr, 100);
2035 gpr += 2;
2036
2037 /* Front Capture Volume + Switch */
2038 for (z = 0; z < 2; z++) {
2039 SWITCH(icode, &ptr, tmp + 0, 10 + z, gpr + 2);
2040 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
2041 }
2042 snd_emu10k1_init_stereo_control(controls + i++, "Front Capture Volume", gpr, 0);
2043 snd_emu10k1_init_mono_onoff_control(controls + i++, "Front Capture Switch", gpr + 2, 0);
2044 gpr += 3;
2045
1da177e4
LT
2046 /*
2047 * Process inputs
2048 */
2049
2050 if (emu->fx8010.extin_mask & ((1<<EXTIN_AC97_L)|(1<<EXTIN_AC97_R))) {
2051 /* AC'97 Playback Volume */
2052 VOLUME_ADDIN(icode, &ptr, playback + 0, EXTIN_AC97_L, gpr); gpr++;
2053 VOLUME_ADDIN(icode, &ptr, playback + 1, EXTIN_AC97_R, gpr); gpr++;
2054 snd_emu10k1_init_stereo_control(controls + i++, "AC97 Playback Volume", gpr-2, 0);
2055 /* AC'97 Capture Volume */
2056 VOLUME_ADDIN(icode, &ptr, capture + 0, EXTIN_AC97_L, gpr); gpr++;
2057 VOLUME_ADDIN(icode, &ptr, capture + 1, EXTIN_AC97_R, gpr); gpr++;
2058 snd_emu10k1_init_stereo_control(controls + i++, "AC97 Capture Volume", gpr-2, 100);
2059 }
2060
2061 if (emu->fx8010.extin_mask & ((1<<EXTIN_SPDIF_CD_L)|(1<<EXTIN_SPDIF_CD_R))) {
2062 /* IEC958 TTL Playback Volume */
2063 for (z = 0; z < 2; z++)
2064 VOLUME_ADDIN(icode, &ptr, playback + z, EXTIN_SPDIF_CD_L + z, gpr + z);
10e8d78a 2065 snd_emu10k1_init_stereo_control(controls + i++, SNDRV_CTL_NAME_IEC958("TTL ",PLAYBACK,VOLUME), gpr, 0);
1da177e4
LT
2066 gpr += 2;
2067
2068 /* IEC958 TTL Capture Volume + Switch */
2069 for (z = 0; z < 2; z++) {
2070 SWITCH_IN(icode, &ptr, tmp + 0, EXTIN_SPDIF_CD_L + z, gpr + 2 + z);
2071 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
2072 }
10e8d78a
CL
2073 snd_emu10k1_init_stereo_control(controls + i++, SNDRV_CTL_NAME_IEC958("TTL ",CAPTURE,VOLUME), gpr, 0);
2074 snd_emu10k1_init_stereo_onoff_control(controls + i++, SNDRV_CTL_NAME_IEC958("TTL ",CAPTURE,SWITCH), gpr + 2, 0);
1da177e4
LT
2075 gpr += 4;
2076 }
2077
2078 if (emu->fx8010.extin_mask & ((1<<EXTIN_ZOOM_L)|(1<<EXTIN_ZOOM_R))) {
2079 /* Zoom Video Playback Volume */
2080 for (z = 0; z < 2; z++)
2081 VOLUME_ADDIN(icode, &ptr, playback + z, EXTIN_ZOOM_L + z, gpr + z);
2082 snd_emu10k1_init_stereo_control(controls + i++, "Zoom Video Playback Volume", gpr, 0);
2083 gpr += 2;
2084
2085 /* Zoom Video Capture Volume + Switch */
2086 for (z = 0; z < 2; z++) {
2087 SWITCH_IN(icode, &ptr, tmp + 0, EXTIN_ZOOM_L + z, gpr + 2 + z);
2088 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
2089 }
2090 snd_emu10k1_init_stereo_control(controls + i++, "Zoom Video Capture Volume", gpr, 0);
2091 snd_emu10k1_init_stereo_onoff_control(controls + i++, "Zoom Video Capture Switch", gpr + 2, 0);
2092 gpr += 4;
2093 }
2094
2095 if (emu->fx8010.extin_mask & ((1<<EXTIN_TOSLINK_L)|(1<<EXTIN_TOSLINK_R))) {
2096 /* IEC958 Optical Playback Volume */
2097 for (z = 0; z < 2; z++)
2098 VOLUME_ADDIN(icode, &ptr, playback + z, EXTIN_TOSLINK_L + z, gpr + z);
10e8d78a 2099 snd_emu10k1_init_stereo_control(controls + i++, SNDRV_CTL_NAME_IEC958("LiveDrive ",PLAYBACK,VOLUME), gpr, 0);
1da177e4
LT
2100 gpr += 2;
2101
2102 /* IEC958 Optical Capture Volume */
2103 for (z = 0; z < 2; z++) {
2104 SWITCH_IN(icode, &ptr, tmp + 0, EXTIN_TOSLINK_L + z, gpr + 2 + z);
2105 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
2106 }
10e8d78a
CL
2107 snd_emu10k1_init_stereo_control(controls + i++, SNDRV_CTL_NAME_IEC958("LiveDrive ",CAPTURE,VOLUME), gpr, 0);
2108 snd_emu10k1_init_stereo_onoff_control(controls + i++, SNDRV_CTL_NAME_IEC958("LiveDrive ",CAPTURE,SWITCH), gpr + 2, 0);
1da177e4
LT
2109 gpr += 4;
2110 }
2111
2112 if (emu->fx8010.extin_mask & ((1<<EXTIN_LINE1_L)|(1<<EXTIN_LINE1_R))) {
2113 /* Line LiveDrive Playback Volume */
2114 for (z = 0; z < 2; z++)
2115 VOLUME_ADDIN(icode, &ptr, playback + z, EXTIN_LINE1_L + z, gpr + z);
2116 snd_emu10k1_init_stereo_control(controls + i++, "Line LiveDrive Playback Volume", gpr, 0);
2117 gpr += 2;
2118
2119 /* Line LiveDrive Capture Volume + Switch */
2120 for (z = 0; z < 2; z++) {
2121 SWITCH_IN(icode, &ptr, tmp + 0, EXTIN_LINE1_L + z, gpr + 2 + z);
2122 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
2123 }
2124 snd_emu10k1_init_stereo_control(controls + i++, "Line LiveDrive Capture Volume", gpr, 0);
2125 snd_emu10k1_init_stereo_onoff_control(controls + i++, "Line LiveDrive Capture Switch", gpr + 2, 0);
2126 gpr += 4;
2127 }
2128
2129 if (emu->fx8010.extin_mask & ((1<<EXTIN_COAX_SPDIF_L)|(1<<EXTIN_COAX_SPDIF_R))) {
2130 /* IEC958 Coax Playback Volume */
2131 for (z = 0; z < 2; z++)
2132 VOLUME_ADDIN(icode, &ptr, playback + z, EXTIN_COAX_SPDIF_L + z, gpr + z);
10e8d78a 2133 snd_emu10k1_init_stereo_control(controls + i++, SNDRV_CTL_NAME_IEC958("Coaxial ",PLAYBACK,VOLUME), gpr, 0);
1da177e4
LT
2134 gpr += 2;
2135
2136 /* IEC958 Coax Capture Volume + Switch */
2137 for (z = 0; z < 2; z++) {
2138 SWITCH_IN(icode, &ptr, tmp + 0, EXTIN_COAX_SPDIF_L + z, gpr + 2 + z);
2139 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
2140 }
10e8d78a
CL
2141 snd_emu10k1_init_stereo_control(controls + i++, SNDRV_CTL_NAME_IEC958("Coaxial ",CAPTURE,VOLUME), gpr, 0);
2142 snd_emu10k1_init_stereo_onoff_control(controls + i++, SNDRV_CTL_NAME_IEC958("Coaxial ",CAPTURE,SWITCH), gpr + 2, 0);
1da177e4
LT
2143 gpr += 4;
2144 }
2145
2146 if (emu->fx8010.extin_mask & ((1<<EXTIN_LINE2_L)|(1<<EXTIN_LINE2_R))) {
2147 /* Line LiveDrive Playback Volume */
2148 for (z = 0; z < 2; z++)
2149 VOLUME_ADDIN(icode, &ptr, playback + z, EXTIN_LINE2_L + z, gpr + z);
2150 snd_emu10k1_init_stereo_control(controls + i++, "Line2 LiveDrive Playback Volume", gpr, 0);
2151 controls[i-1].id.index = 1;
2152 gpr += 2;
2153
2154 /* Line LiveDrive Capture Volume */
2155 for (z = 0; z < 2; z++) {
2156 SWITCH_IN(icode, &ptr, tmp + 0, EXTIN_LINE2_L + z, gpr + 2 + z);
2157 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
2158 }
2159 snd_emu10k1_init_stereo_control(controls + i++, "Line2 LiveDrive Capture Volume", gpr, 0);
2160 controls[i-1].id.index = 1;
2161 snd_emu10k1_init_stereo_onoff_control(controls + i++, "Line2 LiveDrive Capture Switch", gpr + 2, 0);
2162 controls[i-1].id.index = 1;
2163 gpr += 4;
2164 }
2165
2166 /*
2167 * Process tone control
2168 */
2169 OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 0), GPR(playback + 0), C_00000000, C_00000000); /* left */
2170 OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 1), GPR(playback + 1), C_00000000, C_00000000); /* right */
2171 OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 2), GPR(playback + 2), C_00000000, C_00000000); /* rear left */
2172 OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 3), GPR(playback + 3), C_00000000, C_00000000); /* rear right */
2173 OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 4), GPR(playback + 4), C_00000000, C_00000000); /* center */
2174 OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 5), GPR(playback + 5), C_00000000, C_00000000); /* LFE */
2175
2176 ctl = &controls[i + 0];
2177 ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
2178 strcpy(ctl->id.name, "Tone Control - Bass");
2179 ctl->vcount = 2;
2180 ctl->count = 10;
2181 ctl->min = 0;
2182 ctl->max = 40;
2183 ctl->value[0] = ctl->value[1] = 20;
bfe9fc8a 2184 ctl->tlv = snd_emu10k1_bass_treble_db_scale;
1da177e4
LT
2185 ctl->translation = EMU10K1_GPR_TRANSLATION_BASS;
2186 ctl = &controls[i + 1];
2187 ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
2188 strcpy(ctl->id.name, "Tone Control - Treble");
2189 ctl->vcount = 2;
2190 ctl->count = 10;
2191 ctl->min = 0;
2192 ctl->max = 40;
2193 ctl->value[0] = ctl->value[1] = 20;
bfe9fc8a 2194 ctl->tlv = snd_emu10k1_bass_treble_db_scale;
1da177e4
LT
2195 ctl->translation = EMU10K1_GPR_TRANSLATION_TREBLE;
2196
2197#define BASS_GPR 0x8c
2198#define TREBLE_GPR 0x96
2199
2200 for (z = 0; z < 5; z++) {
2201 int j;
2202 for (j = 0; j < 2; j++) {
2203 controls[i + 0].gpr[z * 2 + j] = BASS_GPR + z * 2 + j;
2204 controls[i + 1].gpr[z * 2 + j] = TREBLE_GPR + z * 2 + j;
2205 }
2206 }
2207 for (z = 0; z < 3; z++) { /* front/rear/center-lfe */
2208 int j, k, l, d;
2209 for (j = 0; j < 2; j++) { /* left/right */
2210 k = 0xa0 + (z * 8) + (j * 4);
2211 l = 0xd0 + (z * 8) + (j * 4);
2212 d = playback + SND_EMU10K1_PLAYBACK_CHANNELS + z * 2 + j;
2213
2214 OP(icode, &ptr, iMAC0, C_00000000, C_00000000, GPR(d), GPR(BASS_GPR + 0 + j));
2215 OP(icode, &ptr, iMACMV, GPR(k+1), GPR(k), GPR(k+1), GPR(BASS_GPR + 4 + j));
2216 OP(icode, &ptr, iMACMV, GPR(k), GPR(d), GPR(k), GPR(BASS_GPR + 2 + j));
2217 OP(icode, &ptr, iMACMV, GPR(k+3), GPR(k+2), GPR(k+3), GPR(BASS_GPR + 8 + j));
2218 OP(icode, &ptr, iMAC0, GPR(k+2), GPR_ACCU, GPR(k+2), GPR(BASS_GPR + 6 + j));
2219 OP(icode, &ptr, iACC3, GPR(k+2), GPR(k+2), GPR(k+2), C_00000000);
2220
2221 OP(icode, &ptr, iMAC0, C_00000000, C_00000000, GPR(k+2), GPR(TREBLE_GPR + 0 + j));
2222 OP(icode, &ptr, iMACMV, GPR(l+1), GPR(l), GPR(l+1), GPR(TREBLE_GPR + 4 + j));
2223 OP(icode, &ptr, iMACMV, GPR(l), GPR(k+2), GPR(l), GPR(TREBLE_GPR + 2 + j));
2224 OP(icode, &ptr, iMACMV, GPR(l+3), GPR(l+2), GPR(l+3), GPR(TREBLE_GPR + 8 + j));
2225 OP(icode, &ptr, iMAC0, GPR(l+2), GPR_ACCU, GPR(l+2), GPR(TREBLE_GPR + 6 + j));
2226 OP(icode, &ptr, iMACINT0, GPR(l+2), C_00000000, GPR(l+2), C_00000010);
2227
2228 OP(icode, &ptr, iACC3, GPR(d), GPR(l+2), C_00000000, C_00000000);
2229
2230 if (z == 2) /* center */
2231 break;
2232 }
2233 }
2234 i += 2;
2235
2236#undef BASS_GPR
2237#undef TREBLE_GPR
2238
2239 for (z = 0; z < 6; z++) {
2240 SWITCH(icode, &ptr, tmp + 0, playback + SND_EMU10K1_PLAYBACK_CHANNELS + z, gpr + 0);
2241 SWITCH_NEG(icode, &ptr, tmp + 1, gpr + 0);
2242 SWITCH(icode, &ptr, tmp + 1, playback + z, tmp + 1);
2243 OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + z), GPR(tmp + 0), GPR(tmp + 1), C_00000000);
2244 }
2245 snd_emu10k1_init_stereo_onoff_control(controls + i++, "Tone Control - Switch", gpr, 0);
2246 gpr += 2;
2247
2248 /*
2249 * Process outputs
2250 */
2251 if (emu->fx8010.extout_mask & ((1<<EXTOUT_AC97_L)|(1<<EXTOUT_AC97_R))) {
2252 /* AC'97 Playback Volume */
2253
2254 for (z = 0; z < 2; z++)
2255 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_AC97_L + z), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + z), C_00000000, C_00000000);
2256 }
2257
2258 if (emu->fx8010.extout_mask & ((1<<EXTOUT_TOSLINK_L)|(1<<EXTOUT_TOSLINK_R))) {
2259 /* IEC958 Optical Raw Playback Switch */
2260
2261 for (z = 0; z < 2; z++) {
2262 SWITCH(icode, &ptr, tmp + 0, 8 + z, gpr + z);
2263 SWITCH_NEG(icode, &ptr, tmp + 1, gpr + z);
2264 SWITCH(icode, &ptr, tmp + 1, playback + SND_EMU10K1_PLAYBACK_CHANNELS + z, tmp + 1);
2265 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_TOSLINK_L + z), GPR(tmp + 0), GPR(tmp + 1), C_00000000);
2266#ifdef EMU10K1_CAPTURE_DIGITAL_OUT
2267 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_ADC_CAP_L + z), GPR(tmp + 0), GPR(tmp + 1), C_00000000);
2268#endif
2269 }
2270
10e8d78a 2271 snd_emu10k1_init_stereo_onoff_control(controls + i++, SNDRV_CTL_NAME_IEC958("Optical Raw ",PLAYBACK,SWITCH), gpr, 0);
1da177e4
LT
2272 gpr += 2;
2273 }
2274
2275 if (emu->fx8010.extout_mask & ((1<<EXTOUT_HEADPHONE_L)|(1<<EXTOUT_HEADPHONE_R))) {
2276 /* Headphone Playback Volume */
2277
2278 for (z = 0; z < 2; z++) {
2279 SWITCH(icode, &ptr, tmp + 0, playback + SND_EMU10K1_PLAYBACK_CHANNELS + 4 + z, gpr + 2 + z);
2280 SWITCH_NEG(icode, &ptr, tmp + 1, gpr + 2 + z);
2281 SWITCH(icode, &ptr, tmp + 1, playback + SND_EMU10K1_PLAYBACK_CHANNELS + z, tmp + 1);
2282 OP(icode, &ptr, iACC3, GPR(tmp + 0), GPR(tmp + 0), GPR(tmp + 1), C_00000000);
2283 VOLUME_OUT(icode, &ptr, EXTOUT_HEADPHONE_L + z, tmp + 0, gpr + z);
2284 }
2285
2286 snd_emu10k1_init_stereo_control(controls + i++, "Headphone Playback Volume", gpr + 0, 0);
2287 controls[i-1].id.index = 1; /* AC'97 can have also Headphone control */
2288 snd_emu10k1_init_mono_onoff_control(controls + i++, "Headphone Center Playback Switch", gpr + 2, 0);
2289 controls[i-1].id.index = 1;
2290 snd_emu10k1_init_mono_onoff_control(controls + i++, "Headphone LFE Playback Switch", gpr + 3, 0);
2291 controls[i-1].id.index = 1;
2292
2293 gpr += 4;
2294 }
2295
2296 if (emu->fx8010.extout_mask & ((1<<EXTOUT_REAR_L)|(1<<EXTOUT_REAR_R)))
2297 for (z = 0; z < 2; z++)
2298 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_REAR_L + z), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 2 + z), C_00000000, C_00000000);
2299
2300 if (emu->fx8010.extout_mask & ((1<<EXTOUT_AC97_REAR_L)|(1<<EXTOUT_AC97_REAR_R)))
2301 for (z = 0; z < 2; z++)
2302 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_AC97_REAR_L + z), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 2 + z), C_00000000, C_00000000);
2303
2304 if (emu->fx8010.extout_mask & (1<<EXTOUT_AC97_CENTER)) {
2305#ifndef EMU10K1_CENTER_LFE_FROM_FRONT
2306 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_AC97_CENTER), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 4), C_00000000, C_00000000);
2307 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_ACENTER), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 4), C_00000000, C_00000000);
2308#else
2309 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_AC97_CENTER), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 0), C_00000000, C_00000000);
2310 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_ACENTER), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 0), C_00000000, C_00000000);
2311#endif
2312 }
2313
2314 if (emu->fx8010.extout_mask & (1<<EXTOUT_AC97_LFE)) {
2315#ifndef EMU10K1_CENTER_LFE_FROM_FRONT
2316 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_AC97_LFE), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 5), C_00000000, C_00000000);
2317 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_ALFE), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 5), C_00000000, C_00000000);
2318#else
2319 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_AC97_LFE), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 1), C_00000000, C_00000000);
2320 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_ALFE), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 1), C_00000000, C_00000000);
2321#endif
2322 }
2323
2324#ifndef EMU10K1_CAPTURE_DIGITAL_OUT
2325 for (z = 0; z < 2; z++)
2326 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_ADC_CAP_L + z), GPR(capture + z), C_00000000, C_00000000);
2327#endif
2328
2329 if (emu->fx8010.extout_mask & (1<<EXTOUT_MIC_CAP))
2330 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_MIC_CAP), GPR(capture + 2), C_00000000, C_00000000);
2331
2332 /* EFX capture - capture the 16 EXTINS */
2b637da5
LR
2333 if (emu->card_capabilities->sblive51) {
2334 /* On the Live! 5.1, FXBUS2(1) and FXBUS(2) are shared with EXTOUT_ACENTER
2335 * and EXTOUT_ALFE, so we can't connect inputs to them for multitrack recording.
2336 *
2337 * Since only 14 of the 16 EXTINs are used, this is not a big problem.
2338 * We route AC97L and R to FX capture 14 and 15, SPDIF CD in to FX capture
2339 * 0 and 3, then the rest of the EXTINs to the corresponding FX capture
2340 * channel. Multitrack recorders will still see the center/lfe output signal
2341 * on the second and third channels.
2342 */
2343 OP(icode, &ptr, iACC3, FXBUS2(14), C_00000000, C_00000000, EXTIN(0));
2344 OP(icode, &ptr, iACC3, FXBUS2(15), C_00000000, C_00000000, EXTIN(1));
2345 OP(icode, &ptr, iACC3, FXBUS2(0), C_00000000, C_00000000, EXTIN(2));
2346 OP(icode, &ptr, iACC3, FXBUS2(3), C_00000000, C_00000000, EXTIN(3));
2347 for (z = 4; z < 14; z++)
2348 OP(icode, &ptr, iACC3, FXBUS2(z), C_00000000, C_00000000, EXTIN(z));
2349 } else {
2350 for (z = 0; z < 16; z++)
2351 OP(icode, &ptr, iACC3, FXBUS2(z), C_00000000, C_00000000, EXTIN(z));
1da177e4 2352 }
2b637da5 2353
1da177e4
LT
2354
2355 if (gpr > tmp) {
2356 snd_BUG();
2357 err = -EIO;
2358 goto __err;
2359 }
2360 if (i > SND_EMU10K1_GPR_CONTROLS) {
2361 snd_BUG();
2362 err = -EIO;
2363 goto __err;
2364 }
2365
2366 /* clear remaining instruction memory */
2367 while (ptr < 0x200)
2368 OP(icode, &ptr, iACC3, C_00000000, C_00000000, C_00000000, C_00000000);
2369
2370 if ((err = snd_emu10k1_fx8010_tram_setup(emu, ipcm->buffer_size)) < 0)
2371 goto __err;
2372 seg = snd_enter_user();
2373 icode->gpr_add_control_count = i;
eb4698f3 2374 icode->gpr_add_controls = (struct snd_emu10k1_fx8010_control_gpr __user *)controls;
f7ba7fc6 2375 emu->support_tlv = 1; /* support TLV */
1da177e4 2376 err = snd_emu10k1_icode_poke(emu, icode);
f7ba7fc6 2377 emu->support_tlv = 0; /* clear again */
1da177e4
LT
2378 snd_leave_user(seg);
2379 if (err >= 0)
2380 err = snd_emu10k1_ipcm_poke(emu, ipcm);
f1b4863a 2381__err:
1da177e4 2382 kfree(ipcm);
f1b4863a 2383__err_ipcm:
1da177e4 2384 kfree(controls);
f1b4863a
GB
2385__err_ctrls:
2386 kfree((void __force *)icode->gpr_map);
2387__err_gpr:
2388 kfree(icode);
1da177e4
LT
2389 return err;
2390}
2391
e23e7a14 2392int snd_emu10k1_init_efx(struct snd_emu10k1 *emu)
1da177e4 2393{
09668b44
TI
2394 spin_lock_init(&emu->fx8010.irq_lock);
2395 INIT_LIST_HEAD(&emu->fx8010.gpr_ctl);
1da177e4
LT
2396 if (emu->audigy)
2397 return _snd_emu10k1_audigy_init_efx(emu);
2398 else
2399 return _snd_emu10k1_init_efx(emu);
2400}
2401
eb4698f3 2402void snd_emu10k1_free_efx(struct snd_emu10k1 *emu)
1da177e4
LT
2403{
2404 /* stop processor */
2405 if (emu->audigy)
2406 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg = A_DBG_SINGLE_STEP);
2407 else
2408 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg = EMU10K1_DBG_SINGLE_STEP);
2409}
2410
9f4bd5dd 2411#if 0 /* FIXME: who use them? */
eb4698f3 2412int snd_emu10k1_fx8010_tone_control_activate(struct snd_emu10k1 *emu, int output)
1da177e4 2413{
7c22f1aa
TI
2414 if (output < 0 || output >= 6)
2415 return -EINVAL;
1da177e4
LT
2416 snd_emu10k1_ptr_write(emu, emu->gpr_base + 0x94 + output, 0, 1);
2417 return 0;
2418}
2419
eb4698f3 2420int snd_emu10k1_fx8010_tone_control_deactivate(struct snd_emu10k1 *emu, int output)
1da177e4 2421{
7c22f1aa
TI
2422 if (output < 0 || output >= 6)
2423 return -EINVAL;
1da177e4
LT
2424 snd_emu10k1_ptr_write(emu, emu->gpr_base + 0x94 + output, 0, 0);
2425 return 0;
2426}
2427#endif
2428
eb4698f3 2429int snd_emu10k1_fx8010_tram_setup(struct snd_emu10k1 *emu, u32 size)
1da177e4
LT
2430{
2431 u8 size_reg = 0;
2432
2433 /* size is in samples */
2434 if (size != 0) {
2435 size = (size - 1) >> 13;
2436
2437 while (size) {
2438 size >>= 1;
2439 size_reg++;
2440 }
2441 size = 0x2000 << size_reg;
2442 }
2443 if ((emu->fx8010.etram_pages.bytes / 2) == size)
2444 return 0;
2445 spin_lock_irq(&emu->emu_lock);
2446 outl(HCFG_LOCKTANKCACHE_MASK | inl(emu->port + HCFG), emu->port + HCFG);
2447 spin_unlock_irq(&emu->emu_lock);
2448 snd_emu10k1_ptr_write(emu, TCB, 0, 0);
2449 snd_emu10k1_ptr_write(emu, TCBS, 0, 0);
2450 if (emu->fx8010.etram_pages.area != NULL) {
2451 snd_dma_free_pages(&emu->fx8010.etram_pages);
2452 emu->fx8010.etram_pages.area = NULL;
2453 emu->fx8010.etram_pages.bytes = 0;
2454 }
2455
2456 if (size > 0) {
2457 if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(emu->pci),
2458 size * 2, &emu->fx8010.etram_pages) < 0)
2459 return -ENOMEM;
2460 memset(emu->fx8010.etram_pages.area, 0, size * 2);
2461 snd_emu10k1_ptr_write(emu, TCB, 0, emu->fx8010.etram_pages.addr);
2462 snd_emu10k1_ptr_write(emu, TCBS, 0, size_reg);
2463 spin_lock_irq(&emu->emu_lock);
2464 outl(inl(emu->port + HCFG) & ~HCFG_LOCKTANKCACHE_MASK, emu->port + HCFG);
09668b44 2465 spin_unlock_irq(&emu->emu_lock);
1da177e4
LT
2466 }
2467
2468 return 0;
2469}
2470
eb4698f3 2471static int snd_emu10k1_fx8010_open(struct snd_hwdep * hw, struct file *file)
1da177e4
LT
2472{
2473 return 0;
2474}
2475
2476static void copy_string(char *dst, char *src, char *null, int idx)
2477{
2478 if (src == NULL)
2479 sprintf(dst, "%s %02X", null, idx);
2480 else
2481 strcpy(dst, src);
2482}
2483
51882453 2484static void snd_emu10k1_fx8010_info(struct snd_emu10k1 *emu,
eb4698f3 2485 struct snd_emu10k1_fx8010_info *info)
1da177e4
LT
2486{
2487 char **fxbus, **extin, **extout;
2488 unsigned short fxbus_mask, extin_mask, extout_mask;
2489 int res;
2490
1da177e4
LT
2491 info->internal_tram_size = emu->fx8010.itram_size;
2492 info->external_tram_size = emu->fx8010.etram_pages.bytes / 2;
2493 fxbus = fxbuses;
2494 extin = emu->audigy ? audigy_ins : creative_ins;
2495 extout = emu->audigy ? audigy_outs : creative_outs;
2496 fxbus_mask = emu->fx8010.fxbus_mask;
2497 extin_mask = emu->fx8010.extin_mask;
2498 extout_mask = emu->fx8010.extout_mask;
2499 for (res = 0; res < 16; res++, fxbus++, extin++, extout++) {
2500 copy_string(info->fxbus_names[res], fxbus_mask & (1 << res) ? *fxbus : NULL, "FXBUS", res);
2501 copy_string(info->extin_names[res], extin_mask & (1 << res) ? *extin : NULL, "Unused", res);
2502 copy_string(info->extout_names[res], extout_mask & (1 << res) ? *extout : NULL, "Unused", res);
2503 }
2504 for (res = 16; res < 32; res++, extout++)
2505 copy_string(info->extout_names[res], extout_mask & (1 << res) ? *extout : NULL, "Unused", res);
2506 info->gpr_controls = emu->fx8010.gpr_count;
1da177e4
LT
2507}
2508
eb4698f3 2509static int snd_emu10k1_fx8010_ioctl(struct snd_hwdep * hw, struct file *file, unsigned int cmd, unsigned long arg)
1da177e4 2510{
eb4698f3
TI
2511 struct snd_emu10k1 *emu = hw->private_data;
2512 struct snd_emu10k1_fx8010_info *info;
2513 struct snd_emu10k1_fx8010_code *icode;
2514 struct snd_emu10k1_fx8010_pcm_rec *ipcm;
1da177e4
LT
2515 unsigned int addr;
2516 void __user *argp = (void __user *)arg;
2517 int res;
2518
2519 switch (cmd) {
f7ba7fc6
TI
2520 case SNDRV_EMU10K1_IOCTL_PVERSION:
2521 emu->support_tlv = 1;
2522 return put_user(SNDRV_EMU10K1_VERSION, (int __user *)argp);
1da177e4 2523 case SNDRV_EMU10K1_IOCTL_INFO:
eb4698f3 2524 info = kmalloc(sizeof(*info), GFP_KERNEL);
1da177e4
LT
2525 if (!info)
2526 return -ENOMEM;
51882453 2527 snd_emu10k1_fx8010_info(emu, info);
1da177e4
LT
2528 if (copy_to_user(argp, info, sizeof(*info))) {
2529 kfree(info);
2530 return -EFAULT;
2531 }
2532 kfree(info);
2533 return 0;
2534 case SNDRV_EMU10K1_IOCTL_CODE_POKE:
2535 if (!capable(CAP_SYS_ADMIN))
2536 return -EPERM;
336500f0
LZ
2537
2538 icode = memdup_user(argp, sizeof(*icode));
2539 if (IS_ERR(icode))
2540 return PTR_ERR(icode);
1da177e4
LT
2541 res = snd_emu10k1_icode_poke(emu, icode);
2542 kfree(icode);
2543 return res;
2544 case SNDRV_EMU10K1_IOCTL_CODE_PEEK:
336500f0
LZ
2545 icode = memdup_user(argp, sizeof(*icode));
2546 if (IS_ERR(icode))
2547 return PTR_ERR(icode);
1da177e4
LT
2548 res = snd_emu10k1_icode_peek(emu, icode);
2549 if (res == 0 && copy_to_user(argp, icode, sizeof(*icode))) {
2550 kfree(icode);
2551 return -EFAULT;
2552 }
2553 kfree(icode);
2554 return res;
2555 case SNDRV_EMU10K1_IOCTL_PCM_POKE:
336500f0
LZ
2556 ipcm = memdup_user(argp, sizeof(*ipcm));
2557 if (IS_ERR(ipcm))
2558 return PTR_ERR(ipcm);
1da177e4
LT
2559 res = snd_emu10k1_ipcm_poke(emu, ipcm);
2560 kfree(ipcm);
2561 return res;
2562 case SNDRV_EMU10K1_IOCTL_PCM_PEEK:
336500f0
LZ
2563 ipcm = memdup_user(argp, sizeof(*ipcm));
2564 if (IS_ERR(ipcm))
2565 return PTR_ERR(ipcm);
1da177e4
LT
2566 res = snd_emu10k1_ipcm_peek(emu, ipcm);
2567 if (res == 0 && copy_to_user(argp, ipcm, sizeof(*ipcm))) {
2568 kfree(ipcm);
2569 return -EFAULT;
2570 }
2571 kfree(ipcm);
2572 return res;
2573 case SNDRV_EMU10K1_IOCTL_TRAM_SETUP:
2574 if (!capable(CAP_SYS_ADMIN))
2575 return -EPERM;
2576 if (get_user(addr, (unsigned int __user *)argp))
2577 return -EFAULT;
62932df8 2578 mutex_lock(&emu->fx8010.lock);
1da177e4 2579 res = snd_emu10k1_fx8010_tram_setup(emu, addr);
62932df8 2580 mutex_unlock(&emu->fx8010.lock);
1da177e4
LT
2581 return res;
2582 case SNDRV_EMU10K1_IOCTL_STOP:
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_SINGLE_STEP);
2587 else
2588 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg |= EMU10K1_DBG_SINGLE_STEP);
2589 return 0;
2590 case SNDRV_EMU10K1_IOCTL_CONTINUE:
2591 if (!capable(CAP_SYS_ADMIN))
2592 return -EPERM;
2593 if (emu->audigy)
2594 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg = 0);
2595 else
2596 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg = 0);
2597 return 0;
2598 case SNDRV_EMU10K1_IOCTL_ZERO_TRAM_COUNTER:
2599 if (!capable(CAP_SYS_ADMIN))
2600 return -EPERM;
2601 if (emu->audigy)
2602 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg | A_DBG_ZC);
2603 else
2604 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg | EMU10K1_DBG_ZC);
2605 udelay(10);
2606 if (emu->audigy)
2607 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg);
2608 else
2609 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg);
2610 return 0;
2611 case SNDRV_EMU10K1_IOCTL_SINGLE_STEP:
2612 if (!capable(CAP_SYS_ADMIN))
2613 return -EPERM;
2614 if (get_user(addr, (unsigned int __user *)argp))
2615 return -EFAULT;
2616 if (addr > 0x1ff)
2617 return -EINVAL;
2618 if (emu->audigy)
2619 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg |= A_DBG_SINGLE_STEP | addr);
2620 else
2621 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg |= EMU10K1_DBG_SINGLE_STEP | addr);
2622 udelay(10);
2623 if (emu->audigy)
2624 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg |= A_DBG_SINGLE_STEP | A_DBG_STEP_ADDR | addr);
2625 else
2626 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg |= EMU10K1_DBG_SINGLE_STEP | EMU10K1_DBG_STEP | addr);
2627 return 0;
2628 case SNDRV_EMU10K1_IOCTL_DBG_READ:
2629 if (emu->audigy)
2630 addr = snd_emu10k1_ptr_read(emu, A_DBG, 0);
2631 else
2632 addr = snd_emu10k1_ptr_read(emu, DBG, 0);
2633 if (put_user(addr, (unsigned int __user *)argp))
2634 return -EFAULT;
2635 return 0;
2636 }
2637 return -ENOTTY;
2638}
2639
eb4698f3 2640static int snd_emu10k1_fx8010_release(struct snd_hwdep * hw, struct file *file)
1da177e4
LT
2641{
2642 return 0;
2643}
2644
e23e7a14
BP
2645int snd_emu10k1_fx8010_new(struct snd_emu10k1 *emu, int device,
2646 struct snd_hwdep **rhwdep)
1da177e4 2647{
eb4698f3 2648 struct snd_hwdep *hw;
1da177e4
LT
2649 int err;
2650
2651 if (rhwdep)
2652 *rhwdep = NULL;
2653 if ((err = snd_hwdep_new(emu->card, "FX8010", device, &hw)) < 0)
2654 return err;
2655 strcpy(hw->name, "EMU10K1 (FX8010)");
2656 hw->iface = SNDRV_HWDEP_IFACE_EMU10K1;
2657 hw->ops.open = snd_emu10k1_fx8010_open;
2658 hw->ops.ioctl = snd_emu10k1_fx8010_ioctl;
2659 hw->ops.release = snd_emu10k1_fx8010_release;
2660 hw->private_data = emu;
2661 if (rhwdep)
2662 *rhwdep = hw;
2663 return 0;
2664}
09668b44 2665
c7561cd8 2666#ifdef CONFIG_PM_SLEEP
e23e7a14 2667int snd_emu10k1_efx_alloc_pm_buffer(struct snd_emu10k1 *emu)
09668b44
TI
2668{
2669 int len;
2670
2671 len = emu->audigy ? 0x200 : 0x100;
2672 emu->saved_gpr = kmalloc(len * 4, GFP_KERNEL);
2673 if (! emu->saved_gpr)
2674 return -ENOMEM;
2675 len = emu->audigy ? 0x100 : 0xa0;
2676 emu->tram_val_saved = kmalloc(len * 4, GFP_KERNEL);
2677 emu->tram_addr_saved = kmalloc(len * 4, GFP_KERNEL);
2678 if (! emu->tram_val_saved || ! emu->tram_addr_saved)
2679 return -ENOMEM;
2680 len = emu->audigy ? 2 * 1024 : 2 * 512;
2681 emu->saved_icode = vmalloc(len * 4);
2682 if (! emu->saved_icode)
2683 return -ENOMEM;
2684 return 0;
2685}
2686
2687void snd_emu10k1_efx_free_pm_buffer(struct snd_emu10k1 *emu)
2688{
2689 kfree(emu->saved_gpr);
2690 kfree(emu->tram_val_saved);
2691 kfree(emu->tram_addr_saved);
2692 vfree(emu->saved_icode);
2693}
2694
2695/*
2696 * save/restore GPR, TRAM and codes
2697 */
2698void snd_emu10k1_efx_suspend(struct snd_emu10k1 *emu)
2699{
2700 int i, len;
2701
2702 len = emu->audigy ? 0x200 : 0x100;
2703 for (i = 0; i < len; i++)
2704 emu->saved_gpr[i] = snd_emu10k1_ptr_read(emu, emu->gpr_base + i, 0);
2705
2706 len = emu->audigy ? 0x100 : 0xa0;
2707 for (i = 0; i < len; i++) {
2708 emu->tram_val_saved[i] = snd_emu10k1_ptr_read(emu, TANKMEMDATAREGBASE + i, 0);
2709 emu->tram_addr_saved[i] = snd_emu10k1_ptr_read(emu, TANKMEMADDRREGBASE + i, 0);
2710 if (emu->audigy) {
2711 emu->tram_addr_saved[i] >>= 12;
2712 emu->tram_addr_saved[i] |=
2713 snd_emu10k1_ptr_read(emu, A_TANKMEMCTLREGBASE + i, 0) << 20;
2714 }
2715 }
2716
2717 len = emu->audigy ? 2 * 1024 : 2 * 512;
2718 for (i = 0; i < len; i++)
2719 emu->saved_icode[i] = snd_emu10k1_efx_read(emu, i);
2720}
2721
2722void snd_emu10k1_efx_resume(struct snd_emu10k1 *emu)
2723{
2724 int i, len;
2725
2726 /* set up TRAM */
2727 if (emu->fx8010.etram_pages.bytes > 0) {
2728 unsigned size, size_reg = 0;
2729 size = emu->fx8010.etram_pages.bytes / 2;
2730 size = (size - 1) >> 13;
2731 while (size) {
2732 size >>= 1;
2733 size_reg++;
2734 }
2735 outl(HCFG_LOCKTANKCACHE_MASK | inl(emu->port + HCFG), emu->port + HCFG);
2736 snd_emu10k1_ptr_write(emu, TCB, 0, emu->fx8010.etram_pages.addr);
2737 snd_emu10k1_ptr_write(emu, TCBS, 0, size_reg);
2738 outl(inl(emu->port + HCFG) & ~HCFG_LOCKTANKCACHE_MASK, emu->port + HCFG);
2739 }
2740
2741 if (emu->audigy)
2742 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg | A_DBG_SINGLE_STEP);
2743 else
2744 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg | EMU10K1_DBG_SINGLE_STEP);
2745
2746 len = emu->audigy ? 0x200 : 0x100;
2747 for (i = 0; i < len; i++)
2748 snd_emu10k1_ptr_write(emu, emu->gpr_base + i, 0, emu->saved_gpr[i]);
2749
2750 len = emu->audigy ? 0x100 : 0xa0;
2751 for (i = 0; i < len; i++) {
2752 snd_emu10k1_ptr_write(emu, TANKMEMDATAREGBASE + i, 0,
2753 emu->tram_val_saved[i]);
2754 if (! emu->audigy)
2755 snd_emu10k1_ptr_write(emu, TANKMEMADDRREGBASE + i, 0,
2756 emu->tram_addr_saved[i]);
2757 else {
2758 snd_emu10k1_ptr_write(emu, TANKMEMADDRREGBASE + i, 0,
2759 emu->tram_addr_saved[i] << 12);
2760 snd_emu10k1_ptr_write(emu, TANKMEMADDRREGBASE + i, 0,
2761 emu->tram_addr_saved[i] >> 20);
2762 }
2763 }
2764
2765 len = emu->audigy ? 2 * 1024 : 2 * 512;
2766 for (i = 0; i < len; i++)
2767 snd_emu10k1_efx_write(emu, i, emu->saved_icode[i]);
2768
2769 /* start FX processor when the DSP code is updated */
2770 if (emu->audigy)
2771 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg);
2772 else
2773 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg);
2774}
2775#endif
This page took 0.843084 seconds and 5 git commands to generate.