1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17#include <linux/pci.h>
18#include <linux/capability.h>
19#include <linux/delay.h>
20#include <linux/slab.h>
21#include <linux/vmalloc.h>
22#include <linux/init.h>
23#include <linux/mutex.h>
24#include <linux/moduleparam.h>
25#include <linux/nospec.h>
26
27#include <sound/core.h>
28#include <sound/tlv.h>
29#include <sound/emu10k1.h>
30
31#if 0
32#define EMU10K1_CAPTURE_DIGITAL_OUT
33#endif
34#if 0
35#define EMU10K1_SET_AC3_IEC958
36#endif
37#if 0
38#define EMU10K1_CENTER_LFE_FROM_FRONT
39#endif
40
41static bool high_res_gpr_volume;
42module_param(high_res_gpr_volume, bool, 0444);
43MODULE_PARM_DESC(high_res_gpr_volume, "GPR mixer controls use 31-bit range.");
44
45
46
47
48
49static const char * const fxbuses[16] = {
50 "PCM Left",
51 "PCM Right",
52 "PCM Surround Left",
53 "PCM Surround Right",
54 "MIDI Left",
55 "MIDI Right",
56 "Center",
57 "LFE",
58 NULL,
59 NULL,
60 NULL,
61 NULL,
62 "MIDI Reverb",
63 "MIDI Chorus",
64 NULL,
65 NULL
66};
67
68static const char * const creative_ins[16] = {
69 "AC97 Left",
70 "AC97 Right",
71 "TTL IEC958 Left",
72 "TTL IEC958 Right",
73 "Zoom Video Left",
74 "Zoom Video Right",
75 "Optical IEC958 Left",
76 "Optical IEC958 Right",
77 "Line/Mic 1 Left",
78 "Line/Mic 1 Right",
79 "Coaxial IEC958 Left",
80 "Coaxial IEC958 Right",
81 "Line/Mic 2 Left",
82 "Line/Mic 2 Right",
83 NULL,
84 NULL
85};
86
87static const char * const audigy_ins[16] = {
88 "AC97 Left",
89 "AC97 Right",
90 "Audigy CD Left",
91 "Audigy CD Right",
92 "Optical IEC958 Left",
93 "Optical IEC958 Right",
94 NULL,
95 NULL,
96 "Line/Mic 2 Left",
97 "Line/Mic 2 Right",
98 "SPDIF Left",
99 "SPDIF Right",
100 "Aux2 Left",
101 "Aux2 Right",
102 NULL,
103 NULL
104};
105
106static const char * const creative_outs[32] = {
107 "AC97 Left",
108 "AC97 Right",
109 "Optical IEC958 Left",
110 "Optical IEC958 Right",
111 "Center",
112 "LFE",
113 "Headphone Left",
114 "Headphone Right",
115 "Surround Left",
116 "Surround Right",
117 "PCM Capture Left",
118 "PCM Capture Right",
119 "MIC Capture",
120 "AC97 Surround Left",
121 "AC97 Surround Right",
122 NULL,
123 NULL,
124 "Analog Center",
125 "Analog LFE",
126 NULL,
127 NULL,
128 NULL,
129 NULL,
130 NULL,
131 NULL,
132 NULL,
133 NULL,
134 NULL,
135 NULL,
136 NULL,
137 NULL,
138 NULL,
139};
140
141static const char * const audigy_outs[32] = {
142 "Digital Front Left",
143 "Digital Front Right",
144 "Digital Center",
145 "Digital LEF",
146 "Headphone Left",
147 "Headphone Right",
148 "Digital Rear Left",
149 "Digital Rear Right",
150 "Front Left",
151 "Front Right",
152 "Center",
153 "LFE",
154 NULL,
155 NULL,
156 "Rear Left",
157 "Rear Right",
158 "AC97 Front Left",
159 "AC97 Front Right",
160 "ADC Capture Left",
161 "ADC Capture Right",
162 NULL,
163 NULL,
164 NULL,
165 NULL,
166 NULL,
167 NULL,
168 NULL,
169 NULL,
170 NULL,
171 NULL,
172 NULL,
173 NULL,
174};
175
176static const u32 bass_table[41][5] = {
177 { 0x3e4f844f, 0x84ed4cc3, 0x3cc69927, 0x7b03553a, 0xc4da8486 },
178 { 0x3e69a17a, 0x84c280fb, 0x3cd77cd4, 0x7b2f2a6f, 0xc4b08d1d },
179 { 0x3e82ff42, 0x849991d5, 0x3ce7466b, 0x7b5917c6, 0xc48863ee },
180 { 0x3e9bab3c, 0x847267f0, 0x3cf5ffe8, 0x7b813560, 0xc461f22c },
181 { 0x3eb3b275, 0x844ced29, 0x3d03b295, 0x7ba79a1c, 0xc43d223b },
182 { 0x3ecb2174, 0x84290c8b, 0x3d106714, 0x7bcc5ba3, 0xc419dfa5 },
183 { 0x3ee2044b, 0x8406b244, 0x3d1c2561, 0x7bef8e77, 0xc3f8170f },
184 { 0x3ef86698, 0x83e5cb96, 0x3d26f4d8, 0x7c114600, 0xc3d7b625 },
185 { 0x3f0e5390, 0x83c646c9, 0x3d30dc39, 0x7c319498, 0xc3b8ab97 },
186 { 0x3f23d60b, 0x83a81321, 0x3d39e1af, 0x7c508b9c, 0xc39ae704 },
187 { 0x3f38f884, 0x838b20d2, 0x3d420ad2, 0x7c6e3b75, 0xc37e58f1 },
188 { 0x3f4dc52c, 0x836f60ef, 0x3d495cab, 0x7c8ab3a6, 0xc362f2be },
189 { 0x3f6245e8, 0x8354c565, 0x3d4fdbb8, 0x7ca602d6, 0xc348a69b },
190 { 0x3f76845f, 0x833b40ec, 0x3d558bf0, 0x7cc036df, 0xc32f677c },
191 { 0x3f8a8a03, 0x8322c6fb, 0x3d5a70c4, 0x7cd95cd7, 0xc317290b },
192 { 0x3f9e6014, 0x830b4bc3, 0x3d5e8d25, 0x7cf1811a, 0xc2ffdfa5 },
193 { 0x3fb20fae, 0x82f4c420, 0x3d61e37f, 0x7d08af56, 0xc2e9804a },
194 { 0x3fc5a1cc, 0x82df2592, 0x3d6475c3, 0x7d1ef294, 0xc2d40096 },
195 { 0x3fd91f55, 0x82ca6632, 0x3d664564, 0x7d345541, 0xc2bf56b9 },
196 { 0x3fec9120, 0x82b67cac, 0x3d675356, 0x7d48e138, 0xc2ab796e },
197 { 0x40000000, 0x82a36037, 0x3d67a012, 0x7d5c9fc9, 0xc2985fee },
198 { 0x401374c7, 0x8291088a, 0x3d672b93, 0x7d6f99c3, 0xc28601f2 },
199 { 0x4026f857, 0x827f6dd7, 0x3d65f559, 0x7d81d77c, 0xc27457a3 },
200 { 0x403a939f, 0x826e88c5, 0x3d63fc63, 0x7d9360d4, 0xc2635996 },
201 { 0x404e4faf, 0x825e5266, 0x3d613f32, 0x7da43d42, 0xc25300c6 },
202 { 0x406235ba, 0x824ec434, 0x3d5dbbc3, 0x7db473d7, 0xc243468e },
203 { 0x40764f1f, 0x823fd80c, 0x3d596f8f, 0x7dc40b44, 0xc23424a2 },
204 { 0x408aa576, 0x82318824, 0x3d545787, 0x7dd309e2, 0xc2259509 },
205 { 0x409f4296, 0x8223cf0b, 0x3d4e7012, 0x7de175b5, 0xc2179218 },
206 { 0x40b430a0, 0x8216a7a1, 0x3d47b505, 0x7def5475, 0xc20a1670 },
207 { 0x40c97a0a, 0x820a0d12, 0x3d4021a1, 0x7dfcab8d, 0xc1fd1cf5 },
208 { 0x40df29a6, 0x81fdfad6, 0x3d37b08d, 0x7e098028, 0xc1f0a0ca },
209 { 0x40f54ab1, 0x81f26ca9, 0x3d2e5bd1, 0x7e15d72b, 0xc1e49d52 },
210 { 0x410be8da, 0x81e75e89, 0x3d241cce, 0x7e21b544, 0xc1d90e24 },
211 { 0x41231051, 0x81dcccb3, 0x3d18ec37, 0x7e2d1ee6, 0xc1cdef10 },
212 { 0x413acdd0, 0x81d2b39e, 0x3d0cc20a, 0x7e38184e, 0xc1c33c13 },
213 { 0x41532ea7, 0x81c90ffb, 0x3cff9585, 0x7e42a58b, 0xc1b8f15a },
214 { 0x416c40cd, 0x81bfdeb2, 0x3cf15d21, 0x7e4cca7c, 0xc1af0b3f },
215 { 0x418612ea, 0x81b71cdc, 0x3ce20e85, 0x7e568ad3, 0xc1a58640 },
216 { 0x41a0b465, 0x81aec7c5, 0x3cd19e7c, 0x7e5fea1e, 0xc19c5f03 },
217 { 0x41bc3573, 0x81a6dcea, 0x3cc000e9, 0x7e68ebc2, 0xc1939250 }
218};
219
220static const u32 treble_table[41][5] = {
221 { 0x0125cba9, 0xfed5debd, 0x00599b6c, 0x0d2506da, 0xfa85b354 },
222 { 0x0142f67e, 0xfeb03163, 0x0066cd0f, 0x0d14c69d, 0xfa914473 },
223 { 0x016328bd, 0xfe860158, 0x0075b7f2, 0x0d03eb27, 0xfa9d32d2 },
224 { 0x0186b438, 0xfe56c982, 0x00869234, 0x0cf27048, 0xfaa97fca },
225 { 0x01adf358, 0xfe21f5fe, 0x00999842, 0x0ce051c2, 0xfab62ca5 },
226 { 0x01d949fa, 0xfde6e287, 0x00af0d8d, 0x0ccd8b4a, 0xfac33aa7 },
227 { 0x02092669, 0xfda4d8bf, 0x00c73d4c, 0x0cba1884, 0xfad0ab07 },
228 { 0x023e0268, 0xfd5b0e4a, 0x00e27b54, 0x0ca5f509, 0xfade7ef2 },
229 { 0x0278645c, 0xfd08a2b0, 0x01012509, 0x0c911c63, 0xfaecb788 },
230 { 0x02b8e091, 0xfcac9d1a, 0x0123a262, 0x0c7b8a14, 0xfafb55df },
231 { 0x03001a9a, 0xfc45e9ce, 0x014a6709, 0x0c65398f, 0xfb0a5aff },
232 { 0x034ec6d7, 0xfbd3576b, 0x0175f397, 0x0c4e2643, 0xfb19c7e4 },
233 { 0x03a5ac15, 0xfb5393ee, 0x01a6d6ed, 0x0c364b94, 0xfb299d7c },
234 { 0x0405a562, 0xfac52968, 0x01ddafae, 0x0c1da4e2, 0xfb39dca5 },
235 { 0x046fa3fe, 0xfa267a66, 0x021b2ddd, 0x0c042d8d, 0xfb4a8631 },
236 { 0x04e4b17f, 0xf975be0f, 0x0260149f, 0x0be9e0f2, 0xfb5b9ae0 },
237 { 0x0565f220, 0xf8b0fbe5, 0x02ad3c29, 0x0bceba73, 0xfb6d1b60 },
238 { 0x05f4a745, 0xf7d60722, 0x030393d4, 0x0bb2b578, 0xfb7f084d },
239 { 0x06923236, 0xf6e279bd, 0x03642465, 0x0b95cd75, 0xfb916233 },
240 { 0x07401713, 0xf5d3aef9, 0x03d01283, 0x0b77fded, 0xfba42984 },
241 { 0x08000000, 0xf4a6bd88, 0x0448a161, 0x0b594278, 0xfbb75e9f },
242 { 0x08d3c097, 0xf3587131, 0x04cf35a4, 0x0b3996c9, 0xfbcb01cb },
243 { 0x09bd59a2, 0xf1e543f9, 0x05655880, 0x0b18f6b2, 0xfbdf1333 },
244 { 0x0abefd0f, 0xf04956ca, 0x060cbb12, 0x0af75e2c, 0xfbf392e8 },
245 { 0x0bdb123e, 0xee806984, 0x06c739fe, 0x0ad4c962, 0xfc0880dd },
246 { 0x0d143a94, 0xec85d287, 0x0796e150, 0x0ab134b0, 0xfc1ddce5 },
247 { 0x0e6d5664, 0xea547598, 0x087df0a0, 0x0a8c9cb6, 0xfc33a6ad },
248 { 0x0fe98a2a, 0xe7e6ba35, 0x097edf83, 0x0a66fe5b, 0xfc49ddc2 },
249 { 0x118c4421, 0xe536813a, 0x0a9c6248, 0x0a4056d7, 0xfc608185 },
250 { 0x1359422e, 0xe23d19eb, 0x0bd96efb, 0x0a18a3bf, 0xfc77912c },
251 { 0x1554982b, 0xdef33645, 0x0d3942bd, 0x09efe312, 0xfc8f0bc1 },
252 { 0x1782b68a, 0xdb50deb1, 0x0ebf676d, 0x09c6133f, 0xfca6f019 },
253 { 0x19e8715d, 0xd74d64fd, 0x106fb999, 0x099b3337, 0xfcbf3cd6 },
254 { 0x1c8b07b8, 0xd2df56ab, 0x124e6ec8, 0x096f4274, 0xfcd7f060 },
255 { 0x1f702b6d, 0xcdfc6e92, 0x14601c10, 0x0942410b, 0xfcf108e5 },
256 { 0x229e0933, 0xc89985cd, 0x16a9bcfa, 0x09142fb5, 0xfd0a8451 },
257 { 0x261b5118, 0xc2aa8409, 0x1930bab6, 0x08e50fdc, 0xfd24604d },
258 { 0x29ef3f5d, 0xbc224f28, 0x1bfaf396, 0x08b4e3aa, 0xfd3e9a3b },
259 { 0x2e21a59b, 0xb4f2ba46, 0x1f0ec2d6, 0x0883ae15, 0xfd592f33 },
260 { 0x32baf44b, 0xad0c7429, 0x227308a3, 0x085172eb, 0xfd741bfd },
261 { 0x37c4448b, 0xa45ef51d, 0x262f3267, 0x081e36dc, 0xfd8f5d14 }
262};
263
264
265static const u32 db_table[101] = {
266 0x00000000, 0x01571f82, 0x01674b41, 0x01783a1b, 0x0189f540,
267 0x019c8651, 0x01aff763, 0x01c45306, 0x01d9a446, 0x01eff6b8,
268 0x0207567a, 0x021fd03d, 0x0239714c, 0x02544792, 0x027061a1,
269 0x028dcebb, 0x02ac9edc, 0x02cce2bf, 0x02eeabe8, 0x03120cb0,
270 0x0337184e, 0x035de2df, 0x03868173, 0x03b10a18, 0x03dd93e9,
271 0x040c3713, 0x043d0cea, 0x04702ff3, 0x04a5bbf2, 0x04ddcdfb,
272 0x0518847f, 0x0555ff62, 0x05966005, 0x05d9c95d, 0x06206005,
273 0x066a4a52, 0x06b7b067, 0x0708bc4c, 0x075d9a01, 0x07b6779d,
274 0x08138561, 0x0874f5d5, 0x08dafde1, 0x0945d4ed, 0x09b5b4fd,
275 0x0a2adad1, 0x0aa58605, 0x0b25f936, 0x0bac7a24, 0x0c3951d8,
276 0x0ccccccc, 0x0d673b17, 0x0e08f093, 0x0eb24510, 0x0f639481,
277 0x101d3f2d, 0x10dfa9e6, 0x11ab3e3f, 0x12806ac3, 0x135fa333,
278 0x144960c5, 0x153e2266, 0x163e6cfe, 0x174acbb7, 0x1863d04d,
279 0x198a1357, 0x1abe349f, 0x1c00db77, 0x1d52b712, 0x1eb47ee6,
280 0x2026f30f, 0x21aadcb6, 0x23410e7e, 0x24ea64f9, 0x26a7c71d,
281 0x287a26c4, 0x2a62812c, 0x2c61df84, 0x2e795779, 0x30aa0bcf,
282 0x32f52cfe, 0x355bf9d8, 0x37dfc033, 0x3a81dda4, 0x3d43c038,
283 0x4026e73c, 0x432ce40f, 0x46575af8, 0x49a8040f, 0x4d20ac2a,
284 0x50c335d3, 0x54919a57, 0x588dead1, 0x5cba514a, 0x611911ea,
285 0x65ac8c2f, 0x6a773c39, 0x6f7bbc23, 0x74bcc56c, 0x7a3d3272,
286 0x7fffffff,
287};
288
289
290static const DECLARE_TLV_DB_SCALE(snd_emu10k1_db_scale1, -4000, 40, 1);
291static const DECLARE_TLV_DB_LINEAR(snd_emu10k1_db_linear, TLV_DB_GAIN_MUTE, 0);
292
293
294static const DECLARE_TLV_DB_SCALE(snd_emu10k1_bass_treble_db_scale, -1200, 60, 0);
295
296static const u32 onoff_table[2] = {
297 0x00000000, 0x00000001
298};
299
300
301
302
303
304static int snd_emu10k1_gpr_ctl_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
305{
306 struct snd_emu10k1_fx8010_ctl *ctl =
307 (struct snd_emu10k1_fx8010_ctl *) kcontrol->private_value;
308
309 if (ctl->min == 0 && ctl->max == 1)
310 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
311 else
312 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
313 uinfo->count = ctl->vcount;
314 uinfo->value.integer.min = ctl->min;
315 uinfo->value.integer.max = ctl->max;
316 return 0;
317}
318
319static int snd_emu10k1_gpr_ctl_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
320{
321 struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
322 struct snd_emu10k1_fx8010_ctl *ctl =
323 (struct snd_emu10k1_fx8010_ctl *) kcontrol->private_value;
324 unsigned long flags;
325 unsigned int i;
326
327 spin_lock_irqsave(&emu->reg_lock, flags);
328 for (i = 0; i < ctl->vcount; i++)
329 ucontrol->value.integer.value[i] = ctl->value[i];
330 spin_unlock_irqrestore(&emu->reg_lock, flags);
331 return 0;
332}
333
334static int snd_emu10k1_gpr_ctl_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
335{
336 struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
337 struct snd_emu10k1_fx8010_ctl *ctl =
338 (struct snd_emu10k1_fx8010_ctl *) kcontrol->private_value;
339 unsigned long flags;
340 unsigned int nval, val;
341 unsigned int i, j;
342 int change = 0;
343
344 spin_lock_irqsave(&emu->reg_lock, flags);
345 for (i = 0; i < ctl->vcount; i++) {
346 nval = ucontrol->value.integer.value[i];
347 if (nval < ctl->min)
348 nval = ctl->min;
349 if (nval > ctl->max)
350 nval = ctl->max;
351 if (nval != ctl->value[i])
352 change = 1;
353 val = ctl->value[i] = nval;
354 switch (ctl->translation) {
355 case EMU10K1_GPR_TRANSLATION_NONE:
356 snd_emu10k1_ptr_write(emu, emu->gpr_base + ctl->gpr[i], 0, val);
357 break;
358 case EMU10K1_GPR_TRANSLATION_TABLE100:
359 snd_emu10k1_ptr_write(emu, emu->gpr_base + ctl->gpr[i], 0, db_table[val]);
360 break;
361 case EMU10K1_GPR_TRANSLATION_BASS:
362 if ((ctl->count % 5) != 0 || (ctl->count / 5) != ctl->vcount) {
363 change = -EIO;
364 goto __error;
365 }
366 for (j = 0; j < 5; j++)
367 snd_emu10k1_ptr_write(emu, emu->gpr_base + ctl->gpr[j * ctl->vcount + i], 0, bass_table[val][j]);
368 break;
369 case EMU10K1_GPR_TRANSLATION_TREBLE:
370 if ((ctl->count % 5) != 0 || (ctl->count / 5) != ctl->vcount) {
371 change = -EIO;
372 goto __error;
373 }
374 for (j = 0; j < 5; j++)
375 snd_emu10k1_ptr_write(emu, emu->gpr_base + ctl->gpr[j * ctl->vcount + i], 0, treble_table[val][j]);
376 break;
377 case EMU10K1_GPR_TRANSLATION_ONOFF:
378 snd_emu10k1_ptr_write(emu, emu->gpr_base + ctl->gpr[i], 0, onoff_table[val]);
379 break;
380 }
381 }
382 __error:
383 spin_unlock_irqrestore(&emu->reg_lock, flags);
384 return change;
385}
386
387
388
389
390
391static void snd_emu10k1_fx8010_interrupt(struct snd_emu10k1 *emu)
392{
393 struct snd_emu10k1_fx8010_irq *irq, *nirq;
394
395 irq = emu->fx8010.irq_handlers;
396 while (irq) {
397 nirq = irq->next;
398 if (snd_emu10k1_ptr_read(emu, emu->gpr_base + irq->gpr_running, 0) & 0xffff0000) {
399 if (irq->handler)
400 irq->handler(emu, irq->private_data);
401 snd_emu10k1_ptr_write(emu, emu->gpr_base + irq->gpr_running, 0, 1);
402 }
403 irq = nirq;
404 }
405}
406
407int snd_emu10k1_fx8010_register_irq_handler(struct snd_emu10k1 *emu,
408 snd_fx8010_irq_handler_t *handler,
409 unsigned char gpr_running,
410 void *private_data,
411 struct snd_emu10k1_fx8010_irq *irq)
412{
413 unsigned long flags;
414
415 irq->handler = handler;
416 irq->gpr_running = gpr_running;
417 irq->private_data = private_data;
418 irq->next = NULL;
419 spin_lock_irqsave(&emu->fx8010.irq_lock, flags);
420 if (emu->fx8010.irq_handlers == NULL) {
421 emu->fx8010.irq_handlers = irq;
422 emu->dsp_interrupt = snd_emu10k1_fx8010_interrupt;
423 snd_emu10k1_intr_enable(emu, INTE_FXDSPENABLE);
424 } else {
425 irq->next = emu->fx8010.irq_handlers;
426 emu->fx8010.irq_handlers = irq;
427 }
428 spin_unlock_irqrestore(&emu->fx8010.irq_lock, flags);
429 return 0;
430}
431
432int snd_emu10k1_fx8010_unregister_irq_handler(struct snd_emu10k1 *emu,
433 struct snd_emu10k1_fx8010_irq *irq)
434{
435 struct snd_emu10k1_fx8010_irq *tmp;
436 unsigned long flags;
437
438 spin_lock_irqsave(&emu->fx8010.irq_lock, flags);
439 if ((tmp = emu->fx8010.irq_handlers) == irq) {
440 emu->fx8010.irq_handlers = tmp->next;
441 if (emu->fx8010.irq_handlers == NULL) {
442 snd_emu10k1_intr_disable(emu, INTE_FXDSPENABLE);
443 emu->dsp_interrupt = NULL;
444 }
445 } else {
446 while (tmp && tmp->next != irq)
447 tmp = tmp->next;
448 if (tmp)
449 tmp->next = tmp->next->next;
450 }
451 spin_unlock_irqrestore(&emu->fx8010.irq_lock, flags);
452 return 0;
453}
454
455
456
457
458
459static void snd_emu10k1_write_op(struct snd_emu10k1_fx8010_code *icode,
460 unsigned int *ptr,
461 u32 op, u32 r, u32 a, u32 x, u32 y)
462{
463 u_int32_t *code;
464 if (snd_BUG_ON(*ptr >= 512))
465 return;
466 code = icode->code + (*ptr) * 2;
467 set_bit(*ptr, icode->code_valid);
468 code[0] = ((x & 0x3ff) << 10) | (y & 0x3ff);
469 code[1] = ((op & 0x0f) << 20) | ((r & 0x3ff) << 10) | (a & 0x3ff);
470 (*ptr)++;
471}
472
473#define OP(icode, ptr, op, r, a, x, y) \
474 snd_emu10k1_write_op(icode, ptr, op, r, a, x, y)
475
476static void snd_emu10k1_audigy_write_op(struct snd_emu10k1_fx8010_code *icode,
477 unsigned int *ptr,
478 u32 op, u32 r, u32 a, u32 x, u32 y)
479{
480 u_int32_t *code;
481 if (snd_BUG_ON(*ptr >= 1024))
482 return;
483 code = icode->code + (*ptr) * 2;
484 set_bit(*ptr, icode->code_valid);
485 code[0] = ((x & 0x7ff) << 12) | (y & 0x7ff);
486 code[1] = ((op & 0x0f) << 24) | ((r & 0x7ff) << 12) | (a & 0x7ff);
487 (*ptr)++;
488}
489
490#define A_OP(icode, ptr, op, r, a, x, y) \
491 snd_emu10k1_audigy_write_op(icode, ptr, op, r, a, x, y)
492
493static void snd_emu10k1_efx_write(struct snd_emu10k1 *emu, unsigned int pc, unsigned int data)
494{
495 pc += emu->audigy ? A_MICROCODEBASE : MICROCODEBASE;
496 snd_emu10k1_ptr_write(emu, pc, 0, data);
497}
498
499unsigned int snd_emu10k1_efx_read(struct snd_emu10k1 *emu, unsigned int pc)
500{
501 pc += emu->audigy ? A_MICROCODEBASE : MICROCODEBASE;
502 return snd_emu10k1_ptr_read(emu, pc, 0);
503}
504
505static int snd_emu10k1_gpr_poke(struct snd_emu10k1 *emu,
506 struct snd_emu10k1_fx8010_code *icode,
507 bool in_kernel)
508{
509 int gpr;
510 u32 val;
511
512 for (gpr = 0; gpr < (emu->audigy ? 0x200 : 0x100); gpr++) {
513 if (!test_bit(gpr, icode->gpr_valid))
514 continue;
515 if (in_kernel)
516 val = icode->gpr_map[gpr];
517 else if (get_user(val, (__user u32 *)&icode->gpr_map[gpr]))
518 return -EFAULT;
519 snd_emu10k1_ptr_write(emu, emu->gpr_base + gpr, 0, val);
520 }
521 return 0;
522}
523
524static int snd_emu10k1_gpr_peek(struct snd_emu10k1 *emu,
525 struct snd_emu10k1_fx8010_code *icode)
526{
527 int gpr;
528 u32 val;
529
530 for (gpr = 0; gpr < (emu->audigy ? 0x200 : 0x100); gpr++) {
531 set_bit(gpr, icode->gpr_valid);
532 val = snd_emu10k1_ptr_read(emu, emu->gpr_base + gpr, 0);
533 if (put_user(val, (__user u32 *)&icode->gpr_map[gpr]))
534 return -EFAULT;
535 }
536 return 0;
537}
538
539static int snd_emu10k1_tram_poke(struct snd_emu10k1 *emu,
540 struct snd_emu10k1_fx8010_code *icode,
541 bool in_kernel)
542{
543 int tram;
544 u32 addr, val;
545
546 for (tram = 0; tram < (emu->audigy ? 0x100 : 0xa0); tram++) {
547 if (!test_bit(tram, icode->tram_valid))
548 continue;
549 if (in_kernel) {
550 val = icode->tram_data_map[tram];
551 addr = icode->tram_addr_map[tram];
552 } else {
553 if (get_user(val, (__user __u32 *)&icode->tram_data_map[tram]) ||
554 get_user(addr, (__user __u32 *)&icode->tram_addr_map[tram]))
555 return -EFAULT;
556 }
557 snd_emu10k1_ptr_write(emu, TANKMEMDATAREGBASE + tram, 0, val);
558 if (!emu->audigy) {
559 snd_emu10k1_ptr_write(emu, TANKMEMADDRREGBASE + tram, 0, addr);
560 } else {
561 snd_emu10k1_ptr_write(emu, TANKMEMADDRREGBASE + tram, 0, addr << 12);
562 snd_emu10k1_ptr_write(emu, A_TANKMEMCTLREGBASE + tram, 0, addr >> 20);
563 }
564 }
565 return 0;
566}
567
568static int snd_emu10k1_tram_peek(struct snd_emu10k1 *emu,
569 struct snd_emu10k1_fx8010_code *icode)
570{
571 int tram;
572 u32 val, addr;
573
574 memset(icode->tram_valid, 0, sizeof(icode->tram_valid));
575 for (tram = 0; tram < (emu->audigy ? 0x100 : 0xa0); tram++) {
576 set_bit(tram, icode->tram_valid);
577 val = snd_emu10k1_ptr_read(emu, TANKMEMDATAREGBASE + tram, 0);
578 if (!emu->audigy) {
579 addr = snd_emu10k1_ptr_read(emu, TANKMEMADDRREGBASE + tram, 0);
580 } else {
581 addr = snd_emu10k1_ptr_read(emu, TANKMEMADDRREGBASE + tram, 0) >> 12;
582 addr |= snd_emu10k1_ptr_read(emu, A_TANKMEMCTLREGBASE + tram, 0) << 20;
583 }
584 if (put_user(val, (__user u32 *)&icode->tram_data_map[tram]) ||
585 put_user(addr, (__user u32 *)&icode->tram_addr_map[tram]))
586 return -EFAULT;
587 }
588 return 0;
589}
590
591static int snd_emu10k1_code_poke(struct snd_emu10k1 *emu,
592 struct snd_emu10k1_fx8010_code *icode,
593 bool in_kernel)
594{
595 u32 pc, lo, hi;
596
597 for (pc = 0; pc < (emu->audigy ? 2*1024 : 2*512); pc += 2) {
598 if (!test_bit(pc / 2, icode->code_valid))
599 continue;
600 if (in_kernel) {
601 lo = icode->code[pc + 0];
602 hi = icode->code[pc + 1];
603 } else {
604 if (get_user(lo, (__user u32 *)&icode->code[pc + 0]) ||
605 get_user(hi, (__user u32 *)&icode->code[pc + 1]))
606 return -EFAULT;
607 }
608 snd_emu10k1_efx_write(emu, pc + 0, lo);
609 snd_emu10k1_efx_write(emu, pc + 1, hi);
610 }
611 return 0;
612}
613
614static int snd_emu10k1_code_peek(struct snd_emu10k1 *emu,
615 struct snd_emu10k1_fx8010_code *icode)
616{
617 u32 pc;
618
619 memset(icode->code_valid, 0, sizeof(icode->code_valid));
620 for (pc = 0; pc < (emu->audigy ? 2*1024 : 2*512); pc += 2) {
621 set_bit(pc / 2, icode->code_valid);
622 if (put_user(snd_emu10k1_efx_read(emu, pc + 0),
623 (__user u32 *)&icode->code[pc + 0]))
624 return -EFAULT;
625 if (put_user(snd_emu10k1_efx_read(emu, pc + 1),
626 (__user u32 *)&icode->code[pc + 1]))
627 return -EFAULT;
628 }
629 return 0;
630}
631
632static struct snd_emu10k1_fx8010_ctl *
633snd_emu10k1_look_for_ctl(struct snd_emu10k1 *emu,
634 struct emu10k1_ctl_elem_id *_id)
635{
636 struct snd_ctl_elem_id *id = (struct snd_ctl_elem_id *)_id;
637 struct snd_emu10k1_fx8010_ctl *ctl;
638 struct snd_kcontrol *kcontrol;
639
640 list_for_each_entry(ctl, &emu->fx8010.gpr_ctl, list) {
641 kcontrol = ctl->kcontrol;
642 if (kcontrol->id.iface == id->iface &&
643 !strcmp(kcontrol->id.name, id->name) &&
644 kcontrol->id.index == id->index)
645 return ctl;
646 }
647 return NULL;
648}
649
650#define MAX_TLV_SIZE 256
651
652static unsigned int *copy_tlv(const unsigned int __user *_tlv, bool in_kernel)
653{
654 unsigned int data[2];
655 unsigned int *tlv;
656
657 if (!_tlv)
658 return NULL;
659 if (in_kernel)
660 memcpy(data, (__force void *)_tlv, sizeof(data));
661 else if (copy_from_user(data, _tlv, sizeof(data)))
662 return NULL;
663 if (data[1] >= MAX_TLV_SIZE)
664 return NULL;
665 tlv = kmalloc(data[1] + sizeof(data), GFP_KERNEL);
666 if (!tlv)
667 return NULL;
668 memcpy(tlv, data, sizeof(data));
669 if (in_kernel) {
670 memcpy(tlv + 2, (__force void *)(_tlv + 2), data[1]);
671 } else if (copy_from_user(tlv + 2, _tlv + 2, data[1])) {
672 kfree(tlv);
673 return NULL;
674 }
675 return tlv;
676}
677
678static int copy_gctl(struct snd_emu10k1 *emu,
679 struct snd_emu10k1_fx8010_control_gpr *dst,
680 struct snd_emu10k1_fx8010_control_gpr *src,
681 int idx, bool in_kernel)
682{
683 struct snd_emu10k1_fx8010_control_gpr __user *_src;
684 struct snd_emu10k1_fx8010_control_old_gpr *octl;
685 struct snd_emu10k1_fx8010_control_old_gpr __user *_octl;
686
687 _src = (struct snd_emu10k1_fx8010_control_gpr __user *)src;
688 if (emu->support_tlv) {
689 if (in_kernel)
690 *dst = src[idx];
691 else if (copy_from_user(dst, &_src[idx], sizeof(*src)))
692 return -EFAULT;
693 return 0;
694 }
695
696 octl = (struct snd_emu10k1_fx8010_control_old_gpr *)src;
697 _octl = (struct snd_emu10k1_fx8010_control_old_gpr __user *)octl;
698 if (in_kernel)
699 memcpy(dst, &octl[idx], sizeof(*octl));
700 else if (copy_from_user(dst, &_octl[idx], sizeof(*octl)))
701 return -EFAULT;
702 dst->tlv = NULL;
703 return 0;
704}
705
706static int copy_gctl_to_user(struct snd_emu10k1 *emu,
707 struct snd_emu10k1_fx8010_control_gpr *dst,
708 struct snd_emu10k1_fx8010_control_gpr *src,
709 int idx)
710{
711 struct snd_emu10k1_fx8010_control_gpr __user *_dst;
712 struct snd_emu10k1_fx8010_control_old_gpr __user *octl;
713
714 _dst = (struct snd_emu10k1_fx8010_control_gpr __user *)dst;
715 if (emu->support_tlv)
716 return copy_to_user(&_dst[idx], src, sizeof(*src));
717
718 octl = (struct snd_emu10k1_fx8010_control_old_gpr __user *)dst;
719 return copy_to_user(&octl[idx], src, sizeof(*octl));
720}
721
722static int copy_ctl_elem_id(const struct emu10k1_ctl_elem_id *list, int i,
723 struct emu10k1_ctl_elem_id *ret, bool in_kernel)
724{
725 struct emu10k1_ctl_elem_id __user *_id =
726 (struct emu10k1_ctl_elem_id __user *)&list[i];
727
728 if (in_kernel)
729 *ret = list[i];
730 else if (copy_from_user(ret, _id, sizeof(*ret)))
731 return -EFAULT;
732 return 0;
733}
734
735static int snd_emu10k1_verify_controls(struct snd_emu10k1 *emu,
736 struct snd_emu10k1_fx8010_code *icode,
737 bool in_kernel)
738{
739 unsigned int i;
740 struct emu10k1_ctl_elem_id id;
741 struct snd_emu10k1_fx8010_control_gpr *gctl;
742 struct snd_ctl_elem_id *gctl_id;
743 int err;
744
745 for (i = 0; i < icode->gpr_del_control_count; i++) {
746 err = copy_ctl_elem_id(icode->gpr_del_controls, i, &id,
747 in_kernel);
748 if (err < 0)
749 return err;
750 if (snd_emu10k1_look_for_ctl(emu, &id) == NULL)
751 return -ENOENT;
752 }
753 gctl = kmalloc(sizeof(*gctl), GFP_KERNEL);
754 if (! gctl)
755 return -ENOMEM;
756 err = 0;
757 for (i = 0; i < icode->gpr_add_control_count; i++) {
758 if (copy_gctl(emu, gctl, icode->gpr_add_controls, i,
759 in_kernel)) {
760 err = -EFAULT;
761 goto __error;
762 }
763 if (snd_emu10k1_look_for_ctl(emu, &gctl->id))
764 continue;
765 gctl_id = (struct snd_ctl_elem_id *)&gctl->id;
766 down_read(&emu->card->controls_rwsem);
767 if (snd_ctl_find_id(emu->card, gctl_id)) {
768 up_read(&emu->card->controls_rwsem);
769 err = -EEXIST;
770 goto __error;
771 }
772 up_read(&emu->card->controls_rwsem);
773 if (gctl_id->iface != SNDRV_CTL_ELEM_IFACE_MIXER &&
774 gctl_id->iface != SNDRV_CTL_ELEM_IFACE_PCM) {
775 err = -EINVAL;
776 goto __error;
777 }
778 }
779 for (i = 0; i < icode->gpr_list_control_count; i++) {
780
781 if (copy_gctl(emu, gctl, icode->gpr_list_controls, i,
782 in_kernel)) {
783 err = -EFAULT;
784 goto __error;
785 }
786 }
787 __error:
788 kfree(gctl);
789 return err;
790}
791
792static void snd_emu10k1_ctl_private_free(struct snd_kcontrol *kctl)
793{
794 struct snd_emu10k1_fx8010_ctl *ctl;
795
796 ctl = (struct snd_emu10k1_fx8010_ctl *) kctl->private_value;
797 kctl->private_value = 0;
798 list_del(&ctl->list);
799 kfree(ctl);
800 kfree(kctl->tlv.p);
801}
802
803static int snd_emu10k1_add_controls(struct snd_emu10k1 *emu,
804 struct snd_emu10k1_fx8010_code *icode,
805 bool in_kernel)
806{
807 unsigned int i, j;
808 struct snd_emu10k1_fx8010_control_gpr *gctl;
809 struct snd_ctl_elem_id *gctl_id;
810 struct snd_emu10k1_fx8010_ctl *ctl, *nctl;
811 struct snd_kcontrol_new knew;
812 struct snd_kcontrol *kctl;
813 struct snd_ctl_elem_value *val;
814 int err = 0;
815
816 val = kmalloc(sizeof(*val), GFP_KERNEL);
817 gctl = kmalloc(sizeof(*gctl), GFP_KERNEL);
818 nctl = kmalloc(sizeof(*nctl), GFP_KERNEL);
819 if (!val || !gctl || !nctl) {
820 err = -ENOMEM;
821 goto __error;
822 }
823
824 for (i = 0; i < icode->gpr_add_control_count; i++) {
825 if (copy_gctl(emu, gctl, icode->gpr_add_controls, i,
826 in_kernel)) {
827 err = -EFAULT;
828 goto __error;
829 }
830 gctl_id = (struct snd_ctl_elem_id *)&gctl->id;
831 if (gctl_id->iface != SNDRV_CTL_ELEM_IFACE_MIXER &&
832 gctl_id->iface != SNDRV_CTL_ELEM_IFACE_PCM) {
833 err = -EINVAL;
834 goto __error;
835 }
836 if (!*gctl_id->name) {
837 err = -EINVAL;
838 goto __error;
839 }
840 ctl = snd_emu10k1_look_for_ctl(emu, &gctl->id);
841 memset(&knew, 0, sizeof(knew));
842 knew.iface = gctl_id->iface;
843 knew.name = gctl_id->name;
844 knew.index = gctl_id->index;
845 knew.device = gctl_id->device;
846 knew.subdevice = gctl_id->subdevice;
847 knew.info = snd_emu10k1_gpr_ctl_info;
848 knew.tlv.p = copy_tlv((const unsigned int __user *)gctl->tlv, in_kernel);
849 if (knew.tlv.p)
850 knew.access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
851 SNDRV_CTL_ELEM_ACCESS_TLV_READ;
852 knew.get = snd_emu10k1_gpr_ctl_get;
853 knew.put = snd_emu10k1_gpr_ctl_put;
854 memset(nctl, 0, sizeof(*nctl));
855 nctl->vcount = gctl->vcount;
856 nctl->count = gctl->count;
857 for (j = 0; j < 32; j++) {
858 nctl->gpr[j] = gctl->gpr[j];
859 nctl->value[j] = ~gctl->value[j];
860 val->value.integer.value[j] = gctl->value[j];
861 }
862 nctl->min = gctl->min;
863 nctl->max = gctl->max;
864 nctl->translation = gctl->translation;
865 if (ctl == NULL) {
866 ctl = kmalloc(sizeof(*ctl), GFP_KERNEL);
867 if (ctl == NULL) {
868 err = -ENOMEM;
869 kfree(knew.tlv.p);
870 goto __error;
871 }
872 knew.private_value = (unsigned long)ctl;
873 *ctl = *nctl;
874 if ((err = snd_ctl_add(emu->card, kctl = snd_ctl_new1(&knew, emu))) < 0) {
875 kfree(ctl);
876 kfree(knew.tlv.p);
877 goto __error;
878 }
879 kctl->private_free = snd_emu10k1_ctl_private_free;
880 ctl->kcontrol = kctl;
881 list_add_tail(&ctl->list, &emu->fx8010.gpr_ctl);
882 } else {
883
884 nctl->list = ctl->list;
885 nctl->kcontrol = ctl->kcontrol;
886 *ctl = *nctl;
887 snd_ctl_notify(emu->card, SNDRV_CTL_EVENT_MASK_VALUE |
888 SNDRV_CTL_EVENT_MASK_INFO, &ctl->kcontrol->id);
889 }
890 snd_emu10k1_gpr_ctl_put(ctl->kcontrol, val);
891 }
892 __error:
893 kfree(nctl);
894 kfree(gctl);
895 kfree(val);
896 return err;
897}
898
899static int snd_emu10k1_del_controls(struct snd_emu10k1 *emu,
900 struct snd_emu10k1_fx8010_code *icode,
901 bool in_kernel)
902{
903 unsigned int i;
904 struct emu10k1_ctl_elem_id id;
905 struct snd_emu10k1_fx8010_ctl *ctl;
906 struct snd_card *card = emu->card;
907 int err;
908
909 for (i = 0; i < icode->gpr_del_control_count; i++) {
910 err = copy_ctl_elem_id(icode->gpr_del_controls, i, &id,
911 in_kernel);
912 if (err < 0)
913 return err;
914 down_write(&card->controls_rwsem);
915 ctl = snd_emu10k1_look_for_ctl(emu, &id);
916 if (ctl)
917 snd_ctl_remove(card, ctl->kcontrol);
918 up_write(&card->controls_rwsem);
919 }
920 return 0;
921}
922
923static int snd_emu10k1_list_controls(struct snd_emu10k1 *emu,
924 struct snd_emu10k1_fx8010_code *icode)
925{
926 unsigned int i = 0, j;
927 unsigned int total = 0;
928 struct snd_emu10k1_fx8010_control_gpr *gctl;
929 struct snd_emu10k1_fx8010_ctl *ctl;
930 struct snd_ctl_elem_id *id;
931
932 gctl = kmalloc(sizeof(*gctl), GFP_KERNEL);
933 if (! gctl)
934 return -ENOMEM;
935
936 list_for_each_entry(ctl, &emu->fx8010.gpr_ctl, list) {
937 total++;
938 if (icode->gpr_list_controls &&
939 i < icode->gpr_list_control_count) {
940 memset(gctl, 0, sizeof(*gctl));
941 id = &ctl->kcontrol->id;
942 gctl->id.iface = (__force int)id->iface;
943 strlcpy(gctl->id.name, id->name, sizeof(gctl->id.name));
944 gctl->id.index = id->index;
945 gctl->id.device = id->device;
946 gctl->id.subdevice = id->subdevice;
947 gctl->vcount = ctl->vcount;
948 gctl->count = ctl->count;
949 for (j = 0; j < 32; j++) {
950 gctl->gpr[j] = ctl->gpr[j];
951 gctl->value[j] = ctl->value[j];
952 }
953 gctl->min = ctl->min;
954 gctl->max = ctl->max;
955 gctl->translation = ctl->translation;
956 if (copy_gctl_to_user(emu, icode->gpr_list_controls,
957 gctl, i)) {
958 kfree(gctl);
959 return -EFAULT;
960 }
961 i++;
962 }
963 }
964 icode->gpr_list_control_total = total;
965 kfree(gctl);
966 return 0;
967}
968
969static int snd_emu10k1_icode_poke(struct snd_emu10k1 *emu,
970 struct snd_emu10k1_fx8010_code *icode,
971 bool in_kernel)
972{
973 int err = 0;
974
975 mutex_lock(&emu->fx8010.lock);
976 err = snd_emu10k1_verify_controls(emu, icode, in_kernel);
977 if (err < 0)
978 goto __error;
979 strlcpy(emu->fx8010.name, icode->name, sizeof(emu->fx8010.name));
980
981
982 if (emu->audigy)
983 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg | A_DBG_SINGLE_STEP);
984 else
985 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg | EMU10K1_DBG_SINGLE_STEP);
986
987 err = snd_emu10k1_del_controls(emu, icode, in_kernel);
988 if (err < 0)
989 goto __error;
990 err = snd_emu10k1_gpr_poke(emu, icode, in_kernel);
991 if (err < 0)
992 goto __error;
993 err = snd_emu10k1_tram_poke(emu, icode, in_kernel);
994 if (err < 0)
995 goto __error;
996 err = snd_emu10k1_code_poke(emu, icode, in_kernel);
997 if (err < 0)
998 goto __error;
999 err = snd_emu10k1_add_controls(emu, icode, in_kernel);
1000 if (err < 0)
1001 goto __error;
1002
1003 if (emu->audigy)
1004 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg);
1005 else
1006 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg);
1007 __error:
1008 mutex_unlock(&emu->fx8010.lock);
1009 return err;
1010}
1011
1012static int snd_emu10k1_icode_peek(struct snd_emu10k1 *emu,
1013 struct snd_emu10k1_fx8010_code *icode)
1014{
1015 int err;
1016
1017 mutex_lock(&emu->fx8010.lock);
1018 strlcpy(icode->name, emu->fx8010.name, sizeof(icode->name));
1019
1020 err = snd_emu10k1_gpr_peek(emu, icode);
1021 if (err >= 0)
1022 err = snd_emu10k1_tram_peek(emu, icode);
1023 if (err >= 0)
1024 err = snd_emu10k1_code_peek(emu, icode);
1025 if (err >= 0)
1026 err = snd_emu10k1_list_controls(emu, icode);
1027 mutex_unlock(&emu->fx8010.lock);
1028 return err;
1029}
1030
1031static int snd_emu10k1_ipcm_poke(struct snd_emu10k1 *emu,
1032 struct snd_emu10k1_fx8010_pcm_rec *ipcm)
1033{
1034 unsigned int i;
1035 int err = 0;
1036 struct snd_emu10k1_fx8010_pcm *pcm;
1037
1038 if (ipcm->substream >= EMU10K1_FX8010_PCM_COUNT)
1039 return -EINVAL;
1040 ipcm->substream = array_index_nospec(ipcm->substream,
1041 EMU10K1_FX8010_PCM_COUNT);
1042 if (ipcm->channels > 32)
1043 return -EINVAL;
1044 pcm = &emu->fx8010.pcm[ipcm->substream];
1045 mutex_lock(&emu->fx8010.lock);
1046 spin_lock_irq(&emu->reg_lock);
1047 if (pcm->opened) {
1048 err = -EBUSY;
1049 goto __error;
1050 }
1051 if (ipcm->channels == 0) {
1052 pcm->valid = 0;
1053 } else {
1054
1055 if (ipcm->channels != 2) {
1056 err = -EINVAL;
1057 goto __error;
1058 }
1059 pcm->valid = 1;
1060 pcm->opened = 0;
1061 pcm->channels = ipcm->channels;
1062 pcm->tram_start = ipcm->tram_start;
1063 pcm->buffer_size = ipcm->buffer_size;
1064 pcm->gpr_size = ipcm->gpr_size;
1065 pcm->gpr_count = ipcm->gpr_count;
1066 pcm->gpr_tmpcount = ipcm->gpr_tmpcount;
1067 pcm->gpr_ptr = ipcm->gpr_ptr;
1068 pcm->gpr_trigger = ipcm->gpr_trigger;
1069 pcm->gpr_running = ipcm->gpr_running;
1070 for (i = 0; i < pcm->channels; i++)
1071 pcm->etram[i] = ipcm->etram[i];
1072 }
1073 __error:
1074 spin_unlock_irq(&emu->reg_lock);
1075 mutex_unlock(&emu->fx8010.lock);
1076 return err;
1077}
1078
1079static int snd_emu10k1_ipcm_peek(struct snd_emu10k1 *emu,
1080 struct snd_emu10k1_fx8010_pcm_rec *ipcm)
1081{
1082 unsigned int i;
1083 int err = 0;
1084 struct snd_emu10k1_fx8010_pcm *pcm;
1085
1086 if (ipcm->substream >= EMU10K1_FX8010_PCM_COUNT)
1087 return -EINVAL;
1088 ipcm->substream = array_index_nospec(ipcm->substream,
1089 EMU10K1_FX8010_PCM_COUNT);
1090 pcm = &emu->fx8010.pcm[ipcm->substream];
1091 mutex_lock(&emu->fx8010.lock);
1092 spin_lock_irq(&emu->reg_lock);
1093 ipcm->channels = pcm->channels;
1094 ipcm->tram_start = pcm->tram_start;
1095 ipcm->buffer_size = pcm->buffer_size;
1096 ipcm->gpr_size = pcm->gpr_size;
1097 ipcm->gpr_ptr = pcm->gpr_ptr;
1098 ipcm->gpr_count = pcm->gpr_count;
1099 ipcm->gpr_tmpcount = pcm->gpr_tmpcount;
1100 ipcm->gpr_trigger = pcm->gpr_trigger;
1101 ipcm->gpr_running = pcm->gpr_running;
1102 for (i = 0; i < pcm->channels; i++)
1103 ipcm->etram[i] = pcm->etram[i];
1104 ipcm->res1 = ipcm->res2 = 0;
1105 ipcm->pad = 0;
1106 spin_unlock_irq(&emu->reg_lock);
1107 mutex_unlock(&emu->fx8010.lock);
1108 return err;
1109}
1110
1111#define SND_EMU10K1_GPR_CONTROLS 44
1112#define SND_EMU10K1_INPUTS 12
1113#define SND_EMU10K1_PLAYBACK_CHANNELS 8
1114#define SND_EMU10K1_CAPTURE_CHANNELS 4
1115
1116static void
1117snd_emu10k1_init_mono_control(struct snd_emu10k1_fx8010_control_gpr *ctl,
1118 const char *name, int gpr, int defval)
1119{
1120 ctl->id.iface = (__force int)SNDRV_CTL_ELEM_IFACE_MIXER;
1121 strcpy(ctl->id.name, name);
1122 ctl->vcount = ctl->count = 1;
1123 ctl->gpr[0] = gpr + 0; ctl->value[0] = defval;
1124 if (high_res_gpr_volume) {
1125 ctl->min = 0;
1126 ctl->max = 0x7fffffff;
1127 ctl->tlv = snd_emu10k1_db_linear;
1128 ctl->translation = EMU10K1_GPR_TRANSLATION_NONE;
1129 } else {
1130 ctl->min = 0;
1131 ctl->max = 100;
1132 ctl->tlv = snd_emu10k1_db_scale1;
1133 ctl->translation = EMU10K1_GPR_TRANSLATION_TABLE100;
1134 }
1135}
1136
1137static void
1138snd_emu10k1_init_stereo_control(struct snd_emu10k1_fx8010_control_gpr *ctl,
1139 const char *name, int gpr, int defval)
1140{
1141 ctl->id.iface = (__force int)SNDRV_CTL_ELEM_IFACE_MIXER;
1142 strcpy(ctl->id.name, name);
1143 ctl->vcount = ctl->count = 2;
1144 ctl->gpr[0] = gpr + 0; ctl->value[0] = defval;
1145 ctl->gpr[1] = gpr + 1; ctl->value[1] = defval;
1146 if (high_res_gpr_volume) {
1147 ctl->min = 0;
1148 ctl->max = 0x7fffffff;
1149 ctl->tlv = snd_emu10k1_db_linear;
1150 ctl->translation = EMU10K1_GPR_TRANSLATION_NONE;
1151 } else {
1152 ctl->min = 0;
1153 ctl->max = 100;
1154 ctl->tlv = snd_emu10k1_db_scale1;
1155 ctl->translation = EMU10K1_GPR_TRANSLATION_TABLE100;
1156 }
1157}
1158
1159static void
1160snd_emu10k1_init_mono_onoff_control(struct snd_emu10k1_fx8010_control_gpr *ctl,
1161 const char *name, int gpr, int defval)
1162{
1163 ctl->id.iface = (__force int)SNDRV_CTL_ELEM_IFACE_MIXER;
1164 strcpy(ctl->id.name, name);
1165 ctl->vcount = ctl->count = 1;
1166 ctl->gpr[0] = gpr + 0; ctl->value[0] = defval;
1167 ctl->min = 0;
1168 ctl->max = 1;
1169 ctl->translation = EMU10K1_GPR_TRANSLATION_ONOFF;
1170}
1171
1172static void
1173snd_emu10k1_init_stereo_onoff_control(struct snd_emu10k1_fx8010_control_gpr *ctl,
1174 const char *name, int gpr, int defval)
1175{
1176 ctl->id.iface = (__force int)SNDRV_CTL_ELEM_IFACE_MIXER;
1177 strcpy(ctl->id.name, name);
1178 ctl->vcount = ctl->count = 2;
1179 ctl->gpr[0] = gpr + 0; ctl->value[0] = defval;
1180 ctl->gpr[1] = gpr + 1; ctl->value[1] = defval;
1181 ctl->min = 0;
1182 ctl->max = 1;
1183 ctl->translation = EMU10K1_GPR_TRANSLATION_ONOFF;
1184}
1185
1186
1187
1188
1189
1190
1191static int snd_emu10k1_audigy_dsp_convert_32_to_2x16(
1192 struct snd_emu10k1_fx8010_code *icode,
1193 u32 *ptr, int tmp, int bit_shifter16,
1194 int reg_in, int reg_out)
1195{
1196 A_OP(icode, ptr, iACC3, A_GPR(tmp + 1), reg_in, A_C_00000000, A_C_00000000);
1197 A_OP(icode, ptr, iANDXOR, A_GPR(tmp), A_GPR(tmp + 1), A_GPR(bit_shifter16 - 1), A_C_00000000);
1198 A_OP(icode, ptr, iTSTNEG, A_GPR(tmp + 2), A_GPR(tmp), A_C_80000000, A_GPR(bit_shifter16 - 2));
1199 A_OP(icode, ptr, iANDXOR, A_GPR(tmp + 2), A_GPR(tmp + 2), A_C_80000000, A_C_00000000);
1200 A_OP(icode, ptr, iANDXOR, A_GPR(tmp), A_GPR(tmp), A_GPR(bit_shifter16 - 3), A_C_00000000);
1201 A_OP(icode, ptr, iMACINT0, A_GPR(tmp), A_C_00000000, A_GPR(tmp), A_C_00010000);
1202 A_OP(icode, ptr, iANDXOR, reg_out, A_GPR(tmp), A_C_ffffffff, A_GPR(tmp + 2));
1203 A_OP(icode, ptr, iACC3, reg_out + 1, A_GPR(tmp + 1), A_C_00000000, A_C_00000000);
1204 return 1;
1205}
1206
1207
1208
1209
1210
1211static int _snd_emu10k1_audigy_init_efx(struct snd_emu10k1 *emu)
1212{
1213 int err, i, z, gpr, nctl;
1214 int bit_shifter16;
1215 const int playback = 10;
1216 const int capture = playback + (SND_EMU10K1_PLAYBACK_CHANNELS * 2);
1217 const int stereo_mix = capture + 2;
1218 const int tmp = 0x88;
1219 u32 ptr;
1220 struct snd_emu10k1_fx8010_code *icode = NULL;
1221 struct snd_emu10k1_fx8010_control_gpr *controls = NULL, *ctl;
1222 u32 *gpr_map;
1223
1224 err = -ENOMEM;
1225 icode = kzalloc(sizeof(*icode), GFP_KERNEL);
1226 if (!icode)
1227 return err;
1228
1229 icode->gpr_map = kcalloc(512 + 256 + 256 + 2 * 1024,
1230 sizeof(u_int32_t), GFP_KERNEL);
1231 if (!icode->gpr_map)
1232 goto __err_gpr;
1233 controls = kcalloc(SND_EMU10K1_GPR_CONTROLS,
1234 sizeof(*controls), GFP_KERNEL);
1235 if (!controls)
1236 goto __err_ctrls;
1237
1238 gpr_map = icode->gpr_map;
1239
1240 icode->tram_data_map = icode->gpr_map + 512;
1241 icode->tram_addr_map = icode->tram_data_map + 256;
1242 icode->code = icode->tram_addr_map + 256;
1243
1244
1245 for (i = 0; i < 512; i++)
1246 set_bit(i, icode->gpr_valid);
1247
1248
1249 for (i = 0; i < 256; i++)
1250 set_bit(i, icode->tram_valid);
1251
1252 strcpy(icode->name, "Audigy DSP code for ALSA");
1253 ptr = 0;
1254 nctl = 0;
1255 gpr = stereo_mix + 10;
1256 gpr_map[gpr++] = 0x00007fff;
1257 gpr_map[gpr++] = 0x00008000;
1258 gpr_map[gpr++] = 0x0000ffff;
1259 bit_shifter16 = gpr;
1260
1261
1262 snd_emu10k1_ptr_write(emu, A_DBG, 0, (emu->fx8010.dbg = 0) | A_DBG_SINGLE_STEP);
1263
1264#if 1
1265
1266
1267
1268
1269
1270 A_OP(icode, &ptr, iMAC0, A_GPR(playback), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LEFT_FRONT));
1271 A_OP(icode, &ptr, iMAC0, A_GPR(playback+1), A_C_00000000, A_GPR(gpr+1), A_FXBUS(FXBUS_PCM_RIGHT_FRONT));
1272 snd_emu10k1_init_stereo_control(&controls[nctl++], "PCM Front Playback Volume", gpr, 100);
1273 gpr += 2;
1274
1275
1276 A_OP(icode, &ptr, iMAC0, A_GPR(playback+2), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LEFT_REAR));
1277 A_OP(icode, &ptr, iMAC0, A_GPR(playback+3), A_C_00000000, A_GPR(gpr+1), A_FXBUS(FXBUS_PCM_RIGHT_REAR));
1278 snd_emu10k1_init_stereo_control(&controls[nctl++], "PCM Surround Playback Volume", gpr, 100);
1279 gpr += 2;
1280
1281
1282 if (emu->card_capabilities->spk71) {
1283 A_OP(icode, &ptr, iMAC0, A_GPR(playback+6), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LEFT_SIDE));
1284 A_OP(icode, &ptr, iMAC0, A_GPR(playback+7), A_C_00000000, A_GPR(gpr+1), A_FXBUS(FXBUS_PCM_RIGHT_SIDE));
1285 snd_emu10k1_init_stereo_control(&controls[nctl++], "PCM Side Playback Volume", gpr, 100);
1286 gpr += 2;
1287 }
1288
1289
1290 A_OP(icode, &ptr, iMAC0, A_GPR(playback+4), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_CENTER));
1291 snd_emu10k1_init_mono_control(&controls[nctl++], "PCM Center Playback Volume", gpr, 100);
1292 gpr++;
1293
1294
1295 A_OP(icode, &ptr, iMAC0, A_GPR(playback+5), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LFE));
1296 snd_emu10k1_init_mono_control(&controls[nctl++], "PCM LFE Playback Volume", gpr, 100);
1297 gpr++;
1298
1299
1300
1301
1302
1303 A_OP(icode, &ptr, iMAC0, A_GPR(stereo_mix), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LEFT));
1304 A_OP(icode, &ptr, iMAC0, A_GPR(stereo_mix+1), A_C_00000000, A_GPR(gpr+1), A_FXBUS(FXBUS_PCM_RIGHT));
1305 snd_emu10k1_init_stereo_control(&controls[nctl++], "Wave Playback Volume", gpr, 100);
1306 gpr += 2;
1307
1308
1309 A_OP(icode, &ptr, iMAC0, A_GPR(stereo_mix+0), A_GPR(stereo_mix+0), A_GPR(gpr), A_FXBUS(FXBUS_MIDI_LEFT));
1310 A_OP(icode, &ptr, iMAC0, A_GPR(stereo_mix+1), A_GPR(stereo_mix+1), A_GPR(gpr+1), A_FXBUS(FXBUS_MIDI_RIGHT));
1311 snd_emu10k1_init_stereo_control(&controls[nctl++], "Synth Playback Volume", gpr, 100);
1312 gpr += 2;
1313
1314
1315 A_OP(icode, &ptr, iMAC0, A_GPR(capture+0), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LEFT));
1316 A_OP(icode, &ptr, iMAC0, A_GPR(capture+1), A_C_00000000, A_GPR(gpr+1), A_FXBUS(FXBUS_PCM_RIGHT));
1317 snd_emu10k1_init_stereo_control(&controls[nctl++], "PCM Capture Volume", gpr, 0);
1318 gpr += 2;
1319
1320
1321 A_OP(icode, &ptr, iMAC0, A_GPR(capture+0), A_GPR(capture+0), A_GPR(gpr), A_FXBUS(FXBUS_MIDI_LEFT));
1322 A_OP(icode, &ptr, iMAC0, A_GPR(capture+1), A_GPR(capture+1), A_GPR(gpr+1), A_FXBUS(FXBUS_MIDI_RIGHT));
1323 snd_emu10k1_init_stereo_control(&controls[nctl++], "Synth Capture Volume", gpr, 0);
1324 gpr += 2;
1325
1326
1327
1328
1329#define A_ADD_VOLUME_IN(var,vol,input) \
1330A_OP(icode, &ptr, iMAC0, A_GPR(var), A_GPR(var), A_GPR(vol), A_EXTIN(input))
1331
1332
1333 if (emu->card_capabilities->emu_model) {
1334 if (emu->card_capabilities->ca0108_chip) {
1335
1336 A_OP(icode, &ptr, iMACINT0, A_GPR(tmp), A_C_00000000, A3_EMU32IN(0x0), A_C_00000001);
1337 A_OP(icode, &ptr, iMAC0, A_GPR(capture+0), A_GPR(capture+0), A_GPR(gpr), A_GPR(tmp));
1338 A_OP(icode, &ptr, iMACINT0, A_GPR(tmp), A_C_00000000, A3_EMU32IN(0x1), A_C_00000001);
1339 A_OP(icode, &ptr, iMAC0, A_GPR(capture+1), A_GPR(capture+1), A_GPR(gpr), A_GPR(tmp));
1340 } else {
1341 A_OP(icode, &ptr, iMAC0, A_GPR(capture+0), A_GPR(capture+0), A_GPR(gpr), A_P16VIN(0x0));
1342 A_OP(icode, &ptr, iMAC0, A_GPR(capture+1), A_GPR(capture+1), A_GPR(gpr+1), A_P16VIN(0x1));
1343 }
1344 snd_emu10k1_init_stereo_control(&controls[nctl++], "EMU Capture Volume", gpr, 0);
1345 gpr += 2;
1346 }
1347
1348 A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_AC97_L);
1349 A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_AC97_R);
1350 snd_emu10k1_init_stereo_control(&controls[nctl++], "AMic Playback Volume", gpr, 0);
1351 gpr += 2;
1352
1353 A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_AC97_L);
1354 A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_AC97_R);
1355 snd_emu10k1_init_stereo_control(&controls[nctl++], "Mic Capture Volume", gpr, 0);
1356 gpr += 2;
1357
1358
1359 A_OP(icode, &ptr, iINTERP, A_EXTOUT(A_EXTOUT_MIC_CAP), A_EXTIN(A_EXTIN_AC97_L), 0xcd, A_EXTIN(A_EXTIN_AC97_R));
1360
1361
1362 A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_SPDIF_CD_L);
1363 A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_SPDIF_CD_R);
1364 snd_emu10k1_init_stereo_control(&controls[nctl++],
1365 emu->card_capabilities->ac97_chip ? "Audigy CD Playback Volume" : "CD Playback Volume",
1366 gpr, 0);
1367 gpr += 2;
1368
1369 A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_SPDIF_CD_L);
1370 A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_SPDIF_CD_R);
1371 snd_emu10k1_init_stereo_control(&controls[nctl++],
1372 emu->card_capabilities->ac97_chip ? "Audigy CD Capture Volume" : "CD Capture Volume",
1373 gpr, 0);
1374 gpr += 2;
1375
1376
1377 A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_OPT_SPDIF_L);
1378 A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_OPT_SPDIF_R);
1379 snd_emu10k1_init_stereo_control(&controls[nctl++], SNDRV_CTL_NAME_IEC958("Optical ",PLAYBACK,VOLUME), gpr, 0);
1380 gpr += 2;
1381
1382 A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_OPT_SPDIF_L);
1383 A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_OPT_SPDIF_R);
1384 snd_emu10k1_init_stereo_control(&controls[nctl++], SNDRV_CTL_NAME_IEC958("Optical ",CAPTURE,VOLUME), gpr, 0);
1385 gpr += 2;
1386
1387
1388 A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_LINE2_L);
1389 A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_LINE2_R);
1390 snd_emu10k1_init_stereo_control(&controls[nctl++],
1391 emu->card_capabilities->ac97_chip ? "Line2 Playback Volume" : "Line Playback Volume",
1392 gpr, 0);
1393 gpr += 2;
1394
1395 A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_LINE2_L);
1396 A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_LINE2_R);
1397 snd_emu10k1_init_stereo_control(&controls[nctl++],
1398 emu->card_capabilities->ac97_chip ? "Line2 Capture Volume" : "Line Capture Volume",
1399 gpr, 0);
1400 gpr += 2;
1401
1402
1403 A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_ADC_L);
1404 A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_ADC_R);
1405 snd_emu10k1_init_stereo_control(&controls[nctl++], "Analog Mix Playback Volume", gpr, 0);
1406 gpr += 2;
1407
1408 A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_ADC_L);
1409 A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_ADC_R);
1410 snd_emu10k1_init_stereo_control(&controls[nctl++], "Analog Mix Capture Volume", gpr, 0);
1411 gpr += 2;
1412
1413
1414 A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_AUX2_L);
1415 A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_AUX2_R);
1416 snd_emu10k1_init_stereo_control(&controls[nctl++],
1417 emu->card_capabilities->ac97_chip ? "Aux2 Playback Volume" : "Aux Playback Volume",
1418 gpr, 0);
1419 gpr += 2;
1420
1421 A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_AUX2_L);
1422 A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_AUX2_R);
1423 snd_emu10k1_init_stereo_control(&controls[nctl++],
1424 emu->card_capabilities->ac97_chip ? "Aux2 Capture Volume" : "Aux Capture Volume",
1425 gpr, 0);
1426 gpr += 2;
1427
1428
1429 A_OP(icode, &ptr, iMAC0, A_GPR(playback), A_GPR(playback), A_GPR(gpr), A_GPR(stereo_mix));
1430 A_OP(icode, &ptr, iMAC0, A_GPR(playback+1), A_GPR(playback+1), A_GPR(gpr+1), A_GPR(stereo_mix+1));
1431 snd_emu10k1_init_stereo_control(&controls[nctl++], "Front Playback Volume", gpr, 100);
1432 gpr += 2;
1433
1434
1435 A_OP(icode, &ptr, iMAC0, A_GPR(playback+2), A_GPR(playback+2), A_GPR(gpr), A_GPR(stereo_mix));
1436 A_OP(icode, &ptr, iMAC0, A_GPR(playback+3), A_GPR(playback+3), A_GPR(gpr+1), A_GPR(stereo_mix+1));
1437 snd_emu10k1_init_stereo_control(&controls[nctl++], "Surround Playback Volume", gpr, 0);
1438 gpr += 2;
1439
1440
1441
1442 A_OP(icode, &ptr, iINTERP, A_GPR(tmp), A_GPR(stereo_mix), 0xcd, A_GPR(stereo_mix+1));
1443 A_OP(icode, &ptr, iMAC0, A_GPR(playback+4), A_GPR(playback+4), A_GPR(gpr), A_GPR(tmp));
1444 snd_emu10k1_init_mono_control(&controls[nctl++], "Center Playback Volume", gpr, 0);
1445 gpr++;
1446
1447
1448 A_OP(icode, &ptr, iMAC0, A_GPR(playback+5), A_GPR(playback+5), A_GPR(gpr), A_GPR(tmp));
1449 snd_emu10k1_init_mono_control(&controls[nctl++], "LFE Playback Volume", gpr, 0);
1450 gpr++;
1451
1452 if (emu->card_capabilities->spk71) {
1453
1454 A_OP(icode, &ptr, iMAC0, A_GPR(playback+6), A_GPR(playback+6), A_GPR(gpr), A_GPR(stereo_mix));
1455 A_OP(icode, &ptr, iMAC0, A_GPR(playback+7), A_GPR(playback+7), A_GPR(gpr+1), A_GPR(stereo_mix+1));
1456 snd_emu10k1_init_stereo_control(&controls[nctl++], "Side Playback Volume", gpr, 0);
1457 gpr += 2;
1458 }
1459
1460
1461
1462
1463#define A_PUT_OUTPUT(out,src) A_OP(icode, &ptr, iACC3, A_EXTOUT(out), A_C_00000000, A_C_00000000, A_GPR(src))
1464#define A_PUT_STEREO_OUTPUT(out1,out2,src) \
1465 {A_PUT_OUTPUT(out1,src); A_PUT_OUTPUT(out2,src+1);}
1466
1467#define _A_SWITCH(icode, ptr, dst, src, sw) \
1468 A_OP((icode), ptr, iMACINT0, dst, A_C_00000000, src, sw);
1469#define A_SWITCH(icode, ptr, dst, src, sw) \
1470 _A_SWITCH(icode, ptr, A_GPR(dst), A_GPR(src), A_GPR(sw))
1471#define _A_SWITCH_NEG(icode, ptr, dst, src) \
1472 A_OP((icode), ptr, iANDXOR, dst, src, A_C_00000001, A_C_00000001);
1473#define A_SWITCH_NEG(icode, ptr, dst, src) \
1474 _A_SWITCH_NEG(icode, ptr, A_GPR(dst), A_GPR(src))
1475
1476
1477
1478
1479
1480 A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 0), A_GPR(playback + 0), A_C_00000000, A_C_00000000);
1481 A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 1), A_GPR(playback + 1), A_C_00000000, A_C_00000000);
1482 A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 2), A_GPR(playback + 2), A_C_00000000, A_C_00000000);
1483 A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 3), A_GPR(playback + 3), A_C_00000000, A_C_00000000);
1484 A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 4), A_GPR(playback + 4), A_C_00000000, A_C_00000000);
1485 A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 5), A_GPR(playback + 5), A_C_00000000, A_C_00000000);
1486 if (emu->card_capabilities->spk71) {
1487 A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 6), A_GPR(playback + 6), A_C_00000000, A_C_00000000);
1488 A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 7), A_GPR(playback + 7), A_C_00000000, A_C_00000000);
1489 }
1490
1491
1492 ctl = &controls[nctl + 0];
1493 ctl->id.iface = (__force int)SNDRV_CTL_ELEM_IFACE_MIXER;
1494 strcpy(ctl->id.name, "Tone Control - Bass");
1495 ctl->vcount = 2;
1496 ctl->count = 10;
1497 ctl->min = 0;
1498 ctl->max = 40;
1499 ctl->value[0] = ctl->value[1] = 20;
1500 ctl->translation = EMU10K1_GPR_TRANSLATION_BASS;
1501 ctl = &controls[nctl + 1];
1502 ctl->id.iface = (__force int)SNDRV_CTL_ELEM_IFACE_MIXER;
1503 strcpy(ctl->id.name, "Tone Control - Treble");
1504 ctl->vcount = 2;
1505 ctl->count = 10;
1506 ctl->min = 0;
1507 ctl->max = 40;
1508 ctl->value[0] = ctl->value[1] = 20;
1509 ctl->translation = EMU10K1_GPR_TRANSLATION_TREBLE;
1510
1511#define BASS_GPR 0x8c
1512#define TREBLE_GPR 0x96
1513
1514 for (z = 0; z < 5; z++) {
1515 int j;
1516 for (j = 0; j < 2; j++) {
1517 controls[nctl + 0].gpr[z * 2 + j] = BASS_GPR + z * 2 + j;
1518 controls[nctl + 1].gpr[z * 2 + j] = TREBLE_GPR + z * 2 + j;
1519 }
1520 }
1521 for (z = 0; z < 4; z++) {
1522 int j, k, l, d;
1523 for (j = 0; j < 2; j++) {
1524 k = 0xb0 + (z * 8) + (j * 4);
1525 l = 0xe0 + (z * 8) + (j * 4);
1526 d = playback + SND_EMU10K1_PLAYBACK_CHANNELS + z * 2 + j;
1527
1528 A_OP(icode, &ptr, iMAC0, A_C_00000000, A_C_00000000, A_GPR(d), A_GPR(BASS_GPR + 0 + j));
1529 A_OP(icode, &ptr, iMACMV, A_GPR(k+1), A_GPR(k), A_GPR(k+1), A_GPR(BASS_GPR + 4 + j));
1530 A_OP(icode, &ptr, iMACMV, A_GPR(k), A_GPR(d), A_GPR(k), A_GPR(BASS_GPR + 2 + j));
1531 A_OP(icode, &ptr, iMACMV, A_GPR(k+3), A_GPR(k+2), A_GPR(k+3), A_GPR(BASS_GPR + 8 + j));
1532 A_OP(icode, &ptr, iMAC0, A_GPR(k+2), A_GPR_ACCU, A_GPR(k+2), A_GPR(BASS_GPR + 6 + j));
1533 A_OP(icode, &ptr, iACC3, A_GPR(k+2), A_GPR(k+2), A_GPR(k+2), A_C_00000000);
1534
1535 A_OP(icode, &ptr, iMAC0, A_C_00000000, A_C_00000000, A_GPR(k+2), A_GPR(TREBLE_GPR + 0 + j));
1536 A_OP(icode, &ptr, iMACMV, A_GPR(l+1), A_GPR(l), A_GPR(l+1), A_GPR(TREBLE_GPR + 4 + j));
1537 A_OP(icode, &ptr, iMACMV, A_GPR(l), A_GPR(k+2), A_GPR(l), A_GPR(TREBLE_GPR + 2 + j));
1538 A_OP(icode, &ptr, iMACMV, A_GPR(l+3), A_GPR(l+2), A_GPR(l+3), A_GPR(TREBLE_GPR + 8 + j));
1539 A_OP(icode, &ptr, iMAC0, A_GPR(l+2), A_GPR_ACCU, A_GPR(l+2), A_GPR(TREBLE_GPR + 6 + j));
1540 A_OP(icode, &ptr, iMACINT0, A_GPR(l+2), A_C_00000000, A_GPR(l+2), A_C_00000010);
1541
1542 A_OP(icode, &ptr, iACC3, A_GPR(d), A_GPR(l+2), A_C_00000000, A_C_00000000);
1543
1544 if (z == 2)
1545 break;
1546 }
1547 }
1548 nctl += 2;
1549
1550#undef BASS_GPR
1551#undef TREBLE_GPR
1552
1553 for (z = 0; z < 8; z++) {
1554 A_SWITCH(icode, &ptr, tmp + 0, playback + SND_EMU10K1_PLAYBACK_CHANNELS + z, gpr + 0);
1555 A_SWITCH_NEG(icode, &ptr, tmp + 1, gpr + 0);
1556 A_SWITCH(icode, &ptr, tmp + 1, playback + z, tmp + 1);
1557 A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + z), A_GPR(tmp + 0), A_GPR(tmp + 1), A_C_00000000);
1558 }
1559 snd_emu10k1_init_stereo_onoff_control(controls + nctl++, "Tone Control - Switch", gpr, 0);
1560 gpr += 2;
1561
1562
1563 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));
1564 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));
1565 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));
1566 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));
1567 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));
1568 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));
1569 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));
1570 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));
1571 snd_emu10k1_init_mono_control(&controls[nctl++], "Wave Master Playback Volume", gpr, 0);
1572 gpr += 2;
1573
1574
1575 A_PUT_STEREO_OUTPUT(A_EXTOUT_AFRONT_L, A_EXTOUT_AFRONT_R, playback + SND_EMU10K1_PLAYBACK_CHANNELS);
1576 A_PUT_STEREO_OUTPUT(A_EXTOUT_AREAR_L, A_EXTOUT_AREAR_R, playback+2 + SND_EMU10K1_PLAYBACK_CHANNELS);
1577 A_PUT_OUTPUT(A_EXTOUT_ACENTER, playback+4 + SND_EMU10K1_PLAYBACK_CHANNELS);
1578 A_PUT_OUTPUT(A_EXTOUT_ALFE, playback+5 + SND_EMU10K1_PLAYBACK_CHANNELS);
1579 if (emu->card_capabilities->spk71)
1580 A_PUT_STEREO_OUTPUT(A_EXTOUT_ASIDE_L, A_EXTOUT_ASIDE_R, playback+6 + SND_EMU10K1_PLAYBACK_CHANNELS);
1581
1582
1583 A_PUT_STEREO_OUTPUT(A_EXTOUT_HEADPHONE_L, A_EXTOUT_HEADPHONE_R, playback + SND_EMU10K1_PLAYBACK_CHANNELS);
1584
1585
1586
1587 if (emu->card_capabilities->emu_model) {
1588
1589 dev_info(emu->card->dev, "EMU outputs on\n");
1590 for (z = 0; z < 8; z++) {
1591 if (emu->card_capabilities->ca0108_chip) {
1592 A_OP(icode, &ptr, iACC3, A3_EMU32OUT(z), A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + z), A_C_00000000, A_C_00000000);
1593 } else {
1594 A_OP(icode, &ptr, iACC3, A_EMU32OUTL(z), A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + z), A_C_00000000, A_C_00000000);
1595 }
1596 }
1597 }
1598
1599
1600 gpr_map[gpr++] = 0;
1601 gpr_map[gpr++] = 0x1008;
1602 gpr_map[gpr++] = 0xffff0000;
1603 for (z = 0; z < 2; z++) {
1604 A_OP(icode, &ptr, iMAC0, A_GPR(tmp + 2), A_FXBUS(FXBUS_PT_LEFT + z), A_C_00000000, A_C_00000000);
1605 A_OP(icode, &ptr, iSKIP, A_GPR_COND, A_GPR_COND, A_GPR(gpr - 2), A_C_00000001);
1606 A_OP(icode, &ptr, iACC3, A_GPR(tmp + 2), A_C_00000000, A_C_00010000, A_GPR(tmp + 2));
1607 A_OP(icode, &ptr, iANDXOR, A_GPR(tmp + 2), A_GPR(tmp + 2), A_GPR(gpr - 1), A_C_00000000);
1608 A_SWITCH(icode, &ptr, tmp + 0, tmp + 2, gpr + z);
1609 A_SWITCH_NEG(icode, &ptr, tmp + 1, gpr + z);
1610 A_SWITCH(icode, &ptr, tmp + 1, playback + SND_EMU10K1_PLAYBACK_CHANNELS + z, tmp + 1);
1611 if ((z==1) && (emu->card_capabilities->spdif_bug)) {
1612
1613 dev_info(emu->card->dev,
1614 "Installing spdif_bug patch: %s\n",
1615 emu->card_capabilities->name);
1616 A_OP(icode, &ptr, iACC3, A_EXTOUT(A_EXTOUT_FRONT_L + z), A_GPR(gpr - 3), A_C_00000000, A_C_00000000);
1617 A_OP(icode, &ptr, iACC3, A_GPR(gpr - 3), A_GPR(tmp + 0), A_GPR(tmp + 1), A_C_00000000);
1618 } else {
1619 A_OP(icode, &ptr, iACC3, A_EXTOUT(A_EXTOUT_FRONT_L + z), A_GPR(tmp + 0), A_GPR(tmp + 1), A_C_00000000);
1620 }
1621 }
1622 snd_emu10k1_init_stereo_onoff_control(controls + nctl++, SNDRV_CTL_NAME_IEC958("Optical Raw ",PLAYBACK,SWITCH), gpr, 0);
1623 gpr += 2;
1624
1625 A_PUT_STEREO_OUTPUT(A_EXTOUT_REAR_L, A_EXTOUT_REAR_R, playback+2 + SND_EMU10K1_PLAYBACK_CHANNELS);
1626 A_PUT_OUTPUT(A_EXTOUT_CENTER, playback+4 + SND_EMU10K1_PLAYBACK_CHANNELS);
1627 A_PUT_OUTPUT(A_EXTOUT_LFE, playback+5 + SND_EMU10K1_PLAYBACK_CHANNELS);
1628
1629
1630#ifdef EMU10K1_CAPTURE_DIGITAL_OUT
1631 A_PUT_STEREO_OUTPUT(A_EXTOUT_ADC_CAP_L, A_EXTOUT_ADC_CAP_R, playback + SND_EMU10K1_PLAYBACK_CHANNELS);
1632#else
1633 A_PUT_OUTPUT(A_EXTOUT_ADC_CAP_L, capture);
1634 A_PUT_OUTPUT(A_EXTOUT_ADC_CAP_R, capture+1);
1635#endif
1636
1637 if (emu->card_capabilities->emu_model) {
1638 if (emu->card_capabilities->ca0108_chip) {
1639 dev_info(emu->card->dev, "EMU2 inputs on\n");
1640 for (z = 0; z < 0x10; z++) {
1641 snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp,
1642 bit_shifter16,
1643 A3_EMU32IN(z),
1644 A_FXBUS2(z*2) );
1645 }
1646 } else {
1647 dev_info(emu->card->dev, "EMU inputs on\n");
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659 snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_P16VIN(0x0), A_FXBUS2(0) );
1660
1661 gpr_map[gpr++] = 0x00000000;
1662
1663
1664
1665
1666
1667 snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_GPR(gpr - 1), A_FXBUS2(2) );
1668 A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x1), A_C_00000000, A_C_00000000);
1669 gpr_map[gpr++] = 0x00000000;
1670 snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_GPR(gpr - 1), A_FXBUS2(4) );
1671 A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x2), A_C_00000000, A_C_00000000);
1672 gpr_map[gpr++] = 0x00000000;
1673 snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_GPR(gpr - 1), A_FXBUS2(6) );
1674 A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x3), A_C_00000000, A_C_00000000);
1675
1676
1677 gpr_map[gpr++] = 0x00000000;
1678 snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_GPR(gpr - 1), A_FXBUS2(0x8) );
1679 A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x4), A_C_00000000, A_C_00000000);
1680
1681 gpr_map[gpr++] = 0x00000000;
1682 snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_GPR(gpr - 1), A_FXBUS2(0xa) );
1683 A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x5), A_C_00000000, A_C_00000000);
1684 gpr_map[gpr++] = 0x00000000;
1685 snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_GPR(gpr - 1), A_FXBUS2(0xc) );
1686 A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x6), A_C_00000000, A_C_00000000);
1687 gpr_map[gpr++] = 0x00000000;
1688 snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_GPR(gpr - 1), A_FXBUS2(0xe) );
1689 A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x7), A_C_00000000, A_C_00000000);
1690
1691
1692
1693
1694 gpr_map[gpr++] = 0x00000000;
1695 snd_emu10k1_audigy_dsp_convert_32_to_2x16(icode, &ptr, tmp,
1696 bit_shifter16,
1697 A_GPR(gpr - 1),
1698 A_FXBUS2(0x10));
1699 A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x8),
1700 A_C_00000000, A_C_00000000);
1701 gpr_map[gpr++] = 0x00000000;
1702 snd_emu10k1_audigy_dsp_convert_32_to_2x16(icode, &ptr, tmp,
1703 bit_shifter16,
1704 A_GPR(gpr - 1),
1705 A_FXBUS2(0x12));
1706 A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x9),
1707 A_C_00000000, A_C_00000000);
1708 gpr_map[gpr++] = 0x00000000;
1709 snd_emu10k1_audigy_dsp_convert_32_to_2x16(icode, &ptr, tmp,
1710 bit_shifter16,
1711 A_GPR(gpr - 1),
1712 A_FXBUS2(0x14));
1713 A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0xa),
1714 A_C_00000000, A_C_00000000);
1715 gpr_map[gpr++] = 0x00000000;
1716 snd_emu10k1_audigy_dsp_convert_32_to_2x16(icode, &ptr, tmp,
1717 bit_shifter16,
1718 A_GPR(gpr - 1),
1719 A_FXBUS2(0x16));
1720 A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0xb),
1721 A_C_00000000, A_C_00000000);
1722 gpr_map[gpr++] = 0x00000000;
1723 snd_emu10k1_audigy_dsp_convert_32_to_2x16(icode, &ptr, tmp,
1724 bit_shifter16,
1725 A_GPR(gpr - 1),
1726 A_FXBUS2(0x18));
1727 A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0xc),
1728 A_C_00000000, A_C_00000000);
1729 gpr_map[gpr++] = 0x00000000;
1730 snd_emu10k1_audigy_dsp_convert_32_to_2x16(icode, &ptr, tmp,
1731 bit_shifter16,
1732 A_GPR(gpr - 1),
1733 A_FXBUS2(0x1a));
1734 A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0xd),
1735 A_C_00000000, A_C_00000000);
1736 gpr_map[gpr++] = 0x00000000;
1737 snd_emu10k1_audigy_dsp_convert_32_to_2x16(icode, &ptr, tmp,
1738 bit_shifter16,
1739 A_GPR(gpr - 1),
1740 A_FXBUS2(0x1c));
1741 A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0xe),
1742 A_C_00000000, A_C_00000000);
1743 gpr_map[gpr++] = 0x00000000;
1744 snd_emu10k1_audigy_dsp_convert_32_to_2x16(icode, &ptr, tmp,
1745 bit_shifter16,
1746 A_GPR(gpr - 1),
1747 A_FXBUS2(0x1e));
1748 A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0xf),
1749 A_C_00000000, A_C_00000000);
1750 }
1751
1752#if 0
1753 for (z = 4; z < 8; z++) {
1754 A_OP(icode, &ptr, iACC3, A_FXBUS2(z), A_C_00000000, A_C_00000000, A_C_00000000);
1755 }
1756 for (z = 0xc; z < 0x10; z++) {
1757 A_OP(icode, &ptr, iACC3, A_FXBUS2(z), A_C_00000000, A_C_00000000, A_C_00000000);
1758 }
1759#endif
1760 } else {
1761
1762
1763 for (z = 0; z < 16; z++) {
1764 A_OP(icode, &ptr, iACC3, A_FXBUS2(z), A_C_00000000, A_C_00000000, A_EXTIN(z));
1765 }
1766 }
1767
1768#endif
1769
1770
1771
1772
1773 if (gpr > tmp) {
1774 snd_BUG();
1775 err = -EIO;
1776 goto __err;
1777 }
1778
1779 while (ptr < 0x400)
1780 A_OP(icode, &ptr, 0x0f, 0xc0, 0xc0, 0xcf, 0xc0);
1781
1782 icode->gpr_add_control_count = nctl;
1783 icode->gpr_add_controls = controls;
1784 emu->support_tlv = 1;
1785 err = snd_emu10k1_icode_poke(emu, icode, true);
1786 emu->support_tlv = 0;
1787
1788__err:
1789 kfree(controls);
1790__err_ctrls:
1791 kfree(icode->gpr_map);
1792__err_gpr:
1793 kfree(icode);
1794 return err;
1795}
1796
1797
1798
1799
1800
1801
1802
1803
1804static void _volume(struct snd_emu10k1_fx8010_code *icode, u32 *ptr, u32 dst, u32 src, u32 vol)
1805{
1806 OP(icode, ptr, iMAC0, dst, C_00000000, src, vol);
1807 OP(icode, ptr, iANDXOR, C_00000000, vol, C_ffffffff, C_7fffffff);
1808 OP(icode, ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, C_00000001);
1809 OP(icode, ptr, iACC3, dst, src, C_00000000, C_00000000);
1810}
1811static void _volume_add(struct snd_emu10k1_fx8010_code *icode, u32 *ptr, u32 dst, u32 src, u32 vol)
1812{
1813 OP(icode, ptr, iANDXOR, C_00000000, vol, C_ffffffff, C_7fffffff);
1814 OP(icode, ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, C_00000002);
1815 OP(icode, ptr, iMACINT0, dst, dst, src, C_00000001);
1816 OP(icode, ptr, iSKIP, C_00000000, C_7fffffff, C_7fffffff, C_00000001);
1817 OP(icode, ptr, iMAC0, dst, dst, src, vol);
1818}
1819static void _volume_out(struct snd_emu10k1_fx8010_code *icode, u32 *ptr, u32 dst, u32 src, u32 vol)
1820{
1821 OP(icode, ptr, iANDXOR, C_00000000, vol, C_ffffffff, C_7fffffff);
1822 OP(icode, ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, C_00000002);
1823 OP(icode, ptr, iACC3, dst, src, C_00000000, C_00000000);
1824 OP(icode, ptr, iSKIP, C_00000000, C_7fffffff, C_7fffffff, C_00000001);
1825 OP(icode, ptr, iMAC0, dst, C_00000000, src, vol);
1826}
1827
1828#define VOLUME(icode, ptr, dst, src, vol) \
1829 _volume(icode, ptr, GPR(dst), GPR(src), GPR(vol))
1830#define VOLUME_IN(icode, ptr, dst, src, vol) \
1831 _volume(icode, ptr, GPR(dst), EXTIN(src), GPR(vol))
1832#define VOLUME_ADD(icode, ptr, dst, src, vol) \
1833 _volume_add(icode, ptr, GPR(dst), GPR(src), GPR(vol))
1834#define VOLUME_ADDIN(icode, ptr, dst, src, vol) \
1835 _volume_add(icode, ptr, GPR(dst), EXTIN(src), GPR(vol))
1836#define VOLUME_OUT(icode, ptr, dst, src, vol) \
1837 _volume_out(icode, ptr, EXTOUT(dst), GPR(src), GPR(vol))
1838#define _SWITCH(icode, ptr, dst, src, sw) \
1839 OP((icode), ptr, iMACINT0, dst, C_00000000, src, sw);
1840#define SWITCH(icode, ptr, dst, src, sw) \
1841 _SWITCH(icode, ptr, GPR(dst), GPR(src), GPR(sw))
1842#define SWITCH_IN(icode, ptr, dst, src, sw) \
1843 _SWITCH(icode, ptr, GPR(dst), EXTIN(src), GPR(sw))
1844#define _SWITCH_NEG(icode, ptr, dst, src) \
1845 OP((icode), ptr, iANDXOR, dst, src, C_00000001, C_00000001);
1846#define SWITCH_NEG(icode, ptr, dst, src) \
1847 _SWITCH_NEG(icode, ptr, GPR(dst), GPR(src))
1848
1849
1850static int _snd_emu10k1_init_efx(struct snd_emu10k1 *emu)
1851{
1852 int err, i, z, gpr, tmp, playback, capture;
1853 u32 ptr;
1854 struct snd_emu10k1_fx8010_code *icode;
1855 struct snd_emu10k1_fx8010_pcm_rec *ipcm = NULL;
1856 struct snd_emu10k1_fx8010_control_gpr *controls = NULL, *ctl;
1857 u32 *gpr_map;
1858
1859 err = -ENOMEM;
1860 icode = kzalloc(sizeof(*icode), GFP_KERNEL);
1861 if (!icode)
1862 return err;
1863
1864 icode->gpr_map = kcalloc(256 + 160 + 160 + 2 * 512,
1865 sizeof(u_int32_t), GFP_KERNEL);
1866 if (!icode->gpr_map)
1867 goto __err_gpr;
1868
1869 controls = kcalloc(SND_EMU10K1_GPR_CONTROLS,
1870 sizeof(struct snd_emu10k1_fx8010_control_gpr),
1871 GFP_KERNEL);
1872 if (!controls)
1873 goto __err_ctrls;
1874
1875 ipcm = kzalloc(sizeof(*ipcm), GFP_KERNEL);
1876 if (!ipcm)
1877 goto __err_ipcm;
1878
1879 gpr_map = icode->gpr_map;
1880
1881 icode->tram_data_map = icode->gpr_map + 256;
1882 icode->tram_addr_map = icode->tram_data_map + 160;
1883 icode->code = icode->tram_addr_map + 160;
1884
1885
1886 for (i = 0; i < 256; i++)
1887 set_bit(i, icode->gpr_valid);
1888
1889
1890 for (i = 0; i < 160; i++)
1891 set_bit(i, icode->tram_valid);
1892
1893 strcpy(icode->name, "SB Live! FX8010 code for ALSA v1.2 by Jaroslav Kysela");
1894 ptr = 0; i = 0;
1895
1896 playback = SND_EMU10K1_INPUTS;
1897
1898 capture = playback + (SND_EMU10K1_PLAYBACK_CHANNELS * 2);
1899 gpr = capture + SND_EMU10K1_CAPTURE_CHANNELS;
1900 tmp = 0x88;
1901
1902
1903
1904 snd_emu10k1_ptr_write(emu, DBG, 0, (emu->fx8010.dbg = 0) | EMU10K1_DBG_SINGLE_STEP);
1905
1906
1907
1908
1909 OP(icode, &ptr, iMACINT0, GPR(0), C_00000000, FXBUS(FXBUS_PCM_LEFT), C_00000004);
1910 OP(icode, &ptr, iMACINT0, GPR(1), C_00000000, FXBUS(FXBUS_PCM_RIGHT), C_00000004);
1911 OP(icode, &ptr, iMACINT0, GPR(2), C_00000000, FXBUS(FXBUS_MIDI_LEFT), C_00000004);
1912 OP(icode, &ptr, iMACINT0, GPR(3), C_00000000, FXBUS(FXBUS_MIDI_RIGHT), C_00000004);
1913 OP(icode, &ptr, iMACINT0, GPR(4), C_00000000, FXBUS(FXBUS_PCM_LEFT_REAR), C_00000004);
1914 OP(icode, &ptr, iMACINT0, GPR(5), C_00000000, FXBUS(FXBUS_PCM_RIGHT_REAR), C_00000004);
1915 OP(icode, &ptr, iMACINT0, GPR(6), C_00000000, FXBUS(FXBUS_PCM_CENTER), C_00000004);
1916 OP(icode, &ptr, iMACINT0, GPR(7), C_00000000, FXBUS(FXBUS_PCM_LFE), C_00000004);
1917 OP(icode, &ptr, iMACINT0, GPR(8), C_00000000, C_00000000, C_00000000);
1918 OP(icode, &ptr, iMACINT0, GPR(9), C_00000000, C_00000000, C_00000000);
1919 OP(icode, &ptr, iMACINT0, GPR(10), C_00000000, FXBUS(FXBUS_PCM_LEFT_FRONT), C_00000004);
1920 OP(icode, &ptr, iMACINT0, GPR(11), C_00000000, FXBUS(FXBUS_PCM_RIGHT_FRONT), C_00000004);
1921
1922
1923 ipcm->substream = 0;
1924 ipcm->channels = 2;
1925 ipcm->tram_start = 0;
1926 ipcm->buffer_size = (64 * 1024) / 2;
1927 ipcm->gpr_size = gpr++;
1928 ipcm->gpr_ptr = gpr++;
1929 ipcm->gpr_count = gpr++;
1930 ipcm->gpr_tmpcount = gpr++;
1931 ipcm->gpr_trigger = gpr++;
1932 ipcm->gpr_running = gpr++;
1933 ipcm->etram[0] = 0;
1934 ipcm->etram[1] = 1;
1935
1936 gpr_map[gpr + 0] = 0xfffff000;
1937 gpr_map[gpr + 1] = 0xffff0000;
1938 gpr_map[gpr + 2] = 0x70000000;
1939 gpr_map[gpr + 3] = 0x00000007;
1940 gpr_map[gpr + 4] = 0x001f << 11;
1941 gpr_map[gpr + 5] = 0x001c << 11;
1942 gpr_map[gpr + 6] = (0x22 - 0x01) - 1;
1943 gpr_map[gpr + 7] = (0x22 - 0x06) - 1;
1944 gpr_map[gpr + 8] = 0x2000000 + (2<<11);
1945 gpr_map[gpr + 9] = 0x4000000 + (2<<11);
1946 gpr_map[gpr + 10] = 1<<11;
1947 gpr_map[gpr + 11] = (0x24 - 0x0a) - 1;
1948 gpr_map[gpr + 12] = 0;
1949
1950
1951 OP(icode, &ptr, iMAC0, C_00000000, GPR(ipcm->gpr_trigger), C_00000000, C_00000000);
1952 OP(icode, &ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_ZERO, GPR(gpr + 6));
1953
1954 OP(icode, &ptr, iMAC0, C_00000000, GPR(ipcm->gpr_running), C_00000000, C_00000000);
1955 OP(icode, &ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, C_00000004);
1956
1957 OP(icode, &ptr, iANDXOR, GPR(tmp + 0), GPR_DBAC, GPR(gpr + 4), C_00000000);
1958 OP(icode, &ptr, iMACINT0, C_00000000, GPR(tmp + 0), C_ffffffff, GPR(gpr + 5));
1959 OP(icode, &ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, GPR(gpr + 7));
1960 OP(icode, &ptr, iACC3, GPR(gpr + 12), C_00000010, C_00000001, C_00000000);
1961
1962 OP(icode, &ptr, iANDXOR, GPR(ipcm->gpr_running), GPR(ipcm->gpr_running), C_00000000, C_00000001);
1963 OP(icode, &ptr, iACC3, GPR(gpr + 12), GPR(gpr + 12), C_ffffffff, C_00000000);
1964 OP(icode, &ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, GPR(gpr + 11));
1965 OP(icode, &ptr, iACC3, GPR(gpr + 12), C_00000001, C_00000000, C_00000000);
1966
1967 OP(icode, &ptr, iANDXOR, GPR(tmp + 0), ETRAM_DATA(ipcm->etram[0]), GPR(gpr + 0), C_00000000);
1968 OP(icode, &ptr, iLOG, GPR(tmp + 0), GPR(tmp + 0), GPR(gpr + 3), C_00000000);
1969 OP(icode, &ptr, iANDXOR, GPR(8), GPR(tmp + 0), GPR(gpr + 1), GPR(gpr + 2));
1970 OP(icode, &ptr, iSKIP, C_00000000, GPR_COND, CC_REG_MINUS, C_00000001);
1971 OP(icode, &ptr, iANDXOR, GPR(8), GPR(8), GPR(gpr + 1), GPR(gpr + 2));
1972
1973 OP(icode, &ptr, iANDXOR, GPR(tmp + 0), ETRAM_DATA(ipcm->etram[1]), GPR(gpr + 0), C_00000000);
1974 OP(icode, &ptr, iLOG, GPR(tmp + 0), GPR(tmp + 0), GPR(gpr + 3), C_00000000);
1975 OP(icode, &ptr, iANDXOR, GPR(9), GPR(tmp + 0), GPR(gpr + 1), GPR(gpr + 2));
1976 OP(icode, &ptr, iSKIP, C_00000000, GPR_COND, CC_REG_MINUS, C_00000001);
1977 OP(icode, &ptr, iANDXOR, GPR(9), GPR(9), GPR(gpr + 1), GPR(gpr + 2));
1978
1979 OP(icode, &ptr, iACC3, GPR(tmp + 0), GPR(ipcm->gpr_ptr), C_00000001, C_00000000);
1980 OP(icode, &ptr, iMACINT0, C_00000000, GPR(tmp + 0), C_ffffffff, GPR(ipcm->gpr_size));
1981 OP(icode, &ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_MINUS, C_00000001);
1982 OP(icode, &ptr, iACC3, GPR(tmp + 0), C_00000000, C_00000000, C_00000000);
1983 OP(icode, &ptr, iACC3, GPR(ipcm->gpr_ptr), GPR(tmp + 0), C_00000000, C_00000000);
1984
1985 OP(icode, &ptr, iACC3, GPR(ipcm->gpr_tmpcount), GPR(ipcm->gpr_tmpcount), C_ffffffff, C_00000000);
1986 OP(icode, &ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, C_00000002);
1987 OP(icode, &ptr, iACC3, GPR(ipcm->gpr_tmpcount), GPR(ipcm->gpr_count), C_00000000, C_00000000);
1988 OP(icode, &ptr, iACC3, GPR_IRQ, C_80000000, C_00000000, C_00000000);
1989 OP(icode, &ptr, iANDXOR, GPR(ipcm->gpr_running), GPR(ipcm->gpr_running), C_00000001, C_00010000);
1990
1991 OP(icode, &ptr, iANDXOR, GPR(ipcm->gpr_running), GPR(ipcm->gpr_running), C_00010000, C_00000001);
1992 OP(icode, &ptr, iSKIP, C_00000000, C_7fffffff, C_7fffffff, C_00000002);
1993
1994 OP(icode, &ptr, iMACINT1, ETRAM_ADDR(ipcm->etram[0]), GPR(gpr + 8), GPR_DBAC, C_ffffffff);
1995 OP(icode, &ptr, iMACINT1, ETRAM_ADDR(ipcm->etram[1]), GPR(gpr + 9), GPR_DBAC, C_ffffffff);
1996
1997
1998 gpr += 13;
1999
2000
2001 for (z = 0; z < 2; z++)
2002 VOLUME(icode, &ptr, playback + z, z, gpr + z);
2003 snd_emu10k1_init_stereo_control(controls + i++, "Wave Playback Volume", gpr, 100);
2004 gpr += 2;
2005
2006
2007 for (z = 0; z < 2; z++)
2008 VOLUME(icode, &ptr, playback + 2 + z, z, gpr + z);
2009 snd_emu10k1_init_stereo_control(controls + i++, "Wave Surround Playback Volume", gpr, 0);
2010 gpr += 2;
2011
2012
2013 OP(icode, &ptr, iACC3, GPR(tmp + 0), FXBUS(FXBUS_PCM_LEFT), FXBUS(FXBUS_PCM_RIGHT), C_00000000);
2014 OP(icode, &ptr, iMACINT0, GPR(tmp + 0), C_00000000, GPR(tmp + 0), C_00000002);
2015 VOLUME(icode, &ptr, playback + 4, tmp + 0, gpr);
2016 snd_emu10k1_init_mono_control(controls + i++, "Wave Center Playback Volume", gpr++, 0);
2017 VOLUME(icode, &ptr, playback + 5, tmp + 0, gpr);
2018 snd_emu10k1_init_mono_control(controls + i++, "Wave LFE Playback Volume", gpr++, 0);
2019
2020
2021 for (z = 0; z < 2; z++) {
2022 SWITCH(icode, &ptr, tmp + 0, z, gpr + 2 + z);
2023 VOLUME(icode, &ptr, capture + z, tmp + 0, gpr + z);
2024 }
2025 snd_emu10k1_init_stereo_control(controls + i++, "Wave Capture Volume", gpr, 0);
2026 snd_emu10k1_init_stereo_onoff_control(controls + i++, "Wave Capture Switch", gpr + 2, 0);
2027 gpr += 4;
2028
2029
2030 for (z = 0; z < 2; z++)
2031 VOLUME_ADD(icode, &ptr, playback + z, 2 + z, gpr + z);
2032 snd_emu10k1_init_stereo_control(controls + i++, "Synth Playback Volume", gpr, 100);
2033 gpr += 2;
2034
2035
2036 for (z = 0; z < 2; z++) {
2037 SWITCH(icode, &ptr, tmp + 0, 2 + z, gpr + 2 + z);
2038 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
2039 }
2040 snd_emu10k1_init_stereo_control(controls + i++, "Synth Capture Volume", gpr, 0);
2041 snd_emu10k1_init_stereo_onoff_control(controls + i++, "Synth Capture Switch", gpr + 2, 0);
2042 gpr += 4;
2043
2044
2045 for (z = 0; z < 2; z++)
2046 VOLUME_ADD(icode, &ptr, playback + 2 + z, 4 + z, gpr + z);
2047 snd_emu10k1_init_stereo_control(controls + i++, "Surround Digital Playback Volume", gpr, 100);
2048 gpr += 2;
2049
2050
2051 for (z = 0; z < 2; z++) {
2052 SWITCH(icode, &ptr, tmp + 0, 4 + z, gpr + 2 + z);
2053 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
2054 }
2055 snd_emu10k1_init_stereo_control(controls + i++, "Surround Capture Volume", gpr, 0);
2056 snd_emu10k1_init_stereo_onoff_control(controls + i++, "Surround Capture Switch", gpr + 2, 0);
2057 gpr += 4;
2058
2059
2060 VOLUME_ADD(icode, &ptr, playback + 4, 6, gpr);
2061 snd_emu10k1_init_mono_control(controls + i++, "Center Digital Playback Volume", gpr++, 100);
2062
2063
2064 VOLUME_ADD(icode, &ptr, playback + 5, 7, gpr);
2065 snd_emu10k1_init_mono_control(controls + i++, "LFE Digital Playback Volume", gpr++, 100);
2066
2067
2068 for (z = 0; z < 2; z++)
2069 VOLUME_ADD(icode, &ptr, playback + z, 10 + z, gpr + z);
2070 snd_emu10k1_init_stereo_control(controls + i++, "Front Playback Volume", gpr, 100);
2071 gpr += 2;
2072
2073
2074 for (z = 0; z < 2; z++) {
2075 SWITCH(icode, &ptr, tmp + 0, 10 + z, gpr + 2);
2076 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
2077 }
2078 snd_emu10k1_init_stereo_control(controls + i++, "Front Capture Volume", gpr, 0);
2079 snd_emu10k1_init_mono_onoff_control(controls + i++, "Front Capture Switch", gpr + 2, 0);
2080 gpr += 3;
2081
2082
2083
2084
2085
2086 if (emu->fx8010.extin_mask & ((1<<EXTIN_AC97_L)|(1<<EXTIN_AC97_R))) {
2087
2088 VOLUME_ADDIN(icode, &ptr, playback + 0, EXTIN_AC97_L, gpr); gpr++;
2089 VOLUME_ADDIN(icode, &ptr, playback + 1, EXTIN_AC97_R, gpr); gpr++;
2090 snd_emu10k1_init_stereo_control(controls + i++, "AC97 Playback Volume", gpr-2, 0);
2091
2092 VOLUME_ADDIN(icode, &ptr, capture + 0, EXTIN_AC97_L, gpr); gpr++;
2093 VOLUME_ADDIN(icode, &ptr, capture + 1, EXTIN_AC97_R, gpr); gpr++;
2094 snd_emu10k1_init_stereo_control(controls + i++, "AC97 Capture Volume", gpr-2, 100);
2095 }
2096
2097 if (emu->fx8010.extin_mask & ((1<<EXTIN_SPDIF_CD_L)|(1<<EXTIN_SPDIF_CD_R))) {
2098
2099 for (z = 0; z < 2; z++)
2100 VOLUME_ADDIN(icode, &ptr, playback + z, EXTIN_SPDIF_CD_L + z, gpr + z);
2101 snd_emu10k1_init_stereo_control(controls + i++, SNDRV_CTL_NAME_IEC958("TTL ",PLAYBACK,VOLUME), gpr, 0);
2102 gpr += 2;
2103
2104
2105 for (z = 0; z < 2; z++) {
2106 SWITCH_IN(icode, &ptr, tmp + 0, EXTIN_SPDIF_CD_L + z, gpr + 2 + z);
2107 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
2108 }
2109 snd_emu10k1_init_stereo_control(controls + i++, SNDRV_CTL_NAME_IEC958("TTL ",CAPTURE,VOLUME), gpr, 0);
2110 snd_emu10k1_init_stereo_onoff_control(controls + i++, SNDRV_CTL_NAME_IEC958("TTL ",CAPTURE,SWITCH), gpr + 2, 0);
2111 gpr += 4;
2112 }
2113
2114 if (emu->fx8010.extin_mask & ((1<<EXTIN_ZOOM_L)|(1<<EXTIN_ZOOM_R))) {
2115
2116 for (z = 0; z < 2; z++)
2117 VOLUME_ADDIN(icode, &ptr, playback + z, EXTIN_ZOOM_L + z, gpr + z);
2118 snd_emu10k1_init_stereo_control(controls + i++, "Zoom Video Playback Volume", gpr, 0);
2119 gpr += 2;
2120
2121
2122 for (z = 0; z < 2; z++) {
2123 SWITCH_IN(icode, &ptr, tmp + 0, EXTIN_ZOOM_L + z, gpr + 2 + z);
2124 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
2125 }
2126 snd_emu10k1_init_stereo_control(controls + i++, "Zoom Video Capture Volume", gpr, 0);
2127 snd_emu10k1_init_stereo_onoff_control(controls + i++, "Zoom Video Capture Switch", gpr + 2, 0);
2128 gpr += 4;
2129 }
2130
2131 if (emu->fx8010.extin_mask & ((1<<EXTIN_TOSLINK_L)|(1<<EXTIN_TOSLINK_R))) {
2132
2133 for (z = 0; z < 2; z++)
2134 VOLUME_ADDIN(icode, &ptr, playback + z, EXTIN_TOSLINK_L + z, gpr + z);
2135 snd_emu10k1_init_stereo_control(controls + i++, SNDRV_CTL_NAME_IEC958("LiveDrive ",PLAYBACK,VOLUME), gpr, 0);
2136 gpr += 2;
2137
2138
2139 for (z = 0; z < 2; z++) {
2140 SWITCH_IN(icode, &ptr, tmp + 0, EXTIN_TOSLINK_L + z, gpr + 2 + z);
2141 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
2142 }
2143 snd_emu10k1_init_stereo_control(controls + i++, SNDRV_CTL_NAME_IEC958("LiveDrive ",CAPTURE,VOLUME), gpr, 0);
2144 snd_emu10k1_init_stereo_onoff_control(controls + i++, SNDRV_CTL_NAME_IEC958("LiveDrive ",CAPTURE,SWITCH), gpr + 2, 0);
2145 gpr += 4;
2146 }
2147
2148 if (emu->fx8010.extin_mask & ((1<<EXTIN_LINE1_L)|(1<<EXTIN_LINE1_R))) {
2149
2150 for (z = 0; z < 2; z++)
2151 VOLUME_ADDIN(icode, &ptr, playback + z, EXTIN_LINE1_L + z, gpr + z);
2152 snd_emu10k1_init_stereo_control(controls + i++, "Line LiveDrive Playback Volume", gpr, 0);
2153 gpr += 2;
2154
2155
2156 for (z = 0; z < 2; z++) {
2157 SWITCH_IN(icode, &ptr, tmp + 0, EXTIN_LINE1_L + z, gpr + 2 + z);
2158 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
2159 }
2160 snd_emu10k1_init_stereo_control(controls + i++, "Line LiveDrive Capture Volume", gpr, 0);
2161 snd_emu10k1_init_stereo_onoff_control(controls + i++, "Line LiveDrive Capture Switch", gpr + 2, 0);
2162 gpr += 4;
2163 }
2164
2165 if (emu->fx8010.extin_mask & ((1<<EXTIN_COAX_SPDIF_L)|(1<<EXTIN_COAX_SPDIF_R))) {
2166
2167 for (z = 0; z < 2; z++)
2168 VOLUME_ADDIN(icode, &ptr, playback + z, EXTIN_COAX_SPDIF_L + z, gpr + z);
2169 snd_emu10k1_init_stereo_control(controls + i++, SNDRV_CTL_NAME_IEC958("Coaxial ",PLAYBACK,VOLUME), gpr, 0);
2170 gpr += 2;
2171
2172
2173 for (z = 0; z < 2; z++) {
2174 SWITCH_IN(icode, &ptr, tmp + 0, EXTIN_COAX_SPDIF_L + z, gpr + 2 + z);
2175 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
2176 }
2177 snd_emu10k1_init_stereo_control(controls + i++, SNDRV_CTL_NAME_IEC958("Coaxial ",CAPTURE,VOLUME), gpr, 0);
2178 snd_emu10k1_init_stereo_onoff_control(controls + i++, SNDRV_CTL_NAME_IEC958("Coaxial ",CAPTURE,SWITCH), gpr + 2, 0);
2179 gpr += 4;
2180 }
2181
2182 if (emu->fx8010.extin_mask & ((1<<EXTIN_LINE2_L)|(1<<EXTIN_LINE2_R))) {
2183
2184 for (z = 0; z < 2; z++)
2185 VOLUME_ADDIN(icode, &ptr, playback + z, EXTIN_LINE2_L + z, gpr + z);
2186 snd_emu10k1_init_stereo_control(controls + i++, "Line2 LiveDrive Playback Volume", gpr, 0);
2187 controls[i-1].id.index = 1;
2188 gpr += 2;
2189
2190
2191 for (z = 0; z < 2; z++) {
2192 SWITCH_IN(icode, &ptr, tmp + 0, EXTIN_LINE2_L + z, gpr + 2 + z);
2193 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
2194 }
2195 snd_emu10k1_init_stereo_control(controls + i++, "Line2 LiveDrive Capture Volume", gpr, 0);
2196 controls[i-1].id.index = 1;
2197 snd_emu10k1_init_stereo_onoff_control(controls + i++, "Line2 LiveDrive Capture Switch", gpr + 2, 0);
2198 controls[i-1].id.index = 1;
2199 gpr += 4;
2200 }
2201
2202
2203
2204
2205 OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 0), GPR(playback + 0), C_00000000, C_00000000);
2206 OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 1), GPR(playback + 1), C_00000000, C_00000000);
2207 OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 2), GPR(playback + 2), C_00000000, C_00000000);
2208 OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 3), GPR(playback + 3), C_00000000, C_00000000);
2209 OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 4), GPR(playback + 4), C_00000000, C_00000000);
2210 OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 5), GPR(playback + 5), C_00000000, C_00000000);
2211
2212 ctl = &controls[i + 0];
2213 ctl->id.iface = (__force int)SNDRV_CTL_ELEM_IFACE_MIXER;
2214 strcpy(ctl->id.name, "Tone Control - Bass");
2215 ctl->vcount = 2;
2216 ctl->count = 10;
2217 ctl->min = 0;
2218 ctl->max = 40;
2219 ctl->value[0] = ctl->value[1] = 20;
2220 ctl->tlv = snd_emu10k1_bass_treble_db_scale;
2221 ctl->translation = EMU10K1_GPR_TRANSLATION_BASS;
2222 ctl = &controls[i + 1];
2223 ctl->id.iface = (__force int)SNDRV_CTL_ELEM_IFACE_MIXER;
2224 strcpy(ctl->id.name, "Tone Control - Treble");
2225 ctl->vcount = 2;
2226 ctl->count = 10;
2227 ctl->min = 0;
2228 ctl->max = 40;
2229 ctl->value[0] = ctl->value[1] = 20;
2230 ctl->tlv = snd_emu10k1_bass_treble_db_scale;
2231 ctl->translation = EMU10K1_GPR_TRANSLATION_TREBLE;
2232
2233#define BASS_GPR 0x8c
2234#define TREBLE_GPR 0x96
2235
2236 for (z = 0; z < 5; z++) {
2237 int j;
2238 for (j = 0; j < 2; j++) {
2239 controls[i + 0].gpr[z * 2 + j] = BASS_GPR + z * 2 + j;
2240 controls[i + 1].gpr[z * 2 + j] = TREBLE_GPR + z * 2 + j;
2241 }
2242 }
2243 for (z = 0; z < 3; z++) {
2244 int j, k, l, d;
2245 for (j = 0; j < 2; j++) {
2246 k = 0xa0 + (z * 8) + (j * 4);
2247 l = 0xd0 + (z * 8) + (j * 4);
2248 d = playback + SND_EMU10K1_PLAYBACK_CHANNELS + z * 2 + j;
2249
2250 OP(icode, &ptr, iMAC0, C_00000000, C_00000000, GPR(d), GPR(BASS_GPR + 0 + j));
2251 OP(icode, &ptr, iMACMV, GPR(k+1), GPR(k), GPR(k+1), GPR(BASS_GPR + 4 + j));
2252 OP(icode, &ptr, iMACMV, GPR(k), GPR(d), GPR(k), GPR(BASS_GPR + 2 + j));
2253 OP(icode, &ptr, iMACMV, GPR(k+3), GPR(k+2), GPR(k+3), GPR(BASS_GPR + 8 + j));
2254 OP(icode, &ptr, iMAC0, GPR(k+2), GPR_ACCU, GPR(k+2), GPR(BASS_GPR + 6 + j));
2255 OP(icode, &ptr, iACC3, GPR(k+2), GPR(k+2), GPR(k+2), C_00000000);
2256
2257 OP(icode, &ptr, iMAC0, C_00000000, C_00000000, GPR(k+2), GPR(TREBLE_GPR + 0 + j));
2258 OP(icode, &ptr, iMACMV, GPR(l+1), GPR(l), GPR(l+1), GPR(TREBLE_GPR + 4 + j));
2259 OP(icode, &ptr, iMACMV, GPR(l), GPR(k+2), GPR(l), GPR(TREBLE_GPR + 2 + j));
2260 OP(icode, &ptr, iMACMV, GPR(l+3), GPR(l+2), GPR(l+3), GPR(TREBLE_GPR + 8 + j));
2261 OP(icode, &ptr, iMAC0, GPR(l+2), GPR_ACCU, GPR(l+2), GPR(TREBLE_GPR + 6 + j));
2262 OP(icode, &ptr, iMACINT0, GPR(l+2), C_00000000, GPR(l+2), C_00000010);
2263
2264 OP(icode, &ptr, iACC3, GPR(d), GPR(l+2), C_00000000, C_00000000);
2265
2266 if (z == 2)
2267 break;
2268 }
2269 }
2270 i += 2;
2271
2272#undef BASS_GPR
2273#undef TREBLE_GPR
2274
2275 for (z = 0; z < 6; z++) {
2276 SWITCH(icode, &ptr, tmp + 0, playback + SND_EMU10K1_PLAYBACK_CHANNELS + z, gpr + 0);
2277 SWITCH_NEG(icode, &ptr, tmp + 1, gpr + 0);
2278 SWITCH(icode, &ptr, tmp + 1, playback + z, tmp + 1);
2279 OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + z), GPR(tmp + 0), GPR(tmp + 1), C_00000000);
2280 }
2281 snd_emu10k1_init_stereo_onoff_control(controls + i++, "Tone Control - Switch", gpr, 0);
2282 gpr += 2;
2283
2284
2285
2286
2287 if (emu->fx8010.extout_mask & ((1<<EXTOUT_AC97_L)|(1<<EXTOUT_AC97_R))) {
2288
2289
2290 for (z = 0; z < 2; z++)
2291 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_AC97_L + z), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + z), C_00000000, C_00000000);
2292 }
2293
2294 if (emu->fx8010.extout_mask & ((1<<EXTOUT_TOSLINK_L)|(1<<EXTOUT_TOSLINK_R))) {
2295
2296
2297 for (z = 0; z < 2; z++) {
2298 SWITCH(icode, &ptr, tmp + 0, 8 + z, gpr + z);
2299 SWITCH_NEG(icode, &ptr, tmp + 1, gpr + z);
2300 SWITCH(icode, &ptr, tmp + 1, playback + SND_EMU10K1_PLAYBACK_CHANNELS + z, tmp + 1);
2301 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_TOSLINK_L + z), GPR(tmp + 0), GPR(tmp + 1), C_00000000);
2302#ifdef EMU10K1_CAPTURE_DIGITAL_OUT
2303 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_ADC_CAP_L + z), GPR(tmp + 0), GPR(tmp + 1), C_00000000);
2304#endif
2305 }
2306
2307 snd_emu10k1_init_stereo_onoff_control(controls + i++, SNDRV_CTL_NAME_IEC958("Optical Raw ",PLAYBACK,SWITCH), gpr, 0);
2308 gpr += 2;
2309 }
2310
2311 if (emu->fx8010.extout_mask & ((1<<EXTOUT_HEADPHONE_L)|(1<<EXTOUT_HEADPHONE_R))) {
2312
2313
2314 for (z = 0; z < 2; z++) {
2315 SWITCH(icode, &ptr, tmp + 0, playback + SND_EMU10K1_PLAYBACK_CHANNELS + 4 + z, gpr + 2 + z);
2316 SWITCH_NEG(icode, &ptr, tmp + 1, gpr + 2 + z);
2317 SWITCH(icode, &ptr, tmp + 1, playback + SND_EMU10K1_PLAYBACK_CHANNELS + z, tmp + 1);
2318 OP(icode, &ptr, iACC3, GPR(tmp + 0), GPR(tmp + 0), GPR(tmp + 1), C_00000000);
2319 VOLUME_OUT(icode, &ptr, EXTOUT_HEADPHONE_L + z, tmp + 0, gpr + z);
2320 }
2321
2322 snd_emu10k1_init_stereo_control(controls + i++, "Headphone Playback Volume", gpr + 0, 0);
2323 controls[i-1].id.index = 1;
2324 snd_emu10k1_init_mono_onoff_control(controls + i++, "Headphone Center Playback Switch", gpr + 2, 0);
2325 controls[i-1].id.index = 1;
2326 snd_emu10k1_init_mono_onoff_control(controls + i++, "Headphone LFE Playback Switch", gpr + 3, 0);
2327 controls[i-1].id.index = 1;
2328
2329 gpr += 4;
2330 }
2331
2332 if (emu->fx8010.extout_mask & ((1<<EXTOUT_REAR_L)|(1<<EXTOUT_REAR_R)))
2333 for (z = 0; z < 2; z++)
2334 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_REAR_L + z), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 2 + z), C_00000000, C_00000000);
2335
2336 if (emu->fx8010.extout_mask & ((1<<EXTOUT_AC97_REAR_L)|(1<<EXTOUT_AC97_REAR_R)))
2337 for (z = 0; z < 2; z++)
2338 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_AC97_REAR_L + z), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 2 + z), C_00000000, C_00000000);
2339
2340 if (emu->fx8010.extout_mask & (1<<EXTOUT_AC97_CENTER)) {
2341#ifndef EMU10K1_CENTER_LFE_FROM_FRONT
2342 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_AC97_CENTER), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 4), C_00000000, C_00000000);
2343 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_ACENTER), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 4), C_00000000, C_00000000);
2344#else
2345 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_AC97_CENTER), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 0), C_00000000, C_00000000);
2346 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_ACENTER), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 0), C_00000000, C_00000000);
2347#endif
2348 }
2349
2350 if (emu->fx8010.extout_mask & (1<<EXTOUT_AC97_LFE)) {
2351#ifndef EMU10K1_CENTER_LFE_FROM_FRONT
2352 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_AC97_LFE), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 5), C_00000000, C_00000000);
2353 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_ALFE), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 5), C_00000000, C_00000000);
2354#else
2355 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_AC97_LFE), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 1), C_00000000, C_00000000);
2356 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_ALFE), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 1), C_00000000, C_00000000);
2357#endif
2358 }
2359
2360#ifndef EMU10K1_CAPTURE_DIGITAL_OUT
2361 for (z = 0; z < 2; z++)
2362 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_ADC_CAP_L + z), GPR(capture + z), C_00000000, C_00000000);
2363#endif
2364
2365 if (emu->fx8010.extout_mask & (1<<EXTOUT_MIC_CAP))
2366 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_MIC_CAP), GPR(capture + 2), C_00000000, C_00000000);
2367
2368
2369 if (emu->card_capabilities->sblive51) {
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379 OP(icode, &ptr, iACC3, FXBUS2(14), C_00000000, C_00000000, EXTIN(0));
2380 OP(icode, &ptr, iACC3, FXBUS2(15), C_00000000, C_00000000, EXTIN(1));
2381 OP(icode, &ptr, iACC3, FXBUS2(0), C_00000000, C_00000000, EXTIN(2));
2382 OP(icode, &ptr, iACC3, FXBUS2(3), C_00000000, C_00000000, EXTIN(3));
2383 for (z = 4; z < 14; z++)
2384 OP(icode, &ptr, iACC3, FXBUS2(z), C_00000000, C_00000000, EXTIN(z));
2385 } else {
2386 for (z = 0; z < 16; z++)
2387 OP(icode, &ptr, iACC3, FXBUS2(z), C_00000000, C_00000000, EXTIN(z));
2388 }
2389
2390
2391 if (gpr > tmp) {
2392 snd_BUG();
2393 err = -EIO;
2394 goto __err;
2395 }
2396 if (i > SND_EMU10K1_GPR_CONTROLS) {
2397 snd_BUG();
2398 err = -EIO;
2399 goto __err;
2400 }
2401
2402
2403 while (ptr < 0x200)
2404 OP(icode, &ptr, iACC3, C_00000000, C_00000000, C_00000000, C_00000000);
2405
2406 if ((err = snd_emu10k1_fx8010_tram_setup(emu, ipcm->buffer_size)) < 0)
2407 goto __err;
2408 icode->gpr_add_control_count = i;
2409 icode->gpr_add_controls = controls;
2410 emu->support_tlv = 1;
2411 err = snd_emu10k1_icode_poke(emu, icode, true);
2412 emu->support_tlv = 0;
2413 if (err >= 0)
2414 err = snd_emu10k1_ipcm_poke(emu, ipcm);
2415__err:
2416 kfree(ipcm);
2417__err_ipcm:
2418 kfree(controls);
2419__err_ctrls:
2420 kfree(icode->gpr_map);
2421__err_gpr:
2422 kfree(icode);
2423 return err;
2424}
2425
2426int snd_emu10k1_init_efx(struct snd_emu10k1 *emu)
2427{
2428 spin_lock_init(&emu->fx8010.irq_lock);
2429 INIT_LIST_HEAD(&emu->fx8010.gpr_ctl);
2430 if (emu->audigy)
2431 return _snd_emu10k1_audigy_init_efx(emu);
2432 else
2433 return _snd_emu10k1_init_efx(emu);
2434}
2435
2436void snd_emu10k1_free_efx(struct snd_emu10k1 *emu)
2437{
2438
2439 if (emu->audigy)
2440 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg = A_DBG_SINGLE_STEP);
2441 else
2442 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg = EMU10K1_DBG_SINGLE_STEP);
2443}
2444
2445#if 0
2446int snd_emu10k1_fx8010_tone_control_activate(struct snd_emu10k1 *emu, int output)
2447{
2448 if (output < 0 || output >= 6)
2449 return -EINVAL;
2450 snd_emu10k1_ptr_write(emu, emu->gpr_base + 0x94 + output, 0, 1);
2451 return 0;
2452}
2453
2454int snd_emu10k1_fx8010_tone_control_deactivate(struct snd_emu10k1 *emu, int output)
2455{
2456 if (output < 0 || output >= 6)
2457 return -EINVAL;
2458 snd_emu10k1_ptr_write(emu, emu->gpr_base + 0x94 + output, 0, 0);
2459 return 0;
2460}
2461#endif
2462
2463int snd_emu10k1_fx8010_tram_setup(struct snd_emu10k1 *emu, u32 size)
2464{
2465 u8 size_reg = 0;
2466
2467
2468 if (size != 0) {
2469 size = (size - 1) >> 13;
2470
2471 while (size) {
2472 size >>= 1;
2473 size_reg++;
2474 }
2475 size = 0x2000 << size_reg;
2476 }
2477 if ((emu->fx8010.etram_pages.bytes / 2) == size)
2478 return 0;
2479 spin_lock_irq(&emu->emu_lock);
2480 outl(HCFG_LOCKTANKCACHE_MASK | inl(emu->port + HCFG), emu->port + HCFG);
2481 spin_unlock_irq(&emu->emu_lock);
2482 snd_emu10k1_ptr_write(emu, TCB, 0, 0);
2483 snd_emu10k1_ptr_write(emu, TCBS, 0, 0);
2484 if (emu->fx8010.etram_pages.area != NULL) {
2485 snd_dma_free_pages(&emu->fx8010.etram_pages);
2486 emu->fx8010.etram_pages.area = NULL;
2487 emu->fx8010.etram_pages.bytes = 0;
2488 }
2489
2490 if (size > 0) {
2491 if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, &emu->pci->dev,
2492 size * 2, &emu->fx8010.etram_pages) < 0)
2493 return -ENOMEM;
2494 memset(emu->fx8010.etram_pages.area, 0, size * 2);
2495 snd_emu10k1_ptr_write(emu, TCB, 0, emu->fx8010.etram_pages.addr);
2496 snd_emu10k1_ptr_write(emu, TCBS, 0, size_reg);
2497 spin_lock_irq(&emu->emu_lock);
2498 outl(inl(emu->port + HCFG) & ~HCFG_LOCKTANKCACHE_MASK, emu->port + HCFG);
2499 spin_unlock_irq(&emu->emu_lock);
2500 }
2501
2502 return 0;
2503}
2504
2505static int snd_emu10k1_fx8010_open(struct snd_hwdep * hw, struct file *file)
2506{
2507 return 0;
2508}
2509
2510static void copy_string(char *dst, const char *src, const char *null, int idx)
2511{
2512 if (src == NULL)
2513 sprintf(dst, "%s %02X", null, idx);
2514 else
2515 strcpy(dst, src);
2516}
2517
2518static void snd_emu10k1_fx8010_info(struct snd_emu10k1 *emu,
2519 struct snd_emu10k1_fx8010_info *info)
2520{
2521 const char * const *fxbus, * const *extin, * const *extout;
2522 unsigned short fxbus_mask, extin_mask, extout_mask;
2523 int res;
2524
2525 info->internal_tram_size = emu->fx8010.itram_size;
2526 info->external_tram_size = emu->fx8010.etram_pages.bytes / 2;
2527 fxbus = fxbuses;
2528 extin = emu->audigy ? audigy_ins : creative_ins;
2529 extout = emu->audigy ? audigy_outs : creative_outs;
2530 fxbus_mask = emu->fx8010.fxbus_mask;
2531 extin_mask = emu->fx8010.extin_mask;
2532 extout_mask = emu->fx8010.extout_mask;
2533 for (res = 0; res < 16; res++, fxbus++, extin++, extout++) {
2534 copy_string(info->fxbus_names[res], fxbus_mask & (1 << res) ? *fxbus : NULL, "FXBUS", res);
2535 copy_string(info->extin_names[res], extin_mask & (1 << res) ? *extin : NULL, "Unused", res);
2536 copy_string(info->extout_names[res], extout_mask & (1 << res) ? *extout : NULL, "Unused", res);
2537 }
2538 for (res = 16; res < 32; res++, extout++)
2539 copy_string(info->extout_names[res], extout_mask & (1 << res) ? *extout : NULL, "Unused", res);
2540 info->gpr_controls = emu->fx8010.gpr_count;
2541}
2542
2543static int snd_emu10k1_fx8010_ioctl(struct snd_hwdep * hw, struct file *file, unsigned int cmd, unsigned long arg)
2544{
2545 struct snd_emu10k1 *emu = hw->private_data;
2546 struct snd_emu10k1_fx8010_info *info;
2547 struct snd_emu10k1_fx8010_code *icode;
2548 struct snd_emu10k1_fx8010_pcm_rec *ipcm;
2549 unsigned int addr;
2550 void __user *argp = (void __user *)arg;
2551 int res;
2552
2553 switch (cmd) {
2554 case SNDRV_EMU10K1_IOCTL_PVERSION:
2555 emu->support_tlv = 1;
2556 return put_user(SNDRV_EMU10K1_VERSION, (int __user *)argp);
2557 case SNDRV_EMU10K1_IOCTL_INFO:
2558 info = kzalloc(sizeof(*info), GFP_KERNEL);
2559 if (!info)
2560 return -ENOMEM;
2561 snd_emu10k1_fx8010_info(emu, info);
2562 if (copy_to_user(argp, info, sizeof(*info))) {
2563 kfree(info);
2564 return -EFAULT;
2565 }
2566 kfree(info);
2567 return 0;
2568 case SNDRV_EMU10K1_IOCTL_CODE_POKE:
2569 if (!capable(CAP_SYS_ADMIN))
2570 return -EPERM;
2571
2572 icode = memdup_user(argp, sizeof(*icode));
2573 if (IS_ERR(icode))
2574 return PTR_ERR(icode);
2575 res = snd_emu10k1_icode_poke(emu, icode, false);
2576 kfree(icode);
2577 return res;
2578 case SNDRV_EMU10K1_IOCTL_CODE_PEEK:
2579 icode = memdup_user(argp, sizeof(*icode));
2580 if (IS_ERR(icode))
2581 return PTR_ERR(icode);
2582 res = snd_emu10k1_icode_peek(emu, icode);
2583 if (res == 0 && copy_to_user(argp, icode, sizeof(*icode))) {
2584 kfree(icode);
2585 return -EFAULT;
2586 }
2587 kfree(icode);
2588 return res;
2589 case SNDRV_EMU10K1_IOCTL_PCM_POKE:
2590 ipcm = memdup_user(argp, sizeof(*ipcm));
2591 if (IS_ERR(ipcm))
2592 return PTR_ERR(ipcm);
2593 res = snd_emu10k1_ipcm_poke(emu, ipcm);
2594 kfree(ipcm);
2595 return res;
2596 case SNDRV_EMU10K1_IOCTL_PCM_PEEK:
2597 ipcm = memdup_user(argp, sizeof(*ipcm));
2598 if (IS_ERR(ipcm))
2599 return PTR_ERR(ipcm);
2600 res = snd_emu10k1_ipcm_peek(emu, ipcm);
2601 if (res == 0 && copy_to_user(argp, ipcm, sizeof(*ipcm))) {
2602 kfree(ipcm);
2603 return -EFAULT;
2604 }
2605 kfree(ipcm);
2606 return res;
2607 case SNDRV_EMU10K1_IOCTL_TRAM_SETUP:
2608 if (!capable(CAP_SYS_ADMIN))
2609 return -EPERM;
2610 if (get_user(addr, (unsigned int __user *)argp))
2611 return -EFAULT;
2612 mutex_lock(&emu->fx8010.lock);
2613 res = snd_emu10k1_fx8010_tram_setup(emu, addr);
2614 mutex_unlock(&emu->fx8010.lock);
2615 return res;
2616 case SNDRV_EMU10K1_IOCTL_STOP:
2617 if (!capable(CAP_SYS_ADMIN))
2618 return -EPERM;
2619 if (emu->audigy)
2620 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg |= A_DBG_SINGLE_STEP);
2621 else
2622 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg |= EMU10K1_DBG_SINGLE_STEP);
2623 return 0;
2624 case SNDRV_EMU10K1_IOCTL_CONTINUE:
2625 if (!capable(CAP_SYS_ADMIN))
2626 return -EPERM;
2627 if (emu->audigy)
2628 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg = 0);
2629 else
2630 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg = 0);
2631 return 0;
2632 case SNDRV_EMU10K1_IOCTL_ZERO_TRAM_COUNTER:
2633 if (!capable(CAP_SYS_ADMIN))
2634 return -EPERM;
2635 if (emu->audigy)
2636 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg | A_DBG_ZC);
2637 else
2638 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg | EMU10K1_DBG_ZC);
2639 udelay(10);
2640 if (emu->audigy)
2641 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg);
2642 else
2643 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg);
2644 return 0;
2645 case SNDRV_EMU10K1_IOCTL_SINGLE_STEP:
2646 if (!capable(CAP_SYS_ADMIN))
2647 return -EPERM;
2648 if (get_user(addr, (unsigned int __user *)argp))
2649 return -EFAULT;
2650 if (addr > 0x1ff)
2651 return -EINVAL;
2652 if (emu->audigy)
2653 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg |= A_DBG_SINGLE_STEP | addr);
2654 else
2655 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg |= EMU10K1_DBG_SINGLE_STEP | addr);
2656 udelay(10);
2657 if (emu->audigy)
2658 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg |= A_DBG_SINGLE_STEP | A_DBG_STEP_ADDR | addr);
2659 else
2660 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg |= EMU10K1_DBG_SINGLE_STEP | EMU10K1_DBG_STEP | addr);
2661 return 0;
2662 case SNDRV_EMU10K1_IOCTL_DBG_READ:
2663 if (emu->audigy)
2664 addr = snd_emu10k1_ptr_read(emu, A_DBG, 0);
2665 else
2666 addr = snd_emu10k1_ptr_read(emu, DBG, 0);
2667 if (put_user(addr, (unsigned int __user *)argp))
2668 return -EFAULT;
2669 return 0;
2670 }
2671 return -ENOTTY;
2672}
2673
2674static int snd_emu10k1_fx8010_release(struct snd_hwdep * hw, struct file *file)
2675{
2676 return 0;
2677}
2678
2679int snd_emu10k1_fx8010_new(struct snd_emu10k1 *emu, int device)
2680{
2681 struct snd_hwdep *hw;
2682 int err;
2683
2684 if ((err = snd_hwdep_new(emu->card, "FX8010", device, &hw)) < 0)
2685 return err;
2686 strcpy(hw->name, "EMU10K1 (FX8010)");
2687 hw->iface = SNDRV_HWDEP_IFACE_EMU10K1;
2688 hw->ops.open = snd_emu10k1_fx8010_open;
2689 hw->ops.ioctl = snd_emu10k1_fx8010_ioctl;
2690 hw->ops.release = snd_emu10k1_fx8010_release;
2691 hw->private_data = emu;
2692 return 0;
2693}
2694
2695#ifdef CONFIG_PM_SLEEP
2696int snd_emu10k1_efx_alloc_pm_buffer(struct snd_emu10k1 *emu)
2697{
2698 int len;
2699
2700 len = emu->audigy ? 0x200 : 0x100;
2701 emu->saved_gpr = kmalloc_array(len, 4, GFP_KERNEL);
2702 if (! emu->saved_gpr)
2703 return -ENOMEM;
2704 len = emu->audigy ? 0x100 : 0xa0;
2705 emu->tram_val_saved = kmalloc_array(len, 4, GFP_KERNEL);
2706 emu->tram_addr_saved = kmalloc_array(len, 4, GFP_KERNEL);
2707 if (! emu->tram_val_saved || ! emu->tram_addr_saved)
2708 return -ENOMEM;
2709 len = emu->audigy ? 2 * 1024 : 2 * 512;
2710 emu->saved_icode = vmalloc(array_size(len, 4));
2711 if (! emu->saved_icode)
2712 return -ENOMEM;
2713 return 0;
2714}
2715
2716void snd_emu10k1_efx_free_pm_buffer(struct snd_emu10k1 *emu)
2717{
2718 kfree(emu->saved_gpr);
2719 kfree(emu->tram_val_saved);
2720 kfree(emu->tram_addr_saved);
2721 vfree(emu->saved_icode);
2722}
2723
2724
2725
2726
2727void snd_emu10k1_efx_suspend(struct snd_emu10k1 *emu)
2728{
2729 int i, len;
2730
2731 len = emu->audigy ? 0x200 : 0x100;
2732 for (i = 0; i < len; i++)
2733 emu->saved_gpr[i] = snd_emu10k1_ptr_read(emu, emu->gpr_base + i, 0);
2734
2735 len = emu->audigy ? 0x100 : 0xa0;
2736 for (i = 0; i < len; i++) {
2737 emu->tram_val_saved[i] = snd_emu10k1_ptr_read(emu, TANKMEMDATAREGBASE + i, 0);
2738 emu->tram_addr_saved[i] = snd_emu10k1_ptr_read(emu, TANKMEMADDRREGBASE + i, 0);
2739 if (emu->audigy) {
2740 emu->tram_addr_saved[i] >>= 12;
2741 emu->tram_addr_saved[i] |=
2742 snd_emu10k1_ptr_read(emu, A_TANKMEMCTLREGBASE + i, 0) << 20;
2743 }
2744 }
2745
2746 len = emu->audigy ? 2 * 1024 : 2 * 512;
2747 for (i = 0; i < len; i++)
2748 emu->saved_icode[i] = snd_emu10k1_efx_read(emu, i);
2749}
2750
2751void snd_emu10k1_efx_resume(struct snd_emu10k1 *emu)
2752{
2753 int i, len;
2754
2755
2756 if (emu->fx8010.etram_pages.bytes > 0) {
2757 unsigned size, size_reg = 0;
2758 size = emu->fx8010.etram_pages.bytes / 2;
2759 size = (size - 1) >> 13;
2760 while (size) {
2761 size >>= 1;
2762 size_reg++;
2763 }
2764 outl(HCFG_LOCKTANKCACHE_MASK | inl(emu->port + HCFG), emu->port + HCFG);
2765 snd_emu10k1_ptr_write(emu, TCB, 0, emu->fx8010.etram_pages.addr);
2766 snd_emu10k1_ptr_write(emu, TCBS, 0, size_reg);
2767 outl(inl(emu->port + HCFG) & ~HCFG_LOCKTANKCACHE_MASK, emu->port + HCFG);
2768 }
2769
2770 if (emu->audigy)
2771 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg | A_DBG_SINGLE_STEP);
2772 else
2773 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg | EMU10K1_DBG_SINGLE_STEP);
2774
2775 len = emu->audigy ? 0x200 : 0x100;
2776 for (i = 0; i < len; i++)
2777 snd_emu10k1_ptr_write(emu, emu->gpr_base + i, 0, emu->saved_gpr[i]);
2778
2779 len = emu->audigy ? 0x100 : 0xa0;
2780 for (i = 0; i < len; i++) {
2781 snd_emu10k1_ptr_write(emu, TANKMEMDATAREGBASE + i, 0,
2782 emu->tram_val_saved[i]);
2783 if (! emu->audigy)
2784 snd_emu10k1_ptr_write(emu, TANKMEMADDRREGBASE + i, 0,
2785 emu->tram_addr_saved[i]);
2786 else {
2787 snd_emu10k1_ptr_write(emu, TANKMEMADDRREGBASE + i, 0,
2788 emu->tram_addr_saved[i] << 12);
2789 snd_emu10k1_ptr_write(emu, TANKMEMADDRREGBASE + i, 0,
2790 emu->tram_addr_saved[i] >> 20);
2791 }
2792 }
2793
2794 len = emu->audigy ? 2 * 1024 : 2 * 512;
2795 for (i = 0; i < len; i++)
2796 snd_emu10k1_efx_write(emu, i, emu->saved_icode[i]);
2797
2798
2799 if (emu->audigy)
2800 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg);
2801 else
2802 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg);
2803}
2804#endif
2805