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