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