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