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