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