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