File Index
Files and directories
Sign in
FILE

trident_main.c

File preview with syntax highlighting.

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