linux/sound/pci/cs46xx/cs46xx_lib.c
<<
>>
Prefs
   1/*
   2 *  Copyright (c) by Jaroslav Kysela <perex@perex.cz>
   3 *                   Abramo Bagnara <abramo@alsa-project.org>
   4 *                   Cirrus Logic, Inc.
   5 *  Routines for control of Cirrus Logic CS461x chips
   6 *
   7 *  KNOWN BUGS:
   8 *    - Sometimes the SPDIF input DSP tasks get's unsynchronized
   9 *      and the SPDIF get somewhat "distorcionated", or/and left right channel
  10 *      are swapped. To get around this problem when it happens, mute and unmute 
  11 *      the SPDIF input mixer control.
  12 *    - On the Hercules Game Theater XP the amplifier are sometimes turned
  13 *      off on inadecuate moments which causes distorcions on sound.
  14 *
  15 *  TODO:
  16 *    - Secondary CODEC on some soundcards
  17 *    - SPDIF input support for other sample rates then 48khz
  18 *    - Posibility to mix the SPDIF output with analog sources.
  19 *    - PCM channels for Center and LFE on secondary codec
  20 *
  21 *  NOTE: with CONFIG_SND_CS46XX_NEW_DSP unset uses old DSP image (which
  22 *        is default configuration), no SPDIF, no secondary codec, no
  23 *        multi channel PCM.  But known to work.
  24 *
  25 *  FINALLY: A credit to the developers Tom and Jordan 
  26 *           at Cirrus for have helping me out with the DSP, however we
  27 *           still don't have sufficient documentation and technical
  28 *           references to be able to implement all fancy feutures
  29 *           supported by the cs46xx DSP's. 
  30 *           Benny <benny@hostmobility.com>
  31 *                
  32 *   This program is free software; you can redistribute it and/or modify
  33 *   it under the terms of the GNU General Public License as published by
  34 *   the Free Software Foundation; either version 2 of the License, or
  35 *   (at your option) any later version.
  36 *
  37 *   This program is distributed in the hope that it will be useful,
  38 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
  39 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  40 *   GNU General Public License for more details.
  41 *
  42 *   You should have received a copy of the GNU General Public License
  43 *   along with this program; if not, write to the Free Software
  44 *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  45 *
  46 */
  47
  48#include <linux/delay.h>
  49#include <linux/pci.h>
  50#include <linux/pm.h>
  51#include <linux/init.h>
  52#include <linux/interrupt.h>
  53#include <linux/slab.h>
  54#include <linux/gameport.h>
  55#include <linux/mutex.h>
  56#include <linux/export.h>
  57#include <linux/module.h>
  58#include <linux/firmware.h>
  59#include <linux/vmalloc.h>
  60
  61#include <sound/core.h>
  62#include <sound/control.h>
  63#include <sound/info.h>
  64#include <sound/pcm.h>
  65#include <sound/pcm_params.h>
  66#include "cs46xx.h"
  67
  68#include <asm/io.h>
  69
  70#include "cs46xx_lib.h"
  71#include "dsp_spos.h"
  72
  73static void amp_voyetra(struct snd_cs46xx *chip, int change);
  74
  75#ifdef CONFIG_SND_CS46XX_NEW_DSP
  76static struct snd_pcm_ops snd_cs46xx_playback_rear_ops;
  77static struct snd_pcm_ops snd_cs46xx_playback_indirect_rear_ops;
  78static struct snd_pcm_ops snd_cs46xx_playback_clfe_ops;
  79static struct snd_pcm_ops snd_cs46xx_playback_indirect_clfe_ops;
  80static struct snd_pcm_ops snd_cs46xx_playback_iec958_ops;
  81static struct snd_pcm_ops snd_cs46xx_playback_indirect_iec958_ops;
  82#endif
  83
  84static struct snd_pcm_ops snd_cs46xx_playback_ops;
  85static struct snd_pcm_ops snd_cs46xx_playback_indirect_ops;
  86static struct snd_pcm_ops snd_cs46xx_capture_ops;
  87static struct snd_pcm_ops snd_cs46xx_capture_indirect_ops;
  88
  89static unsigned short snd_cs46xx_codec_read(struct snd_cs46xx *chip,
  90                                            unsigned short reg,
  91                                            int codec_index)
  92{
  93        int count;
  94        unsigned short result,tmp;
  95        u32 offset = 0;
  96
  97        if (snd_BUG_ON(codec_index != CS46XX_PRIMARY_CODEC_INDEX &&
  98                       codec_index != CS46XX_SECONDARY_CODEC_INDEX))
  99                return 0xffff;
 100
 101        chip->active_ctrl(chip, 1);
 102
 103        if (codec_index == CS46XX_SECONDARY_CODEC_INDEX)
 104                offset = CS46XX_SECONDARY_CODEC_OFFSET;
 105
 106        /*
 107         *  1. Write ACCAD = Command Address Register = 46Ch for AC97 register address
 108         *  2. Write ACCDA = Command Data Register = 470h    for data to write to AC97 
 109         *  3. Write ACCTL = Control Register = 460h for initiating the write7---55
 110         *  4. Read ACCTL = 460h, DCV should be reset by now and 460h = 17h
 111         *  5. if DCV not cleared, break and return error
 112         *  6. Read ACSTS = Status Register = 464h, check VSTS bit
 113         */
 114
 115        snd_cs46xx_peekBA0(chip, BA0_ACSDA + offset);
 116
 117        tmp = snd_cs46xx_peekBA0(chip, BA0_ACCTL);
 118        if ((tmp & ACCTL_VFRM) == 0) {
 119                dev_warn(chip->card->dev, "ACCTL_VFRM not set 0x%x\n", tmp);
 120                snd_cs46xx_pokeBA0(chip, BA0_ACCTL, (tmp & (~ACCTL_ESYN)) | ACCTL_VFRM );
 121                msleep(50);
 122                tmp = snd_cs46xx_peekBA0(chip, BA0_ACCTL + offset);
 123                snd_cs46xx_pokeBA0(chip, BA0_ACCTL, tmp | ACCTL_ESYN | ACCTL_VFRM );
 124
 125        }
 126
 127        /*
 128         *  Setup the AC97 control registers on the CS461x to send the
 129         *  appropriate command to the AC97 to perform the read.
 130         *  ACCAD = Command Address Register = 46Ch
 131         *  ACCDA = Command Data Register = 470h
 132         *  ACCTL = Control Register = 460h
 133         *  set DCV - will clear when process completed
 134         *  set CRW - Read command
 135         *  set VFRM - valid frame enabled
 136         *  set ESYN - ASYNC generation enabled
 137         *  set RSTN - ARST# inactive, AC97 codec not reset
 138         */
 139
 140        snd_cs46xx_pokeBA0(chip, BA0_ACCAD, reg);
 141        snd_cs46xx_pokeBA0(chip, BA0_ACCDA, 0);
 142        if (codec_index == CS46XX_PRIMARY_CODEC_INDEX) {
 143                snd_cs46xx_pokeBA0(chip, BA0_ACCTL,/* clear ACCTL_DCV */ ACCTL_CRW | 
 144                                   ACCTL_VFRM | ACCTL_ESYN |
 145                                   ACCTL_RSTN);
 146                snd_cs46xx_pokeBA0(chip, BA0_ACCTL, ACCTL_DCV | ACCTL_CRW |
 147                                   ACCTL_VFRM | ACCTL_ESYN |
 148                                   ACCTL_RSTN);
 149        } else {
 150                snd_cs46xx_pokeBA0(chip, BA0_ACCTL, ACCTL_DCV | ACCTL_TC |
 151                                   ACCTL_CRW | ACCTL_VFRM | ACCTL_ESYN |
 152                                   ACCTL_RSTN);
 153        }
 154
 155        /*
 156         *  Wait for the read to occur.
 157         */
 158        for (count = 0; count < 1000; count++) {
 159                /*
 160                 *  First, we want to wait for a short time.
 161                 */
 162                udelay(10);
 163                /*
 164                 *  Now, check to see if the read has completed.
 165                 *  ACCTL = 460h, DCV should be reset by now and 460h = 17h
 166                 */
 167                if (!(snd_cs46xx_peekBA0(chip, BA0_ACCTL) & ACCTL_DCV))
 168                        goto ok1;
 169        }
 170
 171        dev_err(chip->card->dev,
 172                "AC'97 read problem (ACCTL_DCV), reg = 0x%x\n", reg);
 173        result = 0xffff;
 174        goto end;
 175        
 176 ok1:
 177        /*
 178         *  Wait for the valid status bit to go active.
 179         */
 180        for (count = 0; count < 100; count++) {
 181                /*
 182                 *  Read the AC97 status register.
 183                 *  ACSTS = Status Register = 464h
 184                 *  VSTS - Valid Status
 185                 */
 186                if (snd_cs46xx_peekBA0(chip, BA0_ACSTS + offset) & ACSTS_VSTS)
 187                        goto ok2;
 188                udelay(10);
 189        }
 190        
 191        dev_err(chip->card->dev,
 192                "AC'97 read problem (ACSTS_VSTS), codec_index %d, reg = 0x%x\n",
 193                codec_index, reg);
 194        result = 0xffff;
 195        goto end;
 196
 197 ok2:
 198        /*
 199         *  Read the data returned from the AC97 register.
 200         *  ACSDA = Status Data Register = 474h
 201         */
 202#if 0
 203        dev_dbg(chip->card->dev,
 204                "e) reg = 0x%x, val = 0x%x, BA0_ACCAD = 0x%x\n", reg,
 205                        snd_cs46xx_peekBA0(chip, BA0_ACSDA),
 206                        snd_cs46xx_peekBA0(chip, BA0_ACCAD));
 207#endif
 208
 209        //snd_cs46xx_peekBA0(chip, BA0_ACCAD);
 210        result = snd_cs46xx_peekBA0(chip, BA0_ACSDA + offset);
 211 end:
 212        chip->active_ctrl(chip, -1);
 213        return result;
 214}
 215
 216static unsigned short snd_cs46xx_ac97_read(struct snd_ac97 * ac97,
 217                                            unsigned short reg)
 218{
 219        struct snd_cs46xx *chip = ac97->private_data;
 220        unsigned short val;
 221        int codec_index = ac97->num;
 222
 223        if (snd_BUG_ON(codec_index != CS46XX_PRIMARY_CODEC_INDEX &&
 224                       codec_index != CS46XX_SECONDARY_CODEC_INDEX))
 225                return 0xffff;
 226
 227        val = snd_cs46xx_codec_read(chip, reg, codec_index);
 228
 229        return val;
 230}
 231
 232
 233static void snd_cs46xx_codec_write(struct snd_cs46xx *chip,
 234                                   unsigned short reg,
 235                                   unsigned short val,
 236                                   int codec_index)
 237{
 238        int count;
 239
 240        if (snd_BUG_ON(codec_index != CS46XX_PRIMARY_CODEC_INDEX &&
 241                       codec_index != CS46XX_SECONDARY_CODEC_INDEX))
 242                return;
 243
 244        chip->active_ctrl(chip, 1);
 245
 246        /*
 247         *  1. Write ACCAD = Command Address Register = 46Ch for AC97 register address
 248         *  2. Write ACCDA = Command Data Register = 470h    for data to write to AC97
 249         *  3. Write ACCTL = Control Register = 460h for initiating the write
 250         *  4. Read ACCTL = 460h, DCV should be reset by now and 460h = 07h
 251         *  5. if DCV not cleared, break and return error
 252         */
 253
 254        /*
 255         *  Setup the AC97 control registers on the CS461x to send the
 256         *  appropriate command to the AC97 to perform the read.
 257         *  ACCAD = Command Address Register = 46Ch
 258         *  ACCDA = Command Data Register = 470h
 259         *  ACCTL = Control Register = 460h
 260         *  set DCV - will clear when process completed
 261         *  reset CRW - Write command
 262         *  set VFRM - valid frame enabled
 263         *  set ESYN - ASYNC generation enabled
 264         *  set RSTN - ARST# inactive, AC97 codec not reset
 265         */
 266        snd_cs46xx_pokeBA0(chip, BA0_ACCAD , reg);
 267        snd_cs46xx_pokeBA0(chip, BA0_ACCDA , val);
 268        snd_cs46xx_peekBA0(chip, BA0_ACCTL);
 269
 270        if (codec_index == CS46XX_PRIMARY_CODEC_INDEX) {
 271                snd_cs46xx_pokeBA0(chip, BA0_ACCTL, /* clear ACCTL_DCV */ ACCTL_VFRM |
 272                                   ACCTL_ESYN | ACCTL_RSTN);
 273                snd_cs46xx_pokeBA0(chip, BA0_ACCTL, ACCTL_DCV | ACCTL_VFRM |
 274                                   ACCTL_ESYN | ACCTL_RSTN);
 275        } else {
 276                snd_cs46xx_pokeBA0(chip, BA0_ACCTL, ACCTL_DCV | ACCTL_TC |
 277                                   ACCTL_VFRM | ACCTL_ESYN | ACCTL_RSTN);
 278        }
 279
 280        for (count = 0; count < 4000; count++) {
 281                /*
 282                 *  First, we want to wait for a short time.
 283                 */
 284                udelay(10);
 285                /*
 286                 *  Now, check to see if the write has completed.
 287                 *  ACCTL = 460h, DCV should be reset by now and 460h = 07h
 288                 */
 289                if (!(snd_cs46xx_peekBA0(chip, BA0_ACCTL) & ACCTL_DCV)) {
 290                        goto end;
 291                }
 292        }
 293        dev_err(chip->card->dev,
 294                "AC'97 write problem, codec_index = %d, reg = 0x%x, val = 0x%x\n",
 295                codec_index, reg, val);
 296 end:
 297        chip->active_ctrl(chip, -1);
 298}
 299
 300static void snd_cs46xx_ac97_write(struct snd_ac97 *ac97,
 301                                   unsigned short reg,
 302                                   unsigned short val)
 303{
 304        struct snd_cs46xx *chip = ac97->private_data;
 305        int codec_index = ac97->num;
 306
 307        if (snd_BUG_ON(codec_index != CS46XX_PRIMARY_CODEC_INDEX &&
 308                       codec_index != CS46XX_SECONDARY_CODEC_INDEX))
 309                return;
 310
 311        snd_cs46xx_codec_write(chip, reg, val, codec_index);
 312}
 313
 314
 315/*
 316 *  Chip initialization
 317 */
 318
 319int snd_cs46xx_download(struct snd_cs46xx *chip,
 320                        u32 *src,
 321                        unsigned long offset,
 322                        unsigned long len)
 323{
 324        void __iomem *dst;
 325        unsigned int bank = offset >> 16;
 326        offset = offset & 0xffff;
 327
 328        if (snd_BUG_ON((offset & 3) || (len & 3)))
 329                return -EINVAL;
 330        dst = chip->region.idx[bank+1].remap_addr + offset;
 331        len /= sizeof(u32);
 332
 333        /* writel already converts 32-bit value to right endianess */
 334        while (len-- > 0) {
 335                writel(*src++, dst);
 336                dst += sizeof(u32);
 337        }
 338        return 0;
 339}
 340
 341static inline void memcpy_le32(void *dst, const void *src, unsigned int len)
 342{
 343#ifdef __LITTLE_ENDIAN
 344        memcpy(dst, src, len);
 345#else
 346        u32 *_dst = dst;
 347        const __le32 *_src = src;
 348        len /= 4;
 349        while (len-- > 0)
 350                *_dst++ = le32_to_cpu(*_src++);
 351#endif
 352}
 353
 354#ifdef CONFIG_SND_CS46XX_NEW_DSP
 355
 356static const char *module_names[CS46XX_DSP_MODULES] = {
 357        "cwc4630", "cwcasync", "cwcsnoop", "cwcbinhack", "cwcdma"
 358};
 359
 360MODULE_FIRMWARE("cs46xx/cwc4630");
 361MODULE_FIRMWARE("cs46xx/cwcasync");
 362MODULE_FIRMWARE("cs46xx/cwcsnoop");
 363MODULE_FIRMWARE("cs46xx/cwcbinhack");
 364MODULE_FIRMWARE("cs46xx/cwcdma");
 365
 366static void free_module_desc(struct dsp_module_desc *module)
 367{
 368        if (!module)
 369                return;
 370        kfree(module->module_name);
 371        kfree(module->symbol_table.symbols);
 372        if (module->segments) {
 373                int i;
 374                for (i = 0; i < module->nsegments; i++)
 375                        kfree(module->segments[i].data);
 376                kfree(module->segments);
 377        }
 378        kfree(module);
 379}
 380
 381/* firmware binary format:
 382 * le32 nsymbols;
 383 * struct {
 384 *      le32 address;
 385 *      char symbol_name[DSP_MAX_SYMBOL_NAME];
 386 *      le32 symbol_type;
 387 * } symbols[nsymbols];
 388 * le32 nsegments;
 389 * struct {
 390 *      le32 segment_type;
 391 *      le32 offset;
 392 *      le32 size;
 393 *      le32 data[size];
 394 * } segments[nsegments];
 395 */
 396
 397static int load_firmware(struct snd_cs46xx *chip,
 398                         struct dsp_module_desc **module_ret,
 399                         const char *fw_name)
 400{
 401        int i, err;
 402        unsigned int nums, fwlen, fwsize;
 403        const __le32 *fwdat;
 404        struct dsp_module_desc *module = NULL;
 405        const struct firmware *fw;
 406        char fw_path[32];
 407
 408        sprintf(fw_path, "cs46xx/%s", fw_name);
 409        err = request_firmware(&fw, fw_path, &chip->pci->dev);
 410        if (err < 0)
 411                return err;
 412        fwsize = fw->size / 4;
 413        if (fwsize < 2) {
 414                err = -EINVAL;
 415                goto error;
 416        }
 417
 418        err = -ENOMEM;
 419        module = kzalloc(sizeof(*module), GFP_KERNEL);
 420        if (!module)
 421                goto error;
 422        module->module_name = kstrdup(fw_name, GFP_KERNEL);
 423        if (!module->module_name)
 424                goto error;
 425
 426        fwlen = 0;
 427        fwdat = (const __le32 *)fw->data;
 428        nums = module->symbol_table.nsymbols = le32_to_cpu(fwdat[fwlen++]);
 429        if (nums >= 40)
 430                goto error_inval;
 431        module->symbol_table.symbols =
 432                kcalloc(nums, sizeof(struct dsp_symbol_entry), GFP_KERNEL);
 433        if (!module->symbol_table.symbols)
 434                goto error;
 435        for (i = 0; i < nums; i++) {
 436                struct dsp_symbol_entry *entry =
 437                        &module->symbol_table.symbols[i];
 438                if (fwlen + 2 + DSP_MAX_SYMBOL_NAME / 4 > fwsize)
 439                        goto error_inval;
 440                entry->address = le32_to_cpu(fwdat[fwlen++]);
 441                memcpy(entry->symbol_name, &fwdat[fwlen], DSP_MAX_SYMBOL_NAME - 1);
 442                fwlen += DSP_MAX_SYMBOL_NAME / 4;
 443                entry->symbol_type = le32_to_cpu(fwdat[fwlen++]);
 444        }
 445
 446        if (fwlen >= fwsize)
 447                goto error_inval;
 448        nums = module->nsegments = le32_to_cpu(fwdat[fwlen++]);
 449        if (nums > 10)
 450                goto error_inval;
 451        module->segments =
 452                kcalloc(nums, sizeof(struct dsp_segment_desc), GFP_KERNEL);
 453        if (!module->segments)
 454                goto error;
 455        for (i = 0; i < nums; i++) {
 456                struct dsp_segment_desc *entry = &module->segments[i];
 457                if (fwlen + 3 > fwsize)
 458                        goto error_inval;
 459                entry->segment_type = le32_to_cpu(fwdat[fwlen++]);
 460                entry->offset = le32_to_cpu(fwdat[fwlen++]);
 461                entry->size = le32_to_cpu(fwdat[fwlen++]);
 462                if (fwlen + entry->size > fwsize)
 463                        goto error_inval;
 464                entry->data = kmalloc(entry->size * 4, GFP_KERNEL);
 465                if (!entry->data)
 466                        goto error;
 467                memcpy_le32(entry->data, &fwdat[fwlen], entry->size * 4);
 468                fwlen += entry->size;
 469        }
 470
 471        *module_ret = module;
 472        release_firmware(fw);
 473        return 0;
 474
 475 error_inval:
 476        err = -EINVAL;
 477 error:
 478        free_module_desc(module);
 479        release_firmware(fw);
 480        return err;
 481}
 482
 483int snd_cs46xx_clear_BA1(struct snd_cs46xx *chip,
 484                         unsigned long offset,
 485                         unsigned long len) 
 486{
 487        void __iomem *dst;
 488        unsigned int bank = offset >> 16;
 489        offset = offset & 0xffff;
 490
 491        if (snd_BUG_ON((offset & 3) || (len & 3)))
 492                return -EINVAL;
 493        dst = chip->region.idx[bank+1].remap_addr + offset;
 494        len /= sizeof(u32);
 495
 496        /* writel already converts 32-bit value to right endianess */
 497        while (len-- > 0) {
 498                writel(0, dst);
 499                dst += sizeof(u32);
 500        }
 501        return 0;
 502}
 503
 504#else /* old DSP image */
 505
 506struct ba1_struct {
 507        struct {
 508                u32 offset;
 509                u32 size;
 510        } memory[BA1_MEMORY_COUNT];
 511        u32 map[BA1_DWORD_SIZE];
 512};
 513
 514MODULE_FIRMWARE("cs46xx/ba1");
 515
 516static int load_firmware(struct snd_cs46xx *chip)
 517{
 518        const struct firmware *fw;
 519        int i, size, err;
 520
 521        err = request_firmware(&fw, "cs46xx/ba1", &chip->pci->dev);
 522        if (err < 0)
 523                return err;
 524        if (fw->size != sizeof(*chip->ba1)) {
 525                err = -EINVAL;
 526                goto error;
 527        }
 528
 529        chip->ba1 = vmalloc(sizeof(*chip->ba1));
 530        if (!chip->ba1) {
 531                err = -ENOMEM;
 532                goto error;
 533        }
 534
 535        memcpy_le32(chip->ba1, fw->data, sizeof(*chip->ba1));
 536
 537        /* sanity check */
 538        size = 0;
 539        for (i = 0; i < BA1_MEMORY_COUNT; i++)
 540                size += chip->ba1->memory[i].size;
 541        if (size > BA1_DWORD_SIZE * 4)
 542                err = -EINVAL;
 543
 544 error:
 545        release_firmware(fw);
 546        return err;
 547}
 548
 549int snd_cs46xx_download_image(struct snd_cs46xx *chip)
 550{
 551        int idx, err;
 552        unsigned int offset = 0;
 553        struct ba1_struct *ba1 = chip->ba1;
 554
 555        for (idx = 0; idx < BA1_MEMORY_COUNT; idx++) {
 556                err = snd_cs46xx_download(chip,
 557                                          &ba1->map[offset],
 558                                          ba1->memory[idx].offset,
 559                                          ba1->memory[idx].size);
 560                if (err < 0)
 561                        return err;
 562                offset += ba1->memory[idx].size >> 2;
 563        }       
 564        return 0;
 565}
 566#endif /* CONFIG_SND_CS46XX_NEW_DSP */
 567
 568/*
 569 *  Chip reset
 570 */
 571
 572static void snd_cs46xx_reset(struct snd_cs46xx *chip)
 573{
 574        int idx;
 575
 576        /*
 577         *  Write the reset bit of the SP control register.
 578         */
 579        snd_cs46xx_poke(chip, BA1_SPCR, SPCR_RSTSP);
 580
 581        /*
 582         *  Write the control register.
 583         */
 584        snd_cs46xx_poke(chip, BA1_SPCR, SPCR_DRQEN);
 585
 586        /*
 587         *  Clear the trap registers.
 588         */
 589        for (idx = 0; idx < 8; idx++) {
 590                snd_cs46xx_poke(chip, BA1_DREG, DREG_REGID_TRAP_SELECT + idx);
 591                snd_cs46xx_poke(chip, BA1_TWPR, 0xFFFF);
 592        }
 593        snd_cs46xx_poke(chip, BA1_DREG, 0);
 594
 595        /*
 596         *  Set the frame timer to reflect the number of cycles per frame.
 597         */
 598        snd_cs46xx_poke(chip, BA1_FRMT, 0xadf);
 599}
 600
 601static int cs46xx_wait_for_fifo(struct snd_cs46xx * chip,int retry_timeout) 
 602{
 603        u32 i, status = 0;
 604        /*
 605         * Make sure the previous FIFO write operation has completed.
 606         */
 607        for(i = 0; i < 50; i++){
 608                status = snd_cs46xx_peekBA0(chip, BA0_SERBST);
 609    
 610                if( !(status & SERBST_WBSY) )
 611                        break;
 612
 613                mdelay(retry_timeout);
 614        }
 615  
 616        if(status & SERBST_WBSY) {
 617                dev_err(chip->card->dev,
 618                        "failure waiting for FIFO command to complete\n");
 619                return -EINVAL;
 620        }
 621
 622        return 0;
 623}
 624
 625static void snd_cs46xx_clear_serial_FIFOs(struct snd_cs46xx *chip)
 626{
 627        int idx, powerdown = 0;
 628        unsigned int tmp;
 629
 630        /*
 631         *  See if the devices are powered down.  If so, we must power them up first
 632         *  or they will not respond.
 633         */
 634        tmp = snd_cs46xx_peekBA0(chip, BA0_CLKCR1);
 635        if (!(tmp & CLKCR1_SWCE)) {
 636                snd_cs46xx_pokeBA0(chip, BA0_CLKCR1, tmp | CLKCR1_SWCE);
 637                powerdown = 1;
 638        }
 639
 640        /*
 641         *  We want to clear out the serial port FIFOs so we don't end up playing
 642         *  whatever random garbage happens to be in them.  We fill the sample FIFOS
 643         *  with zero (silence).
 644         */
 645        snd_cs46xx_pokeBA0(chip, BA0_SERBWP, 0);
 646
 647        /*
 648         *  Fill all 256 sample FIFO locations.
 649         */
 650        for (idx = 0; idx < 0xFF; idx++) {
 651                /*
 652                 *  Make sure the previous FIFO write operation has completed.
 653                 */
 654                if (cs46xx_wait_for_fifo(chip,1)) {
 655                        dev_dbg(chip->card->dev,
 656                                "failed waiting for FIFO at addr (%02X)\n",
 657                                idx);
 658
 659                        if (powerdown)
 660                                snd_cs46xx_pokeBA0(chip, BA0_CLKCR1, tmp);
 661          
 662                        break;
 663                }
 664                /*
 665                 *  Write the serial port FIFO index.
 666                 */
 667                snd_cs46xx_pokeBA0(chip, BA0_SERBAD, idx);
 668                /*
 669                 *  Tell the serial port to load the new value into the FIFO location.
 670                 */
 671                snd_cs46xx_pokeBA0(chip, BA0_SERBCM, SERBCM_WRC);
 672        }
 673        /*
 674         *  Now, if we powered up the devices, then power them back down again.
 675         *  This is kinda ugly, but should never happen.
 676         */
 677        if (powerdown)
 678                snd_cs46xx_pokeBA0(chip, BA0_CLKCR1, tmp);
 679}
 680
 681static void snd_cs46xx_proc_start(struct snd_cs46xx *chip)
 682{
 683        int cnt;
 684
 685        /*
 686         *  Set the frame timer to reflect the number of cycles per frame.
 687         */
 688        snd_cs46xx_poke(chip, BA1_FRMT, 0xadf);
 689        /*
 690         *  Turn on the run, run at frame, and DMA enable bits in the local copy of
 691         *  the SP control register.
 692         */
 693        snd_cs46xx_poke(chip, BA1_SPCR, SPCR_RUN | SPCR_RUNFR | SPCR_DRQEN);
 694        /*
 695         *  Wait until the run at frame bit resets itself in the SP control
 696         *  register.
 697         */
 698        for (cnt = 0; cnt < 25; cnt++) {
 699                udelay(50);
 700                if (!(snd_cs46xx_peek(chip, BA1_SPCR) & SPCR_RUNFR))
 701                        break;
 702        }
 703
 704        if (snd_cs46xx_peek(chip, BA1_SPCR) & SPCR_RUNFR)
 705                dev_err(chip->card->dev, "SPCR_RUNFR never reset\n");
 706}
 707
 708static void snd_cs46xx_proc_stop(struct snd_cs46xx *chip)
 709{
 710        /*
 711         *  Turn off the run, run at frame, and DMA enable bits in the local copy of
 712         *  the SP control register.
 713         */
 714        snd_cs46xx_poke(chip, BA1_SPCR, 0);
 715}
 716
 717/*
 718 *  Sample rate routines
 719 */
 720
 721#define GOF_PER_SEC 200
 722
 723static void snd_cs46xx_set_play_sample_rate(struct snd_cs46xx *chip, unsigned int rate)
 724{
 725        unsigned long flags;
 726        unsigned int tmp1, tmp2;
 727        unsigned int phiIncr;
 728        unsigned int correctionPerGOF, correctionPerSec;
 729
 730        /*
 731         *  Compute the values used to drive the actual sample rate conversion.
 732         *  The following formulas are being computed, using inline assembly
 733         *  since we need to use 64 bit arithmetic to compute the values:
 734         *
 735         *  phiIncr = floor((Fs,in * 2^26) / Fs,out)
 736         *  correctionPerGOF = floor((Fs,in * 2^26 - Fs,out * phiIncr) /
 737         *                                   GOF_PER_SEC)
 738         *  ulCorrectionPerSec = Fs,in * 2^26 - Fs,out * phiIncr -M
 739         *                       GOF_PER_SEC * correctionPerGOF
 740         *
 741         *  i.e.
 742         *
 743         *  phiIncr:other = dividend:remainder((Fs,in * 2^26) / Fs,out)
 744         *  correctionPerGOF:correctionPerSec =
 745         *      dividend:remainder(ulOther / GOF_PER_SEC)
 746         */
 747        tmp1 = rate << 16;
 748        phiIncr = tmp1 / 48000;
 749        tmp1 -= phiIncr * 48000;
 750        tmp1 <<= 10;
 751        phiIncr <<= 10;
 752        tmp2 = tmp1 / 48000;
 753        phiIncr += tmp2;
 754        tmp1 -= tmp2 * 48000;
 755        correctionPerGOF = tmp1 / GOF_PER_SEC;
 756        tmp1 -= correctionPerGOF * GOF_PER_SEC;
 757        correctionPerSec = tmp1;
 758
 759        /*
 760         *  Fill in the SampleRateConverter control block.
 761         */
 762        spin_lock_irqsave(&chip->reg_lock, flags);
 763        snd_cs46xx_poke(chip, BA1_PSRC,
 764          ((correctionPerSec << 16) & 0xFFFF0000) | (correctionPerGOF & 0xFFFF));
 765        snd_cs46xx_poke(chip, BA1_PPI, phiIncr);
 766        spin_unlock_irqrestore(&chip->reg_lock, flags);
 767}
 768
 769static void snd_cs46xx_set_capture_sample_rate(struct snd_cs46xx *chip, unsigned int rate)
 770{
 771        unsigned long flags;
 772        unsigned int phiIncr, coeffIncr, tmp1, tmp2;
 773        unsigned int correctionPerGOF, correctionPerSec, initialDelay;
 774        unsigned int frameGroupLength, cnt;
 775
 776        /*
 777         *  We can only decimate by up to a factor of 1/9th the hardware rate.
 778         *  Correct the value if an attempt is made to stray outside that limit.
 779         */
 780        if ((rate * 9) < 48000)
 781                rate = 48000 / 9;
 782
 783        /*
 784         *  We can not capture at at rate greater than the Input Rate (48000).
 785         *  Return an error if an attempt is made to stray outside that limit.
 786         */
 787        if (rate > 48000)
 788                rate = 48000;
 789
 790        /*
 791         *  Compute the values used to drive the actual sample rate conversion.
 792         *  The following formulas are being computed, using inline assembly
 793         *  since we need to use 64 bit arithmetic to compute the values:
 794         *
 795         *     coeffIncr = -floor((Fs,out * 2^23) / Fs,in)
 796         *     phiIncr = floor((Fs,in * 2^26) / Fs,out)
 797         *     correctionPerGOF = floor((Fs,in * 2^26 - Fs,out * phiIncr) /
 798         *                                GOF_PER_SEC)
 799         *     correctionPerSec = Fs,in * 2^26 - Fs,out * phiIncr -
 800         *                          GOF_PER_SEC * correctionPerGOF
 801         *     initialDelay = ceil((24 * Fs,in) / Fs,out)
 802         *
 803         * i.e.
 804         *
 805         *     coeffIncr = neg(dividend((Fs,out * 2^23) / Fs,in))
 806         *     phiIncr:ulOther = dividend:remainder((Fs,in * 2^26) / Fs,out)
 807         *     correctionPerGOF:correctionPerSec =
 808         *          dividend:remainder(ulOther / GOF_PER_SEC)
 809         *     initialDelay = dividend(((24 * Fs,in) + Fs,out - 1) / Fs,out)
 810         */
 811
 812        tmp1 = rate << 16;
 813        coeffIncr = tmp1 / 48000;
 814        tmp1 -= coeffIncr * 48000;
 815        tmp1 <<= 7;
 816        coeffIncr <<= 7;
 817        coeffIncr += tmp1 / 48000;
 818        coeffIncr ^= 0xFFFFFFFF;
 819        coeffIncr++;
 820        tmp1 = 48000 << 16;
 821        phiIncr = tmp1 / rate;
 822        tmp1 -= phiIncr * rate;
 823        tmp1 <<= 10;
 824        phiIncr <<= 10;
 825        tmp2 = tmp1 / rate;
 826        phiIncr += tmp2;
 827        tmp1 -= tmp2 * rate;
 828        correctionPerGOF = tmp1 / GOF_PER_SEC;
 829        tmp1 -= correctionPerGOF * GOF_PER_SEC;
 830        correctionPerSec = tmp1;
 831        initialDelay = ((48000 * 24) + rate - 1) / rate;
 832
 833        /*
 834         *  Fill in the VariDecimate control block.
 835         */
 836        spin_lock_irqsave(&chip->reg_lock, flags);
 837        snd_cs46xx_poke(chip, BA1_CSRC,
 838                ((correctionPerSec << 16) & 0xFFFF0000) | (correctionPerGOF & 0xFFFF));
 839        snd_cs46xx_poke(chip, BA1_CCI, coeffIncr);
 840        snd_cs46xx_poke(chip, BA1_CD,
 841                (((BA1_VARIDEC_BUF_1 + (initialDelay << 2)) << 16) & 0xFFFF0000) | 0x80);
 842        snd_cs46xx_poke(chip, BA1_CPI, phiIncr);
 843        spin_unlock_irqrestore(&chip->reg_lock, flags);
 844
 845        /*
 846         *  Figure out the frame group length for the write back task.  Basically,
 847         *  this is just the factors of 24000 (2^6*3*5^3) that are not present in
 848         *  the output sample rate.
 849         */
 850        frameGroupLength = 1;
 851        for (cnt = 2; cnt <= 64; cnt *= 2) {
 852                if (((rate / cnt) * cnt) != rate)
 853                        frameGroupLength *= 2;
 854        }
 855        if (((rate / 3) * 3) != rate) {
 856                frameGroupLength *= 3;
 857        }
 858        for (cnt = 5; cnt <= 125; cnt *= 5) {
 859                if (((rate / cnt) * cnt) != rate) 
 860                        frameGroupLength *= 5;
 861        }
 862
 863        /*
 864         * Fill in the WriteBack control block.
 865         */
 866        spin_lock_irqsave(&chip->reg_lock, flags);
 867        snd_cs46xx_poke(chip, BA1_CFG1, frameGroupLength);
 868        snd_cs46xx_poke(chip, BA1_CFG2, (0x00800000 | frameGroupLength));
 869        snd_cs46xx_poke(chip, BA1_CCST, 0x0000FFFF);
 870        snd_cs46xx_poke(chip, BA1_CSPB, ((65536 * rate) / 24000));
 871        snd_cs46xx_poke(chip, (BA1_CSPB + 4), 0x0000FFFF);
 872        spin_unlock_irqrestore(&chip->reg_lock, flags);
 873}
 874
 875/*
 876 *  PCM part
 877 */
 878
 879static void snd_cs46xx_pb_trans_copy(struct snd_pcm_substream *substream,
 880                                     struct snd_pcm_indirect *rec, size_t bytes)
 881{
 882        struct snd_pcm_runtime *runtime = substream->runtime;
 883        struct snd_cs46xx_pcm * cpcm = runtime->private_data;
 884        memcpy(cpcm->hw_buf.area + rec->hw_data, runtime->dma_area + rec->sw_data, bytes);
 885}
 886
 887static int snd_cs46xx_playback_transfer(struct snd_pcm_substream *substream)
 888{
 889        struct snd_pcm_runtime *runtime = substream->runtime;
 890        struct snd_cs46xx_pcm * cpcm = runtime->private_data;
 891        snd_pcm_indirect_playback_transfer(substream, &cpcm->pcm_rec, snd_cs46xx_pb_trans_copy);
 892        return 0;
 893}
 894
 895static void snd_cs46xx_cp_trans_copy(struct snd_pcm_substream *substream,
 896                                     struct snd_pcm_indirect *rec, size_t bytes)
 897{
 898        struct snd_cs46xx *chip = snd_pcm_substream_chip(substream);
 899        struct snd_pcm_runtime *runtime = substream->runtime;
 900        memcpy(runtime->dma_area + rec->sw_data,
 901               chip->capt.hw_buf.area + rec->hw_data, bytes);
 902}
 903
 904static int snd_cs46xx_capture_transfer(struct snd_pcm_substream *substream)
 905{
 906        struct snd_cs46xx *chip = snd_pcm_substream_chip(substream);
 907        snd_pcm_indirect_capture_transfer(substream, &chip->capt.pcm_rec, snd_cs46xx_cp_trans_copy);
 908        return 0;
 909}
 910
 911static snd_pcm_uframes_t snd_cs46xx_playback_direct_pointer(struct snd_pcm_substream *substream)
 912{
 913        struct snd_cs46xx *chip = snd_pcm_substream_chip(substream);
 914        size_t ptr;
 915        struct snd_cs46xx_pcm *cpcm = substream->runtime->private_data;
 916
 917        if (snd_BUG_ON(!cpcm->pcm_channel))
 918                return -ENXIO;
 919
 920#ifdef CONFIG_SND_CS46XX_NEW_DSP
 921        ptr = snd_cs46xx_peek(chip, (cpcm->pcm_channel->pcm_reader_scb->address + 2) << 2);
 922#else
 923        ptr = snd_cs46xx_peek(chip, BA1_PBA);
 924#endif
 925        ptr -= cpcm->hw_buf.addr;
 926        return ptr >> cpcm->shift;
 927}
 928
 929static snd_pcm_uframes_t snd_cs46xx_playback_indirect_pointer(struct snd_pcm_substream *substream)
 930{
 931        struct snd_cs46xx *chip = snd_pcm_substream_chip(substream);
 932        size_t ptr;
 933        struct snd_cs46xx_pcm *cpcm = substream->runtime->private_data;
 934
 935#ifdef CONFIG_SND_CS46XX_NEW_DSP
 936        if (snd_BUG_ON(!cpcm->pcm_channel))
 937                return -ENXIO;
 938        ptr = snd_cs46xx_peek(chip, (cpcm->pcm_channel->pcm_reader_scb->address + 2) << 2);
 939#else
 940        ptr = snd_cs46xx_peek(chip, BA1_PBA);
 941#endif
 942        ptr -= cpcm->hw_buf.addr;
 943        return snd_pcm_indirect_playback_pointer(substream, &cpcm->pcm_rec, ptr);
 944}
 945
 946static snd_pcm_uframes_t snd_cs46xx_capture_direct_pointer(struct snd_pcm_substream *substream)
 947{
 948        struct snd_cs46xx *chip = snd_pcm_substream_chip(substream);
 949        size_t ptr = snd_cs46xx_peek(chip, BA1_CBA) - chip->capt.hw_buf.addr;
 950        return ptr >> chip->capt.shift;
 951}
 952
 953static snd_pcm_uframes_t snd_cs46xx_capture_indirect_pointer(struct snd_pcm_substream *substream)
 954{
 955        struct snd_cs46xx *chip = snd_pcm_substream_chip(substream);
 956        size_t ptr = snd_cs46xx_peek(chip, BA1_CBA) - chip->capt.hw_buf.addr;
 957        return snd_pcm_indirect_capture_pointer(substream, &chip->capt.pcm_rec, ptr);
 958}
 959
 960static int snd_cs46xx_playback_trigger(struct snd_pcm_substream *substream,
 961                                       int cmd)
 962{
 963        struct snd_cs46xx *chip = snd_pcm_substream_chip(substream);
 964        /*struct snd_pcm_runtime *runtime = substream->runtime;*/
 965        int result = 0;
 966
 967#ifdef CONFIG_SND_CS46XX_NEW_DSP
 968        struct snd_cs46xx_pcm *cpcm = substream->runtime->private_data;
 969        if (! cpcm->pcm_channel) {
 970                return -ENXIO;
 971        }
 972#endif
 973        switch (cmd) {
 974        case SNDRV_PCM_TRIGGER_START:
 975        case SNDRV_PCM_TRIGGER_RESUME:
 976#ifdef CONFIG_SND_CS46XX_NEW_DSP
 977                /* magic value to unmute PCM stream  playback volume */
 978                snd_cs46xx_poke(chip, (cpcm->pcm_channel->pcm_reader_scb->address + 
 979                                       SCBVolumeCtrl) << 2, 0x80008000);
 980
 981                if (cpcm->pcm_channel->unlinked)
 982                        cs46xx_dsp_pcm_link(chip,cpcm->pcm_channel);
 983
 984                if (substream->runtime->periods != CS46XX_FRAGS)
 985                        snd_cs46xx_playback_transfer(substream);
 986#else
 987                spin_lock(&chip->reg_lock);
 988                if (substream->runtime->periods != CS46XX_FRAGS)
 989                        snd_cs46xx_playback_transfer(substream);
 990                { unsigned int tmp;
 991                tmp = snd_cs46xx_peek(chip, BA1_PCTL);
 992                tmp &= 0x0000ffff;
 993                snd_cs46xx_poke(chip, BA1_PCTL, chip->play_ctl | tmp);
 994                }
 995                spin_unlock(&chip->reg_lock);
 996#endif
 997                break;
 998        case SNDRV_PCM_TRIGGER_STOP:
 999        case SNDRV_PCM_TRIGGER_SUSPEND:
1000#ifdef CONFIG_SND_CS46XX_NEW_DSP
1001                /* magic mute channel */
1002                snd_cs46xx_poke(chip, (cpcm->pcm_channel->pcm_reader_scb->address + 
1003                                       SCBVolumeCtrl) << 2, 0xffffffff);
1004
1005                if (!cpcm->pcm_channel->unlinked)
1006                        cs46xx_dsp_pcm_unlink(chip,cpcm->pcm_channel);
1007#else
1008                spin_lock(&chip->reg_lock);
1009                { unsigned int tmp;
1010                tmp = snd_cs46xx_peek(chip, BA1_PCTL);
1011                tmp &= 0x0000ffff;
1012                snd_cs46xx_poke(chip, BA1_PCTL, tmp);
1013                }
1014                spin_unlock(&chip->reg_lock);
1015#endif
1016                break;
1017        default:
1018                result = -EINVAL;
1019                break;
1020        }
1021
1022        return result;
1023}
1024
1025static int snd_cs46xx_capture_trigger(struct snd_pcm_substream *substream,
1026                                      int cmd)
1027{
1028        struct snd_cs46xx *chip = snd_pcm_substream_chip(substream);
1029        unsigned int tmp;
1030        int result = 0;
1031
1032        spin_lock(&chip->reg_lock);
1033        switch (cmd) {
1034        case SNDRV_PCM_TRIGGER_START:
1035        case SNDRV_PCM_TRIGGER_RESUME:
1036                tmp = snd_cs46xx_peek(chip, BA1_CCTL);
1037                tmp &= 0xffff0000;
1038                snd_cs46xx_poke(chip, BA1_CCTL, chip->capt.ctl | tmp);
1039                break;
1040        case SNDRV_PCM_TRIGGER_STOP:
1041        case SNDRV_PCM_TRIGGER_SUSPEND:
1042                tmp = snd_cs46xx_peek(chip, BA1_CCTL);
1043                tmp &= 0xffff0000;
1044                snd_cs46xx_poke(chip, BA1_CCTL, tmp);
1045                break;
1046        default:
1047                result = -EINVAL;
1048                break;
1049        }
1050        spin_unlock(&chip->reg_lock);
1051
1052        return result;
1053}
1054
1055#ifdef CONFIG_SND_CS46XX_NEW_DSP
1056static int _cs46xx_adjust_sample_rate (struct snd_cs46xx *chip, struct snd_cs46xx_pcm *cpcm,
1057                                       int sample_rate) 
1058{
1059
1060        /* If PCMReaderSCB and SrcTaskSCB not created yet ... */
1061        if ( cpcm->pcm_channel == NULL) {
1062                cpcm->pcm_channel = cs46xx_dsp_create_pcm_channel (chip, sample_rate, 
1063                                                                   cpcm, cpcm->hw_buf.addr,cpcm->pcm_channel_id);
1064                if (cpcm->pcm_channel == NULL) {
1065                        dev_err(chip->card->dev,
1066                                "failed to create virtual PCM channel\n");
1067                        return -ENOMEM;
1068                }
1069                cpcm->pcm_channel->sample_rate = sample_rate;
1070        } else
1071        /* if sample rate is changed */
1072        if ((int)cpcm->pcm_channel->sample_rate != sample_rate) {
1073                int unlinked = cpcm->pcm_channel->unlinked;
1074                cs46xx_dsp_destroy_pcm_channel (chip,cpcm->pcm_channel);
1075
1076                if ( (cpcm->pcm_channel = cs46xx_dsp_create_pcm_channel (chip, sample_rate, cpcm, 
1077                                                                         cpcm->hw_buf.addr,
1078                                                                         cpcm->pcm_channel_id)) == NULL) {
1079                        dev_err(chip->card->dev,
1080                                "failed to re-create virtual PCM channel\n");
1081                        return -ENOMEM;
1082                }
1083
1084                if (!unlinked) cs46xx_dsp_pcm_link (chip,cpcm->pcm_channel);
1085                cpcm->pcm_channel->sample_rate = sample_rate;
1086        }
1087
1088        return 0;
1089}
1090#endif
1091
1092
1093static int snd_cs46xx_playback_hw_params(struct snd_pcm_substream *substream,
1094                                         struct snd_pcm_hw_params *hw_params)
1095{
1096        struct snd_pcm_runtime *runtime = substream->runtime;
1097        struct snd_cs46xx_pcm *cpcm;
1098        int err;
1099#ifdef CONFIG_SND_CS46XX_NEW_DSP
1100        struct snd_cs46xx *chip = snd_pcm_substream_chip(substream);
1101        int sample_rate = params_rate(hw_params);
1102        int period_size = params_period_bytes(hw_params);
1103#endif
1104        cpcm = runtime->private_data;
1105
1106#ifdef CONFIG_SND_CS46XX_NEW_DSP
1107        if (snd_BUG_ON(!sample_rate))
1108                return -ENXIO;
1109
1110        mutex_lock(&chip->spos_mutex);
1111
1112        if (_cs46xx_adjust_sample_rate (chip,cpcm,sample_rate)) {
1113                mutex_unlock(&chip->spos_mutex);
1114                return -ENXIO;
1115        }
1116
1117        snd_BUG_ON(!cpcm->pcm_channel);
1118        if (!cpcm->pcm_channel) {
1119                mutex_unlock(&chip->spos_mutex);
1120                return -ENXIO;
1121        }
1122
1123
1124        if (cs46xx_dsp_pcm_channel_set_period (chip,cpcm->pcm_channel,period_size)) {
1125                 mutex_unlock(&chip->spos_mutex);
1126                 return -EINVAL;
1127         }
1128
1129        dev_dbg(chip->card->dev,
1130                "period_size (%d), periods (%d) buffer_size(%d)\n",
1131                     period_size, params_periods(hw_params),
1132                     params_buffer_bytes(hw_params));
1133#endif
1134
1135        if (params_periods(hw_params) == CS46XX_FRAGS) {
1136                if (runtime->dma_area != cpcm->hw_buf.area)
1137                        snd_pcm_lib_free_pages(substream);
1138                runtime->dma_area = cpcm->hw_buf.area;
1139                runtime->dma_addr = cpcm->hw_buf.addr;
1140                runtime->dma_bytes = cpcm->hw_buf.bytes;
1141
1142
1143#ifdef CONFIG_SND_CS46XX_NEW_DSP
1144                if (cpcm->pcm_channel_id == DSP_PCM_MAIN_CHANNEL) {
1145                        substream->ops = &snd_cs46xx_playback_ops;
1146                } else if (cpcm->pcm_channel_id == DSP_PCM_REAR_CHANNEL) {
1147                        substream->ops = &snd_cs46xx_playback_rear_ops;
1148                } else if (cpcm->pcm_channel_id == DSP_PCM_CENTER_LFE_CHANNEL) {
1149                        substream->ops = &snd_cs46xx_playback_clfe_ops;
1150                } else if (cpcm->pcm_channel_id == DSP_IEC958_CHANNEL) {
1151                        substream->ops = &snd_cs46xx_playback_iec958_ops;
1152                } else {
1153                        snd_BUG();
1154                }
1155#else
1156                substream->ops = &snd_cs46xx_playback_ops;
1157#endif
1158
1159        } else {
1160                if (runtime->dma_area == cpcm->hw_buf.area) {
1161                        runtime->dma_area = NULL;
1162                        runtime->dma_addr = 0;
1163                        runtime->dma_bytes = 0;
1164                }
1165                if ((err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params))) < 0) {
1166#ifdef CONFIG_SND_CS46XX_NEW_DSP
1167                        mutex_unlock(&chip->spos_mutex);
1168#endif
1169                        return err;
1170                }
1171
1172#ifdef CONFIG_SND_CS46XX_NEW_DSP
1173                if (cpcm->pcm_channel_id == DSP_PCM_MAIN_CHANNEL) {
1174                        substream->ops = &snd_cs46xx_playback_indirect_ops;
1175                } else if (cpcm->pcm_channel_id == DSP_PCM_REAR_CHANNEL) {
1176                        substream->ops = &snd_cs46xx_playback_indirect_rear_ops;
1177                } else if (cpcm->pcm_channel_id == DSP_PCM_CENTER_LFE_CHANNEL) {
1178                        substream->ops = &snd_cs46xx_playback_indirect_clfe_ops;
1179                } else if (cpcm->pcm_channel_id == DSP_IEC958_CHANNEL) {
1180                        substream->ops = &snd_cs46xx_playback_indirect_iec958_ops;
1181                } else {
1182                        snd_BUG();
1183                }
1184#else
1185                substream->ops = &snd_cs46xx_playback_indirect_ops;
1186#endif
1187
1188        }
1189
1190#ifdef CONFIG_SND_CS46XX_NEW_DSP
1191        mutex_unlock(&chip->spos_mutex);
1192#endif
1193
1194        return 0;
1195}
1196
1197static int snd_cs46xx_playback_hw_free(struct snd_pcm_substream *substream)
1198{
1199        /*struct snd_cs46xx *chip = snd_pcm_substream_chip(substream);*/
1200        struct snd_pcm_runtime *runtime = substream->runtime;
1201        struct snd_cs46xx_pcm *cpcm;
1202
1203        cpcm = runtime->private_data;
1204
1205        /* if play_back open fails, then this function
1206           is called and cpcm can actually be NULL here */
1207        if (!cpcm) return -ENXIO;
1208
1209        if (runtime->dma_area != cpcm->hw_buf.area)
1210                snd_pcm_lib_free_pages(substream);
1211    
1212        runtime->dma_area = NULL;
1213        runtime->dma_addr = 0;
1214        runtime->dma_bytes = 0;
1215
1216        return 0;
1217}
1218
1219static int snd_cs46xx_playback_prepare(struct snd_pcm_substream *substream)
1220{
1221        unsigned int tmp;
1222        unsigned int pfie;
1223        struct snd_cs46xx *chip = snd_pcm_substream_chip(substream);
1224        struct snd_pcm_runtime *runtime = substream->runtime;
1225        struct snd_cs46xx_pcm *cpcm;
1226
1227        cpcm = runtime->private_data;
1228
1229#ifdef CONFIG_SND_CS46XX_NEW_DSP
1230        if (snd_BUG_ON(!cpcm->pcm_channel))
1231                return -ENXIO;
1232
1233        pfie = snd_cs46xx_peek(chip, (cpcm->pcm_channel->pcm_reader_scb->address + 1) << 2 );
1234        pfie &= ~0x0000f03f;
1235#else
1236        /* old dsp */
1237        pfie = snd_cs46xx_peek(chip, BA1_PFIE);
1238        pfie &= ~0x0000f03f;
1239#endif
1240
1241        cpcm->shift = 2;
1242        /* if to convert from stereo to mono */
1243        if (runtime->channels == 1) {
1244                cpcm->shift--;
1245                pfie |= 0x00002000;
1246        }
1247        /* if to convert from 8 bit to 16 bit */
1248        if (snd_pcm_format_width(runtime->format) == 8) {
1249                cpcm->shift--;
1250                pfie |= 0x00001000;
1251        }
1252        /* if to convert to unsigned */
1253        if (snd_pcm_format_unsigned(runtime->format))
1254                pfie |= 0x00008000;
1255
1256        /* Never convert byte order when sample stream is 8 bit */
1257        if (snd_pcm_format_width(runtime->format) != 8) {
1258                /* convert from big endian to little endian */
1259                if (snd_pcm_format_big_endian(runtime->format))
1260                        pfie |= 0x00004000;
1261        }
1262        
1263        memset(&cpcm->pcm_rec, 0, sizeof(cpcm->pcm_rec));
1264        cpcm->pcm_rec.sw_buffer_size = snd_pcm_lib_buffer_bytes(substream);
1265        cpcm->pcm_rec.hw_buffer_size = runtime->period_size * CS46XX_FRAGS << cpcm->shift;
1266
1267#ifdef CONFIG_SND_CS46XX_NEW_DSP
1268
1269        tmp = snd_cs46xx_peek(chip, (cpcm->pcm_channel->pcm_reader_scb->address) << 2);
1270        tmp &= ~0x000003ff;
1271        tmp |= (4 << cpcm->shift) - 1;
1272        /* playback transaction count register */
1273        snd_cs46xx_poke(chip, (cpcm->pcm_channel->pcm_reader_scb->address) << 2, tmp);
1274
1275        /* playback format && interrupt enable */
1276        snd_cs46xx_poke(chip, (cpcm->pcm_channel->pcm_reader_scb->address + 1) << 2, pfie | cpcm->pcm_channel->pcm_slot);
1277#else
1278        snd_cs46xx_poke(chip, BA1_PBA, cpcm->hw_buf.addr);
1279        tmp = snd_cs46xx_peek(chip, BA1_PDTC);
1280        tmp &= ~0x000003ff;
1281        tmp |= (4 << cpcm->shift) - 1;
1282        snd_cs46xx_poke(chip, BA1_PDTC, tmp);
1283        snd_cs46xx_poke(chip, BA1_PFIE, pfie);
1284        snd_cs46xx_set_play_sample_rate(chip, runtime->rate);
1285#endif
1286
1287        return 0;
1288}
1289
1290static int snd_cs46xx_capture_hw_params(struct snd_pcm_substream *substream,
1291                                        struct snd_pcm_hw_params *hw_params)
1292{
1293        struct snd_cs46xx *chip = snd_pcm_substream_chip(substream);
1294        struct snd_pcm_runtime *runtime = substream->runtime;
1295        int err;
1296
1297#ifdef CONFIG_SND_CS46XX_NEW_DSP
1298        cs46xx_dsp_pcm_ostream_set_period (chip, params_period_bytes(hw_params));
1299#endif
1300        if (runtime->periods == CS46XX_FRAGS) {
1301                if (runtime->dma_area != chip->capt.hw_buf.area)
1302                        snd_pcm_lib_free_pages(substream);
1303                runtime->dma_area = chip->capt.hw_buf.area;
1304                runtime->dma_addr = chip->capt.hw_buf.addr;
1305                runtime->dma_bytes = chip->capt.hw_buf.bytes;
1306                substream->ops = &snd_cs46xx_capture_ops;
1307        } else {
1308                if (runtime->dma_area == chip->capt.hw_buf.area) {
1309                        runtime->dma_area = NULL;
1310                        runtime->dma_addr = 0;
1311                        runtime->dma_bytes = 0;
1312                }
1313                if ((err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params))) < 0)
1314                        return err;
1315                substream->ops = &snd_cs46xx_capture_indirect_ops;
1316        }
1317
1318        return 0;
1319}
1320
1321static int snd_cs46xx_capture_hw_free(struct snd_pcm_substream *substream)
1322{
1323        struct snd_cs46xx *chip = snd_pcm_substream_chip(substream);
1324        struct snd_pcm_runtime *runtime = substream->runtime;
1325
1326        if (runtime->dma_area != chip->capt.hw_buf.area)
1327                snd_pcm_lib_free_pages(substream);
1328        runtime->dma_area = NULL;
1329        runtime->dma_addr = 0;
1330        runtime->dma_bytes = 0;
1331
1332        return 0;
1333}
1334
1335static int snd_cs46xx_capture_prepare(struct snd_pcm_substream *substream)
1336{
1337        struct snd_cs46xx *chip = snd_pcm_substream_chip(substream);
1338        struct snd_pcm_runtime *runtime = substream->runtime;
1339
1340        snd_cs46xx_poke(chip, BA1_CBA, chip->capt.hw_buf.addr);
1341        chip->capt.shift = 2;
1342        memset(&chip->capt.pcm_rec, 0, sizeof(chip->capt.pcm_rec));
1343        chip->capt.pcm_rec.sw_buffer_size = snd_pcm_lib_buffer_bytes(substream);
1344        chip->capt.pcm_rec.hw_buffer_size = runtime->period_size * CS46XX_FRAGS << 2;
1345        snd_cs46xx_set_capture_sample_rate(chip, runtime->rate);
1346
1347        return 0;
1348}
1349
1350static irqreturn_t snd_cs46xx_interrupt(int irq, void *dev_id)
1351{
1352        struct snd_cs46xx *chip = dev_id;
1353        u32 status1;
1354#ifdef CONFIG_SND_CS46XX_NEW_DSP
1355        struct dsp_spos_instance * ins = chip->dsp_spos_instance;
1356        u32 status2;
1357        int i;
1358        struct snd_cs46xx_pcm *cpcm = NULL;
1359#endif
1360
1361        /*
1362         *  Read the Interrupt Status Register to clear the interrupt
1363         */
1364        status1 = snd_cs46xx_peekBA0(chip, BA0_HISR);
1365        if ((status1 & 0x7fffffff) == 0) {
1366                snd_cs46xx_pokeBA0(chip, BA0_HICR, HICR_CHGM | HICR_IEV);
1367                return IRQ_NONE;
1368        }
1369
1370#ifdef CONFIG_SND_CS46XX_NEW_DSP
1371        status2 = snd_cs46xx_peekBA0(chip, BA0_HSR0);
1372
1373        for (i = 0; i < DSP_MAX_PCM_CHANNELS; ++i) {
1374                if (i <= 15) {
1375                        if ( status1 & (1 << i) ) {
1376                                if (i == CS46XX_DSP_CAPTURE_CHANNEL) {
1377                                        if (chip->capt.substream)
1378                                                snd_pcm_period_elapsed(chip->capt.substream);
1379                                } else {
1380                                        if (ins->pcm_channels[i].active &&
1381                                            ins->pcm_channels[i].private_data &&
1382                                            !ins->pcm_channels[i].unlinked) {
1383                                                cpcm = ins->pcm_channels[i].private_data;
1384                                                snd_pcm_period_elapsed(cpcm->substream);
1385                                        }
1386                                }
1387                        }
1388                } else {
1389                        if ( status2 & (1 << (i - 16))) {
1390                                if (ins->pcm_channels[i].active && 
1391                                    ins->pcm_channels[i].private_data &&
1392                                    !ins->pcm_channels[i].unlinked) {
1393                                        cpcm = ins->pcm_channels[i].private_data;
1394                                        snd_pcm_period_elapsed(cpcm->substream);
1395                                }
1396                        }
1397                }
1398        }
1399
1400#else
1401        /* old dsp */
1402        if ((status1 & HISR_VC0) && chip->playback_pcm) {
1403                if (chip->playback_pcm->substream)
1404                        snd_pcm_period_elapsed(chip->playback_pcm->substream);
1405        }
1406        if ((status1 & HISR_VC1) && chip->pcm) {
1407                if (chip->capt.substream)
1408                        snd_pcm_period_elapsed(chip->capt.substream);
1409        }
1410#endif
1411
1412        if ((status1 & HISR_MIDI) && chip->rmidi) {
1413                unsigned char c;
1414                
1415                spin_lock(&chip->reg_lock);
1416                while ((snd_cs46xx_peekBA0(chip, BA0_MIDSR) & MIDSR_RBE) == 0) {
1417                        c = snd_cs46xx_peekBA0(chip, BA0_MIDRP);
1418                        if ((chip->midcr & MIDCR_RIE) == 0)
1419                                continue;
1420                        snd_rawmidi_receive(chip->midi_input, &c, 1);
1421                }
1422                while ((snd_cs46xx_peekBA0(chip, BA0_MIDSR) & MIDSR_TBF) == 0) {
1423                        if ((chip->midcr & MIDCR_TIE) == 0)
1424                                break;
1425                        if (snd_rawmidi_transmit(chip->midi_output, &c, 1) != 1) {
1426                                chip->midcr &= ~MIDCR_TIE;
1427                                snd_cs46xx_pokeBA0(chip, BA0_MIDCR, chip->midcr);
1428                                break;
1429                        }
1430                        snd_cs46xx_pokeBA0(chip, BA0_MIDWP, c);
1431                }
1432                spin_unlock(&chip->reg_lock);
1433        }
1434        /*
1435         *  EOI to the PCI part....reenables interrupts
1436         */
1437        snd_cs46xx_pokeBA0(chip, BA0_HICR, HICR_CHGM | HICR_IEV);
1438
1439        return IRQ_HANDLED;
1440}
1441
1442static struct snd_pcm_hardware snd_cs46xx_playback =
1443{
1444        .info =                 (SNDRV_PCM_INFO_MMAP |
1445                                 SNDRV_PCM_INFO_INTERLEAVED | 
1446                                 SNDRV_PCM_INFO_BLOCK_TRANSFER /*|*/
1447                                 /*SNDRV_PCM_INFO_RESUME*/),
1448        .formats =              (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U8 |
1449                                 SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE |
1450                                 SNDRV_PCM_FMTBIT_U16_LE | SNDRV_PCM_FMTBIT_U16_BE),
1451        .rates =                SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,
1452        .rate_min =             5500,
1453        .rate_max =             48000,
1454        .channels_min =         1,
1455        .channels_max =         2,
1456        .buffer_bytes_max =     (256 * 1024),
1457        .period_bytes_min =     CS46XX_MIN_PERIOD_SIZE,
1458        .period_bytes_max =     CS46XX_MAX_PERIOD_SIZE,
1459        .periods_min =          CS46XX_FRAGS,
1460        .periods_max =          1024,
1461        .fifo_size =            0,
1462};
1463
1464static struct snd_pcm_hardware snd_cs46xx_capture =
1465{
1466        .info =                 (SNDRV_PCM_INFO_MMAP |
1467                                 SNDRV_PCM_INFO_INTERLEAVED |
1468                                 SNDRV_PCM_INFO_BLOCK_TRANSFER /*|*/
1469                                 /*SNDRV_PCM_INFO_RESUME*/),
1470        .formats =              SNDRV_PCM_FMTBIT_S16_LE,
1471        .rates =                SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,
1472        .rate_min =             5500,
1473        .rate_max =             48000,
1474        .channels_min =         2,
1475        .channels_max =         2,
1476        .buffer_bytes_max =     (256 * 1024),
1477        .period_bytes_min =     CS46XX_MIN_PERIOD_SIZE,
1478        .period_bytes_max =     CS46XX_MAX_PERIOD_SIZE,
1479        .periods_min =          CS46XX_FRAGS,
1480        .periods_max =          1024,
1481        .fifo_size =            0,
1482};
1483
1484#ifdef CONFIG_SND_CS46XX_NEW_DSP
1485
1486static unsigned int period_sizes[] = { 32, 64, 128, 256, 512, 1024, 2048 };
1487
1488static struct snd_pcm_hw_constraint_list hw_constraints_period_sizes = {
1489        .count = ARRAY_SIZE(period_sizes),
1490        .list = period_sizes,
1491        .mask = 0
1492};
1493
1494#endif
1495
1496static void snd_cs46xx_pcm_free_substream(struct snd_pcm_runtime *runtime)
1497{
1498        kfree(runtime->private_data);
1499}
1500
1501static int _cs46xx_playback_open_channel (struct snd_pcm_substream *substream,int pcm_channel_id)
1502{
1503        struct snd_cs46xx *chip = snd_pcm_substream_chip(substream);
1504        struct snd_cs46xx_pcm * cpcm;
1505        struct snd_pcm_runtime *runtime = substream->runtime;
1506
1507        cpcm = kzalloc(sizeof(*cpcm), GFP_KERNEL);
1508        if (cpcm == NULL)
1509                return -ENOMEM;
1510        if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(chip->pci),
1511                                PAGE_SIZE, &cpcm->hw_buf) < 0) {
1512                kfree(cpcm);
1513                return -ENOMEM;
1514        }
1515
1516        runtime->hw = snd_cs46xx_playback;
1517        runtime->private_data = cpcm;
1518        runtime->private_free = snd_cs46xx_pcm_free_substream;
1519
1520        cpcm->substream = substream;
1521#ifdef CONFIG_SND_CS46XX_NEW_DSP
1522        mutex_lock(&chip->spos_mutex);
1523        cpcm->pcm_channel = NULL; 
1524        cpcm->pcm_channel_id = pcm_channel_id;
1525
1526
1527        snd_pcm_hw_constraint_list(runtime, 0,
1528                                   SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 
1529                                   &hw_constraints_period_sizes);
1530
1531        mutex_unlock(&chip->spos_mutex);
1532#else
1533        chip->playback_pcm = cpcm; /* HACK */
1534#endif
1535
1536        if (chip->accept_valid)
1537                substream->runtime->hw.info |= SNDRV_PCM_INFO_MMAP_VALID;
1538        chip->active_ctrl(chip, 1);
1539
1540        return 0;
1541}
1542
1543static int snd_cs46xx_playback_open(struct snd_pcm_substream *substream)
1544{
1545        dev_dbg(substream->pcm->card->dev, "open front channel\n");
1546        return _cs46xx_playback_open_channel(substream,DSP_PCM_MAIN_CHANNEL);
1547}
1548
1549#ifdef CONFIG_SND_CS46XX_NEW_DSP
1550static int snd_cs46xx_playback_open_rear(struct snd_pcm_substream *substream)
1551{
1552        dev_dbg(substream->pcm->card->dev, "open rear channel\n");
1553        return _cs46xx_playback_open_channel(substream,DSP_PCM_REAR_CHANNEL);
1554}
1555
1556static int snd_cs46xx_playback_open_clfe(struct snd_pcm_substream *substream)
1557{
1558        dev_dbg(substream->pcm->card->dev, "open center - LFE channel\n");
1559        return _cs46xx_playback_open_channel(substream,DSP_PCM_CENTER_LFE_CHANNEL);
1560}
1561
1562static int snd_cs46xx_playback_open_iec958(struct snd_pcm_substream *substream)
1563{
1564        struct snd_cs46xx *chip = snd_pcm_substream_chip(substream);
1565
1566        dev_dbg(chip->card->dev, "open raw iec958 channel\n");
1567
1568        mutex_lock(&chip->spos_mutex);
1569        cs46xx_iec958_pre_open (chip);
1570        mutex_unlock(&chip->spos_mutex);
1571
1572        return _cs46xx_playback_open_channel(substream,DSP_IEC958_CHANNEL);
1573}
1574
1575static int snd_cs46xx_playback_close(struct snd_pcm_substream *substream);
1576
1577static int snd_cs46xx_playback_close_iec958(struct snd_pcm_substream *substream)
1578{
1579        int err;
1580        struct snd_cs46xx *chip = snd_pcm_substream_chip(substream);
1581  
1582        dev_dbg(chip->card->dev, "close raw iec958 channel\n");
1583
1584        err = snd_cs46xx_playback_close(substream);
1585
1586        mutex_lock(&chip->spos_mutex);
1587        cs46xx_iec958_post_close (chip);
1588        mutex_unlock(&chip->spos_mutex);
1589
1590        return err;
1591}
1592#endif
1593
1594static int snd_cs46xx_capture_open(struct snd_pcm_substream *substream)
1595{
1596        struct snd_cs46xx *chip = snd_pcm_substream_chip(substream);
1597
1598        if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(chip->pci),
1599                                PAGE_SIZE, &chip->capt.hw_buf) < 0)
1600                return -ENOMEM;
1601        chip->capt.substream = substream;
1602        substream->runtime->hw = snd_cs46xx_capture;
1603
1604        if (chip->accept_valid)
1605                substream->runtime->hw.info |= SNDRV_PCM_INFO_MMAP_VALID;
1606
1607        chip->active_ctrl(chip, 1);
1608
1609#ifdef CONFIG_SND_CS46XX_NEW_DSP
1610        snd_pcm_hw_constraint_list(substream->runtime, 0,
1611                                   SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 
1612                                   &hw_constraints_period_sizes);
1613#endif
1614        return 0;
1615}
1616
1617static int snd_cs46xx_playback_close(struct snd_pcm_substream *substream)
1618{
1619        struct snd_cs46xx *chip = snd_pcm_substream_chip(substream);
1620        struct snd_pcm_runtime *runtime = substream->runtime;
1621        struct snd_cs46xx_pcm * cpcm;
1622
1623        cpcm = runtime->private_data;
1624
1625        /* when playback_open fails, then cpcm can be NULL */
1626        if (!cpcm) return -ENXIO;
1627
1628#ifdef CONFIG_SND_CS46XX_NEW_DSP
1629        mutex_lock(&chip->spos_mutex);
1630        if (cpcm->pcm_channel) {
1631                cs46xx_dsp_destroy_pcm_channel(chip,cpcm->pcm_channel);
1632                cpcm->pcm_channel = NULL;
1633        }
1634        mutex_unlock(&chip->spos_mutex);
1635#else
1636        chip->playback_pcm = NULL;
1637#endif
1638
1639        cpcm->substream = NULL;
1640        snd_dma_free_pages(&cpcm->hw_buf);
1641        chip->active_ctrl(chip, -1);
1642
1643        return 0;
1644}
1645
1646static int snd_cs46xx_capture_close(struct snd_pcm_substream *substream)
1647{
1648        struct snd_cs46xx *chip = snd_pcm_substream_chip(substream);
1649
1650        chip->capt.substream = NULL;
1651        snd_dma_free_pages(&chip->capt.hw_buf);
1652        chip->active_ctrl(chip, -1);
1653
1654        return 0;
1655}
1656
1657#ifdef CONFIG_SND_CS46XX_NEW_DSP
1658static struct snd_pcm_ops snd_cs46xx_playback_rear_ops = {
1659        .open =                 snd_cs46xx_playback_open_rear,
1660        .close =                snd_cs46xx_playback_close,
1661        .ioctl =                snd_pcm_lib_ioctl,
1662        .hw_params =            snd_cs46xx_playback_hw_params,
1663        .hw_free =              snd_cs46xx_playback_hw_free,
1664        .prepare =              snd_cs46xx_playback_prepare,
1665        .trigger =              snd_cs46xx_playback_trigger,
1666        .pointer =              snd_cs46xx_playback_direct_pointer,
1667};
1668
1669static struct snd_pcm_ops snd_cs46xx_playback_indirect_rear_ops = {
1670        .open =                 snd_cs46xx_playback_open_rear,
1671        .close =                snd_cs46xx_playback_close,
1672        .ioctl =                snd_pcm_lib_ioctl,
1673        .hw_params =            snd_cs46xx_playback_hw_params,
1674        .hw_free =              snd_cs46xx_playback_hw_free,
1675        .prepare =              snd_cs46xx_playback_prepare,
1676        .trigger =              snd_cs46xx_playback_trigger,
1677        .pointer =              snd_cs46xx_playback_indirect_pointer,
1678        .ack =                  snd_cs46xx_playback_transfer,
1679};
1680
1681static struct snd_pcm_ops snd_cs46xx_playback_clfe_ops = {
1682        .open =                 snd_cs46xx_playback_open_clfe,
1683        .close =                snd_cs46xx_playback_close,
1684        .ioctl =                snd_pcm_lib_ioctl,
1685        .hw_params =            snd_cs46xx_playback_hw_params,
1686        .hw_free =              snd_cs46xx_playback_hw_free,
1687        .prepare =              snd_cs46xx_playback_prepare,
1688        .trigger =              snd_cs46xx_playback_trigger,
1689        .pointer =              snd_cs46xx_playback_direct_pointer,
1690};
1691
1692static struct snd_pcm_ops snd_cs46xx_playback_indirect_clfe_ops = {
1693        .open =                 snd_cs46xx_playback_open_clfe,
1694        .close =                snd_cs46xx_playback_close,
1695        .ioctl =                snd_pcm_lib_ioctl,
1696        .hw_params =            snd_cs46xx_playback_hw_params,
1697        .hw_free =              snd_cs46xx_playback_hw_free,
1698        .prepare =              snd_cs46xx_playback_prepare,
1699        .trigger =              snd_cs46xx_playback_trigger,
1700        .pointer =              snd_cs46xx_playback_indirect_pointer,
1701        .ack =                  snd_cs46xx_playback_transfer,
1702};
1703
1704static struct snd_pcm_ops snd_cs46xx_playback_iec958_ops = {
1705        .open =                 snd_cs46xx_playback_open_iec958,
1706        .close =                snd_cs46xx_playback_close_iec958,
1707        .ioctl =                snd_pcm_lib_ioctl,
1708        .hw_params =            snd_cs46xx_playback_hw_params,
1709        .hw_free =              snd_cs46xx_playback_hw_free,
1710        .prepare =              snd_cs46xx_playback_prepare,
1711        .trigger =              snd_cs46xx_playback_trigger,
1712        .pointer =              snd_cs46xx_playback_direct_pointer,
1713};
1714
1715static struct snd_pcm_ops snd_cs46xx_playback_indirect_iec958_ops = {
1716        .open =                 snd_cs46xx_playback_open_iec958,
1717        .close =                snd_cs46xx_playback_close_iec958,
1718        .ioctl =                snd_pcm_lib_ioctl,
1719        .hw_params =            snd_cs46xx_playback_hw_params,
1720        .hw_free =              snd_cs46xx_playback_hw_free,
1721        .prepare =              snd_cs46xx_playback_prepare,
1722        .trigger =              snd_cs46xx_playback_trigger,
1723        .pointer =              snd_cs46xx_playback_indirect_pointer,
1724        .ack =                  snd_cs46xx_playback_transfer,
1725};
1726
1727#endif
1728
1729static struct snd_pcm_ops snd_cs46xx_playback_ops = {
1730        .open =                 snd_cs46xx_playback_open,
1731        .close =                snd_cs46xx_playback_close,
1732        .ioctl =                snd_pcm_lib_ioctl,
1733        .hw_params =            snd_cs46xx_playback_hw_params,
1734        .hw_free =              snd_cs46xx_playback_hw_free,
1735        .prepare =              snd_cs46xx_playback_prepare,
1736        .trigger =              snd_cs46xx_playback_trigger,
1737        .pointer =              snd_cs46xx_playback_direct_pointer,
1738};
1739
1740static struct snd_pcm_ops snd_cs46xx_playback_indirect_ops = {
1741        .open =                 snd_cs46xx_playback_open,
1742        .close =                snd_cs46xx_playback_close,
1743        .ioctl =                snd_pcm_lib_ioctl,
1744        .hw_params =            snd_cs46xx_playback_hw_params,
1745        .hw_free =              snd_cs46xx_playback_hw_free,
1746        .prepare =              snd_cs46xx_playback_prepare,
1747        .trigger =              snd_cs46xx_playback_trigger,
1748        .pointer =              snd_cs46xx_playback_indirect_pointer,
1749        .ack =                  snd_cs46xx_playback_transfer,
1750};
1751
1752static struct snd_pcm_ops snd_cs46xx_capture_ops = {
1753        .open =                 snd_cs46xx_capture_open,
1754        .close =                snd_cs46xx_capture_close,
1755        .ioctl =                snd_pcm_lib_ioctl,
1756        .hw_params =            snd_cs46xx_capture_hw_params,
1757        .hw_free =              snd_cs46xx_capture_hw_free,
1758        .prepare =              snd_cs46xx_capture_prepare,
1759        .trigger =              snd_cs46xx_capture_trigger,
1760        .pointer =              snd_cs46xx_capture_direct_pointer,
1761};
1762
1763static struct snd_pcm_ops snd_cs46xx_capture_indirect_ops = {
1764        .open =                 snd_cs46xx_capture_open,
1765        .close =                snd_cs46xx_capture_close,
1766        .ioctl =                snd_pcm_lib_ioctl,
1767        .hw_params =            snd_cs46xx_capture_hw_params,
1768        .hw_free =              snd_cs46xx_capture_hw_free,
1769        .prepare =              snd_cs46xx_capture_prepare,
1770        .trigger =              snd_cs46xx_capture_trigger,
1771        .pointer =              snd_cs46xx_capture_indirect_pointer,
1772        .ack =                  snd_cs46xx_capture_transfer,
1773};
1774
1775#ifdef CONFIG_SND_CS46XX_NEW_DSP
1776#define MAX_PLAYBACK_CHANNELS   (DSP_MAX_PCM_CHANNELS - 1)
1777#else
1778#define MAX_PLAYBACK_CHANNELS   1
1779#endif
1780
1781int snd_cs46xx_pcm(struct snd_cs46xx *chip, int device, struct snd_pcm **rpcm)
1782{
1783        struct snd_pcm *pcm;
1784        int err;
1785
1786        if (rpcm)
1787                *rpcm = NULL;
1788        if ((err = snd_pcm_new(chip->card, "CS46xx", device, MAX_PLAYBACK_CHANNELS, 1, &pcm)) < 0)
1789                return err;
1790
1791        pcm->private_data = chip;
1792
1793        snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_cs46xx_playback_ops);
1794        snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_cs46xx_capture_ops);
1795
1796        /* global setup */
1797        pcm->info_flags = 0;
1798        strcpy(pcm->name, "CS46xx");
1799        chip->pcm = pcm;
1800
1801        snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
1802                                              snd_dma_pci_data(chip->pci), 64*1024, 256*1024);
1803
1804        if (rpcm)
1805                *rpcm = pcm;
1806
1807        return 0;
1808}
1809
1810
1811#ifdef CONFIG_SND_CS46XX_NEW_DSP
1812int snd_cs46xx_pcm_rear(struct snd_cs46xx *chip, int device,
1813                        struct snd_pcm **rpcm)
1814{
1815        struct snd_pcm *pcm;
1816        int err;
1817
1818        if (rpcm)
1819                *rpcm = NULL;
1820
1821        if ((err = snd_pcm_new(chip->card, "CS46xx - Rear", device, MAX_PLAYBACK_CHANNELS, 0, &pcm)) < 0)
1822                return err;
1823
1824        pcm->private_data = chip;
1825
1826        snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_cs46xx_playback_rear_ops);
1827
1828        /* global setup */
1829        pcm->info_flags = 0;
1830        strcpy(pcm->name, "CS46xx - Rear");
1831        chip->pcm_rear = pcm;
1832
1833        snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
1834                                              snd_dma_pci_data(chip->pci), 64*1024, 256*1024);
1835
1836        if (rpcm)
1837                *rpcm = pcm;
1838
1839        return 0;
1840}
1841
1842int snd_cs46xx_pcm_center_lfe(struct snd_cs46xx *chip, int device,
1843                              struct snd_pcm **rpcm)
1844{
1845        struct snd_pcm *pcm;
1846        int err;
1847
1848        if (rpcm)
1849                *rpcm = NULL;
1850
1851        if ((err = snd_pcm_new(chip->card, "CS46xx - Center LFE", device, MAX_PLAYBACK_CHANNELS, 0, &pcm)) < 0)
1852                return err;
1853
1854        pcm->private_data = chip;
1855
1856        snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_cs46xx_playback_clfe_ops);
1857
1858        /* global setup */
1859        pcm->info_flags = 0;
1860        strcpy(pcm->name, "CS46xx - Center LFE");
1861        chip->pcm_center_lfe = pcm;
1862
1863        snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
1864                                              snd_dma_pci_data(chip->pci), 64*1024, 256*1024);
1865
1866        if (rpcm)
1867                *rpcm = pcm;
1868
1869        return 0;
1870}
1871
1872int snd_cs46xx_pcm_iec958(struct snd_cs46xx *chip, int device,
1873                          struct snd_pcm **rpcm)
1874{
1875        struct snd_pcm *pcm;
1876        int err;
1877
1878        if (rpcm)
1879                *rpcm = NULL;
1880
1881        if ((err = snd_pcm_new(chip->card, "CS46xx - IEC958", device, 1, 0, &pcm)) < 0)
1882                return err;
1883
1884        pcm->private_data = chip;
1885
1886        snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_cs46xx_playback_iec958_ops);
1887
1888        /* global setup */
1889        pcm->info_flags = 0;
1890        strcpy(pcm->name, "CS46xx - IEC958");
1891        chip->pcm_rear = pcm;
1892
1893        snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
1894                                              snd_dma_pci_data(chip->pci), 64*1024, 256*1024);
1895
1896        if (rpcm)
1897                *rpcm = pcm;
1898
1899        return 0;
1900}
1901#endif
1902
1903/*
1904 *  Mixer routines
1905 */
1906static void snd_cs46xx_mixer_free_ac97_bus(struct snd_ac97_bus *bus)
1907{
1908        struct snd_cs46xx *chip = bus->private_data;
1909
1910        chip->ac97_bus = NULL;
1911}
1912
1913static void snd_cs46xx_mixer_free_ac97(struct snd_ac97 *ac97)
1914{
1915        struct snd_cs46xx *chip = ac97->private_data;
1916
1917        if (snd_BUG_ON(ac97 != chip->ac97[CS46XX_PRIMARY_CODEC_INDEX] &&
1918                       ac97 != chip->ac97[CS46XX_SECONDARY_CODEC_INDEX]))
1919                return;
1920
1921        if (ac97 == chip->ac97[CS46XX_PRIMARY_CODEC_INDEX]) {
1922                chip->ac97[CS46XX_PRIMARY_CODEC_INDEX] = NULL;
1923                chip->eapd_switch = NULL;
1924        }
1925        else
1926                chip->ac97[CS46XX_SECONDARY_CODEC_INDEX] = NULL;
1927}
1928
1929static int snd_cs46xx_vol_info(struct snd_kcontrol *kcontrol, 
1930                               struct snd_ctl_elem_info *uinfo)
1931{
1932        uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
1933        uinfo->count = 2;
1934        uinfo->value.integer.min = 0;
1935        uinfo->value.integer.max = 0x7fff;
1936        return 0;
1937}
1938
1939static int snd_cs46xx_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1940{
1941        struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol);
1942        int reg = kcontrol->private_value;
1943        unsigned int val = snd_cs46xx_peek(chip, reg);
1944        ucontrol->value.integer.value[0] = 0xffff - (val >> 16);
1945        ucontrol->value.integer.value[1] = 0xffff - (val & 0xffff);
1946        return 0;
1947}
1948
1949static int snd_cs46xx_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1950{
1951        struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol);
1952        int reg = kcontrol->private_value;
1953        unsigned int val = ((0xffff - ucontrol->value.integer.value[0]) << 16 | 
1954                            (0xffff - ucontrol->value.integer.value[1]));
1955        unsigned int old = snd_cs46xx_peek(chip, reg);
1956        int change = (old != val);
1957
1958        if (change) {
1959                snd_cs46xx_poke(chip, reg, val);
1960        }
1961
1962        return change;
1963}
1964
1965#ifdef CONFIG_SND_CS46XX_NEW_DSP
1966
1967static int snd_cs46xx_vol_dac_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1968{
1969        struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol);
1970
1971        ucontrol->value.integer.value[0] = chip->dsp_spos_instance->dac_volume_left;
1972        ucontrol->value.integer.value[1] = chip->dsp_spos_instance->dac_volume_right;
1973
1974        return 0;
1975}
1976
1977static int snd_cs46xx_vol_dac_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1978{
1979        struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol);
1980        int change = 0;
1981
1982        if (chip->dsp_spos_instance->dac_volume_right != ucontrol->value.integer.value[0] ||
1983            chip->dsp_spos_instance->dac_volume_left != ucontrol->value.integer.value[1]) {
1984                cs46xx_dsp_set_dac_volume(chip,
1985                                          ucontrol->value.integer.value[0],
1986                                          ucontrol->value.integer.value[1]);
1987                change = 1;
1988        }
1989
1990        return change;
1991}
1992
1993#if 0
1994static int snd_cs46xx_vol_iec958_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1995{
1996        struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol);
1997
1998        ucontrol->value.integer.value[0] = chip->dsp_spos_instance->spdif_input_volume_left;
1999        ucontrol->value.integer.value[1] = chip->dsp_spos_instance->spdif_input_volume_right;
2000        return 0;
2001}
2002
2003static int snd_cs46xx_vol_iec958_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
2004{
2005        struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol);
2006        int change = 0;
2007
2008        if (chip->dsp_spos_instance->spdif_input_volume_left  != ucontrol->value.integer.value[0] ||
2009            chip->dsp_spos_instance->spdif_input_volume_right!= ucontrol->value.integer.value[1]) {
2010                cs46xx_dsp_set_iec958_volume (chip,
2011                                              ucontrol->value.integer.value[0],
2012                                              ucontrol->value.integer.value[1]);
2013                change = 1;
2014        }
2015
2016        return change;
2017}
2018#endif
2019
2020#define snd_mixer_boolean_info          snd_ctl_boolean_mono_info
2021
2022static int snd_cs46xx_iec958_get(struct snd_kcontrol *kcontrol, 
2023                                 struct snd_ctl_elem_value *ucontrol)
2024{
2025        struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol);
2026        int reg = kcontrol->private_value;
2027
2028        if (reg == CS46XX_MIXER_SPDIF_OUTPUT_ELEMENT)
2029                ucontrol->value.integer.value[0] = (chip->dsp_spos_instance->spdif_status_out & DSP_SPDIF_STATUS_OUTPUT_ENABLED);
2030        else
2031                ucontrol->value.integer.value[0] = chip->dsp_spos_instance->spdif_status_in;
2032
2033        return 0;
2034}
2035
2036static int snd_cs46xx_iec958_put(struct snd_kcontrol *kcontrol, 
2037                                  struct snd_ctl_elem_value *ucontrol)
2038{
2039        struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol);
2040        int change, res;
2041
2042        switch (kcontrol->private_value) {
2043        case CS46XX_MIXER_SPDIF_OUTPUT_ELEMENT:
2044                mutex_lock(&chip->spos_mutex);
2045                change = (chip->dsp_spos_instance->spdif_status_out & DSP_SPDIF_STATUS_OUTPUT_ENABLED);
2046                if (ucontrol->value.integer.value[0] && !change) 
2047                        cs46xx_dsp_enable_spdif_out(chip);
2048                else if (change && !ucontrol->value.integer.value[0])
2049                        cs46xx_dsp_disable_spdif_out(chip);
2050
2051                res = (change != (chip->dsp_spos_instance->spdif_status_out & DSP_SPDIF_STATUS_OUTPUT_ENABLED));
2052                mutex_unlock(&chip->spos_mutex);
2053                break;
2054        case CS46XX_MIXER_SPDIF_INPUT_ELEMENT:
2055                change = chip->dsp_spos_instance->spdif_status_in;
2056                if (ucontrol->value.integer.value[0] && !change) {
2057                        cs46xx_dsp_enable_spdif_in(chip);
2058                        /* restore volume */
2059                }
2060                else if (change && !ucontrol->value.integer.value[0])
2061                        cs46xx_dsp_disable_spdif_in(chip);
2062                
2063                res = (change != chip->dsp_spos_instance->spdif_status_in);
2064                break;
2065        default:
2066                res = -EINVAL;
2067                snd_BUG(); /* should never happen ... */
2068        }
2069
2070        return res;
2071}
2072
2073static int snd_cs46xx_adc_capture_get(struct snd_kcontrol *kcontrol, 
2074                                      struct snd_ctl_elem_value *ucontrol)
2075{
2076        struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol);
2077        struct dsp_spos_instance * ins = chip->dsp_spos_instance;
2078
2079        if (ins->adc_input != NULL) 
2080                ucontrol->value.integer.value[0] = 1;
2081        else 
2082                ucontrol->value.integer.value[0] = 0;
2083        
2084        return 0;
2085}
2086
2087static int snd_cs46xx_adc_capture_put(struct snd_kcontrol *kcontrol, 
2088                                      struct snd_ctl_elem_value *ucontrol)
2089{
2090        struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol);
2091        struct dsp_spos_instance * ins = chip->dsp_spos_instance;
2092        int change = 0;
2093
2094        if (ucontrol->value.integer.value[0] && !ins->adc_input) {
2095                cs46xx_dsp_enable_adc_capture(chip);
2096                change = 1;
2097        } else  if (!ucontrol->value.integer.value[0] && ins->adc_input) {
2098                cs46xx_dsp_disable_adc_capture(chip);
2099                change = 1;
2100        }
2101        return change;
2102}
2103
2104static int snd_cs46xx_pcm_capture_get(struct snd_kcontrol *kcontrol, 
2105                                      struct snd_ctl_elem_value *ucontrol)
2106{
2107        struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol);
2108        struct dsp_spos_instance * ins = chip->dsp_spos_instance;
2109
2110        if (ins->pcm_input != NULL) 
2111                ucontrol->value.integer.value[0] = 1;
2112        else 
2113                ucontrol->value.integer.value[0] = 0;
2114
2115        return 0;
2116}
2117
2118
2119static int snd_cs46xx_pcm_capture_put(struct snd_kcontrol *kcontrol, 
2120                                      struct snd_ctl_elem_value *ucontrol)
2121{
2122        struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol);
2123        struct dsp_spos_instance * ins = chip->dsp_spos_instance;
2124        int change = 0;
2125
2126        if (ucontrol->value.integer.value[0] && !ins->pcm_input) {
2127                cs46xx_dsp_enable_pcm_capture(chip);
2128                change = 1;
2129        } else  if (!ucontrol->value.integer.value[0] && ins->pcm_input) {
2130                cs46xx_dsp_disable_pcm_capture(chip);
2131                change = 1;
2132        }
2133
2134        return change;
2135}
2136
2137static int snd_herc_spdif_select_get(struct snd_kcontrol *kcontrol, 
2138                                     struct snd_ctl_elem_value *ucontrol)
2139{
2140        struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol);
2141
2142        int val1 = snd_cs46xx_peekBA0(chip, BA0_EGPIODR);
2143
2144        if (val1 & EGPIODR_GPOE0)
2145                ucontrol->value.integer.value[0] = 1;
2146        else
2147                ucontrol->value.integer.value[0] = 0;
2148
2149        return 0;
2150}
2151
2152/*
2153 *      Game Theatre XP card - EGPIO[0] is used to select SPDIF input optical or coaxial.
2154 */ 
2155static int snd_herc_spdif_select_put(struct snd_kcontrol *kcontrol, 
2156                                       struct snd_ctl_elem_value *ucontrol)
2157{
2158        struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol);
2159        int val1 = snd_cs46xx_peekBA0(chip, BA0_EGPIODR);
2160        int val2 = snd_cs46xx_peekBA0(chip, BA0_EGPIOPTR);
2161
2162        if (ucontrol->value.integer.value[0]) {
2163                /* optical is default */
2164                snd_cs46xx_pokeBA0(chip, BA0_EGPIODR, 
2165                                   EGPIODR_GPOE0 | val1);  /* enable EGPIO0 output */
2166                snd_cs46xx_pokeBA0(chip, BA0_EGPIOPTR, 
2167                                   EGPIOPTR_GPPT0 | val2); /* open-drain on output */
2168        } else {
2169                /* coaxial */
2170                snd_cs46xx_pokeBA0(chip, BA0_EGPIODR,  val1 & ~EGPIODR_GPOE0); /* disable */
2171                snd_cs46xx_pokeBA0(chip, BA0_EGPIOPTR, val2 & ~EGPIOPTR_GPPT0); /* disable */
2172        }
2173
2174        /* checking diff from the EGPIO direction register 
2175           should be enough */
2176        return (val1 != (int)snd_cs46xx_peekBA0(chip, BA0_EGPIODR));
2177}
2178
2179
2180static int snd_cs46xx_spdif_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
2181{
2182        uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
2183        uinfo->count = 1;
2184        return 0;
2185}
2186
2187static int snd_cs46xx_spdif_default_get(struct snd_kcontrol *kcontrol,
2188                                        struct snd_ctl_elem_value *ucontrol)
2189{
2190        struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol);
2191        struct dsp_spos_instance * ins = chip->dsp_spos_instance;
2192
2193        mutex_lock(&chip->spos_mutex);
2194        ucontrol->value.iec958.status[0] = _wrap_all_bits((ins->spdif_csuv_default >> 24) & 0xff);
2195        ucontrol->value.iec958.status[1] = _wrap_all_bits((ins->spdif_csuv_default >> 16) & 0xff);
2196        ucontrol->value.iec958.status[2] = 0;
2197        ucontrol->value.iec958.status[3] = _wrap_all_bits((ins->spdif_csuv_default) & 0xff);
2198        mutex_unlock(&chip->spos_mutex);
2199
2200        return 0;
2201}
2202
2203static int snd_cs46xx_spdif_default_put(struct snd_kcontrol *kcontrol,
2204                                        struct snd_ctl_elem_value *ucontrol)
2205{
2206        struct snd_cs46xx * chip = snd_kcontrol_chip(kcontrol);
2207        struct dsp_spos_instance * ins = chip->dsp_spos_instance;
2208        unsigned int val;
2209        int change;
2210
2211        mutex_lock(&chip->spos_mutex);
2212        val = ((unsigned int)_wrap_all_bits(ucontrol->value.iec958.status[0]) << 24) |
2213                ((unsigned int)_wrap_all_bits(ucontrol->value.iec958.status[2]) << 16) |
2214                ((unsigned int)_wrap_all_bits(ucontrol->value.iec958.status[3]))  |
2215                /* left and right validity bit */
2216                (1 << 13) | (1 << 12);
2217
2218
2219        change = (unsigned int)ins->spdif_csuv_default != val;
2220        ins->spdif_csuv_default = val;
2221
2222        if ( !(ins->spdif_status_out & DSP_SPDIF_STATUS_PLAYBACK_OPEN) )
2223                cs46xx_poke_via_dsp (chip,SP_SPDOUT_CSUV,val);
2224
2225        mutex_unlock(&chip->spos_mutex);
2226
2227        return change;
2228}
2229
2230static int snd_cs46xx_spdif_mask_get(struct snd_kcontrol *kcontrol,
2231                                     struct snd_ctl_elem_value *ucontrol)
2232{
2233        ucontrol->value.iec958.status[0] = 0xff;
2234        ucontrol->value.iec958.status[1] = 0xff;
2235        ucontrol->value.iec958.status[2] = 0x00;
2236        ucontrol->value.iec958.status[3] = 0xff;
2237        return 0;
2238}
2239
2240static int snd_cs46xx_spdif_stream_get(struct snd_kcontrol *kcontrol,
2241                                         struct snd_ctl_elem_value *ucontrol)
2242{
2243        struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol);
2244        struct dsp_spos_instance * ins = chip->dsp_spos_instance;
2245
2246        mutex_lock(&chip->spos_mutex);
2247        ucontrol->value.iec958.status[0] = _wrap_all_bits((ins->spdif_csuv_stream >> 24) & 0xff);
2248        ucontrol->value.iec958.status[1] = _wrap_all_bits((ins->spdif_csuv_stream >> 16) & 0xff);
2249        ucontrol->value.iec958.status[2] = 0;
2250        ucontrol->value.iec958.status[3] = _wrap_all_bits((ins->spdif_csuv_stream) & 0xff);
2251        mutex_unlock(&chip->spos_mutex);
2252
2253        return 0;
2254}
2255
2256static int snd_cs46xx_spdif_stream_put(struct snd_kcontrol *kcontrol,
2257                                        struct snd_ctl_elem_value *ucontrol)
2258{
2259        struct snd_cs46xx * chip = snd_kcontrol_chip(kcontrol);
2260        struct dsp_spos_instance * ins = chip->dsp_spos_instance;
2261        unsigned int val;
2262        int change;
2263
2264        mutex_lock(&chip->spos_mutex);
2265        val = ((unsigned int)_wrap_all_bits(ucontrol->value.iec958.status[0]) << 24) |
2266                ((unsigned int)_wrap_all_bits(ucontrol->value.iec958.status[1]) << 16) |
2267                ((unsigned int)_wrap_all_bits(ucontrol->value.iec958.status[3])) |
2268                /* left and right validity bit */
2269                (1 << 13) | (1 << 12);
2270
2271
2272        change = ins->spdif_csuv_stream != val;
2273        ins->spdif_csuv_stream = val;
2274
2275        if ( ins->spdif_status_out & DSP_SPDIF_STATUS_PLAYBACK_OPEN )
2276                cs46xx_poke_via_dsp (chip,SP_SPDOUT_CSUV,val);
2277
2278        mutex_unlock(&chip->spos_mutex);
2279
2280        return change;
2281}
2282
2283#endif /* CONFIG_SND_CS46XX_NEW_DSP */
2284
2285
2286static struct snd_kcontrol_new snd_cs46xx_controls[] = {
2287{
2288        .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2289        .name = "DAC Volume",
2290        .info = snd_cs46xx_vol_info,
2291#ifndef CONFIG_SND_CS46XX_NEW_DSP
2292        .get = snd_cs46xx_vol_get,
2293        .put = snd_cs46xx_vol_put,
2294        .private_value = BA1_PVOL,
2295#else
2296        .get = snd_cs46xx_vol_dac_get,
2297        .put = snd_cs46xx_vol_dac_put,
2298#endif
2299},
2300
2301{
2302        .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2303        .name = "ADC Volume",
2304        .info = snd_cs46xx_vol_info,
2305        .get = snd_cs46xx_vol_get,
2306        .put = snd_cs46xx_vol_put,
2307#ifndef CONFIG_SND_CS46XX_NEW_DSP
2308        .private_value = BA1_CVOL,
2309#else
2310        .private_value = (VARIDECIMATE_SCB_ADDR + 0xE) << 2,
2311#endif
2312},
2313#ifdef CONFIG_SND_CS46XX_NEW_DSP
2314{
2315        .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2316        .name = "ADC Capture Switch",
2317        .info = snd_mixer_boolean_info,
2318        .get = snd_cs46xx_adc_capture_get,
2319        .put = snd_cs46xx_adc_capture_put
2320},
2321{
2322        .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2323        .name = "DAC Capture Switch",
2324        .info = snd_mixer_boolean_info,
2325        .get = snd_cs46xx_pcm_capture_get,
2326        .put = snd_cs46xx_pcm_capture_put
2327},
2328{
2329        .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2330        .name = SNDRV_CTL_NAME_IEC958("Output ",NONE,SWITCH),
2331        .info = snd_mixer_boolean_info,
2332        .get = snd_cs46xx_iec958_get,
2333        .put = snd_cs46xx_iec958_put,
2334        .private_value = CS46XX_MIXER_SPDIF_OUTPUT_ELEMENT,
2335},
2336{
2337        .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2338        .name = SNDRV_CTL_NAME_IEC958("Input ",NONE,SWITCH),
2339        .info = snd_mixer_boolean_info,
2340        .get = snd_cs46xx_iec958_get,
2341        .put = snd_cs46xx_iec958_put,
2342        .private_value = CS46XX_MIXER_SPDIF_INPUT_ELEMENT,
2343},
2344#if 0
2345/* Input IEC958 volume does not work for the moment. (Benny) */
2346{
2347        .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2348        .name = SNDRV_CTL_NAME_IEC958("Input ",NONE,VOLUME),
2349        .info = snd_cs46xx_vol_info,
2350        .get = snd_cs46xx_vol_iec958_get,
2351        .put = snd_cs46xx_vol_iec958_put,
2352        .private_value = (ASYNCRX_SCB_ADDR + 0xE) << 2,
2353},
2354#endif
2355{
2356        .iface = SNDRV_CTL_ELEM_IFACE_PCM,
2357        .name =  SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),
2358        .info =  snd_cs46xx_spdif_info,
2359        .get =   snd_cs46xx_spdif_default_get,
2360        .put =   snd_cs46xx_spdif_default_put,
2361},
2362{
2363        .iface = SNDRV_CTL_ELEM_IFACE_PCM,
2364        .name =  SNDRV_CTL_NAME_IEC958("",PLAYBACK,MASK),
2365        .info =  snd_cs46xx_spdif_info,
2366        .get =   snd_cs46xx_spdif_mask_get,
2367        .access = SNDRV_CTL_ELEM_ACCESS_READ
2368},
2369{
2370        .iface = SNDRV_CTL_ELEM_IFACE_PCM,
2371        .name =  SNDRV_CTL_NAME_IEC958("",PLAYBACK,PCM_STREAM),
2372        .info =  snd_cs46xx_spdif_info,
2373        .get =   snd_cs46xx_spdif_stream_get,
2374        .put =   snd_cs46xx_spdif_stream_put
2375},
2376
2377#endif
2378};
2379
2380#ifdef CONFIG_SND_CS46XX_NEW_DSP
2381/* set primary cs4294 codec into Extended Audio Mode */
2382static int snd_cs46xx_front_dup_get(struct snd_kcontrol *kcontrol, 
2383                                    struct snd_ctl_elem_value *ucontrol)
2384{
2385        struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol);
2386        unsigned short val;
2387        val = snd_ac97_read(chip->ac97[CS46XX_PRIMARY_CODEC_INDEX], AC97_CSR_ACMODE);
2388        ucontrol->value.integer.value[0] = (val & 0x200) ? 0 : 1;
2389        return 0;
2390}
2391
2392static int snd_cs46xx_front_dup_put(struct snd_kcontrol *kcontrol, 
2393                                    struct snd_ctl_elem_value *ucontrol)
2394{
2395        struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol);
2396        return snd_ac97_update_bits(chip->ac97[CS46XX_PRIMARY_CODEC_INDEX],
2397                                    AC97_CSR_ACMODE, 0x200,
2398                                    ucontrol->value.integer.value[0] ? 0 : 0x200);
2399}
2400
2401static struct snd_kcontrol_new snd_cs46xx_front_dup_ctl = {
2402        .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2403        .name = "Duplicate Front",
2404        .info = snd_mixer_boolean_info,
2405        .get = snd_cs46xx_front_dup_get,
2406        .put = snd_cs46xx_front_dup_put,
2407};
2408#endif
2409
2410#ifdef CONFIG_SND_CS46XX_NEW_DSP
2411/* Only available on the Hercules Game Theater XP soundcard */
2412static struct snd_kcontrol_new snd_hercules_controls[] = {
2413{
2414        .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2415        .name = "Optical/Coaxial SPDIF Input Switch",
2416        .info = snd_mixer_boolean_info,
2417        .get = snd_herc_spdif_select_get,
2418        .put = snd_herc_spdif_select_put,
2419},
2420};
2421
2422
2423static void snd_cs46xx_codec_reset (struct snd_ac97 * ac97)
2424{
2425        unsigned long end_time;
2426        int err;
2427
2428        /* reset to defaults */
2429        snd_ac97_write(ac97, AC97_RESET, 0);    
2430
2431        /* set the desired CODEC mode */
2432        if (ac97->num == CS46XX_PRIMARY_CODEC_INDEX) {
2433                dev_dbg(ac97->bus->card->dev, "CODEC1 mode %04x\n", 0x0);
2434                snd_cs46xx_ac97_write(ac97, AC97_CSR_ACMODE, 0x0);
2435        } else if (ac97->num == CS46XX_SECONDARY_CODEC_INDEX) {
2436                dev_dbg(ac97->bus->card->dev, "CODEC2 mode %04x\n", 0x3);
2437                snd_cs46xx_ac97_write(ac97, AC97_CSR_ACMODE, 0x3);
2438        } else {
2439                snd_BUG(); /* should never happen ... */
2440        }
2441
2442        udelay(50);
2443
2444        /* it's necessary to wait awhile until registers are accessible after RESET */
2445        /* because the PCM or MASTER volume registers can be modified, */
2446        /* the REC_GAIN register is used for tests */
2447        end_time = jiffies + HZ;
2448        do {
2449                unsigned short ext_mid;
2450    
2451                /* use preliminary reads to settle the communication */
2452                snd_ac97_read(ac97, AC97_RESET);
2453                snd_ac97_read(ac97, AC97_VENDOR_ID1);
2454                snd_ac97_read(ac97, AC97_VENDOR_ID2);
2455                /* modem? */
2456                ext_mid = snd_ac97_read(ac97, AC97_EXTENDED_MID);
2457                if (ext_mid != 0xffff && (ext_mid & 1) != 0)
2458                        return;
2459
2460                /* test if we can write to the record gain volume register */
2461                snd_ac97_write(ac97, AC97_REC_GAIN, 0x8a05);
2462                if ((err = snd_ac97_read(ac97, AC97_REC_GAIN)) == 0x8a05)
2463                        return;
2464
2465                msleep(10);
2466        } while (time_after_eq(end_time, jiffies));
2467
2468        dev_err(ac97->bus->card->dev,
2469                "CS46xx secondary codec doesn't respond!\n");
2470}
2471#endif
2472
2473static int cs46xx_detect_codec(struct snd_cs46xx *chip, int codec)
2474{
2475        int idx, err;
2476        struct snd_ac97_template ac97;
2477
2478        memset(&ac97, 0, sizeof(ac97));
2479        ac97.private_data = chip;
2480        ac97.private_free = snd_cs46xx_mixer_free_ac97;
2481        ac97.num = codec;
2482        if (chip->amplifier_ctrl == amp_voyetra)
2483                ac97.scaps = AC97_SCAP_INV_EAPD;
2484
2485        if (codec == CS46XX_SECONDARY_CODEC_INDEX) {
2486                snd_cs46xx_codec_write(chip, AC97_RESET, 0, codec);
2487                udelay(10);
2488                if (snd_cs46xx_codec_read(chip, AC97_RESET, codec) & 0x8000) {
2489                        dev_dbg(chip->card->dev,
2490                                "seconadry codec not present\n");
2491                        return -ENXIO;
2492                }
2493        }
2494
2495        snd_cs46xx_codec_write(chip, AC97_MASTER, 0x8000, codec);
2496        for (idx = 0; idx < 100; ++idx) {
2497                if (snd_cs46xx_codec_read(chip, AC97_MASTER, codec) == 0x8000) {
2498                        err = snd_ac97_mixer(chip->ac97_bus, &ac97, &chip->ac97[codec]);
2499                        return err;
2500                }
2501                msleep(10);
2502        }
2503        dev_dbg(chip->card->dev, "codec %d detection timeout\n", codec);
2504        return -ENXIO;
2505}
2506
2507int snd_cs46xx_mixer(struct snd_cs46xx *chip, int spdif_device)
2508{
2509        struct snd_card *card = chip->card;
2510        struct snd_ctl_elem_id id;
2511        int err;
2512        unsigned int idx;
2513        static struct snd_ac97_bus_ops ops = {
2514#ifdef CONFIG_SND_CS46XX_NEW_DSP
2515                .reset = snd_cs46xx_codec_reset,
2516#endif
2517                .write = snd_cs46xx_ac97_write,
2518                .read = snd_cs46xx_ac97_read,
2519        };
2520
2521        /* detect primary codec */
2522        chip->nr_ac97_codecs = 0;
2523        dev_dbg(chip->card->dev, "detecting primary codec\n");
2524        if ((err = snd_ac97_bus(card, 0, &ops, chip, &chip->ac97_bus)) < 0)
2525                return err;
2526        chip->ac97_bus->private_free = snd_cs46xx_mixer_free_ac97_bus;
2527
2528        if (cs46xx_detect_codec(chip, CS46XX_PRIMARY_CODEC_INDEX) < 0)
2529                return -ENXIO;
2530        chip->nr_ac97_codecs = 1;
2531
2532#ifdef CONFIG_SND_CS46XX_NEW_DSP
2533        dev_dbg(chip->card->dev, "detecting seconadry codec\n");
2534        /* try detect a secondary codec */
2535        if (! cs46xx_detect_codec(chip, CS46XX_SECONDARY_CODEC_INDEX))
2536                chip->nr_ac97_codecs = 2;
2537#endif /* CONFIG_SND_CS46XX_NEW_DSP */
2538
2539        /* add cs4630 mixer controls */
2540        for (idx = 0; idx < ARRAY_SIZE(snd_cs46xx_controls); idx++) {
2541                struct snd_kcontrol *kctl;
2542                kctl = snd_ctl_new1(&snd_cs46xx_controls[idx], chip);
2543                if (kctl && kctl->id.iface == SNDRV_CTL_ELEM_IFACE_PCM)
2544                        kctl->id.device = spdif_device;
2545                if ((err = snd_ctl_add(card, kctl)) < 0)
2546                        return err;
2547        }
2548
2549        /* get EAPD mixer switch (for voyetra hack) */
2550        memset(&id, 0, sizeof(id));
2551        id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
2552        strcpy(id.name, "External Amplifier");
2553        chip->eapd_switch = snd_ctl_find_id(chip->card, &id);
2554    
2555#ifdef CONFIG_SND_CS46XX_NEW_DSP
2556        if (chip->nr_ac97_codecs == 1) {
2557                unsigned int id2 = chip->ac97[CS46XX_PRIMARY_CODEC_INDEX]->id & 0xffff;
2558                if (id2 == 0x592b || id2 == 0x592d) {
2559                        err = snd_ctl_add(card, snd_ctl_new1(&snd_cs46xx_front_dup_ctl, chip));
2560                        if (err < 0)
2561                                return err;
2562                        snd_ac97_write_cache(chip->ac97[CS46XX_PRIMARY_CODEC_INDEX],
2563                                             AC97_CSR_ACMODE, 0x200);
2564                }
2565        }
2566        /* do soundcard specific mixer setup */
2567        if (chip->mixer_init) {
2568                dev_dbg(chip->card->dev, "calling chip->mixer_init(chip);\n");
2569                chip->mixer_init(chip);
2570        }
2571#endif
2572
2573        /* turn on amplifier */
2574        chip->amplifier_ctrl(chip, 1);
2575    
2576        return 0;
2577}
2578
2579/*
2580 *  RawMIDI interface
2581 */
2582
2583static void snd_cs46xx_midi_reset(struct snd_cs46xx *chip)
2584{
2585        snd_cs46xx_pokeBA0(chip, BA0_MIDCR, MIDCR_MRST);
2586        udelay(100);
2587        snd_cs46xx_pokeBA0(chip, BA0_MIDCR, chip->midcr);
2588}
2589
2590static int snd_cs46xx_midi_input_open(struct snd_rawmidi_substream *substream)
2591{
2592        struct snd_cs46xx *chip = substream->rmidi->private_data;
2593
2594        chip->active_ctrl(chip, 1);
2595        spin_lock_irq(&chip->reg_lock);
2596        chip->uartm |= CS46XX_MODE_INPUT;
2597        chip->midcr |= MIDCR_RXE;
2598        chip->midi_input = substream;
2599        if (!(chip->uartm & CS46XX_MODE_OUTPUT)) {
2600                snd_cs46xx_midi_reset(chip);
2601        } else {
2602                snd_cs46xx_pokeBA0(chip, BA0_MIDCR, chip->midcr);
2603        }
2604        spin_unlock_irq(&chip->reg_lock);
2605        return 0;
2606}
2607
2608static int snd_cs46xx_midi_input_close(struct snd_rawmidi_substream *substream)
2609{
2610        struct snd_cs46xx *chip = substream->rmidi->private_data;
2611
2612        spin_lock_irq(&chip->reg_lock);
2613        chip->midcr &= ~(MIDCR_RXE | MIDCR_RIE);
2614        chip->midi_input = NULL;
2615        if (!(chip->uartm & CS46XX_MODE_OUTPUT)) {
2616                snd_cs46xx_midi_reset(chip);
2617        } else {
2618                snd_cs46xx_pokeBA0(chip, BA0_MIDCR, chip->midcr);
2619        }
2620        chip->uartm &= ~CS46XX_MODE_INPUT;
2621        spin_unlock_irq(&chip->reg_lock);
2622        chip->active_ctrl(chip, -1);
2623        return 0;
2624}
2625
2626static int snd_cs46xx_midi_output_open(struct snd_rawmidi_substream *substream)
2627{
2628        struct snd_cs46xx *chip = substream->rmidi->private_data;
2629
2630        chip->active_ctrl(chip, 1);
2631
2632        spin_lock_irq(&chip->reg_lock);
2633        chip->uartm |= CS46XX_MODE_OUTPUT;
2634        chip->midcr |= MIDCR_TXE;
2635        chip->midi_output = substream;
2636        if (!(chip->uartm & CS46XX_MODE_INPUT)) {
2637                snd_cs46xx_midi_reset(chip);
2638        } else {
2639                snd_cs46xx_pokeBA0(chip, BA0_MIDCR, chip->midcr);
2640        }
2641        spin_unlock_irq(&chip->reg_lock);
2642        return 0;
2643}
2644
2645static int snd_cs46xx_midi_output_close(struct snd_rawmidi_substream *substream)
2646{
2647        struct snd_cs46xx *chip = substream->rmidi->private_data;
2648
2649        spin_lock_irq(&chip->reg_lock);
2650        chip->midcr &= ~(MIDCR_TXE | MIDCR_TIE);
2651        chip->midi_output = NULL;
2652        if (!(chip->uartm & CS46XX_MODE_INPUT)) {
2653                snd_cs46xx_midi_reset(chip);
2654        } else {
2655                snd_cs46xx_pokeBA0(chip, BA0_MIDCR, chip->midcr);
2656        }
2657        chip->uartm &= ~CS46XX_MODE_OUTPUT;
2658        spin_unlock_irq(&chip->reg_lock);
2659        chip->active_ctrl(chip, -1);
2660        return 0;
2661}
2662
2663static void snd_cs46xx_midi_input_trigger(struct snd_rawmidi_substream *substream, int up)
2664{
2665        unsigned long flags;
2666        struct snd_cs46xx *chip = substream->rmidi->private_data;
2667
2668        spin_lock_irqsave(&chip->reg_lock, flags);
2669        if (up) {
2670                if ((chip->midcr & MIDCR_RIE) == 0) {
2671                        chip->midcr |= MIDCR_RIE;
2672                        snd_cs46xx_pokeBA0(chip, BA0_MIDCR, chip->midcr);
2673                }
2674        } else {
2675                if (chip->midcr & MIDCR_RIE) {
2676                        chip->midcr &= ~MIDCR_RIE;
2677                        snd_cs46xx_pokeBA0(chip, BA0_MIDCR, chip->midcr);
2678                }
2679        }
2680        spin_unlock_irqrestore(&chip->reg_lock, flags);
2681}
2682
2683static void snd_cs46xx_midi_output_trigger(struct snd_rawmidi_substream *substream, int up)
2684{
2685        unsigned long flags;
2686        struct snd_cs46xx *chip = substream->rmidi->private_data;
2687        unsigned char byte;
2688
2689        spin_lock_irqsave(&chip->reg_lock, flags);
2690        if (up) {
2691                if ((chip->midcr & MIDCR_TIE) == 0) {
2692                        chip->midcr |= MIDCR_TIE;
2693                        /* fill UART FIFO buffer at first, and turn Tx interrupts only if necessary */
2694                        while ((chip->midcr & MIDCR_TIE) &&
2695                               (snd_cs46xx_peekBA0(chip, BA0_MIDSR) & MIDSR_TBF) == 0) {
2696                                if (snd_rawmidi_transmit(substream, &byte, 1) != 1) {
2697                                        chip->midcr &= ~MIDCR_TIE;
2698                                } else {
2699                                        snd_cs46xx_pokeBA0(chip, BA0_MIDWP, byte);
2700                                }
2701                        }
2702                        snd_cs46xx_pokeBA0(chip, BA0_MIDCR, chip->midcr);
2703                }
2704        } else {
2705                if (chip->midcr & MIDCR_TIE) {
2706                        chip->midcr &= ~MIDCR_TIE;
2707                        snd_cs46xx_pokeBA0(chip, BA0_MIDCR, chip->midcr);
2708                }
2709        }
2710        spin_unlock_irqrestore(&chip->reg_lock, flags);
2711}
2712
2713static struct snd_rawmidi_ops snd_cs46xx_midi_output =
2714{
2715        .open =         snd_cs46xx_midi_output_open,
2716        .close =        snd_cs46xx_midi_output_close,
2717        .trigger =      snd_cs46xx_midi_output_trigger,
2718};
2719
2720static struct snd_rawmidi_ops snd_cs46xx_midi_input =
2721{
2722        .open =         snd_cs46xx_midi_input_open,
2723        .close =        snd_cs46xx_midi_input_close,
2724        .trigger =      snd_cs46xx_midi_input_trigger,
2725};
2726
2727int snd_cs46xx_midi(struct snd_cs46xx *chip, int device, struct snd_rawmidi **rrawmidi)
2728{
2729        struct snd_rawmidi *rmidi;
2730        int err;
2731
2732        if (rrawmidi)
2733                *rrawmidi = NULL;
2734        if ((err = snd_rawmidi_new(chip->card, "CS46XX", device, 1, 1, &rmidi)) < 0)
2735                return err;
2736        strcpy(rmidi->name, "CS46XX");
2737        snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, &snd_cs46xx_midi_output);
2738        snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT, &snd_cs46xx_midi_input);
2739        rmidi->info_flags |= SNDRV_RAWMIDI_INFO_OUTPUT | SNDRV_RAWMIDI_INFO_INPUT | SNDRV_RAWMIDI_INFO_DUPLEX;
2740        rmidi->private_data = chip;
2741        chip->rmidi = rmidi;
2742        if (rrawmidi)
2743                *rrawmidi = NULL;
2744        return 0;
2745}
2746
2747
2748/*
2749 * gameport interface
2750 */
2751
2752#if defined(CONFIG_GAMEPORT) || (defined(MODULE) && defined(CONFIG_GAMEPORT_MODULE))
2753
2754static void snd_cs46xx_gameport_trigger(struct gameport *gameport)
2755{
2756        struct snd_cs46xx *chip = gameport_get_port_data(gameport);
2757
2758        if (snd_BUG_ON(!chip))
2759                return;
2760        snd_cs46xx_pokeBA0(chip, BA0_JSPT, 0xFF);  //outb(gameport->io, 0xFF);
2761}
2762
2763static unsigned char snd_cs46xx_gameport_read(struct gameport *gameport)
2764{
2765        struct snd_cs46xx *chip = gameport_get_port_data(gameport);
2766
2767        if (snd_BUG_ON(!chip))
2768                return 0;
2769        return snd_cs46xx_peekBA0(chip, BA0_JSPT); //inb(gameport->io);
2770}
2771
2772static int snd_cs46xx_gameport_cooked_read(struct gameport *gameport, int *axes, int *buttons)
2773{
2774        struct snd_cs46xx *chip = gameport_get_port_data(gameport);
2775        unsigned js1, js2, jst;
2776
2777        if (snd_BUG_ON(!chip))
2778                return 0;
2779
2780        js1 = snd_cs46xx_peekBA0(chip, BA0_JSC1);
2781        js2 = snd_cs46xx_peekBA0(chip, BA0_JSC2);
2782        jst = snd_cs46xx_peekBA0(chip, BA0_JSPT);
2783        
2784        *buttons = (~jst >> 4) & 0x0F; 
2785        
2786        axes[0] = ((js1 & JSC1_Y1V_MASK) >> JSC1_Y1V_SHIFT) & 0xFFFF;
2787        axes[1] = ((js1 & JSC1_X1V_MASK) >> JSC1_X1V_SHIFT) & 0xFFFF;
2788        axes[2] = ((js2 & JSC2_Y2V_MASK) >> JSC2_Y2V_SHIFT) & 0xFFFF;
2789        axes[3] = ((js2 & JSC2_X2V_MASK) >> JSC2_X2V_SHIFT) & 0xFFFF;
2790
2791        for(jst=0;jst<4;++jst)
2792                if(axes[jst]==0xFFFF) axes[jst] = -1;
2793        return 0;
2794}
2795
2796static int snd_cs46xx_gameport_open(struct gameport *gameport, int mode)
2797{
2798        switch (mode) {
2799        case GAMEPORT_MODE_COOKED:
2800                return 0;
2801        case GAMEPORT_MODE_RAW:
2802                return 0;
2803        default:
2804                return -1;
2805        }
2806        return 0;
2807}
2808
2809int snd_cs46xx_gameport(struct snd_cs46xx *chip)
2810{
2811        struct gameport *gp;
2812
2813        chip->gameport = gp = gameport_allocate_port();
2814        if (!gp) {
2815                dev_err(chip->card->dev,
2816                        "cannot allocate memory for gameport\n");
2817                return -ENOMEM;
2818        }
2819
2820        gameport_set_name(gp, "CS46xx Gameport");
2821        gameport_set_phys(gp, "pci%s/gameport0", pci_name(chip->pci));
2822        gameport_set_dev_parent(gp, &chip->pci->dev);
2823        gameport_set_port_data(gp, chip);
2824
2825        gp->open = snd_cs46xx_gameport_open;
2826        gp->read = snd_cs46xx_gameport_read;
2827        gp->trigger = snd_cs46xx_gameport_trigger;
2828        gp->cooked_read = snd_cs46xx_gameport_cooked_read;
2829
2830        snd_cs46xx_pokeBA0(chip, BA0_JSIO, 0xFF); // ?
2831        snd_cs46xx_pokeBA0(chip, BA0_JSCTL, JSCTL_SP_MEDIUM_SLOW);
2832
2833        gameport_register_port(gp);
2834
2835        return 0;
2836}
2837
2838static inline void snd_cs46xx_remove_gameport(struct snd_cs46xx *chip)
2839{
2840        if (chip->gameport) {
2841                gameport_unregister_port(chip->gameport);
2842                chip->gameport = NULL;
2843        }
2844}
2845#else
2846int snd_cs46xx_gameport(struct snd_cs46xx *chip) { return -ENOSYS; }
2847static inline void snd_cs46xx_remove_gameport(struct snd_cs46xx *chip) { }
2848#endif /* CONFIG_GAMEPORT */
2849
2850#ifdef CONFIG_PROC_FS
2851/*
2852 *  proc interface
2853 */
2854
2855static ssize_t snd_cs46xx_io_read(struct snd_info_entry *entry,
2856                                  void *file_private_data,
2857                                  struct file *file, char __user *buf,
2858                                  size_t count, loff_t pos)
2859{
2860        struct snd_cs46xx_region *region = entry->private_data;
2861        
2862        if (copy_to_user_fromio(buf, region->remap_addr + pos, count))
2863                return -EFAULT;
2864        return count;
2865}
2866
2867static struct snd_info_entry_ops snd_cs46xx_proc_io_ops = {
2868        .read = snd_cs46xx_io_read,
2869};
2870
2871static int snd_cs46xx_proc_init(struct snd_card *card, struct snd_cs46xx *chip)
2872{
2873        struct snd_info_entry *entry;
2874        int idx;
2875        
2876        for (idx = 0; idx < 5; idx++) {
2877                struct snd_cs46xx_region *region = &chip->region.idx[idx];
2878                if (! snd_card_proc_new(card, region->name, &entry)) {
2879                        entry->content = SNDRV_INFO_CONTENT_DATA;
2880                        entry->private_data = chip;
2881                        entry->c.ops = &snd_cs46xx_proc_io_ops;
2882                        entry->size = region->size;
2883                        entry->mode = S_IFREG | S_IRUSR;
2884                }
2885        }
2886#ifdef CONFIG_SND_CS46XX_NEW_DSP
2887        cs46xx_dsp_proc_init(card, chip);
2888#endif
2889        return 0;
2890}
2891
2892static int snd_cs46xx_proc_done(struct snd_cs46xx *chip)
2893{
2894#ifdef CONFIG_SND_CS46XX_NEW_DSP
2895        cs46xx_dsp_proc_done(chip);
2896#endif
2897        return 0;
2898}
2899#else /* !CONFIG_PROC_FS */
2900#define snd_cs46xx_proc_init(card, chip)
2901#define snd_cs46xx_proc_done(chip)
2902#endif
2903
2904/*
2905 * stop the h/w
2906 */
2907static void snd_cs46xx_hw_stop(struct snd_cs46xx *chip)
2908{
2909        unsigned int tmp;
2910
2911        tmp = snd_cs46xx_peek(chip, BA1_PFIE);
2912        tmp &= ~0x0000f03f;
2913        tmp |=  0x00000010;
2914        snd_cs46xx_poke(chip, BA1_PFIE, tmp);   /* playback interrupt disable */
2915
2916        tmp = snd_cs46xx_peek(chip, BA1_CIE);
2917        tmp &= ~0x0000003f;
2918        tmp |=  0x00000011;
2919        snd_cs46xx_poke(chip, BA1_CIE, tmp);    /* capture interrupt disable */
2920
2921        /*
2922         *  Stop playback DMA.
2923         */
2924        tmp = snd_cs46xx_peek(chip, BA1_PCTL);
2925        snd_cs46xx_poke(chip, BA1_PCTL, tmp & 0x0000ffff);
2926
2927        /*
2928         *  Stop capture DMA.
2929         */
2930        tmp = snd_cs46xx_peek(chip, BA1_CCTL);
2931        snd_cs46xx_poke(chip, BA1_CCTL, tmp & 0xffff0000);
2932
2933        /*
2934         *  Reset the processor.
2935         */
2936        snd_cs46xx_reset(chip);
2937
2938        snd_cs46xx_proc_stop(chip);
2939
2940        /*
2941         *  Power down the PLL.
2942         */
2943        snd_cs46xx_pokeBA0(chip, BA0_CLKCR1, 0);
2944
2945        /*
2946         *  Turn off the Processor by turning off the software clock enable flag in 
2947         *  the clock control register.
2948         */
2949        tmp = snd_cs46xx_peekBA0(chip, BA0_CLKCR1) & ~CLKCR1_SWCE;
2950        snd_cs46xx_pokeBA0(chip, BA0_CLKCR1, tmp);
2951}
2952
2953
2954static int snd_cs46xx_free(struct snd_cs46xx *chip)
2955{
2956        int idx;
2957
2958        if (snd_BUG_ON(!chip))
2959                return -EINVAL;
2960
2961        if (chip->active_ctrl)
2962                chip->active_ctrl(chip, 1);
2963
2964        snd_cs46xx_remove_gameport(chip);
2965
2966        if (chip->amplifier_ctrl)
2967                chip->amplifier_ctrl(chip, -chip->amplifier); /* force to off */
2968        
2969        snd_cs46xx_proc_done(chip);
2970
2971        if (chip->region.idx[0].resource)
2972                snd_cs46xx_hw_stop(chip);
2973
2974        if (chip->irq >= 0)
2975                free_irq(chip->irq, chip);
2976
2977        if (chip->active_ctrl)
2978                chip->active_ctrl(chip, -chip->amplifier);
2979
2980        for (idx = 0; idx < 5; idx++) {
2981                struct snd_cs46xx_region *region = &chip->region.idx[idx];
2982                if (region->remap_addr)
2983                        iounmap(region->remap_addr);
2984                release_and_free_resource(region->resource);
2985        }
2986
2987#ifdef CONFIG_SND_CS46XX_NEW_DSP
2988        if (chip->dsp_spos_instance) {
2989                cs46xx_dsp_spos_destroy(chip);
2990                chip->dsp_spos_instance = NULL;
2991        }
2992        for (idx = 0; idx < CS46XX_DSP_MODULES; idx++)
2993                free_module_desc(chip->modules[idx]);
2994#else
2995        vfree(chip->ba1);
2996#endif
2997        
2998#ifdef CONFIG_PM_SLEEP
2999        kfree(chip->saved_regs);
3000#endif
3001
3002        pci_disable_device(chip->pci);
3003        kfree(chip);
3004        return 0;
3005}
3006
3007static int snd_cs46xx_dev_free(struct snd_device *device)
3008{
3009        struct snd_cs46xx *chip = device->device_data;
3010        return snd_cs46xx_free(chip);
3011}
3012
3013/*
3014 *  initialize chip
3015 */
3016static int snd_cs46xx_chip_init(struct snd_cs46xx *chip)
3017{
3018        int timeout;
3019
3020        /* 
3021         *  First, blast the clock control register to zero so that the PLL starts
3022         *  out in a known state, and blast the master serial port control register
3023         *  to zero so that the serial ports also start out in a known state.
3024         */
3025        snd_cs46xx_pokeBA0(chip, BA0_CLKCR1, 0);
3026        snd_cs46xx_pokeBA0(chip, BA0_SERMC1, 0);
3027
3028        /*
3029         *  If we are in AC97 mode, then we must set the part to a host controlled
3030         *  AC-link.  Otherwise, we won't be able to bring up the link.
3031         */        
3032#ifdef CONFIG_SND_CS46XX_NEW_DSP
3033        snd_cs46xx_pokeBA0(chip, BA0_SERACC, SERACC_HSP | SERACC_CHIP_TYPE_2_0 | 
3034                           SERACC_TWO_CODECS);  /* 2.00 dual codecs */
3035        /* snd_cs46xx_pokeBA0(chip, BA0_SERACC, SERACC_HSP | SERACC_CHIP_TYPE_2_0); */ /* 2.00 codec */
3036#else
3037        snd_cs46xx_pokeBA0(chip, BA0_SERACC, SERACC_HSP | SERACC_CHIP_TYPE_1_03); /* 1.03 codec */
3038#endif
3039
3040        /*
3041         *  Drive the ARST# pin low for a minimum of 1uS (as defined in the AC97
3042         *  spec) and then drive it high.  This is done for non AC97 modes since
3043         *  there might be logic external to the CS461x that uses the ARST# line
3044         *  for a reset.
3045         */
3046        snd_cs46xx_pokeBA0(chip, BA0_ACCTL, 0);
3047#ifdef CONFIG_SND_CS46XX_NEW_DSP
3048        snd_cs46xx_pokeBA0(chip, BA0_ACCTL2, 0);
3049#endif
3050        udelay(50);
3051        snd_cs46xx_pokeBA0(chip, BA0_ACCTL, ACCTL_RSTN);
3052#ifdef CONFIG_SND_CS46XX_NEW_DSP
3053        snd_cs46xx_pokeBA0(chip, BA0_ACCTL2, ACCTL_RSTN);
3054#endif
3055    
3056        /*
3057         *  The first thing we do here is to enable sync generation.  As soon
3058         *  as we start receiving bit clock, we'll start producing the SYNC
3059         *  signal.
3060         */
3061        snd_cs46xx_pokeBA0(chip, BA0_ACCTL, ACCTL_ESYN | ACCTL_RSTN);
3062#ifdef CONFIG_SND_CS46XX_NEW_DSP
3063        snd_cs46xx_pokeBA0(chip, BA0_ACCTL2, ACCTL_ESYN | ACCTL_RSTN);
3064#endif
3065
3066        /*
3067         *  Now wait for a short while to allow the AC97 part to start
3068         *  generating bit clock (so we don't try to start the PLL without an
3069         *  input clock).
3070         */
3071        mdelay(10);
3072
3073        /*
3074         *  Set the serial port timing configuration, so that
3075         *  the clock control circuit gets its clock from the correct place.
3076         */
3077        snd_cs46xx_pokeBA0(chip, BA0_SERMC1, SERMC1_PTC_AC97);
3078
3079        /*
3080         *  Write the selected clock control setup to the hardware.  Do not turn on
3081         *  SWCE yet (if requested), so that the devices clocked by the output of
3082         *  PLL are not clocked until the PLL is stable.
3083         */
3084        snd_cs46xx_pokeBA0(chip, BA0_PLLCC, PLLCC_LPF_1050_2780_KHZ | PLLCC_CDR_73_104_MHZ);
3085        snd_cs46xx_pokeBA0(chip, BA0_PLLM, 0x3a);
3086        snd_cs46xx_pokeBA0(chip, BA0_CLKCR2, CLKCR2_PDIVS_8);
3087
3088        /*
3089         *  Power up the PLL.
3090         */
3091        snd_cs46xx_pokeBA0(chip, BA0_CLKCR1, CLKCR1_PLLP);
3092
3093        /*
3094         *  Wait until the PLL has stabilized.
3095         */
3096        msleep(100);
3097
3098        /*
3099         *  Turn on clocking of the core so that we can setup the serial ports.
3100         */
3101        snd_cs46xx_pokeBA0(chip, BA0_CLKCR1, CLKCR1_PLLP | CLKCR1_SWCE);
3102
3103        /*
3104         * Enable FIFO  Host Bypass
3105         */
3106        snd_cs46xx_pokeBA0(chip, BA0_SERBCF, SERBCF_HBP);
3107
3108        /*
3109         *  Fill the serial port FIFOs with silence.
3110         */
3111        snd_cs46xx_clear_serial_FIFOs(chip);
3112
3113        /*
3114         *  Set the serial port FIFO pointer to the first sample in the FIFO.
3115         */
3116        /* snd_cs46xx_pokeBA0(chip, BA0_SERBSP, 0); */
3117
3118        /*
3119         *  Write the serial port configuration to the part.  The master
3120         *  enable bit is not set until all other values have been written.
3121         */
3122        snd_cs46xx_pokeBA0(chip, BA0_SERC1, SERC1_SO1F_AC97 | SERC1_SO1EN);
3123        snd_cs46xx_pokeBA0(chip, BA0_SERC2, SERC2_SI1F_AC97 | SERC1_SO1EN);
3124        snd_cs46xx_pokeBA0(chip, BA0_SERMC1, SERMC1_PTC_AC97 | SERMC1_MSPE);
3125
3126
3127#ifdef CONFIG_SND_CS46XX_NEW_DSP
3128        snd_cs46xx_pokeBA0(chip, BA0_SERC7, SERC7_ASDI2EN);
3129        snd_cs46xx_pokeBA0(chip, BA0_SERC3, 0);
3130        snd_cs46xx_pokeBA0(chip, BA0_SERC4, 0);
3131        snd_cs46xx_pokeBA0(chip, BA0_SERC5, 0);
3132        snd_cs46xx_pokeBA0(chip, BA0_SERC6, 1);
3133#endif
3134
3135        mdelay(5);
3136
3137
3138        /*
3139         * Wait for the codec ready signal from the AC97 codec.
3140         */
3141        timeout = 150;
3142        while (timeout-- > 0) {
3143                /*
3144                 *  Read the AC97 status register to see if we've seen a CODEC READY
3145                 *  signal from the AC97 codec.
3146                 */
3147                if (snd_cs46xx_peekBA0(chip, BA0_ACSTS) & ACSTS_CRDY)
3148                        goto ok1;
3149                msleep(10);
3150        }
3151
3152
3153        dev_err(chip->card->dev,
3154                "create - never read codec ready from AC'97\n");
3155        dev_err(chip->card->dev,
3156                "it is not probably bug, try to use CS4236 driver\n");
3157        return -EIO;
3158 ok1:
3159#ifdef CONFIG_SND_CS46XX_NEW_DSP
3160        {
3161                int count;
3162                for (count = 0; count < 150; count++) {
3163                        /* First, we want to wait for a short time. */
3164                        udelay(25);
3165        
3166                        if (snd_cs46xx_peekBA0(chip, BA0_ACSTS2) & ACSTS_CRDY)
3167                                break;
3168                }
3169
3170                /*
3171                 *  Make sure CODEC is READY.
3172                 */
3173                if (!(snd_cs46xx_peekBA0(chip, BA0_ACSTS2) & ACSTS_CRDY))
3174                        dev_dbg(chip->card->dev,
3175                                "never read card ready from secondary AC'97\n");
3176        }
3177#endif
3178
3179        /*
3180         *  Assert the vaid frame signal so that we can start sending commands
3181         *  to the AC97 codec.
3182         */
3183        snd_cs46xx_pokeBA0(chip, BA0_ACCTL, ACCTL_VFRM | ACCTL_ESYN | ACCTL_RSTN);
3184#ifdef CONFIG_SND_CS46XX_NEW_DSP
3185        snd_cs46xx_pokeBA0(chip, BA0_ACCTL2, ACCTL_VFRM | ACCTL_ESYN | ACCTL_RSTN);
3186#endif
3187
3188
3189        /*
3190         *  Wait until we've sampled input slots 3 and 4 as valid, meaning that
3191         *  the codec is pumping ADC data across the AC-link.
3192         */
3193        timeout = 150;
3194        while (timeout-- > 0) {
3195                /*
3196                 *  Read the input slot valid register and see if input slots 3 and
3197                 *  4 are valid yet.
3198                 */
3199                if ((snd_cs46xx_peekBA0(chip, BA0_ACISV) & (ACISV_ISV3 | ACISV_ISV4)) == (ACISV_ISV3 | ACISV_ISV4))
3200                        goto ok2;
3201                msleep(10);
3202        }
3203
3204#ifndef CONFIG_SND_CS46XX_NEW_DSP
3205        dev_err(chip->card->dev,
3206                "create - never read ISV3 & ISV4 from AC'97\n");
3207        return -EIO;
3208#else
3209        /* This may happen on a cold boot with a Terratec SiXPack 5.1.
3210           Reloading the driver may help, if there's other soundcards 
3211           with the same problem I would like to know. (Benny) */
3212
3213        dev_err(chip->card->dev, "never read ISV3 & ISV4 from AC'97\n");
3214        dev_err(chip->card->dev,
3215                "Try reloading the ALSA driver, if you find something\n");
3216        dev_err(chip->card->dev,
3217                "broken or not working on your soundcard upon\n");
3218        dev_err(chip->card->dev,
3219                "this message please report to alsa-devel@alsa-project.org\n");
3220
3221        return -EIO;
3222#endif
3223 ok2:
3224
3225        /*
3226         *  Now, assert valid frame and the slot 3 and 4 valid bits.  This will
3227         *  commense the transfer of digital audio data to the AC97 codec.
3228         */
3229
3230        snd_cs46xx_pokeBA0(chip, BA0_ACOSV, ACOSV_SLV3 | ACOSV_SLV4);
3231
3232
3233        /*
3234         *  Power down the DAC and ADC.  We will power them up (if) when we need
3235         *  them.
3236         */
3237        /* snd_cs46xx_pokeBA0(chip, BA0_AC97_POWERDOWN, 0x300); */
3238
3239        /*
3240         *  Turn off the Processor by turning off the software clock enable flag in 
3241         *  the clock control register.
3242         */
3243        /* tmp = snd_cs46xx_peekBA0(chip, BA0_CLKCR1) & ~CLKCR1_SWCE; */
3244        /* snd_cs46xx_pokeBA0(chip, BA0_CLKCR1, tmp); */
3245
3246        return 0;
3247}
3248
3249/*
3250 *  start and load DSP 
3251 */
3252
3253static void cs46xx_enable_stream_irqs(struct snd_cs46xx *chip)
3254{
3255        unsigned int tmp;
3256
3257        snd_cs46xx_pokeBA0(chip, BA0_HICR, HICR_IEV | HICR_CHGM);
3258        
3259        tmp = snd_cs46xx_peek(chip, BA1_PFIE);
3260        tmp &= ~0x0000f03f;
3261        snd_cs46xx_poke(chip, BA1_PFIE, tmp);   /* playback interrupt enable */
3262
3263        tmp = snd_cs46xx_peek(chip, BA1_CIE);
3264        tmp &= ~0x0000003f;
3265        tmp |=  0x00000001;
3266        snd_cs46xx_poke(chip, BA1_CIE, tmp);    /* capture interrupt enable */
3267}
3268
3269int snd_cs46xx_start_dsp(struct snd_cs46xx *chip)
3270{       
3271        unsigned int tmp;
3272#ifdef CONFIG_SND_CS46XX_NEW_DSP
3273        int i;
3274#endif
3275        int err;
3276
3277        /*
3278         *  Reset the processor.
3279         */
3280        snd_cs46xx_reset(chip);
3281        /*
3282         *  Download the image to the processor.
3283         */
3284#ifdef CONFIG_SND_CS46XX_NEW_DSP
3285        for (i = 0; i < CS46XX_DSP_MODULES; i++) {
3286                err = load_firmware(chip, &chip->modules[i], module_names[i]);
3287                if (err < 0) {
3288                        dev_err(chip->card->dev, "firmware load error [%s]\n",
3289                                   module_names[i]);
3290                        return err;
3291                }
3292                err = cs46xx_dsp_load_module(chip, chip->modules[i]);
3293                if (err < 0) {
3294                        dev_err(chip->card->dev, "image download error [%s]\n",
3295                                   module_names[i]);
3296                        return err;
3297                }
3298        }
3299
3300        if (cs46xx_dsp_scb_and_task_init(chip) < 0)
3301                return -EIO;
3302#else
3303        err = load_firmware(chip);
3304        if (err < 0)
3305                return err;
3306
3307        /* old image */
3308        err = snd_cs46xx_download_image(chip);
3309        if (err < 0) {
3310                dev_err(chip->card->dev, "image download error\n");
3311                return err;
3312        }
3313
3314        /*
3315         *  Stop playback DMA.
3316         */
3317        tmp = snd_cs46xx_peek(chip, BA1_PCTL);
3318        chip->play_ctl = tmp & 0xffff0000;
3319        snd_cs46xx_poke(chip, BA1_PCTL, tmp & 0x0000ffff);
3320#endif
3321
3322        /*
3323         *  Stop capture DMA.
3324         */
3325        tmp = snd_cs46xx_peek(chip, BA1_CCTL);
3326        chip->capt.ctl = tmp & 0x0000ffff;
3327        snd_cs46xx_poke(chip, BA1_CCTL, tmp & 0xffff0000);
3328
3329        mdelay(5);
3330
3331        snd_cs46xx_set_play_sample_rate(chip, 8000);
3332        snd_cs46xx_set_capture_sample_rate(chip, 8000);
3333
3334        snd_cs46xx_proc_start(chip);
3335
3336        cs46xx_enable_stream_irqs(chip);
3337        
3338#ifndef CONFIG_SND_CS46XX_NEW_DSP
3339        /* set the attenuation to 0dB */ 
3340        snd_cs46xx_poke(chip, BA1_PVOL, 0x80008000);
3341        snd_cs46xx_poke(chip, BA1_CVOL, 0x80008000);
3342#endif
3343
3344        return 0;
3345}
3346
3347
3348/*
3349 *      AMP control - null AMP
3350 */
3351 
3352static void amp_none(struct snd_cs46xx *chip, int change)
3353{       
3354}
3355
3356#ifdef CONFIG_SND_CS46XX_NEW_DSP
3357static int voyetra_setup_eapd_slot(struct snd_cs46xx *chip)
3358{
3359        
3360        u32 idx, valid_slots,tmp,powerdown = 0;
3361        u16 modem_power,pin_config,logic_type;
3362
3363        dev_dbg(chip->card->dev, "cs46xx_setup_eapd_slot()+\n");
3364
3365        /*
3366         *  See if the devices are powered down.  If so, we must power them up first
3367         *  or they will not respond.
3368         */
3369        tmp = snd_cs46xx_peekBA0(chip, BA0_CLKCR1);
3370
3371        if (!(tmp & CLKCR1_SWCE)) {
3372                snd_cs46xx_pokeBA0(chip, BA0_CLKCR1, tmp | CLKCR1_SWCE);
3373                powerdown = 1;
3374        }
3375
3376        /*
3377         * Clear PRA.  The Bonzo chip will be used for GPIO not for modem
3378         * stuff.
3379         */
3380        if(chip->nr_ac97_codecs != 2) {
3381                dev_err(chip->card->dev,
3382                        "cs46xx_setup_eapd_slot() - no secondary codec configured\n");
3383                return -EINVAL;
3384        }
3385
3386        modem_power = snd_cs46xx_codec_read (chip, 
3387                                             AC97_EXTENDED_MSTATUS,
3388                                             CS46XX_SECONDARY_CODEC_INDEX);
3389        modem_power &=0xFEFF;
3390
3391        snd_cs46xx_codec_write(chip, 
3392                               AC97_EXTENDED_MSTATUS, modem_power,
3393                               CS46XX_SECONDARY_CODEC_INDEX);
3394
3395        /*
3396         * Set GPIO pin's 7 and 8 so that they are configured for output.
3397         */
3398        pin_config = snd_cs46xx_codec_read (chip, 
3399                                            AC97_GPIO_CFG,
3400                                            CS46XX_SECONDARY_CODEC_INDEX);
3401        pin_config &=0x27F;
3402
3403        snd_cs46xx_codec_write(chip, 
3404                               AC97_GPIO_CFG, pin_config,
3405                               CS46XX_SECONDARY_CODEC_INDEX);
3406    
3407        /*
3408         * Set GPIO pin's 7 and 8 so that they are compatible with CMOS logic.
3409         */
3410
3411        logic_type = snd_cs46xx_codec_read(chip, AC97_GPIO_POLARITY,
3412                                           CS46XX_SECONDARY_CODEC_INDEX);
3413        logic_type &=0x27F; 
3414
3415        snd_cs46xx_codec_write (chip, AC97_GPIO_POLARITY, logic_type,
3416                                CS46XX_SECONDARY_CODEC_INDEX);
3417
3418        valid_slots = snd_cs46xx_peekBA0(chip, BA0_ACOSV);
3419        valid_slots |= 0x200;
3420        snd_cs46xx_pokeBA0(chip, BA0_ACOSV, valid_slots);
3421
3422        if ( cs46xx_wait_for_fifo(chip,1) ) {
3423                dev_dbg(chip->card->dev, "FIFO is busy\n");
3424          
3425          return -EINVAL;
3426        }
3427
3428        /*
3429         * Fill slots 12 with the correct value for the GPIO pins. 
3430         */
3431        for(idx = 0x90; idx <= 0x9F; idx++) {
3432                /*
3433                 * Initialize the fifo so that bits 7 and 8 are on.
3434                 *
3435                 * Remember that the GPIO pins in bonzo are shifted by 4 bits to
3436                 * the left.  0x1800 corresponds to bits 7 and 8.
3437                 */
3438                snd_cs46xx_pokeBA0(chip, BA0_SERBWP, 0x1800);
3439
3440                /*
3441                 * Wait for command to complete
3442                 */
3443                if ( cs46xx_wait_for_fifo(chip,200) ) {
3444                        dev_dbg(chip->card->dev,
3445                                "failed waiting for FIFO at addr (%02X)\n",
3446                                idx);
3447
3448                        return -EINVAL;
3449                }
3450            
3451                /*
3452                 * Write the serial port FIFO index.
3453                 */
3454                snd_cs46xx_pokeBA0(chip, BA0_SERBAD, idx);
3455      
3456                /*
3457                 * Tell the serial port to load the new value into the FIFO location.
3458                 */
3459                snd_cs46xx_pokeBA0(chip, BA0_SERBCM, SERBCM_WRC);
3460        }
3461
3462        /* wait for last command to complete */
3463        cs46xx_wait_for_fifo(chip,200);
3464
3465        /*
3466         *  Now, if we powered up the devices, then power them back down again.
3467         *  This is kinda ugly, but should never happen.
3468         */
3469        if (powerdown)
3470                snd_cs46xx_pokeBA0(chip, BA0_CLKCR1, tmp);
3471
3472        return 0;
3473}
3474#endif
3475
3476/*
3477 *      Crystal EAPD mode
3478 */
3479 
3480static void amp_voyetra(struct snd_cs46xx *chip, int change)
3481{
3482        /* Manage the EAPD bit on the Crystal 4297 
3483           and the Analog AD1885 */
3484           
3485#ifdef CONFIG_SND_CS46XX_NEW_DSP
3486        int old = chip->amplifier;
3487#endif
3488        int oval, val;
3489        
3490        chip->amplifier += change;
3491        oval = snd_cs46xx_codec_read(chip, AC97_POWERDOWN,
3492                                     CS46XX_PRIMARY_CODEC_INDEX);
3493        val = oval;
3494        if (chip->amplifier) {
3495                /* Turn the EAPD amp on */
3496                val |= 0x8000;
3497        } else {
3498                /* Turn the EAPD amp off */
3499                val &= ~0x8000;
3500        }
3501        if (val != oval) {
3502                snd_cs46xx_codec_write(chip, AC97_POWERDOWN, val,
3503                                       CS46XX_PRIMARY_CODEC_INDEX);
3504                if (chip->eapd_switch)
3505                        snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE,
3506                                       &chip->eapd_switch->id);
3507        }
3508
3509#ifdef CONFIG_SND_CS46XX_NEW_DSP
3510        if (chip->amplifier && !old) {
3511                voyetra_setup_eapd_slot(chip);
3512        }
3513#endif
3514}
3515
3516static void hercules_init(struct snd_cs46xx *chip) 
3517{
3518        /* default: AMP off, and SPDIF input optical */
3519        snd_cs46xx_pokeBA0(chip, BA0_EGPIODR, EGPIODR_GPOE0);
3520        snd_cs46xx_pokeBA0(chip, BA0_EGPIOPTR, EGPIODR_GPOE0);
3521}
3522
3523
3524/*
3525 *      Game Theatre XP card - EGPIO[2] is used to enable the external amp.
3526 */ 
3527static void amp_hercules(struct snd_cs46xx *chip, int change)
3528{
3529        int old = chip->amplifier;
3530        int val1 = snd_cs46xx_peekBA0(chip, BA0_EGPIODR);
3531        int val2 = snd_cs46xx_peekBA0(chip, BA0_EGPIOPTR);
3532
3533        chip->amplifier += change;
3534        if (chip->amplifier && !old) {
3535                dev_dbg(chip->card->dev, "Hercules amplifier ON\n");
3536
3537                snd_cs46xx_pokeBA0(chip, BA0_EGPIODR, 
3538                                   EGPIODR_GPOE2 | val1);     /* enable EGPIO2 output */
3539                snd_cs46xx_pokeBA0(chip, BA0_EGPIOPTR, 
3540                                   EGPIOPTR_GPPT2 | val2);   /* open-drain on output */
3541        } else if (old && !chip->amplifier) {
3542                dev_dbg(chip->card->dev, "Hercules amplifier OFF\n");
3543                snd_cs46xx_pokeBA0(chip, BA0_EGPIODR,  val1 & ~EGPIODR_GPOE2); /* disable */
3544                snd_cs46xx_pokeBA0(chip, BA0_EGPIOPTR, val2 & ~EGPIOPTR_GPPT2); /* disable */
3545        }
3546}
3547
3548static void voyetra_mixer_init (struct snd_cs46xx *chip)
3549{
3550        dev_dbg(chip->card->dev, "initializing Voyetra mixer\n");
3551
3552        /* Enable SPDIF out */
3553        snd_cs46xx_pokeBA0(chip, BA0_EGPIODR, EGPIODR_GPOE0);
3554        snd_cs46xx_pokeBA0(chip, BA0_EGPIOPTR, EGPIODR_GPOE0);
3555}
3556
3557static void hercules_mixer_init (struct snd_cs46xx *chip)
3558{
3559#ifdef CONFIG_SND_CS46XX_NEW_DSP
3560        unsigned int idx;
3561        int err;
3562        struct snd_card *card = chip->card;
3563#endif
3564
3565        /* set EGPIO to default */
3566        hercules_init(chip);
3567
3568        dev_dbg(chip->card->dev, "initializing Hercules mixer\n");
3569
3570#ifdef CONFIG_SND_CS46XX_NEW_DSP
3571        if (chip->in_suspend)
3572                return;
3573
3574        for (idx = 0 ; idx < ARRAY_SIZE(snd_hercules_controls); idx++) {
3575                struct snd_kcontrol *kctl;
3576
3577                kctl = snd_ctl_new1(&snd_hercules_controls[idx], chip);
3578                if ((err = snd_ctl_add(card, kctl)) < 0) {
3579                        dev_err(card->dev,
3580                                "failed to initialize Hercules mixer (%d)\n",
3581                                err);
3582                        break;
3583                }
3584        }
3585#endif
3586}
3587
3588
3589#if 0
3590/*
3591 *      Untested
3592 */
3593 
3594static void amp_voyetra_4294(struct snd_cs46xx *chip, int change)
3595{
3596        chip->amplifier += change;
3597
3598        if (chip->amplifier) {
3599                /* Switch the GPIO pins 7 and 8 to open drain */
3600                snd_cs46xx_codec_write(chip, 0x4C,
3601                                       snd_cs46xx_codec_read(chip, 0x4C) & 0xFE7F);
3602                snd_cs46xx_codec_write(chip, 0x4E,
3603                                       snd_cs46xx_codec_read(chip, 0x4E) | 0x0180);
3604                /* Now wake the AMP (this might be backwards) */
3605                snd_cs46xx_codec_write(chip, 0x54,
3606                                       snd_cs46xx_codec_read(chip, 0x54) & ~0x0180);
3607        } else {
3608                snd_cs46xx_codec_write(chip, 0x54,
3609                                       snd_cs46xx_codec_read(chip, 0x54) | 0x0180);
3610        }
3611}
3612#endif
3613
3614
3615/*
3616 *      Handle the CLKRUN on a thinkpad. We must disable CLKRUN support
3617 *      whenever we need to beat on the chip.
3618 *
3619 *      The original idea and code for this hack comes from David Kaiser at
3620 *      Linuxcare. Perhaps one day Crystal will document their chips well
3621 *      enough to make them useful.
3622 */
3623 
3624static void clkrun_hack(struct snd_cs46xx *chip, int change)
3625{
3626        u16 control, nval;
3627        
3628        if (!chip->acpi_port)
3629                return;
3630
3631        chip->amplifier += change;
3632        
3633        /* Read ACPI port */    
3634        nval = control = inw(chip->acpi_port + 0x10);
3635
3636        /* Flip CLKRUN off while running */
3637        if (! chip->amplifier)
3638                nval |= 0x2000;
3639        else
3640                nval &= ~0x2000;
3641        if (nval != control)
3642                outw(nval, chip->acpi_port + 0x10);
3643}
3644
3645        
3646/*
3647 * detect intel piix4
3648 */
3649static void clkrun_init(struct snd_cs46xx *chip)
3650{
3651        struct pci_dev *pdev;
3652        u8 pp;
3653
3654        chip->acpi_port = 0;
3655        
3656        pdev = pci_get_device(PCI_VENDOR_ID_INTEL,
3657                PCI_DEVICE_ID_INTEL_82371AB_3, NULL);
3658        if (pdev == NULL)
3659                return;         /* Not a thinkpad thats for sure */
3660
3661        /* Find the control port */             
3662        pci_read_config_byte(pdev, 0x41, &pp);
3663        chip->acpi_port = pp << 8;
3664        pci_dev_put(pdev);
3665}
3666
3667
3668/*
3669 * Card subid table
3670 */
3671 
3672struct cs_card_type
3673{
3674        u16 vendor;
3675        u16 id;
3676        char *name;
3677        void (*init)(struct snd_cs46xx *);
3678        void (*amp)(struct snd_cs46xx *, int);
3679        void (*active)(struct snd_cs46xx *, int);
3680        void (*mixer_init)(struct snd_cs46xx *);
3681};
3682
3683static struct cs_card_type cards[] = {
3684        {
3685                .vendor = 0x1489,
3686                .id = 0x7001,
3687                .name = "Genius Soundmaker 128 value",
3688                /* nothing special */
3689        },
3690        {
3691                .vendor = 0x5053,
3692                .id = 0x3357,
3693                .name = "Voyetra",
3694                .amp = amp_voyetra,
3695                .mixer_init = voyetra_mixer_init,
3696        },
3697        {
3698                .vendor = 0x1071,
3699                .id = 0x6003,
3700                .name = "Mitac MI6020/21",
3701                .amp = amp_voyetra,
3702        },
3703        /* Hercules Game Theatre XP */
3704        {
3705                .vendor = 0x14af, /* Guillemot Corporation */
3706                .id = 0x0050,
3707                .name = "Hercules Game Theatre XP",
3708                .amp = amp_hercules,
3709                .mixer_init = hercules_mixer_init,
3710        },
3711        {
3712                .vendor = 0x1681,
3713                .id = 0x0050,
3714                .name = "Hercules Game Theatre XP",
3715                .amp = amp_hercules,
3716                .mixer_init = hercules_mixer_init,
3717        },
3718        {
3719                .vendor = 0x1681,
3720                .id = 0x0051,
3721                .name = "Hercules Game Theatre XP",
3722                .amp = amp_hercules,
3723                .mixer_init = hercules_mixer_init,
3724
3725        },
3726        {
3727                .vendor = 0x1681,
3728                .id = 0x0052,
3729                .name = "Hercules Game Theatre XP",
3730                .amp = amp_hercules,
3731                .mixer_init = hercules_mixer_init,
3732        },
3733        {
3734                .vendor = 0x1681,
3735                .id = 0x0053,
3736                .name = "Hercules Game Theatre XP",
3737                .amp = amp_hercules,
3738                .mixer_init = hercules_mixer_init,
3739        },
3740        {
3741                .vendor = 0x1681,
3742                .id = 0x0054,
3743                .name = "Hercules Game Theatre XP",
3744                .amp = amp_hercules,
3745                .mixer_init = hercules_mixer_init,
3746        },
3747        /* Herculess Fortissimo */
3748        {
3749                .vendor = 0x1681,
3750                .id = 0xa010,
3751                .name = "Hercules Gamesurround Fortissimo II",
3752        },
3753        {
3754                .vendor = 0x1681,
3755                .id = 0xa011,
3756                .name = "Hercules Gamesurround Fortissimo III 7.1",
3757        },
3758        /* Teratec */
3759        {
3760                .vendor = 0x153b,
3761                .id = 0x112e,
3762                .name = "Terratec DMX XFire 1024",
3763        },
3764        {
3765                .vendor = 0x153b,
3766                .id = 0x1136,
3767                .name = "Terratec SiXPack 5.1",
3768        },
3769        /* Not sure if the 570 needs the clkrun hack */
3770        {
3771                .vendor = PCI_VENDOR_ID_IBM,
3772                .id = 0x0132,
3773                .name = "Thinkpad 570",
3774                .init = clkrun_init,
3775                .active = clkrun_hack,
3776        },
3777        {
3778                .vendor = PCI_VENDOR_ID_IBM,
3779                .id = 0x0153,
3780                .name = "Thinkpad 600X/A20/T20",
3781                .init = clkrun_init,
3782                .active = clkrun_hack,
3783        },
3784        {
3785                .vendor = PCI_VENDOR_ID_IBM,
3786                .id = 0x1010,
3787                .name = "Thinkpad 600E (unsupported)",
3788        },
3789        {} /* terminator */
3790};
3791
3792
3793/*
3794 * APM support
3795 */
3796#ifdef CONFIG_PM_SLEEP
3797static unsigned int saved_regs[] = {
3798        BA0_ACOSV,
3799        /*BA0_ASER_FADDR,*/
3800        BA0_ASER_MASTER,
3801        BA1_PVOL,
3802        BA1_CVOL,
3803};
3804
3805static int snd_cs46xx_suspend(struct device *dev)
3806{
3807        struct pci_dev *pci = to_pci_dev(dev);
3808        struct snd_card *card = dev_get_drvdata(dev);
3809        struct snd_cs46xx *chip = card->private_data;
3810        int i, amp_saved;
3811
3812        snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
3813        chip->in_suspend = 1;
3814        snd_pcm_suspend_all(chip->pcm);
3815        // chip->ac97_powerdown = snd_cs46xx_codec_read(chip, AC97_POWER_CONTROL);
3816        // chip->ac97_general_purpose = snd_cs46xx_codec_read(chip, BA0_AC97_GENERAL_PURPOSE);
3817
3818        snd_ac97_suspend(chip->ac97[CS46XX_PRIMARY_CODEC_INDEX]);
3819        snd_ac97_suspend(chip->ac97[CS46XX_SECONDARY_CODEC_INDEX]);
3820
3821        /* save some registers */
3822        for (i = 0; i < ARRAY_SIZE(saved_regs); i++)
3823                chip->saved_regs[i] = snd_cs46xx_peekBA0(chip, saved_regs[i]);
3824
3825        amp_saved = chip->amplifier;
3826        /* turn off amp */
3827        chip->amplifier_ctrl(chip, -chip->amplifier);
3828        snd_cs46xx_hw_stop(chip);
3829        /* disable CLKRUN */
3830        chip->active_ctrl(chip, -chip->amplifier);
3831        chip->amplifier = amp_saved; /* restore the status */
3832
3833        pci_disable_device(pci);
3834        pci_save_state(pci);
3835        pci_set_power_state(pci, PCI_D3hot);
3836        return 0;
3837}
3838
3839static int snd_cs46xx_resume(struct device *dev)
3840{
3841        struct pci_dev *pci = to_pci_dev(dev);
3842        struct snd_card *card = dev_get_drvdata(dev);
3843        struct snd_cs46xx *chip = card->private_data;
3844        int amp_saved;
3845#ifdef CONFIG_SND_CS46XX_NEW_DSP
3846        int i;
3847#endif
3848        unsigned int tmp;
3849
3850        pci_set_power_state(pci, PCI_D0);
3851        pci_restore_state(pci);
3852        if (pci_enable_device(pci) < 0) {
3853                dev_err(dev, "pci_enable_device failed, disabling device\n");
3854                snd_card_disconnect(card);
3855                return -EIO;
3856        }
3857        pci_set_master(pci);
3858
3859        amp_saved = chip->amplifier;
3860        chip->amplifier = 0;
3861        chip->active_ctrl(chip, 1); /* force to on */
3862
3863        snd_cs46xx_chip_init(chip);
3864
3865        snd_cs46xx_reset(chip);
3866#ifdef CONFIG_SND_CS46XX_NEW_DSP
3867        cs46xx_dsp_resume(chip);
3868        /* restore some registers */
3869        for (i = 0; i < ARRAY_SIZE(saved_regs); i++)
3870                snd_cs46xx_pokeBA0(chip, saved_regs[i], chip->saved_regs[i]);
3871#else
3872        snd_cs46xx_download_image(chip);
3873#endif
3874
3875#if 0
3876        snd_cs46xx_codec_write(chip, BA0_AC97_GENERAL_PURPOSE, 
3877                               chip->ac97_general_purpose);
3878        snd_cs46xx_codec_write(chip, AC97_POWER_CONTROL, 
3879                               chip->ac97_powerdown);
3880        mdelay(10);
3881        snd_cs46xx_codec_write(chip, BA0_AC97_POWERDOWN,
3882                               chip->ac97_powerdown);
3883        mdelay(5);
3884#endif
3885
3886        snd_ac97_resume(chip->ac97[CS46XX_PRIMARY_CODEC_INDEX]);
3887        snd_ac97_resume(chip->ac97[CS46XX_SECONDARY_CODEC_INDEX]);
3888
3889        /*
3890         *  Stop capture DMA.
3891         */
3892        tmp = snd_cs46xx_peek(chip, BA1_CCTL);
3893        chip->capt.ctl = tmp & 0x0000ffff;
3894        snd_cs46xx_poke(chip, BA1_CCTL, tmp & 0xffff0000);
3895
3896        mdelay(5);
3897
3898        /* reset playback/capture */
3899        snd_cs46xx_set_play_sample_rate(chip, 8000);
3900        snd_cs46xx_set_capture_sample_rate(chip, 8000);
3901        snd_cs46xx_proc_start(chip);
3902
3903        cs46xx_enable_stream_irqs(chip);
3904
3905        if (amp_saved)
3906                chip->amplifier_ctrl(chip, 1); /* turn amp on */
3907        else
3908                chip->active_ctrl(chip, -1); /* disable CLKRUN */
3909        chip->amplifier = amp_saved;
3910        chip->in_suspend = 0;
3911        snd_power_change_state(card, SNDRV_CTL_POWER_D0);
3912        return 0;
3913}
3914
3915SIMPLE_DEV_PM_OPS(snd_cs46xx_pm, snd_cs46xx_suspend, snd_cs46xx_resume);
3916#endif /* CONFIG_PM_SLEEP */
3917
3918
3919/*
3920 */
3921
3922int snd_cs46xx_create(struct snd_card *card,
3923                      struct pci_dev *pci,
3924                      int external_amp, int thinkpad,
3925                      struct snd_cs46xx **rchip)
3926{
3927        struct snd_cs46xx *chip;
3928        int err, idx;
3929        struct snd_cs46xx_region *region;
3930        struct cs_card_type *cp;
3931        u16 ss_card, ss_vendor;
3932        static struct snd_device_ops ops = {
3933                .dev_free =     snd_cs46xx_dev_free,
3934        };
3935        
3936        *rchip = NULL;
3937
3938        /* enable PCI device */
3939        if ((err = pci_enable_device(pci)) < 0)
3940                return err;
3941
3942        chip = kzalloc(sizeof(*chip), GFP_KERNEL);
3943        if (chip == NULL) {
3944                pci_disable_device(pci);
3945                return -ENOMEM;
3946        }
3947        spin_lock_init(&chip->reg_lock);
3948#ifdef CONFIG_SND_CS46XX_NEW_DSP
3949        mutex_init(&chip->spos_mutex);
3950#endif
3951        chip->card = card;
3952        chip->pci = pci;
3953        chip->irq = -1;
3954        chip->ba0_addr = pci_resource_start(pci, 0);
3955        chip->ba1_addr = pci_resource_start(pci, 1);
3956        if (chip->ba0_addr == 0 || chip->ba0_addr == (unsigned long)~0 ||
3957            chip->ba1_addr == 0 || chip->ba1_addr == (unsigned long)~0) {
3958                dev_err(chip->card->dev,
3959                        "wrong address(es) - ba0 = 0x%lx, ba1 = 0x%lx\n",
3960                           chip->ba0_addr, chip->ba1_addr);
3961                snd_cs46xx_free(chip);
3962                return -ENOMEM;
3963        }
3964
3965        region = &chip->region.name.ba0;
3966        strcpy(region->name, "CS46xx_BA0");
3967        region->base = chip->ba0_addr;
3968        region->size = CS46XX_BA0_SIZE;
3969
3970        region = &chip->region.name.data0;
3971        strcpy(region->name, "CS46xx_BA1_data0");
3972        region->base = chip->ba1_addr + BA1_SP_DMEM0;
3973        region->size = CS46XX_BA1_DATA0_SIZE;
3974
3975        region = &chip->region.name.data1;
3976        strcpy(region->name, "CS46xx_BA1_data1");
3977        region->base = chip->ba1_addr + BA1_SP_DMEM1;
3978        region->size = CS46XX_BA1_DATA1_SIZE;
3979
3980        region = &chip->region.name.pmem;
3981        strcpy(region->name, "CS46xx_BA1_pmem");
3982        region->base = chip->ba1_addr + BA1_SP_PMEM;
3983        region->size = CS46XX_BA1_PRG_SIZE;
3984
3985        region = &chip->region.name.reg;
3986        strcpy(region->name, "CS46xx_BA1_reg");
3987        region->base = chip->ba1_addr + BA1_SP_REG;
3988        region->size = CS46XX_BA1_REG_SIZE;
3989
3990        /* set up amp and clkrun hack */
3991        pci_read_config_word(pci, PCI_SUBSYSTEM_VENDOR_ID, &ss_vendor);
3992        pci_read_config_word(pci, PCI_SUBSYSTEM_ID, &ss_card);
3993
3994        for (cp = &cards[0]; cp->name; cp++) {
3995                if (cp->vendor == ss_vendor && cp->id == ss_card) {
3996                        dev_dbg(chip->card->dev, "hack for %s enabled\n",
3997                                cp->name);
3998
3999                        chip->amplifier_ctrl = cp->amp;
4000                        chip->active_ctrl = cp->active;
4001                        chip->mixer_init = cp->mixer_init;
4002
4003                        if (cp->init)
4004                                cp->init(chip);
4005                        break;
4006                }
4007        }
4008
4009        if (external_amp) {
4010                dev_info(chip->card->dev,
4011                         "Crystal EAPD support forced on.\n");
4012                chip->amplifier_ctrl = amp_voyetra;
4013        }
4014
4015        if (thinkpad) {
4016                dev_info(chip->card->dev,
4017                         "Activating CLKRUN hack for Thinkpad.\n");
4018                chip->active_ctrl = clkrun_hack;
4019                clkrun_init(chip);
4020        }
4021        
4022        if (chip->amplifier_ctrl == NULL)
4023                chip->amplifier_ctrl = amp_none;
4024        if (chip->active_ctrl == NULL)
4025                chip->active_ctrl = amp_none;
4026
4027        chip->active_ctrl(chip, 1); /* enable CLKRUN */
4028
4029        pci_set_master(pci);
4030
4031        for (idx = 0; idx < 5; idx++) {
4032                region = &chip->region.idx[idx];
4033                if ((region->resource = request_mem_region(region->base, region->size,
4034                                                           region->name)) == NULL) {
4035                        dev_err(chip->card->dev,
4036                                "unable to request memory region 0x%lx-0x%lx\n",
4037                                   region->base, region->base + region->size - 1);
4038                        snd_cs46xx_free(chip);
4039                        return -EBUSY;
4040                }
4041                region->remap_addr = ioremap_nocache(region->base, region->size);
4042                if (region->remap_addr == NULL) {
4043                        dev_err(chip->card->dev,
4044                                "%s ioremap problem\n", region->name);
4045                        snd_cs46xx_free(chip);
4046                        return -ENOMEM;
4047                }
4048        }
4049
4050        if (request_irq(pci->irq, snd_cs46xx_interrupt, IRQF_SHARED,
4051                        KBUILD_MODNAME, chip)) {
4052                dev_err(chip->card->dev, "unable to grab IRQ %d\n", pci->irq);
4053                snd_cs46xx_free(chip);
4054                return -EBUSY;
4055        }
4056        chip->irq = pci->irq;
4057
4058#ifdef CONFIG_SND_CS46XX_NEW_DSP
4059        chip->dsp_spos_instance = cs46xx_dsp_spos_create(chip);
4060        if (chip->dsp_spos_instance == NULL) {
4061                snd_cs46xx_free(chip);
4062                return -ENOMEM;
4063        }
4064#endif
4065
4066        err = snd_cs46xx_chip_init(chip);
4067        if (err < 0) {
4068                snd_cs46xx_free(chip);
4069                return err;
4070        }
4071
4072        if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) {
4073                snd_cs46xx_free(chip);
4074                return err;
4075        }
4076        
4077        snd_cs46xx_proc_init(card, chip);
4078
4079#ifdef CONFIG_PM_SLEEP
4080        chip->saved_regs = kmalloc(sizeof(*chip->saved_regs) *
4081                                   ARRAY_SIZE(saved_regs), GFP_KERNEL);
4082        if (!chip->saved_regs) {
4083                snd_cs46xx_free(chip);
4084                return -ENOMEM;
4085        }
4086#endif
4087
4088        chip->active_ctrl(chip, -1); /* disable CLKRUN */
4089
4090        *rchip = chip;
4091        return 0;
4092}
4093