net: dsa: Allow DSA and CPU ports to have a phy-mode property
[linux/fpc-iii.git] / sound / pci / emu10k1 / emufx.c
blob56fc47bd6dbab381ad6b9453fbf1c4cb2e23ceb1
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>
38 #include <linux/moduleparam.h>
40 #include <sound/core.h>
41 #include <sound/tlv.h>
42 #include <sound/emu10k1.h>
44 #if 0 /* for testing purposes - digital out -> capture */
45 #define EMU10K1_CAPTURE_DIGITAL_OUT
46 #endif
47 #if 0 /* for testing purposes - set S/PDIF to AC3 output */
48 #define EMU10K1_SET_AC3_IEC958
49 #endif
50 #if 0 /* for testing purposes - feed the front signal to Center/LFE outputs */
51 #define EMU10K1_CENTER_LFE_FROM_FRONT
52 #endif
54 static bool high_res_gpr_volume;
55 module_param(high_res_gpr_volume, bool, 0444);
56 MODULE_PARM_DESC(high_res_gpr_volume, "GPR mixer controls use 31-bit range.");
59 * Tables
60 */
62 static char *fxbuses[16] = {
63 /* 0x00 */ "PCM Left",
64 /* 0x01 */ "PCM Right",
65 /* 0x02 */ "PCM Surround Left",
66 /* 0x03 */ "PCM Surround Right",
67 /* 0x04 */ "MIDI Left",
68 /* 0x05 */ "MIDI Right",
69 /* 0x06 */ "Center",
70 /* 0x07 */ "LFE",
71 /* 0x08 */ NULL,
72 /* 0x09 */ NULL,
73 /* 0x0a */ NULL,
74 /* 0x0b */ NULL,
75 /* 0x0c */ "MIDI Reverb",
76 /* 0x0d */ "MIDI Chorus",
77 /* 0x0e */ NULL,
78 /* 0x0f */ NULL
81 static char *creative_ins[16] = {
82 /* 0x00 */ "AC97 Left",
83 /* 0x01 */ "AC97 Right",
84 /* 0x02 */ "TTL IEC958 Left",
85 /* 0x03 */ "TTL IEC958 Right",
86 /* 0x04 */ "Zoom Video Left",
87 /* 0x05 */ "Zoom Video Right",
88 /* 0x06 */ "Optical IEC958 Left",
89 /* 0x07 */ "Optical IEC958 Right",
90 /* 0x08 */ "Line/Mic 1 Left",
91 /* 0x09 */ "Line/Mic 1 Right",
92 /* 0x0a */ "Coaxial IEC958 Left",
93 /* 0x0b */ "Coaxial IEC958 Right",
94 /* 0x0c */ "Line/Mic 2 Left",
95 /* 0x0d */ "Line/Mic 2 Right",
96 /* 0x0e */ NULL,
97 /* 0x0f */ NULL
100 static char *audigy_ins[16] = {
101 /* 0x00 */ "AC97 Left",
102 /* 0x01 */ "AC97 Right",
103 /* 0x02 */ "Audigy CD Left",
104 /* 0x03 */ "Audigy CD Right",
105 /* 0x04 */ "Optical IEC958 Left",
106 /* 0x05 */ "Optical IEC958 Right",
107 /* 0x06 */ NULL,
108 /* 0x07 */ NULL,
109 /* 0x08 */ "Line/Mic 2 Left",
110 /* 0x09 */ "Line/Mic 2 Right",
111 /* 0x0a */ "SPDIF Left",
112 /* 0x0b */ "SPDIF Right",
113 /* 0x0c */ "Aux2 Left",
114 /* 0x0d */ "Aux2 Right",
115 /* 0x0e */ NULL,
116 /* 0x0f */ NULL
119 static char *creative_outs[32] = {
120 /* 0x00 */ "AC97 Left",
121 /* 0x01 */ "AC97 Right",
122 /* 0x02 */ "Optical IEC958 Left",
123 /* 0x03 */ "Optical IEC958 Right",
124 /* 0x04 */ "Center",
125 /* 0x05 */ "LFE",
126 /* 0x06 */ "Headphone Left",
127 /* 0x07 */ "Headphone Right",
128 /* 0x08 */ "Surround Left",
129 /* 0x09 */ "Surround Right",
130 /* 0x0a */ "PCM Capture Left",
131 /* 0x0b */ "PCM Capture Right",
132 /* 0x0c */ "MIC Capture",
133 /* 0x0d */ "AC97 Surround Left",
134 /* 0x0e */ "AC97 Surround Right",
135 /* 0x0f */ NULL,
136 /* 0x10 */ NULL,
137 /* 0x11 */ "Analog Center",
138 /* 0x12 */ "Analog LFE",
139 /* 0x13 */ NULL,
140 /* 0x14 */ NULL,
141 /* 0x15 */ NULL,
142 /* 0x16 */ NULL,
143 /* 0x17 */ NULL,
144 /* 0x18 */ NULL,
145 /* 0x19 */ NULL,
146 /* 0x1a */ NULL,
147 /* 0x1b */ NULL,
148 /* 0x1c */ NULL,
149 /* 0x1d */ NULL,
150 /* 0x1e */ NULL,
151 /* 0x1f */ NULL,
154 static char *audigy_outs[32] = {
155 /* 0x00 */ "Digital Front Left",
156 /* 0x01 */ "Digital Front Right",
157 /* 0x02 */ "Digital Center",
158 /* 0x03 */ "Digital LEF",
159 /* 0x04 */ "Headphone Left",
160 /* 0x05 */ "Headphone Right",
161 /* 0x06 */ "Digital Rear Left",
162 /* 0x07 */ "Digital Rear Right",
163 /* 0x08 */ "Front Left",
164 /* 0x09 */ "Front Right",
165 /* 0x0a */ "Center",
166 /* 0x0b */ "LFE",
167 /* 0x0c */ NULL,
168 /* 0x0d */ NULL,
169 /* 0x0e */ "Rear Left",
170 /* 0x0f */ "Rear Right",
171 /* 0x10 */ "AC97 Front Left",
172 /* 0x11 */ "AC97 Front Right",
173 /* 0x12 */ "ADC Caputre Left",
174 /* 0x13 */ "ADC Capture Right",
175 /* 0x14 */ NULL,
176 /* 0x15 */ NULL,
177 /* 0x16 */ NULL,
178 /* 0x17 */ NULL,
179 /* 0x18 */ NULL,
180 /* 0x19 */ NULL,
181 /* 0x1a */ NULL,
182 /* 0x1b */ NULL,
183 /* 0x1c */ NULL,
184 /* 0x1d */ NULL,
185 /* 0x1e */ NULL,
186 /* 0x1f */ NULL,
189 static const u32 bass_table[41][5] = {
190 { 0x3e4f844f, 0x84ed4cc3, 0x3cc69927, 0x7b03553a, 0xc4da8486 },
191 { 0x3e69a17a, 0x84c280fb, 0x3cd77cd4, 0x7b2f2a6f, 0xc4b08d1d },
192 { 0x3e82ff42, 0x849991d5, 0x3ce7466b, 0x7b5917c6, 0xc48863ee },
193 { 0x3e9bab3c, 0x847267f0, 0x3cf5ffe8, 0x7b813560, 0xc461f22c },
194 { 0x3eb3b275, 0x844ced29, 0x3d03b295, 0x7ba79a1c, 0xc43d223b },
195 { 0x3ecb2174, 0x84290c8b, 0x3d106714, 0x7bcc5ba3, 0xc419dfa5 },
196 { 0x3ee2044b, 0x8406b244, 0x3d1c2561, 0x7bef8e77, 0xc3f8170f },
197 { 0x3ef86698, 0x83e5cb96, 0x3d26f4d8, 0x7c114600, 0xc3d7b625 },
198 { 0x3f0e5390, 0x83c646c9, 0x3d30dc39, 0x7c319498, 0xc3b8ab97 },
199 { 0x3f23d60b, 0x83a81321, 0x3d39e1af, 0x7c508b9c, 0xc39ae704 },
200 { 0x3f38f884, 0x838b20d2, 0x3d420ad2, 0x7c6e3b75, 0xc37e58f1 },
201 { 0x3f4dc52c, 0x836f60ef, 0x3d495cab, 0x7c8ab3a6, 0xc362f2be },
202 { 0x3f6245e8, 0x8354c565, 0x3d4fdbb8, 0x7ca602d6, 0xc348a69b },
203 { 0x3f76845f, 0x833b40ec, 0x3d558bf0, 0x7cc036df, 0xc32f677c },
204 { 0x3f8a8a03, 0x8322c6fb, 0x3d5a70c4, 0x7cd95cd7, 0xc317290b },
205 { 0x3f9e6014, 0x830b4bc3, 0x3d5e8d25, 0x7cf1811a, 0xc2ffdfa5 },
206 { 0x3fb20fae, 0x82f4c420, 0x3d61e37f, 0x7d08af56, 0xc2e9804a },
207 { 0x3fc5a1cc, 0x82df2592, 0x3d6475c3, 0x7d1ef294, 0xc2d40096 },
208 { 0x3fd91f55, 0x82ca6632, 0x3d664564, 0x7d345541, 0xc2bf56b9 },
209 { 0x3fec9120, 0x82b67cac, 0x3d675356, 0x7d48e138, 0xc2ab796e },
210 { 0x40000000, 0x82a36037, 0x3d67a012, 0x7d5c9fc9, 0xc2985fee },
211 { 0x401374c7, 0x8291088a, 0x3d672b93, 0x7d6f99c3, 0xc28601f2 },
212 { 0x4026f857, 0x827f6dd7, 0x3d65f559, 0x7d81d77c, 0xc27457a3 },
213 { 0x403a939f, 0x826e88c5, 0x3d63fc63, 0x7d9360d4, 0xc2635996 },
214 { 0x404e4faf, 0x825e5266, 0x3d613f32, 0x7da43d42, 0xc25300c6 },
215 { 0x406235ba, 0x824ec434, 0x3d5dbbc3, 0x7db473d7, 0xc243468e },
216 { 0x40764f1f, 0x823fd80c, 0x3d596f8f, 0x7dc40b44, 0xc23424a2 },
217 { 0x408aa576, 0x82318824, 0x3d545787, 0x7dd309e2, 0xc2259509 },
218 { 0x409f4296, 0x8223cf0b, 0x3d4e7012, 0x7de175b5, 0xc2179218 },
219 { 0x40b430a0, 0x8216a7a1, 0x3d47b505, 0x7def5475, 0xc20a1670 },
220 { 0x40c97a0a, 0x820a0d12, 0x3d4021a1, 0x7dfcab8d, 0xc1fd1cf5 },
221 { 0x40df29a6, 0x81fdfad6, 0x3d37b08d, 0x7e098028, 0xc1f0a0ca },
222 { 0x40f54ab1, 0x81f26ca9, 0x3d2e5bd1, 0x7e15d72b, 0xc1e49d52 },
223 { 0x410be8da, 0x81e75e89, 0x3d241cce, 0x7e21b544, 0xc1d90e24 },
224 { 0x41231051, 0x81dcccb3, 0x3d18ec37, 0x7e2d1ee6, 0xc1cdef10 },
225 { 0x413acdd0, 0x81d2b39e, 0x3d0cc20a, 0x7e38184e, 0xc1c33c13 },
226 { 0x41532ea7, 0x81c90ffb, 0x3cff9585, 0x7e42a58b, 0xc1b8f15a },
227 { 0x416c40cd, 0x81bfdeb2, 0x3cf15d21, 0x7e4cca7c, 0xc1af0b3f },
228 { 0x418612ea, 0x81b71cdc, 0x3ce20e85, 0x7e568ad3, 0xc1a58640 },
229 { 0x41a0b465, 0x81aec7c5, 0x3cd19e7c, 0x7e5fea1e, 0xc19c5f03 },
230 { 0x41bc3573, 0x81a6dcea, 0x3cc000e9, 0x7e68ebc2, 0xc1939250 }
233 static const u32 treble_table[41][5] = {
234 { 0x0125cba9, 0xfed5debd, 0x00599b6c, 0x0d2506da, 0xfa85b354 },
235 { 0x0142f67e, 0xfeb03163, 0x0066cd0f, 0x0d14c69d, 0xfa914473 },
236 { 0x016328bd, 0xfe860158, 0x0075b7f2, 0x0d03eb27, 0xfa9d32d2 },
237 { 0x0186b438, 0xfe56c982, 0x00869234, 0x0cf27048, 0xfaa97fca },
238 { 0x01adf358, 0xfe21f5fe, 0x00999842, 0x0ce051c2, 0xfab62ca5 },
239 { 0x01d949fa, 0xfde6e287, 0x00af0d8d, 0x0ccd8b4a, 0xfac33aa7 },
240 { 0x02092669, 0xfda4d8bf, 0x00c73d4c, 0x0cba1884, 0xfad0ab07 },
241 { 0x023e0268, 0xfd5b0e4a, 0x00e27b54, 0x0ca5f509, 0xfade7ef2 },
242 { 0x0278645c, 0xfd08a2b0, 0x01012509, 0x0c911c63, 0xfaecb788 },
243 { 0x02b8e091, 0xfcac9d1a, 0x0123a262, 0x0c7b8a14, 0xfafb55df },
244 { 0x03001a9a, 0xfc45e9ce, 0x014a6709, 0x0c65398f, 0xfb0a5aff },
245 { 0x034ec6d7, 0xfbd3576b, 0x0175f397, 0x0c4e2643, 0xfb19c7e4 },
246 { 0x03a5ac15, 0xfb5393ee, 0x01a6d6ed, 0x0c364b94, 0xfb299d7c },
247 { 0x0405a562, 0xfac52968, 0x01ddafae, 0x0c1da4e2, 0xfb39dca5 },
248 { 0x046fa3fe, 0xfa267a66, 0x021b2ddd, 0x0c042d8d, 0xfb4a8631 },
249 { 0x04e4b17f, 0xf975be0f, 0x0260149f, 0x0be9e0f2, 0xfb5b9ae0 },
250 { 0x0565f220, 0xf8b0fbe5, 0x02ad3c29, 0x0bceba73, 0xfb6d1b60 },
251 { 0x05f4a745, 0xf7d60722, 0x030393d4, 0x0bb2b578, 0xfb7f084d },
252 { 0x06923236, 0xf6e279bd, 0x03642465, 0x0b95cd75, 0xfb916233 },
253 { 0x07401713, 0xf5d3aef9, 0x03d01283, 0x0b77fded, 0xfba42984 },
254 { 0x08000000, 0xf4a6bd88, 0x0448a161, 0x0b594278, 0xfbb75e9f },
255 { 0x08d3c097, 0xf3587131, 0x04cf35a4, 0x0b3996c9, 0xfbcb01cb },
256 { 0x09bd59a2, 0xf1e543f9, 0x05655880, 0x0b18f6b2, 0xfbdf1333 },
257 { 0x0abefd0f, 0xf04956ca, 0x060cbb12, 0x0af75e2c, 0xfbf392e8 },
258 { 0x0bdb123e, 0xee806984, 0x06c739fe, 0x0ad4c962, 0xfc0880dd },
259 { 0x0d143a94, 0xec85d287, 0x0796e150, 0x0ab134b0, 0xfc1ddce5 },
260 { 0x0e6d5664, 0xea547598, 0x087df0a0, 0x0a8c9cb6, 0xfc33a6ad },
261 { 0x0fe98a2a, 0xe7e6ba35, 0x097edf83, 0x0a66fe5b, 0xfc49ddc2 },
262 { 0x118c4421, 0xe536813a, 0x0a9c6248, 0x0a4056d7, 0xfc608185 },
263 { 0x1359422e, 0xe23d19eb, 0x0bd96efb, 0x0a18a3bf, 0xfc77912c },
264 { 0x1554982b, 0xdef33645, 0x0d3942bd, 0x09efe312, 0xfc8f0bc1 },
265 { 0x1782b68a, 0xdb50deb1, 0x0ebf676d, 0x09c6133f, 0xfca6f019 },
266 { 0x19e8715d, 0xd74d64fd, 0x106fb999, 0x099b3337, 0xfcbf3cd6 },
267 { 0x1c8b07b8, 0xd2df56ab, 0x124e6ec8, 0x096f4274, 0xfcd7f060 },
268 { 0x1f702b6d, 0xcdfc6e92, 0x14601c10, 0x0942410b, 0xfcf108e5 },
269 { 0x229e0933, 0xc89985cd, 0x16a9bcfa, 0x09142fb5, 0xfd0a8451 },
270 { 0x261b5118, 0xc2aa8409, 0x1930bab6, 0x08e50fdc, 0xfd24604d },
271 { 0x29ef3f5d, 0xbc224f28, 0x1bfaf396, 0x08b4e3aa, 0xfd3e9a3b },
272 { 0x2e21a59b, 0xb4f2ba46, 0x1f0ec2d6, 0x0883ae15, 0xfd592f33 },
273 { 0x32baf44b, 0xad0c7429, 0x227308a3, 0x085172eb, 0xfd741bfd },
274 { 0x37c4448b, 0xa45ef51d, 0x262f3267, 0x081e36dc, 0xfd8f5d14 }
277 /* dB gain = (float) 20 * log10( float(db_table_value) / 0x8000000 ) */
278 static const u32 db_table[101] = {
279 0x00000000, 0x01571f82, 0x01674b41, 0x01783a1b, 0x0189f540,
280 0x019c8651, 0x01aff763, 0x01c45306, 0x01d9a446, 0x01eff6b8,
281 0x0207567a, 0x021fd03d, 0x0239714c, 0x02544792, 0x027061a1,
282 0x028dcebb, 0x02ac9edc, 0x02cce2bf, 0x02eeabe8, 0x03120cb0,
283 0x0337184e, 0x035de2df, 0x03868173, 0x03b10a18, 0x03dd93e9,
284 0x040c3713, 0x043d0cea, 0x04702ff3, 0x04a5bbf2, 0x04ddcdfb,
285 0x0518847f, 0x0555ff62, 0x05966005, 0x05d9c95d, 0x06206005,
286 0x066a4a52, 0x06b7b067, 0x0708bc4c, 0x075d9a01, 0x07b6779d,
287 0x08138561, 0x0874f5d5, 0x08dafde1, 0x0945d4ed, 0x09b5b4fd,
288 0x0a2adad1, 0x0aa58605, 0x0b25f936, 0x0bac7a24, 0x0c3951d8,
289 0x0ccccccc, 0x0d673b17, 0x0e08f093, 0x0eb24510, 0x0f639481,
290 0x101d3f2d, 0x10dfa9e6, 0x11ab3e3f, 0x12806ac3, 0x135fa333,
291 0x144960c5, 0x153e2266, 0x163e6cfe, 0x174acbb7, 0x1863d04d,
292 0x198a1357, 0x1abe349f, 0x1c00db77, 0x1d52b712, 0x1eb47ee6,
293 0x2026f30f, 0x21aadcb6, 0x23410e7e, 0x24ea64f9, 0x26a7c71d,
294 0x287a26c4, 0x2a62812c, 0x2c61df84, 0x2e795779, 0x30aa0bcf,
295 0x32f52cfe, 0x355bf9d8, 0x37dfc033, 0x3a81dda4, 0x3d43c038,
296 0x4026e73c, 0x432ce40f, 0x46575af8, 0x49a8040f, 0x4d20ac2a,
297 0x50c335d3, 0x54919a57, 0x588dead1, 0x5cba514a, 0x611911ea,
298 0x65ac8c2f, 0x6a773c39, 0x6f7bbc23, 0x74bcc56c, 0x7a3d3272,
299 0x7fffffff,
302 /* EMU10k1/EMU10k2 DSP control db gain */
303 static const DECLARE_TLV_DB_SCALE(snd_emu10k1_db_scale1, -4000, 40, 1);
304 static const DECLARE_TLV_DB_LINEAR(snd_emu10k1_db_linear, TLV_DB_GAIN_MUTE, 0);
306 /* EMU10K1 bass/treble db gain */
307 static const DECLARE_TLV_DB_SCALE(snd_emu10k1_bass_treble_db_scale, -1200, 60, 0);
309 static const u32 onoff_table[2] = {
310 0x00000000, 0x00000001
316 static inline mm_segment_t snd_enter_user(void)
318 mm_segment_t fs = get_fs();
319 set_fs(get_ds());
320 return fs;
323 static inline void snd_leave_user(mm_segment_t fs)
325 set_fs(fs);
329 * controls
332 static int snd_emu10k1_gpr_ctl_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
334 struct snd_emu10k1_fx8010_ctl *ctl =
335 (struct snd_emu10k1_fx8010_ctl *) kcontrol->private_value;
337 if (ctl->min == 0 && ctl->max == 1)
338 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
339 else
340 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
341 uinfo->count = ctl->vcount;
342 uinfo->value.integer.min = ctl->min;
343 uinfo->value.integer.max = ctl->max;
344 return 0;
347 static int snd_emu10k1_gpr_ctl_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
349 struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
350 struct snd_emu10k1_fx8010_ctl *ctl =
351 (struct snd_emu10k1_fx8010_ctl *) kcontrol->private_value;
352 unsigned long flags;
353 unsigned int i;
355 spin_lock_irqsave(&emu->reg_lock, flags);
356 for (i = 0; i < ctl->vcount; i++)
357 ucontrol->value.integer.value[i] = ctl->value[i];
358 spin_unlock_irqrestore(&emu->reg_lock, flags);
359 return 0;
362 static int snd_emu10k1_gpr_ctl_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
364 struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
365 struct snd_emu10k1_fx8010_ctl *ctl =
366 (struct snd_emu10k1_fx8010_ctl *) kcontrol->private_value;
367 unsigned long flags;
368 unsigned int nval, val;
369 unsigned int i, j;
370 int change = 0;
372 spin_lock_irqsave(&emu->reg_lock, flags);
373 for (i = 0; i < ctl->vcount; i++) {
374 nval = ucontrol->value.integer.value[i];
375 if (nval < ctl->min)
376 nval = ctl->min;
377 if (nval > ctl->max)
378 nval = ctl->max;
379 if (nval != ctl->value[i])
380 change = 1;
381 val = ctl->value[i] = nval;
382 switch (ctl->translation) {
383 case EMU10K1_GPR_TRANSLATION_NONE:
384 snd_emu10k1_ptr_write(emu, emu->gpr_base + ctl->gpr[i], 0, val);
385 break;
386 case EMU10K1_GPR_TRANSLATION_TABLE100:
387 snd_emu10k1_ptr_write(emu, emu->gpr_base + ctl->gpr[i], 0, db_table[val]);
388 break;
389 case EMU10K1_GPR_TRANSLATION_BASS:
390 if ((ctl->count % 5) != 0 || (ctl->count / 5) != ctl->vcount) {
391 change = -EIO;
392 goto __error;
394 for (j = 0; j < 5; j++)
395 snd_emu10k1_ptr_write(emu, emu->gpr_base + ctl->gpr[j * ctl->vcount + i], 0, bass_table[val][j]);
396 break;
397 case EMU10K1_GPR_TRANSLATION_TREBLE:
398 if ((ctl->count % 5) != 0 || (ctl->count / 5) != ctl->vcount) {
399 change = -EIO;
400 goto __error;
402 for (j = 0; j < 5; j++)
403 snd_emu10k1_ptr_write(emu, emu->gpr_base + ctl->gpr[j * ctl->vcount + i], 0, treble_table[val][j]);
404 break;
405 case EMU10K1_GPR_TRANSLATION_ONOFF:
406 snd_emu10k1_ptr_write(emu, emu->gpr_base + ctl->gpr[i], 0, onoff_table[val]);
407 break;
410 __error:
411 spin_unlock_irqrestore(&emu->reg_lock, flags);
412 return change;
416 * Interrupt handler
419 static void snd_emu10k1_fx8010_interrupt(struct snd_emu10k1 *emu)
421 struct snd_emu10k1_fx8010_irq *irq, *nirq;
423 irq = emu->fx8010.irq_handlers;
424 while (irq) {
425 nirq = irq->next; /* irq ptr can be removed from list */
426 if (snd_emu10k1_ptr_read(emu, emu->gpr_base + irq->gpr_running, 0) & 0xffff0000) {
427 if (irq->handler)
428 irq->handler(emu, irq->private_data);
429 snd_emu10k1_ptr_write(emu, emu->gpr_base + irq->gpr_running, 0, 1);
431 irq = nirq;
435 int snd_emu10k1_fx8010_register_irq_handler(struct snd_emu10k1 *emu,
436 snd_fx8010_irq_handler_t *handler,
437 unsigned char gpr_running,
438 void *private_data,
439 struct snd_emu10k1_fx8010_irq **r_irq)
441 struct snd_emu10k1_fx8010_irq *irq;
442 unsigned long flags;
444 irq = kmalloc(sizeof(*irq), GFP_ATOMIC);
445 if (irq == NULL)
446 return -ENOMEM;
447 irq->handler = handler;
448 irq->gpr_running = gpr_running;
449 irq->private_data = private_data;
450 irq->next = NULL;
451 spin_lock_irqsave(&emu->fx8010.irq_lock, flags);
452 if (emu->fx8010.irq_handlers == NULL) {
453 emu->fx8010.irq_handlers = irq;
454 emu->dsp_interrupt = snd_emu10k1_fx8010_interrupt;
455 snd_emu10k1_intr_enable(emu, INTE_FXDSPENABLE);
456 } else {
457 irq->next = emu->fx8010.irq_handlers;
458 emu->fx8010.irq_handlers = irq;
460 spin_unlock_irqrestore(&emu->fx8010.irq_lock, flags);
461 if (r_irq)
462 *r_irq = irq;
463 return 0;
466 int snd_emu10k1_fx8010_unregister_irq_handler(struct snd_emu10k1 *emu,
467 struct snd_emu10k1_fx8010_irq *irq)
469 struct snd_emu10k1_fx8010_irq *tmp;
470 unsigned long flags;
472 spin_lock_irqsave(&emu->fx8010.irq_lock, flags);
473 if ((tmp = emu->fx8010.irq_handlers) == irq) {
474 emu->fx8010.irq_handlers = tmp->next;
475 if (emu->fx8010.irq_handlers == NULL) {
476 snd_emu10k1_intr_disable(emu, INTE_FXDSPENABLE);
477 emu->dsp_interrupt = NULL;
479 } else {
480 while (tmp && tmp->next != irq)
481 tmp = tmp->next;
482 if (tmp)
483 tmp->next = tmp->next->next;
485 spin_unlock_irqrestore(&emu->fx8010.irq_lock, flags);
486 kfree(irq);
487 return 0;
490 /*************************************************************************
491 * EMU10K1 effect manager
492 *************************************************************************/
494 static void snd_emu10k1_write_op(struct snd_emu10k1_fx8010_code *icode,
495 unsigned int *ptr,
496 u32 op, u32 r, u32 a, u32 x, u32 y)
498 u_int32_t *code;
499 if (snd_BUG_ON(*ptr >= 512))
500 return;
501 code = (u_int32_t __force *)icode->code + (*ptr) * 2;
502 set_bit(*ptr, icode->code_valid);
503 code[0] = ((x & 0x3ff) << 10) | (y & 0x3ff);
504 code[1] = ((op & 0x0f) << 20) | ((r & 0x3ff) << 10) | (a & 0x3ff);
505 (*ptr)++;
508 #define OP(icode, ptr, op, r, a, x, y) \
509 snd_emu10k1_write_op(icode, ptr, op, r, a, x, y)
511 static void snd_emu10k1_audigy_write_op(struct snd_emu10k1_fx8010_code *icode,
512 unsigned int *ptr,
513 u32 op, u32 r, u32 a, u32 x, u32 y)
515 u_int32_t *code;
516 if (snd_BUG_ON(*ptr >= 1024))
517 return;
518 code = (u_int32_t __force *)icode->code + (*ptr) * 2;
519 set_bit(*ptr, icode->code_valid);
520 code[0] = ((x & 0x7ff) << 12) | (y & 0x7ff);
521 code[1] = ((op & 0x0f) << 24) | ((r & 0x7ff) << 12) | (a & 0x7ff);
522 (*ptr)++;
525 #define A_OP(icode, ptr, op, r, a, x, y) \
526 snd_emu10k1_audigy_write_op(icode, ptr, op, r, a, x, y)
528 static void snd_emu10k1_efx_write(struct snd_emu10k1 *emu, unsigned int pc, unsigned int data)
530 pc += emu->audigy ? A_MICROCODEBASE : MICROCODEBASE;
531 snd_emu10k1_ptr_write(emu, pc, 0, data);
534 unsigned int snd_emu10k1_efx_read(struct snd_emu10k1 *emu, unsigned int pc)
536 pc += emu->audigy ? A_MICROCODEBASE : MICROCODEBASE;
537 return snd_emu10k1_ptr_read(emu, pc, 0);
540 static int snd_emu10k1_gpr_poke(struct snd_emu10k1 *emu,
541 struct snd_emu10k1_fx8010_code *icode)
543 int gpr;
544 u32 val;
546 for (gpr = 0; gpr < (emu->audigy ? 0x200 : 0x100); gpr++) {
547 if (!test_bit(gpr, icode->gpr_valid))
548 continue;
549 if (get_user(val, &icode->gpr_map[gpr]))
550 return -EFAULT;
551 snd_emu10k1_ptr_write(emu, emu->gpr_base + gpr, 0, val);
553 return 0;
556 static int snd_emu10k1_gpr_peek(struct snd_emu10k1 *emu,
557 struct snd_emu10k1_fx8010_code *icode)
559 int gpr;
560 u32 val;
562 for (gpr = 0; gpr < (emu->audigy ? 0x200 : 0x100); gpr++) {
563 set_bit(gpr, icode->gpr_valid);
564 val = snd_emu10k1_ptr_read(emu, emu->gpr_base + gpr, 0);
565 if (put_user(val, &icode->gpr_map[gpr]))
566 return -EFAULT;
568 return 0;
571 static int snd_emu10k1_tram_poke(struct snd_emu10k1 *emu,
572 struct snd_emu10k1_fx8010_code *icode)
574 int tram;
575 u32 addr, val;
577 for (tram = 0; tram < (emu->audigy ? 0x100 : 0xa0); tram++) {
578 if (!test_bit(tram, icode->tram_valid))
579 continue;
580 if (get_user(val, &icode->tram_data_map[tram]) ||
581 get_user(addr, &icode->tram_addr_map[tram]))
582 return -EFAULT;
583 snd_emu10k1_ptr_write(emu, TANKMEMDATAREGBASE + tram, 0, val);
584 if (!emu->audigy) {
585 snd_emu10k1_ptr_write(emu, TANKMEMADDRREGBASE + tram, 0, addr);
586 } else {
587 snd_emu10k1_ptr_write(emu, TANKMEMADDRREGBASE + tram, 0, addr << 12);
588 snd_emu10k1_ptr_write(emu, A_TANKMEMCTLREGBASE + tram, 0, addr >> 20);
591 return 0;
594 static int snd_emu10k1_tram_peek(struct snd_emu10k1 *emu,
595 struct snd_emu10k1_fx8010_code *icode)
597 int tram;
598 u32 val, addr;
600 memset(icode->tram_valid, 0, sizeof(icode->tram_valid));
601 for (tram = 0; tram < (emu->audigy ? 0x100 : 0xa0); tram++) {
602 set_bit(tram, icode->tram_valid);
603 val = snd_emu10k1_ptr_read(emu, TANKMEMDATAREGBASE + tram, 0);
604 if (!emu->audigy) {
605 addr = snd_emu10k1_ptr_read(emu, TANKMEMADDRREGBASE + tram, 0);
606 } else {
607 addr = snd_emu10k1_ptr_read(emu, TANKMEMADDRREGBASE + tram, 0) >> 12;
608 addr |= snd_emu10k1_ptr_read(emu, A_TANKMEMCTLREGBASE + tram, 0) << 20;
610 if (put_user(val, &icode->tram_data_map[tram]) ||
611 put_user(addr, &icode->tram_addr_map[tram]))
612 return -EFAULT;
614 return 0;
617 static int snd_emu10k1_code_poke(struct snd_emu10k1 *emu,
618 struct snd_emu10k1_fx8010_code *icode)
620 u32 pc, lo, hi;
622 for (pc = 0; pc < (emu->audigy ? 2*1024 : 2*512); pc += 2) {
623 if (!test_bit(pc / 2, icode->code_valid))
624 continue;
625 if (get_user(lo, &icode->code[pc + 0]) ||
626 get_user(hi, &icode->code[pc + 1]))
627 return -EFAULT;
628 snd_emu10k1_efx_write(emu, pc + 0, lo);
629 snd_emu10k1_efx_write(emu, pc + 1, hi);
631 return 0;
634 static int snd_emu10k1_code_peek(struct snd_emu10k1 *emu,
635 struct snd_emu10k1_fx8010_code *icode)
637 u32 pc;
639 memset(icode->code_valid, 0, sizeof(icode->code_valid));
640 for (pc = 0; pc < (emu->audigy ? 2*1024 : 2*512); pc += 2) {
641 set_bit(pc / 2, icode->code_valid);
642 if (put_user(snd_emu10k1_efx_read(emu, pc + 0), &icode->code[pc + 0]))
643 return -EFAULT;
644 if (put_user(snd_emu10k1_efx_read(emu, pc + 1), &icode->code[pc + 1]))
645 return -EFAULT;
647 return 0;
650 static struct snd_emu10k1_fx8010_ctl *
651 snd_emu10k1_look_for_ctl(struct snd_emu10k1 *emu, struct snd_ctl_elem_id *id)
653 struct snd_emu10k1_fx8010_ctl *ctl;
654 struct snd_kcontrol *kcontrol;
656 list_for_each_entry(ctl, &emu->fx8010.gpr_ctl, list) {
657 kcontrol = ctl->kcontrol;
658 if (kcontrol->id.iface == id->iface &&
659 !strcmp(kcontrol->id.name, id->name) &&
660 kcontrol->id.index == id->index)
661 return ctl;
663 return NULL;
666 #define MAX_TLV_SIZE 256
668 static unsigned int *copy_tlv(const unsigned int __user *_tlv)
670 unsigned int data[2];
671 unsigned int *tlv;
673 if (!_tlv)
674 return NULL;
675 if (copy_from_user(data, _tlv, sizeof(data)))
676 return NULL;
677 if (data[1] >= MAX_TLV_SIZE)
678 return NULL;
679 tlv = kmalloc(data[1] + sizeof(data), GFP_KERNEL);
680 if (!tlv)
681 return NULL;
682 memcpy(tlv, data, sizeof(data));
683 if (copy_from_user(tlv + 2, _tlv + 2, data[1])) {
684 kfree(tlv);
685 return NULL;
687 return tlv;
690 static int copy_gctl(struct snd_emu10k1 *emu,
691 struct snd_emu10k1_fx8010_control_gpr *gctl,
692 struct snd_emu10k1_fx8010_control_gpr __user *_gctl,
693 int idx)
695 struct snd_emu10k1_fx8010_control_old_gpr __user *octl;
697 if (emu->support_tlv)
698 return copy_from_user(gctl, &_gctl[idx], sizeof(*gctl));
699 octl = (struct snd_emu10k1_fx8010_control_old_gpr __user *)_gctl;
700 if (copy_from_user(gctl, &octl[idx], sizeof(*octl)))
701 return -EFAULT;
702 gctl->tlv = NULL;
703 return 0;
706 static int copy_gctl_to_user(struct snd_emu10k1 *emu,
707 struct snd_emu10k1_fx8010_control_gpr __user *_gctl,
708 struct snd_emu10k1_fx8010_control_gpr *gctl,
709 int idx)
711 struct snd_emu10k1_fx8010_control_old_gpr __user *octl;
713 if (emu->support_tlv)
714 return copy_to_user(&_gctl[idx], gctl, sizeof(*gctl));
716 octl = (struct snd_emu10k1_fx8010_control_old_gpr __user *)_gctl;
717 return copy_to_user(&octl[idx], gctl, sizeof(*octl));
720 static int snd_emu10k1_verify_controls(struct snd_emu10k1 *emu,
721 struct snd_emu10k1_fx8010_code *icode)
723 unsigned int i;
724 struct snd_ctl_elem_id __user *_id;
725 struct snd_ctl_elem_id id;
726 struct snd_emu10k1_fx8010_control_gpr *gctl;
727 int err;
729 for (i = 0, _id = icode->gpr_del_controls;
730 i < icode->gpr_del_control_count; i++, _id++) {
731 if (copy_from_user(&id, _id, sizeof(id)))
732 return -EFAULT;
733 if (snd_emu10k1_look_for_ctl(emu, &id) == NULL)
734 return -ENOENT;
736 gctl = kmalloc(sizeof(*gctl), GFP_KERNEL);
737 if (! gctl)
738 return -ENOMEM;
739 err = 0;
740 for (i = 0; i < icode->gpr_add_control_count; i++) {
741 if (copy_gctl(emu, gctl, icode->gpr_add_controls, i)) {
742 err = -EFAULT;
743 goto __error;
745 if (snd_emu10k1_look_for_ctl(emu, &gctl->id))
746 continue;
747 down_read(&emu->card->controls_rwsem);
748 if (snd_ctl_find_id(emu->card, &gctl->id) != NULL) {
749 up_read(&emu->card->controls_rwsem);
750 err = -EEXIST;
751 goto __error;
753 up_read(&emu->card->controls_rwsem);
754 if (gctl->id.iface != SNDRV_CTL_ELEM_IFACE_MIXER &&
755 gctl->id.iface != SNDRV_CTL_ELEM_IFACE_PCM) {
756 err = -EINVAL;
757 goto __error;
760 for (i = 0; i < icode->gpr_list_control_count; i++) {
761 /* FIXME: we need to check the WRITE access */
762 if (copy_gctl(emu, gctl, icode->gpr_list_controls, i)) {
763 err = -EFAULT;
764 goto __error;
767 __error:
768 kfree(gctl);
769 return err;
772 static void snd_emu10k1_ctl_private_free(struct snd_kcontrol *kctl)
774 struct snd_emu10k1_fx8010_ctl *ctl;
776 ctl = (struct snd_emu10k1_fx8010_ctl *) kctl->private_value;
777 kctl->private_value = 0;
778 list_del(&ctl->list);
779 kfree(ctl);
780 kfree(kctl->tlv.p);
783 static int snd_emu10k1_add_controls(struct snd_emu10k1 *emu,
784 struct snd_emu10k1_fx8010_code *icode)
786 unsigned int i, j;
787 struct snd_emu10k1_fx8010_control_gpr *gctl;
788 struct snd_emu10k1_fx8010_ctl *ctl, *nctl;
789 struct snd_kcontrol_new knew;
790 struct snd_kcontrol *kctl;
791 struct snd_ctl_elem_value *val;
792 int err = 0;
794 val = kmalloc(sizeof(*val), GFP_KERNEL);
795 gctl = kmalloc(sizeof(*gctl), GFP_KERNEL);
796 nctl = kmalloc(sizeof(*nctl), GFP_KERNEL);
797 if (!val || !gctl || !nctl) {
798 err = -ENOMEM;
799 goto __error;
802 for (i = 0; i < icode->gpr_add_control_count; i++) {
803 if (copy_gctl(emu, gctl, icode->gpr_add_controls, i)) {
804 err = -EFAULT;
805 goto __error;
807 if (gctl->id.iface != SNDRV_CTL_ELEM_IFACE_MIXER &&
808 gctl->id.iface != SNDRV_CTL_ELEM_IFACE_PCM) {
809 err = -EINVAL;
810 goto __error;
812 if (! gctl->id.name[0]) {
813 err = -EINVAL;
814 goto __error;
816 ctl = snd_emu10k1_look_for_ctl(emu, &gctl->id);
817 memset(&knew, 0, sizeof(knew));
818 knew.iface = gctl->id.iface;
819 knew.name = gctl->id.name;
820 knew.index = gctl->id.index;
821 knew.device = gctl->id.device;
822 knew.subdevice = gctl->id.subdevice;
823 knew.info = snd_emu10k1_gpr_ctl_info;
824 knew.tlv.p = copy_tlv(gctl->tlv);
825 if (knew.tlv.p)
826 knew.access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
827 SNDRV_CTL_ELEM_ACCESS_TLV_READ;
828 knew.get = snd_emu10k1_gpr_ctl_get;
829 knew.put = snd_emu10k1_gpr_ctl_put;
830 memset(nctl, 0, sizeof(*nctl));
831 nctl->vcount = gctl->vcount;
832 nctl->count = gctl->count;
833 for (j = 0; j < 32; j++) {
834 nctl->gpr[j] = gctl->gpr[j];
835 nctl->value[j] = ~gctl->value[j]; /* inverted, we want to write new value in gpr_ctl_put() */
836 val->value.integer.value[j] = gctl->value[j];
838 nctl->min = gctl->min;
839 nctl->max = gctl->max;
840 nctl->translation = gctl->translation;
841 if (ctl == NULL) {
842 ctl = kmalloc(sizeof(*ctl), GFP_KERNEL);
843 if (ctl == NULL) {
844 err = -ENOMEM;
845 kfree(knew.tlv.p);
846 goto __error;
848 knew.private_value = (unsigned long)ctl;
849 *ctl = *nctl;
850 if ((err = snd_ctl_add(emu->card, kctl = snd_ctl_new1(&knew, emu))) < 0) {
851 kfree(ctl);
852 kfree(knew.tlv.p);
853 goto __error;
855 kctl->private_free = snd_emu10k1_ctl_private_free;
856 ctl->kcontrol = kctl;
857 list_add_tail(&ctl->list, &emu->fx8010.gpr_ctl);
858 } else {
859 /* overwrite */
860 nctl->list = ctl->list;
861 nctl->kcontrol = ctl->kcontrol;
862 *ctl = *nctl;
863 snd_ctl_notify(emu->card, SNDRV_CTL_EVENT_MASK_VALUE |
864 SNDRV_CTL_EVENT_MASK_INFO, &ctl->kcontrol->id);
866 snd_emu10k1_gpr_ctl_put(ctl->kcontrol, val);
868 __error:
869 kfree(nctl);
870 kfree(gctl);
871 kfree(val);
872 return err;
875 static int snd_emu10k1_del_controls(struct snd_emu10k1 *emu,
876 struct snd_emu10k1_fx8010_code *icode)
878 unsigned int i;
879 struct snd_ctl_elem_id id;
880 struct snd_ctl_elem_id __user *_id;
881 struct snd_emu10k1_fx8010_ctl *ctl;
882 struct snd_card *card = emu->card;
884 for (i = 0, _id = icode->gpr_del_controls;
885 i < icode->gpr_del_control_count; i++, _id++) {
886 if (copy_from_user(&id, _id, sizeof(id)))
887 return -EFAULT;
888 down_write(&card->controls_rwsem);
889 ctl = snd_emu10k1_look_for_ctl(emu, &id);
890 if (ctl)
891 snd_ctl_remove(card, ctl->kcontrol);
892 up_write(&card->controls_rwsem);
894 return 0;
897 static int snd_emu10k1_list_controls(struct snd_emu10k1 *emu,
898 struct snd_emu10k1_fx8010_code *icode)
900 unsigned int i = 0, j;
901 unsigned int total = 0;
902 struct snd_emu10k1_fx8010_control_gpr *gctl;
903 struct snd_emu10k1_fx8010_ctl *ctl;
904 struct snd_ctl_elem_id *id;
906 gctl = kmalloc(sizeof(*gctl), GFP_KERNEL);
907 if (! gctl)
908 return -ENOMEM;
910 list_for_each_entry(ctl, &emu->fx8010.gpr_ctl, list) {
911 total++;
912 if (icode->gpr_list_controls &&
913 i < icode->gpr_list_control_count) {
914 memset(gctl, 0, sizeof(*gctl));
915 id = &ctl->kcontrol->id;
916 gctl->id.iface = id->iface;
917 strlcpy(gctl->id.name, id->name, sizeof(gctl->id.name));
918 gctl->id.index = id->index;
919 gctl->id.device = id->device;
920 gctl->id.subdevice = id->subdevice;
921 gctl->vcount = ctl->vcount;
922 gctl->count = ctl->count;
923 for (j = 0; j < 32; j++) {
924 gctl->gpr[j] = ctl->gpr[j];
925 gctl->value[j] = ctl->value[j];
927 gctl->min = ctl->min;
928 gctl->max = ctl->max;
929 gctl->translation = ctl->translation;
930 if (copy_gctl_to_user(emu, icode->gpr_list_controls,
931 gctl, i)) {
932 kfree(gctl);
933 return -EFAULT;
935 i++;
938 icode->gpr_list_control_total = total;
939 kfree(gctl);
940 return 0;
943 static int snd_emu10k1_icode_poke(struct snd_emu10k1 *emu,
944 struct snd_emu10k1_fx8010_code *icode)
946 int err = 0;
948 mutex_lock(&emu->fx8010.lock);
949 if ((err = snd_emu10k1_verify_controls(emu, icode)) < 0)
950 goto __error;
951 strlcpy(emu->fx8010.name, icode->name, sizeof(emu->fx8010.name));
952 /* stop FX processor - this may be dangerous, but it's better to miss
953 some samples than generate wrong ones - [jk] */
954 if (emu->audigy)
955 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg | A_DBG_SINGLE_STEP);
956 else
957 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg | EMU10K1_DBG_SINGLE_STEP);
958 /* ok, do the main job */
959 if ((err = snd_emu10k1_del_controls(emu, icode)) < 0 ||
960 (err = snd_emu10k1_gpr_poke(emu, icode)) < 0 ||
961 (err = snd_emu10k1_tram_poke(emu, icode)) < 0 ||
962 (err = snd_emu10k1_code_poke(emu, icode)) < 0 ||
963 (err = snd_emu10k1_add_controls(emu, icode)) < 0)
964 goto __error;
965 /* start FX processor when the DSP code is updated */
966 if (emu->audigy)
967 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg);
968 else
969 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg);
970 __error:
971 mutex_unlock(&emu->fx8010.lock);
972 return err;
975 static int snd_emu10k1_icode_peek(struct snd_emu10k1 *emu,
976 struct snd_emu10k1_fx8010_code *icode)
978 int err;
980 mutex_lock(&emu->fx8010.lock);
981 strlcpy(icode->name, emu->fx8010.name, sizeof(icode->name));
982 /* ok, do the main job */
983 err = snd_emu10k1_gpr_peek(emu, icode);
984 if (err >= 0)
985 err = snd_emu10k1_tram_peek(emu, icode);
986 if (err >= 0)
987 err = snd_emu10k1_code_peek(emu, icode);
988 if (err >= 0)
989 err = snd_emu10k1_list_controls(emu, icode);
990 mutex_unlock(&emu->fx8010.lock);
991 return err;
994 static int snd_emu10k1_ipcm_poke(struct snd_emu10k1 *emu,
995 struct snd_emu10k1_fx8010_pcm_rec *ipcm)
997 unsigned int i;
998 int err = 0;
999 struct snd_emu10k1_fx8010_pcm *pcm;
1001 if (ipcm->substream >= EMU10K1_FX8010_PCM_COUNT)
1002 return -EINVAL;
1003 if (ipcm->channels > 32)
1004 return -EINVAL;
1005 pcm = &emu->fx8010.pcm[ipcm->substream];
1006 mutex_lock(&emu->fx8010.lock);
1007 spin_lock_irq(&emu->reg_lock);
1008 if (pcm->opened) {
1009 err = -EBUSY;
1010 goto __error;
1012 if (ipcm->channels == 0) { /* remove */
1013 pcm->valid = 0;
1014 } else {
1015 /* FIXME: we need to add universal code to the PCM transfer routine */
1016 if (ipcm->channels != 2) {
1017 err = -EINVAL;
1018 goto __error;
1020 pcm->valid = 1;
1021 pcm->opened = 0;
1022 pcm->channels = ipcm->channels;
1023 pcm->tram_start = ipcm->tram_start;
1024 pcm->buffer_size = ipcm->buffer_size;
1025 pcm->gpr_size = ipcm->gpr_size;
1026 pcm->gpr_count = ipcm->gpr_count;
1027 pcm->gpr_tmpcount = ipcm->gpr_tmpcount;
1028 pcm->gpr_ptr = ipcm->gpr_ptr;
1029 pcm->gpr_trigger = ipcm->gpr_trigger;
1030 pcm->gpr_running = ipcm->gpr_running;
1031 for (i = 0; i < pcm->channels; i++)
1032 pcm->etram[i] = ipcm->etram[i];
1034 __error:
1035 spin_unlock_irq(&emu->reg_lock);
1036 mutex_unlock(&emu->fx8010.lock);
1037 return err;
1040 static int snd_emu10k1_ipcm_peek(struct snd_emu10k1 *emu,
1041 struct snd_emu10k1_fx8010_pcm_rec *ipcm)
1043 unsigned int i;
1044 int err = 0;
1045 struct snd_emu10k1_fx8010_pcm *pcm;
1047 if (ipcm->substream >= EMU10K1_FX8010_PCM_COUNT)
1048 return -EINVAL;
1049 pcm = &emu->fx8010.pcm[ipcm->substream];
1050 mutex_lock(&emu->fx8010.lock);
1051 spin_lock_irq(&emu->reg_lock);
1052 ipcm->channels = pcm->channels;
1053 ipcm->tram_start = pcm->tram_start;
1054 ipcm->buffer_size = pcm->buffer_size;
1055 ipcm->gpr_size = pcm->gpr_size;
1056 ipcm->gpr_ptr = pcm->gpr_ptr;
1057 ipcm->gpr_count = pcm->gpr_count;
1058 ipcm->gpr_tmpcount = pcm->gpr_tmpcount;
1059 ipcm->gpr_trigger = pcm->gpr_trigger;
1060 ipcm->gpr_running = pcm->gpr_running;
1061 for (i = 0; i < pcm->channels; i++)
1062 ipcm->etram[i] = pcm->etram[i];
1063 ipcm->res1 = ipcm->res2 = 0;
1064 ipcm->pad = 0;
1065 spin_unlock_irq(&emu->reg_lock);
1066 mutex_unlock(&emu->fx8010.lock);
1067 return err;
1070 #define SND_EMU10K1_GPR_CONTROLS 44
1071 #define SND_EMU10K1_INPUTS 12
1072 #define SND_EMU10K1_PLAYBACK_CHANNELS 8
1073 #define SND_EMU10K1_CAPTURE_CHANNELS 4
1075 static void
1076 snd_emu10k1_init_mono_control(struct snd_emu10k1_fx8010_control_gpr *ctl,
1077 const char *name, int gpr, int defval)
1079 ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1080 strcpy(ctl->id.name, name);
1081 ctl->vcount = ctl->count = 1;
1082 ctl->gpr[0] = gpr + 0; ctl->value[0] = defval;
1083 if (high_res_gpr_volume) {
1084 ctl->min = 0;
1085 ctl->max = 0x7fffffff;
1086 ctl->tlv = snd_emu10k1_db_linear;
1087 ctl->translation = EMU10K1_GPR_TRANSLATION_NONE;
1088 } else {
1089 ctl->min = 0;
1090 ctl->max = 100;
1091 ctl->tlv = snd_emu10k1_db_scale1;
1092 ctl->translation = EMU10K1_GPR_TRANSLATION_TABLE100;
1096 static void
1097 snd_emu10k1_init_stereo_control(struct snd_emu10k1_fx8010_control_gpr *ctl,
1098 const char *name, int gpr, int defval)
1100 ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1101 strcpy(ctl->id.name, name);
1102 ctl->vcount = ctl->count = 2;
1103 ctl->gpr[0] = gpr + 0; ctl->value[0] = defval;
1104 ctl->gpr[1] = gpr + 1; ctl->value[1] = defval;
1105 if (high_res_gpr_volume) {
1106 ctl->min = 0;
1107 ctl->max = 0x7fffffff;
1108 ctl->tlv = snd_emu10k1_db_linear;
1109 ctl->translation = EMU10K1_GPR_TRANSLATION_NONE;
1110 } else {
1111 ctl->min = 0;
1112 ctl->max = 100;
1113 ctl->tlv = snd_emu10k1_db_scale1;
1114 ctl->translation = EMU10K1_GPR_TRANSLATION_TABLE100;
1118 static void
1119 snd_emu10k1_init_mono_onoff_control(struct snd_emu10k1_fx8010_control_gpr *ctl,
1120 const char *name, int gpr, int defval)
1122 ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1123 strcpy(ctl->id.name, name);
1124 ctl->vcount = ctl->count = 1;
1125 ctl->gpr[0] = gpr + 0; ctl->value[0] = defval;
1126 ctl->min = 0;
1127 ctl->max = 1;
1128 ctl->translation = EMU10K1_GPR_TRANSLATION_ONOFF;
1131 static void
1132 snd_emu10k1_init_stereo_onoff_control(struct snd_emu10k1_fx8010_control_gpr *ctl,
1133 const char *name, int gpr, int defval)
1135 ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1136 strcpy(ctl->id.name, name);
1137 ctl->vcount = ctl->count = 2;
1138 ctl->gpr[0] = gpr + 0; ctl->value[0] = defval;
1139 ctl->gpr[1] = gpr + 1; ctl->value[1] = defval;
1140 ctl->min = 0;
1141 ctl->max = 1;
1142 ctl->translation = EMU10K1_GPR_TRANSLATION_ONOFF;
1146 * Used for emu1010 - conversion from 32-bit capture inputs from HANA
1147 * to 2 x 16-bit registers in audigy - their values are read via DMA.
1148 * Conversion is performed by Audigy DSP instructions of FX8010.
1150 static int snd_emu10k1_audigy_dsp_convert_32_to_2x16(
1151 struct snd_emu10k1_fx8010_code *icode,
1152 u32 *ptr, int tmp, int bit_shifter16,
1153 int reg_in, int reg_out)
1155 A_OP(icode, ptr, iACC3, A_GPR(tmp + 1), reg_in, A_C_00000000, A_C_00000000);
1156 A_OP(icode, ptr, iANDXOR, A_GPR(tmp), A_GPR(tmp + 1), A_GPR(bit_shifter16 - 1), A_C_00000000);
1157 A_OP(icode, ptr, iTSTNEG, A_GPR(tmp + 2), A_GPR(tmp), A_C_80000000, A_GPR(bit_shifter16 - 2));
1158 A_OP(icode, ptr, iANDXOR, A_GPR(tmp + 2), A_GPR(tmp + 2), A_C_80000000, A_C_00000000);
1159 A_OP(icode, ptr, iANDXOR, A_GPR(tmp), A_GPR(tmp), A_GPR(bit_shifter16 - 3), A_C_00000000);
1160 A_OP(icode, ptr, iMACINT0, A_GPR(tmp), A_C_00000000, A_GPR(tmp), A_C_00010000);
1161 A_OP(icode, ptr, iANDXOR, reg_out, A_GPR(tmp), A_C_ffffffff, A_GPR(tmp + 2));
1162 A_OP(icode, ptr, iACC3, reg_out + 1, A_GPR(tmp + 1), A_C_00000000, A_C_00000000);
1163 return 1;
1167 * initial DSP configuration for Audigy
1170 static int _snd_emu10k1_audigy_init_efx(struct snd_emu10k1 *emu)
1172 int err, i, z, gpr, nctl;
1173 int bit_shifter16;
1174 const int playback = 10;
1175 const int capture = playback + (SND_EMU10K1_PLAYBACK_CHANNELS * 2); /* we reserve 10 voices */
1176 const int stereo_mix = capture + 2;
1177 const int tmp = 0x88;
1178 u32 ptr;
1179 struct snd_emu10k1_fx8010_code *icode = NULL;
1180 struct snd_emu10k1_fx8010_control_gpr *controls = NULL, *ctl;
1181 u32 *gpr_map;
1182 mm_segment_t seg;
1184 err = -ENOMEM;
1185 icode = kzalloc(sizeof(*icode), GFP_KERNEL);
1186 if (!icode)
1187 return err;
1189 icode->gpr_map = (u_int32_t __user *) kcalloc(512 + 256 + 256 + 2 * 1024,
1190 sizeof(u_int32_t), GFP_KERNEL);
1191 if (!icode->gpr_map)
1192 goto __err_gpr;
1193 controls = kcalloc(SND_EMU10K1_GPR_CONTROLS,
1194 sizeof(*controls), GFP_KERNEL);
1195 if (!controls)
1196 goto __err_ctrls;
1198 gpr_map = (u32 __force *)icode->gpr_map;
1200 icode->tram_data_map = icode->gpr_map + 512;
1201 icode->tram_addr_map = icode->tram_data_map + 256;
1202 icode->code = icode->tram_addr_map + 256;
1204 /* clear free GPRs */
1205 for (i = 0; i < 512; i++)
1206 set_bit(i, icode->gpr_valid);
1208 /* clear TRAM data & address lines */
1209 for (i = 0; i < 256; i++)
1210 set_bit(i, icode->tram_valid);
1212 strcpy(icode->name, "Audigy DSP code for ALSA");
1213 ptr = 0;
1214 nctl = 0;
1215 gpr = stereo_mix + 10;
1216 gpr_map[gpr++] = 0x00007fff;
1217 gpr_map[gpr++] = 0x00008000;
1218 gpr_map[gpr++] = 0x0000ffff;
1219 bit_shifter16 = gpr;
1221 /* stop FX processor */
1222 snd_emu10k1_ptr_write(emu, A_DBG, 0, (emu->fx8010.dbg = 0) | A_DBG_SINGLE_STEP);
1224 #if 1
1225 /* PCM front Playback Volume (independent from stereo mix)
1226 * playback = 0 + ( gpr * FXBUS_PCM_LEFT_FRONT >> 31)
1227 * where gpr contains attenuation from corresponding mixer control
1228 * (snd_emu10k1_init_stereo_control)
1230 A_OP(icode, &ptr, iMAC0, A_GPR(playback), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LEFT_FRONT));
1231 A_OP(icode, &ptr, iMAC0, A_GPR(playback+1), A_C_00000000, A_GPR(gpr+1), A_FXBUS(FXBUS_PCM_RIGHT_FRONT));
1232 snd_emu10k1_init_stereo_control(&controls[nctl++], "PCM Front Playback Volume", gpr, 100);
1233 gpr += 2;
1235 /* PCM Surround Playback (independent from stereo mix) */
1236 A_OP(icode, &ptr, iMAC0, A_GPR(playback+2), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LEFT_REAR));
1237 A_OP(icode, &ptr, iMAC0, A_GPR(playback+3), A_C_00000000, A_GPR(gpr+1), A_FXBUS(FXBUS_PCM_RIGHT_REAR));
1238 snd_emu10k1_init_stereo_control(&controls[nctl++], "PCM Surround Playback Volume", gpr, 100);
1239 gpr += 2;
1241 /* PCM Side Playback (independent from stereo mix) */
1242 if (emu->card_capabilities->spk71) {
1243 A_OP(icode, &ptr, iMAC0, A_GPR(playback+6), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LEFT_SIDE));
1244 A_OP(icode, &ptr, iMAC0, A_GPR(playback+7), A_C_00000000, A_GPR(gpr+1), A_FXBUS(FXBUS_PCM_RIGHT_SIDE));
1245 snd_emu10k1_init_stereo_control(&controls[nctl++], "PCM Side Playback Volume", gpr, 100);
1246 gpr += 2;
1249 /* PCM Center Playback (independent from stereo mix) */
1250 A_OP(icode, &ptr, iMAC0, A_GPR(playback+4), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_CENTER));
1251 snd_emu10k1_init_mono_control(&controls[nctl++], "PCM Center Playback Volume", gpr, 100);
1252 gpr++;
1254 /* PCM LFE Playback (independent from stereo mix) */
1255 A_OP(icode, &ptr, iMAC0, A_GPR(playback+5), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LFE));
1256 snd_emu10k1_init_mono_control(&controls[nctl++], "PCM LFE Playback Volume", gpr, 100);
1257 gpr++;
1260 * Stereo Mix
1262 /* Wave (PCM) Playback Volume (will be renamed later) */
1263 A_OP(icode, &ptr, iMAC0, A_GPR(stereo_mix), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LEFT));
1264 A_OP(icode, &ptr, iMAC0, A_GPR(stereo_mix+1), A_C_00000000, A_GPR(gpr+1), A_FXBUS(FXBUS_PCM_RIGHT));
1265 snd_emu10k1_init_stereo_control(&controls[nctl++], "Wave Playback Volume", gpr, 100);
1266 gpr += 2;
1268 /* Synth Playback */
1269 A_OP(icode, &ptr, iMAC0, A_GPR(stereo_mix+0), A_GPR(stereo_mix+0), A_GPR(gpr), A_FXBUS(FXBUS_MIDI_LEFT));
1270 A_OP(icode, &ptr, iMAC0, A_GPR(stereo_mix+1), A_GPR(stereo_mix+1), A_GPR(gpr+1), A_FXBUS(FXBUS_MIDI_RIGHT));
1271 snd_emu10k1_init_stereo_control(&controls[nctl++], "Synth Playback Volume", gpr, 100);
1272 gpr += 2;
1274 /* Wave (PCM) Capture */
1275 A_OP(icode, &ptr, iMAC0, A_GPR(capture+0), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LEFT));
1276 A_OP(icode, &ptr, iMAC0, A_GPR(capture+1), A_C_00000000, A_GPR(gpr+1), A_FXBUS(FXBUS_PCM_RIGHT));
1277 snd_emu10k1_init_stereo_control(&controls[nctl++], "PCM Capture Volume", gpr, 0);
1278 gpr += 2;
1280 /* Synth Capture */
1281 A_OP(icode, &ptr, iMAC0, A_GPR(capture+0), A_GPR(capture+0), A_GPR(gpr), A_FXBUS(FXBUS_MIDI_LEFT));
1282 A_OP(icode, &ptr, iMAC0, A_GPR(capture+1), A_GPR(capture+1), A_GPR(gpr+1), A_FXBUS(FXBUS_MIDI_RIGHT));
1283 snd_emu10k1_init_stereo_control(&controls[nctl++], "Synth Capture Volume", gpr, 0);
1284 gpr += 2;
1287 * inputs
1289 #define A_ADD_VOLUME_IN(var,vol,input) \
1290 A_OP(icode, &ptr, iMAC0, A_GPR(var), A_GPR(var), A_GPR(vol), A_EXTIN(input))
1292 /* emu1212 DSP 0 and DSP 1 Capture */
1293 if (emu->card_capabilities->emu_model) {
1294 if (emu->card_capabilities->ca0108_chip) {
1295 /* Note:JCD:No longer bit shift lower 16bits to upper 16bits of 32bit value. */
1296 A_OP(icode, &ptr, iMACINT0, A_GPR(tmp), A_C_00000000, A3_EMU32IN(0x0), A_C_00000001);
1297 A_OP(icode, &ptr, iMAC0, A_GPR(capture+0), A_GPR(capture+0), A_GPR(gpr), A_GPR(tmp));
1298 A_OP(icode, &ptr, iMACINT0, A_GPR(tmp), A_C_00000000, A3_EMU32IN(0x1), A_C_00000001);
1299 A_OP(icode, &ptr, iMAC0, A_GPR(capture+1), A_GPR(capture+1), A_GPR(gpr), A_GPR(tmp));
1300 } else {
1301 A_OP(icode, &ptr, iMAC0, A_GPR(capture+0), A_GPR(capture+0), A_GPR(gpr), A_P16VIN(0x0));
1302 A_OP(icode, &ptr, iMAC0, A_GPR(capture+1), A_GPR(capture+1), A_GPR(gpr+1), A_P16VIN(0x1));
1304 snd_emu10k1_init_stereo_control(&controls[nctl++], "EMU Capture Volume", gpr, 0);
1305 gpr += 2;
1307 /* AC'97 Playback Volume - used only for mic (renamed later) */
1308 A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_AC97_L);
1309 A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_AC97_R);
1310 snd_emu10k1_init_stereo_control(&controls[nctl++], "AMic Playback Volume", gpr, 0);
1311 gpr += 2;
1312 /* AC'97 Capture Volume - used only for mic */
1313 A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_AC97_L);
1314 A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_AC97_R);
1315 snd_emu10k1_init_stereo_control(&controls[nctl++], "Mic Capture Volume", gpr, 0);
1316 gpr += 2;
1318 /* mic capture buffer */
1319 A_OP(icode, &ptr, iINTERP, A_EXTOUT(A_EXTOUT_MIC_CAP), A_EXTIN(A_EXTIN_AC97_L), 0xcd, A_EXTIN(A_EXTIN_AC97_R));
1321 /* Audigy CD Playback Volume */
1322 A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_SPDIF_CD_L);
1323 A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_SPDIF_CD_R);
1324 snd_emu10k1_init_stereo_control(&controls[nctl++],
1325 emu->card_capabilities->ac97_chip ? "Audigy CD Playback Volume" : "CD Playback Volume",
1326 gpr, 0);
1327 gpr += 2;
1328 /* Audigy CD Capture Volume */
1329 A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_SPDIF_CD_L);
1330 A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_SPDIF_CD_R);
1331 snd_emu10k1_init_stereo_control(&controls[nctl++],
1332 emu->card_capabilities->ac97_chip ? "Audigy CD Capture Volume" : "CD Capture Volume",
1333 gpr, 0);
1334 gpr += 2;
1336 /* Optical SPDIF Playback Volume */
1337 A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_OPT_SPDIF_L);
1338 A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_OPT_SPDIF_R);
1339 snd_emu10k1_init_stereo_control(&controls[nctl++], SNDRV_CTL_NAME_IEC958("Optical ",PLAYBACK,VOLUME), gpr, 0);
1340 gpr += 2;
1341 /* Optical SPDIF Capture Volume */
1342 A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_OPT_SPDIF_L);
1343 A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_OPT_SPDIF_R);
1344 snd_emu10k1_init_stereo_control(&controls[nctl++], SNDRV_CTL_NAME_IEC958("Optical ",CAPTURE,VOLUME), gpr, 0);
1345 gpr += 2;
1347 /* Line2 Playback Volume */
1348 A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_LINE2_L);
1349 A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_LINE2_R);
1350 snd_emu10k1_init_stereo_control(&controls[nctl++],
1351 emu->card_capabilities->ac97_chip ? "Line2 Playback Volume" : "Line Playback Volume",
1352 gpr, 0);
1353 gpr += 2;
1354 /* Line2 Capture Volume */
1355 A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_LINE2_L);
1356 A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_LINE2_R);
1357 snd_emu10k1_init_stereo_control(&controls[nctl++],
1358 emu->card_capabilities->ac97_chip ? "Line2 Capture Volume" : "Line Capture Volume",
1359 gpr, 0);
1360 gpr += 2;
1362 /* Philips ADC Playback Volume */
1363 A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_ADC_L);
1364 A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_ADC_R);
1365 snd_emu10k1_init_stereo_control(&controls[nctl++], "Analog Mix Playback Volume", gpr, 0);
1366 gpr += 2;
1367 /* Philips ADC Capture Volume */
1368 A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_ADC_L);
1369 A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_ADC_R);
1370 snd_emu10k1_init_stereo_control(&controls[nctl++], "Analog Mix Capture Volume", gpr, 0);
1371 gpr += 2;
1373 /* Aux2 Playback Volume */
1374 A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_AUX2_L);
1375 A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_AUX2_R);
1376 snd_emu10k1_init_stereo_control(&controls[nctl++],
1377 emu->card_capabilities->ac97_chip ? "Aux2 Playback Volume" : "Aux Playback Volume",
1378 gpr, 0);
1379 gpr += 2;
1380 /* Aux2 Capture Volume */
1381 A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_AUX2_L);
1382 A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_AUX2_R);
1383 snd_emu10k1_init_stereo_control(&controls[nctl++],
1384 emu->card_capabilities->ac97_chip ? "Aux2 Capture Volume" : "Aux Capture Volume",
1385 gpr, 0);
1386 gpr += 2;
1388 /* Stereo Mix Front Playback Volume */
1389 A_OP(icode, &ptr, iMAC0, A_GPR(playback), A_GPR(playback), A_GPR(gpr), A_GPR(stereo_mix));
1390 A_OP(icode, &ptr, iMAC0, A_GPR(playback+1), A_GPR(playback+1), A_GPR(gpr+1), A_GPR(stereo_mix+1));
1391 snd_emu10k1_init_stereo_control(&controls[nctl++], "Front Playback Volume", gpr, 100);
1392 gpr += 2;
1394 /* Stereo Mix Surround Playback */
1395 A_OP(icode, &ptr, iMAC0, A_GPR(playback+2), A_GPR(playback+2), A_GPR(gpr), A_GPR(stereo_mix));
1396 A_OP(icode, &ptr, iMAC0, A_GPR(playback+3), A_GPR(playback+3), A_GPR(gpr+1), A_GPR(stereo_mix+1));
1397 snd_emu10k1_init_stereo_control(&controls[nctl++], "Surround Playback Volume", gpr, 0);
1398 gpr += 2;
1400 /* Stereo Mix Center Playback */
1401 /* Center = sub = Left/2 + Right/2 */
1402 A_OP(icode, &ptr, iINTERP, A_GPR(tmp), A_GPR(stereo_mix), 0xcd, A_GPR(stereo_mix+1));
1403 A_OP(icode, &ptr, iMAC0, A_GPR(playback+4), A_GPR(playback+4), A_GPR(gpr), A_GPR(tmp));
1404 snd_emu10k1_init_mono_control(&controls[nctl++], "Center Playback Volume", gpr, 0);
1405 gpr++;
1407 /* Stereo Mix LFE Playback */
1408 A_OP(icode, &ptr, iMAC0, A_GPR(playback+5), A_GPR(playback+5), A_GPR(gpr), A_GPR(tmp));
1409 snd_emu10k1_init_mono_control(&controls[nctl++], "LFE Playback Volume", gpr, 0);
1410 gpr++;
1412 if (emu->card_capabilities->spk71) {
1413 /* Stereo Mix Side Playback */
1414 A_OP(icode, &ptr, iMAC0, A_GPR(playback+6), A_GPR(playback+6), A_GPR(gpr), A_GPR(stereo_mix));
1415 A_OP(icode, &ptr, iMAC0, A_GPR(playback+7), A_GPR(playback+7), A_GPR(gpr+1), A_GPR(stereo_mix+1));
1416 snd_emu10k1_init_stereo_control(&controls[nctl++], "Side Playback Volume", gpr, 0);
1417 gpr += 2;
1421 * outputs
1423 #define A_PUT_OUTPUT(out,src) A_OP(icode, &ptr, iACC3, A_EXTOUT(out), A_C_00000000, A_C_00000000, A_GPR(src))
1424 #define A_PUT_STEREO_OUTPUT(out1,out2,src) \
1425 {A_PUT_OUTPUT(out1,src); A_PUT_OUTPUT(out2,src+1);}
1427 #define _A_SWITCH(icode, ptr, dst, src, sw) \
1428 A_OP((icode), ptr, iMACINT0, dst, A_C_00000000, src, sw);
1429 #define A_SWITCH(icode, ptr, dst, src, sw) \
1430 _A_SWITCH(icode, ptr, A_GPR(dst), A_GPR(src), A_GPR(sw))
1431 #define _A_SWITCH_NEG(icode, ptr, dst, src) \
1432 A_OP((icode), ptr, iANDXOR, dst, src, A_C_00000001, A_C_00000001);
1433 #define A_SWITCH_NEG(icode, ptr, dst, src) \
1434 _A_SWITCH_NEG(icode, ptr, A_GPR(dst), A_GPR(src))
1438 * Process tone control
1440 A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 0), A_GPR(playback + 0), A_C_00000000, A_C_00000000); /* left */
1441 A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 1), A_GPR(playback + 1), A_C_00000000, A_C_00000000); /* right */
1442 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 */
1443 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 */
1444 A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 4), A_GPR(playback + 4), A_C_00000000, A_C_00000000); /* center */
1445 A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 5), A_GPR(playback + 5), A_C_00000000, A_C_00000000); /* LFE */
1446 if (emu->card_capabilities->spk71) {
1447 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 */
1448 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 */
1452 ctl = &controls[nctl + 0];
1453 ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1454 strcpy(ctl->id.name, "Tone Control - Bass");
1455 ctl->vcount = 2;
1456 ctl->count = 10;
1457 ctl->min = 0;
1458 ctl->max = 40;
1459 ctl->value[0] = ctl->value[1] = 20;
1460 ctl->translation = EMU10K1_GPR_TRANSLATION_BASS;
1461 ctl = &controls[nctl + 1];
1462 ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1463 strcpy(ctl->id.name, "Tone Control - Treble");
1464 ctl->vcount = 2;
1465 ctl->count = 10;
1466 ctl->min = 0;
1467 ctl->max = 40;
1468 ctl->value[0] = ctl->value[1] = 20;
1469 ctl->translation = EMU10K1_GPR_TRANSLATION_TREBLE;
1471 #define BASS_GPR 0x8c
1472 #define TREBLE_GPR 0x96
1474 for (z = 0; z < 5; z++) {
1475 int j;
1476 for (j = 0; j < 2; j++) {
1477 controls[nctl + 0].gpr[z * 2 + j] = BASS_GPR + z * 2 + j;
1478 controls[nctl + 1].gpr[z * 2 + j] = TREBLE_GPR + z * 2 + j;
1481 for (z = 0; z < 4; z++) { /* front/rear/center-lfe/side */
1482 int j, k, l, d;
1483 for (j = 0; j < 2; j++) { /* left/right */
1484 k = 0xb0 + (z * 8) + (j * 4);
1485 l = 0xe0 + (z * 8) + (j * 4);
1486 d = playback + SND_EMU10K1_PLAYBACK_CHANNELS + z * 2 + j;
1488 A_OP(icode, &ptr, iMAC0, A_C_00000000, A_C_00000000, A_GPR(d), A_GPR(BASS_GPR + 0 + j));
1489 A_OP(icode, &ptr, iMACMV, A_GPR(k+1), A_GPR(k), A_GPR(k+1), A_GPR(BASS_GPR + 4 + j));
1490 A_OP(icode, &ptr, iMACMV, A_GPR(k), A_GPR(d), A_GPR(k), A_GPR(BASS_GPR + 2 + j));
1491 A_OP(icode, &ptr, iMACMV, A_GPR(k+3), A_GPR(k+2), A_GPR(k+3), A_GPR(BASS_GPR + 8 + j));
1492 A_OP(icode, &ptr, iMAC0, A_GPR(k+2), A_GPR_ACCU, A_GPR(k+2), A_GPR(BASS_GPR + 6 + j));
1493 A_OP(icode, &ptr, iACC3, A_GPR(k+2), A_GPR(k+2), A_GPR(k+2), A_C_00000000);
1495 A_OP(icode, &ptr, iMAC0, A_C_00000000, A_C_00000000, A_GPR(k+2), A_GPR(TREBLE_GPR + 0 + j));
1496 A_OP(icode, &ptr, iMACMV, A_GPR(l+1), A_GPR(l), A_GPR(l+1), A_GPR(TREBLE_GPR + 4 + j));
1497 A_OP(icode, &ptr, iMACMV, A_GPR(l), A_GPR(k+2), A_GPR(l), A_GPR(TREBLE_GPR + 2 + j));
1498 A_OP(icode, &ptr, iMACMV, A_GPR(l+3), A_GPR(l+2), A_GPR(l+3), A_GPR(TREBLE_GPR + 8 + j));
1499 A_OP(icode, &ptr, iMAC0, A_GPR(l+2), A_GPR_ACCU, A_GPR(l+2), A_GPR(TREBLE_GPR + 6 + j));
1500 A_OP(icode, &ptr, iMACINT0, A_GPR(l+2), A_C_00000000, A_GPR(l+2), A_C_00000010);
1502 A_OP(icode, &ptr, iACC3, A_GPR(d), A_GPR(l+2), A_C_00000000, A_C_00000000);
1504 if (z == 2) /* center */
1505 break;
1508 nctl += 2;
1510 #undef BASS_GPR
1511 #undef TREBLE_GPR
1513 for (z = 0; z < 8; z++) {
1514 A_SWITCH(icode, &ptr, tmp + 0, playback + SND_EMU10K1_PLAYBACK_CHANNELS + z, gpr + 0);
1515 A_SWITCH_NEG(icode, &ptr, tmp + 1, gpr + 0);
1516 A_SWITCH(icode, &ptr, tmp + 1, playback + z, tmp + 1);
1517 A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + z), A_GPR(tmp + 0), A_GPR(tmp + 1), A_C_00000000);
1519 snd_emu10k1_init_stereo_onoff_control(controls + nctl++, "Tone Control - Switch", gpr, 0);
1520 gpr += 2;
1522 /* Master volume (will be renamed later) */
1523 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));
1524 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));
1525 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));
1526 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));
1527 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));
1528 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));
1529 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));
1530 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));
1531 snd_emu10k1_init_mono_control(&controls[nctl++], "Wave Master Playback Volume", gpr, 0);
1532 gpr += 2;
1534 /* analog speakers */
1535 A_PUT_STEREO_OUTPUT(A_EXTOUT_AFRONT_L, A_EXTOUT_AFRONT_R, playback + SND_EMU10K1_PLAYBACK_CHANNELS);
1536 A_PUT_STEREO_OUTPUT(A_EXTOUT_AREAR_L, A_EXTOUT_AREAR_R, playback+2 + SND_EMU10K1_PLAYBACK_CHANNELS);
1537 A_PUT_OUTPUT(A_EXTOUT_ACENTER, playback+4 + SND_EMU10K1_PLAYBACK_CHANNELS);
1538 A_PUT_OUTPUT(A_EXTOUT_ALFE, playback+5 + SND_EMU10K1_PLAYBACK_CHANNELS);
1539 if (emu->card_capabilities->spk71)
1540 A_PUT_STEREO_OUTPUT(A_EXTOUT_ASIDE_L, A_EXTOUT_ASIDE_R, playback+6 + SND_EMU10K1_PLAYBACK_CHANNELS);
1542 /* headphone */
1543 A_PUT_STEREO_OUTPUT(A_EXTOUT_HEADPHONE_L, A_EXTOUT_HEADPHONE_R, playback + SND_EMU10K1_PLAYBACK_CHANNELS);
1545 /* digital outputs */
1546 /* A_PUT_STEREO_OUTPUT(A_EXTOUT_FRONT_L, A_EXTOUT_FRONT_R, playback + SND_EMU10K1_PLAYBACK_CHANNELS); */
1547 if (emu->card_capabilities->emu_model) {
1548 /* EMU1010 Outputs from PCM Front, Rear, Center, LFE, Side */
1549 dev_info(emu->card->dev, "EMU outputs on\n");
1550 for (z = 0; z < 8; z++) {
1551 if (emu->card_capabilities->ca0108_chip) {
1552 A_OP(icode, &ptr, iACC3, A3_EMU32OUT(z), A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + z), A_C_00000000, A_C_00000000);
1553 } else {
1554 A_OP(icode, &ptr, iACC3, A_EMU32OUTL(z), A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + z), A_C_00000000, A_C_00000000);
1559 /* IEC958 Optical Raw Playback Switch */
1560 gpr_map[gpr++] = 0;
1561 gpr_map[gpr++] = 0x1008;
1562 gpr_map[gpr++] = 0xffff0000;
1563 for (z = 0; z < 2; z++) {
1564 A_OP(icode, &ptr, iMAC0, A_GPR(tmp + 2), A_FXBUS(FXBUS_PT_LEFT + z), A_C_00000000, A_C_00000000);
1565 A_OP(icode, &ptr, iSKIP, A_GPR_COND, A_GPR_COND, A_GPR(gpr - 2), A_C_00000001);
1566 A_OP(icode, &ptr, iACC3, A_GPR(tmp + 2), A_C_00000000, A_C_00010000, A_GPR(tmp + 2));
1567 A_OP(icode, &ptr, iANDXOR, A_GPR(tmp + 2), A_GPR(tmp + 2), A_GPR(gpr - 1), A_C_00000000);
1568 A_SWITCH(icode, &ptr, tmp + 0, tmp + 2, gpr + z);
1569 A_SWITCH_NEG(icode, &ptr, tmp + 1, gpr + z);
1570 A_SWITCH(icode, &ptr, tmp + 1, playback + SND_EMU10K1_PLAYBACK_CHANNELS + z, tmp + 1);
1571 if ((z==1) && (emu->card_capabilities->spdif_bug)) {
1572 /* Due to a SPDIF output bug on some Audigy cards, this code delays the Right channel by 1 sample */
1573 dev_info(emu->card->dev,
1574 "Installing spdif_bug patch: %s\n",
1575 emu->card_capabilities->name);
1576 A_OP(icode, &ptr, iACC3, A_EXTOUT(A_EXTOUT_FRONT_L + z), A_GPR(gpr - 3), A_C_00000000, A_C_00000000);
1577 A_OP(icode, &ptr, iACC3, A_GPR(gpr - 3), A_GPR(tmp + 0), A_GPR(tmp + 1), A_C_00000000);
1578 } else {
1579 A_OP(icode, &ptr, iACC3, A_EXTOUT(A_EXTOUT_FRONT_L + z), A_GPR(tmp + 0), A_GPR(tmp + 1), A_C_00000000);
1582 snd_emu10k1_init_stereo_onoff_control(controls + nctl++, SNDRV_CTL_NAME_IEC958("Optical Raw ",PLAYBACK,SWITCH), gpr, 0);
1583 gpr += 2;
1585 A_PUT_STEREO_OUTPUT(A_EXTOUT_REAR_L, A_EXTOUT_REAR_R, playback+2 + SND_EMU10K1_PLAYBACK_CHANNELS);
1586 A_PUT_OUTPUT(A_EXTOUT_CENTER, playback+4 + SND_EMU10K1_PLAYBACK_CHANNELS);
1587 A_PUT_OUTPUT(A_EXTOUT_LFE, playback+5 + SND_EMU10K1_PLAYBACK_CHANNELS);
1589 /* ADC buffer */
1590 #ifdef EMU10K1_CAPTURE_DIGITAL_OUT
1591 A_PUT_STEREO_OUTPUT(A_EXTOUT_ADC_CAP_L, A_EXTOUT_ADC_CAP_R, playback + SND_EMU10K1_PLAYBACK_CHANNELS);
1592 #else
1593 A_PUT_OUTPUT(A_EXTOUT_ADC_CAP_L, capture);
1594 A_PUT_OUTPUT(A_EXTOUT_ADC_CAP_R, capture+1);
1595 #endif
1597 if (emu->card_capabilities->emu_model) {
1598 if (emu->card_capabilities->ca0108_chip) {
1599 dev_info(emu->card->dev, "EMU2 inputs on\n");
1600 for (z = 0; z < 0x10; z++) {
1601 snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp,
1602 bit_shifter16,
1603 A3_EMU32IN(z),
1604 A_FXBUS2(z*2) );
1606 } else {
1607 dev_info(emu->card->dev, "EMU inputs on\n");
1608 /* Capture 16 (originally 8) channels of S32_LE sound */
1611 dev_dbg(emu->card->dev, "emufx.c: gpr=0x%x, tmp=0x%x\n",
1612 gpr, tmp);
1614 /* For the EMU1010: How to get 32bit values from the DSP. High 16bits into L, low 16bits into R. */
1615 /* A_P16VIN(0) is delayed by one sample,
1616 * so all other A_P16VIN channels will need to also be delayed
1618 /* Left ADC in. 1 of 2 */
1619 snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_P16VIN(0x0), A_FXBUS2(0) );
1620 /* Right ADC in 1 of 2 */
1621 gpr_map[gpr++] = 0x00000000;
1622 /* Delaying by one sample: instead of copying the input
1623 * value A_P16VIN to output A_FXBUS2 as in the first channel,
1624 * we use an auxiliary register, delaying the value by one
1625 * sample
1627 snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_GPR(gpr - 1), A_FXBUS2(2) );
1628 A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x1), A_C_00000000, A_C_00000000);
1629 gpr_map[gpr++] = 0x00000000;
1630 snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_GPR(gpr - 1), A_FXBUS2(4) );
1631 A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x2), A_C_00000000, A_C_00000000);
1632 gpr_map[gpr++] = 0x00000000;
1633 snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_GPR(gpr - 1), A_FXBUS2(6) );
1634 A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x3), A_C_00000000, A_C_00000000);
1635 /* For 96kHz mode */
1636 /* Left ADC in. 2 of 2 */
1637 gpr_map[gpr++] = 0x00000000;
1638 snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_GPR(gpr - 1), A_FXBUS2(0x8) );
1639 A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x4), A_C_00000000, A_C_00000000);
1640 /* Right ADC in 2 of 2 */
1641 gpr_map[gpr++] = 0x00000000;
1642 snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_GPR(gpr - 1), A_FXBUS2(0xa) );
1643 A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x5), A_C_00000000, A_C_00000000);
1644 gpr_map[gpr++] = 0x00000000;
1645 snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_GPR(gpr - 1), A_FXBUS2(0xc) );
1646 A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x6), A_C_00000000, A_C_00000000);
1647 gpr_map[gpr++] = 0x00000000;
1648 snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_GPR(gpr - 1), A_FXBUS2(0xe) );
1649 A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x7), A_C_00000000, A_C_00000000);
1650 /* Pavel Hofman - we still have voices, A_FXBUS2s, and
1651 * A_P16VINs available -
1652 * let's add 8 more capture channels - total of 16
1654 gpr_map[gpr++] = 0x00000000;
1655 snd_emu10k1_audigy_dsp_convert_32_to_2x16(icode, &ptr, tmp,
1656 bit_shifter16,
1657 A_GPR(gpr - 1),
1658 A_FXBUS2(0x10));
1659 A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x8),
1660 A_C_00000000, A_C_00000000);
1661 gpr_map[gpr++] = 0x00000000;
1662 snd_emu10k1_audigy_dsp_convert_32_to_2x16(icode, &ptr, tmp,
1663 bit_shifter16,
1664 A_GPR(gpr - 1),
1665 A_FXBUS2(0x12));
1666 A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x9),
1667 A_C_00000000, A_C_00000000);
1668 gpr_map[gpr++] = 0x00000000;
1669 snd_emu10k1_audigy_dsp_convert_32_to_2x16(icode, &ptr, tmp,
1670 bit_shifter16,
1671 A_GPR(gpr - 1),
1672 A_FXBUS2(0x14));
1673 A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0xa),
1674 A_C_00000000, A_C_00000000);
1675 gpr_map[gpr++] = 0x00000000;
1676 snd_emu10k1_audigy_dsp_convert_32_to_2x16(icode, &ptr, tmp,
1677 bit_shifter16,
1678 A_GPR(gpr - 1),
1679 A_FXBUS2(0x16));
1680 A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0xb),
1681 A_C_00000000, A_C_00000000);
1682 gpr_map[gpr++] = 0x00000000;
1683 snd_emu10k1_audigy_dsp_convert_32_to_2x16(icode, &ptr, tmp,
1684 bit_shifter16,
1685 A_GPR(gpr - 1),
1686 A_FXBUS2(0x18));
1687 A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0xc),
1688 A_C_00000000, A_C_00000000);
1689 gpr_map[gpr++] = 0x00000000;
1690 snd_emu10k1_audigy_dsp_convert_32_to_2x16(icode, &ptr, tmp,
1691 bit_shifter16,
1692 A_GPR(gpr - 1),
1693 A_FXBUS2(0x1a));
1694 A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0xd),
1695 A_C_00000000, A_C_00000000);
1696 gpr_map[gpr++] = 0x00000000;
1697 snd_emu10k1_audigy_dsp_convert_32_to_2x16(icode, &ptr, tmp,
1698 bit_shifter16,
1699 A_GPR(gpr - 1),
1700 A_FXBUS2(0x1c));
1701 A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0xe),
1702 A_C_00000000, A_C_00000000);
1703 gpr_map[gpr++] = 0x00000000;
1704 snd_emu10k1_audigy_dsp_convert_32_to_2x16(icode, &ptr, tmp,
1705 bit_shifter16,
1706 A_GPR(gpr - 1),
1707 A_FXBUS2(0x1e));
1708 A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0xf),
1709 A_C_00000000, A_C_00000000);
1712 #if 0
1713 for (z = 4; z < 8; z++) {
1714 A_OP(icode, &ptr, iACC3, A_FXBUS2(z), A_C_00000000, A_C_00000000, A_C_00000000);
1716 for (z = 0xc; z < 0x10; z++) {
1717 A_OP(icode, &ptr, iACC3, A_FXBUS2(z), A_C_00000000, A_C_00000000, A_C_00000000);
1719 #endif
1720 } else {
1721 /* EFX capture - capture the 16 EXTINs */
1722 /* Capture 16 channels of S16_LE sound */
1723 for (z = 0; z < 16; z++) {
1724 A_OP(icode, &ptr, iACC3, A_FXBUS2(z), A_C_00000000, A_C_00000000, A_EXTIN(z));
1728 #endif /* JCD test */
1730 * ok, set up done..
1733 if (gpr > tmp) {
1734 snd_BUG();
1735 err = -EIO;
1736 goto __err;
1738 /* clear remaining instruction memory */
1739 while (ptr < 0x400)
1740 A_OP(icode, &ptr, 0x0f, 0xc0, 0xc0, 0xcf, 0xc0);
1742 seg = snd_enter_user();
1743 icode->gpr_add_control_count = nctl;
1744 icode->gpr_add_controls = (struct snd_emu10k1_fx8010_control_gpr __user *)controls;
1745 emu->support_tlv = 1; /* support TLV */
1746 err = snd_emu10k1_icode_poke(emu, icode);
1747 emu->support_tlv = 0; /* clear again */
1748 snd_leave_user(seg);
1750 __err:
1751 kfree(controls);
1752 __err_ctrls:
1753 kfree((void __force *)icode->gpr_map);
1754 __err_gpr:
1755 kfree(icode);
1756 return err;
1761 * initial DSP configuration for Emu10k1
1764 /* when volume = max, then copy only to avoid volume modification */
1765 /* with iMAC0 (negative values) */
1766 static void _volume(struct snd_emu10k1_fx8010_code *icode, u32 *ptr, u32 dst, u32 src, u32 vol)
1768 OP(icode, ptr, iMAC0, dst, C_00000000, src, vol);
1769 OP(icode, ptr, iANDXOR, C_00000000, vol, C_ffffffff, C_7fffffff);
1770 OP(icode, ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, C_00000001);
1771 OP(icode, ptr, iACC3, dst, src, C_00000000, C_00000000);
1773 static void _volume_add(struct snd_emu10k1_fx8010_code *icode, u32 *ptr, u32 dst, u32 src, u32 vol)
1775 OP(icode, ptr, iANDXOR, C_00000000, vol, C_ffffffff, C_7fffffff);
1776 OP(icode, ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, C_00000002);
1777 OP(icode, ptr, iMACINT0, dst, dst, src, C_00000001);
1778 OP(icode, ptr, iSKIP, C_00000000, C_7fffffff, C_7fffffff, C_00000001);
1779 OP(icode, ptr, iMAC0, dst, dst, src, vol);
1781 static void _volume_out(struct snd_emu10k1_fx8010_code *icode, u32 *ptr, u32 dst, u32 src, u32 vol)
1783 OP(icode, ptr, iANDXOR, C_00000000, vol, C_ffffffff, C_7fffffff);
1784 OP(icode, ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, C_00000002);
1785 OP(icode, ptr, iACC3, dst, src, C_00000000, C_00000000);
1786 OP(icode, ptr, iSKIP, C_00000000, C_7fffffff, C_7fffffff, C_00000001);
1787 OP(icode, ptr, iMAC0, dst, C_00000000, src, vol);
1790 #define VOLUME(icode, ptr, dst, src, vol) \
1791 _volume(icode, ptr, GPR(dst), GPR(src), GPR(vol))
1792 #define VOLUME_IN(icode, ptr, dst, src, vol) \
1793 _volume(icode, ptr, GPR(dst), EXTIN(src), GPR(vol))
1794 #define VOLUME_ADD(icode, ptr, dst, src, vol) \
1795 _volume_add(icode, ptr, GPR(dst), GPR(src), GPR(vol))
1796 #define VOLUME_ADDIN(icode, ptr, dst, src, vol) \
1797 _volume_add(icode, ptr, GPR(dst), EXTIN(src), GPR(vol))
1798 #define VOLUME_OUT(icode, ptr, dst, src, vol) \
1799 _volume_out(icode, ptr, EXTOUT(dst), GPR(src), GPR(vol))
1800 #define _SWITCH(icode, ptr, dst, src, sw) \
1801 OP((icode), ptr, iMACINT0, dst, C_00000000, src, sw);
1802 #define SWITCH(icode, ptr, dst, src, sw) \
1803 _SWITCH(icode, ptr, GPR(dst), GPR(src), GPR(sw))
1804 #define SWITCH_IN(icode, ptr, dst, src, sw) \
1805 _SWITCH(icode, ptr, GPR(dst), EXTIN(src), GPR(sw))
1806 #define _SWITCH_NEG(icode, ptr, dst, src) \
1807 OP((icode), ptr, iANDXOR, dst, src, C_00000001, C_00000001);
1808 #define SWITCH_NEG(icode, ptr, dst, src) \
1809 _SWITCH_NEG(icode, ptr, GPR(dst), GPR(src))
1812 static int _snd_emu10k1_init_efx(struct snd_emu10k1 *emu)
1814 int err, i, z, gpr, tmp, playback, capture;
1815 u32 ptr;
1816 struct snd_emu10k1_fx8010_code *icode;
1817 struct snd_emu10k1_fx8010_pcm_rec *ipcm = NULL;
1818 struct snd_emu10k1_fx8010_control_gpr *controls = NULL, *ctl;
1819 u32 *gpr_map;
1820 mm_segment_t seg;
1822 err = -ENOMEM;
1823 icode = kzalloc(sizeof(*icode), GFP_KERNEL);
1824 if (!icode)
1825 return err;
1827 icode->gpr_map = (u_int32_t __user *) kcalloc(256 + 160 + 160 + 2 * 512,
1828 sizeof(u_int32_t), GFP_KERNEL);
1829 if (!icode->gpr_map)
1830 goto __err_gpr;
1832 controls = kcalloc(SND_EMU10K1_GPR_CONTROLS,
1833 sizeof(struct snd_emu10k1_fx8010_control_gpr),
1834 GFP_KERNEL);
1835 if (!controls)
1836 goto __err_ctrls;
1838 ipcm = kzalloc(sizeof(*ipcm), GFP_KERNEL);
1839 if (!ipcm)
1840 goto __err_ipcm;
1842 gpr_map = (u32 __force *)icode->gpr_map;
1844 icode->tram_data_map = icode->gpr_map + 256;
1845 icode->tram_addr_map = icode->tram_data_map + 160;
1846 icode->code = icode->tram_addr_map + 160;
1848 /* clear free GPRs */
1849 for (i = 0; i < 256; i++)
1850 set_bit(i, icode->gpr_valid);
1852 /* clear TRAM data & address lines */
1853 for (i = 0; i < 160; i++)
1854 set_bit(i, icode->tram_valid);
1856 strcpy(icode->name, "SB Live! FX8010 code for ALSA v1.2 by Jaroslav Kysela");
1857 ptr = 0; i = 0;
1858 /* we have 12 inputs */
1859 playback = SND_EMU10K1_INPUTS;
1860 /* we have 6 playback channels and tone control doubles */
1861 capture = playback + (SND_EMU10K1_PLAYBACK_CHANNELS * 2);
1862 gpr = capture + SND_EMU10K1_CAPTURE_CHANNELS;
1863 tmp = 0x88; /* we need 4 temporary GPR */
1864 /* from 0x8c to 0xff is the area for tone control */
1866 /* stop FX processor */
1867 snd_emu10k1_ptr_write(emu, DBG, 0, (emu->fx8010.dbg = 0) | EMU10K1_DBG_SINGLE_STEP);
1870 * Process FX Buses
1872 OP(icode, &ptr, iMACINT0, GPR(0), C_00000000, FXBUS(FXBUS_PCM_LEFT), C_00000004);
1873 OP(icode, &ptr, iMACINT0, GPR(1), C_00000000, FXBUS(FXBUS_PCM_RIGHT), C_00000004);
1874 OP(icode, &ptr, iMACINT0, GPR(2), C_00000000, FXBUS(FXBUS_MIDI_LEFT), C_00000004);
1875 OP(icode, &ptr, iMACINT0, GPR(3), C_00000000, FXBUS(FXBUS_MIDI_RIGHT), C_00000004);
1876 OP(icode, &ptr, iMACINT0, GPR(4), C_00000000, FXBUS(FXBUS_PCM_LEFT_REAR), C_00000004);
1877 OP(icode, &ptr, iMACINT0, GPR(5), C_00000000, FXBUS(FXBUS_PCM_RIGHT_REAR), C_00000004);
1878 OP(icode, &ptr, iMACINT0, GPR(6), C_00000000, FXBUS(FXBUS_PCM_CENTER), C_00000004);
1879 OP(icode, &ptr, iMACINT0, GPR(7), C_00000000, FXBUS(FXBUS_PCM_LFE), C_00000004);
1880 OP(icode, &ptr, iMACINT0, GPR(8), C_00000000, C_00000000, C_00000000); /* S/PDIF left */
1881 OP(icode, &ptr, iMACINT0, GPR(9), C_00000000, C_00000000, C_00000000); /* S/PDIF right */
1882 OP(icode, &ptr, iMACINT0, GPR(10), C_00000000, FXBUS(FXBUS_PCM_LEFT_FRONT), C_00000004);
1883 OP(icode, &ptr, iMACINT0, GPR(11), C_00000000, FXBUS(FXBUS_PCM_RIGHT_FRONT), C_00000004);
1885 /* Raw S/PDIF PCM */
1886 ipcm->substream = 0;
1887 ipcm->channels = 2;
1888 ipcm->tram_start = 0;
1889 ipcm->buffer_size = (64 * 1024) / 2;
1890 ipcm->gpr_size = gpr++;
1891 ipcm->gpr_ptr = gpr++;
1892 ipcm->gpr_count = gpr++;
1893 ipcm->gpr_tmpcount = gpr++;
1894 ipcm->gpr_trigger = gpr++;
1895 ipcm->gpr_running = gpr++;
1896 ipcm->etram[0] = 0;
1897 ipcm->etram[1] = 1;
1899 gpr_map[gpr + 0] = 0xfffff000;
1900 gpr_map[gpr + 1] = 0xffff0000;
1901 gpr_map[gpr + 2] = 0x70000000;
1902 gpr_map[gpr + 3] = 0x00000007;
1903 gpr_map[gpr + 4] = 0x001f << 11;
1904 gpr_map[gpr + 5] = 0x001c << 11;
1905 gpr_map[gpr + 6] = (0x22 - 0x01) - 1; /* skip at 01 to 22 */
1906 gpr_map[gpr + 7] = (0x22 - 0x06) - 1; /* skip at 06 to 22 */
1907 gpr_map[gpr + 8] = 0x2000000 + (2<<11);
1908 gpr_map[gpr + 9] = 0x4000000 + (2<<11);
1909 gpr_map[gpr + 10] = 1<<11;
1910 gpr_map[gpr + 11] = (0x24 - 0x0a) - 1; /* skip at 0a to 24 */
1911 gpr_map[gpr + 12] = 0;
1913 /* if the trigger flag is not set, skip */
1914 /* 00: */ OP(icode, &ptr, iMAC0, C_00000000, GPR(ipcm->gpr_trigger), C_00000000, C_00000000);
1915 /* 01: */ OP(icode, &ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_ZERO, GPR(gpr + 6));
1916 /* if the running flag is set, we're running */
1917 /* 02: */ OP(icode, &ptr, iMAC0, C_00000000, GPR(ipcm->gpr_running), C_00000000, C_00000000);
1918 /* 03: */ OP(icode, &ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, C_00000004);
1919 /* wait until ((GPR_DBAC>>11) & 0x1f) == 0x1c) */
1920 /* 04: */ OP(icode, &ptr, iANDXOR, GPR(tmp + 0), GPR_DBAC, GPR(gpr + 4), C_00000000);
1921 /* 05: */ OP(icode, &ptr, iMACINT0, C_00000000, GPR(tmp + 0), C_ffffffff, GPR(gpr + 5));
1922 /* 06: */ OP(icode, &ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, GPR(gpr + 7));
1923 /* 07: */ OP(icode, &ptr, iACC3, GPR(gpr + 12), C_00000010, C_00000001, C_00000000);
1925 /* 08: */ OP(icode, &ptr, iANDXOR, GPR(ipcm->gpr_running), GPR(ipcm->gpr_running), C_00000000, C_00000001);
1926 /* 09: */ OP(icode, &ptr, iACC3, GPR(gpr + 12), GPR(gpr + 12), C_ffffffff, C_00000000);
1927 /* 0a: */ OP(icode, &ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, GPR(gpr + 11));
1928 /* 0b: */ OP(icode, &ptr, iACC3, GPR(gpr + 12), C_00000001, C_00000000, C_00000000);
1930 /* 0c: */ OP(icode, &ptr, iANDXOR, GPR(tmp + 0), ETRAM_DATA(ipcm->etram[0]), GPR(gpr + 0), C_00000000);
1931 /* 0d: */ OP(icode, &ptr, iLOG, GPR(tmp + 0), GPR(tmp + 0), GPR(gpr + 3), C_00000000);
1932 /* 0e: */ OP(icode, &ptr, iANDXOR, GPR(8), GPR(tmp + 0), GPR(gpr + 1), GPR(gpr + 2));
1933 /* 0f: */ OP(icode, &ptr, iSKIP, C_00000000, GPR_COND, CC_REG_MINUS, C_00000001);
1934 /* 10: */ OP(icode, &ptr, iANDXOR, GPR(8), GPR(8), GPR(gpr + 1), GPR(gpr + 2));
1936 /* 11: */ OP(icode, &ptr, iANDXOR, GPR(tmp + 0), ETRAM_DATA(ipcm->etram[1]), GPR(gpr + 0), C_00000000);
1937 /* 12: */ OP(icode, &ptr, iLOG, GPR(tmp + 0), GPR(tmp + 0), GPR(gpr + 3), C_00000000);
1938 /* 13: */ OP(icode, &ptr, iANDXOR, GPR(9), GPR(tmp + 0), GPR(gpr + 1), GPR(gpr + 2));
1939 /* 14: */ OP(icode, &ptr, iSKIP, C_00000000, GPR_COND, CC_REG_MINUS, C_00000001);
1940 /* 15: */ OP(icode, &ptr, iANDXOR, GPR(9), GPR(9), GPR(gpr + 1), GPR(gpr + 2));
1942 /* 16: */ OP(icode, &ptr, iACC3, GPR(tmp + 0), GPR(ipcm->gpr_ptr), C_00000001, C_00000000);
1943 /* 17: */ OP(icode, &ptr, iMACINT0, C_00000000, GPR(tmp + 0), C_ffffffff, GPR(ipcm->gpr_size));
1944 /* 18: */ OP(icode, &ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_MINUS, C_00000001);
1945 /* 19: */ OP(icode, &ptr, iACC3, GPR(tmp + 0), C_00000000, C_00000000, C_00000000);
1946 /* 1a: */ OP(icode, &ptr, iACC3, GPR(ipcm->gpr_ptr), GPR(tmp + 0), C_00000000, C_00000000);
1948 /* 1b: */ OP(icode, &ptr, iACC3, GPR(ipcm->gpr_tmpcount), GPR(ipcm->gpr_tmpcount), C_ffffffff, C_00000000);
1949 /* 1c: */ OP(icode, &ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, C_00000002);
1950 /* 1d: */ OP(icode, &ptr, iACC3, GPR(ipcm->gpr_tmpcount), GPR(ipcm->gpr_count), C_00000000, C_00000000);
1951 /* 1e: */ OP(icode, &ptr, iACC3, GPR_IRQ, C_80000000, C_00000000, C_00000000);
1952 /* 1f: */ OP(icode, &ptr, iANDXOR, GPR(ipcm->gpr_running), GPR(ipcm->gpr_running), C_00000001, C_00010000);
1954 /* 20: */ OP(icode, &ptr, iANDXOR, GPR(ipcm->gpr_running), GPR(ipcm->gpr_running), C_00010000, C_00000001);
1955 /* 21: */ OP(icode, &ptr, iSKIP, C_00000000, C_7fffffff, C_7fffffff, C_00000002);
1957 /* 22: */ OP(icode, &ptr, iMACINT1, ETRAM_ADDR(ipcm->etram[0]), GPR(gpr + 8), GPR_DBAC, C_ffffffff);
1958 /* 23: */ OP(icode, &ptr, iMACINT1, ETRAM_ADDR(ipcm->etram[1]), GPR(gpr + 9), GPR_DBAC, C_ffffffff);
1960 /* 24: */
1961 gpr += 13;
1963 /* Wave Playback Volume */
1964 for (z = 0; z < 2; z++)
1965 VOLUME(icode, &ptr, playback + z, z, gpr + z);
1966 snd_emu10k1_init_stereo_control(controls + i++, "Wave Playback Volume", gpr, 100);
1967 gpr += 2;
1969 /* Wave Surround Playback Volume */
1970 for (z = 0; z < 2; z++)
1971 VOLUME(icode, &ptr, playback + 2 + z, z, gpr + z);
1972 snd_emu10k1_init_stereo_control(controls + i++, "Wave Surround Playback Volume", gpr, 0);
1973 gpr += 2;
1975 /* Wave Center/LFE Playback Volume */
1976 OP(icode, &ptr, iACC3, GPR(tmp + 0), FXBUS(FXBUS_PCM_LEFT), FXBUS(FXBUS_PCM_RIGHT), C_00000000);
1977 OP(icode, &ptr, iMACINT0, GPR(tmp + 0), C_00000000, GPR(tmp + 0), C_00000002);
1978 VOLUME(icode, &ptr, playback + 4, tmp + 0, gpr);
1979 snd_emu10k1_init_mono_control(controls + i++, "Wave Center Playback Volume", gpr++, 0);
1980 VOLUME(icode, &ptr, playback + 5, tmp + 0, gpr);
1981 snd_emu10k1_init_mono_control(controls + i++, "Wave LFE Playback Volume", gpr++, 0);
1983 /* Wave Capture Volume + Switch */
1984 for (z = 0; z < 2; z++) {
1985 SWITCH(icode, &ptr, tmp + 0, z, gpr + 2 + z);
1986 VOLUME(icode, &ptr, capture + z, tmp + 0, gpr + z);
1988 snd_emu10k1_init_stereo_control(controls + i++, "Wave Capture Volume", gpr, 0);
1989 snd_emu10k1_init_stereo_onoff_control(controls + i++, "Wave Capture Switch", gpr + 2, 0);
1990 gpr += 4;
1992 /* Synth Playback Volume */
1993 for (z = 0; z < 2; z++)
1994 VOLUME_ADD(icode, &ptr, playback + z, 2 + z, gpr + z);
1995 snd_emu10k1_init_stereo_control(controls + i++, "Synth Playback Volume", gpr, 100);
1996 gpr += 2;
1998 /* Synth Capture Volume + Switch */
1999 for (z = 0; z < 2; z++) {
2000 SWITCH(icode, &ptr, tmp + 0, 2 + z, gpr + 2 + z);
2001 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
2003 snd_emu10k1_init_stereo_control(controls + i++, "Synth Capture Volume", gpr, 0);
2004 snd_emu10k1_init_stereo_onoff_control(controls + i++, "Synth Capture Switch", gpr + 2, 0);
2005 gpr += 4;
2007 /* Surround Digital Playback Volume (renamed later without Digital) */
2008 for (z = 0; z < 2; z++)
2009 VOLUME_ADD(icode, &ptr, playback + 2 + z, 4 + z, gpr + z);
2010 snd_emu10k1_init_stereo_control(controls + i++, "Surround Digital Playback Volume", gpr, 100);
2011 gpr += 2;
2013 /* Surround Capture Volume + Switch */
2014 for (z = 0; z < 2; z++) {
2015 SWITCH(icode, &ptr, tmp + 0, 4 + z, gpr + 2 + z);
2016 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
2018 snd_emu10k1_init_stereo_control(controls + i++, "Surround Capture Volume", gpr, 0);
2019 snd_emu10k1_init_stereo_onoff_control(controls + i++, "Surround Capture Switch", gpr + 2, 0);
2020 gpr += 4;
2022 /* Center Playback Volume (renamed later without Digital) */
2023 VOLUME_ADD(icode, &ptr, playback + 4, 6, gpr);
2024 snd_emu10k1_init_mono_control(controls + i++, "Center Digital Playback Volume", gpr++, 100);
2026 /* LFE Playback Volume + Switch (renamed later without Digital) */
2027 VOLUME_ADD(icode, &ptr, playback + 5, 7, gpr);
2028 snd_emu10k1_init_mono_control(controls + i++, "LFE Digital Playback Volume", gpr++, 100);
2030 /* Front Playback Volume */
2031 for (z = 0; z < 2; z++)
2032 VOLUME_ADD(icode, &ptr, playback + z, 10 + z, gpr + z);
2033 snd_emu10k1_init_stereo_control(controls + i++, "Front Playback Volume", gpr, 100);
2034 gpr += 2;
2036 /* Front Capture Volume + Switch */
2037 for (z = 0; z < 2; z++) {
2038 SWITCH(icode, &ptr, tmp + 0, 10 + z, gpr + 2);
2039 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
2041 snd_emu10k1_init_stereo_control(controls + i++, "Front Capture Volume", gpr, 0);
2042 snd_emu10k1_init_mono_onoff_control(controls + i++, "Front Capture Switch", gpr + 2, 0);
2043 gpr += 3;
2046 * Process inputs
2049 if (emu->fx8010.extin_mask & ((1<<EXTIN_AC97_L)|(1<<EXTIN_AC97_R))) {
2050 /* AC'97 Playback Volume */
2051 VOLUME_ADDIN(icode, &ptr, playback + 0, EXTIN_AC97_L, gpr); gpr++;
2052 VOLUME_ADDIN(icode, &ptr, playback + 1, EXTIN_AC97_R, gpr); gpr++;
2053 snd_emu10k1_init_stereo_control(controls + i++, "AC97 Playback Volume", gpr-2, 0);
2054 /* AC'97 Capture Volume */
2055 VOLUME_ADDIN(icode, &ptr, capture + 0, EXTIN_AC97_L, gpr); gpr++;
2056 VOLUME_ADDIN(icode, &ptr, capture + 1, EXTIN_AC97_R, gpr); gpr++;
2057 snd_emu10k1_init_stereo_control(controls + i++, "AC97 Capture Volume", gpr-2, 100);
2060 if (emu->fx8010.extin_mask & ((1<<EXTIN_SPDIF_CD_L)|(1<<EXTIN_SPDIF_CD_R))) {
2061 /* IEC958 TTL Playback Volume */
2062 for (z = 0; z < 2; z++)
2063 VOLUME_ADDIN(icode, &ptr, playback + z, EXTIN_SPDIF_CD_L + z, gpr + z);
2064 snd_emu10k1_init_stereo_control(controls + i++, SNDRV_CTL_NAME_IEC958("TTL ",PLAYBACK,VOLUME), gpr, 0);
2065 gpr += 2;
2067 /* IEC958 TTL Capture Volume + Switch */
2068 for (z = 0; z < 2; z++) {
2069 SWITCH_IN(icode, &ptr, tmp + 0, EXTIN_SPDIF_CD_L + z, gpr + 2 + z);
2070 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
2072 snd_emu10k1_init_stereo_control(controls + i++, SNDRV_CTL_NAME_IEC958("TTL ",CAPTURE,VOLUME), gpr, 0);
2073 snd_emu10k1_init_stereo_onoff_control(controls + i++, SNDRV_CTL_NAME_IEC958("TTL ",CAPTURE,SWITCH), gpr + 2, 0);
2074 gpr += 4;
2077 if (emu->fx8010.extin_mask & ((1<<EXTIN_ZOOM_L)|(1<<EXTIN_ZOOM_R))) {
2078 /* Zoom Video Playback Volume */
2079 for (z = 0; z < 2; z++)
2080 VOLUME_ADDIN(icode, &ptr, playback + z, EXTIN_ZOOM_L + z, gpr + z);
2081 snd_emu10k1_init_stereo_control(controls + i++, "Zoom Video Playback Volume", gpr, 0);
2082 gpr += 2;
2084 /* Zoom Video Capture Volume + Switch */
2085 for (z = 0; z < 2; z++) {
2086 SWITCH_IN(icode, &ptr, tmp + 0, EXTIN_ZOOM_L + z, gpr + 2 + z);
2087 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
2089 snd_emu10k1_init_stereo_control(controls + i++, "Zoom Video Capture Volume", gpr, 0);
2090 snd_emu10k1_init_stereo_onoff_control(controls + i++, "Zoom Video Capture Switch", gpr + 2, 0);
2091 gpr += 4;
2094 if (emu->fx8010.extin_mask & ((1<<EXTIN_TOSLINK_L)|(1<<EXTIN_TOSLINK_R))) {
2095 /* IEC958 Optical Playback Volume */
2096 for (z = 0; z < 2; z++)
2097 VOLUME_ADDIN(icode, &ptr, playback + z, EXTIN_TOSLINK_L + z, gpr + z);
2098 snd_emu10k1_init_stereo_control(controls + i++, SNDRV_CTL_NAME_IEC958("LiveDrive ",PLAYBACK,VOLUME), gpr, 0);
2099 gpr += 2;
2101 /* IEC958 Optical Capture Volume */
2102 for (z = 0; z < 2; z++) {
2103 SWITCH_IN(icode, &ptr, tmp + 0, EXTIN_TOSLINK_L + z, gpr + 2 + z);
2104 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
2106 snd_emu10k1_init_stereo_control(controls + i++, SNDRV_CTL_NAME_IEC958("LiveDrive ",CAPTURE,VOLUME), gpr, 0);
2107 snd_emu10k1_init_stereo_onoff_control(controls + i++, SNDRV_CTL_NAME_IEC958("LiveDrive ",CAPTURE,SWITCH), gpr + 2, 0);
2108 gpr += 4;
2111 if (emu->fx8010.extin_mask & ((1<<EXTIN_LINE1_L)|(1<<EXTIN_LINE1_R))) {
2112 /* Line LiveDrive Playback Volume */
2113 for (z = 0; z < 2; z++)
2114 VOLUME_ADDIN(icode, &ptr, playback + z, EXTIN_LINE1_L + z, gpr + z);
2115 snd_emu10k1_init_stereo_control(controls + i++, "Line LiveDrive Playback Volume", gpr, 0);
2116 gpr += 2;
2118 /* Line LiveDrive Capture Volume + Switch */
2119 for (z = 0; z < 2; z++) {
2120 SWITCH_IN(icode, &ptr, tmp + 0, EXTIN_LINE1_L + z, gpr + 2 + z);
2121 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
2123 snd_emu10k1_init_stereo_control(controls + i++, "Line LiveDrive Capture Volume", gpr, 0);
2124 snd_emu10k1_init_stereo_onoff_control(controls + i++, "Line LiveDrive Capture Switch", gpr + 2, 0);
2125 gpr += 4;
2128 if (emu->fx8010.extin_mask & ((1<<EXTIN_COAX_SPDIF_L)|(1<<EXTIN_COAX_SPDIF_R))) {
2129 /* IEC958 Coax Playback Volume */
2130 for (z = 0; z < 2; z++)
2131 VOLUME_ADDIN(icode, &ptr, playback + z, EXTIN_COAX_SPDIF_L + z, gpr + z);
2132 snd_emu10k1_init_stereo_control(controls + i++, SNDRV_CTL_NAME_IEC958("Coaxial ",PLAYBACK,VOLUME), gpr, 0);
2133 gpr += 2;
2135 /* IEC958 Coax Capture Volume + Switch */
2136 for (z = 0; z < 2; z++) {
2137 SWITCH_IN(icode, &ptr, tmp + 0, EXTIN_COAX_SPDIF_L + z, gpr + 2 + z);
2138 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
2140 snd_emu10k1_init_stereo_control(controls + i++, SNDRV_CTL_NAME_IEC958("Coaxial ",CAPTURE,VOLUME), gpr, 0);
2141 snd_emu10k1_init_stereo_onoff_control(controls + i++, SNDRV_CTL_NAME_IEC958("Coaxial ",CAPTURE,SWITCH), gpr + 2, 0);
2142 gpr += 4;
2145 if (emu->fx8010.extin_mask & ((1<<EXTIN_LINE2_L)|(1<<EXTIN_LINE2_R))) {
2146 /* Line LiveDrive Playback Volume */
2147 for (z = 0; z < 2; z++)
2148 VOLUME_ADDIN(icode, &ptr, playback + z, EXTIN_LINE2_L + z, gpr + z);
2149 snd_emu10k1_init_stereo_control(controls + i++, "Line2 LiveDrive Playback Volume", gpr, 0);
2150 controls[i-1].id.index = 1;
2151 gpr += 2;
2153 /* Line LiveDrive Capture Volume */
2154 for (z = 0; z < 2; z++) {
2155 SWITCH_IN(icode, &ptr, tmp + 0, EXTIN_LINE2_L + z, gpr + 2 + z);
2156 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
2158 snd_emu10k1_init_stereo_control(controls + i++, "Line2 LiveDrive Capture Volume", gpr, 0);
2159 controls[i-1].id.index = 1;
2160 snd_emu10k1_init_stereo_onoff_control(controls + i++, "Line2 LiveDrive Capture Switch", gpr + 2, 0);
2161 controls[i-1].id.index = 1;
2162 gpr += 4;
2166 * Process tone control
2168 OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 0), GPR(playback + 0), C_00000000, C_00000000); /* left */
2169 OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 1), GPR(playback + 1), C_00000000, C_00000000); /* right */
2170 OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 2), GPR(playback + 2), C_00000000, C_00000000); /* rear left */
2171 OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 3), GPR(playback + 3), C_00000000, C_00000000); /* rear right */
2172 OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 4), GPR(playback + 4), C_00000000, C_00000000); /* center */
2173 OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 5), GPR(playback + 5), C_00000000, C_00000000); /* LFE */
2175 ctl = &controls[i + 0];
2176 ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
2177 strcpy(ctl->id.name, "Tone Control - Bass");
2178 ctl->vcount = 2;
2179 ctl->count = 10;
2180 ctl->min = 0;
2181 ctl->max = 40;
2182 ctl->value[0] = ctl->value[1] = 20;
2183 ctl->tlv = snd_emu10k1_bass_treble_db_scale;
2184 ctl->translation = EMU10K1_GPR_TRANSLATION_BASS;
2185 ctl = &controls[i + 1];
2186 ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
2187 strcpy(ctl->id.name, "Tone Control - Treble");
2188 ctl->vcount = 2;
2189 ctl->count = 10;
2190 ctl->min = 0;
2191 ctl->max = 40;
2192 ctl->value[0] = ctl->value[1] = 20;
2193 ctl->tlv = snd_emu10k1_bass_treble_db_scale;
2194 ctl->translation = EMU10K1_GPR_TRANSLATION_TREBLE;
2196 #define BASS_GPR 0x8c
2197 #define TREBLE_GPR 0x96
2199 for (z = 0; z < 5; z++) {
2200 int j;
2201 for (j = 0; j < 2; j++) {
2202 controls[i + 0].gpr[z * 2 + j] = BASS_GPR + z * 2 + j;
2203 controls[i + 1].gpr[z * 2 + j] = TREBLE_GPR + z * 2 + j;
2206 for (z = 0; z < 3; z++) { /* front/rear/center-lfe */
2207 int j, k, l, d;
2208 for (j = 0; j < 2; j++) { /* left/right */
2209 k = 0xa0 + (z * 8) + (j * 4);
2210 l = 0xd0 + (z * 8) + (j * 4);
2211 d = playback + SND_EMU10K1_PLAYBACK_CHANNELS + z * 2 + j;
2213 OP(icode, &ptr, iMAC0, C_00000000, C_00000000, GPR(d), GPR(BASS_GPR + 0 + j));
2214 OP(icode, &ptr, iMACMV, GPR(k+1), GPR(k), GPR(k+1), GPR(BASS_GPR + 4 + j));
2215 OP(icode, &ptr, iMACMV, GPR(k), GPR(d), GPR(k), GPR(BASS_GPR + 2 + j));
2216 OP(icode, &ptr, iMACMV, GPR(k+3), GPR(k+2), GPR(k+3), GPR(BASS_GPR + 8 + j));
2217 OP(icode, &ptr, iMAC0, GPR(k+2), GPR_ACCU, GPR(k+2), GPR(BASS_GPR + 6 + j));
2218 OP(icode, &ptr, iACC3, GPR(k+2), GPR(k+2), GPR(k+2), C_00000000);
2220 OP(icode, &ptr, iMAC0, C_00000000, C_00000000, GPR(k+2), GPR(TREBLE_GPR + 0 + j));
2221 OP(icode, &ptr, iMACMV, GPR(l+1), GPR(l), GPR(l+1), GPR(TREBLE_GPR + 4 + j));
2222 OP(icode, &ptr, iMACMV, GPR(l), GPR(k+2), GPR(l), GPR(TREBLE_GPR + 2 + j));
2223 OP(icode, &ptr, iMACMV, GPR(l+3), GPR(l+2), GPR(l+3), GPR(TREBLE_GPR + 8 + j));
2224 OP(icode, &ptr, iMAC0, GPR(l+2), GPR_ACCU, GPR(l+2), GPR(TREBLE_GPR + 6 + j));
2225 OP(icode, &ptr, iMACINT0, GPR(l+2), C_00000000, GPR(l+2), C_00000010);
2227 OP(icode, &ptr, iACC3, GPR(d), GPR(l+2), C_00000000, C_00000000);
2229 if (z == 2) /* center */
2230 break;
2233 i += 2;
2235 #undef BASS_GPR
2236 #undef TREBLE_GPR
2238 for (z = 0; z < 6; z++) {
2239 SWITCH(icode, &ptr, tmp + 0, playback + SND_EMU10K1_PLAYBACK_CHANNELS + z, gpr + 0);
2240 SWITCH_NEG(icode, &ptr, tmp + 1, gpr + 0);
2241 SWITCH(icode, &ptr, tmp + 1, playback + z, tmp + 1);
2242 OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + z), GPR(tmp + 0), GPR(tmp + 1), C_00000000);
2244 snd_emu10k1_init_stereo_onoff_control(controls + i++, "Tone Control - Switch", gpr, 0);
2245 gpr += 2;
2248 * Process outputs
2250 if (emu->fx8010.extout_mask & ((1<<EXTOUT_AC97_L)|(1<<EXTOUT_AC97_R))) {
2251 /* AC'97 Playback Volume */
2253 for (z = 0; z < 2; z++)
2254 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_AC97_L + z), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + z), C_00000000, C_00000000);
2257 if (emu->fx8010.extout_mask & ((1<<EXTOUT_TOSLINK_L)|(1<<EXTOUT_TOSLINK_R))) {
2258 /* IEC958 Optical Raw Playback Switch */
2260 for (z = 0; z < 2; z++) {
2261 SWITCH(icode, &ptr, tmp + 0, 8 + z, gpr + z);
2262 SWITCH_NEG(icode, &ptr, tmp + 1, gpr + z);
2263 SWITCH(icode, &ptr, tmp + 1, playback + SND_EMU10K1_PLAYBACK_CHANNELS + z, tmp + 1);
2264 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_TOSLINK_L + z), GPR(tmp + 0), GPR(tmp + 1), C_00000000);
2265 #ifdef EMU10K1_CAPTURE_DIGITAL_OUT
2266 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_ADC_CAP_L + z), GPR(tmp + 0), GPR(tmp + 1), C_00000000);
2267 #endif
2270 snd_emu10k1_init_stereo_onoff_control(controls + i++, SNDRV_CTL_NAME_IEC958("Optical Raw ",PLAYBACK,SWITCH), gpr, 0);
2271 gpr += 2;
2274 if (emu->fx8010.extout_mask & ((1<<EXTOUT_HEADPHONE_L)|(1<<EXTOUT_HEADPHONE_R))) {
2275 /* Headphone Playback Volume */
2277 for (z = 0; z < 2; z++) {
2278 SWITCH(icode, &ptr, tmp + 0, playback + SND_EMU10K1_PLAYBACK_CHANNELS + 4 + z, gpr + 2 + z);
2279 SWITCH_NEG(icode, &ptr, tmp + 1, gpr + 2 + z);
2280 SWITCH(icode, &ptr, tmp + 1, playback + SND_EMU10K1_PLAYBACK_CHANNELS + z, tmp + 1);
2281 OP(icode, &ptr, iACC3, GPR(tmp + 0), GPR(tmp + 0), GPR(tmp + 1), C_00000000);
2282 VOLUME_OUT(icode, &ptr, EXTOUT_HEADPHONE_L + z, tmp + 0, gpr + z);
2285 snd_emu10k1_init_stereo_control(controls + i++, "Headphone Playback Volume", gpr + 0, 0);
2286 controls[i-1].id.index = 1; /* AC'97 can have also Headphone control */
2287 snd_emu10k1_init_mono_onoff_control(controls + i++, "Headphone Center Playback Switch", gpr + 2, 0);
2288 controls[i-1].id.index = 1;
2289 snd_emu10k1_init_mono_onoff_control(controls + i++, "Headphone LFE Playback Switch", gpr + 3, 0);
2290 controls[i-1].id.index = 1;
2292 gpr += 4;
2295 if (emu->fx8010.extout_mask & ((1<<EXTOUT_REAR_L)|(1<<EXTOUT_REAR_R)))
2296 for (z = 0; z < 2; z++)
2297 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_REAR_L + z), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 2 + z), C_00000000, C_00000000);
2299 if (emu->fx8010.extout_mask & ((1<<EXTOUT_AC97_REAR_L)|(1<<EXTOUT_AC97_REAR_R)))
2300 for (z = 0; z < 2; z++)
2301 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_AC97_REAR_L + z), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 2 + z), C_00000000, C_00000000);
2303 if (emu->fx8010.extout_mask & (1<<EXTOUT_AC97_CENTER)) {
2304 #ifndef EMU10K1_CENTER_LFE_FROM_FRONT
2305 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_AC97_CENTER), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 4), C_00000000, C_00000000);
2306 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_ACENTER), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 4), C_00000000, C_00000000);
2307 #else
2308 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_AC97_CENTER), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 0), C_00000000, C_00000000);
2309 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_ACENTER), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 0), C_00000000, C_00000000);
2310 #endif
2313 if (emu->fx8010.extout_mask & (1<<EXTOUT_AC97_LFE)) {
2314 #ifndef EMU10K1_CENTER_LFE_FROM_FRONT
2315 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_AC97_LFE), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 5), C_00000000, C_00000000);
2316 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_ALFE), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 5), C_00000000, C_00000000);
2317 #else
2318 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_AC97_LFE), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 1), C_00000000, C_00000000);
2319 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_ALFE), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 1), C_00000000, C_00000000);
2320 #endif
2323 #ifndef EMU10K1_CAPTURE_DIGITAL_OUT
2324 for (z = 0; z < 2; z++)
2325 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_ADC_CAP_L + z), GPR(capture + z), C_00000000, C_00000000);
2326 #endif
2328 if (emu->fx8010.extout_mask & (1<<EXTOUT_MIC_CAP))
2329 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_MIC_CAP), GPR(capture + 2), C_00000000, C_00000000);
2331 /* EFX capture - capture the 16 EXTINS */
2332 if (emu->card_capabilities->sblive51) {
2333 /* On the Live! 5.1, FXBUS2(1) and FXBUS(2) are shared with EXTOUT_ACENTER
2334 * and EXTOUT_ALFE, so we can't connect inputs to them for multitrack recording.
2336 * Since only 14 of the 16 EXTINs are used, this is not a big problem.
2337 * We route AC97L and R to FX capture 14 and 15, SPDIF CD in to FX capture
2338 * 0 and 3, then the rest of the EXTINs to the corresponding FX capture
2339 * channel. Multitrack recorders will still see the center/lfe output signal
2340 * on the second and third channels.
2342 OP(icode, &ptr, iACC3, FXBUS2(14), C_00000000, C_00000000, EXTIN(0));
2343 OP(icode, &ptr, iACC3, FXBUS2(15), C_00000000, C_00000000, EXTIN(1));
2344 OP(icode, &ptr, iACC3, FXBUS2(0), C_00000000, C_00000000, EXTIN(2));
2345 OP(icode, &ptr, iACC3, FXBUS2(3), C_00000000, C_00000000, EXTIN(3));
2346 for (z = 4; z < 14; z++)
2347 OP(icode, &ptr, iACC3, FXBUS2(z), C_00000000, C_00000000, EXTIN(z));
2348 } else {
2349 for (z = 0; z < 16; z++)
2350 OP(icode, &ptr, iACC3, FXBUS2(z), C_00000000, C_00000000, EXTIN(z));
2354 if (gpr > tmp) {
2355 snd_BUG();
2356 err = -EIO;
2357 goto __err;
2359 if (i > SND_EMU10K1_GPR_CONTROLS) {
2360 snd_BUG();
2361 err = -EIO;
2362 goto __err;
2365 /* clear remaining instruction memory */
2366 while (ptr < 0x200)
2367 OP(icode, &ptr, iACC3, C_00000000, C_00000000, C_00000000, C_00000000);
2369 if ((err = snd_emu10k1_fx8010_tram_setup(emu, ipcm->buffer_size)) < 0)
2370 goto __err;
2371 seg = snd_enter_user();
2372 icode->gpr_add_control_count = i;
2373 icode->gpr_add_controls = (struct snd_emu10k1_fx8010_control_gpr __user *)controls;
2374 emu->support_tlv = 1; /* support TLV */
2375 err = snd_emu10k1_icode_poke(emu, icode);
2376 emu->support_tlv = 0; /* clear again */
2377 snd_leave_user(seg);
2378 if (err >= 0)
2379 err = snd_emu10k1_ipcm_poke(emu, ipcm);
2380 __err:
2381 kfree(ipcm);
2382 __err_ipcm:
2383 kfree(controls);
2384 __err_ctrls:
2385 kfree((void __force *)icode->gpr_map);
2386 __err_gpr:
2387 kfree(icode);
2388 return err;
2391 int snd_emu10k1_init_efx(struct snd_emu10k1 *emu)
2393 spin_lock_init(&emu->fx8010.irq_lock);
2394 INIT_LIST_HEAD(&emu->fx8010.gpr_ctl);
2395 if (emu->audigy)
2396 return _snd_emu10k1_audigy_init_efx(emu);
2397 else
2398 return _snd_emu10k1_init_efx(emu);
2401 void snd_emu10k1_free_efx(struct snd_emu10k1 *emu)
2403 /* stop processor */
2404 if (emu->audigy)
2405 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg = A_DBG_SINGLE_STEP);
2406 else
2407 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg = EMU10K1_DBG_SINGLE_STEP);
2410 #if 0 /* FIXME: who use them? */
2411 int snd_emu10k1_fx8010_tone_control_activate(struct snd_emu10k1 *emu, int output)
2413 if (output < 0 || output >= 6)
2414 return -EINVAL;
2415 snd_emu10k1_ptr_write(emu, emu->gpr_base + 0x94 + output, 0, 1);
2416 return 0;
2419 int snd_emu10k1_fx8010_tone_control_deactivate(struct snd_emu10k1 *emu, int output)
2421 if (output < 0 || output >= 6)
2422 return -EINVAL;
2423 snd_emu10k1_ptr_write(emu, emu->gpr_base + 0x94 + output, 0, 0);
2424 return 0;
2426 #endif
2428 int snd_emu10k1_fx8010_tram_setup(struct snd_emu10k1 *emu, u32 size)
2430 u8 size_reg = 0;
2432 /* size is in samples */
2433 if (size != 0) {
2434 size = (size - 1) >> 13;
2436 while (size) {
2437 size >>= 1;
2438 size_reg++;
2440 size = 0x2000 << size_reg;
2442 if ((emu->fx8010.etram_pages.bytes / 2) == size)
2443 return 0;
2444 spin_lock_irq(&emu->emu_lock);
2445 outl(HCFG_LOCKTANKCACHE_MASK | inl(emu->port + HCFG), emu->port + HCFG);
2446 spin_unlock_irq(&emu->emu_lock);
2447 snd_emu10k1_ptr_write(emu, TCB, 0, 0);
2448 snd_emu10k1_ptr_write(emu, TCBS, 0, 0);
2449 if (emu->fx8010.etram_pages.area != NULL) {
2450 snd_dma_free_pages(&emu->fx8010.etram_pages);
2451 emu->fx8010.etram_pages.area = NULL;
2452 emu->fx8010.etram_pages.bytes = 0;
2455 if (size > 0) {
2456 if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(emu->pci),
2457 size * 2, &emu->fx8010.etram_pages) < 0)
2458 return -ENOMEM;
2459 memset(emu->fx8010.etram_pages.area, 0, size * 2);
2460 snd_emu10k1_ptr_write(emu, TCB, 0, emu->fx8010.etram_pages.addr);
2461 snd_emu10k1_ptr_write(emu, TCBS, 0, size_reg);
2462 spin_lock_irq(&emu->emu_lock);
2463 outl(inl(emu->port + HCFG) & ~HCFG_LOCKTANKCACHE_MASK, emu->port + HCFG);
2464 spin_unlock_irq(&emu->emu_lock);
2467 return 0;
2470 static int snd_emu10k1_fx8010_open(struct snd_hwdep * hw, struct file *file)
2472 return 0;
2475 static void copy_string(char *dst, char *src, char *null, int idx)
2477 if (src == NULL)
2478 sprintf(dst, "%s %02X", null, idx);
2479 else
2480 strcpy(dst, src);
2483 static void snd_emu10k1_fx8010_info(struct snd_emu10k1 *emu,
2484 struct snd_emu10k1_fx8010_info *info)
2486 char **fxbus, **extin, **extout;
2487 unsigned short fxbus_mask, extin_mask, extout_mask;
2488 int res;
2490 info->internal_tram_size = emu->fx8010.itram_size;
2491 info->external_tram_size = emu->fx8010.etram_pages.bytes / 2;
2492 fxbus = fxbuses;
2493 extin = emu->audigy ? audigy_ins : creative_ins;
2494 extout = emu->audigy ? audigy_outs : creative_outs;
2495 fxbus_mask = emu->fx8010.fxbus_mask;
2496 extin_mask = emu->fx8010.extin_mask;
2497 extout_mask = emu->fx8010.extout_mask;
2498 for (res = 0; res < 16; res++, fxbus++, extin++, extout++) {
2499 copy_string(info->fxbus_names[res], fxbus_mask & (1 << res) ? *fxbus : NULL, "FXBUS", res);
2500 copy_string(info->extin_names[res], extin_mask & (1 << res) ? *extin : NULL, "Unused", res);
2501 copy_string(info->extout_names[res], extout_mask & (1 << res) ? *extout : NULL, "Unused", res);
2503 for (res = 16; res < 32; res++, extout++)
2504 copy_string(info->extout_names[res], extout_mask & (1 << res) ? *extout : NULL, "Unused", res);
2505 info->gpr_controls = emu->fx8010.gpr_count;
2508 static int snd_emu10k1_fx8010_ioctl(struct snd_hwdep * hw, struct file *file, unsigned int cmd, unsigned long arg)
2510 struct snd_emu10k1 *emu = hw->private_data;
2511 struct snd_emu10k1_fx8010_info *info;
2512 struct snd_emu10k1_fx8010_code *icode;
2513 struct snd_emu10k1_fx8010_pcm_rec *ipcm;
2514 unsigned int addr;
2515 void __user *argp = (void __user *)arg;
2516 int res;
2518 switch (cmd) {
2519 case SNDRV_EMU10K1_IOCTL_PVERSION:
2520 emu->support_tlv = 1;
2521 return put_user(SNDRV_EMU10K1_VERSION, (int __user *)argp);
2522 case SNDRV_EMU10K1_IOCTL_INFO:
2523 info = kmalloc(sizeof(*info), GFP_KERNEL);
2524 if (!info)
2525 return -ENOMEM;
2526 snd_emu10k1_fx8010_info(emu, info);
2527 if (copy_to_user(argp, info, sizeof(*info))) {
2528 kfree(info);
2529 return -EFAULT;
2531 kfree(info);
2532 return 0;
2533 case SNDRV_EMU10K1_IOCTL_CODE_POKE:
2534 if (!capable(CAP_SYS_ADMIN))
2535 return -EPERM;
2537 icode = memdup_user(argp, sizeof(*icode));
2538 if (IS_ERR(icode))
2539 return PTR_ERR(icode);
2540 res = snd_emu10k1_icode_poke(emu, icode);
2541 kfree(icode);
2542 return res;
2543 case SNDRV_EMU10K1_IOCTL_CODE_PEEK:
2544 icode = memdup_user(argp, sizeof(*icode));
2545 if (IS_ERR(icode))
2546 return PTR_ERR(icode);
2547 res = snd_emu10k1_icode_peek(emu, icode);
2548 if (res == 0 && copy_to_user(argp, icode, sizeof(*icode))) {
2549 kfree(icode);
2550 return -EFAULT;
2552 kfree(icode);
2553 return res;
2554 case SNDRV_EMU10K1_IOCTL_PCM_POKE:
2555 ipcm = memdup_user(argp, sizeof(*ipcm));
2556 if (IS_ERR(ipcm))
2557 return PTR_ERR(ipcm);
2558 res = snd_emu10k1_ipcm_poke(emu, ipcm);
2559 kfree(ipcm);
2560 return res;
2561 case SNDRV_EMU10K1_IOCTL_PCM_PEEK:
2562 ipcm = memdup_user(argp, sizeof(*ipcm));
2563 if (IS_ERR(ipcm))
2564 return PTR_ERR(ipcm);
2565 res = snd_emu10k1_ipcm_peek(emu, ipcm);
2566 if (res == 0 && copy_to_user(argp, ipcm, sizeof(*ipcm))) {
2567 kfree(ipcm);
2568 return -EFAULT;
2570 kfree(ipcm);
2571 return res;
2572 case SNDRV_EMU10K1_IOCTL_TRAM_SETUP:
2573 if (!capable(CAP_SYS_ADMIN))
2574 return -EPERM;
2575 if (get_user(addr, (unsigned int __user *)argp))
2576 return -EFAULT;
2577 mutex_lock(&emu->fx8010.lock);
2578 res = snd_emu10k1_fx8010_tram_setup(emu, addr);
2579 mutex_unlock(&emu->fx8010.lock);
2580 return res;
2581 case SNDRV_EMU10K1_IOCTL_STOP:
2582 if (!capable(CAP_SYS_ADMIN))
2583 return -EPERM;
2584 if (emu->audigy)
2585 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg |= A_DBG_SINGLE_STEP);
2586 else
2587 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg |= EMU10K1_DBG_SINGLE_STEP);
2588 return 0;
2589 case SNDRV_EMU10K1_IOCTL_CONTINUE:
2590 if (!capable(CAP_SYS_ADMIN))
2591 return -EPERM;
2592 if (emu->audigy)
2593 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg = 0);
2594 else
2595 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg = 0);
2596 return 0;
2597 case SNDRV_EMU10K1_IOCTL_ZERO_TRAM_COUNTER:
2598 if (!capable(CAP_SYS_ADMIN))
2599 return -EPERM;
2600 if (emu->audigy)
2601 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg | A_DBG_ZC);
2602 else
2603 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg | EMU10K1_DBG_ZC);
2604 udelay(10);
2605 if (emu->audigy)
2606 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg);
2607 else
2608 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg);
2609 return 0;
2610 case SNDRV_EMU10K1_IOCTL_SINGLE_STEP:
2611 if (!capable(CAP_SYS_ADMIN))
2612 return -EPERM;
2613 if (get_user(addr, (unsigned int __user *)argp))
2614 return -EFAULT;
2615 if (addr > 0x1ff)
2616 return -EINVAL;
2617 if (emu->audigy)
2618 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg |= A_DBG_SINGLE_STEP | addr);
2619 else
2620 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg |= EMU10K1_DBG_SINGLE_STEP | addr);
2621 udelay(10);
2622 if (emu->audigy)
2623 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg |= A_DBG_SINGLE_STEP | A_DBG_STEP_ADDR | addr);
2624 else
2625 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg |= EMU10K1_DBG_SINGLE_STEP | EMU10K1_DBG_STEP | addr);
2626 return 0;
2627 case SNDRV_EMU10K1_IOCTL_DBG_READ:
2628 if (emu->audigy)
2629 addr = snd_emu10k1_ptr_read(emu, A_DBG, 0);
2630 else
2631 addr = snd_emu10k1_ptr_read(emu, DBG, 0);
2632 if (put_user(addr, (unsigned int __user *)argp))
2633 return -EFAULT;
2634 return 0;
2636 return -ENOTTY;
2639 static int snd_emu10k1_fx8010_release(struct snd_hwdep * hw, struct file *file)
2641 return 0;
2644 int snd_emu10k1_fx8010_new(struct snd_emu10k1 *emu, int device)
2646 struct snd_hwdep *hw;
2647 int err;
2649 if ((err = snd_hwdep_new(emu->card, "FX8010", device, &hw)) < 0)
2650 return err;
2651 strcpy(hw->name, "EMU10K1 (FX8010)");
2652 hw->iface = SNDRV_HWDEP_IFACE_EMU10K1;
2653 hw->ops.open = snd_emu10k1_fx8010_open;
2654 hw->ops.ioctl = snd_emu10k1_fx8010_ioctl;
2655 hw->ops.release = snd_emu10k1_fx8010_release;
2656 hw->private_data = emu;
2657 return 0;
2660 #ifdef CONFIG_PM_SLEEP
2661 int snd_emu10k1_efx_alloc_pm_buffer(struct snd_emu10k1 *emu)
2663 int len;
2665 len = emu->audigy ? 0x200 : 0x100;
2666 emu->saved_gpr = kmalloc(len * 4, GFP_KERNEL);
2667 if (! emu->saved_gpr)
2668 return -ENOMEM;
2669 len = emu->audigy ? 0x100 : 0xa0;
2670 emu->tram_val_saved = kmalloc(len * 4, GFP_KERNEL);
2671 emu->tram_addr_saved = kmalloc(len * 4, GFP_KERNEL);
2672 if (! emu->tram_val_saved || ! emu->tram_addr_saved)
2673 return -ENOMEM;
2674 len = emu->audigy ? 2 * 1024 : 2 * 512;
2675 emu->saved_icode = vmalloc(len * 4);
2676 if (! emu->saved_icode)
2677 return -ENOMEM;
2678 return 0;
2681 void snd_emu10k1_efx_free_pm_buffer(struct snd_emu10k1 *emu)
2683 kfree(emu->saved_gpr);
2684 kfree(emu->tram_val_saved);
2685 kfree(emu->tram_addr_saved);
2686 vfree(emu->saved_icode);
2690 * save/restore GPR, TRAM and codes
2692 void snd_emu10k1_efx_suspend(struct snd_emu10k1 *emu)
2694 int i, len;
2696 len = emu->audigy ? 0x200 : 0x100;
2697 for (i = 0; i < len; i++)
2698 emu->saved_gpr[i] = snd_emu10k1_ptr_read(emu, emu->gpr_base + i, 0);
2700 len = emu->audigy ? 0x100 : 0xa0;
2701 for (i = 0; i < len; i++) {
2702 emu->tram_val_saved[i] = snd_emu10k1_ptr_read(emu, TANKMEMDATAREGBASE + i, 0);
2703 emu->tram_addr_saved[i] = snd_emu10k1_ptr_read(emu, TANKMEMADDRREGBASE + i, 0);
2704 if (emu->audigy) {
2705 emu->tram_addr_saved[i] >>= 12;
2706 emu->tram_addr_saved[i] |=
2707 snd_emu10k1_ptr_read(emu, A_TANKMEMCTLREGBASE + i, 0) << 20;
2711 len = emu->audigy ? 2 * 1024 : 2 * 512;
2712 for (i = 0; i < len; i++)
2713 emu->saved_icode[i] = snd_emu10k1_efx_read(emu, i);
2716 void snd_emu10k1_efx_resume(struct snd_emu10k1 *emu)
2718 int i, len;
2720 /* set up TRAM */
2721 if (emu->fx8010.etram_pages.bytes > 0) {
2722 unsigned size, size_reg = 0;
2723 size = emu->fx8010.etram_pages.bytes / 2;
2724 size = (size - 1) >> 13;
2725 while (size) {
2726 size >>= 1;
2727 size_reg++;
2729 outl(HCFG_LOCKTANKCACHE_MASK | inl(emu->port + HCFG), emu->port + HCFG);
2730 snd_emu10k1_ptr_write(emu, TCB, 0, emu->fx8010.etram_pages.addr);
2731 snd_emu10k1_ptr_write(emu, TCBS, 0, size_reg);
2732 outl(inl(emu->port + HCFG) & ~HCFG_LOCKTANKCACHE_MASK, emu->port + HCFG);
2735 if (emu->audigy)
2736 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg | A_DBG_SINGLE_STEP);
2737 else
2738 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg | EMU10K1_DBG_SINGLE_STEP);
2740 len = emu->audigy ? 0x200 : 0x100;
2741 for (i = 0; i < len; i++)
2742 snd_emu10k1_ptr_write(emu, emu->gpr_base + i, 0, emu->saved_gpr[i]);
2744 len = emu->audigy ? 0x100 : 0xa0;
2745 for (i = 0; i < len; i++) {
2746 snd_emu10k1_ptr_write(emu, TANKMEMDATAREGBASE + i, 0,
2747 emu->tram_val_saved[i]);
2748 if (! emu->audigy)
2749 snd_emu10k1_ptr_write(emu, TANKMEMADDRREGBASE + i, 0,
2750 emu->tram_addr_saved[i]);
2751 else {
2752 snd_emu10k1_ptr_write(emu, TANKMEMADDRREGBASE + i, 0,
2753 emu->tram_addr_saved[i] << 12);
2754 snd_emu10k1_ptr_write(emu, TANKMEMADDRREGBASE + i, 0,
2755 emu->tram_addr_saved[i] >> 20);
2759 len = emu->audigy ? 2 * 1024 : 2 * 512;
2760 for (i = 0; i < len; i++)
2761 snd_emu10k1_efx_write(emu, i, emu->saved_icode[i]);
2763 /* start FX processor when the DSP code is updated */
2764 if (emu->audigy)
2765 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg);
2766 else
2767 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg);
2769 #endif