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 } 476 477 outb(voice->number, TRID_REG(trident, T4D_LFO_GC_CIR)); 478 outl(regs[0], TRID_REG(trident, CH_START + 0)); 479 outl(regs[1], TRID_REG(trident, CH_START + 4)); 480 outl(regs[2], TRID_REG(trident, CH_START + 8)); 481 outl(regs[3], TRID_REG(trident, CH_START + 12)); 482 outl(regs[4], TRID_REG(trident, CH_START + 16)); 483 484 #if 0 485 printk("written %i channel:\n", voice->number); 486 printk(" regs[0] = 0x%x/0x%x\n", regs[0], inl(TRID_REG(trident, CH_START + 0))); 487 printk(" regs[1] = 0x%x/0x%x\n", regs[1], inl(TRID_REG(trident, CH_START + 4))); 488 printk(" regs[2] = 0x%x/0x%x\n", regs[2], inl(TRID_REG(trident, CH_START + 8))); 489 printk(" regs[3] = 0x%x/0x%x\n", regs[3], inl(TRID_REG(trident, CH_START + 12))); 490 printk(" regs[4] = 0x%x/0x%x\n", regs[4], inl(TRID_REG(trident, CH_START + 16))); 491 #endif 492 } 493 494 /*--------------------------------------------------------------------------- 495 snd_trident_write_cso_reg 496 497 Description: This routine will write the new CSO offset 498 register to hardware. 499 500 Paramters: trident - pointer to target device class for 4DWave. 501 voice - synthesizer voice structure 502 CSO - new CSO value 503 504 ---------------------------------------------------------------------------*/ 505 506 static void snd_trident_write_cso_reg(trident_t * trident, snd_trident_voice_t * voice, unsigned int CSO) 507 { 508 voice->CSO = CSO; 509 outb(voice->number, TRID_REG(trident, T4D_LFO_GC_CIR)); 510 if (trident->device != TRIDENT_DEVICE_ID_NX) { 511 outw(voice->CSO, TRID_REG(trident, CH_DX_CSO_ALPHA_FMS) + 2); 512 } else { 513 outl((voice->Delta << 24) | (voice->CSO & 0x00ffffff), TRID_REG(trident, CH_NX_DELTA_CSO)); 514 } 515 } 516 517 /*--------------------------------------------------------------------------- 518 snd_trident_write_eso_reg 519 520 Description: This routine will write the new ESO offset 521 register to hardware. 522 523 Paramters: trident - pointer to target device class for 4DWave. 524 voice - synthesizer voice structure 525 ESO - new ESO value 526 527 ---------------------------------------------------------------------------*/ 528 529 static void snd_trident_write_eso_reg(trident_t * trident, snd_trident_voice_t * voice, unsigned int ESO) 530 { 531 voice->ESO = ESO; 532 outb(voice->number, TRID_REG(trident, T4D_LFO_GC_CIR)); 533 if (trident->device != TRIDENT_DEVICE_ID_NX) { 534 outw(voice->ESO, TRID_REG(trident, CH_DX_ESO_DELTA) + 2); 535 } else { 536 outl(((voice->Delta << 16) & 0xff000000) | (voice->ESO & 0x00ffffff), TRID_REG(trident, CH_NX_DELTA_ESO)); 537 } 538 } 539 540 /*--------------------------------------------------------------------------- 541 snd_trident_write_vol_reg 542 543 Description: This routine will write the new voice volume 544 register to hardware. 545 546 Paramters: trident - pointer to target device class for 4DWave. 547 voice - synthesizer voice structure 548 Vol - new voice volume 549 550 ---------------------------------------------------------------------------*/ 551 552 static void snd_trident_write_vol_reg(trident_t * trident, snd_trident_voice_t * voice, unsigned int Vol) 553 { 554 voice->Vol = Vol; 555 outb(voice->number, TRID_REG(trident, T4D_LFO_GC_CIR)); 556 switch (trident->device) { 557 case TRIDENT_DEVICE_ID_DX: 558 case TRIDENT_DEVICE_ID_NX: 559 outb(voice->Vol >> 2, TRID_REG(trident, CH_GVSEL_PAN_VOL_CTRL_EC + 2)); 560 break; 561 case TRIDENT_DEVICE_ID_SI7018: 562 // printk("voice->Vol = 0x%x\n", voice->Vol); 563 outw((voice->CTRL << 12) | voice->Vol, TRID_REG(trident, CH_GVSEL_PAN_VOL_CTRL_EC)); 564 break; 565 } 566 } 567 568 /*--------------------------------------------------------------------------- 569 snd_trident_write_pan_reg 570 571 Description: This routine will write the new voice pan 572 register to hardware. 573 574 Paramters: trident - pointer to target device class for 4DWave. 575 voice - synthesizer voice structure 576 Pan - new pan value 577 578 ---------------------------------------------------------------------------*/ 579 580 static void snd_trident_write_pan_reg(trident_t * trident, snd_trident_voice_t * voice, unsigned int Pan) 581 { 582 voice->Pan = Pan; 583 outb(voice->number, TRID_REG(trident, T4D_LFO_GC_CIR)); 584 outb(((voice->GVSel & 0x01) << 7) | (voice->Pan & 0x7f), TRID_REG(trident, CH_GVSEL_PAN_VOL_CTRL_EC + 3)); 585 } 586 587 /*--------------------------------------------------------------------------- 588 snd_trident_write_rvol_reg 589 590 Description: This routine will write the new reverb volume 591 register to hardware. 592 593 Paramters: trident - pointer to target device class for 4DWave. 594 voice - synthesizer voice structure 595 RVol - new reverb volume 596 597 ---------------------------------------------------------------------------*/ 598 599 static void snd_trident_write_rvol_reg(trident_t * trident, snd_trident_voice_t * voice, unsigned int RVol) 600 { 601 voice->RVol = RVol; 602 outb(voice->number, TRID_REG(trident, T4D_LFO_GC_CIR)); 603 outw(((voice->FMC & 0x0003) << 14) | ((voice->RVol & 0x007f) << 7) | (voice->CVol & 0x007f), 604 TRID_REG(trident, trident->device == TRIDENT_DEVICE_ID_NX ? CH_NX_ALPHA_FMS_FMC_RVOL_CVOL : CH_DX_FMC_RVOL_CVOL)); 605 } 606 607 /*--------------------------------------------------------------------------- 608 snd_trident_write_cvol_reg 609 610 Description: This routine will write the new chorus volume 611 register to hardware. 612 613 Paramters: trident - pointer to target device class for 4DWave. 614 voice - synthesizer voice structure 615 CVol - new chorus volume 616 617 ---------------------------------------------------------------------------*/ 618 619 static void snd_trident_write_cvol_reg(trident_t * trident, snd_trident_voice_t * voice, unsigned int CVol) 620 { 621 voice->CVol = CVol; 622 outb(voice->number, TRID_REG(trident, T4D_LFO_GC_CIR)); 623 outw(((voice->FMC & 0x0003) << 14) | ((voice->RVol & 0x007f) << 7) | (voice->CVol & 0x007f), 624 TRID_REG(trident, trident->device == TRIDENT_DEVICE_ID_NX ? CH_NX_ALPHA_FMS_FMC_RVOL_CVOL : CH_DX_FMC_RVOL_CVOL)); 625 } 626 627 /*--------------------------------------------------------------------------- 628 snd_trident_convert_rate 629 630 Description: This routine converts rate in HZ to hardware delta value. 631 632 Paramters: trident - pointer to target device class for 4DWave. 633 rate - Real or Virtual channel number. 634 635 Returns: Delta value. 636 637 ---------------------------------------------------------------------------*/ 638 static unsigned int snd_trident_convert_rate(unsigned int rate) 639 { 640 unsigned int delta; 641 642 // We special case 44100 and 8000 since rounding with the equation 643 // does not give us an accurate enough value. For 11025 and 22050 644 // the equation gives us the best answer. All other frequencies will 645 // also use the equation. JDW 646 if (rate == 44100) 647 delta = 0xeb3; 648 else if (rate == 8000) 649 delta = 0x2ab; 650 else if (rate == 48000) 651 delta = 0x1000; 652 else 653 delta = (((rate << 12) + 24000) / 48000) & 0x0000ffff; 654 return delta; 655 } 656 657 /*--------------------------------------------------------------------------- 658 snd_trident_convert_adc_rate 659 660 Description: This routine converts rate in HZ to hardware delta value. 661 662 Paramters: trident - pointer to target device class for 4DWave. 663 rate - Real or Virtual channel number. 664 665 Returns: Delta value. 666 667 ---------------------------------------------------------------------------*/ 668 static unsigned int snd_trident_convert_adc_rate(unsigned int rate) 669 { 670 unsigned int delta; 671 672 // We special case 44100 and 8000 since rounding with the equation 673 // does not give us an accurate enough value. For 11025 and 22050 674 // the equation gives us the best answer. All other frequencies will 675 // also use the equation. JDW 676 if (rate == 44100) 677 delta = 0x116a; 678 else if (rate == 8000) 679 delta = 0x6000; 680 else if (rate == 48000) 681 delta = 0x1000; 682 else 683 delta = ((48000 << 12) / rate) & 0x0000ffff; 684 return delta; 685 } 686 687 /*--------------------------------------------------------------------------- 688 snd_trident_spurious_threshold 689 690 Description: This routine converts rate in HZ to spurious threshold. 691 692 Paramters: trident - pointer to target device class for 4DWave. 693 rate - Real or Virtual channel number. 694 695 Returns: Delta value. 696 697 ---------------------------------------------------------------------------*/ 698 static unsigned int snd_trident_spurious_threshold(unsigned int rate, unsigned int period_size) 699 { 700 unsigned int res = (rate * period_size) / 48000; 701 if (res < 64) 702 res = res / 2; 703 else 704 res -= 32; 705 return res; 706 } 707 708 /*--------------------------------------------------------------------------- 709 snd_trident_control_mode 710 711 Description: This routine returns a control mode for a PCM channel. 712 713 Paramters: trident - pointer to target device class for 4DWave. 714 substream - PCM substream 715 716 Returns: Control value. 717 718 ---------------------------------------------------------------------------*/ 719 static unsigned int snd_trident_control_mode(snd_pcm_substream_t *substream) 720 { 721 unsigned int CTRL; 722 snd_pcm_runtime_t *runtime = substream->runtime; 723 724 /* set ctrl mode 725 CTRL default: 8-bit (unsigned) mono, loop mode enabled 726 */ 727 CTRL = 0x00000001; 728 if (snd_pcm_format_width(runtime->format) == 16) 729 CTRL |= 0x00000008; // 16-bit data 730 if (snd_pcm_format_signed(runtime->format)) 731 CTRL |= 0x00000002; // signed data 732 if (runtime->channels > 1) 733 CTRL |= 0x00000004; // stereo data 734 return CTRL; 735 } 736 737 /* 738 * PCM part 739 */ 740 741 /*--------------------------------------------------------------------------- 742 snd_trident_ioctl 743 744 Description: Device I/O control handler for playback/capture parameters. 745 746 Paramters: substream - PCM substream class 747 cmd - what ioctl message to process 748 arg - additional message infoarg 749 750 Returns: Error status 751 752 ---------------------------------------------------------------------------*/ 753 754 static int snd_trident_ioctl(snd_pcm_substream_t * substream, 755 unsigned int cmd, 756 void *arg) 757 { 758 /* FIXME: it seems that with small periods the behaviour of 759 trident hardware is unpredictable and interrupt generator 760 is broken */ 761 return snd_pcm_lib_ioctl(substream, cmd, arg); 762 } 763 764 /*--------------------------------------------------------------------------- 765 snd_trident_allocate_pcm_mem 766 767 Description: Allocate PCM ring buffer for given substream 768 769 Parameters: substream - PCM substream class 770 hw_params - hardware parameters 771 772 Returns: Error status 773 774 ---------------------------------------------------------------------------*/ 775 776 static int snd_trident_allocate_pcm_mem(snd_pcm_substream_t * substream, 777 snd_pcm_hw_params_t * hw_params) 778 { 779 trident_t *trident = snd_pcm_substream_chip(substream); 780 snd_pcm_runtime_t *runtime = substream->runtime; 781 snd_trident_voice_t *voice = (snd_trident_voice_t *) runtime->private_data; 782 int err; 783 784 if ((err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params))) < 0) 785 return err; 786 if (trident->tlb.entries) { 787 if (err > 0) { /* change */ 788 if (voice->memblk) 789 snd_trident_free_pages(trident, voice->memblk); 790 voice->memblk = snd_trident_alloc_pages(trident, substream); 791 if (voice->memblk == NULL) 792 return -ENOMEM; 793 } 794 } 795 return 0; 796 } 797 798 /*--------------------------------------------------------------------------- 799 snd_trident_allocate_evoice 800 801 Description: Allocate extra voice as interrupt generator 802 803 Parameters: substream - PCM substream class 804 hw_params - hardware parameters 805 806 Returns: Error status 807 808 ---------------------------------------------------------------------------*/ 809 810 static int snd_trident_allocate_evoice(snd_pcm_substream_t * substream, 811 snd_pcm_hw_params_t * hw_params) 812 { 813 trident_t *trident = snd_pcm_substream_chip(substream); 814 snd_pcm_runtime_t *runtime = substream->runtime; 815 snd_trident_voice_t *voice = (snd_trident_voice_t *) runtime->private_data; 816 snd_trident_voice_t *evoice = voice->extra; 817 818 /* voice management */ 819 820 if (params_buffer_size(hw_params) / 2 != params_period_size(hw_params)) { 821 if (evoice == NULL) { 822 evoice = snd_trident_alloc_voice(trident, SNDRV_TRIDENT_VOICE_TYPE_PCM, 0, 0); 823 if (evoice == NULL) 824 return -ENOMEM; 825 voice->extra = evoice; 826 evoice->substream = substream; 827 } 828 } else { 829 if (evoice != NULL) { 830 snd_trident_free_voice(trident, evoice); 831 voice->extra = evoice = NULL; 832 } 833 } 834 835 return 0; 836 } 837 838 /*--------------------------------------------------------------------------- 839 snd_trident_hw_params 840 841 Description: Set the hardware parameters for the playback device. 842 843 Parameters: substream - PCM substream class 844 hw_params - hardware parameters 845 846 Returns: Error status 847 848 ---------------------------------------------------------------------------*/ 849 850 static int snd_trident_hw_params(snd_pcm_substream_t * substream, 851 snd_pcm_hw_params_t * hw_params) 852 { 853 int err; 854 855 err = snd_trident_allocate_pcm_mem(substream, hw_params); 856 if (err >= 0) 857 err = snd_trident_allocate_evoice(substream, hw_params); 858 return err; 859 } 860 861 /*--------------------------------------------------------------------------- 862 snd_trident_playback_hw_free 863 864 Description: Release the hardware resources for the playback device. 865 866 Parameters: substream - PCM substream class 867 868 Returns: Error status 869 870 ---------------------------------------------------------------------------*/ 871 872 static int snd_trident_hw_free(snd_pcm_substream_t * substream) 873 { 874 trident_t *trident = snd_pcm_substream_chip(substream); 875 snd_pcm_runtime_t *runtime = substream->runtime; 876 snd_trident_voice_t *voice = (snd_trident_voice_t *) runtime->private_data; 877 snd_trident_voice_t *evoice = voice ? voice->extra : NULL; 878 879 if (trident->tlb.entries) { 880 if (voice && voice->memblk) { 881 snd_trident_free_pages(trident, voice->memblk); 882 voice->memblk = NULL; 883 } 884 } 885 snd_pcm_lib_free_pages(substream); 886 if (evoice != NULL) { 887 snd_trident_free_voice(trident, evoice); 888 voice->extra = NULL; 889 } 890 return 0; 891 } 892 893 /*--------------------------------------------------------------------------- 894 snd_trident_playback_prepare 895 896 Description: Prepare playback device for playback. 897 898 Parameters: substream - PCM substream class 899 900 Returns: Error status 901 902 ---------------------------------------------------------------------------*/ 903 904 static int snd_trident_playback_prepare(snd_pcm_substream_t * substream) 905 { 906 trident_t *trident = snd_pcm_substream_chip(substream); 907 snd_pcm_runtime_t *runtime = substream->runtime; 908 snd_trident_voice_t *voice = (snd_trident_voice_t *) runtime->private_data; 909 snd_trident_voice_t *evoice = voice->extra; 910 snd_trident_pcm_mixer_t *mix = &trident->pcm_mixer[substream->number]; 911 912 spin_lock_irq(&trident->reg_lock); 913 914 /* set delta (rate) value */ 915 voice->Delta = snd_trident_convert_rate(runtime->rate); 916 voice->spurious_threshold = snd_trident_spurious_threshold(runtime->rate, runtime->period_size); 917 918 /* set Loop Begin Address */ 919 if (voice->memblk) 920 voice->LBA = voice->memblk->offset; 921 else 922 voice->LBA = runtime->dma_addr; 923 924 voice->CSO = 0; 925 voice->ESO = runtime->buffer_size - 1; /* in samples */ 926 voice->CTRL = snd_trident_control_mode(substream); 927 voice->FMC = 3; 928 voice->GVSel = 1; 929 voice->EC = 0; 930 voice->Alpha = 0; 931 voice->FMS = 0; 932 voice->Vol = mix->vol; 933 voice->RVol = mix->rvol; 934 voice->CVol = mix->cvol; 935 voice->Pan = mix->pan; 936 voice->Attribute = 0; 937 #if 0 938 voice->Attribute = (1<<(30-16))|(2<<(26-16))| 939 (0<<(24-16))|(0x1f<<(19-16)); 940 #else 941 voice->Attribute = 0; 942 #endif 943 944 snd_trident_write_voice_regs(trident, voice); 945 946 if (evoice != NULL) { 947 evoice->Delta = voice->Delta; 948 evoice->spurious_threshold = voice->spurious_threshold; 949 evoice->LBA = voice->LBA; 950 evoice->CSO = 0; 951 evoice->ESO = (runtime->period_size * 2) + 4 - 1; /* in samples */ 952 evoice->CTRL = voice->CTRL; 953 evoice->FMC = 3; 954 evoice->GVSel = trident->device == TRIDENT_DEVICE_ID_SI7018 ? 0 : 1; 955 evoice->EC = 0; 956 evoice->Alpha = 0; 957 evoice->FMS = 0; 958 evoice->Vol = 0x3ff; /* mute */ 959 evoice->RVol = evoice->CVol = 0x7f; /* mute */ 960 evoice->Pan = 0x7f; /* mute */ 961 #if 0 962 evoice->Attribute = (1<<(30-16))|(2<<(26-16))| 963 (0<<(24-16))|(0x1f<<(19-16)); 964 #else 965 evoice->Attribute = 0; 966 #endif 967 snd_trident_write_voice_regs(trident, evoice); 968 evoice->isync2 = 1; 969 evoice->isync_mark = runtime->period_size; 970 evoice->ESO = (runtime->period_size * 2) - 1; 971 } 972 973 spin_unlock_irq(&trident->reg_lock); 974 975 return 0; 976 } 977 978 /*--------------------------------------------------------------------------- 979 snd_trident_capture_hw_params 980 981 Description: Set the hardware parameters for the capture device. 982 983 Parameters: substream - PCM substream class 984 hw_params - hardware parameters 985 986 Returns: Error status 987 988 ---------------------------------------------------------------------------*/ 989 990 static int snd_trident_capture_hw_params(snd_pcm_substream_t * substream, 991 snd_pcm_hw_params_t * hw_params) 992 { 993 return snd_trident_allocate_pcm_mem(substream, hw_params); 994 } 995 996 /*--------------------------------------------------------------------------- 997 snd_trident_capture_prepare 998 999 Description: Prepare capture device for playback. 1000 1001 Parameters: substream - PCM substream class 1002 1003 Returns: Error status 1004 1005 ---------------------------------------------------------------------------*/ 1006 1007 static int snd_trident_capture_prepare(snd_pcm_substream_t * substream) 1008 { 1009 trident_t *trident = snd_pcm_substream_chip(substream); 1010 snd_pcm_runtime_t *runtime = substream->runtime; 1011 snd_trident_voice_t *voice = (snd_trident_voice_t *) runtime->private_data; 1012 unsigned int val, ESO_bytes; 1013 1014 spin_lock_irq(&trident->reg_lock); 1015 1016 // Initilize the channel and set channel Mode 1017 outb(0, TRID_REG(trident, LEGACY_DMAR15)); 1018 1019 // Set DMA channel operation mode register 1020 outb(0x54, TRID_REG(trident, LEGACY_DMAR11)); 1021 1022 // Set channel buffer Address, DMAR0 expects contiguous PCI memory area 1023 voice->LBA = runtime->dma_addr; 1024 outl(voice->LBA, TRID_REG(trident, LEGACY_DMAR0)); 1025 if (voice->memblk) 1026 voice->LBA = voice->memblk->offset; 1027 1028 // set ESO 1029 ESO_bytes = snd_pcm_lib_buffer_bytes(substream) - 1; 1030 outb((ESO_bytes & 0x00ff0000) >> 16, TRID_REG(trident, LEGACY_DMAR6)); 1031 outw((ESO_bytes & 0x0000ffff), TRID_REG(trident, LEGACY_DMAR4)); 1032 ESO_bytes++; 1033 1034 // Set channel sample rate, 4.12 format 1035 val = (((unsigned int) 48000L << 12) + (runtime->rate/2)) / runtime->rate; 1036 outw(val, TRID_REG(trident, T4D_SBDELTA_DELTA_R)); 1037 1038 // Set channel interrupt blk length 1039 if (snd_pcm_format_width(runtime->format) == 16) { 1040 val = (unsigned short) ((ESO_bytes >> 1) - 1); 1041 } else { 1042 val = (unsigned short) (ESO_bytes - 1); 1043 } 1044 1045 outl((val << 16) | val, TRID_REG(trident, T4D_SBBL_SBCL)); 1046 1047 // Right now, set format and start to run captureing, 1048 // continuous run loop enable. 1049 trident->bDMAStart = 0x19; // 0001 1001b 1050 1051 if (snd_pcm_format_width(runtime->format) == 16) 1052 trident->bDMAStart |= 0x80; 1053 if (snd_pcm_format_signed(runtime->format)) 1054 trident->bDMAStart |= 0x20; 1055 if (runtime->channels > 1) 1056 trident->bDMAStart |= 0x40; 1057 1058 // Prepare capture intr channel 1059 1060 voice->Delta = snd_trident_convert_rate(runtime->rate); 1061 voice->spurious_threshold = snd_trident_spurious_threshold(runtime->rate, runtime->period_size); 1062 voice->isync = 1; 1063 voice->isync_mark = runtime->period_size; 1064 voice->isync_max = runtime->buffer_size; 1065 1066 // Set voice parameters 1067 voice->CSO = 0; 1068 voice->ESO = voice->isync_ESO = (runtime->period_size * 2) + 6 - 1; 1069 voice->CTRL = snd_trident_control_mode(substream); 1070 voice->FMC = 3; 1071 voice->RVol = 0x7f; 1072 voice->CVol = 0x7f; 1073 voice->GVSel = 1; 1074 voice->Pan = 0x7f; /* mute */ 1075 voice->Vol = 0x3ff; /* mute */ 1076 voice->EC = 0; 1077 voice->Alpha = 0; 1078 voice->FMS = 0; 1079 voice->Attribute = 0; 1080 1081 snd_trident_write_voice_regs(trident, voice); 1082 1083 spin_unlock_irq(&trident->reg_lock); 1084 return 0; 1085 } 1086 1087 /*--------------------------------------------------------------------------- 1088 snd_trident_si7018_capture_hw_params 1089 1090 Description: Set the hardware parameters for the capture device. 1091 1092 Parameters: substream - PCM substream class 1093 hw_params - hardware parameters 1094 1095 Returns: Error status 1096 1097 ---------------------------------------------------------------------------*/ 1098 1099 static int snd_trident_si7018_capture_hw_params(snd_pcm_substream_t * substream, 1100 snd_pcm_hw_params_t * hw_params) 1101 { 1102 int err; 1103 1104 if ((err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params))) < 0) 1105 return err; 1106 1107 return snd_trident_allocate_evoice(substream, hw_params); 1108 } 1109 1110 /*--------------------------------------------------------------------------- 1111 snd_trident_si7018_capture_hw_free 1112 1113 Description: Release the hardware resources for the capture device. 1114 1115 Parameters: substream - PCM substream class 1116 1117 Returns: Error status 1118 1119 ---------------------------------------------------------------------------*/ 1120 1121 static int snd_trident_si7018_capture_hw_free(snd_pcm_substream_t * substream) 1122 { 1123 trident_t *trident = snd_pcm_substream_chip(substream); 1124 snd_pcm_runtime_t *runtime = substream->runtime; 1125 snd_trident_voice_t *voice = (snd_trident_voice_t *) runtime->private_data; 1126 snd_trident_voice_t *evoice = voice ? voice->extra : NULL; 1127 1128 snd_pcm_lib_free_pages(substream); 1129 if (evoice != NULL) { 1130 snd_trident_free_voice(trident, evoice); 1131 voice->extra = NULL; 1132 } 1133 return 0; 1134 } 1135 1136 /*--------------------------------------------------------------------------- 1137 snd_trident_si7018_capture_prepare 1138 1139 Description: Prepare capture device for playback. 1140 1141 Parameters: substream - PCM substream class 1142 1143 Returns: Error status 1144 1145 ---------------------------------------------------------------------------*/ 1146 1147 static int snd_trident_si7018_capture_prepare(snd_pcm_substream_t * substream) 1148 { 1149 trident_t *trident = snd_pcm_substream_chip(substream); 1150 snd_pcm_runtime_t *runtime = substream->runtime; 1151 snd_trident_voice_t *voice = (snd_trident_voice_t *) runtime->private_data; 1152 snd_trident_voice_t *evoice = voice->extra; 1153 1154 spin_lock_irq(&trident->reg_lock); 1155 1156 voice->LBA = runtime->dma_addr; 1157 voice->Delta = snd_trident_convert_adc_rate(runtime->rate); 1158 voice->spurious_threshold = snd_trident_spurious_threshold(runtime->rate, runtime->period_size); 1159 1160 // Set voice parameters 1161 voice->CSO = 0; 1162 voice->ESO = runtime->buffer_size - 1; /* in samples */ 1163 voice->CTRL = snd_trident_control_mode(substream); 1164 voice->FMC = 0; 1165 voice->RVol = 0; 1166 voice->CVol = 0; 1167 voice->GVSel = 1; 1168 voice->Pan = T4D_DEFAULT_PCM_PAN; 1169 voice->Vol = 0; 1170 voice->EC = 0; 1171 voice->Alpha = 0; 1172 voice->FMS = 0; 1173 1174 voice->Attribute = (2 << (30-16)) | 1175 (2 << (26-16)) | 1176 (2 << (24-16)) | 1177 (1 << (23-16)); 1178 1179 snd_trident_write_voice_regs(trident, voice); 1180 1181 if (evoice != NULL) { 1182 evoice->Delta = snd_trident_convert_rate(runtime->rate); 1183 evoice->spurious_threshold = voice->spurious_threshold; 1184 evoice->LBA = voice->LBA; 1185 evoice->CSO = 0; 1186 evoice->ESO = (runtime->period_size * 2) + 20 - 1; /* in samples, 20 means correction */ 1187 evoice->CTRL = voice->CTRL; 1188 evoice->FMC = 3; 1189 evoice->GVSel = 0; 1190 evoice->EC = 0; 1191 evoice->Alpha = 0; 1192 evoice->FMS = 0; 1193 evoice->Vol = 0x3ff; /* mute */ 1194 evoice->RVol = evoice->CVol = 0x7f; /* mute */ 1195 evoice->Pan = 0x7f; /* mute */ 1196 evoice->Attribute = 0; 1197 snd_trident_write_voice_regs(trident, evoice); 1198 evoice->isync2 = 1; 1199 evoice->isync_mark = runtime->period_size; 1200 evoice->ESO = (runtime->period_size * 2) - 1; 1201 } 1202 1203 spin_unlock_irq(&trident->reg_lock); 1204 return 0; 1205 } 1206 1207 /*--------------------------------------------------------------------------- 1208 snd_trident_foldback_prepare 1209 1210 Description: Prepare foldback capture device for playback. 1211 1212 Parameters: substream - PCM substream class 1213 1214 Returns: Error status 1215 1216 ---------------------------------------------------------------------------*/ 1217 1218 static int snd_trident_foldback_prepare(snd_pcm_substream_t * substream) 1219 { 1220 trident_t *trident = snd_pcm_substream_chip(substream); 1221 snd_pcm_runtime_t *runtime = substream->runtime; 1222 snd_trident_voice_t *voice = (snd_trident_voice_t *) runtime->private_data; 1223 snd_trident_voice_t *evoice = voice->extra; 1224 1225 spin_lock_irq(&trident->reg_lock); 1226 1227 /* Set channel buffer Address */ 1228 if (voice->memblk) 1229 voice->LBA = voice->memblk->offset; 1230 else 1231 voice->LBA = runtime->dma_addr; 1232 1233 /* set target ESO for channel */ 1234 voice->ESO = runtime->buffer_size - 1; /* in samples */ 1235 1236 /* set sample rate */ 1237 voice->Delta = 0x1000; 1238 voice->spurious_threshold = snd_trident_spurious_threshold(48000, runtime->period_size); 1239 1240 voice->CSO = 0; 1241 voice->CTRL = snd_trident_control_mode(substream); 1242 voice->FMC = 3; 1243 voice->RVol = 0x7f; 1244 voice->CVol = 0x7f; 1245 voice->GVSel = 1; 1246 voice->Pan = 0x7f; /* mute */ 1247 voice->Vol = 0x3ff; /* mute */ 1248 voice->EC = 0; 1249 voice->Alpha = 0; 1250 voice->FMS = 0; 1251 voice->Attribute = 0; 1252 1253 /* set up capture channel */ 1254 outb(((voice->number & 0x3f) | 0x80), TRID_REG(trident, T4D_RCI + voice->foldback_chan)); 1255 1256 snd_trident_write_voice_regs(trident, voice); 1257 1258 if (evoice != NULL) { 1259 evoice->Delta = voice->Delta; 1260 evoice->spurious_threshold = voice->spurious_threshold; 1261 evoice->LBA = voice->LBA; 1262 evoice->CSO = 0; 1263 evoice->ESO = (runtime->period_size * 2) + 4 - 1; /* in samples */ 1264 evoice->CTRL = voice->CTRL; 1265 evoice->FMC = 3; 1266 evoice->GVSel = trident->device == TRIDENT_DEVICE_ID_SI7018 ? 0 : 1; 1267 evoice->EC = 0; 1268 evoice->Alpha = 0; 1269 evoice->FMS = 0; 1270 evoice->Vol = 0x3ff; /* mute */ 1271 evoice->RVol = evoice->CVol = 0x7f; /* mute */ 1272 evoice->Pan = 0x7f; /* mute */ 1273 evoice->Attribute = 0; 1274 snd_trident_write_voice_regs(trident, evoice); 1275 evoice->isync2 = 1; 1276 evoice->isync_mark = runtime->period_size; 1277 evoice->ESO = (runtime->period_size * 2) - 1; 1278 } 1279 1280 spin_unlock_irq(&trident->reg_lock); 1281 return 0; 1282 } 1283 1284 /*--------------------------------------------------------------------------- 1285 snd_trident_spdif_hw_params 1286 1287 Description: Set the hardware parameters for the spdif device. 1288 1289 Parameters: substream - PCM substream class 1290 hw_params - hardware parameters 1291 1292 Returns: Error status 1293 1294 ---------------------------------------------------------------------------*/ 1295 1296 static int snd_trident_spdif_hw_params(snd_pcm_substream_t * substream, 1297 snd_pcm_hw_params_t * hw_params) 1298 { 1299 trident_t *trident = snd_pcm_substream_chip(substream); 1300 unsigned int old_bits = 0, change = 0; 1301 int err; 1302 1303 err = snd_trident_allocate_pcm_mem(substream, hw_params); 1304 if (err < 0) 1305 return err; 1306 1307 if (trident->device == TRIDENT_DEVICE_ID_SI7018) { 1308 err = snd_trident_allocate_evoice(substream, hw_params); 1309 if (err < 0) 1310 return err; 1311 } 1312 1313 /* prepare SPDIF channel */ 1314 spin_lock_irq(&trident->reg_lock); 1315 old_bits = trident->spdif_pcm_bits; 1316 if (old_bits & IEC958_AES0_PROFESSIONAL) 1317 trident->spdif_pcm_bits &= ~IEC958_AES0_PRO_FS; 1318 else 1319 trident->spdif_pcm_bits &= ~(IEC958_AES3_CON_FS << 24); 1320 if (params_rate(hw_params) >= 48000) { 1321 trident->spdif_pcm_ctrl = 0x3c; // 48000 Hz 1322 trident->spdif_pcm_bits |= 1323 trident->spdif_bits & IEC958_AES0_PROFESSIONAL ? 1324 IEC958_AES0_PRO_FS_48000 : 1325 (IEC958_AES3_CON_FS_48000 << 24); 1326 } 1327 else if (params_rate(hw_params) >= 44100) { 1328 trident->spdif_pcm_ctrl = 0x3e; // 44100 Hz 1329 trident->spdif_pcm_bits |= 1330 trident->spdif_bits & IEC958_AES0_PROFESSIONAL ? 1331 IEC958_AES0_PRO_FS_44100 : 1332 (IEC958_AES3_CON_FS_44100 << 24); 1333 } 1334 else { 1335 trident->spdif_pcm_ctrl = 0x3d; // 32000 Hz 1336 trident->spdif_pcm_bits |= 1337 trident->spdif_bits & IEC958_AES0_PROFESSIONAL ? 1338 IEC958_AES0_PRO_FS_32000 : 1339 (IEC958_AES3_CON_FS_32000 << 24); 1340 } 1341 change = old_bits != trident->spdif_pcm_bits; 1342 spin_unlock_irq(&trident->reg_lock); 1343 1344 if (change) 1345 snd_ctl_notify(trident->card, SNDRV_CTL_EVENT_MASK_VALUE, &trident->spdif_pcm_ctl->id); 1346 1347 return 0; 1348 } 1349 1350 /*--------------------------------------------------------------------------- 1351 snd_trident_spdif_prepare 1352 1353 Description: Prepare SPDIF device for playback. 1354 1355 Parameters: substream - PCM substream class 1356 1357 Returns: Error status 1358 1359 ---------------------------------------------------------------------------*/ 1360 1361 static int snd_trident_spdif_prepare(snd_pcm_substream_t * substream) 1362 { 1363 trident_t *trident = snd_pcm_substream_chip(substream); 1364 snd_pcm_runtime_t *runtime = substream->runtime; 1365 snd_trident_voice_t *voice = (snd_trident_voice_t *) runtime->private_data; 1366 snd_trident_voice_t *evoice = voice->extra; 1367 snd_trident_pcm_mixer_t *mix = &trident->pcm_mixer[substream->number]; 1368 unsigned int RESO, LBAO; 1369 unsigned int temp; 1370 1371 spin_lock_irq(&trident->reg_lock); 1372 1373 if (trident->device != TRIDENT_DEVICE_ID_SI7018) { 1374 1375 /* set delta (rate) value */ 1376 voice->Delta = snd_trident_convert_rate(runtime->rate); 1377 voice->spurious_threshold = snd_trident_spurious_threshold(runtime->rate, runtime->period_size); 1378 1379 /* set Loop Back Address */ 1380 LBAO = runtime->dma_addr; 1381 if (voice->memblk) 1382 voice->LBA = voice->memblk->offset; 1383 else 1384 voice->LBA = LBAO; 1385 1386 voice->isync = 1; 1387 voice->isync3 = 1; 1388 voice->isync_mark = runtime->period_size; 1389 voice->isync_max = runtime->buffer_size; 1390 1391 /* set target ESO for channel */ 1392 RESO = runtime->buffer_size - 1; 1393 voice->ESO = voice->isync_ESO = (runtime->period_size * 2) + 6 - 1; 1394 1395 /* set ctrl mode */ 1396 voice->CTRL = snd_trident_control_mode(substream); 1397 1398 voice->FMC = 3; 1399 voice->RVol = 0x7f; 1400 voice->CVol = 0x7f; 1401 voice->GVSel = 1; 1402 voice->Pan = 0x7f; 1403 voice->Vol = 0x3ff; 1404 voice->EC = 0; 1405 voice->CSO = 0; 1406 voice->Alpha = 0; 1407 voice->FMS = 0; 1408 voice->Attribute = 0; 1409 1410 /* prepare surrogate IRQ channel */ 1411 snd_trident_write_voice_regs(trident, voice); 1412 1413 outw((RESO & 0xffff), TRID_REG(trident, NX_SPESO)); 1414 outb((RESO >> 16), TRID_REG(trident, NX_SPESO + 2)); 1415 outl((LBAO & 0xfffffffc), TRID_REG(trident, NX_SPLBA)); 1416 outw((voice->CSO & 0xffff), TRID_REG(trident, NX_SPCTRL_SPCSO)); 1417 outb((voice->CSO >> 16), TRID_REG(trident, NX_SPCTRL_SPCSO + 2)); 1418 1419 /* set SPDIF setting */ 1420 outb(trident->spdif_pcm_ctrl, TRID_REG(trident, NX_SPCTRL_SPCSO + 3)); 1421 outl(trident->spdif_pcm_bits, TRID_REG(trident, NX_SPCSTATUS)); 1422 1423 } else { /* SiS */ 1424 1425 /* set delta (rate) value */ 1426 voice->Delta = 0x800; 1427 voice->spurious_threshold = snd_trident_spurious_threshold(48000, runtime->period_size); 1428 1429 /* set Loop Begin Address */ 1430 if (voice->memblk) 1431 voice->LBA = voice->memblk->offset; 1432 else 1433 voice->LBA = runtime->dma_addr; 1434 1435 voice->CSO = 0; 1436 voice->ESO = runtime->buffer_size - 1; /* in samples */ 1437 voice->CTRL = snd_trident_control_mode(substream); 1438 voice->FMC = 3; 1439 voice->GVSel = 1; 1440 voice->EC = 0; 1441 voice->Alpha = 0; 1442 voice->FMS = 0; 1443 voice->Vol = mix->vol; 1444 voice->RVol = mix->rvol; 1445 voice->CVol = mix->cvol; 1446 voice->Pan = mix->pan; 1447 voice->Attribute = (1<<(30-16))|(7<<(26-16))| 1448 (0<<(24-16))|(0<<(19-16)); 1449 1450 snd_trident_write_voice_regs(trident, voice); 1451 1452 if (evoice != NULL) { 1453 evoice->Delta = voice->Delta; 1454 evoice->spurious_threshold = voice->spurious_threshold; 1455 evoice->LBA = voice->LBA; 1456 evoice->CSO = 0; 1457 evoice->ESO = (runtime->period_size * 2) + 4 - 1; /* in samples */ 1458 evoice->CTRL = voice->CTRL; 1459 evoice->FMC = 3; 1460 evoice->GVSel = trident->device == TRIDENT_DEVICE_ID_SI7018 ? 0 : 1; 1461 evoice->EC = 0; 1462 evoice->Alpha = 0; 1463 evoice->FMS = 0; 1464 evoice->Vol = 0x3ff; /* mute */ 1465 evoice->RVol = evoice->CVol = 0x7f; /* mute */ 1466 evoice->Pan = 0x7f; /* mute */ 1467 evoice->Attribute = 0; 1468 snd_trident_write_voice_regs(trident, evoice); 1469 evoice->isync2 = 1; 1470 evoice->isync_mark = runtime->period_size; 1471 evoice->ESO = (runtime->period_size * 2) - 1; 1472 } 1473 1474 outl(trident->spdif_pcm_bits, TRID_REG(trident, SI_SPDIF_CS)); 1475 temp = inl(TRID_REG(trident, T4D_LFO_GC_CIR)); 1476 temp &= ~(1<<19); 1477 outl(temp, TRID_REG(trident, T4D_LFO_GC_CIR)); 1478 temp = inl(TRID_REG(trident, SI_SERIAL_INTF_CTRL)); 1479 temp |= SPDIF_EN; 1480 outl(temp, TRID_REG(trident, SI_SERIAL_INTF_CTRL)); 1481 } 1482 1483 spin_unlock_irq(&trident->reg_lock); 1484 1485 return 0; 1486 } 1487 1488 /*--------------------------------------------------------------------------- 1489 snd_trident_trigger 1490 1491 Description: Start/stop devices 1492 1493 Parameters: substream - PCM substream class 1494 cmd - trigger command (STOP, GO) 1495 1496 Returns: Error status 1497 1498 ---------------------------------------------------------------------------*/ 1499 1500 static int snd_trident_trigger(snd_pcm_substream_t *substream, 1501 int cmd) 1502 1503 { 1504 trident_t *trident = snd_pcm_substream_chip(substream); 1505 struct list_head *pos; 1506 snd_pcm_substream_t *s; 1507 unsigned int what, whati, capture_flag, spdif_flag; 1508 snd_trident_voice_t *voice, *evoice; 1509 unsigned int val, go; 1510 1511 switch (cmd) { 1512 case SNDRV_PCM_TRIGGER_START: 1513 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 1514 case SNDRV_PCM_TRIGGER_RESUME: 1515 go = 1; 1516 break; 1517 case SNDRV_PCM_TRIGGER_STOP: 1518 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 1519 case SNDRV_PCM_TRIGGER_SUSPEND: 1520 go = 0; 1521 break; 1522 default: 1523 return -EINVAL; 1524 } 1525 what = whati = capture_flag = spdif_flag = 0; 1526 spin_lock(&trident->reg_lock); 1527 val = inl(TRID_REG(trident, T4D_STIMER)) & 0x00ffffff; 1528 snd_pcm_group_for_each(pos, substream) { 1529 s = snd_pcm_group_substream_entry(pos); 1530 if ((trident_t *) snd_pcm_substream_chip(s) == trident) { 1531 voice = (snd_trident_voice_t *) s->runtime->private_data; 1532 evoice = voice->extra; 1533 what |= 1 << (voice->number & 0x1f); 1534 if (evoice == NULL) { 1535 whati |= 1 << (voice->number & 0x1f); 1536 } else { 1537 what |= 1 << (evoice->number & 0x1f); 1538 whati |= 1 << (evoice->number & 0x1f); 1539 if (go) 1540 evoice->stimer = val; 1541 } 1542 if (go) { 1543 voice->running = 1; 1544 voice->stimer = val; 1545 } else { 1546 voice->running = 0; 1547 } 1548 snd_pcm_trigger_done(s, substream); 1549 if (voice->capture) 1550 capture_flag = 1; 1551 if (voice->spdif) 1552 spdif_flag = 1; 1553 } 1554 } 1555 if (spdif_flag) { 1556 if (trident->device != TRIDENT_DEVICE_ID_SI7018) { 1557 outl(trident->spdif_pcm_bits, TRID_REG(trident, NX_SPCSTATUS)); 1558 outb(trident->spdif_pcm_ctrl, TRID_REG(trident, NX_SPCTRL_SPCSO + 3)); 1559 } else { 1560 outl(trident->spdif_pcm_bits, TRID_REG(trident, SI_SPDIF_CS)); 1561 val = inl(TRID_REG(trident, SI_SERIAL_INTF_CTRL)) | SPDIF_EN; 1562 outl(val, TRID_REG(trident, SI_SERIAL_INTF_CTRL)); 1563 } 1564 } 1565 if (!go) 1566 outl(what, TRID_REG(trident, T4D_STOP_B)); 1567 val = inl(TRID_REG(trident, T4D_AINTEN_B)); 1568 if (go) { 1569 val |= whati; 1570 } else { 1571 val &= ~whati; 1572 } 1573 outl(val, TRID_REG(trident, T4D_AINTEN_B)); 1574 if (go) { 1575 outl(what, TRID_REG(trident, T4D_START_B)); 1576 1577 if (capture_flag && trident->device != TRIDENT_DEVICE_ID_SI7018) 1578 outb(trident->bDMAStart, TRID_REG(trident, T4D_SBCTRL_SBE2R_SBDD)); 1579 } else { 1580 if (capture_flag && trident->device != TRIDENT_DEVICE_ID_SI7018) 1581 outb(0x00, TRID_REG(trident, T4D_SBCTRL_SBE2R_SBDD)); 1582 } 1583 spin_unlock(&trident->reg_lock); 1584 return 0; 1585 } 1586 1587 /*--------------------------------------------------------------------------- 1588 snd_trident_playback_pointer 1589 1590 Description: This routine return the playback position 1591 1592 Parameters: substream - PCM substream class 1593 1594 Returns: position of buffer 1595 1596 ---------------------------------------------------------------------------*/ 1597 1598 static snd_pcm_uframes_t snd_trident_playback_pointer(snd_pcm_substream_t * substream) 1599 { 1600 trident_t *trident = snd_pcm_substream_chip(substream); 1601 snd_pcm_runtime_t *runtime = substream->runtime; 1602 snd_trident_voice_t *voice = (snd_trident_voice_t *) runtime->private_data; 1603 unsigned int cso; 1604 1605 if (!voice->running) 1606 return 0; 1607 1608 spin_lock(&trident->reg_lock); 1609 1610 outb(voice->number, TRID_REG(trident, T4D_LFO_GC_CIR)); 1611 1612 if (trident->device != TRIDENT_DEVICE_ID_NX) { 1613 cso = inw(TRID_REG(trident, CH_DX_CSO_ALPHA_FMS + 2)); 1614 } else { // ID_4DWAVE_NX 1615 cso = (unsigned int) inl(TRID_REG(trident, CH_NX_DELTA_CSO)) & 0x00ffffff; 1616 } 1617 1618 spin_unlock(&trident->reg_lock); 1619 1620 if (cso >= runtime->buffer_size) 1621 cso = 0; 1622 1623 return cso; 1624 } 1625 1626 /*--------------------------------------------------------------------------- 1627 snd_trident_capture_pointer 1628 1629 Description: This routine return the capture position 1630 1631 Paramters: pcm1 - PCM device class 1632 1633 Returns: position of buffer 1634 1635 ---------------------------------------------------------------------------*/ 1636 1637 static snd_pcm_uframes_t snd_trident_capture_pointer(snd_pcm_substream_t * substream) 1638 { 1639 trident_t *trident = snd_pcm_substream_chip(substream); 1640 snd_pcm_runtime_t *runtime = substream->runtime; 1641 snd_trident_voice_t *voice = (snd_trident_voice_t *) runtime->private_data; 1642 unsigned int result; 1643 1644 if (!voice->running) 1645 return 0; 1646 1647 result = inw(TRID_REG(trident, T4D_SBBL_SBCL)); 1648 if (runtime->channels > 1) 1649 result >>= 1; 1650 if (result > 0) 1651 result = runtime->buffer_size - result; 1652 1653 return result; 1654 } 1655 1656 /*--------------------------------------------------------------------------- 1657 snd_trident_spdif_pointer 1658 1659 Description: This routine return the SPDIF playback position 1660 1661 Parameters: substream - PCM substream class 1662 1663 Returns: position of buffer 1664 1665 ---------------------------------------------------------------------------*/ 1666 1667 static snd_pcm_uframes_t snd_trident_spdif_pointer(snd_pcm_substream_t * substream) 1668 { 1669 trident_t *trident = snd_pcm_substream_chip(substream); 1670 snd_pcm_runtime_t *runtime = substream->runtime; 1671 snd_trident_voice_t *voice = (snd_trident_voice_t *) runtime->private_data; 1672 unsigned int result; 1673 1674 if (!voice->running) 1675 return 0; 1676 1677 result = inl(TRID_REG(trident, NX_SPCTRL_SPCSO)) & 0x00ffffff; 1678 1679 return result; 1680 } 1681 1682 /* 1683 * Playback support device description 1684 */ 1685 1686 static snd_pcm_hardware_t snd_trident_playback = 1687 { 1688 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | 1689 SNDRV_PCM_INFO_BLOCK_TRANSFER | 1690 SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_SYNC_START | 1691 SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME), 1692 .formats = (SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE | 1693 SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U16_LE), 1694 .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000, 1695 .rate_min = 4000, 1696 .rate_max = 48000, 1697 .channels_min = 1, 1698 .channels_max = 2, 1699 .buffer_bytes_max = (256*1024), 1700 .period_bytes_min = 64, 1701 .period_bytes_max = (256*1024), 1702 .periods_min = 1, 1703 .periods_max = 1024, 1704 .fifo_size = 0, 1705 }; 1706 1707 /* 1708 * Capture support device description 1709 */ 1710 1711 static snd_pcm_hardware_t snd_trident_capture = 1712 { 1713 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | 1714 SNDRV_PCM_INFO_BLOCK_TRANSFER | 1715 SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_SYNC_START | 1716 SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME), 1717 .formats = (SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE | 1718 SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U16_LE), 1719 .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000, 1720 .rate_min = 4000, 1721 .rate_max = 48000, 1722 .channels_min = 1, 1723 .channels_max = 2, 1724 .buffer_bytes_max = (128*1024), 1725 .period_bytes_min = 64, 1726 .period_bytes_max = (128*1024), 1727 .periods_min = 1, 1728 .periods_max = 1024, 1729 .fifo_size = 0, 1730 }; 1731 1732 /* 1733 * Foldback capture support device description 1734 */ 1735 1736 static snd_pcm_hardware_t snd_trident_foldback = 1737 { 1738 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | 1739 SNDRV_PCM_INFO_BLOCK_TRANSFER | 1740 SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_SYNC_START | 1741 SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME), 1742 .formats = SNDRV_PCM_FMTBIT_S16_LE, 1743 .rates = SNDRV_PCM_RATE_48000, 1744 .rate_min = 48000, 1745 .rate_max = 48000, 1746 .channels_min = 2, 1747 .channels_max = 2, 1748 .buffer_bytes_max = (128*1024), 1749 .period_bytes_min = 64, 1750 .period_bytes_max = (128*1024), 1751 .periods_min = 1, 1752 .periods_max = 1024, 1753 .fifo_size = 0, 1754 }; 1755 1756 /* 1757 * SPDIF playback support device description 1758 */ 1759 1760 static snd_pcm_hardware_t snd_trident_spdif = 1761 { 1762 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | 1763 SNDRV_PCM_INFO_BLOCK_TRANSFER | 1764 SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_SYNC_START | 1765 SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME), 1766 .formats = SNDRV_PCM_FMTBIT_S16_LE, 1767 .rates = (SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | 1768 SNDRV_PCM_RATE_48000), 1769 .rate_min = 32000, 1770 .rate_max = 48000, 1771 .channels_min = 2, 1772 .channels_max = 2, 1773 .buffer_bytes_max = (128*1024), 1774 .period_bytes_min = 64, 1775 .period_bytes_max = (128*1024), 1776 .periods_min = 1, 1777 .periods_max = 1024, 1778 .fifo_size = 0, 1779 }; 1780 1781 static snd_pcm_hardware_t snd_trident_spdif_7018 = 1782 { 1783 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | 1784 SNDRV_PCM_INFO_BLOCK_TRANSFER | 1785 SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_SYNC_START | 1786 SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME), 1787 .formats = SNDRV_PCM_FMTBIT_S16_LE, 1788 .rates = SNDRV_PCM_RATE_48000, 1789 .rate_min = 48000, 1790 .rate_max = 48000, 1791 .channels_min = 2, 1792 .channels_max = 2, 1793 .buffer_bytes_max = (128*1024), 1794 .period_bytes_min = 64, 1795 .period_bytes_max = (128*1024), 1796 .periods_min = 1, 1797 .periods_max = 1024, 1798 .fifo_size = 0, 1799 }; 1800 1801 static void snd_trident_pcm_free_substream(snd_pcm_runtime_t *runtime) 1802 { 1803 snd_trident_voice_t *voice = (snd_trident_voice_t *) runtime->private_data; 1804 trident_t *trident; 1805 1806 if (voice) { 1807 trident = voice->trident; 1808 snd_trident_free_voice(trident, voice); 1809 } 1810 } 1811 1812 static int snd_trident_playback_open(snd_pcm_substream_t * substream) 1813 { 1814 trident_t *trident = snd_pcm_substream_chip(substream); 1815 snd_pcm_runtime_t *runtime = substream->runtime; 1816 snd_trident_voice_t *voice; 1817 1818 voice = snd_trident_alloc_voice(trident, SNDRV_TRIDENT_VOICE_TYPE_PCM, 0, 0); 1819 if (voice == NULL) 1820 return -EAGAIN; 1821 snd_trident_pcm_mixer_build(trident, voice, substream); 1822 voice->substream = substream; 1823 runtime->private_data = voice; 1824 runtime->private_free = snd_trident_pcm_free_substream; 1825 runtime->hw = snd_trident_playback; 1826 snd_pcm_set_sync(substream); 1827 snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_SIZE, 0, 64*1024); 1828 return 0; 1829 } 1830 1831 /*--------------------------------------------------------------------------- 1832 snd_trident_playback_close 1833 1834 Description: This routine will close the 4DWave playback device. For now 1835 we will simply free the dma transfer buffer. 1836 1837 Parameters: substream - PCM substream class 1838 1839 ---------------------------------------------------------------------------*/ 1840 static int snd_trident_playback_close(snd_pcm_substream_t * substream) 1841 { 1842 trident_t *trident = snd_pcm_substream_chip(substream); 1843 snd_pcm_runtime_t *runtime = substream->runtime; 1844 snd_trident_voice_t *voice = (snd_trident_voice_t *) runtime->private_data; 1845 1846 snd_trident_pcm_mixer_free(trident, voice, substream); 1847 return 0; 1848 } 1849 1850 /*--------------------------------------------------------------------------- 1851 snd_trident_spdif_open 1852 1853 Description: This routine will open the 4DWave SPDIF device. 1854 1855 Parameters: substream - PCM substream class 1856 1857 Returns: status - success or failure flag 1858 1859 ---------------------------------------------------------------------------*/ 1860 1861 static int snd_trident_spdif_open(snd_pcm_substream_t * substream) 1862 { 1863 trident_t *trident = snd_pcm_substream_chip(substream); 1864 snd_trident_voice_t *voice; 1865 snd_pcm_runtime_t *runtime = substream->runtime; 1866 1867 voice = snd_trident_alloc_voice(trident, SNDRV_TRIDENT_VOICE_TYPE_PCM, 0, 0); 1868 if (voice == NULL) 1869 return -EAGAIN; 1870 voice->spdif = 1; 1871 voice->substream = substream; 1872 spin_lock_irq(&trident->reg_lock); 1873 trident->spdif_pcm_bits = trident->spdif_bits; 1874 spin_unlock_irq(&trident->reg_lock); 1875 1876 runtime->private_data = voice; 1877 runtime->private_free = snd_trident_pcm_free_substream; 1878 if (trident->device == TRIDENT_DEVICE_ID_SI7018) { 1879 runtime->hw = snd_trident_spdif; 1880 } else { 1881 runtime->hw = snd_trident_spdif_7018; 1882 } 1883 1884 trident->spdif_pcm_ctl->vd[0].access &= ~SNDRV_CTL_ELEM_ACCESS_INACTIVE; 1885 snd_ctl_notify(trident->card, SNDRV_CTL_EVENT_MASK_VALUE | 1886 SNDRV_CTL_EVENT_MASK_INFO, &trident->spdif_pcm_ctl->id); 1887 1888 snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_SIZE, 0, 64*1024); 1889 return 0; 1890 } 1891 1892 1893 /*--------------------------------------------------------------------------- 1894 snd_trident_spdif_close 1895 1896 Description: This routine will close the 4DWave SPDIF device. 1897 1898 Parameters: substream - PCM substream class 1899 1900 ---------------------------------------------------------------------------*/ 1901 1902 static int snd_trident_spdif_close(snd_pcm_substream_t * substream) 1903 { 1904 trident_t *trident = snd_pcm_substream_chip(substream); 1905 unsigned int temp; 1906 1907 spin_lock_irq(&trident->reg_lock); 1908 // restore default SPDIF setting 1909 if (trident->device != TRIDENT_DEVICE_ID_SI7018) { 1910 outb(trident->spdif_ctrl, TRID_REG(trident, NX_SPCTRL_SPCSO + 3)); 1911 outl(trident->spdif_bits, TRID_REG(trident, NX_SPCSTATUS)); 1912 } else { 1913 outl(trident->spdif_bits, TRID_REG(trident, SI_SPDIF_CS)); 1914 temp = inl(TRID_REG(trident, SI_SERIAL_INTF_CTRL)); 1915 if (trident->spdif_ctrl) { 1916 temp |= SPDIF_EN; 1917 } else { 1918 temp &= ~SPDIF_EN; 1919 } 1920 outl(temp, TRID_REG(trident, SI_SERIAL_INTF_CTRL)); 1921 } 1922 spin_unlock_irq(&trident->reg_lock); 1923 trident->spdif_pcm_ctl->vd[0].access |= SNDRV_CTL_ELEM_ACCESS_INACTIVE; 1924 snd_ctl_notify(trident->card, SNDRV_CTL_EVENT_MASK_VALUE | 1925 SNDRV_CTL_EVENT_MASK_INFO, &trident->spdif_pcm_ctl->id); 1926 return 0; 1927 } 1928 1929 /*--------------------------------------------------------------------------- 1930 snd_trident_capture_open 1931 1932 Description: This routine will open the 4DWave capture device. 1933 1934 Parameters: substream - PCM substream class 1935 1936 Returns: status - success or failure flag 1937 1938 ---------------------------------------------------------------------------*/ 1939 1940 static int snd_trident_capture_open(snd_pcm_substream_t * substream) 1941 { 1942 trident_t *trident = snd_pcm_substream_chip(substream); 1943 snd_trident_voice_t *voice; 1944 snd_pcm_runtime_t *runtime = substream->runtime; 1945 1946 voice = snd_trident_alloc_voice(trident, SNDRV_TRIDENT_VOICE_TYPE_PCM, 0, 0); 1947 if (voice == NULL) 1948 return -EAGAIN; 1949 voice->capture = 1; 1950 voice->substream = substream; 1951 runtime->private_data = voice; 1952 runtime->private_free = snd_trident_pcm_free_substream; 1953 runtime->hw = snd_trident_capture; 1954 snd_pcm_set_sync(substream); 1955 snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_SIZE, 0, 64*1024); 1956 return 0; 1957 } 1958 1959 /*--------------------------------------------------------------------------- 1960 snd_trident_capture_close 1961 1962 Description: This routine will close the 4DWave capture device. For now 1963 we will simply free the dma transfer buffer. 1964 1965 Parameters: substream - PCM substream class 1966 1967 ---------------------------------------------------------------------------*/ 1968 static int snd_trident_capture_close(snd_pcm_substream_t * substream) 1969 { 1970 return 0; 1971 } 1972 1973 /*--------------------------------------------------------------------------- 1974 snd_trident_foldback_open 1975 1976 Description: This routine will open the 4DWave foldback capture device. 1977 1978 Parameters: substream - PCM substream class 1979 1980 Returns: status - success or failure flag 1981 1982 ---------------------------------------------------------------------------*/ 1983 1984 static int snd_trident_foldback_open(snd_pcm_substream_t * substream) 1985 { 1986 trident_t *trident = snd_pcm_substream_chip(substream); 1987 snd_trident_voice_t *voice; 1988 snd_pcm_runtime_t *runtime = substream->runtime; 1989 1990 voice = snd_trident_alloc_voice(trident, SNDRV_TRIDENT_VOICE_TYPE_PCM, 0, 0); 1991 if (voice == NULL) 1992 return -EAGAIN; 1993 voice->foldback_chan = substream->number; 1994 voice->substream = substream; 1995 runtime->private_data = voice; 1996 runtime->private_free = snd_trident_pcm_free_substream; 1997 runtime->hw = snd_trident_foldback; 1998 snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_SIZE, 0, 64*1024); 1999 return 0; 2000 } 2001 2002 /*--------------------------------------------------------------------------- 2003 snd_trident_foldback_close 2004 2005 Description: This routine will close the 4DWave foldback capture device. 2006 For now we will simply free the dma transfer buffer. 2007 2008 Parameters: substream - PCM substream class 2009 2010 ---------------------------------------------------------------------------*/ 2011 static int snd_trident_foldback_close(snd_pcm_substream_t * substream) 2012 { 2013 trident_t *trident = snd_pcm_substream_chip(substream); 2014 snd_trident_voice_t *voice; 2015 snd_pcm_runtime_t *runtime = substream->runtime; 2016 voice = (snd_trident_voice_t *) runtime->private_data; 2017 2018 /* stop capture channel */ 2019 spin_lock_irq(&trident->reg_lock); 2020 outb(0x00, TRID_REG(trident, T4D_RCI + voice->foldback_chan)); 2021 spin_unlock_irq(&trident->reg_lock); 2022 return 0; 2023 } 2024 2025 /*--------------------------------------------------------------------------- 2026 PCM operations 2027 ---------------------------------------------------------------------------*/ 2028 2029 static snd_pcm_ops_t snd_trident_playback_ops = { 2030 .open = snd_trident_playback_open, 2031 .close = snd_trident_playback_close, 2032 .ioctl = snd_trident_ioctl, 2033 .hw_params = snd_trident_hw_params, 2034 .hw_free = snd_trident_hw_free, 2035 .prepare = snd_trident_playback_prepare, 2036 .trigger = snd_trident_trigger, 2037 .pointer = snd_trident_playback_pointer, 2038 }; 2039 2040 static snd_pcm_ops_t snd_trident_nx_playback_ops = { 2041 .open = snd_trident_playback_open, 2042 .close = snd_trident_playback_close, 2043 .ioctl = snd_trident_ioctl, 2044 .hw_params = snd_trident_hw_params, 2045 .hw_free = snd_trident_hw_free, 2046 .prepare = snd_trident_playback_prepare, 2047 .trigger = snd_trident_trigger, 2048 .pointer = snd_trident_playback_pointer, 2049 .page = snd_pcm_sgbuf_ops_page, 2050 }; 2051 2052 static snd_pcm_ops_t snd_trident_capture_ops = { 2053 .open = snd_trident_capture_open, 2054 .close = snd_trident_capture_close, 2055 .ioctl = snd_trident_ioctl, 2056 .hw_params = snd_trident_capture_hw_params, 2057 .hw_free = snd_trident_hw_free, 2058 .prepare = snd_trident_capture_prepare, 2059 .trigger = snd_trident_trigger, 2060 .pointer = snd_trident_capture_pointer, 2061 }; 2062 2063 static snd_pcm_ops_t snd_trident_si7018_capture_ops = { 2064 .open = snd_trident_capture_open, 2065 .close = snd_trident_capture_close, 2066 .ioctl = snd_trident_ioctl, 2067 .hw_params = snd_trident_si7018_capture_hw_params, 2068 .hw_free = snd_trident_si7018_capture_hw_free, 2069 .prepare = snd_trident_si7018_capture_prepare, 2070 .trigger = snd_trident_trigger, 2071 .pointer = snd_trident_playback_pointer, 2072 }; 2073 2074 static snd_pcm_ops_t snd_trident_foldback_ops = { 2075 .open = snd_trident_foldback_open, 2076 .close = snd_trident_foldback_close, 2077 .ioctl = snd_trident_ioctl, 2078 .hw_params = snd_trident_hw_params, 2079 .hw_free = snd_trident_hw_free, 2080 .prepare = snd_trident_foldback_prepare, 2081 .trigger = snd_trident_trigger, 2082 .pointer = snd_trident_playback_pointer, 2083 }; 2084 2085 static snd_pcm_ops_t snd_trident_nx_foldback_ops = { 2086 .open = snd_trident_foldback_open, 2087 .close = snd_trident_foldback_close, 2088 .ioctl = snd_trident_ioctl, 2089 .hw_params = snd_trident_hw_params, 2090 .hw_free = snd_trident_hw_free, 2091 .prepare = snd_trident_foldback_prepare, 2092 .trigger = snd_trident_trigger, 2093 .pointer = snd_trident_playback_pointer, 2094 .page = snd_pcm_sgbuf_ops_page, 2095 }; 2096 2097 static snd_pcm_ops_t snd_trident_spdif_ops = { 2098 .open = snd_trident_spdif_open, 2099 .close = snd_trident_spdif_close, 2100 .ioctl = snd_trident_ioctl, 2101 .hw_params = snd_trident_spdif_hw_params, 2102 .hw_free = snd_trident_hw_free, 2103 .prepare = snd_trident_spdif_prepare, 2104 .trigger = snd_trident_trigger, 2105 .pointer = snd_trident_spdif_pointer, 2106 }; 2107 2108 static snd_pcm_ops_t snd_trident_spdif_7018_ops = { 2109 .open = snd_trident_spdif_open, 2110 .close = snd_trident_spdif_close, 2111 .ioctl = snd_trident_ioctl, 2112 .hw_params = snd_trident_spdif_hw_params, 2113 .hw_free = snd_trident_hw_free, 2114 .prepare = snd_trident_spdif_prepare, 2115 .trigger = snd_trident_trigger, 2116 .pointer = snd_trident_playback_pointer, 2117 }; 2118 2119 /*--------------------------------------------------------------------------- 2120 snd_trident_pcm_free 2121 2122 Description: This routine release the 4DWave private data. 2123 2124 Paramters: private_data - pointer to 4DWave device info. 2125 2126 Returns: None 2127 2128 ---------------------------------------------------------------------------*/ 2129 static void snd_trident_pcm_free(snd_pcm_t *pcm) 2130 { 2131 trident_t *trident = pcm->private_data; 2132 trident->pcm = NULL; 2133 snd_pcm_lib_preallocate_free_for_all(pcm); 2134 } 2135 2136 static void snd_trident_foldback_pcm_free(snd_pcm_t *pcm) 2137 { 2138 trident_t *trident = pcm->private_data; 2139 trident->foldback = NULL; 2140 snd_pcm_lib_preallocate_free_for_all(pcm); 2141 } 2142 2143 static void snd_trident_spdif_pcm_free(snd_pcm_t *pcm) 2144 { 2145 trident_t *trident = pcm->private_data; 2146 trident->spdif = NULL; 2147 snd_pcm_lib_preallocate_free_for_all(pcm); 2148 } 2149 2150 /*--------------------------------------------------------------------------- 2151 snd_trident_pcm 2152 2153 Description: This routine registers the 4DWave device for PCM support. 2154 2155 Paramters: trident - pointer to target device class for 4DWave. 2156 2157 Returns: None 2158 2159 ---------------------------------------------------------------------------*/ 2160 2161 int __devinit snd_trident_pcm(trident_t * trident, int device, snd_pcm_t ** rpcm) 2162 { 2163 snd_pcm_t *pcm; 2164 int err; 2165 2166 if (rpcm) 2167 *rpcm = NULL; 2168 if ((err = snd_pcm_new(trident->card, "trident_dx_nx", device, trident->ChanPCM, 1, &pcm)) < 0) 2169 return err; 2170 2171 pcm->private_data = trident; 2172 pcm->private_free = snd_trident_pcm_free; 2173 2174 if (trident->tlb.entries) { 2175 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_trident_nx_playback_ops); 2176 } else { 2177 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_trident_playback_ops); 2178 } 2179 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, 2180 trident->device != TRIDENT_DEVICE_ID_SI7018 ? 2181 &snd_trident_capture_ops : 2182 &snd_trident_si7018_capture_ops); 2183 2184 pcm->info_flags = 0; 2185 pcm->dev_subclass = SNDRV_PCM_SUBCLASS_GENERIC_MIX; 2186 strcpy(pcm->name, "Trident 4DWave"); 2187 trident->pcm = pcm; 2188 2189 if (trident->tlb.entries) { 2190 snd_pcm_substream_t *substream; 2191 for (substream = pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream; substream; substream = substream->next) 2192 snd_pcm_lib_preallocate_pages(substream, SNDRV_DMA_TYPE_DEV_SG, 2193 snd_dma_pci_data(trident->pci), 2194 64*1024, 128*1024); 2195 snd_pcm_lib_preallocate_pages(pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream, 2196 SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(trident->pci), 2197 64*1024, 128*1024); 2198 } else { 2199 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, 2200 snd_dma_pci_data(trident->pci), 64*1024, 128*1024); 2201 } 2202 2203 if (rpcm) 2204 *rpcm = pcm; 2205 return 0; 2206 } 2207 2208 /*--------------------------------------------------------------------------- 2209 snd_trident_foldback_pcm 2210 2211 Description: This routine registers the 4DWave device for foldback PCM support. 2212 2213 Paramters: trident - pointer to target device class for 4DWave. 2214 2215 Returns: None 2216 2217 ---------------------------------------------------------------------------*/ 2218 2219 int __devinit snd_trident_foldback_pcm(trident_t * trident, int device, snd_pcm_t ** rpcm) 2220 { 2221 snd_pcm_t *foldback; 2222 int err; 2223 int num_chan = 3; 2224 snd_pcm_substream_t *substream; 2225 2226 if (rpcm) 2227 *rpcm = NULL; 2228 if (trident->device == TRIDENT_DEVICE_ID_NX) 2229 num_chan = 4; 2230 if ((err = snd_pcm_new(trident->card, "trident_dx_nx", device, 0, num_chan, &foldback)) < 0) 2231 return err; 2232 2233 foldback->private_data = trident; 2234 foldback->private_free = snd_trident_foldback_pcm_free; 2235 if (trident->tlb.entries) 2236 snd_pcm_set_ops(foldback, SNDRV_PCM_STREAM_CAPTURE, &snd_trident_nx_foldback_ops); 2237 else 2238 snd_pcm_set_ops(foldback, SNDRV_PCM_STREAM_CAPTURE, &snd_trident_foldback_ops); 2239 foldback->info_flags = 0; 2240 strcpy(foldback->name, "Trident 4DWave"); 2241 substream = foldback->streams[SNDRV_PCM_STREAM_CAPTURE].substream; 2242 strcpy(substream->name, "Front Mixer"); 2243 substream = substream->next; 2244 strcpy(substream->name, "Reverb Mixer"); 2245 substream = substream->next; 2246 strcpy(substream->name, "Chorus Mixer"); 2247 if (num_chan == 4) { 2248 substream = substream->next; 2249 strcpy(substream->name, "Second AC'97 ADC"); 2250 } 2251 trident->foldback = foldback; 2252 2253 if (trident->tlb.entries) 2254 snd_pcm_lib_preallocate_pages_for_all(foldback, SNDRV_DMA_TYPE_DEV_SG, 2255 snd_dma_pci_data(trident->pci), 0, 128*1024); 2256 else 2257 snd_pcm_lib_preallocate_pages_for_all(foldback, SNDRV_DMA_TYPE_DEV, 2258 snd_dma_pci_data(trident->pci), 64*1024, 128*1024); 2259 2260 if (rpcm) 2261 *rpcm = foldback; 2262 return 0; 2263 } 2264 2265 /*--------------------------------------------------------------------------- 2266 snd_trident_spdif 2267 2268 Description: This routine registers the 4DWave-NX device for SPDIF support. 2269 2270 Paramters: trident - pointer to target device class for 4DWave-NX. 2271 2272 Returns: None 2273 2274 ---------------------------------------------------------------------------*/ 2275 2276 int __devinit snd_trident_spdif_pcm(trident_t * trident, int device, snd_pcm_t ** rpcm) 2277 { 2278 snd_pcm_t *spdif; 2279 int err; 2280 2281 if (rpcm) 2282 *rpcm = NULL; 2283 if ((err = snd_pcm_new(trident->card, "trident_dx_nx IEC958", device, 1, 0, &spdif)) < 0) 2284 return err; 2285 2286 spdif->private_data = trident; 2287 spdif->private_free = snd_trident_spdif_pcm_free; 2288 if (trident->device != TRIDENT_DEVICE_ID_SI7018) { 2289 snd_pcm_set_ops(spdif, SNDRV_PCM_STREAM_PLAYBACK, &snd_trident_spdif_ops); 2290 } else { 2291 snd_pcm_set_ops(spdif, SNDRV_PCM_STREAM_PLAYBACK, &snd_trident_spdif_7018_ops); 2292 } 2293 spdif->info_flags = 0; 2294 strcpy(spdif->name, "Trident 4DWave IEC958"); 2295 trident->spdif = spdif; 2296 2297 snd_pcm_lib_preallocate_pages_for_all(spdif, SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(trident->pci), 64*1024, 128*1024); 2298 2299 if (rpcm) 2300 *rpcm = spdif; 2301 return 0; 2302 } 2303 2304 /* 2305 * Mixer part 2306 */ 2307 2308 2309 /*--------------------------------------------------------------------------- 2310 snd_trident_spdif_control 2311 2312 Description: enable/disable S/PDIF out from ac97 mixer 2313 ---------------------------------------------------------------------------*/ 2314 2315 static int snd_trident_spdif_control_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo) 2316 { 2317 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; 2318 uinfo->count = 1; 2319 uinfo->value.integer.min = 0; 2320 uinfo->value.integer.max = 1; 2321 return 0; 2322 } 2323 2324 static int snd_trident_spdif_control_get(snd_kcontrol_t * kcontrol, 2325 snd_ctl_elem_value_t * ucontrol) 2326 { 2327 trident_t *trident = snd_kcontrol_chip(kcontrol); 2328 unsigned char val; 2329 2330 spin_lock_irq(&trident->reg_lock); 2331 val = trident->spdif_ctrl; 2332 ucontrol->value.integer.value[0] = val == kcontrol->private_value; 2333 spin_unlock_irq(&trident->reg_lock); 2334 return 0; 2335 } 2336 2337 static int snd_trident_spdif_control_put(snd_kcontrol_t * kcontrol, 2338 snd_ctl_elem_value_t * ucontrol) 2339 { 2340 trident_t *trident = snd_kcontrol_chip(kcontrol); 2341 unsigned char val; 2342 int change; 2343 2344 val = ucontrol->value.integer.value[0] ? (unsigned char) kcontrol->private_value : 0x00; 2345 spin_lock_irq(&trident->reg_lock); 2346 /* S/PDIF C Channel bits 0-31 : 48khz, SCMS disabled */ 2347 change = trident->spdif_ctrl != val; 2348 trident->spdif_ctrl = val; 2349 if (trident->device != TRIDENT_DEVICE_ID_SI7018) { 2350 if ((inb(TRID_REG(trident, NX_SPCTRL_SPCSO + 3)) & 0x10) == 0) { 2351 outl(trident->spdif_bits, TRID_REG(trident, NX_SPCSTATUS)); 2352 outb(trident->spdif_ctrl, TRID_REG(trident, NX_SPCTRL_SPCSO + 3)); 2353 } 2354 } else { 2355 if (trident->spdif == NULL) { 2356 unsigned int temp; 2357 outl(trident->spdif_bits, TRID_REG(trident, SI_SPDIF_CS)); 2358 temp = inl(TRID_REG(trident, SI_SERIAL_INTF_CTRL)) & ~SPDIF_EN; 2359 if (val) 2360 temp |= SPDIF_EN; 2361 outl(temp, TRID_REG(trident, SI_SERIAL_INTF_CTRL)); 2362 } 2363 } 2364 spin_unlock_irq(&trident->reg_lock); 2365 return change; 2366 } 2367 2368 static snd_kcontrol_new_t snd_trident_spdif_control __devinitdata = 2369 { 2370 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2371 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,SWITCH), 2372 .info = snd_trident_spdif_control_info, 2373 .get = snd_trident_spdif_control_get, 2374 .put = snd_trident_spdif_control_put, 2375 .private_value = 0x28, 2376 }; 2377 2378 /*--------------------------------------------------------------------------- 2379 snd_trident_spdif_default 2380 2381 Description: put/get the S/PDIF default settings 2382 ---------------------------------------------------------------------------*/ 2383 2384 static int snd_trident_spdif_default_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo) 2385 { 2386 uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958; 2387 uinfo->count = 1; 2388 return 0; 2389 } 2390 2391 static int snd_trident_spdif_default_get(snd_kcontrol_t * kcontrol, 2392 snd_ctl_elem_value_t * ucontrol) 2393 { 2394 trident_t *trident = snd_kcontrol_chip(kcontrol); 2395 2396 spin_lock_irq(&trident->reg_lock); 2397 ucontrol->value.iec958.status[0] = (trident->spdif_bits >> 0) & 0xff; 2398 ucontrol->value.iec958.status[1] = (trident->spdif_bits >> 8) & 0xff; 2399 ucontrol->value.iec958.status[2] = (trident->spdif_bits >> 16) & 0xff; 2400 ucontrol->value.iec958.status[3] = (trident->spdif_bits >> 24) & 0xff; 2401 spin_unlock_irq(&trident->reg_lock); 2402 return 0; 2403 } 2404 2405 static int snd_trident_spdif_default_put(snd_kcontrol_t * kcontrol, 2406 snd_ctl_elem_value_t * ucontrol) 2407 { 2408 trident_t *trident = snd_kcontrol_chip(kcontrol); 2409 unsigned int val; 2410 int change; 2411 2412 val = (ucontrol->value.iec958.status[0] << 0) | 2413 (ucontrol->value.iec958.status[1] << 8) | 2414 (ucontrol->value.iec958.status[2] << 16) | 2415 (ucontrol->value.iec958.status[3] << 24); 2416 spin_lock_irq(&trident->reg_lock); 2417 change = trident->spdif_bits != val; 2418 trident->spdif_bits = val; 2419 if (trident->device != TRIDENT_DEVICE_ID_SI7018) { 2420 if ((inb(TRID_REG(trident, NX_SPCTRL_SPCSO + 3)) & 0x10) == 0) 2421 outl(trident->spdif_bits, TRID_REG(trident, NX_SPCSTATUS)); 2422 } else { 2423 if (trident->spdif == NULL) 2424 outl(trident->spdif_bits, TRID_REG(trident, SI_SPDIF_CS)); 2425 } 2426 spin_unlock_irq(&trident->reg_lock); 2427 return change; 2428 } 2429 2430 static snd_kcontrol_new_t snd_trident_spdif_default __devinitdata = 2431 { 2432 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 2433 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT), 2434 .info = snd_trident_spdif_default_info, 2435 .get = snd_trident_spdif_default_get, 2436 .put = snd_trident_spdif_default_put 2437 }; 2438 2439 /*--------------------------------------------------------------------------- 2440 snd_trident_spdif_mask 2441 2442 Description: put/get the S/PDIF mask 2443 ---------------------------------------------------------------------------*/ 2444 2445 static int snd_trident_spdif_mask_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo) 2446 { 2447 uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958; 2448 uinfo->count = 1; 2449 return 0; 2450 } 2451 2452 static int snd_trident_spdif_mask_get(snd_kcontrol_t * kcontrol, 2453 snd_ctl_elem_value_t * ucontrol) 2454 { 2455 ucontrol->value.iec958.status[0] = 0xff; 2456 ucontrol->value.iec958.status[1] = 0xff; 2457 ucontrol->value.iec958.status[2] = 0xff; 2458 ucontrol->value.iec958.status[3] = 0xff; 2459 return 0; 2460 } 2461 2462 static snd_kcontrol_new_t snd_trident_spdif_mask __devinitdata = 2463 { 2464 .access = SNDRV_CTL_ELEM_ACCESS_READ, 2465 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 2466 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,MASK), 2467 .info = snd_trident_spdif_mask_info, 2468 .get = snd_trident_spdif_mask_get, 2469 }; 2470 2471 /*--------------------------------------------------------------------------- 2472 snd_trident_spdif_stream 2473 2474 Description: put/get the S/PDIF stream settings 2475 ---------------------------------------------------------------------------*/ 2476 2477 static int snd_trident_spdif_stream_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo) 2478 { 2479 uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958; 2480 uinfo->count = 1; 2481 return 0; 2482 } 2483 2484 static int snd_trident_spdif_stream_get(snd_kcontrol_t * kcontrol, 2485 snd_ctl_elem_value_t * ucontrol) 2486 { 2487 trident_t *trident = snd_kcontrol_chip(kcontrol); 2488 2489 spin_lock_irq(&trident->reg_lock); 2490 ucontrol->value.iec958.status[0] = (trident->spdif_pcm_bits >> 0) & 0xff; 2491 ucontrol->value.iec958.status[1] = (trident->spdif_pcm_bits >> 8) & 0xff; 2492 ucontrol->value.iec958.status[2] = (trident->spdif_pcm_bits >> 16) & 0xff; 2493 ucontrol->value.iec958.status[3] = (trident->spdif_pcm_bits >> 24) & 0xff; 2494 spin_unlock_irq(&trident->reg_lock); 2495 return 0; 2496 } 2497 2498 static int snd_trident_spdif_stream_put(snd_kcontrol_t * kcontrol, 2499 snd_ctl_elem_value_t * ucontrol) 2500 { 2501 trident_t *trident = snd_kcontrol_chip(kcontrol); 2502 unsigned int val; 2503 int change; 2504 2505 val = (ucontrol->value.iec958.status[0] << 0) | 2506 (ucontrol->value.iec958.status[1] << 8) | 2507 (ucontrol->value.iec958.status[2] << 16) | 2508 (ucontrol->value.iec958.status[3] << 24); 2509 spin_lock_irq(&trident->reg_lock); 2510 change = trident->spdif_pcm_bits != val; 2511 trident->spdif_pcm_bits = val; 2512 if (trident->spdif != NULL) { 2513 if (trident->device != TRIDENT_DEVICE_ID_SI7018) { 2514 outl(trident->spdif_pcm_bits, TRID_REG(trident, NX_SPCSTATUS)); 2515 } else { 2516 outl(trident->spdif_bits, TRID_REG(trident, SI_SPDIF_CS)); 2517 } 2518 } 2519 spin_unlock_irq(&trident->reg_lock); 2520 return change; 2521 } 2522 2523 static snd_kcontrol_new_t snd_trident_spdif_stream __devinitdata = 2524 { 2525 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE, 2526 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 2527 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,PCM_STREAM), 2528 .info = snd_trident_spdif_stream_info, 2529 .get = snd_trident_spdif_stream_get, 2530 .put = snd_trident_spdif_stream_put 2531 }; 2532 2533 /*--------------------------------------------------------------------------- 2534 snd_trident_ac97_control 2535 2536 Description: enable/disable rear path for ac97 2537 ---------------------------------------------------------------------------*/ 2538 2539 static int snd_trident_ac97_control_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo) 2540 { 2541 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; 2542 uinfo->count = 1; 2543 uinfo->value.integer.min = 0; 2544 uinfo->value.integer.max = 1; 2545 return 0; 2546 } 2547 2548 static int snd_trident_ac97_control_get(snd_kcontrol_t * kcontrol, 2549 snd_ctl_elem_value_t * ucontrol) 2550 { 2551 trident_t *trident = snd_kcontrol_chip(kcontrol); 2552 unsigned char val; 2553 2554 spin_lock_irq(&trident->reg_lock); 2555 val = trident->ac97_ctrl = inl(TRID_REG(trident, NX_ACR0_AC97_COM_STAT)); 2556 ucontrol->value.integer.value[0] = (val & (1 << kcontrol->private_value)) ? 1 : 0; 2557 spin_unlock_irq(&trident->reg_lock); 2558 return 0; 2559 } 2560 2561 static int snd_trident_ac97_control_put(snd_kcontrol_t * kcontrol, 2562 snd_ctl_elem_value_t * ucontrol) 2563 { 2564 trident_t *trident = snd_kcontrol_chip(kcontrol); 2565 unsigned char val; 2566 int change = 0; 2567 2568 spin_lock_irq(&trident->reg_lock); 2569 val = trident->ac97_ctrl = inl(TRID_REG(trident, NX_ACR0_AC97_COM_STAT)); 2570 val &= ~(1 << kcontrol->private_value); 2571 if (ucontrol->value.integer.value[0]) 2572 val |= 1 << kcontrol->private_value; 2573 change = val != trident->ac97_ctrl; 2574 trident->ac97_ctrl = val; 2575 outl(trident->ac97_ctrl = val, TRID_REG(trident, NX_ACR0_AC97_COM_STAT)); 2576 spin_unlock_irq(&trident->reg_lock); 2577 return change; 2578 } 2579 2580 static snd_kcontrol_new_t snd_trident_ac97_rear_control __devinitdata = 2581 { 2582 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2583 .name = "Rear Path", 2584 .info = snd_trident_ac97_control_info, 2585 .get = snd_trident_ac97_control_get, 2586 .put = snd_trident_ac97_control_put, 2587 .private_value = 4, 2588 }; 2589 2590 /*--------------------------------------------------------------------------- 2591 snd_trident_vol_control 2592 2593 Description: wave & music volume control 2594 ---------------------------------------------------------------------------*/ 2595 2596 static int snd_trident_vol_control_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo) 2597 { 2598 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 2599 uinfo->count = 2; 2600 uinfo->value.integer.min = 0; 2601 uinfo->value.integer.max = 255; 2602 return 0; 2603 } 2604 2605 static int snd_trident_vol_control_get(snd_kcontrol_t * kcontrol, 2606 snd_ctl_elem_value_t * ucontrol) 2607 { 2608 trident_t *trident = snd_kcontrol_chip(kcontrol); 2609 unsigned int val; 2610 2611 val = trident->musicvol_wavevol; 2612 ucontrol->value.integer.value[0] = 255 - ((val >> kcontrol->private_value) & 0xff); 2613 ucontrol->value.integer.value[1] = 255 - ((val >> (kcontrol->private_value + 8)) & 0xff); 2614 return 0; 2615 } 2616 2617 static int snd_trident_vol_control_put(snd_kcontrol_t * kcontrol, 2618 snd_ctl_elem_value_t * ucontrol) 2619 { 2620 trident_t *trident = snd_kcontrol_chip(kcontrol); 2621 unsigned int val; 2622 int change = 0; 2623 2624 spin_lock_irq(&trident->reg_lock); 2625 val = trident->musicvol_wavevol; 2626 val &= ~(0xffff << kcontrol->private_value); 2627 val |= ((255 - (ucontrol->value.integer.value[0] & 0xff)) | 2628 ((255 - (ucontrol->value.integer.value[1] & 0xff)) << 8)) << kcontrol->private_value; 2629 change = val != trident->musicvol_wavevol; 2630 outl(trident->musicvol_wavevol = val, TRID_REG(trident, T4D_MUSICVOL_WAVEVOL)); 2631 spin_unlock_irq(&trident->reg_lock); 2632 return change; 2633 } 2634 2635 static snd_kcontrol_new_t snd_trident_vol_music_control __devinitdata = 2636 { 2637 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2638 .name = "Music Playback Volume", 2639 .info = snd_trident_vol_control_info, 2640 .get = snd_trident_vol_control_get, 2641 .put = snd_trident_vol_control_put, 2642 .private_value = 16, 2643 }; 2644 2645 static snd_kcontrol_new_t snd_trident_vol_wave_control __devinitdata = 2646 { 2647 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2648 .name = "Wave Playback Volume", 2649 .info = snd_trident_vol_control_info, 2650 .get = snd_trident_vol_control_get, 2651 .put = snd_trident_vol_control_put, 2652 .private_value = 0, 2653 }; 2654 2655 /*--------------------------------------------------------------------------- 2656 snd_trident_pcm_vol_control 2657 2658 Description: PCM front volume control 2659 ---------------------------------------------------------------------------*/ 2660 2661 static int snd_trident_pcm_vol_control_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo) 2662 { 2663 trident_t *trident = snd_kcontrol_chip(kcontrol); 2664 2665 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 2666 uinfo->count = 1; 2667 uinfo->value.integer.min = 0; 2668 uinfo->value.integer.max = 255; 2669 if (trident->device == TRIDENT_DEVICE_ID_SI7018) 2670 uinfo->value.integer.max = 1023; 2671 return 0; 2672 } 2673 2674 static int snd_trident_pcm_vol_control_get(snd_kcontrol_t * kcontrol, 2675 snd_ctl_elem_value_t * ucontrol) 2676 { 2677 trident_t *trident = snd_kcontrol_chip(kcontrol); 2678 snd_trident_pcm_mixer_t *mix = &trident->pcm_mixer[snd_ctl_get_ioffnum(kcontrol, &ucontrol->id)]; 2679 2680 if (trident->device == TRIDENT_DEVICE_ID_SI7018) { 2681 ucontrol->value.integer.value[0] = 1023 - mix->vol; 2682 } else { 2683 ucontrol->value.integer.value[0] = 255 - (mix->vol>>2); 2684 } 2685 return 0; 2686 } 2687 2688 static int snd_trident_pcm_vol_control_put(snd_kcontrol_t * kcontrol, 2689 snd_ctl_elem_value_t * ucontrol) 2690 { 2691 trident_t *trident = snd_kcontrol_chip(kcontrol); 2692 snd_trident_pcm_mixer_t *mix = &trident->pcm_mixer[snd_ctl_get_ioffnum(kcontrol, &ucontrol->id)]; 2693 unsigned int val; 2694 int change = 0; 2695 2696 if (trident->device == TRIDENT_DEVICE_ID_SI7018) { 2697 val = 1023 - (ucontrol->value.integer.value[0] & 1023); 2698 } else { 2699 val = (255 - (ucontrol->value.integer.value[0] & 255)) << 2; 2700 } 2701 spin_lock_irq(&trident->reg_lock); 2702 change = val != mix->vol; 2703 mix->vol = val; 2704 if (mix->voice != NULL) 2705 snd_trident_write_vol_reg(trident, mix->voice, val); 2706 spin_unlock_irq(&trident->reg_lock); 2707 return change; 2708 } 2709 2710 static snd_kcontrol_new_t snd_trident_pcm_vol_control __devinitdata = 2711 { 2712 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2713 .name = "PCM Front Playback Volume", 2714 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE, 2715 .count = 32, 2716 .info = snd_trident_pcm_vol_control_info, 2717 .get = snd_trident_pcm_vol_control_get, 2718 .put = snd_trident_pcm_vol_control_put, 2719 }; 2720 2721 /*--------------------------------------------------------------------------- 2722 snd_trident_pcm_pan_control 2723 2724 Description: PCM front pan control 2725 ---------------------------------------------------------------------------*/ 2726 2727 static int snd_trident_pcm_pan_control_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo) 2728 { 2729 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 2730 uinfo->count = 1; 2731 uinfo->value.integer.min = 0; 2732 uinfo->value.integer.max = 127; 2733 return 0; 2734 } 2735 2736 static int snd_trident_pcm_pan_control_get(snd_kcontrol_t * kcontrol, 2737 snd_ctl_elem_value_t * ucontrol) 2738 { 2739 trident_t *trident = snd_kcontrol_chip(kcontrol); 2740 snd_trident_pcm_mixer_t *mix = &trident->pcm_mixer[snd_ctl_get_ioffnum(kcontrol, &ucontrol->id)]; 2741 2742 ucontrol->value.integer.value[0] = mix->pan; 2743 if (ucontrol->value.integer.value[0] & 0x40) { 2744 ucontrol->value.integer.value[0] = (0x3f - (ucontrol->value.integer.value[0] & 0x3f)); 2745 } else { 2746 ucontrol->value.integer.value[0] |= 0x40; 2747 } 2748 return 0; 2749 } 2750 2751 static int snd_trident_pcm_pan_control_put(snd_kcontrol_t * kcontrol, 2752 snd_ctl_elem_value_t * ucontrol) 2753 { 2754 trident_t *trident = snd_kcontrol_chip(kcontrol); 2755 snd_trident_pcm_mixer_t *mix = &trident->pcm_mixer[snd_ctl_get_ioffnum(kcontrol, &ucontrol->id)]; 2756 unsigned char val; 2757 int change = 0; 2758 2759 if (ucontrol->value.integer.value[0] & 0x40) 2760 val = ucontrol->value.integer.value[0] & 0x3f; 2761 else 2762 val = (0x3f - (ucontrol->value.integer.value[0] & 0x3f)) | 0x40; 2763 spin_lock_irq(&trident->reg_lock); 2764 change = val != mix->pan; 2765 mix->pan = val; 2766 if (mix->voice != NULL) 2767 snd_trident_write_pan_reg(trident, mix->voice, val); 2768 spin_unlock_irq(&trident->reg_lock); 2769 return change; 2770 } 2771 2772 static snd_kcontrol_new_t snd_trident_pcm_pan_control __devinitdata = 2773 { 2774 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2775 .name = "PCM Pan Playback Control", 2776 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE, 2777 .count = 32, 2778 .info = snd_trident_pcm_pan_control_info, 2779 .get = snd_trident_pcm_pan_control_get, 2780 .put = snd_trident_pcm_pan_control_put, 2781 }; 2782 2783 /*--------------------------------------------------------------------------- 2784 snd_trident_pcm_rvol_control 2785 2786 Description: PCM reverb volume control 2787 ---------------------------------------------------------------------------*/ 2788 2789 static int snd_trident_pcm_rvol_control_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo) 2790 { 2791 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 2792 uinfo->count = 1; 2793 uinfo->value.integer.min = 0; 2794 uinfo->value.integer.max = 127; 2795 return 0; 2796 } 2797 2798 static int snd_trident_pcm_rvol_control_get(snd_kcontrol_t * kcontrol, 2799 snd_ctl_elem_value_t * ucontrol) 2800 { 2801 trident_t *trident = snd_kcontrol_chip(kcontrol); 2802 snd_trident_pcm_mixer_t *mix = &trident->pcm_mixer[snd_ctl_get_ioffnum(kcontrol, &ucontrol->id)]; 2803 2804 ucontrol->value.integer.value[0] = 127 - mix->rvol; 2805 return 0; 2806 } 2807 2808 static int snd_trident_pcm_rvol_control_put(snd_kcontrol_t * kcontrol, 2809 snd_ctl_elem_value_t * ucontrol) 2810 { 2811 trident_t *trident = snd_kcontrol_chip(kcontrol); 2812 snd_trident_pcm_mixer_t *mix = &trident->pcm_mixer[snd_ctl_get_ioffnum(kcontrol, &ucontrol->id)]; 2813 unsigned short val; 2814 int change = 0; 2815 2816 val = 0x7f - (ucontrol->value.integer.value[0] & 0x7f); 2817 spin_lock_irq(&trident->reg_lock); 2818 change = val != mix->rvol; 2819 mix->rvol = val; 2820 if (mix->voice != NULL) 2821 snd_trident_write_rvol_reg(trident, mix->voice, val); 2822 spin_unlock_irq(&trident->reg_lock); 2823 return change; 2824 } 2825 2826 static snd_kcontrol_new_t snd_trident_pcm_rvol_control __devinitdata = 2827 { 2828 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2829 .name = "PCM Reverb Playback Volume", 2830 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE, 2831 .count = 32, 2832 .info = snd_trident_pcm_rvol_control_info, 2833 .get = snd_trident_pcm_rvol_control_get, 2834 .put = snd_trident_pcm_rvol_control_put, 2835 }; 2836 2837 /*--------------------------------------------------------------------------- 2838 snd_trident_pcm_cvol_control 2839 2840 Description: PCM chorus volume control 2841 ---------------------------------------------------------------------------*/ 2842 2843 static int snd_trident_pcm_cvol_control_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo) 2844 { 2845 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 2846 uinfo->count = 1; 2847 uinfo->value.integer.min = 0; 2848 uinfo->value.integer.max = 127; 2849 return 0; 2850 } 2851 2852 static int snd_trident_pcm_cvol_control_get(snd_kcontrol_t * kcontrol, 2853 snd_ctl_elem_value_t * ucontrol) 2854 { 2855 trident_t *trident = snd_kcontrol_chip(kcontrol); 2856 snd_trident_pcm_mixer_t *mix = &trident->pcm_mixer[snd_ctl_get_ioffnum(kcontrol, &ucontrol->id)]; 2857 2858 ucontrol->value.integer.value[0] = 127 - mix->cvol; 2859 return 0; 2860 } 2861 2862 static int snd_trident_pcm_cvol_control_put(snd_kcontrol_t * kcontrol, 2863 snd_ctl_elem_value_t * ucontrol) 2864 { 2865 trident_t *trident = snd_kcontrol_chip(kcontrol); 2866 snd_trident_pcm_mixer_t *mix = &trident->pcm_mixer[snd_ctl_get_ioffnum(kcontrol, &ucontrol->id)]; 2867 unsigned short val; 2868 int change = 0; 2869 2870 val = 0x7f - (ucontrol->value.integer.value[0] & 0x7f); 2871 spin_lock_irq(&trident->reg_lock); 2872 change = val != mix->cvol; 2873 mix->cvol = val; 2874 if (mix->voice != NULL) 2875 snd_trident_write_cvol_reg(trident, mix->voice, val); 2876 spin_unlock_irq(&trident->reg_lock); 2877 return change; 2878 } 2879 2880 static snd_kcontrol_new_t snd_trident_pcm_cvol_control __devinitdata = 2881 { 2882 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2883 .name = "PCM Chorus Playback Volume", 2884 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE, 2885 .count = 32, 2886 .info = snd_trident_pcm_cvol_control_info, 2887 .get = snd_trident_pcm_cvol_control_get, 2888 .put = snd_trident_pcm_cvol_control_put, 2889 }; 2890 2891 static void snd_trident_notify_pcm_change1(snd_card_t * card, snd_kcontrol_t *kctl, int num, int activate) 2892 { 2893 snd_ctl_elem_id_t id; 2894 2895 snd_runtime_check(kctl != NULL, return); 2896 if (activate) 2897 kctl->vd[num].access &= ~SNDRV_CTL_ELEM_ACCESS_INACTIVE; 2898 else 2899 kctl->vd[num].access |= SNDRV_CTL_ELEM_ACCESS_INACTIVE; 2900 snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE | 2901 SNDRV_CTL_EVENT_MASK_INFO, 2902 snd_ctl_build_ioff(&id, kctl, num)); 2903 } 2904 2905 static void snd_trident_notify_pcm_change(trident_t *trident, snd_trident_pcm_mixer_t *tmix, int num, int activate) 2906 { 2907 snd_trident_notify_pcm_change1(trident->card, trident->ctl_vol, num, activate); 2908 snd_trident_notify_pcm_change1(trident->card, trident->ctl_pan, num, activate); 2909 snd_trident_notify_pcm_change1(trident->card, trident->ctl_rvol, num, activate); 2910 snd_trident_notify_pcm_change1(trident->card, trident->ctl_cvol, num, activate); 2911 } 2912 2913 static int snd_trident_pcm_mixer_build(trident_t *trident, snd_trident_voice_t *voice, snd_pcm_substream_t *substream) 2914 { 2915 snd_trident_pcm_mixer_t *tmix; 2916 2917 snd_assert(trident != NULL && voice != NULL && substream != NULL, return -EINVAL); 2918 tmix = &trident->pcm_mixer[substream->number]; 2919 tmix->voice = voice; 2920 tmix->vol = T4D_DEFAULT_PCM_VOL; 2921 tmix->pan = T4D_DEFAULT_PCM_PAN; 2922 tmix->rvol = T4D_DEFAULT_PCM_RVOL; 2923 tmix->cvol = T4D_DEFAULT_PCM_CVOL; 2924 snd_trident_notify_pcm_change(trident, tmix, substream->number, 1); 2925 return 0; 2926 } 2927 2928 static int snd_trident_pcm_mixer_free(trident_t *trident, snd_trident_voice_t *voice, snd_pcm_substream_t *substream) 2929 { 2930 snd_trident_pcm_mixer_t *tmix; 2931 2932 snd_assert(trident != NULL && substream != NULL, return -EINVAL); 2933 tmix = &trident->pcm_mixer[substream->number]; 2934 tmix->voice = NULL; 2935 snd_trident_notify_pcm_change(trident, tmix, substream->number, 0); 2936 return 0; 2937 } 2938 2939 /*--------------------------------------------------------------------------- 2940 snd_trident_mixer 2941 2942 Description: This routine registers the 4DWave device for mixer support. 2943 2944 Paramters: trident - pointer to target device class for 4DWave. 2945 2946 Returns: None 2947 2948 ---------------------------------------------------------------------------*/ 2949 2950 static int __devinit snd_trident_mixer(trident_t * trident, int pcm_spdif_device) 2951 { 2952 ac97_template_t _ac97; 2953 snd_card_t * card = trident->card; 2954 snd_kcontrol_t *kctl; 2955 snd_ctl_elem_value_t *uctl; 2956 int idx, err, retries = 2; 2957 static ac97_bus_ops_t ops = { 2958 .write = snd_trident_codec_write, 2959 .read = snd_trident_codec_read, 2960 }; 2961 2962 uctl = kcalloc(1, sizeof(*uctl), GFP_KERNEL); 2963 if (!uctl) 2964 return -ENOMEM; 2965 2966 if ((err = snd_ac97_bus(trident->card, 0, &ops, NULL, &trident->ac97_bus)) < 0) 2967 goto __out; 2968 2969 memset(&_ac97, 0, sizeof(_ac97)); 2970 _ac97.private_data = trident; 2971 trident->ac97_detect = 1; 2972 2973 __again: 2974 if ((err = snd_ac97_mixer(trident->ac97_bus, &_ac97, &trident->ac97)) < 0) { 2975 if (trident->device == TRIDENT_DEVICE_ID_SI7018) { 2976 if ((err = snd_trident_sis_reset(trident)) < 0) 2977 goto __out; 2978 if (retries-- > 0) 2979 goto __again; 2980 err = -EIO; 2981 } 2982 goto __out; 2983 } 2984 2985 /* secondary codec? */ 2986 if (trident->device == TRIDENT_DEVICE_ID_SI7018 && 2987 (inl(TRID_REG(trident, SI_SERIAL_INTF_CTRL)) & SI_AC97_PRIMARY_READY) != 0) { 2988 _ac97.num = 1; 2989 err = snd_ac97_mixer(trident->ac97_bus, &_ac97, &trident->ac97_sec); 2990 if (err < 0) 2991 snd_printk("SI7018: the secondary codec - invalid access\n"); 2992 #if 0 // only for my testing purpose --jk 2993 { 2994 ac97_t *mc97; 2995 err = snd_ac97_modem(trident->card, &_ac97, &mc97); 2996 if (err < 0) 2997 snd_printk("snd_ac97_modem returned error %i\n", err); 2998 } 2999 #endif 3000 } 3001 3002 trident->ac97_detect = 0; 3003 3004 if (trident->device != TRIDENT_DEVICE_ID_SI7018) { 3005 if ((err = snd_ctl_add(card, kctl = snd_ctl_new1(&snd_trident_vol_wave_control, trident))) < 0) 3006 goto __out; 3007 kctl->put(kctl, uctl); 3008 if ((err = snd_ctl_add(card, kctl = snd_ctl_new1(&snd_trident_vol_music_control, trident))) < 0) 3009 goto __out; 3010 kctl->put(kctl, uctl); 3011 outl(trident->musicvol_wavevol = 0x00000000, TRID_REG(trident, T4D_MUSICVOL_WAVEVOL)); 3012 } else { 3013 outl(trident->musicvol_wavevol = 0xffff0000, TRID_REG(trident, T4D_MUSICVOL_WAVEVOL)); 3014 } 3015 3016 for (idx = 0; idx < 32; idx++) { 3017 snd_trident_pcm_mixer_t *tmix; 3018 3019 tmix = &trident->pcm_mixer[idx]; 3020 tmix->voice = NULL; 3021 } 3022 if ((trident->ctl_vol = snd_ctl_new1(&snd_trident_pcm_vol_control, trident)) == NULL) 3023 goto __nomem; 3024 if ((err = snd_ctl_add(card, trident->ctl_vol))) 3025 goto __out; 3026 3027 if ((trident->ctl_pan = snd_ctl_new1(&snd_trident_pcm_pan_control, trident)) == NULL) 3028 goto __nomem; 3029 if ((err = snd_ctl_add(card, trident->ctl_pan))) 3030 goto __out; 3031 3032 if ((trident->ctl_rvol = snd_ctl_new1(&snd_trident_pcm_rvol_control, trident)) == NULL) 3033 goto __nomem; 3034 if ((err = snd_ctl_add(card, trident->ctl_rvol))) 3035 goto __out; 3036 3037 if ((trident->ctl_cvol = snd_ctl_new1(&snd_trident_pcm_cvol_control, trident)) == NULL) 3038 goto __nomem; 3039 if ((err = snd_ctl_add(card, trident->ctl_cvol))) 3040 goto __out; 3041 3042 if (trident->device == TRIDENT_DEVICE_ID_NX) { 3043 if ((err = snd_ctl_add(card, kctl = snd_ctl_new1(&snd_trident_ac97_rear_control, trident))) < 0) 3044 goto __out; 3045 kctl->put(kctl, uctl); 3046 } 3047 if (trident->device == TRIDENT_DEVICE_ID_NX || trident->device == TRIDENT_DEVICE_ID_SI7018) { 3048 3049 kctl = snd_ctl_new1(&snd_trident_spdif_control, trident); 3050 if (kctl == NULL) { 3051 err = -ENOMEM; 3052 goto __out; 3053 } 3054 if (trident->ac97->ext_id & AC97_EI_SPDIF) 3055 kctl->id.index++; 3056 if (trident->ac97_sec && (trident->ac97_sec->ext_id & AC97_EI_SPDIF)) 3057 kctl->id.index++; 3058 idx = kctl->id.index; 3059 if ((err = snd_ctl_add(card, kctl)) < 0) 3060 goto __out; 3061 kctl->put(kctl, uctl); 3062 3063 kctl = snd_ctl_new1(&snd_trident_spdif_default, trident); 3064 if (kctl == NULL) { 3065 err = -ENOMEM; 3066 goto __out; 3067 } 3068 kctl->id.index = idx; 3069 kctl->id.device = pcm_spdif_device; 3070 if ((err = snd_ctl_add(card, kctl)) < 0) 3071 goto __out; 3072 3073 kctl = snd_ctl_new1(&snd_trident_spdif_mask, trident); 3074 if (kctl == NULL) { 3075 err = -ENOMEM; 3076 goto __out; 3077 } 3078 kctl->id.index = idx; 3079 kctl->id.device = pcm_spdif_device; 3080 if ((err = snd_ctl_add(card, kctl)) < 0) 3081 goto __out; 3082 3083 kctl = snd_ctl_new1(&snd_trident_spdif_stream, trident); 3084 if (kctl == NULL) { 3085 err = -ENOMEM; 3086 goto __out; 3087 } 3088 kctl->id.index = idx; 3089 kctl->id.device = pcm_spdif_device; 3090 if ((err = snd_ctl_add(card, kctl)) < 0) 3091 goto __out; 3092 trident->spdif_pcm_ctl = kctl; 3093 } 3094 3095 err = 0; 3096 goto __out; 3097 3098 __nomem: 3099 err = -ENOMEM; 3100 3101 __out: 3102 kfree(uctl); 3103 3104 return err; 3105 } 3106 3107 /* 3108 * gameport interface 3109 */ 3110 3111 #if defined(CONFIG_GAMEPORT) || (defined(MODULE) && defined(CONFIG_GAMEPORT_MODULE)) 3112 3113 static unsigned char snd_trident_gameport_read(struct gameport *gameport) 3114 { 3115 trident_t *chip = gameport_get_port_data(gameport); 3116 3117 snd_assert(chip, return 0); 3118 return inb(TRID_REG(chip, GAMEPORT_LEGACY)); 3119 } 3120 3121 static void snd_trident_gameport_trigger(struct gameport *gameport) 3122 { 3123 trident_t *chip = gameport_get_port_data(gameport); 3124 3125 snd_assert(chip, return); 3126 outb(0xff, TRID_REG(chip, GAMEPORT_LEGACY)); 3127 } 3128 3129 static int snd_trident_gameport_cooked_read(struct gameport *gameport, int *axes, int *buttons) 3130 { 3131 trident_t *chip = gameport_get_port_data(gameport); 3132 int i; 3133 3134 snd_assert(chip, return 0); 3135 3136 *buttons = (~inb(TRID_REG(chip, GAMEPORT_LEGACY)) >> 4) & 0xf; 3137 3138 for (i = 0; i < 4; i++) { 3139 axes[i] = inw(TRID_REG(chip, GAMEPORT_AXES + i * 2)); 3140 if (axes[i] == 0xffff) axes[i] = -1; 3141 } 3142 3143 return 0; 3144 } 3145 3146 static int snd_trident_gameport_open(struct gameport *gameport, int mode) 3147 { 3148 trident_t *chip = gameport_get_port_data(gameport); 3149 3150 snd_assert(chip, return 0); 3151 3152 switch (mode) { 3153 case GAMEPORT_MODE_COOKED: 3154 outb(GAMEPORT_MODE_ADC, TRID_REG(chip, GAMEPORT_GCR)); 3155 set_current_state(TASK_UNINTERRUPTIBLE); 3156 schedule_timeout(1 + 20 * HZ / 1000); /* 20msec */ 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 inline static 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 = kcalloc(1, 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