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