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