1 /* 2 * Copyright (c) by Jaroslav Kysela <perex@suse.cz> 3 * Creative Labs, Inc. 4 * Routines for control of EMU10K1 chips / PCM routines 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/delay.h> 30 #include <linux/slab.h> 31 #include <linux/time.h> 32 #include <linux/init.h> 33 #include <sound/core.h> 34 #include <sound/emu10k1.h> 35 36 #define chip_t emu10k1_t 37 38 static void snd_emu10k1_pcm_interrupt(emu10k1_t *emu, emu10k1_voice_t *voice) 39 { 40 emu10k1_pcm_t *epcm; 41 42 if ((epcm = voice->epcm) == NULL) 43 return; 44 if (epcm->substream == NULL) 45 return; 46 #if 0 47 printk("IRQ: position = 0x%x, period = 0x%x, size = 0x%x\n", 48 epcm->substream->runtime->hw->pointer(emu, epcm->substream), 49 snd_pcm_lib_period_bytes(epcm->substream), 50 snd_pcm_lib_buffer_bytes(epcm->substream)); 51 #endif 52 snd_pcm_period_elapsed(epcm->substream); 53 } 54 55 static void snd_emu10k1_pcm_ac97adc_interrupt(emu10k1_t *emu, unsigned int status) 56 { 57 #if 0 58 if (status & IPR_ADCBUFHALFFULL) { 59 if (emu->pcm_capture_substream->runtime->mode == SNDRV_PCM_MODE_FRAME) 60 return; 61 } 62 #endif 63 snd_pcm_period_elapsed(emu->pcm_capture_substream); 64 } 65 66 static void snd_emu10k1_pcm_ac97mic_interrupt(emu10k1_t *emu, unsigned int status) 67 { 68 #if 0 69 if (status & IPR_MICBUFHALFFULL) { 70 if (emu->pcm_capture_mic_substream->runtime->mode == SNDRV_PCM_MODE_FRAME) 71 return; 72 } 73 #endif 74 snd_pcm_period_elapsed(emu->pcm_capture_mic_substream); 75 } 76 77 static void snd_emu10k1_pcm_efx_interrupt(emu10k1_t *emu, unsigned int status) 78 { 79 #if 0 80 if (status & IPR_EFXBUFHALFFULL) { 81 if (emu->pcm_capture_efx_substream->runtime->mode == SNDRV_PCM_MODE_FRAME) 82 return; 83 } 84 #endif 85 snd_pcm_period_elapsed(emu->pcm_capture_efx_substream); 86 } 87 88 static int snd_emu10k1_pcm_channel_alloc(emu10k1_pcm_t * epcm, int voices) 89 { 90 int err; 91 92 if (epcm->voices[1] != NULL && voices < 2) { 93 snd_emu10k1_voice_free(epcm->emu, epcm->voices[1]); 94 epcm->voices[1] = NULL; 95 } 96 if (voices == 1 && epcm->voices[0] != NULL) 97 return 0; /* already allocated */ 98 if (voices == 2 && epcm->voices[0] != NULL && epcm->voices[1] != NULL) 99 return 0; 100 if (voices > 1) { 101 if (epcm->voices[0] != NULL && epcm->voices[1] == NULL) { 102 snd_emu10k1_voice_free(epcm->emu, epcm->voices[0]); 103 epcm->voices[0] = NULL; 104 } 105 } 106 err = snd_emu10k1_voice_alloc(epcm->emu, EMU10K1_PCM, voices > 1, &epcm->voices[0]); 107 if (err < 0) 108 return err; 109 epcm->voices[0]->epcm = epcm; 110 if (voices > 1) { 111 epcm->voices[1] = &epcm->emu->voices[epcm->voices[0]->number + 1]; 112 epcm->voices[1]->epcm = epcm; 113 } 114 if (epcm->extra == NULL) { 115 err = snd_emu10k1_voice_alloc(epcm->emu, EMU10K1_PCM, 0, &epcm->extra); 116 if (err < 0) { 117 // printk("pcm_channel_alloc: failed extra: voices=%d, frame=%d\n", voices, frame); 118 snd_emu10k1_voice_free(epcm->emu, epcm->voices[0]); 119 epcm->voices[0] = NULL; 120 if (epcm->voices[1]) 121 snd_emu10k1_voice_free(epcm->emu, epcm->voices[1]); 122 epcm->voices[1] = NULL; 123 return err; 124 } 125 epcm->extra->epcm = epcm; 126 epcm->extra->interrupt = snd_emu10k1_pcm_interrupt; 127 } 128 return 0; 129 } 130 131 static unsigned int capture_period_sizes[31] = { 132 384, 448, 512, 640, 133 384*2, 448*2, 512*2, 640*2, 134 384*4, 448*4, 512*4, 640*4, 135 384*8, 448*8, 512*8, 640*8, 136 384*16, 448*16, 512*16, 640*16, 137 384*32, 448*32, 512*32, 640*32, 138 384*64, 448*64, 512*64, 640*64, 139 384*128,448*128,512*128 140 }; 141 142 static snd_pcm_hw_constraint_list_t hw_constraints_capture_period_sizes = { 143 .count = 31, 144 .list = capture_period_sizes, 145 .mask = 0 146 }; 147 148 static unsigned int capture_rates[8] = { 149 8000, 11025, 16000, 22050, 24000, 32000, 44100, 48000 150 }; 151 152 static snd_pcm_hw_constraint_list_t hw_constraints_capture_rates = { 153 .count = 8, 154 .list = capture_rates, 155 .mask = 0 156 }; 157 158 static unsigned int snd_emu10k1_capture_rate_reg(unsigned int rate) 159 { 160 switch (rate) { 161 case 8000: return ADCCR_SAMPLERATE_8; 162 case 11025: return ADCCR_SAMPLERATE_11; 163 case 16000: return ADCCR_SAMPLERATE_16; 164 case 22050: return ADCCR_SAMPLERATE_22; 165 case 24000: return ADCCR_SAMPLERATE_24; 166 case 32000: return ADCCR_SAMPLERATE_32; 167 case 44100: return ADCCR_SAMPLERATE_44; 168 case 48000: return ADCCR_SAMPLERATE_48; 169 default: 170 snd_BUG(); 171 return ADCCR_SAMPLERATE_8; 172 } 173 } 174 175 static unsigned int snd_emu10k1_audigy_capture_rate_reg(unsigned int rate) 176 { 177 switch (rate) { 178 case 8000: return A_ADCCR_SAMPLERATE_8; 179 case 11025: return A_ADCCR_SAMPLERATE_11; 180 case 12000: return A_ADCCR_SAMPLERATE_12; /* really supported? */ 181 case 16000: return ADCCR_SAMPLERATE_16; 182 case 22050: return ADCCR_SAMPLERATE_22; 183 case 24000: return ADCCR_SAMPLERATE_24; 184 case 32000: return ADCCR_SAMPLERATE_32; 185 case 44100: return ADCCR_SAMPLERATE_44; 186 case 48000: return ADCCR_SAMPLERATE_48; 187 default: 188 snd_BUG(); 189 return A_ADCCR_SAMPLERATE_8; 190 } 191 } 192 193 static unsigned int emu10k1_calc_pitch_target(unsigned int rate) 194 { 195 unsigned int pitch_target; 196 197 pitch_target = (rate << 8) / 375; 198 pitch_target = (pitch_target >> 1) + (pitch_target & 1); 199 return pitch_target; 200 } 201 202 #define PITCH_48000 0x00004000 203 #define PITCH_96000 0x00008000 204 #define PITCH_85000 0x00007155 205 #define PITCH_80726 0x00006ba2 206 #define PITCH_67882 0x00005a82 207 #define PITCH_57081 0x00004c1c 208 209 static unsigned int emu10k1_select_interprom(unsigned int pitch_target) 210 { 211 if (pitch_target == PITCH_48000) 212 return CCCA_INTERPROM_0; 213 else if (pitch_target < PITCH_48000) 214 return CCCA_INTERPROM_1; 215 else if (pitch_target >= PITCH_96000) 216 return CCCA_INTERPROM_0; 217 else if (pitch_target >= PITCH_85000) 218 return CCCA_INTERPROM_6; 219 else if (pitch_target >= PITCH_80726) 220 return CCCA_INTERPROM_5; 221 else if (pitch_target >= PITCH_67882) 222 return CCCA_INTERPROM_4; 223 else if (pitch_target >= PITCH_57081) 224 return CCCA_INTERPROM_3; 225 else 226 return CCCA_INTERPROM_2; 227 } 228 229 230 static void snd_emu10k1_pcm_init_voice(emu10k1_t *emu, 231 int master, int extra, 232 emu10k1_voice_t *evoice, 233 unsigned int start_addr, 234 unsigned int end_addr) 235 { 236 snd_pcm_substream_t *substream = evoice->epcm->substream; 237 snd_pcm_runtime_t *runtime = substream->runtime; 238 emu10k1_pcm_mixer_t *mix = &emu->pcm_mixer[substream->number]; 239 unsigned int silent_page, tmp; 240 int voice, stereo, w_16; 241 unsigned char attn, send_amount[8]; 242 unsigned char send_routing[8]; 243 unsigned long flags; 244 unsigned int pitch_target; 245 246 voice = evoice->number; 247 stereo = runtime->channels == 2; 248 w_16 = snd_pcm_format_width(runtime->format) == 16; 249 250 if (!extra && stereo) { 251 start_addr >>= 1; 252 end_addr >>= 1; 253 } 254 if (w_16) { 255 start_addr >>= 1; 256 end_addr >>= 1; 257 } 258 259 spin_lock_irqsave(&emu->reg_lock, flags); 260 261 /* volume parameters */ 262 if (extra) { 263 attn = 0; 264 memset(send_routing, 0, sizeof(send_routing)); 265 send_routing[0] = 0; 266 send_routing[1] = 1; 267 send_routing[2] = 2; 268 send_routing[3] = 3; 269 memset(send_amount, 0, sizeof(send_amount)); 270 } else { 271 tmp = stereo ? (master ? 1 : 2) : 0; 272 memcpy(send_routing, &mix->send_routing[tmp][0], 8); 273 memcpy(send_amount, &mix->send_volume[tmp][0], 8); 274 } 275 276 if (master) { 277 unsigned int ccis = stereo ? 28 : 30; 278 if (w_16) 279 ccis *= 2; 280 evoice->epcm->ccca_start_addr = start_addr + ccis; 281 if (extra) { 282 start_addr += ccis; 283 end_addr += ccis; 284 } 285 if (stereo && !extra) { 286 snd_emu10k1_ptr_write(emu, CPF, voice, CPF_STEREO_MASK); 287 snd_emu10k1_ptr_write(emu, CPF, (voice + 1), CPF_STEREO_MASK); 288 } else { 289 snd_emu10k1_ptr_write(emu, CPF, voice, 0); 290 } 291 } 292 293 // setup routing 294 if (emu->audigy) { 295 snd_emu10k1_ptr_write(emu, A_FXRT1, voice, 296 ((unsigned int)send_routing[3] << 24) | 297 ((unsigned int)send_routing[2] << 16) | 298 ((unsigned int)send_routing[1] << 8) | 299 (unsigned int)send_routing[0]); 300 snd_emu10k1_ptr_write(emu, A_FXRT2, voice, 301 ((unsigned int)send_routing[7] << 24) | 302 ((unsigned int)send_routing[6] << 16) | 303 ((unsigned int)send_routing[5] << 8) | 304 (unsigned int)send_routing[4]); 305 snd_emu10k1_ptr_write(emu, A_SENDAMOUNTS, voice, 306 ((unsigned int)send_amount[4] << 24) | 307 ((unsigned int)send_amount[5] << 16) | 308 ((unsigned int)send_amount[6] << 8) | 309 (unsigned int)send_amount[7]); 310 } else 311 snd_emu10k1_ptr_write(emu, FXRT, voice, 312 snd_emu10k1_compose_send_routing(send_routing)); 313 // Stop CA 314 // Assumption that PT is already 0 so no harm overwriting 315 snd_emu10k1_ptr_write(emu, PTRX, voice, (send_amount[0] << 8) | send_amount[1]); 316 snd_emu10k1_ptr_write(emu, DSL, voice, end_addr | (send_amount[3] << 24)); 317 snd_emu10k1_ptr_write(emu, PSST, voice, start_addr | (send_amount[2] << 24)); 318 pitch_target = emu10k1_calc_pitch_target(runtime->rate); 319 snd_emu10k1_ptr_write(emu, CCCA, voice, evoice->epcm->ccca_start_addr | 320 emu10k1_select_interprom(pitch_target) | 321 (w_16 ? 0 : CCCA_8BITSELECT)); 322 // Clear filter delay memory 323 snd_emu10k1_ptr_write(emu, Z1, voice, 0); 324 snd_emu10k1_ptr_write(emu, Z2, voice, 0); 325 // invalidate maps 326 silent_page = ((unsigned int)emu->silent_page_dmaaddr << 1) | MAP_PTI_MASK; 327 snd_emu10k1_ptr_write(emu, MAPA, voice, silent_page); 328 snd_emu10k1_ptr_write(emu, MAPB, voice, silent_page); 329 // modulation envelope 330 snd_emu10k1_ptr_write(emu, CVCF, voice, 0xffff); 331 snd_emu10k1_ptr_write(emu, VTFT, voice, 0xffff); 332 snd_emu10k1_ptr_write(emu, ATKHLDM, voice, 0); 333 snd_emu10k1_ptr_write(emu, DCYSUSM, voice, 0x007f); 334 snd_emu10k1_ptr_write(emu, LFOVAL1, voice, 0x8000); 335 snd_emu10k1_ptr_write(emu, LFOVAL2, voice, 0x8000); 336 snd_emu10k1_ptr_write(emu, FMMOD, voice, 0); 337 snd_emu10k1_ptr_write(emu, TREMFRQ, voice, 0); 338 snd_emu10k1_ptr_write(emu, FM2FRQ2, voice, 0); 339 snd_emu10k1_ptr_write(emu, ENVVAL, voice, 0x8000); 340 // volume envelope 341 snd_emu10k1_ptr_write(emu, ATKHLDV, voice, 0x7f7f); 342 snd_emu10k1_ptr_write(emu, ENVVOL, voice, 0x0000); 343 // filter envelope 344 snd_emu10k1_ptr_write(emu, PEFE_FILTERAMOUNT, voice, 0x7f); 345 // pitch envelope 346 snd_emu10k1_ptr_write(emu, PEFE_PITCHAMOUNT, voice, 0); 347 348 spin_unlock_irqrestore(&emu->reg_lock, flags); 349 } 350 351 static int snd_emu10k1_playback_hw_params(snd_pcm_substream_t * substream, 352 snd_pcm_hw_params_t * hw_params) 353 { 354 emu10k1_t *emu = snd_pcm_substream_chip(substream); 355 snd_pcm_runtime_t *runtime = substream->runtime; 356 emu10k1_pcm_t *epcm = snd_magic_cast(emu10k1_pcm_t, runtime->private_data, return -ENXIO); 357 int err; 358 359 if ((err = snd_emu10k1_pcm_channel_alloc(epcm, params_channels(hw_params))) < 0) 360 return err; 361 if ((err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params))) < 0) 362 return err; 363 if (err > 0) { /* change */ 364 snd_util_memblk_t *memblk; 365 if (epcm->memblk != NULL) 366 snd_emu10k1_free_pages(emu, epcm->memblk); 367 memblk = snd_emu10k1_alloc_pages(emu, substream); 368 if ((epcm->memblk = memblk) == NULL || ((emu10k1_memblk_t *)memblk)->mapped_page < 0) { 369 epcm->start_addr = 0; 370 return -ENOMEM; 371 } 372 epcm->start_addr = ((emu10k1_memblk_t *)memblk)->mapped_page << PAGE_SHIFT; 373 } 374 return 0; 375 } 376 377 static int snd_emu10k1_playback_hw_free(snd_pcm_substream_t * substream) 378 { 379 emu10k1_t *emu = snd_pcm_substream_chip(substream); 380 snd_pcm_runtime_t *runtime = substream->runtime; 381 emu10k1_pcm_t *epcm; 382 383 if (runtime->private_data == NULL) 384 return 0; 385 epcm = snd_magic_cast(emu10k1_pcm_t, runtime->private_data, return -ENXIO); 386 if (epcm->extra) { 387 snd_emu10k1_voice_free(epcm->emu, epcm->extra); 388 epcm->extra = NULL; 389 } 390 if (epcm->voices[1]) { 391 snd_emu10k1_voice_free(epcm->emu, epcm->voices[1]); 392 epcm->voices[1] = NULL; 393 } 394 if (epcm->voices[0]) { 395 snd_emu10k1_voice_free(epcm->emu, epcm->voices[0]); 396 epcm->voices[0] = NULL; 397 } 398 if (epcm->memblk) { 399 snd_emu10k1_free_pages(emu, epcm->memblk); 400 epcm->memblk = NULL; 401 epcm->start_addr = 0; 402 } 403 snd_pcm_lib_free_pages(substream); 404 return 0; 405 } 406 407 static int snd_emu10k1_playback_prepare(snd_pcm_substream_t * substream) 408 { 409 emu10k1_t *emu = snd_pcm_substream_chip(substream); 410 snd_pcm_runtime_t *runtime = substream->runtime; 411 emu10k1_pcm_t *epcm = snd_magic_cast(emu10k1_pcm_t, runtime->private_data, return -ENXIO); 412 unsigned int start_addr, end_addr; 413 414 start_addr = epcm->start_addr; 415 end_addr = snd_pcm_lib_period_bytes(substream); 416 if (runtime->channels == 2) 417 end_addr >>= 1; 418 end_addr += start_addr; 419 snd_emu10k1_pcm_init_voice(emu, 1, 1, epcm->extra, 420 start_addr, end_addr); 421 end_addr = epcm->start_addr + snd_pcm_lib_buffer_bytes(substream); 422 snd_emu10k1_pcm_init_voice(emu, 1, 0, epcm->voices[0], 423 start_addr, end_addr); 424 if (epcm->voices[1]) 425 snd_emu10k1_pcm_init_voice(emu, 0, 0, epcm->voices[1], 426 start_addr, end_addr); 427 return 0; 428 } 429 430 static int snd_emu10k1_capture_hw_params(snd_pcm_substream_t * substream, 431 snd_pcm_hw_params_t * hw_params) 432 { 433 return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params)); 434 } 435 436 static int snd_emu10k1_capture_hw_free(snd_pcm_substream_t * substream) 437 { 438 return snd_pcm_lib_free_pages(substream); 439 } 440 441 static int snd_emu10k1_capture_prepare(snd_pcm_substream_t * substream) 442 { 443 emu10k1_t *emu = snd_pcm_substream_chip(substream); 444 snd_pcm_runtime_t *runtime = substream->runtime; 445 emu10k1_pcm_t *epcm = snd_magic_cast(emu10k1_pcm_t, runtime->private_data, return -ENXIO); 446 int idx; 447 448 snd_emu10k1_ptr_write(emu, epcm->capture_bs_reg, 0, 0); 449 switch (epcm->type) { 450 case CAPTURE_AC97ADC: 451 snd_emu10k1_ptr_write(emu, ADCCR, 0, 0); 452 break; 453 case CAPTURE_EFX: 454 snd_emu10k1_ptr_write(emu, FXWC, 0, 0); 455 break; 456 default: 457 break; 458 } 459 snd_emu10k1_ptr_write(emu, epcm->capture_ba_reg, 0, runtime->dma_addr); 460 epcm->capture_bufsize = snd_pcm_lib_buffer_bytes(substream); 461 epcm->capture_bs_val = 0; 462 for (idx = 0; idx < 31; idx++) { 463 if (capture_period_sizes[idx] == epcm->capture_bufsize) { 464 epcm->capture_bs_val = idx + 1; 465 break; 466 } 467 } 468 if (epcm->capture_bs_val == 0) { 469 snd_BUG(); 470 epcm->capture_bs_val++; 471 } 472 if (epcm->type == CAPTURE_AC97ADC) { 473 epcm->capture_cr_val = emu->audigy ? A_ADCCR_LCHANENABLE : ADCCR_LCHANENABLE; 474 if (runtime->channels > 1) 475 epcm->capture_cr_val |= emu->audigy ? A_ADCCR_RCHANENABLE : ADCCR_RCHANENABLE; 476 epcm->capture_cr_val |= emu->audigy ? 477 snd_emu10k1_audigy_capture_rate_reg(runtime->rate) : 478 snd_emu10k1_capture_rate_reg(runtime->rate); 479 } 480 return 0; 481 } 482 483 static void snd_emu10k1_playback_invalidate_cache(emu10k1_t *emu, emu10k1_voice_t *evoice) 484 { 485 snd_pcm_runtime_t *runtime; 486 unsigned int voice, i, ccis, cra = 64, cs, sample; 487 488 if (evoice == NULL) 489 return; 490 runtime = evoice->epcm->substream->runtime; 491 voice = evoice->number; 492 sample = snd_pcm_format_width(runtime->format) == 16 ? 0 : 0x80808080; 493 if (runtime->channels > 1) { 494 ccis = 28; 495 cs = 4; 496 } else { 497 ccis = 30; 498 cs = 2; 499 } 500 if (sample == 0) /* 16-bit */ 501 ccis *= 2; 502 for (i = 0; i < cs; i++) 503 snd_emu10k1_ptr_write(emu, CD0 + i, voice, sample); 504 // reset cache 505 snd_emu10k1_ptr_write(emu, CCR_CACHEINVALIDSIZE, voice, 0); 506 snd_emu10k1_ptr_write(emu, CCR_READADDRESS, voice, cra); 507 if (runtime->channels > 1) { 508 snd_emu10k1_ptr_write(emu, CCR_CACHEINVALIDSIZE, voice + 1, 0); 509 snd_emu10k1_ptr_write(emu, CCR_READADDRESS, voice + 1, cra); 510 } 511 // fill cache 512 snd_emu10k1_ptr_write(emu, CCR_CACHEINVALIDSIZE, voice, ccis); 513 } 514 515 static void snd_emu10k1_playback_trigger_voice(emu10k1_t *emu, emu10k1_voice_t *evoice, int master, int extra) 516 { 517 snd_pcm_substream_t *substream; 518 snd_pcm_runtime_t *runtime; 519 emu10k1_pcm_mixer_t *mix; 520 unsigned int voice, pitch, pitch_target, tmp; 521 unsigned int attn; 522 523 if (evoice == NULL) /* skip second voice for mono */ 524 return; 525 substream = evoice->epcm->substream; 526 runtime = substream->runtime; 527 mix = &emu->pcm_mixer[substream->number]; 528 voice = evoice->number; 529 pitch = snd_emu10k1_rate_to_pitch(runtime->rate) >> 8; 530 pitch_target = emu10k1_calc_pitch_target(runtime->rate); 531 attn = extra ? 0 : 0x00ff; 532 tmp = runtime->channels == 2 ? (master ? 1 : 2) : 0; 533 snd_emu10k1_ptr_write(emu, IFATN, voice, attn); 534 snd_emu10k1_ptr_write(emu, VTFT, voice, (mix->attn[tmp] << 16) | 0xffff); 535 snd_emu10k1_ptr_write(emu, CVCF, voice, (mix->attn[tmp] << 16) | 0xffff); 536 snd_emu10k1_voice_clear_loop_stop(emu, voice); 537 if (extra) 538 snd_emu10k1_voice_intr_enable(emu, voice); 539 snd_emu10k1_ptr_write(emu, DCYSUSV, voice, 0x7f7f); 540 snd_emu10k1_ptr_write(emu, PTRX_PITCHTARGET, voice, pitch_target); 541 if (master) 542 snd_emu10k1_ptr_write(emu, CPF_CURRENTPITCH, voice, pitch_target); 543 snd_emu10k1_ptr_write(emu, IP, voice, pitch); 544 } 545 546 static void snd_emu10k1_playback_stop_voice(emu10k1_t *emu, emu10k1_voice_t *evoice) 547 { 548 unsigned int voice; 549 550 if (evoice == NULL) 551 return; 552 voice = evoice->number; 553 snd_emu10k1_voice_intr_disable(emu, voice); 554 snd_emu10k1_ptr_write(emu, PTRX_PITCHTARGET, voice, 0); 555 snd_emu10k1_ptr_write(emu, CPF_CURRENTPITCH, voice, 0); 556 snd_emu10k1_ptr_write(emu, IFATN, voice, 0xffff); 557 snd_emu10k1_ptr_write(emu, VTFT, voice, 0xffff); 558 snd_emu10k1_ptr_write(emu, CVCF, voice, 0xffff); 559 snd_emu10k1_ptr_write(emu, IP, voice, 0); 560 } 561 562 static int snd_emu10k1_playback_trigger(snd_pcm_substream_t * substream, 563 int cmd) 564 { 565 emu10k1_t *emu = snd_pcm_substream_chip(substream); 566 snd_pcm_runtime_t *runtime = substream->runtime; 567 emu10k1_pcm_t *epcm = snd_magic_cast(emu10k1_pcm_t, runtime->private_data, return -ENXIO); 568 unsigned long flags; 569 int result = 0; 570 571 // printk("trigger - emu10k1 = 0x%x, cmd = %i, pointer = %i\n", (int)emu, cmd, substream->ops->pointer(substream)); 572 spin_lock_irqsave(&emu->reg_lock, flags); 573 switch (cmd) { 574 case SNDRV_PCM_TRIGGER_START: 575 snd_emu10k1_playback_invalidate_cache(emu, epcm->extra); /* do we need this? */ 576 snd_emu10k1_playback_invalidate_cache(emu, epcm->voices[0]); 577 /* follow thru */ 578 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 579 snd_emu10k1_playback_trigger_voice(emu, epcm->voices[0], 1, 0); 580 snd_emu10k1_playback_trigger_voice(emu, epcm->voices[1], 0, 0); 581 snd_emu10k1_playback_trigger_voice(emu, epcm->extra, 1, 1); 582 epcm->running = 1; 583 break; 584 case SNDRV_PCM_TRIGGER_STOP: 585 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 586 epcm->running = 0; 587 snd_emu10k1_playback_stop_voice(emu, epcm->voices[0]); 588 snd_emu10k1_playback_stop_voice(emu, epcm->voices[1]); 589 snd_emu10k1_playback_stop_voice(emu, epcm->extra); 590 break; 591 default: 592 result = -EINVAL; 593 break; 594 } 595 spin_unlock_irqrestore(&emu->reg_lock, flags); 596 return result; 597 } 598 599 static int snd_emu10k1_capture_trigger(snd_pcm_substream_t * substream, 600 int cmd) 601 { 602 emu10k1_t *emu = snd_pcm_substream_chip(substream); 603 snd_pcm_runtime_t *runtime = substream->runtime; 604 emu10k1_pcm_t *epcm = snd_magic_cast(emu10k1_pcm_t, runtime->private_data, return -ENXIO); 605 unsigned long flags; 606 int result = 0; 607 608 // printk("trigger - emu10k1 = %p, cmd = %i, pointer = %i\n", emu, cmd, substream->ops->pointer(substream)); 609 spin_lock_irqsave(&emu->reg_lock, flags); 610 switch (cmd) { 611 case SNDRV_PCM_TRIGGER_START: 612 outl(epcm->capture_ipr, emu->port + IPR); 613 snd_emu10k1_intr_enable(emu, epcm->capture_inte); 614 // printk("adccr = 0x%x, adcbs = 0x%x\n", epcm->adccr, epcm->adcbs); 615 switch (epcm->type) { 616 case CAPTURE_AC97ADC: 617 snd_emu10k1_ptr_write(emu, ADCCR, 0, epcm->capture_cr_val); 618 break; 619 case CAPTURE_EFX: 620 snd_emu10k1_ptr_write(emu, FXWC, 0, epcm->capture_cr_val); 621 break; 622 default: 623 break; 624 } 625 snd_emu10k1_ptr_write(emu, epcm->capture_bs_reg, 0, epcm->capture_bs_val); 626 epcm->running = 1; 627 epcm->first_ptr = 1; 628 break; 629 case SNDRV_PCM_TRIGGER_STOP: 630 epcm->running = 0; 631 snd_emu10k1_intr_disable(emu, epcm->capture_inte); 632 outl(epcm->capture_ipr, emu->port + IPR); 633 snd_emu10k1_ptr_write(emu, epcm->capture_bs_reg, 0, 0); 634 switch (epcm->type) { 635 case CAPTURE_AC97ADC: 636 snd_emu10k1_ptr_write(emu, ADCCR, 0, 0); 637 break; 638 case CAPTURE_EFX: 639 snd_emu10k1_ptr_write(emu, FXWC, 0, 0); 640 break; 641 default: 642 break; 643 } 644 break; 645 default: 646 result = -EINVAL; 647 } 648 spin_unlock_irqrestore(&emu->reg_lock, flags); 649 return result; 650 } 651 652 static snd_pcm_uframes_t snd_emu10k1_playback_pointer(snd_pcm_substream_t * substream) 653 { 654 emu10k1_t *emu = snd_pcm_substream_chip(substream); 655 snd_pcm_runtime_t *runtime = substream->runtime; 656 emu10k1_pcm_t *epcm = snd_magic_cast(emu10k1_pcm_t, runtime->private_data, return -ENXIO); 657 unsigned int ptr; 658 659 if (!epcm->running) 660 return 0; 661 ptr = snd_emu10k1_ptr_read(emu, CCCA, epcm->voices[0]->number) & 0x00ffffff; 662 #if 0 /* Perex's code */ 663 ptr += runtime->buffer_size; 664 ptr -= epcm->ccca_start_addr; 665 ptr %= runtime->buffer_size; 666 #else /* EMU10K1 Open Source code from Creative */ 667 if (ptr < epcm->ccca_start_addr) 668 ptr += runtime->buffer_size - epcm->ccca_start_addr; 669 else { 670 ptr -= epcm->ccca_start_addr; 671 if (ptr >= runtime->buffer_size) 672 ptr -= runtime->buffer_size; 673 } 674 #endif 675 // printk("ptr = 0x%x, buffer_size = 0x%x, period_size = 0x%x\n", ptr, runtime->buffer_size, runtime->period_size); 676 return ptr; 677 } 678 679 static snd_pcm_uframes_t snd_emu10k1_capture_pointer(snd_pcm_substream_t * substream) 680 { 681 emu10k1_t *emu = snd_pcm_substream_chip(substream); 682 snd_pcm_runtime_t *runtime = substream->runtime; 683 emu10k1_pcm_t *epcm = snd_magic_cast(emu10k1_pcm_t, runtime->private_data, return -ENXIO); 684 unsigned int ptr; 685 686 if (!epcm->running) 687 return 0; 688 if (epcm->first_ptr) { 689 udelay(50); // hack, it takes awhile until capture is started 690 epcm->first_ptr = 0; 691 } 692 ptr = snd_emu10k1_ptr_read(emu, epcm->capture_idx_reg, 0) & 0x0000ffff; 693 return bytes_to_frames(runtime, ptr); 694 } 695 696 /* 697 * Playback support device description 698 */ 699 700 static snd_pcm_hardware_t snd_emu10k1_playback = 701 { 702 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | 703 SNDRV_PCM_INFO_BLOCK_TRANSFER | 704 SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_PAUSE), 705 .formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE, 706 .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000, 707 .rate_min = 4000, 708 .rate_max = 48000, 709 .channels_min = 1, 710 .channels_max = 2, 711 .buffer_bytes_max = (128*1024), 712 .period_bytes_min = 64, 713 .period_bytes_max = (128*1024), 714 .periods_min = 1, 715 .periods_max = 1024, 716 .fifo_size = 0, 717 }; 718 719 /* 720 * Capture support device description 721 */ 722 723 static snd_pcm_hardware_t snd_emu10k1_capture = 724 { 725 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | 726 SNDRV_PCM_INFO_BLOCK_TRANSFER | 727 SNDRV_PCM_INFO_MMAP_VALID), 728 .formats = SNDRV_PCM_FMTBIT_S16_LE, 729 .rates = SNDRV_PCM_RATE_8000_48000, 730 .rate_min = 8000, 731 .rate_max = 48000, 732 .channels_min = 1, 733 .channels_max = 2, 734 .buffer_bytes_max = (64*1024), 735 .period_bytes_min = 384, 736 .period_bytes_max = (64*1024), 737 .periods_min = 2, 738 .periods_max = 2, 739 .fifo_size = 0, 740 }; 741 742 /* 743 * 744 */ 745 746 static void snd_emu10k1_pcm_mixer_notify1(emu10k1_t *emu, snd_kcontrol_t *kctl, int idx, int activate) 747 { 748 snd_ctl_elem_id_t id; 749 750 snd_runtime_check(kctl != NULL, return); 751 if (activate) 752 kctl->vd[idx].access &= ~SNDRV_CTL_ELEM_ACCESS_INACTIVE; 753 else 754 kctl->vd[idx].access |= SNDRV_CTL_ELEM_ACCESS_INACTIVE; 755 snd_ctl_notify(emu->card, SNDRV_CTL_EVENT_MASK_VALUE | 756 SNDRV_CTL_EVENT_MASK_INFO, 757 snd_ctl_build_ioff(&id, kctl, idx)); 758 } 759 760 static void snd_emu10k1_pcm_mixer_notify(emu10k1_t *emu, int idx, int activate) 761 { 762 snd_emu10k1_pcm_mixer_notify1(emu, emu->ctl_send_routing, idx, activate); 763 snd_emu10k1_pcm_mixer_notify1(emu, emu->ctl_send_volume, idx, activate); 764 snd_emu10k1_pcm_mixer_notify1(emu, emu->ctl_attn, idx, activate); 765 } 766 767 static void snd_emu10k1_pcm_free_substream(snd_pcm_runtime_t *runtime) 768 { 769 emu10k1_pcm_t *epcm = snd_magic_cast(emu10k1_pcm_t, runtime->private_data, return); 770 771 if (epcm) 772 snd_magic_kfree(epcm); 773 } 774 775 static int snd_emu10k1_playback_open(snd_pcm_substream_t * substream) 776 { 777 emu10k1_t *emu = snd_pcm_substream_chip(substream); 778 emu10k1_pcm_t *epcm; 779 emu10k1_pcm_mixer_t *mix; 780 snd_pcm_runtime_t *runtime = substream->runtime; 781 int i, err; 782 783 epcm = snd_magic_kcalloc(emu10k1_pcm_t, 0, GFP_KERNEL); 784 if (epcm == NULL) 785 return -ENOMEM; 786 epcm->emu = emu; 787 epcm->type = PLAYBACK_EMUVOICE; 788 epcm->substream = substream; 789 runtime->private_data = epcm; 790 runtime->private_free = snd_emu10k1_pcm_free_substream; 791 runtime->hw = snd_emu10k1_playback; 792 if ((err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS)) < 0) { 793 snd_magic_kfree(epcm); 794 return err; 795 } 796 if ((err = snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 256, UINT_MAX)) < 0) { 797 snd_magic_kfree(epcm); 798 return err; 799 } 800 mix = &emu->pcm_mixer[substream->number]; 801 for (i = 0; i < 4; i++) 802 mix->send_routing[0][i] = mix->send_routing[1][i] = mix->send_routing[2][i] = i; 803 memset(&mix->send_volume, 0, sizeof(mix->send_volume)); 804 mix->send_volume[0][0] = mix->send_volume[0][1] = 805 mix->send_volume[1][0] = mix->send_volume[2][1] = 255; 806 mix->attn[0] = mix->attn[1] = mix->attn[2] = 0xffff; 807 mix->epcm = epcm; 808 snd_emu10k1_pcm_mixer_notify(emu, substream->number, 1); 809 return 0; 810 } 811 812 static int snd_emu10k1_playback_close(snd_pcm_substream_t * substream) 813 { 814 emu10k1_t *emu = snd_pcm_substream_chip(substream); 815 emu10k1_pcm_mixer_t *mix = &emu->pcm_mixer[substream->number]; 816 817 mix->epcm = NULL; 818 snd_emu10k1_pcm_mixer_notify(emu, substream->number, 0); 819 return 0; 820 } 821 822 static int snd_emu10k1_capture_open(snd_pcm_substream_t * substream) 823 { 824 emu10k1_t *emu = snd_pcm_substream_chip(substream); 825 snd_pcm_runtime_t *runtime = substream->runtime; 826 emu10k1_pcm_t *epcm; 827 828 epcm = snd_magic_kcalloc(emu10k1_pcm_t, 0, GFP_KERNEL); 829 if (epcm == NULL) 830 return -ENOMEM; 831 epcm->emu = emu; 832 epcm->type = CAPTURE_AC97ADC; 833 epcm->substream = substream; 834 epcm->capture_ipr = IPR_ADCBUFFULL|IPR_ADCBUFHALFFULL; 835 epcm->capture_inte = INTE_ADCBUFENABLE; 836 epcm->capture_ba_reg = ADCBA; 837 epcm->capture_bs_reg = ADCBS; 838 epcm->capture_idx_reg = emu->audigy ? A_ADCIDX : ADCIDX; 839 runtime->private_data = epcm; 840 runtime->private_free = snd_emu10k1_pcm_free_substream; 841 runtime->hw = snd_emu10k1_capture; 842 emu->capture_interrupt = snd_emu10k1_pcm_ac97adc_interrupt; 843 emu->pcm_capture_substream = substream; 844 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, &hw_constraints_capture_period_sizes); 845 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, &hw_constraints_capture_rates); 846 return 0; 847 } 848 849 static int snd_emu10k1_capture_close(snd_pcm_substream_t * substream) 850 { 851 emu10k1_t *emu = snd_pcm_substream_chip(substream); 852 853 emu->capture_interrupt = NULL; 854 emu->pcm_capture_substream = NULL; 855 return 0; 856 } 857 858 static int snd_emu10k1_capture_mic_open(snd_pcm_substream_t * substream) 859 { 860 emu10k1_t *emu = snd_pcm_substream_chip(substream); 861 emu10k1_pcm_t *epcm; 862 snd_pcm_runtime_t *runtime = substream->runtime; 863 864 epcm = snd_magic_kcalloc(emu10k1_pcm_t, 0, GFP_KERNEL); 865 if (epcm == NULL) 866 return -ENOMEM; 867 epcm->emu = emu; 868 epcm->type = CAPTURE_AC97MIC; 869 epcm->substream = substream; 870 epcm->capture_ipr = IPR_MICBUFFULL|IPR_MICBUFHALFFULL; 871 epcm->capture_inte = INTE_MICBUFENABLE; 872 epcm->capture_ba_reg = MICBA; 873 epcm->capture_bs_reg = MICBS; 874 epcm->capture_idx_reg = MICIDX; 875 substream->runtime->private_data = epcm; 876 substream->runtime->private_free = snd_emu10k1_pcm_free_substream; 877 runtime->hw = snd_emu10k1_capture; 878 runtime->hw.rates = SNDRV_PCM_RATE_8000; 879 runtime->hw.rate_min = runtime->hw.rate_max = 8000; 880 runtime->hw.channels_min = 1; 881 emu->capture_mic_interrupt = snd_emu10k1_pcm_ac97mic_interrupt; 882 emu->pcm_capture_mic_substream = substream; 883 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, &hw_constraints_capture_period_sizes); 884 return 0; 885 } 886 887 static int snd_emu10k1_capture_mic_close(snd_pcm_substream_t * substream) 888 { 889 emu10k1_t *emu = snd_pcm_substream_chip(substream); 890 891 emu->capture_interrupt = NULL; 892 emu->pcm_capture_mic_substream = NULL; 893 return 0; 894 } 895 896 static int snd_emu10k1_capture_efx_open(snd_pcm_substream_t * substream) 897 { 898 emu10k1_t *emu = snd_pcm_substream_chip(substream); 899 emu10k1_pcm_t *epcm; 900 snd_pcm_runtime_t *runtime = substream->runtime; 901 unsigned long flags; 902 int nefx = emu->audigy ? 64 : 32; 903 int idx; 904 905 epcm = snd_magic_kcalloc(emu10k1_pcm_t, 0, GFP_KERNEL); 906 if (epcm == NULL) 907 return -ENOMEM; 908 epcm->emu = emu; 909 epcm->type = CAPTURE_EFX; 910 epcm->substream = substream; 911 epcm->capture_ipr = IPR_EFXBUFFULL|IPR_EFXBUFHALFFULL; 912 epcm->capture_inte = INTE_EFXBUFENABLE; 913 epcm->capture_ba_reg = FXBA; 914 epcm->capture_bs_reg = FXBS; 915 epcm->capture_idx_reg = FXIDX; 916 substream->runtime->private_data = epcm; 917 substream->runtime->private_free = snd_emu10k1_pcm_free_substream; 918 runtime->hw = snd_emu10k1_capture; 919 runtime->hw.rates = SNDRV_PCM_RATE_48000; 920 runtime->hw.rate_min = runtime->hw.rate_max = 48000; 921 spin_lock_irqsave(&emu->reg_lock, flags); 922 runtime->hw.channels_min = runtime->hw.channels_max = 0; 923 for (idx = 0; idx < nefx; idx++) { 924 if (emu->efx_voices_mask[idx/32] & (1 << (idx%32))) { 925 runtime->hw.channels_min++; 926 runtime->hw.channels_max++; 927 } 928 } 929 epcm->capture_cr_val = emu->efx_voices_mask[0]; 930 epcm->capture_cr_val2 = emu->efx_voices_mask[1]; 931 spin_unlock_irqrestore(&emu->reg_lock, flags); 932 emu->capture_efx_interrupt = snd_emu10k1_pcm_efx_interrupt; 933 emu->pcm_capture_efx_substream = substream; 934 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, &hw_constraints_capture_period_sizes); 935 return 0; 936 } 937 938 static int snd_emu10k1_capture_efx_close(snd_pcm_substream_t * substream) 939 { 940 emu10k1_t *emu = snd_pcm_substream_chip(substream); 941 942 emu->capture_interrupt = NULL; 943 emu->pcm_capture_efx_substream = NULL; 944 return 0; 945 } 946 947 static snd_pcm_ops_t snd_emu10k1_playback_ops = { 948 .open = snd_emu10k1_playback_open, 949 .close = snd_emu10k1_playback_close, 950 .ioctl = snd_pcm_lib_ioctl, 951 .hw_params = snd_emu10k1_playback_hw_params, 952 .hw_free = snd_emu10k1_playback_hw_free, 953 .prepare = snd_emu10k1_playback_prepare, 954 .trigger = snd_emu10k1_playback_trigger, 955 .pointer = snd_emu10k1_playback_pointer, 956 .page = snd_pcm_sgbuf_ops_page, 957 }; 958 959 static snd_pcm_ops_t snd_emu10k1_capture_ops = { 960 .open = snd_emu10k1_capture_open, 961 .close = snd_emu10k1_capture_close, 962 .ioctl = snd_pcm_lib_ioctl, 963 .hw_params = snd_emu10k1_capture_hw_params, 964 .hw_free = snd_emu10k1_capture_hw_free, 965 .prepare = snd_emu10k1_capture_prepare, 966 .trigger = snd_emu10k1_capture_trigger, 967 .pointer = snd_emu10k1_capture_pointer, 968 }; 969 970 static void snd_emu10k1_pcm_free(snd_pcm_t *pcm) 971 { 972 emu10k1_t *emu = snd_magic_cast(emu10k1_t, pcm->private_data, return); 973 emu->pcm = NULL; 974 snd_pcm_lib_preallocate_free_for_all(pcm); 975 } 976 977 int __devinit snd_emu10k1_pcm(emu10k1_t * emu, int device, snd_pcm_t ** rpcm) 978 { 979 snd_pcm_t *pcm; 980 snd_pcm_substream_t *substream; 981 int err; 982 983 if (rpcm) 984 *rpcm = NULL; 985 986 if ((err = snd_pcm_new(emu->card, "emu10k1", device, 32, 1, &pcm)) < 0) 987 return err; 988 989 pcm->private_data = emu; 990 pcm->private_free = snd_emu10k1_pcm_free; 991 992 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_emu10k1_playback_ops); 993 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_emu10k1_capture_ops); 994 995 pcm->info_flags = 0; 996 pcm->dev_subclass = SNDRV_PCM_SUBCLASS_GENERIC_MIX; 997 strcpy(pcm->name, "EMU10K1"); 998 emu->pcm = pcm; 999 1000 for (substream = pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream; substream; substream = substream->next) 1001 if ((err = snd_pcm_lib_preallocate_sg_pages(emu->pci, substream, 64*1024, 64*1024)) < 0) 1002 return err; 1003 1004 for (substream = pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream; substream; substream = substream->next) 1005 snd_pcm_lib_preallocate_pci_pages(emu->pci, substream, 64*1024, 64*1024); 1006 1007 if (rpcm) 1008 *rpcm = pcm; 1009 1010 return 0; 1011 } 1012 1013 static snd_pcm_ops_t snd_emu10k1_capture_mic_ops = { 1014 .open = snd_emu10k1_capture_mic_open, 1015 .close = snd_emu10k1_capture_mic_close, 1016 .ioctl = snd_pcm_lib_ioctl, 1017 .hw_params = snd_emu10k1_capture_hw_params, 1018 .hw_free = snd_emu10k1_capture_hw_free, 1019 .prepare = snd_emu10k1_capture_prepare, 1020 .trigger = snd_emu10k1_capture_trigger, 1021 .pointer = snd_emu10k1_capture_pointer, 1022 }; 1023 1024 static void snd_emu10k1_pcm_mic_free(snd_pcm_t *pcm) 1025 { 1026 emu10k1_t *emu = snd_magic_cast(emu10k1_t, pcm->private_data, return); 1027 emu->pcm_mic = NULL; 1028 snd_pcm_lib_preallocate_free_for_all(pcm); 1029 } 1030 1031 int __devinit snd_emu10k1_pcm_mic(emu10k1_t * emu, int device, snd_pcm_t ** rpcm) 1032 { 1033 snd_pcm_t *pcm; 1034 int err; 1035 1036 if (rpcm) 1037 *rpcm = NULL; 1038 1039 if ((err = snd_pcm_new(emu->card, "emu10k1 mic", device, 0, 1, &pcm)) < 0) 1040 return err; 1041 1042 pcm->private_data = emu; 1043 pcm->private_free = snd_emu10k1_pcm_mic_free; 1044 1045 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_emu10k1_capture_mic_ops); 1046 1047 pcm->info_flags = 0; 1048 strcpy(pcm->name, "EMU10K1 MIC"); 1049 emu->pcm_mic = pcm; 1050 1051 snd_pcm_lib_preallocate_pci_pages_for_all(emu->pci, pcm, 64*1024, 64*1024); 1052 1053 if (rpcm) 1054 *rpcm = pcm; 1055 return 0; 1056 } 1057 1058 static int snd_emu10k1_pcm_efx_voices_mask_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo) 1059 { 1060 emu10k1_t *emu = snd_kcontrol_chip(kcontrol); 1061 int nefx = emu->audigy ? 64 : 32; 1062 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; 1063 uinfo->count = nefx; 1064 uinfo->value.integer.min = 0; 1065 uinfo->value.integer.max = 1; 1066 return 0; 1067 } 1068 1069 static int snd_emu10k1_pcm_efx_voices_mask_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) 1070 { 1071 emu10k1_t *emu = snd_kcontrol_chip(kcontrol); 1072 unsigned long flags; 1073 int nefx = emu->audigy ? 64 : 32; 1074 int idx; 1075 1076 spin_lock_irqsave(&emu->reg_lock, flags); 1077 for (idx = 0; idx < nefx; idx++) 1078 ucontrol->value.integer.value[idx] = (emu->efx_voices_mask[idx / 32] & (1 << (idx % 32))) ? 1 : 0; 1079 spin_unlock_irqrestore(&emu->reg_lock, flags); 1080 return 0; 1081 } 1082 1083 static int snd_emu10k1_pcm_efx_voices_mask_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) 1084 { 1085 emu10k1_t *emu = snd_kcontrol_chip(kcontrol); 1086 unsigned long flags; 1087 unsigned int nval[2], bits; 1088 int nefx = emu->audigy ? 64 : 32; 1089 int change, idx; 1090 1091 nval[0] = nval[1] = 0; 1092 for (idx = 0, bits = 0; idx < nefx; idx++) 1093 if (ucontrol->value.integer.value[idx]) { 1094 nval[idx / 32] |= 1 << (idx % 32); 1095 bits++; 1096 } 1097 if (bits != 1 && bits != 2 && bits != 4 && bits != 8) 1098 return -EINVAL; 1099 spin_lock_irqsave(&emu->reg_lock, flags); 1100 change = (nval[0] != emu->efx_voices_mask[0]) || 1101 (nval[1] != emu->efx_voices_mask[1]); 1102 emu->efx_voices_mask[0] = nval[0]; 1103 emu->efx_voices_mask[1] = nval[1]; 1104 spin_unlock_irqrestore(&emu->reg_lock, flags); 1105 return change; 1106 } 1107 1108 static snd_kcontrol_new_t snd_emu10k1_pcm_efx_voices_mask = { 1109 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 1110 .name = "EFX voices mask", 1111 .info = snd_emu10k1_pcm_efx_voices_mask_info, 1112 .get = snd_emu10k1_pcm_efx_voices_mask_get, 1113 .put = snd_emu10k1_pcm_efx_voices_mask_put 1114 }; 1115 1116 static snd_pcm_ops_t snd_emu10k1_capture_efx_ops = { 1117 .open = snd_emu10k1_capture_efx_open, 1118 .close = snd_emu10k1_capture_efx_close, 1119 .ioctl = snd_pcm_lib_ioctl, 1120 .hw_params = snd_emu10k1_capture_hw_params, 1121 .hw_free = snd_emu10k1_capture_hw_free, 1122 .prepare = snd_emu10k1_capture_prepare, 1123 .trigger = snd_emu10k1_capture_trigger, 1124 .pointer = snd_emu10k1_capture_pointer, 1125 }; 1126 1127 static void snd_emu10k1_pcm_efx_free(snd_pcm_t *pcm) 1128 { 1129 emu10k1_t *emu = snd_magic_cast(emu10k1_t, pcm->private_data, return); 1130 emu->pcm_efx = NULL; 1131 snd_pcm_lib_preallocate_free_for_all(pcm); 1132 } 1133 1134 int __devinit snd_emu10k1_pcm_efx(emu10k1_t * emu, int device, snd_pcm_t ** rpcm) 1135 { 1136 snd_pcm_t *pcm; 1137 int err; 1138 1139 if (rpcm) 1140 *rpcm = NULL; 1141 1142 if ((err = snd_pcm_new(emu->card, "emu10k1 efx", device, 0, 1, &pcm)) < 0) 1143 return err; 1144 1145 pcm->private_data = emu; 1146 pcm->private_free = snd_emu10k1_pcm_efx_free; 1147 1148 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_emu10k1_capture_efx_ops); 1149 1150 pcm->info_flags = 0; 1151 strcpy(pcm->name, "EMU10K1 EFX"); 1152 emu->pcm_efx = pcm; 1153 if (rpcm) 1154 *rpcm = pcm; 1155 1156 emu->efx_voices_mask[0] = FXWC_DEFAULTROUTE_C | FXWC_DEFAULTROUTE_A; 1157 emu->efx_voices_mask[1] = 0; 1158 snd_ctl_add(emu->card, snd_ctl_new1(&snd_emu10k1_pcm_efx_voices_mask, emu)); 1159 1160 snd_pcm_lib_preallocate_pci_pages_for_all(emu->pci, pcm, 64*1024, 64*1024); 1161 1162 return 0; 1163 } 1164
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.