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