1 /* 2 * Maintained by Jaroslav Kysela <perex@suse.cz> 3 * Originated by audio@tridentmicro.com 4 * Fri Feb 19 15:55:28 MST 1999 5 * Routines for control of Trident 4DWave (DX and NX) chip 6 * 7 * BUGS: 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 * SiS7018 S/PDIF support by Thomas Winischhofer <thomas@winischhofer.net> 28 */ 29 30 #include <sound/driver.h> 31 #include <linux/delay.h> 32 #include <linux/init.h> 33 #include <linux/interrupt.h> 34 #include <linux/pci.h> 35 #include <linux/slab.h> 36 #include <linux/vmalloc.h> 37 #include <linux/gameport.h> 38 39 #include <sound/core.h> 40 #include <sound/info.h> 41 #include <sound/control.h> 42 #include <sound/trident.h> 43 #include <sound/asoundef.h> 44 45 #include <asm/io.h> 46 47 static int snd_trident_pcm_mixer_build(trident_t *trident, snd_trident_voice_t * voice, snd_pcm_substream_t *substream); 48 static int snd_trident_pcm_mixer_free(trident_t *trident, snd_trident_voice_t * voice, snd_pcm_substream_t *substream); 49 static irqreturn_t snd_trident_interrupt(int irq, void *dev_id, struct pt_regs *regs); 50 #ifdef CONFIG_PM 51 static int snd_trident_suspend(snd_card_t *card, pm_message_t state); 52 static int snd_trident_resume(snd_card_t *card); 53 #endif 54 static int snd_trident_sis_reset(trident_t *trident); 55 56 static void snd_trident_clear_voices(trident_t * trident, unsigned short v_min, unsigned short v_max); 57 static int snd_trident_free(trident_t *trident); 58 59 /* 60 * common I/O routines 61 */ 62 63 64 #if 0 65 static void snd_trident_print_voice_regs(trident_t *trident, int voice) 66 { 67 unsigned int val, tmp; 68 69 printk("Trident voice %i:\n", voice); 70 outb(voice, TRID_REG(trident, T4D_LFO_GC_CIR)); 71 val = inl(TRID_REG(trident, CH_LBA)); 72 printk("LBA: 0x%x\n", val); 73 val = inl(TRID_REG(trident, CH_GVSEL_PAN_VOL_CTRL_EC)); 74 printk("GVSel: %i\n", val >> 31); 75 printk("Pan: 0x%x\n", (val >> 24) & 0x7f); 76 printk("Vol: 0x%x\n", (val >> 16) & 0xff); 77 printk("CTRL: 0x%x\n", (val >> 12) & 0x0f); 78 printk("EC: 0x%x\n", val & 0x0fff); 79 if (trident->device != TRIDENT_DEVICE_ID_NX) { 80 val = inl(TRID_REG(trident, CH_DX_CSO_ALPHA_FMS)); 81 printk("CSO: 0x%x\n", val >> 16); 82 printk("Alpha: 0x%x\n", (val >> 4) & 0x0fff); 83 printk("FMS: 0x%x\n", val & 0x0f); 84 val = inl(TRID_REG(trident, CH_DX_ESO_DELTA)); 85 printk("ESO: 0x%x\n", val >> 16); 86 printk("Delta: 0x%x\n", val & 0xffff); 87 val = inl(TRID_REG(trident, CH_DX_FMC_RVOL_CVOL)); 88 } else { // TRIDENT_DEVICE_ID_NX 89 val = inl(TRID_REG(trident, CH_NX_DELTA_CSO)); 90 tmp = (val >> 24) & 0xff; 91 printk("CSO: 0x%x\n", val & 0x00ffffff); 92 val = inl(TRID_REG(trident, CH_NX_DELTA_ESO)); 93 tmp |= (val >> 16) & 0xff00; 94 printk("Delta: 0x%x\n", tmp); 95 printk("ESO: 0x%x\n", val & 0x00ffffff); 96 val = inl(TRID_REG(trident, CH_NX_ALPHA_FMS_FMC_RVOL_CVOL)); 97 printk("Alpha: 0x%x\n", val >> 20); 98 printk("FMS: 0x%x\n", (val >> 16) & 0x0f); 99 } 100 printk("FMC: 0x%x\n", (val >> 14) & 3); 101 printk("RVol: 0x%x\n", (val >> 7) & 0x7f); 102 printk("CVol: 0x%x\n", val & 0x7f); 103 } 104 #endif 105 106 /*--------------------------------------------------------------------------- 107 unsigned short snd_trident_codec_read(ac97_t *ac97, unsigned short reg) 108 109 Description: This routine will do all of the reading from the external 110 CODEC (AC97). 111 112 Parameters: ac97 - ac97 codec structure 113 reg - CODEC register index, from AC97 Hal. 114 115 returns: 16 bit value read from the AC97. 116 117 ---------------------------------------------------------------------------*/ 118 static unsigned short snd_trident_codec_read(ac97_t *ac97, unsigned short reg) 119 { 120 unsigned int data = 0, treg; 121 unsigned short count = 0xffff; 122 unsigned long flags; 123 trident_t *trident = ac97->private_data; 124 125 spin_lock_irqsave(&trident->reg_lock, flags); 126 if (trident->device == TRIDENT_DEVICE_ID_DX) { 127 data = (DX_AC97_BUSY_READ | (reg & 0x000000ff)); 128 outl(data, TRID_REG(trident, DX_ACR1_AC97_R)); 129 do { 130 data = inl(TRID_REG(trident, DX_ACR1_AC97_R)); 131 if ((data & DX_AC97_BUSY_READ) == 0) 132 break; 133 } while (--count); 134 } else if (trident->device == TRIDENT_DEVICE_ID_NX) { 135 data = (NX_AC97_BUSY_READ | (reg & 0x000000ff)); 136 treg = ac97->num == 0 ? NX_ACR2_AC97_R_PRIMARY : NX_ACR3_AC97_R_SECONDARY; 137 outl(data, TRID_REG(trident, treg)); 138 do { 139 data = inl(TRID_REG(trident, treg)); 140 if ((data & 0x00000C00) == 0) 141 break; 142 } while (--count); 143 } else if (trident->device == TRIDENT_DEVICE_ID_SI7018) { 144 data = SI_AC97_BUSY_READ | SI_AC97_AUDIO_BUSY | (reg & 0x000000ff); 145 if (ac97->num == 1) 146 data |= SI_AC97_SECONDARY; 147 outl(data, TRID_REG(trident, SI_AC97_READ)); 148 do { 149 data = inl(TRID_REG(trident, SI_AC97_READ)); 150 if ((data & (SI_AC97_BUSY_READ)) == 0) 151 break; 152 } while (--count); 153 } 154 155 if (count == 0 && !trident->ac97_detect) { 156 snd_printk("ac97 codec read TIMEOUT [0x%x/0x%x]!!!\n", reg, data); 157 data = 0; 158 } 159 160 spin_unlock_irqrestore(&trident->reg_lock, flags); 161 return ((unsigned short) (data >> 16)); 162 } 163 164 /*--------------------------------------------------------------------------- 165 void snd_trident_codec_write(ac97_t *ac97, unsigned short reg, unsigned short wdata) 166 167 Description: This routine will do all of the writing to the external 168 CODEC (AC97). 169 170 Parameters: ac97 - ac97 codec structure 171 reg - CODEC register index, from AC97 Hal. 172 data - Lower 16 bits are the data to write to CODEC. 173 174 returns: TRUE if everything went ok, else FALSE. 175 176 ---------------------------------------------------------------------------*/ 177 static void snd_trident_codec_write(ac97_t *ac97, unsigned short reg, unsigned short wdata) 178 { 179 unsigned int address, data; 180 unsigned short count = 0xffff; 181 unsigned long flags; 182 trident_t *trident = ac97->private_data; 183 184 data = ((unsigned long) wdata) << 16; 185 186 spin_lock_irqsave(&trident->reg_lock, flags); 187 if (trident->device == TRIDENT_DEVICE_ID_DX) { 188 address = DX_ACR0_AC97_W; 189 190 /* read AC-97 write register status */ 191 do { 192 if ((inw(TRID_REG(trident, address)) & DX_AC97_BUSY_WRITE) == 0) 193 break; 194 } while (--count); 195 196 data |= (DX_AC97_BUSY_WRITE | (reg & 0x000000ff)); 197 } else if (trident->device == TRIDENT_DEVICE_ID_NX) { 198 address = NX_ACR1_AC97_W; 199 200 /* read AC-97 write register status */ 201 do { 202 if ((inw(TRID_REG(trident, address)) & NX_AC97_BUSY_WRITE) == 0) 203 break; 204 } while (--count); 205 206 data |= (NX_AC97_BUSY_WRITE | (ac97->num << 8) | (reg & 0x000000ff)); 207 } else if (trident->device == TRIDENT_DEVICE_ID_SI7018) { 208 address = SI_AC97_WRITE; 209 210 /* read AC-97 write register status */ 211 do { 212 if ((inw(TRID_REG(trident, address)) & (SI_AC97_BUSY_WRITE)) == 0) 213 break; 214 } while (--count); 215 216 data |= SI_AC97_BUSY_WRITE | SI_AC97_AUDIO_BUSY | (reg & 0x000000ff); 217 if (ac97->num == 1) 218 data |= SI_AC97_SECONDARY; 219 } else { 220 address = 0; /* keep GCC happy */ 221 count = 0; /* return */ 222 } 223 224 if (count == 0) { 225 spin_unlock_irqrestore(&trident->reg_lock, flags); 226 return; 227 } 228 outl(data, TRID_REG(trident, address)); 229 spin_unlock_irqrestore(&trident->reg_lock, flags); 230 } 231 232 /*--------------------------------------------------------------------------- 233 void snd_trident_enable_eso(trident_t *trident) 234 235 Description: This routine will enable end of loop interrupts. 236 End of loop interrupts will occur when a running 237 channel reaches ESO. 238 Also enables middle of loop interrupts. 239 240 Parameters: trident - pointer to target device class for 4DWave. 241 242 ---------------------------------------------------------------------------*/ 243 244 static void snd_trident_enable_eso(trident_t * trident) 245 { 246 unsigned int val; 247 248 val = inl(TRID_REG(trident, T4D_LFO_GC_CIR)); 249 val |= ENDLP_IE; 250 val |= MIDLP_IE; 251 if (trident->device == TRIDENT_DEVICE_ID_SI7018) 252 val |= BANK_B_EN; 253 outl(val, TRID_REG(trident, T4D_LFO_GC_CIR)); 254 } 255 256 /*--------------------------------------------------------------------------- 257 void snd_trident_disable_eso(trident_t *trident) 258 259 Description: This routine will disable end of loop interrupts. 260 End of loop interrupts will occur when a running 261 channel reaches ESO. 262 Also disables middle of loop interrupts. 263 264 Parameters: 265 trident - pointer to target device class for 4DWave. 266 267 returns: TRUE if everything went ok, else FALSE. 268 269 ---------------------------------------------------------------------------*/ 270 271 static void snd_trident_disable_eso(trident_t * trident) 272 { 273 unsigned int tmp; 274 275 tmp = inl(TRID_REG(trident, T4D_LFO_GC_CIR)); 276 tmp &= ~ENDLP_IE; 277 tmp &= ~MIDLP_IE; 278 outl(tmp, TRID_REG(trident, T4D_LFO_GC_CIR)); 279 } 280 281 /*--------------------------------------------------------------------------- 282 void snd_trident_start_voice(trident_t * trident, unsigned int voice) 283 284 Description: Start a voice, any channel 0 thru 63. 285 This routine automatically handles the fact that there are 286 more than 32 channels available. 287 288 Parameters : voice - Voice number 0 thru n. 289 trident - pointer to target device class for 4DWave. 290 291 Return Value: None. 292 293 ---------------------------------------------------------------------------*/ 294 295 void snd_trident_start_voice(trident_t * trident, unsigned int voice) 296 { 297 unsigned int mask = 1 << (voice & 0x1f); 298 unsigned int reg = (voice & 0x20) ? T4D_START_B : T4D_START_A; 299 300 outl(mask, TRID_REG(trident, reg)); 301 } 302 303 /*--------------------------------------------------------------------------- 304 void snd_trident_stop_voice(trident_t * trident, unsigned int voice) 305 306 Description: Stop a voice, any channel 0 thru 63. 307 This routine automatically handles the fact that there are 308 more than 32 channels available. 309 310 Parameters : voice - Voice number 0 thru n. 311 trident - pointer to target device class for 4DWave. 312 313 Return Value: None. 314 315 ---------------------------------------------------------------------------*/ 316 317 void snd_trident_stop_voice(trident_t * trident, unsigned int voice) 318 { 319 unsigned int mask = 1 << (voice & 0x1f); 320 unsigned int reg = (voice & 0x20) ? T4D_STOP_B : T4D_STOP_A; 321 322 outl(mask, TRID_REG(trident, reg)); 323 } 324 325 /*--------------------------------------------------------------------------- 326 int snd_trident_allocate_pcm_channel(trident_t *trident) 327 328 Description: Allocate hardware channel in Bank B (32-63). 329 330 Parameters : trident - pointer to target device class for 4DWave. 331 332 Return Value: hardware channel - 32-63 or -1 when no channel is available 333 334 ---------------------------------------------------------------------------*/ 335 336 static int snd_trident_allocate_pcm_channel(trident_t * trident) 337 { 338 int idx; 339 340 if (trident->ChanPCMcnt >= trident->ChanPCM) 341 return -1; 342 for (idx = 31; idx >= 0; idx--) { 343 if (!(trident->ChanMap[T4D_BANK_B] & (1 << idx))) { 344 trident->ChanMap[T4D_BANK_B] |= 1 << idx; 345 trident->ChanPCMcnt++; 346 return idx + 32; 347 } 348 } 349 return -1; 350 } 351 352 /*--------------------------------------------------------------------------- 353 void snd_trident_free_pcm_channel(int channel) 354 355 Description: Free hardware channel in Bank B (32-63) 356 357 Parameters : trident - pointer to target device class for 4DWave. 358 channel - hardware channel number 0-63 359 360 Return Value: none 361 362 ---------------------------------------------------------------------------*/ 363 364 static void snd_trident_free_pcm_channel(trident_t *trident, int channel) 365 { 366 if (channel < 32 || channel > 63) 367 return; 368 channel &= 0x1f; 369 if (trident->ChanMap[T4D_BANK_B] & (1 << channel)) { 370 trident->ChanMap[T4D_BANK_B] &= ~(1 << channel); 371 trident->ChanPCMcnt--; 372 } 373 } 374 375 /*--------------------------------------------------------------------------- 376 unsigned int snd_trident_allocate_synth_channel(void) 377 378 Description: Allocate hardware channel in Bank A (0-31). 379 380 Parameters : trident - pointer to target device class for 4DWave. 381 382 Return Value: hardware channel - 0-31 or -1 when no channel is available 383 384 ---------------------------------------------------------------------------*/ 385 386 static int snd_trident_allocate_synth_channel(trident_t * trident) 387 { 388 int idx; 389 390 for (idx = 31; idx >= 0; idx--) { 391 if (!(trident->ChanMap[T4D_BANK_A] & (1 << idx))) { 392 trident->ChanMap[T4D_BANK_A] |= 1 << idx; 393 trident->synth.ChanSynthCount++; 394 return idx; 395 } 396 } 397 return -1; 398 } 399 400 /*--------------------------------------------------------------------------- 401 void snd_trident_free_synth_channel( int channel ) 402 403 Description: Free hardware channel in Bank B (0-31). 404 405 Parameters : trident - pointer to target device class for 4DWave. 406 channel - hardware channel number 0-63 407 408 Return Value: none 409 410 ---------------------------------------------------------------------------*/ 411 412 static void snd_trident_free_synth_channel(trident_t *trident, int channel) 413 { 414 if (channel < 0 || channel > 31) 415 return; 416 channel &= 0x1f; 417 if (trident->ChanMap[T4D_BANK_A] & (1 << channel)) { 418 trident->ChanMap[T4D_BANK_A] &= ~(1 << channel); 419 trident->synth.ChanSynthCount--; 420 } 421 } 422 423 /*--------------------------------------------------------------------------- 424 snd_trident_write_voice_regs 425 426 Description: This routine will complete and write the 5 hardware channel 427 registers to hardware. 428 429 Paramters: trident - pointer to target device class for 4DWave. 430 voice - synthesizer voice structure 431 Each register field. 432 433 ---------------------------------------------------------------------------*/ 434 435 void snd_trident_write_voice_regs(trident_t * trident, 436 snd_trident_voice_t * voice) 437 { 438 unsigned int FmcRvolCvol; 439 unsigned int regs[5]; 440 441 regs[1] = voice->LBA; 442 regs[4] = (voice->GVSel << 31) | 443 ((voice->Pan & 0x0000007f) << 24) | 444 ((voice->CTRL & 0x0000000f) << 12); 445 FmcRvolCvol = ((voice->FMC & 3) << 14) | 446 ((voice->RVol & 0x7f) << 7) | 447 (voice->CVol & 0x7f); 448 449 switch (trident->device) { 450 case TRIDENT_DEVICE_ID_SI7018: 451 regs[4] |= voice->number > 31 ? 452 (voice->Vol & 0x000003ff) : 453 ((voice->Vol & 0x00003fc) << (16-2)) | 454 (voice->EC & 0x00000fff); 455 regs[0] = (voice->CSO << 16) | ((voice->Alpha & 0x00000fff) << 4) | (voice->FMS & 0x0000000f); 456 regs[2] = (voice->ESO << 16) | (voice->Delta & 0x0ffff); 457 regs[3] = (voice->Attribute << 16) | FmcRvolCvol; 458 break; 459 case TRIDENT_DEVICE_ID_DX: 460 regs[4] |= ((voice->Vol & 0x000003fc) << (16-2)) | 461 (voice->EC & 0x00000fff); 462 regs[0] = (voice->CSO << 16) | ((voice->Alpha & 0x00000fff) << 4) | (voice->FMS & 0x0000000f); 463 regs[2] = (voice->ESO << 16) | (voice->Delta & 0x0ffff); 464 regs[3] = FmcRvolCvol; 465 break; 466 case TRIDENT_DEVICE_ID_NX: 467 regs[4] |= ((voice->Vol & 0x000003fc) << (16-2)) | 468 (voice->EC & 0x00000fff); 469 regs[0] = (voice->Delta << 24) | (voice->CSO & 0x00ffffff); 470 regs[2] = ((voice->Delta << 16) & 0xff000000) | (voice->ESO & 0x00ffffff); 471 regs[3] = (voice->Alpha << 20) | ((voice->FMS & 0x0000000f) << 16) | FmcRvolCvol; 472 break; 473 default: 474 snd_BUG(); 475 return; 476 } 477 478 outb(voice->number, TRID_REG(trident, T4D_LFO_GC_CIR)); 479 outl(regs[0], TRID_REG(trident, CH_START + 0)); 480 outl(regs[1], TRID_REG(trident, CH_START + 4)); 481 outl(regs[2], TRID_REG(trident, CH_START + 8)); 482 outl(regs[3], TRID_REG(trident, CH_START + 12)); 483 outl(regs[4], TRID_REG(trident, CH_START + 16)); 484 485 #if 0 486 printk("written %i channel:\n", voice->number); 487 printk(" regs[0] = 0x%x/0x%x\n", regs[0], inl(TRID_REG(trident, CH_START + 0))); 488 printk(" regs[1] = 0x%x/0x%x\n", regs[1], inl(TRID_REG(trident, CH_START + 4))); 489 printk(" regs[2] = 0x%x/0x%x\n", regs[2], inl(TRID_REG(trident, CH_START + 8))); 490 printk(" regs[3] = 0x%x/0x%x\n", regs[3], inl(TRID_REG(trident, CH_START + 12))); 491 printk(" regs[4] = 0x%x/0x%x\n", regs[4], inl(TRID_REG(trident, CH_START + 16))); 492 #endif 493 } 494 495 /*--------------------------------------------------------------------------- 496 snd_trident_write_cso_reg 497 498 Description: This routine will write the new CSO offset 499 register to hardware. 500 501 Paramters: trident - pointer to target device class for 4DWave. 502 voice - synthesizer voice structure 503 CSO - new CSO value 504 505 ---------------------------------------------------------------------------*/ 506 507 static void snd_trident_write_cso_reg(trident_t * trident, snd_trident_voice_t * voice, unsigned int CSO) 508 { 509 voice->CSO = CSO; 510 outb(voice->number, TRID_REG(trident, T4D_LFO_GC_CIR)); 511 if (trident->device != TRIDENT_DEVICE_ID_NX) { 512 outw(voice->CSO, TRID_REG(trident, CH_DX_CSO_ALPHA_FMS) + 2); 513 } else { 514 outl((voice->Delta << 24) | (voice->CSO & 0x00ffffff), TRID_REG(trident, CH_NX_DELTA_CSO)); 515 } 516 } 517 518 /*--------------------------------------------------------------------------- 519 snd_trident_write_eso_reg 520 521 Description: This routine will write the new ESO offset 522 register to hardware. 523 524 Paramters: trident - pointer to target device class for 4DWave. 525 voice - synthesizer voice structure 526 ESO - new ESO value 527 528 ---------------------------------------------------------------------------*/ 529 530 static void snd_trident_write_eso_reg(trident_t * trident, snd_trident_voice_t * voice, unsigned int ESO) 531 { 532 voice->ESO = ESO; 533 outb(voice->number, TRID_REG(trident, T4D_LFO_GC_CIR)); 534 if (trident->device != TRIDENT_DEVICE_ID_NX) { 535 outw(voice->ESO, TRID_REG(trident, CH_DX_ESO_DELTA) + 2); 536 } else { 537 outl(((voice->Delta << 16) & 0xff000000) | (voice->ESO & 0x00ffffff), TRID_REG(trident, CH_NX_DELTA_ESO)); 538 } 539 } 540 541 /*--------------------------------------------------------------------------- 542 snd_trident_write_vol_reg 543 544 Description: This routine will write the new voice volume 545 register to hardware. 546 547 Paramters: trident - pointer to target device class for 4DWave. 548 voice - synthesizer voice structure 549 Vol - new voice volume 550 551 ---------------------------------------------------------------------------*/ 552 553 static void snd_trident_write_vol_reg(trident_t * trident, snd_trident_voice_t * voice, unsigned int Vol) 554 { 555 voice->Vol = Vol; 556 outb(voice->number, TRID_REG(trident, T4D_LFO_GC_CIR)); 557 switch (trident->device) { 558 case TRIDENT_DEVICE_ID_DX: 559 case TRIDENT_DEVICE_ID_NX: 560 outb(voice->Vol >> 2, TRID_REG(trident, CH_GVSEL_PAN_VOL_CTRL_EC + 2)); 561 break; 562 case TRIDENT_DEVICE_ID_SI7018: 563 // printk("voice->Vol = 0x%x\n", voice->Vol); 564 outw((voice->CTRL << 12) | voice->Vol, TRID_REG(trident, CH_GVSEL_PAN_VOL_CTRL_EC)); 565 break; 566 } 567 } 568 569 /*--------------------------------------------------------------------------- 570 snd_trident_write_pan_reg 571 572 Description: This routine will write the new voice pan 573 register to hardware. 574 575 Paramters: trident - pointer to target device class for 4DWave. 576 voice - synthesizer voice structure 577 Pan - new pan value 578 579 ---------------------------------------------------------------------------*/ 580 581 static void snd_trident_write_pan_reg(trident_t * trident, snd_trident_voice_t * voice, unsigned int Pan) 582 { 583 voice->Pan = Pan; 584 outb(voice->number, TRID_REG(trident, T4D_LFO_GC_CIR)); 585 outb(((voice->GVSel & 0x01) << 7) | (voice->Pan & 0x7f), TRID_REG(trident, CH_GVSEL_PAN_VOL_CTRL_EC + 3)); 586 } 587 588 /*--------------------------------------------------------------------------- 589 snd_trident_write_rvol_reg 590 591 Description: This routine will write the new reverb volume 592 register to hardware. 593 594 Paramters: trident - pointer to target device class for 4DWave. 595 voice - synthesizer voice structure 596 RVol - new reverb volume 597 598 ---------------------------------------------------------------------------*/ 599 600 static void snd_trident_write_rvol_reg(trident_t * trident, snd_trident_voice_t * voice, unsigned int RVol) 601 { 602 voice->RVol = RVol; 603 outb(voice->number, TRID_REG(trident, T4D_LFO_GC_CIR)); 604 outw(((voice->FMC & 0x0003) << 14) | ((voice->RVol & 0x007f) << 7) | (voice->CVol & 0x007f), 605 TRID_REG(trident, trident->device == TRIDENT_DEVICE_ID_NX ? CH_NX_ALPHA_FMS_FMC_RVOL_CVOL : CH_DX_FMC_RVOL_CVOL)); 606 } 607 608 /*--------------------------------------------------------------------------- 609 snd_trident_write_cvol_reg 610 611 Description: This routine will write the new chorus volume 612 register to hardware. 613 614 Paramters: trident - pointer to target device class for 4DWave. 615 voice - synthesizer voice structure 616 CVol - new chorus volume 617 618 ---------------------------------------------------------------------------*/ 619 620 static void snd_trident_write_cvol_reg(trident_t * trident, snd_trident_voice_t * voice, unsigned int CVol) 621 { 622 voice->CVol = CVol; 623 outb(voice->number, TRID_REG(trident, T4D_LFO_GC_CIR)); 624 outw(((voice->FMC & 0x0003) << 14) | ((voice->RVol & 0x007f) << 7) | (voice->CVol & 0x007f), 625 TRID_REG(trident, trident->device == TRIDENT_DEVICE_ID_NX ? CH_NX_ALPHA_FMS_FMC_RVOL_CVOL : CH_DX_FMC_RVOL_CVOL)); 626 } 627 628 /*--------------------------------------------------------------------------- 629 snd_trident_convert_rate 630 631 Description: This routine converts rate in HZ to hardware delta value. 632 633 Paramters: trident - pointer to target device class for 4DWave. 634 rate - Real or Virtual channel number. 635 636 Returns: Delta value. 637 638 ---------------------------------------------------------------------------*/ 639 static unsigned int snd_trident_convert_rate(unsigned int rate) 640 { 641 unsigned int delta; 642 643 // We special case 44100 and 8000 since rounding with the equation 644 // does not give us an accurate enough value. For 11025 and 22050 645 // the equation gives us the best answer. All other frequencies will 646 // also use the equation. JDW 647 if (rate == 44100) 648 delta = 0xeb3; 649 else if (rate == 8000) 650 delta = 0x2ab; 651 else if (rate == 48000) 652 delta = 0x1000; 653 else 654 delta = (((rate << 12) + 24000) / 48000) & 0x0000ffff; 655 return delta; 656 } 657 658 /*--------------------------------------------------------------------------- 659 snd_trident_convert_adc_rate 660 661 Description: This routine converts rate in HZ to hardware delta value. 662 663 Paramters: trident - pointer to target device class for 4DWave. 664 rate - Real or Virtual channel number. 665 666 Returns: Delta value. 667 668 ---------------------------------------------------------------------------*/ 669 static unsigned int snd_trident_convert_adc_rate(unsigned int rate) 670 { 671 unsigned int delta; 672 673 // We special case 44100 and 8000 since rounding with the equation 674 // does not give us an accurate enough value. For 11025 and 22050 675 // the equation gives us the best answer. All other frequencies will 676 // also use the equation. JDW 677 if (rate == 44100) 678 delta = 0x116a; 679 else if (rate == 8000) 680 delta = 0x6000; 681 else if (rate == 48000) 682 delta = 0x1000; 683 else 684 delta = ((48000 << 12) / rate) & 0x0000ffff; 685 return delta; 686 } 687 688 /*--------------------------------------------------------------------------- 689 snd_trident_spurious_threshold 690 691 Description: This routine converts rate in HZ to spurious threshold. 692 693 Paramters: trident - pointer to target device class for 4DWave. 694 rate - Real or Virtual channel number. 695 696 Returns: Delta value. 697 698 ---------------------------------------------------------------------------*/ 699 static unsigned int snd_trident_spurious_threshold(unsigned int rate, unsigned int period_size) 700 { 701 unsigned int res = (rate * period_size) / 48000; 702 if (res < 64) 703 res = res / 2; 704 else 705 res -= 32; 706 return res; 707 } 708 709 /*--------------------------------------------------------------------------- 710 snd_trident_control_mode 711 712 Description: This routine returns a control mode for a PCM channel. 713 714 Paramters: trident - pointer to target device class for 4DWave. 715 substream - PCM substream 716 717 Returns: Control value. 718 719 ---------------------------------------------------------------------------*/ 720 static unsigned int snd_trident_control_mode(snd_pcm_substream_t *substream) 721 { 722 unsigned int CTRL; 723 snd_pcm_runtime_t *runtime = substream->runtime; 724 725 /* set ctrl mode 726 CTRL default: 8-bit (unsigned) mono, loop mode enabled 727 */ 728 CTRL = 0x00000001; 729 if (snd_pcm_format_width(runtime->format) == 16) 730 CTRL |= 0x00000008; // 16-bit data 731 if (snd_pcm_format_signed(runtime->format)) 732 CTRL |= 0x00000002; // signed data 733 if (runtime->channels > 1) 734 CTRL |= 0x00000004; // stereo data 735 return CTRL; 736 } 737 738 /* 739 * PCM part 740 */ 741 742 /*--------------------------------------------------------------------------- 743 snd_trident_ioctl 744 745 Description: Device I/O control handler for playback/capture parameters. 746 747 Paramters: substream - PCM substream class 748 cmd - what ioctl message to process 749 arg - additional message infoarg 750 751 Returns: Error status 752 753 ---------------------------------------------------------------------------*/ 754 755 static int snd_trident_ioctl(snd_pcm_substream_t * substream, 756 unsigned int cmd, 757 void *arg) 758 { 759 /* FIXME: it seems that with small periods the behaviour of 760 trident hardware is unpredictable and interrupt generator 761 is broken */ 762 return snd_pcm_lib_ioctl(substream, cmd, arg); 763 } 764 765 /*--------------------------------------------------------------------------- 766 snd_trident_allocate_pcm_mem 767 768 Description: Allocate PCM ring buffer for given substream 769 770 Parameters: substream - PCM substream class 771 hw_params - hardware parameters 772 773 Returns: Error status 774 775 ---------------------------------------------------------------------------*/ 776 777 static int snd_trident_allocate_pcm_mem(snd_pcm_substream_t * substream, 778 snd_pcm_hw_params_t * hw_params) 779 { 780 trident_t *trident = snd_pcm_substream_chip(substream); 781 snd_pcm_runtime_t *runtime = substream->runtime; 782 snd_trident_voice_t *voice = (snd_trident_voice_t *) runtime->private_data; 783 int err; 784 785 if ((err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params))) < 0) 786 return err; 787 if (trident->tlb.entries) { 788 if (err > 0) { /* change */ 789 if (voice->memblk) 790 snd_trident_free_pages(trident, voice->memblk); 791 voice->memblk = snd_trident_alloc_pages(trident, substream); 792 if (voice->memblk == NULL) 793 return -ENOMEM; 794 } 795 } 796 return 0; 797 } 798 799 /*--------------------------------------------------------------------------- 800 snd_trident_allocate_evoice 801 802 Description: Allocate extra voice as interrupt generator 803 804 Parameters: substream - PCM substream class 805 hw_params - hardware parameters 806 807 Returns: Error status 808 809 ---------------------------------------------------------------------------*/ 810 811 static int snd_trident_allocate_evoice(snd_pcm_substream_t * substream, 812 snd_pcm_hw_params_t * hw_params) 813 { 814 trident_t *trident = snd_pcm_substream_chip(substream); 815 snd_pcm_runtime_t *runtime = substream->runtime; 816 snd_trident_voice_t *voice = (snd_trident_voice_t *) runtime->private_data; 817 snd_trident_voice_t *evoice = voice->extra; 818 819 /* voice management */ 820 821 if (params_buffer_size(hw_params) / 2 != params_period_size(hw_params)) { 822 if (evoice == NULL) { 823 evoice = snd_trident_alloc_voice(trident, SNDRV_TRIDENT_VOICE_TYPE_PCM, 0, 0); 824 if (evoice == NULL) 825 return -ENOMEM; 826 voice->extra = evoice; 827 evoice->substream = substream; 828 } 829 } else { 830 if (evoice != NULL) { 831 snd_trident_free_voice(trident, evoice); 832 voice->extra = evoice = NULL; 833 } 834 } 835 836 return 0; 837 } 838 839 /*--------------------------------------------------------------------------- 840 snd_trident_hw_params 841 842 Description: Set the hardware parameters for the playback device. 843 844 Parameters: substream - PCM substream class 845 hw_params - hardware parameters 846 847 Returns: Error status 848 849 ---------------------------------------------------------------------------*/ 850 851 static int snd_trident_hw_params(snd_pcm_substream_t * substream, 852 snd_pcm_hw_params_t * hw_params) 853 { 854 int err; 855 856 err = snd_trident_allocate_pcm_mem(substream, hw_params); 857 if (err >= 0) 858 err = snd_trident_allocate_evoice(substream, hw_params); 859 return err; 860 } 861 862 /*--------------------------------------------------------------------------- 863 snd_trident_playback_hw_free 864 865 Description: Release the hardware resources for the playback device. 866 867 Parameters: substream - PCM substream class 868 869 Returns: Error status 870 871 ---------------------------------------------------------------------------*/ 872 873 static int snd_trident_hw_free(snd_pcm_substream_t * substream) 874 { 875 trident_t *trident = snd_pcm_substream_chip(substream); 876 snd_pcm_runtime_t *runtime = substream->runtime; 877 snd_trident_voice_t *voice = (snd_trident_voice_t *) runtime->private_data; 878 snd_trident_voice_t *evoice = voice ? voice->extra : NULL; 879 880 if (trident->tlb.entries) { 881 if (voice && voice->memblk) { 882 snd_trident_free_pages(trident, voice->memblk); 883 voice->memblk = NULL; 884 } 885 } 886 snd_pcm_lib_free_pages(substream); 887 if (evoice != NULL) { 888 snd_trident_free_voice(trident, evoice); 889 voice->extra = NULL; 890 } 891 return 0; 892 } 893 894 /*--------------------------------------------------------------------------- 895 snd_trident_playback_prepare 896 897 Description: Prepare playback device for playback. 898 899 Parameters: substream - PCM substream class 900 901 Returns: Error status 902 903 ---------------------------------------------------------------------------*/ 904 905 static int snd_trident_playback_prepare(snd_pcm_substream_t * substream) 906 { 907 trident_t *trident = snd_pcm_substream_chip(substream); 908 snd_pcm_runtime_t *runtime = substream->runtime; 909 snd_trident_voice_t *voice = (snd_trident_voice_t *) runtime->private_data; 910 snd_trident_voice_t *evoice = voice->extra; 911 snd_trident_pcm_mixer_t *mix = &trident->pcm_mixer[substream->number]; 912 913 spin_lock_irq(&trident->reg_lock); 914 915 /* set delta (rate) value */ 916 voice->Delta = snd_trident_convert_rate(runtime->rate); 917 voice->spurious_threshold = snd_trident_spurious_threshold(runtime->rate, runtime->period_size); 918 919 /* set Loop Begin Address */ 920 if (voice->memblk) 921 voice->LBA = voice->memblk->offset; 922 else 923 voice->LBA = runtime->dma_addr; 924 925 voice->CSO = 0; 926 voice->ESO = runtime->buffer_size - 1; /* in samples */ 927 voice->CTRL = snd_trident_control_mode(substream); 928 voice->FMC = 3; 929 voice->GVSel = 1; 930 voice->EC = 0; 931 voice->Alpha = 0; 932 voice->FMS = 0; 933 voice->Vol = mix->vol; 934 voice->RVol = mix->rvol; 935 voice->CVol = mix->cvol; 936 voice->Pan = mix->pan; 937 voice->Attribute = 0; 938 #if 0 939 voice->Attribute = (1<<(30-16))|(2<<(26-16))| 940 (0<<(24-16))|(0x1f<<(19-16)); 941 #else 942 voice->Attribute = 0; 943 #endif 944 945 snd_trident_write_voice_regs(trident, voice); 946 947 if (evoice != NULL) { 948 evoice->Delta = voice->Delta; 949 evoice->spurious_threshold = voice->spurious_threshold; 950 evoice->LBA = voice->LBA; 951 evoice->CSO = 0; 952 evoice->ESO = (runtime->period_size * 2) + 4 - 1; /* in samples */ 953 evoice->CTRL = voice->CTRL; 954 evoice->FMC = 3; 955 evoice->GVSel = trident->device == TRIDENT_DEVICE_ID_SI7018 ? 0 : 1; 956 evoice->EC = 0; 957 evoice->Alpha = 0; 958 evoice->FMS = 0; 959 evoice->Vol = 0x3ff; /* mute */ 960 evoice->RVol = evoice->CVol = 0x7f; /* mute */ 961 evoice->Pan = 0x7f; /* mute */ 962 #if 0 963 evoice->Attribute = (1<<(30-16))|(2<<(26-16))| 964 (0<<(24-16))|(0x1f<<(19-16)); 965 #else 966 evoice->Attribute = 0; 967 #endif 968 snd_trident_write_voice_regs(trident, evoice); 969 evoice->isync2 = 1; 970 evoice->isync_mark = runtime->period_size; 971 evoice->ESO = (runtime->period_size * 2) - 1; 972 } 973 974 spin_unlock_irq(&trident->reg_lock); 975 976 return 0; 977 } 978 979 /*--------------------------------------------------------------------------- 980 snd_trident_capture_hw_params 981 982 Description: Set the hardware parameters for the capture device. 983 984 Parameters: substream - PCM substream class 985 hw_params - hardware parameters 986 987 Returns: Error status 988 989 ---------------------------------------------------------------------------*/ 990 991 static int snd_trident_capture_hw_params(snd_pcm_substream_t * substream, 992 snd_pcm_hw_params_t * hw_params) 993 { 994 return snd_trident_allocate_pcm_mem(substream, hw_params); 995 } 996 997 /*--------------------------------------------------------------------------- 998 snd_trident_capture_prepare 999 1000 Description: Prepare capture device for playback. 1001 1002 Parameters: substream - PCM substream class 1003 1004 Returns: Error status 1005 1006 ---------------------------------------------------------------------------*/ 1007 1008 static int snd_trident_capture_prepare(snd_pcm_substream_t * substream) 1009 { 1010 trident_t *trident = snd_pcm_substream_chip(substream); 1011 snd_pcm_runtime_t *runtime = substream->runtime; 1012 snd_trident_voice_t *voice = (snd_trident_voice_t *) runtime->private_data; 1013 unsigned int val, ESO_bytes; 1014 1015 spin_lock_irq(&trident->reg_lock); 1016 1017 // Initilize the channel and set channel Mode 1018 outb(0, TRID_REG(trident, LEGACY_DMAR15)); 1019 1020 // Set DMA channel operation mode register 1021 outb(0x54, TRID_REG(trident, LEGACY_DMAR11)); 1022 1023 // Set channel buffer Address, DMAR0 expects contiguous PCI memory area 1024 voice->LBA = runtime->dma_addr; 1025 outl(voice->LBA, TRID_REG(trident, LEGACY_DMAR0)); 1026 if (voice->memblk) 1027 voice->LBA = voice->memblk->offset; 1028 1029 // set ESO 1030 ESO_bytes = snd_pcm_lib_buffer_bytes(substream) - 1; 1031 outb((ESO_bytes & 0x00ff0000) >> 16, TRID_REG(trident, LEGACY_DMAR6)); 1032 outw((ESO_bytes & 0x0000ffff), TRID_REG(trident, LEGACY_DMAR4)); 1033 ESO_bytes++; 1034 1035 // Set channel sample rate, 4.12 format 1036 val = (((unsigned int) 48000L << 12) + (runtime->rate/2)) / runtime->rate; 1037 outw(val, TRID_REG(trident, T4D_SBDELTA_DELTA_R)); 1038 1039 // Set channel interrupt blk length 1040 if (snd_pcm_format_width(runtime->format) == 16) { 1041 val = (unsigned short) ((ESO_bytes >> 1) - 1); 1042 } else { 1043 val = (unsigned short) (ESO_bytes - 1); 1044 } 1045 1046 outl((val << 16) | val, TRID_REG(trident, T4D_SBBL_SBCL)); 1047 1048 // Right now, set format and start to run captureing, 1049 // continuous run loop enable. 1050 trident->bDMAStart = 0x19; // 0001 1001b 1051 1052 if (snd_pcm_format_width(runtime->format) == 16) 1053 trident->bDMAStart |= 0x80; 1054 if (snd_pcm_format_signed(runtime->format)) 1055 trident->bDMAStart |= 0x20; 1056 if (runtime->channels > 1) 1057 trident->bDMAStart |= 0x40; 1058 1059 // Prepare capture intr channel 1060 1061 voice->Delta = snd_trident_convert_rate(runtime->rate); 1062 voice->spurious_threshold = snd_trident_spurious_threshold(runtime->rate, runtime->period_size); 1063 voice->isync = 1; 1064 voice->isync_mark = runtime->period_size; 1065 voice->isync_max = runtime->buffer_size; 1066 1067 // Set voice parameters 1068 voice->CSO = 0; 1069 voice->ESO = voice->isync_ESO = (runtime->period_size * 2) + 6 - 1; 1070 voice->CTRL = snd_trident_control_mode(substream); 1071 voice->FMC = 3; 1072 voice->RVol = 0x7f; 1073 voice->CVol = 0x7f; 1074 voice->GVSel = 1; 1075 voice->Pan = 0x7f; /* mute */ 1076 voice->Vol = 0x3ff; /* mute */ 1077 voice->EC = 0; 1078 voice->Alpha = 0; 1079 voice->FMS = 0; 1080 voice->Attribute = 0; 1081 1082 snd_trident_write_voice_regs(trident, voice); 1083 1084 spin_unlock_irq(&trident->reg_lock); 1085 return 0; 1086 } 1087 1088 /*--------------------------------------------------------------------------- 1089 snd_trident_si7018_capture_hw_params 1090 1091 Description: Set the hardware parameters for the capture device. 1092 1093 Parameters: substream - PCM substream class 1094 hw_params - hardware parameters 1095 1096 Returns: Error status 1097 1098 ---------------------------------------------------------------------------*/ 1099 1100 static int snd_trident_si7018_capture_hw_params(snd_pcm_substream_t * substream, 1101 snd_pcm_hw_params_t * hw_params) 1102 { 1103 int err; 1104 1105 if ((err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params))) < 0) 1106 return err; 1107 1108 return snd_trident_allocate_evoice(substream, hw_params); 1109 } 1110 1111 /*--------------------------------------------------------------------------- 1112 snd_trident_si7018_capture_hw_free 1113 1114 Description: Release the hardware resources for the capture device. 1115 1116 Parameters: substream - PCM substream class 1117 1118 Returns: Error status 1119 1120 ---------------------------------------------------------------------------*/ 1121 1122 static int snd_trident_si7018_capture_hw_free(snd_pcm_substream_t * substream) 1123 { 1124 trident_t *trident = snd_pcm_substream_chip(substream); 1125 snd_pcm_runtime_t *runtime = substream->runtime; 1126 snd_trident_voice_t *voice = (snd_trident_voice_t *) runtime->private_data; 1127 snd_trident_voice_t *evoice = voice ? voice->extra : NULL; 1128 1129 snd_pcm_lib_free_pages(substream); 1130 if (evoice != NULL) { 1131 snd_trident_free_voice(trident, evoice); 1132 voice->extra = NULL; 1133 } 1134 return 0; 1135 } 1136 1137 /*--------------------------------------------------------------------------- 1138 snd_trident_si7018_capture_prepare 1139 1140 Description: Prepare capture device for playback. 1141 1142 Parameters: substream - PCM substream class 1143 1144 Returns: Error status 1145 1146 ---------------------------------------------------------------------------*/ 1147 1148 static int snd_trident_si7018_capture_prepare(snd_pcm_substream_t * substream) 1149 { 1150 trident_t *trident = snd_pcm_substream_chip(substream); 1151 snd_pcm_runtime_t *runtime = substream->runtime; 1152 snd_trident_voice_t *voice = (snd_trident_voice_t *) runtime->private_data; 1153 snd_trident_voice_t *evoice = voice->extra; 1154 1155 spin_lock_irq(&trident->reg_lock); 1156 1157 voice->LBA = runtime->dma_addr; 1158 voice->Delta = snd_trident_convert_adc_rate(runtime->rate); 1159 voice->spurious_threshold = snd_trident_spurious_threshold(runtime->rate, runtime->period_size); 1160 1161 // Set voice parameters 1162 voice->CSO = 0; 1163 voice->ESO = runtime->buffer_size - 1; /* in samples */ 1164 voice->CTRL = snd_trident_control_mode(substream); 1165 voice->FMC = 0; 1166 voice->RVol = 0; 1167 voice->CVol = 0; 1168 voice->GVSel = 1; 1169 voice->Pan = T4D_DEFAULT_PCM_PAN; 1170 voice->Vol = 0; 1171 voice->EC = 0; 1172 voice->Alpha = 0; 1173 voice->FMS = 0; 1174 1175 voice->Attribute = (2 << (30-16)) | 1176 (2 << (26-16)) | 1177 (2 << (24-16)) | 1178 (1 << (23-16)); 1179 1180 snd_trident_write_voice_regs(trident, voice); 1181 1182 if (evoice != NULL) { 1183 evoice->Delta = snd_trident_convert_rate(runtime->rate); 1184 evoice->spurious_threshold = voice->spurious_threshold; 1185 evoice->LBA = voice->LBA; 1186 evoice->CSO = 0; 1187 evoice->ESO = (runtime->period_size * 2) + 20 - 1; /* in samples, 20 means correction */ 1188 evoice->CTRL = voice->CTRL; 1189 evoice->FMC = 3; 1190 evoice->GVSel = 0; 1191 evoice->EC = 0; 1192 evoice->Alpha = 0; 1193 evoice->FMS = 0; 1194 evoice->Vol = 0x3ff; /* mute */ 1195 evoice->RVol = evoice->CVol = 0x7f; /* mute */ 1196 evoice->Pan = 0x7f; /* mute */ 1197 evoice->Attribute = 0; 1198 snd_trident_write_voice_regs(trident, evoice); 1199 evoice->isync2 = 1; 1200 evoice->isync_mark = runtime->period_size; 1201 evoice->ESO = (runtime->period_size * 2) - 1; 1202 } 1203 1204 spin_unlock_irq(&trident->reg_lock); 1205 return 0; 1206 } 1207 1208 /*--------------------------------------------------------------------------- 1209 snd_trident_foldback_prepare 1210 1211 Description: Prepare foldback capture device for playback. 1212 1213 Parameters: substream - PCM substream class 1214 1215 Returns: Error status 1216 1217 ---------------------------------------------------------------------------*/ 1218 1219 static int snd_trident_foldback_prepare(snd_pcm_substream_t * substream) 1220 { 1221 trident_t *trident = snd_pcm_substream_chip(substream); 1222 snd_pcm_runtime_t *runtime = substream->runtime; 1223 snd_trident_voice_t *voice = (snd_trident_voice_t *) runtime->private_data; 1224 snd_trident_voice_t *evoice = voice->extra; 1225 1226 spin_lock_irq(&trident->reg_lock); 1227 1228 /* Set channel buffer Address */ 1229 if (voice->memblk) 1230 voice->LBA = voice->memblk->offset; 1231 else 1232 voice->LBA = runtime->dma_addr; 1233 1234 /* set target ESO for channel */ 1235 voice->ESO = runtime->buffer_size - 1; /* in samples */ 1236 1237 /* set sample rate */ 1238 voice->Delta = 0x1000; 1239 voice->spurious_threshold = snd_trident_spurious_threshold(48000, runtime->period_size); 1240 1241 voice->CSO = 0; 1242 voice->CTRL = snd_trident_control_mode(substream); 1243 voice->FMC = 3; 1244 voice->RVol = 0x7f; 1245 voice->CVol = 0x7f; 1246 voice->GVSel = 1; 1247 voice->Pan = 0x7f; /* mute */ 1248 voice->Vol = 0x3ff; /* mute */ 1249 voice->EC = 0; 1250 voice->Alpha = 0; 1251 voice->FMS = 0; 1252 voice->Attribute = 0; 1253 1254 /* set up capture channel */ 1255 outb(((voice->number & 0x3f) | 0x80), TRID_REG(trident, T4D_RCI + voice->foldback_chan)); 1256 1257 snd_trident_write_voice_regs(trident, voice); 1258 1259 if (evoice != NULL) { 1260 evoice->Delta = voice->Delta; 1261 evoice->spurious_threshold = voice->spurious_threshold; 1262 evoice->LBA = voice->LBA; 1263 evoice->CSO = 0; 1264 evoice->ESO = (runtime->period_size * 2) + 4 - 1; /* in samples */ 1265 evoice->CTRL = voice->CTRL; 1266 evoice->FMC = 3; 1267 evoice->GVSel = trident->device == TRIDENT_DEVICE_ID_SI7018 ? 0 : 1; 1268 evoice->EC = 0; 1269 evoice->Alpha = 0; 1270 evoice->FMS = 0; 1271 evoice->Vol = 0x3ff; /* mute */ 1272 evoice->RVol = evoice->CVol = 0x7f; /* mute */ 1273 evoice->Pan = 0x7f; /* mute */ 1274 evoice->Attribute = 0; 1275 snd_trident_write_voice_regs(trident, evoice); 1276 evoice->isync2 = 1; 1277 evoice->isync_mark = runtime->period_size; 1278 evoice->ESO = (runtime->period_size * 2) - 1; 1279 } 1280 1281 spin_unlock_irq(&trident->reg_lock); 1282 return 0; 1283 } 1284 1285 /*--------------------------------------------------------------------------- 1286 snd_trident_spdif_hw_params 1287 1288 Description: Set the hardware parameters for the spdif device. 1289 1290 Parameters: substream - PCM substream class 1291 hw_params - hardware parameters 1292 1293 Returns: Error status 1294 1295 ---------------------------------------------------------------------------*/ 1296 1297 static int snd_trident_spdif_hw_params(snd_pcm_substream_t * substream, 1298 snd_pcm_hw_params_t * hw_params) 1299 { 1300 trident_t *trident = snd_pcm_substream_chip(substream); 1301 unsigned int old_bits = 0, change = 0; 1302 int err; 1303 1304 err = snd_trident_allocate_pcm_mem(substream, hw_params); 1305 if (err < 0) 1306 return err; 1307 1308 if (trident->device == TRIDENT_DEVICE_ID_SI7018) { 1309 err = snd_trident_allocate_evoice(substream, hw_params); 1310 if (err < 0) 1311 return err; 1312 } 1313 1314 /* prepare SPDIF channel */ 1315 spin_lock_irq(&trident->reg_lock); 1316 old_bits = trident->spdif_pcm_bits; 1317 if (old_bits & IEC958_AES0_PROFESSIONAL) 1318 trident->spdif_pcm_bits &= ~IEC958_AES0_PRO_FS; 1319 else 1320 trident->spdif_pcm_bits &= ~(IEC958_AES3_CON_FS << 24); 1321 if (params_rate(hw_params) >= 48000) { 1322 trident->spdif_pcm_ctrl = 0x3c; // 48000 Hz 1323 trident->spdif_pcm_bits |= 1324 trident->spdif_bits & IEC958_AES0_PROFESSIONAL ? 1325 IEC958_AES0_PRO_FS_48000 : 1326 (IEC958_AES3_CON_FS_48000 << 24); 1327 } 1328 else if (params_rate(hw_params) >= 44100) { 1329 trident->spdif_pcm_ctrl = 0x3e; // 44100 Hz 1330 trident->spdif_pcm_bits |= 1331 trident->spdif_bits & IEC958_AES0_PROFESSIONAL ? 1332 IEC958_AES0_PRO_FS_44100 : 1333 (IEC958_AES3_CON_FS_44100 << 24); 1334 } 1335 else { 1336 trident->spdif_pcm_ctrl = 0x3d; // 32000 Hz 1337 trident->spdif_pcm_bits |= 1338 trident->spdif_bits & IEC958_AES0_PROFESSIONAL ? 1339 IEC958_AES0_PRO_FS_32000 : 1340 (IEC958_AES3_CON_FS_32000 << 24); 1341 } 1342 change = old_bits != trident->spdif_pcm_bits; 1343 spin_unlock_irq(&trident->reg_lock); 1344 1345 if (change) 1346 snd_ctl_notify(trident->card, SNDRV_CTL_EVENT_MASK_VALUE, &trident->spdif_pcm_ctl->id); 1347 1348 return 0; 1349 } 1350 1351 /*--------------------------------------------------------------------------- 1352 snd_trident_spdif_prepare 1353 1354 Description: Prepare SPDIF device for playback. 1355 1356 Parameters: substream - PCM substream class 1357 1358 Returns: Error status 1359 1360 ---------------------------------------------------------------------------*/ 1361 1362 static int snd_trident_spdif_prepare(snd_pcm_substream_t * substream) 1363 { 1364 trident_t *trident = snd_pcm_substream_chip(substream); 1365 snd_pcm_runtime_t *runtime = substream->runtime; 1366 snd_trident_voice_t *voice = (snd_trident_voice_t *) runtime->private_data; 1367 snd_trident_voice_t *evoice = voice->extra; 1368 snd_trident_pcm_mixer_t *mix = &trident->pcm_mixer[substream->number]; 1369 unsigned int RESO, LBAO; 1370 unsigned int temp; 1371 1372 spin_lock_irq(&trident->reg_lock); 1373 1374 if (trident->device != TRIDENT_DEVICE_ID_SI7018) { 1375 1376 /* set delta (rate) value */ 1377 voice->Delta = snd_trident_convert_rate(runtime->rate); 1378 voice->spurious_threshold = snd_trident_spurious_threshold(runtime->rate, runtime->period_size); 1379 1380 /* set Loop Back Address */ 1381 LBAO = runtime->dma_addr; 1382 if (voice->memblk) 1383 voice->LBA = voice->memblk->offset; 1384 else 1385 voice->LBA = LBAO; 1386 1387 voice->isync = 1; 1388 voice->isync3 = 1; 1389 voice->isync_mark = runtime->period_size; 1390 voice->isync_max = runtime->buffer_size; 1391 1392 /* set target ESO for channel */ 1393 RESO = runtime->buffer_size - 1; 1394 voice->ESO = voice->isync_ESO = (runtime->period_size * 2) + 6 - 1; 1395 1396 /* set ctrl mode */ 1397 voice->CTRL = snd_trident_control_mode(substream); 1398 1399 voice->FMC = 3; 1400 voice->RVol = 0x7f; 1401 voice->CVol = 0x7f; 1402 voice->GVSel = 1; 1403 voice->Pan = 0x7f; 1404 voice->Vol = 0x3ff; 1405 voice->EC = 0; 1406 voice->CSO = 0; 1407 voice->Alpha = 0; 1408 voice->FMS = 0; 1409 voice->Attribute = 0; 1410 1411 /* prepare surrogate IRQ channel */ 1412 snd_trident_write_voice_regs(trident, voice); 1413 1414 outw((RESO & 0xffff), TRID_REG(trident, NX_SPESO)); 1415 outb((RESO >> 16), TRID_REG(trident, NX_SPESO + 2)); 1416 outl((LBAO & 0xfffffffc), TRID_REG(trident, NX_SPLBA)); 1417 outw((voice->CSO & 0xffff), TRID_REG(trident, NX_SPCTRL_SPCSO)); 1418 outb((voice->CSO >> 16), TRID_REG(trident, NX_SPCTRL_SPCSO + 2)); 1419 1420 /* set SPDIF setting */ 1421 outb(trident->spdif_pcm_ctrl, TRID_REG(trident, NX_SPCTRL_SPCSO + 3)); 1422 outl(trident->spdif_pcm_bits, TRID_REG(trident, NX_SPCSTATUS)); 1423 1424 } else { /* SiS */ 1425 1426 /* set delta (rate) value */ 1427 voice->Delta = 0x800; 1428 voice->spurious_threshold = snd_trident_spurious_threshold(48000, runtime->period_size); 1429 1430 /* set Loop Begin Address */ 1431 if (voice->memblk) 1432 voice->LBA = voice->memblk->offset; 1433 else 1434 voice->LBA = runtime->dma_addr; 1435 1436 voice->CSO = 0; 1437 voice->ESO = runtime->buffer_size - 1; /* in samples */ 1438 voice->CTRL = snd_trident_control_mode(substream); 1439 voice->FMC = 3; 1440 voice->GVSel = 1; 1441 voice->EC = 0; 1442 voice->Alpha = 0; 1443 voice->FMS = 0; 1444 voice->Vol = mix->vol; 1445 voice->RVol = mix->rvol; 1446 voice->CVol = mix->cvol; 1447 voice->Pan = mix->pan; 1448 voice->Attribute = (1<<(30-16))|(7<<(26-16))| 1449 (0<<(24-16))|(0<<(19-16)); 1450 1451 snd_trident_write_voice_regs(trident, voice); 1452 1453 if (evoice != NULL) { 1454 evoice->Delta = voice->Delta; 1455 evoice->spurious_threshold = voice->spurious_threshold; 1456 evoice->LBA = voice->LBA; 1457 evoice->CSO = 0; 1458 evoice->ESO = (runtime->period_size * 2) + 4 - 1; /* in samples */ 1459 evoice->CTRL = voice->CTRL; 1460 evoice->FMC = 3; 1461 evoice->GVSel = trident->device == TRIDENT_DEVICE_ID_SI7018 ? 0 : 1; 1462 evoice->EC = 0; 1463 evoice->Alpha = 0; 1464 evoice->FMS = 0; 1465 evoice->Vol = 0x3ff; /* mute */ 1466 evoice->RVol = evoice->CVol = 0x7f; /* mute */ 1467 evoice->Pan = 0x7f; /* mute */ 1468 evoice->Attribute = 0; 1469 snd_trident_write_voice_regs(trident, evoice); 1470 evoice->isync2 = 1; 1471 evoice->isync_mark = runtime->period_size; 1472 evoice->ESO = (runtime->period_size * 2) - 1; 1473 } 1474 1475 outl(trident->spdif_pcm_bits, TRID_REG(trident, SI_SPDIF_CS)); 1476 temp = inl(TRID_REG(trident, T4D_LFO_GC_CIR)); 1477 temp &= ~(1<<19); 1478 outl(temp, TRID_REG(trident, T4D_LFO_GC_CIR)); 1479 temp = inl(TRID_REG(trident, SI_SERIAL_INTF_CTRL)); 1480 temp |= SPDIF_EN; 1481 outl(temp, TRID_REG(trident, SI_SERIAL_INTF_CTRL)); 1482 } 1483 1484 spin_unlock_irq(&trident->reg_lock); 1485 1486 return 0; 1487 } 1488 1489 /*--------------------------------------------------------------------------- 1490 snd_trident_trigger 1491 1492 Description: Start/stop devices 1493 1494 Parameters: substream - PCM substream class 1495 cmd - trigger command (STOP, GO) 1496 1497 Returns: Error status 1498 1499 ---------------------------------------------------------------------------*/ 1500 1501 static int snd_trident_trigger(snd_pcm_substream_t *substream, 1502 int cmd) 1503 1504 { 1505 trident_t *trident = snd_pcm_substream_chip(substream); 1506 struct list_head *pos; 1507 snd_pcm_substream_t *s; 1508 unsigned int what, whati, capture_flag, spdif_flag; 1509 snd_trident_voice_t *voice, *evoice; 1510 unsigned int val, go; 1511 1512 switch (cmd) { 1513 case SNDRV_PCM_TRIGGER_START: 1514 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 1515 case SNDRV_PCM_TRIGGER_RESUME: 1516 go = 1; 1517 break; 1518 case SNDRV_PCM_TRIGGER_STOP: 1519 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 1520 case SNDRV_PCM_TRIGGER_SUSPEND: 1521 go = 0; 1522 break; 1523 default: 1524 return -EINVAL; 1525 } 1526 what = whati = capture_flag = spdif_flag = 0; 1527 spin_lock(&trident->reg_lock); 1528 val = inl(TRID_REG(trident, T4D_STIMER)) & 0x00ffffff; 1529 snd_pcm_group_for_each(pos, substream) { 1530 s = snd_pcm_group_substream_entry(pos); 1531 if ((trident_t *) snd_pcm_substream_chip(s) == trident) { 1532 voice = (snd_trident_voice_t *) s->runtime->private_data; 1533 evoice = voice->extra; 1534 what |= 1 << (voice->number & 0x1f); 1535 if (evoice == NULL) { 1536 whati |= 1 << (voice->number & 0x1f); 1537 } else { 1538 what |= 1 << (evoice->number & 0x1f); 1539 whati |= 1 << (evoice->number & 0x1f); 1540 if (go) 1541 evoice->stimer = val; 1542 } 1543 if (go) { 1544 voice->running = 1; 1545 voice->stimer = val; 1546 } else { 1547 voice->running = 0; 1548 } 1549 snd_pcm_trigger_done(s, substream); 1550 if (voice->capture) 1551 capture_flag = 1; 1552 if (voice->spdif) 1553 spdif_flag = 1; 1554 } 1555 } 1556 if (spdif_flag) { 1557 if (trident->device != TRIDENT_DEVICE_ID_SI7018) { 1558 outl(trident->spdif_pcm_bits, TRID_REG(trident, NX_SPCSTATUS)); 1559 outb(trident->spdif_pcm_ctrl, TRID_REG(trident, NX_SPCTRL_SPCSO + 3)); 1560 } else { 1561 outl(trident->spdif_pcm_bits, TRID_REG(trident, SI_SPDIF_CS)); 1562 val = inl(TRID_REG(trident, SI_SERIAL_INTF_CTRL)) | SPDIF_EN; 1563 outl(val, TRID_REG(trident, SI_SERIAL_INTF_CTRL)); 1564 } 1565 } 1566 if (!go) 1567 outl(what, TRID_REG(trident, T4D_STOP_B)); 1568 val = inl(TRID_REG(trident, T4D_AINTEN_B)); 1569 if (go) { 1570 val |= whati; 1571 } else { 1572 val &= ~whati; 1573 } 1574 outl(val, TRID_REG(trident, T4D_AINTEN_B)); 1575 if (go) { 1576 outl(what, TRID_REG(trident, T4D_START_B)); 1577 1578 if (capture_flag && trident->device != TRIDENT_DEVICE_ID_SI7018) 1579 outb(trident->bDMAStart, TRID_REG(trident, T4D_SBCTRL_SBE2R_SBDD)); 1580 } else { 1581 if (capture_flag && trident->device != TRIDENT_DEVICE_ID_SI7018) 1582 outb(0x00, TRID_REG(trident, T4D_SBCTRL_SBE2R_SBDD)); 1583 } 1584 spin_unlock(&trident->reg_lock); 1585 return 0; 1586 } 1587 1588 /*--------------------------------------------------------------------------- 1589 snd_trident_playback_pointer 1590 1591 Description: This routine return the playback position 1592 1593 Parameters: substream - PCM substream class 1594 1595 Returns: position of buffer 1596 1597 ---------------------------------------------------------------------------*/ 1598 1599 static snd_pcm_uframes_t snd_trident_playback_pointer(snd_pcm_substream_t * substream) 1600 { 1601 trident_t *trident = snd_pcm_substream_chip(substream); 1602 snd_pcm_runtime_t *runtime = substream->runtime; 1603 snd_trident_voice_t *voice = (snd_trident_voice_t *) runtime->private_data; 1604 unsigned int cso; 1605 1606 if (!voice->running) 1607 return 0; 1608 1609 spin_lock(&trident->reg_lock); 1610 1611 outb(voice->number, TRID_REG(trident, T4D_LFO_GC_CIR)); 1612 1613 if (trident->device != TRIDENT_DEVICE_ID_NX) { 1614 cso = inw(TRID_REG(trident, CH_DX_CSO_ALPHA_FMS + 2)); 1615 } else { // ID_4DWAVE_NX 1616 cso = (unsigned int) inl(TRID_REG(trident, CH_NX_DELTA_CSO)) & 0x00ffffff; 1617 } 1618 1619 spin_unlock(&trident->reg_lock); 1620 1621 if (cso >= runtime->buffer_size) 1622 cso = 0; 1623 1624 return cso; 1625 } 1626 1627 /*--------------------------------------------------------------------------- 1628 snd_trident_capture_pointer 1629 1630 Description: This routine return the capture position 1631 1632 Paramters: pcm1 - PCM device class 1633 1634 Returns: position of buffer 1635 1636 ---------------------------------------------------------------------------*/ 1637 1638 static snd_pcm_uframes_t snd_trident_capture_pointer(snd_pcm_substream_t * substream) 1639 { 1640 trident_t *trident = snd_pcm_substream_chip(substream); 1641 snd_pcm_runtime_t *runtime = substream->runtime; 1642 snd_trident_voice_t *voice = (snd_trident_voice_t *) runtime->private_data; 1643 unsigned int result; 1644 1645 if (!voice->running) 1646 return 0; 1647 1648 result = inw(TRID_REG(trident, T4D_SBBL_SBCL)); 1649 if (runtime->channels > 1) 1650 result >>= 1; 1651 if (result > 0) 1652 result = runtime->buffer_size - result; 1653 1654 return result; 1655 } 1656 1657 /*--------------------------------------------------------------------------- 1658 snd_trident_spdif_pointer 1659 1660 Description: This routine return the SPDIF playback position 1661 1662 Parameters: substream - PCM substream class 1663 1664 Returns: position of buffer 1665 1666 ---------------------------------------------------------------------------*/ 1667 1668 static snd_pcm_uframes_t snd_trident_spdif_pointer(snd_pcm_substream_t * substream) 1669 { 1670 trident_t *trident = snd_pcm_substream_chip(substream); 1671 snd_pcm_runtime_t *runtime = substream->runtime; 1672 snd_trident_voice_t *voice = (snd_trident_voice_t *) runtime->private_data; 1673 unsigned int result; 1674 1675 if (!voice->running) 1676 return 0; 1677 1678 result = inl(TRID_REG(trident, NX_SPCTRL_SPCSO)) & 0x00ffffff; 1679 1680 return result; 1681 } 1682 1683 /* 1684 * Playback support device description 1685 */ 1686 1687 static snd_pcm_hardware_t snd_trident_playback = 1688 { 1689 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | 1690 SNDRV_PCM_INFO_BLOCK_TRANSFER | 1691 SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_SYNC_START | 1692 SNDRV_PCM_INFO_PAUSE /* | SNDRV_PCM_INFO_RESUME */), 1693 .formats = (SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE | 1694 SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U16_LE), 1695 .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000, 1696 .rate_min = 4000, 1697 .rate_max = 48000, 1698 .channels_min = 1, 1699 .channels_max = 2, 1700 .buffer_bytes_max = (256*1024), 1701 .period_bytes_min = 64, 1702 .period_bytes_max = (256*1024), 1703 .periods_min = 1, 1704 .periods_max = 1024, 1705 .fifo_size = 0, 1706 }; 1707 1708 /* 1709 * Capture support device description 1710 */ 1711 1712 static snd_pcm_hardware_t snd_trident_capture = 1713 { 1714 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | 1715 SNDRV_PCM_INFO_BLOCK_TRANSFER | 1716 SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_SYNC_START | 1717 SNDRV_PCM_INFO_PAUSE /* | SNDRV_PCM_INFO_RESUME */), 1718 .formats = (SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE | 1719 SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U16_LE), 1720 .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000, 1721 .rate_min = 4000, 1722 .rate_max = 48000, 1723 .channels_min = 1, 1724 .channels_max = 2, 1725 .buffer_bytes_max = (128*1024), 1726 .period_bytes_min = 64, 1727 .period_bytes_max = (128*1024), 1728 .periods_min = 1, 1729 .periods_max = 1024, 1730 .fifo_size = 0, 1731 }; 1732 1733 /* 1734 * Foldback capture support device description 1735 */ 1736 1737 static snd_pcm_hardware_t snd_trident_foldback = 1738 { 1739 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | 1740 SNDRV_PCM_INFO_BLOCK_TRANSFER | 1741 SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_SYNC_START | 1742 SNDRV_PCM_INFO_PAUSE /* | SNDRV_PCM_INFO_RESUME */), 1743 .formats = SNDRV_PCM_FMTBIT_S16_LE, 1744 .rates = SNDRV_PCM_RATE_48000, 1745 .rate_min = 48000, 1746 .rate_max = 48000, 1747 .channels_min = 2, 1748 .channels_max = 2, 1749 .buffer_bytes_max = (128*1024), 1750 .period_bytes_min = 64, 1751 .period_bytes_max = (128*1024), 1752 .periods_min = 1, 1753 .periods_max = 1024, 1754 .fifo_size = 0, 1755 }; 1756 1757 /* 1758 * SPDIF playback support device description 1759 */ 1760 1761 static snd_pcm_hardware_t snd_trident_spdif = 1762 { 1763 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | 1764 SNDRV_PCM_INFO_BLOCK_TRANSFER | 1765 SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_SYNC_START | 1766 SNDRV_PCM_INFO_PAUSE /* | SNDRV_PCM_INFO_RESUME */), 1767 .formats = SNDRV_PCM_FMTBIT_S16_LE, 1768 .rates = (SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | 1769 SNDRV_PCM_RATE_48000), 1770 .rate_min = 32000, 1771 .rate_max = 48000, 1772 .channels_min = 2, 1773 .channels_max = 2, 1774 .buffer_bytes_max = (128*1024), 1775 .period_bytes_min = 64, 1776 .period_bytes_max = (128*1024), 1777 .periods_min = 1, 1778 .periods_max = 1024, 1779 .fifo_size = 0, 1780 }; 1781 1782 static snd_pcm_hardware_t snd_trident_spdif_7018 = 1783 { 1784 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | 1785 SNDRV_PCM_INFO_BLOCK_TRANSFER | 1786 SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_SYNC_START | 1787 SNDRV_PCM_INFO_PAUSE /* | SNDRV_PCM_INFO_RESUME */), 1788 .formats = SNDRV_PCM_FMTBIT_S16_LE, 1789 .rates = SNDRV_PCM_RATE_48000, 1790 .rate_min = 48000, 1791 .rate_max = 48000, 1792 .channels_min = 2, 1793 .channels_max = 2, 1794 .buffer_bytes_max = (128*1024), 1795 .period_bytes_min = 64, 1796 .period_bytes_max = (128*1024), 1797 .periods_min = 1, 1798 .periods_max = 1024, 1799 .fifo_size = 0, 1800 }; 1801 1802 static void snd_trident_pcm_free_substream(snd_pcm_runtime_t *runtime) 1803 { 1804 snd_trident_voice_t *voice = (snd_trident_voice_t *) runtime->private_data; 1805 trident_t *trident; 1806 1807 if (voice) { 1808 trident = voice->trident; 1809 snd_trident_free_voice(trident, voice); 1810 } 1811 } 1812 1813 static int snd_trident_playback_open(snd_pcm_substream_t * substream) 1814 { 1815 trident_t *trident = snd_pcm_substream_chip(substream); 1816 snd_pcm_runtime_t *runtime = substream->runtime; 1817 snd_trident_voice_t *voice; 1818 1819 voice = snd_trident_alloc_voice(trident, SNDRV_TRIDENT_VOICE_TYPE_PCM, 0, 0); 1820 if (voice == NULL) 1821 return -EAGAIN; 1822 snd_trident_pcm_mixer_build(trident, voice, substream); 1823 voice->substream = substream; 1824 runtime->private_data = voice; 1825 runtime->private_free = snd_trident_pcm_free_substream; 1826 runtime->hw = snd_trident_playback; 1827 snd_pcm_set_sync(substream); 1828 snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_SIZE, 0, 64*1024); 1829 return 0; 1830 } 1831 1832 /*--------------------------------------------------------------------------- 1833 snd_trident_playback_close 1834 1835 Description: This routine will close the 4DWave playback device. For now 1836 we will simply free the dma transfer buffer. 1837 1838 Parameters: substream - PCM substream class 1839 1840 ---------------------------------------------------------------------------*/ 1841 static int snd_trident_playback_close(snd_pcm_substream_t * substream) 1842 { 1843 trident_t *trident = snd_pcm_substream_chip(substream); 1844 snd_pcm_runtime_t *runtime = substream->runtime; 1845 snd_trident_voice_t *voice = (snd_trident_voice_t *) runtime->private_data; 1846 1847 snd_trident_pcm_mixer_free(trident, voice, substream); 1848 return 0; 1849 } 1850 1851 /*--------------------------------------------------------------------------- 1852 snd_trident_spdif_open 1853 1854 Description: This routine will open the 4DWave SPDIF device. 1855 1856 Parameters: substream - PCM substream class 1857 1858 Returns: status - success or failure flag 1859 1860 ---------------------------------------------------------------------------*/ 1861 1862 static int snd_trident_spdif_open(snd_pcm_substream_t * substream) 1863 { 1864 trident_t *trident = snd_pcm_substream_chip(substream); 1865 snd_trident_voice_t *voice; 1866 snd_pcm_runtime_t *runtime = substream->runtime; 1867 1868 voice = snd_trident_alloc_voice(trident, SNDRV_TRIDENT_VOICE_TYPE_PCM, 0, 0); 1869 if (voice == NULL) 1870 return -EAGAIN; 1871 voice->spdif = 1; 1872 voice->substream = substream; 1873 spin_lock_irq(&trident->reg_lock); 1874 trident->spdif_pcm_bits = trident->spdif_bits; 1875 spin_unlock_irq(&trident->reg_lock); 1876 1877 runtime->private_data = voice; 1878 runtime->private_free = snd_trident_pcm_free_substream; 1879 if (trident->device == TRIDENT_DEVICE_ID_SI7018) { 1880 runtime->hw = snd_trident_spdif; 1881 } else { 1882 runtime->hw = snd_trident_spdif_7018; 1883 } 1884 1885 trident->spdif_pcm_ctl->vd[0].access &= ~SNDRV_CTL_ELEM_ACCESS_INACTIVE; 1886 snd_ctl_notify(trident->card, SNDRV_CTL_EVENT_MASK_VALUE | 1887 SNDRV_CTL_EVENT_MASK_INFO, &trident->spdif_pcm_ctl->id); 1888 1889 snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_SIZE, 0, 64*1024); 1890 return 0; 1891 } 1892 1893 1894 /*--------------------------------------------------------------------------- 1895 snd_trident_spdif_close 1896 1897 Description: This routine will close the 4DWave SPDIF device. 1898 1899 Parameters: substream - PCM substream class 1900 1901 ---------------------------------------------------------------------------*/ 1902 1903 static int snd_trident_spdif_close(snd_pcm_substream_t * substream) 1904 { 1905 trident_t *trident = snd_pcm_substream_chip(substream); 1906 unsigned int temp; 1907 1908 spin_lock_irq(&trident->reg_lock); 1909 // restore default SPDIF setting 1910 if (trident->device != TRIDENT_DEVICE_ID_SI7018) { 1911 outb(trident->spdif_ctrl, TRID_REG(trident, NX_SPCTRL_SPCSO + 3)); 1912 outl(trident->spdif_bits, TRID_REG(trident, NX_SPCSTATUS)); 1913 } else { 1914 outl(trident->spdif_bits, TRID_REG(trident, SI_SPDIF_CS)); 1915 temp = inl(TRID_REG(trident, SI_SERIAL_INTF_CTRL)); 1916 if (trident->spdif_ctrl) { 1917 temp |= SPDIF_EN; 1918 } else { 1919 temp &= ~SPDIF_EN; 1920 } 1921 outl(temp, TRID_REG(trident, SI_SERIAL_INTF_CTRL)); 1922 } 1923 spin_unlock_irq(&trident->reg_lock); 1924 trident->spdif_pcm_ctl->vd[0].access |= SNDRV_CTL_ELEM_ACCESS_INACTIVE; 1925 snd_ctl_notify(trident->card, SNDRV_CTL_EVENT_MASK_VALUE | 1926 SNDRV_CTL_EVENT_MASK_INFO, &trident->spdif_pcm_ctl->id); 1927 return 0; 1928 } 1929 1930 /*--------------------------------------------------------------------------- 1931 snd_trident_capture_open 1932 1933 Description: This routine will open the 4DWave capture device. 1934 1935 Parameters: substream - PCM substream class 1936 1937 Returns: status - success or failure flag 1938 1939 ---------------------------------------------------------------------------*/ 1940 1941 static int snd_trident_capture_open(snd_pcm_substream_t * substream) 1942 { 1943 trident_t *trident = snd_pcm_substream_chip(substream); 1944 snd_trident_voice_t *voice; 1945 snd_pcm_runtime_t *runtime = substream->runtime; 1946 1947 voice = snd_trident_alloc_voice(trident, SNDRV_TRIDENT_VOICE_TYPE_PCM, 0, 0); 1948 if (voice == NULL) 1949 return -EAGAIN; 1950 voice->capture = 1; 1951 voice->substream = substream; 1952 runtime->private_data = voice; 1953 runtime->private_free = snd_trident_pcm_free_substream; 1954 runtime->hw = snd_trident_capture; 1955 snd_pcm_set_sync(substream); 1956 snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_SIZE, 0, 64*1024); 1957 return 0; 1958 } 1959 1960 /*--------------------------------------------------------------------------- 1961 snd_trident_capture_close 1962 1963 Description: This routine will close the 4DWave capture device. For now 1964 we will simply free the dma transfer buffer. 1965 1966 Parameters: substream - PCM substream class 1967 1968 ---------------------------------------------------------------------------*/ 1969 static int snd_trident_capture_close(snd_pcm_substream_t * substream) 1970 { 1971 return 0; 1972 } 1973 1974 /*--------------------------------------------------------------------------- 1975 snd_trident_foldback_open 1976 1977 Description: This routine will open the 4DWave foldback capture device. 1978 1979 Parameters: substream - PCM substream class 1980 1981 Returns: status - success or failure flag 1982 1983 ---------------------------------------------------------------------------*/ 1984 1985 static int snd_trident_foldback_open(snd_pcm_substream_t * substream) 1986 { 1987 trident_t *trident = snd_pcm_substream_chip(substream); 1988 snd_trident_voice_t *voice; 1989 snd_pcm_runtime_t *runtime = substream->runtime; 1990 1991 voice = snd_trident_alloc_voice(trident, SNDRV_TRIDENT_VOICE_TYPE_PCM, 0, 0); 1992 if (voice == NULL) 1993 return -EAGAIN; 1994 voice->foldback_chan = substream->number; 1995 voice->substream = substream; 1996 runtime->private_data = voice; 1997 runtime->private_free = snd_trident_pcm_free_substream; 1998 runtime->hw = snd_trident_foldback; 1999 snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_SIZE, 0, 64*1024); 2000 return 0; 2001 } 2002 2003 /*--------------------------------------------------------------------------- 2004 snd_trident_foldback_close 2005 2006 Description: This routine will close the 4DWave foldback capture device. 2007 For now we will simply free the dma transfer buffer. 2008 2009 Parameters: substream - PCM substream class 2010 2011 ---------------------------------------------------------------------------*/ 2012 static int snd_trident_foldback_close(snd_pcm_substream_t * substream) 2013 { 2014 trident_t *trident = snd_pcm_substream_chip(substream); 2015 snd_trident_voice_t *voice; 2016 snd_pcm_runtime_t *runtime = substream->runtime; 2017 voice = (snd_trident_voice_t *) runtime->private_data; 2018 2019 /* stop capture channel */ 2020 spin_lock_irq(&trident->reg_lock); 2021 outb(0x00, TRID_REG(trident, T4D_RCI + voice->foldback_chan)); 2022 spin_unlock_irq(&trident->reg_lock); 2023 return 0; 2024 } 2025 2026 /*--------------------------------------------------------------------------- 2027 PCM operations 2028 ---------------------------------------------------------------------------*/ 2029 2030 static snd_pcm_ops_t snd_trident_playback_ops = { 2031 .open = snd_trident_playback_open, 2032 .close = snd_trident_playback_close, 2033 .ioctl = snd_trident_ioctl, 2034 .hw_params = snd_trident_hw_params, 2035 .hw_free = snd_trident_hw_free, 2036 .prepare = snd_trident_playback_prepare, 2037 .trigger = snd_trident_trigger, 2038 .pointer = snd_trident_playback_pointer, 2039 }; 2040 2041 static snd_pcm_ops_t snd_trident_nx_playback_ops = { 2042 .open = snd_trident_playback_open, 2043 .close = snd_trident_playback_close, 2044 .ioctl = snd_trident_ioctl, 2045 .hw_params = snd_trident_hw_params, 2046 .hw_free = snd_trident_hw_free, 2047 .prepare = snd_trident_playback_prepare, 2048 .trigger = snd_trident_trigger, 2049 .pointer = snd_trident_playback_pointer, 2050 .page = snd_pcm_sgbuf_ops_page, 2051 }; 2052 2053 static snd_pcm_ops_t snd_trident_capture_ops = { 2054 .open = snd_trident_capture_open, 2055 .close = snd_trident_capture_close, 2056 .ioctl = snd_trident_ioctl, 2057 .hw_params = snd_trident_capture_hw_params, 2058 .hw_free = snd_trident_hw_free, 2059 .prepare = snd_trident_capture_prepare, 2060 .trigger = snd_trident_trigger, 2061 .pointer = snd_trident_capture_pointer, 2062 }; 2063 2064 static snd_pcm_ops_t snd_trident_si7018_capture_ops = { 2065 .open = snd_trident_capture_open, 2066 .close = snd_trident_capture_close, 2067 .ioctl = snd_trident_ioctl, 2068 .hw_params = snd_trident_si7018_capture_hw_params, 2069 .hw_free = snd_trident_si7018_capture_hw_free, 2070 .prepare = snd_trident_si7018_capture_prepare, 2071 .trigger = snd_trident_trigger, 2072 .pointer = snd_trident_playback_pointer, 2073 }; 2074 2075 static snd_pcm_ops_t snd_trident_foldback_ops = { 2076 .open = snd_trident_foldback_open, 2077 .close = snd_trident_foldback_close, 2078 .ioctl = snd_trident_ioctl, 2079 .hw_params = snd_trident_hw_params, 2080 .hw_free = snd_trident_hw_free, 2081 .prepare = snd_trident_foldback_prepare, 2082 .trigger = snd_trident_trigger, 2083 .pointer = snd_trident_playback_pointer, 2084 }; 2085 2086 static snd_pcm_ops_t snd_trident_nx_foldback_ops = { 2087 .open = snd_trident_foldback_open, 2088 .close = snd_trident_foldback_close, 2089 .ioctl = snd_trident_ioctl, 2090 .hw_params = snd_trident_hw_params, 2091 .hw_free = snd_trident_hw_free, 2092 .prepare = snd_trident_foldback_prepare, 2093 .trigger = snd_trident_trigger, 2094 .pointer = snd_trident_playback_pointer, 2095 .page = snd_pcm_sgbuf_ops_page, 2096 }; 2097 2098 static snd_pcm_ops_t snd_trident_spdif_ops = { 2099 .open = snd_trident_spdif_open, 2100 .close = snd_trident_spdif_close, 2101 .ioctl = snd_trident_ioctl, 2102 .hw_params = snd_trident_spdif_hw_params, 2103 .hw_free = snd_trident_hw_free, 2104 .prepare = snd_trident_spdif_prepare, 2105 .trigger = snd_trident_trigger, 2106 .pointer = snd_trident_spdif_pointer, 2107 }; 2108 2109 static snd_pcm_ops_t snd_trident_spdif_7018_ops = { 2110 .open = snd_trident_spdif_open, 2111 .close = snd_trident_spdif_close, 2112 .ioctl = snd_trident_ioctl, 2113 .hw_params = snd_trident_spdif_hw_params, 2114 .hw_free = snd_trident_hw_free, 2115 .prepare = snd_trident_spdif_prepare, 2116 .trigger = snd_trident_trigger, 2117 .pointer = snd_trident_playback_pointer, 2118 }; 2119 2120 /*--------------------------------------------------------------------------- 2121 snd_trident_pcm_free 2122 2123 Description: This routine release the 4DWave private data. 2124 2125 Paramters: private_data - pointer to 4DWave device info. 2126 2127 Returns: None 2128 2129 ---------------------------------------------------------------------------*/ 2130 static void snd_trident_pcm_free(snd_pcm_t *pcm) 2131 { 2132 trident_t *trident = pcm->private_data; 2133 trident->pcm = NULL; 2134 snd_pcm_lib_preallocate_free_for_all(pcm); 2135 } 2136 2137 static void snd_trident_foldback_pcm_free(snd_pcm_t *pcm) 2138 { 2139 trident_t *trident = pcm->private_data; 2140 trident->foldback = NULL; 2141 snd_pcm_lib_preallocate_free_for_all(pcm); 2142 } 2143 2144 static void snd_trident_spdif_pcm_free(snd_pcm_t *pcm) 2145 { 2146 trident_t *trident = pcm->private_data; 2147 trident->spdif = NULL; 2148 snd_pcm_lib_preallocate_free_for_all(pcm); 2149 } 2150 2151 /*--------------------------------------------------------------------------- 2152 snd_trident_pcm 2153 2154 Description: This routine registers the 4DWave device for PCM support. 2155 2156 Paramters: trident - pointer to target device class for 4DWave. 2157 2158 Returns: None 2159 2160 ---------------------------------------------------------------------------*/ 2161 2162 int __devinit snd_trident_pcm(trident_t * trident, int device, snd_pcm_t ** rpcm) 2163 { 2164 snd_pcm_t *pcm; 2165 int err; 2166 2167 if (rpcm) 2168 *rpcm = NULL; 2169 if ((err = snd_pcm_new(trident->card, "trident_dx_nx", device, trident->ChanPCM, 1, &pcm)) < 0) 2170 return err; 2171 2172 pcm->private_data = trident; 2173 pcm->private_free = snd_trident_pcm_free; 2174 2175 if (trident->tlb.entries) { 2176 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_trident_nx_playback_ops); 2177 } else { 2178 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_trident_playback_ops); 2179 } 2180 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, 2181 trident->device != TRIDENT_DEVICE_ID_SI7018 ? 2182 &snd_trident_capture_ops : 2183 &snd_trident_si7018_capture_ops); 2184 2185 pcm->info_flags = 0; 2186 pcm->dev_subclass = SNDRV_PCM_SUBCLASS_GENERIC_MIX; 2187 strcpy(pcm->name, "Trident 4DWave"); 2188 trident->pcm = pcm; 2189 2190 if (trident->tlb.entries) { 2191 snd_pcm_substream_t *substream; 2192 for (substream = pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream; substream; substream = substream->next) 2193 snd_pcm_lib_preallocate_pages(substream, SNDRV_DMA_TYPE_DEV_SG, 2194 snd_dma_pci_data(trident->pci), 2195 64*1024, 128*1024); 2196 snd_pcm_lib_preallocate_pages(pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream, 2197 SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(trident->pci), 2198 64*1024, 128*1024); 2199 } else { 2200 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, 2201 snd_dma_pci_data(trident->pci), 64*1024, 128*1024); 2202 } 2203 2204 if (rpcm) 2205 *rpcm = pcm; 2206 return 0; 2207 } 2208 2209 /*--------------------------------------------------------------------------- 2210 snd_trident_foldback_pcm 2211 2212 Description: This routine registers the 4DWave device for foldback PCM support. 2213 2214 Paramters: trident - pointer to target device class for 4DWave. 2215 2216 Returns: None 2217 2218 ---------------------------------------------------------------------------*/ 2219 2220 int __devinit snd_trident_foldback_pcm(trident_t * trident, int device, snd_pcm_t ** rpcm) 2221 { 2222 snd_pcm_t *foldback; 2223 int err; 2224 int num_chan = 3; 2225 snd_pcm_substream_t *substream; 2226 2227 if (rpcm) 2228 *rpcm = NULL; 2229 if (trident->device == TRIDENT_DEVICE_ID_NX) 2230 num_chan = 4; 2231 if ((err = snd_pcm_new(trident->card, "trident_dx_nx", device, 0, num_chan, &foldback)) < 0) 2232 return err; 2233 2234 foldback->private_data = trident; 2235 foldback->private_free = snd_trident_foldback_pcm_free; 2236 if (trident->tlb.entries) 2237 snd_pcm_set_ops(foldback, SNDRV_PCM_STREAM_CAPTURE, &snd_trident_nx_foldback_ops); 2238 else 2239 snd_pcm_set_ops(foldback, SNDRV_PCM_STREAM_CAPTURE, &snd_trident_foldback_ops); 2240 foldback->info_flags = 0; 2241 strcpy(foldback->name, "Trident 4DWave"); 2242 substream = foldback->streams[SNDRV_PCM_STREAM_CAPTURE].substream; 2243 strcpy(substream->name, "Front Mixer"); 2244 substream = substream->next; 2245 strcpy(substream->name, "Reverb Mixer"); 2246 substream = substream->next; 2247 strcpy(substream->name, "Chorus Mixer"); 2248 if (num_chan == 4) { 2249 substream = substream->next; 2250 strcpy(substream->name, "Second AC'97 ADC"); 2251 } 2252 trident->foldback = foldback; 2253 2254 if (trident->tlb.entries) 2255 snd_pcm_lib_preallocate_pages_for_all(foldback, SNDRV_DMA_TYPE_DEV_SG, 2256 snd_dma_pci_data(trident->pci), 0, 128*1024); 2257 else 2258 snd_pcm_lib_preallocate_pages_for_all(foldback, SNDRV_DMA_TYPE_DEV, 2259 snd_dma_pci_data(trident->pci), 64*1024, 128*1024); 2260 2261 if (rpcm) 2262 *rpcm = foldback; 2263 return 0; 2264 } 2265 2266 /*--------------------------------------------------------------------------- 2267 snd_trident_spdif 2268 2269 Description: This routine registers the 4DWave-NX device for SPDIF support. 2270 2271 Paramters: trident - pointer to target device class for 4DWave-NX. 2272 2273 Returns: None 2274 2275 ---------------------------------------------------------------------------*/ 2276 2277 int __devinit snd_trident_spdif_pcm(trident_t * trident, int device, snd_pcm_t ** rpcm) 2278 { 2279 snd_pcm_t *spdif; 2280 int err; 2281 2282 if (rpcm) 2283 *rpcm = NULL; 2284 if ((err = snd_pcm_new(trident->card, "trident_dx_nx IEC958", device, 1, 0, &spdif)) < 0) 2285 return err; 2286 2287 spdif->private_data = trident; 2288 spdif->private_free = snd_trident_spdif_pcm_free; 2289 if (trident->device != TRIDENT_DEVICE_ID_SI7018) { 2290 snd_pcm_set_ops(spdif, SNDRV_PCM_STREAM_PLAYBACK, &snd_trident_spdif_ops); 2291 } else { 2292 snd_pcm_set_ops(spdif, SNDRV_PCM_STREAM_PLAYBACK, &snd_trident_spdif_7018_ops); 2293 } 2294 spdif->info_flags = 0; 2295 strcpy(spdif->name, "Trident 4DWave IEC958"); 2296 trident->spdif = spdif; 2297 2298 snd_pcm_lib_preallocate_pages_for_all(spdif, SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(trident->pci), 64*1024, 128*1024); 2299 2300 if (rpcm) 2301 *rpcm = spdif; 2302 return 0; 2303 } 2304 2305 /* 2306 * Mixer part 2307 */ 2308 2309 2310 /*--------------------------------------------------------------------------- 2311 snd_trident_spdif_control 2312 2313 Description: enable/disable S/PDIF out from ac97 mixer 2314 ---------------------------------------------------------------------------*/ 2315 2316 static int snd_trident_spdif_control_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo) 2317 { 2318 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; 2319 uinfo->count = 1; 2320 uinfo->value.integer.min = 0; 2321 uinfo->value.integer.max = 1; 2322 return 0; 2323 } 2324 2325 static int snd_trident_spdif_control_get(snd_kcontrol_t * kcontrol, 2326 snd_ctl_elem_value_t * ucontrol) 2327 { 2328 trident_t *trident = snd_kcontrol_chip(kcontrol); 2329 unsigned char val; 2330 2331 spin_lock_irq(&trident->reg_lock); 2332 val = trident->spdif_ctrl; 2333 ucontrol->value.integer.value[0] = val == kcontrol->private_value; 2334 spin_unlock_irq(&trident->reg_lock); 2335 return 0; 2336 } 2337 2338 static int snd_trident_spdif_control_put(snd_kcontrol_t * kcontrol, 2339 snd_ctl_elem_value_t * ucontrol) 2340 { 2341 trident_t *trident = snd_kcontrol_chip(kcontrol); 2342 unsigned char val; 2343 int change; 2344 2345 val = ucontrol->value.integer.value[0] ? (unsigned char) kcontrol->private_value : 0x00; 2346 spin_lock_irq(&trident->reg_lock); 2347 /* S/PDIF C Channel bits 0-31 : 48khz, SCMS disabled */ 2348 change = trident->spdif_ctrl != val; 2349 trident->spdif_ctrl = val; 2350 if (trident->device != TRIDENT_DEVICE_ID_SI7018) { 2351 if ((inb(TRID_REG(trident, NX_SPCTRL_SPCSO + 3)) & 0x10) == 0) { 2352 outl(trident->spdif_bits, TRID_REG(trident, NX_SPCSTATUS)); 2353 outb(trident->spdif_ctrl, TRID_REG(trident, NX_SPCTRL_SPCSO + 3)); 2354 } 2355 } else { 2356 if (trident->spdif == NULL) { 2357 unsigned int temp; 2358 outl(trident->spdif_bits, TRID_REG(trident, SI_SPDIF_CS)); 2359 temp = inl(TRID_REG(trident, SI_SERIAL_INTF_CTRL)) & ~SPDIF_EN; 2360 if (val) 2361 temp |= SPDIF_EN; 2362 outl(temp, TRID_REG(trident, SI_SERIAL_INTF_CTRL)); 2363 } 2364 } 2365 spin_unlock_irq(&trident->reg_lock); 2366 return change; 2367 } 2368 2369 static snd_kcontrol_new_t snd_trident_spdif_control __devinitdata = 2370 { 2371 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2372 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,SWITCH), 2373 .info = snd_trident_spdif_control_info, 2374 .get = snd_trident_spdif_control_get, 2375 .put = snd_trident_spdif_control_put, 2376 .private_value = 0x28, 2377 }; 2378 2379 /*--------------------------------------------------------------------------- 2380 snd_trident_spdif_default 2381 2382 Description: put/get the S/PDIF default settings 2383 ---------------------------------------------------------------------------*/ 2384 2385 static int snd_trident_spdif_default_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo) 2386 { 2387 uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958; 2388 uinfo->count = 1; 2389 return 0; 2390 } 2391 2392 static int snd_trident_spdif_default_get(snd_kcontrol_t * kcontrol, 2393 snd_ctl_elem_value_t * ucontrol) 2394 { 2395 trident_t *trident = snd_kcontrol_chip(kcontrol); 2396 2397 spin_lock_irq(&trident->reg_lock); 2398 ucontrol->value.iec958.status[0] = (trident->spdif_bits >> 0) & 0xff; 2399 ucontrol->value.iec958.status[1] = (trident->spdif_bits >> 8) & 0xff; 2400 ucontrol->value.iec958.status[2] = (trident->spdif_bits >> 16) & 0xff; 2401 ucontrol->value.iec958.status[3] = (trident->spdif_bits >> 24) & 0xff; 2402 spin_unlock_irq(&trident->reg_lock); 2403 return 0; 2404 } 2405 2406 static int snd_trident_spdif_default_put(snd_kcontrol_t * kcontrol, 2407 snd_ctl_elem_value_t * ucontrol) 2408 { 2409 trident_t *trident = snd_kcontrol_chip(kcontrol); 2410 unsigned int val; 2411 int change; 2412 2413 val = (ucontrol->value.iec958.status[0] << 0) | 2414 (ucontrol->value.iec958.status[1] << 8) | 2415 (ucontrol->value.iec958.status[2] << 16) | 2416 (ucontrol->value.iec958.status[3] << 24); 2417 spin_lock_irq(&trident->reg_lock); 2418 change = trident->spdif_bits != val; 2419 trident->spdif_bits = val; 2420 if (trident->device != TRIDENT_DEVICE_ID_SI7018) { 2421 if ((inb(TRID_REG(trident, NX_SPCTRL_SPCSO + 3)) & 0x10) == 0) 2422 outl(trident->spdif_bits, TRID_REG(trident, NX_SPCSTATUS)); 2423 } else { 2424 if (trident->spdif == NULL) 2425 outl(trident->spdif_bits, TRID_REG(trident, SI_SPDIF_CS)); 2426 } 2427 spin_unlock_irq(&trident->reg_lock); 2428 return change; 2429 } 2430 2431 static snd_kcontrol_new_t snd_trident_spdif_default __devinitdata = 2432 { 2433 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 2434 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT), 2435 .info = snd_trident_spdif_default_info, 2436 .get = snd_trident_spdif_default_get, 2437 .put = snd_trident_spdif_default_put 2438 }; 2439 2440 /*--------------------------------------------------------------------------- 2441 snd_trident_spdif_mask 2442 2443 Description: put/get the S/PDIF mask 2444 ---------------------------------------------------------------------------*/ 2445 2446 static int snd_trident_spdif_mask_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo) 2447 { 2448 uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958; 2449 uinfo->count = 1; 2450 return 0; 2451 } 2452 2453 static int snd_trident_spdif_mask_get(snd_kcontrol_t * kcontrol, 2454 snd_ctl_elem_value_t * ucontrol) 2455 { 2456 ucontrol->value.iec958.status[0] = 0xff; 2457 ucontrol->value.iec958.status[1] = 0xff; 2458 ucontrol->value.iec958.status[2] = 0xff; 2459 ucontrol->value.iec958.status[3] = 0xff; 2460 return 0; 2461 } 2462 2463 static snd_kcontrol_new_t snd_trident_spdif_mask __devinitdata = 2464 { 2465 .access = SNDRV_CTL_ELEM_ACCESS_READ, 2466 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 2467 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,MASK), 2468 .info = snd_trident_spdif_mask_info, 2469 .get = snd_trident_spdif_mask_get, 2470 }; 2471 2472 /*--------------------------------------------------------------------------- 2473 snd_trident_spdif_stream 2474 2475 Description: put/get the S/PDIF stream settings 2476 ---------------------------------------------------------------------------*/ 2477 2478 static int snd_trident_spdif_stream_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo) 2479 { 2480 uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958; 2481 uinfo->count = 1; 2482 return 0; 2483 } 2484 2485 static int snd_trident_spdif_stream_get(snd_kcontrol_t * kcontrol, 2486 snd_ctl_elem_value_t * ucontrol) 2487 { 2488 trident_t *trident = snd_kcontrol_chip(kcontrol); 2489 2490 spin_lock_irq(&trident->reg_lock); 2491 ucontrol->value.iec958.status[0] = (trident->spdif_pcm_bits >> 0) & 0xff; 2492 ucontrol->value.iec958.status[1] = (trident->spdif_pcm_bits >> 8) & 0xff; 2493 ucontrol->value.iec958.status[2] = (trident->spdif_pcm_bits >> 16) & 0xff; 2494 ucontrol->value.iec958.status[3] = (trident->spdif_pcm_bits >> 24) & 0xff; 2495 spin_unlock_irq(&trident->reg_lock); 2496 return 0; 2497 } 2498 2499 static int snd_trident_spdif_stream_put(snd_kcontrol_t * kcontrol, 2500 snd_ctl_elem_value_t * ucontrol) 2501 { 2502 trident_t *trident = snd_kcontrol_chip(kcontrol); 2503 unsigned int val; 2504 int change; 2505 2506 val = (ucontrol->value.iec958.status[0] << 0) | 2507 (ucontrol->value.iec958.status[1] << 8) | 2508 (ucontrol->value.iec958.status[2] << 16) | 2509 (ucontrol->value.iec958.status[3] << 24); 2510 spin_lock_irq(&trident->reg_lock); 2511 change = trident->spdif_pcm_bits != val; 2512 trident->spdif_pcm_bits = val; 2513 if (trident->spdif != NULL) { 2514 if (trident->device != TRIDENT_DEVICE_ID_SI7018) { 2515 outl(trident->spdif_pcm_bits, TRID_REG(trident, NX_SPCSTATUS)); 2516 } else { 2517 outl(trident->spdif_bits, TRID_REG(trident, SI_SPDIF_CS)); 2518 } 2519 } 2520 spin_unlock_irq(&trident->reg_lock); 2521 return change; 2522 } 2523 2524 static snd_kcontrol_new_t snd_trident_spdif_stream __devinitdata = 2525 { 2526 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE, 2527 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 2528 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,PCM_STREAM), 2529 .info = snd_trident_spdif_stream_info, 2530 .get = snd_trident_spdif_stream_get, 2531 .put = snd_trident_spdif_stream_put 2532 }; 2533 2534 /*--------------------------------------------------------------------------- 2535 snd_trident_ac97_control 2536 2537 Description: enable/disable rear path for ac97 2538 ---------------------------------------------------------------------------*/ 2539 2540 static int snd_trident_ac97_control_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo) 2541 { 2542 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; 2543 uinfo->count = 1; 2544 uinfo->value.integer.min = 0; 2545 uinfo->value.integer.max = 1; 2546 return 0; 2547 } 2548 2549 static int snd_trident_ac97_control_get(snd_kcontrol_t * kcontrol, 2550 snd_ctl_elem_value_t * ucontrol) 2551 { 2552 trident_t *trident = snd_kcontrol_chip(kcontrol); 2553 unsigned char val; 2554 2555 spin_lock_irq(&trident->reg_lock); 2556 val = trident->ac97_ctrl = inl(TRID_REG(trident, NX_ACR0_AC97_COM_STAT)); 2557 ucontrol->value.integer.value[0] = (val & (1 << kcontrol->private_value)) ? 1 : 0; 2558 spin_unlock_irq(&trident->reg_lock); 2559 return 0; 2560 } 2561 2562 static int snd_trident_ac97_control_put(snd_kcontrol_t * kcontrol, 2563 snd_ctl_elem_value_t * ucontrol) 2564 { 2565 trident_t *trident = snd_kcontrol_chip(kcontrol); 2566 unsigned char val; 2567 int change = 0; 2568 2569 spin_lock_irq(&trident->reg_lock); 2570 val = trident->ac97_ctrl = inl(TRID_REG(trident, NX_ACR0_AC97_COM_STAT)); 2571 val &= ~(1 << kcontrol->private_value); 2572 if (ucontrol->value.integer.value[0]) 2573 val |= 1 << kcontrol->private_value; 2574 change = val != trident->ac97_ctrl; 2575 trident->ac97_ctrl = val; 2576 outl(trident->ac97_ctrl = val, TRID_REG(trident, NX_ACR0_AC97_COM_STAT)); 2577 spin_unlock_irq(&trident->reg_lock); 2578 return change; 2579 } 2580 2581 static snd_kcontrol_new_t snd_trident_ac97_rear_control __devinitdata = 2582 { 2583 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2584 .name = "Rear Path", 2585 .info = snd_trident_ac97_control_info, 2586 .get = snd_trident_ac97_control_get, 2587 .put = snd_trident_ac97_control_put, 2588 .private_value = 4, 2589 }; 2590 2591 /*--------------------------------------------------------------------------- 2592 snd_trident_vol_control 2593 2594 Description: wave & music volume control 2595 ---------------------------------------------------------------------------*/ 2596 2597 static int snd_trident_vol_control_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo) 2598 { 2599 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 2600 uinfo->count = 2; 2601 uinfo->value.integer.min = 0; 2602 uinfo->value.integer.max = 255; 2603 return 0; 2604 } 2605 2606 static int snd_trident_vol_control_get(snd_kcontrol_t * kcontrol, 2607 snd_ctl_elem_value_t * ucontrol) 2608 { 2609 trident_t *trident = snd_kcontrol_chip(kcontrol); 2610 unsigned int val; 2611 2612 val = trident->musicvol_wavevol; 2613 ucontrol->value.integer.value[0] = 255 - ((val >> kcontrol->private_value) & 0xff); 2614 ucontrol->value.integer.value[1] = 255 - ((val >> (kcontrol->private_value + 8)) & 0xff); 2615 return 0; 2616 } 2617 2618 static int snd_trident_vol_control_put(snd_kcontrol_t * kcontrol, 2619 snd_ctl_elem_value_t * ucontrol) 2620 { 2621 trident_t *trident = snd_kcontrol_chip(kcontrol); 2622 unsigned int val; 2623 int change = 0; 2624 2625 spin_lock_irq(&trident->reg_lock); 2626 val = trident->musicvol_wavevol; 2627 val &= ~(0xffff << kcontrol->private_value); 2628 val |= ((255 - (ucontrol->value.integer.value[0] & 0xff)) | 2629 ((255 - (ucontrol->value.integer.value[1] & 0xff)) << 8)) << kcontrol->private_value; 2630 change = val != trident->musicvol_wavevol; 2631 outl(trident->musicvol_wavevol = val, TRID_REG(trident, T4D_MUSICVOL_WAVEVOL)); 2632 spin_unlock_irq(&trident->reg_lock); 2633 return change; 2634 } 2635 2636 static snd_kcontrol_new_t snd_trident_vol_music_control __devinitdata = 2637 { 2638 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2639 .name = "Music Playback Volume", 2640 .info = snd_trident_vol_control_info, 2641 .get = snd_trident_vol_control_get, 2642 .put = snd_trident_vol_control_put, 2643 .private_value = 16, 2644 }; 2645 2646 static snd_kcontrol_new_t snd_trident_vol_wave_control __devinitdata = 2647 { 2648 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2649 .name = "Wave Playback Volume", 2650 .info = snd_trident_vol_control_info, 2651 .get = snd_trident_vol_control_get, 2652 .put = snd_trident_vol_control_put, 2653 .private_value = 0, 2654 }; 2655 2656 /*--------------------------------------------------------------------------- 2657 snd_trident_pcm_vol_control 2658 2659 Description: PCM front volume control 2660 ---------------------------------------------------------------------------*/ 2661 2662 static int snd_trident_pcm_vol_control_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo) 2663 { 2664 trident_t *trident = snd_kcontrol_chip(kcontrol); 2665 2666 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 2667 uinfo->count = 1; 2668 uinfo->value.integer.min = 0; 2669 uinfo->value.integer.max = 255; 2670 if (trident->device == TRIDENT_DEVICE_ID_SI7018) 2671 uinfo->value.integer.max = 1023; 2672 return 0; 2673 } 2674 2675 static int snd_trident_pcm_vol_control_get(snd_kcontrol_t * kcontrol, 2676 snd_ctl_elem_value_t * ucontrol) 2677 { 2678 trident_t *trident = snd_kcontrol_chip(kcontrol); 2679 snd_trident_pcm_mixer_t *mix = &trident->pcm_mixer[snd_ctl_get_ioffnum(kcontrol, &ucontrol->id)]; 2680 2681 if (trident->device == TRIDENT_DEVICE_ID_SI7018) { 2682 ucontrol->value.integer.value[0] = 1023 - mix->vol; 2683 } else { 2684 ucontrol->value.integer.value[0] = 255 - (mix->vol>>2); 2685 } 2686 return 0; 2687 } 2688 2689 static int snd_trident_pcm_vol_control_put(snd_kcontrol_t * kcontrol, 2690 snd_ctl_elem_value_t * ucontrol) 2691 { 2692 trident_t *trident = snd_kcontrol_chip(kcontrol); 2693 snd_trident_pcm_mixer_t *mix = &trident->pcm_mixer[snd_ctl_get_ioffnum(kcontrol, &ucontrol->id)]; 2694 unsigned int val; 2695 int change = 0; 2696 2697 if (trident->device == TRIDENT_DEVICE_ID_SI7018) { 2698 val = 1023 - (ucontrol->value.integer.value[0] & 1023); 2699 } else { 2700 val = (255 - (ucontrol->value.integer.value[0] & 255)) << 2; 2701 } 2702 spin_lock_irq(&trident->reg_lock); 2703 change = val != mix->vol; 2704 mix->vol = val; 2705 if (mix->voice != NULL) 2706 snd_trident_write_vol_reg(trident, mix->voice, val); 2707 spin_unlock_irq(&trident->reg_lock); 2708 return change; 2709 } 2710 2711 static snd_kcontrol_new_t snd_trident_pcm_vol_control __devinitdata = 2712 { 2713 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2714 .name = "PCM Front Playback Volume", 2715 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE, 2716 .count = 32, 2717 .info = snd_trident_pcm_vol_control_info, 2718 .get = snd_trident_pcm_vol_control_get, 2719 .put = snd_trident_pcm_vol_control_put, 2720 }; 2721 2722 /*--------------------------------------------------------------------------- 2723 snd_trident_pcm_pan_control 2724 2725 Description: PCM front pan control 2726 ---------------------------------------------------------------------------*/ 2727 2728 static int snd_trident_pcm_pan_control_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo) 2729 { 2730 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 2731 uinfo->count = 1; 2732 uinfo->value.integer.min = 0; 2733 uinfo->value.integer.max = 127; 2734 return 0; 2735 } 2736 2737 static int snd_trident_pcm_pan_control_get(snd_kcontrol_t * kcontrol, 2738 snd_ctl_elem_value_t * ucontrol) 2739 { 2740 trident_t *trident = snd_kcontrol_chip(kcontrol); 2741 snd_trident_pcm_mixer_t *mix = &trident->pcm_mixer[snd_ctl_get_ioffnum(kcontrol, &ucontrol->id)]; 2742 2743 ucontrol->value.integer.value[0] = mix->pan; 2744 if (ucontrol->value.integer.value[0] & 0x40) { 2745 ucontrol->value.integer.value[0] = (0x3f - (ucontrol->value.integer.value[0] & 0x3f)); 2746 } else { 2747 ucontrol->value.integer.value[0] |= 0x40; 2748 } 2749 return 0; 2750 } 2751 2752 static int snd_trident_pcm_pan_control_put(snd_kcontrol_t * kcontrol, 2753 snd_ctl_elem_value_t * ucontrol) 2754 { 2755 trident_t *trident = snd_kcontrol_chip(kcontrol); 2756 snd_trident_pcm_mixer_t *mix = &trident->pcm_mixer[snd_ctl_get_ioffnum(kcontrol, &ucontrol->id)]; 2757 unsigned char val; 2758 int change = 0; 2759 2760 if (ucontrol->value.integer.value[0] & 0x40) 2761 val = ucontrol->value.integer.value[0] & 0x3f; 2762 else 2763 val = (0x3f - (ucontrol->value.integer.value[0] & 0x3f)) | 0x40; 2764 spin_lock_irq(&trident->reg_lock); 2765 change = val != mix->pan; 2766 mix->pan = val; 2767 if (mix->voice != NULL) 2768 snd_trident_write_pan_reg(trident, mix->voice, val); 2769 spin_unlock_irq(&trident->reg_lock); 2770 return change; 2771 } 2772 2773 static snd_kcontrol_new_t snd_trident_pcm_pan_control __devinitdata = 2774 { 2775 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2776 .name = "PCM Pan Playback Control", 2777 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE, 2778 .count = 32, 2779 .info = snd_trident_pcm_pan_control_info, 2780 .get = snd_trident_pcm_pan_control_get, 2781 .put = snd_trident_pcm_pan_control_put, 2782 }; 2783 2784 /*--------------------------------------------------------------------------- 2785 snd_trident_pcm_rvol_control 2786 2787 Description: PCM reverb volume control 2788 ---------------------------------------------------------------------------*/ 2789 2790 static int snd_trident_pcm_rvol_control_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo) 2791 { 2792 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 2793 uinfo->count = 1; 2794 uinfo->value.integer.min = 0; 2795 uinfo->value.integer.max = 127; 2796 return 0; 2797 } 2798 2799 static int snd_trident_pcm_rvol_control_get(snd_kcontrol_t * kcontrol, 2800 snd_ctl_elem_value_t * ucontrol) 2801 { 2802 trident_t *trident = snd_kcontrol_chip(kcontrol); 2803 snd_trident_pcm_mixer_t *mix = &trident->pcm_mixer[snd_ctl_get_ioffnum(kcontrol, &ucontrol->id)]; 2804 2805 ucontrol->value.integer.value[0] = 127 - mix->rvol; 2806 return 0; 2807 } 2808 2809 static int snd_trident_pcm_rvol_control_put(snd_kcontrol_t * kcontrol, 2810 snd_ctl_elem_value_t * ucontrol) 2811 { 2812 trident_t *trident = snd_kcontrol_chip(kcontrol); 2813 snd_trident_pcm_mixer_t *mix = &trident->pcm_mixer[snd_ctl_get_ioffnum(kcontrol, &ucontrol->id)]; 2814 unsigned short val; 2815 int change = 0; 2816 2817 val = 0x7f - (ucontrol->value.integer.value[0] & 0x7f); 2818 spin_lock_irq(&trident->reg_lock); 2819 change = val != mix->rvol; 2820 mix->rvol = val; 2821 if (mix->voice != NULL) 2822 snd_trident_write_rvol_reg(trident, mix->voice, val); 2823 spin_unlock_irq(&trident->reg_lock); 2824 return change; 2825 } 2826 2827 static snd_kcontrol_new_t snd_trident_pcm_rvol_control __devinitdata = 2828 { 2829 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2830 .name = "PCM Reverb Playback Volume", 2831 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE, 2832 .count = 32, 2833 .info = snd_trident_pcm_rvol_control_info, 2834 .get = snd_trident_pcm_rvol_control_get, 2835 .put = snd_trident_pcm_rvol_control_put, 2836 }; 2837 2838 /*--------------------------------------------------------------------------- 2839 snd_trident_pcm_cvol_control 2840 2841 Description: PCM chorus volume control 2842 ---------------------------------------------------------------------------*/ 2843 2844 static int snd_trident_pcm_cvol_control_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo) 2845 { 2846 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 2847 uinfo->count = 1; 2848 uinfo->value.integer.min = 0; 2849 uinfo->value.integer.max = 127; 2850 return 0; 2851 } 2852 2853 static int snd_trident_pcm_cvol_control_get(snd_kcontrol_t * kcontrol, 2854 snd_ctl_elem_value_t * ucontrol) 2855 { 2856 trident_t *trident = snd_kcontrol_chip(kcontrol); 2857 snd_trident_pcm_mixer_t *mix = &trident->pcm_mixer[snd_ctl_get_ioffnum(kcontrol, &ucontrol->id)]; 2858 2859 ucontrol->value.integer.value[0] = 127 - mix->cvol; 2860 return 0; 2861 } 2862 2863 static int snd_trident_pcm_cvol_control_put(snd_kcontrol_t * kcontrol, 2864 snd_ctl_elem_value_t * ucontrol) 2865 { 2866 trident_t *trident = snd_kcontrol_chip(kcontrol); 2867 snd_trident_pcm_mixer_t *mix = &trident->pcm_mixer[snd_ctl_get_ioffnum(kcontrol, &ucontrol->id)]; 2868 unsigned short val; 2869 int change = 0; 2870 2871 val = 0x7f - (ucontrol->value.integer.value[0] & 0x7f); 2872 spin_lock_irq(&trident->reg_lock); 2873 change = val != mix->cvol; 2874 mix->cvol = val; 2875 if (mix->voice != NULL) 2876 snd_trident_write_cvol_reg(trident, mix->voice, val); 2877 spin_unlock_irq(&trident->reg_lock); 2878 return change; 2879 } 2880 2881 static snd_kcontrol_new_t snd_trident_pcm_cvol_control __devinitdata = 2882 { 2883 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2884 .name = "PCM Chorus Playback Volume", 2885 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE, 2886 .count = 32, 2887 .info = snd_trident_pcm_cvol_control_info, 2888 .get = snd_trident_pcm_cvol_control_get, 2889 .put = snd_trident_pcm_cvol_control_put, 2890 }; 2891 2892 static void snd_trident_notify_pcm_change1(snd_card_t * card, snd_kcontrol_t *kctl, int num, int activate) 2893 { 2894 snd_ctl_elem_id_t id; 2895 2896 snd_runtime_check(kctl != NULL, return); 2897 if (activate) 2898 kctl->vd[num].access &= ~SNDRV_CTL_ELEM_ACCESS_INACTIVE; 2899 else 2900 kctl->vd[num].access |= SNDRV_CTL_ELEM_ACCESS_INACTIVE; 2901 snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE | 2902 SNDRV_CTL_EVENT_MASK_INFO, 2903 snd_ctl_build_ioff(&id, kctl, num)); 2904 } 2905 2906 static void snd_trident_notify_pcm_change(trident_t *trident, snd_trident_pcm_mixer_t *tmix, int num, int activate) 2907 { 2908 snd_trident_notify_pcm_change1(trident->card, trident->ctl_vol, num, activate); 2909 snd_trident_notify_pcm_change1(trident->card, trident->ctl_pan, num, activate); 2910 snd_trident_notify_pcm_change1(trident->card, trident->ctl_rvol, num, activate); 2911 snd_trident_notify_pcm_change1(trident->card, trident->ctl_cvol, num, activate); 2912 } 2913 2914 static int snd_trident_pcm_mixer_build(trident_t *trident, snd_trident_voice_t *voice, snd_pcm_substream_t *substream) 2915 { 2916 snd_trident_pcm_mixer_t *tmix; 2917 2918 snd_assert(trident != NULL && voice != NULL && substream != NULL, return -EINVAL); 2919 tmix = &trident->pcm_mixer[substream->number]; 2920 tmix->voice = voice; 2921 tmix->vol = T4D_DEFAULT_PCM_VOL; 2922 tmix->pan = T4D_DEFAULT_PCM_PAN; 2923 tmix->rvol = T4D_DEFAULT_PCM_RVOL; 2924 tmix->cvol = T4D_DEFAULT_PCM_CVOL; 2925 snd_trident_notify_pcm_change(trident, tmix, substream->number, 1); 2926 return 0; 2927 } 2928 2929 static int snd_trident_pcm_mixer_free(trident_t *trident, snd_trident_voice_t *voice, snd_pcm_substream_t *substream) 2930 { 2931 snd_trident_pcm_mixer_t *tmix; 2932 2933 snd_assert(trident != NULL && substream != NULL, return -EINVAL); 2934 tmix = &trident->pcm_mixer[substream->number]; 2935 tmix->voice = NULL; 2936 snd_trident_notify_pcm_change(trident, tmix, substream->number, 0); 2937 return 0; 2938 } 2939 2940 /*--------------------------------------------------------------------------- 2941 snd_trident_mixer 2942 2943 Description: This routine registers the 4DWave device for mixer support. 2944 2945 Paramters: trident - pointer to target device class for 4DWave. 2946 2947 Returns: None 2948 2949 ---------------------------------------------------------------------------*/ 2950 2951 static int __devinit snd_trident_mixer(trident_t * trident, int pcm_spdif_device) 2952 { 2953 ac97_template_t _ac97; 2954 snd_card_t * card = trident->card; 2955 snd_kcontrol_t *kctl; 2956 snd_ctl_elem_value_t *uctl; 2957 int idx, err, retries = 2; 2958 static ac97_bus_ops_t ops = { 2959 .write = snd_trident_codec_write, 2960 .read = snd_trident_codec_read, 2961 }; 2962 2963 uctl = kzalloc(sizeof(*uctl), GFP_KERNEL); 2964 if (!uctl) 2965 return -ENOMEM; 2966 2967 if ((err = snd_ac97_bus(trident->card, 0, &ops, NULL, &trident->ac97_bus)) < 0) 2968 goto __out; 2969 2970 memset(&_ac97, 0, sizeof(_ac97)); 2971 _ac97.private_data = trident; 2972 trident->ac97_detect = 1; 2973 2974 __again: 2975 if ((err = snd_ac97_mixer(trident->ac97_bus, &_ac97, &trident->ac97)) < 0) { 2976 if (trident->device == TRIDENT_DEVICE_ID_SI7018) { 2977 if ((err = snd_trident_sis_reset(trident)) < 0) 2978 goto __out; 2979 if (retries-- > 0) 2980 goto __again; 2981 err = -EIO; 2982 } 2983 goto __out; 2984 } 2985 2986 /* secondary codec? */ 2987 if (trident->device == TRIDENT_DEVICE_ID_SI7018 && 2988 (inl(TRID_REG(trident, SI_SERIAL_INTF_CTRL)) & SI_AC97_PRIMARY_READY) != 0) { 2989 _ac97.num = 1; 2990 err = snd_ac97_mixer(trident->ac97_bus, &_ac97, &trident->ac97_sec); 2991 if (err < 0) 2992 snd_printk("SI7018: the secondary codec - invalid access\n"); 2993 #if 0 // only for my testing purpose --jk 2994 { 2995 ac97_t *mc97; 2996 err = snd_ac97_modem(trident->card, &_ac97, &mc97); 2997 if (err < 0) 2998 snd_printk("snd_ac97_modem returned error %i\n", err); 2999 } 3000 #endif 3001 } 3002 3003 trident->ac97_detect = 0; 3004 3005 if (trident->device != TRIDENT_DEVICE_ID_SI7018) { 3006 if ((err = snd_ctl_add(card, kctl = snd_ctl_new1(&snd_trident_vol_wave_control, trident))) < 0) 3007 goto __out; 3008 kctl->put(kctl, uctl); 3009 if ((err = snd_ctl_add(card, kctl = snd_ctl_new1(&snd_trident_vol_music_control, trident))) < 0) 3010 goto __out; 3011 kctl->put(kctl, uctl); 3012 outl(trident->musicvol_wavevol = 0x00000000, TRID_REG(trident, T4D_MUSICVOL_WAVEVOL)); 3013 } else { 3014 outl(trident->musicvol_wavevol = 0xffff0000, TRID_REG(trident, T4D_MUSICVOL_WAVEVOL)); 3015 } 3016 3017 for (idx = 0; idx < 32; idx++) { 3018 snd_trident_pcm_mixer_t *tmix; 3019 3020 tmix = &trident->pcm_mixer[idx]; 3021 tmix->voice = NULL; 3022 } 3023 if ((trident->ctl_vol = snd_ctl_new1(&snd_trident_pcm_vol_control, trident)) == NULL) 3024 goto __nomem; 3025 if ((err = snd_ctl_add(card, trident->ctl_vol))) 3026 goto __out; 3027 3028 if ((trident->ctl_pan = snd_ctl_new1(&snd_trident_pcm_pan_control, trident)) == NULL) 3029 goto __nomem; 3030 if ((err = snd_ctl_add(card, trident->ctl_pan))) 3031 goto __out; 3032 3033 if ((trident->ctl_rvol = snd_ctl_new1(&snd_trident_pcm_rvol_control, trident)) == NULL) 3034 goto __nomem; 3035 if ((err = snd_ctl_add(card, trident->ctl_rvol))) 3036 goto __out; 3037 3038 if ((trident->ctl_cvol = snd_ctl_new1(&snd_trident_pcm_cvol_control, trident)) == NULL) 3039 goto __nomem; 3040 if ((err = snd_ctl_add(card, trident->ctl_cvol))) 3041 goto __out; 3042 3043 if (trident->device == TRIDENT_DEVICE_ID_NX) { 3044 if ((err = snd_ctl_add(card, kctl = snd_ctl_new1(&snd_trident_ac97_rear_control, trident))) < 0) 3045 goto __out; 3046 kctl->put(kctl, uctl); 3047 } 3048 if (trident->device == TRIDENT_DEVICE_ID_NX || trident->device == TRIDENT_DEVICE_ID_SI7018) { 3049 3050 kctl = snd_ctl_new1(&snd_trident_spdif_control, trident); 3051 if (kctl == NULL) { 3052 err = -ENOMEM; 3053 goto __out; 3054 } 3055 if (trident->ac97->ext_id & AC97_EI_SPDIF) 3056 kctl->id.index++; 3057 if (trident->ac97_sec && (trident->ac97_sec->ext_id & AC97_EI_SPDIF)) 3058 kctl->id.index++; 3059 idx = kctl->id.index; 3060 if ((err = snd_ctl_add(card, kctl)) < 0) 3061 goto __out; 3062 kctl->put(kctl, uctl); 3063 3064 kctl = snd_ctl_new1(&snd_trident_spdif_default, trident); 3065 if (kctl == NULL) { 3066 err = -ENOMEM; 3067 goto __out; 3068 } 3069 kctl->id.index = idx; 3070 kctl->id.device = pcm_spdif_device; 3071 if ((err = snd_ctl_add(card, kctl)) < 0) 3072 goto __out; 3073 3074 kctl = snd_ctl_new1(&snd_trident_spdif_mask, trident); 3075 if (kctl == NULL) { 3076 err = -ENOMEM; 3077 goto __out; 3078 } 3079 kctl->id.index = idx; 3080 kctl->id.device = pcm_spdif_device; 3081 if ((err = snd_ctl_add(card, kctl)) < 0) 3082 goto __out; 3083 3084 kctl = snd_ctl_new1(&snd_trident_spdif_stream, trident); 3085 if (kctl == NULL) { 3086 err = -ENOMEM; 3087 goto __out; 3088 } 3089 kctl->id.index = idx; 3090 kctl->id.device = pcm_spdif_device; 3091 if ((err = snd_ctl_add(card, kctl)) < 0) 3092 goto __out; 3093 trident->spdif_pcm_ctl = kctl; 3094 } 3095 3096 err = 0; 3097 goto __out; 3098 3099 __nomem: 3100 err = -ENOMEM; 3101 3102 __out: 3103 kfree(uctl); 3104 3105 return err; 3106 } 3107 3108 /* 3109 * gameport interface 3110 */ 3111 3112 #if defined(CONFIG_GAMEPORT) || (defined(MODULE) && defined(CONFIG_GAMEPORT_MODULE)) 3113 3114 static unsigned char snd_trident_gameport_read(struct gameport *gameport) 3115 { 3116 trident_t *chip = gameport_get_port_data(gameport); 3117 3118 snd_assert(chip, return 0); 3119 return inb(TRID_REG(chip, GAMEPORT_LEGACY)); 3120 } 3121 3122 static void snd_trident_gameport_trigger(struct gameport *gameport) 3123 { 3124 trident_t *chip = gameport_get_port_data(gameport); 3125 3126 snd_assert(chip, return); 3127 outb(0xff, TRID_REG(chip, GAMEPORT_LEGACY)); 3128 } 3129 3130 static int snd_trident_gameport_cooked_read(struct gameport *gameport, int *axes, int *buttons) 3131 { 3132 trident_t *chip = gameport_get_port_data(gameport); 3133 int i; 3134 3135 snd_assert(chip, return 0); 3136 3137 *buttons = (~inb(TRID_REG(chip, GAMEPORT_LEGACY)) >> 4) & 0xf; 3138 3139 for (i = 0; i < 4; i++) { 3140 axes[i] = inw(TRID_REG(chip, GAMEPORT_AXES + i * 2)); 3141 if (axes[i] == 0xffff) axes[i] = -1; 3142 } 3143 3144 return 0; 3145 } 3146 3147 static int snd_trident_gameport_open(struct gameport *gameport, int mode) 3148 { 3149 trident_t *chip = gameport_get_port_data(gameport); 3150 3151 snd_assert(chip, return 0); 3152 3153 switch (mode) { 3154 case GAMEPORT_MODE_COOKED: 3155 outb(GAMEPORT_MODE_ADC, TRID_REG(chip, GAMEPORT_GCR)); 3156 msleep(20); 3157 return 0; 3158 case GAMEPORT_MODE_RAW: 3159 outb(0, TRID_REG(chip, GAMEPORT_GCR)); 3160 return 0; 3161 default: 3162 return -1; 3163 } 3164 } 3165 3166 int __devinit snd_trident_create_gameport(trident_t *chip) 3167 { 3168 struct gameport *gp; 3169 3170 chip->gameport = gp = gameport_allocate_port(); 3171 if (!gp) { 3172 printk(KERN_ERR "trident: cannot allocate memory for gameport\n"); 3173 return -ENOMEM; 3174 } 3175 3176 gameport_set_name(gp, "Trident 4DWave"); 3177 gameport_set_phys(gp, "pci%s/gameport0", pci_name(chip->pci)); 3178 gameport_set_dev_parent(gp, &chip->pci->dev); 3179 3180 gameport_set_port_data(gp, chip); 3181 gp->fuzz = 64; 3182 gp->read = snd_trident_gameport_read; 3183 gp->trigger = snd_trident_gameport_trigger; 3184 gp->cooked_read = snd_trident_gameport_cooked_read; 3185 gp->open = snd_trident_gameport_open; 3186 3187 gameport_register_port(gp); 3188 3189 return 0; 3190 } 3191 3192 static inline void snd_trident_free_gameport(trident_t *chip) 3193 { 3194 if (chip->gameport) { 3195 gameport_unregister_port(chip->gameport); 3196 chip->gameport = NULL; 3197 } 3198 } 3199 #else 3200 int __devinit snd_trident_create_gameport(trident_t *chip) { return -ENOSYS; } 3201 static inline void snd_trident_free_gameport(trident_t *chip) { } 3202 #endif /* CONFIG_GAMEPORT */ 3203 3204 /* 3205 * delay for 1 tick 3206 */ 3207 static inline void do_delay(trident_t *chip) 3208 { 3209 set_current_state(TASK_UNINTERRUPTIBLE); 3210 schedule_timeout(1); 3211 } 3212 3213 /* 3214 * SiS reset routine 3215 */ 3216 3217 static int snd_trident_sis_reset(trident_t *trident) 3218 { 3219 unsigned long end_time; 3220 unsigned int i; 3221 int r; 3222 3223 r = trident->in_suspend ? 0 : 2; /* count of retries */ 3224 __si7018_retry: 3225 pci_write_config_byte(trident->pci, 0x46, 0x04); /* SOFTWARE RESET */ 3226 udelay(100); 3227 pci_write_config_byte(trident->pci, 0x46, 0x00); 3228 udelay(100); 3229 /* disable AC97 GPIO interrupt */ 3230 outb(0x00, TRID_REG(trident, SI_AC97_GPIO)); 3231 /* initialize serial interface, force cold reset */ 3232 i = PCMOUT|SURROUT|CENTEROUT|LFEOUT|SECONDARY_ID|COLD_RESET; 3233 outl(i, TRID_REG(trident, SI_SERIAL_INTF_CTRL)); 3234 udelay(1000); 3235 /* remove cold reset */ 3236 i &= ~COLD_RESET; 3237 outl(i, TRID_REG(trident, SI_SERIAL_INTF_CTRL)); 3238 udelay(2000); 3239 /* wait, until the codec is ready */ 3240 end_time = (jiffies + (HZ * 3) / 4) + 1; 3241 do { 3242 if ((inl(TRID_REG(trident, SI_SERIAL_INTF_CTRL)) & SI_AC97_PRIMARY_READY) != 0) 3243 goto __si7018_ok; 3244 do_delay(trident); 3245 } while (time_after_eq(end_time, jiffies)); 3246 snd_printk("AC'97 codec ready error [0x%x]\n", inl(TRID_REG(trident, SI_SERIAL_INTF_CTRL))); 3247 if (r-- > 0) { 3248 end_time = jiffies + HZ; 3249 do { 3250 do_delay(trident); 3251 } while (time_after_eq(end_time, jiffies)); 3252 goto __si7018_retry; 3253 } 3254 __si7018_ok: 3255 /* wait for the second codec */ 3256 do { 3257 if ((inl(TRID_REG(trident, SI_SERIAL_INTF_CTRL)) & SI_AC97_SECONDARY_READY) != 0) 3258 break; 3259 do_delay(trident); 3260 } while (time_after_eq(end_time, jiffies)); 3261 /* enable 64 channel mode */ 3262 outl(BANK_B_EN, TRID_REG(trident, T4D_LFO_GC_CIR)); 3263 return 0; 3264 } 3265 3266 /* 3267 * /proc interface 3268 */ 3269 3270 static void snd_trident_proc_read(snd_info_entry_t *entry, 3271 snd_info_buffer_t * buffer) 3272 { 3273 trident_t *trident = entry->private_data; 3274 char *s; 3275 3276 switch (trident->device) { 3277 case TRIDENT_DEVICE_ID_SI7018: 3278 s = "SiS 7018 Audio"; 3279 break; 3280 case TRIDENT_DEVICE_ID_DX: 3281 s = "Trident 4DWave PCI DX"; 3282 break; 3283 case TRIDENT_DEVICE_ID_NX: 3284 s = "Trident 4DWave PCI NX"; 3285 break; 3286 default: 3287 s = "???"; 3288 } 3289 snd_iprintf(buffer, "%s\n\n", s); 3290 snd_iprintf(buffer, "Spurious IRQs : %d\n", trident->spurious_irq_count); 3291 snd_iprintf(buffer, "Spurious IRQ dlta: %d\n", trident->spurious_irq_max_delta); 3292 if (trident->device == TRIDENT_DEVICE_ID_NX || trident->device == TRIDENT_DEVICE_ID_SI7018) 3293 snd_iprintf(buffer, "IEC958 Mixer Out : %s\n", trident->spdif_ctrl == 0x28 ? "on" : "off"); 3294 if (trident->device == TRIDENT_DEVICE_ID_NX) { 3295 snd_iprintf(buffer, "Rear Speakers : %s\n", trident->ac97_ctrl & 0x00000010 ? "on" : "off"); 3296 if (trident->tlb.entries) { 3297 snd_iprintf(buffer,"\nVirtual Memory\n"); 3298 snd_iprintf(buffer, "Memory Maximum : %d\n", trident->tlb.memhdr->size); 3299 snd_iprintf(buffer, "Memory Used : %d\n", trident->tlb.memhdr->used); 3300 snd_iprintf(buffer, "Memory Free : %d\n", snd_util_mem_avail(trident->tlb.memhdr)); 3301 } 3302 } 3303 #if defined(CONFIG_SND_SEQUENCER) || (defined(MODULE) && defined(CONFIG_SND_SEQUENCER_MODULE)) 3304 snd_iprintf(buffer,"\nWavetable Synth\n"); 3305 snd_iprintf(buffer, "Memory Maximum : %d\n", trident->synth.max_size); 3306 snd_iprintf(buffer, "Memory Used : %d\n", trident->synth.current_size); 3307 snd_iprintf(buffer, "Memory Free : %d\n", (trident->synth.max_size-trident->synth.current_size)); 3308 #endif 3309 } 3310 3311 static void __devinit snd_trident_proc_init(trident_t * trident) 3312 { 3313 snd_info_entry_t *entry; 3314 const char *s = "trident"; 3315 3316 if (trident->device == TRIDENT_DEVICE_ID_SI7018) 3317 s = "sis7018"; 3318 if (! snd_card_proc_new(trident->card, s, &entry)) 3319 snd_info_set_text_ops(entry, trident, 1024, snd_trident_proc_read); 3320 } 3321 3322 static int snd_trident_dev_free(snd_device_t *device) 3323 { 3324 trident_t *trident = device->device_data; 3325 return snd_trident_free(trident); 3326 } 3327 3328 /*--------------------------------------------------------------------------- 3329 snd_trident_tlb_alloc 3330 3331 Description: Allocate and set up the TLB page table on 4D NX. 3332 Each entry has 4 bytes (physical PCI address). 3333 3334 Paramters: trident - pointer to target device class for 4DWave. 3335 3336 Returns: 0 or negative error code 3337 3338 ---------------------------------------------------------------------------*/ 3339 3340 static int __devinit snd_trident_tlb_alloc(trident_t *trident) 3341 { 3342 int i; 3343 3344 /* TLB array must be aligned to 16kB !!! so we allocate 3345 32kB region and correct offset when necessary */ 3346 3347 if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(trident->pci), 3348 2 * SNDRV_TRIDENT_MAX_PAGES * 4, &trident->tlb.buffer) < 0) { 3349 snd_printk(KERN_ERR "trident: unable to allocate TLB buffer\n"); 3350 return -ENOMEM; 3351 } 3352 trident->tlb.entries = (unsigned int*)(((unsigned long)trident->tlb.buffer.area + SNDRV_TRIDENT_MAX_PAGES * 4 - 1) & ~(SNDRV_TRIDENT_MAX_PAGES * 4 - 1)); 3353 trident->tlb.entries_dmaaddr = (trident->tlb.buffer.addr + SNDRV_TRIDENT_MAX_PAGES * 4 - 1) & ~(SNDRV_TRIDENT_MAX_PAGES * 4 - 1); 3354 /* allocate shadow TLB page table (virtual addresses) */ 3355 trident->tlb.shadow_entries = (unsigned long *)vmalloc(SNDRV_TRIDENT_MAX_PAGES*sizeof(unsigned long)); 3356 if (trident->tlb.shadow_entries == NULL) { 3357 snd_printk(KERN_ERR "trident: unable to allocate shadow TLB entries\n"); 3358 return -ENOMEM; 3359 } 3360 /* allocate and setup silent page and initialise TLB entries */ 3361 if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(trident->pci), 3362 SNDRV_TRIDENT_PAGE_SIZE, &trident->tlb.silent_page) < 0) { 3363 snd_printk(KERN_ERR "trident: unable to allocate silent page\n"); 3364 return -ENOMEM; 3365 } 3366 memset(trident->tlb.silent_page.area, 0, SNDRV_TRIDENT_PAGE_SIZE); 3367 for (i = 0; i < SNDRV_TRIDENT_MAX_PAGES; i++) { 3368 trident->tlb.entries[i] = cpu_to_le32(trident->tlb.silent_page.addr & ~(SNDRV_TRIDENT_PAGE_SIZE-1)); 3369 trident->tlb.shadow_entries[i] = (unsigned long)trident->tlb.silent_page.area; 3370 } 3371 3372 /* use emu memory block manager code to manage tlb page allocation */ 3373 trident->tlb.memhdr = snd_util_memhdr_new(SNDRV_TRIDENT_PAGE_SIZE * SNDRV_TRIDENT_MAX_PAGES); 3374 if (trident->tlb.memhdr == NULL) 3375 return -ENOMEM; 3376 3377 trident->tlb.memhdr->block_extra_size = sizeof(snd_trident_memblk_arg_t); 3378 return 0; 3379 } 3380 3381 /* 3382 * initialize 4D DX chip 3383 */ 3384 3385 static void snd_trident_stop_all_voices(trident_t *trident) 3386 { 3387 outl(0xffffffff, TRID_REG(trident, T4D_STOP_A)); 3388 outl(0xffffffff, TRID_REG(trident, T4D_STOP_B)); 3389 outl(0, TRID_REG(trident, T4D_AINTEN_A)); 3390 outl(0, TRID_REG(trident, T4D_AINTEN_B)); 3391 } 3392 3393 static int snd_trident_4d_dx_init(trident_t *trident) 3394 { 3395 struct pci_dev *pci = trident->pci; 3396 unsigned long end_time; 3397 3398 /* reset the legacy configuration and whole audio/wavetable block */ 3399 pci_write_config_dword(pci, 0x40, 0); /* DDMA */ 3400 pci_write_config_byte(pci, 0x44, 0); /* ports */ 3401 pci_write_config_byte(pci, 0x45, 0); /* Legacy DMA */ 3402 pci_write_config_byte(pci, 0x46, 4); /* reset */ 3403 udelay(100); 3404 pci_write_config_byte(pci, 0x46, 0); /* release reset */ 3405 udelay(100); 3406 3407 /* warm reset of the AC'97 codec */ 3408 outl(0x00000001, TRID_REG(trident, DX_ACR2_AC97_COM_STAT)); 3409 udelay(100); 3410 outl(0x00000000, TRID_REG(trident, DX_ACR2_AC97_COM_STAT)); 3411 /* DAC on, disable SB IRQ and try to force ADC valid signal */ 3412 trident->ac97_ctrl = 0x0000004a; 3413 outl(trident->ac97_ctrl, TRID_REG(trident, DX_ACR2_AC97_COM_STAT)); 3414 /* wait, until the codec is ready */ 3415 end_time = (jiffies + (HZ * 3) / 4) + 1; 3416 do { 3417 if ((inl(TRID_REG(trident, DX_ACR2_AC97_COM_STAT)) & 0x0010) != 0) 3418 goto __dx_ok; 3419 do_delay(trident); 3420 } while (time_after_eq(end_time, jiffies)); 3421 snd_printk(KERN_ERR "AC'97 codec ready error\n"); 3422 return -EIO; 3423 3424 __dx_ok: 3425 snd_trident_stop_all_voices(trident); 3426 3427 return 0; 3428 } 3429 3430 /* 3431 * initialize 4D NX chip 3432 */ 3433 static int snd_trident_4d_nx_init(trident_t *trident) 3434 { 3435 struct pci_dev *pci = trident->pci; 3436 unsigned long end_time; 3437 3438 /* reset the legacy configuration and whole audio/wavetable block */ 3439 pci_write_config_dword(pci, 0x40, 0); /* DDMA */ 3440 pci_write_config_byte(pci, 0x44, 0); /* ports */ 3441 pci_write_config_byte(pci, 0x45, 0); /* Legacy DMA */ 3442 3443 pci_write_config_byte(pci, 0x46, 1); /* reset */ 3444 udelay(100); 3445 pci_write_config_byte(pci, 0x46, 0); /* release reset */ 3446 udelay(100); 3447 3448 /* warm reset of the AC'97 codec */ 3449 outl(0x00000001, TRID_REG(trident, NX_ACR0_AC97_COM_STAT)); 3450 udelay(100); 3451 outl(0x00000000, TRID_REG(trident, NX_ACR0_AC97_COM_STAT)); 3452 /* wait, until the codec is ready */ 3453 end_time = (jiffies + (HZ * 3) / 4) + 1; 3454 do { 3455 if ((inl(TRID_REG(trident, NX_ACR0_AC97_COM_STAT)) & 0x0008) != 0) 3456 goto __nx_ok; 3457 do_delay(trident); 3458 } while (time_after_eq(end_time, jiffies)); 3459 snd_printk(KERN_ERR "AC'97 codec ready error [0x%x]\n", inl(TRID_REG(trident, NX_ACR0_AC97_COM_STAT))); 3460 return -EIO; 3461 3462 __nx_ok: 3463 /* DAC on */ 3464 trident->ac97_ctrl = 0x00000002; 3465 outl(trident->ac97_ctrl, TRID_REG(trident, NX_ACR0_AC97_COM_STAT)); 3466 /* disable SB IRQ */ 3467 outl(NX_SB_IRQ_DISABLE, TRID_REG(trident, T4D_MISCINT)); 3468 3469 snd_trident_stop_all_voices(trident); 3470 3471 if (trident->tlb.entries != NULL) { 3472 unsigned int i; 3473 /* enable virtual addressing via TLB */ 3474 i = trident->tlb.entries_dmaaddr; 3475 i |= 0x00000001; 3476 outl(i, TRID_REG(trident, NX_TLBC)); 3477 } else { 3478 outl(0, TRID_REG(trident, NX_TLBC)); 3479 } 3480 /* initialize S/PDIF */ 3481 outl(trident->spdif_bits, TRID_REG(trident, NX_SPCSTATUS)); 3482 outb(trident->spdif_ctrl, TRID_REG(trident, NX_SPCTRL_SPCSO + 3)); 3483 3484 return 0; 3485 } 3486 3487 /* 3488 * initialize sis7018 chip 3489 */ 3490 static int snd_trident_sis_init(trident_t *trident) 3491 { 3492 int err; 3493 3494 if ((err = snd_trident_sis_reset(trident)) < 0) 3495 return err; 3496 3497 snd_trident_stop_all_voices(trident); 3498 3499 /* initialize S/PDIF */ 3500 outl(trident->spdif_bits, TRID_REG(trident, SI_SPDIF_CS)); 3501 3502 return 0; 3503 } 3504 3505 /*--------------------------------------------------------------------------- 3506 snd_trident_create 3507 3508 Description: This routine will create the device specific class for 3509 the 4DWave card. It will also perform basic initialization. 3510 3511 Paramters: card - which card to create 3512 pci - interface to PCI bus resource info 3513 dma1ptr - playback dma buffer 3514 dma2ptr - capture dma buffer 3515 irqptr - interrupt resource info 3516 3517 Returns: 4DWave device class private data 3518 3519 ---------------------------------------------------------------------------*/ 3520 3521 int __devinit snd_trident_create(snd_card_t * card, 3522 struct pci_dev *pci, 3523 int pcm_streams, 3524 int pcm_spdif_device, 3525 int max_wavetable_size, 3526 trident_t ** rtrident) 3527 { 3528 trident_t *trident; 3529 int i, err; 3530 snd_trident_voice_t *voice; 3531 snd_trident_pcm_mixer_t *tmix; 3532 static snd_device_ops_t ops = { 3533 .dev_free = snd_trident_dev_free, 3534 }; 3535 3536 *rtrident = NULL; 3537 3538 /* enable PCI device */ 3539 if ((err = pci_enable_device(pci)) < 0) 3540 return err; 3541 /* check, if we can restrict PCI DMA transfers to 30 bits */ 3542 if (pci_set_dma_mask(pci, 0x3fffffff) < 0 || 3543 pci_set_consistent_dma_mask(pci, 0x3fffffff) < 0) { 3544 snd_printk("architecture does not support 30bit PCI busmaster DMA\n"); 3545 pci_disable_device(pci); 3546 return -ENXIO; 3547 } 3548 3549 trident = kzalloc(sizeof(*trident), GFP_KERNEL); 3550 if (trident == NULL) { 3551 pci_disable_device(pci); 3552 return -ENOMEM; 3553 } 3554 trident->device = (pci->vendor << 16) | pci->device; 3555 trident->card = card; 3556 trident->pci = pci; 3557 spin_lock_init(&trident->reg_lock); 3558 spin_lock_init(&trident->event_lock); 3559 spin_lock_init(&trident->voice_alloc); 3560 if (pcm_streams < 1) 3561 pcm_streams = 1; 3562 if (pcm_streams > 32) 3563 pcm_streams = 32; 3564 trident->ChanPCM = pcm_streams; 3565 if (max_wavetable_size < 0 ) 3566 max_wavetable_size = 0; 3567 trident->synth.max_size = max_wavetable_size * 1024; 3568 trident->irq = -1; 3569 3570 trident->midi_port = TRID_REG(trident, T4D_MPU401_BASE); 3571 pci_set_master(pci); 3572 3573 if ((err = pci_request_regions(pci, "Trident Audio")) < 0) { 3574 kfree(trident); 3575 pci_disable_device(pci); 3576 return err; 3577 } 3578 trident->port = pci_resource_start(pci, 0); 3579 3580 if (request_irq(pci->irq, snd_trident_interrupt, SA_INTERRUPT|SA_SHIRQ, "Trident Audio", (void *) trident)) { 3581 snd_printk("unable to grab IRQ %d\n", pci->irq); 3582 snd_trident_free(trident); 3583 return -EBUSY; 3584 } 3585 trident->irq = pci->irq; 3586 3587 /* allocate 16k-aligned TLB for NX cards */ 3588 trident->tlb.entries = NULL; 3589 trident->tlb.buffer.area = NULL; 3590 if (trident->device == TRIDENT_DEVICE_ID_NX) { 3591 if ((err = snd_trident_tlb_alloc(trident)) < 0) { 3592 snd_trident_free(trident); 3593 return err; 3594 } 3595 } 3596 3597 trident->spdif_bits = trident->spdif_pcm_bits = SNDRV_PCM_DEFAULT_CON_SPDIF; 3598 3599 /* initialize chip */ 3600 switch (trident->device) { 3601 case TRIDENT_DEVICE_ID_DX: 3602 err = snd_trident_4d_dx_init(trident); 3603 break; 3604 case TRIDENT_DEVICE_ID_NX: 3605 err = snd_trident_4d_nx_init(trident); 3606 break; 3607 case TRIDENT_DEVICE_ID_SI7018: 3608 err = snd_trident_sis_init(trident); 3609 break; 3610 default: 3611 snd_BUG(); 3612 break; 3613 } 3614 if (err < 0) { 3615 snd_trident_free(trident); 3616 return err; 3617 } 3618 3619 if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, trident, &ops)) < 0) { 3620 snd_trident_free(trident); 3621 return err; 3622 } 3623 3624 if ((err = snd_trident_mixer(trident, pcm_spdif_device)) < 0) 3625 return err; 3626 3627 /* initialise synth voices */ 3628 for (i = 0; i < 64; i++) { 3629 voice = &trident->synth.voices[i]; 3630 voice->number = i; 3631 voice->trident = trident; 3632 } 3633 /* initialize pcm mixer entries */ 3634 for (i = 0; i < 32; i++) { 3635 tmix = &trident->pcm_mixer[i]; 3636 tmix->vol = T4D_DEFAULT_PCM_VOL; 3637 tmix->pan = T4D_DEFAULT_PCM_PAN; 3638 tmix->rvol = T4D_DEFAULT_PCM_RVOL; 3639 tmix->cvol = T4D_DEFAULT_PCM_CVOL; 3640 } 3641 3642 snd_trident_enable_eso(trident); 3643 3644 3645 snd_card_set_pm_callback(card, snd_trident_suspend, snd_trident_resume, trident); 3646 snd_trident_proc_init(trident); 3647 snd_card_set_dev(card, &pci->dev); 3648 *rtrident = trident; 3649 return 0; 3650 } 3651 3652 /*--------------------------------------------------------------------------- 3653 snd_trident_free 3654 3655 Description: This routine will free the device specific class for 3656 the 4DWave card. 3657 3658 Paramters: trident - device specific private data for 4DWave card 3659 3660 Returns: None. 3661 3662 ---------------------------------------------------------------------------*/ 3663 3664 static int snd_trident_free(trident_t *trident) 3665 { 3666 snd_trident_free_gameport(trident); 3667 snd_trident_disable_eso(trident); 3668 // Disable S/PDIF out 3669 if (trident->device == TRIDENT_DEVICE_ID_NX) 3670 outb(0x00, TRID_REG(trident, NX_SPCTRL_SPCSO + 3)); 3671 else if (trident->device == TRIDENT_DEVICE_ID_SI7018) { 3672 outl(0, TRID_REG(trident, SI_SERIAL_INTF_CTRL)); 3673 } 3674 if (trident->tlb.buffer.area) { 3675 outl(0, TRID_REG(trident, NX_TLBC)); 3676 if (trident->tlb.memhdr) 3677 snd_util_memhdr_free(trident->tlb.memhdr); 3678 if (trident->tlb.silent_page.area) 3679 snd_dma_free_pages(&trident->tlb.silent_page); 3680 vfree(trident->tlb.shadow_entries); 3681 snd_dma_free_pages(&trident->tlb.buffer); 3682 } 3683 if (trident->irq >= 0) 3684 free_irq(trident->irq, (void *)trident); 3685 pci_release_regions(trident->pci); 3686 pci_disable_device(trident->pci); 3687 kfree(trident); 3688 return 0; 3689 } 3690 3691 /*--------------------------------------------------------------------------- 3692 snd_trident_interrupt 3693 3694 Description: ISR for Trident 4DWave device 3695 3696 Paramters: trident - device specific private data for 4DWave card 3697 3698 Problems: It seems that Trident chips generates interrupts more than 3699 one time in special cases. The spurious interrupts are 3700 detected via sample timer (T4D_STIMER) and computing 3701 corresponding delta value. The limits are detected with 3702 the method try & fail so it is possible that it won't 3703 work on all computers. [jaroslav] 3704 3705 Returns: None. 3706 3707 ---------------------------------------------------------------------------*/ 3708 3709 static irqreturn_t snd_trident_interrupt(int irq, void *dev_id, struct pt_regs *regs) 3710 { 3711 trident_t *trident = dev_id; 3712 unsigned int audio_int, chn_int, stimer, channel, mask, tmp; 3713 int delta; 3714 snd_trident_voice_t *voice; 3715 3716 audio_int = inl(TRID_REG(trident, T4D_MISCINT)); 3717 if ((audio_int & (ADDRESS_IRQ|MPU401_IRQ)) == 0) 3718 return IRQ_NONE; 3719 if (audio_int & ADDRESS_IRQ) { 3720 // get interrupt status for all channels 3721 spin_lock(&trident->reg_lock); 3722 stimer = inl(TRID_REG(trident, T4D_STIMER)) & 0x00ffffff; 3723 chn_int = inl(TRID_REG(trident, T4D_AINT_A)); 3724 if (chn_int == 0) 3725 goto __skip1; 3726 outl(chn_int, TRID_REG(trident, T4D_AINT_A)); /* ack */ 3727 __skip1: 3728 chn_int = inl(TRID_REG(trident, T4D_AINT_B)); 3729 if (chn_int == 0) 3730 goto __skip2; 3731 for (channel = 63; channel >= 32; channel--) { 3732 mask = 1 << (channel&0x1f); 3733 if ((chn_int & mask) == 0) 3734 continue; 3735 voice = &trident->synth.voices[channel]; 3736 if (!voice->pcm || voice->substream == NULL) { 3737 outl(mask, TRID_REG(trident, T4D_STOP_B)); 3738 continue; 3739 } 3740 delta = (int)stimer - (int)voice->stimer; 3741 if (delta < 0) 3742 delta = -delta; 3743 if ((unsigned int)delta < voice->spurious_threshold) { 3744 /* do some statistics here */ 3745 trident->spurious_irq_count++; 3746 if (trident->spurious_irq_max_delta < (unsigned int)delta) 3747 trident->spurious_irq_max_delta = delta; 3748 continue; 3749 } 3750 voice->stimer = stimer; 3751 if (voice->isync) { 3752 if (!voice->isync3) { 3753 tmp = inw(TRID_REG(trident, T4D_SBBL_SBCL)); 3754 if (trident->bDMAStart & 0x40) 3755 tmp >>= 1; 3756 if (tmp > 0) 3757 tmp = voice->isync_max - tmp; 3758 } else { 3759 tmp = inl(TRID_REG(trident, NX_SPCTRL_SPCSO)) & 0x00ffffff; 3760 } 3761 if (tmp < voice->isync_mark) { 3762 if (tmp > 0x10) 3763 tmp = voice->isync_ESO - 7; 3764 else 3765 tmp = voice->isync_ESO + 2; 3766 /* update ESO for IRQ voice to preserve sync */ 3767 snd_trident_stop_voice(trident, voice->number); 3768 snd_trident_write_eso_reg(trident, voice, tmp); 3769 snd_trident_start_voice(trident, voice->number); 3770 } 3771 } else if (voice->isync2) { 3772 voice->isync2 = 0; 3773 /* write original ESO and update CSO for IRQ voice to preserve sync */ 3774 snd_trident_stop_voice(trident, voice->number); 3775 snd_trident_write_cso_reg(trident, voice, voice->isync_mark); 3776 snd_trident_write_eso_reg(trident, voice, voice->ESO); 3777 snd_trident_start_voice(trident, voice->number); 3778 } 3779 #if 0 3780 if (voice->extra) { 3781 /* update CSO for extra voice to preserve sync */ 3782 snd_trident_stop_voice(trident, voice->extra->number); 3783 snd_trident_write_cso_reg(trident, voice->extra, 0); 3784 snd_trident_start_voice(trident, voice->extra->number); 3785 } 3786 #endif 3787 spin_unlock(&trident->reg_lock); 3788 snd_pcm_period_elapsed(voice->substream); 3789 spin_lock(&trident->reg_lock); 3790 } 3791 outl(chn_int, TRID_REG(trident, T4D_AINT_B)); /* ack */ 3792 __skip2: 3793 spin_unlock(&trident->reg_lock); 3794 } 3795 if (audio_int & MPU401_IRQ) { 3796 if (trident->rmidi) { 3797 snd_mpu401_uart_interrupt(irq, trident->rmidi->private_data, regs); 3798 } else { 3799 inb(TRID_REG(trident, T4D_MPUR0)); 3800 } 3801 } 3802 // outl((ST_TARGET_REACHED | MIXER_OVERFLOW | MIXER_UNDERFLOW), TRID_REG(trident, T4D_MISCINT)); 3803 return IRQ_HANDLED; 3804 } 3805 3806 /*--------------------------------------------------------------------------- 3807 snd_trident_attach_synthesizer 3808 3809 Description: Attach synthesizer hooks 3810 3811 Paramters: trident - device specific private data for 4DWave card 3812 3813 Returns: None. 3814 3815 ---------------------------------------------------------------------------*/ 3816 int snd_trident_attach_synthesizer(trident_t *trident) 3817 { 3818 #if defined(CONFIG_SND_SEQUENCER) || (defined(MODULE) && defined(CONFIG_SND_SEQUENCER_MODULE)) 3819 if (snd_seq_device_new(trident->card, 1, SNDRV_SEQ_DEV_ID_TRIDENT, 3820 sizeof(trident_t*), &trident->seq_dev) >= 0) { 3821 strcpy(trident->seq_dev->name, "4DWave"); 3822 *(trident_t**)SNDRV_SEQ_DEVICE_ARGPTR(trident->seq_dev) = trident; 3823 } 3824 #endif 3825 return 0; 3826 } 3827 3828 snd_trident_voice_t *snd_trident_alloc_voice(trident_t * trident, int type, int client, int port) 3829 { 3830 snd_trident_voice_t *pvoice; 3831 unsigned long flags; 3832 int idx; 3833 3834 spin_lock_irqsave(&trident->voice_alloc, flags); 3835 if (type == SNDRV_TRIDENT_VOICE_TYPE_PCM) { 3836 idx = snd_trident_allocate_pcm_channel(trident); 3837 if(idx < 0) { 3838 spin_unlock_irqrestore(&trident->voice_alloc, flags); 3839 return NULL; 3840 } 3841 pvoice = &trident->synth.voices[idx]; 3842 pvoice->use = 1; 3843 pvoice->pcm = 1; 3844 pvoice->capture = 0; 3845 pvoice->spdif = 0; 3846 pvoice->memblk = NULL; 3847 pvoice->substream = NULL; 3848 spin_unlock_irqrestore(&trident->voice_alloc, flags); 3849 return pvoice; 3850 } 3851 if (type == SNDRV_TRIDENT_VOICE_TYPE_SYNTH) { 3852 idx = snd_trident_allocate_synth_channel(trident); 3853 if(idx < 0) { 3854 spin_unlock_irqrestore(&trident->voice_alloc, flags); 3855 return NULL; 3856 } 3857 pvoice = &trident->synth.voices[idx]; 3858 pvoice->use = 1; 3859 pvoice->synth = 1; 3860 pvoice->client = client; 3861 pvoice->port = port; 3862 pvoice->memblk = NULL; 3863 spin_unlock_irqrestore(&trident->voice_alloc, flags); 3864 return pvoice; 3865 } 3866 if (type == SNDRV_TRIDENT_VOICE_TYPE_MIDI) { 3867 } 3868 spin_unlock_irqrestore(&trident->voice_alloc, flags); 3869 return NULL; 3870 } 3871 3872 void snd_trident_free_voice(trident_t * trident, snd_trident_voice_t *voice) 3873 { 3874 unsigned long flags; 3875 void (*private_free)(snd_trident_voice_t *); 3876 void *private_data; 3877 3878 if (voice == NULL || !voice->use) 3879 return; 3880 snd_trident_clear_voices(trident, voice->number, voice->number); 3881 spin_lock_irqsave(&trident->voice_alloc, flags); 3882 private_free = voice->private_free; 3883 private_data = voice->private_data; 3884 voice->private_free = NULL; 3885 voice->private_data = NULL; 3886 if (voice->pcm) 3887 snd_trident_free_pcm_channel(trident, voice->number); 3888 if (voice->synth) 3889 snd_trident_free_synth_channel(trident, voice->number); 3890 voice->use = voice->pcm = voice->synth = voice->midi = 0; 3891 voice->capture = voice->spdif = 0; 3892 voice->sample_ops = NULL; 3893 voice->substream = NULL; 3894 voice->extra = NULL; 3895 spin_unlock_irqrestore(&trident->voice_alloc, flags); 3896 if (private_free) 3897 private_free(voice); 3898 } 3899 3900 static void snd_trident_clear_voices(trident_t * trident, unsigned short v_min, unsigned short v_max) 3901 { 3902 unsigned int i, val, mask[2] = { 0, 0 }; 3903 3904 snd_assert(v_min <= 63, return); 3905 snd_assert(v_max <= 63, return); 3906 for (i = v_min; i <= v_max; i++) 3907 mask[i >> 5] |= 1 << (i & 0x1f); 3908 if (mask[0]) { 3909 outl(mask[0], TRID_REG(trident, T4D_STOP_A)); 3910 val = inl(TRID_REG(trident, T4D_AINTEN_A)); 3911 outl(val & ~mask[0], TRID_REG(trident, T4D_AINTEN_A)); 3912 } 3913 if (mask[1]) { 3914 outl(mask[1], TRID_REG(trident, T4D_STOP_B)); 3915 val = inl(TRID_REG(trident, T4D_AINTEN_B)); 3916 outl(val & ~mask[1], TRID_REG(trident, T4D_AINTEN_B)); 3917 } 3918 } 3919 3920 #ifdef CONFIG_PM 3921 static int snd_trident_suspend(snd_card_t *card, pm_message_t state) 3922 { 3923 trident_t *trident = card->pm_private_data; 3924 3925 trident->in_suspend = 1; 3926 snd_pcm_suspend_all(trident->pcm); 3927 if (trident->foldback) 3928 snd_pcm_suspend_all(trident->foldback); 3929 if (trident->spdif) 3930 snd_pcm_suspend_all(trident->spdif); 3931 3932 snd_ac97_suspend(trident->ac97); 3933 if (trident->ac97_sec) 3934 snd_ac97_suspend(trident->ac97_sec); 3935 3936 switch (trident->device) { 3937 case TRIDENT_DEVICE_ID_DX: 3938 case TRIDENT_DEVICE_ID_NX: 3939 break; /* TODO */ 3940 case TRIDENT_DEVICE_ID_SI7018: 3941 break; 3942 } 3943 pci_disable_device(trident->pci); 3944 return 0; 3945 } 3946 3947 static int snd_trident_resume(snd_card_t *card) 3948 { 3949 trident_t *trident = card->pm_private_data; 3950 3951 pci_enable_device(trident->pci); 3952 if (pci_set_dma_mask(trident->pci, 0x3fffffff) < 0 || 3953 pci_set_consistent_dma_mask(trident->pci, 0x3fffffff) < 0) 3954 snd_printk(KERN_WARNING "trident: can't set the proper DMA mask\n"); 3955 pci_set_master(trident->pci); /* to be sure */ 3956 3957 switch (trident->device) { 3958 case TRIDENT_DEVICE_ID_DX: 3959 snd_trident_4d_dx_init(trident); 3960 break; 3961 case TRIDENT_DEVICE_ID_NX: 3962 snd_trident_4d_nx_init(trident); 3963 break; 3964 case TRIDENT_DEVICE_ID_SI7018: 3965 snd_trident_sis_init(trident); 3966 break; 3967 } 3968 3969 snd_ac97_resume(trident->ac97); 3970 if (trident->ac97_sec) 3971 snd_ac97_resume(trident->ac97_sec); 3972 3973 /* restore some registers */ 3974 outl(trident->musicvol_wavevol, TRID_REG(trident, T4D_MUSICVOL_WAVEVOL)); 3975 3976 snd_trident_enable_eso(trident); 3977 3978 trident->in_suspend = 0; 3979 return 0; 3980 } 3981 #endif /* CONFIG_PM */ 3982 3983 EXPORT_SYMBOL(snd_trident_alloc_voice); 3984 EXPORT_SYMBOL(snd_trident_free_voice); 3985 EXPORT_SYMBOL(snd_trident_start_voice); 3986 EXPORT_SYMBOL(snd_trident_stop_voice); 3987 EXPORT_SYMBOL(snd_trident_write_voice_regs); 3988 /* trident_memory.c symbols */ 3989 EXPORT_SYMBOL(snd_trident_synth_alloc); 3990 EXPORT_SYMBOL(snd_trident_synth_free); 3991 EXPORT_SYMBOL(snd_trident_synth_copy_from_user); 3992