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