Merge 4.14.73 into android-4.14-p
[GitHub/moto-9609/android_kernel_motorola_exynos9610.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
1da177e4
LT
313/*
314 * controls
315 */
316
eb4698f3 317static int snd_emu10k1_gpr_ctl_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
1da177e4 318{
eb4698f3
TI
319 struct snd_emu10k1_fx8010_ctl *ctl =
320 (struct snd_emu10k1_fx8010_ctl *) kcontrol->private_value;
1da177e4
LT
321
322 if (ctl->min == 0 && ctl->max == 1)
323 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
324 else
325 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
326 uinfo->count = ctl->vcount;
327 uinfo->value.integer.min = ctl->min;
328 uinfo->value.integer.max = ctl->max;
329 return 0;
330}
331
eb4698f3 332static int snd_emu10k1_gpr_ctl_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1da177e4 333{
eb4698f3
TI
334 struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
335 struct snd_emu10k1_fx8010_ctl *ctl =
336 (struct snd_emu10k1_fx8010_ctl *) kcontrol->private_value;
1da177e4
LT
337 unsigned long flags;
338 unsigned int i;
339
340 spin_lock_irqsave(&emu->reg_lock, flags);
341 for (i = 0; i < ctl->vcount; i++)
342 ucontrol->value.integer.value[i] = ctl->value[i];
343 spin_unlock_irqrestore(&emu->reg_lock, flags);
344 return 0;
345}
346
eb4698f3 347static int snd_emu10k1_gpr_ctl_put(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 nval, val;
354 unsigned int i, j;
355 int change = 0;
356
357 spin_lock_irqsave(&emu->reg_lock, flags);
358 for (i = 0; i < ctl->vcount; i++) {
359 nval = ucontrol->value.integer.value[i];
360 if (nval < ctl->min)
361 nval = ctl->min;
362 if (nval > ctl->max)
363 nval = ctl->max;
364 if (nval != ctl->value[i])
365 change = 1;
366 val = ctl->value[i] = nval;
367 switch (ctl->translation) {
368 case EMU10K1_GPR_TRANSLATION_NONE:
369 snd_emu10k1_ptr_write(emu, emu->gpr_base + ctl->gpr[i], 0, val);
370 break;
371 case EMU10K1_GPR_TRANSLATION_TABLE100:
372 snd_emu10k1_ptr_write(emu, emu->gpr_base + ctl->gpr[i], 0, db_table[val]);
373 break;
374 case EMU10K1_GPR_TRANSLATION_BASS:
7c22f1aa
TI
375 if ((ctl->count % 5) != 0 || (ctl->count / 5) != ctl->vcount) {
376 change = -EIO;
377 goto __error;
378 }
1da177e4
LT
379 for (j = 0; j < 5; j++)
380 snd_emu10k1_ptr_write(emu, emu->gpr_base + ctl->gpr[j * ctl->vcount + i], 0, bass_table[val][j]);
381 break;
382 case EMU10K1_GPR_TRANSLATION_TREBLE:
7c22f1aa
TI
383 if ((ctl->count % 5) != 0 || (ctl->count / 5) != ctl->vcount) {
384 change = -EIO;
385 goto __error;
386 }
1da177e4
LT
387 for (j = 0; j < 5; j++)
388 snd_emu10k1_ptr_write(emu, emu->gpr_base + ctl->gpr[j * ctl->vcount + i], 0, treble_table[val][j]);
389 break;
390 case EMU10K1_GPR_TRANSLATION_ONOFF:
391 snd_emu10k1_ptr_write(emu, emu->gpr_base + ctl->gpr[i], 0, onoff_table[val]);
392 break;
393 }
394 }
395 __error:
396 spin_unlock_irqrestore(&emu->reg_lock, flags);
397 return change;
398}
399
400/*
401 * Interrupt handler
402 */
403
eb4698f3 404static void snd_emu10k1_fx8010_interrupt(struct snd_emu10k1 *emu)
1da177e4 405{
eb4698f3 406 struct snd_emu10k1_fx8010_irq *irq, *nirq;
1da177e4
LT
407
408 irq = emu->fx8010.irq_handlers;
409 while (irq) {
410 nirq = irq->next; /* irq ptr can be removed from list */
411 if (snd_emu10k1_ptr_read(emu, emu->gpr_base + irq->gpr_running, 0) & 0xffff0000) {
412 if (irq->handler)
413 irq->handler(emu, irq->private_data);
414 snd_emu10k1_ptr_write(emu, emu->gpr_base + irq->gpr_running, 0, 1);
415 }
416 irq = nirq;
417 }
418}
419
eb4698f3
TI
420int snd_emu10k1_fx8010_register_irq_handler(struct snd_emu10k1 *emu,
421 snd_fx8010_irq_handler_t *handler,
422 unsigned char gpr_running,
423 void *private_data,
424 struct snd_emu10k1_fx8010_irq **r_irq)
1da177e4 425{
eb4698f3 426 struct snd_emu10k1_fx8010_irq *irq;
1da177e4
LT
427 unsigned long flags;
428
1da177e4
LT
429 irq = kmalloc(sizeof(*irq), GFP_ATOMIC);
430 if (irq == NULL)
431 return -ENOMEM;
432 irq->handler = handler;
433 irq->gpr_running = gpr_running;
434 irq->private_data = private_data;
435 irq->next = NULL;
436 spin_lock_irqsave(&emu->fx8010.irq_lock, flags);
437 if (emu->fx8010.irq_handlers == NULL) {
438 emu->fx8010.irq_handlers = irq;
439 emu->dsp_interrupt = snd_emu10k1_fx8010_interrupt;
440 snd_emu10k1_intr_enable(emu, INTE_FXDSPENABLE);
441 } else {
442 irq->next = emu->fx8010.irq_handlers;
443 emu->fx8010.irq_handlers = irq;
444 }
445 spin_unlock_irqrestore(&emu->fx8010.irq_lock, flags);
446 if (r_irq)
447 *r_irq = irq;
448 return 0;
449}
450
eb4698f3
TI
451int snd_emu10k1_fx8010_unregister_irq_handler(struct snd_emu10k1 *emu,
452 struct snd_emu10k1_fx8010_irq *irq)
1da177e4 453{
eb4698f3 454 struct snd_emu10k1_fx8010_irq *tmp;
1da177e4
LT
455 unsigned long flags;
456
1da177e4
LT
457 spin_lock_irqsave(&emu->fx8010.irq_lock, flags);
458 if ((tmp = emu->fx8010.irq_handlers) == irq) {
459 emu->fx8010.irq_handlers = tmp->next;
460 if (emu->fx8010.irq_handlers == NULL) {
461 snd_emu10k1_intr_disable(emu, INTE_FXDSPENABLE);
462 emu->dsp_interrupt = NULL;
463 }
464 } else {
465 while (tmp && tmp->next != irq)
466 tmp = tmp->next;
467 if (tmp)
468 tmp->next = tmp->next->next;
469 }
470 spin_unlock_irqrestore(&emu->fx8010.irq_lock, flags);
471 kfree(irq);
472 return 0;
473}
474
475/*************************************************************************
476 * EMU10K1 effect manager
477 *************************************************************************/
478
eb4698f3
TI
479static void snd_emu10k1_write_op(struct snd_emu10k1_fx8010_code *icode,
480 unsigned int *ptr,
1da177e4
LT
481 u32 op, u32 r, u32 a, u32 x, u32 y)
482{
483 u_int32_t *code;
da3cec35
TI
484 if (snd_BUG_ON(*ptr >= 512))
485 return;
4d23359b 486 code = (u_int32_t __force *)icode->code + (*ptr) * 2;
1da177e4
LT
487 set_bit(*ptr, icode->code_valid);
488 code[0] = ((x & 0x3ff) << 10) | (y & 0x3ff);
489 code[1] = ((op & 0x0f) << 20) | ((r & 0x3ff) << 10) | (a & 0x3ff);
490 (*ptr)++;
491}
492
493#define OP(icode, ptr, op, r, a, x, y) \
494 snd_emu10k1_write_op(icode, ptr, op, r, a, x, y)
495
eb4698f3
TI
496static void snd_emu10k1_audigy_write_op(struct snd_emu10k1_fx8010_code *icode,
497 unsigned int *ptr,
1da177e4
LT
498 u32 op, u32 r, u32 a, u32 x, u32 y)
499{
500 u_int32_t *code;
da3cec35
TI
501 if (snd_BUG_ON(*ptr >= 1024))
502 return;
4d23359b 503 code = (u_int32_t __force *)icode->code + (*ptr) * 2;
1da177e4
LT
504 set_bit(*ptr, icode->code_valid);
505 code[0] = ((x & 0x7ff) << 12) | (y & 0x7ff);
506 code[1] = ((op & 0x0f) << 24) | ((r & 0x7ff) << 12) | (a & 0x7ff);
507 (*ptr)++;
508}
509
510#define A_OP(icode, ptr, op, r, a, x, y) \
511 snd_emu10k1_audigy_write_op(icode, ptr, op, r, a, x, y)
512
eb4698f3 513static void snd_emu10k1_efx_write(struct snd_emu10k1 *emu, unsigned int pc, unsigned int data)
1da177e4
LT
514{
515 pc += emu->audigy ? A_MICROCODEBASE : MICROCODEBASE;
516 snd_emu10k1_ptr_write(emu, pc, 0, data);
517}
518
eb4698f3 519unsigned int snd_emu10k1_efx_read(struct snd_emu10k1 *emu, unsigned int pc)
1da177e4
LT
520{
521 pc += emu->audigy ? A_MICROCODEBASE : MICROCODEBASE;
522 return snd_emu10k1_ptr_read(emu, pc, 0);
523}
524
eb4698f3 525static int snd_emu10k1_gpr_poke(struct snd_emu10k1 *emu,
d42fe63d
TI
526 struct snd_emu10k1_fx8010_code *icode,
527 bool in_kernel)
1da177e4
LT
528{
529 int gpr;
530 u32 val;
531
532 for (gpr = 0; gpr < (emu->audigy ? 0x200 : 0x100); gpr++) {
533 if (!test_bit(gpr, icode->gpr_valid))
534 continue;
d42fe63d
TI
535 if (in_kernel)
536 val = *(u32 *)&icode->gpr_map[gpr];
537 else if (get_user(val, &icode->gpr_map[gpr]))
1da177e4
LT
538 return -EFAULT;
539 snd_emu10k1_ptr_write(emu, emu->gpr_base + gpr, 0, val);
540 }
541 return 0;
542}
543
eb4698f3
TI
544static int snd_emu10k1_gpr_peek(struct snd_emu10k1 *emu,
545 struct snd_emu10k1_fx8010_code *icode)
1da177e4
LT
546{
547 int gpr;
548 u32 val;
549
550 for (gpr = 0; gpr < (emu->audigy ? 0x200 : 0x100); gpr++) {
551 set_bit(gpr, icode->gpr_valid);
552 val = snd_emu10k1_ptr_read(emu, emu->gpr_base + gpr, 0);
553 if (put_user(val, &icode->gpr_map[gpr]))
554 return -EFAULT;
555 }
556 return 0;
557}
558
eb4698f3 559static int snd_emu10k1_tram_poke(struct snd_emu10k1 *emu,
d42fe63d
TI
560 struct snd_emu10k1_fx8010_code *icode,
561 bool in_kernel)
1da177e4
LT
562{
563 int tram;
564 u32 addr, val;
565
566 for (tram = 0; tram < (emu->audigy ? 0x100 : 0xa0); tram++) {
567 if (!test_bit(tram, icode->tram_valid))
568 continue;
d42fe63d
TI
569 if (in_kernel) {
570 val = *(u32 *)&icode->tram_data_map[tram];
571 addr = *(u32 *)&icode->tram_addr_map[tram];
572 } else {
573 if (get_user(val, &icode->tram_data_map[tram]) ||
574 get_user(addr, &icode->tram_addr_map[tram]))
575 return -EFAULT;
576 }
1da177e4
LT
577 snd_emu10k1_ptr_write(emu, TANKMEMDATAREGBASE + tram, 0, val);
578 if (!emu->audigy) {
579 snd_emu10k1_ptr_write(emu, TANKMEMADDRREGBASE + tram, 0, addr);
580 } else {
581 snd_emu10k1_ptr_write(emu, TANKMEMADDRREGBASE + tram, 0, addr << 12);
582 snd_emu10k1_ptr_write(emu, A_TANKMEMCTLREGBASE + tram, 0, addr >> 20);
583 }
584 }
585 return 0;
586}
587
eb4698f3
TI
588static int snd_emu10k1_tram_peek(struct snd_emu10k1 *emu,
589 struct snd_emu10k1_fx8010_code *icode)
1da177e4
LT
590{
591 int tram;
592 u32 val, addr;
593
594 memset(icode->tram_valid, 0, sizeof(icode->tram_valid));
595 for (tram = 0; tram < (emu->audigy ? 0x100 : 0xa0); tram++) {
596 set_bit(tram, icode->tram_valid);
597 val = snd_emu10k1_ptr_read(emu, TANKMEMDATAREGBASE + tram, 0);
598 if (!emu->audigy) {
599 addr = snd_emu10k1_ptr_read(emu, TANKMEMADDRREGBASE + tram, 0);
600 } else {
601 addr = snd_emu10k1_ptr_read(emu, TANKMEMADDRREGBASE + tram, 0) >> 12;
602 addr |= snd_emu10k1_ptr_read(emu, A_TANKMEMCTLREGBASE + tram, 0) << 20;
603 }
604 if (put_user(val, &icode->tram_data_map[tram]) ||
605 put_user(addr, &icode->tram_addr_map[tram]))
606 return -EFAULT;
607 }
608 return 0;
609}
610
eb4698f3 611static int snd_emu10k1_code_poke(struct snd_emu10k1 *emu,
d42fe63d
TI
612 struct snd_emu10k1_fx8010_code *icode,
613 bool in_kernel)
1da177e4
LT
614{
615 u32 pc, lo, hi;
616
617 for (pc = 0; pc < (emu->audigy ? 2*1024 : 2*512); pc += 2) {
618 if (!test_bit(pc / 2, icode->code_valid))
619 continue;
d42fe63d
TI
620 if (in_kernel) {
621 lo = *(u32 *)&icode->code[pc + 0];
622 hi = *(u32 *)&icode->code[pc + 1];
623 } else {
624 if (get_user(lo, &icode->code[pc + 0]) ||
625 get_user(hi, &icode->code[pc + 1]))
626 return -EFAULT;
627 }
1da177e4
LT
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
d42fe63d 668static unsigned int *copy_tlv(const unsigned int __user *_tlv, bool in_kernel)
f7ba7fc6
TI
669{
670 unsigned int data[2];
671 unsigned int *tlv;
672
673 if (!_tlv)
674 return NULL;
d42fe63d
TI
675 if (in_kernel)
676 memcpy(data, (void *)_tlv, sizeof(data));
677 else if (copy_from_user(data, _tlv, sizeof(data)))
f7ba7fc6
TI
678 return NULL;
679 if (data[1] >= MAX_TLV_SIZE)
680 return NULL;
6735e572 681 tlv = kmalloc(data[1] + sizeof(data), GFP_KERNEL);
f7ba7fc6
TI
682 if (!tlv)
683 return NULL;
684 memcpy(tlv, data, sizeof(data));
d42fe63d
TI
685 if (in_kernel) {
686 memcpy(tlv + 2, (void *)(_tlv + 2), data[1]);
687 } else if (copy_from_user(tlv + 2, _tlv + 2, data[1])) {
f7ba7fc6
TI
688 kfree(tlv);
689 return NULL;
690 }
691 return tlv;
692}
693
694static int copy_gctl(struct snd_emu10k1 *emu,
695 struct snd_emu10k1_fx8010_control_gpr *gctl,
696 struct snd_emu10k1_fx8010_control_gpr __user *_gctl,
d42fe63d 697 int idx, bool in_kernel)
f7ba7fc6
TI
698{
699 struct snd_emu10k1_fx8010_control_old_gpr __user *octl;
700
0b36f2bd
TI
701 if (emu->support_tlv) {
702 if (in_kernel)
703 memcpy(gctl, (void *)&_gctl[idx], sizeof(*gctl));
704 else if (copy_from_user(gctl, &_gctl[idx], sizeof(*gctl)))
705 return -EFAULT;
706 return 0;
707 }
708
f7ba7fc6 709 octl = (struct snd_emu10k1_fx8010_control_old_gpr __user *)_gctl;
0b36f2bd
TI
710 if (in_kernel)
711 memcpy(gctl, (void *)&octl[idx], sizeof(*octl));
712 else if (copy_from_user(gctl, &octl[idx], sizeof(*octl)))
f7ba7fc6
TI
713 return -EFAULT;
714 gctl->tlv = NULL;
715 return 0;
716}
717
718static int copy_gctl_to_user(struct snd_emu10k1 *emu,
719 struct snd_emu10k1_fx8010_control_gpr __user *_gctl,
720 struct snd_emu10k1_fx8010_control_gpr *gctl,
721 int idx)
722{
723 struct snd_emu10k1_fx8010_control_old_gpr __user *octl;
724
725 if (emu->support_tlv)
726 return copy_to_user(&_gctl[idx], gctl, sizeof(*gctl));
727
728 octl = (struct snd_emu10k1_fx8010_control_old_gpr __user *)_gctl;
729 return copy_to_user(&octl[idx], gctl, sizeof(*octl));
730}
731
eb4698f3 732static int snd_emu10k1_verify_controls(struct snd_emu10k1 *emu,
d42fe63d
TI
733 struct snd_emu10k1_fx8010_code *icode,
734 bool in_kernel)
1da177e4
LT
735{
736 unsigned int i;
eb4698f3
TI
737 struct snd_ctl_elem_id __user *_id;
738 struct snd_ctl_elem_id id;
eb4698f3 739 struct snd_emu10k1_fx8010_control_gpr *gctl;
1da177e4
LT
740 int err;
741
742 for (i = 0, _id = icode->gpr_del_controls;
743 i < icode->gpr_del_control_count; i++, _id++) {
d42fe63d
TI
744 if (in_kernel)
745 id = *(struct snd_ctl_elem_id *)_id;
746 else if (copy_from_user(&id, _id, sizeof(id)))
1da177e4
LT
747 return -EFAULT;
748 if (snd_emu10k1_look_for_ctl(emu, &id) == NULL)
749 return -ENOENT;
750 }
751 gctl = kmalloc(sizeof(*gctl), GFP_KERNEL);
752 if (! gctl)
753 return -ENOMEM;
754 err = 0;
f7ba7fc6 755 for (i = 0; i < icode->gpr_add_control_count; i++) {
d42fe63d
TI
756 if (copy_gctl(emu, gctl, icode->gpr_add_controls, i,
757 in_kernel)) {
1da177e4
LT
758 err = -EFAULT;
759 goto __error;
760 }
761 if (snd_emu10k1_look_for_ctl(emu, &gctl->id))
762 continue;
763 down_read(&emu->card->controls_rwsem);
764 if (snd_ctl_find_id(emu->card, &gctl->id) != NULL) {
765 up_read(&emu->card->controls_rwsem);
766 err = -EEXIST;
767 goto __error;
768 }
769 up_read(&emu->card->controls_rwsem);
770 if (gctl->id.iface != SNDRV_CTL_ELEM_IFACE_MIXER &&
771 gctl->id.iface != SNDRV_CTL_ELEM_IFACE_PCM) {
772 err = -EINVAL;
773 goto __error;
774 }
775 }
f7ba7fc6 776 for (i = 0; i < icode->gpr_list_control_count; i++) {
1da177e4 777 /* FIXME: we need to check the WRITE access */
d42fe63d
TI
778 if (copy_gctl(emu, gctl, icode->gpr_list_controls, i,
779 in_kernel)) {
1da177e4
LT
780 err = -EFAULT;
781 goto __error;
782 }
783 }
784 __error:
785 kfree(gctl);
786 return err;
787}
788
eb4698f3 789static void snd_emu10k1_ctl_private_free(struct snd_kcontrol *kctl)
1da177e4 790{
eb4698f3 791 struct snd_emu10k1_fx8010_ctl *ctl;
1da177e4 792
eb4698f3 793 ctl = (struct snd_emu10k1_fx8010_ctl *) kctl->private_value;
1da177e4
LT
794 kctl->private_value = 0;
795 list_del(&ctl->list);
796 kfree(ctl);
31604d35 797 kfree(kctl->tlv.p);
1da177e4
LT
798}
799
eb4698f3 800static int snd_emu10k1_add_controls(struct snd_emu10k1 *emu,
d42fe63d
TI
801 struct snd_emu10k1_fx8010_code *icode,
802 bool in_kernel)
1da177e4
LT
803{
804 unsigned int i, j;
eb4698f3
TI
805 struct snd_emu10k1_fx8010_control_gpr *gctl;
806 struct snd_emu10k1_fx8010_ctl *ctl, *nctl;
807 struct snd_kcontrol_new knew;
808 struct snd_kcontrol *kctl;
809 struct snd_ctl_elem_value *val;
1da177e4
LT
810 int err = 0;
811
eb4698f3 812 val = kmalloc(sizeof(*val), GFP_KERNEL);
1da177e4
LT
813 gctl = kmalloc(sizeof(*gctl), GFP_KERNEL);
814 nctl = kmalloc(sizeof(*nctl), GFP_KERNEL);
815 if (!val || !gctl || !nctl) {
816 err = -ENOMEM;
817 goto __error;
818 }
819
f7ba7fc6 820 for (i = 0; i < icode->gpr_add_control_count; i++) {
d42fe63d
TI
821 if (copy_gctl(emu, gctl, icode->gpr_add_controls, i,
822 in_kernel)) {
1da177e4
LT
823 err = -EFAULT;
824 goto __error;
825 }
7c22f1aa
TI
826 if (gctl->id.iface != SNDRV_CTL_ELEM_IFACE_MIXER &&
827 gctl->id.iface != SNDRV_CTL_ELEM_IFACE_PCM) {
828 err = -EINVAL;
829 goto __error;
830 }
831 if (! gctl->id.name[0]) {
832 err = -EINVAL;
833 goto __error;
834 }
1da177e4
LT
835 ctl = snd_emu10k1_look_for_ctl(emu, &gctl->id);
836 memset(&knew, 0, sizeof(knew));
837 knew.iface = gctl->id.iface;
838 knew.name = gctl->id.name;
839 knew.index = gctl->id.index;
840 knew.device = gctl->id.device;
841 knew.subdevice = gctl->id.subdevice;
842 knew.info = snd_emu10k1_gpr_ctl_info;
d42fe63d 843 knew.tlv.p = copy_tlv(gctl->tlv, in_kernel);
f7ba7fc6 844 if (knew.tlv.p)
31508f83
JCD
845 knew.access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
846 SNDRV_CTL_ELEM_ACCESS_TLV_READ;
1da177e4
LT
847 knew.get = snd_emu10k1_gpr_ctl_get;
848 knew.put = snd_emu10k1_gpr_ctl_put;
849 memset(nctl, 0, sizeof(*nctl));
850 nctl->vcount = gctl->vcount;
851 nctl->count = gctl->count;
852 for (j = 0; j < 32; j++) {
853 nctl->gpr[j] = gctl->gpr[j];
854 nctl->value[j] = ~gctl->value[j]; /* inverted, we want to write new value in gpr_ctl_put() */
855 val->value.integer.value[j] = gctl->value[j];
856 }
857 nctl->min = gctl->min;
858 nctl->max = gctl->max;
859 nctl->translation = gctl->translation;
860 if (ctl == NULL) {
eb4698f3 861 ctl = kmalloc(sizeof(*ctl), GFP_KERNEL);
1da177e4
LT
862 if (ctl == NULL) {
863 err = -ENOMEM;
f7ba7fc6 864 kfree(knew.tlv.p);
1da177e4
LT
865 goto __error;
866 }
867 knew.private_value = (unsigned long)ctl;
868 *ctl = *nctl;
869 if ((err = snd_ctl_add(emu->card, kctl = snd_ctl_new1(&knew, emu))) < 0) {
870 kfree(ctl);
f7ba7fc6 871 kfree(knew.tlv.p);
1da177e4
LT
872 goto __error;
873 }
874 kctl->private_free = snd_emu10k1_ctl_private_free;
875 ctl->kcontrol = kctl;
876 list_add_tail(&ctl->list, &emu->fx8010.gpr_ctl);
877 } else {
878 /* overwrite */
879 nctl->list = ctl->list;
880 nctl->kcontrol = ctl->kcontrol;
881 *ctl = *nctl;
882 snd_ctl_notify(emu->card, SNDRV_CTL_EVENT_MASK_VALUE |
883 SNDRV_CTL_EVENT_MASK_INFO, &ctl->kcontrol->id);
884 }
885 snd_emu10k1_gpr_ctl_put(ctl->kcontrol, val);
886 }
887 __error:
888 kfree(nctl);
889 kfree(gctl);
890 kfree(val);
891 return err;
892}
893
eb4698f3 894static int snd_emu10k1_del_controls(struct snd_emu10k1 *emu,
d42fe63d
TI
895 struct snd_emu10k1_fx8010_code *icode,
896 bool in_kernel)
1da177e4
LT
897{
898 unsigned int i;
eb4698f3
TI
899 struct snd_ctl_elem_id id;
900 struct snd_ctl_elem_id __user *_id;
901 struct snd_emu10k1_fx8010_ctl *ctl;
902 struct snd_card *card = emu->card;
1da177e4
LT
903
904 for (i = 0, _id = icode->gpr_del_controls;
905 i < icode->gpr_del_control_count; i++, _id++) {
d42fe63d
TI
906 if (in_kernel)
907 id = *(struct snd_ctl_elem_id *)_id;
908 else if (copy_from_user(&id, _id, sizeof(id)))
7c22f1aa 909 return -EFAULT;
1da177e4
LT
910 down_write(&card->controls_rwsem);
911 ctl = snd_emu10k1_look_for_ctl(emu, &id);
912 if (ctl)
913 snd_ctl_remove(card, ctl->kcontrol);
914 up_write(&card->controls_rwsem);
915 }
916 return 0;
917}
918
eb4698f3
TI
919static int snd_emu10k1_list_controls(struct snd_emu10k1 *emu,
920 struct snd_emu10k1_fx8010_code *icode)
1da177e4
LT
921{
922 unsigned int i = 0, j;
923 unsigned int total = 0;
eb4698f3 924 struct snd_emu10k1_fx8010_control_gpr *gctl;
eb4698f3
TI
925 struct snd_emu10k1_fx8010_ctl *ctl;
926 struct snd_ctl_elem_id *id;
1da177e4
LT
927
928 gctl = kmalloc(sizeof(*gctl), GFP_KERNEL);
929 if (! gctl)
930 return -ENOMEM;
931
c2d7051e 932 list_for_each_entry(ctl, &emu->fx8010.gpr_ctl, list) {
1da177e4 933 total++;
f7ba7fc6
TI
934 if (icode->gpr_list_controls &&
935 i < icode->gpr_list_control_count) {
1da177e4
LT
936 memset(gctl, 0, sizeof(*gctl));
937 id = &ctl->kcontrol->id;
938 gctl->id.iface = id->iface;
939 strlcpy(gctl->id.name, id->name, sizeof(gctl->id.name));
940 gctl->id.index = id->index;
941 gctl->id.device = id->device;
942 gctl->id.subdevice = id->subdevice;
943 gctl->vcount = ctl->vcount;
944 gctl->count = ctl->count;
945 for (j = 0; j < 32; j++) {
946 gctl->gpr[j] = ctl->gpr[j];
947 gctl->value[j] = ctl->value[j];
948 }
949 gctl->min = ctl->min;
950 gctl->max = ctl->max;
951 gctl->translation = ctl->translation;
f7ba7fc6
TI
952 if (copy_gctl_to_user(emu, icode->gpr_list_controls,
953 gctl, i)) {
1da177e4
LT
954 kfree(gctl);
955 return -EFAULT;
956 }
1da177e4
LT
957 i++;
958 }
959 }
960 icode->gpr_list_control_total = total;
961 kfree(gctl);
962 return 0;
963}
964
eb4698f3 965static int snd_emu10k1_icode_poke(struct snd_emu10k1 *emu,
d42fe63d
TI
966 struct snd_emu10k1_fx8010_code *icode,
967 bool in_kernel)
1da177e4
LT
968{
969 int err = 0;
970
62932df8 971 mutex_lock(&emu->fx8010.lock);
d42fe63d
TI
972 err = snd_emu10k1_verify_controls(emu, icode, in_kernel);
973 if (err < 0)
1da177e4
LT
974 goto __error;
975 strlcpy(emu->fx8010.name, icode->name, sizeof(emu->fx8010.name));
976 /* stop FX processor - this may be dangerous, but it's better to miss
977 some samples than generate wrong ones - [jk] */
978 if (emu->audigy)
979 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg | A_DBG_SINGLE_STEP);
980 else
981 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg | EMU10K1_DBG_SINGLE_STEP);
982 /* ok, do the main job */
d42fe63d
TI
983 err = snd_emu10k1_del_controls(emu, icode, in_kernel);
984 if (err < 0)
985 goto __error;
986 err = snd_emu10k1_gpr_poke(emu, icode, in_kernel);
987 if (err < 0)
988 goto __error;
989 err = snd_emu10k1_tram_poke(emu, icode, in_kernel);
990 if (err < 0)
991 goto __error;
992 err = snd_emu10k1_code_poke(emu, icode, in_kernel);
993 if (err < 0)
994 goto __error;
995 err = snd_emu10k1_add_controls(emu, icode, in_kernel);
996 if (err < 0)
1da177e4
LT
997 goto __error;
998 /* start FX processor when the DSP code is updated */
999 if (emu->audigy)
1000 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg);
1001 else
1002 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg);
1003 __error:
62932df8 1004 mutex_unlock(&emu->fx8010.lock);
1da177e4
LT
1005 return err;
1006}
1007
eb4698f3
TI
1008static int snd_emu10k1_icode_peek(struct snd_emu10k1 *emu,
1009 struct snd_emu10k1_fx8010_code *icode)
1da177e4
LT
1010{
1011 int err;
1012
62932df8 1013 mutex_lock(&emu->fx8010.lock);
1da177e4
LT
1014 strlcpy(icode->name, emu->fx8010.name, sizeof(icode->name));
1015 /* ok, do the main job */
1016 err = snd_emu10k1_gpr_peek(emu, icode);
1017 if (err >= 0)
1018 err = snd_emu10k1_tram_peek(emu, icode);
1019 if (err >= 0)
1020 err = snd_emu10k1_code_peek(emu, icode);
1021 if (err >= 0)
1022 err = snd_emu10k1_list_controls(emu, icode);
62932df8 1023 mutex_unlock(&emu->fx8010.lock);
1da177e4
LT
1024 return err;
1025}
1026
eb4698f3
TI
1027static int snd_emu10k1_ipcm_poke(struct snd_emu10k1 *emu,
1028 struct snd_emu10k1_fx8010_pcm_rec *ipcm)
1da177e4
LT
1029{
1030 unsigned int i;
1031 int err = 0;
eb4698f3 1032 struct snd_emu10k1_fx8010_pcm *pcm;
1da177e4
LT
1033
1034 if (ipcm->substream >= EMU10K1_FX8010_PCM_COUNT)
1035 return -EINVAL;
1036 if (ipcm->channels > 32)
1037 return -EINVAL;
1038 pcm = &emu->fx8010.pcm[ipcm->substream];
62932df8 1039 mutex_lock(&emu->fx8010.lock);
1da177e4
LT
1040 spin_lock_irq(&emu->reg_lock);
1041 if (pcm->opened) {
1042 err = -EBUSY;
1043 goto __error;
1044 }
1045 if (ipcm->channels == 0) { /* remove */
1046 pcm->valid = 0;
1047 } else {
1048 /* FIXME: we need to add universal code to the PCM transfer routine */
1049 if (ipcm->channels != 2) {
1050 err = -EINVAL;
1051 goto __error;
1052 }
1053 pcm->valid = 1;
1054 pcm->opened = 0;
1055 pcm->channels = ipcm->channels;
1056 pcm->tram_start = ipcm->tram_start;
1057 pcm->buffer_size = ipcm->buffer_size;
1058 pcm->gpr_size = ipcm->gpr_size;
1059 pcm->gpr_count = ipcm->gpr_count;
1060 pcm->gpr_tmpcount = ipcm->gpr_tmpcount;
1061 pcm->gpr_ptr = ipcm->gpr_ptr;
1062 pcm->gpr_trigger = ipcm->gpr_trigger;
1063 pcm->gpr_running = ipcm->gpr_running;
1064 for (i = 0; i < pcm->channels; i++)
1065 pcm->etram[i] = ipcm->etram[i];
1066 }
1067 __error:
1068 spin_unlock_irq(&emu->reg_lock);
62932df8 1069 mutex_unlock(&emu->fx8010.lock);
1da177e4
LT
1070 return err;
1071}
1072
eb4698f3
TI
1073static int snd_emu10k1_ipcm_peek(struct snd_emu10k1 *emu,
1074 struct snd_emu10k1_fx8010_pcm_rec *ipcm)
1da177e4
LT
1075{
1076 unsigned int i;
1077 int err = 0;
eb4698f3 1078 struct snd_emu10k1_fx8010_pcm *pcm;
1da177e4
LT
1079
1080 if (ipcm->substream >= EMU10K1_FX8010_PCM_COUNT)
1081 return -EINVAL;
1082 pcm = &emu->fx8010.pcm[ipcm->substream];
62932df8 1083 mutex_lock(&emu->fx8010.lock);
1da177e4
LT
1084 spin_lock_irq(&emu->reg_lock);
1085 ipcm->channels = pcm->channels;
1086 ipcm->tram_start = pcm->tram_start;
1087 ipcm->buffer_size = pcm->buffer_size;
1088 ipcm->gpr_size = pcm->gpr_size;
1089 ipcm->gpr_ptr = pcm->gpr_ptr;
1090 ipcm->gpr_count = pcm->gpr_count;
1091 ipcm->gpr_tmpcount = pcm->gpr_tmpcount;
1092 ipcm->gpr_trigger = pcm->gpr_trigger;
1093 ipcm->gpr_running = pcm->gpr_running;
1094 for (i = 0; i < pcm->channels; i++)
1095 ipcm->etram[i] = pcm->etram[i];
1096 ipcm->res1 = ipcm->res2 = 0;
1097 ipcm->pad = 0;
1098 spin_unlock_irq(&emu->reg_lock);
62932df8 1099 mutex_unlock(&emu->fx8010.lock);
1da177e4
LT
1100 return err;
1101}
1102
edf8e456
MM
1103#define SND_EMU10K1_GPR_CONTROLS 44
1104#define SND_EMU10K1_INPUTS 12
1da177e4
LT
1105#define SND_EMU10K1_PLAYBACK_CHANNELS 8
1106#define SND_EMU10K1_CAPTURE_CHANNELS 4
1107
e23e7a14 1108static void
eb4698f3
TI
1109snd_emu10k1_init_mono_control(struct snd_emu10k1_fx8010_control_gpr *ctl,
1110 const char *name, int gpr, int defval)
1da177e4
LT
1111{
1112 ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1113 strcpy(ctl->id.name, name);
1114 ctl->vcount = ctl->count = 1;
1115 ctl->gpr[0] = gpr + 0; ctl->value[0] = defval;
4daf7a0c
CL
1116 if (high_res_gpr_volume) {
1117 ctl->min = 0;
1118 ctl->max = 0x7fffffff;
1119 ctl->tlv = snd_emu10k1_db_linear;
1120 ctl->translation = EMU10K1_GPR_TRANSLATION_NONE;
1121 } else {
1122 ctl->min = 0;
1123 ctl->max = 100;
1124 ctl->tlv = snd_emu10k1_db_scale1;
1125 ctl->translation = EMU10K1_GPR_TRANSLATION_TABLE100;
1126 }
1da177e4
LT
1127}
1128
e23e7a14 1129static void
eb4698f3
TI
1130snd_emu10k1_init_stereo_control(struct snd_emu10k1_fx8010_control_gpr *ctl,
1131 const char *name, int gpr, int defval)
1da177e4
LT
1132{
1133 ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1134 strcpy(ctl->id.name, name);
1135 ctl->vcount = ctl->count = 2;
1136 ctl->gpr[0] = gpr + 0; ctl->value[0] = defval;
1137 ctl->gpr[1] = gpr + 1; ctl->value[1] = defval;
4daf7a0c
CL
1138 if (high_res_gpr_volume) {
1139 ctl->min = 0;
1140 ctl->max = 0x7fffffff;
1141 ctl->tlv = snd_emu10k1_db_linear;
1142 ctl->translation = EMU10K1_GPR_TRANSLATION_NONE;
1143 } else {
1144 ctl->min = 0;
1145 ctl->max = 100;
1146 ctl->tlv = snd_emu10k1_db_scale1;
1147 ctl->translation = EMU10K1_GPR_TRANSLATION_TABLE100;
1148 }
1da177e4
LT
1149}
1150
e23e7a14 1151static void
eb4698f3
TI
1152snd_emu10k1_init_mono_onoff_control(struct snd_emu10k1_fx8010_control_gpr *ctl,
1153 const char *name, int gpr, int defval)
1da177e4
LT
1154{
1155 ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1156 strcpy(ctl->id.name, name);
1157 ctl->vcount = ctl->count = 1;
1158 ctl->gpr[0] = gpr + 0; ctl->value[0] = defval;
1159 ctl->min = 0;
1160 ctl->max = 1;
1161 ctl->translation = EMU10K1_GPR_TRANSLATION_ONOFF;
1162}
1163
e23e7a14 1164static void
eb4698f3
TI
1165snd_emu10k1_init_stereo_onoff_control(struct snd_emu10k1_fx8010_control_gpr *ctl,
1166 const char *name, int gpr, int defval)
1da177e4
LT
1167{
1168 ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1169 strcpy(ctl->id.name, name);
1170 ctl->vcount = ctl->count = 2;
1171 ctl->gpr[0] = gpr + 0; ctl->value[0] = defval;
1172 ctl->gpr[1] = gpr + 1; ctl->value[1] = defval;
1173 ctl->min = 0;
1174 ctl->max = 1;
1175 ctl->translation = EMU10K1_GPR_TRANSLATION_ONOFF;
1176}
1177
13d45709
PH
1178/*
1179 * Used for emu1010 - conversion from 32-bit capture inputs from HANA
1180 * to 2 x 16-bit registers in audigy - their values are read via DMA.
1181 * Conversion is performed by Audigy DSP instructions of FX8010.
1182 */
9f4bd5dd
JCD
1183static int snd_emu10k1_audigy_dsp_convert_32_to_2x16(
1184 struct snd_emu10k1_fx8010_code *icode,
1185 u32 *ptr, int tmp, int bit_shifter16,
1186 int reg_in, int reg_out)
1187{
1188 A_OP(icode, ptr, iACC3, A_GPR(tmp + 1), reg_in, A_C_00000000, A_C_00000000);
1189 A_OP(icode, ptr, iANDXOR, A_GPR(tmp), A_GPR(tmp + 1), A_GPR(bit_shifter16 - 1), A_C_00000000);
1190 A_OP(icode, ptr, iTSTNEG, A_GPR(tmp + 2), A_GPR(tmp), A_C_80000000, A_GPR(bit_shifter16 - 2));
1191 A_OP(icode, ptr, iANDXOR, A_GPR(tmp + 2), A_GPR(tmp + 2), A_C_80000000, A_C_00000000);
1192 A_OP(icode, ptr, iANDXOR, A_GPR(tmp), A_GPR(tmp), A_GPR(bit_shifter16 - 3), A_C_00000000);
1193 A_OP(icode, ptr, iMACINT0, A_GPR(tmp), A_C_00000000, A_GPR(tmp), A_C_00010000);
1194 A_OP(icode, ptr, iANDXOR, reg_out, A_GPR(tmp), A_C_ffffffff, A_GPR(tmp + 2));
1195 A_OP(icode, ptr, iACC3, reg_out + 1, A_GPR(tmp + 1), A_C_00000000, A_C_00000000);
1196 return 1;
1197}
1da177e4
LT
1198
1199/*
1200 * initial DSP configuration for Audigy
1201 */
1202
e23e7a14 1203static int _snd_emu10k1_audigy_init_efx(struct snd_emu10k1 *emu)
1da177e4
LT
1204{
1205 int err, i, z, gpr, nctl;
9f4bd5dd 1206 int bit_shifter16;
1da177e4
LT
1207 const int playback = 10;
1208 const int capture = playback + (SND_EMU10K1_PLAYBACK_CHANNELS * 2); /* we reserve 10 voices */
1209 const int stereo_mix = capture + 2;
1210 const int tmp = 0x88;
1211 u32 ptr;
eb4698f3
TI
1212 struct snd_emu10k1_fx8010_code *icode = NULL;
1213 struct snd_emu10k1_fx8010_control_gpr *controls = NULL, *ctl;
1da177e4 1214 u32 *gpr_map;
1da177e4 1215
f1b4863a
GB
1216 err = -ENOMEM;
1217 icode = kzalloc(sizeof(*icode), GFP_KERNEL);
1218 if (!icode)
1219 return err;
1220
1221 icode->gpr_map = (u_int32_t __user *) kcalloc(512 + 256 + 256 + 2 * 1024,
1222 sizeof(u_int32_t), GFP_KERNEL);
1223 if (!icode->gpr_map)
1224 goto __err_gpr;
1225 controls = kcalloc(SND_EMU10K1_GPR_CONTROLS,
1226 sizeof(*controls), GFP_KERNEL);
1227 if (!controls)
1228 goto __err_ctrls;
1229
4d23359b 1230 gpr_map = (u32 __force *)icode->gpr_map;
1da177e4
LT
1231
1232 icode->tram_data_map = icode->gpr_map + 512;
1233 icode->tram_addr_map = icode->tram_data_map + 256;
1234 icode->code = icode->tram_addr_map + 256;
1235
1236 /* clear free GPRs */
1237 for (i = 0; i < 512; i++)
1238 set_bit(i, icode->gpr_valid);
1239
1240 /* clear TRAM data & address lines */
1241 for (i = 0; i < 256; i++)
1242 set_bit(i, icode->tram_valid);
1243
1244 strcpy(icode->name, "Audigy DSP code for ALSA");
1245 ptr = 0;
1246 nctl = 0;
1247 gpr = stereo_mix + 10;
9f4bd5dd
JCD
1248 gpr_map[gpr++] = 0x00007fff;
1249 gpr_map[gpr++] = 0x00008000;
1250 gpr_map[gpr++] = 0x0000ffff;
1251 bit_shifter16 = gpr;
1da177e4
LT
1252
1253 /* stop FX processor */
1254 snd_emu10k1_ptr_write(emu, A_DBG, 0, (emu->fx8010.dbg = 0) | A_DBG_SINGLE_STEP);
1255
19b99fba 1256#if 1
13d45709
PH
1257 /* PCM front Playback Volume (independent from stereo mix)
1258 * playback = 0 + ( gpr * FXBUS_PCM_LEFT_FRONT >> 31)
1259 * where gpr contains attenuation from corresponding mixer control
1260 * (snd_emu10k1_init_stereo_control)
1261 */
1da177e4
LT
1262 A_OP(icode, &ptr, iMAC0, A_GPR(playback), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LEFT_FRONT));
1263 A_OP(icode, &ptr, iMAC0, A_GPR(playback+1), A_C_00000000, A_GPR(gpr+1), A_FXBUS(FXBUS_PCM_RIGHT_FRONT));
1264 snd_emu10k1_init_stereo_control(&controls[nctl++], "PCM Front Playback Volume", gpr, 100);
1265 gpr += 2;
90fd5ce5 1266
1da177e4
LT
1267 /* PCM Surround Playback (independent from stereo mix) */
1268 A_OP(icode, &ptr, iMAC0, A_GPR(playback+2), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LEFT_REAR));
1269 A_OP(icode, &ptr, iMAC0, A_GPR(playback+3), A_C_00000000, A_GPR(gpr+1), A_FXBUS(FXBUS_PCM_RIGHT_REAR));
1270 snd_emu10k1_init_stereo_control(&controls[nctl++], "PCM Surround Playback Volume", gpr, 100);
1271 gpr += 2;
1272
1273 /* PCM Side Playback (independent from stereo mix) */
2b637da5 1274 if (emu->card_capabilities->spk71) {
1da177e4
LT
1275 A_OP(icode, &ptr, iMAC0, A_GPR(playback+6), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LEFT_SIDE));
1276 A_OP(icode, &ptr, iMAC0, A_GPR(playback+7), A_C_00000000, A_GPR(gpr+1), A_FXBUS(FXBUS_PCM_RIGHT_SIDE));
1277 snd_emu10k1_init_stereo_control(&controls[nctl++], "PCM Side Playback Volume", gpr, 100);
1278 gpr += 2;
1279 }
1280
1281 /* PCM Center Playback (independent from stereo mix) */
1282 A_OP(icode, &ptr, iMAC0, A_GPR(playback+4), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_CENTER));
1283 snd_emu10k1_init_mono_control(&controls[nctl++], "PCM Center Playback Volume", gpr, 100);
1284 gpr++;
1285
1286 /* PCM LFE Playback (independent from stereo mix) */
1287 A_OP(icode, &ptr, iMAC0, A_GPR(playback+5), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LFE));
1288 snd_emu10k1_init_mono_control(&controls[nctl++], "PCM LFE Playback Volume", gpr, 100);
1289 gpr++;
1290
1291 /*
1292 * Stereo Mix
1293 */
1294 /* Wave (PCM) Playback Volume (will be renamed later) */
1295 A_OP(icode, &ptr, iMAC0, A_GPR(stereo_mix), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LEFT));
1296 A_OP(icode, &ptr, iMAC0, A_GPR(stereo_mix+1), A_C_00000000, A_GPR(gpr+1), A_FXBUS(FXBUS_PCM_RIGHT));
1297 snd_emu10k1_init_stereo_control(&controls[nctl++], "Wave Playback Volume", gpr, 100);
1298 gpr += 2;
1299
1300 /* Synth Playback */
1301 A_OP(icode, &ptr, iMAC0, A_GPR(stereo_mix+0), A_GPR(stereo_mix+0), A_GPR(gpr), A_FXBUS(FXBUS_MIDI_LEFT));
1302 A_OP(icode, &ptr, iMAC0, A_GPR(stereo_mix+1), A_GPR(stereo_mix+1), A_GPR(gpr+1), A_FXBUS(FXBUS_MIDI_RIGHT));
1303 snd_emu10k1_init_stereo_control(&controls[nctl++], "Synth Playback Volume", gpr, 100);
1304 gpr += 2;
1305
1306 /* Wave (PCM) Capture */
1307 A_OP(icode, &ptr, iMAC0, A_GPR(capture+0), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LEFT));
1308 A_OP(icode, &ptr, iMAC0, A_GPR(capture+1), A_C_00000000, A_GPR(gpr+1), A_FXBUS(FXBUS_PCM_RIGHT));
1309 snd_emu10k1_init_stereo_control(&controls[nctl++], "PCM Capture Volume", gpr, 0);
1310 gpr += 2;
1311
1312 /* Synth Capture */
1313 A_OP(icode, &ptr, iMAC0, A_GPR(capture+0), A_GPR(capture+0), A_GPR(gpr), A_FXBUS(FXBUS_MIDI_LEFT));
1314 A_OP(icode, &ptr, iMAC0, A_GPR(capture+1), A_GPR(capture+1), A_GPR(gpr+1), A_FXBUS(FXBUS_MIDI_RIGHT));
1315 snd_emu10k1_init_stereo_control(&controls[nctl++], "Synth Capture Volume", gpr, 0);
1316 gpr += 2;
9f4bd5dd 1317
1da177e4
LT
1318 /*
1319 * inputs
1320 */
1321#define A_ADD_VOLUME_IN(var,vol,input) \
1322A_OP(icode, &ptr, iMAC0, A_GPR(var), A_GPR(var), A_GPR(vol), A_EXTIN(input))
1323
9f4bd5dd 1324 /* emu1212 DSP 0 and DSP 1 Capture */
190d2c46 1325 if (emu->card_capabilities->emu_model) {
90fd5ce5
JCD
1326 if (emu->card_capabilities->ca0108_chip) {
1327 /* Note:JCD:No longer bit shift lower 16bits to upper 16bits of 32bit value. */
1328 A_OP(icode, &ptr, iMACINT0, A_GPR(tmp), A_C_00000000, A3_EMU32IN(0x0), A_C_00000001);
1329 A_OP(icode, &ptr, iMAC0, A_GPR(capture+0), A_GPR(capture+0), A_GPR(gpr), A_GPR(tmp));
1330 A_OP(icode, &ptr, iMACINT0, A_GPR(tmp), A_C_00000000, A3_EMU32IN(0x1), A_C_00000001);
1331 A_OP(icode, &ptr, iMAC0, A_GPR(capture+1), A_GPR(capture+1), A_GPR(gpr), A_GPR(tmp));
1332 } else {
1333 A_OP(icode, &ptr, iMAC0, A_GPR(capture+0), A_GPR(capture+0), A_GPR(gpr), A_P16VIN(0x0));
1334 A_OP(icode, &ptr, iMAC0, A_GPR(capture+1), A_GPR(capture+1), A_GPR(gpr+1), A_P16VIN(0x1));
1335 }
9f4bd5dd
JCD
1336 snd_emu10k1_init_stereo_control(&controls[nctl++], "EMU Capture Volume", gpr, 0);
1337 gpr += 2;
1338 }
1da177e4
LT
1339 /* AC'97 Playback Volume - used only for mic (renamed later) */
1340 A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_AC97_L);
1341 A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_AC97_R);
1342 snd_emu10k1_init_stereo_control(&controls[nctl++], "AMic Playback Volume", gpr, 0);
1343 gpr += 2;
1344 /* AC'97 Capture Volume - used only for mic */
1345 A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_AC97_L);
1346 A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_AC97_R);
1347 snd_emu10k1_init_stereo_control(&controls[nctl++], "Mic Capture Volume", gpr, 0);
1348 gpr += 2;
1349
1350 /* mic capture buffer */
1351 A_OP(icode, &ptr, iINTERP, A_EXTOUT(A_EXTOUT_MIC_CAP), A_EXTIN(A_EXTIN_AC97_L), 0xcd, A_EXTIN(A_EXTIN_AC97_R));
1352
1353 /* Audigy CD Playback Volume */
1354 A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_SPDIF_CD_L);
1355 A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_SPDIF_CD_R);
1356 snd_emu10k1_init_stereo_control(&controls[nctl++],
2b637da5 1357 emu->card_capabilities->ac97_chip ? "Audigy CD Playback Volume" : "CD Playback Volume",
1da177e4
LT
1358 gpr, 0);
1359 gpr += 2;
1360 /* Audigy CD Capture Volume */
1361 A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_SPDIF_CD_L);
1362 A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_SPDIF_CD_R);
1363 snd_emu10k1_init_stereo_control(&controls[nctl++],
2b637da5 1364 emu->card_capabilities->ac97_chip ? "Audigy CD Capture Volume" : "CD Capture Volume",
1da177e4
LT
1365 gpr, 0);
1366 gpr += 2;
1367
1368 /* Optical SPDIF Playback Volume */
1369 A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_OPT_SPDIF_L);
1370 A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_OPT_SPDIF_R);
10e8d78a 1371 snd_emu10k1_init_stereo_control(&controls[nctl++], SNDRV_CTL_NAME_IEC958("Optical ",PLAYBACK,VOLUME), gpr, 0);
1da177e4
LT
1372 gpr += 2;
1373 /* Optical SPDIF Capture Volume */
1374 A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_OPT_SPDIF_L);
1375 A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_OPT_SPDIF_R);
10e8d78a 1376 snd_emu10k1_init_stereo_control(&controls[nctl++], SNDRV_CTL_NAME_IEC958("Optical ",CAPTURE,VOLUME), gpr, 0);
1da177e4
LT
1377 gpr += 2;
1378
1379 /* Line2 Playback Volume */
1380 A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_LINE2_L);
1381 A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_LINE2_R);
1382 snd_emu10k1_init_stereo_control(&controls[nctl++],
2b637da5 1383 emu->card_capabilities->ac97_chip ? "Line2 Playback Volume" : "Line Playback Volume",
1da177e4
LT
1384 gpr, 0);
1385 gpr += 2;
1386 /* Line2 Capture Volume */
1387 A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_LINE2_L);
1388 A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_LINE2_R);
1389 snd_emu10k1_init_stereo_control(&controls[nctl++],
2b637da5 1390 emu->card_capabilities->ac97_chip ? "Line2 Capture Volume" : "Line Capture Volume",
1da177e4
LT
1391 gpr, 0);
1392 gpr += 2;
1393
1394 /* Philips ADC Playback Volume */
1395 A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_ADC_L);
1396 A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_ADC_R);
1397 snd_emu10k1_init_stereo_control(&controls[nctl++], "Analog Mix Playback Volume", gpr, 0);
1398 gpr += 2;
1399 /* Philips ADC Capture Volume */
1400 A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_ADC_L);
1401 A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_ADC_R);
1402 snd_emu10k1_init_stereo_control(&controls[nctl++], "Analog Mix Capture Volume", gpr, 0);
1403 gpr += 2;
1404
1405 /* Aux2 Playback Volume */
1406 A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_AUX2_L);
1407 A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_AUX2_R);
1408 snd_emu10k1_init_stereo_control(&controls[nctl++],
2b637da5 1409 emu->card_capabilities->ac97_chip ? "Aux2 Playback Volume" : "Aux Playback Volume",
1da177e4
LT
1410 gpr, 0);
1411 gpr += 2;
1412 /* Aux2 Capture Volume */
1413 A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_AUX2_L);
1414 A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_AUX2_R);
1415 snd_emu10k1_init_stereo_control(&controls[nctl++],
2b637da5 1416 emu->card_capabilities->ac97_chip ? "Aux2 Capture Volume" : "Aux Capture Volume",
1da177e4
LT
1417 gpr, 0);
1418 gpr += 2;
1419
1420 /* Stereo Mix Front Playback Volume */
1421 A_OP(icode, &ptr, iMAC0, A_GPR(playback), A_GPR(playback), A_GPR(gpr), A_GPR(stereo_mix));
1422 A_OP(icode, &ptr, iMAC0, A_GPR(playback+1), A_GPR(playback+1), A_GPR(gpr+1), A_GPR(stereo_mix+1));
1423 snd_emu10k1_init_stereo_control(&controls[nctl++], "Front Playback Volume", gpr, 100);
1424 gpr += 2;
1425
1426 /* Stereo Mix Surround Playback */
1427 A_OP(icode, &ptr, iMAC0, A_GPR(playback+2), A_GPR(playback+2), A_GPR(gpr), A_GPR(stereo_mix));
1428 A_OP(icode, &ptr, iMAC0, A_GPR(playback+3), A_GPR(playback+3), A_GPR(gpr+1), A_GPR(stereo_mix+1));
1429 snd_emu10k1_init_stereo_control(&controls[nctl++], "Surround Playback Volume", gpr, 0);
1430 gpr += 2;
1431
1432 /* Stereo Mix Center Playback */
1433 /* Center = sub = Left/2 + Right/2 */
1434 A_OP(icode, &ptr, iINTERP, A_GPR(tmp), A_GPR(stereo_mix), 0xcd, A_GPR(stereo_mix+1));
1435 A_OP(icode, &ptr, iMAC0, A_GPR(playback+4), A_GPR(playback+4), A_GPR(gpr), A_GPR(tmp));
1436 snd_emu10k1_init_mono_control(&controls[nctl++], "Center Playback Volume", gpr, 0);
1437 gpr++;
1438
1439 /* Stereo Mix LFE Playback */
1440 A_OP(icode, &ptr, iMAC0, A_GPR(playback+5), A_GPR(playback+5), A_GPR(gpr), A_GPR(tmp));
1441 snd_emu10k1_init_mono_control(&controls[nctl++], "LFE Playback Volume", gpr, 0);
1442 gpr++;
1443
2b637da5 1444 if (emu->card_capabilities->spk71) {
1da177e4
LT
1445 /* Stereo Mix Side Playback */
1446 A_OP(icode, &ptr, iMAC0, A_GPR(playback+6), A_GPR(playback+6), A_GPR(gpr), A_GPR(stereo_mix));
1447 A_OP(icode, &ptr, iMAC0, A_GPR(playback+7), A_GPR(playback+7), A_GPR(gpr+1), A_GPR(stereo_mix+1));
1448 snd_emu10k1_init_stereo_control(&controls[nctl++], "Side Playback Volume", gpr, 0);
1449 gpr += 2;
1450 }
1451
1452 /*
1453 * outputs
1454 */
1455#define A_PUT_OUTPUT(out,src) A_OP(icode, &ptr, iACC3, A_EXTOUT(out), A_C_00000000, A_C_00000000, A_GPR(src))
1456#define A_PUT_STEREO_OUTPUT(out1,out2,src) \
1457 {A_PUT_OUTPUT(out1,src); A_PUT_OUTPUT(out2,src+1);}
1458
1459#define _A_SWITCH(icode, ptr, dst, src, sw) \
1460 A_OP((icode), ptr, iMACINT0, dst, A_C_00000000, src, sw);
1461#define A_SWITCH(icode, ptr, dst, src, sw) \
1462 _A_SWITCH(icode, ptr, A_GPR(dst), A_GPR(src), A_GPR(sw))
1463#define _A_SWITCH_NEG(icode, ptr, dst, src) \
1464 A_OP((icode), ptr, iANDXOR, dst, src, A_C_00000001, A_C_00000001);
1465#define A_SWITCH_NEG(icode, ptr, dst, src) \
1466 _A_SWITCH_NEG(icode, ptr, A_GPR(dst), A_GPR(src))
1467
1468
1469 /*
1470 * Process tone control
1471 */
1472 A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 0), A_GPR(playback + 0), A_C_00000000, A_C_00000000); /* left */
1473 A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 1), A_GPR(playback + 1), A_C_00000000, A_C_00000000); /* right */
1474 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 */
1475 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 */
1476 A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 4), A_GPR(playback + 4), A_C_00000000, A_C_00000000); /* center */
1477 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 1478 if (emu->card_capabilities->spk71) {
1da177e4
LT
1479 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 */
1480 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 */
1481 }
1482
1483
1484 ctl = &controls[nctl + 0];
1485 ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1486 strcpy(ctl->id.name, "Tone Control - Bass");
1487 ctl->vcount = 2;
1488 ctl->count = 10;
1489 ctl->min = 0;
1490 ctl->max = 40;
1491 ctl->value[0] = ctl->value[1] = 20;
1492 ctl->translation = EMU10K1_GPR_TRANSLATION_BASS;
1493 ctl = &controls[nctl + 1];
1494 ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1495 strcpy(ctl->id.name, "Tone Control - Treble");
1496 ctl->vcount = 2;
1497 ctl->count = 10;
1498 ctl->min = 0;
1499 ctl->max = 40;
1500 ctl->value[0] = ctl->value[1] = 20;
1501 ctl->translation = EMU10K1_GPR_TRANSLATION_TREBLE;
1502
1503#define BASS_GPR 0x8c
1504#define TREBLE_GPR 0x96
1505
1506 for (z = 0; z < 5; z++) {
1507 int j;
1508 for (j = 0; j < 2; j++) {
1509 controls[nctl + 0].gpr[z * 2 + j] = BASS_GPR + z * 2 + j;
1510 controls[nctl + 1].gpr[z * 2 + j] = TREBLE_GPR + z * 2 + j;
1511 }
1512 }
1513 for (z = 0; z < 4; z++) { /* front/rear/center-lfe/side */
1514 int j, k, l, d;
1515 for (j = 0; j < 2; j++) { /* left/right */
1516 k = 0xb0 + (z * 8) + (j * 4);
1517 l = 0xe0 + (z * 8) + (j * 4);
1518 d = playback + SND_EMU10K1_PLAYBACK_CHANNELS + z * 2 + j;
1519
1520 A_OP(icode, &ptr, iMAC0, A_C_00000000, A_C_00000000, A_GPR(d), A_GPR(BASS_GPR + 0 + j));
1521 A_OP(icode, &ptr, iMACMV, A_GPR(k+1), A_GPR(k), A_GPR(k+1), A_GPR(BASS_GPR + 4 + j));
1522 A_OP(icode, &ptr, iMACMV, A_GPR(k), A_GPR(d), A_GPR(k), A_GPR(BASS_GPR + 2 + j));
1523 A_OP(icode, &ptr, iMACMV, A_GPR(k+3), A_GPR(k+2), A_GPR(k+3), A_GPR(BASS_GPR + 8 + j));
1524 A_OP(icode, &ptr, iMAC0, A_GPR(k+2), A_GPR_ACCU, A_GPR(k+2), A_GPR(BASS_GPR + 6 + j));
1525 A_OP(icode, &ptr, iACC3, A_GPR(k+2), A_GPR(k+2), A_GPR(k+2), A_C_00000000);
1526
1527 A_OP(icode, &ptr, iMAC0, A_C_00000000, A_C_00000000, A_GPR(k+2), A_GPR(TREBLE_GPR + 0 + j));
1528 A_OP(icode, &ptr, iMACMV, A_GPR(l+1), A_GPR(l), A_GPR(l+1), A_GPR(TREBLE_GPR + 4 + j));
1529 A_OP(icode, &ptr, iMACMV, A_GPR(l), A_GPR(k+2), A_GPR(l), A_GPR(TREBLE_GPR + 2 + j));
1530 A_OP(icode, &ptr, iMACMV, A_GPR(l+3), A_GPR(l+2), A_GPR(l+3), A_GPR(TREBLE_GPR + 8 + j));
1531 A_OP(icode, &ptr, iMAC0, A_GPR(l+2), A_GPR_ACCU, A_GPR(l+2), A_GPR(TREBLE_GPR + 6 + j));
1532 A_OP(icode, &ptr, iMACINT0, A_GPR(l+2), A_C_00000000, A_GPR(l+2), A_C_00000010);
1533
1534 A_OP(icode, &ptr, iACC3, A_GPR(d), A_GPR(l+2), A_C_00000000, A_C_00000000);
1535
1536 if (z == 2) /* center */
1537 break;
1538 }
1539 }
1540 nctl += 2;
1541
1542#undef BASS_GPR
1543#undef TREBLE_GPR
1544
1545 for (z = 0; z < 8; z++) {
1546 A_SWITCH(icode, &ptr, tmp + 0, playback + SND_EMU10K1_PLAYBACK_CHANNELS + z, gpr + 0);
1547 A_SWITCH_NEG(icode, &ptr, tmp + 1, gpr + 0);
1548 A_SWITCH(icode, &ptr, tmp + 1, playback + z, tmp + 1);
1549 A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + z), A_GPR(tmp + 0), A_GPR(tmp + 1), A_C_00000000);
1550 }
1551 snd_emu10k1_init_stereo_onoff_control(controls + nctl++, "Tone Control - Switch", gpr, 0);
1552 gpr += 2;
1553
1554 /* Master volume (will be renamed later) */
1555 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));
1556 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));
1557 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));
1558 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));
1559 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));
1560 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));
1561 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));
1562 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));
1563 snd_emu10k1_init_mono_control(&controls[nctl++], "Wave Master Playback Volume", gpr, 0);
1564 gpr += 2;
1565
1566 /* analog speakers */
1567 A_PUT_STEREO_OUTPUT(A_EXTOUT_AFRONT_L, A_EXTOUT_AFRONT_R, playback + SND_EMU10K1_PLAYBACK_CHANNELS);
1568 A_PUT_STEREO_OUTPUT(A_EXTOUT_AREAR_L, A_EXTOUT_AREAR_R, playback+2 + SND_EMU10K1_PLAYBACK_CHANNELS);
1569 A_PUT_OUTPUT(A_EXTOUT_ACENTER, playback+4 + SND_EMU10K1_PLAYBACK_CHANNELS);
1570 A_PUT_OUTPUT(A_EXTOUT_ALFE, playback+5 + SND_EMU10K1_PLAYBACK_CHANNELS);
2b637da5 1571 if (emu->card_capabilities->spk71)
1da177e4
LT
1572 A_PUT_STEREO_OUTPUT(A_EXTOUT_ASIDE_L, A_EXTOUT_ASIDE_R, playback+6 + SND_EMU10K1_PLAYBACK_CHANNELS);
1573
1574 /* headphone */
1575 A_PUT_STEREO_OUTPUT(A_EXTOUT_HEADPHONE_L, A_EXTOUT_HEADPHONE_R, playback + SND_EMU10K1_PLAYBACK_CHANNELS);
1576
1577 /* digital outputs */
1578 /* A_PUT_STEREO_OUTPUT(A_EXTOUT_FRONT_L, A_EXTOUT_FRONT_R, playback + SND_EMU10K1_PLAYBACK_CHANNELS); */
190d2c46 1579 if (emu->card_capabilities->emu_model) {
9f4bd5dd 1580 /* EMU1010 Outputs from PCM Front, Rear, Center, LFE, Side */
6f002b02 1581 dev_info(emu->card->dev, "EMU outputs on\n");
9f4bd5dd 1582 for (z = 0; z < 8; z++) {
90fd5ce5
JCD
1583 if (emu->card_capabilities->ca0108_chip) {
1584 A_OP(icode, &ptr, iACC3, A3_EMU32OUT(z), A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + z), A_C_00000000, A_C_00000000);
1585 } else {
1586 A_OP(icode, &ptr, iACC3, A_EMU32OUTL(z), A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + z), A_C_00000000, A_C_00000000);
1587 }
9f4bd5dd
JCD
1588 }
1589 }
1da177e4
LT
1590
1591 /* IEC958 Optical Raw Playback Switch */
1592 gpr_map[gpr++] = 0;
1593 gpr_map[gpr++] = 0x1008;
1594 gpr_map[gpr++] = 0xffff0000;
1595 for (z = 0; z < 2; z++) {
1596 A_OP(icode, &ptr, iMAC0, A_GPR(tmp + 2), A_FXBUS(FXBUS_PT_LEFT + z), A_C_00000000, A_C_00000000);
1597 A_OP(icode, &ptr, iSKIP, A_GPR_COND, A_GPR_COND, A_GPR(gpr - 2), A_C_00000001);
1598 A_OP(icode, &ptr, iACC3, A_GPR(tmp + 2), A_C_00000000, A_C_00010000, A_GPR(tmp + 2));
1599 A_OP(icode, &ptr, iANDXOR, A_GPR(tmp + 2), A_GPR(tmp + 2), A_GPR(gpr - 1), A_C_00000000);
1600 A_SWITCH(icode, &ptr, tmp + 0, tmp + 2, gpr + z);
1601 A_SWITCH_NEG(icode, &ptr, tmp + 1, gpr + z);
1602 A_SWITCH(icode, &ptr, tmp + 1, playback + SND_EMU10K1_PLAYBACK_CHANNELS + z, tmp + 1);
1603 if ((z==1) && (emu->card_capabilities->spdif_bug)) {
1604 /* Due to a SPDIF output bug on some Audigy cards, this code delays the Right channel by 1 sample */
6f002b02
TI
1605 dev_info(emu->card->dev,
1606 "Installing spdif_bug patch: %s\n",
1607 emu->card_capabilities->name);
1da177e4
LT
1608 A_OP(icode, &ptr, iACC3, A_EXTOUT(A_EXTOUT_FRONT_L + z), A_GPR(gpr - 3), A_C_00000000, A_C_00000000);
1609 A_OP(icode, &ptr, iACC3, A_GPR(gpr - 3), A_GPR(tmp + 0), A_GPR(tmp + 1), A_C_00000000);
1610 } else {
1611 A_OP(icode, &ptr, iACC3, A_EXTOUT(A_EXTOUT_FRONT_L + z), A_GPR(tmp + 0), A_GPR(tmp + 1), A_C_00000000);
1612 }
1613 }
10e8d78a 1614 snd_emu10k1_init_stereo_onoff_control(controls + nctl++, SNDRV_CTL_NAME_IEC958("Optical Raw ",PLAYBACK,SWITCH), gpr, 0);
1da177e4
LT
1615 gpr += 2;
1616
1617 A_PUT_STEREO_OUTPUT(A_EXTOUT_REAR_L, A_EXTOUT_REAR_R, playback+2 + SND_EMU10K1_PLAYBACK_CHANNELS);
1618 A_PUT_OUTPUT(A_EXTOUT_CENTER, playback+4 + SND_EMU10K1_PLAYBACK_CHANNELS);
1619 A_PUT_OUTPUT(A_EXTOUT_LFE, playback+5 + SND_EMU10K1_PLAYBACK_CHANNELS);
1620
1621 /* ADC buffer */
1622#ifdef EMU10K1_CAPTURE_DIGITAL_OUT
1623 A_PUT_STEREO_OUTPUT(A_EXTOUT_ADC_CAP_L, A_EXTOUT_ADC_CAP_R, playback + SND_EMU10K1_PLAYBACK_CHANNELS);
1624#else
1625 A_PUT_OUTPUT(A_EXTOUT_ADC_CAP_L, capture);
1626 A_PUT_OUTPUT(A_EXTOUT_ADC_CAP_R, capture+1);
1627#endif
1628
190d2c46 1629 if (emu->card_capabilities->emu_model) {
90fd5ce5 1630 if (emu->card_capabilities->ca0108_chip) {
6f002b02 1631 dev_info(emu->card->dev, "EMU2 inputs on\n");
90fd5ce5
JCD
1632 for (z = 0; z < 0x10; z++) {
1633 snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp,
1634 bit_shifter16,
1635 A3_EMU32IN(z),
1636 A_FXBUS2(z*2) );
1637 }
1638 } else {
6f002b02 1639 dev_info(emu->card->dev, "EMU inputs on\n");
90fd5ce5
JCD
1640 /* Capture 16 (originally 8) channels of S32_LE sound */
1641
28a97c19 1642 /*
6f002b02 1643 dev_dbg(emu->card->dev, "emufx.c: gpr=0x%x, tmp=0x%x\n",
28a97c19
TI
1644 gpr, tmp);
1645 */
90fd5ce5
JCD
1646 /* For the EMU1010: How to get 32bit values from the DSP. High 16bits into L, low 16bits into R. */
1647 /* A_P16VIN(0) is delayed by one sample,
1648 * so all other A_P16VIN channels will need to also be delayed
1649 */
1650 /* Left ADC in. 1 of 2 */
1651 snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_P16VIN(0x0), A_FXBUS2(0) );
1652 /* Right ADC in 1 of 2 */
1653 gpr_map[gpr++] = 0x00000000;
1654 /* Delaying by one sample: instead of copying the input
1655 * value A_P16VIN to output A_FXBUS2 as in the first channel,
1656 * we use an auxiliary register, delaying the value by one
1657 * sample
1658 */
1659 snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_GPR(gpr - 1), A_FXBUS2(2) );
1660 A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x1), A_C_00000000, A_C_00000000);
1661 gpr_map[gpr++] = 0x00000000;
1662 snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_GPR(gpr - 1), A_FXBUS2(4) );
1663 A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x2), A_C_00000000, A_C_00000000);
1664 gpr_map[gpr++] = 0x00000000;
1665 snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_GPR(gpr - 1), A_FXBUS2(6) );
1666 A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x3), A_C_00000000, A_C_00000000);
1667 /* For 96kHz mode */
1668 /* Left ADC in. 2 of 2 */
1669 gpr_map[gpr++] = 0x00000000;
1670 snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_GPR(gpr - 1), A_FXBUS2(0x8) );
1671 A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x4), A_C_00000000, A_C_00000000);
1672 /* Right ADC in 2 of 2 */
1673 gpr_map[gpr++] = 0x00000000;
1674 snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_GPR(gpr - 1), A_FXBUS2(0xa) );
1675 A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x5), A_C_00000000, A_C_00000000);
1676 gpr_map[gpr++] = 0x00000000;
1677 snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_GPR(gpr - 1), A_FXBUS2(0xc) );
1678 A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x6), A_C_00000000, A_C_00000000);
1679 gpr_map[gpr++] = 0x00000000;
1680 snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_GPR(gpr - 1), A_FXBUS2(0xe) );
1681 A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x7), A_C_00000000, A_C_00000000);
1682 /* Pavel Hofman - we still have voices, A_FXBUS2s, and
1683 * A_P16VINs available -
1684 * let's add 8 more capture channels - total of 16
1685 */
1686 gpr_map[gpr++] = 0x00000000;
1687 snd_emu10k1_audigy_dsp_convert_32_to_2x16(icode, &ptr, tmp,
1688 bit_shifter16,
1689 A_GPR(gpr - 1),
1690 A_FXBUS2(0x10));
1691 A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x8),
1692 A_C_00000000, A_C_00000000);
1693 gpr_map[gpr++] = 0x00000000;
1694 snd_emu10k1_audigy_dsp_convert_32_to_2x16(icode, &ptr, tmp,
1695 bit_shifter16,
1696 A_GPR(gpr - 1),
1697 A_FXBUS2(0x12));
1698 A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x9),
1699 A_C_00000000, A_C_00000000);
1700 gpr_map[gpr++] = 0x00000000;
1701 snd_emu10k1_audigy_dsp_convert_32_to_2x16(icode, &ptr, tmp,
1702 bit_shifter16,
1703 A_GPR(gpr - 1),
1704 A_FXBUS2(0x14));
1705 A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0xa),
1706 A_C_00000000, A_C_00000000);
1707 gpr_map[gpr++] = 0x00000000;
1708 snd_emu10k1_audigy_dsp_convert_32_to_2x16(icode, &ptr, tmp,
1709 bit_shifter16,
1710 A_GPR(gpr - 1),
1711 A_FXBUS2(0x16));
1712 A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0xb),
1713 A_C_00000000, A_C_00000000);
1714 gpr_map[gpr++] = 0x00000000;
1715 snd_emu10k1_audigy_dsp_convert_32_to_2x16(icode, &ptr, tmp,
1716 bit_shifter16,
1717 A_GPR(gpr - 1),
1718 A_FXBUS2(0x18));
1719 A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0xc),
1720 A_C_00000000, A_C_00000000);
1721 gpr_map[gpr++] = 0x00000000;
1722 snd_emu10k1_audigy_dsp_convert_32_to_2x16(icode, &ptr, tmp,
1723 bit_shifter16,
1724 A_GPR(gpr - 1),
1725 A_FXBUS2(0x1a));
1726 A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0xd),
1727 A_C_00000000, A_C_00000000);
1728 gpr_map[gpr++] = 0x00000000;
1729 snd_emu10k1_audigy_dsp_convert_32_to_2x16(icode, &ptr, tmp,
1730 bit_shifter16,
1731 A_GPR(gpr - 1),
1732 A_FXBUS2(0x1c));
1733 A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0xe),
1734 A_C_00000000, A_C_00000000);
1735 gpr_map[gpr++] = 0x00000000;
1736 snd_emu10k1_audigy_dsp_convert_32_to_2x16(icode, &ptr, tmp,
1737 bit_shifter16,
1738 A_GPR(gpr - 1),
1739 A_FXBUS2(0x1e));
1740 A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0xf),
1741 A_C_00000000, A_C_00000000);
1742 }
9f4bd5dd
JCD
1743
1744#if 0
1745 for (z = 4; z < 8; z++) {
1746 A_OP(icode, &ptr, iACC3, A_FXBUS2(z), A_C_00000000, A_C_00000000, A_C_00000000);
1747 }
1748 for (z = 0xc; z < 0x10; z++) {
1749 A_OP(icode, &ptr, iACC3, A_FXBUS2(z), A_C_00000000, A_C_00000000, A_C_00000000);
1750 }
1751#endif
1752 } else {
1753 /* EFX capture - capture the 16 EXTINs */
1754 /* Capture 16 channels of S16_LE sound */
1755 for (z = 0; z < 16; z++) {
1756 A_OP(icode, &ptr, iACC3, A_FXBUS2(z), A_C_00000000, A_C_00000000, A_EXTIN(z));
1757 }
1da177e4
LT
1758 }
1759
19b99fba 1760#endif /* JCD test */
1da177e4
LT
1761 /*
1762 * ok, set up done..
1763 */
1764
1765 if (gpr > tmp) {
1766 snd_BUG();
1767 err = -EIO;
1768 goto __err;
1769 }
1770 /* clear remaining instruction memory */
1771 while (ptr < 0x400)
1772 A_OP(icode, &ptr, 0x0f, 0xc0, 0xc0, 0xcf, 0xc0);
1773
1da177e4 1774 icode->gpr_add_control_count = nctl;
eb4698f3 1775 icode->gpr_add_controls = (struct snd_emu10k1_fx8010_control_gpr __user *)controls;
f7ba7fc6 1776 emu->support_tlv = 1; /* support TLV */
d42fe63d 1777 err = snd_emu10k1_icode_poke(emu, icode, true);
f7ba7fc6 1778 emu->support_tlv = 0; /* clear again */
1da177e4 1779
f1b4863a 1780__err:
1da177e4 1781 kfree(controls);
f1b4863a
GB
1782__err_ctrls:
1783 kfree((void __force *)icode->gpr_map);
1784__err_gpr:
1785 kfree(icode);
1da177e4
LT
1786 return err;
1787}
1788
1789
1790/*
1791 * initial DSP configuration for Emu10k1
1792 */
1793
1794/* when volume = max, then copy only to avoid volume modification */
1795/* with iMAC0 (negative values) */
e23e7a14 1796static void _volume(struct snd_emu10k1_fx8010_code *icode, u32 *ptr, u32 dst, u32 src, u32 vol)
1da177e4
LT
1797{
1798 OP(icode, ptr, iMAC0, dst, C_00000000, src, vol);
1799 OP(icode, ptr, iANDXOR, C_00000000, vol, C_ffffffff, C_7fffffff);
1800 OP(icode, ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, C_00000001);
1801 OP(icode, ptr, iACC3, dst, src, C_00000000, C_00000000);
1802}
e23e7a14 1803static void _volume_add(struct snd_emu10k1_fx8010_code *icode, u32 *ptr, u32 dst, u32 src, u32 vol)
1da177e4
LT
1804{
1805 OP(icode, ptr, iANDXOR, C_00000000, vol, C_ffffffff, C_7fffffff);
1806 OP(icode, ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, C_00000002);
1807 OP(icode, ptr, iMACINT0, dst, dst, src, C_00000001);
1808 OP(icode, ptr, iSKIP, C_00000000, C_7fffffff, C_7fffffff, C_00000001);
1809 OP(icode, ptr, iMAC0, dst, dst, src, vol);
1810}
e23e7a14 1811static void _volume_out(struct snd_emu10k1_fx8010_code *icode, u32 *ptr, u32 dst, u32 src, u32 vol)
1da177e4
LT
1812{
1813 OP(icode, ptr, iANDXOR, C_00000000, vol, C_ffffffff, C_7fffffff);
1814 OP(icode, ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, C_00000002);
1815 OP(icode, ptr, iACC3, dst, src, C_00000000, C_00000000);
1816 OP(icode, ptr, iSKIP, C_00000000, C_7fffffff, C_7fffffff, C_00000001);
1817 OP(icode, ptr, iMAC0, dst, C_00000000, src, vol);
1818}
1819
1820#define VOLUME(icode, ptr, dst, src, vol) \
1821 _volume(icode, ptr, GPR(dst), GPR(src), GPR(vol))
1822#define VOLUME_IN(icode, ptr, dst, src, vol) \
1823 _volume(icode, ptr, GPR(dst), EXTIN(src), GPR(vol))
1824#define VOLUME_ADD(icode, ptr, dst, src, vol) \
1825 _volume_add(icode, ptr, GPR(dst), GPR(src), GPR(vol))
1826#define VOLUME_ADDIN(icode, ptr, dst, src, vol) \
1827 _volume_add(icode, ptr, GPR(dst), EXTIN(src), GPR(vol))
1828#define VOLUME_OUT(icode, ptr, dst, src, vol) \
1829 _volume_out(icode, ptr, EXTOUT(dst), GPR(src), GPR(vol))
1830#define _SWITCH(icode, ptr, dst, src, sw) \
1831 OP((icode), ptr, iMACINT0, dst, C_00000000, src, sw);
1832#define SWITCH(icode, ptr, dst, src, sw) \
1833 _SWITCH(icode, ptr, GPR(dst), GPR(src), GPR(sw))
1834#define SWITCH_IN(icode, ptr, dst, src, sw) \
1835 _SWITCH(icode, ptr, GPR(dst), EXTIN(src), GPR(sw))
1836#define _SWITCH_NEG(icode, ptr, dst, src) \
1837 OP((icode), ptr, iANDXOR, dst, src, C_00000001, C_00000001);
1838#define SWITCH_NEG(icode, ptr, dst, src) \
1839 _SWITCH_NEG(icode, ptr, GPR(dst), GPR(src))
1840
1841
e23e7a14 1842static int _snd_emu10k1_init_efx(struct snd_emu10k1 *emu)
1da177e4
LT
1843{
1844 int err, i, z, gpr, tmp, playback, capture;
1845 u32 ptr;
eb4698f3
TI
1846 struct snd_emu10k1_fx8010_code *icode;
1847 struct snd_emu10k1_fx8010_pcm_rec *ipcm = NULL;
1848 struct snd_emu10k1_fx8010_control_gpr *controls = NULL, *ctl;
1da177e4 1849 u32 *gpr_map;
1da177e4 1850
f1b4863a
GB
1851 err = -ENOMEM;
1852 icode = kzalloc(sizeof(*icode), GFP_KERNEL);
1853 if (!icode)
1854 return err;
1855
1856 icode->gpr_map = (u_int32_t __user *) kcalloc(256 + 160 + 160 + 2 * 512,
1857 sizeof(u_int32_t), GFP_KERNEL);
1858 if (!icode->gpr_map)
1859 goto __err_gpr;
1860
1861 controls = kcalloc(SND_EMU10K1_GPR_CONTROLS,
1862 sizeof(struct snd_emu10k1_fx8010_control_gpr),
1863 GFP_KERNEL);
1864 if (!controls)
1865 goto __err_ctrls;
1866
1867 ipcm = kzalloc(sizeof(*ipcm), GFP_KERNEL);
1868 if (!ipcm)
1869 goto __err_ipcm;
1870
4d23359b 1871 gpr_map = (u32 __force *)icode->gpr_map;
1da177e4
LT
1872
1873 icode->tram_data_map = icode->gpr_map + 256;
1874 icode->tram_addr_map = icode->tram_data_map + 160;
1875 icode->code = icode->tram_addr_map + 160;
1876
1877 /* clear free GPRs */
1878 for (i = 0; i < 256; i++)
1879 set_bit(i, icode->gpr_valid);
1880
1881 /* clear TRAM data & address lines */
1882 for (i = 0; i < 160; i++)
1883 set_bit(i, icode->tram_valid);
1884
1885 strcpy(icode->name, "SB Live! FX8010 code for ALSA v1.2 by Jaroslav Kysela");
1886 ptr = 0; i = 0;
edf8e456 1887 /* we have 12 inputs */
1da177e4
LT
1888 playback = SND_EMU10K1_INPUTS;
1889 /* we have 6 playback channels and tone control doubles */
1890 capture = playback + (SND_EMU10K1_PLAYBACK_CHANNELS * 2);
1891 gpr = capture + SND_EMU10K1_CAPTURE_CHANNELS;
1892 tmp = 0x88; /* we need 4 temporary GPR */
1893 /* from 0x8c to 0xff is the area for tone control */
1894
1895 /* stop FX processor */
1896 snd_emu10k1_ptr_write(emu, DBG, 0, (emu->fx8010.dbg = 0) | EMU10K1_DBG_SINGLE_STEP);
1897
1898 /*
1899 * Process FX Buses
1900 */
1901 OP(icode, &ptr, iMACINT0, GPR(0), C_00000000, FXBUS(FXBUS_PCM_LEFT), C_00000004);
1902 OP(icode, &ptr, iMACINT0, GPR(1), C_00000000, FXBUS(FXBUS_PCM_RIGHT), C_00000004);
1903 OP(icode, &ptr, iMACINT0, GPR(2), C_00000000, FXBUS(FXBUS_MIDI_LEFT), C_00000004);
1904 OP(icode, &ptr, iMACINT0, GPR(3), C_00000000, FXBUS(FXBUS_MIDI_RIGHT), C_00000004);
1905 OP(icode, &ptr, iMACINT0, GPR(4), C_00000000, FXBUS(FXBUS_PCM_LEFT_REAR), C_00000004);
1906 OP(icode, &ptr, iMACINT0, GPR(5), C_00000000, FXBUS(FXBUS_PCM_RIGHT_REAR), C_00000004);
1907 OP(icode, &ptr, iMACINT0, GPR(6), C_00000000, FXBUS(FXBUS_PCM_CENTER), C_00000004);
1908 OP(icode, &ptr, iMACINT0, GPR(7), C_00000000, FXBUS(FXBUS_PCM_LFE), C_00000004);
1909 OP(icode, &ptr, iMACINT0, GPR(8), C_00000000, C_00000000, C_00000000); /* S/PDIF left */
1910 OP(icode, &ptr, iMACINT0, GPR(9), C_00000000, C_00000000, C_00000000); /* S/PDIF right */
edf8e456
MM
1911 OP(icode, &ptr, iMACINT0, GPR(10), C_00000000, FXBUS(FXBUS_PCM_LEFT_FRONT), C_00000004);
1912 OP(icode, &ptr, iMACINT0, GPR(11), C_00000000, FXBUS(FXBUS_PCM_RIGHT_FRONT), C_00000004);
1da177e4
LT
1913
1914 /* Raw S/PDIF PCM */
1915 ipcm->substream = 0;
1916 ipcm->channels = 2;
1917 ipcm->tram_start = 0;
1918 ipcm->buffer_size = (64 * 1024) / 2;
1919 ipcm->gpr_size = gpr++;
1920 ipcm->gpr_ptr = gpr++;
1921 ipcm->gpr_count = gpr++;
1922 ipcm->gpr_tmpcount = gpr++;
1923 ipcm->gpr_trigger = gpr++;
1924 ipcm->gpr_running = gpr++;
1925 ipcm->etram[0] = 0;
1926 ipcm->etram[1] = 1;
1927
1928 gpr_map[gpr + 0] = 0xfffff000;
1929 gpr_map[gpr + 1] = 0xffff0000;
1930 gpr_map[gpr + 2] = 0x70000000;
1931 gpr_map[gpr + 3] = 0x00000007;
1932 gpr_map[gpr + 4] = 0x001f << 11;
1933 gpr_map[gpr + 5] = 0x001c << 11;
1934 gpr_map[gpr + 6] = (0x22 - 0x01) - 1; /* skip at 01 to 22 */
1935 gpr_map[gpr + 7] = (0x22 - 0x06) - 1; /* skip at 06 to 22 */
1936 gpr_map[gpr + 8] = 0x2000000 + (2<<11);
1937 gpr_map[gpr + 9] = 0x4000000 + (2<<11);
1938 gpr_map[gpr + 10] = 1<<11;
1939 gpr_map[gpr + 11] = (0x24 - 0x0a) - 1; /* skip at 0a to 24 */
1940 gpr_map[gpr + 12] = 0;
1941
1942 /* if the trigger flag is not set, skip */
1943 /* 00: */ OP(icode, &ptr, iMAC0, C_00000000, GPR(ipcm->gpr_trigger), C_00000000, C_00000000);
1944 /* 01: */ OP(icode, &ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_ZERO, GPR(gpr + 6));
1945 /* if the running flag is set, we're running */
1946 /* 02: */ OP(icode, &ptr, iMAC0, C_00000000, GPR(ipcm->gpr_running), C_00000000, C_00000000);
1947 /* 03: */ OP(icode, &ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, C_00000004);
1948 /* wait until ((GPR_DBAC>>11) & 0x1f) == 0x1c) */
1949 /* 04: */ OP(icode, &ptr, iANDXOR, GPR(tmp + 0), GPR_DBAC, GPR(gpr + 4), C_00000000);
1950 /* 05: */ OP(icode, &ptr, iMACINT0, C_00000000, GPR(tmp + 0), C_ffffffff, GPR(gpr + 5));
1951 /* 06: */ OP(icode, &ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, GPR(gpr + 7));
1952 /* 07: */ OP(icode, &ptr, iACC3, GPR(gpr + 12), C_00000010, C_00000001, C_00000000);
1953
1954 /* 08: */ OP(icode, &ptr, iANDXOR, GPR(ipcm->gpr_running), GPR(ipcm->gpr_running), C_00000000, C_00000001);
1955 /* 09: */ OP(icode, &ptr, iACC3, GPR(gpr + 12), GPR(gpr + 12), C_ffffffff, C_00000000);
1956 /* 0a: */ OP(icode, &ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, GPR(gpr + 11));
1957 /* 0b: */ OP(icode, &ptr, iACC3, GPR(gpr + 12), C_00000001, C_00000000, C_00000000);
1958
1959 /* 0c: */ OP(icode, &ptr, iANDXOR, GPR(tmp + 0), ETRAM_DATA(ipcm->etram[0]), GPR(gpr + 0), C_00000000);
1960 /* 0d: */ OP(icode, &ptr, iLOG, GPR(tmp + 0), GPR(tmp + 0), GPR(gpr + 3), C_00000000);
1961 /* 0e: */ OP(icode, &ptr, iANDXOR, GPR(8), GPR(tmp + 0), GPR(gpr + 1), GPR(gpr + 2));
1962 /* 0f: */ OP(icode, &ptr, iSKIP, C_00000000, GPR_COND, CC_REG_MINUS, C_00000001);
1963 /* 10: */ OP(icode, &ptr, iANDXOR, GPR(8), GPR(8), GPR(gpr + 1), GPR(gpr + 2));
1964
1965 /* 11: */ OP(icode, &ptr, iANDXOR, GPR(tmp + 0), ETRAM_DATA(ipcm->etram[1]), GPR(gpr + 0), C_00000000);
1966 /* 12: */ OP(icode, &ptr, iLOG, GPR(tmp + 0), GPR(tmp + 0), GPR(gpr + 3), C_00000000);
1967 /* 13: */ OP(icode, &ptr, iANDXOR, GPR(9), GPR(tmp + 0), GPR(gpr + 1), GPR(gpr + 2));
1968 /* 14: */ OP(icode, &ptr, iSKIP, C_00000000, GPR_COND, CC_REG_MINUS, C_00000001);
1969 /* 15: */ OP(icode, &ptr, iANDXOR, GPR(9), GPR(9), GPR(gpr + 1), GPR(gpr + 2));
1970
1971 /* 16: */ OP(icode, &ptr, iACC3, GPR(tmp + 0), GPR(ipcm->gpr_ptr), C_00000001, C_00000000);
1972 /* 17: */ OP(icode, &ptr, iMACINT0, C_00000000, GPR(tmp + 0), C_ffffffff, GPR(ipcm->gpr_size));
1973 /* 18: */ OP(icode, &ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_MINUS, C_00000001);
1974 /* 19: */ OP(icode, &ptr, iACC3, GPR(tmp + 0), C_00000000, C_00000000, C_00000000);
1975 /* 1a: */ OP(icode, &ptr, iACC3, GPR(ipcm->gpr_ptr), GPR(tmp + 0), C_00000000, C_00000000);
1976
1977 /* 1b: */ OP(icode, &ptr, iACC3, GPR(ipcm->gpr_tmpcount), GPR(ipcm->gpr_tmpcount), C_ffffffff, C_00000000);
1978 /* 1c: */ OP(icode, &ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, C_00000002);
1979 /* 1d: */ OP(icode, &ptr, iACC3, GPR(ipcm->gpr_tmpcount), GPR(ipcm->gpr_count), C_00000000, C_00000000);
1980 /* 1e: */ OP(icode, &ptr, iACC3, GPR_IRQ, C_80000000, C_00000000, C_00000000);
1981 /* 1f: */ OP(icode, &ptr, iANDXOR, GPR(ipcm->gpr_running), GPR(ipcm->gpr_running), C_00000001, C_00010000);
1982
1983 /* 20: */ OP(icode, &ptr, iANDXOR, GPR(ipcm->gpr_running), GPR(ipcm->gpr_running), C_00010000, C_00000001);
1984 /* 21: */ OP(icode, &ptr, iSKIP, C_00000000, C_7fffffff, C_7fffffff, C_00000002);
1985
1986 /* 22: */ OP(icode, &ptr, iMACINT1, ETRAM_ADDR(ipcm->etram[0]), GPR(gpr + 8), GPR_DBAC, C_ffffffff);
1987 /* 23: */ OP(icode, &ptr, iMACINT1, ETRAM_ADDR(ipcm->etram[1]), GPR(gpr + 9), GPR_DBAC, C_ffffffff);
1988
1989 /* 24: */
1990 gpr += 13;
1991
1992 /* Wave Playback Volume */
1993 for (z = 0; z < 2; z++)
1994 VOLUME(icode, &ptr, playback + z, z, gpr + z);
1995 snd_emu10k1_init_stereo_control(controls + i++, "Wave Playback Volume", gpr, 100);
1996 gpr += 2;
1997
1998 /* Wave Surround Playback Volume */
1999 for (z = 0; z < 2; z++)
2000 VOLUME(icode, &ptr, playback + 2 + z, z, gpr + z);
2001 snd_emu10k1_init_stereo_control(controls + i++, "Wave Surround Playback Volume", gpr, 0);
2002 gpr += 2;
2003
2004 /* Wave Center/LFE Playback Volume */
2005 OP(icode, &ptr, iACC3, GPR(tmp + 0), FXBUS(FXBUS_PCM_LEFT), FXBUS(FXBUS_PCM_RIGHT), C_00000000);
2006 OP(icode, &ptr, iMACINT0, GPR(tmp + 0), C_00000000, GPR(tmp + 0), C_00000002);
2007 VOLUME(icode, &ptr, playback + 4, tmp + 0, gpr);
2008 snd_emu10k1_init_mono_control(controls + i++, "Wave Center Playback Volume", gpr++, 0);
2009 VOLUME(icode, &ptr, playback + 5, tmp + 0, gpr);
2010 snd_emu10k1_init_mono_control(controls + i++, "Wave LFE Playback Volume", gpr++, 0);
2011
2012 /* Wave Capture Volume + Switch */
2013 for (z = 0; z < 2; z++) {
2014 SWITCH(icode, &ptr, tmp + 0, z, gpr + 2 + z);
2015 VOLUME(icode, &ptr, capture + z, tmp + 0, gpr + z);
2016 }
2017 snd_emu10k1_init_stereo_control(controls + i++, "Wave Capture Volume", gpr, 0);
2018 snd_emu10k1_init_stereo_onoff_control(controls + i++, "Wave Capture Switch", gpr + 2, 0);
2019 gpr += 4;
2020
2021 /* Synth Playback Volume */
2022 for (z = 0; z < 2; z++)
2023 VOLUME_ADD(icode, &ptr, playback + z, 2 + z, gpr + z);
2024 snd_emu10k1_init_stereo_control(controls + i++, "Synth Playback Volume", gpr, 100);
2025 gpr += 2;
2026
2027 /* Synth Capture Volume + Switch */
2028 for (z = 0; z < 2; z++) {
2029 SWITCH(icode, &ptr, tmp + 0, 2 + z, gpr + 2 + z);
2030 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
2031 }
2032 snd_emu10k1_init_stereo_control(controls + i++, "Synth Capture Volume", gpr, 0);
2033 snd_emu10k1_init_stereo_onoff_control(controls + i++, "Synth Capture Switch", gpr + 2, 0);
2034 gpr += 4;
2035
2036 /* Surround Digital Playback Volume (renamed later without Digital) */
2037 for (z = 0; z < 2; z++)
2038 VOLUME_ADD(icode, &ptr, playback + 2 + z, 4 + z, gpr + z);
2039 snd_emu10k1_init_stereo_control(controls + i++, "Surround Digital Playback Volume", gpr, 100);
2040 gpr += 2;
2041
2042 /* Surround Capture Volume + Switch */
2043 for (z = 0; z < 2; z++) {
2044 SWITCH(icode, &ptr, tmp + 0, 4 + z, gpr + 2 + z);
2045 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
2046 }
2047 snd_emu10k1_init_stereo_control(controls + i++, "Surround Capture Volume", gpr, 0);
2048 snd_emu10k1_init_stereo_onoff_control(controls + i++, "Surround Capture Switch", gpr + 2, 0);
2049 gpr += 4;
2050
2051 /* Center Playback Volume (renamed later without Digital) */
2052 VOLUME_ADD(icode, &ptr, playback + 4, 6, gpr);
2053 snd_emu10k1_init_mono_control(controls + i++, "Center Digital Playback Volume", gpr++, 100);
2054
2055 /* LFE Playback Volume + Switch (renamed later without Digital) */
2056 VOLUME_ADD(icode, &ptr, playback + 5, 7, gpr);
2057 snd_emu10k1_init_mono_control(controls + i++, "LFE Digital Playback Volume", gpr++, 100);
2058
edf8e456
MM
2059 /* Front Playback Volume */
2060 for (z = 0; z < 2; z++)
2061 VOLUME_ADD(icode, &ptr, playback + z, 10 + z, gpr + z);
2062 snd_emu10k1_init_stereo_control(controls + i++, "Front Playback Volume", gpr, 100);
2063 gpr += 2;
2064
2065 /* Front Capture Volume + Switch */
2066 for (z = 0; z < 2; z++) {
2067 SWITCH(icode, &ptr, tmp + 0, 10 + z, gpr + 2);
2068 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
2069 }
2070 snd_emu10k1_init_stereo_control(controls + i++, "Front Capture Volume", gpr, 0);
2071 snd_emu10k1_init_mono_onoff_control(controls + i++, "Front Capture Switch", gpr + 2, 0);
2072 gpr += 3;
2073
1da177e4
LT
2074 /*
2075 * Process inputs
2076 */
2077
2078 if (emu->fx8010.extin_mask & ((1<<EXTIN_AC97_L)|(1<<EXTIN_AC97_R))) {
2079 /* AC'97 Playback Volume */
2080 VOLUME_ADDIN(icode, &ptr, playback + 0, EXTIN_AC97_L, gpr); gpr++;
2081 VOLUME_ADDIN(icode, &ptr, playback + 1, EXTIN_AC97_R, gpr); gpr++;
2082 snd_emu10k1_init_stereo_control(controls + i++, "AC97 Playback Volume", gpr-2, 0);
2083 /* AC'97 Capture Volume */
2084 VOLUME_ADDIN(icode, &ptr, capture + 0, EXTIN_AC97_L, gpr); gpr++;
2085 VOLUME_ADDIN(icode, &ptr, capture + 1, EXTIN_AC97_R, gpr); gpr++;
2086 snd_emu10k1_init_stereo_control(controls + i++, "AC97 Capture Volume", gpr-2, 100);
2087 }
2088
2089 if (emu->fx8010.extin_mask & ((1<<EXTIN_SPDIF_CD_L)|(1<<EXTIN_SPDIF_CD_R))) {
2090 /* IEC958 TTL Playback Volume */
2091 for (z = 0; z < 2; z++)
2092 VOLUME_ADDIN(icode, &ptr, playback + z, EXTIN_SPDIF_CD_L + z, gpr + z);
10e8d78a 2093 snd_emu10k1_init_stereo_control(controls + i++, SNDRV_CTL_NAME_IEC958("TTL ",PLAYBACK,VOLUME), gpr, 0);
1da177e4
LT
2094 gpr += 2;
2095
2096 /* IEC958 TTL Capture Volume + Switch */
2097 for (z = 0; z < 2; z++) {
2098 SWITCH_IN(icode, &ptr, tmp + 0, EXTIN_SPDIF_CD_L + z, gpr + 2 + z);
2099 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
2100 }
10e8d78a
CL
2101 snd_emu10k1_init_stereo_control(controls + i++, SNDRV_CTL_NAME_IEC958("TTL ",CAPTURE,VOLUME), gpr, 0);
2102 snd_emu10k1_init_stereo_onoff_control(controls + i++, SNDRV_CTL_NAME_IEC958("TTL ",CAPTURE,SWITCH), gpr + 2, 0);
1da177e4
LT
2103 gpr += 4;
2104 }
2105
2106 if (emu->fx8010.extin_mask & ((1<<EXTIN_ZOOM_L)|(1<<EXTIN_ZOOM_R))) {
2107 /* Zoom Video Playback Volume */
2108 for (z = 0; z < 2; z++)
2109 VOLUME_ADDIN(icode, &ptr, playback + z, EXTIN_ZOOM_L + z, gpr + z);
2110 snd_emu10k1_init_stereo_control(controls + i++, "Zoom Video Playback Volume", gpr, 0);
2111 gpr += 2;
2112
2113 /* Zoom Video Capture Volume + Switch */
2114 for (z = 0; z < 2; z++) {
2115 SWITCH_IN(icode, &ptr, tmp + 0, EXTIN_ZOOM_L + z, gpr + 2 + z);
2116 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
2117 }
2118 snd_emu10k1_init_stereo_control(controls + i++, "Zoom Video Capture Volume", gpr, 0);
2119 snd_emu10k1_init_stereo_onoff_control(controls + i++, "Zoom Video Capture Switch", gpr + 2, 0);
2120 gpr += 4;
2121 }
2122
2123 if (emu->fx8010.extin_mask & ((1<<EXTIN_TOSLINK_L)|(1<<EXTIN_TOSLINK_R))) {
2124 /* IEC958 Optical Playback Volume */
2125 for (z = 0; z < 2; z++)
2126 VOLUME_ADDIN(icode, &ptr, playback + z, EXTIN_TOSLINK_L + z, gpr + z);
10e8d78a 2127 snd_emu10k1_init_stereo_control(controls + i++, SNDRV_CTL_NAME_IEC958("LiveDrive ",PLAYBACK,VOLUME), gpr, 0);
1da177e4
LT
2128 gpr += 2;
2129
2130 /* IEC958 Optical Capture Volume */
2131 for (z = 0; z < 2; z++) {
2132 SWITCH_IN(icode, &ptr, tmp + 0, EXTIN_TOSLINK_L + z, gpr + 2 + z);
2133 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
2134 }
10e8d78a
CL
2135 snd_emu10k1_init_stereo_control(controls + i++, SNDRV_CTL_NAME_IEC958("LiveDrive ",CAPTURE,VOLUME), gpr, 0);
2136 snd_emu10k1_init_stereo_onoff_control(controls + i++, SNDRV_CTL_NAME_IEC958("LiveDrive ",CAPTURE,SWITCH), gpr + 2, 0);
1da177e4
LT
2137 gpr += 4;
2138 }
2139
2140 if (emu->fx8010.extin_mask & ((1<<EXTIN_LINE1_L)|(1<<EXTIN_LINE1_R))) {
2141 /* Line LiveDrive Playback Volume */
2142 for (z = 0; z < 2; z++)
2143 VOLUME_ADDIN(icode, &ptr, playback + z, EXTIN_LINE1_L + z, gpr + z);
2144 snd_emu10k1_init_stereo_control(controls + i++, "Line LiveDrive Playback Volume", gpr, 0);
2145 gpr += 2;
2146
2147 /* Line LiveDrive Capture Volume + Switch */
2148 for (z = 0; z < 2; z++) {
2149 SWITCH_IN(icode, &ptr, tmp + 0, EXTIN_LINE1_L + z, gpr + 2 + z);
2150 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
2151 }
2152 snd_emu10k1_init_stereo_control(controls + i++, "Line LiveDrive Capture Volume", gpr, 0);
2153 snd_emu10k1_init_stereo_onoff_control(controls + i++, "Line LiveDrive Capture Switch", gpr + 2, 0);
2154 gpr += 4;
2155 }
2156
2157 if (emu->fx8010.extin_mask & ((1<<EXTIN_COAX_SPDIF_L)|(1<<EXTIN_COAX_SPDIF_R))) {
2158 /* IEC958 Coax Playback Volume */
2159 for (z = 0; z < 2; z++)
2160 VOLUME_ADDIN(icode, &ptr, playback + z, EXTIN_COAX_SPDIF_L + z, gpr + z);
10e8d78a 2161 snd_emu10k1_init_stereo_control(controls + i++, SNDRV_CTL_NAME_IEC958("Coaxial ",PLAYBACK,VOLUME), gpr, 0);
1da177e4
LT
2162 gpr += 2;
2163
2164 /* IEC958 Coax Capture Volume + Switch */
2165 for (z = 0; z < 2; z++) {
2166 SWITCH_IN(icode, &ptr, tmp + 0, EXTIN_COAX_SPDIF_L + z, gpr + 2 + z);
2167 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
2168 }
10e8d78a
CL
2169 snd_emu10k1_init_stereo_control(controls + i++, SNDRV_CTL_NAME_IEC958("Coaxial ",CAPTURE,VOLUME), gpr, 0);
2170 snd_emu10k1_init_stereo_onoff_control(controls + i++, SNDRV_CTL_NAME_IEC958("Coaxial ",CAPTURE,SWITCH), gpr + 2, 0);
1da177e4
LT
2171 gpr += 4;
2172 }
2173
2174 if (emu->fx8010.extin_mask & ((1<<EXTIN_LINE2_L)|(1<<EXTIN_LINE2_R))) {
2175 /* Line LiveDrive Playback Volume */
2176 for (z = 0; z < 2; z++)
2177 VOLUME_ADDIN(icode, &ptr, playback + z, EXTIN_LINE2_L + z, gpr + z);
2178 snd_emu10k1_init_stereo_control(controls + i++, "Line2 LiveDrive Playback Volume", gpr, 0);
2179 controls[i-1].id.index = 1;
2180 gpr += 2;
2181
2182 /* Line LiveDrive Capture Volume */
2183 for (z = 0; z < 2; z++) {
2184 SWITCH_IN(icode, &ptr, tmp + 0, EXTIN_LINE2_L + z, gpr + 2 + z);
2185 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
2186 }
2187 snd_emu10k1_init_stereo_control(controls + i++, "Line2 LiveDrive Capture Volume", gpr, 0);
2188 controls[i-1].id.index = 1;
2189 snd_emu10k1_init_stereo_onoff_control(controls + i++, "Line2 LiveDrive Capture Switch", gpr + 2, 0);
2190 controls[i-1].id.index = 1;
2191 gpr += 4;
2192 }
2193
2194 /*
2195 * Process tone control
2196 */
2197 OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 0), GPR(playback + 0), C_00000000, C_00000000); /* left */
2198 OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 1), GPR(playback + 1), C_00000000, C_00000000); /* right */
2199 OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 2), GPR(playback + 2), C_00000000, C_00000000); /* rear left */
2200 OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 3), GPR(playback + 3), C_00000000, C_00000000); /* rear right */
2201 OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 4), GPR(playback + 4), C_00000000, C_00000000); /* center */
2202 OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 5), GPR(playback + 5), C_00000000, C_00000000); /* LFE */
2203
2204 ctl = &controls[i + 0];
2205 ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
2206 strcpy(ctl->id.name, "Tone Control - Bass");
2207 ctl->vcount = 2;
2208 ctl->count = 10;
2209 ctl->min = 0;
2210 ctl->max = 40;
2211 ctl->value[0] = ctl->value[1] = 20;
bfe9fc8a 2212 ctl->tlv = snd_emu10k1_bass_treble_db_scale;
1da177e4
LT
2213 ctl->translation = EMU10K1_GPR_TRANSLATION_BASS;
2214 ctl = &controls[i + 1];
2215 ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
2216 strcpy(ctl->id.name, "Tone Control - Treble");
2217 ctl->vcount = 2;
2218 ctl->count = 10;
2219 ctl->min = 0;
2220 ctl->max = 40;
2221 ctl->value[0] = ctl->value[1] = 20;
bfe9fc8a 2222 ctl->tlv = snd_emu10k1_bass_treble_db_scale;
1da177e4
LT
2223 ctl->translation = EMU10K1_GPR_TRANSLATION_TREBLE;
2224
2225#define BASS_GPR 0x8c
2226#define TREBLE_GPR 0x96
2227
2228 for (z = 0; z < 5; z++) {
2229 int j;
2230 for (j = 0; j < 2; j++) {
2231 controls[i + 0].gpr[z * 2 + j] = BASS_GPR + z * 2 + j;
2232 controls[i + 1].gpr[z * 2 + j] = TREBLE_GPR + z * 2 + j;
2233 }
2234 }
2235 for (z = 0; z < 3; z++) { /* front/rear/center-lfe */
2236 int j, k, l, d;
2237 for (j = 0; j < 2; j++) { /* left/right */
2238 k = 0xa0 + (z * 8) + (j * 4);
2239 l = 0xd0 + (z * 8) + (j * 4);
2240 d = playback + SND_EMU10K1_PLAYBACK_CHANNELS + z * 2 + j;
2241
2242 OP(icode, &ptr, iMAC0, C_00000000, C_00000000, GPR(d), GPR(BASS_GPR + 0 + j));
2243 OP(icode, &ptr, iMACMV, GPR(k+1), GPR(k), GPR(k+1), GPR(BASS_GPR + 4 + j));
2244 OP(icode, &ptr, iMACMV, GPR(k), GPR(d), GPR(k), GPR(BASS_GPR + 2 + j));
2245 OP(icode, &ptr, iMACMV, GPR(k+3), GPR(k+2), GPR(k+3), GPR(BASS_GPR + 8 + j));
2246 OP(icode, &ptr, iMAC0, GPR(k+2), GPR_ACCU, GPR(k+2), GPR(BASS_GPR + 6 + j));
2247 OP(icode, &ptr, iACC3, GPR(k+2), GPR(k+2), GPR(k+2), C_00000000);
2248
2249 OP(icode, &ptr, iMAC0, C_00000000, C_00000000, GPR(k+2), GPR(TREBLE_GPR + 0 + j));
2250 OP(icode, &ptr, iMACMV, GPR(l+1), GPR(l), GPR(l+1), GPR(TREBLE_GPR + 4 + j));
2251 OP(icode, &ptr, iMACMV, GPR(l), GPR(k+2), GPR(l), GPR(TREBLE_GPR + 2 + j));
2252 OP(icode, &ptr, iMACMV, GPR(l+3), GPR(l+2), GPR(l+3), GPR(TREBLE_GPR + 8 + j));
2253 OP(icode, &ptr, iMAC0, GPR(l+2), GPR_ACCU, GPR(l+2), GPR(TREBLE_GPR + 6 + j));
2254 OP(icode, &ptr, iMACINT0, GPR(l+2), C_00000000, GPR(l+2), C_00000010);
2255
2256 OP(icode, &ptr, iACC3, GPR(d), GPR(l+2), C_00000000, C_00000000);
2257
2258 if (z == 2) /* center */
2259 break;
2260 }
2261 }
2262 i += 2;
2263
2264#undef BASS_GPR
2265#undef TREBLE_GPR
2266
2267 for (z = 0; z < 6; z++) {
2268 SWITCH(icode, &ptr, tmp + 0, playback + SND_EMU10K1_PLAYBACK_CHANNELS + z, gpr + 0);
2269 SWITCH_NEG(icode, &ptr, tmp + 1, gpr + 0);
2270 SWITCH(icode, &ptr, tmp + 1, playback + z, tmp + 1);
2271 OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + z), GPR(tmp + 0), GPR(tmp + 1), C_00000000);
2272 }
2273 snd_emu10k1_init_stereo_onoff_control(controls + i++, "Tone Control - Switch", gpr, 0);
2274 gpr += 2;
2275
2276 /*
2277 * Process outputs
2278 */
2279 if (emu->fx8010.extout_mask & ((1<<EXTOUT_AC97_L)|(1<<EXTOUT_AC97_R))) {
2280 /* AC'97 Playback Volume */
2281
2282 for (z = 0; z < 2; z++)
2283 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_AC97_L + z), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + z), C_00000000, C_00000000);
2284 }
2285
2286 if (emu->fx8010.extout_mask & ((1<<EXTOUT_TOSLINK_L)|(1<<EXTOUT_TOSLINK_R))) {
2287 /* IEC958 Optical Raw Playback Switch */
2288
2289 for (z = 0; z < 2; z++) {
2290 SWITCH(icode, &ptr, tmp + 0, 8 + z, gpr + z);
2291 SWITCH_NEG(icode, &ptr, tmp + 1, gpr + z);
2292 SWITCH(icode, &ptr, tmp + 1, playback + SND_EMU10K1_PLAYBACK_CHANNELS + z, tmp + 1);
2293 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_TOSLINK_L + z), GPR(tmp + 0), GPR(tmp + 1), C_00000000);
2294#ifdef EMU10K1_CAPTURE_DIGITAL_OUT
2295 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_ADC_CAP_L + z), GPR(tmp + 0), GPR(tmp + 1), C_00000000);
2296#endif
2297 }
2298
10e8d78a 2299 snd_emu10k1_init_stereo_onoff_control(controls + i++, SNDRV_CTL_NAME_IEC958("Optical Raw ",PLAYBACK,SWITCH), gpr, 0);
1da177e4
LT
2300 gpr += 2;
2301 }
2302
2303 if (emu->fx8010.extout_mask & ((1<<EXTOUT_HEADPHONE_L)|(1<<EXTOUT_HEADPHONE_R))) {
2304 /* Headphone Playback Volume */
2305
2306 for (z = 0; z < 2; z++) {
2307 SWITCH(icode, &ptr, tmp + 0, playback + SND_EMU10K1_PLAYBACK_CHANNELS + 4 + z, gpr + 2 + z);
2308 SWITCH_NEG(icode, &ptr, tmp + 1, gpr + 2 + z);
2309 SWITCH(icode, &ptr, tmp + 1, playback + SND_EMU10K1_PLAYBACK_CHANNELS + z, tmp + 1);
2310 OP(icode, &ptr, iACC3, GPR(tmp + 0), GPR(tmp + 0), GPR(tmp + 1), C_00000000);
2311 VOLUME_OUT(icode, &ptr, EXTOUT_HEADPHONE_L + z, tmp + 0, gpr + z);
2312 }
2313
2314 snd_emu10k1_init_stereo_control(controls + i++, "Headphone Playback Volume", gpr + 0, 0);
2315 controls[i-1].id.index = 1; /* AC'97 can have also Headphone control */
2316 snd_emu10k1_init_mono_onoff_control(controls + i++, "Headphone Center Playback Switch", gpr + 2, 0);
2317 controls[i-1].id.index = 1;
2318 snd_emu10k1_init_mono_onoff_control(controls + i++, "Headphone LFE Playback Switch", gpr + 3, 0);
2319 controls[i-1].id.index = 1;
2320
2321 gpr += 4;
2322 }
2323
2324 if (emu->fx8010.extout_mask & ((1<<EXTOUT_REAR_L)|(1<<EXTOUT_REAR_R)))
2325 for (z = 0; z < 2; z++)
2326 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_REAR_L + z), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 2 + z), C_00000000, C_00000000);
2327
2328 if (emu->fx8010.extout_mask & ((1<<EXTOUT_AC97_REAR_L)|(1<<EXTOUT_AC97_REAR_R)))
2329 for (z = 0; z < 2; z++)
2330 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_AC97_REAR_L + z), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 2 + z), C_00000000, C_00000000);
2331
2332 if (emu->fx8010.extout_mask & (1<<EXTOUT_AC97_CENTER)) {
2333#ifndef EMU10K1_CENTER_LFE_FROM_FRONT
2334 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_AC97_CENTER), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 4), C_00000000, C_00000000);
2335 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_ACENTER), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 4), C_00000000, C_00000000);
2336#else
2337 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_AC97_CENTER), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 0), C_00000000, C_00000000);
2338 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_ACENTER), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 0), C_00000000, C_00000000);
2339#endif
2340 }
2341
2342 if (emu->fx8010.extout_mask & (1<<EXTOUT_AC97_LFE)) {
2343#ifndef EMU10K1_CENTER_LFE_FROM_FRONT
2344 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_AC97_LFE), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 5), C_00000000, C_00000000);
2345 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_ALFE), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 5), C_00000000, C_00000000);
2346#else
2347 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_AC97_LFE), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 1), C_00000000, C_00000000);
2348 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_ALFE), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 1), C_00000000, C_00000000);
2349#endif
2350 }
2351
2352#ifndef EMU10K1_CAPTURE_DIGITAL_OUT
2353 for (z = 0; z < 2; z++)
2354 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_ADC_CAP_L + z), GPR(capture + z), C_00000000, C_00000000);
2355#endif
2356
2357 if (emu->fx8010.extout_mask & (1<<EXTOUT_MIC_CAP))
2358 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_MIC_CAP), GPR(capture + 2), C_00000000, C_00000000);
2359
2360 /* EFX capture - capture the 16 EXTINS */
2b637da5
LR
2361 if (emu->card_capabilities->sblive51) {
2362 /* On the Live! 5.1, FXBUS2(1) and FXBUS(2) are shared with EXTOUT_ACENTER
2363 * and EXTOUT_ALFE, so we can't connect inputs to them for multitrack recording.
2364 *
2365 * Since only 14 of the 16 EXTINs are used, this is not a big problem.
2366 * We route AC97L and R to FX capture 14 and 15, SPDIF CD in to FX capture
2367 * 0 and 3, then the rest of the EXTINs to the corresponding FX capture
2368 * channel. Multitrack recorders will still see the center/lfe output signal
2369 * on the second and third channels.
2370 */
2371 OP(icode, &ptr, iACC3, FXBUS2(14), C_00000000, C_00000000, EXTIN(0));
2372 OP(icode, &ptr, iACC3, FXBUS2(15), C_00000000, C_00000000, EXTIN(1));
2373 OP(icode, &ptr, iACC3, FXBUS2(0), C_00000000, C_00000000, EXTIN(2));
2374 OP(icode, &ptr, iACC3, FXBUS2(3), C_00000000, C_00000000, EXTIN(3));
2375 for (z = 4; z < 14; z++)
2376 OP(icode, &ptr, iACC3, FXBUS2(z), C_00000000, C_00000000, EXTIN(z));
2377 } else {
2378 for (z = 0; z < 16; z++)
2379 OP(icode, &ptr, iACC3, FXBUS2(z), C_00000000, C_00000000, EXTIN(z));
1da177e4 2380 }
2b637da5 2381
1da177e4
LT
2382
2383 if (gpr > tmp) {
2384 snd_BUG();
2385 err = -EIO;
2386 goto __err;
2387 }
2388 if (i > SND_EMU10K1_GPR_CONTROLS) {
2389 snd_BUG();
2390 err = -EIO;
2391 goto __err;
2392 }
2393
2394 /* clear remaining instruction memory */
2395 while (ptr < 0x200)
2396 OP(icode, &ptr, iACC3, C_00000000, C_00000000, C_00000000, C_00000000);
2397
2398 if ((err = snd_emu10k1_fx8010_tram_setup(emu, ipcm->buffer_size)) < 0)
2399 goto __err;
1da177e4 2400 icode->gpr_add_control_count = i;
eb4698f3 2401 icode->gpr_add_controls = (struct snd_emu10k1_fx8010_control_gpr __user *)controls;
f7ba7fc6 2402 emu->support_tlv = 1; /* support TLV */
d42fe63d 2403 err = snd_emu10k1_icode_poke(emu, icode, true);
f7ba7fc6 2404 emu->support_tlv = 0; /* clear again */
1da177e4
LT
2405 if (err >= 0)
2406 err = snd_emu10k1_ipcm_poke(emu, ipcm);
f1b4863a 2407__err:
1da177e4 2408 kfree(ipcm);
f1b4863a 2409__err_ipcm:
1da177e4 2410 kfree(controls);
f1b4863a
GB
2411__err_ctrls:
2412 kfree((void __force *)icode->gpr_map);
2413__err_gpr:
2414 kfree(icode);
1da177e4
LT
2415 return err;
2416}
2417
e23e7a14 2418int snd_emu10k1_init_efx(struct snd_emu10k1 *emu)
1da177e4 2419{
09668b44
TI
2420 spin_lock_init(&emu->fx8010.irq_lock);
2421 INIT_LIST_HEAD(&emu->fx8010.gpr_ctl);
1da177e4
LT
2422 if (emu->audigy)
2423 return _snd_emu10k1_audigy_init_efx(emu);
2424 else
2425 return _snd_emu10k1_init_efx(emu);
2426}
2427
eb4698f3 2428void snd_emu10k1_free_efx(struct snd_emu10k1 *emu)
1da177e4
LT
2429{
2430 /* stop processor */
2431 if (emu->audigy)
2432 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg = A_DBG_SINGLE_STEP);
2433 else
2434 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg = EMU10K1_DBG_SINGLE_STEP);
2435}
2436
9f4bd5dd 2437#if 0 /* FIXME: who use them? */
eb4698f3 2438int snd_emu10k1_fx8010_tone_control_activate(struct snd_emu10k1 *emu, int output)
1da177e4 2439{
7c22f1aa
TI
2440 if (output < 0 || output >= 6)
2441 return -EINVAL;
1da177e4
LT
2442 snd_emu10k1_ptr_write(emu, emu->gpr_base + 0x94 + output, 0, 1);
2443 return 0;
2444}
2445
eb4698f3 2446int snd_emu10k1_fx8010_tone_control_deactivate(struct snd_emu10k1 *emu, int output)
1da177e4 2447{
7c22f1aa
TI
2448 if (output < 0 || output >= 6)
2449 return -EINVAL;
1da177e4
LT
2450 snd_emu10k1_ptr_write(emu, emu->gpr_base + 0x94 + output, 0, 0);
2451 return 0;
2452}
2453#endif
2454
eb4698f3 2455int snd_emu10k1_fx8010_tram_setup(struct snd_emu10k1 *emu, u32 size)
1da177e4
LT
2456{
2457 u8 size_reg = 0;
2458
2459 /* size is in samples */
2460 if (size != 0) {
2461 size = (size - 1) >> 13;
2462
2463 while (size) {
2464 size >>= 1;
2465 size_reg++;
2466 }
2467 size = 0x2000 << size_reg;
2468 }
2469 if ((emu->fx8010.etram_pages.bytes / 2) == size)
2470 return 0;
2471 spin_lock_irq(&emu->emu_lock);
2472 outl(HCFG_LOCKTANKCACHE_MASK | inl(emu->port + HCFG), emu->port + HCFG);
2473 spin_unlock_irq(&emu->emu_lock);
2474 snd_emu10k1_ptr_write(emu, TCB, 0, 0);
2475 snd_emu10k1_ptr_write(emu, TCBS, 0, 0);
2476 if (emu->fx8010.etram_pages.area != NULL) {
2477 snd_dma_free_pages(&emu->fx8010.etram_pages);
2478 emu->fx8010.etram_pages.area = NULL;
2479 emu->fx8010.etram_pages.bytes = 0;
2480 }
2481
2482 if (size > 0) {
2483 if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(emu->pci),
2484 size * 2, &emu->fx8010.etram_pages) < 0)
2485 return -ENOMEM;
2486 memset(emu->fx8010.etram_pages.area, 0, size * 2);
2487 snd_emu10k1_ptr_write(emu, TCB, 0, emu->fx8010.etram_pages.addr);
2488 snd_emu10k1_ptr_write(emu, TCBS, 0, size_reg);
2489 spin_lock_irq(&emu->emu_lock);
2490 outl(inl(emu->port + HCFG) & ~HCFG_LOCKTANKCACHE_MASK, emu->port + HCFG);
09668b44 2491 spin_unlock_irq(&emu->emu_lock);
1da177e4
LT
2492 }
2493
2494 return 0;
2495}
2496
eb4698f3 2497static int snd_emu10k1_fx8010_open(struct snd_hwdep * hw, struct file *file)
1da177e4
LT
2498{
2499 return 0;
2500}
2501
2502static void copy_string(char *dst, char *src, char *null, int idx)
2503{
2504 if (src == NULL)
2505 sprintf(dst, "%s %02X", null, idx);
2506 else
2507 strcpy(dst, src);
2508}
2509
51882453 2510static void snd_emu10k1_fx8010_info(struct snd_emu10k1 *emu,
eb4698f3 2511 struct snd_emu10k1_fx8010_info *info)
1da177e4
LT
2512{
2513 char **fxbus, **extin, **extout;
2514 unsigned short fxbus_mask, extin_mask, extout_mask;
2515 int res;
2516
1da177e4
LT
2517 info->internal_tram_size = emu->fx8010.itram_size;
2518 info->external_tram_size = emu->fx8010.etram_pages.bytes / 2;
2519 fxbus = fxbuses;
2520 extin = emu->audigy ? audigy_ins : creative_ins;
2521 extout = emu->audigy ? audigy_outs : creative_outs;
2522 fxbus_mask = emu->fx8010.fxbus_mask;
2523 extin_mask = emu->fx8010.extin_mask;
2524 extout_mask = emu->fx8010.extout_mask;
2525 for (res = 0; res < 16; res++, fxbus++, extin++, extout++) {
2526 copy_string(info->fxbus_names[res], fxbus_mask & (1 << res) ? *fxbus : NULL, "FXBUS", res);
2527 copy_string(info->extin_names[res], extin_mask & (1 << res) ? *extin : NULL, "Unused", res);
2528 copy_string(info->extout_names[res], extout_mask & (1 << res) ? *extout : NULL, "Unused", res);
2529 }
2530 for (res = 16; res < 32; res++, extout++)
2531 copy_string(info->extout_names[res], extout_mask & (1 << res) ? *extout : NULL, "Unused", res);
2532 info->gpr_controls = emu->fx8010.gpr_count;
1da177e4
LT
2533}
2534
eb4698f3 2535static int snd_emu10k1_fx8010_ioctl(struct snd_hwdep * hw, struct file *file, unsigned int cmd, unsigned long arg)
1da177e4 2536{
eb4698f3
TI
2537 struct snd_emu10k1 *emu = hw->private_data;
2538 struct snd_emu10k1_fx8010_info *info;
2539 struct snd_emu10k1_fx8010_code *icode;
2540 struct snd_emu10k1_fx8010_pcm_rec *ipcm;
1da177e4
LT
2541 unsigned int addr;
2542 void __user *argp = (void __user *)arg;
2543 int res;
2544
2545 switch (cmd) {
f7ba7fc6
TI
2546 case SNDRV_EMU10K1_IOCTL_PVERSION:
2547 emu->support_tlv = 1;
2548 return put_user(SNDRV_EMU10K1_VERSION, (int __user *)argp);
1da177e4 2549 case SNDRV_EMU10K1_IOCTL_INFO:
352701c2 2550 info = kzalloc(sizeof(*info), GFP_KERNEL);
1da177e4
LT
2551 if (!info)
2552 return -ENOMEM;
51882453 2553 snd_emu10k1_fx8010_info(emu, info);
1da177e4
LT
2554 if (copy_to_user(argp, info, sizeof(*info))) {
2555 kfree(info);
2556 return -EFAULT;
2557 }
2558 kfree(info);
2559 return 0;
2560 case SNDRV_EMU10K1_IOCTL_CODE_POKE:
2561 if (!capable(CAP_SYS_ADMIN))
2562 return -EPERM;
336500f0
LZ
2563
2564 icode = memdup_user(argp, sizeof(*icode));
2565 if (IS_ERR(icode))
2566 return PTR_ERR(icode);
d42fe63d 2567 res = snd_emu10k1_icode_poke(emu, icode, false);
1da177e4
LT
2568 kfree(icode);
2569 return res;
2570 case SNDRV_EMU10K1_IOCTL_CODE_PEEK:
336500f0
LZ
2571 icode = memdup_user(argp, sizeof(*icode));
2572 if (IS_ERR(icode))
2573 return PTR_ERR(icode);
1da177e4
LT
2574 res = snd_emu10k1_icode_peek(emu, icode);
2575 if (res == 0 && copy_to_user(argp, icode, sizeof(*icode))) {
2576 kfree(icode);
2577 return -EFAULT;
2578 }
2579 kfree(icode);
2580 return res;
2581 case SNDRV_EMU10K1_IOCTL_PCM_POKE:
336500f0
LZ
2582 ipcm = memdup_user(argp, sizeof(*ipcm));
2583 if (IS_ERR(ipcm))
2584 return PTR_ERR(ipcm);
1da177e4
LT
2585 res = snd_emu10k1_ipcm_poke(emu, ipcm);
2586 kfree(ipcm);
2587 return res;
2588 case SNDRV_EMU10K1_IOCTL_PCM_PEEK:
336500f0
LZ
2589 ipcm = memdup_user(argp, sizeof(*ipcm));
2590 if (IS_ERR(ipcm))
2591 return PTR_ERR(ipcm);
1da177e4
LT
2592 res = snd_emu10k1_ipcm_peek(emu, ipcm);
2593 if (res == 0 && copy_to_user(argp, ipcm, sizeof(*ipcm))) {
2594 kfree(ipcm);
2595 return -EFAULT;
2596 }
2597 kfree(ipcm);
2598 return res;
2599 case SNDRV_EMU10K1_IOCTL_TRAM_SETUP:
2600 if (!capable(CAP_SYS_ADMIN))
2601 return -EPERM;
2602 if (get_user(addr, (unsigned int __user *)argp))
2603 return -EFAULT;
62932df8 2604 mutex_lock(&emu->fx8010.lock);
1da177e4 2605 res = snd_emu10k1_fx8010_tram_setup(emu, addr);
62932df8 2606 mutex_unlock(&emu->fx8010.lock);
1da177e4
LT
2607 return res;
2608 case SNDRV_EMU10K1_IOCTL_STOP:
2609 if (!capable(CAP_SYS_ADMIN))
2610 return -EPERM;
2611 if (emu->audigy)
2612 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg |= A_DBG_SINGLE_STEP);
2613 else
2614 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg |= EMU10K1_DBG_SINGLE_STEP);
2615 return 0;
2616 case SNDRV_EMU10K1_IOCTL_CONTINUE:
2617 if (!capable(CAP_SYS_ADMIN))
2618 return -EPERM;
2619 if (emu->audigy)
2620 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg = 0);
2621 else
2622 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg = 0);
2623 return 0;
2624 case SNDRV_EMU10K1_IOCTL_ZERO_TRAM_COUNTER:
2625 if (!capable(CAP_SYS_ADMIN))
2626 return -EPERM;
2627 if (emu->audigy)
2628 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg | A_DBG_ZC);
2629 else
2630 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg | EMU10K1_DBG_ZC);
2631 udelay(10);
2632 if (emu->audigy)
2633 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg);
2634 else
2635 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg);
2636 return 0;
2637 case SNDRV_EMU10K1_IOCTL_SINGLE_STEP:
2638 if (!capable(CAP_SYS_ADMIN))
2639 return -EPERM;
2640 if (get_user(addr, (unsigned int __user *)argp))
2641 return -EFAULT;
2642 if (addr > 0x1ff)
2643 return -EINVAL;
2644 if (emu->audigy)
2645 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg |= A_DBG_SINGLE_STEP | addr);
2646 else
2647 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg |= EMU10K1_DBG_SINGLE_STEP | addr);
2648 udelay(10);
2649 if (emu->audigy)
2650 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg |= A_DBG_SINGLE_STEP | A_DBG_STEP_ADDR | addr);
2651 else
2652 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg |= EMU10K1_DBG_SINGLE_STEP | EMU10K1_DBG_STEP | addr);
2653 return 0;
2654 case SNDRV_EMU10K1_IOCTL_DBG_READ:
2655 if (emu->audigy)
2656 addr = snd_emu10k1_ptr_read(emu, A_DBG, 0);
2657 else
2658 addr = snd_emu10k1_ptr_read(emu, DBG, 0);
2659 if (put_user(addr, (unsigned int __user *)argp))
2660 return -EFAULT;
2661 return 0;
2662 }
2663 return -ENOTTY;
2664}
2665
eb4698f3 2666static int snd_emu10k1_fx8010_release(struct snd_hwdep * hw, struct file *file)
1da177e4
LT
2667{
2668 return 0;
2669}
2670
bb814c39 2671int snd_emu10k1_fx8010_new(struct snd_emu10k1 *emu, int device)
1da177e4 2672{
eb4698f3 2673 struct snd_hwdep *hw;
1da177e4
LT
2674 int err;
2675
1da177e4
LT
2676 if ((err = snd_hwdep_new(emu->card, "FX8010", device, &hw)) < 0)
2677 return err;
2678 strcpy(hw->name, "EMU10K1 (FX8010)");
2679 hw->iface = SNDRV_HWDEP_IFACE_EMU10K1;
2680 hw->ops.open = snd_emu10k1_fx8010_open;
2681 hw->ops.ioctl = snd_emu10k1_fx8010_ioctl;
2682 hw->ops.release = snd_emu10k1_fx8010_release;
2683 hw->private_data = emu;
1da177e4
LT
2684 return 0;
2685}
09668b44 2686
c7561cd8 2687#ifdef CONFIG_PM_SLEEP
e23e7a14 2688int snd_emu10k1_efx_alloc_pm_buffer(struct snd_emu10k1 *emu)
09668b44
TI
2689{
2690 int len;
2691
2692 len = emu->audigy ? 0x200 : 0x100;
2693 emu->saved_gpr = kmalloc(len * 4, GFP_KERNEL);
2694 if (! emu->saved_gpr)
2695 return -ENOMEM;
2696 len = emu->audigy ? 0x100 : 0xa0;
2697 emu->tram_val_saved = kmalloc(len * 4, GFP_KERNEL);
2698 emu->tram_addr_saved = kmalloc(len * 4, GFP_KERNEL);
2699 if (! emu->tram_val_saved || ! emu->tram_addr_saved)
2700 return -ENOMEM;
2701 len = emu->audigy ? 2 * 1024 : 2 * 512;
2702 emu->saved_icode = vmalloc(len * 4);
2703 if (! emu->saved_icode)
2704 return -ENOMEM;
2705 return 0;
2706}
2707
2708void snd_emu10k1_efx_free_pm_buffer(struct snd_emu10k1 *emu)
2709{
2710 kfree(emu->saved_gpr);
2711 kfree(emu->tram_val_saved);
2712 kfree(emu->tram_addr_saved);
2713 vfree(emu->saved_icode);
2714}
2715
2716/*
2717 * save/restore GPR, TRAM and codes
2718 */
2719void snd_emu10k1_efx_suspend(struct snd_emu10k1 *emu)
2720{
2721 int i, len;
2722
2723 len = emu->audigy ? 0x200 : 0x100;
2724 for (i = 0; i < len; i++)
2725 emu->saved_gpr[i] = snd_emu10k1_ptr_read(emu, emu->gpr_base + i, 0);
2726
2727 len = emu->audigy ? 0x100 : 0xa0;
2728 for (i = 0; i < len; i++) {
2729 emu->tram_val_saved[i] = snd_emu10k1_ptr_read(emu, TANKMEMDATAREGBASE + i, 0);
2730 emu->tram_addr_saved[i] = snd_emu10k1_ptr_read(emu, TANKMEMADDRREGBASE + i, 0);
2731 if (emu->audigy) {
2732 emu->tram_addr_saved[i] >>= 12;
2733 emu->tram_addr_saved[i] |=
2734 snd_emu10k1_ptr_read(emu, A_TANKMEMCTLREGBASE + i, 0) << 20;
2735 }
2736 }
2737
2738 len = emu->audigy ? 2 * 1024 : 2 * 512;
2739 for (i = 0; i < len; i++)
2740 emu->saved_icode[i] = snd_emu10k1_efx_read(emu, i);
2741}
2742
2743void snd_emu10k1_efx_resume(struct snd_emu10k1 *emu)
2744{
2745 int i, len;
2746
2747 /* set up TRAM */
2748 if (emu->fx8010.etram_pages.bytes > 0) {
2749 unsigned size, size_reg = 0;
2750 size = emu->fx8010.etram_pages.bytes / 2;
2751 size = (size - 1) >> 13;
2752 while (size) {
2753 size >>= 1;
2754 size_reg++;
2755 }
2756 outl(HCFG_LOCKTANKCACHE_MASK | inl(emu->port + HCFG), emu->port + HCFG);
2757 snd_emu10k1_ptr_write(emu, TCB, 0, emu->fx8010.etram_pages.addr);
2758 snd_emu10k1_ptr_write(emu, TCBS, 0, size_reg);
2759 outl(inl(emu->port + HCFG) & ~HCFG_LOCKTANKCACHE_MASK, emu->port + HCFG);
2760 }
2761
2762 if (emu->audigy)
2763 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg | A_DBG_SINGLE_STEP);
2764 else
2765 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg | EMU10K1_DBG_SINGLE_STEP);
2766
2767 len = emu->audigy ? 0x200 : 0x100;
2768 for (i = 0; i < len; i++)
2769 snd_emu10k1_ptr_write(emu, emu->gpr_base + i, 0, emu->saved_gpr[i]);
2770
2771 len = emu->audigy ? 0x100 : 0xa0;
2772 for (i = 0; i < len; i++) {
2773 snd_emu10k1_ptr_write(emu, TANKMEMDATAREGBASE + i, 0,
2774 emu->tram_val_saved[i]);
2775 if (! emu->audigy)
2776 snd_emu10k1_ptr_write(emu, TANKMEMADDRREGBASE + i, 0,
2777 emu->tram_addr_saved[i]);
2778 else {
2779 snd_emu10k1_ptr_write(emu, TANKMEMADDRREGBASE + i, 0,
2780 emu->tram_addr_saved[i] << 12);
2781 snd_emu10k1_ptr_write(emu, TANKMEMADDRREGBASE + i, 0,
2782 emu->tram_addr_saved[i] >> 20);
2783 }
2784 }
2785
2786 len = emu->audigy ? 2 * 1024 : 2 * 512;
2787 for (i = 0; i < len; i++)
2788 snd_emu10k1_efx_write(emu, i, emu->saved_icode[i]);
2789
2790 /* start FX processor when the DSP code is updated */
2791 if (emu->audigy)
2792 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg);
2793 else
2794 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg);
2795}
2796#endif