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#include <linux/io.h>
  40
  41#include <sound/core.h>
  42#include <sound/info.h>
  43#include <sound/control.h>
  44#include <sound/tlv.h>
  45#include "trident.h"
  46#include <sound/asoundef.h>
  47
  48static int snd_trident_pcm_mixer_build(struct snd_trident *trident,
  49                                       struct snd_trident_voice * voice,
  50                                       struct snd_pcm_substream *substream);
  51static int snd_trident_pcm_mixer_free(struct snd_trident *trident,
  52                                      struct snd_trident_voice * voice,
  53                                      struct snd_pcm_substream *substream);
  54static irqreturn_t snd_trident_interrupt(int irq, void *dev_id);
  55static int snd_trident_sis_reset(struct snd_trident *trident);
  56
  57static void snd_trident_clear_voices(struct snd_trident * trident,
  58                                     unsigned short v_min, unsigned short v_max);
  59static int snd_trident_free(struct snd_trident *trident);
  60
  61/*
  62 *  common I/O routines
  63 */
  64
  65
  66#if 0
  67static void snd_trident_print_voice_regs(struct snd_trident *trident, int voice)
  68{
  69        unsigned int val, tmp;
  70
  71        dev_dbg(trident->card->dev, "Trident voice %i:\n", voice);
  72        outb(voice, TRID_REG(trident, T4D_LFO_GC_CIR));
  73        val = inl(TRID_REG(trident, CH_LBA));
  74        dev_dbg(trident->card->dev, "LBA: 0x%x\n", val);
  75        val = inl(TRID_REG(trident, CH_GVSEL_PAN_VOL_CTRL_EC));
  76        dev_dbg(trident->card->dev, "GVSel: %i\n", val >> 31);
  77        dev_dbg(trident->card->dev, "Pan: 0x%x\n", (val >> 24) & 0x7f);
  78        dev_dbg(trident->card->dev, "Vol: 0x%x\n", (val >> 16) & 0xff);
  79        dev_dbg(trident->card->dev, "CTRL: 0x%x\n", (val >> 12) & 0x0f);
  80        dev_dbg(trident->card->dev, "EC: 0x%x\n", val & 0x0fff);
  81        if (trident->device != TRIDENT_DEVICE_ID_NX) {
  82                val = inl(TRID_REG(trident, CH_DX_CSO_ALPHA_FMS));
  83                dev_dbg(trident->card->dev, "CSO: 0x%x\n", val >> 16);
  84                dev_dbg(trident->card->dev, "Alpha: 0x%x\n", (val >> 4) & 0x0fff);
  85                dev_dbg(trident->card->dev, "FMS: 0x%x\n", val & 0x0f);
  86                val = inl(TRID_REG(trident, CH_DX_ESO_DELTA));
  87                dev_dbg(trident->card->dev, "ESO: 0x%x\n", val >> 16);
  88                dev_dbg(trident->card->dev, "Delta: 0x%x\n", val & 0xffff);
  89                val = inl(TRID_REG(trident, CH_DX_FMC_RVOL_CVOL));
  90        } else {                // TRIDENT_DEVICE_ID_NX
  91                val = inl(TRID_REG(trident, CH_NX_DELTA_CSO));
  92                tmp = (val >> 24) & 0xff;
  93                dev_dbg(trident->card->dev, "CSO: 0x%x\n", val & 0x00ffffff);
  94                val = inl(TRID_REG(trident, CH_NX_DELTA_ESO));
  95                tmp |= (val >> 16) & 0xff00;
  96                dev_dbg(trident->card->dev, "Delta: 0x%x\n", tmp);
  97                dev_dbg(trident->card->dev, "ESO: 0x%x\n", val & 0x00ffffff);
  98                val = inl(TRID_REG(trident, CH_NX_ALPHA_FMS_FMC_RVOL_CVOL));
  99                dev_dbg(trident->card->dev, "Alpha: 0x%x\n", val >> 20);
 100                dev_dbg(trident->card->dev, "FMS: 0x%x\n", (val >> 16) & 0x0f);
 101        }
 102        dev_dbg(trident->card->dev, "FMC: 0x%x\n", (val >> 14) & 3);
 103        dev_dbg(trident->card->dev, "RVol: 0x%x\n", (val >> 7) & 0x7f);
 104        dev_dbg(trident->card->dev, "CVol: 0x%x\n", val & 0x7f);
 105}
 106#endif
 107
 108/*---------------------------------------------------------------------------
 109   unsigned short snd_trident_codec_read(struct snd_ac97 *ac97, unsigned short reg)
 110  
 111   Description: This routine will do all of the reading from the external
 112                CODEC (AC97).
 113  
 114   Parameters:  ac97 - ac97 codec structure
 115                reg - CODEC register index, from AC97 Hal.
 116 
 117   returns:     16 bit value read from the AC97.
 118  
 119  ---------------------------------------------------------------------------*/
 120static unsigned short snd_trident_codec_read(struct snd_ac97 *ac97, unsigned short reg)
 121{
 122        unsigned int data = 0, treg;
 123        unsigned short count = 0xffff;
 124        unsigned long flags;
 125        struct snd_trident *trident = ac97->private_data;
 126
 127        spin_lock_irqsave(&trident->reg_lock, flags);
 128        if (trident->device == TRIDENT_DEVICE_ID_DX) {
 129                data = (DX_AC97_BUSY_READ | (reg & 0x000000ff));
 130                outl(data, TRID_REG(trident, DX_ACR1_AC97_R));
 131                do {
 132                        data = inl(TRID_REG(trident, DX_ACR1_AC97_R));
 133                        if ((data & DX_AC97_BUSY_READ) == 0)
 134                                break;
 135                } while (--count);
 136        } else if (trident->device == TRIDENT_DEVICE_ID_NX) {
 137                data = (NX_AC97_BUSY_READ | (reg & 0x000000ff));
 138                treg = ac97->num == 0 ? NX_ACR2_AC97_R_PRIMARY : NX_ACR3_AC97_R_SECONDARY;
 139                outl(data, TRID_REG(trident, treg));
 140                do {
 141                        data = inl(TRID_REG(trident, treg));
 142                        if ((data & 0x00000C00) == 0)
 143                                break;
 144                } while (--count);
 145        } else if (trident->device == TRIDENT_DEVICE_ID_SI7018) {
 146                data = SI_AC97_BUSY_READ | SI_AC97_AUDIO_BUSY | (reg & 0x000000ff);
 147                if (ac97->num == 1)
 148                        data |= SI_AC97_SECONDARY;
 149                outl(data, TRID_REG(trident, SI_AC97_READ));
 150                do {
 151                        data = inl(TRID_REG(trident, SI_AC97_READ));
 152                        if ((data & (SI_AC97_BUSY_READ)) == 0)
 153                                break;
 154                } while (--count);
 155        }
 156
 157        if (count == 0 && !trident->ac97_detect) {
 158                dev_err(trident->card->dev,
 159                        "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        dev_dbg(trident->card->dev, "written %i channel:\n", voice->number);
 501        dev_dbg(trident->card->dev, "  regs[0] = 0x%x/0x%x\n",
 502               regs[0], inl(TRID_REG(trident, CH_START + 0)));
 503        dev_dbg(trident->card->dev, "  regs[1] = 0x%x/0x%x\n",
 504               regs[1], inl(TRID_REG(trident, CH_START + 4)));
 505        dev_dbg(trident->card->dev, "  regs[2] = 0x%x/0x%x\n",
 506               regs[2], inl(TRID_REG(trident, CH_START + 8)));
 507        dev_dbg(trident->card->dev, "  regs[3] = 0x%x/0x%x\n",
 508               regs[3], inl(TRID_REG(trident, CH_START + 12)));
 509        dev_dbg(trident->card->dev, "  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                /* dev_dbg(trident->card->dev, "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 const 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 const 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 const 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 const 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 const 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 const 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 const 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 const 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 const 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 const 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 const 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 const 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 const 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, int device)
2175{
2176        struct snd_pcm *pcm;
2177        int err;
2178
2179        if ((err = snd_pcm_new(trident->card, "trident_dx_nx", device, trident->ChanPCM, 1, &pcm)) < 0)
2180                return err;
2181
2182        pcm->private_data = trident;
2183
2184        if (trident->tlb.entries) {
2185                snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_trident_nx_playback_ops);
2186        } else {
2187                snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_trident_playback_ops);
2188        }
2189        snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
2190                        trident->device != TRIDENT_DEVICE_ID_SI7018 ?
2191                        &snd_trident_capture_ops :
2192                        &snd_trident_si7018_capture_ops);
2193
2194        pcm->info_flags = 0;
2195        pcm->dev_subclass = SNDRV_PCM_SUBCLASS_GENERIC_MIX;
2196        strcpy(pcm->name, "Trident 4DWave");
2197        trident->pcm = pcm;
2198
2199        if (trident->tlb.entries) {
2200                struct snd_pcm_substream *substream;
2201                for (substream = pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream; substream; substream = substream->next)
2202                        snd_pcm_lib_preallocate_pages(substream, SNDRV_DMA_TYPE_DEV_SG,
2203                                                      snd_dma_pci_data(trident->pci),
2204                                                      64*1024, 128*1024);
2205                snd_pcm_lib_preallocate_pages(pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream,
2206                                              SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(trident->pci),
2207                                              64*1024, 128*1024);
2208        } else {
2209                snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
2210                                                      snd_dma_pci_data(trident->pci), 64*1024, 128*1024);
2211        }
2212
2213        return 0;
2214}
2215
2216/*---------------------------------------------------------------------------
2217   snd_trident_foldback_pcm
2218  
2219   Description: This routine registers the 4DWave device for foldback PCM support.
2220                
2221   Parameters:  trident - pointer to target device class for 4DWave.
2222
2223   Returns:     None
2224  
2225  ---------------------------------------------------------------------------*/
2226
2227int snd_trident_foldback_pcm(struct snd_trident *trident, int device)
2228{
2229        struct snd_pcm *foldback;
2230        int err;
2231        int num_chan = 3;
2232        struct snd_pcm_substream *substream;
2233
2234        if (trident->device == TRIDENT_DEVICE_ID_NX)
2235                num_chan = 4;
2236        if ((err = snd_pcm_new(trident->card, "trident_dx_nx", device, 0, num_chan, &foldback)) < 0)
2237                return err;
2238
2239        foldback->private_data = trident;
2240        if (trident->tlb.entries)
2241                snd_pcm_set_ops(foldback, SNDRV_PCM_STREAM_CAPTURE, &snd_trident_nx_foldback_ops);
2242        else
2243                snd_pcm_set_ops(foldback, SNDRV_PCM_STREAM_CAPTURE, &snd_trident_foldback_ops);
2244        foldback->info_flags = 0;
2245        strcpy(foldback->name, "Trident 4DWave");
2246        substream = foldback->streams[SNDRV_PCM_STREAM_CAPTURE].substream;
2247        strcpy(substream->name, "Front Mixer");
2248        substream = substream->next;
2249        strcpy(substream->name, "Reverb Mixer");
2250        substream = substream->next;
2251        strcpy(substream->name, "Chorus Mixer");
2252        if (num_chan == 4) {
2253                substream = substream->next;
2254                strcpy(substream->name, "Second AC'97 ADC");
2255        }
2256        trident->foldback = foldback;
2257
2258        if (trident->tlb.entries)
2259                snd_pcm_lib_preallocate_pages_for_all(foldback, SNDRV_DMA_TYPE_DEV_SG,
2260                                                      snd_dma_pci_data(trident->pci), 0, 128*1024);
2261        else
2262                snd_pcm_lib_preallocate_pages_for_all(foldback, SNDRV_DMA_TYPE_DEV,
2263                                                      snd_dma_pci_data(trident->pci), 64*1024, 128*1024);
2264
2265        return 0;
2266}
2267
2268/*---------------------------------------------------------------------------
2269   snd_trident_spdif
2270  
2271   Description: This routine registers the 4DWave-NX device for SPDIF support.
2272                
2273   Parameters:  trident - pointer to target device class for 4DWave-NX.
2274
2275   Returns:     None
2276  
2277  ---------------------------------------------------------------------------*/
2278
2279int snd_trident_spdif_pcm(struct snd_trident *trident, int device)
2280{
2281        struct snd_pcm *spdif;
2282        int err;
2283
2284        if ((err = snd_pcm_new(trident->card, "trident_dx_nx IEC958", device, 1, 0, &spdif)) < 0)
2285                return err;
2286
2287        spdif->private_data = trident;
2288        if (trident->device != TRIDENT_DEVICE_ID_SI7018) {
2289                snd_pcm_set_ops(spdif, SNDRV_PCM_STREAM_PLAYBACK, &snd_trident_spdif_ops);
2290        } else {
2291                snd_pcm_set_ops(spdif, SNDRV_PCM_STREAM_PLAYBACK, &snd_trident_spdif_7018_ops);
2292        }
2293        spdif->info_flags = 0;
2294        strcpy(spdif->name, "Trident 4DWave IEC958");
2295        trident->spdif = spdif;
2296
2297        snd_pcm_lib_preallocate_pages_for_all(spdif, SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(trident->pci), 64*1024, 128*1024);
2298
2299        return 0;
2300}
2301
2302/*
2303 *  Mixer part
2304 */
2305
2306
2307/*---------------------------------------------------------------------------
2308    snd_trident_spdif_control
2309
2310    Description: enable/disable S/PDIF out from ac97 mixer
2311  ---------------------------------------------------------------------------*/
2312
2313#define snd_trident_spdif_control_info  snd_ctl_boolean_mono_info
2314
2315static int snd_trident_spdif_control_get(struct snd_kcontrol *kcontrol,
2316                                         struct snd_ctl_elem_value *ucontrol)
2317{
2318        struct snd_trident *trident = snd_kcontrol_chip(kcontrol);
2319        unsigned char val;
2320
2321        spin_lock_irq(&trident->reg_lock);
2322        val = trident->spdif_ctrl;
2323        ucontrol->value.integer.value[0] = val == kcontrol->private_value;
2324        spin_unlock_irq(&trident->reg_lock);
2325        return 0;
2326}
2327
2328static int snd_trident_spdif_control_put(struct snd_kcontrol *kcontrol,
2329                                         struct snd_ctl_elem_value *ucontrol)
2330{
2331        struct snd_trident *trident = snd_kcontrol_chip(kcontrol);
2332        unsigned char val;
2333        int change;
2334
2335        val = ucontrol->value.integer.value[0] ? (unsigned char) kcontrol->private_value : 0x00;
2336        spin_lock_irq(&trident->reg_lock);
2337        /* S/PDIF C Channel bits 0-31 : 48khz, SCMS disabled */
2338        change = trident->spdif_ctrl != val;
2339        trident->spdif_ctrl = val;
2340        if (trident->device != TRIDENT_DEVICE_ID_SI7018) {
2341                if ((inb(TRID_REG(trident, NX_SPCTRL_SPCSO + 3)) & 0x10) == 0) {
2342                        outl(trident->spdif_bits, TRID_REG(trident, NX_SPCSTATUS));
2343                        outb(trident->spdif_ctrl, TRID_REG(trident, NX_SPCTRL_SPCSO + 3));
2344                }
2345        } else {
2346                if (trident->spdif == NULL) {
2347                        unsigned int temp;
2348                        outl(trident->spdif_bits, TRID_REG(trident, SI_SPDIF_CS));
2349                        temp = inl(TRID_REG(trident, SI_SERIAL_INTF_CTRL)) & ~SPDIF_EN;
2350                        if (val)
2351                                temp |= SPDIF_EN;
2352                        outl(temp, TRID_REG(trident, SI_SERIAL_INTF_CTRL));
2353                }
2354        }
2355        spin_unlock_irq(&trident->reg_lock);
2356        return change;
2357}
2358
2359static const struct snd_kcontrol_new snd_trident_spdif_control =
2360{
2361        .iface =        SNDRV_CTL_ELEM_IFACE_MIXER,
2362        .name =         SNDRV_CTL_NAME_IEC958("",PLAYBACK,SWITCH),
2363        .info =         snd_trident_spdif_control_info,
2364        .get =          snd_trident_spdif_control_get,
2365        .put =          snd_trident_spdif_control_put,
2366        .private_value = 0x28,
2367};
2368
2369/*---------------------------------------------------------------------------
2370    snd_trident_spdif_default
2371
2372    Description: put/get the S/PDIF default settings
2373  ---------------------------------------------------------------------------*/
2374
2375static int snd_trident_spdif_default_info(struct snd_kcontrol *kcontrol,
2376                                          struct snd_ctl_elem_info *uinfo)
2377{
2378        uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
2379        uinfo->count = 1;
2380        return 0;
2381}
2382
2383static int snd_trident_spdif_default_get(struct snd_kcontrol *kcontrol,
2384                                         struct snd_ctl_elem_value *ucontrol)
2385{
2386        struct snd_trident *trident = snd_kcontrol_chip(kcontrol);
2387
2388        spin_lock_irq(&trident->reg_lock);
2389        ucontrol->value.iec958.status[0] = (trident->spdif_bits >> 0) & 0xff;
2390        ucontrol->value.iec958.status[1] = (trident->spdif_bits >> 8) & 0xff;
2391        ucontrol->value.iec958.status[2] = (trident->spdif_bits >> 16) & 0xff;
2392        ucontrol->value.iec958.status[3] = (trident->spdif_bits >> 24) & 0xff;
2393        spin_unlock_irq(&trident->reg_lock);
2394        return 0;
2395}
2396
2397static int snd_trident_spdif_default_put(struct snd_kcontrol *kcontrol,
2398                                         struct snd_ctl_elem_value *ucontrol)
2399{
2400        struct snd_trident *trident = snd_kcontrol_chip(kcontrol);
2401        unsigned int val;
2402        int change;
2403
2404        val = (ucontrol->value.iec958.status[0] << 0) |
2405              (ucontrol->value.iec958.status[1] << 8) |
2406              (ucontrol->value.iec958.status[2] << 16) |
2407              (ucontrol->value.iec958.status[3] << 24);
2408        spin_lock_irq(&trident->reg_lock);
2409        change = trident->spdif_bits != val;
2410        trident->spdif_bits = val;
2411        if (trident->device != TRIDENT_DEVICE_ID_SI7018) {
2412                if ((inb(TRID_REG(trident, NX_SPCTRL_SPCSO + 3)) & 0x10) == 0)
2413                        outl(trident->spdif_bits, TRID_REG(trident, NX_SPCSTATUS));
2414        } else {
2415                if (trident->spdif == NULL)
2416                        outl(trident->spdif_bits, TRID_REG(trident, SI_SPDIF_CS));
2417        }
2418        spin_unlock_irq(&trident->reg_lock);
2419        return change;
2420}
2421
2422static const struct snd_kcontrol_new snd_trident_spdif_default =
2423{
2424        .iface =        SNDRV_CTL_ELEM_IFACE_PCM,
2425        .name =         SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),
2426        .info =         snd_trident_spdif_default_info,
2427        .get =          snd_trident_spdif_default_get,
2428        .put =          snd_trident_spdif_default_put
2429};
2430
2431/*---------------------------------------------------------------------------
2432    snd_trident_spdif_mask
2433
2434    Description: put/get the S/PDIF mask
2435  ---------------------------------------------------------------------------*/
2436
2437static int snd_trident_spdif_mask_info(struct snd_kcontrol *kcontrol,
2438                                       struct snd_ctl_elem_info *uinfo)
2439{
2440        uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
2441        uinfo->count = 1;
2442        return 0;
2443}
2444
2445static int snd_trident_spdif_mask_get(struct snd_kcontrol *kcontrol,
2446                                      struct snd_ctl_elem_value *ucontrol)
2447{
2448        ucontrol->value.iec958.status[0] = 0xff;
2449        ucontrol->value.iec958.status[1] = 0xff;
2450        ucontrol->value.iec958.status[2] = 0xff;
2451        ucontrol->value.iec958.status[3] = 0xff;
2452        return 0;
2453}
2454
2455static const struct snd_kcontrol_new snd_trident_spdif_mask =
2456{
2457        .access =       SNDRV_CTL_ELEM_ACCESS_READ,
2458        .iface =        SNDRV_CTL_ELEM_IFACE_PCM,
2459        .name =         SNDRV_CTL_NAME_IEC958("",PLAYBACK,MASK),
2460        .info =         snd_trident_spdif_mask_info,
2461        .get =          snd_trident_spdif_mask_get,
2462};
2463
2464/*---------------------------------------------------------------------------
2465    snd_trident_spdif_stream
2466
2467    Description: put/get the S/PDIF stream settings
2468  ---------------------------------------------------------------------------*/
2469
2470static int snd_trident_spdif_stream_info(struct snd_kcontrol *kcontrol,
2471                                         struct snd_ctl_elem_info *uinfo)
2472{
2473        uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
2474        uinfo->count = 1;
2475        return 0;
2476}
2477
2478static int snd_trident_spdif_stream_get(struct snd_kcontrol *kcontrol,
2479                                        struct snd_ctl_elem_value *ucontrol)
2480{
2481        struct snd_trident *trident = snd_kcontrol_chip(kcontrol);
2482
2483        spin_lock_irq(&trident->reg_lock);
2484        ucontrol->value.iec958.status[0] = (trident->spdif_pcm_bits >> 0) & 0xff;
2485        ucontrol->value.iec958.status[1] = (trident->spdif_pcm_bits >> 8) & 0xff;
2486        ucontrol->value.iec958.status[2] = (trident->spdif_pcm_bits >> 16) & 0xff;
2487        ucontrol->value.iec958.status[3] = (trident->spdif_pcm_bits >> 24) & 0xff;
2488        spin_unlock_irq(&trident->reg_lock);
2489        return 0;
2490}
2491
2492static int snd_trident_spdif_stream_put(struct snd_kcontrol *kcontrol,
2493                                        struct snd_ctl_elem_value *ucontrol)
2494{
2495        struct snd_trident *trident = snd_kcontrol_chip(kcontrol);
2496        unsigned int val;
2497        int change;
2498
2499        val = (ucontrol->value.iec958.status[0] << 0) |
2500              (ucontrol->value.iec958.status[1] << 8) |
2501              (ucontrol->value.iec958.status[2] << 16) |
2502              (ucontrol->value.iec958.status[3] << 24);
2503        spin_lock_irq(&trident->reg_lock);
2504        change = trident->spdif_pcm_bits != val;
2505        trident->spdif_pcm_bits = val;
2506        if (trident->spdif != NULL) {
2507                if (trident->device != TRIDENT_DEVICE_ID_SI7018) {
2508                        outl(trident->spdif_pcm_bits, TRID_REG(trident, NX_SPCSTATUS));
2509                } else {
2510                        outl(trident->spdif_bits, TRID_REG(trident, SI_SPDIF_CS));
2511                }
2512        }
2513        spin_unlock_irq(&trident->reg_lock);
2514        return change;
2515}
2516
2517static const struct snd_kcontrol_new snd_trident_spdif_stream =
2518{
2519        .access =       SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE,
2520        .iface =        SNDRV_CTL_ELEM_IFACE_PCM,
2521        .name =         SNDRV_CTL_NAME_IEC958("",PLAYBACK,PCM_STREAM),
2522        .info =         snd_trident_spdif_stream_info,
2523        .get =          snd_trident_spdif_stream_get,
2524        .put =          snd_trident_spdif_stream_put
2525};
2526
2527/*---------------------------------------------------------------------------
2528    snd_trident_ac97_control
2529
2530    Description: enable/disable rear path for ac97
2531  ---------------------------------------------------------------------------*/
2532
2533#define snd_trident_ac97_control_info   snd_ctl_boolean_mono_info
2534
2535static int snd_trident_ac97_control_get(struct snd_kcontrol *kcontrol,
2536                                        struct snd_ctl_elem_value *ucontrol)
2537{
2538        struct snd_trident *trident = snd_kcontrol_chip(kcontrol);
2539        unsigned char val;
2540
2541        spin_lock_irq(&trident->reg_lock);
2542        val = trident->ac97_ctrl = inl(TRID_REG(trident, NX_ACR0_AC97_COM_STAT));
2543        ucontrol->value.integer.value[0] = (val & (1 << kcontrol->private_value)) ? 1 : 0;
2544        spin_unlock_irq(&trident->reg_lock);
2545        return 0;
2546}
2547
2548static int snd_trident_ac97_control_put(struct snd_kcontrol *kcontrol,
2549                                        struct snd_ctl_elem_value *ucontrol)
2550{
2551        struct snd_trident *trident = snd_kcontrol_chip(kcontrol);
2552        unsigned char val;
2553        int change = 0;
2554
2555        spin_lock_irq(&trident->reg_lock);
2556        val = trident->ac97_ctrl = inl(TRID_REG(trident, NX_ACR0_AC97_COM_STAT));
2557        val &= ~(1 << kcontrol->private_value);
2558        if (ucontrol->value.integer.value[0])
2559                val |= 1 << kcontrol->private_value;
2560        change = val != trident->ac97_ctrl;
2561        trident->ac97_ctrl = val;
2562        outl(trident->ac97_ctrl = val, TRID_REG(trident, NX_ACR0_AC97_COM_STAT));
2563        spin_unlock_irq(&trident->reg_lock);
2564        return change;
2565}
2566
2567static const struct snd_kcontrol_new snd_trident_ac97_rear_control =
2568{
2569        .iface =        SNDRV_CTL_ELEM_IFACE_MIXER,
2570        .name =         "Rear Path",
2571        .info =         snd_trident_ac97_control_info,
2572        .get =          snd_trident_ac97_control_get,
2573        .put =          snd_trident_ac97_control_put,
2574        .private_value = 4,
2575};
2576
2577/*---------------------------------------------------------------------------
2578    snd_trident_vol_control
2579
2580    Description: wave & music volume control
2581  ---------------------------------------------------------------------------*/
2582
2583static int snd_trident_vol_control_info(struct snd_kcontrol *kcontrol,
2584                                        struct snd_ctl_elem_info *uinfo)
2585{
2586        uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
2587        uinfo->count = 2;
2588        uinfo->value.integer.min = 0;
2589        uinfo->value.integer.max = 255;
2590        return 0;
2591}
2592
2593static int snd_trident_vol_control_get(struct snd_kcontrol *kcontrol,
2594                                       struct snd_ctl_elem_value *ucontrol)
2595{
2596        struct snd_trident *trident = snd_kcontrol_chip(kcontrol);
2597        unsigned int val;
2598
2599        val = trident->musicvol_wavevol;
2600        ucontrol->value.integer.value[0] = 255 - ((val >> kcontrol->private_value) & 0xff);
2601        ucontrol->value.integer.value[1] = 255 - ((val >> (kcontrol->private_value + 8)) & 0xff);
2602        return 0;
2603}
2604
2605static const DECLARE_TLV_DB_SCALE(db_scale_gvol, -6375, 25, 0);
2606
2607static int snd_trident_vol_control_put(struct snd_kcontrol *kcontrol,
2608                                       struct snd_ctl_elem_value *ucontrol)
2609{
2610        struct snd_trident *trident = snd_kcontrol_chip(kcontrol);
2611        unsigned int val;
2612        int change = 0;
2613
2614        spin_lock_irq(&trident->reg_lock);
2615        val = trident->musicvol_wavevol;
2616        val &= ~(0xffff << kcontrol->private_value);
2617        val |= ((255 - (ucontrol->value.integer.value[0] & 0xff)) |
2618                ((255 - (ucontrol->value.integer.value[1] & 0xff)) << 8)) << kcontrol->private_value;
2619        change = val != trident->musicvol_wavevol;
2620        outl(trident->musicvol_wavevol = val, TRID_REG(trident, T4D_MUSICVOL_WAVEVOL));
2621        spin_unlock_irq(&trident->reg_lock);
2622        return change;
2623}
2624
2625static const struct snd_kcontrol_new snd_trident_vol_music_control =
2626{
2627        .iface =        SNDRV_CTL_ELEM_IFACE_MIXER,
2628        .name =         "Music Playback Volume",
2629        .info =         snd_trident_vol_control_info,
2630        .get =          snd_trident_vol_control_get,
2631        .put =          snd_trident_vol_control_put,
2632        .private_value = 16,
2633        .tlv = { .p = db_scale_gvol },
2634};
2635
2636static const struct snd_kcontrol_new snd_trident_vol_wave_control =
2637{
2638        .iface =        SNDRV_CTL_ELEM_IFACE_MIXER,
2639        .name =         "Wave Playback Volume",
2640        .info =         snd_trident_vol_control_info,
2641        .get =          snd_trident_vol_control_get,
2642        .put =          snd_trident_vol_control_put,
2643        .private_value = 0,
2644        .tlv = { .p = db_scale_gvol },
2645};
2646
2647/*---------------------------------------------------------------------------
2648    snd_trident_pcm_vol_control
2649
2650    Description: PCM front volume control
2651  ---------------------------------------------------------------------------*/
2652
2653static int snd_trident_pcm_vol_control_info(struct snd_kcontrol *kcontrol,
2654                                            struct snd_ctl_elem_info *uinfo)
2655{
2656        struct snd_trident *trident = snd_kcontrol_chip(kcontrol);
2657
2658        uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
2659        uinfo->count = 1;
2660        uinfo->value.integer.min = 0;
2661        uinfo->value.integer.max = 255;
2662        if (trident->device == TRIDENT_DEVICE_ID_SI7018)
2663                uinfo->value.integer.max = 1023;
2664        return 0;
2665}
2666
2667static int snd_trident_pcm_vol_control_get(struct snd_kcontrol *kcontrol,
2668                                           struct snd_ctl_elem_value *ucontrol)
2669{
2670        struct snd_trident *trident = snd_kcontrol_chip(kcontrol);
2671        struct snd_trident_pcm_mixer *mix = &trident->pcm_mixer[snd_ctl_get_ioffnum(kcontrol, &ucontrol->id)];
2672
2673        if (trident->device == TRIDENT_DEVICE_ID_SI7018) {
2674                ucontrol->value.integer.value[0] = 1023 - mix->vol;
2675        } else {
2676                ucontrol->value.integer.value[0] = 255 - (mix->vol>>2);
2677        }
2678        return 0;
2679}
2680
2681static int snd_trident_pcm_vol_control_put(struct snd_kcontrol *kcontrol,
2682                                           struct snd_ctl_elem_value *ucontrol)
2683{
2684        struct snd_trident *trident = snd_kcontrol_chip(kcontrol);
2685        struct snd_trident_pcm_mixer *mix = &trident->pcm_mixer[snd_ctl_get_ioffnum(kcontrol, &ucontrol->id)];
2686        unsigned int val;
2687        int change = 0;
2688
2689        if (trident->device == TRIDENT_DEVICE_ID_SI7018) {
2690                val = 1023 - (ucontrol->value.integer.value[0] & 1023);
2691        } else {
2692                val = (255 - (ucontrol->value.integer.value[0] & 255)) << 2;
2693        }
2694        spin_lock_irq(&trident->reg_lock);
2695        change = val != mix->vol;
2696        mix->vol = val;
2697        if (mix->voice != NULL)
2698                snd_trident_write_vol_reg(trident, mix->voice, val);
2699        spin_unlock_irq(&trident->reg_lock);
2700        return change;
2701}
2702
2703static const struct snd_kcontrol_new snd_trident_pcm_vol_control =
2704{
2705        .iface =        SNDRV_CTL_ELEM_IFACE_MIXER,
2706        .name =         "PCM Front Playback Volume",
2707        .access =       SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE,
2708        .count =        32,
2709        .info =         snd_trident_pcm_vol_control_info,
2710        .get =          snd_trident_pcm_vol_control_get,
2711        .put =          snd_trident_pcm_vol_control_put,
2712        /* FIXME: no tlv yet */
2713};
2714
2715/*---------------------------------------------------------------------------
2716    snd_trident_pcm_pan_control
2717
2718    Description: PCM front pan control
2719  ---------------------------------------------------------------------------*/
2720
2721static int snd_trident_pcm_pan_control_info(struct snd_kcontrol *kcontrol,
2722                                            struct snd_ctl_elem_info *uinfo)
2723{
2724        uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
2725        uinfo->count = 1;
2726        uinfo->value.integer.min = 0;
2727        uinfo->value.integer.max = 127;
2728        return 0;
2729}
2730
2731static int snd_trident_pcm_pan_control_get(struct snd_kcontrol *kcontrol,
2732                                           struct snd_ctl_elem_value *ucontrol)
2733{
2734        struct snd_trident *trident = snd_kcontrol_chip(kcontrol);
2735        struct snd_trident_pcm_mixer *mix = &trident->pcm_mixer[snd_ctl_get_ioffnum(kcontrol, &ucontrol->id)];
2736
2737        ucontrol->value.integer.value[0] = mix->pan;
2738        if (ucontrol->value.integer.value[0] & 0x40) {
2739                ucontrol->value.integer.value[0] = (0x3f - (ucontrol->value.integer.value[0] & 0x3f));
2740        } else {
2741                ucontrol->value.integer.value[0] |= 0x40;
2742        }
2743        return 0;
2744}
2745
2746static int snd_trident_pcm_pan_control_put(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        unsigned char val;
2752        int change = 0;
2753
2754        if (ucontrol->value.integer.value[0] & 0x40)
2755                val = ucontrol->value.integer.value[0] & 0x3f;
2756        else
2757                val = (0x3f - (ucontrol->value.integer.value[0] & 0x3f)) | 0x40;
2758        spin_lock_irq(&trident->reg_lock);
2759        change = val != mix->pan;
2760        mix->pan = val;
2761        if (mix->voice != NULL)
2762                snd_trident_write_pan_reg(trident, mix->voice, val);
2763        spin_unlock_irq(&trident->reg_lock);
2764        return change;
2765}
2766
2767static const struct snd_kcontrol_new snd_trident_pcm_pan_control =
2768{
2769        .iface =        SNDRV_CTL_ELEM_IFACE_MIXER,
2770        .name =         "PCM Pan Playback Control",
2771        .access =       SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE,
2772        .count =        32,
2773        .info =         snd_trident_pcm_pan_control_info,
2774        .get =          snd_trident_pcm_pan_control_get,
2775        .put =          snd_trident_pcm_pan_control_put,
2776};
2777
2778/*---------------------------------------------------------------------------
2779    snd_trident_pcm_rvol_control
2780
2781    Description: PCM reverb volume control
2782  ---------------------------------------------------------------------------*/
2783
2784static int snd_trident_pcm_rvol_control_info(struct snd_kcontrol *kcontrol,
2785                                             struct snd_ctl_elem_info *uinfo)
2786{
2787        uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
2788        uinfo->count = 1;
2789        uinfo->value.integer.min = 0;
2790        uinfo->value.integer.max = 127;
2791        return 0;
2792}
2793
2794static int snd_trident_pcm_rvol_control_get(struct snd_kcontrol *kcontrol,
2795                                            struct snd_ctl_elem_value *ucontrol)
2796{
2797        struct snd_trident *trident = snd_kcontrol_chip(kcontrol);
2798        struct snd_trident_pcm_mixer *mix = &trident->pcm_mixer[snd_ctl_get_ioffnum(kcontrol, &ucontrol->id)];
2799
2800        ucontrol->value.integer.value[0] = 127 - mix->rvol;
2801        return 0;
2802}
2803
2804static int snd_trident_pcm_rvol_control_put(struct snd_kcontrol *kcontrol,
2805                                            struct snd_ctl_elem_value *ucontrol)
2806{
2807        struct snd_trident *trident = snd_kcontrol_chip(kcontrol);
2808        struct snd_trident_pcm_mixer *mix = &trident->pcm_mixer[snd_ctl_get_ioffnum(kcontrol, &ucontrol->id)];
2809        unsigned short val;
2810        int change = 0;
2811
2812        val = 0x7f - (ucontrol->value.integer.value[0] & 0x7f);
2813        spin_lock_irq(&trident->reg_lock);
2814        change = val != mix->rvol;
2815        mix->rvol = val;
2816        if (mix->voice != NULL)
2817                snd_trident_write_rvol_reg(trident, mix->voice, val);
2818        spin_unlock_irq(&trident->reg_lock);
2819        return change;
2820}
2821
2822static const DECLARE_TLV_DB_SCALE(db_scale_crvol, -3175, 25, 1);
2823
2824static const struct snd_kcontrol_new snd_trident_pcm_rvol_control =
2825{
2826        .iface =        SNDRV_CTL_ELEM_IFACE_MIXER,
2827        .name =         "PCM Reverb Playback Volume",
2828        .access =       SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE,
2829        .count =        32,
2830        .info =         snd_trident_pcm_rvol_control_info,
2831        .get =          snd_trident_pcm_rvol_control_get,
2832        .put =          snd_trident_pcm_rvol_control_put,
2833        .tlv = { .p = db_scale_crvol },
2834};
2835
2836/*---------------------------------------------------------------------------
2837    snd_trident_pcm_cvol_control
2838
2839    Description: PCM chorus volume control
2840  ---------------------------------------------------------------------------*/
2841
2842static int snd_trident_pcm_cvol_control_info(struct snd_kcontrol *kcontrol,
2843                                             struct snd_ctl_elem_info *uinfo)
2844{
2845        uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
2846        uinfo->count = 1;
2847        uinfo->value.integer.min = 0;
2848        uinfo->value.integer.max = 127;
2849        return 0;
2850}
2851
2852static int snd_trident_pcm_cvol_control_get(struct snd_kcontrol *kcontrol,
2853                                            struct snd_ctl_elem_value *ucontrol)
2854{
2855        struct snd_trident *trident = snd_kcontrol_chip(kcontrol);
2856        struct snd_trident_pcm_mixer *mix = &trident->pcm_mixer[snd_ctl_get_ioffnum(kcontrol, &ucontrol->id)];
2857
2858        ucontrol->value.integer.value[0] = 127 - mix->cvol;
2859        return 0;
2860}
2861
2862static int snd_trident_pcm_cvol_control_put(struct snd_kcontrol *kcontrol,
2863                                            struct snd_ctl_elem_value *ucontrol)
2864{
2865        struct snd_trident *trident = snd_kcontrol_chip(kcontrol);
2866        struct snd_trident_pcm_mixer *mix = &trident->pcm_mixer[snd_ctl_get_ioffnum(kcontrol, &ucontrol->id)];
2867        unsigned short val;
2868        int change = 0;
2869
2870        val = 0x7f - (ucontrol->value.integer.value[0] & 0x7f);
2871        spin_lock_irq(&trident->reg_lock);
2872        change = val != mix->cvol;
2873        mix->cvol = val;
2874        if (mix->voice != NULL)
2875                snd_trident_write_cvol_reg(trident, mix->voice, val);
2876        spin_unlock_irq(&trident->reg_lock);
2877        return change;
2878}
2879
2880static const struct snd_kcontrol_new snd_trident_pcm_cvol_control =
2881{
2882        .iface =        SNDRV_CTL_ELEM_IFACE_MIXER,
2883        .name =         "PCM Chorus Playback Volume",
2884        .access =       SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE,
2885        .count =        32,
2886        .info =         snd_trident_pcm_cvol_control_info,
2887        .get =          snd_trident_pcm_cvol_control_get,
2888        .put =          snd_trident_pcm_cvol_control_put,
2889        .tlv = { .p = db_scale_crvol },
2890};
2891
2892static void snd_trident_notify_pcm_change1(struct snd_card *card,
2893                                           struct snd_kcontrol *kctl,
2894                                           int num, int activate)
2895{
2896        struct snd_ctl_elem_id id;
2897
2898        if (! kctl)
2899                return;
2900        if (activate)
2901                kctl->vd[num].access &= ~SNDRV_CTL_ELEM_ACCESS_INACTIVE;
2902        else
2903                kctl->vd[num].access |= SNDRV_CTL_ELEM_ACCESS_INACTIVE;
2904        snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE |
2905                       SNDRV_CTL_EVENT_MASK_INFO,
2906                       snd_ctl_build_ioff(&id, kctl, num));
2907}
2908
2909static void snd_trident_notify_pcm_change(struct snd_trident *trident,
2910                                          struct snd_trident_pcm_mixer *tmix,
2911                                          int num, int activate)
2912{
2913        snd_trident_notify_pcm_change1(trident->card, trident->ctl_vol, num, activate);
2914        snd_trident_notify_pcm_change1(trident->card, trident->ctl_pan, num, activate);
2915        snd_trident_notify_pcm_change1(trident->card, trident->ctl_rvol, num, activate);
2916        snd_trident_notify_pcm_change1(trident->card, trident->ctl_cvol, num, activate);
2917}
2918
2919static int snd_trident_pcm_mixer_build(struct snd_trident *trident,
2920                                       struct snd_trident_voice *voice,
2921                                       struct snd_pcm_substream *substream)
2922{
2923        struct snd_trident_pcm_mixer *tmix;
2924
2925        if (snd_BUG_ON(!trident || !voice || !substream))
2926                return -EINVAL;
2927        tmix = &trident->pcm_mixer[substream->number];
2928        tmix->voice = voice;
2929        tmix->vol = T4D_DEFAULT_PCM_VOL;
2930        tmix->pan = T4D_DEFAULT_PCM_PAN;
2931        tmix->rvol = T4D_DEFAULT_PCM_RVOL;
2932        tmix->cvol = T4D_DEFAULT_PCM_CVOL;
2933        snd_trident_notify_pcm_change(trident, tmix, substream->number, 1);
2934        return 0;
2935}
2936
2937static int snd_trident_pcm_mixer_free(struct snd_trident *trident, struct snd_trident_voice *voice, struct snd_pcm_substream *substream)
2938{
2939        struct snd_trident_pcm_mixer *tmix;
2940
2941        if (snd_BUG_ON(!trident || !substream))
2942                return -EINVAL;
2943        tmix = &trident->pcm_mixer[substream->number];
2944        tmix->voice = NULL;
2945        snd_trident_notify_pcm_change(trident, tmix, substream->number, 0);
2946        return 0;
2947}
2948
2949/*---------------------------------------------------------------------------
2950   snd_trident_mixer
2951  
2952   Description: This routine registers the 4DWave device for mixer support.
2953                
2954   Parameters:  trident - pointer to target device class for 4DWave.
2955
2956   Returns:     None
2957  
2958  ---------------------------------------------------------------------------*/
2959
2960static int snd_trident_mixer(struct snd_trident *trident, int pcm_spdif_device)
2961{
2962        struct snd_ac97_template _ac97;
2963        struct snd_card *card = trident->card;
2964        struct snd_kcontrol *kctl;
2965        struct snd_ctl_elem_value *uctl;
2966        int idx, err, retries = 2;
2967        static struct snd_ac97_bus_ops ops = {
2968                .write = snd_trident_codec_write,
2969                .read = snd_trident_codec_read,
2970        };
2971
2972        uctl = kzalloc(sizeof(*uctl), GFP_KERNEL);
2973        if (!uctl)
2974                return -ENOMEM;
2975
2976        if ((err = snd_ac97_bus(trident->card, 0, &ops, NULL, &trident->ac97_bus)) < 0)
2977                goto __out;
2978
2979        memset(&_ac97, 0, sizeof(_ac97));
2980        _ac97.private_data = trident;
2981        trident->ac97_detect = 1;
2982
2983      __again:
2984        if ((err = snd_ac97_mixer(trident->ac97_bus, &_ac97, &trident->ac97)) < 0) {
2985                if (trident->device == TRIDENT_DEVICE_ID_SI7018) {
2986                        if ((err = snd_trident_sis_reset(trident)) < 0)
2987                                goto __out;
2988                        if (retries-- > 0)
2989                                goto __again;
2990                        err = -EIO;
2991                }
2992                goto __out;
2993        }
2994        
2995        /* secondary codec? */
2996        if (trident->device == TRIDENT_DEVICE_ID_SI7018 &&
2997            (inl(TRID_REG(trident, SI_SERIAL_INTF_CTRL)) & SI_AC97_PRIMARY_READY) != 0) {
2998                _ac97.num = 1;
2999                err = snd_ac97_mixer(trident->ac97_bus, &_ac97, &trident->ac97_sec);
3000                if (err < 0)
3001                        dev_err(trident->card->dev,
3002                                "SI7018: the secondary codec - invalid access\n");
3003#if 0   // only for my testing purpose --jk
3004                {
3005                        struct snd_ac97 *mc97;
3006                        err = snd_ac97_modem(trident->card, &_ac97, &mc97);
3007                        if (err < 0)
3008                                dev_err(trident->card->dev,
3009                                        "snd_ac97_modem returned error %i\n", err);
3010                }
3011#endif
3012        }
3013        
3014        trident->ac97_detect = 0;
3015
3016        if (trident->device != TRIDENT_DEVICE_ID_SI7018) {
3017                if ((err = snd_ctl_add(card, kctl = snd_ctl_new1(&snd_trident_vol_wave_control, trident))) < 0)
3018                        goto __out;
3019                kctl->put(kctl, uctl);
3020                if ((err = snd_ctl_add(card, kctl = snd_ctl_new1(&snd_trident_vol_music_control, trident))) < 0)
3021                        goto __out;
3022                kctl->put(kctl, uctl);
3023                outl(trident->musicvol_wavevol = 0x00000000, TRID_REG(trident, T4D_MUSICVOL_WAVEVOL));
3024        } else {
3025                outl(trident->musicvol_wavevol = 0xffff0000, TRID_REG(trident, T4D_MUSICVOL_WAVEVOL));
3026        }
3027
3028        for (idx = 0; idx < 32; idx++) {
3029                struct snd_trident_pcm_mixer *tmix;
3030                
3031                tmix = &trident->pcm_mixer[idx];
3032                tmix->voice = NULL;
3033        }
3034        if ((trident->ctl_vol = snd_ctl_new1(&snd_trident_pcm_vol_control, trident)) == NULL)
3035                goto __nomem;
3036        if ((err = snd_ctl_add(card, trident->ctl_vol)))
3037                goto __out;
3038                
3039        if ((trident->ctl_pan = snd_ctl_new1(&snd_trident_pcm_pan_control, trident)) == NULL)
3040                goto __nomem;
3041        if ((err = snd_ctl_add(card, trident->ctl_pan)))
3042                goto __out;
3043
3044        if ((trident->ctl_rvol = snd_ctl_new1(&snd_trident_pcm_rvol_control, trident)) == NULL)
3045                goto __nomem;
3046        if ((err = snd_ctl_add(card, trident->ctl_rvol)))
3047                goto __out;
3048
3049        if ((trident->ctl_cvol = snd_ctl_new1(&snd_trident_pcm_cvol_control, trident)) == NULL)
3050                goto __nomem;
3051        if ((err = snd_ctl_add(card, trident->ctl_cvol)))
3052                goto __out;
3053
3054        if (trident->device == TRIDENT_DEVICE_ID_NX) {
3055                if ((err = snd_ctl_add(card, kctl = snd_ctl_new1(&snd_trident_ac97_rear_control, trident))) < 0)
3056                        goto __out;
3057                kctl->put(kctl, uctl);
3058        }
3059        if (trident->device == TRIDENT_DEVICE_ID_NX || trident->device == TRIDENT_DEVICE_ID_SI7018) {
3060
3061                kctl = snd_ctl_new1(&snd_trident_spdif_control, trident);
3062                if (kctl == NULL) {
3063                        err = -ENOMEM;
3064                        goto __out;
3065                }
3066                if (trident->ac97->ext_id & AC97_EI_SPDIF)
3067                        kctl->id.index++;
3068                if (trident->ac97_sec && (trident->ac97_sec->ext_id & AC97_EI_SPDIF))
3069                        kctl->id.index++;
3070                idx = kctl->id.index;
3071                if ((err = snd_ctl_add(card, kctl)) < 0)
3072                        goto __out;
3073                kctl->put(kctl, uctl);
3074
3075                kctl = snd_ctl_new1(&snd_trident_spdif_default, trident);
3076                if (kctl == NULL) {
3077                        err = -ENOMEM;
3078                        goto __out;
3079                }
3080                kctl->id.index = idx;
3081                kctl->id.device = pcm_spdif_device;
3082                if ((err = snd_ctl_add(card, kctl)) < 0)
3083                        goto __out;
3084
3085                kctl = snd_ctl_new1(&snd_trident_spdif_mask, trident);
3086                if (kctl == NULL) {
3087                        err = -ENOMEM;
3088                        goto __out;
3089                }
3090                kctl->id.index = idx;
3091                kctl->id.device = pcm_spdif_device;
3092                if ((err = snd_ctl_add(card, kctl)) < 0)
3093                        goto __out;
3094
3095                kctl = snd_ctl_new1(&snd_trident_spdif_stream, trident);
3096                if (kctl == NULL) {
3097                        err = -ENOMEM;
3098                        goto __out;
3099                }
3100                kctl->id.index = idx;
3101                kctl->id.device = pcm_spdif_device;
3102                if ((err = snd_ctl_add(card, kctl)) < 0)
3103                        goto __out;
3104                trident->spdif_pcm_ctl = kctl;
3105        }
3106
3107        err = 0;
3108        goto __out;
3109
3110 __nomem:
3111        err = -ENOMEM;
3112
3113 __out:
3114        kfree(uctl);
3115
3116        return err;
3117}
3118
3119/*
3120 * gameport interface
3121 */
3122
3123#if IS_REACHABLE(CONFIG_GAMEPORT)
3124
3125static unsigned char snd_trident_gameport_read(struct gameport *gameport)
3126{
3127        struct snd_trident *chip = gameport_get_port_data(gameport);
3128
3129        if (snd_BUG_ON(!chip))
3130                return 0;
3131        return inb(TRID_REG(chip, GAMEPORT_LEGACY));
3132}
3133
3134static void snd_trident_gameport_trigger(struct gameport *gameport)
3135{
3136        struct snd_trident *chip = gameport_get_port_data(gameport);
3137
3138        if (snd_BUG_ON(!chip))
3139                return;
3140        outb(0xff, TRID_REG(chip, GAMEPORT_LEGACY));
3141}
3142
3143static int snd_trident_gameport_cooked_read(struct gameport *gameport, int *axes, int *buttons)
3144{
3145        struct snd_trident *chip = gameport_get_port_data(gameport);
3146        int i;
3147
3148        if (snd_BUG_ON(!chip))
3149                return 0;
3150
3151        *buttons = (~inb(TRID_REG(chip, GAMEPORT_LEGACY)) >> 4) & 0xf;
3152
3153        for (i = 0; i < 4; i++) {
3154                axes[i] = inw(TRID_REG(chip, GAMEPORT_AXES + i * 2));
3155                if (axes[i] == 0xffff) axes[i] = -1;
3156        }
3157        
3158        return 0;
3159}
3160
3161static int snd_trident_gameport_open(struct gameport *gameport, int mode)
3162{
3163        struct snd_trident *chip = gameport_get_port_data(gameport);
3164
3165        if (snd_BUG_ON(!chip))
3166                return 0;
3167
3168        switch (mode) {
3169                case GAMEPORT_MODE_COOKED:
3170                        outb(GAMEPORT_MODE_ADC, TRID_REG(chip, GAMEPORT_GCR));
3171                        msleep(20);
3172                        return 0;
3173                case GAMEPORT_MODE_RAW:
3174                        outb(0, TRID_REG(chip, GAMEPORT_GCR));
3175                        return 0;
3176                default:
3177                        return -1;
3178        }
3179}
3180
3181int snd_trident_create_gameport(struct snd_trident *chip)
3182{
3183        struct gameport *gp;
3184
3185        chip->gameport = gp = gameport_allocate_port();
3186        if (!gp) {
3187                dev_err(chip->card->dev,
3188                        "cannot allocate memory for gameport\n");
3189                return -ENOMEM;
3190        }
3191
3192        gameport_set_name(gp, "Trident 4DWave");
3193        gameport_set_phys(gp, "pci%s/gameport0", pci_name(chip->pci));
3194        gameport_set_dev_parent(gp, &chip->pci->dev);
3195
3196        gameport_set_port_data(gp, chip);
3197        gp->fuzz = 64;
3198        gp->read = snd_trident_gameport_read;
3199        gp->trigger = snd_trident_gameport_trigger;
3200        gp->cooked_read = snd_trident_gameport_cooked_read;
3201        gp->open = snd_trident_gameport_open;
3202
3203        gameport_register_port(gp);
3204
3205        return 0;
3206}
3207
3208static inline void snd_trident_free_gameport(struct snd_trident *chip)
3209{
3210        if (chip->gameport) {
3211                gameport_unregister_port(chip->gameport);
3212                chip->gameport = NULL;
3213        }
3214}
3215#else
3216int snd_trident_create_gameport(struct snd_trident *chip) { return -ENOSYS; }
3217static inline void snd_trident_free_gameport(struct snd_trident *chip) { }
3218#endif /* CONFIG_GAMEPORT */
3219
3220/*
3221 * delay for 1 tick
3222 */
3223static inline void do_delay(struct snd_trident *chip)
3224{
3225        schedule_timeout_uninterruptible(1);
3226}
3227
3228/*
3229 *  SiS reset routine
3230 */
3231
3232static int snd_trident_sis_reset(struct snd_trident *trident)
3233{
3234        unsigned long end_time;
3235        unsigned int i;
3236        int r;
3237
3238        r = trident->in_suspend ? 0 : 2;        /* count of retries */
3239      __si7018_retry:
3240        pci_write_config_byte(trident->pci, 0x46, 0x04);        /* SOFTWARE RESET */
3241        udelay(100);
3242        pci_write_config_byte(trident->pci, 0x46, 0x00);
3243        udelay(100);
3244        /* disable AC97 GPIO interrupt */
3245        outb(0x00, TRID_REG(trident, SI_AC97_GPIO));
3246        /* initialize serial interface, force cold reset */
3247        i = PCMOUT|SURROUT|CENTEROUT|LFEOUT|SECONDARY_ID|COLD_RESET;
3248        outl(i, TRID_REG(trident, SI_SERIAL_INTF_CTRL));
3249        udelay(1000);
3250        /* remove cold reset */
3251        i &= ~COLD_RESET;
3252        outl(i, TRID_REG(trident, SI_SERIAL_INTF_CTRL));
3253        udelay(2000);
3254        /* wait, until the codec is ready */
3255        end_time = (jiffies + (HZ * 3) / 4) + 1;
3256        do {
3257                if ((inl(TRID_REG(trident, SI_SERIAL_INTF_CTRL)) & SI_AC97_PRIMARY_READY) != 0)
3258                        goto __si7018_ok;
3259                do_delay(trident);
3260        } while (time_after_eq(end_time, jiffies));
3261        dev_err(trident->card->dev, "AC'97 codec ready error [0x%x]\n",
3262                inl(TRID_REG(trident, SI_SERIAL_INTF_CTRL)));
3263        if (r-- > 0) {
3264                end_time = jiffies + HZ;
3265                do {
3266                        do_delay(trident);
3267                } while (time_after_eq(end_time, jiffies));
3268                goto __si7018_retry;
3269        }
3270      __si7018_ok:
3271        /* wait for the second codec */
3272        do {
3273                if ((inl(TRID_REG(trident, SI_SERIAL_INTF_CTRL)) & SI_AC97_SECONDARY_READY) != 0)
3274                        break;
3275                do_delay(trident);
3276        } while (time_after_eq(end_time, jiffies));
3277        /* enable 64 channel mode */
3278        outl(BANK_B_EN, TRID_REG(trident, T4D_LFO_GC_CIR));
3279        return 0;
3280}
3281
3282/*  
3283 *  /proc interface
3284 */
3285
3286static void snd_trident_proc_read(struct snd_info_entry *entry, 
3287                                  struct snd_info_buffer *buffer)
3288{
3289        struct snd_trident *trident = entry->private_data;
3290        char *s;
3291
3292        switch (trident->device) {
3293        case TRIDENT_DEVICE_ID_SI7018:
3294                s = "SiS 7018 Audio";
3295                break;
3296        case TRIDENT_DEVICE_ID_DX:
3297                s = "Trident 4DWave PCI DX";
3298                break;
3299        case TRIDENT_DEVICE_ID_NX:
3300                s = "Trident 4DWave PCI NX";
3301                break;
3302        default:
3303                s = "???";
3304        }
3305        snd_iprintf(buffer, "%s\n\n", s);
3306        snd_iprintf(buffer, "Spurious IRQs    : %d\n", trident->spurious_irq_count);
3307        snd_iprintf(buffer, "Spurious IRQ dlta: %d\n", trident->spurious_irq_max_delta);
3308        if (trident->device == TRIDENT_DEVICE_ID_NX || trident->device == TRIDENT_DEVICE_ID_SI7018)
3309                snd_iprintf(buffer, "IEC958 Mixer Out : %s\n", trident->spdif_ctrl == 0x28 ? "on" : "off");
3310        if (trident->device == TRIDENT_DEVICE_ID_NX) {
3311                snd_iprintf(buffer, "Rear Speakers    : %s\n", trident->ac97_ctrl & 0x00000010 ? "on" : "off");
3312                if (trident->tlb.entries) {
3313                        snd_iprintf(buffer,"\nVirtual Memory\n");
3314                        snd_iprintf(buffer, "Memory Maximum : %d\n", trident->tlb.memhdr->size);
3315                        snd_iprintf(buffer, "Memory Used    : %d\n", trident->tlb.memhdr->used);
3316                        snd_iprintf(buffer, "Memory Free    : %d\n", snd_util_mem_avail(trident->tlb.memhdr));
3317                }
3318        }
3319}
3320
3321static void snd_trident_proc_init(struct snd_trident *trident)
3322{
3323        struct snd_info_entry *entry;
3324        const char *s = "trident";
3325        
3326        if (trident->device == TRIDENT_DEVICE_ID_SI7018)
3327                s = "sis7018";
3328        if (! snd_card_proc_new(trident->card, s, &entry))
3329                snd_info_set_text_ops(entry, trident, snd_trident_proc_read);
3330}
3331
3332static int snd_trident_dev_free(struct snd_device *device)
3333{
3334        struct snd_trident *trident = device->device_data;
3335        return snd_trident_free(trident);
3336}
3337
3338/*---------------------------------------------------------------------------
3339   snd_trident_tlb_alloc
3340  
3341   Description: Allocate and set up the TLB page table on 4D NX.
3342                Each entry has 4 bytes (physical PCI address).
3343                
3344   Parameters:  trident - pointer to target device class for 4DWave.
3345
3346   Returns:     0 or negative error code
3347  
3348  ---------------------------------------------------------------------------*/
3349
3350static int snd_trident_tlb_alloc(struct snd_trident *trident)
3351{
3352        int i;
3353
3354        /* TLB array must be aligned to 16kB !!! so we allocate
3355           32kB region and correct offset when necessary */
3356
3357        if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(trident->pci),
3358                                2 * SNDRV_TRIDENT_MAX_PAGES * 4, &trident->tlb.buffer) < 0) {
3359                dev_err(trident->card->dev, "unable to allocate TLB buffer\n");
3360                return -ENOMEM;
3361        }
3362        trident->tlb.entries = (unsigned int*)ALIGN((unsigned long)trident->tlb.buffer.area, SNDRV_TRIDENT_MAX_PAGES * 4);
3363        trident->tlb.entries_dmaaddr = ALIGN(trident->tlb.buffer.addr, SNDRV_TRIDENT_MAX_PAGES * 4);
3364        /* allocate shadow TLB page table (virtual addresses) */
3365        trident->tlb.shadow_entries = vmalloc(SNDRV_TRIDENT_MAX_PAGES*sizeof(unsigned long));
3366        if (!trident->tlb.shadow_entries)
3367                return -ENOMEM;
3368
3369        /* allocate and setup silent page and initialise TLB entries */
3370        if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(trident->pci),
3371                                SNDRV_TRIDENT_PAGE_SIZE, &trident->tlb.silent_page) < 0) {
3372                dev_err(trident->card->dev, "unable to allocate silent page\n");
3373                return -ENOMEM;
3374        }
3375        memset(trident->tlb.silent_page.area, 0, SNDRV_TRIDENT_PAGE_SIZE);
3376        for (i = 0; i < SNDRV_TRIDENT_MAX_PAGES; i++) {
3377                trident->tlb.entries[i] = cpu_to_le32(trident->tlb.silent_page.addr & ~(SNDRV_TRIDENT_PAGE_SIZE-1));
3378                trident->tlb.shadow_entries[i] = (unsigned long)trident->tlb.silent_page.area;
3379        }
3380
3381        /* use emu memory block manager code to manage tlb page allocation */
3382        trident->tlb.memhdr = snd_util_memhdr_new(SNDRV_TRIDENT_PAGE_SIZE * SNDRV_TRIDENT_MAX_PAGES);
3383        if (trident->tlb.memhdr == NULL)
3384                return -ENOMEM;
3385
3386        trident->tlb.memhdr->block_extra_size = sizeof(struct snd_trident_memblk_arg);
3387        return 0;
3388}
3389
3390/*
3391 * initialize 4D DX chip
3392 */
3393
3394static void snd_trident_stop_all_voices(struct snd_trident *trident)
3395{
3396        outl(0xffffffff, TRID_REG(trident, T4D_STOP_A));
3397        outl(0xffffffff, TRID_REG(trident, T4D_STOP_B));
3398        outl(0, TRID_REG(trident, T4D_AINTEN_A));
3399        outl(0, TRID_REG(trident, T4D_AINTEN_B));
3400}
3401
3402static int snd_trident_4d_dx_init(struct snd_trident *trident)
3403{
3404        struct pci_dev *pci = trident->pci;
3405        unsigned long end_time;
3406
3407        /* reset the legacy configuration and whole audio/wavetable block */
3408        pci_write_config_dword(pci, 0x40, 0);   /* DDMA */
3409        pci_write_config_byte(pci, 0x44, 0);    /* ports */
3410        pci_write_config_byte(pci, 0x45, 0);    /* Legacy DMA */
3411        pci_write_config_byte(pci, 0x46, 4); /* reset */
3412        udelay(100);
3413        pci_write_config_byte(pci, 0x46, 0); /* release reset */
3414        udelay(100);
3415        
3416        /* warm reset of the AC'97 codec */
3417        outl(0x00000001, TRID_REG(trident, DX_ACR2_AC97_COM_STAT));
3418        udelay(100);
3419        outl(0x00000000, TRID_REG(trident, DX_ACR2_AC97_COM_STAT));
3420        /* DAC on, disable SB IRQ and try to force ADC valid signal */
3421        trident->ac97_ctrl = 0x0000004a;
3422        outl(trident->ac97_ctrl, TRID_REG(trident, DX_ACR2_AC97_COM_STAT));
3423        /* wait, until the codec is ready */
3424        end_time = (jiffies + (HZ * 3) / 4) + 1;
3425        do {
3426                if ((inl(TRID_REG(trident, DX_ACR2_AC97_COM_STAT)) & 0x0010) != 0)
3427                        goto __dx_ok;
3428                do_delay(trident);
3429        } while (time_after_eq(end_time, jiffies));
3430        dev_err(trident->card->dev, "AC'97 codec ready error\n");
3431        return -EIO;
3432
3433 __dx_ok:
3434        snd_trident_stop_all_voices(trident);
3435
3436        return 0;
3437}
3438
3439/*
3440 * initialize 4D NX chip
3441 */
3442static int snd_trident_4d_nx_init(struct snd_trident *trident)
3443{
3444        struct pci_dev *pci = trident->pci;
3445        unsigned long end_time;
3446
3447        /* reset the legacy configuration and whole audio/wavetable block */
3448        pci_write_config_dword(pci, 0x40, 0);   /* DDMA */
3449        pci_write_config_byte(pci, 0x44, 0);    /* ports */
3450        pci_write_config_byte(pci, 0x45, 0);    /* Legacy DMA */
3451
3452        pci_write_config_byte(pci, 0x46, 1); /* reset */
3453        udelay(100);
3454        pci_write_config_byte(pci, 0x46, 0); /* release reset */
3455        udelay(100);
3456
3457        /* warm reset of the AC'97 codec */
3458        outl(0x00000001, TRID_REG(trident, NX_ACR0_AC97_COM_STAT));
3459        udelay(100);
3460        outl(0x00000000, TRID_REG(trident, NX_ACR0_AC97_COM_STAT));
3461        /* wait, until the codec is ready */
3462        end_time = (jiffies + (HZ * 3) / 4) + 1;
3463        do {
3464                if ((inl(TRID_REG(trident, NX_ACR0_AC97_COM_STAT)) & 0x0008) != 0)
3465                        goto __nx_ok;
3466                do_delay(trident);
3467        } while (time_after_eq(end_time, jiffies));
3468        dev_err(trident->card->dev, "AC'97 codec ready error [0x%x]\n",
3469                inl(TRID_REG(trident, NX_ACR0_AC97_COM_STAT)));
3470        return -EIO;
3471
3472 __nx_ok:
3473        /* DAC on */
3474        trident->ac97_ctrl = 0x00000002;
3475        outl(trident->ac97_ctrl, TRID_REG(trident, NX_ACR0_AC97_COM_STAT));
3476        /* disable SB IRQ */
3477        outl(NX_SB_IRQ_DISABLE, TRID_REG(trident, T4D_MISCINT));
3478
3479        snd_trident_stop_all_voices(trident);
3480
3481        if (trident->tlb.entries != NULL) {
3482                unsigned int i;
3483                /* enable virtual addressing via TLB */
3484                i = trident->tlb.entries_dmaaddr;
3485                i |= 0x00000001;
3486                outl(i, TRID_REG(trident, NX_TLBC));
3487        } else {
3488                outl(0, TRID_REG(trident, NX_TLBC));
3489        }
3490        /* initialize S/PDIF */
3491        outl(trident->spdif_bits, TRID_REG(trident, NX_SPCSTATUS));
3492        outb(trident->spdif_ctrl, TRID_REG(trident, NX_SPCTRL_SPCSO + 3));
3493
3494        return 0;
3495}
3496
3497/*
3498 * initialize sis7018 chip
3499 */
3500static int snd_trident_sis_init(struct snd_trident *trident)
3501{
3502        int err;
3503
3504        if ((err = snd_trident_sis_reset(trident)) < 0)
3505                return err;
3506
3507        snd_trident_stop_all_voices(trident);
3508
3509        /* initialize S/PDIF */
3510        outl(trident->spdif_bits, TRID_REG(trident, SI_SPDIF_CS));
3511
3512        return 0;
3513}
3514
3515/*---------------------------------------------------------------------------
3516   snd_trident_create
3517  
3518   Description: This routine will create the device specific class for
3519                the 4DWave card. It will also perform basic initialization.
3520                
3521   Parameters:  card  - which card to create
3522                pci   - interface to PCI bus resource info
3523                dma1ptr - playback dma buffer
3524                dma2ptr - capture dma buffer
3525                irqptr  -  interrupt resource info
3526
3527   Returns:     4DWave device class private data
3528  
3529  ---------------------------------------------------------------------------*/
3530
3531int snd_trident_create(struct snd_card *card,
3532                       struct pci_dev *pci,
3533                       int pcm_streams,
3534                       int pcm_spdif_device,
3535                       int max_wavetable_size,
3536                       struct snd_trident ** rtrident)
3537{
3538        struct snd_trident *trident;
3539        int i, err;
3540        struct snd_trident_voice *voice;
3541        struct snd_trident_pcm_mixer *tmix;
3542        static struct snd_device_ops ops = {
3543                .dev_free =     snd_trident_dev_free,
3544        };
3545
3546        *rtrident = NULL;
3547
3548        /* enable PCI device */
3549        if ((err = pci_enable_device(pci)) < 0)
3550                return err;
3551        /* check, if we can restrict PCI DMA transfers to 30 bits */
3552        if (dma_set_mask(&pci->dev, DMA_BIT_MASK(30)) < 0 ||
3553            dma_set_coherent_mask(&pci->dev, DMA_BIT_MASK(30)) < 0) {
3554                dev_err(card->dev,
3555                        "architecture does not support 30bit PCI busmaster DMA\n");
3556                pci_disable_device(pci);
3557                return -ENXIO;
3558        }
3559        
3560        trident = kzalloc(sizeof(*trident), GFP_KERNEL);
3561        if (trident == NULL) {
3562                pci_disable_device(pci);
3563                return -ENOMEM;
3564        }
3565        trident->device = (pci->vendor << 16) | pci->device;
3566        trident->card = card;
3567        trident->pci = pci;
3568        spin_lock_init(&trident->reg_lock);
3569        spin_lock_init(&trident->event_lock);
3570        spin_lock_init(&trident->voice_alloc);
3571        if (pcm_streams < 1)
3572                pcm_streams = 1;
3573        if (pcm_streams > 32)
3574                pcm_streams = 32;
3575        trident->ChanPCM = pcm_streams;
3576        if (max_wavetable_size < 0 )
3577                max_wavetable_size = 0;
3578        trident->synth.max_size = max_wavetable_size * 1024;
3579        trident->irq = -1;
3580
3581        trident->midi_port = TRID_REG(trident, T4D_MPU401_BASE);
3582        pci_set_master(pci);
3583
3584        if ((err = pci_request_regions(pci, "Trident Audio")) < 0) {
3585                kfree(trident);
3586                pci_disable_device(pci);
3587                return err;
3588        }
3589        trident->port = pci_resource_start(pci, 0);
3590
3591        if (request_irq(pci->irq, snd_trident_interrupt, IRQF_SHARED,
3592                        KBUILD_MODNAME, trident)) {
3593                dev_err(card->dev, "unable to grab IRQ %d\n", pci->irq);
3594                snd_trident_free(trident);
3595                return -EBUSY;
3596        }
3597        trident->irq = pci->irq;
3598
3599        /* allocate 16k-aligned TLB for NX cards */
3600        trident->tlb.entries = NULL;
3601        trident->tlb.buffer.area = NULL;
3602        if (trident->device == TRIDENT_DEVICE_ID_NX) {
3603                if ((err = snd_trident_tlb_alloc(trident)) < 0) {
3604                        snd_trident_free(trident);
3605                        return err;
3606                }
3607        }
3608
3609        trident->spdif_bits = trident->spdif_pcm_bits = SNDRV_PCM_DEFAULT_CON_SPDIF;
3610
3611        /* initialize chip */
3612        switch (trident->device) {
3613        case TRIDENT_DEVICE_ID_DX:
3614                err = snd_trident_4d_dx_init(trident);
3615                break;
3616        case TRIDENT_DEVICE_ID_NX:
3617                err = snd_trident_4d_nx_init(trident);
3618                break;
3619        case TRIDENT_DEVICE_ID_SI7018:
3620                err = snd_trident_sis_init(trident);
3621                break;
3622        default:
3623                snd_BUG();
3624                break;
3625        }
3626        if (err < 0) {
3627                snd_trident_free(trident);
3628                return err;
3629        }
3630
3631        if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, trident, &ops)) < 0) {
3632                snd_trident_free(trident);
3633                return err;
3634        }
3635
3636        if ((err = snd_trident_mixer(trident, pcm_spdif_device)) < 0)
3637                return err;
3638        
3639        /* initialise synth voices */
3640        for (i = 0; i < 64; i++) {
3641                voice = &trident->synth.voices[i];
3642                voice->number = i;
3643                voice->trident = trident;
3644        }
3645        /* initialize pcm mixer entries */
3646        for (i = 0; i < 32; i++) {
3647                tmix = &trident->pcm_mixer[i];
3648                tmix->vol = T4D_DEFAULT_PCM_VOL;
3649                tmix->pan = T4D_DEFAULT_PCM_PAN;
3650                tmix->rvol = T4D_DEFAULT_PCM_RVOL;
3651                tmix->cvol = T4D_DEFAULT_PCM_CVOL;
3652        }
3653
3654        snd_trident_enable_eso(trident);
3655
3656        snd_trident_proc_init(trident);
3657        *rtrident = trident;
3658        return 0;
3659}
3660
3661/*---------------------------------------------------------------------------
3662   snd_trident_free
3663  
3664   Description: This routine will free the device specific class for
3665                the 4DWave card. 
3666                
3667   Parameters:  trident  - device specific private data for 4DWave card
3668
3669   Returns:     None.
3670  
3671  ---------------------------------------------------------------------------*/
3672
3673static int snd_trident_free(struct snd_trident *trident)
3674{
3675        snd_trident_free_gameport(trident);
3676        snd_trident_disable_eso(trident);
3677        // Disable S/PDIF out
3678        if (trident->device == TRIDENT_DEVICE_ID_NX)
3679                outb(0x00, TRID_REG(trident, NX_SPCTRL_SPCSO + 3));
3680        else if (trident->device == TRIDENT_DEVICE_ID_SI7018) {
3681                outl(0, TRID_REG(trident, SI_SERIAL_INTF_CTRL));
3682        }
3683        if (trident->irq >= 0)
3684                free_irq(trident->irq, trident);
3685        if (trident->tlb.buffer.area) {
3686                outl(0, TRID_REG(trident, NX_TLBC));
3687                snd_util_memhdr_free(trident->tlb.memhdr);
3688                if (trident->tlb.silent_page.area)
3689                        snd_dma_free_pages(&trident->tlb.silent_page);
3690                vfree(trident->tlb.shadow_entries);
3691                snd_dma_free_pages(&trident->tlb.buffer);
3692        }
3693        pci_release_regions(trident->pci);
3694        pci_disable_device(trident->pci);
3695        kfree(trident);
3696        return 0;
3697}
3698
3699/*---------------------------------------------------------------------------
3700   snd_trident_interrupt
3701  
3702   Description: ISR for Trident 4DWave device
3703                
3704   Parameters:  trident  - device specific private data for 4DWave card
3705
3706   Problems:    It seems that Trident chips generates interrupts more than
3707                one time in special cases. The spurious interrupts are
3708                detected via sample timer (T4D_STIMER) and computing
3709                corresponding delta value. The limits are detected with
3710                the method try & fail so it is possible that it won't
3711                work on all computers. [jaroslav]
3712
3713   Returns:     None.
3714  
3715  ---------------------------------------------------------------------------*/
3716
3717static irqreturn_t snd_trident_interrupt(int irq, void *dev_id)
3718{
3719        struct snd_trident *trident = dev_id;
3720        unsigned int audio_int, chn_int, stimer, channel, mask, tmp;
3721        int delta;
3722        struct snd_trident_voice *voice;
3723
3724        audio_int = inl(TRID_REG(trident, T4D_MISCINT));
3725        if ((audio_int & (ADDRESS_IRQ|MPU401_IRQ)) == 0)
3726                return IRQ_NONE;
3727        if (audio_int & ADDRESS_IRQ) {
3728                // get interrupt status for all channels
3729                spin_lock(&trident->reg_lock);
3730                stimer = inl(TRID_REG(trident, T4D_STIMER)) & 0x00ffffff;
3731                chn_int = inl(TRID_REG(trident, T4D_AINT_A));
3732                if (chn_int == 0)
3733                        goto __skip1;
3734                outl(chn_int, TRID_REG(trident, T4D_AINT_A));   /* ack */
3735              __skip1:
3736                chn_int = inl(TRID_REG(trident, T4D_AINT_B));
3737                if (chn_int == 0)
3738                        goto __skip2;
3739                for (channel = 63; channel >= 32; channel--) {
3740                        mask = 1 << (channel&0x1f);
3741                        if ((chn_int & mask) == 0)
3742                                continue;
3743                        voice = &trident->synth.voices[channel];
3744                        if (!voice->pcm || voice->substream == NULL) {
3745                                outl(mask, TRID_REG(trident, T4D_STOP_B));
3746                                continue;
3747                        }
3748                        delta = (int)stimer - (int)voice->stimer;
3749                        if (delta < 0)
3750                                delta = -delta;
3751                        if ((unsigned int)delta < voice->spurious_threshold) {
3752                                /* do some statistics here */
3753                                trident->spurious_irq_count++;
3754                                if (trident->spurious_irq_max_delta < (unsigned int)delta)
3755                                        trident->spurious_irq_max_delta = delta;
3756                                continue;
3757                        }
3758                        voice->stimer = stimer;
3759                        if (voice->isync) {
3760                                if (!voice->isync3) {
3761                                        tmp = inw(TRID_REG(trident, T4D_SBBL_SBCL));
3762                                        if (trident->bDMAStart & 0x40)
3763                                                tmp >>= 1;
3764                                        if (tmp > 0)
3765                                                tmp = voice->isync_max - tmp;
3766                                } else {
3767                                        tmp = inl(TRID_REG(trident, NX_SPCTRL_SPCSO)) & 0x00ffffff;
3768                                }
3769                                if (tmp < voice->isync_mark) {
3770                                        if (tmp > 0x10)
3771                                                tmp = voice->isync_ESO - 7;
3772                                        else
3773                                                tmp = voice->isync_ESO + 2;
3774                                        /* update ESO for IRQ voice to preserve sync */
3775                                        snd_trident_stop_voice(trident, voice->number);
3776                                        snd_trident_write_eso_reg(trident, voice, tmp);
3777                                        snd_trident_start_voice(trident, voice->number);
3778                                }
3779                        } else if (voice->isync2) {
3780                                voice->isync2 = 0;
3781                                /* write original ESO and update CSO for IRQ voice to preserve sync */
3782                                snd_trident_stop_voice(trident, voice->number);
3783                                snd_trident_write_cso_reg(trident, voice, voice->isync_mark);
3784                                snd_trident_write_eso_reg(trident, voice, voice->ESO);
3785                                snd_trident_start_voice(trident, voice->number);
3786                        }
3787#if 0
3788                        if (voice->extra) {
3789                                /* update CSO for extra voice to preserve sync */
3790                                snd_trident_stop_voice(trident, voice->extra->number);
3791                                snd_trident_write_cso_reg(trident, voice->extra, 0);
3792                                snd_trident_start_voice(trident, voice->extra->number);
3793                        }
3794#endif
3795                        spin_unlock(&trident->reg_lock);
3796                        snd_pcm_period_elapsed(voice->substream);
3797                        spin_lock(&trident->reg_lock);
3798                }
3799                outl(chn_int, TRID_REG(trident, T4D_AINT_B));   /* ack */
3800              __skip2:
3801                spin_unlock(&trident->reg_lock);
3802        }
3803        if (audio_int & MPU401_IRQ) {
3804                if (trident->rmidi) {
3805                        snd_mpu401_uart_interrupt(irq, trident->rmidi->private_data);
3806                } else {
3807                        inb(TRID_REG(trident, T4D_MPUR0));
3808                }
3809        }
3810        // outl((ST_TARGET_REACHED | MIXER_OVERFLOW | MIXER_UNDERFLOW), TRID_REG(trident, T4D_MISCINT));
3811        return IRQ_HANDLED;
3812}
3813
3814struct snd_trident_voice *snd_trident_alloc_voice(struct snd_trident * trident, int type, int client, int port)
3815{
3816        struct snd_trident_voice *pvoice;
3817        unsigned long flags;
3818        int idx;
3819
3820        spin_lock_irqsave(&trident->voice_alloc, flags);
3821        if (type == SNDRV_TRIDENT_VOICE_TYPE_PCM) {
3822                idx = snd_trident_allocate_pcm_channel(trident);
3823                if(idx < 0) {
3824                        spin_unlock_irqrestore(&trident->voice_alloc, flags);
3825                        return NULL;
3826                }
3827                pvoice = &trident->synth.voices[idx];
3828                pvoice->use = 1;
3829                pvoice->pcm = 1;
3830                pvoice->capture = 0;
3831                pvoice->spdif = 0;
3832                pvoice->memblk = NULL;
3833                pvoice->substream = NULL;
3834                spin_unlock_irqrestore(&trident->voice_alloc, flags);
3835                return pvoice;
3836        }
3837        if (type == SNDRV_TRIDENT_VOICE_TYPE_SYNTH) {
3838                idx = snd_trident_allocate_synth_channel(trident);
3839                if(idx < 0) {
3840                        spin_unlock_irqrestore(&trident->voice_alloc, flags);
3841                        return NULL;
3842                }
3843                pvoice = &trident->synth.voices[idx];
3844                pvoice->use = 1;
3845                pvoice->synth = 1;
3846                pvoice->client = client;
3847                pvoice->port = port;
3848                pvoice->memblk = NULL;
3849                spin_unlock_irqrestore(&trident->voice_alloc, flags);
3850                return pvoice;
3851        }
3852        if (type == SNDRV_TRIDENT_VOICE_TYPE_MIDI) {
3853        }
3854        spin_unlock_irqrestore(&trident->voice_alloc, flags);
3855        return NULL;
3856}
3857
3858EXPORT_SYMBOL(snd_trident_alloc_voice);
3859
3860void snd_trident_free_voice(struct snd_trident * trident, struct snd_trident_voice *voice)
3861{
3862        unsigned long flags;
3863        void (*private_free)(struct snd_trident_voice *);
3864
3865        if (voice == NULL || !voice->use)
3866                return;
3867        snd_trident_clear_voices(trident, voice->number, voice->number);
3868        spin_lock_irqsave(&trident->voice_alloc, flags);
3869        private_free = voice->private_free;
3870        voice->private_free = NULL;
3871        voice->private_data = NULL;
3872        if (voice->pcm)
3873                snd_trident_free_pcm_channel(trident, voice->number);
3874        if (voice->synth)
3875                snd_trident_free_synth_channel(trident, voice->number);
3876        voice->use = voice->pcm = voice->synth = voice->midi = 0;
3877        voice->capture = voice->spdif = 0;
3878        voice->sample_ops = NULL;
3879        voice->substream = NULL;
3880        voice->extra = NULL;
3881        spin_unlock_irqrestore(&trident->voice_alloc, flags);
3882        if (private_free)
3883                private_free(voice);
3884}
3885
3886EXPORT_SYMBOL(snd_trident_free_voice);
3887
3888static void snd_trident_clear_voices(struct snd_trident * trident, unsigned short v_min, unsigned short v_max)
3889{
3890        unsigned int i, val, mask[2] = { 0, 0 };
3891
3892        if (snd_BUG_ON(v_min > 63 || v_max > 63))
3893                return;
3894        for (i = v_min; i <= v_max; i++)
3895                mask[i >> 5] |= 1 << (i & 0x1f);
3896        if (mask[0]) {
3897                outl(mask[0], TRID_REG(trident, T4D_STOP_A));
3898                val = inl(TRID_REG(trident, T4D_AINTEN_A));
3899                outl(val & ~mask[0], TRID_REG(trident, T4D_AINTEN_A));
3900        }
3901        if (mask[1]) {
3902                outl(mask[1], TRID_REG(trident, T4D_STOP_B));
3903                val = inl(TRID_REG(trident, T4D_AINTEN_B));
3904                outl(val & ~mask[1], TRID_REG(trident, T4D_AINTEN_B));
3905        }
3906}
3907
3908#ifdef CONFIG_PM_SLEEP
3909static int snd_trident_suspend(struct device *dev)
3910{
3911        struct snd_card *card = dev_get_drvdata(dev);
3912        struct snd_trident *trident = card->private_data;
3913
3914        trident->in_suspend = 1;
3915        snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
3916        snd_pcm_suspend_all(trident->pcm);
3917        snd_pcm_suspend_all(trident->foldback);
3918        snd_pcm_suspend_all(trident->spdif);
3919
3920        snd_ac97_suspend(trident->ac97);
3921        snd_ac97_suspend(trident->ac97_sec);
3922        return 0;
3923}
3924
3925static int snd_trident_resume(struct device *dev)
3926{
3927        struct snd_card *card = dev_get_drvdata(dev);
3928        struct snd_trident *trident = card->private_data;
3929
3930        switch (trident->device) {
3931        case TRIDENT_DEVICE_ID_DX:
3932                snd_trident_4d_dx_init(trident);
3933                break;
3934        case TRIDENT_DEVICE_ID_NX:
3935                snd_trident_4d_nx_init(trident);
3936                break;
3937        case TRIDENT_DEVICE_ID_SI7018:
3938                snd_trident_sis_init(trident);
3939                break;
3940        }
3941
3942        snd_ac97_resume(trident->ac97);
3943        snd_ac97_resume(trident->ac97_sec);
3944
3945        /* restore some registers */
3946        outl(trident->musicvol_wavevol, TRID_REG(trident, T4D_MUSICVOL_WAVEVOL));
3947
3948        snd_trident_enable_eso(trident);
3949
3950        snd_power_change_state(card, SNDRV_CTL_POWER_D0);
3951        trident->in_suspend = 0;
3952        return 0;
3953}
3954
3955SIMPLE_DEV_PM_OPS(snd_trident_pm, snd_trident_suspend, snd_trident_resume);
3956#endif /* CONFIG_PM_SLEEP */
3957