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