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