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