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