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