linux/sound/drivers/vx/vx_pcm.c
<<
>>
Prefs
   1/*
   2 * Driver for Digigram VX soundcards
   3 *
   4 * PCM part
   5 *
   6 * Copyright (c) 2002,2003 by Takashi Iwai <tiwai@suse.de>
   7 *
   8 *   This program is free software; you can redistribute it and/or modify
   9 *   it under the terms of the GNU General Public License as published by
  10 *   the Free Software Foundation; either version 2 of the License, or
  11 *   (at your option) any later version.
  12 *
  13 *   This program is distributed in the hope that it will be useful,
  14 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
  15 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16 *   GNU General Public License for more details.
  17 *
  18 *   You should have received a copy of the GNU General Public License
  19 *   along with this program; if not, write to the Free Software
  20 *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  21 *
  22 *
  23 * STRATEGY
  24 *  for playback, we send series of "chunks", which size is equal with the
  25 *  IBL size, typically 126 samples.  at each end of chunk, the end-of-buffer
  26 *  interrupt is notified, and the interrupt handler will feed the next chunk.
  27 *
  28 *  the current position is calculated from the sample count RMH.
  29 *  pipe->transferred is the counter of data which has been already transferred.
  30 *  if this counter reaches to the period size, snd_pcm_period_elapsed() will
  31 *  be issued.
  32 *
  33 *  for capture, the situation is much easier.
  34 *  to get a low latency response, we'll check the capture streams at each
  35 *  interrupt (capture stream has no EOB notification).  if the pending
  36 *  data is accumulated to the period size, snd_pcm_period_elapsed() is
  37 *  called and the pointer is updated.
  38 *
  39 *  the current point of read buffer is kept in pipe->hw_ptr.  note that
  40 *  this is in bytes.
  41 *
  42 *
  43 * TODO
  44 *  - linked trigger for full-duplex mode.
  45 *  - scheduled action on the stream.
  46 */
  47
  48#include <linux/slab.h>
  49#include <linux/delay.h>
  50#include <sound/core.h>
  51#include <sound/asoundef.h>
  52#include <sound/pcm.h>
  53#include <sound/vx_core.h>
  54#include "vx_cmd.h"
  55
  56
  57/*
  58 * read three pending pcm bytes via inb()
  59 */
  60static void vx_pcm_read_per_bytes(struct vx_core *chip, struct snd_pcm_runtime *runtime,
  61                                  struct vx_pipe *pipe)
  62{
  63        int offset = pipe->hw_ptr;
  64        unsigned char *buf = (unsigned char *)(runtime->dma_area + offset);
  65        *buf++ = vx_inb(chip, RXH);
  66        if (++offset >= pipe->buffer_bytes) {
  67                offset = 0;
  68                buf = (unsigned char *)runtime->dma_area;
  69        }
  70        *buf++ = vx_inb(chip, RXM);
  71        if (++offset >= pipe->buffer_bytes) {
  72                offset = 0;
  73                buf = (unsigned char *)runtime->dma_area;
  74        }
  75        *buf++ = vx_inb(chip, RXL);
  76        if (++offset >= pipe->buffer_bytes) {
  77                offset = 0;
  78                buf = (unsigned char *)runtime->dma_area;
  79        }
  80        pipe->hw_ptr = offset;
  81}
  82
  83/*
  84 * vx_set_pcx_time - convert from the PC time to the RMH status time.
  85 * @pc_time: the pointer for the PC-time to set
  86 * @dsp_time: the pointer for RMH status time array
  87 */
  88static void vx_set_pcx_time(struct vx_core *chip, pcx_time_t *pc_time,
  89                            unsigned int *dsp_time)
  90{
  91        dsp_time[0] = (unsigned int)((*pc_time) >> 24) & PCX_TIME_HI_MASK;
  92        dsp_time[1] = (unsigned int)(*pc_time) &  MASK_DSP_WORD;
  93}
  94
  95/*
  96 * vx_set_differed_time - set the differed time if specified
  97 * @rmh: the rmh record to modify
  98 * @pipe: the pipe to be checked
  99 *
 100 * if the pipe is programmed with the differed time, set the DSP time
 101 * on the rmh and changes its command length.
 102 *
 103 * returns the increase of the command length.
 104 */
 105static int vx_set_differed_time(struct vx_core *chip, struct vx_rmh *rmh,
 106                                struct vx_pipe *pipe)
 107{
 108        /* Update The length added to the RMH command by the timestamp */
 109        if (! (pipe->differed_type & DC_DIFFERED_DELAY))
 110                return 0;
 111                
 112        /* Set the T bit */
 113        rmh->Cmd[0] |= DSP_DIFFERED_COMMAND_MASK;
 114
 115        /* Time stamp is the 1st following parameter */
 116        vx_set_pcx_time(chip, &pipe->pcx_time, &rmh->Cmd[1]);
 117
 118        /* Add the flags to a notified differed command */
 119        if (pipe->differed_type & DC_NOTIFY_DELAY)
 120                rmh->Cmd[1] |= NOTIFY_MASK_TIME_HIGH ;
 121
 122        /* Add the flags to a multiple differed command */
 123        if (pipe->differed_type & DC_MULTIPLE_DELAY)
 124                rmh->Cmd[1] |= MULTIPLE_MASK_TIME_HIGH;
 125
 126        /* Add the flags to a stream-time differed command */
 127        if (pipe->differed_type & DC_STREAM_TIME_DELAY)
 128                rmh->Cmd[1] |= STREAM_MASK_TIME_HIGH;
 129                
 130        rmh->LgCmd += 2;
 131        return 2;
 132}
 133
 134/*
 135 * vx_set_stream_format - send the stream format command
 136 * @pipe: the affected pipe
 137 * @data: format bitmask
 138 */
 139static int vx_set_stream_format(struct vx_core *chip, struct vx_pipe *pipe,
 140                                unsigned int data)
 141{
 142        struct vx_rmh rmh;
 143
 144        vx_init_rmh(&rmh, pipe->is_capture ?
 145                    CMD_FORMAT_STREAM_IN : CMD_FORMAT_STREAM_OUT);
 146        rmh.Cmd[0] |= pipe->number << FIELD_SIZE;
 147
 148        /* Command might be longer since we may have to add a timestamp */
 149        vx_set_differed_time(chip, &rmh, pipe);
 150
 151        rmh.Cmd[rmh.LgCmd] = (data & 0xFFFFFF00) >> 8;
 152        rmh.Cmd[rmh.LgCmd + 1] = (data & 0xFF) << 16 /*| (datal & 0xFFFF00) >> 8*/;
 153        rmh.LgCmd += 2;
 154    
 155        return vx_send_msg(chip, &rmh);
 156}
 157
 158
 159/*
 160 * vx_set_format - set the format of a pipe
 161 * @pipe: the affected pipe
 162 * @runtime: pcm runtime instance to be referred
 163 *
 164 * returns 0 if successful, or a negative error code.
 165 */
 166static int vx_set_format(struct vx_core *chip, struct vx_pipe *pipe,
 167                         struct snd_pcm_runtime *runtime)
 168{
 169        unsigned int header = HEADER_FMT_BASE;
 170
 171        if (runtime->channels == 1)
 172                header |= HEADER_FMT_MONO;
 173        if (snd_pcm_format_little_endian(runtime->format))
 174                header |= HEADER_FMT_INTEL;
 175        if (runtime->rate < 32000 && runtime->rate > 11025)
 176                header |= HEADER_FMT_UPTO32;
 177        else if (runtime->rate <= 11025)
 178                header |= HEADER_FMT_UPTO11;
 179
 180        switch (snd_pcm_format_physical_width(runtime->format)) {
 181        // case 8: break;
 182        case 16: header |= HEADER_FMT_16BITS; break;
 183        case 24: header |= HEADER_FMT_24BITS; break;
 184        default : 
 185                snd_BUG();
 186                return -EINVAL;
 187        }
 188
 189        return vx_set_stream_format(chip, pipe, header);
 190}
 191
 192/*
 193 * set / query the IBL size
 194 */
 195static int vx_set_ibl(struct vx_core *chip, struct vx_ibl_info *info)
 196{
 197        int err;
 198        struct vx_rmh rmh;
 199
 200        vx_init_rmh(&rmh, CMD_IBL);
 201        rmh.Cmd[0] |= info->size & 0x03ffff;
 202        err = vx_send_msg(chip, &rmh);
 203        if (err < 0)
 204                return err;
 205        info->size = rmh.Stat[0];
 206        info->max_size = rmh.Stat[1];
 207        info->min_size = rmh.Stat[2];
 208        info->granularity = rmh.Stat[3];
 209        snd_printdd(KERN_DEBUG "vx_set_ibl: size = %d, max = %d, min = %d, gran = %d\n",
 210                   info->size, info->max_size, info->min_size, info->granularity);
 211        return 0;
 212}
 213
 214
 215/*
 216 * vx_get_pipe_state - get the state of a pipe
 217 * @pipe: the pipe to be checked
 218 * @state: the pointer for the returned state
 219 *
 220 * checks the state of a given pipe, and stores the state (1 = running,
 221 * 0 = paused) on the given pointer.
 222 *
 223 * called from trigger callback only
 224 */
 225static int vx_get_pipe_state(struct vx_core *chip, struct vx_pipe *pipe, int *state)
 226{
 227        int err;
 228        struct vx_rmh rmh;
 229
 230        vx_init_rmh(&rmh, CMD_PIPE_STATE);
 231        vx_set_pipe_cmd_params(&rmh, pipe->is_capture, pipe->number, 0);
 232        err = vx_send_msg(chip, &rmh);
 233        if (! err)
 234                *state = (rmh.Stat[0] & (1 << pipe->number)) ? 1 : 0;
 235        return err;
 236}
 237
 238
 239/*
 240 * vx_query_hbuffer_size - query available h-buffer size in bytes
 241 * @pipe: the pipe to be checked
 242 *
 243 * return the available size on h-buffer in bytes,
 244 * or a negative error code.
 245 *
 246 * NOTE: calling this function always switches to the stream mode.
 247 *       you'll need to disconnect the host to get back to the
 248 *       normal mode.
 249 */
 250static int vx_query_hbuffer_size(struct vx_core *chip, struct vx_pipe *pipe)
 251{
 252        int result;
 253        struct vx_rmh rmh;
 254
 255        vx_init_rmh(&rmh, CMD_SIZE_HBUFFER);
 256        vx_set_pipe_cmd_params(&rmh, pipe->is_capture, pipe->number, 0);
 257        if (pipe->is_capture)
 258                rmh.Cmd[0] |= 0x00000001;
 259        result = vx_send_msg(chip, &rmh);
 260        if (! result)
 261                result = rmh.Stat[0] & 0xffff;
 262        return result;
 263}
 264
 265
 266/*
 267 * vx_pipe_can_start - query whether a pipe is ready for start
 268 * @pipe: the pipe to be checked
 269 *
 270 * return 1 if ready, 0 if not ready, and negative value on error.
 271 *
 272 * called from trigger callback only
 273 */
 274static int vx_pipe_can_start(struct vx_core *chip, struct vx_pipe *pipe)
 275{
 276        int err;
 277        struct vx_rmh rmh;
 278        
 279        vx_init_rmh(&rmh, CMD_CAN_START_PIPE);
 280        vx_set_pipe_cmd_params(&rmh, pipe->is_capture, pipe->number, 0);
 281        rmh.Cmd[0] |= 1;
 282
 283        err = vx_send_msg(chip, &rmh);
 284        if (! err) {
 285                if (rmh.Stat[0])
 286                        err = 1;
 287        }
 288        return err;
 289}
 290
 291/*
 292 * vx_conf_pipe - tell the pipe to stand by and wait for IRQA.
 293 * @pipe: the pipe to be configured
 294 */
 295static int vx_conf_pipe(struct vx_core *chip, struct vx_pipe *pipe)
 296{
 297        struct vx_rmh rmh;
 298
 299        vx_init_rmh(&rmh, CMD_CONF_PIPE);
 300        if (pipe->is_capture)
 301                rmh.Cmd[0] |= COMMAND_RECORD_MASK;
 302        rmh.Cmd[1] = 1 << pipe->number;
 303        return vx_send_msg(chip, &rmh);
 304}
 305
 306/*
 307 * vx_send_irqa - trigger IRQA
 308 */
 309static int vx_send_irqa(struct vx_core *chip)
 310{
 311        struct vx_rmh rmh;
 312
 313        vx_init_rmh(&rmh, CMD_SEND_IRQA);
 314        return vx_send_msg(chip, &rmh);
 315}
 316
 317
 318#define MAX_WAIT_FOR_DSP        250
 319/*
 320 * vx boards do not support inter-card sync, besides
 321 * only 126 samples require to be prepared before a pipe can start
 322 */
 323#define CAN_START_DELAY         2       /* wait 2ms only before asking if the pipe is ready*/
 324#define WAIT_STATE_DELAY        2       /* wait 2ms after irqA was requested and check if the pipe state toggled*/
 325
 326/*
 327 * vx_toggle_pipe - start / pause a pipe
 328 * @pipe: the pipe to be triggered
 329 * @state: start = 1, pause = 0
 330 *
 331 * called from trigger callback only
 332 *
 333 */
 334static int vx_toggle_pipe(struct vx_core *chip, struct vx_pipe *pipe, int state)
 335{
 336        int err, i, cur_state;
 337
 338        /* Check the pipe is not already in the requested state */
 339        if (vx_get_pipe_state(chip, pipe, &cur_state) < 0)
 340                return -EBADFD;
 341        if (state == cur_state)
 342                return 0;
 343
 344        /* If a start is requested, ask the DSP to get prepared
 345         * and wait for a positive acknowledge (when there are
 346         * enough sound buffer for this pipe)
 347         */
 348        if (state) {
 349                for (i = 0 ; i < MAX_WAIT_FOR_DSP; i++) {
 350                        err = vx_pipe_can_start(chip, pipe);
 351                        if (err > 0)
 352                                break;
 353                        /* Wait for a few, before asking again
 354                         * to avoid flooding the DSP with our requests
 355                         */
 356                        mdelay(1);
 357                }
 358        }
 359    
 360        if ((err = vx_conf_pipe(chip, pipe)) < 0)
 361                return err;
 362
 363        if ((err = vx_send_irqa(chip)) < 0)
 364                return err;
 365    
 366        /* If it completes successfully, wait for the pipes
 367         * reaching the expected state before returning
 368         * Check one pipe only (since they are synchronous)
 369         */
 370        for (i = 0; i < MAX_WAIT_FOR_DSP; i++) {
 371                err = vx_get_pipe_state(chip, pipe, &cur_state);
 372                if (err < 0 || cur_state == state)
 373                        break;
 374                err = -EIO;
 375                mdelay(1);
 376        }
 377        return err < 0 ? -EIO : 0;
 378}
 379
 380    
 381/*
 382 * vx_stop_pipe - stop a pipe
 383 * @pipe: the pipe to be stopped
 384 *
 385 * called from trigger callback only
 386 */
 387static int vx_stop_pipe(struct vx_core *chip, struct vx_pipe *pipe)
 388{
 389        struct vx_rmh rmh;
 390        vx_init_rmh(&rmh, CMD_STOP_PIPE);
 391        vx_set_pipe_cmd_params(&rmh, pipe->is_capture, pipe->number, 0);
 392        return vx_send_msg(chip, &rmh);
 393}
 394
 395
 396/*
 397 * vx_alloc_pipe - allocate a pipe and initialize the pipe instance
 398 * @capture: 0 = playback, 1 = capture operation
 399 * @audioid: the audio id to be assigned
 400 * @num_audio: number of audio channels
 401 * @pipep: the returned pipe instance
 402 *
 403 * return 0 on success, or a negative error code.
 404 */
 405static int vx_alloc_pipe(struct vx_core *chip, int capture,
 406                         int audioid, int num_audio,
 407                         struct vx_pipe **pipep)
 408{
 409        int err;
 410        struct vx_pipe *pipe;
 411        struct vx_rmh rmh;
 412        int data_mode;
 413
 414        *pipep = NULL;
 415        vx_init_rmh(&rmh, CMD_RES_PIPE);
 416        vx_set_pipe_cmd_params(&rmh, capture, audioid, num_audio);
 417#if 0   // NYI
 418        if (underrun_skip_sound)
 419                rmh.Cmd[0] |= BIT_SKIP_SOUND;
 420#endif  // NYI
 421        data_mode = (chip->uer_bits & IEC958_AES0_NONAUDIO) != 0;
 422        if (! capture && data_mode)
 423                rmh.Cmd[0] |= BIT_DATA_MODE;
 424        err = vx_send_msg(chip, &rmh);
 425        if (err < 0)
 426                return err;
 427
 428        /* initialize the pipe record */
 429        pipe = kzalloc(sizeof(*pipe), GFP_KERNEL);
 430        if (! pipe) {
 431                /* release the pipe */
 432                vx_init_rmh(&rmh, CMD_FREE_PIPE);
 433                vx_set_pipe_cmd_params(&rmh, capture, audioid, 0);
 434                vx_send_msg(chip, &rmh);
 435                return -ENOMEM;
 436        }
 437
 438        /* the pipe index should be identical with the audio index */
 439        pipe->number = audioid;
 440        pipe->is_capture = capture;
 441        pipe->channels = num_audio;
 442        pipe->differed_type = 0;
 443        pipe->pcx_time = 0;
 444        pipe->data_mode = data_mode;
 445        *pipep = pipe;
 446
 447        return 0;
 448}
 449
 450
 451/*
 452 * vx_free_pipe - release a pipe
 453 * @pipe: pipe to be released
 454 */
 455static int vx_free_pipe(struct vx_core *chip, struct vx_pipe *pipe)
 456{
 457        struct vx_rmh rmh;
 458
 459        vx_init_rmh(&rmh, CMD_FREE_PIPE);
 460        vx_set_pipe_cmd_params(&rmh, pipe->is_capture, pipe->number, 0);
 461        vx_send_msg(chip, &rmh);
 462
 463        kfree(pipe);
 464        return 0;
 465}
 466
 467
 468/*
 469 * vx_start_stream - start the stream
 470 *
 471 * called from trigger callback only
 472 */
 473static int vx_start_stream(struct vx_core *chip, struct vx_pipe *pipe)
 474{
 475        struct vx_rmh rmh;
 476
 477        vx_init_rmh(&rmh, CMD_START_ONE_STREAM);
 478        vx_set_stream_cmd_params(&rmh, pipe->is_capture, pipe->number);
 479        vx_set_differed_time(chip, &rmh, pipe);
 480        return vx_send_msg(chip, &rmh);
 481}
 482
 483
 484/*
 485 * vx_stop_stream - stop the stream
 486 *
 487 * called from trigger callback only
 488 */
 489static int vx_stop_stream(struct vx_core *chip, struct vx_pipe *pipe)
 490{
 491        struct vx_rmh rmh;
 492
 493        vx_init_rmh(&rmh, CMD_STOP_STREAM);
 494        vx_set_stream_cmd_params(&rmh, pipe->is_capture, pipe->number);
 495        return vx_send_msg(chip, &rmh);
 496}
 497
 498
 499/*
 500 * playback hw information
 501 */
 502
 503static struct snd_pcm_hardware vx_pcm_playback_hw = {
 504        .info =                 (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
 505                                 SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_MMAP_VALID /*|*/
 506                                 /*SNDRV_PCM_INFO_RESUME*/),
 507        .formats =              (/*SNDRV_PCM_FMTBIT_U8 |*/
 508                                 SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_3LE),
 509        .rates =                SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,
 510        .rate_min =             5000,
 511        .rate_max =             48000,
 512        .channels_min =         1,
 513        .channels_max =         2,
 514        .buffer_bytes_max =     (128*1024),
 515        .period_bytes_min =     126,
 516        .period_bytes_max =     (128*1024),
 517        .periods_min =          2,
 518        .periods_max =          VX_MAX_PERIODS,
 519        .fifo_size =            126,
 520};
 521
 522
 523/*
 524 * vx_pcm_playback_open - open callback for playback
 525 */
 526static int vx_pcm_playback_open(struct snd_pcm_substream *subs)
 527{
 528        struct snd_pcm_runtime *runtime = subs->runtime;
 529        struct vx_core *chip = snd_pcm_substream_chip(subs);
 530        struct vx_pipe *pipe = NULL;
 531        unsigned int audio;
 532        int err;
 533
 534        if (chip->chip_status & VX_STAT_IS_STALE)
 535                return -EBUSY;
 536
 537        audio = subs->pcm->device * 2;
 538        if (snd_BUG_ON(audio >= chip->audio_outs))
 539                return -EINVAL;
 540        
 541        /* playback pipe may have been already allocated for monitoring */
 542        pipe = chip->playback_pipes[audio];
 543        if (! pipe) {
 544                /* not allocated yet */
 545                err = vx_alloc_pipe(chip, 0, audio, 2, &pipe); /* stereo playback */
 546                if (err < 0)
 547                        return err;
 548                chip->playback_pipes[audio] = pipe;
 549        }
 550        /* open for playback */
 551        pipe->references++;
 552
 553        pipe->substream = subs;
 554        chip->playback_pipes[audio] = pipe;
 555
 556        runtime->hw = vx_pcm_playback_hw;
 557        runtime->hw.period_bytes_min = chip->ibl.size;
 558        runtime->private_data = pipe;
 559
 560        /* align to 4 bytes (otherwise will be problematic when 24bit is used) */ 
 561        snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 4);
 562        snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 4);
 563
 564        return 0;
 565}
 566
 567/*
 568 * vx_pcm_playback_close - close callback for playback
 569 */
 570static int vx_pcm_playback_close(struct snd_pcm_substream *subs)
 571{
 572        struct vx_core *chip = snd_pcm_substream_chip(subs);
 573        struct vx_pipe *pipe;
 574
 575        if (! subs->runtime->private_data)
 576                return -EINVAL;
 577
 578        pipe = subs->runtime->private_data;
 579
 580        if (--pipe->references == 0) {
 581                chip->playback_pipes[pipe->number] = NULL;
 582                vx_free_pipe(chip, pipe);
 583        }
 584
 585        return 0;
 586
 587}
 588
 589
 590/*
 591 * vx_notify_end_of_buffer - send "end-of-buffer" notifier at the given pipe
 592 * @pipe: the pipe to notify
 593 *
 594 * NB: call with a certain lock.
 595 */
 596static int vx_notify_end_of_buffer(struct vx_core *chip, struct vx_pipe *pipe)
 597{
 598        int err;
 599        struct vx_rmh rmh;  /* use a temporary rmh here */
 600
 601        /* Toggle Dsp Host Interface into Message mode */
 602        vx_send_rih_nolock(chip, IRQ_PAUSE_START_CONNECT);
 603        vx_init_rmh(&rmh, CMD_NOTIFY_END_OF_BUFFER);
 604        vx_set_stream_cmd_params(&rmh, 0, pipe->number);
 605        err = vx_send_msg_nolock(chip, &rmh);
 606        if (err < 0)
 607                return err;
 608        /* Toggle Dsp Host Interface back to sound transfer mode */
 609        vx_send_rih_nolock(chip, IRQ_PAUSE_START_CONNECT);
 610        return 0;
 611}
 612
 613/*
 614 * vx_pcm_playback_transfer_chunk - transfer a single chunk
 615 * @subs: substream
 616 * @pipe: the pipe to transfer
 617 * @size: chunk size in bytes
 618 *
 619 * transfer a single buffer chunk.  EOB notificaton is added after that.
 620 * called from the interrupt handler, too.
 621 *
 622 * return 0 if ok.
 623 */
 624static int vx_pcm_playback_transfer_chunk(struct vx_core *chip,
 625                                          struct snd_pcm_runtime *runtime,
 626                                          struct vx_pipe *pipe, int size)
 627{
 628        int space, err = 0;
 629
 630        space = vx_query_hbuffer_size(chip, pipe);
 631        if (space < 0) {
 632                /* disconnect the host, SIZE_HBUF command always switches to the stream mode */
 633                vx_send_rih(chip, IRQ_CONNECT_STREAM_NEXT);
 634                snd_printd("error hbuffer\n");
 635                return space;
 636        }
 637        if (space < size) {
 638                vx_send_rih(chip, IRQ_CONNECT_STREAM_NEXT);
 639                snd_printd("no enough hbuffer space %d\n", space);
 640                return -EIO; /* XRUN */
 641        }
 642                
 643        /* we don't need irqsave here, because this function
 644         * is called from either trigger callback or irq handler
 645         */
 646        mutex_lock(&chip->lock);
 647        vx_pseudo_dma_write(chip, runtime, pipe, size);
 648        err = vx_notify_end_of_buffer(chip, pipe);
 649        /* disconnect the host, SIZE_HBUF command always switches to the stream mode */
 650        vx_send_rih_nolock(chip, IRQ_CONNECT_STREAM_NEXT);
 651        mutex_unlock(&chip->lock);
 652        return err;
 653}
 654
 655/*
 656 * update the position of the given pipe.
 657 * pipe->position is updated and wrapped within the buffer size.
 658 * pipe->transferred is updated, too, but the size is not wrapped,
 659 * so that the caller can check the total transferred size later
 660 * (to call snd_pcm_period_elapsed).
 661 */
 662static int vx_update_pipe_position(struct vx_core *chip,
 663                                   struct snd_pcm_runtime *runtime,
 664                                   struct vx_pipe *pipe)
 665{
 666        struct vx_rmh rmh;
 667        int err, update;
 668        u64 count;
 669
 670        vx_init_rmh(&rmh, CMD_STREAM_SAMPLE_COUNT);
 671        vx_set_pipe_cmd_params(&rmh, pipe->is_capture, pipe->number, 0);
 672        err = vx_send_msg(chip, &rmh);
 673        if (err < 0)
 674                return err;
 675
 676        count = ((u64)(rmh.Stat[0] & 0xfffff) << 24) | (u64)rmh.Stat[1];
 677        update = (int)(count - pipe->cur_count);
 678        pipe->cur_count = count;
 679        pipe->position += update;
 680        if (pipe->position >= (int)runtime->buffer_size)
 681                pipe->position %= runtime->buffer_size;
 682        pipe->transferred += update;
 683        return 0;
 684}
 685
 686/*
 687 * transfer the pending playback buffer data to DSP
 688 * called from interrupt handler
 689 */
 690static void vx_pcm_playback_transfer(struct vx_core *chip,
 691                                     struct snd_pcm_substream *subs,
 692                                     struct vx_pipe *pipe, int nchunks)
 693{
 694        int i, err;
 695        struct snd_pcm_runtime *runtime = subs->runtime;
 696
 697        if (! pipe->prepared || (chip->chip_status & VX_STAT_IS_STALE))
 698                return;
 699        for (i = 0; i < nchunks; i++) {
 700                if ((err = vx_pcm_playback_transfer_chunk(chip, runtime, pipe,
 701                                                          chip->ibl.size)) < 0)
 702                        return;
 703        }
 704}
 705
 706/*
 707 * update the playback position and call snd_pcm_period_elapsed() if necessary
 708 * called from interrupt handler
 709 */
 710static void vx_pcm_playback_update(struct vx_core *chip,
 711                                   struct snd_pcm_substream *subs,
 712                                   struct vx_pipe *pipe)
 713{
 714        int err;
 715        struct snd_pcm_runtime *runtime = subs->runtime;
 716
 717        if (pipe->running && ! (chip->chip_status & VX_STAT_IS_STALE)) {
 718                if ((err = vx_update_pipe_position(chip, runtime, pipe)) < 0)
 719                        return;
 720                if (pipe->transferred >= (int)runtime->period_size) {
 721                        pipe->transferred %= runtime->period_size;
 722                        snd_pcm_period_elapsed(subs);
 723                }
 724        }
 725}
 726
 727/*
 728 * vx_pcm_playback_trigger - trigger callback for playback
 729 */
 730static int vx_pcm_trigger(struct snd_pcm_substream *subs, int cmd)
 731{
 732        struct vx_core *chip = snd_pcm_substream_chip(subs);
 733        struct vx_pipe *pipe = subs->runtime->private_data;
 734        int err;
 735
 736        if (chip->chip_status & VX_STAT_IS_STALE)
 737                return -EBUSY;
 738                
 739        switch (cmd) {
 740        case SNDRV_PCM_TRIGGER_START:
 741        case SNDRV_PCM_TRIGGER_RESUME:
 742                if (! pipe->is_capture)
 743                        vx_pcm_playback_transfer(chip, subs, pipe, 2);
 744                err = vx_start_stream(chip, pipe);
 745                if (err < 0) {
 746                        pr_debug("vx: cannot start stream\n");
 747                        return err;
 748                }
 749                err = vx_toggle_pipe(chip, pipe, 1);
 750                if (err < 0) {
 751                        pr_debug("vx: cannot start pipe\n");
 752                        vx_stop_stream(chip, pipe);
 753                        return err;
 754                }
 755                chip->pcm_running++;
 756                pipe->running = 1;
 757                break;
 758        case SNDRV_PCM_TRIGGER_STOP:
 759        case SNDRV_PCM_TRIGGER_SUSPEND:
 760                vx_toggle_pipe(chip, pipe, 0);
 761                vx_stop_pipe(chip, pipe);
 762                vx_stop_stream(chip, pipe);
 763                chip->pcm_running--;
 764                pipe->running = 0;
 765                break;
 766        case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
 767                if ((err = vx_toggle_pipe(chip, pipe, 0)) < 0)
 768                        return err;
 769                break;
 770        case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
 771                if ((err = vx_toggle_pipe(chip, pipe, 1)) < 0)
 772                        return err;
 773                break;
 774        default:
 775                return -EINVAL;
 776        }
 777        return 0;
 778}
 779
 780/*
 781 * vx_pcm_playback_pointer - pointer callback for playback
 782 */
 783static snd_pcm_uframes_t vx_pcm_playback_pointer(struct snd_pcm_substream *subs)
 784{
 785        struct snd_pcm_runtime *runtime = subs->runtime;
 786        struct vx_pipe *pipe = runtime->private_data;
 787        return pipe->position;
 788}
 789
 790/*
 791 * vx_pcm_hw_params - hw_params callback for playback and capture
 792 */
 793static int vx_pcm_hw_params(struct snd_pcm_substream *subs,
 794                                     struct snd_pcm_hw_params *hw_params)
 795{
 796        return snd_pcm_lib_alloc_vmalloc_32_buffer
 797                                        (subs, params_buffer_bytes(hw_params));
 798}
 799
 800/*
 801 * vx_pcm_hw_free - hw_free callback for playback and capture
 802 */
 803static int vx_pcm_hw_free(struct snd_pcm_substream *subs)
 804{
 805        return snd_pcm_lib_free_vmalloc_buffer(subs);
 806}
 807
 808/*
 809 * vx_pcm_prepare - prepare callback for playback and capture
 810 */
 811static int vx_pcm_prepare(struct snd_pcm_substream *subs)
 812{
 813        struct vx_core *chip = snd_pcm_substream_chip(subs);
 814        struct snd_pcm_runtime *runtime = subs->runtime;
 815        struct vx_pipe *pipe = runtime->private_data;
 816        int err, data_mode;
 817        // int max_size, nchunks;
 818
 819        if (chip->chip_status & VX_STAT_IS_STALE)
 820                return -EBUSY;
 821
 822        data_mode = (chip->uer_bits & IEC958_AES0_NONAUDIO) != 0;
 823        if (data_mode != pipe->data_mode && ! pipe->is_capture) {
 824                /* IEC958 status (raw-mode) was changed */
 825                /* we reopen the pipe */
 826                struct vx_rmh rmh;
 827                snd_printdd(KERN_DEBUG "reopen the pipe with data_mode = %d\n", data_mode);
 828                vx_init_rmh(&rmh, CMD_FREE_PIPE);
 829                vx_set_pipe_cmd_params(&rmh, 0, pipe->number, 0);
 830                if ((err = vx_send_msg(chip, &rmh)) < 0)
 831                        return err;
 832                vx_init_rmh(&rmh, CMD_RES_PIPE);
 833                vx_set_pipe_cmd_params(&rmh, 0, pipe->number, pipe->channels);
 834                if (data_mode)
 835                        rmh.Cmd[0] |= BIT_DATA_MODE;
 836                if ((err = vx_send_msg(chip, &rmh)) < 0)
 837                        return err;
 838                pipe->data_mode = data_mode;
 839        }
 840
 841        if (chip->pcm_running && chip->freq != runtime->rate) {
 842                snd_printk(KERN_ERR "vx: cannot set different clock %d "
 843                           "from the current %d\n", runtime->rate, chip->freq);
 844                return -EINVAL;
 845        }
 846        vx_set_clock(chip, runtime->rate);
 847
 848        if ((err = vx_set_format(chip, pipe, runtime)) < 0)
 849                return err;
 850
 851        if (vx_is_pcmcia(chip)) {
 852                pipe->align = 2; /* 16bit word */
 853        } else {
 854                pipe->align = 4; /* 32bit word */
 855        }
 856
 857        pipe->buffer_bytes = frames_to_bytes(runtime, runtime->buffer_size);
 858        pipe->period_bytes = frames_to_bytes(runtime, runtime->period_size);
 859        pipe->hw_ptr = 0;
 860
 861        /* set the timestamp */
 862        vx_update_pipe_position(chip, runtime, pipe);
 863        /* clear again */
 864        pipe->transferred = 0;
 865        pipe->position = 0;
 866
 867        pipe->prepared = 1;
 868
 869        return 0;
 870}
 871
 872
 873/*
 874 * operators for PCM playback
 875 */
 876static struct snd_pcm_ops vx_pcm_playback_ops = {
 877        .open =         vx_pcm_playback_open,
 878        .close =        vx_pcm_playback_close,
 879        .ioctl =        snd_pcm_lib_ioctl,
 880        .hw_params =    vx_pcm_hw_params,
 881        .hw_free =      vx_pcm_hw_free,
 882        .prepare =      vx_pcm_prepare,
 883        .trigger =      vx_pcm_trigger,
 884        .pointer =      vx_pcm_playback_pointer,
 885        .page =         snd_pcm_lib_get_vmalloc_page,
 886        .mmap =         snd_pcm_lib_mmap_vmalloc,
 887};
 888
 889
 890/*
 891 * playback hw information
 892 */
 893
 894static struct snd_pcm_hardware vx_pcm_capture_hw = {
 895        .info =                 (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
 896                                 SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_MMAP_VALID /*|*/
 897                                 /*SNDRV_PCM_INFO_RESUME*/),
 898        .formats =              (/*SNDRV_PCM_FMTBIT_U8 |*/
 899                                 SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_3LE),
 900        .rates =                SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,
 901        .rate_min =             5000,
 902        .rate_max =             48000,
 903        .channels_min =         1,
 904        .channels_max =         2,
 905        .buffer_bytes_max =     (128*1024),
 906        .period_bytes_min =     126,
 907        .period_bytes_max =     (128*1024),
 908        .periods_min =          2,
 909        .periods_max =          VX_MAX_PERIODS,
 910        .fifo_size =            126,
 911};
 912
 913
 914/*
 915 * vx_pcm_capture_open - open callback for capture
 916 */
 917static int vx_pcm_capture_open(struct snd_pcm_substream *subs)
 918{
 919        struct snd_pcm_runtime *runtime = subs->runtime;
 920        struct vx_core *chip = snd_pcm_substream_chip(subs);
 921        struct vx_pipe *pipe;
 922        struct vx_pipe *pipe_out_monitoring = NULL;
 923        unsigned int audio;
 924        int err;
 925
 926        if (chip->chip_status & VX_STAT_IS_STALE)
 927                return -EBUSY;
 928
 929        audio = subs->pcm->device * 2;
 930        if (snd_BUG_ON(audio >= chip->audio_ins))
 931                return -EINVAL;
 932        err = vx_alloc_pipe(chip, 1, audio, 2, &pipe);
 933        if (err < 0)
 934                return err;
 935        pipe->substream = subs;
 936        chip->capture_pipes[audio] = pipe;
 937
 938        /* check if monitoring is needed */
 939        if (chip->audio_monitor_active[audio]) {
 940                pipe_out_monitoring = chip->playback_pipes[audio];
 941                if (! pipe_out_monitoring) {
 942                        /* allocate a pipe */
 943                        err = vx_alloc_pipe(chip, 0, audio, 2, &pipe_out_monitoring);
 944                        if (err < 0)
 945                                return err;
 946                        chip->playback_pipes[audio] = pipe_out_monitoring;
 947                }
 948                pipe_out_monitoring->references++;
 949                /* 
 950                   if an output pipe is available, it's audios still may need to be 
 951                   unmuted. hence we'll have to call a mixer entry point.
 952                */
 953                vx_set_monitor_level(chip, audio, chip->audio_monitor[audio],
 954                                     chip->audio_monitor_active[audio]);
 955                /* assuming stereo */
 956                vx_set_monitor_level(chip, audio+1, chip->audio_monitor[audio+1],
 957                                     chip->audio_monitor_active[audio+1]); 
 958        }
 959
 960        pipe->monitoring_pipe = pipe_out_monitoring; /* default value NULL */
 961
 962        runtime->hw = vx_pcm_capture_hw;
 963        runtime->hw.period_bytes_min = chip->ibl.size;
 964        runtime->private_data = pipe;
 965
 966        /* align to 4 bytes (otherwise will be problematic when 24bit is used) */ 
 967        snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 4);
 968        snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 4);
 969
 970        return 0;
 971}
 972
 973/*
 974 * vx_pcm_capture_close - close callback for capture
 975 */
 976static int vx_pcm_capture_close(struct snd_pcm_substream *subs)
 977{
 978        struct vx_core *chip = snd_pcm_substream_chip(subs);
 979        struct vx_pipe *pipe;
 980        struct vx_pipe *pipe_out_monitoring;
 981        
 982        if (! subs->runtime->private_data)
 983                return -EINVAL;
 984        pipe = subs->runtime->private_data;
 985        chip->capture_pipes[pipe->number] = NULL;
 986
 987        pipe_out_monitoring = pipe->monitoring_pipe;
 988
 989        /*
 990          if an output pipe is attached to this input, 
 991          check if it needs to be released.
 992        */
 993        if (pipe_out_monitoring) {
 994                if (--pipe_out_monitoring->references == 0) {
 995                        vx_free_pipe(chip, pipe_out_monitoring);
 996                        chip->playback_pipes[pipe->number] = NULL;
 997                        pipe->monitoring_pipe = NULL;
 998                }
 999        }
1000        
1001        vx_free_pipe(chip, pipe);
1002        return 0;
1003}
1004
1005
1006
1007#define DMA_READ_ALIGN  6       /* hardware alignment for read */
1008
1009/*
1010 * vx_pcm_capture_update - update the capture buffer
1011 */
1012static void vx_pcm_capture_update(struct vx_core *chip, struct snd_pcm_substream *subs,
1013                                  struct vx_pipe *pipe)
1014{
1015        int size, space, count;
1016        struct snd_pcm_runtime *runtime = subs->runtime;
1017
1018        if (! pipe->prepared || (chip->chip_status & VX_STAT_IS_STALE))
1019                return;
1020
1021        size = runtime->buffer_size - snd_pcm_capture_avail(runtime);
1022        if (! size)
1023                return;
1024        size = frames_to_bytes(runtime, size);
1025        space = vx_query_hbuffer_size(chip, pipe);
1026        if (space < 0)
1027                goto _error;
1028        if (size > space)
1029                size = space;
1030        size = (size / 3) * 3; /* align to 3 bytes */
1031        if (size < DMA_READ_ALIGN)
1032                goto _error;
1033
1034        /* keep the last 6 bytes, they will be read after disconnection */
1035        count = size - DMA_READ_ALIGN;
1036        /* read bytes until the current pointer reaches to the aligned position
1037         * for word-transfer
1038         */
1039        while (count > 0) {
1040                if ((pipe->hw_ptr % pipe->align) == 0)
1041                        break;
1042                if (vx_wait_for_rx_full(chip) < 0)
1043                        goto _error;
1044                vx_pcm_read_per_bytes(chip, runtime, pipe);
1045                count -= 3;
1046        }
1047        if (count > 0) {
1048                /* ok, let's accelerate! */
1049                int align = pipe->align * 3;
1050                space = (count / align) * align;
1051                vx_pseudo_dma_read(chip, runtime, pipe, space);
1052                count -= space;
1053        }
1054        /* read the rest of bytes */
1055        while (count > 0) {
1056                if (vx_wait_for_rx_full(chip) < 0)
1057                        goto _error;
1058                vx_pcm_read_per_bytes(chip, runtime, pipe);
1059                count -= 3;
1060        }
1061        /* disconnect the host, SIZE_HBUF command always switches to the stream mode */
1062        vx_send_rih(chip, IRQ_CONNECT_STREAM_NEXT);
1063        /* read the last pending 6 bytes */
1064        count = DMA_READ_ALIGN;
1065        while (count > 0) {
1066                vx_pcm_read_per_bytes(chip, runtime, pipe);
1067                count -= 3;
1068        }
1069        /* update the position */
1070        pipe->transferred += size;
1071        if (pipe->transferred >= pipe->period_bytes) {
1072                pipe->transferred %= pipe->period_bytes;
1073                snd_pcm_period_elapsed(subs);
1074        }
1075        return;
1076
1077 _error:
1078        /* disconnect the host, SIZE_HBUF command always switches to the stream mode */
1079        vx_send_rih(chip, IRQ_CONNECT_STREAM_NEXT);
1080        return;
1081}
1082
1083/*
1084 * vx_pcm_capture_pointer - pointer callback for capture
1085 */
1086static snd_pcm_uframes_t vx_pcm_capture_pointer(struct snd_pcm_substream *subs)
1087{
1088        struct snd_pcm_runtime *runtime = subs->runtime;
1089        struct vx_pipe *pipe = runtime->private_data;
1090        return bytes_to_frames(runtime, pipe->hw_ptr);
1091}
1092
1093/*
1094 * operators for PCM capture
1095 */
1096static struct snd_pcm_ops vx_pcm_capture_ops = {
1097        .open =         vx_pcm_capture_open,
1098        .close =        vx_pcm_capture_close,
1099        .ioctl =        snd_pcm_lib_ioctl,
1100        .hw_params =    vx_pcm_hw_params,
1101        .hw_free =      vx_pcm_hw_free,
1102        .prepare =      vx_pcm_prepare,
1103        .trigger =      vx_pcm_trigger,
1104        .pointer =      vx_pcm_capture_pointer,
1105        .page =         snd_pcm_lib_get_vmalloc_page,
1106        .mmap =         snd_pcm_lib_mmap_vmalloc,
1107};
1108
1109
1110/*
1111 * interrupt handler for pcm streams
1112 */
1113void vx_pcm_update_intr(struct vx_core *chip, unsigned int events)
1114{
1115        unsigned int i;
1116        struct vx_pipe *pipe;
1117
1118#define EVENT_MASK      (END_OF_BUFFER_EVENTS_PENDING|ASYNC_EVENTS_PENDING)
1119
1120        if (events & EVENT_MASK) {
1121                vx_init_rmh(&chip->irq_rmh, CMD_ASYNC);
1122                if (events & ASYNC_EVENTS_PENDING)
1123                        chip->irq_rmh.Cmd[0] |= 0x00000001;     /* SEL_ASYNC_EVENTS */
1124                if (events & END_OF_BUFFER_EVENTS_PENDING)
1125                        chip->irq_rmh.Cmd[0] |= 0x00000002;     /* SEL_END_OF_BUF_EVENTS */
1126
1127                if (vx_send_msg(chip, &chip->irq_rmh) < 0) {
1128                        snd_printdd(KERN_ERR "msg send error!!\n");
1129                        return;
1130                }
1131
1132                i = 1;
1133                while (i < chip->irq_rmh.LgStat) {
1134                        int p, buf, capture, eob;
1135                        p = chip->irq_rmh.Stat[i] & MASK_FIRST_FIELD;
1136                        capture = (chip->irq_rmh.Stat[i] & 0x400000) ? 1 : 0;
1137                        eob = (chip->irq_rmh.Stat[i] & 0x800000) ? 1 : 0;
1138                        i++;
1139                        if (events & ASYNC_EVENTS_PENDING)
1140                                i++;
1141                        buf = 1; /* force to transfer */
1142                        if (events & END_OF_BUFFER_EVENTS_PENDING) {
1143                                if (eob)
1144                                        buf = chip->irq_rmh.Stat[i];
1145                                i++;
1146                        }
1147                        if (capture)
1148                                continue;
1149                        if (snd_BUG_ON(p < 0 || p >= chip->audio_outs))
1150                                continue;
1151                        pipe = chip->playback_pipes[p];
1152                        if (pipe && pipe->substream) {
1153                                vx_pcm_playback_update(chip, pipe->substream, pipe);
1154                                vx_pcm_playback_transfer(chip, pipe->substream, pipe, buf);
1155                        }
1156                }
1157        }
1158
1159        /* update the capture pcm pointers as frequently as possible */
1160        for (i = 0; i < chip->audio_ins; i++) {
1161                pipe = chip->capture_pipes[i];
1162                if (pipe && pipe->substream)
1163                        vx_pcm_capture_update(chip, pipe->substream, pipe);
1164        }
1165}
1166
1167
1168/*
1169 * vx_init_audio_io - check the available audio i/o and allocate pipe arrays
1170 */
1171static int vx_init_audio_io(struct vx_core *chip)
1172{
1173        struct vx_rmh rmh;
1174        int preferred;
1175
1176        vx_init_rmh(&rmh, CMD_SUPPORTED);
1177        if (vx_send_msg(chip, &rmh) < 0) {
1178                snd_printk(KERN_ERR "vx: cannot get the supported audio data\n");
1179                return -ENXIO;
1180        }
1181
1182        chip->audio_outs = rmh.Stat[0] & MASK_FIRST_FIELD;
1183        chip->audio_ins = (rmh.Stat[0] >> (FIELD_SIZE*2)) & MASK_FIRST_FIELD;
1184        chip->audio_info = rmh.Stat[1];
1185
1186        /* allocate pipes */
1187        chip->playback_pipes = kcalloc(chip->audio_outs, sizeof(struct vx_pipe *), GFP_KERNEL);
1188        if (!chip->playback_pipes)
1189                return -ENOMEM;
1190        chip->capture_pipes = kcalloc(chip->audio_ins, sizeof(struct vx_pipe *), GFP_KERNEL);
1191        if (!chip->capture_pipes) {
1192                kfree(chip->playback_pipes);
1193                return -ENOMEM;
1194        }
1195
1196        preferred = chip->ibl.size;
1197        chip->ibl.size = 0;
1198        vx_set_ibl(chip, &chip->ibl); /* query the info */
1199        if (preferred > 0) {
1200                chip->ibl.size = ((preferred + chip->ibl.granularity - 1) /
1201                                  chip->ibl.granularity) * chip->ibl.granularity;
1202                if (chip->ibl.size > chip->ibl.max_size)
1203                        chip->ibl.size = chip->ibl.max_size;
1204        } else
1205                chip->ibl.size = chip->ibl.min_size; /* set to the minimum */
1206        vx_set_ibl(chip, &chip->ibl);
1207
1208        return 0;
1209}
1210
1211
1212/*
1213 * free callback for pcm
1214 */
1215static void snd_vx_pcm_free(struct snd_pcm *pcm)
1216{
1217        struct vx_core *chip = pcm->private_data;
1218        chip->pcm[pcm->device] = NULL;
1219        kfree(chip->playback_pipes);
1220        chip->playback_pipes = NULL;
1221        kfree(chip->capture_pipes);
1222        chip->capture_pipes = NULL;
1223}
1224
1225/*
1226 * snd_vx_pcm_new - create and initialize a pcm
1227 */
1228int snd_vx_pcm_new(struct vx_core *chip)
1229{
1230        struct snd_pcm *pcm;
1231        unsigned int i;
1232        int err;
1233
1234        if ((err = vx_init_audio_io(chip)) < 0)
1235                return err;
1236
1237        for (i = 0; i < chip->hw->num_codecs; i++) {
1238                unsigned int outs, ins;
1239                outs = chip->audio_outs > i * 2 ? 1 : 0;
1240                ins = chip->audio_ins > i * 2 ? 1 : 0;
1241                if (! outs && ! ins)
1242                        break;
1243                err = snd_pcm_new(chip->card, "VX PCM", i,
1244                                  outs, ins, &pcm);
1245                if (err < 0)
1246                        return err;
1247                if (outs)
1248                        snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &vx_pcm_playback_ops);
1249                if (ins)
1250                        snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &vx_pcm_capture_ops);
1251
1252                pcm->private_data = chip;
1253                pcm->private_free = snd_vx_pcm_free;
1254                pcm->info_flags = 0;
1255                pcm->nonatomic = true;
1256                strcpy(pcm->name, chip->card->shortname);
1257                chip->pcm[i] = pcm;
1258        }
1259
1260        return 0;
1261}
1262