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