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