2 * Maintained by Jaroslav Kysela <perex@suse.cz>
3 * Originated by audio@tridentmicro.com
4 * Fri Feb 19 15:55:28 MST 1999
5 * Routines for control of Trident 4DWave (DX and NX) chip
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.
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.
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
27 * SiS7018 S/PDIF support by Thomas Winischhofer <thomas@winischhofer.net>
30 #include <sound/driver.h>
31 #include <linux/delay.h>
32 #include <linux/init.h>
33 #include <linux/interrupt.h>
34 #include <linux/pci.h>
35 #include <linux/slab.h>
36 #include <linux/vmalloc.h>
37 #include <linux/gameport.h>
39 #include <sound/core.h>
40 #include <sound/info.h>
41 #include <sound/control.h>
42 #include <sound/trident.h>
43 #include <sound/asoundef.h>
47 #define chip_t trident_t
49 static int snd_trident_pcm_mixer_build(trident_t *trident, snd_trident_voice_t * voice, snd_pcm_substream_t *substream);
50 static int snd_trident_pcm_mixer_free(trident_t *trident, snd_trident_voice_t * voice, snd_pcm_substream_t *substream);
51 static irqreturn_t snd_trident_interrupt(int irq, void *dev_id, struct pt_regs *regs);
53 static int snd_trident_set_power_state(snd_card_t *card, unsigned int power_state);
55 static int snd_trident_sis_reset(trident_t *trident);
63 static void snd_trident_print_voice_regs(trident_t *trident, int voice)
65 unsigned int val, tmp;
67 printk("Trident voice %i:\n", voice);
68 outb(voice, TRID_REG(trident, T4D_LFO_GC_CIR));
69 val = inl(TRID_REG(trident, CH_LBA));
70 printk("LBA: 0x%x\n", val);
71 val = inl(TRID_REG(trident, CH_GVSEL_PAN_VOL_CTRL_EC));
72 printk("GVSel: %i\n", val >> 31);
73 printk("Pan: 0x%x\n", (val >> 24) & 0x7f);
74 printk("Vol: 0x%x\n", (val >> 16) & 0xff);
75 printk("CTRL: 0x%x\n", (val >> 12) & 0x0f);
76 printk("EC: 0x%x\n", val & 0x0fff);
77 if (trident->device != TRIDENT_DEVICE_ID_NX) {
78 val = inl(TRID_REG(trident, CH_DX_CSO_ALPHA_FMS));
79 printk("CSO: 0x%x\n", val >> 16);
80 printk("Alpha: 0x%x\n", (val >> 4) & 0x0fff);
81 printk("FMS: 0x%x\n", val & 0x0f);
82 val = inl(TRID_REG(trident, CH_DX_ESO_DELTA));
83 printk("ESO: 0x%x\n", val >> 16);
84 printk("Delta: 0x%x\n", val & 0xffff);
85 val = inl(TRID_REG(trident, CH_DX_FMC_RVOL_CVOL));
86 } else { // TRIDENT_DEVICE_ID_NX
87 val = inl(TRID_REG(trident, CH_NX_DELTA_CSO));
88 tmp = (val >> 24) & 0xff;
89 printk("CSO: 0x%x\n", val & 0x00ffffff);
90 val = inl(TRID_REG(trident, CH_NX_DELTA_ESO));
91 tmp |= (val >> 16) & 0xff00;
92 printk("Delta: 0x%x\n", tmp);
93 printk("ESO: 0x%x\n", val & 0x00ffffff);
94 val = inl(TRID_REG(trident, CH_NX_ALPHA_FMS_FMC_RVOL_CVOL));
95 printk("Alpha: 0x%x\n", val >> 20);
96 printk("FMS: 0x%x\n", (val >> 16) & 0x0f);
98 printk("FMC: 0x%x\n", (val >> 14) & 3);
99 printk("RVol: 0x%x\n", (val >> 7) & 0x7f);
100 printk("CVol: 0x%x\n", val & 0x7f);
104 /*---------------------------------------------------------------------------
105 unsigned short snd_trident_codec_read(ac97_t *ac97, unsigned short reg)
107 Description: This routine will do all of the reading from the external
110 Parameters: ac97 - ac97 codec structure
111 reg - CODEC register index, from AC97 Hal.
113 returns: 16 bit value read from the AC97.
115 ---------------------------------------------------------------------------*/
116 static unsigned short snd_trident_codec_read(ac97_t *ac97, unsigned short reg)
118 unsigned int data = 0, treg;
119 unsigned short count = 0xffff;
121 trident_t *trident = snd_magic_cast(trident_t, ac97->private_data, return -ENXIO);
123 spin_lock_irqsave(&trident->reg_lock, flags);
124 if (trident->device == TRIDENT_DEVICE_ID_DX) {
125 data = (DX_AC97_BUSY_READ | (reg & 0x000000ff));
126 outl(data, TRID_REG(trident, DX_ACR1_AC97_R));
128 data = inl(TRID_REG(trident, DX_ACR1_AC97_R));
129 if ((data & DX_AC97_BUSY_READ) == 0)
132 } else if (trident->device == TRIDENT_DEVICE_ID_NX) {
133 data = (NX_AC97_BUSY_READ | (reg & 0x000000ff));
134 treg = ac97->num == 0 ? NX_ACR2_AC97_R_PRIMARY : NX_ACR3_AC97_R_SECONDARY;
135 outl(data, TRID_REG(trident, treg));
137 data = inl(TRID_REG(trident, treg));
138 if ((data & 0x00000C00) == 0)
141 } else if (trident->device == TRIDENT_DEVICE_ID_SI7018) {
142 data = SI_AC97_BUSY_READ | SI_AC97_AUDIO_BUSY | (reg & 0x000000ff);
144 data |= SI_AC97_SECONDARY;
145 outl(data, TRID_REG(trident, SI_AC97_READ));
147 data = inl(TRID_REG(trident, SI_AC97_READ));
148 if ((data & (SI_AC97_BUSY_READ)) == 0)
153 if (count == 0 && !trident->ac97_detect) {
154 snd_printk("ac97 codec read TIMEOUT [0x%x/0x%x]!!!\n", reg, data);
158 spin_unlock_irqrestore(&trident->reg_lock, flags);
159 return ((unsigned short) (data >> 16));
162 /*---------------------------------------------------------------------------
163 void snd_trident_codec_write(ac97_t *ac97, unsigned short reg, unsigned short wdata)
165 Description: This routine will do all of the writing to the external
168 Parameters: ac97 - ac97 codec structure
169 reg - CODEC register index, from AC97 Hal.
170 data - Lower 16 bits are the data to write to CODEC.
172 returns: TRUE if everything went ok, else FALSE.
174 ---------------------------------------------------------------------------*/
175 static void snd_trident_codec_write(ac97_t *ac97, unsigned short reg, unsigned short wdata)
177 unsigned int address, data;
178 unsigned short count = 0xffff;
180 trident_t *trident = snd_magic_cast(trident_t, ac97->private_data, return);
182 data = ((unsigned long) wdata) << 16;
184 spin_lock_irqsave(&trident->reg_lock, flags);
185 if (trident->device == TRIDENT_DEVICE_ID_DX) {
186 address = DX_ACR0_AC97_W;
188 /* read AC-97 write register status */
190 if ((inw(TRID_REG(trident, address)) & DX_AC97_BUSY_WRITE) == 0)
194 data |= (DX_AC97_BUSY_WRITE | (reg & 0x000000ff));
195 } else if (trident->device == TRIDENT_DEVICE_ID_NX) {
196 address = NX_ACR1_AC97_W;
198 /* read AC-97 write register status */
200 if ((inw(TRID_REG(trident, address)) & NX_AC97_BUSY_WRITE) == 0)
204 data |= (NX_AC97_BUSY_WRITE | (ac97->num << 8) | (reg & 0x000000ff));
205 } else if (trident->device == TRIDENT_DEVICE_ID_SI7018) {
206 address = SI_AC97_WRITE;
208 /* read AC-97 write register status */
210 if ((inw(TRID_REG(trident, address)) & (SI_AC97_BUSY_WRITE)) == 0)
214 data |= SI_AC97_BUSY_WRITE | SI_AC97_AUDIO_BUSY | (reg & 0x000000ff);
216 data |= SI_AC97_SECONDARY;
218 address = 0; /* keep GCC happy */
219 count = 0; /* return */
223 spin_unlock_irqrestore(&trident->reg_lock, flags);
226 outl(data, TRID_REG(trident, address));
227 spin_unlock_irqrestore(&trident->reg_lock, flags);
230 /*---------------------------------------------------------------------------
231 void snd_trident_enable_eso(trident_t *trident)
233 Description: This routine will enable end of loop interrupts.
234 End of loop interrupts will occur when a running
236 Also enables middle of loop interrupts.
238 Parameters: trident - pointer to target device class for 4DWave.
240 ---------------------------------------------------------------------------*/
242 static void snd_trident_enable_eso(trident_t * trident)
246 val = inl(TRID_REG(trident, T4D_LFO_GC_CIR));
249 if (trident->device == TRIDENT_DEVICE_ID_SI7018)
251 outl(val, TRID_REG(trident, T4D_LFO_GC_CIR));
254 /*---------------------------------------------------------------------------
255 void snd_trident_disable_eso(trident_t *trident)
257 Description: This routine will disable end of loop interrupts.
258 End of loop interrupts will occur when a running
260 Also disables middle of loop interrupts.
263 trident - pointer to target device class for 4DWave.
265 returns: TRUE if everything went ok, else FALSE.
267 ---------------------------------------------------------------------------*/
269 static void snd_trident_disable_eso(trident_t * trident)
273 tmp = inl(TRID_REG(trident, T4D_LFO_GC_CIR));
276 outl(tmp, TRID_REG(trident, T4D_LFO_GC_CIR));
279 /*---------------------------------------------------------------------------
280 void snd_trident_start_voice(trident_t * trident, unsigned int voice)
282 Description: Start a voice, any channel 0 thru 63.
283 This routine automatically handles the fact that there are
284 more than 32 channels available.
286 Parameters : voice - Voice number 0 thru n.
287 trident - pointer to target device class for 4DWave.
291 ---------------------------------------------------------------------------*/
293 void snd_trident_start_voice(trident_t * trident, unsigned int voice)
295 unsigned int mask = 1 << (voice & 0x1f);
296 unsigned int reg = (voice & 0x20) ? T4D_START_B : T4D_START_A;
298 outl(mask, TRID_REG(trident, reg));
301 /*---------------------------------------------------------------------------
302 void snd_trident_stop_voice(trident_t * trident, unsigned int voice)
304 Description: Stop a voice, any channel 0 thru 63.
305 This routine automatically handles the fact that there are
306 more than 32 channels available.
308 Parameters : voice - Voice number 0 thru n.
309 trident - pointer to target device class for 4DWave.
313 ---------------------------------------------------------------------------*/
315 void snd_trident_stop_voice(trident_t * trident, unsigned int voice)
317 unsigned int mask = 1 << (voice & 0x1f);
318 unsigned int reg = (voice & 0x20) ? T4D_STOP_B : T4D_STOP_A;
320 outl(mask, TRID_REG(trident, reg));
323 /*---------------------------------------------------------------------------
324 int snd_trident_allocate_pcm_channel(trident_t *trident)
326 Description: Allocate hardware channel in Bank B (32-63).
328 Parameters : trident - pointer to target device class for 4DWave.
330 Return Value: hardware channel - 32-63 or -1 when no channel is available
332 ---------------------------------------------------------------------------*/
334 static int snd_trident_allocate_pcm_channel(trident_t * trident)
338 if (trident->ChanPCMcnt >= trident->ChanPCM)
340 for (idx = 31; idx >= 0; idx--) {
341 if (!(trident->ChanMap[T4D_BANK_B] & (1 << idx))) {
342 trident->ChanMap[T4D_BANK_B] |= 1 << idx;
343 trident->ChanPCMcnt++;
350 /*---------------------------------------------------------------------------
351 void snd_trident_free_pcm_channel(int channel)
353 Description: Free hardware channel in Bank B (32-63)
355 Parameters : trident - pointer to target device class for 4DWave.
356 channel - hardware channel number 0-63
360 ---------------------------------------------------------------------------*/
362 static void snd_trident_free_pcm_channel(trident_t *trident, int channel)
364 if (channel < 32 || channel > 63)
367 if (trident->ChanMap[T4D_BANK_B] & (1 << channel)) {
368 trident->ChanMap[T4D_BANK_B] &= ~(1 << channel);
369 trident->ChanPCMcnt--;
373 /*---------------------------------------------------------------------------
374 unsigned int snd_trident_allocate_synth_channel(void)
376 Description: Allocate hardware channel in Bank A (0-31).
378 Parameters : trident - pointer to target device class for 4DWave.
380 Return Value: hardware channel - 0-31 or -1 when no channel is available
382 ---------------------------------------------------------------------------*/
384 static int snd_trident_allocate_synth_channel(trident_t * trident)
388 for (idx = 31; idx >= 0; idx--) {
389 if (!(trident->ChanMap[T4D_BANK_A] & (1 << idx))) {
390 trident->ChanMap[T4D_BANK_A] |= 1 << idx;
391 trident->synth.ChanSynthCount++;
398 /*---------------------------------------------------------------------------
399 void snd_trident_free_synth_channel( int channel )
401 Description: Free hardware channel in Bank B (0-31).
403 Parameters : trident - pointer to target device class for 4DWave.
404 channel - hardware channel number 0-63
408 ---------------------------------------------------------------------------*/
410 static void snd_trident_free_synth_channel(trident_t *trident, int channel)
412 if (channel < 0 || channel > 31)
415 if (trident->ChanMap[T4D_BANK_A] & (1 << channel)) {
416 trident->ChanMap[T4D_BANK_A] &= ~(1 << channel);
417 trident->synth.ChanSynthCount--;
421 /*---------------------------------------------------------------------------
422 snd_trident_write_voice_regs
424 Description: This routine will complete and write the 5 hardware channel
425 registers to hardware.
427 Paramters: trident - pointer to target device class for 4DWave.
428 voice - synthesizer voice structure
431 ---------------------------------------------------------------------------*/
433 void snd_trident_write_voice_regs(trident_t * trident,
434 snd_trident_voice_t * voice)
436 unsigned int FmcRvolCvol;
437 unsigned int regs[5];
439 regs[1] = voice->LBA;
440 regs[4] = (voice->GVSel << 31) |
441 ((voice->Pan & 0x0000007f) << 24) |
442 ((voice->CTRL & 0x0000000f) << 12);
443 FmcRvolCvol = ((voice->FMC & 3) << 14) |
444 ((voice->RVol & 0x7f) << 7) |
445 (voice->CVol & 0x7f);
447 switch (trident->device) {
448 case TRIDENT_DEVICE_ID_SI7018:
449 regs[4] |= voice->number > 31 ?
450 (voice->Vol & 0x000003ff) :
451 ((voice->Vol & 0x00003fc) << (16-2)) |
452 (voice->EC & 0x00000fff);
453 regs[0] = (voice->CSO << 16) | ((voice->Alpha & 0x00000fff) << 4) | (voice->FMS & 0x0000000f);
454 regs[2] = (voice->ESO << 16) | (voice->Delta & 0x0ffff);
455 regs[3] = (voice->Attribute << 16) | FmcRvolCvol;
457 case TRIDENT_DEVICE_ID_DX:
458 regs[4] |= ((voice->Vol & 0x000003fc) << (16-2)) |
459 (voice->EC & 0x00000fff);
460 regs[0] = (voice->CSO << 16) | ((voice->Alpha & 0x00000fff) << 4) | (voice->FMS & 0x0000000f);
461 regs[2] = (voice->ESO << 16) | (voice->Delta & 0x0ffff);
462 regs[3] = FmcRvolCvol;
464 case TRIDENT_DEVICE_ID_NX:
465 regs[4] |= ((voice->Vol & 0x000003fc) << (16-2)) |
466 (voice->EC & 0x00000fff);
467 regs[0] = (voice->Delta << 24) | (voice->CSO & 0x00ffffff);
468 regs[2] = ((voice->Delta << 16) & 0xff000000) | (voice->ESO & 0x00ffffff);
469 regs[3] = (voice->Alpha << 20) | ((voice->FMS & 0x0000000f) << 16) | FmcRvolCvol;
475 outb(voice->number, TRID_REG(trident, T4D_LFO_GC_CIR));
476 outl(regs[0], TRID_REG(trident, CH_START + 0));
477 outl(regs[1], TRID_REG(trident, CH_START + 4));
478 outl(regs[2], TRID_REG(trident, CH_START + 8));
479 outl(regs[3], TRID_REG(trident, CH_START + 12));
480 outl(regs[4], TRID_REG(trident, CH_START + 16));
483 printk("written %i channel:\n", voice->number);
484 printk(" regs[0] = 0x%x/0x%x\n", regs[0], inl(TRID_REG(trident, CH_START + 0)));
485 printk(" regs[1] = 0x%x/0x%x\n", regs[1], inl(TRID_REG(trident, CH_START + 4)));
486 printk(" regs[2] = 0x%x/0x%x\n", regs[2], inl(TRID_REG(trident, CH_START + 8)));
487 printk(" regs[3] = 0x%x/0x%x\n", regs[3], inl(TRID_REG(trident, CH_START + 12)));
488 printk(" regs[4] = 0x%x/0x%x\n", regs[4], inl(TRID_REG(trident, CH_START + 16)));
492 /*---------------------------------------------------------------------------
493 snd_trident_write_cso_reg
495 Description: This routine will write the new CSO offset
496 register to hardware.
498 Paramters: trident - pointer to target device class for 4DWave.
499 voice - synthesizer voice structure
502 ---------------------------------------------------------------------------*/
504 static void snd_trident_write_cso_reg(trident_t * trident, snd_trident_voice_t * voice, unsigned int CSO)
507 outb(voice->number, TRID_REG(trident, T4D_LFO_GC_CIR));
508 if (trident->device != TRIDENT_DEVICE_ID_NX) {
509 outw(voice->CSO, TRID_REG(trident, CH_DX_CSO_ALPHA_FMS) + 2);
511 outl((voice->Delta << 24) | (voice->CSO & 0x00ffffff), TRID_REG(trident, CH_NX_DELTA_CSO));
515 /*---------------------------------------------------------------------------
516 snd_trident_write_eso_reg
518 Description: This routine will write the new ESO offset
519 register to hardware.
521 Paramters: trident - pointer to target device class for 4DWave.
522 voice - synthesizer voice structure
525 ---------------------------------------------------------------------------*/
527 static void snd_trident_write_eso_reg(trident_t * trident, snd_trident_voice_t * voice, unsigned int ESO)
530 outb(voice->number, TRID_REG(trident, T4D_LFO_GC_CIR));
531 if (trident->device != TRIDENT_DEVICE_ID_NX) {
532 outw(voice->ESO, TRID_REG(trident, CH_DX_ESO_DELTA) + 2);
534 outl(((voice->Delta << 16) & 0xff000000) | (voice->ESO & 0x00ffffff), TRID_REG(trident, CH_NX_DELTA_ESO));
538 /*---------------------------------------------------------------------------
539 snd_trident_write_vol_reg
541 Description: This routine will write the new voice volume
542 register to hardware.
544 Paramters: trident - pointer to target device class for 4DWave.
545 voice - synthesizer voice structure
546 Vol - new voice volume
548 ---------------------------------------------------------------------------*/
550 static void snd_trident_write_vol_reg(trident_t * trident, snd_trident_voice_t * voice, unsigned int Vol)
553 outb(voice->number, TRID_REG(trident, T4D_LFO_GC_CIR));
554 switch (trident->device) {
555 case TRIDENT_DEVICE_ID_DX:
556 case TRIDENT_DEVICE_ID_NX:
557 outb(voice->Vol >> 2, TRID_REG(trident, CH_GVSEL_PAN_VOL_CTRL_EC + 2));
559 case TRIDENT_DEVICE_ID_SI7018:
560 // printk("voice->Vol = 0x%x\n", voice->Vol);
561 outw((voice->CTRL << 12) | voice->Vol, TRID_REG(trident, CH_GVSEL_PAN_VOL_CTRL_EC));
566 /*---------------------------------------------------------------------------
567 snd_trident_write_pan_reg
569 Description: This routine will write the new voice pan
570 register to hardware.
572 Paramters: trident - pointer to target device class for 4DWave.
573 voice - synthesizer voice structure
576 ---------------------------------------------------------------------------*/
578 static void snd_trident_write_pan_reg(trident_t * trident, snd_trident_voice_t * voice, unsigned int Pan)
581 outb(voice->number, TRID_REG(trident, T4D_LFO_GC_CIR));
582 outb(((voice->GVSel & 0x01) << 7) | (voice->Pan & 0x7f), TRID_REG(trident, CH_GVSEL_PAN_VOL_CTRL_EC + 3));
585 /*---------------------------------------------------------------------------
586 snd_trident_write_rvol_reg
588 Description: This routine will write the new reverb volume
589 register to hardware.
591 Paramters: trident - pointer to target device class for 4DWave.
592 voice - synthesizer voice structure
593 RVol - new reverb volume
595 ---------------------------------------------------------------------------*/
597 static void snd_trident_write_rvol_reg(trident_t * trident, snd_trident_voice_t * voice, unsigned int RVol)
600 outb(voice->number, TRID_REG(trident, T4D_LFO_GC_CIR));
601 outw(((voice->FMC & 0x0003) << 14) | ((voice->RVol & 0x007f) << 7) | (voice->CVol & 0x007f),
602 TRID_REG(trident, trident->device == TRIDENT_DEVICE_ID_NX ? CH_NX_ALPHA_FMS_FMC_RVOL_CVOL : CH_DX_FMC_RVOL_CVOL));
605 /*---------------------------------------------------------------------------
606 snd_trident_write_cvol_reg
608 Description: This routine will write the new chorus volume
609 register to hardware.
611 Paramters: trident - pointer to target device class for 4DWave.
612 voice - synthesizer voice structure
613 CVol - new chorus volume
615 ---------------------------------------------------------------------------*/
617 static void snd_trident_write_cvol_reg(trident_t * trident, snd_trident_voice_t * voice, unsigned int CVol)
620 outb(voice->number, TRID_REG(trident, T4D_LFO_GC_CIR));
621 outw(((voice->FMC & 0x0003) << 14) | ((voice->RVol & 0x007f) << 7) | (voice->CVol & 0x007f),
622 TRID_REG(trident, trident->device == TRIDENT_DEVICE_ID_NX ? CH_NX_ALPHA_FMS_FMC_RVOL_CVOL : CH_DX_FMC_RVOL_CVOL));
625 /*---------------------------------------------------------------------------
626 snd_trident_convert_rate
628 Description: This routine converts rate in HZ to hardware delta value.
630 Paramters: trident - pointer to target device class for 4DWave.
631 rate - Real or Virtual channel number.
633 Returns: Delta value.
635 ---------------------------------------------------------------------------*/
636 unsigned int snd_trident_convert_rate(unsigned int rate)
640 // We special case 44100 and 8000 since rounding with the equation
641 // does not give us an accurate enough value. For 11025 and 22050
642 // the equation gives us the best answer. All other frequencies will
643 // also use the equation. JDW
646 else if (rate == 8000)
648 else if (rate == 48000)
651 delta = (((rate << 12) + 24000) / 48000) & 0x0000ffff;
655 /*---------------------------------------------------------------------------
656 snd_trident_convert_adc_rate
658 Description: This routine converts rate in HZ to hardware delta value.
660 Paramters: trident - pointer to target device class for 4DWave.
661 rate - Real or Virtual channel number.
663 Returns: Delta value.
665 ---------------------------------------------------------------------------*/
666 static unsigned int snd_trident_convert_adc_rate(unsigned int rate)
670 // We special case 44100 and 8000 since rounding with the equation
671 // does not give us an accurate enough value. For 11025 and 22050
672 // the equation gives us the best answer. All other frequencies will
673 // also use the equation. JDW
676 else if (rate == 8000)
678 else if (rate == 48000)
681 delta = ((48000 << 12) / rate) & 0x0000ffff;
685 /*---------------------------------------------------------------------------
686 snd_trident_spurious_threshold
688 Description: This routine converts rate in HZ to spurious threshold.
690 Paramters: trident - pointer to target device class for 4DWave.
691 rate - Real or Virtual channel number.
693 Returns: Delta value.
695 ---------------------------------------------------------------------------*/
696 unsigned int snd_trident_spurious_threshold(unsigned int rate, unsigned int period_size)
698 unsigned int res = (rate * period_size) / 48000;
706 /*---------------------------------------------------------------------------
707 snd_trident_control_mode
709 Description: This routine returns a control mode for a PCM channel.
711 Paramters: trident - pointer to target device class for 4DWave.
712 substream - PCM substream
714 Returns: Control value.
716 ---------------------------------------------------------------------------*/
717 unsigned int snd_trident_control_mode(snd_pcm_substream_t *substream)
720 snd_pcm_runtime_t *runtime = substream->runtime;
723 CTRL default: 8-bit (unsigned) mono, loop mode enabled
726 if (snd_pcm_format_width(runtime->format) == 16)
727 CTRL |= 0x00000008; // 16-bit data
728 if (snd_pcm_format_signed(runtime->format))
729 CTRL |= 0x00000002; // signed data
730 if (runtime->channels > 1)
731 CTRL |= 0x00000004; // stereo data
739 /*---------------------------------------------------------------------------
742 Description: Device I/O control handler for playback/capture parameters.
744 Paramters: substream - PCM substream class
745 cmd - what ioctl message to process
746 arg - additional message infoarg
748 Returns: Error status
750 ---------------------------------------------------------------------------*/
752 static int snd_trident_ioctl(snd_pcm_substream_t * substream,
756 /* FIXME: it seems that with small periods the behaviour of
757 trident hardware is unpredictable and interrupt generator
759 return snd_pcm_lib_ioctl(substream, cmd, arg);
762 /*---------------------------------------------------------------------------
763 snd_trident_allocate_pcm_mem
765 Description: Allocate PCM ring buffer for given substream
767 Parameters: substream - PCM substream class
768 hw_params - hardware parameters
770 Returns: Error status
772 ---------------------------------------------------------------------------*/
774 int snd_trident_allocate_pcm_mem(snd_pcm_substream_t * substream,
775 snd_pcm_hw_params_t * hw_params)
777 trident_t *trident = snd_pcm_substream_chip(substream);
778 snd_pcm_runtime_t *runtime = substream->runtime;
779 snd_trident_voice_t *voice = (snd_trident_voice_t *) runtime->private_data;
782 if ((err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params))) < 0)
784 if (trident->tlb.entries) {
785 if (err > 0) { /* change */
787 snd_trident_free_pages(trident, voice->memblk);
788 voice->memblk = snd_trident_alloc_pages(trident, substream);
789 if (voice->memblk == NULL)
796 /*---------------------------------------------------------------------------
797 snd_trident_allocate_evoice
799 Description: Allocate extra voice as interrupt generator
801 Parameters: substream - PCM substream class
802 hw_params - hardware parameters
804 Returns: Error status
806 ---------------------------------------------------------------------------*/
808 int snd_trident_allocate_evoice(snd_pcm_substream_t * substream,
809 snd_pcm_hw_params_t * hw_params)
811 trident_t *trident = snd_pcm_substream_chip(substream);
812 snd_pcm_runtime_t *runtime = substream->runtime;
813 snd_trident_voice_t *voice = (snd_trident_voice_t *) runtime->private_data;
814 snd_trident_voice_t *evoice = voice->extra;
816 /* voice management */
818 if (params_buffer_size(hw_params) / 2 != params_period_size(hw_params)) {
819 if (evoice == NULL) {
820 evoice = snd_trident_alloc_voice(trident, SNDRV_TRIDENT_VOICE_TYPE_PCM, 0, 0);
823 voice->extra = evoice;
824 evoice->substream = substream;
827 if (evoice != NULL) {
828 snd_trident_free_voice(trident, evoice);
829 voice->extra = evoice = NULL;
836 /*---------------------------------------------------------------------------
837 snd_trident_hw_params
839 Description: Set the hardware parameters for the playback device.
841 Parameters: substream - PCM substream class
842 hw_params - hardware parameters
844 Returns: Error status
846 ---------------------------------------------------------------------------*/
848 static int snd_trident_hw_params(snd_pcm_substream_t * substream,
849 snd_pcm_hw_params_t * hw_params)
853 err = snd_trident_allocate_pcm_mem(substream, hw_params);
855 err = snd_trident_allocate_evoice(substream, hw_params);
859 /*---------------------------------------------------------------------------
860 snd_trident_playback_hw_free
862 Description: Release the hardware resources for the playback device.
864 Parameters: substream - PCM substream class
866 Returns: Error status
868 ---------------------------------------------------------------------------*/
870 static int snd_trident_hw_free(snd_pcm_substream_t * substream)
872 trident_t *trident = snd_pcm_substream_chip(substream);
873 snd_pcm_runtime_t *runtime = substream->runtime;
874 snd_trident_voice_t *voice = (snd_trident_voice_t *) runtime->private_data;
875 snd_trident_voice_t *evoice = voice ? voice->extra : NULL;
877 if (trident->tlb.entries) {
878 if (voice && voice->memblk) {
879 snd_trident_free_pages(trident, voice->memblk);
880 voice->memblk = NULL;
883 snd_pcm_lib_free_pages(substream);
884 if (evoice != NULL) {
885 snd_trident_free_voice(trident, evoice);
891 /*---------------------------------------------------------------------------
892 snd_trident_playback_prepare
894 Description: Prepare playback device for playback.
896 Parameters: substream - PCM substream class
898 Returns: Error status
900 ---------------------------------------------------------------------------*/
902 static int snd_trident_playback_prepare(snd_pcm_substream_t * substream)
904 trident_t *trident = snd_pcm_substream_chip(substream);
905 snd_pcm_runtime_t *runtime = substream->runtime;
906 snd_trident_voice_t *voice = (snd_trident_voice_t *) runtime->private_data;
907 snd_trident_voice_t *evoice = voice->extra;
908 snd_trident_pcm_mixer_t *mix = &trident->pcm_mixer[substream->number];
910 spin_lock(&trident->reg_lock);
912 /* set delta (rate) value */
913 voice->Delta = snd_trident_convert_rate(runtime->rate);
914 voice->spurious_threshold = snd_trident_spurious_threshold(runtime->rate, runtime->period_size);
916 /* set Loop Begin Address */
918 voice->LBA = voice->memblk->offset;
920 voice->LBA = runtime->dma_addr;
923 voice->ESO = runtime->buffer_size - 1; /* in samples */
924 voice->CTRL = snd_trident_control_mode(substream);
930 voice->Vol = mix->vol;
931 voice->RVol = mix->rvol;
932 voice->CVol = mix->cvol;
933 voice->Pan = mix->pan;
934 voice->Attribute = 0;
936 voice->Attribute = (1<<(30-16))|(2<<(26-16))|
937 (0<<(24-16))|(0x1f<<(19-16));
939 voice->Attribute = 0;
942 snd_trident_write_voice_regs(trident, voice);
944 if (evoice != NULL) {
945 evoice->Delta = voice->Delta;
946 evoice->spurious_threshold = voice->spurious_threshold;
947 evoice->LBA = voice->LBA;
949 evoice->ESO = (runtime->period_size * 2) + 4 - 1; /* in samples */
950 evoice->CTRL = voice->CTRL;
952 evoice->GVSel = trident->device == TRIDENT_DEVICE_ID_SI7018 ? 0 : 1;
956 evoice->Vol = 0x3ff; /* mute */
957 evoice->RVol = evoice->CVol = 0x7f; /* mute */
958 evoice->Pan = 0x7f; /* mute */
960 evoice->Attribute = (1<<(30-16))|(2<<(26-16))|
961 (0<<(24-16))|(0x1f<<(19-16));
963 evoice->Attribute = 0;
965 snd_trident_write_voice_regs(trident, evoice);
967 evoice->isync_mark = runtime->period_size;
968 evoice->ESO = (runtime->period_size * 2) - 1;
971 spin_unlock(&trident->reg_lock);
976 /*---------------------------------------------------------------------------
977 snd_trident_capture_hw_params
979 Description: Set the hardware parameters for the capture device.
981 Parameters: substream - PCM substream class
982 hw_params - hardware parameters
984 Returns: Error status
986 ---------------------------------------------------------------------------*/
988 static int snd_trident_capture_hw_params(snd_pcm_substream_t * substream,
989 snd_pcm_hw_params_t * hw_params)
991 return snd_trident_allocate_pcm_mem(substream, hw_params);
994 /*---------------------------------------------------------------------------
995 snd_trident_capture_prepare
997 Description: Prepare capture device for playback.
999 Parameters: substream - PCM substream class
1001 Returns: Error status
1003 ---------------------------------------------------------------------------*/
1005 static int snd_trident_capture_prepare(snd_pcm_substream_t * substream)
1007 trident_t *trident = snd_pcm_substream_chip(substream);
1008 snd_pcm_runtime_t *runtime = substream->runtime;
1009 snd_trident_voice_t *voice = (snd_trident_voice_t *) runtime->private_data;
1010 unsigned int val, ESO_bytes;
1012 spin_lock(&trident->reg_lock);
1014 // Initilize the channel and set channel Mode
1015 outb(0, TRID_REG(trident, LEGACY_DMAR15));
1017 // Set DMA channel operation mode register
1018 outb(0x54, TRID_REG(trident, LEGACY_DMAR11));
1020 // Set channel buffer Address, DMAR0 expects contiguous PCI memory area
1021 voice->LBA = runtime->dma_addr;
1022 outl(voice->LBA, TRID_REG(trident, LEGACY_DMAR0));
1024 voice->LBA = voice->memblk->offset;
1027 ESO_bytes = snd_pcm_lib_buffer_bytes(substream) - 1;
1028 outb((ESO_bytes & 0x00ff0000) >> 16, TRID_REG(trident, LEGACY_DMAR6));
1029 outw((ESO_bytes & 0x0000ffff), TRID_REG(trident, LEGACY_DMAR4));
1032 // Set channel sample rate, 4.12 format
1033 val = (((unsigned int) 48000L << 12) + (runtime->rate/2)) / runtime->rate;
1034 outw(val, TRID_REG(trident, T4D_SBDELTA_DELTA_R));
1036 // Set channel interrupt blk length
1037 if (snd_pcm_format_width(runtime->format) == 16) {
1038 val = (unsigned short) ((ESO_bytes >> 1) - 1);
1040 val = (unsigned short) (ESO_bytes - 1);
1043 outl((val << 16) | val, TRID_REG(trident, T4D_SBBL_SBCL));
1045 // Right now, set format and start to run captureing,
1046 // continuous run loop enable.
1047 trident->bDMAStart = 0x19; // 0001 1001b
1049 if (snd_pcm_format_width(runtime->format) == 16)
1050 trident->bDMAStart |= 0x80;
1051 if (snd_pcm_format_signed(runtime->format))
1052 trident->bDMAStart |= 0x20;
1053 if (runtime->channels > 1)
1054 trident->bDMAStart |= 0x40;
1056 // Prepare capture intr channel
1058 voice->Delta = snd_trident_convert_rate(runtime->rate);
1059 voice->spurious_threshold = snd_trident_spurious_threshold(runtime->rate, runtime->period_size);
1061 voice->isync_mark = runtime->period_size;
1062 voice->isync_max = runtime->buffer_size;
1064 // Set voice parameters
1066 voice->ESO = voice->isync_ESO = (runtime->period_size * 2) + 6 - 1;
1067 voice->CTRL = snd_trident_control_mode(substream);
1072 voice->Pan = 0x7f; /* mute */
1073 voice->Vol = 0x3ff; /* mute */
1077 voice->Attribute = 0;
1079 snd_trident_write_voice_regs(trident, voice);
1081 spin_unlock(&trident->reg_lock);
1085 /*---------------------------------------------------------------------------
1086 snd_trident_si7018_capture_hw_params
1088 Description: Set the hardware parameters for the capture device.
1090 Parameters: substream - PCM substream class
1091 hw_params - hardware parameters
1093 Returns: Error status
1095 ---------------------------------------------------------------------------*/
1097 static int snd_trident_si7018_capture_hw_params(snd_pcm_substream_t * substream,
1098 snd_pcm_hw_params_t * hw_params)
1102 if ((err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params))) < 0)
1105 return snd_trident_allocate_evoice(substream, hw_params);
1108 /*---------------------------------------------------------------------------
1109 snd_trident_si7018_capture_hw_free
1111 Description: Release the hardware resources for the capture device.
1113 Parameters: substream - PCM substream class
1115 Returns: Error status
1117 ---------------------------------------------------------------------------*/
1119 static int snd_trident_si7018_capture_hw_free(snd_pcm_substream_t * substream)
1121 trident_t *trident = snd_pcm_substream_chip(substream);
1122 snd_pcm_runtime_t *runtime = substream->runtime;
1123 snd_trident_voice_t *voice = (snd_trident_voice_t *) runtime->private_data;
1124 snd_trident_voice_t *evoice = voice ? voice->extra : NULL;
1126 snd_pcm_lib_free_pages(substream);
1127 if (evoice != NULL) {
1128 snd_trident_free_voice(trident, evoice);
1129 voice->extra = NULL;
1134 /*---------------------------------------------------------------------------
1135 snd_trident_si7018_capture_prepare
1137 Description: Prepare capture device for playback.
1139 Parameters: substream - PCM substream class
1141 Returns: Error status
1143 ---------------------------------------------------------------------------*/
1145 static int snd_trident_si7018_capture_prepare(snd_pcm_substream_t * substream)
1147 trident_t *trident = snd_pcm_substream_chip(substream);
1148 snd_pcm_runtime_t *runtime = substream->runtime;
1149 snd_trident_voice_t *voice = (snd_trident_voice_t *) runtime->private_data;
1150 snd_trident_voice_t *evoice = voice->extra;
1152 spin_lock(&trident->reg_lock);
1154 voice->LBA = runtime->dma_addr;
1155 voice->Delta = snd_trident_convert_adc_rate(runtime->rate);
1156 voice->spurious_threshold = snd_trident_spurious_threshold(runtime->rate, runtime->period_size);
1158 // Set voice parameters
1160 voice->ESO = runtime->buffer_size - 1; /* in samples */
1161 voice->CTRL = snd_trident_control_mode(substream);
1166 voice->Pan = T4D_DEFAULT_PCM_PAN;
1172 voice->Attribute = (2 << (30-16)) |
1177 snd_trident_write_voice_regs(trident, voice);
1179 if (evoice != NULL) {
1180 evoice->Delta = snd_trident_convert_rate(runtime->rate);
1181 evoice->spurious_threshold = voice->spurious_threshold;
1182 evoice->LBA = voice->LBA;
1184 evoice->ESO = (runtime->period_size * 2) + 20 - 1; /* in samples, 20 means correction */
1185 evoice->CTRL = voice->CTRL;
1191 evoice->Vol = 0x3ff; /* mute */
1192 evoice->RVol = evoice->CVol = 0x7f; /* mute */
1193 evoice->Pan = 0x7f; /* mute */
1194 evoice->Attribute = 0;
1195 snd_trident_write_voice_regs(trident, evoice);
1197 evoice->isync_mark = runtime->period_size;
1198 evoice->ESO = (runtime->period_size * 2) - 1;
1201 spin_unlock(&trident->reg_lock);
1205 /*---------------------------------------------------------------------------
1206 snd_trident_foldback_prepare
1208 Description: Prepare foldback capture device for playback.
1210 Parameters: substream - PCM substream class
1212 Returns: Error status
1214 ---------------------------------------------------------------------------*/
1216 static int snd_trident_foldback_prepare(snd_pcm_substream_t * substream)
1218 trident_t *trident = snd_pcm_substream_chip(substream);
1219 snd_pcm_runtime_t *runtime = substream->runtime;
1220 snd_trident_voice_t *voice = (snd_trident_voice_t *) runtime->private_data;
1221 snd_trident_voice_t *evoice = voice->extra;
1223 spin_lock(&trident->reg_lock);
1225 /* Set channel buffer Address */
1227 voice->LBA = voice->memblk->offset;
1229 voice->LBA = runtime->dma_addr;
1231 /* set target ESO for channel */
1232 voice->ESO = runtime->buffer_size - 1; /* in samples */
1234 /* set sample rate */
1235 voice->Delta = 0x1000;
1236 voice->spurious_threshold = snd_trident_spurious_threshold(48000, runtime->period_size);
1239 voice->CTRL = snd_trident_control_mode(substream);
1244 voice->Pan = 0x7f; /* mute */
1245 voice->Vol = 0x3ff; /* mute */
1249 voice->Attribute = 0;
1251 /* set up capture channel */
1252 outb(((voice->number & 0x3f) | 0x80), TRID_REG(trident, T4D_RCI + voice->foldback_chan));
1254 snd_trident_write_voice_regs(trident, voice);
1256 if (evoice != NULL) {
1257 evoice->Delta = voice->Delta;
1258 evoice->spurious_threshold = voice->spurious_threshold;
1259 evoice->LBA = voice->LBA;
1261 evoice->ESO = (runtime->period_size * 2) + 4 - 1; /* in samples */
1262 evoice->CTRL = voice->CTRL;
1264 evoice->GVSel = trident->device == TRIDENT_DEVICE_ID_SI7018 ? 0 : 1;
1268 evoice->Vol = 0x3ff; /* mute */
1269 evoice->RVol = evoice->CVol = 0x7f; /* mute */
1270 evoice->Pan = 0x7f; /* mute */
1271 evoice->Attribute = 0;
1272 snd_trident_write_voice_regs(trident, evoice);
1274 evoice->isync_mark = runtime->period_size;
1275 evoice->ESO = (runtime->period_size * 2) - 1;
1278 spin_unlock(&trident->reg_lock);
1282 /*---------------------------------------------------------------------------
1283 snd_trident_spdif_hw_params
1285 Description: Set the hardware parameters for the spdif device.
1287 Parameters: substream - PCM substream class
1288 hw_params - hardware parameters
1290 Returns: Error status
1292 ---------------------------------------------------------------------------*/
1294 static int snd_trident_spdif_hw_params(snd_pcm_substream_t * substream,
1295 snd_pcm_hw_params_t * hw_params)
1297 trident_t *trident = snd_pcm_substream_chip(substream);
1298 unsigned int old_bits = 0, change = 0;
1301 err = snd_trident_allocate_pcm_mem(substream, hw_params);
1305 if (trident->device == TRIDENT_DEVICE_ID_SI7018) {
1306 err = snd_trident_allocate_evoice(substream, hw_params);
1311 /* prepare SPDIF channel */
1312 spin_lock_irq(&trident->reg_lock);
1313 old_bits = trident->spdif_pcm_bits;
1314 if (old_bits & IEC958_AES0_PROFESSIONAL)
1315 trident->spdif_pcm_bits &= ~IEC958_AES0_PRO_FS;
1317 trident->spdif_pcm_bits &= ~(IEC958_AES3_CON_FS << 24);
1318 if (params_rate(hw_params) >= 48000) {
1319 trident->spdif_pcm_ctrl = 0x3c; // 48000 Hz
1320 trident->spdif_pcm_bits |=
1321 trident->spdif_bits & IEC958_AES0_PROFESSIONAL ?
1322 IEC958_AES0_PRO_FS_48000 :
1323 (IEC958_AES3_CON_FS_48000 << 24);
1325 else if (params_rate(hw_params) >= 44100) {
1326 trident->spdif_pcm_ctrl = 0x3e; // 44100 Hz
1327 trident->spdif_pcm_bits |=
1328 trident->spdif_bits & IEC958_AES0_PROFESSIONAL ?
1329 IEC958_AES0_PRO_FS_44100 :
1330 (IEC958_AES3_CON_FS_44100 << 24);
1333 trident->spdif_pcm_ctrl = 0x3d; // 32000 Hz
1334 trident->spdif_pcm_bits |=
1335 trident->spdif_bits & IEC958_AES0_PROFESSIONAL ?
1336 IEC958_AES0_PRO_FS_32000 :
1337 (IEC958_AES3_CON_FS_32000 << 24);
1339 change = old_bits != trident->spdif_pcm_bits;
1340 spin_unlock_irq(&trident->reg_lock);
1343 snd_ctl_notify(trident->card, SNDRV_CTL_EVENT_MASK_VALUE, &trident->spdif_pcm_ctl->id);
1348 /*---------------------------------------------------------------------------
1349 snd_trident_spdif_prepare
1351 Description: Prepare SPDIF device for playback.
1353 Parameters: substream - PCM substream class
1355 Returns: Error status
1357 ---------------------------------------------------------------------------*/
1359 static int snd_trident_spdif_prepare(snd_pcm_substream_t * substream)
1361 trident_t *trident = snd_pcm_substream_chip(substream);
1362 snd_pcm_runtime_t *runtime = substream->runtime;
1363 snd_trident_voice_t *voice = (snd_trident_voice_t *) runtime->private_data;
1364 snd_trident_voice_t *evoice = voice->extra;
1365 snd_trident_pcm_mixer_t *mix = &trident->pcm_mixer[substream->number];
1366 unsigned int RESO, LBAO;
1369 spin_lock(&trident->reg_lock);
1371 if (trident->device != TRIDENT_DEVICE_ID_SI7018) {
1373 /* set delta (rate) value */
1374 voice->Delta = snd_trident_convert_rate(runtime->rate);
1375 voice->spurious_threshold = snd_trident_spurious_threshold(runtime->rate, runtime->period_size);
1377 /* set Loop Back Address */
1378 LBAO = runtime->dma_addr;
1380 voice->LBA = voice->memblk->offset;
1386 voice->isync_mark = runtime->period_size;
1387 voice->isync_max = runtime->buffer_size;
1389 /* set target ESO for channel */
1390 RESO = runtime->buffer_size - 1;
1391 voice->ESO = voice->isync_ESO = (runtime->period_size * 2) + 6 - 1;
1394 voice->CTRL = snd_trident_control_mode(substream);
1406 voice->Attribute = 0;
1408 /* prepare surrogate IRQ channel */
1409 snd_trident_write_voice_regs(trident, voice);
1411 outw((RESO & 0xffff), TRID_REG(trident, NX_SPESO));
1412 outb((RESO >> 16), TRID_REG(trident, NX_SPESO + 2));
1413 outl((LBAO & 0xfffffffc), TRID_REG(trident, NX_SPLBA));
1414 outw((voice->CSO & 0xffff), TRID_REG(trident, NX_SPCTRL_SPCSO));
1415 outb((voice->CSO >> 16), TRID_REG(trident, NX_SPCTRL_SPCSO + 2));
1417 /* set SPDIF setting */
1418 outb(trident->spdif_pcm_ctrl, TRID_REG(trident, NX_SPCTRL_SPCSO + 3));
1419 outl(trident->spdif_pcm_bits, TRID_REG(trident, NX_SPCSTATUS));
1423 /* set delta (rate) value */
1424 voice->Delta = 0x800;
1425 voice->spurious_threshold = snd_trident_spurious_threshold(48000, runtime->period_size);
1427 /* set Loop Begin Address */
1429 voice->LBA = voice->memblk->offset;
1431 voice->LBA = runtime->dma_addr;
1434 voice->ESO = runtime->buffer_size - 1; /* in samples */
1435 voice->CTRL = snd_trident_control_mode(substream);
1441 voice->Vol = mix->vol;
1442 voice->RVol = mix->rvol;
1443 voice->CVol = mix->cvol;
1444 voice->Pan = mix->pan;
1445 voice->Attribute = (1<<(30-16))|(7<<(26-16))|
1446 (0<<(24-16))|(0<<(19-16));
1448 snd_trident_write_voice_regs(trident, voice);
1450 if (evoice != NULL) {
1451 evoice->Delta = voice->Delta;
1452 evoice->spurious_threshold = voice->spurious_threshold;
1453 evoice->LBA = voice->LBA;
1455 evoice->ESO = (runtime->period_size * 2) + 4 - 1; /* in samples */
1456 evoice->CTRL = voice->CTRL;
1458 evoice->GVSel = trident->device == TRIDENT_DEVICE_ID_SI7018 ? 0 : 1;
1462 evoice->Vol = 0x3ff; /* mute */
1463 evoice->RVol = evoice->CVol = 0x7f; /* mute */
1464 evoice->Pan = 0x7f; /* mute */
1465 evoice->Attribute = 0;
1466 snd_trident_write_voice_regs(trident, evoice);
1468 evoice->isync_mark = runtime->period_size;
1469 evoice->ESO = (runtime->period_size * 2) - 1;
1472 outl(trident->spdif_pcm_bits, TRID_REG(trident, SI_SPDIF_CS));
1473 temp = inl(TRID_REG(trident, T4D_LFO_GC_CIR));
1475 outl(temp, TRID_REG(trident, T4D_LFO_GC_CIR));
1476 temp = inl(TRID_REG(trident, SI_SERIAL_INTF_CTRL));
1478 outl(temp, TRID_REG(trident, SI_SERIAL_INTF_CTRL));
1481 spin_unlock(&trident->reg_lock);
1486 /*---------------------------------------------------------------------------
1489 Description: Start/stop devices
1491 Parameters: substream - PCM substream class
1492 cmd - trigger command (STOP, GO)
1494 Returns: Error status
1496 ---------------------------------------------------------------------------*/
1498 static int snd_trident_trigger(snd_pcm_substream_t *substream,
1502 trident_t *trident = snd_pcm_substream_chip(substream);
1503 struct list_head *pos;
1504 snd_pcm_substream_t *s;
1505 unsigned int what, whati, capture_flag, spdif_flag;
1506 snd_trident_voice_t *voice, *evoice;
1507 unsigned int val, go;
1510 case SNDRV_PCM_TRIGGER_START:
1511 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
1512 case SNDRV_PCM_TRIGGER_RESUME:
1515 case SNDRV_PCM_TRIGGER_STOP:
1516 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
1517 case SNDRV_PCM_TRIGGER_SUSPEND:
1523 what = whati = capture_flag = spdif_flag = 0;
1524 spin_lock(&trident->reg_lock);
1525 val = inl(TRID_REG(trident, T4D_STIMER)) & 0x00ffffff;
1526 snd_pcm_group_for_each(pos, substream) {
1527 s = snd_pcm_group_substream_entry(pos);
1528 if ((trident_t *) _snd_pcm_chip(s->pcm) == trident) {
1529 voice = (snd_trident_voice_t *) s->runtime->private_data;
1530 evoice = voice->extra;
1531 what |= 1 << (voice->number & 0x1f);
1532 if (evoice == NULL) {
1533 whati |= 1 << (voice->number & 0x1f);
1535 what |= 1 << (evoice->number & 0x1f);
1536 whati |= 1 << (evoice->number & 0x1f);
1538 evoice->stimer = val;
1542 voice->stimer = val;
1546 snd_pcm_trigger_done(s, substream);
1554 if (trident->device != TRIDENT_DEVICE_ID_SI7018) {
1555 outl(trident->spdif_pcm_bits, TRID_REG(trident, NX_SPCSTATUS));
1556 outb(trident->spdif_pcm_ctrl, TRID_REG(trident, NX_SPCTRL_SPCSO + 3));
1558 outl(trident->spdif_pcm_bits, TRID_REG(trident, SI_SPDIF_CS));
1559 val = inl(TRID_REG(trident, SI_SERIAL_INTF_CTRL)) | SPDIF_EN;
1560 outl(val, TRID_REG(trident, SI_SERIAL_INTF_CTRL));
1564 outl(what, TRID_REG(trident, T4D_STOP_B));
1565 val = inl(TRID_REG(trident, T4D_AINTEN_B));
1571 outl(val, TRID_REG(trident, T4D_AINTEN_B));
1573 outl(what, TRID_REG(trident, T4D_START_B));
1575 if (capture_flag && trident->device != TRIDENT_DEVICE_ID_SI7018)
1576 outb(trident->bDMAStart, TRID_REG(trident, T4D_SBCTRL_SBE2R_SBDD));
1578 if (capture_flag && trident->device != TRIDENT_DEVICE_ID_SI7018)
1579 outb(0x00, TRID_REG(trident, T4D_SBCTRL_SBE2R_SBDD));
1581 spin_unlock(&trident->reg_lock);
1585 /*---------------------------------------------------------------------------
1586 snd_trident_playback_pointer
1588 Description: This routine return the playback position
1590 Parameters: substream - PCM substream class
1592 Returns: position of buffer
1594 ---------------------------------------------------------------------------*/
1596 static snd_pcm_uframes_t snd_trident_playback_pointer(snd_pcm_substream_t * substream)
1598 trident_t *trident = snd_pcm_substream_chip(substream);
1599 snd_pcm_runtime_t *runtime = substream->runtime;
1600 snd_trident_voice_t *voice = (snd_trident_voice_t *) runtime->private_data;
1603 if (!voice->running)
1606 spin_lock(&trident->reg_lock);
1608 outb(voice->number, TRID_REG(trident, T4D_LFO_GC_CIR));
1610 if (trident->device != TRIDENT_DEVICE_ID_NX) {
1611 cso = inw(TRID_REG(trident, CH_DX_CSO_ALPHA_FMS + 2));
1612 } else { // ID_4DWAVE_NX
1613 cso = (unsigned int) inl(TRID_REG(trident, CH_NX_DELTA_CSO)) & 0x00ffffff;
1616 spin_unlock(&trident->reg_lock);
1618 if (cso >= runtime->buffer_size)
1624 /*---------------------------------------------------------------------------
1625 snd_trident_capture_pointer
1627 Description: This routine return the capture position
1629 Paramters: pcm1 - PCM device class
1631 Returns: position of buffer
1633 ---------------------------------------------------------------------------*/
1635 static snd_pcm_uframes_t snd_trident_capture_pointer(snd_pcm_substream_t * substream)
1637 trident_t *trident = snd_pcm_substream_chip(substream);
1638 snd_pcm_runtime_t *runtime = substream->runtime;
1639 snd_trident_voice_t *voice = (snd_trident_voice_t *) runtime->private_data;
1640 unsigned int result;
1642 if (!voice->running)
1645 result = inw(TRID_REG(trident, T4D_SBBL_SBCL));
1646 if (runtime->channels > 1)
1649 result = runtime->buffer_size - result;
1654 /*---------------------------------------------------------------------------
1655 snd_trident_spdif_pointer
1657 Description: This routine return the SPDIF playback position
1659 Parameters: substream - PCM substream class
1661 Returns: position of buffer
1663 ---------------------------------------------------------------------------*/
1665 static snd_pcm_uframes_t snd_trident_spdif_pointer(snd_pcm_substream_t * substream)
1667 trident_t *trident = snd_pcm_substream_chip(substream);
1668 snd_pcm_runtime_t *runtime = substream->runtime;
1669 snd_trident_voice_t *voice = (snd_trident_voice_t *) runtime->private_data;
1670 unsigned int result;
1672 if (!voice->running)
1675 result = inl(TRID_REG(trident, NX_SPCTRL_SPCSO)) & 0x00ffffff;
1681 * Playback support device description
1684 static snd_pcm_hardware_t snd_trident_playback =
1686 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
1687 SNDRV_PCM_INFO_BLOCK_TRANSFER |
1688 SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_SYNC_START |
1689 SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME),
1690 .formats = (SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE |
1691 SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U16_LE),
1692 .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,
1697 .buffer_bytes_max = (256*1024),
1698 .period_bytes_min = 64,
1699 .period_bytes_max = (256*1024),
1701 .periods_max = 1024,
1706 * Capture support device description
1709 static snd_pcm_hardware_t snd_trident_capture =
1711 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
1712 SNDRV_PCM_INFO_BLOCK_TRANSFER |
1713 SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_SYNC_START |
1714 SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME),
1715 .formats = (SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE |
1716 SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U16_LE),
1717 .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,
1722 .buffer_bytes_max = (128*1024),
1723 .period_bytes_min = 64,
1724 .period_bytes_max = (128*1024),
1726 .periods_max = 1024,
1731 * Foldback capture support device description
1734 static snd_pcm_hardware_t snd_trident_foldback =
1736 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
1737 SNDRV_PCM_INFO_BLOCK_TRANSFER |
1738 SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_SYNC_START |
1739 SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME),
1740 .formats = SNDRV_PCM_FMTBIT_S16_LE,
1741 .rates = SNDRV_PCM_RATE_48000,
1746 .buffer_bytes_max = (128*1024),
1747 .period_bytes_min = 64,
1748 .period_bytes_max = (128*1024),
1750 .periods_max = 1024,
1755 * SPDIF playback support device description
1758 static snd_pcm_hardware_t snd_trident_spdif =
1760 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
1761 SNDRV_PCM_INFO_BLOCK_TRANSFER |
1762 SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_SYNC_START |
1763 SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME),
1764 .formats = SNDRV_PCM_FMTBIT_S16_LE,
1765 .rates = (SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |
1766 SNDRV_PCM_RATE_48000),
1771 .buffer_bytes_max = (128*1024),
1772 .period_bytes_min = 64,
1773 .period_bytes_max = (128*1024),
1775 .periods_max = 1024,
1779 static snd_pcm_hardware_t snd_trident_spdif_7018 =
1781 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
1782 SNDRV_PCM_INFO_BLOCK_TRANSFER |
1783 SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_SYNC_START |
1784 SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME),
1785 .formats = SNDRV_PCM_FMTBIT_S16_LE,
1786 .rates = SNDRV_PCM_RATE_48000,
1791 .buffer_bytes_max = (128*1024),
1792 .period_bytes_min = 64,
1793 .period_bytes_max = (128*1024),
1795 .periods_max = 1024,
1799 static void snd_trident_pcm_free_substream(snd_pcm_runtime_t *runtime)
1801 snd_trident_voice_t *voice = (snd_trident_voice_t *) runtime->private_data;
1805 trident = voice->trident;
1806 snd_trident_free_voice(trident, voice);
1810 static int snd_trident_playback_open(snd_pcm_substream_t * substream)
1812 trident_t *trident = snd_pcm_substream_chip(substream);
1813 snd_pcm_runtime_t *runtime = substream->runtime;
1814 snd_trident_voice_t *voice;
1816 voice = snd_trident_alloc_voice(trident, SNDRV_TRIDENT_VOICE_TYPE_PCM, 0, 0);
1819 snd_trident_pcm_mixer_build(trident, voice, substream);
1820 voice->substream = substream;
1821 runtime->private_data = voice;
1822 runtime->private_free = snd_trident_pcm_free_substream;
1823 runtime->hw = snd_trident_playback;
1824 snd_pcm_set_sync(substream);
1825 snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_SIZE, 0, 64*1024);
1829 /*---------------------------------------------------------------------------
1830 snd_trident_playback_close
1832 Description: This routine will close the 4DWave playback device. For now
1833 we will simply free the dma transfer buffer.
1835 Parameters: substream - PCM substream class
1837 ---------------------------------------------------------------------------*/
1838 static int snd_trident_playback_close(snd_pcm_substream_t * substream)
1840 trident_t *trident = snd_pcm_substream_chip(substream);
1841 snd_pcm_runtime_t *runtime = substream->runtime;
1842 snd_trident_voice_t *voice = (snd_trident_voice_t *) runtime->private_data;
1844 snd_trident_pcm_mixer_free(trident, voice, substream);
1848 /*---------------------------------------------------------------------------
1849 snd_trident_spdif_open
1851 Description: This routine will open the 4DWave SPDIF device.
1853 Parameters: substream - PCM substream class
1855 Returns: status - success or failure flag
1857 ---------------------------------------------------------------------------*/
1859 static int snd_trident_spdif_open(snd_pcm_substream_t * substream)
1861 trident_t *trident = snd_pcm_substream_chip(substream);
1862 snd_trident_voice_t *voice;
1863 snd_pcm_runtime_t *runtime = substream->runtime;
1865 voice = snd_trident_alloc_voice(trident, SNDRV_TRIDENT_VOICE_TYPE_PCM, 0, 0);
1869 voice->substream = substream;
1870 spin_lock_irq(&trident->reg_lock);
1871 trident->spdif_pcm_bits = trident->spdif_bits;
1872 spin_unlock_irq(&trident->reg_lock);
1874 runtime->private_data = voice;
1875 runtime->private_free = snd_trident_pcm_free_substream;
1876 if (trident->device == TRIDENT_DEVICE_ID_SI7018) {
1877 runtime->hw = snd_trident_spdif;
1879 runtime->hw = snd_trident_spdif_7018;
1882 trident->spdif_pcm_ctl->vd[0].access &= ~SNDRV_CTL_ELEM_ACCESS_INACTIVE;
1883 snd_ctl_notify(trident->card, SNDRV_CTL_EVENT_MASK_VALUE |
1884 SNDRV_CTL_EVENT_MASK_INFO, &trident->spdif_pcm_ctl->id);
1886 snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_SIZE, 0, 64*1024);
1891 /*---------------------------------------------------------------------------
1892 snd_trident_spdif_close
1894 Description: This routine will close the 4DWave SPDIF device.
1896 Parameters: substream - PCM substream class
1898 ---------------------------------------------------------------------------*/
1900 static int snd_trident_spdif_close(snd_pcm_substream_t * substream)
1902 trident_t *trident = snd_pcm_substream_chip(substream);
1905 spin_lock_irq(&trident->reg_lock);
1906 // restore default SPDIF setting
1907 if (trident->device != TRIDENT_DEVICE_ID_SI7018) {
1908 outb(trident->spdif_ctrl, TRID_REG(trident, NX_SPCTRL_SPCSO + 3));
1909 outl(trident->spdif_bits, TRID_REG(trident, NX_SPCSTATUS));
1911 outl(trident->spdif_bits, TRID_REG(trident, SI_SPDIF_CS));
1912 temp = inl(TRID_REG(trident, SI_SERIAL_INTF_CTRL));
1913 if (trident->spdif_ctrl) {
1918 outl(temp, TRID_REG(trident, SI_SERIAL_INTF_CTRL));
1920 spin_unlock_irq(&trident->reg_lock);
1921 trident->spdif_pcm_ctl->vd[0].access |= SNDRV_CTL_ELEM_ACCESS_INACTIVE;
1922 snd_ctl_notify(trident->card, SNDRV_CTL_EVENT_MASK_VALUE |
1923 SNDRV_CTL_EVENT_MASK_INFO, &trident->spdif_pcm_ctl->id);
1927 /*---------------------------------------------------------------------------
1928 snd_trident_capture_open
1930 Description: This routine will open the 4DWave capture device.
1932 Parameters: substream - PCM substream class
1934 Returns: status - success or failure flag
1936 ---------------------------------------------------------------------------*/
1938 static int snd_trident_capture_open(snd_pcm_substream_t * substream)
1940 trident_t *trident = snd_pcm_substream_chip(substream);
1941 snd_trident_voice_t *voice;
1942 snd_pcm_runtime_t *runtime = substream->runtime;
1944 voice = snd_trident_alloc_voice(trident, SNDRV_TRIDENT_VOICE_TYPE_PCM, 0, 0);
1948 voice->substream = substream;
1949 runtime->private_data = voice;
1950 runtime->private_free = snd_trident_pcm_free_substream;
1951 runtime->hw = snd_trident_capture;
1952 snd_pcm_set_sync(substream);
1953 snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_SIZE, 0, 64*1024);
1957 /*---------------------------------------------------------------------------
1958 snd_trident_capture_close
1960 Description: This routine will close the 4DWave capture device. For now
1961 we will simply free the dma transfer buffer.
1963 Parameters: substream - PCM substream class
1965 ---------------------------------------------------------------------------*/
1966 static int snd_trident_capture_close(snd_pcm_substream_t * substream)
1971 /*---------------------------------------------------------------------------
1972 snd_trident_foldback_open
1974 Description: This routine will open the 4DWave foldback capture device.
1976 Parameters: substream - PCM substream class
1978 Returns: status - success or failure flag
1980 ---------------------------------------------------------------------------*/
1982 static int snd_trident_foldback_open(snd_pcm_substream_t * substream)
1984 trident_t *trident = snd_pcm_substream_chip(substream);
1985 snd_trident_voice_t *voice;
1986 snd_pcm_runtime_t *runtime = substream->runtime;
1988 voice = snd_trident_alloc_voice(trident, SNDRV_TRIDENT_VOICE_TYPE_PCM, 0, 0);
1991 voice->foldback_chan = substream->number;
1992 voice->substream = substream;
1993 runtime->private_data = voice;
1994 runtime->private_free = snd_trident_pcm_free_substream;
1995 runtime->hw = snd_trident_foldback;
1996 snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_SIZE, 0, 64*1024);
2000 /*---------------------------------------------------------------------------
2001 snd_trident_foldback_close
2003 Description: This routine will close the 4DWave foldback capture device.
2004 For now we will simply free the dma transfer buffer.
2006 Parameters: substream - PCM substream class
2008 ---------------------------------------------------------------------------*/
2009 static int snd_trident_foldback_close(snd_pcm_substream_t * substream)
2011 trident_t *trident = snd_pcm_substream_chip(substream);
2012 snd_trident_voice_t *voice;
2013 snd_pcm_runtime_t *runtime = substream->runtime;
2014 voice = (snd_trident_voice_t *) runtime->private_data;
2016 /* stop capture channel */
2017 spin_lock_irq(&trident->reg_lock);
2018 outb(0x00, TRID_REG(trident, T4D_RCI + voice->foldback_chan));
2019 spin_unlock_irq(&trident->reg_lock);
2023 /*---------------------------------------------------------------------------
2025 ---------------------------------------------------------------------------*/
2027 static snd_pcm_ops_t snd_trident_playback_ops = {
2028 .open = snd_trident_playback_open,
2029 .close = snd_trident_playback_close,
2030 .ioctl = snd_trident_ioctl,
2031 .hw_params = snd_trident_hw_params,
2032 .hw_free = snd_trident_hw_free,
2033 .prepare = snd_trident_playback_prepare,
2034 .trigger = snd_trident_trigger,
2035 .pointer = snd_trident_playback_pointer,
2038 static snd_pcm_ops_t snd_trident_nx_playback_ops = {
2039 .open = snd_trident_playback_open,
2040 .close = snd_trident_playback_close,
2041 .ioctl = snd_trident_ioctl,
2042 .hw_params = snd_trident_hw_params,
2043 .hw_free = snd_trident_hw_free,
2044 .prepare = snd_trident_playback_prepare,
2045 .trigger = snd_trident_trigger,
2046 .pointer = snd_trident_playback_pointer,
2047 .page = snd_pcm_sgbuf_ops_page,
2050 static snd_pcm_ops_t snd_trident_capture_ops = {
2051 .open = snd_trident_capture_open,
2052 .close = snd_trident_capture_close,
2053 .ioctl = snd_trident_ioctl,
2054 .hw_params = snd_trident_capture_hw_params,
2055 .hw_free = snd_trident_hw_free,
2056 .prepare = snd_trident_capture_prepare,
2057 .trigger = snd_trident_trigger,
2058 .pointer = snd_trident_capture_pointer,
2061 static snd_pcm_ops_t snd_trident_si7018_capture_ops = {
2062 .open = snd_trident_capture_open,
2063 .close = snd_trident_capture_close,
2064 .ioctl = snd_trident_ioctl,
2065 .hw_params = snd_trident_si7018_capture_hw_params,
2066 .hw_free = snd_trident_si7018_capture_hw_free,
2067 .prepare = snd_trident_si7018_capture_prepare,
2068 .trigger = snd_trident_trigger,
2069 .pointer = snd_trident_playback_pointer,
2072 static snd_pcm_ops_t snd_trident_foldback_ops = {
2073 .open = snd_trident_foldback_open,
2074 .close = snd_trident_foldback_close,
2075 .ioctl = snd_trident_ioctl,
2076 .hw_params = snd_trident_hw_params,
2077 .hw_free = snd_trident_hw_free,
2078 .prepare = snd_trident_foldback_prepare,
2079 .trigger = snd_trident_trigger,
2080 .pointer = snd_trident_playback_pointer,
2083 static snd_pcm_ops_t snd_trident_nx_foldback_ops = {
2084 .open = snd_trident_foldback_open,
2085 .close = snd_trident_foldback_close,
2086 .ioctl = snd_trident_ioctl,
2087 .hw_params = snd_trident_hw_params,
2088 .hw_free = snd_trident_hw_free,
2089 .prepare = snd_trident_foldback_prepare,
2090 .trigger = snd_trident_trigger,
2091 .pointer = snd_trident_playback_pointer,
2092 .page = snd_pcm_sgbuf_ops_page,
2095 static snd_pcm_ops_t snd_trident_spdif_ops = {
2096 .open = snd_trident_spdif_open,
2097 .close = snd_trident_spdif_close,
2098 .ioctl = snd_trident_ioctl,
2099 .hw_params = snd_trident_spdif_hw_params,
2100 .hw_free = snd_trident_hw_free,
2101 .prepare = snd_trident_spdif_prepare,
2102 .trigger = snd_trident_trigger,
2103 .pointer = snd_trident_spdif_pointer,
2106 static snd_pcm_ops_t snd_trident_spdif_7018_ops = {
2107 .open = snd_trident_spdif_open,
2108 .close = snd_trident_spdif_close,
2109 .ioctl = snd_trident_ioctl,
2110 .hw_params = snd_trident_spdif_hw_params,
2111 .hw_free = snd_trident_hw_free,
2112 .prepare = snd_trident_spdif_prepare,
2113 .trigger = snd_trident_trigger,
2114 .pointer = snd_trident_playback_pointer,
2117 /*---------------------------------------------------------------------------
2118 snd_trident_pcm_free
2120 Description: This routine release the 4DWave private data.
2122 Paramters: private_data - pointer to 4DWave device info.
2126 ---------------------------------------------------------------------------*/
2127 static void snd_trident_pcm_free(snd_pcm_t *pcm)
2129 trident_t *trident = snd_magic_cast(trident_t, pcm->private_data, return);
2130 trident->pcm = NULL;
2131 snd_pcm_lib_preallocate_free_for_all(pcm);
2134 static void snd_trident_foldback_pcm_free(snd_pcm_t *pcm)
2136 trident_t *trident = snd_magic_cast(trident_t, pcm->private_data, return);
2137 trident->foldback = NULL;
2138 snd_pcm_lib_preallocate_free_for_all(pcm);
2141 static void snd_trident_spdif_pcm_free(snd_pcm_t *pcm)
2143 trident_t *trident = snd_magic_cast(trident_t, pcm->private_data, return);
2144 trident->spdif = NULL;
2145 snd_pcm_lib_preallocate_free_for_all(pcm);
2148 /*---------------------------------------------------------------------------
2151 Description: This routine registers the 4DWave device for PCM support.
2153 Paramters: trident - pointer to target device class for 4DWave.
2157 ---------------------------------------------------------------------------*/
2159 int __devinit snd_trident_pcm(trident_t * trident, int device, snd_pcm_t ** rpcm)
2166 if ((err = snd_pcm_new(trident->card, "trident_dx_nx", device, trident->ChanPCM, 1, &pcm)) < 0)
2169 pcm->private_data = trident;
2170 pcm->private_free = snd_trident_pcm_free;
2172 if (trident->tlb.entries) {
2173 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_trident_nx_playback_ops);
2175 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_trident_playback_ops);
2177 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
2178 trident->device != TRIDENT_DEVICE_ID_SI7018 ?
2179 &snd_trident_capture_ops :
2180 &snd_trident_si7018_capture_ops);
2182 pcm->info_flags = 0;
2183 pcm->dev_subclass = SNDRV_PCM_SUBCLASS_GENERIC_MIX;
2184 strcpy(pcm->name, "Trident 4DWave");
2187 if (trident->tlb.entries) {
2188 snd_pcm_substream_t *substream;
2189 for (substream = pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream; substream; substream = substream->next)
2190 snd_pcm_lib_preallocate_pages(substream, SNDRV_DMA_TYPE_DEV_SG,
2191 snd_dma_pci_data(trident->pci),
2193 snd_pcm_lib_preallocate_pages(pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream,
2194 SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(trident->pci),
2197 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
2198 snd_dma_pci_data(trident->pci), 64*1024, 128*1024);
2206 /*---------------------------------------------------------------------------
2207 snd_trident_foldback_pcm
2209 Description: This routine registers the 4DWave device for foldback PCM support.
2211 Paramters: trident - pointer to target device class for 4DWave.
2215 ---------------------------------------------------------------------------*/
2217 int __devinit snd_trident_foldback_pcm(trident_t * trident, int device, snd_pcm_t ** rpcm)
2219 snd_pcm_t *foldback;
2222 snd_pcm_substream_t *substream;
2226 if (trident->device == TRIDENT_DEVICE_ID_NX)
2228 if ((err = snd_pcm_new(trident->card, "trident_dx_nx", device, 0, num_chan, &foldback)) < 0)
2231 foldback->private_data = trident;
2232 foldback->private_free = snd_trident_foldback_pcm_free;
2233 if (trident->tlb.entries)
2234 snd_pcm_set_ops(foldback, SNDRV_PCM_STREAM_CAPTURE, &snd_trident_nx_foldback_ops);
2236 snd_pcm_set_ops(foldback, SNDRV_PCM_STREAM_CAPTURE, &snd_trident_foldback_ops);
2237 foldback->info_flags = 0;
2238 strcpy(foldback->name, "Trident 4DWave");
2239 substream = foldback->streams[SNDRV_PCM_STREAM_CAPTURE].substream;
2240 strcpy(substream->name, "Front Mixer");
2241 substream = substream->next;
2242 strcpy(substream->name, "Reverb Mixer");
2243 substream = substream->next;
2244 strcpy(substream->name, "Chorus Mixer");
2245 if (num_chan == 4) {
2246 substream = substream->next;
2247 strcpy(substream->name, "Second AC'97 ADC");
2249 trident->foldback = foldback;
2251 if (trident->tlb.entries)
2252 snd_pcm_lib_preallocate_pages_for_all(foldback, SNDRV_DMA_TYPE_DEV_SG,
2253 snd_dma_pci_data(trident->pci), 0, 128*1024);
2255 snd_pcm_lib_preallocate_pages_for_all(foldback, SNDRV_DMA_TYPE_DEV,
2256 snd_dma_pci_data(trident->pci), 64*1024, 128*1024);
2263 /*---------------------------------------------------------------------------
2266 Description: This routine registers the 4DWave-NX device for SPDIF support.
2268 Paramters: trident - pointer to target device class for 4DWave-NX.
2272 ---------------------------------------------------------------------------*/
2274 int __devinit snd_trident_spdif_pcm(trident_t * trident, int device, snd_pcm_t ** rpcm)
2281 if ((err = snd_pcm_new(trident->card, "trident_dx_nx IEC958", device, 1, 0, &spdif)) < 0)
2284 spdif->private_data = trident;
2285 spdif->private_free = snd_trident_spdif_pcm_free;
2286 if (trident->device != TRIDENT_DEVICE_ID_SI7018) {
2287 snd_pcm_set_ops(spdif, SNDRV_PCM_STREAM_PLAYBACK, &snd_trident_spdif_ops);
2289 snd_pcm_set_ops(spdif, SNDRV_PCM_STREAM_PLAYBACK, &snd_trident_spdif_7018_ops);
2291 spdif->info_flags = 0;
2292 strcpy(spdif->name, "Trident 4DWave IEC958");
2293 trident->spdif = spdif;
2295 snd_pcm_lib_preallocate_pages_for_all(spdif, SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(trident->pci), 64*1024, 128*1024);
2307 /*---------------------------------------------------------------------------
2308 snd_trident_spdif_control
2310 Description: enable/disable S/PDIF out from ac97 mixer
2311 ---------------------------------------------------------------------------*/
2313 static int snd_trident_spdif_control_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
2315 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
2317 uinfo->value.integer.min = 0;
2318 uinfo->value.integer.max = 1;
2322 static int snd_trident_spdif_control_get(snd_kcontrol_t * kcontrol,
2323 snd_ctl_elem_value_t * ucontrol)
2325 trident_t *trident = snd_kcontrol_chip(kcontrol);
2326 unsigned long flags;
2329 spin_lock_irqsave(&trident->reg_lock, flags);
2330 val = trident->spdif_ctrl;
2331 ucontrol->value.integer.value[0] = val == kcontrol->private_value;
2332 spin_unlock_irqrestore(&trident->reg_lock, flags);
2336 static int snd_trident_spdif_control_put(snd_kcontrol_t * kcontrol,
2337 snd_ctl_elem_value_t * ucontrol)
2339 trident_t *trident = snd_kcontrol_chip(kcontrol);
2340 unsigned long flags;
2344 val = ucontrol->value.integer.value[0] ? (unsigned char) kcontrol->private_value : 0x00;
2345 spin_lock_irqsave(&trident->reg_lock, flags);
2346 /* S/PDIF C Channel bits 0-31 : 48khz, SCMS disabled */
2347 change = trident->spdif_ctrl != val;
2348 trident->spdif_ctrl = val;
2349 if (trident->device != TRIDENT_DEVICE_ID_SI7018) {
2350 if ((inb(TRID_REG(trident, NX_SPCTRL_SPCSO + 3)) & 0x10) == 0) {
2351 outl(trident->spdif_bits, TRID_REG(trident, NX_SPCSTATUS));
2352 outb(trident->spdif_ctrl, TRID_REG(trident, NX_SPCTRL_SPCSO + 3));
2355 if (trident->spdif == NULL) {
2357 outl(trident->spdif_bits, TRID_REG(trident, SI_SPDIF_CS));
2358 temp = inl(TRID_REG(trident, SI_SERIAL_INTF_CTRL)) & ~SPDIF_EN;
2361 outl(temp, TRID_REG(trident, SI_SERIAL_INTF_CTRL));
2364 spin_unlock_irqrestore(&trident->reg_lock, flags);
2368 static snd_kcontrol_new_t snd_trident_spdif_control __devinitdata =
2370 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2371 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,SWITCH),
2372 .info = snd_trident_spdif_control_info,
2373 .get = snd_trident_spdif_control_get,
2374 .put = snd_trident_spdif_control_put,
2375 .private_value = 0x28,
2378 /*---------------------------------------------------------------------------
2379 snd_trident_spdif_default
2381 Description: put/get the S/PDIF default settings
2382 ---------------------------------------------------------------------------*/
2384 static int snd_trident_spdif_default_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
2386 uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
2391 static int snd_trident_spdif_default_get(snd_kcontrol_t * kcontrol,
2392 snd_ctl_elem_value_t * ucontrol)
2394 trident_t *trident = snd_kcontrol_chip(kcontrol);
2395 unsigned long flags;
2397 spin_lock_irqsave(&trident->reg_lock, flags);
2398 ucontrol->value.iec958.status[0] = (trident->spdif_bits >> 0) & 0xff;
2399 ucontrol->value.iec958.status[1] = (trident->spdif_bits >> 8) & 0xff;
2400 ucontrol->value.iec958.status[2] = (trident->spdif_bits >> 16) & 0xff;
2401 ucontrol->value.iec958.status[3] = (trident->spdif_bits >> 24) & 0xff;
2402 spin_unlock_irqrestore(&trident->reg_lock, flags);
2406 static int snd_trident_spdif_default_put(snd_kcontrol_t * kcontrol,
2407 snd_ctl_elem_value_t * ucontrol)
2409 trident_t *trident = snd_kcontrol_chip(kcontrol);
2410 unsigned long flags;
2414 val = (ucontrol->value.iec958.status[0] << 0) |
2415 (ucontrol->value.iec958.status[1] << 8) |
2416 (ucontrol->value.iec958.status[2] << 16) |
2417 (ucontrol->value.iec958.status[3] << 24);
2418 spin_lock_irqsave(&trident->reg_lock, flags);
2419 change = trident->spdif_bits != val;
2420 trident->spdif_bits = val;
2421 if (trident->device != TRIDENT_DEVICE_ID_SI7018) {
2422 if ((inb(TRID_REG(trident, NX_SPCTRL_SPCSO + 3)) & 0x10) == 0)
2423 outl(trident->spdif_bits, TRID_REG(trident, NX_SPCSTATUS));
2425 if (trident->spdif == NULL)
2426 outl(trident->spdif_bits, TRID_REG(trident, SI_SPDIF_CS));
2428 spin_unlock_irqrestore(&trident->reg_lock, flags);
2432 static snd_kcontrol_new_t snd_trident_spdif_default __devinitdata =
2434 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
2435 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),
2436 .info = snd_trident_spdif_default_info,
2437 .get = snd_trident_spdif_default_get,
2438 .put = snd_trident_spdif_default_put
2441 /*---------------------------------------------------------------------------
2442 snd_trident_spdif_mask
2444 Description: put/get the S/PDIF mask
2445 ---------------------------------------------------------------------------*/
2447 static int snd_trident_spdif_mask_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
2449 uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
2454 static int snd_trident_spdif_mask_get(snd_kcontrol_t * kcontrol,
2455 snd_ctl_elem_value_t * ucontrol)
2457 ucontrol->value.iec958.status[0] = 0xff;
2458 ucontrol->value.iec958.status[1] = 0xff;
2459 ucontrol->value.iec958.status[2] = 0xff;
2460 ucontrol->value.iec958.status[3] = 0xff;
2464 static snd_kcontrol_new_t snd_trident_spdif_mask __devinitdata =
2466 .access = SNDRV_CTL_ELEM_ACCESS_READ,
2467 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
2468 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,MASK),
2469 .info = snd_trident_spdif_mask_info,
2470 .get = snd_trident_spdif_mask_get,
2473 /*---------------------------------------------------------------------------
2474 snd_trident_spdif_stream
2476 Description: put/get the S/PDIF stream settings
2477 ---------------------------------------------------------------------------*/
2479 static int snd_trident_spdif_stream_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
2481 uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
2486 static int snd_trident_spdif_stream_get(snd_kcontrol_t * kcontrol,
2487 snd_ctl_elem_value_t * ucontrol)
2489 trident_t *trident = snd_kcontrol_chip(kcontrol);
2490 unsigned long flags;
2492 spin_lock_irqsave(&trident->reg_lock, flags);
2493 ucontrol->value.iec958.status[0] = (trident->spdif_pcm_bits >> 0) & 0xff;
2494 ucontrol->value.iec958.status[1] = (trident->spdif_pcm_bits >> 8) & 0xff;
2495 ucontrol->value.iec958.status[2] = (trident->spdif_pcm_bits >> 16) & 0xff;
2496 ucontrol->value.iec958.status[3] = (trident->spdif_pcm_bits >> 24) & 0xff;
2497 spin_unlock_irqrestore(&trident->reg_lock, flags);
2501 static int snd_trident_spdif_stream_put(snd_kcontrol_t * kcontrol,
2502 snd_ctl_elem_value_t * ucontrol)
2504 trident_t *trident = snd_kcontrol_chip(kcontrol);
2505 unsigned long flags;
2509 val = (ucontrol->value.iec958.status[0] << 0) |
2510 (ucontrol->value.iec958.status[1] << 8) |
2511 (ucontrol->value.iec958.status[2] << 16) |
2512 (ucontrol->value.iec958.status[3] << 24);
2513 spin_lock_irqsave(&trident->reg_lock, flags);
2514 change = trident->spdif_pcm_bits != val;
2515 trident->spdif_pcm_bits = val;
2516 if (trident->spdif != NULL) {
2517 if (trident->device != TRIDENT_DEVICE_ID_SI7018) {
2518 outl(trident->spdif_pcm_bits, TRID_REG(trident, NX_SPCSTATUS));
2520 outl(trident->spdif_bits, TRID_REG(trident, SI_SPDIF_CS));
2523 spin_unlock_irqrestore(&trident->reg_lock, flags);
2527 static snd_kcontrol_new_t snd_trident_spdif_stream __devinitdata =
2529 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE,
2530 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
2531 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,PCM_STREAM),
2532 .info = snd_trident_spdif_stream_info,
2533 .get = snd_trident_spdif_stream_get,
2534 .put = snd_trident_spdif_stream_put
2537 /*---------------------------------------------------------------------------
2538 snd_trident_ac97_control
2540 Description: enable/disable rear path for ac97
2541 ---------------------------------------------------------------------------*/
2543 static int snd_trident_ac97_control_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
2545 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
2547 uinfo->value.integer.min = 0;
2548 uinfo->value.integer.max = 1;
2552 static int snd_trident_ac97_control_get(snd_kcontrol_t * kcontrol,
2553 snd_ctl_elem_value_t * ucontrol)
2555 trident_t *trident = snd_kcontrol_chip(kcontrol);
2556 unsigned long flags;
2559 spin_lock_irqsave(&trident->reg_lock, flags);
2560 val = trident->ac97_ctrl = inl(TRID_REG(trident, NX_ACR0_AC97_COM_STAT));
2561 ucontrol->value.integer.value[0] = (val & (1 << kcontrol->private_value)) ? 1 : 0;
2562 spin_unlock_irqrestore(&trident->reg_lock, flags);
2566 static int snd_trident_ac97_control_put(snd_kcontrol_t * kcontrol,
2567 snd_ctl_elem_value_t * ucontrol)
2569 trident_t *trident = snd_kcontrol_chip(kcontrol);
2570 unsigned long flags;
2574 spin_lock_irqsave(&trident->reg_lock, flags);
2575 val = trident->ac97_ctrl = inl(TRID_REG(trident, NX_ACR0_AC97_COM_STAT));
2576 val &= ~(1 << kcontrol->private_value);
2577 if (ucontrol->value.integer.value[0])
2578 val |= 1 << kcontrol->private_value;
2579 change = val != trident->ac97_ctrl;
2580 trident->ac97_ctrl = val;
2581 outl(trident->ac97_ctrl = val, TRID_REG(trident, NX_ACR0_AC97_COM_STAT));
2582 spin_unlock_irqrestore(&trident->reg_lock, flags);
2586 static snd_kcontrol_new_t snd_trident_ac97_rear_control __devinitdata =
2588 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2589 .name = "Rear Path",
2590 .info = snd_trident_ac97_control_info,
2591 .get = snd_trident_ac97_control_get,
2592 .put = snd_trident_ac97_control_put,
2596 /*---------------------------------------------------------------------------
2597 snd_trident_vol_control
2599 Description: wave & music volume control
2600 ---------------------------------------------------------------------------*/
2602 static int snd_trident_vol_control_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
2604 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
2606 uinfo->value.integer.min = 0;
2607 uinfo->value.integer.max = 255;
2611 static int snd_trident_vol_control_get(snd_kcontrol_t * kcontrol,
2612 snd_ctl_elem_value_t * ucontrol)
2614 trident_t *trident = snd_kcontrol_chip(kcontrol);
2617 val = trident->musicvol_wavevol;
2618 ucontrol->value.integer.value[0] = 255 - ((val >> kcontrol->private_value) & 0xff);
2619 ucontrol->value.integer.value[1] = 255 - ((val >> (kcontrol->private_value + 8)) & 0xff);
2623 static int snd_trident_vol_control_put(snd_kcontrol_t * kcontrol,
2624 snd_ctl_elem_value_t * ucontrol)
2626 unsigned long flags;
2627 trident_t *trident = snd_kcontrol_chip(kcontrol);
2631 spin_lock_irqsave(&trident->reg_lock, flags);
2632 val = trident->musicvol_wavevol;
2633 val &= ~(0xffff << kcontrol->private_value);
2634 val |= ((255 - (ucontrol->value.integer.value[0] & 0xff)) |
2635 ((255 - (ucontrol->value.integer.value[1] & 0xff)) << 8)) << kcontrol->private_value;
2636 change = val != trident->musicvol_wavevol;
2637 outl(trident->musicvol_wavevol = val, TRID_REG(trident, T4D_MUSICVOL_WAVEVOL));
2638 spin_unlock_irqrestore(&trident->reg_lock, flags);
2642 static snd_kcontrol_new_t snd_trident_vol_music_control __devinitdata =
2644 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2645 .name = "Music Playback Volume",
2646 .info = snd_trident_vol_control_info,
2647 .get = snd_trident_vol_control_get,
2648 .put = snd_trident_vol_control_put,
2649 .private_value = 16,
2652 static snd_kcontrol_new_t snd_trident_vol_wave_control __devinitdata =
2654 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2655 .name = "Wave Playback Volume",
2656 .info = snd_trident_vol_control_info,
2657 .get = snd_trident_vol_control_get,
2658 .put = snd_trident_vol_control_put,
2662 /*---------------------------------------------------------------------------
2663 snd_trident_pcm_vol_control
2665 Description: PCM front volume control
2666 ---------------------------------------------------------------------------*/
2668 static int snd_trident_pcm_vol_control_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
2670 trident_t *trident = snd_kcontrol_chip(kcontrol);
2672 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
2674 uinfo->value.integer.min = 0;
2675 uinfo->value.integer.max = 255;
2676 if (trident->device == TRIDENT_DEVICE_ID_SI7018)
2677 uinfo->value.integer.max = 1023;
2681 static int snd_trident_pcm_vol_control_get(snd_kcontrol_t * kcontrol,
2682 snd_ctl_elem_value_t * ucontrol)
2684 trident_t *trident = snd_kcontrol_chip(kcontrol);
2685 snd_trident_pcm_mixer_t *mix = &trident->pcm_mixer[snd_ctl_get_ioffnum(kcontrol, &ucontrol->id)];
2687 if (trident->device == TRIDENT_DEVICE_ID_SI7018) {
2688 ucontrol->value.integer.value[0] = 1023 - mix->vol;
2690 ucontrol->value.integer.value[0] = 255 - (mix->vol>>2);
2695 static int snd_trident_pcm_vol_control_put(snd_kcontrol_t * kcontrol,
2696 snd_ctl_elem_value_t * ucontrol)
2698 unsigned long flags;
2699 trident_t *trident = snd_kcontrol_chip(kcontrol);
2700 snd_trident_pcm_mixer_t *mix = &trident->pcm_mixer[snd_ctl_get_ioffnum(kcontrol, &ucontrol->id)];
2704 if (trident->device == TRIDENT_DEVICE_ID_SI7018) {
2705 val = 1023 - (ucontrol->value.integer.value[0] & 1023);
2707 val = (255 - (ucontrol->value.integer.value[0] & 255)) << 2;
2709 spin_lock_irqsave(&trident->reg_lock, flags);
2710 change = val != mix->vol;
2712 if (mix->voice != NULL)
2713 snd_trident_write_vol_reg(trident, mix->voice, val);
2714 spin_unlock_irqrestore(&trident->reg_lock, flags);
2718 static snd_kcontrol_new_t snd_trident_pcm_vol_control __devinitdata =
2720 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2721 .name = "PCM Front Playback Volume",
2722 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE,
2724 .info = snd_trident_pcm_vol_control_info,
2725 .get = snd_trident_pcm_vol_control_get,
2726 .put = snd_trident_pcm_vol_control_put,
2729 /*---------------------------------------------------------------------------
2730 snd_trident_pcm_pan_control
2732 Description: PCM front pan control
2733 ---------------------------------------------------------------------------*/
2735 static int snd_trident_pcm_pan_control_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
2737 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
2739 uinfo->value.integer.min = 0;
2740 uinfo->value.integer.max = 127;
2744 static int snd_trident_pcm_pan_control_get(snd_kcontrol_t * kcontrol,
2745 snd_ctl_elem_value_t * ucontrol)
2747 trident_t *trident = snd_kcontrol_chip(kcontrol);
2748 snd_trident_pcm_mixer_t *mix = &trident->pcm_mixer[snd_ctl_get_ioffnum(kcontrol, &ucontrol->id)];
2750 ucontrol->value.integer.value[0] = mix->pan;
2751 if (ucontrol->value.integer.value[0] & 0x40) {
2752 ucontrol->value.integer.value[0] = (0x3f - (ucontrol->value.integer.value[0] & 0x3f));
2754 ucontrol->value.integer.value[0] |= 0x40;
2759 static int snd_trident_pcm_pan_control_put(snd_kcontrol_t * kcontrol,
2760 snd_ctl_elem_value_t * ucontrol)
2762 unsigned long flags;
2763 trident_t *trident = snd_kcontrol_chip(kcontrol);
2764 snd_trident_pcm_mixer_t *mix = &trident->pcm_mixer[snd_ctl_get_ioffnum(kcontrol, &ucontrol->id)];
2768 if (ucontrol->value.integer.value[0] & 0x40)
2769 val = ucontrol->value.integer.value[0] & 0x3f;
2771 val = (0x3f - (ucontrol->value.integer.value[0] & 0x3f)) | 0x40;
2772 spin_lock_irqsave(&trident->reg_lock, flags);
2773 change = val != mix->pan;
2775 if (mix->voice != NULL)
2776 snd_trident_write_pan_reg(trident, mix->voice, val);
2777 spin_unlock_irqrestore(&trident->reg_lock, flags);
2781 static snd_kcontrol_new_t snd_trident_pcm_pan_control __devinitdata =
2783 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2784 .name = "PCM Pan Playback Control",
2785 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE,
2787 .info = snd_trident_pcm_pan_control_info,
2788 .get = snd_trident_pcm_pan_control_get,
2789 .put = snd_trident_pcm_pan_control_put,
2792 /*---------------------------------------------------------------------------
2793 snd_trident_pcm_rvol_control
2795 Description: PCM reverb volume control
2796 ---------------------------------------------------------------------------*/
2798 static int snd_trident_pcm_rvol_control_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
2800 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
2802 uinfo->value.integer.min = 0;
2803 uinfo->value.integer.max = 127;
2807 static int snd_trident_pcm_rvol_control_get(snd_kcontrol_t * kcontrol,
2808 snd_ctl_elem_value_t * ucontrol)
2810 trident_t *trident = snd_kcontrol_chip(kcontrol);
2811 snd_trident_pcm_mixer_t *mix = &trident->pcm_mixer[snd_ctl_get_ioffnum(kcontrol, &ucontrol->id)];
2813 ucontrol->value.integer.value[0] = 127 - mix->rvol;
2817 static int snd_trident_pcm_rvol_control_put(snd_kcontrol_t * kcontrol,
2818 snd_ctl_elem_value_t * ucontrol)
2820 unsigned long flags;
2821 trident_t *trident = snd_kcontrol_chip(kcontrol);
2822 snd_trident_pcm_mixer_t *mix = &trident->pcm_mixer[snd_ctl_get_ioffnum(kcontrol, &ucontrol->id)];
2826 val = 0x7f - (ucontrol->value.integer.value[0] & 0x7f);
2827 spin_lock_irqsave(&trident->reg_lock, flags);
2828 change = val != mix->rvol;
2830 if (mix->voice != NULL)
2831 snd_trident_write_rvol_reg(trident, mix->voice, val);
2832 spin_unlock_irqrestore(&trident->reg_lock, flags);
2836 static snd_kcontrol_new_t snd_trident_pcm_rvol_control __devinitdata =
2838 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2839 .name = "PCM Reverb Playback Volume",
2840 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE,
2842 .info = snd_trident_pcm_rvol_control_info,
2843 .get = snd_trident_pcm_rvol_control_get,
2844 .put = snd_trident_pcm_rvol_control_put,
2847 /*---------------------------------------------------------------------------
2848 snd_trident_pcm_cvol_control
2850 Description: PCM chorus volume control
2851 ---------------------------------------------------------------------------*/
2853 static int snd_trident_pcm_cvol_control_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
2855 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
2857 uinfo->value.integer.min = 0;
2858 uinfo->value.integer.max = 127;
2862 static int snd_trident_pcm_cvol_control_get(snd_kcontrol_t * kcontrol,
2863 snd_ctl_elem_value_t * ucontrol)
2865 trident_t *trident = snd_kcontrol_chip(kcontrol);
2866 snd_trident_pcm_mixer_t *mix = &trident->pcm_mixer[snd_ctl_get_ioffnum(kcontrol, &ucontrol->id)];
2868 ucontrol->value.integer.value[0] = 127 - mix->cvol;
2872 static int snd_trident_pcm_cvol_control_put(snd_kcontrol_t * kcontrol,
2873 snd_ctl_elem_value_t * ucontrol)
2875 unsigned long flags;
2876 trident_t *trident = snd_kcontrol_chip(kcontrol);
2877 snd_trident_pcm_mixer_t *mix = &trident->pcm_mixer[snd_ctl_get_ioffnum(kcontrol, &ucontrol->id)];
2881 val = 0x7f - (ucontrol->value.integer.value[0] & 0x7f);
2882 spin_lock_irqsave(&trident->reg_lock, flags);
2883 change = val != mix->cvol;
2885 if (mix->voice != NULL)
2886 snd_trident_write_cvol_reg(trident, mix->voice, val);
2887 spin_unlock_irqrestore(&trident->reg_lock, flags);
2891 static snd_kcontrol_new_t snd_trident_pcm_cvol_control __devinitdata =
2893 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2894 .name = "PCM Chorus Playback Volume",
2895 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE,
2897 .info = snd_trident_pcm_cvol_control_info,
2898 .get = snd_trident_pcm_cvol_control_get,
2899 .put = snd_trident_pcm_cvol_control_put,
2902 static void snd_trident_notify_pcm_change1(snd_card_t * card, snd_kcontrol_t *kctl, int num, int activate)
2904 snd_ctl_elem_id_t id;
2906 snd_runtime_check(kctl != NULL, return);
2908 kctl->vd[num].access &= ~SNDRV_CTL_ELEM_ACCESS_INACTIVE;
2910 kctl->vd[num].access |= SNDRV_CTL_ELEM_ACCESS_INACTIVE;
2911 snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE |
2912 SNDRV_CTL_EVENT_MASK_INFO,
2913 snd_ctl_build_ioff(&id, kctl, num));
2916 static void snd_trident_notify_pcm_change(trident_t *trident, snd_trident_pcm_mixer_t *tmix, int num, int activate)
2918 snd_trident_notify_pcm_change1(trident->card, trident->ctl_vol, num, activate);
2919 snd_trident_notify_pcm_change1(trident->card, trident->ctl_pan, num, activate);
2920 snd_trident_notify_pcm_change1(trident->card, trident->ctl_rvol, num, activate);
2921 snd_trident_notify_pcm_change1(trident->card, trident->ctl_cvol, num, activate);
2924 static int snd_trident_pcm_mixer_build(trident_t *trident, snd_trident_voice_t *voice, snd_pcm_substream_t *substream)
2926 snd_trident_pcm_mixer_t *tmix;
2928 snd_assert(trident != NULL && voice != NULL && substream != NULL, return -EINVAL);
2929 tmix = &trident->pcm_mixer[substream->number];
2930 tmix->voice = voice;
2931 tmix->vol = T4D_DEFAULT_PCM_VOL;
2932 tmix->pan = T4D_DEFAULT_PCM_PAN;
2933 tmix->rvol = T4D_DEFAULT_PCM_RVOL;
2934 tmix->cvol = T4D_DEFAULT_PCM_CVOL;
2935 snd_trident_notify_pcm_change(trident, tmix, substream->number, 1);
2939 static int snd_trident_pcm_mixer_free(trident_t *trident, snd_trident_voice_t *voice, snd_pcm_substream_t *substream)
2941 snd_trident_pcm_mixer_t *tmix;
2943 snd_assert(trident != NULL && substream != NULL, return -EINVAL);
2944 tmix = &trident->pcm_mixer[substream->number];
2946 snd_trident_notify_pcm_change(trident, tmix, substream->number, 0);
2950 /*---------------------------------------------------------------------------
2953 Description: This routine registers the 4DWave device for mixer support.
2955 Paramters: trident - pointer to target device class for 4DWave.
2959 ---------------------------------------------------------------------------*/
2961 static int __devinit snd_trident_mixer(trident_t * trident, int pcm_spdif_device)
2965 snd_card_t * card = trident->card;
2966 snd_kcontrol_t *kctl;
2967 snd_ctl_elem_value_t *uctl;
2968 int idx, err, retries = 2;
2970 uctl = (snd_ctl_elem_value_t *)snd_kcalloc(sizeof(*uctl), GFP_KERNEL);
2974 memset(&_bus, 0, sizeof(_bus));
2975 _bus.write = snd_trident_codec_write;
2976 _bus.read = snd_trident_codec_read;
2977 if ((err = snd_ac97_bus(trident->card, &_bus, &trident->ac97_bus)) < 0)
2980 memset(&_ac97, 0, sizeof(_ac97));
2981 _ac97.private_data = trident;
2982 trident->ac97_detect = 1;
2985 if ((err = snd_ac97_mixer(trident->ac97_bus, &_ac97, &trident->ac97)) < 0) {
2986 if (trident->device == TRIDENT_DEVICE_ID_SI7018) {
2987 if ((err = snd_trident_sis_reset(trident)) < 0)
2996 /* secondary codec? */
2997 if (trident->device == TRIDENT_DEVICE_ID_SI7018 &&
2998 (inl(TRID_REG(trident, SI_SERIAL_INTF_CTRL)) & SI_AC97_PRIMARY_READY) != 0) {
3000 err = snd_ac97_mixer(trident->ac97_bus, &_ac97, &trident->ac97_sec);
3002 snd_printk("SI7018: the secondary codec - invalid access\n");
3003 #if 0 // only for my testing purpose --jk
3006 err = snd_ac97_modem(trident->card, &_ac97, &mc97);
3008 snd_printk("snd_ac97_modem returned error %i\n", err);
3013 trident->ac97_detect = 0;
3015 if (trident->device != TRIDENT_DEVICE_ID_SI7018) {
3016 if ((err = snd_ctl_add(card, kctl = snd_ctl_new1(&snd_trident_vol_wave_control, trident))) < 0)
3018 kctl->put(kctl, uctl);
3019 if ((err = snd_ctl_add(card, kctl = snd_ctl_new1(&snd_trident_vol_music_control, trident))) < 0)
3021 kctl->put(kctl, uctl);
3022 outl(trident->musicvol_wavevol = 0x00000000, TRID_REG(trident, T4D_MUSICVOL_WAVEVOL));
3024 outl(trident->musicvol_wavevol = 0xffff0000, TRID_REG(trident, T4D_MUSICVOL_WAVEVOL));
3027 for (idx = 0; idx < 32; idx++) {
3028 snd_trident_pcm_mixer_t *tmix;
3030 tmix = &trident->pcm_mixer[idx];
3033 if ((trident->ctl_vol = snd_ctl_new1(&snd_trident_pcm_vol_control, trident)) == NULL)
3035 if ((err = snd_ctl_add(card, trident->ctl_vol)))
3038 if ((trident->ctl_pan = snd_ctl_new1(&snd_trident_pcm_pan_control, trident)) == NULL)
3040 if ((err = snd_ctl_add(card, trident->ctl_pan)))
3043 if ((trident->ctl_rvol = snd_ctl_new1(&snd_trident_pcm_rvol_control, trident)) == NULL)
3045 if ((err = snd_ctl_add(card, trident->ctl_rvol)))
3048 if ((trident->ctl_cvol = snd_ctl_new1(&snd_trident_pcm_cvol_control, trident)) == NULL)
3050 if ((err = snd_ctl_add(card, trident->ctl_cvol)))
3053 if (trident->device == TRIDENT_DEVICE_ID_NX) {
3054 if ((err = snd_ctl_add(card, kctl = snd_ctl_new1(&snd_trident_ac97_rear_control, trident))) < 0)
3056 kctl->put(kctl, uctl);
3058 if (trident->device == TRIDENT_DEVICE_ID_NX || trident->device == TRIDENT_DEVICE_ID_SI7018) {
3060 kctl = snd_ctl_new1(&snd_trident_spdif_control, trident);
3065 if (trident->ac97->ext_id & AC97_EI_SPDIF)
3067 if (trident->ac97_sec && (trident->ac97_sec->ext_id & AC97_EI_SPDIF))
3069 idx = kctl->id.index;
3070 if ((err = snd_ctl_add(card, kctl)) < 0)
3072 kctl->put(kctl, uctl);
3074 kctl = snd_ctl_new1(&snd_trident_spdif_default, trident);
3079 kctl->id.index = idx;
3080 kctl->id.device = pcm_spdif_device;
3081 if ((err = snd_ctl_add(card, kctl)) < 0)
3084 kctl = snd_ctl_new1(&snd_trident_spdif_mask, trident);
3089 kctl->id.index = idx;
3090 kctl->id.device = pcm_spdif_device;
3091 if ((err = snd_ctl_add(card, kctl)) < 0)
3094 kctl = snd_ctl_new1(&snd_trident_spdif_stream, trident);
3099 kctl->id.index = idx;
3100 kctl->id.device = pcm_spdif_device;
3101 if ((err = snd_ctl_add(card, kctl)) < 0)
3103 trident->spdif_pcm_ctl = kctl;
3119 * gameport interface
3122 #if defined(CONFIG_GAMEPORT) || (defined(MODULE) && defined(CONFIG_GAMEPORT_MODULE))
3124 typedef struct snd_trident_gameport {
3125 struct gameport info;
3127 } trident_gameport_t;
3129 static unsigned char snd_trident_gameport_read(struct gameport *gameport)
3131 trident_gameport_t *gp = (trident_gameport_t *)gameport;
3133 snd_assert(gp, return 0);
3134 chip = snd_magic_cast(trident_t, gp->chip, return 0);
3135 return inb(TRID_REG(chip, GAMEPORT_LEGACY));
3138 static void snd_trident_gameport_trigger(struct gameport *gameport)
3140 trident_gameport_t *gp = (trident_gameport_t *)gameport;
3142 snd_assert(gp, return);
3143 chip = snd_magic_cast(trident_t, gp->chip, return);
3144 outb(0xff, TRID_REG(chip, GAMEPORT_LEGACY));
3147 static int snd_trident_gameport_cooked_read(struct gameport *gameport, int *axes, int *buttons)
3149 trident_gameport_t *gp = (trident_gameport_t *)gameport;
3153 snd_assert(gp, return 0);
3154 chip = snd_magic_cast(trident_t, gp->chip, return 0);
3156 *buttons = (~inb(TRID_REG(chip, GAMEPORT_LEGACY)) >> 4) & 0xf;
3158 for (i = 0; i < 4; i++) {
3159 axes[i] = inw(TRID_REG(chip, GAMEPORT_AXES + i * 2));
3160 if (axes[i] == 0xffff) axes[i] = -1;
3166 static int snd_trident_gameport_open(struct gameport *gameport, int mode)
3168 trident_gameport_t *gp = (trident_gameport_t *)gameport;
3170 snd_assert(gp, return -1);
3171 chip = snd_magic_cast(trident_t, gp->chip, return -1);
3174 case GAMEPORT_MODE_COOKED:
3175 outb(GAMEPORT_MODE_ADC, TRID_REG(chip, GAMEPORT_GCR));
3176 set_current_state(TASK_UNINTERRUPTIBLE);
3177 schedule_timeout(1 + 20 * HZ / 1000); /* 20msec */
3179 case GAMEPORT_MODE_RAW:
3180 outb(0, TRID_REG(chip, GAMEPORT_GCR));
3187 void __devinit snd_trident_gameport(trident_t *chip)
3189 trident_gameport_t *gp;
3190 gp = kmalloc(sizeof(*gp), GFP_KERNEL);
3192 snd_printk("cannot allocate gameport area\n");
3195 memset(gp, 0, sizeof(*gp));
3198 gp->info.read = snd_trident_gameport_read;
3199 gp->info.trigger = snd_trident_gameport_trigger;
3200 gp->info.cooked_read = snd_trident_gameport_cooked_read;
3201 gp->info.open = snd_trident_gameport_open;
3202 chip->gameport = gp;
3204 gameport_register_port(&gp->info);
3208 void __devinit snd_trident_gameport(trident_t *chip)
3211 #endif /* CONFIG_GAMEPORT */
3216 inline static void do_delay(trident_t *chip)
3218 set_current_state(TASK_UNINTERRUPTIBLE);
3219 schedule_timeout(1);
3226 static int snd_trident_sis_reset(trident_t *trident)
3228 unsigned long end_time;
3232 r = trident->in_suspend ? 0 : 2; /* count of retries */
3234 pci_write_config_byte(trident->pci, 0x46, 0x04); /* SOFTWARE RESET */
3236 pci_write_config_byte(trident->pci, 0x46, 0x00);
3238 /* disable AC97 GPIO interrupt */
3239 outb(0x00, TRID_REG(trident, SI_AC97_GPIO));
3240 /* initialize serial interface, force cold reset */
3241 i = PCMOUT|SURROUT|CENTEROUT|LFEOUT|SECONDARY_ID|COLD_RESET;
3242 outl(i, TRID_REG(trident, SI_SERIAL_INTF_CTRL));
3244 /* remove cold reset */
3246 outl(i, TRID_REG(trident, SI_SERIAL_INTF_CTRL));
3248 /* wait, until the codec is ready */
3249 end_time = (jiffies + (HZ * 3) / 4) + 1;
3251 if ((inl(TRID_REG(trident, SI_SERIAL_INTF_CTRL)) & SI_AC97_PRIMARY_READY) != 0)
3254 } while (time_after_eq(end_time, jiffies));
3255 snd_printk("AC'97 codec ready error [0x%x]\n", inl(TRID_REG(trident, SI_SERIAL_INTF_CTRL)));
3257 end_time = jiffies + HZ;
3260 } while (time_after_eq(end_time, jiffies));
3261 goto __si7018_retry;
3264 /* wait for the second codec */
3266 if ((inl(TRID_REG(trident, SI_SERIAL_INTF_CTRL)) & SI_AC97_SECONDARY_READY) != 0)
3269 } while (time_after_eq(end_time, jiffies));
3270 /* enable 64 channel mode */
3271 outl(BANK_B_EN, TRID_REG(trident, T4D_LFO_GC_CIR));
3279 static void snd_trident_proc_read(snd_info_entry_t *entry,
3280 snd_info_buffer_t * buffer)
3282 trident_t *trident = snd_magic_cast(trident_t, entry->private_data, return);
3285 switch (trident->device) {
3286 case TRIDENT_DEVICE_ID_SI7018:
3287 s = "SiS 7018 Audio";
3289 case TRIDENT_DEVICE_ID_DX:
3290 s = "Trident 4DWave PCI DX";
3292 case TRIDENT_DEVICE_ID_NX:
3293 s = "Trident 4DWave PCI NX";
3298 snd_iprintf(buffer, "%s\n\n", s);
3299 snd_iprintf(buffer, "Spurious IRQs : %d\n", trident->spurious_irq_count);
3300 snd_iprintf(buffer, "Spurious IRQ dlta: %d\n", trident->spurious_irq_max_delta);
3301 if (trident->device == TRIDENT_DEVICE_ID_NX || trident->device == TRIDENT_DEVICE_ID_SI7018)
3302 snd_iprintf(buffer, "IEC958 Mixer Out : %s\n", trident->spdif_ctrl == 0x28 ? "on" : "off");
3303 if (trident->device == TRIDENT_DEVICE_ID_NX) {
3304 snd_iprintf(buffer, "Rear Speakers : %s\n", trident->ac97_ctrl & 0x00000010 ? "on" : "off");
3305 if (trident->tlb.entries) {
3306 snd_iprintf(buffer,"\nVirtual Memory\n");
3307 snd_iprintf(buffer, "Memory Maximum : %d\n", trident->tlb.memhdr->size);
3308 snd_iprintf(buffer, "Memory Used : %d\n", trident->tlb.memhdr->used);
3309 snd_iprintf(buffer, "Memory Free : %d\n", snd_util_mem_avail(trident->tlb.memhdr));
3312 #if defined(CONFIG_SND_SEQUENCER) || (defined(MODULE) && defined(CONFIG_SND_SEQUENCER_MODULE))
3313 snd_iprintf(buffer,"\nWavetable Synth\n");
3314 snd_iprintf(buffer, "Memory Maximum : %d\n", trident->synth.max_size);
3315 snd_iprintf(buffer, "Memory Used : %d\n", trident->synth.current_size);
3316 snd_iprintf(buffer, "Memory Free : %d\n", (trident->synth.max_size-trident->synth.current_size));
3320 static void __devinit snd_trident_proc_init(trident_t * trident)
3322 snd_info_entry_t *entry;
3323 const char *s = "trident";
3325 if (trident->device == TRIDENT_DEVICE_ID_SI7018)
3327 if (! snd_card_proc_new(trident->card, s, &entry))
3328 snd_info_set_text_ops(entry, trident, 1024, snd_trident_proc_read);
3331 static int snd_trident_dev_free(snd_device_t *device)
3333 trident_t *trident = snd_magic_cast(trident_t, device->device_data, return -ENXIO);
3334 return snd_trident_free(trident);
3337 /*---------------------------------------------------------------------------
3338 snd_trident_tlb_alloc
3340 Description: Allocate and set up the TLB page table on 4D NX.
3341 Each entry has 4 bytes (physical PCI address).
3343 Paramters: trident - pointer to target device class for 4DWave.
3345 Returns: 0 or negative error code
3347 ---------------------------------------------------------------------------*/
3349 static int __devinit snd_trident_tlb_alloc(trident_t *trident)
3353 /* TLB array must be aligned to 16kB !!! so we allocate
3354 32kB region and correct offset when necessary */
3356 if (snd_dma_alloc_pages(&trident->dma_dev, 2 * SNDRV_TRIDENT_MAX_PAGES * 4, &trident->tlb.buffer) < 0) {
3357 snd_printk(KERN_ERR "trident: unable to allocate TLB buffer\n");
3360 trident->tlb.entries = (unsigned int*)(((unsigned long)trident->tlb.buffer.area + SNDRV_TRIDENT_MAX_PAGES * 4 - 1) & ~(SNDRV_TRIDENT_MAX_PAGES * 4 - 1));
3361 trident->tlb.entries_dmaaddr = (trident->tlb.buffer.addr + SNDRV_TRIDENT_MAX_PAGES * 4 - 1) & ~(SNDRV_TRIDENT_MAX_PAGES * 4 - 1);
3362 /* allocate shadow TLB page table (virtual addresses) */
3363 trident->tlb.shadow_entries = (unsigned long *)vmalloc(SNDRV_TRIDENT_MAX_PAGES*sizeof(unsigned long));
3364 if (trident->tlb.shadow_entries == NULL) {
3365 snd_printk(KERN_ERR "trident: unable to allocate shadow TLB entries\n");
3368 /* allocate and setup silent page and initialise TLB entries */
3369 if (snd_dma_alloc_pages(&trident->dma_dev, SNDRV_TRIDENT_PAGE_SIZE, &trident->tlb.silent_page) < 0) {
3370 snd_printk(KERN_ERR "trident: unable to allocate silent page\n");
3373 memset(trident->tlb.silent_page.area, 0, SNDRV_TRIDENT_PAGE_SIZE);
3374 for (i = 0; i < SNDRV_TRIDENT_MAX_PAGES; i++) {
3375 trident->tlb.entries[i] = cpu_to_le32(trident->tlb.silent_page.addr & ~(SNDRV_TRIDENT_PAGE_SIZE-1));
3376 trident->tlb.shadow_entries[i] = (unsigned long)trident->tlb.silent_page.area;
3379 /* use emu memory block manager code to manage tlb page allocation */
3380 trident->tlb.memhdr = snd_util_memhdr_new(SNDRV_TRIDENT_PAGE_SIZE * SNDRV_TRIDENT_MAX_PAGES);
3381 if (trident->tlb.memhdr == NULL)
3384 trident->tlb.memhdr->block_extra_size = sizeof(snd_trident_memblk_arg_t);
3389 * initialize 4D DX chip
3392 static void snd_trident_stop_all_voices(trident_t *trident)
3394 outl(0xffffffff, TRID_REG(trident, T4D_STOP_A));
3395 outl(0xffffffff, TRID_REG(trident, T4D_STOP_B));
3396 outl(0, TRID_REG(trident, T4D_AINTEN_A));
3397 outl(0, TRID_REG(trident, T4D_AINTEN_B));
3400 static int snd_trident_4d_dx_init(trident_t *trident)
3402 struct pci_dev *pci = trident->pci;
3403 unsigned long end_time;
3405 /* reset the legacy configuration and whole audio/wavetable block */
3406 pci_write_config_dword(pci, 0x40, 0); /* DDMA */
3407 pci_write_config_byte(pci, 0x44, 0); /* ports */
3408 pci_write_config_byte(pci, 0x45, 0); /* Legacy DMA */
3409 pci_write_config_byte(pci, 0x46, 4); /* reset */
3411 pci_write_config_byte(pci, 0x46, 0); /* release reset */
3414 /* warm reset of the AC'97 codec */
3415 outl(0x00000001, TRID_REG(trident, DX_ACR2_AC97_COM_STAT));
3417 outl(0x00000000, TRID_REG(trident, DX_ACR2_AC97_COM_STAT));
3418 /* DAC on, disable SB IRQ and try to force ADC valid signal */
3419 trident->ac97_ctrl = 0x0000004a;
3420 outl(trident->ac97_ctrl, TRID_REG(trident, DX_ACR2_AC97_COM_STAT));
3421 /* wait, until the codec is ready */
3422 end_time = (jiffies + (HZ * 3) / 4) + 1;
3424 if ((inl(TRID_REG(trident, DX_ACR2_AC97_COM_STAT)) & 0x0010) != 0)
3427 } while (time_after_eq(end_time, jiffies));
3428 snd_printk(KERN_ERR "AC'97 codec ready error\n");
3432 snd_trident_stop_all_voices(trident);
3438 * initialize 4D NX chip
3440 static int snd_trident_4d_nx_init(trident_t *trident)
3442 struct pci_dev *pci = trident->pci;
3443 unsigned long end_time;
3445 /* reset the legacy configuration and whole audio/wavetable block */
3446 pci_write_config_dword(pci, 0x40, 0); /* DDMA */
3447 pci_write_config_byte(pci, 0x44, 0); /* ports */
3448 pci_write_config_byte(pci, 0x45, 0); /* Legacy DMA */
3450 pci_write_config_byte(pci, 0x46, 1); /* reset */
3452 pci_write_config_byte(pci, 0x46, 0); /* release reset */
3455 /* warm reset of the AC'97 codec */
3456 outl(0x00000001, TRID_REG(trident, NX_ACR0_AC97_COM_STAT));
3458 outl(0x00000000, TRID_REG(trident, NX_ACR0_AC97_COM_STAT));
3459 /* wait, until the codec is ready */
3460 end_time = (jiffies + (HZ * 3) / 4) + 1;
3462 if ((inl(TRID_REG(trident, NX_ACR0_AC97_COM_STAT)) & 0x0008) != 0)
3465 } while (time_after_eq(end_time, jiffies));
3466 snd_printk(KERN_ERR "AC'97 codec ready error [0x%x]\n", inl(TRID_REG(trident, NX_ACR0_AC97_COM_STAT)));
3471 trident->ac97_ctrl = 0x00000002;
3472 outl(trident->ac97_ctrl, TRID_REG(trident, NX_ACR0_AC97_COM_STAT));
3473 /* disable SB IRQ */
3474 outl(NX_SB_IRQ_DISABLE, TRID_REG(trident, T4D_MISCINT));
3476 snd_trident_stop_all_voices(trident);
3478 if (trident->tlb.entries != NULL) {
3480 /* enable virtual addressing via TLB */
3481 i = trident->tlb.entries_dmaaddr;
3483 outl(i, TRID_REG(trident, NX_TLBC));
3485 outl(0, TRID_REG(trident, NX_TLBC));
3487 /* initialize S/PDIF */
3488 outl(trident->spdif_bits, TRID_REG(trident, NX_SPCSTATUS));
3489 outb(trident->spdif_ctrl, TRID_REG(trident, NX_SPCTRL_SPCSO + 3));
3495 * initialize sis7018 chip
3497 static int snd_trident_sis_init(trident_t *trident)
3501 if ((err = snd_trident_sis_reset(trident)) < 0)
3504 snd_trident_stop_all_voices(trident);
3506 /* initialize S/PDIF */
3507 outl(trident->spdif_bits, TRID_REG(trident, SI_SPDIF_CS));
3512 /*---------------------------------------------------------------------------
3515 Description: This routine will create the device specific class for
3516 the 4DWave card. It will also perform basic initialization.
3518 Paramters: card - which card to create
3519 pci - interface to PCI bus resource info
3520 dma1ptr - playback dma buffer
3521 dma2ptr - capture dma buffer
3522 irqptr - interrupt resource info
3524 Returns: 4DWave device class private data
3526 ---------------------------------------------------------------------------*/
3528 int __devinit snd_trident_create(snd_card_t * card,
3529 struct pci_dev *pci,
3531 int pcm_spdif_device,
3532 int max_wavetable_size,
3533 trident_t ** rtrident)
3537 snd_trident_voice_t *voice;
3538 snd_trident_pcm_mixer_t *tmix;
3539 static snd_device_ops_t ops = {
3540 .dev_free = snd_trident_dev_free,
3545 /* enable PCI device */
3546 if ((err = pci_enable_device(pci)) < 0)
3548 /* check, if we can restrict PCI DMA transfers to 30 bits */
3549 if (pci_set_dma_mask(pci, 0x3fffffff) < 0 ||
3550 pci_set_consistent_dma_mask(pci, 0x3fffffff) < 0) {
3551 snd_printk("architecture does not support 30bit PCI busmaster DMA\n");
3555 trident = snd_magic_kcalloc(trident_t, 0, GFP_KERNEL);
3556 if (trident == NULL)
3558 trident->device = (pci->vendor << 16) | pci->device;
3559 trident->card = card;
3561 spin_lock_init(&trident->reg_lock);
3562 spin_lock_init(&trident->event_lock);
3563 spin_lock_init(&trident->voice_alloc);
3564 if (pcm_streams < 1)
3566 if (pcm_streams > 32)
3568 trident->ChanPCM = pcm_streams;
3569 if (max_wavetable_size < 0 )
3570 max_wavetable_size = 0;
3571 trident->synth.max_size = max_wavetable_size * 1024;
3572 trident->port = pci_resource_start(pci, 0);
3575 trident->midi_port = TRID_REG(trident, T4D_MPU401_BASE);
3576 pci_set_master(pci);
3577 trident->port = pci_resource_start(pci, 0);
3579 if ((trident->res_port = request_region(trident->port, 0x100, "Trident Audio")) == NULL) {
3580 snd_printk("unable to grab I/O region 0x%lx-0x%lx\n", trident->port, trident->port + 0x100 - 1);
3581 snd_trident_free(trident);
3584 if (request_irq(pci->irq, snd_trident_interrupt, SA_INTERRUPT|SA_SHIRQ, "Trident Audio", (void *) trident)) {
3585 snd_printk("unable to grab IRQ %d\n", pci->irq);
3586 snd_trident_free(trident);
3589 trident->irq = pci->irq;
3591 memset(&trident->dma_dev, 0, sizeof(trident->dma_dev));
3592 trident->dma_dev.type = SNDRV_DMA_TYPE_DEV;
3593 trident->dma_dev.dev = snd_dma_pci_data(pci);
3595 /* allocate 16k-aligned TLB for NX cards */
3596 trident->tlb.entries = NULL;
3597 trident->tlb.buffer.area = NULL;
3598 if (trident->device == TRIDENT_DEVICE_ID_NX) {
3599 if ((err = snd_trident_tlb_alloc(trident)) < 0) {
3600 snd_trident_free(trident);
3605 trident->spdif_bits = trident->spdif_pcm_bits = SNDRV_PCM_DEFAULT_CON_SPDIF;
3607 /* initialize chip */
3608 switch (trident->device) {
3609 case TRIDENT_DEVICE_ID_DX:
3610 err = snd_trident_4d_dx_init(trident);
3612 case TRIDENT_DEVICE_ID_NX:
3613 err = snd_trident_4d_nx_init(trident);
3615 case TRIDENT_DEVICE_ID_SI7018:
3616 err = snd_trident_sis_init(trident);
3623 snd_trident_free(trident);
3627 if ((err = snd_trident_mixer(trident, pcm_spdif_device)) < 0) {
3628 snd_trident_free(trident);
3632 /* initialise synth voices */
3633 for (i = 0; i < 64; i++) {
3634 voice = &trident->synth.voices[i];
3636 voice->trident = trident;
3638 /* initialize pcm mixer entries */
3639 for (i = 0; i < 32; i++) {
3640 tmix = &trident->pcm_mixer[i];
3641 tmix->vol = T4D_DEFAULT_PCM_VOL;
3642 tmix->pan = T4D_DEFAULT_PCM_PAN;
3643 tmix->rvol = T4D_DEFAULT_PCM_RVOL;
3644 tmix->cvol = T4D_DEFAULT_PCM_CVOL;
3647 snd_trident_enable_eso(trident);
3650 card->set_power_state = snd_trident_set_power_state;
3651 card->power_state_private_data = trident;
3654 snd_trident_proc_init(trident);
3655 if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, trident, &ops)) < 0) {
3656 snd_trident_free(trident);
3659 snd_card_set_dev(card, &pci->dev);
3660 *rtrident = trident;
3664 /*---------------------------------------------------------------------------
3667 Description: This routine will free the device specific class for
3670 Paramters: trident - device specific private data for 4DWave card
3674 ---------------------------------------------------------------------------*/
3676 int snd_trident_free(trident_t *trident)
3678 #if defined(CONFIG_GAMEPORT) || (defined(MODULE) && defined(CONFIG_GAMEPORT_MODULE))
3679 if (trident->gameport) {
3680 gameport_unregister_port(&trident->gameport->info);
3681 kfree(trident->gameport);
3684 snd_trident_disable_eso(trident);
3685 // Disable S/PDIF out
3686 if (trident->device == TRIDENT_DEVICE_ID_NX)
3687 outb(0x00, TRID_REG(trident, NX_SPCTRL_SPCSO + 3));
3688 else if (trident->device == TRIDENT_DEVICE_ID_SI7018) {
3689 outl(0, TRID_REG(trident, SI_SERIAL_INTF_CTRL));
3691 if (trident->tlb.buffer.area) {
3692 outl(0, TRID_REG(trident, NX_TLBC));
3693 if (trident->tlb.memhdr)
3694 snd_util_memhdr_free(trident->tlb.memhdr);
3695 if (trident->tlb.silent_page.area)
3696 snd_dma_free_pages(&trident->dma_dev, &trident->tlb.silent_page);
3697 if (trident->tlb.shadow_entries)
3698 vfree(trident->tlb.shadow_entries);
3699 snd_dma_free_pages(&trident->dma_dev, &trident->tlb.buffer);
3701 if (trident->irq >= 0)
3702 free_irq(trident->irq, (void *)trident);
3703 if (trident->res_port) {
3704 release_resource(trident->res_port);
3705 kfree_nocheck(trident->res_port);
3707 snd_magic_kfree(trident);
3711 /*---------------------------------------------------------------------------
3712 snd_trident_interrupt
3714 Description: ISR for Trident 4DWave device
3716 Paramters: trident - device specific private data for 4DWave card
3718 Problems: It seems that Trident chips generates interrupts more than
3719 one time in special cases. The spurious interrupts are
3720 detected via sample timer (T4D_STIMER) and computing
3721 corresponding delta value. The limits are detected with
3722 the method try & fail so it is possible that it won't
3723 work on all computers. [jaroslav]
3727 ---------------------------------------------------------------------------*/
3729 static irqreturn_t snd_trident_interrupt(int irq, void *dev_id, struct pt_regs *regs)
3731 trident_t *trident = snd_magic_cast(trident_t, dev_id, return IRQ_NONE);
3732 unsigned int audio_int, chn_int, stimer, channel, mask, tmp;
3734 snd_trident_voice_t *voice;
3736 audio_int = inl(TRID_REG(trident, T4D_MISCINT));
3737 if ((audio_int & (ADDRESS_IRQ|MPU401_IRQ)) == 0)
3739 if (audio_int & ADDRESS_IRQ) {
3740 // get interrupt status for all channels
3741 spin_lock(&trident->reg_lock);
3742 stimer = inl(TRID_REG(trident, T4D_STIMER)) & 0x00ffffff;
3743 chn_int = inl(TRID_REG(trident, T4D_AINT_A));
3746 outl(chn_int, TRID_REG(trident, T4D_AINT_A)); /* ack */
3748 chn_int = inl(TRID_REG(trident, T4D_AINT_B));
3751 for (channel = 63; channel >= 32; channel--) {
3752 mask = 1 << (channel&0x1f);
3753 if ((chn_int & mask) == 0)
3755 voice = &trident->synth.voices[channel];
3756 if (!voice->pcm || voice->substream == NULL) {
3757 outl(mask, TRID_REG(trident, T4D_STOP_B));
3760 delta = (int)stimer - (int)voice->stimer;
3763 if ((unsigned int)delta < voice->spurious_threshold) {
3764 /* do some statistics here */
3765 trident->spurious_irq_count++;
3766 if (trident->spurious_irq_max_delta < (unsigned int)delta)
3767 trident->spurious_irq_max_delta = delta;
3770 voice->stimer = stimer;
3772 if (!voice->isync3) {
3773 tmp = inw(TRID_REG(trident, T4D_SBBL_SBCL));
3774 if (trident->bDMAStart & 0x40)
3777 tmp = voice->isync_max - tmp;
3779 tmp = inl(TRID_REG(trident, NX_SPCTRL_SPCSO)) & 0x00ffffff;
3781 if (tmp < voice->isync_mark) {
3783 tmp = voice->isync_ESO - 7;
3785 tmp = voice->isync_ESO + 2;
3786 /* update ESO for IRQ voice to preserve sync */
3787 snd_trident_stop_voice(trident, voice->number);
3788 snd_trident_write_eso_reg(trident, voice, tmp);
3789 snd_trident_start_voice(trident, voice->number);
3791 } else if (voice->isync2) {
3793 /* write original ESO and update CSO for IRQ voice to preserve sync */
3794 snd_trident_stop_voice(trident, voice->number);
3795 snd_trident_write_cso_reg(trident, voice, voice->isync_mark);
3796 snd_trident_write_eso_reg(trident, voice, voice->ESO);
3797 snd_trident_start_voice(trident, voice->number);
3801 /* update CSO for extra voice to preserve sync */
3802 snd_trident_stop_voice(trident, voice->extra->number);
3803 snd_trident_write_cso_reg(trident, voice->extra, 0);
3804 snd_trident_start_voice(trident, voice->extra->number);
3807 spin_unlock(&trident->reg_lock);
3808 snd_pcm_period_elapsed(voice->substream);
3809 spin_lock(&trident->reg_lock);
3811 outl(chn_int, TRID_REG(trident, T4D_AINT_B)); /* ack */
3813 spin_unlock(&trident->reg_lock);
3815 if (audio_int & MPU401_IRQ) {
3816 if (trident->rmidi) {
3817 snd_mpu401_uart_interrupt(irq, trident->rmidi->private_data, regs);
3819 inb(TRID_REG(trident, T4D_MPUR0));
3822 // outl((ST_TARGET_REACHED | MIXER_OVERFLOW | MIXER_UNDERFLOW), TRID_REG(trident, T4D_MISCINT));
3826 /*---------------------------------------------------------------------------
3827 snd_trident_attach_synthesizer, snd_trident_detach_synthesizer
3829 Description: Attach/detach synthesizer hooks
3831 Paramters: trident - device specific private data for 4DWave card
3835 ---------------------------------------------------------------------------*/
3836 int snd_trident_attach_synthesizer(trident_t *trident)
3838 #if defined(CONFIG_SND_SEQUENCER) || (defined(MODULE) && defined(CONFIG_SND_SEQUENCER_MODULE))
3839 if (snd_seq_device_new(trident->card, 1, SNDRV_SEQ_DEV_ID_TRIDENT,
3840 sizeof(trident_t*), &trident->seq_dev) >= 0) {
3841 strcpy(trident->seq_dev->name, "4DWave");
3842 *(trident_t**)SNDRV_SEQ_DEVICE_ARGPTR(trident->seq_dev) = trident;
3848 int snd_trident_detach_synthesizer(trident_t *trident)
3850 #if defined(CONFIG_SND_SEQUENCER) || (defined(MODULE) && defined(CONFIG_SND_SEQUENCER_MODULE))
3851 if (trident->seq_dev) {
3852 snd_device_free(trident->card, trident->seq_dev);
3853 trident->seq_dev = NULL;
3859 snd_trident_voice_t *snd_trident_alloc_voice(trident_t * trident, int type, int client, int port)
3861 snd_trident_voice_t *pvoice;
3862 unsigned long flags;
3865 spin_lock_irqsave(&trident->voice_alloc, flags);
3866 if (type == SNDRV_TRIDENT_VOICE_TYPE_PCM) {
3867 idx = snd_trident_allocate_pcm_channel(trident);
3869 spin_unlock_irqrestore(&trident->voice_alloc, flags);
3872 pvoice = &trident->synth.voices[idx];
3875 pvoice->capture = 0;
3877 pvoice->memblk = NULL;
3878 pvoice->substream = NULL;
3879 spin_unlock_irqrestore(&trident->voice_alloc, flags);
3882 if (type == SNDRV_TRIDENT_VOICE_TYPE_SYNTH) {
3883 idx = snd_trident_allocate_synth_channel(trident);
3885 spin_unlock_irqrestore(&trident->voice_alloc, flags);
3888 pvoice = &trident->synth.voices[idx];
3891 pvoice->client = client;
3892 pvoice->port = port;
3893 pvoice->memblk = NULL;
3894 spin_unlock_irqrestore(&trident->voice_alloc, flags);
3897 if (type == SNDRV_TRIDENT_VOICE_TYPE_MIDI) {
3899 spin_unlock_irqrestore(&trident->voice_alloc, flags);
3903 void snd_trident_free_voice(trident_t * trident, snd_trident_voice_t *voice)
3905 unsigned long flags;
3906 void (*private_free)(snd_trident_voice_t *);
3909 if (voice == NULL || !voice->use)
3911 snd_trident_clear_voices(trident, voice->number, voice->number);
3912 spin_lock_irqsave(&trident->voice_alloc, flags);
3913 private_free = voice->private_free;
3914 private_data = voice->private_data;
3915 voice->private_free = NULL;
3916 voice->private_data = NULL;
3918 snd_trident_free_pcm_channel(trident, voice->number);
3920 snd_trident_free_synth_channel(trident, voice->number);
3921 voice->use = voice->pcm = voice->synth = voice->midi = 0;
3922 voice->capture = voice->spdif = 0;
3923 voice->sample_ops = NULL;
3924 voice->substream = NULL;
3925 voice->extra = NULL;
3926 spin_unlock_irqrestore(&trident->voice_alloc, flags);
3928 private_free(voice);
3931 void snd_trident_clear_voices(trident_t * trident, unsigned short v_min, unsigned short v_max)
3933 unsigned int i, val, mask[2] = { 0, 0 };
3935 snd_assert(v_min <= 63, return);
3936 snd_assert(v_max <= 63, return);
3937 for (i = v_min; i <= v_max; i++)
3938 mask[i >> 5] |= 1 << (i & 0x1f);
3940 outl(mask[0], TRID_REG(trident, T4D_STOP_A));
3941 val = inl(TRID_REG(trident, T4D_AINTEN_A));
3942 outl(val & ~mask[0], TRID_REG(trident, T4D_AINTEN_A));
3945 outl(mask[1], TRID_REG(trident, T4D_STOP_B));
3946 val = inl(TRID_REG(trident, T4D_AINTEN_B));
3947 outl(val & ~mask[1], TRID_REG(trident, T4D_AINTEN_B));
3953 void snd_trident_suspend(trident_t *trident)
3955 snd_card_t *card = trident->card;
3957 if (card->power_state == SNDRV_CTL_POWER_D3hot)
3959 trident->in_suspend = 1;
3960 snd_pcm_suspend_all(trident->pcm);
3961 if (trident->foldback)
3962 snd_pcm_suspend_all(trident->foldback);
3964 snd_pcm_suspend_all(trident->spdif);
3965 switch (trident->device) {
3966 case TRIDENT_DEVICE_ID_DX:
3967 case TRIDENT_DEVICE_ID_NX:
3969 case TRIDENT_DEVICE_ID_SI7018:
3972 snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
3975 void snd_trident_resume(trident_t *trident)
3977 snd_card_t *card = trident->card;
3979 if (card->power_state == SNDRV_CTL_POWER_D0)
3982 pci_enable_device(trident->pci);
3983 if (pci_set_dma_mask(trident->pci, 0x3fffffff) < 0 ||
3984 pci_set_consistent_dma_mask(trident->pci, 0x3fffffff) < 0)
3985 snd_printk(KERN_WARNING "trident: can't set the proper DMA mask\n");
3986 pci_set_master(trident->pci); /* to be sure */
3988 switch (trident->device) {
3989 case TRIDENT_DEVICE_ID_DX:
3990 snd_trident_4d_dx_init(trident);
3992 case TRIDENT_DEVICE_ID_NX:
3993 snd_trident_4d_nx_init(trident);
3995 case TRIDENT_DEVICE_ID_SI7018:
3996 snd_trident_sis_init(trident);
4000 snd_ac97_resume(trident->ac97);
4002 /* restore some registers */
4003 outl(trident->musicvol_wavevol, TRID_REG(trident, T4D_MUSICVOL_WAVEVOL));
4005 snd_trident_enable_eso(trident);
4007 snd_power_change_state(card, SNDRV_CTL_POWER_D0);
4008 trident->in_suspend = 0;
4011 static int snd_trident_set_power_state(snd_card_t *card, unsigned int power_state)
4013 trident_t *chip = snd_magic_cast(trident_t, card->power_state_private_data, return -ENXIO);
4015 switch (power_state) {
4016 case SNDRV_CTL_POWER_D0:
4017 case SNDRV_CTL_POWER_D1:
4018 case SNDRV_CTL_POWER_D2:
4019 snd_trident_resume(chip);
4021 case SNDRV_CTL_POWER_D3hot:
4022 case SNDRV_CTL_POWER_D3cold:
4023 snd_trident_suspend(chip);
4031 #endif /* CONFIG_PM */
4033 EXPORT_SYMBOL(snd_trident_alloc_voice);
4034 EXPORT_SYMBOL(snd_trident_free_voice);
4035 EXPORT_SYMBOL(snd_trident_start_voice);
4036 EXPORT_SYMBOL(snd_trident_stop_voice);
4037 EXPORT_SYMBOL(snd_trident_write_voice_regs);
4038 EXPORT_SYMBOL(snd_trident_clear_voices);
4039 /* trident_memory.c symbols */
4040 EXPORT_SYMBOL(snd_trident_synth_alloc);
4041 EXPORT_SYMBOL(snd_trident_synth_free);
4042 EXPORT_SYMBOL(snd_trident_synth_bzero);
4043 EXPORT_SYMBOL(snd_trident_synth_copy_from_user);