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