~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/sound/pci/trident/trident_main.c

Version: ~ [ linux-5.4-rc3 ] ~ [ linux-5.3.6 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.79 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.149 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.196 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.196 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.19.8 ] ~ [ linux-3.18.140 ] ~ [ linux-3.17.8 ] ~ [ linux-3.16.75 ] ~ [ linux-3.15.10 ] ~ [ linux-3.14.79 ] ~ [ linux-3.13.11 ] ~ [ linux-3.12.74 ] ~ [ linux-3.11.10 ] ~ [ linux-3.10.108 ] ~ [ linux-3.9.11 ] ~ [ linux-3.8.13 ] ~ [ linux-3.7.10 ] ~ [ linux-3.6.11 ] ~ [ linux-3.5.7 ] ~ [ linux-3.4.113 ] ~ [ linux-3.3.8 ] ~ [ linux-3.2.102 ] ~ [ linux-3.1.10 ] ~ [ linux-3.0.101 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.5 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

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

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

osdn.jp