[ALSA] emu10k1 - Fix missing declarations
[linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git] / sound / pci / emu10k1 / emufx.c
blob1a903390ad6dc99d79a16bade1c498246b88789a
1 /*
2 * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
3 * Creative Labs, Inc.
4 * Routines for effect processor FX8010
6 * BUGS:
7 * --
9 * TODO:
10 * --
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.
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.
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
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>
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
48 * Tables
49 */
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
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
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
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,
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,
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 }
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 }
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,
290 static const u32 onoff_table[2] = {
291 0x00000000, 0x00000001
297 static inline mm_segment_t snd_enter_user(void)
299 mm_segment_t fs = get_fs();
300 set_fs(get_ds());
301 return fs;
304 static inline void snd_leave_user(mm_segment_t fs)
306 set_fs(fs);
310 * controls
313 static int snd_emu10k1_gpr_ctl_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
315 struct snd_emu10k1_fx8010_ctl *ctl =
316 (struct snd_emu10k1_fx8010_ctl *) kcontrol->private_value;
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;
328 static int snd_emu10k1_gpr_ctl_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
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;
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;
343 static int snd_emu10k1_gpr_ctl_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
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;
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;
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;
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;
391 __error:
392 spin_unlock_irqrestore(&emu->reg_lock, flags);
393 return change;
397 * Interrupt handler
400 static void snd_emu10k1_fx8010_interrupt(struct snd_emu10k1 *emu)
402 struct snd_emu10k1_fx8010_irq *irq, *nirq;
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);
412 irq = nirq;
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)
422 struct snd_emu10k1_fx8010_irq *irq;
423 unsigned long flags;
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;
441 spin_unlock_irqrestore(&emu->fx8010.irq_lock, flags);
442 if (r_irq)
443 *r_irq = irq;
444 return 0;
447 int snd_emu10k1_fx8010_unregister_irq_handler(struct snd_emu10k1 *emu,
448 struct snd_emu10k1_fx8010_irq *irq)
450 struct snd_emu10k1_fx8010_irq *tmp;
451 unsigned long flags;
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;
460 } else {
461 while (tmp && tmp->next != irq)
462 tmp = tmp->next;
463 if (tmp)
464 tmp->next = tmp->next->next;
466 spin_unlock_irqrestore(&emu->fx8010.irq_lock, flags);
467 kfree(irq);
468 return 0;
471 /*************************************************************************
472 * EMU10K1 effect manager
473 *************************************************************************/
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)
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)++;
488 #define OP(icode, ptr, op, r, a, x, y) \
489 snd_emu10k1_write_op(icode, ptr, op, r, a, x, y)
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)
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)++;
504 #define A_OP(icode, ptr, op, r, a, x, y) \
505 snd_emu10k1_audigy_write_op(icode, ptr, op, r, a, x, y)
507 static void snd_emu10k1_efx_write(struct snd_emu10k1 *emu, unsigned int pc, unsigned int data)
509 pc += emu->audigy ? A_MICROCODEBASE : MICROCODEBASE;
510 snd_emu10k1_ptr_write(emu, pc, 0, data);
513 unsigned int snd_emu10k1_efx_read(struct snd_emu10k1 *emu, unsigned int pc)
515 pc += emu->audigy ? A_MICROCODEBASE : MICROCODEBASE;
516 return snd_emu10k1_ptr_read(emu, pc, 0);
519 static int snd_emu10k1_gpr_poke(struct snd_emu10k1 *emu,
520 struct snd_emu10k1_fx8010_code *icode)
522 int gpr;
523 u32 val;
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);
532 return 0;
535 static int snd_emu10k1_gpr_peek(struct snd_emu10k1 *emu,
536 struct snd_emu10k1_fx8010_code *icode)
538 int gpr;
539 u32 val;
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;
547 return 0;
550 static int snd_emu10k1_tram_poke(struct snd_emu10k1 *emu,
551 struct snd_emu10k1_fx8010_code *icode)
553 int tram;
554 u32 addr, val;
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);
570 return 0;
573 static int snd_emu10k1_tram_peek(struct snd_emu10k1 *emu,
574 struct snd_emu10k1_fx8010_code *icode)
576 int tram;
577 u32 val, addr;
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;
589 if (put_user(val, &icode->tram_data_map[tram]) ||
590 put_user(addr, &icode->tram_addr_map[tram]))
591 return -EFAULT;
593 return 0;
596 static int snd_emu10k1_code_poke(struct snd_emu10k1 *emu,
597 struct snd_emu10k1_fx8010_code *icode)
599 u32 pc, lo, hi;
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);
610 return 0;
613 static int snd_emu10k1_code_peek(struct snd_emu10k1 *emu,
614 struct snd_emu10k1_fx8010_code *icode)
616 u32 pc;
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;
626 return 0;
629 static struct snd_emu10k1_fx8010_ctl *
630 snd_emu10k1_look_for_ctl(struct snd_emu10k1 *emu, struct snd_ctl_elem_id *id)
632 struct snd_emu10k1_fx8010_ctl *ctl;
633 struct snd_kcontrol *kcontrol;
634 struct list_head *list;
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;
644 return NULL;
647 static int snd_emu10k1_verify_controls(struct snd_emu10k1 *emu,
648 struct snd_emu10k1_fx8010_code *icode)
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;
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;
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;
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;
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;
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;
697 __error:
698 kfree(gctl);
699 return err;
702 static void snd_emu10k1_ctl_private_free(struct snd_kcontrol *kctl)
704 struct snd_emu10k1_fx8010_ctl *ctl;
706 ctl = (struct snd_emu10k1_fx8010_ctl *) kctl->private_value;
707 kctl->private_value = 0;
708 list_del(&ctl->list);
709 kfree(ctl);
712 static int snd_emu10k1_add_controls(struct snd_emu10k1 *emu,
713 struct snd_emu10k1_fx8010_code *icode)
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;
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;
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;
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;
743 if (! gctl->id.name[0]) {
744 err = -EINVAL;
745 goto __error;
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];
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;
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;
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);
791 snd_emu10k1_gpr_ctl_put(ctl->kcontrol, val);
793 __error:
794 kfree(nctl);
795 kfree(gctl);
796 kfree(val);
797 return err;
800 static int snd_emu10k1_del_controls(struct snd_emu10k1 *emu,
801 struct snd_emu10k1_fx8010_code *icode)
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;
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);
819 return 0;
822 static int snd_emu10k1_list_controls(struct snd_emu10k1 *emu,
823 struct snd_emu10k1_fx8010_code *icode)
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;
833 gctl = kmalloc(sizeof(*gctl), GFP_KERNEL);
834 if (! gctl)
835 return -ENOMEM;
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];
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;
862 _gctl++;
863 i++;
866 icode->gpr_list_control_total = total;
867 kfree(gctl);
868 return 0;
871 static int snd_emu10k1_icode_poke(struct snd_emu10k1 *emu,
872 struct snd_emu10k1_fx8010_code *icode)
874 int err = 0;
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;
903 static int snd_emu10k1_icode_peek(struct snd_emu10k1 *emu,
904 struct snd_emu10k1_fx8010_code *icode)
906 int err;
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;
922 static int snd_emu10k1_ipcm_poke(struct snd_emu10k1 *emu,
923 struct snd_emu10k1_fx8010_pcm_rec *ipcm)
925 unsigned int i;
926 int err = 0;
927 struct snd_emu10k1_fx8010_pcm *pcm;
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;
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;
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];
962 __error:
963 spin_unlock_irq(&emu->reg_lock);
964 up(&emu->fx8010.lock);
965 return err;
968 static int snd_emu10k1_ipcm_peek(struct snd_emu10k1 *emu,
969 struct snd_emu10k1_fx8010_pcm_rec *ipcm)
971 unsigned int i;
972 int err = 0;
973 struct snd_emu10k1_fx8010_pcm *pcm;
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;
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
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)
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;
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)
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;
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)
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;
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)
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;
1059 * initial DSP configuration for Audigy
1062 static int __devinit _snd_emu10k1_audigy_init_efx(struct snd_emu10k1 *emu)
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;
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;
1084 gpr_map = (u32 __force *)icode->gpr_map;
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;
1090 /* clear free GPRs */
1091 for (i = 0; i < 512; i++)
1092 set_bit(i, icode->gpr_valid);
1094 /* clear TRAM data & address lines */
1095 for (i = 0; i < 256; i++)
1096 set_bit(i, icode->tram_valid);
1098 strcpy(icode->name, "Audigy DSP code for ALSA");
1099 ptr = 0;
1100 nctl = 0;
1101 gpr = stereo_mix + 10;
1103 /* stop FX processor */
1104 snd_emu10k1_ptr_write(emu, A_DBG, 0, (emu->fx8010.dbg = 0) | A_DBG_SINGLE_STEP);
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 */
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;
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;
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;
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++;
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++;
1145 * Stereo Mix
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;
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;
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;
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;
1172 * inputs
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))
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;
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));
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;
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;
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;
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;
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;
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;
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;
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++;
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++;
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;
1291 * outputs
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);}
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))
1308 * Process tone control
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 */
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;
1341 #define BASS_GPR 0x8c
1342 #define TREBLE_GPR 0x96
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;
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;
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);
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);
1372 A_OP(icode, &ptr, iACC3, A_GPR(d), A_GPR(l+2), A_C_00000000, A_C_00000000);
1374 if (z == 2) /* center */
1375 break;
1378 nctl += 2;
1380 #undef BASS_GPR
1381 #undef TREBLE_GPR
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);
1389 snd_emu10k1_init_stereo_onoff_control(controls + nctl++, "Tone Control - Switch", gpr, 0);
1390 gpr += 2;
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;
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);
1412 /* headphone */
1413 A_PUT_STEREO_OUTPUT(A_EXTOUT_HEADPHONE_L, A_EXTOUT_HEADPHONE_R, playback + SND_EMU10K1_PLAYBACK_CHANNELS);
1415 /* digital outputs */
1416 /* A_PUT_STEREO_OUTPUT(A_EXTOUT_FRONT_L, A_EXTOUT_FRONT_R, playback + SND_EMU10K1_PLAYBACK_CHANNELS); */
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);
1439 snd_emu10k1_init_stereo_onoff_control(controls + nctl++, SNDRV_CTL_NAME_IEC958("Optical Raw ",PLAYBACK,SWITCH), gpr, 0);
1440 gpr += 2;
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);
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
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));
1459 #endif /* JCD test */
1461 * ok, set up done..
1464 if (gpr > tmp) {
1465 snd_BUG();
1466 err = -EIO;
1467 goto __err;
1469 /* clear remaining instruction memory */
1470 while (ptr < 0x400)
1471 A_OP(icode, &ptr, 0x0f, 0xc0, 0xc0, 0xcf, 0xc0);
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);
1479 __err:
1480 kfree(controls);
1481 if (icode != NULL) {
1482 kfree((void __force *)icode->gpr_map);
1483 kfree(icode);
1485 return err;
1490 * initial DSP configuration for Emu10k1
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)
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);
1502 static void __devinit _volume_add(struct snd_emu10k1_fx8010_code *icode, u32 *ptr, u32 dst, u32 src, u32 vol)
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);
1510 static void __devinit _volume_out(struct snd_emu10k1_fx8010_code *icode, u32 *ptr, u32 dst, u32 src, u32 vol)
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);
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))
1541 static int __devinit _snd_emu10k1_init_efx(struct snd_emu10k1 *emu)
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;
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;
1563 gpr_map = (u32 __force *)icode->gpr_map;
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;
1569 /* clear free GPRs */
1570 for (i = 0; i < 256; i++)
1571 set_bit(i, icode->gpr_valid);
1573 /* clear TRAM data & address lines */
1574 for (i = 0; i < 160; i++)
1575 set_bit(i, icode->tram_valid);
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 */
1587 /* stop FX processor */
1588 snd_emu10k1_ptr_write(emu, DBG, 0, (emu->fx8010.dbg = 0) | EMU10K1_DBG_SINGLE_STEP);
1591 * Process FX Buses
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);
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;
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;
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);
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);
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));
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));
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);
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);
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);
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);
1681 /* 24: */
1682 gpr += 13;
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;
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;
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);
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);
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;
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;
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);
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;
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;
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);
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;
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);
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);
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;
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);
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;
1767 * Process inputs
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);
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;
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);
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;
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;
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);
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;
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;
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);
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;
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;
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);
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;
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;
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);
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;
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;
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);
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;
1887 * Process tone control
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 */
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;
1915 #define BASS_GPR 0x8c
1916 #define TREBLE_GPR 0x96
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;
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;
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);
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);
1946 OP(icode, &ptr, iACC3, GPR(d), GPR(l+2), C_00000000, C_00000000);
1948 if (z == 2) /* center */
1949 break;
1952 i += 2;
1954 #undef BASS_GPR
1955 #undef TREBLE_GPR
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);
1963 snd_emu10k1_init_stereo_onoff_control(controls + i++, "Tone Control - Switch", gpr, 0);
1964 gpr += 2;
1967 * Process outputs
1969 if (emu->fx8010.extout_mask & ((1<<EXTOUT_AC97_L)|(1<<EXTOUT_AC97_R))) {
1970 /* AC'97 Playback Volume */
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);
1976 if (emu->fx8010.extout_mask & ((1<<EXTOUT_TOSLINK_L)|(1<<EXTOUT_TOSLINK_R))) {
1977 /* IEC958 Optical Raw Playback Switch */
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
1989 snd_emu10k1_init_stereo_onoff_control(controls + i++, SNDRV_CTL_NAME_IEC958("Optical Raw ",PLAYBACK,SWITCH), gpr, 0);
1990 gpr += 2;
1993 if (emu->fx8010.extout_mask & ((1<<EXTOUT_HEADPHONE_L)|(1<<EXTOUT_HEADPHONE_R))) {
1994 /* Headphone Playback Volume */
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);
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;
2011 gpr += 4;
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);
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);
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
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
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
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);
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.
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.
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));
2073 if (gpr > tmp) {
2074 snd_BUG();
2075 err = -EIO;
2076 goto __err;
2078 if (i > SND_EMU10K1_GPR_CONTROLS) {
2079 snd_BUG();
2080 err = -EIO;
2081 goto __err;
2084 /* clear remaining instruction memory */
2085 while (ptr < 0x200)
2086 OP(icode, &ptr, iACC3, C_00000000, C_00000000, C_00000000, C_00000000);
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);
2104 return err;
2107 int __devinit snd_emu10k1_init_efx(struct snd_emu10k1 *emu)
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);
2117 void snd_emu10k1_free_efx(struct snd_emu10k1 *emu)
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);
2126 #if 0 // FIXME: who use them?
2127 int snd_emu10k1_fx8010_tone_control_activate(struct snd_emu10k1 *emu, int output)
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;
2135 int snd_emu10k1_fx8010_tone_control_deactivate(struct snd_emu10k1 *emu, int output)
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;
2142 #endif
2144 int snd_emu10k1_fx8010_tram_setup(struct snd_emu10k1 *emu, u32 size)
2146 u8 size_reg = 0;
2148 /* size is in samples */
2149 if (size != 0) {
2150 size = (size - 1) >> 13;
2152 while (size) {
2153 size >>= 1;
2154 size_reg++;
2156 size = 0x2000 << size_reg;
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;
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);
2183 return 0;
2186 static int snd_emu10k1_fx8010_open(struct snd_hwdep * hw, struct file *file)
2188 return 0;
2191 static void copy_string(char *dst, char *src, char *null, int idx)
2193 if (src == NULL)
2194 sprintf(dst, "%s %02X", null, idx);
2195 else
2196 strcpy(dst, src);
2199 static int snd_emu10k1_fx8010_info(struct snd_emu10k1 *emu,
2200 struct snd_emu10k1_fx8010_info *info)
2202 char **fxbus, **extin, **extout;
2203 unsigned short fxbus_mask, extin_mask, extout_mask;
2204 int res;
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);
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;
2226 static int snd_emu10k1_fx8010_ioctl(struct snd_hwdep * hw, struct file *file, unsigned int cmd, unsigned long arg)
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;
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;
2245 if (copy_to_user(argp, info, sizeof(*info))) {
2246 kfree(info);
2247 return -EFAULT;
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;
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;
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;
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;
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;
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;
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;
2369 return -ENOTTY;
2372 static int snd_emu10k1_fx8010_release(struct snd_hwdep * hw, struct file *file)
2374 return 0;
2377 int __devinit snd_emu10k1_fx8010_new(struct snd_emu10k1 *emu, int device, struct snd_hwdep ** rhwdep)
2379 struct snd_hwdep *hw;
2380 int err;
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;
2397 #ifdef CONFIG_PM
2398 int __devinit snd_emu10k1_efx_alloc_pm_buffer(struct snd_emu10k1 *emu)
2400 int len;
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;
2418 void snd_emu10k1_efx_free_pm_buffer(struct snd_emu10k1 *emu)
2420 kfree(emu->saved_gpr);
2421 kfree(emu->tram_val_saved);
2422 kfree(emu->tram_addr_saved);
2423 vfree(emu->saved_icode);
2427 * save/restore GPR, TRAM and codes
2429 void snd_emu10k1_efx_suspend(struct snd_emu10k1 *emu)
2431 int i, len;
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);
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;
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);
2453 void snd_emu10k1_efx_resume(struct snd_emu10k1 *emu)
2455 int i, len;
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++;
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);
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);
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]);
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);
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]);
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);
2506 #endif