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