root/sound/drivers/vx/vx_pcm.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. vx_pcm_read_per_bytes
  2. vx_set_pcx_time
  3. vx_set_differed_time
  4. vx_set_stream_format
  5. vx_set_format
  6. vx_set_ibl
  7. vx_get_pipe_state
  8. vx_query_hbuffer_size
  9. vx_pipe_can_start
  10. vx_conf_pipe
  11. vx_send_irqa
  12. vx_toggle_pipe
  13. vx_stop_pipe
  14. vx_alloc_pipe
  15. vx_free_pipe
  16. vx_start_stream
  17. vx_stop_stream
  18. vx_pcm_playback_open
  19. vx_pcm_playback_close
  20. vx_notify_end_of_buffer
  21. vx_pcm_playback_transfer_chunk
  22. vx_update_pipe_position
  23. vx_pcm_playback_transfer
  24. vx_pcm_playback_update
  25. vx_pcm_trigger
  26. vx_pcm_playback_pointer
  27. vx_pcm_hw_params
  28. vx_pcm_hw_free
  29. vx_pcm_prepare
  30. vx_pcm_capture_open
  31. vx_pcm_capture_close
  32. vx_pcm_capture_update
  33. vx_pcm_capture_pointer
  34. vx_pcm_update_intr
  35. vx_init_audio_io
  36. snd_vx_pcm_free
  37. snd_vx_pcm_new

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

/* [<][>][^][v][top][bottom][index][help] */