Linux Audio

Check our new training course

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