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