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