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(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 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        .formats =              (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U8 |
1448                                 SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE |
1449                                 SNDRV_PCM_FMTBIT_U16_LE | SNDRV_PCM_FMTBIT_U16_BE),
1450        .rates =                SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,
1451        .rate_min =             5500,
1452        .rate_max =             48000,
1453        .channels_min =         1,
1454        .channels_max =         2,
1455        .buffer_bytes_max =     (256 * 1024),
1456        .period_bytes_min =     CS46XX_MIN_PERIOD_SIZE,
1457        .period_bytes_max =     CS46XX_MAX_PERIOD_SIZE,
1458        .periods_min =          CS46XX_FRAGS,
1459        .periods_max =          1024,
1460        .fifo_size =            0,
1461};
1462
1463static struct snd_pcm_hardware snd_cs46xx_capture =
1464{
1465        .info =                 (SNDRV_PCM_INFO_MMAP |
1466                                 SNDRV_PCM_INFO_INTERLEAVED |
1467                                 SNDRV_PCM_INFO_BLOCK_TRANSFER /*|*/
1468                                 /*SNDRV_PCM_INFO_RESUME*/),
1469        .formats =              SNDRV_PCM_FMTBIT_S16_LE,
1470        .rates =                SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,
1471        .rate_min =             5500,
1472        .rate_max =             48000,
1473        .channels_min =         2,
1474        .channels_max =         2,
1475        .buffer_bytes_max =     (256 * 1024),
1476        .period_bytes_min =     CS46XX_MIN_PERIOD_SIZE,
1477        .period_bytes_max =     CS46XX_MAX_PERIOD_SIZE,
1478        .periods_min =          CS46XX_FRAGS,
1479        .periods_max =          1024,
1480        .fifo_size =            0,
1481};
1482
1483#ifdef CONFIG_SND_CS46XX_NEW_DSP
1484
1485static const unsigned int period_sizes[] = { 32, 64, 128, 256, 512, 1024, 2048 };
1486
1487static const struct snd_pcm_hw_constraint_list hw_constraints_period_sizes = {
1488        .count = ARRAY_SIZE(period_sizes),
1489        .list = period_sizes,
1490        .mask = 0
1491};
1492
1493#endif
1494
1495static void snd_cs46xx_pcm_free_substream(struct snd_pcm_runtime *runtime)
1496{
1497        kfree(runtime->private_data);
1498}
1499
1500static int _cs46xx_playback_open_channel (struct snd_pcm_substream *substream,int pcm_channel_id)
1501{
1502        struct snd_cs46xx *chip = snd_pcm_substream_chip(substream);
1503        struct snd_cs46xx_pcm * cpcm;
1504        struct snd_pcm_runtime *runtime = substream->runtime;
1505
1506        cpcm = kzalloc(sizeof(*cpcm), GFP_KERNEL);
1507        if (cpcm == NULL)
1508                return -ENOMEM;
1509        if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(chip->pci),
1510                                PAGE_SIZE, &cpcm->hw_buf) < 0) {
1511                kfree(cpcm);
1512                return -ENOMEM;
1513        }
1514
1515        runtime->hw = snd_cs46xx_playback;
1516        runtime->private_data = cpcm;
1517        runtime->private_free = snd_cs46xx_pcm_free_substream;
1518
1519        cpcm->substream = substream;
1520#ifdef CONFIG_SND_CS46XX_NEW_DSP
1521        mutex_lock(&chip->spos_mutex);
1522        cpcm->pcm_channel = NULL; 
1523        cpcm->pcm_channel_id = pcm_channel_id;
1524
1525
1526        snd_pcm_hw_constraint_list(runtime, 0,
1527                                   SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 
1528                                   &hw_constraints_period_sizes);
1529
1530        mutex_unlock(&chip->spos_mutex);
1531#else
1532        chip->playback_pcm = cpcm; /* HACK */
1533#endif
1534
1535        if (chip->accept_valid)
1536                substream->runtime->hw.info |= SNDRV_PCM_INFO_MMAP_VALID;
1537        chip->active_ctrl(chip, 1);
1538
1539        return 0;
1540}
1541
1542static int snd_cs46xx_playback_open(struct snd_pcm_substream *substream)
1543{
1544        dev_dbg(substream->pcm->card->dev, "open front channel\n");
1545        return _cs46xx_playback_open_channel(substream,DSP_PCM_MAIN_CHANNEL);
1546}
1547
1548#ifdef CONFIG_SND_CS46XX_NEW_DSP
1549static int snd_cs46xx_playback_open_rear(struct snd_pcm_substream *substream)
1550{
1551        dev_dbg(substream->pcm->card->dev, "open rear channel\n");
1552        return _cs46xx_playback_open_channel(substream,DSP_PCM_REAR_CHANNEL);
1553}
1554
1555static int snd_cs46xx_playback_open_clfe(struct snd_pcm_substream *substream)
1556{
1557        dev_dbg(substream->pcm->card->dev, "open center - LFE channel\n");
1558        return _cs46xx_playback_open_channel(substream,DSP_PCM_CENTER_LFE_CHANNEL);
1559}
1560
1561static int snd_cs46xx_playback_open_iec958(struct snd_pcm_substream *substream)
1562{
1563        struct snd_cs46xx *chip = snd_pcm_substream_chip(substream);
1564
1565        dev_dbg(chip->card->dev, "open raw iec958 channel\n");
1566
1567        mutex_lock(&chip->spos_mutex);
1568        cs46xx_iec958_pre_open (chip);
1569        mutex_unlock(&chip->spos_mutex);
1570
1571        return _cs46xx_playback_open_channel(substream,DSP_IEC958_CHANNEL);
1572}
1573
1574static int snd_cs46xx_playback_close(struct snd_pcm_substream *substream);
1575
1576static int snd_cs46xx_playback_close_iec958(struct snd_pcm_substream *substream)
1577{
1578        int err;
1579        struct snd_cs46xx *chip = snd_pcm_substream_chip(substream);
1580  
1581        dev_dbg(chip->card->dev, "close raw iec958 channel\n");
1582
1583        err = snd_cs46xx_playback_close(substream);
1584
1585        mutex_lock(&chip->spos_mutex);
1586        cs46xx_iec958_post_close (chip);
1587        mutex_unlock(&chip->spos_mutex);
1588
1589        return err;
1590}
1591#endif
1592
1593static int snd_cs46xx_capture_open(struct snd_pcm_substream *substream)
1594{
1595        struct snd_cs46xx *chip = snd_pcm_substream_chip(substream);
1596
1597        if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(chip->pci),
1598                                PAGE_SIZE, &chip->capt.hw_buf) < 0)
1599                return -ENOMEM;
1600        chip->capt.substream = substream;
1601        substream->runtime->hw = snd_cs46xx_capture;
1602
1603        if (chip->accept_valid)
1604                substream->runtime->hw.info |= SNDRV_PCM_INFO_MMAP_VALID;
1605
1606        chip->active_ctrl(chip, 1);
1607
1608#ifdef CONFIG_SND_CS46XX_NEW_DSP
1609        snd_pcm_hw_constraint_list(substream->runtime, 0,
1610                                   SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 
1611                                   &hw_constraints_period_sizes);
1612#endif
1613        return 0;
1614}
1615
1616static int snd_cs46xx_playback_close(struct snd_pcm_substream *substream)
1617{
1618        struct snd_cs46xx *chip = snd_pcm_substream_chip(substream);
1619        struct snd_pcm_runtime *runtime = substream->runtime;
1620        struct snd_cs46xx_pcm * cpcm;
1621
1622        cpcm = runtime->private_data;
1623
1624        /* when playback_open fails, then cpcm can be NULL */
1625        if (!cpcm) return -ENXIO;
1626
1627#ifdef CONFIG_SND_CS46XX_NEW_DSP
1628        mutex_lock(&chip->spos_mutex);
1629        if (cpcm->pcm_channel) {
1630                cs46xx_dsp_destroy_pcm_channel(chip,cpcm->pcm_channel);
1631                cpcm->pcm_channel = NULL;
1632        }
1633        mutex_unlock(&chip->spos_mutex);
1634#else
1635        chip->playback_pcm = NULL;
1636#endif
1637
1638        cpcm->substream = NULL;
1639        snd_dma_free_pages(&cpcm->hw_buf);
1640        chip->active_ctrl(chip, -1);
1641
1642        return 0;
1643}
1644
1645static int snd_cs46xx_capture_close(struct snd_pcm_substream *substream)
1646{
1647        struct snd_cs46xx *chip = snd_pcm_substream_chip(substream);
1648
1649        chip->capt.substream = NULL;
1650        snd_dma_free_pages(&chip->capt.hw_buf);
1651        chip->active_ctrl(chip, -1);
1652
1653        return 0;
1654}
1655
1656#ifdef CONFIG_SND_CS46XX_NEW_DSP
1657static const struct snd_pcm_ops snd_cs46xx_playback_rear_ops = {
1658        .open =                 snd_cs46xx_playback_open_rear,
1659        .close =                snd_cs46xx_playback_close,
1660        .ioctl =                snd_pcm_lib_ioctl,
1661        .hw_params =            snd_cs46xx_playback_hw_params,
1662        .hw_free =              snd_cs46xx_playback_hw_free,
1663        .prepare =              snd_cs46xx_playback_prepare,
1664        .trigger =              snd_cs46xx_playback_trigger,
1665        .pointer =              snd_cs46xx_playback_direct_pointer,
1666};
1667
1668static const struct snd_pcm_ops snd_cs46xx_playback_indirect_rear_ops = {
1669        .open =                 snd_cs46xx_playback_open_rear,
1670        .close =                snd_cs46xx_playback_close,
1671        .ioctl =                snd_pcm_lib_ioctl,
1672        .hw_params =            snd_cs46xx_playback_hw_params,
1673        .hw_free =              snd_cs46xx_playback_hw_free,
1674        .prepare =              snd_cs46xx_playback_prepare,
1675        .trigger =              snd_cs46xx_playback_trigger,
1676        .pointer =              snd_cs46xx_playback_indirect_pointer,
1677        .ack =                  snd_cs46xx_playback_transfer,
1678};
1679
1680static const struct snd_pcm_ops snd_cs46xx_playback_clfe_ops = {
1681        .open =                 snd_cs46xx_playback_open_clfe,
1682        .close =                snd_cs46xx_playback_close,
1683        .ioctl =                snd_pcm_lib_ioctl,
1684        .hw_params =            snd_cs46xx_playback_hw_params,
1685        .hw_free =              snd_cs46xx_playback_hw_free,
1686        .prepare =              snd_cs46xx_playback_prepare,
1687        .trigger =              snd_cs46xx_playback_trigger,
1688        .pointer =              snd_cs46xx_playback_direct_pointer,
1689};
1690
1691static const struct snd_pcm_ops snd_cs46xx_playback_indirect_clfe_ops = {
1692        .open =                 snd_cs46xx_playback_open_clfe,
1693        .close =                snd_cs46xx_playback_close,
1694        .ioctl =                snd_pcm_lib_ioctl,
1695        .hw_params =            snd_cs46xx_playback_hw_params,
1696        .hw_free =              snd_cs46xx_playback_hw_free,
1697        .prepare =              snd_cs46xx_playback_prepare,
1698        .trigger =              snd_cs46xx_playback_trigger,
1699        .pointer =              snd_cs46xx_playback_indirect_pointer,
1700        .ack =                  snd_cs46xx_playback_transfer,
1701};
1702
1703static const struct snd_pcm_ops snd_cs46xx_playback_iec958_ops = {
1704        .open =                 snd_cs46xx_playback_open_iec958,
1705        .close =                snd_cs46xx_playback_close_iec958,
1706        .ioctl =                snd_pcm_lib_ioctl,
1707        .hw_params =            snd_cs46xx_playback_hw_params,
1708        .hw_free =              snd_cs46xx_playback_hw_free,
1709        .prepare =              snd_cs46xx_playback_prepare,
1710        .trigger =              snd_cs46xx_playback_trigger,
1711        .pointer =              snd_cs46xx_playback_direct_pointer,
1712};
1713
1714static const struct snd_pcm_ops snd_cs46xx_playback_indirect_iec958_ops = {
1715        .open =                 snd_cs46xx_playback_open_iec958,
1716        .close =                snd_cs46xx_playback_close_iec958,
1717        .ioctl =                snd_pcm_lib_ioctl,
1718        .hw_params =            snd_cs46xx_playback_hw_params,
1719        .hw_free =              snd_cs46xx_playback_hw_free,
1720        .prepare =              snd_cs46xx_playback_prepare,
1721        .trigger =              snd_cs46xx_playback_trigger,
1722        .pointer =              snd_cs46xx_playback_indirect_pointer,
1723        .ack =                  snd_cs46xx_playback_transfer,
1724};
1725
1726#endif
1727
1728static const struct snd_pcm_ops snd_cs46xx_playback_ops = {
1729        .open =                 snd_cs46xx_playback_open,
1730        .close =                snd_cs46xx_playback_close,
1731        .ioctl =                snd_pcm_lib_ioctl,
1732        .hw_params =            snd_cs46xx_playback_hw_params,
1733        .hw_free =              snd_cs46xx_playback_hw_free,
1734        .prepare =              snd_cs46xx_playback_prepare,
1735        .trigger =              snd_cs46xx_playback_trigger,
1736        .pointer =              snd_cs46xx_playback_direct_pointer,
1737};
1738
1739static const struct snd_pcm_ops snd_cs46xx_playback_indirect_ops = {
1740        .open =                 snd_cs46xx_playback_open,
1741        .close =                snd_cs46xx_playback_close,
1742        .ioctl =                snd_pcm_lib_ioctl,
1743        .hw_params =            snd_cs46xx_playback_hw_params,
1744        .hw_free =              snd_cs46xx_playback_hw_free,
1745        .prepare =              snd_cs46xx_playback_prepare,
1746        .trigger =              snd_cs46xx_playback_trigger,
1747        .pointer =              snd_cs46xx_playback_indirect_pointer,
1748        .ack =                  snd_cs46xx_playback_transfer,
1749};
1750
1751static const struct snd_pcm_ops snd_cs46xx_capture_ops = {
1752        .open =                 snd_cs46xx_capture_open,
1753        .close =                snd_cs46xx_capture_close,
1754        .ioctl =                snd_pcm_lib_ioctl,
1755        .hw_params =            snd_cs46xx_capture_hw_params,
1756        .hw_free =              snd_cs46xx_capture_hw_free,
1757        .prepare =              snd_cs46xx_capture_prepare,
1758        .trigger =              snd_cs46xx_capture_trigger,
1759        .pointer =              snd_cs46xx_capture_direct_pointer,
1760};
1761
1762static const struct snd_pcm_ops snd_cs46xx_capture_indirect_ops = {
1763        .open =                 snd_cs46xx_capture_open,
1764        .close =                snd_cs46xx_capture_close,
1765        .ioctl =                snd_pcm_lib_ioctl,
1766        .hw_params =            snd_cs46xx_capture_hw_params,
1767        .hw_free =              snd_cs46xx_capture_hw_free,
1768        .prepare =              snd_cs46xx_capture_prepare,
1769        .trigger =              snd_cs46xx_capture_trigger,
1770        .pointer =              snd_cs46xx_capture_indirect_pointer,
1771        .ack =                  snd_cs46xx_capture_transfer,
1772};
1773
1774#ifdef CONFIG_SND_CS46XX_NEW_DSP
1775#define MAX_PLAYBACK_CHANNELS   (DSP_MAX_PCM_CHANNELS - 1)
1776#else
1777#define MAX_PLAYBACK_CHANNELS   1
1778#endif
1779
1780int snd_cs46xx_pcm(struct snd_cs46xx *chip, int device)
1781{
1782        struct snd_pcm *pcm;
1783        int err;
1784
1785        if ((err = snd_pcm_new(chip->card, "CS46xx", device, MAX_PLAYBACK_CHANNELS, 1, &pcm)) < 0)
1786                return err;
1787
1788        pcm->private_data = chip;
1789
1790        snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_cs46xx_playback_ops);
1791        snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_cs46xx_capture_ops);
1792
1793        /* global setup */
1794        pcm->info_flags = 0;
1795        strcpy(pcm->name, "CS46xx");
1796        chip->pcm = pcm;
1797
1798        snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
1799                                              snd_dma_pci_data(chip->pci), 64*1024, 256*1024);
1800
1801        return 0;
1802}
1803
1804
1805#ifdef CONFIG_SND_CS46XX_NEW_DSP
1806int snd_cs46xx_pcm_rear(struct snd_cs46xx *chip, int device)
1807{
1808        struct snd_pcm *pcm;
1809        int err;
1810
1811        if ((err = snd_pcm_new(chip->card, "CS46xx - Rear", device, MAX_PLAYBACK_CHANNELS, 0, &pcm)) < 0)
1812                return err;
1813
1814        pcm->private_data = chip;
1815
1816        snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_cs46xx_playback_rear_ops);
1817
1818        /* global setup */
1819        pcm->info_flags = 0;
1820        strcpy(pcm->name, "CS46xx - Rear");
1821        chip->pcm_rear = pcm;
1822
1823        snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
1824                                              snd_dma_pci_data(chip->pci), 64*1024, 256*1024);
1825
1826        return 0;
1827}
1828
1829int snd_cs46xx_pcm_center_lfe(struct snd_cs46xx *chip, int device)
1830{
1831        struct snd_pcm *pcm;
1832        int err;
1833
1834        if ((err = snd_pcm_new(chip->card, "CS46xx - Center LFE", device, MAX_PLAYBACK_CHANNELS, 0, &pcm)) < 0)
1835                return err;
1836
1837        pcm->private_data = chip;
1838
1839        snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_cs46xx_playback_clfe_ops);
1840
1841        /* global setup */
1842        pcm->info_flags = 0;
1843        strcpy(pcm->name, "CS46xx - Center LFE");
1844        chip->pcm_center_lfe = pcm;
1845
1846        snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
1847                                              snd_dma_pci_data(chip->pci), 64*1024, 256*1024);
1848
1849        return 0;
1850}
1851
1852int snd_cs46xx_pcm_iec958(struct snd_cs46xx *chip, int device)
1853{
1854        struct snd_pcm *pcm;
1855        int err;
1856
1857        if ((err = snd_pcm_new(chip->card, "CS46xx - IEC958", device, 1, 0, &pcm)) < 0)
1858                return err;
1859
1860        pcm->private_data = chip;
1861
1862        snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_cs46xx_playback_iec958_ops);
1863
1864        /* global setup */
1865        pcm->info_flags = 0;
1866        strcpy(pcm->name, "CS46xx - IEC958");
1867        chip->pcm_iec958 = pcm;
1868
1869        snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
1870                                              snd_dma_pci_data(chip->pci), 64*1024, 256*1024);
1871
1872        return 0;
1873}
1874#endif
1875
1876/*
1877 *  Mixer routines
1878 */
1879static void snd_cs46xx_mixer_free_ac97_bus(struct snd_ac97_bus *bus)
1880{
1881        struct snd_cs46xx *chip = bus->private_data;
1882
1883        chip->ac97_bus = NULL;
1884}
1885
1886static void snd_cs46xx_mixer_free_ac97(struct snd_ac97 *ac97)
1887{
1888        struct snd_cs46xx *chip = ac97->private_data;
1889
1890        if (snd_BUG_ON(ac97 != chip->ac97[CS46XX_PRIMARY_CODEC_INDEX] &&
1891                       ac97 != chip->ac97[CS46XX_SECONDARY_CODEC_INDEX]))
1892                return;
1893
1894        if (ac97 == chip->ac97[CS46XX_PRIMARY_CODEC_INDEX]) {
1895                chip->ac97[CS46XX_PRIMARY_CODEC_INDEX] = NULL;
1896                chip->eapd_switch = NULL;
1897        }
1898        else
1899                chip->ac97[CS46XX_SECONDARY_CODEC_INDEX] = NULL;
1900}
1901
1902static int snd_cs46xx_vol_info(struct snd_kcontrol *kcontrol, 
1903                               struct snd_ctl_elem_info *uinfo)
1904{
1905        uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
1906        uinfo->count = 2;
1907        uinfo->value.integer.min = 0;
1908        uinfo->value.integer.max = 0x7fff;
1909        return 0;
1910}
1911
1912static int snd_cs46xx_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1913{
1914        struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol);
1915        int reg = kcontrol->private_value;
1916        unsigned int val = snd_cs46xx_peek(chip, reg);
1917        ucontrol->value.integer.value[0] = 0xffff - (val >> 16);
1918        ucontrol->value.integer.value[1] = 0xffff - (val & 0xffff);
1919        return 0;
1920}
1921
1922static int snd_cs46xx_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1923{
1924        struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol);
1925        int reg = kcontrol->private_value;
1926        unsigned int val = ((0xffff - ucontrol->value.integer.value[0]) << 16 | 
1927                            (0xffff - ucontrol->value.integer.value[1]));
1928        unsigned int old = snd_cs46xx_peek(chip, reg);
1929        int change = (old != val);
1930
1931        if (change) {
1932                snd_cs46xx_poke(chip, reg, val);
1933        }
1934
1935        return change;
1936}
1937
1938#ifdef CONFIG_SND_CS46XX_NEW_DSP
1939
1940static int snd_cs46xx_vol_dac_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1941{
1942        struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol);
1943
1944        ucontrol->value.integer.value[0] = chip->dsp_spos_instance->dac_volume_left;
1945        ucontrol->value.integer.value[1] = chip->dsp_spos_instance->dac_volume_right;
1946
1947        return 0;
1948}
1949
1950static int snd_cs46xx_vol_dac_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1951{
1952        struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol);
1953        int change = 0;
1954
1955        if (chip->dsp_spos_instance->dac_volume_right != ucontrol->value.integer.value[0] ||
1956            chip->dsp_spos_instance->dac_volume_left != ucontrol->value.integer.value[1]) {
1957                cs46xx_dsp_set_dac_volume(chip,
1958                                          ucontrol->value.integer.value[0],
1959                                          ucontrol->value.integer.value[1]);
1960                change = 1;
1961        }
1962
1963        return change;
1964}
1965
1966#if 0
1967static int snd_cs46xx_vol_iec958_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1968{
1969        struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol);
1970
1971        ucontrol->value.integer.value[0] = chip->dsp_spos_instance->spdif_input_volume_left;
1972        ucontrol->value.integer.value[1] = chip->dsp_spos_instance->spdif_input_volume_right;
1973        return 0;
1974}
1975
1976static int snd_cs46xx_vol_iec958_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1977{
1978        struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol);
1979        int change = 0;
1980
1981        if (chip->dsp_spos_instance->spdif_input_volume_left  != ucontrol->value.integer.value[0] ||
1982            chip->dsp_spos_instance->spdif_input_volume_right!= ucontrol->value.integer.value[1]) {
1983                cs46xx_dsp_set_iec958_volume (chip,
1984                                              ucontrol->value.integer.value[0],
1985                                              ucontrol->value.integer.value[1]);
1986                change = 1;
1987        }
1988
1989        return change;
1990}
1991#endif
1992
1993#define snd_mixer_boolean_info          snd_ctl_boolean_mono_info
1994
1995static int snd_cs46xx_iec958_get(struct snd_kcontrol *kcontrol, 
1996                                 struct snd_ctl_elem_value *ucontrol)
1997{
1998        struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol);
1999        int reg = kcontrol->private_value;
2000
2001        if (reg == CS46XX_MIXER_SPDIF_OUTPUT_ELEMENT)
2002                ucontrol->value.integer.value[0] = (chip->dsp_spos_instance->spdif_status_out & DSP_SPDIF_STATUS_OUTPUT_ENABLED);
2003        else
2004                ucontrol->value.integer.value[0] = chip->dsp_spos_instance->spdif_status_in;
2005
2006        return 0;
2007}
2008
2009static int snd_cs46xx_iec958_put(struct snd_kcontrol *kcontrol, 
2010                                  struct snd_ctl_elem_value *ucontrol)
2011{
2012        struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol);
2013        int change, res;
2014
2015        switch (kcontrol->private_value) {
2016        case CS46XX_MIXER_SPDIF_OUTPUT_ELEMENT:
2017                mutex_lock(&chip->spos_mutex);
2018                change = (chip->dsp_spos_instance->spdif_status_out & DSP_SPDIF_STATUS_OUTPUT_ENABLED);
2019                if (ucontrol->value.integer.value[0] && !change) 
2020                        cs46xx_dsp_enable_spdif_out(chip);
2021                else if (change && !ucontrol->value.integer.value[0])
2022                        cs46xx_dsp_disable_spdif_out(chip);
2023
2024                res = (change != (chip->dsp_spos_instance->spdif_status_out & DSP_SPDIF_STATUS_OUTPUT_ENABLED));
2025                mutex_unlock(&chip->spos_mutex);
2026                break;
2027        case CS46XX_MIXER_SPDIF_INPUT_ELEMENT:
2028                change = chip->dsp_spos_instance->spdif_status_in;
2029                if (ucontrol->value.integer.value[0] && !change) {
2030                        cs46xx_dsp_enable_spdif_in(chip);
2031                        /* restore volume */
2032                }
2033                else if (change && !ucontrol->value.integer.value[0])
2034                        cs46xx_dsp_disable_spdif_in(chip);
2035                
2036                res = (change != chip->dsp_spos_instance->spdif_status_in);
2037                break;
2038        default:
2039                res = -EINVAL;
2040                snd_BUG(); /* should never happen ... */
2041        }
2042
2043        return res;
2044}
2045
2046static int snd_cs46xx_adc_capture_get(struct snd_kcontrol *kcontrol, 
2047                                      struct snd_ctl_elem_value *ucontrol)
2048{
2049        struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol);
2050        struct dsp_spos_instance * ins = chip->dsp_spos_instance;
2051
2052        if (ins->adc_input != NULL) 
2053                ucontrol->value.integer.value[0] = 1;
2054        else 
2055                ucontrol->value.integer.value[0] = 0;
2056        
2057        return 0;
2058}
2059
2060static int snd_cs46xx_adc_capture_put(struct snd_kcontrol *kcontrol, 
2061                                      struct snd_ctl_elem_value *ucontrol)
2062{
2063        struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol);
2064        struct dsp_spos_instance * ins = chip->dsp_spos_instance;
2065        int change = 0;
2066
2067        if (ucontrol->value.integer.value[0] && !ins->adc_input) {
2068                cs46xx_dsp_enable_adc_capture(chip);
2069                change = 1;
2070        } else  if (!ucontrol->value.integer.value[0] && ins->adc_input) {
2071                cs46xx_dsp_disable_adc_capture(chip);
2072                change = 1;
2073        }
2074        return change;
2075}
2076
2077static int snd_cs46xx_pcm_capture_get(struct snd_kcontrol *kcontrol, 
2078                                      struct snd_ctl_elem_value *ucontrol)
2079{
2080        struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol);
2081        struct dsp_spos_instance * ins = chip->dsp_spos_instance;
2082
2083        if (ins->pcm_input != NULL) 
2084                ucontrol->value.integer.value[0] = 1;
2085        else 
2086                ucontrol->value.integer.value[0] = 0;
2087
2088        return 0;
2089}
2090
2091
2092static int snd_cs46xx_pcm_capture_put(struct snd_kcontrol *kcontrol, 
2093                                      struct snd_ctl_elem_value *ucontrol)
2094{
2095        struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol);
2096        struct dsp_spos_instance * ins = chip->dsp_spos_instance;
2097        int change = 0;
2098
2099        if (ucontrol->value.integer.value[0] && !ins->pcm_input) {
2100                cs46xx_dsp_enable_pcm_capture(chip);
2101                change = 1;
2102        } else  if (!ucontrol->value.integer.value[0] && ins->pcm_input) {
2103                cs46xx_dsp_disable_pcm_capture(chip);
2104                change = 1;
2105        }
2106
2107        return change;
2108}
2109
2110static int snd_herc_spdif_select_get(struct snd_kcontrol *kcontrol, 
2111                                     struct snd_ctl_elem_value *ucontrol)
2112{
2113        struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol);
2114
2115        int val1 = snd_cs46xx_peekBA0(chip, BA0_EGPIODR);
2116
2117        if (val1 & EGPIODR_GPOE0)
2118                ucontrol->value.integer.value[0] = 1;
2119        else
2120                ucontrol->value.integer.value[0] = 0;
2121
2122        return 0;
2123}
2124
2125/*
2126 *      Game Theatre XP card - EGPIO[0] is used to select SPDIF input optical or coaxial.
2127 */ 
2128static int snd_herc_spdif_select_put(struct snd_kcontrol *kcontrol, 
2129                                       struct snd_ctl_elem_value *ucontrol)
2130{
2131        struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol);
2132        int val1 = snd_cs46xx_peekBA0(chip, BA0_EGPIODR);
2133        int val2 = snd_cs46xx_peekBA0(chip, BA0_EGPIOPTR);
2134
2135        if (ucontrol->value.integer.value[0]) {
2136                /* optical is default */
2137                snd_cs46xx_pokeBA0(chip, BA0_EGPIODR, 
2138                                   EGPIODR_GPOE0 | val1);  /* enable EGPIO0 output */
2139                snd_cs46xx_pokeBA0(chip, BA0_EGPIOPTR, 
2140                                   EGPIOPTR_GPPT0 | val2); /* open-drain on output */
2141        } else {
2142                /* coaxial */
2143                snd_cs46xx_pokeBA0(chip, BA0_EGPIODR,  val1 & ~EGPIODR_GPOE0); /* disable */
2144                snd_cs46xx_pokeBA0(chip, BA0_EGPIOPTR, val2 & ~EGPIOPTR_GPPT0); /* disable */
2145        }
2146
2147        /* checking diff from the EGPIO direction register 
2148           should be enough */
2149        return (val1 != (int)snd_cs46xx_peekBA0(chip, BA0_EGPIODR));
2150}
2151
2152
2153static int snd_cs46xx_spdif_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
2154{
2155        uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
2156        uinfo->count = 1;
2157        return 0;
2158}
2159
2160static int snd_cs46xx_spdif_default_get(struct snd_kcontrol *kcontrol,
2161                                        struct snd_ctl_elem_value *ucontrol)
2162{
2163        struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol);
2164        struct dsp_spos_instance * ins = chip->dsp_spos_instance;
2165
2166        mutex_lock(&chip->spos_mutex);
2167        ucontrol->value.iec958.status[0] = _wrap_all_bits((ins->spdif_csuv_default >> 24) & 0xff);
2168        ucontrol->value.iec958.status[1] = _wrap_all_bits((ins->spdif_csuv_default >> 16) & 0xff);
2169        ucontrol->value.iec958.status[2] = 0;
2170        ucontrol->value.iec958.status[3] = _wrap_all_bits((ins->spdif_csuv_default) & 0xff);
2171        mutex_unlock(&chip->spos_mutex);
2172
2173        return 0;
2174}
2175
2176static int snd_cs46xx_spdif_default_put(struct snd_kcontrol *kcontrol,
2177                                        struct snd_ctl_elem_value *ucontrol)
2178{
2179        struct snd_cs46xx * chip = snd_kcontrol_chip(kcontrol);
2180        struct dsp_spos_instance * ins = chip->dsp_spos_instance;
2181        unsigned int val;
2182        int change;
2183
2184        mutex_lock(&chip->spos_mutex);
2185        val = ((unsigned int)_wrap_all_bits(ucontrol->value.iec958.status[0]) << 24) |
2186                ((unsigned int)_wrap_all_bits(ucontrol->value.iec958.status[2]) << 16) |
2187                ((unsigned int)_wrap_all_bits(ucontrol->value.iec958.status[3]))  |
2188                /* left and right validity bit */
2189                (1 << 13) | (1 << 12);
2190
2191
2192        change = (unsigned int)ins->spdif_csuv_default != val;
2193        ins->spdif_csuv_default = val;
2194
2195        if ( !(ins->spdif_status_out & DSP_SPDIF_STATUS_PLAYBACK_OPEN) )
2196                cs46xx_poke_via_dsp (chip,SP_SPDOUT_CSUV,val);
2197
2198        mutex_unlock(&chip->spos_mutex);
2199
2200        return change;
2201}
2202
2203static int snd_cs46xx_spdif_mask_get(struct snd_kcontrol *kcontrol,
2204                                     struct snd_ctl_elem_value *ucontrol)
2205{
2206        ucontrol->value.iec958.status[0] = 0xff;
2207        ucontrol->value.iec958.status[1] = 0xff;
2208        ucontrol->value.iec958.status[2] = 0x00;
2209        ucontrol->value.iec958.status[3] = 0xff;
2210        return 0;
2211}
2212
2213static int snd_cs46xx_spdif_stream_get(struct snd_kcontrol *kcontrol,
2214                                         struct snd_ctl_elem_value *ucontrol)
2215{
2216        struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol);
2217        struct dsp_spos_instance * ins = chip->dsp_spos_instance;
2218
2219        mutex_lock(&chip->spos_mutex);
2220        ucontrol->value.iec958.status[0] = _wrap_all_bits((ins->spdif_csuv_stream >> 24) & 0xff);
2221        ucontrol->value.iec958.status[1] = _wrap_all_bits((ins->spdif_csuv_stream >> 16) & 0xff);
2222        ucontrol->value.iec958.status[2] = 0;
2223        ucontrol->value.iec958.status[3] = _wrap_all_bits((ins->spdif_csuv_stream) & 0xff);
2224        mutex_unlock(&chip->spos_mutex);
2225
2226        return 0;
2227}
2228
2229static int snd_cs46xx_spdif_stream_put(struct snd_kcontrol *kcontrol,
2230                                        struct snd_ctl_elem_value *ucontrol)
2231{
2232        struct snd_cs46xx * chip = snd_kcontrol_chip(kcontrol);
2233        struct dsp_spos_instance * ins = chip->dsp_spos_instance;
2234        unsigned int val;
2235        int change;
2236
2237        mutex_lock(&chip->spos_mutex);
2238        val = ((unsigned int)_wrap_all_bits(ucontrol->value.iec958.status[0]) << 24) |
2239                ((unsigned int)_wrap_all_bits(ucontrol->value.iec958.status[1]) << 16) |
2240                ((unsigned int)_wrap_all_bits(ucontrol->value.iec958.status[3])) |
2241                /* left and right validity bit */
2242                (1 << 13) | (1 << 12);
2243
2244
2245        change = ins->spdif_csuv_stream != val;
2246        ins->spdif_csuv_stream = val;
2247
2248        if ( ins->spdif_status_out & DSP_SPDIF_STATUS_PLAYBACK_OPEN )
2249                cs46xx_poke_via_dsp (chip,SP_SPDOUT_CSUV,val);
2250
2251        mutex_unlock(&chip->spos_mutex);
2252
2253        return change;
2254}
2255
2256#endif /* CONFIG_SND_CS46XX_NEW_DSP */
2257
2258
2259static struct snd_kcontrol_new snd_cs46xx_controls[] = {
2260{
2261        .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2262        .name = "DAC Volume",
2263        .info = snd_cs46xx_vol_info,
2264#ifndef CONFIG_SND_CS46XX_NEW_DSP
2265        .get = snd_cs46xx_vol_get,
2266        .put = snd_cs46xx_vol_put,
2267        .private_value = BA1_PVOL,
2268#else
2269        .get = snd_cs46xx_vol_dac_get,
2270        .put = snd_cs46xx_vol_dac_put,
2271#endif
2272},
2273
2274{
2275        .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2276        .name = "ADC Volume",
2277        .info = snd_cs46xx_vol_info,
2278        .get = snd_cs46xx_vol_get,
2279        .put = snd_cs46xx_vol_put,
2280#ifndef CONFIG_SND_CS46XX_NEW_DSP
2281        .private_value = BA1_CVOL,
2282#else
2283        .private_value = (VARIDECIMATE_SCB_ADDR + 0xE) << 2,
2284#endif
2285},
2286#ifdef CONFIG_SND_CS46XX_NEW_DSP
2287{
2288        .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2289        .name = "ADC Capture Switch",
2290        .info = snd_mixer_boolean_info,
2291        .get = snd_cs46xx_adc_capture_get,
2292        .put = snd_cs46xx_adc_capture_put
2293},
2294{
2295        .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2296        .name = "DAC Capture Switch",
2297        .info = snd_mixer_boolean_info,
2298        .get = snd_cs46xx_pcm_capture_get,
2299        .put = snd_cs46xx_pcm_capture_put
2300},
2301{
2302        .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2303        .name = SNDRV_CTL_NAME_IEC958("Output ",NONE,SWITCH),
2304        .info = snd_mixer_boolean_info,
2305        .get = snd_cs46xx_iec958_get,
2306        .put = snd_cs46xx_iec958_put,
2307        .private_value = CS46XX_MIXER_SPDIF_OUTPUT_ELEMENT,
2308},
2309{
2310        .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2311        .name = SNDRV_CTL_NAME_IEC958("Input ",NONE,SWITCH),
2312        .info = snd_mixer_boolean_info,
2313        .get = snd_cs46xx_iec958_get,
2314        .put = snd_cs46xx_iec958_put,
2315        .private_value = CS46XX_MIXER_SPDIF_INPUT_ELEMENT,
2316},
2317#if 0
2318/* Input IEC958 volume does not work for the moment. (Benny) */
2319{
2320        .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2321        .name = SNDRV_CTL_NAME_IEC958("Input ",NONE,VOLUME),
2322        .info = snd_cs46xx_vol_info,
2323        .get = snd_cs46xx_vol_iec958_get,
2324        .put = snd_cs46xx_vol_iec958_put,
2325        .private_value = (ASYNCRX_SCB_ADDR + 0xE) << 2,
2326},
2327#endif
2328{
2329        .iface = SNDRV_CTL_ELEM_IFACE_PCM,
2330        .name =  SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),
2331        .info =  snd_cs46xx_spdif_info,
2332        .get =   snd_cs46xx_spdif_default_get,
2333        .put =   snd_cs46xx_spdif_default_put,
2334},
2335{
2336        .iface = SNDRV_CTL_ELEM_IFACE_PCM,
2337        .name =  SNDRV_CTL_NAME_IEC958("",PLAYBACK,MASK),
2338        .info =  snd_cs46xx_spdif_info,
2339        .get =   snd_cs46xx_spdif_mask_get,
2340        .access = SNDRV_CTL_ELEM_ACCESS_READ
2341},
2342{
2343        .iface = SNDRV_CTL_ELEM_IFACE_PCM,
2344        .name =  SNDRV_CTL_NAME_IEC958("",PLAYBACK,PCM_STREAM),
2345        .info =  snd_cs46xx_spdif_info,
2346        .get =   snd_cs46xx_spdif_stream_get,
2347        .put =   snd_cs46xx_spdif_stream_put
2348},
2349
2350#endif
2351};
2352
2353#ifdef CONFIG_SND_CS46XX_NEW_DSP
2354/* set primary cs4294 codec into Extended Audio Mode */
2355static int snd_cs46xx_front_dup_get(struct snd_kcontrol *kcontrol, 
2356                                    struct snd_ctl_elem_value *ucontrol)
2357{
2358        struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol);
2359        unsigned short val;
2360        val = snd_ac97_read(chip->ac97[CS46XX_PRIMARY_CODEC_INDEX], AC97_CSR_ACMODE);
2361        ucontrol->value.integer.value[0] = (val & 0x200) ? 0 : 1;
2362        return 0;
2363}
2364
2365static int snd_cs46xx_front_dup_put(struct snd_kcontrol *kcontrol, 
2366                                    struct snd_ctl_elem_value *ucontrol)
2367{
2368        struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol);
2369        return snd_ac97_update_bits(chip->ac97[CS46XX_PRIMARY_CODEC_INDEX],
2370                                    AC97_CSR_ACMODE, 0x200,
2371                                    ucontrol->value.integer.value[0] ? 0 : 0x200);
2372}
2373
2374static const struct snd_kcontrol_new snd_cs46xx_front_dup_ctl = {
2375        .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2376        .name = "Duplicate Front",
2377        .info = snd_mixer_boolean_info,
2378        .get = snd_cs46xx_front_dup_get,
2379        .put = snd_cs46xx_front_dup_put,
2380};
2381#endif
2382
2383#ifdef CONFIG_SND_CS46XX_NEW_DSP
2384/* Only available on the Hercules Game Theater XP soundcard */
2385static struct snd_kcontrol_new snd_hercules_controls[] = {
2386{
2387        .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2388        .name = "Optical/Coaxial SPDIF Input Switch",
2389        .info = snd_mixer_boolean_info,
2390        .get = snd_herc_spdif_select_get,
2391        .put = snd_herc_spdif_select_put,
2392},
2393};
2394
2395
2396static void snd_cs46xx_codec_reset (struct snd_ac97 * ac97)
2397{
2398        unsigned long end_time;
2399        int err;
2400
2401        /* reset to defaults */
2402        snd_ac97_write(ac97, AC97_RESET, 0);    
2403
2404        /* set the desired CODEC mode */
2405        if (ac97->num == CS46XX_PRIMARY_CODEC_INDEX) {
2406                dev_dbg(ac97->bus->card->dev, "CODEC1 mode %04x\n", 0x0);
2407                snd_cs46xx_ac97_write(ac97, AC97_CSR_ACMODE, 0x0);
2408        } else if (ac97->num == CS46XX_SECONDARY_CODEC_INDEX) {
2409                dev_dbg(ac97->bus->card->dev, "CODEC2 mode %04x\n", 0x3);
2410                snd_cs46xx_ac97_write(ac97, AC97_CSR_ACMODE, 0x3);
2411        } else {
2412                snd_BUG(); /* should never happen ... */
2413        }
2414
2415        udelay(50);
2416
2417        /* it's necessary to wait awhile until registers are accessible after RESET */
2418        /* because the PCM or MASTER volume registers can be modified, */
2419        /* the REC_GAIN register is used for tests */
2420        end_time = jiffies + HZ;
2421        do {
2422                unsigned short ext_mid;
2423    
2424                /* use preliminary reads to settle the communication */
2425                snd_ac97_read(ac97, AC97_RESET);
2426                snd_ac97_read(ac97, AC97_VENDOR_ID1);
2427                snd_ac97_read(ac97, AC97_VENDOR_ID2);
2428                /* modem? */
2429                ext_mid = snd_ac97_read(ac97, AC97_EXTENDED_MID);
2430                if (ext_mid != 0xffff && (ext_mid & 1) != 0)
2431                        return;
2432
2433                /* test if we can write to the record gain volume register */
2434                snd_ac97_write(ac97, AC97_REC_GAIN, 0x8a05);
2435                if ((err = snd_ac97_read(ac97, AC97_REC_GAIN)) == 0x8a05)
2436                        return;
2437
2438                msleep(10);
2439        } while (time_after_eq(end_time, jiffies));
2440
2441        dev_err(ac97->bus->card->dev,
2442                "CS46xx secondary codec doesn't respond!\n");
2443}
2444#endif
2445
2446static int cs46xx_detect_codec(struct snd_cs46xx *chip, int codec)
2447{
2448        int idx, err;
2449        struct snd_ac97_template ac97;
2450
2451        memset(&ac97, 0, sizeof(ac97));
2452        ac97.private_data = chip;
2453        ac97.private_free = snd_cs46xx_mixer_free_ac97;
2454        ac97.num = codec;
2455        if (chip->amplifier_ctrl == amp_voyetra)
2456                ac97.scaps = AC97_SCAP_INV_EAPD;
2457
2458        if (codec == CS46XX_SECONDARY_CODEC_INDEX) {
2459                snd_cs46xx_codec_write(chip, AC97_RESET, 0, codec);
2460                udelay(10);
2461                if (snd_cs46xx_codec_read(chip, AC97_RESET, codec) & 0x8000) {
2462                        dev_dbg(chip->card->dev,
2463                                "secondary codec not present\n");
2464                        return -ENXIO;
2465                }
2466        }
2467
2468        snd_cs46xx_codec_write(chip, AC97_MASTER, 0x8000, codec);
2469        for (idx = 0; idx < 100; ++idx) {
2470                if (snd_cs46xx_codec_read(chip, AC97_MASTER, codec) == 0x8000) {
2471                        err = snd_ac97_mixer(chip->ac97_bus, &ac97, &chip->ac97[codec]);
2472                        return err;
2473                }
2474                msleep(10);
2475        }
2476        dev_dbg(chip->card->dev, "codec %d detection timeout\n", codec);
2477        return -ENXIO;
2478}
2479
2480int snd_cs46xx_mixer(struct snd_cs46xx *chip, int spdif_device)
2481{
2482        struct snd_card *card = chip->card;
2483        struct snd_ctl_elem_id id;
2484        int err;
2485        unsigned int idx;
2486        static struct snd_ac97_bus_ops ops = {
2487#ifdef CONFIG_SND_CS46XX_NEW_DSP
2488                .reset = snd_cs46xx_codec_reset,
2489#endif
2490                .write = snd_cs46xx_ac97_write,
2491                .read = snd_cs46xx_ac97_read,
2492        };
2493
2494        /* detect primary codec */
2495        chip->nr_ac97_codecs = 0;
2496        dev_dbg(chip->card->dev, "detecting primary codec\n");
2497        if ((err = snd_ac97_bus(card, 0, &ops, chip, &chip->ac97_bus)) < 0)
2498                return err;
2499        chip->ac97_bus->private_free = snd_cs46xx_mixer_free_ac97_bus;
2500
2501        if (cs46xx_detect_codec(chip, CS46XX_PRIMARY_CODEC_INDEX) < 0)
2502                return -ENXIO;
2503        chip->nr_ac97_codecs = 1;
2504
2505#ifdef CONFIG_SND_CS46XX_NEW_DSP
2506        dev_dbg(chip->card->dev, "detecting secondary codec\n");
2507        /* try detect a secondary codec */
2508        if (! cs46xx_detect_codec(chip, CS46XX_SECONDARY_CODEC_INDEX))
2509                chip->nr_ac97_codecs = 2;
2510#endif /* CONFIG_SND_CS46XX_NEW_DSP */
2511
2512        /* add cs4630 mixer controls */
2513        for (idx = 0; idx < ARRAY_SIZE(snd_cs46xx_controls); idx++) {
2514                struct snd_kcontrol *kctl;
2515                kctl = snd_ctl_new1(&snd_cs46xx_controls[idx], chip);
2516                if (kctl && kctl->id.iface == SNDRV_CTL_ELEM_IFACE_PCM)
2517                        kctl->id.device = spdif_device;
2518                if ((err = snd_ctl_add(card, kctl)) < 0)
2519                        return err;
2520        }
2521
2522        /* get EAPD mixer switch (for voyetra hack) */
2523        memset(&id, 0, sizeof(id));
2524        id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
2525        strcpy(id.name, "External Amplifier");
2526        chip->eapd_switch = snd_ctl_find_id(chip->card, &id);
2527    
2528#ifdef CONFIG_SND_CS46XX_NEW_DSP
2529        if (chip->nr_ac97_codecs == 1) {
2530                unsigned int id2 = chip->ac97[CS46XX_PRIMARY_CODEC_INDEX]->id & 0xffff;
2531                if ((id2 & 0xfff0) == 0x5920) { /* CS4294 and CS4298 */
2532                        err = snd_ctl_add(card, snd_ctl_new1(&snd_cs46xx_front_dup_ctl, chip));
2533                        if (err < 0)
2534                                return err;
2535                        snd_ac97_write_cache(chip->ac97[CS46XX_PRIMARY_CODEC_INDEX],
2536                                             AC97_CSR_ACMODE, 0x200);
2537                }
2538        }
2539        /* do soundcard specific mixer setup */
2540        if (chip->mixer_init) {
2541                dev_dbg(chip->card->dev, "calling chip->mixer_init(chip);\n");
2542                chip->mixer_init(chip);
2543        }
2544#endif
2545
2546        /* turn on amplifier */
2547        chip->amplifier_ctrl(chip, 1);
2548    
2549        return 0;
2550}
2551
2552/*
2553 *  RawMIDI interface
2554 */
2555
2556static void snd_cs46xx_midi_reset(struct snd_cs46xx *chip)
2557{
2558        snd_cs46xx_pokeBA0(chip, BA0_MIDCR, MIDCR_MRST);
2559        udelay(100);
2560        snd_cs46xx_pokeBA0(chip, BA0_MIDCR, chip->midcr);
2561}
2562
2563static int snd_cs46xx_midi_input_open(struct snd_rawmidi_substream *substream)
2564{
2565        struct snd_cs46xx *chip = substream->rmidi->private_data;
2566
2567        chip->active_ctrl(chip, 1);
2568        spin_lock_irq(&chip->reg_lock);
2569        chip->uartm |= CS46XX_MODE_INPUT;
2570        chip->midcr |= MIDCR_RXE;
2571        chip->midi_input = substream;
2572        if (!(chip->uartm & CS46XX_MODE_OUTPUT)) {
2573                snd_cs46xx_midi_reset(chip);
2574        } else {
2575                snd_cs46xx_pokeBA0(chip, BA0_MIDCR, chip->midcr);
2576        }
2577        spin_unlock_irq(&chip->reg_lock);
2578        return 0;
2579}
2580
2581static int snd_cs46xx_midi_input_close(struct snd_rawmidi_substream *substream)
2582{
2583        struct snd_cs46xx *chip = substream->rmidi->private_data;
2584
2585        spin_lock_irq(&chip->reg_lock);
2586        chip->midcr &= ~(MIDCR_RXE | MIDCR_RIE);
2587        chip->midi_input = NULL;
2588        if (!(chip->uartm & CS46XX_MODE_OUTPUT)) {
2589                snd_cs46xx_midi_reset(chip);
2590        } else {
2591                snd_cs46xx_pokeBA0(chip, BA0_MIDCR, chip->midcr);
2592        }
2593        chip->uartm &= ~CS46XX_MODE_INPUT;
2594        spin_unlock_irq(&chip->reg_lock);
2595        chip->active_ctrl(chip, -1);
2596        return 0;
2597}
2598
2599static int snd_cs46xx_midi_output_open(struct snd_rawmidi_substream *substream)
2600{
2601        struct snd_cs46xx *chip = substream->rmidi->private_data;
2602
2603        chip->active_ctrl(chip, 1);
2604
2605        spin_lock_irq(&chip->reg_lock);
2606        chip->uartm |= CS46XX_MODE_OUTPUT;
2607        chip->midcr |= MIDCR_TXE;
2608        chip->midi_output = substream;
2609        if (!(chip->uartm & CS46XX_MODE_INPUT)) {
2610                snd_cs46xx_midi_reset(chip);
2611        } else {
2612                snd_cs46xx_pokeBA0(chip, BA0_MIDCR, chip->midcr);
2613        }
2614        spin_unlock_irq(&chip->reg_lock);
2615        return 0;
2616}
2617
2618static int snd_cs46xx_midi_output_close(struct snd_rawmidi_substream *substream)
2619{
2620        struct snd_cs46xx *chip = substream->rmidi->private_data;
2621
2622        spin_lock_irq(&chip->reg_lock);
2623        chip->midcr &= ~(MIDCR_TXE | MIDCR_TIE);
2624        chip->midi_output = NULL;
2625        if (!(chip->uartm & CS46XX_MODE_INPUT)) {
2626                snd_cs46xx_midi_reset(chip);
2627        } else {
2628                snd_cs46xx_pokeBA0(chip, BA0_MIDCR, chip->midcr);
2629        }
2630        chip->uartm &= ~CS46XX_MODE_OUTPUT;
2631        spin_unlock_irq(&chip->reg_lock);
2632        chip->active_ctrl(chip, -1);
2633        return 0;
2634}
2635
2636static void snd_cs46xx_midi_input_trigger(struct snd_rawmidi_substream *substream, int up)
2637{
2638        unsigned long flags;
2639        struct snd_cs46xx *chip = substream->rmidi->private_data;
2640
2641        spin_lock_irqsave(&chip->reg_lock, flags);
2642        if (up) {
2643                if ((chip->midcr & MIDCR_RIE) == 0) {
2644                        chip->midcr |= MIDCR_RIE;
2645                        snd_cs46xx_pokeBA0(chip, BA0_MIDCR, chip->midcr);
2646                }
2647        } else {
2648                if (chip->midcr & MIDCR_RIE) {
2649                        chip->midcr &= ~MIDCR_RIE;
2650                        snd_cs46xx_pokeBA0(chip, BA0_MIDCR, chip->midcr);
2651                }
2652        }
2653        spin_unlock_irqrestore(&chip->reg_lock, flags);
2654}
2655
2656static void snd_cs46xx_midi_output_trigger(struct snd_rawmidi_substream *substream, int up)
2657{
2658        unsigned long flags;
2659        struct snd_cs46xx *chip = substream->rmidi->private_data;
2660        unsigned char byte;
2661
2662        spin_lock_irqsave(&chip->reg_lock, flags);
2663        if (up) {
2664                if ((chip->midcr & MIDCR_TIE) == 0) {
2665                        chip->midcr |= MIDCR_TIE;
2666                        /* fill UART FIFO buffer at first, and turn Tx interrupts only if necessary */
2667                        while ((chip->midcr & MIDCR_TIE) &&
2668                               (snd_cs46xx_peekBA0(chip, BA0_MIDSR) & MIDSR_TBF) == 0) {
2669                                if (snd_rawmidi_transmit(substream, &byte, 1) != 1) {
2670                                        chip->midcr &= ~MIDCR_TIE;
2671                                } else {
2672                                        snd_cs46xx_pokeBA0(chip, BA0_MIDWP, byte);
2673                                }
2674                        }
2675                        snd_cs46xx_pokeBA0(chip, BA0_MIDCR, chip->midcr);
2676                }
2677        } else {
2678                if (chip->midcr & MIDCR_TIE) {
2679                        chip->midcr &= ~MIDCR_TIE;
2680                        snd_cs46xx_pokeBA0(chip, BA0_MIDCR, chip->midcr);
2681                }
2682        }
2683        spin_unlock_irqrestore(&chip->reg_lock, flags);
2684}
2685
2686static const struct snd_rawmidi_ops snd_cs46xx_midi_output =
2687{
2688        .open =         snd_cs46xx_midi_output_open,
2689        .close =        snd_cs46xx_midi_output_close,
2690        .trigger =      snd_cs46xx_midi_output_trigger,
2691};
2692
2693static const struct snd_rawmidi_ops snd_cs46xx_midi_input =
2694{
2695        .open =         snd_cs46xx_midi_input_open,
2696        .close =        snd_cs46xx_midi_input_close,
2697        .trigger =      snd_cs46xx_midi_input_trigger,
2698};
2699
2700int snd_cs46xx_midi(struct snd_cs46xx *chip, int device)
2701{
2702        struct snd_rawmidi *rmidi;
2703        int err;
2704
2705        if ((err = snd_rawmidi_new(chip->card, "CS46XX", device, 1, 1, &rmidi)) < 0)
2706                return err;
2707        strcpy(rmidi->name, "CS46XX");
2708        snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, &snd_cs46xx_midi_output);
2709        snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT, &snd_cs46xx_midi_input);
2710        rmidi->info_flags |= SNDRV_RAWMIDI_INFO_OUTPUT | SNDRV_RAWMIDI_INFO_INPUT | SNDRV_RAWMIDI_INFO_DUPLEX;
2711        rmidi->private_data = chip;
2712        chip->rmidi = rmidi;
2713        return 0;
2714}
2715
2716
2717/*
2718 * gameport interface
2719 */
2720
2721#if IS_REACHABLE(CONFIG_GAMEPORT)
2722
2723static void snd_cs46xx_gameport_trigger(struct gameport *gameport)
2724{
2725        struct snd_cs46xx *chip = gameport_get_port_data(gameport);
2726
2727        if (snd_BUG_ON(!chip))
2728                return;
2729        snd_cs46xx_pokeBA0(chip, BA0_JSPT, 0xFF);  //outb(gameport->io, 0xFF);
2730}
2731
2732static unsigned char snd_cs46xx_gameport_read(struct gameport *gameport)
2733{
2734        struct snd_cs46xx *chip = gameport_get_port_data(gameport);
2735
2736        if (snd_BUG_ON(!chip))
2737                return 0;
2738        return snd_cs46xx_peekBA0(chip, BA0_JSPT); //inb(gameport->io);
2739}
2740
2741static int snd_cs46xx_gameport_cooked_read(struct gameport *gameport, int *axes, int *buttons)
2742{
2743        struct snd_cs46xx *chip = gameport_get_port_data(gameport);
2744        unsigned js1, js2, jst;
2745
2746        if (snd_BUG_ON(!chip))
2747                return 0;
2748
2749        js1 = snd_cs46xx_peekBA0(chip, BA0_JSC1);
2750        js2 = snd_cs46xx_peekBA0(chip, BA0_JSC2);
2751        jst = snd_cs46xx_peekBA0(chip, BA0_JSPT);
2752        
2753        *buttons = (~jst >> 4) & 0x0F; 
2754        
2755        axes[0] = ((js1 & JSC1_Y1V_MASK) >> JSC1_Y1V_SHIFT) & 0xFFFF;
2756        axes[1] = ((js1 & JSC1_X1V_MASK) >> JSC1_X1V_SHIFT) & 0xFFFF;
2757        axes[2] = ((js2 & JSC2_Y2V_MASK) >> JSC2_Y2V_SHIFT) & 0xFFFF;
2758        axes[3] = ((js2 & JSC2_X2V_MASK) >> JSC2_X2V_SHIFT) & 0xFFFF;
2759
2760        for(jst=0;jst<4;++jst)
2761                if(axes[jst]==0xFFFF) axes[jst] = -1;
2762        return 0;
2763}
2764
2765static int snd_cs46xx_gameport_open(struct gameport *gameport, int mode)
2766{
2767        switch (mode) {
2768        case GAMEPORT_MODE_COOKED:
2769                return 0;
2770        case GAMEPORT_MODE_RAW:
2771                return 0;
2772        default:
2773                return -1;
2774        }
2775        return 0;
2776}
2777
2778int snd_cs46xx_gameport(struct snd_cs46xx *chip)
2779{
2780        struct gameport *gp;
2781
2782        chip->gameport = gp = gameport_allocate_port();
2783        if (!gp) {
2784                dev_err(chip->card->dev,
2785                        "cannot allocate memory for gameport\n");
2786                return -ENOMEM;
2787        }
2788
2789        gameport_set_name(gp, "CS46xx Gameport");
2790        gameport_set_phys(gp, "pci%s/gameport0", pci_name(chip->pci));
2791        gameport_set_dev_parent(gp, &chip->pci->dev);
2792        gameport_set_port_data(gp, chip);
2793
2794        gp->open = snd_cs46xx_gameport_open;
2795        gp->read = snd_cs46xx_gameport_read;
2796        gp->trigger = snd_cs46xx_gameport_trigger;
2797        gp->cooked_read = snd_cs46xx_gameport_cooked_read;
2798
2799        snd_cs46xx_pokeBA0(chip, BA0_JSIO, 0xFF); // ?
2800        snd_cs46xx_pokeBA0(chip, BA0_JSCTL, JSCTL_SP_MEDIUM_SLOW);
2801
2802        gameport_register_port(gp);
2803
2804        return 0;
2805}
2806
2807static inline void snd_cs46xx_remove_gameport(struct snd_cs46xx *chip)
2808{
2809        if (chip->gameport) {
2810                gameport_unregister_port(chip->gameport);
2811                chip->gameport = NULL;
2812        }
2813}
2814#else
2815int snd_cs46xx_gameport(struct snd_cs46xx *chip) { return -ENOSYS; }
2816static inline void snd_cs46xx_remove_gameport(struct snd_cs46xx *chip) { }
2817#endif /* CONFIG_GAMEPORT */
2818
2819#ifdef CONFIG_SND_PROC_FS
2820/*
2821 *  proc interface
2822 */
2823
2824static ssize_t snd_cs46xx_io_read(struct snd_info_entry *entry,
2825                                  void *file_private_data,
2826                                  struct file *file, char __user *buf,
2827                                  size_t count, loff_t pos)
2828{
2829        struct snd_cs46xx_region *region = entry->private_data;
2830        
2831        if (copy_to_user_fromio(buf, region->remap_addr + pos, count))
2832                return -EFAULT;
2833        return count;
2834}
2835
2836static struct snd_info_entry_ops snd_cs46xx_proc_io_ops = {
2837        .read = snd_cs46xx_io_read,
2838};
2839
2840static int snd_cs46xx_proc_init(struct snd_card *card, struct snd_cs46xx *chip)
2841{
2842        struct snd_info_entry *entry;
2843        int idx;
2844        
2845        for (idx = 0; idx < 5; idx++) {
2846                struct snd_cs46xx_region *region = &chip->region.idx[idx];
2847                if (! snd_card_proc_new(card, region->name, &entry)) {
2848                        entry->content = SNDRV_INFO_CONTENT_DATA;
2849                        entry->private_data = chip;
2850                        entry->c.ops = &snd_cs46xx_proc_io_ops;
2851                        entry->size = region->size;
2852                        entry->mode = S_IFREG | S_IRUSR;
2853                }
2854        }
2855#ifdef CONFIG_SND_CS46XX_NEW_DSP
2856        cs46xx_dsp_proc_init(card, chip);
2857#endif
2858        return 0;
2859}
2860
2861static int snd_cs46xx_proc_done(struct snd_cs46xx *chip)
2862{
2863#ifdef CONFIG_SND_CS46XX_NEW_DSP
2864        cs46xx_dsp_proc_done(chip);
2865#endif
2866        return 0;
2867}
2868#else /* !CONFIG_SND_PROC_FS */
2869#define snd_cs46xx_proc_init(card, chip)
2870#define snd_cs46xx_proc_done(chip)
2871#endif
2872
2873/*
2874 * stop the h/w
2875 */
2876static void snd_cs46xx_hw_stop(struct snd_cs46xx *chip)
2877{
2878        unsigned int tmp;
2879
2880        tmp = snd_cs46xx_peek(chip, BA1_PFIE);
2881        tmp &= ~0x0000f03f;
2882        tmp |=  0x00000010;
2883        snd_cs46xx_poke(chip, BA1_PFIE, tmp);   /* playback interrupt disable */
2884
2885        tmp = snd_cs46xx_peek(chip, BA1_CIE);
2886        tmp &= ~0x0000003f;
2887        tmp |=  0x00000011;
2888        snd_cs46xx_poke(chip, BA1_CIE, tmp);    /* capture interrupt disable */
2889
2890        /*
2891         *  Stop playback DMA.
2892         */
2893        tmp = snd_cs46xx_peek(chip, BA1_PCTL);
2894        snd_cs46xx_poke(chip, BA1_PCTL, tmp & 0x0000ffff);
2895
2896        /*
2897         *  Stop capture DMA.
2898         */
2899        tmp = snd_cs46xx_peek(chip, BA1_CCTL);
2900        snd_cs46xx_poke(chip, BA1_CCTL, tmp & 0xffff0000);
2901
2902        /*
2903         *  Reset the processor.
2904         */
2905        snd_cs46xx_reset(chip);
2906
2907        snd_cs46xx_proc_stop(chip);
2908
2909        /*
2910         *  Power down the PLL.
2911         */
2912        snd_cs46xx_pokeBA0(chip, BA0_CLKCR1, 0);
2913
2914        /*
2915         *  Turn off the Processor by turning off the software clock enable flag in 
2916         *  the clock control register.
2917         */
2918        tmp = snd_cs46xx_peekBA0(chip, BA0_CLKCR1) & ~CLKCR1_SWCE;
2919        snd_cs46xx_pokeBA0(chip, BA0_CLKCR1, tmp);
2920}
2921
2922
2923static int snd_cs46xx_free(struct snd_cs46xx *chip)
2924{
2925        int idx;
2926
2927        if (snd_BUG_ON(!chip))
2928                return -EINVAL;
2929
2930        if (chip->active_ctrl)
2931                chip->active_ctrl(chip, 1);
2932
2933        snd_cs46xx_remove_gameport(chip);
2934
2935        if (chip->amplifier_ctrl)
2936                chip->amplifier_ctrl(chip, -chip->amplifier); /* force to off */
2937        
2938        snd_cs46xx_proc_done(chip);
2939
2940        if (chip->region.idx[0].resource)
2941                snd_cs46xx_hw_stop(chip);
2942
2943        if (chip->irq >= 0)
2944                free_irq(chip->irq, chip);
2945
2946        if (chip->active_ctrl)
2947                chip->active_ctrl(chip, -chip->amplifier);
2948
2949        for (idx = 0; idx < 5; idx++) {
2950                struct snd_cs46xx_region *region = &chip->region.idx[idx];
2951
2952                iounmap(region->remap_addr);
2953                release_and_free_resource(region->resource);
2954        }
2955
2956#ifdef CONFIG_SND_CS46XX_NEW_DSP
2957        if (chip->dsp_spos_instance) {
2958                cs46xx_dsp_spos_destroy(chip);
2959                chip->dsp_spos_instance = NULL;
2960        }
2961        for (idx = 0; idx < CS46XX_DSP_MODULES; idx++)
2962                free_module_desc(chip->modules[idx]);
2963#else
2964        vfree(chip->ba1);
2965#endif
2966        
2967#ifdef CONFIG_PM_SLEEP
2968        kfree(chip->saved_regs);
2969#endif
2970
2971        pci_disable_device(chip->pci);
2972        kfree(chip);
2973        return 0;
2974}
2975
2976static int snd_cs46xx_dev_free(struct snd_device *device)
2977{
2978        struct snd_cs46xx *chip = device->device_data;
2979        return snd_cs46xx_free(chip);
2980}
2981
2982/*
2983 *  initialize chip
2984 */
2985static int snd_cs46xx_chip_init(struct snd_cs46xx *chip)
2986{
2987        int timeout;
2988
2989        /* 
2990         *  First, blast the clock control register to zero so that the PLL starts
2991         *  out in a known state, and blast the master serial port control register
2992         *  to zero so that the serial ports also start out in a known state.
2993         */
2994        snd_cs46xx_pokeBA0(chip, BA0_CLKCR1, 0);
2995        snd_cs46xx_pokeBA0(chip, BA0_SERMC1, 0);
2996
2997        /*
2998         *  If we are in AC97 mode, then we must set the part to a host controlled
2999         *  AC-link.  Otherwise, we won't be able to bring up the link.
3000         */        
3001#ifdef CONFIG_SND_CS46XX_NEW_DSP
3002        snd_cs46xx_pokeBA0(chip, BA0_SERACC, SERACC_HSP | SERACC_CHIP_TYPE_2_0 | 
3003                           SERACC_TWO_CODECS);  /* 2.00 dual codecs */
3004        /* snd_cs46xx_pokeBA0(chip, BA0_SERACC, SERACC_HSP | SERACC_CHIP_TYPE_2_0); */ /* 2.00 codec */
3005#else
3006        snd_cs46xx_pokeBA0(chip, BA0_SERACC, SERACC_HSP | SERACC_CHIP_TYPE_1_03); /* 1.03 codec */
3007#endif
3008
3009        /*
3010         *  Drive the ARST# pin low for a minimum of 1uS (as defined in the AC97
3011         *  spec) and then drive it high.  This is done for non AC97 modes since
3012         *  there might be logic external to the CS461x that uses the ARST# line
3013         *  for a reset.
3014         */
3015        snd_cs46xx_pokeBA0(chip, BA0_ACCTL, 0);
3016#ifdef CONFIG_SND_CS46XX_NEW_DSP
3017        snd_cs46xx_pokeBA0(chip, BA0_ACCTL2, 0);
3018#endif
3019        udelay(50);
3020        snd_cs46xx_pokeBA0(chip, BA0_ACCTL, ACCTL_RSTN);
3021#ifdef CONFIG_SND_CS46XX_NEW_DSP
3022        snd_cs46xx_pokeBA0(chip, BA0_ACCTL2, ACCTL_RSTN);
3023#endif
3024    
3025        /*
3026         *  The first thing we do here is to enable sync generation.  As soon
3027         *  as we start receiving bit clock, we'll start producing the SYNC
3028         *  signal.
3029         */
3030        snd_cs46xx_pokeBA0(chip, BA0_ACCTL, ACCTL_ESYN | ACCTL_RSTN);
3031#ifdef CONFIG_SND_CS46XX_NEW_DSP
3032        snd_cs46xx_pokeBA0(chip, BA0_ACCTL2, ACCTL_ESYN | ACCTL_RSTN);
3033#endif
3034
3035        /*
3036         *  Now wait for a short while to allow the AC97 part to start
3037         *  generating bit clock (so we don't try to start the PLL without an
3038         *  input clock).
3039         */
3040        mdelay(10);
3041
3042        /*
3043         *  Set the serial port timing configuration, so that
3044         *  the clock control circuit gets its clock from the correct place.
3045         */
3046        snd_cs46xx_pokeBA0(chip, BA0_SERMC1, SERMC1_PTC_AC97);
3047
3048        /*
3049         *  Write the selected clock control setup to the hardware.  Do not turn on
3050         *  SWCE yet (if requested), so that the devices clocked by the output of
3051         *  PLL are not clocked until the PLL is stable.
3052         */
3053        snd_cs46xx_pokeBA0(chip, BA0_PLLCC, PLLCC_LPF_1050_2780_KHZ | PLLCC_CDR_73_104_MHZ);
3054        snd_cs46xx_pokeBA0(chip, BA0_PLLM, 0x3a);
3055        snd_cs46xx_pokeBA0(chip, BA0_CLKCR2, CLKCR2_PDIVS_8);
3056
3057        /*
3058         *  Power up the PLL.
3059         */
3060        snd_cs46xx_pokeBA0(chip, BA0_CLKCR1, CLKCR1_PLLP);
3061
3062        /*
3063         *  Wait until the PLL has stabilized.
3064         */
3065        msleep(100);
3066
3067        /*
3068         *  Turn on clocking of the core so that we can setup the serial ports.
3069         */
3070        snd_cs46xx_pokeBA0(chip, BA0_CLKCR1, CLKCR1_PLLP | CLKCR1_SWCE);
3071
3072        /*
3073         * Enable FIFO  Host Bypass
3074         */
3075        snd_cs46xx_pokeBA0(chip, BA0_SERBCF, SERBCF_HBP);
3076
3077        /*
3078         *  Fill the serial port FIFOs with silence.
3079         */
3080        snd_cs46xx_clear_serial_FIFOs(chip);
3081
3082        /*
3083         *  Set the serial port FIFO pointer to the first sample in the FIFO.
3084         */
3085        /* snd_cs46xx_pokeBA0(chip, BA0_SERBSP, 0); */
3086
3087        /*
3088         *  Write the serial port configuration to the part.  The master
3089         *  enable bit is not set until all other values have been written.
3090         */
3091        snd_cs46xx_pokeBA0(chip, BA0_SERC1, SERC1_SO1F_AC97 | SERC1_SO1EN);
3092        snd_cs46xx_pokeBA0(chip, BA0_SERC2, SERC2_SI1F_AC97 | SERC1_SO1EN);
3093        snd_cs46xx_pokeBA0(chip, BA0_SERMC1, SERMC1_PTC_AC97 | SERMC1_MSPE);
3094
3095
3096#ifdef CONFIG_SND_CS46XX_NEW_DSP
3097        snd_cs46xx_pokeBA0(chip, BA0_SERC7, SERC7_ASDI2EN);
3098        snd_cs46xx_pokeBA0(chip, BA0_SERC3, 0);
3099        snd_cs46xx_pokeBA0(chip, BA0_SERC4, 0);
3100        snd_cs46xx_pokeBA0(chip, BA0_SERC5, 0);
3101        snd_cs46xx_pokeBA0(chip, BA0_SERC6, 1);
3102#endif
3103
3104        mdelay(5);
3105
3106
3107        /*
3108         * Wait for the codec ready signal from the AC97 codec.
3109         */
3110        timeout = 150;
3111        while (timeout-- > 0) {
3112                /*
3113                 *  Read the AC97 status register to see if we've seen a CODEC READY
3114                 *  signal from the AC97 codec.
3115                 */
3116                if (snd_cs46xx_peekBA0(chip, BA0_ACSTS) & ACSTS_CRDY)
3117                        goto ok1;
3118                msleep(10);
3119        }
3120
3121
3122        dev_err(chip->card->dev,
3123                "create - never read codec ready from AC'97\n");
3124        dev_err(chip->card->dev,
3125                "it is not probably bug, try to use CS4236 driver\n");
3126        return -EIO;
3127 ok1:
3128#ifdef CONFIG_SND_CS46XX_NEW_DSP
3129        {
3130                int count;
3131                for (count = 0; count < 150; count++) {
3132                        /* First, we want to wait for a short time. */
3133                        udelay(25);
3134        
3135                        if (snd_cs46xx_peekBA0(chip, BA0_ACSTS2) & ACSTS_CRDY)
3136                                break;
3137                }
3138
3139                /*
3140                 *  Make sure CODEC is READY.
3141                 */
3142                if (!(snd_cs46xx_peekBA0(chip, BA0_ACSTS2) & ACSTS_CRDY))
3143                        dev_dbg(chip->card->dev,
3144                                "never read card ready from secondary AC'97\n");
3145        }
3146#endif
3147
3148        /*
3149         *  Assert the vaid frame signal so that we can start sending commands
3150         *  to the AC97 codec.
3151         */
3152        snd_cs46xx_pokeBA0(chip, BA0_ACCTL, ACCTL_VFRM | ACCTL_ESYN | ACCTL_RSTN);
3153#ifdef CONFIG_SND_CS46XX_NEW_DSP
3154        snd_cs46xx_pokeBA0(chip, BA0_ACCTL2, ACCTL_VFRM | ACCTL_ESYN | ACCTL_RSTN);
3155#endif
3156
3157
3158        /*
3159         *  Wait until we've sampled input slots 3 and 4 as valid, meaning that
3160         *  the codec is pumping ADC data across the AC-link.
3161         */
3162        timeout = 150;
3163        while (timeout-- > 0) {
3164                /*
3165                 *  Read the input slot valid register and see if input slots 3 and
3166                 *  4 are valid yet.
3167                 */
3168                if ((snd_cs46xx_peekBA0(chip, BA0_ACISV) & (ACISV_ISV3 | ACISV_ISV4)) == (ACISV_ISV3 | ACISV_ISV4))
3169                        goto ok2;
3170                msleep(10);
3171        }
3172
3173#ifndef CONFIG_SND_CS46XX_NEW_DSP
3174        dev_err(chip->card->dev,
3175                "create - never read ISV3 & ISV4 from AC'97\n");
3176        return -EIO;
3177#else
3178        /* This may happen on a cold boot with a Terratec SiXPack 5.1.
3179           Reloading the driver may help, if there's other soundcards 
3180           with the same problem I would like to know. (Benny) */
3181
3182        dev_err(chip->card->dev, "never read ISV3 & ISV4 from AC'97\n");
3183        dev_err(chip->card->dev,
3184                "Try reloading the ALSA driver, if you find something\n");
3185        dev_err(chip->card->dev,
3186                "broken or not working on your soundcard upon\n");
3187        dev_err(chip->card->dev,
3188                "this message please report to alsa-devel@alsa-project.org\n");
3189
3190        return -EIO;
3191#endif
3192 ok2:
3193
3194        /*
3195         *  Now, assert valid frame and the slot 3 and 4 valid bits.  This will
3196         *  commense the transfer of digital audio data to the AC97 codec.
3197         */
3198
3199        snd_cs46xx_pokeBA0(chip, BA0_ACOSV, ACOSV_SLV3 | ACOSV_SLV4);
3200
3201
3202        /*
3203         *  Power down the DAC and ADC.  We will power them up (if) when we need
3204         *  them.
3205         */
3206        /* snd_cs46xx_pokeBA0(chip, BA0_AC97_POWERDOWN, 0x300); */
3207
3208        /*
3209         *  Turn off the Processor by turning off the software clock enable flag in 
3210         *  the clock control register.
3211         */
3212        /* tmp = snd_cs46xx_peekBA0(chip, BA0_CLKCR1) & ~CLKCR1_SWCE; */
3213        /* snd_cs46xx_pokeBA0(chip, BA0_CLKCR1, tmp); */
3214
3215        return 0;
3216}
3217
3218/*
3219 *  start and load DSP 
3220 */
3221
3222static void cs46xx_enable_stream_irqs(struct snd_cs46xx *chip)
3223{
3224        unsigned int tmp;
3225
3226        snd_cs46xx_pokeBA0(chip, BA0_HICR, HICR_IEV | HICR_CHGM);
3227        
3228        tmp = snd_cs46xx_peek(chip, BA1_PFIE);
3229        tmp &= ~0x0000f03f;
3230        snd_cs46xx_poke(chip, BA1_PFIE, tmp);   /* playback interrupt enable */
3231
3232        tmp = snd_cs46xx_peek(chip, BA1_CIE);
3233        tmp &= ~0x0000003f;
3234        tmp |=  0x00000001;
3235        snd_cs46xx_poke(chip, BA1_CIE, tmp);    /* capture interrupt enable */
3236}
3237
3238int snd_cs46xx_start_dsp(struct snd_cs46xx *chip)
3239{       
3240        unsigned int tmp;
3241#ifdef CONFIG_SND_CS46XX_NEW_DSP
3242        int i;
3243#endif
3244        int err;
3245
3246        /*
3247         *  Reset the processor.
3248         */
3249        snd_cs46xx_reset(chip);
3250        /*
3251         *  Download the image to the processor.
3252         */
3253#ifdef CONFIG_SND_CS46XX_NEW_DSP
3254        for (i = 0; i < CS46XX_DSP_MODULES; i++) {
3255                err = load_firmware(chip, &chip->modules[i], module_names[i]);
3256                if (err < 0) {
3257                        dev_err(chip->card->dev, "firmware load error [%s]\n",
3258                                   module_names[i]);
3259                        return err;
3260                }
3261                err = cs46xx_dsp_load_module(chip, chip->modules[i]);
3262                if (err < 0) {
3263                        dev_err(chip->card->dev, "image download error [%s]\n",
3264                                   module_names[i]);
3265                        return err;
3266                }
3267        }
3268
3269        if (cs46xx_dsp_scb_and_task_init(chip) < 0)
3270                return -EIO;
3271#else
3272        err = load_firmware(chip);
3273        if (err < 0)
3274                return err;
3275
3276        /* old image */
3277        err = snd_cs46xx_download_image(chip);
3278        if (err < 0) {
3279                dev_err(chip->card->dev, "image download error\n");
3280                return err;
3281        }
3282
3283        /*
3284         *  Stop playback DMA.
3285         */
3286        tmp = snd_cs46xx_peek(chip, BA1_PCTL);
3287        chip->play_ctl = tmp & 0xffff0000;
3288        snd_cs46xx_poke(chip, BA1_PCTL, tmp & 0x0000ffff);
3289#endif
3290
3291        /*
3292         *  Stop capture DMA.
3293         */
3294        tmp = snd_cs46xx_peek(chip, BA1_CCTL);
3295        chip->capt.ctl = tmp & 0x0000ffff;
3296        snd_cs46xx_poke(chip, BA1_CCTL, tmp & 0xffff0000);
3297
3298        mdelay(5);
3299
3300        snd_cs46xx_set_play_sample_rate(chip, 8000);
3301        snd_cs46xx_set_capture_sample_rate(chip, 8000);
3302
3303        snd_cs46xx_proc_start(chip);
3304
3305        cs46xx_enable_stream_irqs(chip);
3306        
3307#ifndef CONFIG_SND_CS46XX_NEW_DSP
3308        /* set the attenuation to 0dB */ 
3309        snd_cs46xx_poke(chip, BA1_PVOL, 0x80008000);
3310        snd_cs46xx_poke(chip, BA1_CVOL, 0x80008000);
3311#endif
3312
3313        return 0;
3314}
3315
3316
3317/*
3318 *      AMP control - null AMP
3319 */
3320 
3321static void amp_none(struct snd_cs46xx *chip, int change)
3322{       
3323}
3324
3325#ifdef CONFIG_SND_CS46XX_NEW_DSP
3326static int voyetra_setup_eapd_slot(struct snd_cs46xx *chip)
3327{
3328        
3329        u32 idx, valid_slots,tmp,powerdown = 0;
3330        u16 modem_power,pin_config,logic_type;
3331
3332        dev_dbg(chip->card->dev, "cs46xx_setup_eapd_slot()+\n");
3333
3334        /*
3335         *  See if the devices are powered down.  If so, we must power them up first
3336         *  or they will not respond.
3337         */
3338        tmp = snd_cs46xx_peekBA0(chip, BA0_CLKCR1);
3339
3340        if (!(tmp & CLKCR1_SWCE)) {
3341                snd_cs46xx_pokeBA0(chip, BA0_CLKCR1, tmp | CLKCR1_SWCE);
3342                powerdown = 1;
3343        }
3344
3345        /*
3346         * Clear PRA.  The Bonzo chip will be used for GPIO not for modem
3347         * stuff.
3348         */
3349        if(chip->nr_ac97_codecs != 2) {
3350                dev_err(chip->card->dev,
3351                        "cs46xx_setup_eapd_slot() - no secondary codec configured\n");
3352                return -EINVAL;
3353        }
3354
3355        modem_power = snd_cs46xx_codec_read (chip, 
3356                                             AC97_EXTENDED_MSTATUS,
3357                                             CS46XX_SECONDARY_CODEC_INDEX);
3358        modem_power &=0xFEFF;
3359
3360        snd_cs46xx_codec_write(chip, 
3361                               AC97_EXTENDED_MSTATUS, modem_power,
3362                               CS46XX_SECONDARY_CODEC_INDEX);
3363
3364        /*
3365         * Set GPIO pin's 7 and 8 so that they are configured for output.
3366         */
3367        pin_config = snd_cs46xx_codec_read (chip, 
3368                                            AC97_GPIO_CFG,
3369                                            CS46XX_SECONDARY_CODEC_INDEX);
3370        pin_config &=0x27F;
3371
3372        snd_cs46xx_codec_write(chip, 
3373                               AC97_GPIO_CFG, pin_config,
3374                               CS46XX_SECONDARY_CODEC_INDEX);
3375    
3376        /*
3377         * Set GPIO pin's 7 and 8 so that they are compatible with CMOS logic.
3378         */
3379
3380        logic_type = snd_cs46xx_codec_read(chip, AC97_GPIO_POLARITY,
3381                                           CS46XX_SECONDARY_CODEC_INDEX);
3382        logic_type &=0x27F; 
3383
3384        snd_cs46xx_codec_write (chip, AC97_GPIO_POLARITY, logic_type,
3385                                CS46XX_SECONDARY_CODEC_INDEX);
3386
3387        valid_slots = snd_cs46xx_peekBA0(chip, BA0_ACOSV);
3388        valid_slots |= 0x200;
3389        snd_cs46xx_pokeBA0(chip, BA0_ACOSV, valid_slots);
3390
3391        if ( cs46xx_wait_for_fifo(chip,1) ) {
3392                dev_dbg(chip->card->dev, "FIFO is busy\n");
3393          
3394          return -EINVAL;
3395        }
3396
3397        /*
3398         * Fill slots 12 with the correct value for the GPIO pins. 
3399         */
3400        for(idx = 0x90; idx <= 0x9F; idx++) {
3401                /*
3402                 * Initialize the fifo so that bits 7 and 8 are on.
3403                 *
3404                 * Remember that the GPIO pins in bonzo are shifted by 4 bits to
3405                 * the left.  0x1800 corresponds to bits 7 and 8.
3406                 */
3407                snd_cs46xx_pokeBA0(chip, BA0_SERBWP, 0x1800);
3408
3409                /*
3410                 * Wait for command to complete
3411                 */
3412                if ( cs46xx_wait_for_fifo(chip,200) ) {
3413                        dev_dbg(chip->card->dev,
3414                                "failed waiting for FIFO at addr (%02X)\n",
3415                                idx);
3416
3417                        return -EINVAL;
3418                }
3419            
3420                /*
3421                 * Write the serial port FIFO index.
3422                 */
3423                snd_cs46xx_pokeBA0(chip, BA0_SERBAD, idx);
3424      
3425                /*
3426                 * Tell the serial port to load the new value into the FIFO location.
3427                 */
3428                snd_cs46xx_pokeBA0(chip, BA0_SERBCM, SERBCM_WRC);
3429        }
3430
3431        /* wait for last command to complete */
3432        cs46xx_wait_for_fifo(chip,200);
3433
3434        /*
3435         *  Now, if we powered up the devices, then power them back down again.
3436         *  This is kinda ugly, but should never happen.
3437         */
3438        if (powerdown)
3439                snd_cs46xx_pokeBA0(chip, BA0_CLKCR1, tmp);
3440
3441        return 0;
3442}
3443#endif
3444
3445/*
3446 *      Crystal EAPD mode
3447 */
3448 
3449static void amp_voyetra(struct snd_cs46xx *chip, int change)
3450{
3451        /* Manage the EAPD bit on the Crystal 4297 
3452           and the Analog AD1885 */
3453           
3454#ifdef CONFIG_SND_CS46XX_NEW_DSP
3455        int old = chip->amplifier;
3456#endif
3457        int oval, val;
3458        
3459        chip->amplifier += change;
3460        oval = snd_cs46xx_codec_read(chip, AC97_POWERDOWN,
3461                                     CS46XX_PRIMARY_CODEC_INDEX);
3462        val = oval;
3463        if (chip->amplifier) {
3464                /* Turn the EAPD amp on */
3465                val |= 0x8000;
3466        } else {
3467                /* Turn the EAPD amp off */
3468                val &= ~0x8000;
3469        }
3470        if (val != oval) {
3471                snd_cs46xx_codec_write(chip, AC97_POWERDOWN, val,
3472                                       CS46XX_PRIMARY_CODEC_INDEX);
3473                if (chip->eapd_switch)
3474                        snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE,
3475                                       &chip->eapd_switch->id);
3476        }
3477
3478#ifdef CONFIG_SND_CS46XX_NEW_DSP
3479        if (chip->amplifier && !old) {
3480                voyetra_setup_eapd_slot(chip);
3481        }
3482#endif
3483}
3484
3485static void hercules_init(struct snd_cs46xx *chip) 
3486{
3487        /* default: AMP off, and SPDIF input optical */
3488        snd_cs46xx_pokeBA0(chip, BA0_EGPIODR, EGPIODR_GPOE0);
3489        snd_cs46xx_pokeBA0(chip, BA0_EGPIOPTR, EGPIODR_GPOE0);
3490}
3491
3492
3493/*
3494 *      Game Theatre XP card - EGPIO[2] is used to enable the external amp.
3495 */ 
3496static void amp_hercules(struct snd_cs46xx *chip, int change)
3497{
3498        int old = chip->amplifier;
3499        int val1 = snd_cs46xx_peekBA0(chip, BA0_EGPIODR);
3500        int val2 = snd_cs46xx_peekBA0(chip, BA0_EGPIOPTR);
3501
3502        chip->amplifier += change;
3503        if (chip->amplifier && !old) {
3504                dev_dbg(chip->card->dev, "Hercules amplifier ON\n");
3505
3506                snd_cs46xx_pokeBA0(chip, BA0_EGPIODR, 
3507                                   EGPIODR_GPOE2 | val1);     /* enable EGPIO2 output */
3508                snd_cs46xx_pokeBA0(chip, BA0_EGPIOPTR, 
3509                                   EGPIOPTR_GPPT2 | val2);   /* open-drain on output */
3510        } else if (old && !chip->amplifier) {
3511                dev_dbg(chip->card->dev, "Hercules amplifier OFF\n");
3512                snd_cs46xx_pokeBA0(chip, BA0_EGPIODR,  val1 & ~EGPIODR_GPOE2); /* disable */
3513                snd_cs46xx_pokeBA0(chip, BA0_EGPIOPTR, val2 & ~EGPIOPTR_GPPT2); /* disable */
3514        }
3515}
3516
3517static void voyetra_mixer_init (struct snd_cs46xx *chip)
3518{
3519        dev_dbg(chip->card->dev, "initializing Voyetra mixer\n");
3520
3521        /* Enable SPDIF out */
3522        snd_cs46xx_pokeBA0(chip, BA0_EGPIODR, EGPIODR_GPOE0);
3523        snd_cs46xx_pokeBA0(chip, BA0_EGPIOPTR, EGPIODR_GPOE0);
3524}
3525
3526static void hercules_mixer_init (struct snd_cs46xx *chip)
3527{
3528#ifdef CONFIG_SND_CS46XX_NEW_DSP
3529        unsigned int idx;
3530        int err;
3531        struct snd_card *card = chip->card;
3532#endif
3533
3534        /* set EGPIO to default */
3535        hercules_init(chip);
3536
3537        dev_dbg(chip->card->dev, "initializing Hercules mixer\n");
3538
3539#ifdef CONFIG_SND_CS46XX_NEW_DSP
3540        if (chip->in_suspend)
3541                return;
3542
3543        for (idx = 0 ; idx < ARRAY_SIZE(snd_hercules_controls); idx++) {
3544                struct snd_kcontrol *kctl;
3545
3546                kctl = snd_ctl_new1(&snd_hercules_controls[idx], chip);
3547                if ((err = snd_ctl_add(card, kctl)) < 0) {
3548                        dev_err(card->dev,
3549                                "failed to initialize Hercules mixer (%d)\n",
3550                                err);
3551                        break;
3552                }
3553        }
3554#endif
3555}
3556
3557
3558#if 0
3559/*
3560 *      Untested
3561 */
3562 
3563static void amp_voyetra_4294(struct snd_cs46xx *chip, int change)
3564{
3565        chip->amplifier += change;
3566
3567        if (chip->amplifier) {
3568                /* Switch the GPIO pins 7 and 8 to open drain */
3569                snd_cs46xx_codec_write(chip, 0x4C,
3570                                       snd_cs46xx_codec_read(chip, 0x4C) & 0xFE7F);
3571                snd_cs46xx_codec_write(chip, 0x4E,
3572                                       snd_cs46xx_codec_read(chip, 0x4E) | 0x0180);
3573                /* Now wake the AMP (this might be backwards) */
3574                snd_cs46xx_codec_write(chip, 0x54,
3575                                       snd_cs46xx_codec_read(chip, 0x54) & ~0x0180);
3576        } else {
3577                snd_cs46xx_codec_write(chip, 0x54,
3578                                       snd_cs46xx_codec_read(chip, 0x54) | 0x0180);
3579        }
3580}
3581#endif
3582
3583
3584/*
3585 *      Handle the CLKRUN on a thinkpad. We must disable CLKRUN support
3586 *      whenever we need to beat on the chip.
3587 *
3588 *      The original idea and code for this hack comes from David Kaiser at
3589 *      Linuxcare. Perhaps one day Crystal will document their chips well
3590 *      enough to make them useful.
3591 */
3592 
3593static void clkrun_hack(struct snd_cs46xx *chip, int change)
3594{
3595        u16 control, nval;
3596        
3597        if (!chip->acpi_port)
3598                return;
3599
3600        chip->amplifier += change;
3601        
3602        /* Read ACPI port */    
3603        nval = control = inw(chip->acpi_port + 0x10);
3604
3605        /* Flip CLKRUN off while running */
3606        if (! chip->amplifier)
3607                nval |= 0x2000;
3608        else
3609                nval &= ~0x2000;
3610        if (nval != control)
3611                outw(nval, chip->acpi_port + 0x10);
3612}
3613
3614        
3615/*
3616 * detect intel piix4
3617 */
3618static void clkrun_init(struct snd_cs46xx *chip)
3619{
3620        struct pci_dev *pdev;
3621        u8 pp;
3622
3623        chip->acpi_port = 0;
3624        
3625        pdev = pci_get_device(PCI_VENDOR_ID_INTEL,
3626                PCI_DEVICE_ID_INTEL_82371AB_3, NULL);
3627        if (pdev == NULL)
3628                return;         /* Not a thinkpad thats for sure */
3629
3630        /* Find the control port */             
3631        pci_read_config_byte(pdev, 0x41, &pp);
3632        chip->acpi_port = pp << 8;
3633        pci_dev_put(pdev);
3634}
3635
3636
3637/*
3638 * Card subid table
3639 */
3640 
3641struct cs_card_type
3642{
3643        u16 vendor;
3644        u16 id;
3645        char *name;
3646        void (*init)(struct snd_cs46xx *);
3647        void (*amp)(struct snd_cs46xx *, int);
3648        void (*active)(struct snd_cs46xx *, int);
3649        void (*mixer_init)(struct snd_cs46xx *);
3650};
3651
3652static struct cs_card_type cards[] = {
3653        {
3654                .vendor = 0x1489,
3655                .id = 0x7001,
3656                .name = "Genius Soundmaker 128 value",
3657                /* nothing special */
3658        },
3659        {
3660                .vendor = 0x5053,
3661                .id = 0x3357,
3662                .name = "Voyetra",
3663                .amp = amp_voyetra,
3664                .mixer_init = voyetra_mixer_init,
3665        },
3666        {
3667                .vendor = 0x1071,
3668                .id = 0x6003,
3669                .name = "Mitac MI6020/21",
3670                .amp = amp_voyetra,
3671        },
3672        /* Hercules Game Theatre XP */
3673        {
3674                .vendor = 0x14af, /* Guillemot Corporation */
3675                .id = 0x0050,
3676                .name = "Hercules Game Theatre XP",
3677                .amp = amp_hercules,
3678                .mixer_init = hercules_mixer_init,
3679        },
3680        {
3681                .vendor = 0x1681,
3682                .id = 0x0050,
3683                .name = "Hercules Game Theatre XP",
3684                .amp = amp_hercules,
3685                .mixer_init = hercules_mixer_init,
3686        },
3687        {
3688                .vendor = 0x1681,
3689                .id = 0x0051,
3690                .name = "Hercules Game Theatre XP",
3691                .amp = amp_hercules,
3692                .mixer_init = hercules_mixer_init,
3693
3694        },
3695        {
3696                .vendor = 0x1681,
3697                .id = 0x0052,
3698                .name = "Hercules Game Theatre XP",
3699                .amp = amp_hercules,
3700                .mixer_init = hercules_mixer_init,
3701        },
3702        {
3703                .vendor = 0x1681,
3704                .id = 0x0053,
3705                .name = "Hercules Game Theatre XP",
3706                .amp = amp_hercules,
3707                .mixer_init = hercules_mixer_init,
3708        },
3709        {
3710                .vendor = 0x1681,
3711                .id = 0x0054,
3712                .name = "Hercules Game Theatre XP",
3713                .amp = amp_hercules,
3714                .mixer_init = hercules_mixer_init,
3715        },
3716        /* Herculess Fortissimo */
3717        {
3718                .vendor = 0x1681,
3719                .id = 0xa010,
3720                .name = "Hercules Gamesurround Fortissimo II",
3721        },
3722        {
3723                .vendor = 0x1681,
3724                .id = 0xa011,
3725                .name = "Hercules Gamesurround Fortissimo III 7.1",
3726        },
3727        /* Teratec */
3728        {
3729                .vendor = 0x153b,
3730                .id = 0x112e,
3731                .name = "Terratec DMX XFire 1024",
3732        },
3733        {
3734                .vendor = 0x153b,
3735                .id = 0x1136,
3736                .name = "Terratec SiXPack 5.1",
3737        },
3738        /* Not sure if the 570 needs the clkrun hack */
3739        {
3740                .vendor = PCI_VENDOR_ID_IBM,
3741                .id = 0x0132,
3742                .name = "Thinkpad 570",
3743                .init = clkrun_init,
3744                .active = clkrun_hack,
3745        },
3746        {
3747                .vendor = PCI_VENDOR_ID_IBM,
3748                .id = 0x0153,
3749                .name = "Thinkpad 600X/A20/T20",
3750                .init = clkrun_init,
3751                .active = clkrun_hack,
3752        },
3753        {
3754                .vendor = PCI_VENDOR_ID_IBM,
3755                .id = 0x1010,
3756                .name = "Thinkpad 600E (unsupported)",
3757        },
3758        {} /* terminator */
3759};
3760
3761
3762/*
3763 * APM support
3764 */
3765#ifdef CONFIG_PM_SLEEP
3766static unsigned int saved_regs[] = {
3767        BA0_ACOSV,
3768        /*BA0_ASER_FADDR,*/
3769        BA0_ASER_MASTER,
3770        BA1_PVOL,
3771        BA1_CVOL,
3772};
3773
3774static int snd_cs46xx_suspend(struct device *dev)
3775{
3776        struct snd_card *card = dev_get_drvdata(dev);
3777        struct snd_cs46xx *chip = card->private_data;
3778        int i, amp_saved;
3779
3780        snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
3781        chip->in_suspend = 1;
3782        snd_pcm_suspend_all(chip->pcm);
3783#ifdef CONFIG_SND_CS46XX_NEW_DSP
3784        snd_pcm_suspend_all(chip->pcm_rear);
3785        snd_pcm_suspend_all(chip->pcm_center_lfe);
3786        snd_pcm_suspend_all(chip->pcm_iec958);
3787#endif
3788        // chip->ac97_powerdown = snd_cs46xx_codec_read(chip, AC97_POWER_CONTROL);
3789        // chip->ac97_general_purpose = snd_cs46xx_codec_read(chip, BA0_AC97_GENERAL_PURPOSE);
3790
3791        snd_ac97_suspend(chip->ac97[CS46XX_PRIMARY_CODEC_INDEX]);
3792        snd_ac97_suspend(chip->ac97[CS46XX_SECONDARY_CODEC_INDEX]);
3793
3794        /* save some registers */
3795        for (i = 0; i < ARRAY_SIZE(saved_regs); i++)
3796                chip->saved_regs[i] = snd_cs46xx_peekBA0(chip, saved_regs[i]);
3797
3798        amp_saved = chip->amplifier;
3799        /* turn off amp */
3800        chip->amplifier_ctrl(chip, -chip->amplifier);
3801        snd_cs46xx_hw_stop(chip);
3802        /* disable CLKRUN */
3803        chip->active_ctrl(chip, -chip->amplifier);
3804        chip->amplifier = amp_saved; /* restore the status */
3805        return 0;
3806}
3807
3808static int snd_cs46xx_resume(struct device *dev)
3809{
3810        struct snd_card *card = dev_get_drvdata(dev);
3811        struct snd_cs46xx *chip = card->private_data;
3812        int amp_saved;
3813#ifdef CONFIG_SND_CS46XX_NEW_DSP
3814        int i;
3815#endif
3816        unsigned int tmp;
3817
3818        amp_saved = chip->amplifier;
3819        chip->amplifier = 0;
3820        chip->active_ctrl(chip, 1); /* force to on */
3821
3822        snd_cs46xx_chip_init(chip);
3823
3824        snd_cs46xx_reset(chip);
3825#ifdef CONFIG_SND_CS46XX_NEW_DSP
3826        cs46xx_dsp_resume(chip);
3827        /* restore some registers */
3828        for (i = 0; i < ARRAY_SIZE(saved_regs); i++)
3829                snd_cs46xx_pokeBA0(chip, saved_regs[i], chip->saved_regs[i]);
3830#else
3831        snd_cs46xx_download_image(chip);
3832#endif
3833
3834#if 0
3835        snd_cs46xx_codec_write(chip, BA0_AC97_GENERAL_PURPOSE, 
3836                               chip->ac97_general_purpose);
3837        snd_cs46xx_codec_write(chip, AC97_POWER_CONTROL, 
3838                               chip->ac97_powerdown);
3839        mdelay(10);
3840        snd_cs46xx_codec_write(chip, BA0_AC97_POWERDOWN,
3841                               chip->ac97_powerdown);
3842        mdelay(5);
3843#endif
3844
3845        snd_ac97_resume(chip->ac97[CS46XX_PRIMARY_CODEC_INDEX]);
3846        snd_ac97_resume(chip->ac97[CS46XX_SECONDARY_CODEC_INDEX]);
3847
3848        /*
3849         *  Stop capture DMA.
3850         */
3851        tmp = snd_cs46xx_peek(chip, BA1_CCTL);
3852        chip->capt.ctl = tmp & 0x0000ffff;
3853        snd_cs46xx_poke(chip, BA1_CCTL, tmp & 0xffff0000);
3854
3855        mdelay(5);
3856
3857        /* reset playback/capture */
3858        snd_cs46xx_set_play_sample_rate(chip, 8000);
3859        snd_cs46xx_set_capture_sample_rate(chip, 8000);
3860        snd_cs46xx_proc_start(chip);
3861
3862        cs46xx_enable_stream_irqs(chip);
3863
3864        if (amp_saved)
3865                chip->amplifier_ctrl(chip, 1); /* turn amp on */
3866        else
3867                chip->active_ctrl(chip, -1); /* disable CLKRUN */
3868        chip->amplifier = amp_saved;
3869        chip->in_suspend = 0;
3870        snd_power_change_state(card, SNDRV_CTL_POWER_D0);
3871        return 0;
3872}
3873
3874SIMPLE_DEV_PM_OPS(snd_cs46xx_pm, snd_cs46xx_suspend, snd_cs46xx_resume);
3875#endif /* CONFIG_PM_SLEEP */
3876
3877
3878/*
3879 */
3880
3881int snd_cs46xx_create(struct snd_card *card,
3882                      struct pci_dev *pci,
3883                      int external_amp, int thinkpad,
3884                      struct snd_cs46xx **rchip)
3885{
3886        struct snd_cs46xx *chip;
3887        int err, idx;
3888        struct snd_cs46xx_region *region;
3889        struct cs_card_type *cp;
3890        u16 ss_card, ss_vendor;
3891        static struct snd_device_ops ops = {
3892                .dev_free =     snd_cs46xx_dev_free,
3893        };
3894        
3895        *rchip = NULL;
3896
3897        /* enable PCI device */
3898        if ((err = pci_enable_device(pci)) < 0)
3899                return err;
3900
3901        chip = kzalloc(sizeof(*chip), GFP_KERNEL);
3902        if (chip == NULL) {
3903                pci_disable_device(pci);
3904                return -ENOMEM;
3905        }
3906        spin_lock_init(&chip->reg_lock);
3907#ifdef CONFIG_SND_CS46XX_NEW_DSP
3908        mutex_init(&chip->spos_mutex);
3909#endif
3910        chip->card = card;
3911        chip->pci = pci;
3912        chip->irq = -1;
3913        chip->ba0_addr = pci_resource_start(pci, 0);
3914        chip->ba1_addr = pci_resource_start(pci, 1);
3915        if (chip->ba0_addr == 0 || chip->ba0_addr == (unsigned long)~0 ||
3916            chip->ba1_addr == 0 || chip->ba1_addr == (unsigned long)~0) {
3917                dev_err(chip->card->dev,
3918                        "wrong address(es) - ba0 = 0x%lx, ba1 = 0x%lx\n",
3919                           chip->ba0_addr, chip->ba1_addr);
3920                snd_cs46xx_free(chip);
3921                return -ENOMEM;
3922        }
3923
3924        region = &chip->region.name.ba0;
3925        strcpy(region->name, "CS46xx_BA0");
3926        region->base = chip->ba0_addr;
3927        region->size = CS46XX_BA0_SIZE;
3928
3929        region = &chip->region.name.data0;
3930        strcpy(region->name, "CS46xx_BA1_data0");
3931        region->base = chip->ba1_addr + BA1_SP_DMEM0;
3932        region->size = CS46XX_BA1_DATA0_SIZE;
3933
3934        region = &chip->region.name.data1;
3935        strcpy(region->name, "CS46xx_BA1_data1");
3936        region->base = chip->ba1_addr + BA1_SP_DMEM1;
3937        region->size = CS46XX_BA1_DATA1_SIZE;
3938
3939        region = &chip->region.name.pmem;
3940        strcpy(region->name, "CS46xx_BA1_pmem");
3941        region->base = chip->ba1_addr + BA1_SP_PMEM;
3942        region->size = CS46XX_BA1_PRG_SIZE;
3943
3944        region = &chip->region.name.reg;
3945        strcpy(region->name, "CS46xx_BA1_reg");
3946        region->base = chip->ba1_addr + BA1_SP_REG;
3947        region->size = CS46XX_BA1_REG_SIZE;
3948
3949        /* set up amp and clkrun hack */
3950        pci_read_config_word(pci, PCI_SUBSYSTEM_VENDOR_ID, &ss_vendor);
3951        pci_read_config_word(pci, PCI_SUBSYSTEM_ID, &ss_card);
3952
3953        for (cp = &cards[0]; cp->name; cp++) {
3954                if (cp->vendor == ss_vendor && cp->id == ss_card) {
3955                        dev_dbg(chip->card->dev, "hack for %s enabled\n",
3956                                cp->name);
3957
3958                        chip->amplifier_ctrl = cp->amp;
3959                        chip->active_ctrl = cp->active;
3960                        chip->mixer_init = cp->mixer_init;
3961
3962                        if (cp->init)
3963                                cp->init(chip);
3964                        break;
3965                }
3966        }
3967
3968        if (external_amp) {
3969                dev_info(chip->card->dev,
3970                         "Crystal EAPD support forced on.\n");
3971                chip->amplifier_ctrl = amp_voyetra;
3972        }
3973
3974        if (thinkpad) {
3975                dev_info(chip->card->dev,
3976                         "Activating CLKRUN hack for Thinkpad.\n");
3977                chip->active_ctrl = clkrun_hack;
3978                clkrun_init(chip);
3979        }
3980        
3981        if (chip->amplifier_ctrl == NULL)
3982                chip->amplifier_ctrl = amp_none;
3983        if (chip->active_ctrl == NULL)
3984                chip->active_ctrl = amp_none;
3985
3986        chip->active_ctrl(chip, 1); /* enable CLKRUN */
3987
3988        pci_set_master(pci);
3989
3990        for (idx = 0; idx < 5; idx++) {
3991                region = &chip->region.idx[idx];
3992                if ((region->resource = request_mem_region(region->base, region->size,
3993                                                           region->name)) == NULL) {
3994                        dev_err(chip->card->dev,
3995                                "unable to request memory region 0x%lx-0x%lx\n",
3996                                   region->base, region->base + region->size - 1);
3997                        snd_cs46xx_free(chip);
3998                        return -EBUSY;
3999                }
4000                region->remap_addr = ioremap_nocache(region->base, region->size);
4001                if (region->remap_addr == NULL) {
4002                        dev_err(chip->card->dev,
4003                                "%s ioremap problem\n", region->name);
4004                        snd_cs46xx_free(chip);
4005                        return -ENOMEM;
4006                }
4007        }
4008
4009        if (request_irq(pci->irq, snd_cs46xx_interrupt, IRQF_SHARED,
4010                        KBUILD_MODNAME, chip)) {
4011                dev_err(chip->card->dev, "unable to grab IRQ %d\n", pci->irq);
4012                snd_cs46xx_free(chip);
4013                return -EBUSY;
4014        }
4015        chip->irq = pci->irq;
4016
4017#ifdef CONFIG_SND_CS46XX_NEW_DSP
4018        chip->dsp_spos_instance = cs46xx_dsp_spos_create(chip);
4019        if (chip->dsp_spos_instance == NULL) {
4020                snd_cs46xx_free(chip);
4021                return -ENOMEM;
4022        }
4023#endif
4024
4025        err = snd_cs46xx_chip_init(chip);
4026        if (err < 0) {
4027                snd_cs46xx_free(chip);
4028                return err;
4029        }
4030
4031        if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) {
4032                snd_cs46xx_free(chip);
4033                return err;
4034        }
4035        
4036        snd_cs46xx_proc_init(card, chip);
4037
4038#ifdef CONFIG_PM_SLEEP
4039        chip->saved_regs = kmalloc(sizeof(*chip->saved_regs) *
4040                                   ARRAY_SIZE(saved_regs), GFP_KERNEL);
4041        if (!chip->saved_regs) {
4042                snd_cs46xx_free(chip);
4043                return -ENOMEM;
4044        }
4045#endif
4046
4047        chip->active_ctrl(chip, -1); /* disable CLKRUN */
4048
4049        *rchip = chip;
4050        return 0;
4051}
4052