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