2 * Maintained by Jaroslav Kysela <perex@perex.cz>
3 * Originated by audio@tridentmicro.com
4 * Fri Feb 19 15:55:28 MST 1999
5 * Routines for control of Trident 4DWave (DX and NX) chip
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 <linux/delay.h>
31 #include <linux/init.h>
32 #include <linux/interrupt.h>
33 #include <linux/pci.h>
34 #include <linux/slab.h>
35 #include <linux/vmalloc.h>
36 #include <linux/gameport.h>
37 #include <linux/dma-mapping.h>
39 #include <sound/core.h>
40 #include <sound/info.h>
41 #include <sound/control.h>
42 #include <sound/tlv.h>
43 #include <sound/trident.h>
44 #include <sound/asoundef.h>
48 static int snd_trident_pcm_mixer_build(struct snd_trident
*trident
,
49 struct snd_trident_voice
* voice
,
50 struct snd_pcm_substream
*substream
);
51 static int snd_trident_pcm_mixer_free(struct snd_trident
*trident
,
52 struct snd_trident_voice
* voice
,
53 struct snd_pcm_substream
*substream
);
54 static irqreturn_t
snd_trident_interrupt(int irq
, void *dev_id
);
55 static int snd_trident_sis_reset(struct snd_trident
*trident
);
57 static void snd_trident_clear_voices(struct snd_trident
* trident
,
58 unsigned short v_min
, unsigned short v_max
);
59 static int snd_trident_free(struct snd_trident
*trident
);
67 static void snd_trident_print_voice_regs(struct snd_trident
*trident
, int voice
)
69 unsigned int val
, tmp
;
71 printk(KERN_DEBUG
"Trident voice %i:\n", voice
);
72 outb(voice
, TRID_REG(trident
, T4D_LFO_GC_CIR
));
73 val
= inl(TRID_REG(trident
, CH_LBA
));
74 printk(KERN_DEBUG
"LBA: 0x%x\n", val
);
75 val
= inl(TRID_REG(trident
, CH_GVSEL_PAN_VOL_CTRL_EC
));
76 printk(KERN_DEBUG
"GVSel: %i\n", val
>> 31);
77 printk(KERN_DEBUG
"Pan: 0x%x\n", (val
>> 24) & 0x7f);
78 printk(KERN_DEBUG
"Vol: 0x%x\n", (val
>> 16) & 0xff);
79 printk(KERN_DEBUG
"CTRL: 0x%x\n", (val
>> 12) & 0x0f);
80 printk(KERN_DEBUG
"EC: 0x%x\n", val
& 0x0fff);
81 if (trident
->device
!= TRIDENT_DEVICE_ID_NX
) {
82 val
= inl(TRID_REG(trident
, CH_DX_CSO_ALPHA_FMS
));
83 printk(KERN_DEBUG
"CSO: 0x%x\n", val
>> 16);
84 printk("Alpha: 0x%x\n", (val
>> 4) & 0x0fff);
85 printk(KERN_DEBUG
"FMS: 0x%x\n", val
& 0x0f);
86 val
= inl(TRID_REG(trident
, CH_DX_ESO_DELTA
));
87 printk(KERN_DEBUG
"ESO: 0x%x\n", val
>> 16);
88 printk(KERN_DEBUG
"Delta: 0x%x\n", val
& 0xffff);
89 val
= inl(TRID_REG(trident
, CH_DX_FMC_RVOL_CVOL
));
90 } else { // TRIDENT_DEVICE_ID_NX
91 val
= inl(TRID_REG(trident
, CH_NX_DELTA_CSO
));
92 tmp
= (val
>> 24) & 0xff;
93 printk(KERN_DEBUG
"CSO: 0x%x\n", val
& 0x00ffffff);
94 val
= inl(TRID_REG(trident
, CH_NX_DELTA_ESO
));
95 tmp
|= (val
>> 16) & 0xff00;
96 printk(KERN_DEBUG
"Delta: 0x%x\n", tmp
);
97 printk(KERN_DEBUG
"ESO: 0x%x\n", val
& 0x00ffffff);
98 val
= inl(TRID_REG(trident
, CH_NX_ALPHA_FMS_FMC_RVOL_CVOL
));
99 printk(KERN_DEBUG
"Alpha: 0x%x\n", val
>> 20);
100 printk(KERN_DEBUG
"FMS: 0x%x\n", (val
>> 16) & 0x0f);
102 printk(KERN_DEBUG
"FMC: 0x%x\n", (val
>> 14) & 3);
103 printk(KERN_DEBUG
"RVol: 0x%x\n", (val
>> 7) & 0x7f);
104 printk(KERN_DEBUG
"CVol: 0x%x\n", val
& 0x7f);
108 /*---------------------------------------------------------------------------
109 unsigned short snd_trident_codec_read(struct snd_ac97 *ac97, unsigned short reg)
111 Description: This routine will do all of the reading from the external
114 Parameters: ac97 - ac97 codec structure
115 reg - CODEC register index, from AC97 Hal.
117 returns: 16 bit value read from the AC97.
119 ---------------------------------------------------------------------------*/
120 static unsigned short snd_trident_codec_read(struct snd_ac97
*ac97
, unsigned short reg
)
122 unsigned int data
= 0, treg
;
123 unsigned short count
= 0xffff;
125 struct snd_trident
*trident
= ac97
->private_data
;
127 spin_lock_irqsave(&trident
->reg_lock
, flags
);
128 if (trident
->device
== TRIDENT_DEVICE_ID_DX
) {
129 data
= (DX_AC97_BUSY_READ
| (reg
& 0x000000ff));
130 outl(data
, TRID_REG(trident
, DX_ACR1_AC97_R
));
132 data
= inl(TRID_REG(trident
, DX_ACR1_AC97_R
));
133 if ((data
& DX_AC97_BUSY_READ
) == 0)
136 } else if (trident
->device
== TRIDENT_DEVICE_ID_NX
) {
137 data
= (NX_AC97_BUSY_READ
| (reg
& 0x000000ff));
138 treg
= ac97
->num
== 0 ? NX_ACR2_AC97_R_PRIMARY
: NX_ACR3_AC97_R_SECONDARY
;
139 outl(data
, TRID_REG(trident
, treg
));
141 data
= inl(TRID_REG(trident
, treg
));
142 if ((data
& 0x00000C00) == 0)
145 } else if (trident
->device
== TRIDENT_DEVICE_ID_SI7018
) {
146 data
= SI_AC97_BUSY_READ
| SI_AC97_AUDIO_BUSY
| (reg
& 0x000000ff);
148 data
|= SI_AC97_SECONDARY
;
149 outl(data
, TRID_REG(trident
, SI_AC97_READ
));
151 data
= inl(TRID_REG(trident
, SI_AC97_READ
));
152 if ((data
& (SI_AC97_BUSY_READ
)) == 0)
157 if (count
== 0 && !trident
->ac97_detect
) {
158 snd_printk(KERN_ERR
"ac97 codec read TIMEOUT [0x%x/0x%x]!!!\n",
163 spin_unlock_irqrestore(&trident
->reg_lock
, flags
);
164 return ((unsigned short) (data
>> 16));
167 /*---------------------------------------------------------------------------
168 void snd_trident_codec_write(struct snd_ac97 *ac97, unsigned short reg,
169 unsigned short wdata)
171 Description: This routine will do all of the writing to the external
174 Parameters: ac97 - ac97 codec structure
175 reg - CODEC register index, from AC97 Hal.
176 data - Lower 16 bits are the data to write to CODEC.
178 returns: TRUE if everything went ok, else FALSE.
180 ---------------------------------------------------------------------------*/
181 static void snd_trident_codec_write(struct snd_ac97
*ac97
, unsigned short reg
,
182 unsigned short wdata
)
184 unsigned int address
, data
;
185 unsigned short count
= 0xffff;
187 struct snd_trident
*trident
= ac97
->private_data
;
189 data
= ((unsigned long) wdata
) << 16;
191 spin_lock_irqsave(&trident
->reg_lock
, flags
);
192 if (trident
->device
== TRIDENT_DEVICE_ID_DX
) {
193 address
= DX_ACR0_AC97_W
;
195 /* read AC-97 write register status */
197 if ((inw(TRID_REG(trident
, address
)) & DX_AC97_BUSY_WRITE
) == 0)
201 data
|= (DX_AC97_BUSY_WRITE
| (reg
& 0x000000ff));
202 } else if (trident
->device
== TRIDENT_DEVICE_ID_NX
) {
203 address
= NX_ACR1_AC97_W
;
205 /* read AC-97 write register status */
207 if ((inw(TRID_REG(trident
, address
)) & NX_AC97_BUSY_WRITE
) == 0)
211 data
|= (NX_AC97_BUSY_WRITE
| (ac97
->num
<< 8) | (reg
& 0x000000ff));
212 } else if (trident
->device
== TRIDENT_DEVICE_ID_SI7018
) {
213 address
= SI_AC97_WRITE
;
215 /* read AC-97 write register status */
217 if ((inw(TRID_REG(trident
, address
)) & (SI_AC97_BUSY_WRITE
)) == 0)
221 data
|= SI_AC97_BUSY_WRITE
| SI_AC97_AUDIO_BUSY
| (reg
& 0x000000ff);
223 data
|= SI_AC97_SECONDARY
;
225 address
= 0; /* keep GCC happy */
226 count
= 0; /* return */
230 spin_unlock_irqrestore(&trident
->reg_lock
, flags
);
233 outl(data
, TRID_REG(trident
, address
));
234 spin_unlock_irqrestore(&trident
->reg_lock
, flags
);
237 /*---------------------------------------------------------------------------
238 void snd_trident_enable_eso(struct snd_trident *trident)
240 Description: This routine will enable end of loop interrupts.
241 End of loop interrupts will occur when a running
243 Also enables middle of loop interrupts.
245 Parameters: trident - pointer to target device class for 4DWave.
247 ---------------------------------------------------------------------------*/
249 static void snd_trident_enable_eso(struct snd_trident
* trident
)
253 val
= inl(TRID_REG(trident
, T4D_LFO_GC_CIR
));
256 if (trident
->device
== TRIDENT_DEVICE_ID_SI7018
)
258 outl(val
, TRID_REG(trident
, T4D_LFO_GC_CIR
));
261 /*---------------------------------------------------------------------------
262 void snd_trident_disable_eso(struct snd_trident *trident)
264 Description: This routine will disable end of loop interrupts.
265 End of loop interrupts will occur when a running
267 Also disables middle of loop interrupts.
270 trident - pointer to target device class for 4DWave.
272 returns: TRUE if everything went ok, else FALSE.
274 ---------------------------------------------------------------------------*/
276 static void snd_trident_disable_eso(struct snd_trident
* trident
)
280 tmp
= inl(TRID_REG(trident
, T4D_LFO_GC_CIR
));
283 outl(tmp
, TRID_REG(trident
, T4D_LFO_GC_CIR
));
286 /*---------------------------------------------------------------------------
287 void snd_trident_start_voice(struct snd_trident * trident, unsigned int voice)
289 Description: Start a voice, any channel 0 thru 63.
290 This routine automatically handles the fact that there are
291 more than 32 channels available.
293 Parameters : voice - Voice number 0 thru n.
294 trident - pointer to target device class for 4DWave.
298 ---------------------------------------------------------------------------*/
300 void snd_trident_start_voice(struct snd_trident
* trident
, unsigned int voice
)
302 unsigned int mask
= 1 << (voice
& 0x1f);
303 unsigned int reg
= (voice
& 0x20) ? T4D_START_B
: T4D_START_A
;
305 outl(mask
, TRID_REG(trident
, reg
));
308 EXPORT_SYMBOL(snd_trident_start_voice
);
310 /*---------------------------------------------------------------------------
311 void snd_trident_stop_voice(struct snd_trident * trident, unsigned int voice)
313 Description: Stop a voice, any channel 0 thru 63.
314 This routine automatically handles the fact that there are
315 more than 32 channels available.
317 Parameters : voice - Voice number 0 thru n.
318 trident - pointer to target device class for 4DWave.
322 ---------------------------------------------------------------------------*/
324 void snd_trident_stop_voice(struct snd_trident
* trident
, unsigned int voice
)
326 unsigned int mask
= 1 << (voice
& 0x1f);
327 unsigned int reg
= (voice
& 0x20) ? T4D_STOP_B
: T4D_STOP_A
;
329 outl(mask
, TRID_REG(trident
, reg
));
332 EXPORT_SYMBOL(snd_trident_stop_voice
);
334 /*---------------------------------------------------------------------------
335 int snd_trident_allocate_pcm_channel(struct snd_trident *trident)
337 Description: Allocate hardware channel in Bank B (32-63).
339 Parameters : trident - pointer to target device class for 4DWave.
341 Return Value: hardware channel - 32-63 or -1 when no channel is available
343 ---------------------------------------------------------------------------*/
345 static int snd_trident_allocate_pcm_channel(struct snd_trident
* trident
)
349 if (trident
->ChanPCMcnt
>= trident
->ChanPCM
)
351 for (idx
= 31; idx
>= 0; idx
--) {
352 if (!(trident
->ChanMap
[T4D_BANK_B
] & (1 << idx
))) {
353 trident
->ChanMap
[T4D_BANK_B
] |= 1 << idx
;
354 trident
->ChanPCMcnt
++;
361 /*---------------------------------------------------------------------------
362 void snd_trident_free_pcm_channel(int channel)
364 Description: Free hardware channel in Bank B (32-63)
366 Parameters : trident - pointer to target device class for 4DWave.
367 channel - hardware channel number 0-63
371 ---------------------------------------------------------------------------*/
373 static void snd_trident_free_pcm_channel(struct snd_trident
*trident
, int channel
)
375 if (channel
< 32 || channel
> 63)
378 if (trident
->ChanMap
[T4D_BANK_B
] & (1 << channel
)) {
379 trident
->ChanMap
[T4D_BANK_B
] &= ~(1 << channel
);
380 trident
->ChanPCMcnt
--;
384 /*---------------------------------------------------------------------------
385 unsigned int snd_trident_allocate_synth_channel(void)
387 Description: Allocate hardware channel in Bank A (0-31).
389 Parameters : trident - pointer to target device class for 4DWave.
391 Return Value: hardware channel - 0-31 or -1 when no channel is available
393 ---------------------------------------------------------------------------*/
395 static int snd_trident_allocate_synth_channel(struct snd_trident
* trident
)
399 for (idx
= 31; idx
>= 0; idx
--) {
400 if (!(trident
->ChanMap
[T4D_BANK_A
] & (1 << idx
))) {
401 trident
->ChanMap
[T4D_BANK_A
] |= 1 << idx
;
402 trident
->synth
.ChanSynthCount
++;
409 /*---------------------------------------------------------------------------
410 void snd_trident_free_synth_channel( int channel )
412 Description: Free hardware channel in Bank B (0-31).
414 Parameters : trident - pointer to target device class for 4DWave.
415 channel - hardware channel number 0-63
419 ---------------------------------------------------------------------------*/
421 static void snd_trident_free_synth_channel(struct snd_trident
*trident
, int channel
)
423 if (channel
< 0 || channel
> 31)
426 if (trident
->ChanMap
[T4D_BANK_A
] & (1 << channel
)) {
427 trident
->ChanMap
[T4D_BANK_A
] &= ~(1 << channel
);
428 trident
->synth
.ChanSynthCount
--;
432 /*---------------------------------------------------------------------------
433 snd_trident_write_voice_regs
435 Description: This routine will complete and write the 5 hardware channel
436 registers to hardware.
438 Parameters: trident - pointer to target device class for 4DWave.
439 voice - synthesizer voice structure
442 ---------------------------------------------------------------------------*/
444 void snd_trident_write_voice_regs(struct snd_trident
* trident
,
445 struct snd_trident_voice
* voice
)
447 unsigned int FmcRvolCvol
;
448 unsigned int regs
[5];
450 regs
[1] = voice
->LBA
;
451 regs
[4] = (voice
->GVSel
<< 31) |
452 ((voice
->Pan
& 0x0000007f) << 24) |
453 ((voice
->CTRL
& 0x0000000f) << 12);
454 FmcRvolCvol
= ((voice
->FMC
& 3) << 14) |
455 ((voice
->RVol
& 0x7f) << 7) |
456 (voice
->CVol
& 0x7f);
458 switch (trident
->device
) {
459 case TRIDENT_DEVICE_ID_SI7018
:
460 regs
[4] |= voice
->number
> 31 ?
461 (voice
->Vol
& 0x000003ff) :
462 ((voice
->Vol
& 0x00003fc) << (16-2)) |
463 (voice
->EC
& 0x00000fff);
464 regs
[0] = (voice
->CSO
<< 16) | ((voice
->Alpha
& 0x00000fff) << 4) |
465 (voice
->FMS
& 0x0000000f);
466 regs
[2] = (voice
->ESO
<< 16) | (voice
->Delta
& 0x0ffff);
467 regs
[3] = (voice
->Attribute
<< 16) | FmcRvolCvol
;
469 case TRIDENT_DEVICE_ID_DX
:
470 regs
[4] |= ((voice
->Vol
& 0x000003fc) << (16-2)) |
471 (voice
->EC
& 0x00000fff);
472 regs
[0] = (voice
->CSO
<< 16) | ((voice
->Alpha
& 0x00000fff) << 4) |
473 (voice
->FMS
& 0x0000000f);
474 regs
[2] = (voice
->ESO
<< 16) | (voice
->Delta
& 0x0ffff);
475 regs
[3] = FmcRvolCvol
;
477 case TRIDENT_DEVICE_ID_NX
:
478 regs
[4] |= ((voice
->Vol
& 0x000003fc) << (16-2)) |
479 (voice
->EC
& 0x00000fff);
480 regs
[0] = (voice
->Delta
<< 24) | (voice
->CSO
& 0x00ffffff);
481 regs
[2] = ((voice
->Delta
<< 16) & 0xff000000) |
482 (voice
->ESO
& 0x00ffffff);
483 regs
[3] = (voice
->Alpha
<< 20) |
484 ((voice
->FMS
& 0x0000000f) << 16) | FmcRvolCvol
;
491 outb(voice
->number
, TRID_REG(trident
, T4D_LFO_GC_CIR
));
492 outl(regs
[0], TRID_REG(trident
, CH_START
+ 0));
493 outl(regs
[1], TRID_REG(trident
, CH_START
+ 4));
494 outl(regs
[2], TRID_REG(trident
, CH_START
+ 8));
495 outl(regs
[3], TRID_REG(trident
, CH_START
+ 12));
496 outl(regs
[4], TRID_REG(trident
, CH_START
+ 16));
499 printk(KERN_DEBUG
"written %i channel:\n", voice
->number
);
500 printk(KERN_DEBUG
" regs[0] = 0x%x/0x%x\n",
501 regs
[0], inl(TRID_REG(trident
, CH_START
+ 0)));
502 printk(KERN_DEBUG
" regs[1] = 0x%x/0x%x\n",
503 regs
[1], inl(TRID_REG(trident
, CH_START
+ 4)));
504 printk(KERN_DEBUG
" regs[2] = 0x%x/0x%x\n",
505 regs
[2], inl(TRID_REG(trident
, CH_START
+ 8)));
506 printk(KERN_DEBUG
" regs[3] = 0x%x/0x%x\n",
507 regs
[3], inl(TRID_REG(trident
, CH_START
+ 12)));
508 printk(KERN_DEBUG
" regs[4] = 0x%x/0x%x\n",
509 regs
[4], inl(TRID_REG(trident
, CH_START
+ 16)));
513 EXPORT_SYMBOL(snd_trident_write_voice_regs
);
515 /*---------------------------------------------------------------------------
516 snd_trident_write_cso_reg
518 Description: This routine will write the new CSO offset
519 register to hardware.
521 Parameters: trident - pointer to target device class for 4DWave.
522 voice - synthesizer voice structure
525 ---------------------------------------------------------------------------*/
527 static void snd_trident_write_cso_reg(struct snd_trident
* trident
,
528 struct snd_trident_voice
* voice
,
532 outb(voice
->number
, TRID_REG(trident
, T4D_LFO_GC_CIR
));
533 if (trident
->device
!= TRIDENT_DEVICE_ID_NX
) {
534 outw(voice
->CSO
, TRID_REG(trident
, CH_DX_CSO_ALPHA_FMS
) + 2);
536 outl((voice
->Delta
<< 24) |
537 (voice
->CSO
& 0x00ffffff), TRID_REG(trident
, CH_NX_DELTA_CSO
));
541 /*---------------------------------------------------------------------------
542 snd_trident_write_eso_reg
544 Description: This routine will write the new ESO offset
545 register to hardware.
547 Parameters: trident - pointer to target device class for 4DWave.
548 voice - synthesizer voice structure
551 ---------------------------------------------------------------------------*/
553 static void snd_trident_write_eso_reg(struct snd_trident
* trident
,
554 struct snd_trident_voice
* voice
,
558 outb(voice
->number
, TRID_REG(trident
, T4D_LFO_GC_CIR
));
559 if (trident
->device
!= TRIDENT_DEVICE_ID_NX
) {
560 outw(voice
->ESO
, TRID_REG(trident
, CH_DX_ESO_DELTA
) + 2);
562 outl(((voice
->Delta
<< 16) & 0xff000000) | (voice
->ESO
& 0x00ffffff),
563 TRID_REG(trident
, CH_NX_DELTA_ESO
));
567 /*---------------------------------------------------------------------------
568 snd_trident_write_vol_reg
570 Description: This routine will write the new voice volume
571 register to hardware.
573 Parameters: trident - pointer to target device class for 4DWave.
574 voice - synthesizer voice structure
575 Vol - new voice volume
577 ---------------------------------------------------------------------------*/
579 static void snd_trident_write_vol_reg(struct snd_trident
* trident
,
580 struct snd_trident_voice
* voice
,
584 outb(voice
->number
, TRID_REG(trident
, T4D_LFO_GC_CIR
));
585 switch (trident
->device
) {
586 case TRIDENT_DEVICE_ID_DX
:
587 case TRIDENT_DEVICE_ID_NX
:
588 outb(voice
->Vol
>> 2, TRID_REG(trident
, CH_GVSEL_PAN_VOL_CTRL_EC
+ 2));
590 case TRIDENT_DEVICE_ID_SI7018
:
591 /* printk(KERN_DEBUG "voice->Vol = 0x%x\n", voice->Vol); */
592 outw((voice
->CTRL
<< 12) | voice
->Vol
,
593 TRID_REG(trident
, CH_GVSEL_PAN_VOL_CTRL_EC
));
598 /*---------------------------------------------------------------------------
599 snd_trident_write_pan_reg
601 Description: This routine will write the new voice pan
602 register to hardware.
604 Parameters: trident - pointer to target device class for 4DWave.
605 voice - synthesizer voice structure
608 ---------------------------------------------------------------------------*/
610 static void snd_trident_write_pan_reg(struct snd_trident
* trident
,
611 struct snd_trident_voice
* voice
,
615 outb(voice
->number
, TRID_REG(trident
, T4D_LFO_GC_CIR
));
616 outb(((voice
->GVSel
& 0x01) << 7) | (voice
->Pan
& 0x7f),
617 TRID_REG(trident
, CH_GVSEL_PAN_VOL_CTRL_EC
+ 3));
620 /*---------------------------------------------------------------------------
621 snd_trident_write_rvol_reg
623 Description: This routine will write the new reverb volume
624 register to hardware.
626 Parameters: trident - pointer to target device class for 4DWave.
627 voice - synthesizer voice structure
628 RVol - new reverb volume
630 ---------------------------------------------------------------------------*/
632 static void snd_trident_write_rvol_reg(struct snd_trident
* trident
,
633 struct snd_trident_voice
* voice
,
637 outb(voice
->number
, TRID_REG(trident
, T4D_LFO_GC_CIR
));
638 outw(((voice
->FMC
& 0x0003) << 14) | ((voice
->RVol
& 0x007f) << 7) |
639 (voice
->CVol
& 0x007f),
640 TRID_REG(trident
, trident
->device
== TRIDENT_DEVICE_ID_NX
?
641 CH_NX_ALPHA_FMS_FMC_RVOL_CVOL
: CH_DX_FMC_RVOL_CVOL
));
644 /*---------------------------------------------------------------------------
645 snd_trident_write_cvol_reg
647 Description: This routine will write the new chorus volume
648 register to hardware.
650 Parameters: trident - pointer to target device class for 4DWave.
651 voice - synthesizer voice structure
652 CVol - new chorus volume
654 ---------------------------------------------------------------------------*/
656 static void snd_trident_write_cvol_reg(struct snd_trident
* trident
,
657 struct snd_trident_voice
* voice
,
661 outb(voice
->number
, TRID_REG(trident
, T4D_LFO_GC_CIR
));
662 outw(((voice
->FMC
& 0x0003) << 14) | ((voice
->RVol
& 0x007f) << 7) |
663 (voice
->CVol
& 0x007f),
664 TRID_REG(trident
, trident
->device
== TRIDENT_DEVICE_ID_NX
?
665 CH_NX_ALPHA_FMS_FMC_RVOL_CVOL
: CH_DX_FMC_RVOL_CVOL
));
668 /*---------------------------------------------------------------------------
669 snd_trident_convert_rate
671 Description: This routine converts rate in HZ to hardware delta value.
673 Parameters: trident - pointer to target device class for 4DWave.
674 rate - Real or Virtual channel number.
676 Returns: Delta value.
678 ---------------------------------------------------------------------------*/
679 static unsigned int snd_trident_convert_rate(unsigned int rate
)
683 // We special case 44100 and 8000 since rounding with the equation
684 // does not give us an accurate enough value. For 11025 and 22050
685 // the equation gives us the best answer. All other frequencies will
686 // also use the equation. JDW
689 else if (rate
== 8000)
691 else if (rate
== 48000)
694 delta
= (((rate
<< 12) + 24000) / 48000) & 0x0000ffff;
698 /*---------------------------------------------------------------------------
699 snd_trident_convert_adc_rate
701 Description: This routine converts rate in HZ to hardware delta value.
703 Parameters: trident - pointer to target device class for 4DWave.
704 rate - Real or Virtual channel number.
706 Returns: Delta value.
708 ---------------------------------------------------------------------------*/
709 static unsigned int snd_trident_convert_adc_rate(unsigned int rate
)
713 // We special case 44100 and 8000 since rounding with the equation
714 // does not give us an accurate enough value. For 11025 and 22050
715 // the equation gives us the best answer. All other frequencies will
716 // also use the equation. JDW
719 else if (rate
== 8000)
721 else if (rate
== 48000)
724 delta
= ((48000 << 12) / rate
) & 0x0000ffff;
728 /*---------------------------------------------------------------------------
729 snd_trident_spurious_threshold
731 Description: This routine converts rate in HZ to spurious threshold.
733 Parameters: trident - pointer to target device class for 4DWave.
734 rate - Real or Virtual channel number.
736 Returns: Delta value.
738 ---------------------------------------------------------------------------*/
739 static unsigned int snd_trident_spurious_threshold(unsigned int rate
,
740 unsigned int period_size
)
742 unsigned int res
= (rate
* period_size
) / 48000;
750 /*---------------------------------------------------------------------------
751 snd_trident_control_mode
753 Description: This routine returns a control mode for a PCM channel.
755 Parameters: trident - pointer to target device class for 4DWave.
756 substream - PCM substream
758 Returns: Control value.
760 ---------------------------------------------------------------------------*/
761 static unsigned int snd_trident_control_mode(struct snd_pcm_substream
*substream
)
764 struct snd_pcm_runtime
*runtime
= substream
->runtime
;
767 CTRL default: 8-bit (unsigned) mono, loop mode enabled
770 if (snd_pcm_format_width(runtime
->format
) == 16)
771 CTRL
|= 0x00000008; // 16-bit data
772 if (snd_pcm_format_signed(runtime
->format
))
773 CTRL
|= 0x00000002; // signed data
774 if (runtime
->channels
> 1)
775 CTRL
|= 0x00000004; // stereo data
783 /*---------------------------------------------------------------------------
786 Description: Device I/O control handler for playback/capture parameters.
788 Parameters: substream - PCM substream class
789 cmd - what ioctl message to process
790 arg - additional message infoarg
792 Returns: Error status
794 ---------------------------------------------------------------------------*/
796 static int snd_trident_ioctl(struct snd_pcm_substream
*substream
,
800 /* FIXME: it seems that with small periods the behaviour of
801 trident hardware is unpredictable and interrupt generator
803 return snd_pcm_lib_ioctl(substream
, cmd
, arg
);
806 /*---------------------------------------------------------------------------
807 snd_trident_allocate_pcm_mem
809 Description: Allocate PCM ring buffer for given substream
811 Parameters: substream - PCM substream class
812 hw_params - hardware parameters
814 Returns: Error status
816 ---------------------------------------------------------------------------*/
818 static int snd_trident_allocate_pcm_mem(struct snd_pcm_substream
*substream
,
819 struct snd_pcm_hw_params
*hw_params
)
821 struct snd_trident
*trident
= snd_pcm_substream_chip(substream
);
822 struct snd_pcm_runtime
*runtime
= substream
->runtime
;
823 struct snd_trident_voice
*voice
= runtime
->private_data
;
826 if ((err
= snd_pcm_lib_malloc_pages(substream
, params_buffer_bytes(hw_params
))) < 0)
828 if (trident
->tlb
.entries
) {
829 if (err
> 0) { /* change */
831 snd_trident_free_pages(trident
, voice
->memblk
);
832 voice
->memblk
= snd_trident_alloc_pages(trident
, substream
);
833 if (voice
->memblk
== NULL
)
840 /*---------------------------------------------------------------------------
841 snd_trident_allocate_evoice
843 Description: Allocate extra voice as interrupt generator
845 Parameters: substream - PCM substream class
846 hw_params - hardware parameters
848 Returns: Error status
850 ---------------------------------------------------------------------------*/
852 static int snd_trident_allocate_evoice(struct snd_pcm_substream
*substream
,
853 struct snd_pcm_hw_params
*hw_params
)
855 struct snd_trident
*trident
= snd_pcm_substream_chip(substream
);
856 struct snd_pcm_runtime
*runtime
= substream
->runtime
;
857 struct snd_trident_voice
*voice
= runtime
->private_data
;
858 struct snd_trident_voice
*evoice
= voice
->extra
;
860 /* voice management */
862 if (params_buffer_size(hw_params
) / 2 != params_period_size(hw_params
)) {
863 if (evoice
== NULL
) {
864 evoice
= snd_trident_alloc_voice(trident
, SNDRV_TRIDENT_VOICE_TYPE_PCM
, 0, 0);
867 voice
->extra
= evoice
;
868 evoice
->substream
= substream
;
871 if (evoice
!= NULL
) {
872 snd_trident_free_voice(trident
, evoice
);
873 voice
->extra
= evoice
= NULL
;
880 /*---------------------------------------------------------------------------
881 snd_trident_hw_params
883 Description: Set the hardware parameters for the playback device.
885 Parameters: substream - PCM substream class
886 hw_params - hardware parameters
888 Returns: Error status
890 ---------------------------------------------------------------------------*/
892 static int snd_trident_hw_params(struct snd_pcm_substream
*substream
,
893 struct snd_pcm_hw_params
*hw_params
)
897 err
= snd_trident_allocate_pcm_mem(substream
, hw_params
);
899 err
= snd_trident_allocate_evoice(substream
, hw_params
);
903 /*---------------------------------------------------------------------------
904 snd_trident_playback_hw_free
906 Description: Release the hardware resources for the playback device.
908 Parameters: substream - PCM substream class
910 Returns: Error status
912 ---------------------------------------------------------------------------*/
914 static int snd_trident_hw_free(struct snd_pcm_substream
*substream
)
916 struct snd_trident
*trident
= snd_pcm_substream_chip(substream
);
917 struct snd_pcm_runtime
*runtime
= substream
->runtime
;
918 struct snd_trident_voice
*voice
= runtime
->private_data
;
919 struct snd_trident_voice
*evoice
= voice
? voice
->extra
: NULL
;
921 if (trident
->tlb
.entries
) {
922 if (voice
&& voice
->memblk
) {
923 snd_trident_free_pages(trident
, voice
->memblk
);
924 voice
->memblk
= NULL
;
927 snd_pcm_lib_free_pages(substream
);
928 if (evoice
!= NULL
) {
929 snd_trident_free_voice(trident
, evoice
);
935 /*---------------------------------------------------------------------------
936 snd_trident_playback_prepare
938 Description: Prepare playback device for playback.
940 Parameters: substream - PCM substream class
942 Returns: Error status
944 ---------------------------------------------------------------------------*/
946 static int snd_trident_playback_prepare(struct snd_pcm_substream
*substream
)
948 struct snd_trident
*trident
= snd_pcm_substream_chip(substream
);
949 struct snd_pcm_runtime
*runtime
= substream
->runtime
;
950 struct snd_trident_voice
*voice
= runtime
->private_data
;
951 struct snd_trident_voice
*evoice
= voice
->extra
;
952 struct snd_trident_pcm_mixer
*mix
= &trident
->pcm_mixer
[substream
->number
];
954 spin_lock_irq(&trident
->reg_lock
);
956 /* set delta (rate) value */
957 voice
->Delta
= snd_trident_convert_rate(runtime
->rate
);
958 voice
->spurious_threshold
= snd_trident_spurious_threshold(runtime
->rate
, runtime
->period_size
);
960 /* set Loop Begin Address */
962 voice
->LBA
= voice
->memblk
->offset
;
964 voice
->LBA
= runtime
->dma_addr
;
967 voice
->ESO
= runtime
->buffer_size
- 1; /* in samples */
968 voice
->CTRL
= snd_trident_control_mode(substream
);
974 voice
->Vol
= mix
->vol
;
975 voice
->RVol
= mix
->rvol
;
976 voice
->CVol
= mix
->cvol
;
977 voice
->Pan
= mix
->pan
;
978 voice
->Attribute
= 0;
980 voice
->Attribute
= (1<<(30-16))|(2<<(26-16))|
981 (0<<(24-16))|(0x1f<<(19-16));
983 voice
->Attribute
= 0;
986 snd_trident_write_voice_regs(trident
, voice
);
988 if (evoice
!= NULL
) {
989 evoice
->Delta
= voice
->Delta
;
990 evoice
->spurious_threshold
= voice
->spurious_threshold
;
991 evoice
->LBA
= voice
->LBA
;
993 evoice
->ESO
= (runtime
->period_size
* 2) + 4 - 1; /* in samples */
994 evoice
->CTRL
= voice
->CTRL
;
996 evoice
->GVSel
= trident
->device
== TRIDENT_DEVICE_ID_SI7018
? 0 : 1;
1000 evoice
->Vol
= 0x3ff; /* mute */
1001 evoice
->RVol
= evoice
->CVol
= 0x7f; /* mute */
1002 evoice
->Pan
= 0x7f; /* mute */
1004 evoice
->Attribute
= (1<<(30-16))|(2<<(26-16))|
1005 (0<<(24-16))|(0x1f<<(19-16));
1007 evoice
->Attribute
= 0;
1009 snd_trident_write_voice_regs(trident
, evoice
);
1011 evoice
->isync_mark
= runtime
->period_size
;
1012 evoice
->ESO
= (runtime
->period_size
* 2) - 1;
1015 spin_unlock_irq(&trident
->reg_lock
);
1020 /*---------------------------------------------------------------------------
1021 snd_trident_capture_hw_params
1023 Description: Set the hardware parameters for the capture device.
1025 Parameters: substream - PCM substream class
1026 hw_params - hardware parameters
1028 Returns: Error status
1030 ---------------------------------------------------------------------------*/
1032 static int snd_trident_capture_hw_params(struct snd_pcm_substream
*substream
,
1033 struct snd_pcm_hw_params
*hw_params
)
1035 return snd_trident_allocate_pcm_mem(substream
, hw_params
);
1038 /*---------------------------------------------------------------------------
1039 snd_trident_capture_prepare
1041 Description: Prepare capture device for playback.
1043 Parameters: substream - PCM substream class
1045 Returns: Error status
1047 ---------------------------------------------------------------------------*/
1049 static int snd_trident_capture_prepare(struct snd_pcm_substream
*substream
)
1051 struct snd_trident
*trident
= snd_pcm_substream_chip(substream
);
1052 struct snd_pcm_runtime
*runtime
= substream
->runtime
;
1053 struct snd_trident_voice
*voice
= runtime
->private_data
;
1054 unsigned int val
, ESO_bytes
;
1056 spin_lock_irq(&trident
->reg_lock
);
1058 // Initilize the channel and set channel Mode
1059 outb(0, TRID_REG(trident
, LEGACY_DMAR15
));
1061 // Set DMA channel operation mode register
1062 outb(0x54, TRID_REG(trident
, LEGACY_DMAR11
));
1064 // Set channel buffer Address, DMAR0 expects contiguous PCI memory area
1065 voice
->LBA
= runtime
->dma_addr
;
1066 outl(voice
->LBA
, TRID_REG(trident
, LEGACY_DMAR0
));
1068 voice
->LBA
= voice
->memblk
->offset
;
1071 ESO_bytes
= snd_pcm_lib_buffer_bytes(substream
) - 1;
1072 outb((ESO_bytes
& 0x00ff0000) >> 16, TRID_REG(trident
, LEGACY_DMAR6
));
1073 outw((ESO_bytes
& 0x0000ffff), TRID_REG(trident
, LEGACY_DMAR4
));
1076 // Set channel sample rate, 4.12 format
1077 val
= (((unsigned int) 48000L << 12) + (runtime
->rate
/2)) / runtime
->rate
;
1078 outw(val
, TRID_REG(trident
, T4D_SBDELTA_DELTA_R
));
1080 // Set channel interrupt blk length
1081 if (snd_pcm_format_width(runtime
->format
) == 16) {
1082 val
= (unsigned short) ((ESO_bytes
>> 1) - 1);
1084 val
= (unsigned short) (ESO_bytes
- 1);
1087 outl((val
<< 16) | val
, TRID_REG(trident
, T4D_SBBL_SBCL
));
1089 // Right now, set format and start to run captureing,
1090 // continuous run loop enable.
1091 trident
->bDMAStart
= 0x19; // 0001 1001b
1093 if (snd_pcm_format_width(runtime
->format
) == 16)
1094 trident
->bDMAStart
|= 0x80;
1095 if (snd_pcm_format_signed(runtime
->format
))
1096 trident
->bDMAStart
|= 0x20;
1097 if (runtime
->channels
> 1)
1098 trident
->bDMAStart
|= 0x40;
1100 // Prepare capture intr channel
1102 voice
->Delta
= snd_trident_convert_rate(runtime
->rate
);
1103 voice
->spurious_threshold
= snd_trident_spurious_threshold(runtime
->rate
, runtime
->period_size
);
1105 voice
->isync_mark
= runtime
->period_size
;
1106 voice
->isync_max
= runtime
->buffer_size
;
1108 // Set voice parameters
1110 voice
->ESO
= voice
->isync_ESO
= (runtime
->period_size
* 2) + 6 - 1;
1111 voice
->CTRL
= snd_trident_control_mode(substream
);
1116 voice
->Pan
= 0x7f; /* mute */
1117 voice
->Vol
= 0x3ff; /* mute */
1121 voice
->Attribute
= 0;
1123 snd_trident_write_voice_regs(trident
, voice
);
1125 spin_unlock_irq(&trident
->reg_lock
);
1129 /*---------------------------------------------------------------------------
1130 snd_trident_si7018_capture_hw_params
1132 Description: Set the hardware parameters for the capture device.
1134 Parameters: substream - PCM substream class
1135 hw_params - hardware parameters
1137 Returns: Error status
1139 ---------------------------------------------------------------------------*/
1141 static int snd_trident_si7018_capture_hw_params(struct snd_pcm_substream
*substream
,
1142 struct snd_pcm_hw_params
*hw_params
)
1146 if ((err
= snd_pcm_lib_malloc_pages(substream
, params_buffer_bytes(hw_params
))) < 0)
1149 return snd_trident_allocate_evoice(substream
, hw_params
);
1152 /*---------------------------------------------------------------------------
1153 snd_trident_si7018_capture_hw_free
1155 Description: Release the hardware resources for the capture device.
1157 Parameters: substream - PCM substream class
1159 Returns: Error status
1161 ---------------------------------------------------------------------------*/
1163 static int snd_trident_si7018_capture_hw_free(struct snd_pcm_substream
*substream
)
1165 struct snd_trident
*trident
= snd_pcm_substream_chip(substream
);
1166 struct snd_pcm_runtime
*runtime
= substream
->runtime
;
1167 struct snd_trident_voice
*voice
= runtime
->private_data
;
1168 struct snd_trident_voice
*evoice
= voice
? voice
->extra
: NULL
;
1170 snd_pcm_lib_free_pages(substream
);
1171 if (evoice
!= NULL
) {
1172 snd_trident_free_voice(trident
, evoice
);
1173 voice
->extra
= NULL
;
1178 /*---------------------------------------------------------------------------
1179 snd_trident_si7018_capture_prepare
1181 Description: Prepare capture device for playback.
1183 Parameters: substream - PCM substream class
1185 Returns: Error status
1187 ---------------------------------------------------------------------------*/
1189 static int snd_trident_si7018_capture_prepare(struct snd_pcm_substream
*substream
)
1191 struct snd_trident
*trident
= snd_pcm_substream_chip(substream
);
1192 struct snd_pcm_runtime
*runtime
= substream
->runtime
;
1193 struct snd_trident_voice
*voice
= runtime
->private_data
;
1194 struct snd_trident_voice
*evoice
= voice
->extra
;
1196 spin_lock_irq(&trident
->reg_lock
);
1198 voice
->LBA
= runtime
->dma_addr
;
1199 voice
->Delta
= snd_trident_convert_adc_rate(runtime
->rate
);
1200 voice
->spurious_threshold
= snd_trident_spurious_threshold(runtime
->rate
, runtime
->period_size
);
1202 // Set voice parameters
1204 voice
->ESO
= runtime
->buffer_size
- 1; /* in samples */
1205 voice
->CTRL
= snd_trident_control_mode(substream
);
1210 voice
->Pan
= T4D_DEFAULT_PCM_PAN
;
1216 voice
->Attribute
= (2 << (30-16)) |
1221 snd_trident_write_voice_regs(trident
, voice
);
1223 if (evoice
!= NULL
) {
1224 evoice
->Delta
= snd_trident_convert_rate(runtime
->rate
);
1225 evoice
->spurious_threshold
= voice
->spurious_threshold
;
1226 evoice
->LBA
= voice
->LBA
;
1228 evoice
->ESO
= (runtime
->period_size
* 2) + 20 - 1; /* in samples, 20 means correction */
1229 evoice
->CTRL
= voice
->CTRL
;
1235 evoice
->Vol
= 0x3ff; /* mute */
1236 evoice
->RVol
= evoice
->CVol
= 0x7f; /* mute */
1237 evoice
->Pan
= 0x7f; /* mute */
1238 evoice
->Attribute
= 0;
1239 snd_trident_write_voice_regs(trident
, evoice
);
1241 evoice
->isync_mark
= runtime
->period_size
;
1242 evoice
->ESO
= (runtime
->period_size
* 2) - 1;
1245 spin_unlock_irq(&trident
->reg_lock
);
1249 /*---------------------------------------------------------------------------
1250 snd_trident_foldback_prepare
1252 Description: Prepare foldback capture device for playback.
1254 Parameters: substream - PCM substream class
1256 Returns: Error status
1258 ---------------------------------------------------------------------------*/
1260 static int snd_trident_foldback_prepare(struct snd_pcm_substream
*substream
)
1262 struct snd_trident
*trident
= snd_pcm_substream_chip(substream
);
1263 struct snd_pcm_runtime
*runtime
= substream
->runtime
;
1264 struct snd_trident_voice
*voice
= runtime
->private_data
;
1265 struct snd_trident_voice
*evoice
= voice
->extra
;
1267 spin_lock_irq(&trident
->reg_lock
);
1269 /* Set channel buffer Address */
1271 voice
->LBA
= voice
->memblk
->offset
;
1273 voice
->LBA
= runtime
->dma_addr
;
1275 /* set target ESO for channel */
1276 voice
->ESO
= runtime
->buffer_size
- 1; /* in samples */
1278 /* set sample rate */
1279 voice
->Delta
= 0x1000;
1280 voice
->spurious_threshold
= snd_trident_spurious_threshold(48000, runtime
->period_size
);
1283 voice
->CTRL
= snd_trident_control_mode(substream
);
1288 voice
->Pan
= 0x7f; /* mute */
1289 voice
->Vol
= 0x3ff; /* mute */
1293 voice
->Attribute
= 0;
1295 /* set up capture channel */
1296 outb(((voice
->number
& 0x3f) | 0x80), TRID_REG(trident
, T4D_RCI
+ voice
->foldback_chan
));
1298 snd_trident_write_voice_regs(trident
, voice
);
1300 if (evoice
!= NULL
) {
1301 evoice
->Delta
= voice
->Delta
;
1302 evoice
->spurious_threshold
= voice
->spurious_threshold
;
1303 evoice
->LBA
= voice
->LBA
;
1305 evoice
->ESO
= (runtime
->period_size
* 2) + 4 - 1; /* in samples */
1306 evoice
->CTRL
= voice
->CTRL
;
1308 evoice
->GVSel
= trident
->device
== TRIDENT_DEVICE_ID_SI7018
? 0 : 1;
1312 evoice
->Vol
= 0x3ff; /* mute */
1313 evoice
->RVol
= evoice
->CVol
= 0x7f; /* mute */
1314 evoice
->Pan
= 0x7f; /* mute */
1315 evoice
->Attribute
= 0;
1316 snd_trident_write_voice_regs(trident
, evoice
);
1318 evoice
->isync_mark
= runtime
->period_size
;
1319 evoice
->ESO
= (runtime
->period_size
* 2) - 1;
1322 spin_unlock_irq(&trident
->reg_lock
);
1326 /*---------------------------------------------------------------------------
1327 snd_trident_spdif_hw_params
1329 Description: Set the hardware parameters for the spdif device.
1331 Parameters: substream - PCM substream class
1332 hw_params - hardware parameters
1334 Returns: Error status
1336 ---------------------------------------------------------------------------*/
1338 static int snd_trident_spdif_hw_params(struct snd_pcm_substream
*substream
,
1339 struct snd_pcm_hw_params
*hw_params
)
1341 struct snd_trident
*trident
= snd_pcm_substream_chip(substream
);
1342 unsigned int old_bits
= 0, change
= 0;
1345 err
= snd_trident_allocate_pcm_mem(substream
, hw_params
);
1349 if (trident
->device
== TRIDENT_DEVICE_ID_SI7018
) {
1350 err
= snd_trident_allocate_evoice(substream
, hw_params
);
1355 /* prepare SPDIF channel */
1356 spin_lock_irq(&trident
->reg_lock
);
1357 old_bits
= trident
->spdif_pcm_bits
;
1358 if (old_bits
& IEC958_AES0_PROFESSIONAL
)
1359 trident
->spdif_pcm_bits
&= ~IEC958_AES0_PRO_FS
;
1361 trident
->spdif_pcm_bits
&= ~(IEC958_AES3_CON_FS
<< 24);
1362 if (params_rate(hw_params
) >= 48000) {
1363 trident
->spdif_pcm_ctrl
= 0x3c; // 48000 Hz
1364 trident
->spdif_pcm_bits
|=
1365 trident
->spdif_bits
& IEC958_AES0_PROFESSIONAL
?
1366 IEC958_AES0_PRO_FS_48000
:
1367 (IEC958_AES3_CON_FS_48000
<< 24);
1369 else if (params_rate(hw_params
) >= 44100) {
1370 trident
->spdif_pcm_ctrl
= 0x3e; // 44100 Hz
1371 trident
->spdif_pcm_bits
|=
1372 trident
->spdif_bits
& IEC958_AES0_PROFESSIONAL
?
1373 IEC958_AES0_PRO_FS_44100
:
1374 (IEC958_AES3_CON_FS_44100
<< 24);
1377 trident
->spdif_pcm_ctrl
= 0x3d; // 32000 Hz
1378 trident
->spdif_pcm_bits
|=
1379 trident
->spdif_bits
& IEC958_AES0_PROFESSIONAL
?
1380 IEC958_AES0_PRO_FS_32000
:
1381 (IEC958_AES3_CON_FS_32000
<< 24);
1383 change
= old_bits
!= trident
->spdif_pcm_bits
;
1384 spin_unlock_irq(&trident
->reg_lock
);
1387 snd_ctl_notify(trident
->card
, SNDRV_CTL_EVENT_MASK_VALUE
, &trident
->spdif_pcm_ctl
->id
);
1392 /*---------------------------------------------------------------------------
1393 snd_trident_spdif_prepare
1395 Description: Prepare SPDIF device for playback.
1397 Parameters: substream - PCM substream class
1399 Returns: Error status
1401 ---------------------------------------------------------------------------*/
1403 static int snd_trident_spdif_prepare(struct snd_pcm_substream
*substream
)
1405 struct snd_trident
*trident
= snd_pcm_substream_chip(substream
);
1406 struct snd_pcm_runtime
*runtime
= substream
->runtime
;
1407 struct snd_trident_voice
*voice
= runtime
->private_data
;
1408 struct snd_trident_voice
*evoice
= voice
->extra
;
1409 struct snd_trident_pcm_mixer
*mix
= &trident
->pcm_mixer
[substream
->number
];
1410 unsigned int RESO
, LBAO
;
1413 spin_lock_irq(&trident
->reg_lock
);
1415 if (trident
->device
!= TRIDENT_DEVICE_ID_SI7018
) {
1417 /* set delta (rate) value */
1418 voice
->Delta
= snd_trident_convert_rate(runtime
->rate
);
1419 voice
->spurious_threshold
= snd_trident_spurious_threshold(runtime
->rate
, runtime
->period_size
);
1421 /* set Loop Back Address */
1422 LBAO
= runtime
->dma_addr
;
1424 voice
->LBA
= voice
->memblk
->offset
;
1430 voice
->isync_mark
= runtime
->period_size
;
1431 voice
->isync_max
= runtime
->buffer_size
;
1433 /* set target ESO for channel */
1434 RESO
= runtime
->buffer_size
- 1;
1435 voice
->ESO
= voice
->isync_ESO
= (runtime
->period_size
* 2) + 6 - 1;
1438 voice
->CTRL
= snd_trident_control_mode(substream
);
1450 voice
->Attribute
= 0;
1452 /* prepare surrogate IRQ channel */
1453 snd_trident_write_voice_regs(trident
, voice
);
1455 outw((RESO
& 0xffff), TRID_REG(trident
, NX_SPESO
));
1456 outb((RESO
>> 16), TRID_REG(trident
, NX_SPESO
+ 2));
1457 outl((LBAO
& 0xfffffffc), TRID_REG(trident
, NX_SPLBA
));
1458 outw((voice
->CSO
& 0xffff), TRID_REG(trident
, NX_SPCTRL_SPCSO
));
1459 outb((voice
->CSO
>> 16), TRID_REG(trident
, NX_SPCTRL_SPCSO
+ 2));
1461 /* set SPDIF setting */
1462 outb(trident
->spdif_pcm_ctrl
, TRID_REG(trident
, NX_SPCTRL_SPCSO
+ 3));
1463 outl(trident
->spdif_pcm_bits
, TRID_REG(trident
, NX_SPCSTATUS
));
1467 /* set delta (rate) value */
1468 voice
->Delta
= 0x800;
1469 voice
->spurious_threshold
= snd_trident_spurious_threshold(48000, runtime
->period_size
);
1471 /* set Loop Begin Address */
1473 voice
->LBA
= voice
->memblk
->offset
;
1475 voice
->LBA
= runtime
->dma_addr
;
1478 voice
->ESO
= runtime
->buffer_size
- 1; /* in samples */
1479 voice
->CTRL
= snd_trident_control_mode(substream
);
1485 voice
->Vol
= mix
->vol
;
1486 voice
->RVol
= mix
->rvol
;
1487 voice
->CVol
= mix
->cvol
;
1488 voice
->Pan
= mix
->pan
;
1489 voice
->Attribute
= (1<<(30-16))|(7<<(26-16))|
1490 (0<<(24-16))|(0<<(19-16));
1492 snd_trident_write_voice_regs(trident
, voice
);
1494 if (evoice
!= NULL
) {
1495 evoice
->Delta
= voice
->Delta
;
1496 evoice
->spurious_threshold
= voice
->spurious_threshold
;
1497 evoice
->LBA
= voice
->LBA
;
1499 evoice
->ESO
= (runtime
->period_size
* 2) + 4 - 1; /* in samples */
1500 evoice
->CTRL
= voice
->CTRL
;
1502 evoice
->GVSel
= trident
->device
== TRIDENT_DEVICE_ID_SI7018
? 0 : 1;
1506 evoice
->Vol
= 0x3ff; /* mute */
1507 evoice
->RVol
= evoice
->CVol
= 0x7f; /* mute */
1508 evoice
->Pan
= 0x7f; /* mute */
1509 evoice
->Attribute
= 0;
1510 snd_trident_write_voice_regs(trident
, evoice
);
1512 evoice
->isync_mark
= runtime
->period_size
;
1513 evoice
->ESO
= (runtime
->period_size
* 2) - 1;
1516 outl(trident
->spdif_pcm_bits
, TRID_REG(trident
, SI_SPDIF_CS
));
1517 temp
= inl(TRID_REG(trident
, T4D_LFO_GC_CIR
));
1519 outl(temp
, TRID_REG(trident
, T4D_LFO_GC_CIR
));
1520 temp
= inl(TRID_REG(trident
, SI_SERIAL_INTF_CTRL
));
1522 outl(temp
, TRID_REG(trident
, SI_SERIAL_INTF_CTRL
));
1525 spin_unlock_irq(&trident
->reg_lock
);
1530 /*---------------------------------------------------------------------------
1533 Description: Start/stop devices
1535 Parameters: substream - PCM substream class
1536 cmd - trigger command (STOP, GO)
1538 Returns: Error status
1540 ---------------------------------------------------------------------------*/
1542 static int snd_trident_trigger(struct snd_pcm_substream
*substream
,
1546 struct snd_trident
*trident
= snd_pcm_substream_chip(substream
);
1547 struct snd_pcm_substream
*s
;
1548 unsigned int what
, whati
, capture_flag
, spdif_flag
;
1549 struct snd_trident_voice
*voice
, *evoice
;
1550 unsigned int val
, go
;
1553 case SNDRV_PCM_TRIGGER_START
:
1554 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE
:
1555 case SNDRV_PCM_TRIGGER_RESUME
:
1558 case SNDRV_PCM_TRIGGER_STOP
:
1559 case SNDRV_PCM_TRIGGER_PAUSE_PUSH
:
1560 case SNDRV_PCM_TRIGGER_SUSPEND
:
1566 what
= whati
= capture_flag
= spdif_flag
= 0;
1567 spin_lock(&trident
->reg_lock
);
1568 val
= inl(TRID_REG(trident
, T4D_STIMER
)) & 0x00ffffff;
1569 snd_pcm_group_for_each_entry(s
, substream
) {
1570 if ((struct snd_trident
*) snd_pcm_substream_chip(s
) == trident
) {
1571 voice
= s
->runtime
->private_data
;
1572 evoice
= voice
->extra
;
1573 what
|= 1 << (voice
->number
& 0x1f);
1574 if (evoice
== NULL
) {
1575 whati
|= 1 << (voice
->number
& 0x1f);
1577 what
|= 1 << (evoice
->number
& 0x1f);
1578 whati
|= 1 << (evoice
->number
& 0x1f);
1580 evoice
->stimer
= val
;
1584 voice
->stimer
= val
;
1588 snd_pcm_trigger_done(s
, substream
);
1596 if (trident
->device
!= TRIDENT_DEVICE_ID_SI7018
) {
1597 outl(trident
->spdif_pcm_bits
, TRID_REG(trident
, NX_SPCSTATUS
));
1598 val
= trident
->spdif_pcm_ctrl
;
1601 outb(val
, TRID_REG(trident
, NX_SPCTRL_SPCSO
+ 3));
1603 outl(trident
->spdif_pcm_bits
, TRID_REG(trident
, SI_SPDIF_CS
));
1604 val
= inl(TRID_REG(trident
, SI_SERIAL_INTF_CTRL
)) | SPDIF_EN
;
1605 outl(val
, TRID_REG(trident
, SI_SERIAL_INTF_CTRL
));
1609 outl(what
, TRID_REG(trident
, T4D_STOP_B
));
1610 val
= inl(TRID_REG(trident
, T4D_AINTEN_B
));
1616 outl(val
, TRID_REG(trident
, T4D_AINTEN_B
));
1618 outl(what
, TRID_REG(trident
, T4D_START_B
));
1620 if (capture_flag
&& trident
->device
!= TRIDENT_DEVICE_ID_SI7018
)
1621 outb(trident
->bDMAStart
, TRID_REG(trident
, T4D_SBCTRL_SBE2R_SBDD
));
1623 if (capture_flag
&& trident
->device
!= TRIDENT_DEVICE_ID_SI7018
)
1624 outb(0x00, TRID_REG(trident
, T4D_SBCTRL_SBE2R_SBDD
));
1626 spin_unlock(&trident
->reg_lock
);
1630 /*---------------------------------------------------------------------------
1631 snd_trident_playback_pointer
1633 Description: This routine return the playback position
1635 Parameters: substream - PCM substream class
1637 Returns: position of buffer
1639 ---------------------------------------------------------------------------*/
1641 static snd_pcm_uframes_t
snd_trident_playback_pointer(struct snd_pcm_substream
*substream
)
1643 struct snd_trident
*trident
= snd_pcm_substream_chip(substream
);
1644 struct snd_pcm_runtime
*runtime
= substream
->runtime
;
1645 struct snd_trident_voice
*voice
= runtime
->private_data
;
1648 if (!voice
->running
)
1651 spin_lock(&trident
->reg_lock
);
1653 outb(voice
->number
, TRID_REG(trident
, T4D_LFO_GC_CIR
));
1655 if (trident
->device
!= TRIDENT_DEVICE_ID_NX
) {
1656 cso
= inw(TRID_REG(trident
, CH_DX_CSO_ALPHA_FMS
+ 2));
1657 } else { // ID_4DWAVE_NX
1658 cso
= (unsigned int) inl(TRID_REG(trident
, CH_NX_DELTA_CSO
)) & 0x00ffffff;
1661 spin_unlock(&trident
->reg_lock
);
1663 if (cso
>= runtime
->buffer_size
)
1669 /*---------------------------------------------------------------------------
1670 snd_trident_capture_pointer
1672 Description: This routine return the capture position
1674 Parameters: pcm1 - PCM device class
1676 Returns: position of buffer
1678 ---------------------------------------------------------------------------*/
1680 static snd_pcm_uframes_t
snd_trident_capture_pointer(struct snd_pcm_substream
*substream
)
1682 struct snd_trident
*trident
= snd_pcm_substream_chip(substream
);
1683 struct snd_pcm_runtime
*runtime
= substream
->runtime
;
1684 struct snd_trident_voice
*voice
= runtime
->private_data
;
1685 unsigned int result
;
1687 if (!voice
->running
)
1690 result
= inw(TRID_REG(trident
, T4D_SBBL_SBCL
));
1691 if (runtime
->channels
> 1)
1694 result
= runtime
->buffer_size
- result
;
1699 /*---------------------------------------------------------------------------
1700 snd_trident_spdif_pointer
1702 Description: This routine return the SPDIF playback position
1704 Parameters: substream - PCM substream class
1706 Returns: position of buffer
1708 ---------------------------------------------------------------------------*/
1710 static snd_pcm_uframes_t
snd_trident_spdif_pointer(struct snd_pcm_substream
*substream
)
1712 struct snd_trident
*trident
= snd_pcm_substream_chip(substream
);
1713 struct snd_pcm_runtime
*runtime
= substream
->runtime
;
1714 struct snd_trident_voice
*voice
= runtime
->private_data
;
1715 unsigned int result
;
1717 if (!voice
->running
)
1720 result
= inl(TRID_REG(trident
, NX_SPCTRL_SPCSO
)) & 0x00ffffff;
1726 * Playback support device description
1729 static struct snd_pcm_hardware snd_trident_playback
=
1731 .info
= (SNDRV_PCM_INFO_MMAP
| SNDRV_PCM_INFO_INTERLEAVED
|
1732 SNDRV_PCM_INFO_BLOCK_TRANSFER
|
1733 SNDRV_PCM_INFO_MMAP_VALID
| SNDRV_PCM_INFO_SYNC_START
|
1734 SNDRV_PCM_INFO_PAUSE
/* | SNDRV_PCM_INFO_RESUME */),
1735 .formats
= (SNDRV_PCM_FMTBIT_U8
| SNDRV_PCM_FMTBIT_S16_LE
|
1736 SNDRV_PCM_FMTBIT_S8
| SNDRV_PCM_FMTBIT_U16_LE
),
1737 .rates
= SNDRV_PCM_RATE_CONTINUOUS
| SNDRV_PCM_RATE_8000_48000
,
1742 .buffer_bytes_max
= (256*1024),
1743 .period_bytes_min
= 64,
1744 .period_bytes_max
= (256*1024),
1746 .periods_max
= 1024,
1751 * Capture support device description
1754 static struct snd_pcm_hardware snd_trident_capture
=
1756 .info
= (SNDRV_PCM_INFO_MMAP
| SNDRV_PCM_INFO_INTERLEAVED
|
1757 SNDRV_PCM_INFO_BLOCK_TRANSFER
|
1758 SNDRV_PCM_INFO_MMAP_VALID
| SNDRV_PCM_INFO_SYNC_START
|
1759 SNDRV_PCM_INFO_PAUSE
/* | SNDRV_PCM_INFO_RESUME */),
1760 .formats
= (SNDRV_PCM_FMTBIT_U8
| SNDRV_PCM_FMTBIT_S16_LE
|
1761 SNDRV_PCM_FMTBIT_S8
| SNDRV_PCM_FMTBIT_U16_LE
),
1762 .rates
= SNDRV_PCM_RATE_CONTINUOUS
| SNDRV_PCM_RATE_8000_48000
,
1767 .buffer_bytes_max
= (128*1024),
1768 .period_bytes_min
= 64,
1769 .period_bytes_max
= (128*1024),
1771 .periods_max
= 1024,
1776 * Foldback capture support device description
1779 static struct snd_pcm_hardware snd_trident_foldback
=
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,
1800 * SPDIF playback support device description
1803 static struct snd_pcm_hardware snd_trident_spdif
=
1805 .info
= (SNDRV_PCM_INFO_MMAP
| SNDRV_PCM_INFO_INTERLEAVED
|
1806 SNDRV_PCM_INFO_BLOCK_TRANSFER
|
1807 SNDRV_PCM_INFO_MMAP_VALID
| SNDRV_PCM_INFO_SYNC_START
|
1808 SNDRV_PCM_INFO_PAUSE
/* | SNDRV_PCM_INFO_RESUME */),
1809 .formats
= SNDRV_PCM_FMTBIT_S16_LE
,
1810 .rates
= (SNDRV_PCM_RATE_32000
| SNDRV_PCM_RATE_44100
|
1811 SNDRV_PCM_RATE_48000
),
1816 .buffer_bytes_max
= (128*1024),
1817 .period_bytes_min
= 64,
1818 .period_bytes_max
= (128*1024),
1820 .periods_max
= 1024,
1824 static struct snd_pcm_hardware snd_trident_spdif_7018
=
1826 .info
= (SNDRV_PCM_INFO_MMAP
| SNDRV_PCM_INFO_INTERLEAVED
|
1827 SNDRV_PCM_INFO_BLOCK_TRANSFER
|
1828 SNDRV_PCM_INFO_MMAP_VALID
| SNDRV_PCM_INFO_SYNC_START
|
1829 SNDRV_PCM_INFO_PAUSE
/* | SNDRV_PCM_INFO_RESUME */),
1830 .formats
= SNDRV_PCM_FMTBIT_S16_LE
,
1831 .rates
= SNDRV_PCM_RATE_48000
,
1836 .buffer_bytes_max
= (128*1024),
1837 .period_bytes_min
= 64,
1838 .period_bytes_max
= (128*1024),
1840 .periods_max
= 1024,
1844 static void snd_trident_pcm_free_substream(struct snd_pcm_runtime
*runtime
)
1846 struct snd_trident_voice
*voice
= runtime
->private_data
;
1847 struct snd_trident
*trident
;
1850 trident
= voice
->trident
;
1851 snd_trident_free_voice(trident
, voice
);
1855 static int snd_trident_playback_open(struct snd_pcm_substream
*substream
)
1857 struct snd_trident
*trident
= snd_pcm_substream_chip(substream
);
1858 struct snd_pcm_runtime
*runtime
= substream
->runtime
;
1859 struct snd_trident_voice
*voice
;
1861 voice
= snd_trident_alloc_voice(trident
, SNDRV_TRIDENT_VOICE_TYPE_PCM
, 0, 0);
1864 snd_trident_pcm_mixer_build(trident
, voice
, substream
);
1865 voice
->substream
= substream
;
1866 runtime
->private_data
= voice
;
1867 runtime
->private_free
= snd_trident_pcm_free_substream
;
1868 runtime
->hw
= snd_trident_playback
;
1869 snd_pcm_set_sync(substream
);
1870 snd_pcm_hw_constraint_minmax(runtime
, SNDRV_PCM_HW_PARAM_BUFFER_SIZE
, 0, 64*1024);
1874 /*---------------------------------------------------------------------------
1875 snd_trident_playback_close
1877 Description: This routine will close the 4DWave playback device. For now
1878 we will simply free the dma transfer buffer.
1880 Parameters: substream - PCM substream class
1882 ---------------------------------------------------------------------------*/
1883 static int snd_trident_playback_close(struct snd_pcm_substream
*substream
)
1885 struct snd_trident
*trident
= snd_pcm_substream_chip(substream
);
1886 struct snd_pcm_runtime
*runtime
= substream
->runtime
;
1887 struct snd_trident_voice
*voice
= runtime
->private_data
;
1889 snd_trident_pcm_mixer_free(trident
, voice
, substream
);
1893 /*---------------------------------------------------------------------------
1894 snd_trident_spdif_open
1896 Description: This routine will open the 4DWave SPDIF device.
1898 Parameters: substream - PCM substream class
1900 Returns: status - success or failure flag
1902 ---------------------------------------------------------------------------*/
1904 static int snd_trident_spdif_open(struct snd_pcm_substream
*substream
)
1906 struct snd_trident
*trident
= snd_pcm_substream_chip(substream
);
1907 struct snd_trident_voice
*voice
;
1908 struct snd_pcm_runtime
*runtime
= substream
->runtime
;
1910 voice
= snd_trident_alloc_voice(trident
, SNDRV_TRIDENT_VOICE_TYPE_PCM
, 0, 0);
1914 voice
->substream
= substream
;
1915 spin_lock_irq(&trident
->reg_lock
);
1916 trident
->spdif_pcm_bits
= trident
->spdif_bits
;
1917 spin_unlock_irq(&trident
->reg_lock
);
1919 runtime
->private_data
= voice
;
1920 runtime
->private_free
= snd_trident_pcm_free_substream
;
1921 if (trident
->device
== TRIDENT_DEVICE_ID_SI7018
) {
1922 runtime
->hw
= snd_trident_spdif
;
1924 runtime
->hw
= snd_trident_spdif_7018
;
1927 trident
->spdif_pcm_ctl
->vd
[0].access
&= ~SNDRV_CTL_ELEM_ACCESS_INACTIVE
;
1928 snd_ctl_notify(trident
->card
, SNDRV_CTL_EVENT_MASK_VALUE
|
1929 SNDRV_CTL_EVENT_MASK_INFO
, &trident
->spdif_pcm_ctl
->id
);
1931 snd_pcm_hw_constraint_minmax(runtime
, SNDRV_PCM_HW_PARAM_BUFFER_SIZE
, 0, 64*1024);
1936 /*---------------------------------------------------------------------------
1937 snd_trident_spdif_close
1939 Description: This routine will close the 4DWave SPDIF device.
1941 Parameters: substream - PCM substream class
1943 ---------------------------------------------------------------------------*/
1945 static int snd_trident_spdif_close(struct snd_pcm_substream
*substream
)
1947 struct snd_trident
*trident
= snd_pcm_substream_chip(substream
);
1950 spin_lock_irq(&trident
->reg_lock
);
1951 // restore default SPDIF setting
1952 if (trident
->device
!= TRIDENT_DEVICE_ID_SI7018
) {
1953 outb(trident
->spdif_ctrl
, TRID_REG(trident
, NX_SPCTRL_SPCSO
+ 3));
1954 outl(trident
->spdif_bits
, TRID_REG(trident
, NX_SPCSTATUS
));
1956 outl(trident
->spdif_bits
, TRID_REG(trident
, SI_SPDIF_CS
));
1957 temp
= inl(TRID_REG(trident
, SI_SERIAL_INTF_CTRL
));
1958 if (trident
->spdif_ctrl
) {
1963 outl(temp
, TRID_REG(trident
, SI_SERIAL_INTF_CTRL
));
1965 spin_unlock_irq(&trident
->reg_lock
);
1966 trident
->spdif_pcm_ctl
->vd
[0].access
|= SNDRV_CTL_ELEM_ACCESS_INACTIVE
;
1967 snd_ctl_notify(trident
->card
, SNDRV_CTL_EVENT_MASK_VALUE
|
1968 SNDRV_CTL_EVENT_MASK_INFO
, &trident
->spdif_pcm_ctl
->id
);
1972 /*---------------------------------------------------------------------------
1973 snd_trident_capture_open
1975 Description: This routine will open the 4DWave capture device.
1977 Parameters: substream - PCM substream class
1979 Returns: status - success or failure flag
1981 ---------------------------------------------------------------------------*/
1983 static int snd_trident_capture_open(struct snd_pcm_substream
*substream
)
1985 struct snd_trident
*trident
= snd_pcm_substream_chip(substream
);
1986 struct snd_trident_voice
*voice
;
1987 struct snd_pcm_runtime
*runtime
= substream
->runtime
;
1989 voice
= snd_trident_alloc_voice(trident
, SNDRV_TRIDENT_VOICE_TYPE_PCM
, 0, 0);
1993 voice
->substream
= substream
;
1994 runtime
->private_data
= voice
;
1995 runtime
->private_free
= snd_trident_pcm_free_substream
;
1996 runtime
->hw
= snd_trident_capture
;
1997 snd_pcm_set_sync(substream
);
1998 snd_pcm_hw_constraint_minmax(runtime
, SNDRV_PCM_HW_PARAM_BUFFER_SIZE
, 0, 64*1024);
2002 /*---------------------------------------------------------------------------
2003 snd_trident_capture_close
2005 Description: This routine will close the 4DWave capture device. For now
2006 we will simply free the dma transfer buffer.
2008 Parameters: substream - PCM substream class
2010 ---------------------------------------------------------------------------*/
2011 static int snd_trident_capture_close(struct snd_pcm_substream
*substream
)
2016 /*---------------------------------------------------------------------------
2017 snd_trident_foldback_open
2019 Description: This routine will open the 4DWave foldback capture device.
2021 Parameters: substream - PCM substream class
2023 Returns: status - success or failure flag
2025 ---------------------------------------------------------------------------*/
2027 static int snd_trident_foldback_open(struct snd_pcm_substream
*substream
)
2029 struct snd_trident
*trident
= snd_pcm_substream_chip(substream
);
2030 struct snd_trident_voice
*voice
;
2031 struct snd_pcm_runtime
*runtime
= substream
->runtime
;
2033 voice
= snd_trident_alloc_voice(trident
, SNDRV_TRIDENT_VOICE_TYPE_PCM
, 0, 0);
2036 voice
->foldback_chan
= substream
->number
;
2037 voice
->substream
= substream
;
2038 runtime
->private_data
= voice
;
2039 runtime
->private_free
= snd_trident_pcm_free_substream
;
2040 runtime
->hw
= snd_trident_foldback
;
2041 snd_pcm_hw_constraint_minmax(runtime
, SNDRV_PCM_HW_PARAM_BUFFER_SIZE
, 0, 64*1024);
2045 /*---------------------------------------------------------------------------
2046 snd_trident_foldback_close
2048 Description: This routine will close the 4DWave foldback capture device.
2049 For now we will simply free the dma transfer buffer.
2051 Parameters: substream - PCM substream class
2053 ---------------------------------------------------------------------------*/
2054 static int snd_trident_foldback_close(struct snd_pcm_substream
*substream
)
2056 struct snd_trident
*trident
= snd_pcm_substream_chip(substream
);
2057 struct snd_trident_voice
*voice
;
2058 struct snd_pcm_runtime
*runtime
= substream
->runtime
;
2059 voice
= runtime
->private_data
;
2061 /* stop capture channel */
2062 spin_lock_irq(&trident
->reg_lock
);
2063 outb(0x00, TRID_REG(trident
, T4D_RCI
+ voice
->foldback_chan
));
2064 spin_unlock_irq(&trident
->reg_lock
);
2068 /*---------------------------------------------------------------------------
2070 ---------------------------------------------------------------------------*/
2072 static struct snd_pcm_ops snd_trident_playback_ops
= {
2073 .open
= snd_trident_playback_open
,
2074 .close
= snd_trident_playback_close
,
2075 .ioctl
= snd_trident_ioctl
,
2076 .hw_params
= snd_trident_hw_params
,
2077 .hw_free
= snd_trident_hw_free
,
2078 .prepare
= snd_trident_playback_prepare
,
2079 .trigger
= snd_trident_trigger
,
2080 .pointer
= snd_trident_playback_pointer
,
2083 static struct snd_pcm_ops snd_trident_nx_playback_ops
= {
2084 .open
= snd_trident_playback_open
,
2085 .close
= snd_trident_playback_close
,
2086 .ioctl
= snd_trident_ioctl
,
2087 .hw_params
= snd_trident_hw_params
,
2088 .hw_free
= snd_trident_hw_free
,
2089 .prepare
= snd_trident_playback_prepare
,
2090 .trigger
= snd_trident_trigger
,
2091 .pointer
= snd_trident_playback_pointer
,
2092 .page
= snd_pcm_sgbuf_ops_page
,
2095 static struct snd_pcm_ops snd_trident_capture_ops
= {
2096 .open
= snd_trident_capture_open
,
2097 .close
= snd_trident_capture_close
,
2098 .ioctl
= snd_trident_ioctl
,
2099 .hw_params
= snd_trident_capture_hw_params
,
2100 .hw_free
= snd_trident_hw_free
,
2101 .prepare
= snd_trident_capture_prepare
,
2102 .trigger
= snd_trident_trigger
,
2103 .pointer
= snd_trident_capture_pointer
,
2106 static struct snd_pcm_ops snd_trident_si7018_capture_ops
= {
2107 .open
= snd_trident_capture_open
,
2108 .close
= snd_trident_capture_close
,
2109 .ioctl
= snd_trident_ioctl
,
2110 .hw_params
= snd_trident_si7018_capture_hw_params
,
2111 .hw_free
= snd_trident_si7018_capture_hw_free
,
2112 .prepare
= snd_trident_si7018_capture_prepare
,
2113 .trigger
= snd_trident_trigger
,
2114 .pointer
= snd_trident_playback_pointer
,
2117 static struct snd_pcm_ops snd_trident_foldback_ops
= {
2118 .open
= snd_trident_foldback_open
,
2119 .close
= snd_trident_foldback_close
,
2120 .ioctl
= snd_trident_ioctl
,
2121 .hw_params
= snd_trident_hw_params
,
2122 .hw_free
= snd_trident_hw_free
,
2123 .prepare
= snd_trident_foldback_prepare
,
2124 .trigger
= snd_trident_trigger
,
2125 .pointer
= snd_trident_playback_pointer
,
2128 static struct snd_pcm_ops snd_trident_nx_foldback_ops
= {
2129 .open
= snd_trident_foldback_open
,
2130 .close
= snd_trident_foldback_close
,
2131 .ioctl
= snd_trident_ioctl
,
2132 .hw_params
= snd_trident_hw_params
,
2133 .hw_free
= snd_trident_hw_free
,
2134 .prepare
= snd_trident_foldback_prepare
,
2135 .trigger
= snd_trident_trigger
,
2136 .pointer
= snd_trident_playback_pointer
,
2137 .page
= snd_pcm_sgbuf_ops_page
,
2140 static struct snd_pcm_ops snd_trident_spdif_ops
= {
2141 .open
= snd_trident_spdif_open
,
2142 .close
= snd_trident_spdif_close
,
2143 .ioctl
= snd_trident_ioctl
,
2144 .hw_params
= snd_trident_spdif_hw_params
,
2145 .hw_free
= snd_trident_hw_free
,
2146 .prepare
= snd_trident_spdif_prepare
,
2147 .trigger
= snd_trident_trigger
,
2148 .pointer
= snd_trident_spdif_pointer
,
2151 static struct snd_pcm_ops snd_trident_spdif_7018_ops
= {
2152 .open
= snd_trident_spdif_open
,
2153 .close
= snd_trident_spdif_close
,
2154 .ioctl
= snd_trident_ioctl
,
2155 .hw_params
= snd_trident_spdif_hw_params
,
2156 .hw_free
= snd_trident_hw_free
,
2157 .prepare
= snd_trident_spdif_prepare
,
2158 .trigger
= snd_trident_trigger
,
2159 .pointer
= snd_trident_playback_pointer
,
2162 /*---------------------------------------------------------------------------
2165 Description: This routine registers the 4DWave device for PCM support.
2167 Parameters: trident - pointer to target device class for 4DWave.
2171 ---------------------------------------------------------------------------*/
2173 int __devinit
snd_trident_pcm(struct snd_trident
* trident
,
2174 int device
, struct snd_pcm
** rpcm
)
2176 struct snd_pcm
*pcm
;
2181 if ((err
= snd_pcm_new(trident
->card
, "trident_dx_nx", device
, trident
->ChanPCM
, 1, &pcm
)) < 0)
2184 pcm
->private_data
= trident
;
2186 if (trident
->tlb
.entries
) {
2187 snd_pcm_set_ops(pcm
, SNDRV_PCM_STREAM_PLAYBACK
, &snd_trident_nx_playback_ops
);
2189 snd_pcm_set_ops(pcm
, SNDRV_PCM_STREAM_PLAYBACK
, &snd_trident_playback_ops
);
2191 snd_pcm_set_ops(pcm
, SNDRV_PCM_STREAM_CAPTURE
,
2192 trident
->device
!= TRIDENT_DEVICE_ID_SI7018
?
2193 &snd_trident_capture_ops
:
2194 &snd_trident_si7018_capture_ops
);
2196 pcm
->info_flags
= 0;
2197 pcm
->dev_subclass
= SNDRV_PCM_SUBCLASS_GENERIC_MIX
;
2198 strcpy(pcm
->name
, "Trident 4DWave");
2201 if (trident
->tlb
.entries
) {
2202 struct snd_pcm_substream
*substream
;
2203 for (substream
= pcm
->streams
[SNDRV_PCM_STREAM_PLAYBACK
].substream
; substream
; substream
= substream
->next
)
2204 snd_pcm_lib_preallocate_pages(substream
, SNDRV_DMA_TYPE_DEV_SG
,
2205 snd_dma_pci_data(trident
->pci
),
2207 snd_pcm_lib_preallocate_pages(pcm
->streams
[SNDRV_PCM_STREAM_CAPTURE
].substream
,
2208 SNDRV_DMA_TYPE_DEV
, snd_dma_pci_data(trident
->pci
),
2211 snd_pcm_lib_preallocate_pages_for_all(pcm
, SNDRV_DMA_TYPE_DEV
,
2212 snd_dma_pci_data(trident
->pci
), 64*1024, 128*1024);
2220 /*---------------------------------------------------------------------------
2221 snd_trident_foldback_pcm
2223 Description: This routine registers the 4DWave device for foldback PCM support.
2225 Parameters: trident - pointer to target device class for 4DWave.
2229 ---------------------------------------------------------------------------*/
2231 int __devinit
snd_trident_foldback_pcm(struct snd_trident
* trident
,
2232 int device
, struct snd_pcm
** rpcm
)
2234 struct snd_pcm
*foldback
;
2237 struct snd_pcm_substream
*substream
;
2241 if (trident
->device
== TRIDENT_DEVICE_ID_NX
)
2243 if ((err
= snd_pcm_new(trident
->card
, "trident_dx_nx", device
, 0, num_chan
, &foldback
)) < 0)
2246 foldback
->private_data
= trident
;
2247 if (trident
->tlb
.entries
)
2248 snd_pcm_set_ops(foldback
, SNDRV_PCM_STREAM_CAPTURE
, &snd_trident_nx_foldback_ops
);
2250 snd_pcm_set_ops(foldback
, SNDRV_PCM_STREAM_CAPTURE
, &snd_trident_foldback_ops
);
2251 foldback
->info_flags
= 0;
2252 strcpy(foldback
->name
, "Trident 4DWave");
2253 substream
= foldback
->streams
[SNDRV_PCM_STREAM_CAPTURE
].substream
;
2254 strcpy(substream
->name
, "Front Mixer");
2255 substream
= substream
->next
;
2256 strcpy(substream
->name
, "Reverb Mixer");
2257 substream
= substream
->next
;
2258 strcpy(substream
->name
, "Chorus Mixer");
2259 if (num_chan
== 4) {
2260 substream
= substream
->next
;
2261 strcpy(substream
->name
, "Second AC'97 ADC");
2263 trident
->foldback
= foldback
;
2265 if (trident
->tlb
.entries
)
2266 snd_pcm_lib_preallocate_pages_for_all(foldback
, SNDRV_DMA_TYPE_DEV_SG
,
2267 snd_dma_pci_data(trident
->pci
), 0, 128*1024);
2269 snd_pcm_lib_preallocate_pages_for_all(foldback
, SNDRV_DMA_TYPE_DEV
,
2270 snd_dma_pci_data(trident
->pci
), 64*1024, 128*1024);
2277 /*---------------------------------------------------------------------------
2280 Description: This routine registers the 4DWave-NX device for SPDIF support.
2282 Parameters: trident - pointer to target device class for 4DWave-NX.
2286 ---------------------------------------------------------------------------*/
2288 int __devinit
snd_trident_spdif_pcm(struct snd_trident
* trident
,
2289 int device
, struct snd_pcm
** rpcm
)
2291 struct snd_pcm
*spdif
;
2296 if ((err
= snd_pcm_new(trident
->card
, "trident_dx_nx IEC958", device
, 1, 0, &spdif
)) < 0)
2299 spdif
->private_data
= trident
;
2300 if (trident
->device
!= TRIDENT_DEVICE_ID_SI7018
) {
2301 snd_pcm_set_ops(spdif
, SNDRV_PCM_STREAM_PLAYBACK
, &snd_trident_spdif_ops
);
2303 snd_pcm_set_ops(spdif
, SNDRV_PCM_STREAM_PLAYBACK
, &snd_trident_spdif_7018_ops
);
2305 spdif
->info_flags
= 0;
2306 strcpy(spdif
->name
, "Trident 4DWave IEC958");
2307 trident
->spdif
= spdif
;
2309 snd_pcm_lib_preallocate_pages_for_all(spdif
, SNDRV_DMA_TYPE_DEV
, snd_dma_pci_data(trident
->pci
), 64*1024, 128*1024);
2321 /*---------------------------------------------------------------------------
2322 snd_trident_spdif_control
2324 Description: enable/disable S/PDIF out from ac97 mixer
2325 ---------------------------------------------------------------------------*/
2327 #define snd_trident_spdif_control_info snd_ctl_boolean_mono_info
2329 static int snd_trident_spdif_control_get(struct snd_kcontrol
*kcontrol
,
2330 struct snd_ctl_elem_value
*ucontrol
)
2332 struct snd_trident
*trident
= snd_kcontrol_chip(kcontrol
);
2335 spin_lock_irq(&trident
->reg_lock
);
2336 val
= trident
->spdif_ctrl
;
2337 ucontrol
->value
.integer
.value
[0] = val
== kcontrol
->private_value
;
2338 spin_unlock_irq(&trident
->reg_lock
);
2342 static int snd_trident_spdif_control_put(struct snd_kcontrol
*kcontrol
,
2343 struct snd_ctl_elem_value
*ucontrol
)
2345 struct snd_trident
*trident
= snd_kcontrol_chip(kcontrol
);
2349 val
= ucontrol
->value
.integer
.value
[0] ? (unsigned char) kcontrol
->private_value
: 0x00;
2350 spin_lock_irq(&trident
->reg_lock
);
2351 /* S/PDIF C Channel bits 0-31 : 48khz, SCMS disabled */
2352 change
= trident
->spdif_ctrl
!= val
;
2353 trident
->spdif_ctrl
= val
;
2354 if (trident
->device
!= TRIDENT_DEVICE_ID_SI7018
) {
2355 if ((inb(TRID_REG(trident
, NX_SPCTRL_SPCSO
+ 3)) & 0x10) == 0) {
2356 outl(trident
->spdif_bits
, TRID_REG(trident
, NX_SPCSTATUS
));
2357 outb(trident
->spdif_ctrl
, TRID_REG(trident
, NX_SPCTRL_SPCSO
+ 3));
2360 if (trident
->spdif
== NULL
) {
2362 outl(trident
->spdif_bits
, TRID_REG(trident
, SI_SPDIF_CS
));
2363 temp
= inl(TRID_REG(trident
, SI_SERIAL_INTF_CTRL
)) & ~SPDIF_EN
;
2366 outl(temp
, TRID_REG(trident
, SI_SERIAL_INTF_CTRL
));
2369 spin_unlock_irq(&trident
->reg_lock
);
2373 static struct snd_kcontrol_new snd_trident_spdif_control __devinitdata
=
2375 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
2376 .name
= SNDRV_CTL_NAME_IEC958("",PLAYBACK
,SWITCH
),
2377 .info
= snd_trident_spdif_control_info
,
2378 .get
= snd_trident_spdif_control_get
,
2379 .put
= snd_trident_spdif_control_put
,
2380 .private_value
= 0x28,
2383 /*---------------------------------------------------------------------------
2384 snd_trident_spdif_default
2386 Description: put/get the S/PDIF default settings
2387 ---------------------------------------------------------------------------*/
2389 static int snd_trident_spdif_default_info(struct snd_kcontrol
*kcontrol
,
2390 struct snd_ctl_elem_info
*uinfo
)
2392 uinfo
->type
= SNDRV_CTL_ELEM_TYPE_IEC958
;
2397 static int snd_trident_spdif_default_get(struct snd_kcontrol
*kcontrol
,
2398 struct snd_ctl_elem_value
*ucontrol
)
2400 struct snd_trident
*trident
= snd_kcontrol_chip(kcontrol
);
2402 spin_lock_irq(&trident
->reg_lock
);
2403 ucontrol
->value
.iec958
.status
[0] = (trident
->spdif_bits
>> 0) & 0xff;
2404 ucontrol
->value
.iec958
.status
[1] = (trident
->spdif_bits
>> 8) & 0xff;
2405 ucontrol
->value
.iec958
.status
[2] = (trident
->spdif_bits
>> 16) & 0xff;
2406 ucontrol
->value
.iec958
.status
[3] = (trident
->spdif_bits
>> 24) & 0xff;
2407 spin_unlock_irq(&trident
->reg_lock
);
2411 static int snd_trident_spdif_default_put(struct snd_kcontrol
*kcontrol
,
2412 struct snd_ctl_elem_value
*ucontrol
)
2414 struct snd_trident
*trident
= snd_kcontrol_chip(kcontrol
);
2418 val
= (ucontrol
->value
.iec958
.status
[0] << 0) |
2419 (ucontrol
->value
.iec958
.status
[1] << 8) |
2420 (ucontrol
->value
.iec958
.status
[2] << 16) |
2421 (ucontrol
->value
.iec958
.status
[3] << 24);
2422 spin_lock_irq(&trident
->reg_lock
);
2423 change
= trident
->spdif_bits
!= val
;
2424 trident
->spdif_bits
= val
;
2425 if (trident
->device
!= TRIDENT_DEVICE_ID_SI7018
) {
2426 if ((inb(TRID_REG(trident
, NX_SPCTRL_SPCSO
+ 3)) & 0x10) == 0)
2427 outl(trident
->spdif_bits
, TRID_REG(trident
, NX_SPCSTATUS
));
2429 if (trident
->spdif
== NULL
)
2430 outl(trident
->spdif_bits
, TRID_REG(trident
, SI_SPDIF_CS
));
2432 spin_unlock_irq(&trident
->reg_lock
);
2436 static struct snd_kcontrol_new snd_trident_spdif_default __devinitdata
=
2438 .iface
= SNDRV_CTL_ELEM_IFACE_PCM
,
2439 .name
= SNDRV_CTL_NAME_IEC958("",PLAYBACK
,DEFAULT
),
2440 .info
= snd_trident_spdif_default_info
,
2441 .get
= snd_trident_spdif_default_get
,
2442 .put
= snd_trident_spdif_default_put
2445 /*---------------------------------------------------------------------------
2446 snd_trident_spdif_mask
2448 Description: put/get the S/PDIF mask
2449 ---------------------------------------------------------------------------*/
2451 static int snd_trident_spdif_mask_info(struct snd_kcontrol
*kcontrol
,
2452 struct snd_ctl_elem_info
*uinfo
)
2454 uinfo
->type
= SNDRV_CTL_ELEM_TYPE_IEC958
;
2459 static int snd_trident_spdif_mask_get(struct snd_kcontrol
*kcontrol
,
2460 struct snd_ctl_elem_value
*ucontrol
)
2462 ucontrol
->value
.iec958
.status
[0] = 0xff;
2463 ucontrol
->value
.iec958
.status
[1] = 0xff;
2464 ucontrol
->value
.iec958
.status
[2] = 0xff;
2465 ucontrol
->value
.iec958
.status
[3] = 0xff;
2469 static struct snd_kcontrol_new snd_trident_spdif_mask __devinitdata
=
2471 .access
= SNDRV_CTL_ELEM_ACCESS_READ
,
2472 .iface
= SNDRV_CTL_ELEM_IFACE_PCM
,
2473 .name
= SNDRV_CTL_NAME_IEC958("",PLAYBACK
,MASK
),
2474 .info
= snd_trident_spdif_mask_info
,
2475 .get
= snd_trident_spdif_mask_get
,
2478 /*---------------------------------------------------------------------------
2479 snd_trident_spdif_stream
2481 Description: put/get the S/PDIF stream settings
2482 ---------------------------------------------------------------------------*/
2484 static int snd_trident_spdif_stream_info(struct snd_kcontrol
*kcontrol
,
2485 struct snd_ctl_elem_info
*uinfo
)
2487 uinfo
->type
= SNDRV_CTL_ELEM_TYPE_IEC958
;
2492 static int snd_trident_spdif_stream_get(struct snd_kcontrol
*kcontrol
,
2493 struct snd_ctl_elem_value
*ucontrol
)
2495 struct snd_trident
*trident
= snd_kcontrol_chip(kcontrol
);
2497 spin_lock_irq(&trident
->reg_lock
);
2498 ucontrol
->value
.iec958
.status
[0] = (trident
->spdif_pcm_bits
>> 0) & 0xff;
2499 ucontrol
->value
.iec958
.status
[1] = (trident
->spdif_pcm_bits
>> 8) & 0xff;
2500 ucontrol
->value
.iec958
.status
[2] = (trident
->spdif_pcm_bits
>> 16) & 0xff;
2501 ucontrol
->value
.iec958
.status
[3] = (trident
->spdif_pcm_bits
>> 24) & 0xff;
2502 spin_unlock_irq(&trident
->reg_lock
);
2506 static int snd_trident_spdif_stream_put(struct snd_kcontrol
*kcontrol
,
2507 struct snd_ctl_elem_value
*ucontrol
)
2509 struct snd_trident
*trident
= snd_kcontrol_chip(kcontrol
);
2513 val
= (ucontrol
->value
.iec958
.status
[0] << 0) |
2514 (ucontrol
->value
.iec958
.status
[1] << 8) |
2515 (ucontrol
->value
.iec958
.status
[2] << 16) |
2516 (ucontrol
->value
.iec958
.status
[3] << 24);
2517 spin_lock_irq(&trident
->reg_lock
);
2518 change
= trident
->spdif_pcm_bits
!= val
;
2519 trident
->spdif_pcm_bits
= val
;
2520 if (trident
->spdif
!= NULL
) {
2521 if (trident
->device
!= TRIDENT_DEVICE_ID_SI7018
) {
2522 outl(trident
->spdif_pcm_bits
, TRID_REG(trident
, NX_SPCSTATUS
));
2524 outl(trident
->spdif_bits
, TRID_REG(trident
, SI_SPDIF_CS
));
2527 spin_unlock_irq(&trident
->reg_lock
);
2531 static struct snd_kcontrol_new snd_trident_spdif_stream __devinitdata
=
2533 .access
= SNDRV_CTL_ELEM_ACCESS_READWRITE
| SNDRV_CTL_ELEM_ACCESS_INACTIVE
,
2534 .iface
= SNDRV_CTL_ELEM_IFACE_PCM
,
2535 .name
= SNDRV_CTL_NAME_IEC958("",PLAYBACK
,PCM_STREAM
),
2536 .info
= snd_trident_spdif_stream_info
,
2537 .get
= snd_trident_spdif_stream_get
,
2538 .put
= snd_trident_spdif_stream_put
2541 /*---------------------------------------------------------------------------
2542 snd_trident_ac97_control
2544 Description: enable/disable rear path for ac97
2545 ---------------------------------------------------------------------------*/
2547 #define snd_trident_ac97_control_info snd_ctl_boolean_mono_info
2549 static int snd_trident_ac97_control_get(struct snd_kcontrol
*kcontrol
,
2550 struct snd_ctl_elem_value
*ucontrol
)
2552 struct snd_trident
*trident
= snd_kcontrol_chip(kcontrol
);
2555 spin_lock_irq(&trident
->reg_lock
);
2556 val
= trident
->ac97_ctrl
= inl(TRID_REG(trident
, NX_ACR0_AC97_COM_STAT
));
2557 ucontrol
->value
.integer
.value
[0] = (val
& (1 << kcontrol
->private_value
)) ? 1 : 0;
2558 spin_unlock_irq(&trident
->reg_lock
);
2562 static int snd_trident_ac97_control_put(struct snd_kcontrol
*kcontrol
,
2563 struct snd_ctl_elem_value
*ucontrol
)
2565 struct snd_trident
*trident
= snd_kcontrol_chip(kcontrol
);
2569 spin_lock_irq(&trident
->reg_lock
);
2570 val
= trident
->ac97_ctrl
= inl(TRID_REG(trident
, NX_ACR0_AC97_COM_STAT
));
2571 val
&= ~(1 << kcontrol
->private_value
);
2572 if (ucontrol
->value
.integer
.value
[0])
2573 val
|= 1 << kcontrol
->private_value
;
2574 change
= val
!= trident
->ac97_ctrl
;
2575 trident
->ac97_ctrl
= val
;
2576 outl(trident
->ac97_ctrl
= val
, TRID_REG(trident
, NX_ACR0_AC97_COM_STAT
));
2577 spin_unlock_irq(&trident
->reg_lock
);
2581 static struct snd_kcontrol_new snd_trident_ac97_rear_control __devinitdata
=
2583 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
2584 .name
= "Rear Path",
2585 .info
= snd_trident_ac97_control_info
,
2586 .get
= snd_trident_ac97_control_get
,
2587 .put
= snd_trident_ac97_control_put
,
2591 /*---------------------------------------------------------------------------
2592 snd_trident_vol_control
2594 Description: wave & music volume control
2595 ---------------------------------------------------------------------------*/
2597 static int snd_trident_vol_control_info(struct snd_kcontrol
*kcontrol
,
2598 struct snd_ctl_elem_info
*uinfo
)
2600 uinfo
->type
= SNDRV_CTL_ELEM_TYPE_INTEGER
;
2602 uinfo
->value
.integer
.min
= 0;
2603 uinfo
->value
.integer
.max
= 255;
2607 static int snd_trident_vol_control_get(struct snd_kcontrol
*kcontrol
,
2608 struct snd_ctl_elem_value
*ucontrol
)
2610 struct snd_trident
*trident
= snd_kcontrol_chip(kcontrol
);
2613 val
= trident
->musicvol_wavevol
;
2614 ucontrol
->value
.integer
.value
[0] = 255 - ((val
>> kcontrol
->private_value
) & 0xff);
2615 ucontrol
->value
.integer
.value
[1] = 255 - ((val
>> (kcontrol
->private_value
+ 8)) & 0xff);
2619 static const DECLARE_TLV_DB_SCALE(db_scale_gvol
, -6375, 25, 0);
2621 static int snd_trident_vol_control_put(struct snd_kcontrol
*kcontrol
,
2622 struct snd_ctl_elem_value
*ucontrol
)
2624 struct snd_trident
*trident
= snd_kcontrol_chip(kcontrol
);
2628 spin_lock_irq(&trident
->reg_lock
);
2629 val
= trident
->musicvol_wavevol
;
2630 val
&= ~(0xffff << kcontrol
->private_value
);
2631 val
|= ((255 - (ucontrol
->value
.integer
.value
[0] & 0xff)) |
2632 ((255 - (ucontrol
->value
.integer
.value
[1] & 0xff)) << 8)) << kcontrol
->private_value
;
2633 change
= val
!= trident
->musicvol_wavevol
;
2634 outl(trident
->musicvol_wavevol
= val
, TRID_REG(trident
, T4D_MUSICVOL_WAVEVOL
));
2635 spin_unlock_irq(&trident
->reg_lock
);
2639 static struct snd_kcontrol_new snd_trident_vol_music_control __devinitdata
=
2641 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
2642 .name
= "Music Playback Volume",
2643 .info
= snd_trident_vol_control_info
,
2644 .get
= snd_trident_vol_control_get
,
2645 .put
= snd_trident_vol_control_put
,
2646 .private_value
= 16,
2647 .tlv
= { .p
= db_scale_gvol
},
2650 static struct snd_kcontrol_new snd_trident_vol_wave_control __devinitdata
=
2652 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
2653 .name
= "Wave Playback Volume",
2654 .info
= snd_trident_vol_control_info
,
2655 .get
= snd_trident_vol_control_get
,
2656 .put
= snd_trident_vol_control_put
,
2658 .tlv
= { .p
= db_scale_gvol
},
2661 /*---------------------------------------------------------------------------
2662 snd_trident_pcm_vol_control
2664 Description: PCM front volume control
2665 ---------------------------------------------------------------------------*/
2667 static int snd_trident_pcm_vol_control_info(struct snd_kcontrol
*kcontrol
,
2668 struct snd_ctl_elem_info
*uinfo
)
2670 struct snd_trident
*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(struct snd_kcontrol
*kcontrol
,
2682 struct snd_ctl_elem_value
*ucontrol
)
2684 struct snd_trident
*trident
= snd_kcontrol_chip(kcontrol
);
2685 struct snd_trident_pcm_mixer
*mix
= &trident
->pcm_mixer
[snd_ctl_get_ioffnum(kcontrol
, &ucontrol
->id
)];
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(struct snd_kcontrol
*kcontrol
,
2696 struct snd_ctl_elem_value
*ucontrol
)
2698 struct snd_trident
*trident
= snd_kcontrol_chip(kcontrol
);
2699 struct snd_trident_pcm_mixer
*mix
= &trident
->pcm_mixer
[snd_ctl_get_ioffnum(kcontrol
, &ucontrol
->id
)];
2703 if (trident
->device
== TRIDENT_DEVICE_ID_SI7018
) {
2704 val
= 1023 - (ucontrol
->value
.integer
.value
[0] & 1023);
2706 val
= (255 - (ucontrol
->value
.integer
.value
[0] & 255)) << 2;
2708 spin_lock_irq(&trident
->reg_lock
);
2709 change
= val
!= mix
->vol
;
2711 if (mix
->voice
!= NULL
)
2712 snd_trident_write_vol_reg(trident
, mix
->voice
, val
);
2713 spin_unlock_irq(&trident
->reg_lock
);
2717 static struct snd_kcontrol_new snd_trident_pcm_vol_control __devinitdata
=
2719 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
2720 .name
= "PCM Front Playback Volume",
2721 .access
= SNDRV_CTL_ELEM_ACCESS_READWRITE
| SNDRV_CTL_ELEM_ACCESS_INACTIVE
,
2723 .info
= snd_trident_pcm_vol_control_info
,
2724 .get
= snd_trident_pcm_vol_control_get
,
2725 .put
= snd_trident_pcm_vol_control_put
,
2726 /* FIXME: no tlv yet */
2729 /*---------------------------------------------------------------------------
2730 snd_trident_pcm_pan_control
2732 Description: PCM front pan control
2733 ---------------------------------------------------------------------------*/
2735 static int snd_trident_pcm_pan_control_info(struct snd_kcontrol
*kcontrol
,
2736 struct snd_ctl_elem_info
*uinfo
)
2738 uinfo
->type
= SNDRV_CTL_ELEM_TYPE_INTEGER
;
2740 uinfo
->value
.integer
.min
= 0;
2741 uinfo
->value
.integer
.max
= 127;
2745 static int snd_trident_pcm_pan_control_get(struct snd_kcontrol
*kcontrol
,
2746 struct snd_ctl_elem_value
*ucontrol
)
2748 struct snd_trident
*trident
= snd_kcontrol_chip(kcontrol
);
2749 struct snd_trident_pcm_mixer
*mix
= &trident
->pcm_mixer
[snd_ctl_get_ioffnum(kcontrol
, &ucontrol
->id
)];
2751 ucontrol
->value
.integer
.value
[0] = mix
->pan
;
2752 if (ucontrol
->value
.integer
.value
[0] & 0x40) {
2753 ucontrol
->value
.integer
.value
[0] = (0x3f - (ucontrol
->value
.integer
.value
[0] & 0x3f));
2755 ucontrol
->value
.integer
.value
[0] |= 0x40;
2760 static int snd_trident_pcm_pan_control_put(struct snd_kcontrol
*kcontrol
,
2761 struct snd_ctl_elem_value
*ucontrol
)
2763 struct snd_trident
*trident
= snd_kcontrol_chip(kcontrol
);
2764 struct snd_trident_pcm_mixer
*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_irq(&trident
->reg_lock
);
2773 change
= val
!= mix
->pan
;
2775 if (mix
->voice
!= NULL
)
2776 snd_trident_write_pan_reg(trident
, mix
->voice
, val
);
2777 spin_unlock_irq(&trident
->reg_lock
);
2781 static struct snd_kcontrol_new 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(struct snd_kcontrol
*kcontrol
,
2799 struct snd_ctl_elem_info
*uinfo
)
2801 uinfo
->type
= SNDRV_CTL_ELEM_TYPE_INTEGER
;
2803 uinfo
->value
.integer
.min
= 0;
2804 uinfo
->value
.integer
.max
= 127;
2808 static int snd_trident_pcm_rvol_control_get(struct snd_kcontrol
*kcontrol
,
2809 struct snd_ctl_elem_value
*ucontrol
)
2811 struct snd_trident
*trident
= snd_kcontrol_chip(kcontrol
);
2812 struct snd_trident_pcm_mixer
*mix
= &trident
->pcm_mixer
[snd_ctl_get_ioffnum(kcontrol
, &ucontrol
->id
)];
2814 ucontrol
->value
.integer
.value
[0] = 127 - mix
->rvol
;
2818 static int snd_trident_pcm_rvol_control_put(struct snd_kcontrol
*kcontrol
,
2819 struct snd_ctl_elem_value
*ucontrol
)
2821 struct snd_trident
*trident
= snd_kcontrol_chip(kcontrol
);
2822 struct snd_trident_pcm_mixer
*mix
= &trident
->pcm_mixer
[snd_ctl_get_ioffnum(kcontrol
, &ucontrol
->id
)];
2826 val
= 0x7f - (ucontrol
->value
.integer
.value
[0] & 0x7f);
2827 spin_lock_irq(&trident
->reg_lock
);
2828 change
= val
!= mix
->rvol
;
2830 if (mix
->voice
!= NULL
)
2831 snd_trident_write_rvol_reg(trident
, mix
->voice
, val
);
2832 spin_unlock_irq(&trident
->reg_lock
);
2836 static const DECLARE_TLV_DB_SCALE(db_scale_crvol
, -3175, 25, 1);
2838 static struct snd_kcontrol_new snd_trident_pcm_rvol_control __devinitdata
=
2840 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
2841 .name
= "PCM Reverb Playback Volume",
2842 .access
= SNDRV_CTL_ELEM_ACCESS_READWRITE
| SNDRV_CTL_ELEM_ACCESS_INACTIVE
,
2844 .info
= snd_trident_pcm_rvol_control_info
,
2845 .get
= snd_trident_pcm_rvol_control_get
,
2846 .put
= snd_trident_pcm_rvol_control_put
,
2847 .tlv
= { .p
= db_scale_crvol
},
2850 /*---------------------------------------------------------------------------
2851 snd_trident_pcm_cvol_control
2853 Description: PCM chorus volume control
2854 ---------------------------------------------------------------------------*/
2856 static int snd_trident_pcm_cvol_control_info(struct snd_kcontrol
*kcontrol
,
2857 struct snd_ctl_elem_info
*uinfo
)
2859 uinfo
->type
= SNDRV_CTL_ELEM_TYPE_INTEGER
;
2861 uinfo
->value
.integer
.min
= 0;
2862 uinfo
->value
.integer
.max
= 127;
2866 static int snd_trident_pcm_cvol_control_get(struct snd_kcontrol
*kcontrol
,
2867 struct snd_ctl_elem_value
*ucontrol
)
2869 struct snd_trident
*trident
= snd_kcontrol_chip(kcontrol
);
2870 struct snd_trident_pcm_mixer
*mix
= &trident
->pcm_mixer
[snd_ctl_get_ioffnum(kcontrol
, &ucontrol
->id
)];
2872 ucontrol
->value
.integer
.value
[0] = 127 - mix
->cvol
;
2876 static int snd_trident_pcm_cvol_control_put(struct snd_kcontrol
*kcontrol
,
2877 struct snd_ctl_elem_value
*ucontrol
)
2879 struct snd_trident
*trident
= snd_kcontrol_chip(kcontrol
);
2880 struct snd_trident_pcm_mixer
*mix
= &trident
->pcm_mixer
[snd_ctl_get_ioffnum(kcontrol
, &ucontrol
->id
)];
2884 val
= 0x7f - (ucontrol
->value
.integer
.value
[0] & 0x7f);
2885 spin_lock_irq(&trident
->reg_lock
);
2886 change
= val
!= mix
->cvol
;
2888 if (mix
->voice
!= NULL
)
2889 snd_trident_write_cvol_reg(trident
, mix
->voice
, val
);
2890 spin_unlock_irq(&trident
->reg_lock
);
2894 static struct snd_kcontrol_new snd_trident_pcm_cvol_control __devinitdata
=
2896 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
2897 .name
= "PCM Chorus Playback Volume",
2898 .access
= SNDRV_CTL_ELEM_ACCESS_READWRITE
| SNDRV_CTL_ELEM_ACCESS_INACTIVE
,
2900 .info
= snd_trident_pcm_cvol_control_info
,
2901 .get
= snd_trident_pcm_cvol_control_get
,
2902 .put
= snd_trident_pcm_cvol_control_put
,
2903 .tlv
= { .p
= db_scale_crvol
},
2906 static void snd_trident_notify_pcm_change1(struct snd_card
*card
,
2907 struct snd_kcontrol
*kctl
,
2908 int num
, int activate
)
2910 struct snd_ctl_elem_id id
;
2915 kctl
->vd
[num
].access
&= ~SNDRV_CTL_ELEM_ACCESS_INACTIVE
;
2917 kctl
->vd
[num
].access
|= SNDRV_CTL_ELEM_ACCESS_INACTIVE
;
2918 snd_ctl_notify(card
, SNDRV_CTL_EVENT_MASK_VALUE
|
2919 SNDRV_CTL_EVENT_MASK_INFO
,
2920 snd_ctl_build_ioff(&id
, kctl
, num
));
2923 static void snd_trident_notify_pcm_change(struct snd_trident
*trident
,
2924 struct snd_trident_pcm_mixer
*tmix
,
2925 int num
, int activate
)
2927 snd_trident_notify_pcm_change1(trident
->card
, trident
->ctl_vol
, num
, activate
);
2928 snd_trident_notify_pcm_change1(trident
->card
, trident
->ctl_pan
, num
, activate
);
2929 snd_trident_notify_pcm_change1(trident
->card
, trident
->ctl_rvol
, num
, activate
);
2930 snd_trident_notify_pcm_change1(trident
->card
, trident
->ctl_cvol
, num
, activate
);
2933 static int snd_trident_pcm_mixer_build(struct snd_trident
*trident
,
2934 struct snd_trident_voice
*voice
,
2935 struct snd_pcm_substream
*substream
)
2937 struct snd_trident_pcm_mixer
*tmix
;
2939 if (snd_BUG_ON(!trident
|| !voice
|| !substream
))
2941 tmix
= &trident
->pcm_mixer
[substream
->number
];
2942 tmix
->voice
= voice
;
2943 tmix
->vol
= T4D_DEFAULT_PCM_VOL
;
2944 tmix
->pan
= T4D_DEFAULT_PCM_PAN
;
2945 tmix
->rvol
= T4D_DEFAULT_PCM_RVOL
;
2946 tmix
->cvol
= T4D_DEFAULT_PCM_CVOL
;
2947 snd_trident_notify_pcm_change(trident
, tmix
, substream
->number
, 1);
2951 static int snd_trident_pcm_mixer_free(struct snd_trident
*trident
, struct snd_trident_voice
*voice
, struct snd_pcm_substream
*substream
)
2953 struct snd_trident_pcm_mixer
*tmix
;
2955 if (snd_BUG_ON(!trident
|| !substream
))
2957 tmix
= &trident
->pcm_mixer
[substream
->number
];
2959 snd_trident_notify_pcm_change(trident
, tmix
, substream
->number
, 0);
2963 /*---------------------------------------------------------------------------
2966 Description: This routine registers the 4DWave device for mixer support.
2968 Parameters: trident - pointer to target device class for 4DWave.
2972 ---------------------------------------------------------------------------*/
2974 static int __devinit
snd_trident_mixer(struct snd_trident
* trident
, int pcm_spdif_device
)
2976 struct snd_ac97_template _ac97
;
2977 struct snd_card
*card
= trident
->card
;
2978 struct snd_kcontrol
*kctl
;
2979 struct snd_ctl_elem_value
*uctl
;
2980 int idx
, err
, retries
= 2;
2981 static struct snd_ac97_bus_ops ops
= {
2982 .write
= snd_trident_codec_write
,
2983 .read
= snd_trident_codec_read
,
2986 uctl
= kzalloc(sizeof(*uctl
), GFP_KERNEL
);
2990 if ((err
= snd_ac97_bus(trident
->card
, 0, &ops
, NULL
, &trident
->ac97_bus
)) < 0)
2993 memset(&_ac97
, 0, sizeof(_ac97
));
2994 _ac97
.private_data
= trident
;
2995 trident
->ac97_detect
= 1;
2998 if ((err
= snd_ac97_mixer(trident
->ac97_bus
, &_ac97
, &trident
->ac97
)) < 0) {
2999 if (trident
->device
== TRIDENT_DEVICE_ID_SI7018
) {
3000 if ((err
= snd_trident_sis_reset(trident
)) < 0)
3009 /* secondary codec? */
3010 if (trident
->device
== TRIDENT_DEVICE_ID_SI7018
&&
3011 (inl(TRID_REG(trident
, SI_SERIAL_INTF_CTRL
)) & SI_AC97_PRIMARY_READY
) != 0) {
3013 err
= snd_ac97_mixer(trident
->ac97_bus
, &_ac97
, &trident
->ac97_sec
);
3015 snd_printk(KERN_ERR
"SI7018: the secondary codec - invalid access\n");
3016 #if 0 // only for my testing purpose --jk
3018 struct snd_ac97
*mc97
;
3019 err
= snd_ac97_modem(trident
->card
, &_ac97
, &mc97
);
3021 snd_printk(KERN_ERR
"snd_ac97_modem returned error %i\n", err
);
3026 trident
->ac97_detect
= 0;
3028 if (trident
->device
!= TRIDENT_DEVICE_ID_SI7018
) {
3029 if ((err
= snd_ctl_add(card
, kctl
= snd_ctl_new1(&snd_trident_vol_wave_control
, trident
))) < 0)
3031 kctl
->put(kctl
, uctl
);
3032 if ((err
= snd_ctl_add(card
, kctl
= snd_ctl_new1(&snd_trident_vol_music_control
, trident
))) < 0)
3034 kctl
->put(kctl
, uctl
);
3035 outl(trident
->musicvol_wavevol
= 0x00000000, TRID_REG(trident
, T4D_MUSICVOL_WAVEVOL
));
3037 outl(trident
->musicvol_wavevol
= 0xffff0000, TRID_REG(trident
, T4D_MUSICVOL_WAVEVOL
));
3040 for (idx
= 0; idx
< 32; idx
++) {
3041 struct snd_trident_pcm_mixer
*tmix
;
3043 tmix
= &trident
->pcm_mixer
[idx
];
3046 if ((trident
->ctl_vol
= snd_ctl_new1(&snd_trident_pcm_vol_control
, trident
)) == NULL
)
3048 if ((err
= snd_ctl_add(card
, trident
->ctl_vol
)))
3051 if ((trident
->ctl_pan
= snd_ctl_new1(&snd_trident_pcm_pan_control
, trident
)) == NULL
)
3053 if ((err
= snd_ctl_add(card
, trident
->ctl_pan
)))
3056 if ((trident
->ctl_rvol
= snd_ctl_new1(&snd_trident_pcm_rvol_control
, trident
)) == NULL
)
3058 if ((err
= snd_ctl_add(card
, trident
->ctl_rvol
)))
3061 if ((trident
->ctl_cvol
= snd_ctl_new1(&snd_trident_pcm_cvol_control
, trident
)) == NULL
)
3063 if ((err
= snd_ctl_add(card
, trident
->ctl_cvol
)))
3066 if (trident
->device
== TRIDENT_DEVICE_ID_NX
) {
3067 if ((err
= snd_ctl_add(card
, kctl
= snd_ctl_new1(&snd_trident_ac97_rear_control
, trident
))) < 0)
3069 kctl
->put(kctl
, uctl
);
3071 if (trident
->device
== TRIDENT_DEVICE_ID_NX
|| trident
->device
== TRIDENT_DEVICE_ID_SI7018
) {
3073 kctl
= snd_ctl_new1(&snd_trident_spdif_control
, trident
);
3078 if (trident
->ac97
->ext_id
& AC97_EI_SPDIF
)
3080 if (trident
->ac97_sec
&& (trident
->ac97_sec
->ext_id
& AC97_EI_SPDIF
))
3082 idx
= kctl
->id
.index
;
3083 if ((err
= snd_ctl_add(card
, kctl
)) < 0)
3085 kctl
->put(kctl
, uctl
);
3087 kctl
= snd_ctl_new1(&snd_trident_spdif_default
, trident
);
3092 kctl
->id
.index
= idx
;
3093 kctl
->id
.device
= pcm_spdif_device
;
3094 if ((err
= snd_ctl_add(card
, kctl
)) < 0)
3097 kctl
= snd_ctl_new1(&snd_trident_spdif_mask
, trident
);
3102 kctl
->id
.index
= idx
;
3103 kctl
->id
.device
= pcm_spdif_device
;
3104 if ((err
= snd_ctl_add(card
, kctl
)) < 0)
3107 kctl
= snd_ctl_new1(&snd_trident_spdif_stream
, trident
);
3112 kctl
->id
.index
= idx
;
3113 kctl
->id
.device
= pcm_spdif_device
;
3114 if ((err
= snd_ctl_add(card
, kctl
)) < 0)
3116 trident
->spdif_pcm_ctl
= kctl
;
3132 * gameport interface
3135 #if defined(CONFIG_GAMEPORT) || (defined(MODULE) && defined(CONFIG_GAMEPORT_MODULE))
3137 static unsigned char snd_trident_gameport_read(struct gameport
*gameport
)
3139 struct snd_trident
*chip
= gameport_get_port_data(gameport
);
3141 if (snd_BUG_ON(!chip
))
3143 return inb(TRID_REG(chip
, GAMEPORT_LEGACY
));
3146 static void snd_trident_gameport_trigger(struct gameport
*gameport
)
3148 struct snd_trident
*chip
= gameport_get_port_data(gameport
);
3150 if (snd_BUG_ON(!chip
))
3152 outb(0xff, TRID_REG(chip
, GAMEPORT_LEGACY
));
3155 static int snd_trident_gameport_cooked_read(struct gameport
*gameport
, int *axes
, int *buttons
)
3157 struct snd_trident
*chip
= gameport_get_port_data(gameport
);
3160 if (snd_BUG_ON(!chip
))
3163 *buttons
= (~inb(TRID_REG(chip
, GAMEPORT_LEGACY
)) >> 4) & 0xf;
3165 for (i
= 0; i
< 4; i
++) {
3166 axes
[i
] = inw(TRID_REG(chip
, GAMEPORT_AXES
+ i
* 2));
3167 if (axes
[i
] == 0xffff) axes
[i
] = -1;
3173 static int snd_trident_gameport_open(struct gameport
*gameport
, int mode
)
3175 struct snd_trident
*chip
= gameport_get_port_data(gameport
);
3177 if (snd_BUG_ON(!chip
))
3181 case GAMEPORT_MODE_COOKED
:
3182 outb(GAMEPORT_MODE_ADC
, TRID_REG(chip
, GAMEPORT_GCR
));
3185 case GAMEPORT_MODE_RAW
:
3186 outb(0, TRID_REG(chip
, GAMEPORT_GCR
));
3193 int __devinit
snd_trident_create_gameport(struct snd_trident
*chip
)
3195 struct gameport
*gp
;
3197 chip
->gameport
= gp
= gameport_allocate_port();
3199 printk(KERN_ERR
"trident: cannot allocate memory for gameport\n");
3203 gameport_set_name(gp
, "Trident 4DWave");
3204 gameport_set_phys(gp
, "pci%s/gameport0", pci_name(chip
->pci
));
3205 gameport_set_dev_parent(gp
, &chip
->pci
->dev
);
3207 gameport_set_port_data(gp
, chip
);
3209 gp
->read
= snd_trident_gameport_read
;
3210 gp
->trigger
= snd_trident_gameport_trigger
;
3211 gp
->cooked_read
= snd_trident_gameport_cooked_read
;
3212 gp
->open
= snd_trident_gameport_open
;
3214 gameport_register_port(gp
);
3219 static inline void snd_trident_free_gameport(struct snd_trident
*chip
)
3221 if (chip
->gameport
) {
3222 gameport_unregister_port(chip
->gameport
);
3223 chip
->gameport
= NULL
;
3227 int __devinit
snd_trident_create_gameport(struct snd_trident
*chip
) { return -ENOSYS
; }
3228 static inline void snd_trident_free_gameport(struct snd_trident
*chip
) { }
3229 #endif /* CONFIG_GAMEPORT */
3234 static inline void do_delay(struct snd_trident
*chip
)
3236 schedule_timeout_uninterruptible(1);
3243 static int snd_trident_sis_reset(struct snd_trident
*trident
)
3245 unsigned long end_time
;
3249 r
= trident
->in_suspend
? 0 : 2; /* count of retries */
3251 pci_write_config_byte(trident
->pci
, 0x46, 0x04); /* SOFTWARE RESET */
3253 pci_write_config_byte(trident
->pci
, 0x46, 0x00);
3255 /* disable AC97 GPIO interrupt */
3256 outb(0x00, TRID_REG(trident
, SI_AC97_GPIO
));
3257 /* initialize serial interface, force cold reset */
3258 i
= PCMOUT
|SURROUT
|CENTEROUT
|LFEOUT
|SECONDARY_ID
|COLD_RESET
;
3259 outl(i
, TRID_REG(trident
, SI_SERIAL_INTF_CTRL
));
3261 /* remove cold reset */
3263 outl(i
, TRID_REG(trident
, SI_SERIAL_INTF_CTRL
));
3265 /* wait, until the codec is ready */
3266 end_time
= (jiffies
+ (HZ
* 3) / 4) + 1;
3268 if ((inl(TRID_REG(trident
, SI_SERIAL_INTF_CTRL
)) & SI_AC97_PRIMARY_READY
) != 0)
3271 } while (time_after_eq(end_time
, jiffies
));
3272 snd_printk(KERN_ERR
"AC'97 codec ready error [0x%x]\n", inl(TRID_REG(trident
, SI_SERIAL_INTF_CTRL
)));
3274 end_time
= jiffies
+ HZ
;
3277 } while (time_after_eq(end_time
, jiffies
));
3278 goto __si7018_retry
;
3281 /* wait for the second codec */
3283 if ((inl(TRID_REG(trident
, SI_SERIAL_INTF_CTRL
)) & SI_AC97_SECONDARY_READY
) != 0)
3286 } while (time_after_eq(end_time
, jiffies
));
3287 /* enable 64 channel mode */
3288 outl(BANK_B_EN
, TRID_REG(trident
, T4D_LFO_GC_CIR
));
3296 static void snd_trident_proc_read(struct snd_info_entry
*entry
,
3297 struct snd_info_buffer
*buffer
)
3299 struct snd_trident
*trident
= entry
->private_data
;
3302 switch (trident
->device
) {
3303 case TRIDENT_DEVICE_ID_SI7018
:
3304 s
= "SiS 7018 Audio";
3306 case TRIDENT_DEVICE_ID_DX
:
3307 s
= "Trident 4DWave PCI DX";
3309 case TRIDENT_DEVICE_ID_NX
:
3310 s
= "Trident 4DWave PCI NX";
3315 snd_iprintf(buffer
, "%s\n\n", s
);
3316 snd_iprintf(buffer
, "Spurious IRQs : %d\n", trident
->spurious_irq_count
);
3317 snd_iprintf(buffer
, "Spurious IRQ dlta: %d\n", trident
->spurious_irq_max_delta
);
3318 if (trident
->device
== TRIDENT_DEVICE_ID_NX
|| trident
->device
== TRIDENT_DEVICE_ID_SI7018
)
3319 snd_iprintf(buffer
, "IEC958 Mixer Out : %s\n", trident
->spdif_ctrl
== 0x28 ? "on" : "off");
3320 if (trident
->device
== TRIDENT_DEVICE_ID_NX
) {
3321 snd_iprintf(buffer
, "Rear Speakers : %s\n", trident
->ac97_ctrl
& 0x00000010 ? "on" : "off");
3322 if (trident
->tlb
.entries
) {
3323 snd_iprintf(buffer
,"\nVirtual Memory\n");
3324 snd_iprintf(buffer
, "Memory Maximum : %d\n", trident
->tlb
.memhdr
->size
);
3325 snd_iprintf(buffer
, "Memory Used : %d\n", trident
->tlb
.memhdr
->used
);
3326 snd_iprintf(buffer
, "Memory Free : %d\n", snd_util_mem_avail(trident
->tlb
.memhdr
));
3331 static void __devinit
snd_trident_proc_init(struct snd_trident
* trident
)
3333 struct snd_info_entry
*entry
;
3334 const char *s
= "trident";
3336 if (trident
->device
== TRIDENT_DEVICE_ID_SI7018
)
3338 if (! snd_card_proc_new(trident
->card
, s
, &entry
))
3339 snd_info_set_text_ops(entry
, trident
, snd_trident_proc_read
);
3342 static int snd_trident_dev_free(struct snd_device
*device
)
3344 struct snd_trident
*trident
= device
->device_data
;
3345 return snd_trident_free(trident
);
3348 /*---------------------------------------------------------------------------
3349 snd_trident_tlb_alloc
3351 Description: Allocate and set up the TLB page table on 4D NX.
3352 Each entry has 4 bytes (physical PCI address).
3354 Parameters: trident - pointer to target device class for 4DWave.
3356 Returns: 0 or negative error code
3358 ---------------------------------------------------------------------------*/
3360 static int __devinit
snd_trident_tlb_alloc(struct snd_trident
*trident
)
3364 /* TLB array must be aligned to 16kB !!! so we allocate
3365 32kB region and correct offset when necessary */
3367 if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV
, snd_dma_pci_data(trident
->pci
),
3368 2 * SNDRV_TRIDENT_MAX_PAGES
* 4, &trident
->tlb
.buffer
) < 0) {
3369 snd_printk(KERN_ERR
"trident: unable to allocate TLB buffer\n");
3372 trident
->tlb
.entries
= (unsigned int*)ALIGN((unsigned long)trident
->tlb
.buffer
.area
, SNDRV_TRIDENT_MAX_PAGES
* 4);
3373 trident
->tlb
.entries_dmaaddr
= ALIGN(trident
->tlb
.buffer
.addr
, SNDRV_TRIDENT_MAX_PAGES
* 4);
3374 /* allocate shadow TLB page table (virtual addresses) */
3375 trident
->tlb
.shadow_entries
= vmalloc(SNDRV_TRIDENT_MAX_PAGES
*sizeof(unsigned long));
3376 if (trident
->tlb
.shadow_entries
== NULL
) {
3377 snd_printk(KERN_ERR
"trident: unable to allocate shadow TLB entries\n");
3380 /* allocate and setup silent page and initialise TLB entries */
3381 if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV
, snd_dma_pci_data(trident
->pci
),
3382 SNDRV_TRIDENT_PAGE_SIZE
, &trident
->tlb
.silent_page
) < 0) {
3383 snd_printk(KERN_ERR
"trident: unable to allocate silent page\n");
3386 memset(trident
->tlb
.silent_page
.area
, 0, SNDRV_TRIDENT_PAGE_SIZE
);
3387 for (i
= 0; i
< SNDRV_TRIDENT_MAX_PAGES
; i
++) {
3388 trident
->tlb
.entries
[i
] = cpu_to_le32(trident
->tlb
.silent_page
.addr
& ~(SNDRV_TRIDENT_PAGE_SIZE
-1));
3389 trident
->tlb
.shadow_entries
[i
] = (unsigned long)trident
->tlb
.silent_page
.area
;
3392 /* use emu memory block manager code to manage tlb page allocation */
3393 trident
->tlb
.memhdr
= snd_util_memhdr_new(SNDRV_TRIDENT_PAGE_SIZE
* SNDRV_TRIDENT_MAX_PAGES
);
3394 if (trident
->tlb
.memhdr
== NULL
)
3397 trident
->tlb
.memhdr
->block_extra_size
= sizeof(struct snd_trident_memblk_arg
);
3402 * initialize 4D DX chip
3405 static void snd_trident_stop_all_voices(struct snd_trident
*trident
)
3407 outl(0xffffffff, TRID_REG(trident
, T4D_STOP_A
));
3408 outl(0xffffffff, TRID_REG(trident
, T4D_STOP_B
));
3409 outl(0, TRID_REG(trident
, T4D_AINTEN_A
));
3410 outl(0, TRID_REG(trident
, T4D_AINTEN_B
));
3413 static int snd_trident_4d_dx_init(struct snd_trident
*trident
)
3415 struct pci_dev
*pci
= trident
->pci
;
3416 unsigned long end_time
;
3418 /* reset the legacy configuration and whole audio/wavetable block */
3419 pci_write_config_dword(pci
, 0x40, 0); /* DDMA */
3420 pci_write_config_byte(pci
, 0x44, 0); /* ports */
3421 pci_write_config_byte(pci
, 0x45, 0); /* Legacy DMA */
3422 pci_write_config_byte(pci
, 0x46, 4); /* reset */
3424 pci_write_config_byte(pci
, 0x46, 0); /* release reset */
3427 /* warm reset of the AC'97 codec */
3428 outl(0x00000001, TRID_REG(trident
, DX_ACR2_AC97_COM_STAT
));
3430 outl(0x00000000, TRID_REG(trident
, DX_ACR2_AC97_COM_STAT
));
3431 /* DAC on, disable SB IRQ and try to force ADC valid signal */
3432 trident
->ac97_ctrl
= 0x0000004a;
3433 outl(trident
->ac97_ctrl
, TRID_REG(trident
, DX_ACR2_AC97_COM_STAT
));
3434 /* wait, until the codec is ready */
3435 end_time
= (jiffies
+ (HZ
* 3) / 4) + 1;
3437 if ((inl(TRID_REG(trident
, DX_ACR2_AC97_COM_STAT
)) & 0x0010) != 0)
3440 } while (time_after_eq(end_time
, jiffies
));
3441 snd_printk(KERN_ERR
"AC'97 codec ready error\n");
3445 snd_trident_stop_all_voices(trident
);
3451 * initialize 4D NX chip
3453 static int snd_trident_4d_nx_init(struct snd_trident
*trident
)
3455 struct pci_dev
*pci
= trident
->pci
;
3456 unsigned long end_time
;
3458 /* reset the legacy configuration and whole audio/wavetable block */
3459 pci_write_config_dword(pci
, 0x40, 0); /* DDMA */
3460 pci_write_config_byte(pci
, 0x44, 0); /* ports */
3461 pci_write_config_byte(pci
, 0x45, 0); /* Legacy DMA */
3463 pci_write_config_byte(pci
, 0x46, 1); /* reset */
3465 pci_write_config_byte(pci
, 0x46, 0); /* release reset */
3468 /* warm reset of the AC'97 codec */
3469 outl(0x00000001, TRID_REG(trident
, NX_ACR0_AC97_COM_STAT
));
3471 outl(0x00000000, TRID_REG(trident
, NX_ACR0_AC97_COM_STAT
));
3472 /* wait, until the codec is ready */
3473 end_time
= (jiffies
+ (HZ
* 3) / 4) + 1;
3475 if ((inl(TRID_REG(trident
, NX_ACR0_AC97_COM_STAT
)) & 0x0008) != 0)
3478 } while (time_after_eq(end_time
, jiffies
));
3479 snd_printk(KERN_ERR
"AC'97 codec ready error [0x%x]\n", inl(TRID_REG(trident
, NX_ACR0_AC97_COM_STAT
)));
3484 trident
->ac97_ctrl
= 0x00000002;
3485 outl(trident
->ac97_ctrl
, TRID_REG(trident
, NX_ACR0_AC97_COM_STAT
));
3486 /* disable SB IRQ */
3487 outl(NX_SB_IRQ_DISABLE
, TRID_REG(trident
, T4D_MISCINT
));
3489 snd_trident_stop_all_voices(trident
);
3491 if (trident
->tlb
.entries
!= NULL
) {
3493 /* enable virtual addressing via TLB */
3494 i
= trident
->tlb
.entries_dmaaddr
;
3496 outl(i
, TRID_REG(trident
, NX_TLBC
));
3498 outl(0, TRID_REG(trident
, NX_TLBC
));
3500 /* initialize S/PDIF */
3501 outl(trident
->spdif_bits
, TRID_REG(trident
, NX_SPCSTATUS
));
3502 outb(trident
->spdif_ctrl
, TRID_REG(trident
, NX_SPCTRL_SPCSO
+ 3));
3508 * initialize sis7018 chip
3510 static int snd_trident_sis_init(struct snd_trident
*trident
)
3514 if ((err
= snd_trident_sis_reset(trident
)) < 0)
3517 snd_trident_stop_all_voices(trident
);
3519 /* initialize S/PDIF */
3520 outl(trident
->spdif_bits
, TRID_REG(trident
, SI_SPDIF_CS
));
3525 /*---------------------------------------------------------------------------
3528 Description: This routine will create the device specific class for
3529 the 4DWave card. It will also perform basic initialization.
3531 Parameters: card - which card to create
3532 pci - interface to PCI bus resource info
3533 dma1ptr - playback dma buffer
3534 dma2ptr - capture dma buffer
3535 irqptr - interrupt resource info
3537 Returns: 4DWave device class private data
3539 ---------------------------------------------------------------------------*/
3541 int __devinit
snd_trident_create(struct snd_card
*card
,
3542 struct pci_dev
*pci
,
3544 int pcm_spdif_device
,
3545 int max_wavetable_size
,
3546 struct snd_trident
** rtrident
)
3548 struct snd_trident
*trident
;
3550 struct snd_trident_voice
*voice
;
3551 struct snd_trident_pcm_mixer
*tmix
;
3552 static struct snd_device_ops ops
= {
3553 .dev_free
= snd_trident_dev_free
,
3558 /* enable PCI device */
3559 if ((err
= pci_enable_device(pci
)) < 0)
3561 /* check, if we can restrict PCI DMA transfers to 30 bits */
3562 if (pci_set_dma_mask(pci
, DMA_BIT_MASK(30)) < 0 ||
3563 pci_set_consistent_dma_mask(pci
, DMA_BIT_MASK(30)) < 0) {
3564 snd_printk(KERN_ERR
"architecture does not support 30bit PCI busmaster DMA\n");
3565 pci_disable_device(pci
);
3569 trident
= kzalloc(sizeof(*trident
), GFP_KERNEL
);
3570 if (trident
== NULL
) {
3571 pci_disable_device(pci
);
3574 trident
->device
= (pci
->vendor
<< 16) | pci
->device
;
3575 trident
->card
= card
;
3577 spin_lock_init(&trident
->reg_lock
);
3578 spin_lock_init(&trident
->event_lock
);
3579 spin_lock_init(&trident
->voice_alloc
);
3580 if (pcm_streams
< 1)
3582 if (pcm_streams
> 32)
3584 trident
->ChanPCM
= pcm_streams
;
3585 if (max_wavetable_size
< 0 )
3586 max_wavetable_size
= 0;
3587 trident
->synth
.max_size
= max_wavetable_size
* 1024;
3590 trident
->midi_port
= TRID_REG(trident
, T4D_MPU401_BASE
);
3591 pci_set_master(pci
);
3593 if ((err
= pci_request_regions(pci
, "Trident Audio")) < 0) {
3595 pci_disable_device(pci
);
3598 trident
->port
= pci_resource_start(pci
, 0);
3600 if (request_irq(pci
->irq
, snd_trident_interrupt
, IRQF_SHARED
,
3601 "Trident Audio", trident
)) {
3602 snd_printk(KERN_ERR
"unable to grab IRQ %d\n", pci
->irq
);
3603 snd_trident_free(trident
);
3606 trident
->irq
= pci
->irq
;
3608 /* allocate 16k-aligned TLB for NX cards */
3609 trident
->tlb
.entries
= NULL
;
3610 trident
->tlb
.buffer
.area
= NULL
;
3611 if (trident
->device
== TRIDENT_DEVICE_ID_NX
) {
3612 if ((err
= snd_trident_tlb_alloc(trident
)) < 0) {
3613 snd_trident_free(trident
);
3618 trident
->spdif_bits
= trident
->spdif_pcm_bits
= SNDRV_PCM_DEFAULT_CON_SPDIF
;
3620 /* initialize chip */
3621 switch (trident
->device
) {
3622 case TRIDENT_DEVICE_ID_DX
:
3623 err
= snd_trident_4d_dx_init(trident
);
3625 case TRIDENT_DEVICE_ID_NX
:
3626 err
= snd_trident_4d_nx_init(trident
);
3628 case TRIDENT_DEVICE_ID_SI7018
:
3629 err
= snd_trident_sis_init(trident
);
3636 snd_trident_free(trident
);
3640 if ((err
= snd_device_new(card
, SNDRV_DEV_LOWLEVEL
, trident
, &ops
)) < 0) {
3641 snd_trident_free(trident
);
3645 if ((err
= snd_trident_mixer(trident
, pcm_spdif_device
)) < 0)
3648 /* initialise synth voices */
3649 for (i
= 0; i
< 64; i
++) {
3650 voice
= &trident
->synth
.voices
[i
];
3652 voice
->trident
= trident
;
3654 /* initialize pcm mixer entries */
3655 for (i
= 0; i
< 32; i
++) {
3656 tmix
= &trident
->pcm_mixer
[i
];
3657 tmix
->vol
= T4D_DEFAULT_PCM_VOL
;
3658 tmix
->pan
= T4D_DEFAULT_PCM_PAN
;
3659 tmix
->rvol
= T4D_DEFAULT_PCM_RVOL
;
3660 tmix
->cvol
= T4D_DEFAULT_PCM_CVOL
;
3663 snd_trident_enable_eso(trident
);
3665 snd_trident_proc_init(trident
);
3666 snd_card_set_dev(card
, &pci
->dev
);
3667 *rtrident
= trident
;
3671 /*---------------------------------------------------------------------------
3674 Description: This routine will free the device specific class for
3677 Parameters: trident - device specific private data for 4DWave card
3681 ---------------------------------------------------------------------------*/
3683 static int snd_trident_free(struct snd_trident
*trident
)
3685 snd_trident_free_gameport(trident
);
3686 snd_trident_disable_eso(trident
);
3687 // Disable S/PDIF out
3688 if (trident
->device
== TRIDENT_DEVICE_ID_NX
)
3689 outb(0x00, TRID_REG(trident
, NX_SPCTRL_SPCSO
+ 3));
3690 else if (trident
->device
== TRIDENT_DEVICE_ID_SI7018
) {
3691 outl(0, TRID_REG(trident
, SI_SERIAL_INTF_CTRL
));
3693 if (trident
->irq
>= 0)
3694 free_irq(trident
->irq
, trident
);
3695 if (trident
->tlb
.buffer
.area
) {
3696 outl(0, TRID_REG(trident
, NX_TLBC
));
3697 if (trident
->tlb
.memhdr
)
3698 snd_util_memhdr_free(trident
->tlb
.memhdr
);
3699 if (trident
->tlb
.silent_page
.area
)
3700 snd_dma_free_pages(&trident
->tlb
.silent_page
);
3701 vfree(trident
->tlb
.shadow_entries
);
3702 snd_dma_free_pages(&trident
->tlb
.buffer
);
3704 pci_release_regions(trident
->pci
);
3705 pci_disable_device(trident
->pci
);
3710 /*---------------------------------------------------------------------------
3711 snd_trident_interrupt
3713 Description: ISR for Trident 4DWave device
3715 Parameters: trident - device specific private data for 4DWave card
3717 Problems: It seems that Trident chips generates interrupts more than
3718 one time in special cases. The spurious interrupts are
3719 detected via sample timer (T4D_STIMER) and computing
3720 corresponding delta value. The limits are detected with
3721 the method try & fail so it is possible that it won't
3722 work on all computers. [jaroslav]
3726 ---------------------------------------------------------------------------*/
3728 static irqreturn_t
snd_trident_interrupt(int irq
, void *dev_id
)
3730 struct snd_trident
*trident
= dev_id
;
3731 unsigned int audio_int
, chn_int
, stimer
, channel
, mask
, tmp
;
3733 struct snd_trident_voice
*voice
;
3735 audio_int
= inl(TRID_REG(trident
, T4D_MISCINT
));
3736 if ((audio_int
& (ADDRESS_IRQ
|MPU401_IRQ
)) == 0)
3738 if (audio_int
& ADDRESS_IRQ
) {
3739 // get interrupt status for all channels
3740 spin_lock(&trident
->reg_lock
);
3741 stimer
= inl(TRID_REG(trident
, T4D_STIMER
)) & 0x00ffffff;
3742 chn_int
= inl(TRID_REG(trident
, T4D_AINT_A
));
3745 outl(chn_int
, TRID_REG(trident
, T4D_AINT_A
)); /* ack */
3747 chn_int
= inl(TRID_REG(trident
, T4D_AINT_B
));
3750 for (channel
= 63; channel
>= 32; channel
--) {
3751 mask
= 1 << (channel
&0x1f);
3752 if ((chn_int
& mask
) == 0)
3754 voice
= &trident
->synth
.voices
[channel
];
3755 if (!voice
->pcm
|| voice
->substream
== NULL
) {
3756 outl(mask
, TRID_REG(trident
, T4D_STOP_B
));
3759 delta
= (int)stimer
- (int)voice
->stimer
;
3762 if ((unsigned int)delta
< voice
->spurious_threshold
) {
3763 /* do some statistics here */
3764 trident
->spurious_irq_count
++;
3765 if (trident
->spurious_irq_max_delta
< (unsigned int)delta
)
3766 trident
->spurious_irq_max_delta
= delta
;
3769 voice
->stimer
= stimer
;
3771 if (!voice
->isync3
) {
3772 tmp
= inw(TRID_REG(trident
, T4D_SBBL_SBCL
));
3773 if (trident
->bDMAStart
& 0x40)
3776 tmp
= voice
->isync_max
- tmp
;
3778 tmp
= inl(TRID_REG(trident
, NX_SPCTRL_SPCSO
)) & 0x00ffffff;
3780 if (tmp
< voice
->isync_mark
) {
3782 tmp
= voice
->isync_ESO
- 7;
3784 tmp
= voice
->isync_ESO
+ 2;
3785 /* update ESO for IRQ voice to preserve sync */
3786 snd_trident_stop_voice(trident
, voice
->number
);
3787 snd_trident_write_eso_reg(trident
, voice
, tmp
);
3788 snd_trident_start_voice(trident
, voice
->number
);
3790 } else if (voice
->isync2
) {
3792 /* write original ESO and update CSO for IRQ voice to preserve sync */
3793 snd_trident_stop_voice(trident
, voice
->number
);
3794 snd_trident_write_cso_reg(trident
, voice
, voice
->isync_mark
);
3795 snd_trident_write_eso_reg(trident
, voice
, voice
->ESO
);
3796 snd_trident_start_voice(trident
, voice
->number
);
3800 /* update CSO for extra voice to preserve sync */
3801 snd_trident_stop_voice(trident
, voice
->extra
->number
);
3802 snd_trident_write_cso_reg(trident
, voice
->extra
, 0);
3803 snd_trident_start_voice(trident
, voice
->extra
->number
);
3806 spin_unlock(&trident
->reg_lock
);
3807 snd_pcm_period_elapsed(voice
->substream
);
3808 spin_lock(&trident
->reg_lock
);
3810 outl(chn_int
, TRID_REG(trident
, T4D_AINT_B
)); /* ack */
3812 spin_unlock(&trident
->reg_lock
);
3814 if (audio_int
& MPU401_IRQ
) {
3815 if (trident
->rmidi
) {
3816 snd_mpu401_uart_interrupt(irq
, trident
->rmidi
->private_data
);
3818 inb(TRID_REG(trident
, T4D_MPUR0
));
3821 // outl((ST_TARGET_REACHED | MIXER_OVERFLOW | MIXER_UNDERFLOW), TRID_REG(trident, T4D_MISCINT));
3825 struct snd_trident_voice
*snd_trident_alloc_voice(struct snd_trident
* trident
, int type
, int client
, int port
)
3827 struct snd_trident_voice
*pvoice
;
3828 unsigned long flags
;
3831 spin_lock_irqsave(&trident
->voice_alloc
, flags
);
3832 if (type
== SNDRV_TRIDENT_VOICE_TYPE_PCM
) {
3833 idx
= snd_trident_allocate_pcm_channel(trident
);
3835 spin_unlock_irqrestore(&trident
->voice_alloc
, flags
);
3838 pvoice
= &trident
->synth
.voices
[idx
];
3841 pvoice
->capture
= 0;
3843 pvoice
->memblk
= NULL
;
3844 pvoice
->substream
= NULL
;
3845 spin_unlock_irqrestore(&trident
->voice_alloc
, flags
);
3848 if (type
== SNDRV_TRIDENT_VOICE_TYPE_SYNTH
) {
3849 idx
= snd_trident_allocate_synth_channel(trident
);
3851 spin_unlock_irqrestore(&trident
->voice_alloc
, flags
);
3854 pvoice
= &trident
->synth
.voices
[idx
];
3857 pvoice
->client
= client
;
3858 pvoice
->port
= port
;
3859 pvoice
->memblk
= NULL
;
3860 spin_unlock_irqrestore(&trident
->voice_alloc
, flags
);
3863 if (type
== SNDRV_TRIDENT_VOICE_TYPE_MIDI
) {
3865 spin_unlock_irqrestore(&trident
->voice_alloc
, flags
);
3869 EXPORT_SYMBOL(snd_trident_alloc_voice
);
3871 void snd_trident_free_voice(struct snd_trident
* trident
, struct snd_trident_voice
*voice
)
3873 unsigned long flags
;
3874 void (*private_free
)(struct snd_trident_voice
*);
3877 if (voice
== NULL
|| !voice
->use
)
3879 snd_trident_clear_voices(trident
, voice
->number
, voice
->number
);
3880 spin_lock_irqsave(&trident
->voice_alloc
, flags
);
3881 private_free
= voice
->private_free
;
3882 private_data
= voice
->private_data
;
3883 voice
->private_free
= NULL
;
3884 voice
->private_data
= NULL
;
3886 snd_trident_free_pcm_channel(trident
, voice
->number
);
3888 snd_trident_free_synth_channel(trident
, voice
->number
);
3889 voice
->use
= voice
->pcm
= voice
->synth
= voice
->midi
= 0;
3890 voice
->capture
= voice
->spdif
= 0;
3891 voice
->sample_ops
= NULL
;
3892 voice
->substream
= NULL
;
3893 voice
->extra
= NULL
;
3894 spin_unlock_irqrestore(&trident
->voice_alloc
, flags
);
3896 private_free(voice
);
3899 EXPORT_SYMBOL(snd_trident_free_voice
);
3901 static void snd_trident_clear_voices(struct snd_trident
* trident
, unsigned short v_min
, unsigned short v_max
)
3903 unsigned int i
, val
, mask
[2] = { 0, 0 };
3905 if (snd_BUG_ON(v_min
> 63 || v_max
> 63))
3907 for (i
= v_min
; i
<= v_max
; i
++)
3908 mask
[i
>> 5] |= 1 << (i
& 0x1f);
3910 outl(mask
[0], TRID_REG(trident
, T4D_STOP_A
));
3911 val
= inl(TRID_REG(trident
, T4D_AINTEN_A
));
3912 outl(val
& ~mask
[0], TRID_REG(trident
, T4D_AINTEN_A
));
3915 outl(mask
[1], TRID_REG(trident
, T4D_STOP_B
));
3916 val
= inl(TRID_REG(trident
, T4D_AINTEN_B
));
3917 outl(val
& ~mask
[1], TRID_REG(trident
, T4D_AINTEN_B
));
3922 int snd_trident_suspend(struct pci_dev
*pci
, pm_message_t state
)
3924 struct snd_card
*card
= pci_get_drvdata(pci
);
3925 struct snd_trident
*trident
= card
->private_data
;
3927 trident
->in_suspend
= 1;
3928 snd_power_change_state(card
, SNDRV_CTL_POWER_D3hot
);
3929 snd_pcm_suspend_all(trident
->pcm
);
3930 snd_pcm_suspend_all(trident
->foldback
);
3931 snd_pcm_suspend_all(trident
->spdif
);
3933 snd_ac97_suspend(trident
->ac97
);
3934 snd_ac97_suspend(trident
->ac97_sec
);
3936 pci_disable_device(pci
);
3937 pci_save_state(pci
);
3938 pci_set_power_state(pci
, pci_choose_state(pci
, state
));
3942 int snd_trident_resume(struct pci_dev
*pci
)
3944 struct snd_card
*card
= pci_get_drvdata(pci
);
3945 struct snd_trident
*trident
= card
->private_data
;
3947 pci_set_power_state(pci
, PCI_D0
);
3948 pci_restore_state(pci
);
3949 if (pci_enable_device(pci
) < 0) {
3950 printk(KERN_ERR
"trident: pci_enable_device failed, "
3951 "disabling device\n");
3952 snd_card_disconnect(card
);
3955 pci_set_master(pci
);
3957 switch (trident
->device
) {
3958 case TRIDENT_DEVICE_ID_DX
:
3959 snd_trident_4d_dx_init(trident
);
3961 case TRIDENT_DEVICE_ID_NX
:
3962 snd_trident_4d_nx_init(trident
);
3964 case TRIDENT_DEVICE_ID_SI7018
:
3965 snd_trident_sis_init(trident
);
3969 snd_ac97_resume(trident
->ac97
);
3970 snd_ac97_resume(trident
->ac97_sec
);
3972 /* restore some registers */
3973 outl(trident
->musicvol_wavevol
, TRID_REG(trident
, T4D_MUSICVOL_WAVEVOL
));
3975 snd_trident_enable_eso(trident
);
3977 snd_power_change_state(card
, SNDRV_CTL_POWER_D0
);
3978 trident
->in_suspend
= 0;
3981 #endif /* CONFIG_PM */