linux/sound/pci/au88x0/au88x0_pcm.c
<<
>>
Prefs
   1/*
   2 *  This program is free software; you can redistribute it and/or modify
   3 *  it under the terms of the GNU General Public License as published by
   4 *  the Free Software Foundation; either version 2 of the License, or
   5 *  (at your option) any later version.
   6 *
   7 *  This program is distributed in the hope that it will be useful,
   8 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
   9 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  10 *  GNU Library General Public License for more details.
  11 *
  12 *  You should have received a copy of the GNU General Public License
  13 *  along with this program; if not, write to the Free Software
  14 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  15 */
  16 
  17/*
  18 * Vortex PCM ALSA driver.
  19 *
  20 * Supports ADB and WT DMA. Unfortunately, WT channels do not run yet.
  21 * It remains stuck,and DMA transfers do not happen. 
  22 */
  23#include <sound/asoundef.h>
  24#include <linux/time.h>
  25#include <sound/core.h>
  26#include <sound/pcm.h>
  27#include <sound/pcm_params.h>
  28#include "au88x0.h"
  29
  30#define VORTEX_PCM_TYPE(x) (x->name[40])
  31
  32/* hardware definition */
  33static struct snd_pcm_hardware snd_vortex_playback_hw_adb = {
  34        .info =
  35            (SNDRV_PCM_INFO_MMAP | /* SNDRV_PCM_INFO_RESUME | */
  36             SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_INTERLEAVED |
  37             SNDRV_PCM_INFO_MMAP_VALID),
  38        .formats =
  39            SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_U8 |
  40            SNDRV_PCM_FMTBIT_MU_LAW | SNDRV_PCM_FMTBIT_A_LAW,
  41        .rates = SNDRV_PCM_RATE_CONTINUOUS,
  42        .rate_min = 5000,
  43        .rate_max = 48000,
  44        .channels_min = 1,
  45        .channels_max = 2,
  46        .buffer_bytes_max = 0x10000,
  47        .period_bytes_min = 0x1,
  48        .period_bytes_max = 0x1000,
  49        .periods_min = 2,
  50        .periods_max = 32,
  51};
  52
  53#ifndef CHIP_AU8820
  54static struct snd_pcm_hardware snd_vortex_playback_hw_a3d = {
  55        .info =
  56            (SNDRV_PCM_INFO_MMAP | /* SNDRV_PCM_INFO_RESUME | */
  57             SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_INTERLEAVED |
  58             SNDRV_PCM_INFO_MMAP_VALID),
  59        .formats =
  60            SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_U8 |
  61            SNDRV_PCM_FMTBIT_MU_LAW | SNDRV_PCM_FMTBIT_A_LAW,
  62        .rates = SNDRV_PCM_RATE_CONTINUOUS,
  63        .rate_min = 5000,
  64        .rate_max = 48000,
  65        .channels_min = 1,
  66        .channels_max = 1,
  67        .buffer_bytes_max = 0x10000,
  68        .period_bytes_min = 0x100,
  69        .period_bytes_max = 0x1000,
  70        .periods_min = 2,
  71        .periods_max = 64,
  72};
  73#endif
  74static struct snd_pcm_hardware snd_vortex_playback_hw_spdif = {
  75        .info =
  76            (SNDRV_PCM_INFO_MMAP | /* SNDRV_PCM_INFO_RESUME | */
  77             SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_INTERLEAVED |
  78             SNDRV_PCM_INFO_MMAP_VALID),
  79        .formats =
  80            SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_U8 |
  81            SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_LE | SNDRV_PCM_FMTBIT_MU_LAW |
  82            SNDRV_PCM_FMTBIT_A_LAW,
  83        .rates =
  84            SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000,
  85        .rate_min = 32000,
  86        .rate_max = 48000,
  87        .channels_min = 1,
  88        .channels_max = 2,
  89        .buffer_bytes_max = 0x10000,
  90        .period_bytes_min = 0x100,
  91        .period_bytes_max = 0x1000,
  92        .periods_min = 2,
  93        .periods_max = 64,
  94};
  95
  96#ifndef CHIP_AU8810
  97static struct snd_pcm_hardware snd_vortex_playback_hw_wt = {
  98        .info = (SNDRV_PCM_INFO_MMAP |
  99                 SNDRV_PCM_INFO_INTERLEAVED |
 100                 SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_MMAP_VALID),
 101        .formats = SNDRV_PCM_FMTBIT_S16_LE,
 102        .rates = SNDRV_PCM_RATE_8000_48000 | SNDRV_PCM_RATE_CONTINUOUS, // SNDRV_PCM_RATE_48000,
 103        .rate_min = 8000,
 104        .rate_max = 48000,
 105        .channels_min = 1,
 106        .channels_max = 2,
 107        .buffer_bytes_max = 0x10000,
 108        .period_bytes_min = 0x0400,
 109        .period_bytes_max = 0x1000,
 110        .periods_min = 2,
 111        .periods_max = 64,
 112};
 113#endif
 114#ifdef CHIP_AU8830
 115static unsigned int au8830_channels[3] = {
 116        1, 2, 4,
 117};
 118
 119static struct snd_pcm_hw_constraint_list hw_constraints_au8830_channels = {
 120        .count = ARRAY_SIZE(au8830_channels),
 121        .list = au8830_channels,
 122        .mask = 0,
 123};
 124#endif
 125/* open callback */
 126static int snd_vortex_pcm_open(struct snd_pcm_substream *substream)
 127{
 128        vortex_t *vortex = snd_pcm_substream_chip(substream);
 129        struct snd_pcm_runtime *runtime = substream->runtime;
 130        int err;
 131        
 132        /* Force equal size periods */
 133        if ((err =
 134             snd_pcm_hw_constraint_integer(runtime,
 135                                           SNDRV_PCM_HW_PARAM_PERIODS)) < 0)
 136                return err;
 137        /* Avoid PAGE_SIZE boundary to fall inside of a period. */
 138        if ((err =
 139             snd_pcm_hw_constraint_pow2(runtime, 0,
 140                                        SNDRV_PCM_HW_PARAM_PERIOD_BYTES)) < 0)
 141                return err;
 142
 143        if (VORTEX_PCM_TYPE(substream->pcm) != VORTEX_PCM_WT) {
 144#ifndef CHIP_AU8820
 145                if (VORTEX_PCM_TYPE(substream->pcm) == VORTEX_PCM_A3D) {
 146                        runtime->hw = snd_vortex_playback_hw_a3d;
 147                }
 148#endif
 149                if (VORTEX_PCM_TYPE(substream->pcm) == VORTEX_PCM_SPDIF) {
 150                        runtime->hw = snd_vortex_playback_hw_spdif;
 151                        switch (vortex->spdif_sr) {
 152                        case 32000:
 153                                runtime->hw.rates = SNDRV_PCM_RATE_32000;
 154                                break;
 155                        case 44100:
 156                                runtime->hw.rates = SNDRV_PCM_RATE_44100;
 157                                break;
 158                        case 48000:
 159                                runtime->hw.rates = SNDRV_PCM_RATE_48000;
 160                                break;
 161                        }
 162                }
 163                if (VORTEX_PCM_TYPE(substream->pcm) == VORTEX_PCM_ADB
 164                    || VORTEX_PCM_TYPE(substream->pcm) == VORTEX_PCM_I2S)
 165                        runtime->hw = snd_vortex_playback_hw_adb;
 166#ifdef CHIP_AU8830
 167                if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK &&
 168                        VORTEX_PCM_TYPE(substream->pcm) == VORTEX_PCM_ADB) {
 169                        runtime->hw.channels_max = 4;
 170                        snd_pcm_hw_constraint_list(runtime, 0,
 171                                SNDRV_PCM_HW_PARAM_CHANNELS,
 172                                &hw_constraints_au8830_channels);
 173                }
 174#endif
 175                substream->runtime->private_data = NULL;
 176        }
 177#ifndef CHIP_AU8810
 178        else {
 179                runtime->hw = snd_vortex_playback_hw_wt;
 180                substream->runtime->private_data = NULL;
 181        }
 182#endif
 183        return 0;
 184}
 185
 186/* close callback */
 187static int snd_vortex_pcm_close(struct snd_pcm_substream *substream)
 188{
 189        //vortex_t *chip = snd_pcm_substream_chip(substream);
 190        stream_t *stream = (stream_t *) substream->runtime->private_data;
 191
 192        // the hardware-specific codes will be here
 193        if (stream != NULL) {
 194                stream->substream = NULL;
 195                stream->nr_ch = 0;
 196        }
 197        substream->runtime->private_data = NULL;
 198        return 0;
 199}
 200
 201/* hw_params callback */
 202static int
 203snd_vortex_pcm_hw_params(struct snd_pcm_substream *substream,
 204                         struct snd_pcm_hw_params *hw_params)
 205{
 206        vortex_t *chip = snd_pcm_substream_chip(substream);
 207        stream_t *stream = (stream_t *) (substream->runtime->private_data);
 208        int err;
 209
 210        // Alloc buffer memory.
 211        err =
 212            snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
 213        if (err < 0) {
 214                printk(KERN_ERR "Vortex: pcm page alloc failed!\n");
 215                return err;
 216        }
 217        /*
 218           printk(KERN_INFO "Vortex: periods %d, period_bytes %d, channels = %d\n", params_periods(hw_params),
 219           params_period_bytes(hw_params), params_channels(hw_params));
 220         */
 221        spin_lock_irq(&chip->lock);
 222        // Make audio routes and config buffer DMA.
 223        if (VORTEX_PCM_TYPE(substream->pcm) != VORTEX_PCM_WT) {
 224                int dma, type = VORTEX_PCM_TYPE(substream->pcm);
 225                /* Dealloc any routes. */
 226                if (stream != NULL)
 227                        vortex_adb_allocroute(chip, stream->dma,
 228                                              stream->nr_ch, stream->dir,
 229                                              stream->type);
 230                /* Alloc routes. */
 231                dma =
 232                    vortex_adb_allocroute(chip, -1,
 233                                          params_channels(hw_params),
 234                                          substream->stream, type);
 235                if (dma < 0) {
 236                        spin_unlock_irq(&chip->lock);
 237                        return dma;
 238                }
 239                stream = substream->runtime->private_data = &chip->dma_adb[dma];
 240                stream->substream = substream;
 241                /* Setup Buffers. */
 242                vortex_adbdma_setbuffers(chip, dma,
 243                                         params_period_bytes(hw_params),
 244                                         params_periods(hw_params));
 245        }
 246#ifndef CHIP_AU8810
 247        else {
 248                /* if (stream != NULL)
 249                   vortex_wt_allocroute(chip, substream->number, 0); */
 250                vortex_wt_allocroute(chip, substream->number,
 251                                     params_channels(hw_params));
 252                stream = substream->runtime->private_data =
 253                    &chip->dma_wt[substream->number];
 254                stream->dma = substream->number;
 255                stream->substream = substream;
 256                vortex_wtdma_setbuffers(chip, substream->number,
 257                                        params_period_bytes(hw_params),
 258                                        params_periods(hw_params));
 259        }
 260#endif
 261        spin_unlock_irq(&chip->lock);
 262        return 0;
 263}
 264
 265/* hw_free callback */
 266static int snd_vortex_pcm_hw_free(struct snd_pcm_substream *substream)
 267{
 268        vortex_t *chip = snd_pcm_substream_chip(substream);
 269        stream_t *stream = (stream_t *) (substream->runtime->private_data);
 270
 271        spin_lock_irq(&chip->lock);
 272        // Delete audio routes.
 273        if (VORTEX_PCM_TYPE(substream->pcm) != VORTEX_PCM_WT) {
 274                if (stream != NULL)
 275                        vortex_adb_allocroute(chip, stream->dma,
 276                                              stream->nr_ch, stream->dir,
 277                                              stream->type);
 278        }
 279#ifndef CHIP_AU8810
 280        else {
 281                if (stream != NULL)
 282                        vortex_wt_allocroute(chip, stream->dma, 0);
 283        }
 284#endif
 285        substream->runtime->private_data = NULL;
 286        spin_unlock_irq(&chip->lock);
 287
 288        return snd_pcm_lib_free_pages(substream);
 289}
 290
 291/* prepare callback */
 292static int snd_vortex_pcm_prepare(struct snd_pcm_substream *substream)
 293{
 294        vortex_t *chip = snd_pcm_substream_chip(substream);
 295        struct snd_pcm_runtime *runtime = substream->runtime;
 296        stream_t *stream = (stream_t *) substream->runtime->private_data;
 297        int dma = stream->dma, fmt, dir;
 298
 299        // set up the hardware with the current configuration.
 300        if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
 301                dir = 1;
 302        else
 303                dir = 0;
 304        fmt = vortex_alsafmt_aspfmt(runtime->format);
 305        spin_lock_irq(&chip->lock);
 306        if (VORTEX_PCM_TYPE(substream->pcm) != VORTEX_PCM_WT) {
 307                vortex_adbdma_setmode(chip, dma, 1, dir, fmt, 0 /*? */ ,
 308                                      0);
 309                vortex_adbdma_setstartbuffer(chip, dma, 0);
 310                if (VORTEX_PCM_TYPE(substream->pcm) != VORTEX_PCM_SPDIF)
 311                        vortex_adb_setsrc(chip, dma, runtime->rate, dir);
 312        }
 313#ifndef CHIP_AU8810
 314        else {
 315                vortex_wtdma_setmode(chip, dma, 1, fmt, 0, 0);
 316                // FIXME: Set rate (i guess using vortex_wt_writereg() somehow).
 317                vortex_wtdma_setstartbuffer(chip, dma, 0);
 318        }
 319#endif
 320        spin_unlock_irq(&chip->lock);
 321        return 0;
 322}
 323
 324/* trigger callback */
 325static int snd_vortex_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
 326{
 327        vortex_t *chip = snd_pcm_substream_chip(substream);
 328        stream_t *stream = (stream_t *) substream->runtime->private_data;
 329        int dma = stream->dma;
 330
 331        spin_lock(&chip->lock);
 332        switch (cmd) {
 333        case SNDRV_PCM_TRIGGER_START:
 334                // do something to start the PCM engine
 335                //printk(KERN_INFO "vortex: start %d\n", dma);
 336                stream->fifo_enabled = 1;
 337                if (VORTEX_PCM_TYPE(substream->pcm) != VORTEX_PCM_WT) {
 338                        vortex_adbdma_resetup(chip, dma);
 339                        vortex_adbdma_startfifo(chip, dma);
 340                }
 341#ifndef CHIP_AU8810
 342                else {
 343                        printk(KERN_INFO "vortex: wt start %d\n", dma);
 344                        vortex_wtdma_startfifo(chip, dma);
 345                }
 346#endif
 347                break;
 348        case SNDRV_PCM_TRIGGER_STOP:
 349                // do something to stop the PCM engine
 350                //printk(KERN_INFO "vortex: stop %d\n", dma);
 351                stream->fifo_enabled = 0;
 352                if (VORTEX_PCM_TYPE(substream->pcm) != VORTEX_PCM_WT)
 353                        vortex_adbdma_pausefifo(chip, dma);
 354                //vortex_adbdma_stopfifo(chip, dma);
 355#ifndef CHIP_AU8810
 356                else {
 357                        printk(KERN_INFO "vortex: wt stop %d\n", dma);
 358                        vortex_wtdma_stopfifo(chip, dma);
 359                }
 360#endif
 361                break;
 362        case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
 363                //printk(KERN_INFO "vortex: pause %d\n", dma);
 364                if (VORTEX_PCM_TYPE(substream->pcm) != VORTEX_PCM_WT)
 365                        vortex_adbdma_pausefifo(chip, dma);
 366#ifndef CHIP_AU8810
 367                else
 368                        vortex_wtdma_pausefifo(chip, dma);
 369#endif
 370                break;
 371        case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
 372                //printk(KERN_INFO "vortex: resume %d\n", dma);
 373                if (VORTEX_PCM_TYPE(substream->pcm) != VORTEX_PCM_WT)
 374                        vortex_adbdma_resumefifo(chip, dma);
 375#ifndef CHIP_AU8810
 376                else
 377                        vortex_wtdma_resumefifo(chip, dma);
 378#endif
 379                break;
 380        default:
 381                spin_unlock(&chip->lock);
 382                return -EINVAL;
 383        }
 384        spin_unlock(&chip->lock);
 385        return 0;
 386}
 387
 388/* pointer callback */
 389static snd_pcm_uframes_t snd_vortex_pcm_pointer(struct snd_pcm_substream *substream)
 390{
 391        vortex_t *chip = snd_pcm_substream_chip(substream);
 392        stream_t *stream = (stream_t *) substream->runtime->private_data;
 393        int dma = stream->dma;
 394        snd_pcm_uframes_t current_ptr = 0;
 395
 396        spin_lock(&chip->lock);
 397        if (VORTEX_PCM_TYPE(substream->pcm) != VORTEX_PCM_WT)
 398                current_ptr = vortex_adbdma_getlinearpos(chip, dma);
 399#ifndef CHIP_AU8810
 400        else
 401                current_ptr = vortex_wtdma_getlinearpos(chip, dma);
 402#endif
 403        //printk(KERN_INFO "vortex: pointer = 0x%x\n", current_ptr);
 404        spin_unlock(&chip->lock);
 405        return (bytes_to_frames(substream->runtime, current_ptr));
 406}
 407
 408/* operators */
 409static struct snd_pcm_ops snd_vortex_playback_ops = {
 410        .open = snd_vortex_pcm_open,
 411        .close = snd_vortex_pcm_close,
 412        .ioctl = snd_pcm_lib_ioctl,
 413        .hw_params = snd_vortex_pcm_hw_params,
 414        .hw_free = snd_vortex_pcm_hw_free,
 415        .prepare = snd_vortex_pcm_prepare,
 416        .trigger = snd_vortex_pcm_trigger,
 417        .pointer = snd_vortex_pcm_pointer,
 418        .page = snd_pcm_sgbuf_ops_page,
 419};
 420
 421/*
 422*  definitions of capture are omitted here...
 423*/
 424
 425static char *vortex_pcm_prettyname[VORTEX_PCM_LAST] = {
 426        "AU88x0 ADB",
 427        "AU88x0 SPDIF",
 428        "AU88x0 A3D",
 429        "AU88x0 WT",
 430        "AU88x0 I2S",
 431};
 432static char *vortex_pcm_name[VORTEX_PCM_LAST] = {
 433        "adb",
 434        "spdif",
 435        "a3d",
 436        "wt",
 437        "i2s",
 438};
 439
 440/* SPDIF kcontrol */
 441
 442static int snd_vortex_spdif_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 443{
 444        uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
 445        uinfo->count = 1;
 446        return 0;
 447}
 448
 449static int snd_vortex_spdif_mask_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 450{
 451        ucontrol->value.iec958.status[0] = 0xff;
 452        ucontrol->value.iec958.status[1] = 0xff;
 453        ucontrol->value.iec958.status[2] = 0xff;
 454        ucontrol->value.iec958.status[3] = IEC958_AES3_CON_FS;
 455        return 0;
 456}
 457
 458static int snd_vortex_spdif_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 459{
 460        vortex_t *vortex = snd_kcontrol_chip(kcontrol);
 461        ucontrol->value.iec958.status[0] = 0x00;
 462        ucontrol->value.iec958.status[1] = IEC958_AES1_CON_ORIGINAL|IEC958_AES1_CON_DIGDIGCONV_ID;
 463        ucontrol->value.iec958.status[2] = 0x00;
 464        switch (vortex->spdif_sr) {
 465        case 32000: ucontrol->value.iec958.status[3] = IEC958_AES3_CON_FS_32000; break;
 466        case 44100: ucontrol->value.iec958.status[3] = IEC958_AES3_CON_FS_44100; break;
 467        case 48000: ucontrol->value.iec958.status[3] = IEC958_AES3_CON_FS_48000; break;
 468        }
 469        return 0;
 470}
 471
 472static int snd_vortex_spdif_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 473{
 474        vortex_t *vortex = snd_kcontrol_chip(kcontrol);
 475        int spdif_sr = 48000;
 476        switch (ucontrol->value.iec958.status[3] & IEC958_AES3_CON_FS) {
 477        case IEC958_AES3_CON_FS_32000: spdif_sr = 32000; break;
 478        case IEC958_AES3_CON_FS_44100: spdif_sr = 44100; break;
 479        case IEC958_AES3_CON_FS_48000: spdif_sr = 48000; break;
 480        }
 481        if (spdif_sr == vortex->spdif_sr)
 482                return 0;
 483        vortex->spdif_sr = spdif_sr;
 484        vortex_spdif_init(vortex, vortex->spdif_sr, 1);
 485        return 1;
 486}
 487
 488/* spdif controls */
 489static struct snd_kcontrol_new snd_vortex_mixer_spdif[] __devinitdata = {
 490        {
 491                .iface =        SNDRV_CTL_ELEM_IFACE_PCM,
 492                .name =         SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),
 493                .info =         snd_vortex_spdif_info,
 494                .get =          snd_vortex_spdif_get,
 495                .put =          snd_vortex_spdif_put,
 496        },
 497        {
 498                .access =       SNDRV_CTL_ELEM_ACCESS_READ,
 499                .iface =        SNDRV_CTL_ELEM_IFACE_PCM,
 500                .name =         SNDRV_CTL_NAME_IEC958("",PLAYBACK,CON_MASK),
 501                .info =         snd_vortex_spdif_info,
 502                .get =          snd_vortex_spdif_mask_get
 503        },
 504};
 505
 506/* create a pcm device */
 507static int __devinit snd_vortex_new_pcm(vortex_t *chip, int idx, int nr)
 508{
 509        struct snd_pcm *pcm;
 510        struct snd_kcontrol *kctl;
 511        int i;
 512        int err, nr_capt;
 513
 514        if (!chip || idx < 0 || idx >= VORTEX_PCM_LAST)
 515                return -ENODEV;
 516
 517        /* idx indicates which kind of PCM device. ADB, SPDIF, I2S and A3D share the 
 518         * same dma engine. WT uses it own separate dma engine whcih cant capture. */
 519        if (idx == VORTEX_PCM_ADB)
 520                nr_capt = nr;
 521        else
 522                nr_capt = 0;
 523        err = snd_pcm_new(chip->card, vortex_pcm_prettyname[idx], idx, nr,
 524                          nr_capt, &pcm);
 525        if (err < 0)
 526                return err;
 527        strcpy(pcm->name, vortex_pcm_name[idx]);
 528        chip->pcm[idx] = pcm;
 529        // This is an evil hack, but it saves a lot of duplicated code.
 530        VORTEX_PCM_TYPE(pcm) = idx;
 531        pcm->private_data = chip;
 532        /* set operators */
 533        snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
 534                        &snd_vortex_playback_ops);
 535        if (idx == VORTEX_PCM_ADB)
 536                snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
 537                                &snd_vortex_playback_ops);
 538        
 539        /* pre-allocation of Scatter-Gather buffers */
 540        
 541        snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV_SG,
 542                                              snd_dma_pci_data(chip->pci_dev),
 543                                              0x10000, 0x10000);
 544
 545        if (VORTEX_PCM_TYPE(pcm) == VORTEX_PCM_SPDIF) {
 546                for (i = 0; i < ARRAY_SIZE(snd_vortex_mixer_spdif); i++) {
 547                        kctl = snd_ctl_new1(&snd_vortex_mixer_spdif[i], chip);
 548                        if (!kctl)
 549                                return -ENOMEM;
 550                        if ((err = snd_ctl_add(chip->card, kctl)) < 0)
 551                                return err;
 552                }
 553        }
 554        return 0;
 555}
 556