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