File Index
Files and directories
Sign in
FILE

vx_pcm.c

File preview with syntax highlighting.

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