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