/*
 * Driver for Digigram VX soundcards
 *
 * PCM part
 *
 * Copyright (c) 2002,2003 by Takashi Iwai <tiwai@suse.de>
 *
 *   This program is free software; you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License as published by
 *   the Free Software Foundation; either version 2 of the License, or
 *   (at your option) any later version.
 *
 *   This program is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU General Public License for more details.
 *
 *   You should have received a copy of the GNU General Public License
 *   along with this program; if not, write to the Free Software
 *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 *
 *
 * STRATEGY
 *  for playback, we send series of "chunks", which size is equal with the
 *  IBL size, typically 126 samples.  at each end of chunk, the end-of-buffer
 *  interrupt is notified, and the interrupt handler will feed the next chunk.
 *
 *  the current position is calculated from the sample count RMH.
 *  pipe->transferred is the counter of data which has been already transferred.
 *  if this counter reaches to the period size, snd_pcm_period_elapsed() will
 *  be issued.
 *
 *  for capture, the situation is much easier.
 *  to get a low latency response, we'll check the capture streams at each
 *  interrupt (capture stream has no EOB notification).  if the pending
 *  data is accumulated to the period size, snd_pcm_period_elapsed() is
 *  called and the pointer is updated.
 *
 *  the current point of read buffer is kept in pipe->hw_ptr.  note that
 *  this is in bytes.
 *
 *
 * TODO
 *  - linked trigger for full-duplex mode.
 *  - scheduled action on the stream.
 */

#include <sound/driver.h>
#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <linux/delay.h>
#include <sound/core.h>
#include <sound/asoundef.h>
#include <sound/pcm.h>
#include <sound/vx_core.h>
#include "vx_cmd.h"


/*
 * we use a vmalloc'ed (sg-)buffer
 */

/* get the physical page pointer on the given offset */
static struct page *snd_pcm_get_vmalloc_page(struct snd_pcm_substream *subs,
					     unsigned long offset)
{
	void *pageptr = subs->runtime->dma_area + offset;
	return vmalloc_to_page(pageptr);
}

/*
 * allocate a buffer via vmalloc_32().
 * called from hw_params
 * NOTE: this may be called not only once per pcm open!
 */
static int snd_pcm_alloc_vmalloc_buffer(struct snd_pcm_substream *subs, size_t size)
{
	struct snd_pcm_runtime *runtime = subs->runtime;
	if (runtime->dma_area) {
		/* already allocated */
		if (runtime->dma_bytes >= size)
			return 0; /* already enough large */
		vfree(runtime->dma_area);
	}
	runtime->dma_area = vmalloc_32(size);
	if (! runtime->dma_area)
		return -ENOMEM;
	memset(runtime->dma_area, 0, size);
	runtime->dma_bytes = size;
	return 1; /* changed */
}

/*
 * free the buffer.
 * called from hw_free callback
 * NOTE: this may be called not only once per pcm open!
 */
static int snd_pcm_free_vmalloc_buffer(struct snd_pcm_substream *subs)
{
	struct snd_pcm_runtime *runtime = subs->runtime;

	vfree(runtime->dma_area);
	runtime->dma_area = NULL;
	return 0;
}


/*
 * read three pending pcm bytes via inb()
 */
static void vx_pcm_read_per_bytes(struct vx_core *chip, struct snd_pcm_runtime *runtime,
				  struct vx_pipe *pipe)
{
	int offset = pipe->hw_ptr;
	unsigned char *buf = (unsigned char *)(runtime->dma_area + offset);
	*buf++ = vx_inb(chip, RXH);
	if (++offset >= pipe->buffer_bytes) {
		offset = 0;
		buf = (unsigned char *)runtime->dma_area;
	}
	*buf++ = vx_inb(chip, RXM);
	if (++offset >= pipe->buffer_bytes) {
		offset = 0;
		buf = (unsigned char *)runtime->dma_area;
	}
	*buf++ = vx_inb(chip, RXL);
	if (++offset >= pipe->buffer_bytes) {
		offset = 0;
		buf = (unsigned char *)runtime->dma_area;
	}
	pipe->hw_ptr = offset;
}

/*
 * vx_set_pcx_time - convert from the PC time to the RMH status time.
 * @pc_time: the pointer for the PC-time to set
 * @dsp_time: the pointer for RMH status time array
 */
static void vx_set_pcx_time(struct vx_core *chip, pcx_time_t *pc_time,
			    unsigned int *dsp_time)
{
	dsp_time[0] = (unsigned int)((*pc_time) >> 24) & PCX_TIME_HI_MASK;
	dsp_time[1] = (unsigned int)(*pc_time) &  MASK_DSP_WORD;
}

/*
 * vx_set_differed_time - set the differed time if specified
 * @rmh: the rmh record to modify
 * @pipe: the pipe to be checked
 *
 * if the pipe is programmed with the differed time, set the DSP time
 * on the rmh and changes its command length.
 *
 * returns the increase of the command length.
 */
static int vx_set_differed_time(struct vx_core *chip, struct vx_rmh *rmh,
				struct vx_pipe *pipe)
{
	/* Update The length added to the RMH command by the timestamp */
	if (! (pipe->differed_type & DC_DIFFERED_DELAY))
		return 0;
		
	/* Set the T bit */
	rmh->Cmd[0] |= DSP_DIFFERED_COMMAND_MASK;

	/* Time stamp is the 1st following parameter */
	vx_set_pcx_time(chip, &pipe->pcx_time, &rmh->Cmd[1]);

	/* Add the flags to a notified differed command */
	if (pipe->differed_type & DC_NOTIFY_DELAY)
		rmh->Cmd[1] |= NOTIFY_MASK_TIME_HIGH ;

	/* Add the flags to a multiple differed command */
	if (pipe->differed_type & DC_MULTIPLE_DELAY)
		rmh->Cmd[1] |= MULTIPLE_MASK_TIME_HIGH;

	/* Add the flags to a stream-time differed command */
	if (pipe->differed_type & DC_STREAM_TIME_DELAY)
		rmh->Cmd[1] |= STREAM_MASK_TIME_HIGH;
		
	rmh->LgCmd += 2;
	return 2;
}

/*
 * vx_set_stream_format - send the stream format command
 * @pipe: the affected pipe
 * @data: format bitmask
 */
static int vx_set_stream_format(struct vx_core *chip, struct vx_pipe *pipe,
				unsigned int data)
{
	struct vx_rmh rmh;

	vx_init_rmh(&rmh, pipe->is_capture ?
		    CMD_FORMAT_STREAM_IN : CMD_FORMAT_STREAM_OUT);
	rmh.Cmd[0] |= pipe->number << FIELD_SIZE;

        /* Command might be longer since we may have to add a timestamp */
	vx_set_differed_time(chip, &rmh, pipe);

	rmh.Cmd[rmh.LgCmd] = (data & 0xFFFFFF00) >> 8;
	rmh.Cmd[rmh.LgCmd + 1] = (data & 0xFF) << 16 /*| (datal & 0xFFFF00) >> 8*/;
	rmh.LgCmd += 2;
    
	return vx_send_msg(chip, &rmh);
}


/*
 * vx_set_format - set the format of a pipe
 * @pipe: the affected pipe
 * @runtime: pcm runtime instance to be referred
 *
 * returns 0 if successful, or a negative error code.
 */
static int vx_set_format(struct vx_core *chip, struct vx_pipe *pipe,
			 struct snd_pcm_runtime *runtime)
{
	unsigned int header = HEADER_FMT_BASE;

	if (runtime->channels == 1)
		header |= HEADER_FMT_MONO;
	if (snd_pcm_format_little_endian(runtime->format))
		header |= HEADER_FMT_INTEL;
	if (runtime->rate < 32000 && runtime->rate > 11025)
		header |= HEADER_FMT_UPTO32;
	else if (runtime->rate <= 11025)
		header |= HEADER_FMT_UPTO11;

	switch (snd_pcm_format_physical_width(runtime->format)) {
	// case 8: break;
	case 16: header |= HEADER_FMT_16BITS; break;
	case 24: header |= HEADER_FMT_24BITS; break;
	default : 
		snd_BUG();
		return -EINVAL;
        };

	return vx_set_stream_format(chip, pipe, header);
}

/*
 * set / query the IBL size
 */
static int vx_set_ibl(struct vx_core *chip, struct vx_ibl_info *info)
{
	int err;
	struct vx_rmh rmh;

	vx_init_rmh(&rmh, CMD_IBL);
	rmh.Cmd[0] |= info->size & 0x03ffff;
	err = vx_send_msg(chip, &rmh);
	if (err < 0)
		return err;
	info->size = rmh.Stat[0];
	info->max_size = rmh.Stat[1];
	info->min_size = rmh.Stat[2];
	info->granularity = rmh.Stat[3];
	snd_printdd(KERN_DEBUG "vx_set_ibl: size = %d, max = %d, min = %d, gran = %d\n",
		   info->size, info->max_size, info->min_size, info->granularity);
	return 0;
}


/*
 * vx_get_pipe_state - get the state of a pipe
 * @pipe: the pipe to be checked
 * @state: the pointer for the returned state
 *
 * checks the state of a given pipe, and stores the state (1 = running,
 * 0 = paused) on the given pointer.
 *
 * called from trigger callback only
 */
static int vx_get_pipe_state(struct vx_core *chip, struct vx_pipe *pipe, int *state)
{
	int err;
	struct vx_rmh rmh;

	vx_init_rmh(&rmh, CMD_PIPE_STATE);
	vx_set_pipe_cmd_params(&rmh, pipe->is_capture, pipe->number, 0);
	err = vx_send_msg_nolock(chip, &rmh); /* no lock needed for trigger */ 
	if (! err)
		*state = (rmh.Stat[0] & (1 << pipe->number)) ? 1 : 0;
	return err;
}


/*
 * vx_query_hbuffer_size - query available h-buffer size in bytes
 * @pipe: the pipe to be checked
 *
 * return the available size on h-buffer in bytes,
 * or a negative error code.
 *
 * NOTE: calling this function always switches to the stream mode.
 *       you'll need to disconnect the host to get back to the
 *       normal mode.
 */
static int vx_query_hbuffer_size(struct vx_core *chip, struct vx_pipe *pipe)
{
	int result;
	struct vx_rmh rmh;

	vx_init_rmh(&rmh, CMD_SIZE_HBUFFER);
	vx_set_pipe_cmd_params(&rmh, pipe->is_capture, pipe->number, 0);
	if (pipe->is_capture)
		rmh.Cmd[0] |= 0x00000001;
	result = vx_send_msg(chip, &rmh);
	if (! result)
		result = rmh.Stat[0] & 0xffff;
	return result;
}


/*
 * vx_pipe_can_start - query whether a pipe is ready for start
 * @pipe: the pipe to be checked
 *
 * return 1 if ready, 0 if not ready, and negative value on error.
 *
 * called from trigger callback only
 */
static int vx_pipe_can_start(struct vx_core *chip, struct vx_pipe *pipe)
{
	int err;
	struct vx_rmh rmh;
        
	vx_init_rmh(&rmh, CMD_CAN_START_PIPE);
	vx_set_pipe_cmd_params(&rmh, pipe->is_capture, pipe->number, 0);
	rmh.Cmd[0] |= 1;

	err = vx_send_msg_nolock(chip, &rmh); /* no lock needed for trigger */ 
	if (! err) {
		if (rmh.Stat[0])
			err = 1;
	}
	return err;
}

/*
 * vx_conf_pipe - tell the pipe to stand by and wait for IRQA.
 * @pipe: the pipe to be configured
 */
static int vx_conf_pipe(struct vx_core *chip, struct vx_pipe *pipe)
{
	struct vx_rmh rmh;

	vx_init_rmh(&rmh, CMD_CONF_PIPE);
	if (pipe->is_capture)
		rmh.Cmd[0] |= COMMAND_RECORD_MASK;
	rmh.Cmd[1] = 1 << pipe->number;
	return vx_send_msg_nolock(chip, &rmh); /* no lock needed for trigger */
}

/*
 * vx_send_irqa - trigger IRQA
 */
static int vx_send_irqa(struct vx_core *chip)
{
	struct vx_rmh rmh;

	vx_init_rmh(&rmh, CMD_SEND_IRQA);
	return vx_send_msg_nolock(chip, &rmh); /* no lock needed for trigger */ 
}


#define MAX_WAIT_FOR_DSP        250
/*
 * vx boards do not support inter-card sync, besides
 * only 126 samples require to be prepared before a pipe can start
 */
#define CAN_START_DELAY         2	/* wait 2ms only before asking if the pipe is ready*/
#define WAIT_STATE_DELAY        2	/* wait 2ms after irqA was requested and check if the pipe state toggled*/

/*
 * vx_toggle_pipe - start / pause a pipe
 * @pipe: the pipe to be triggered
 * @state: start = 1, pause = 0
 *
 * called from trigger callback only
 *
 */
static int vx_toggle_pipe(struct vx_core *chip, struct vx_pipe *pipe, int state)
{
	int err, i, cur_state;

	/* Check the pipe is not already in the requested state */
	if (vx_get_pipe_state(chip, pipe, &cur_state) < 0)
		return -EBADFD;
	if (state == cur_state)
		return 0;

	/* If a start is requested, ask the DSP to get prepared
	 * and wait for a positive acknowledge (when there are
	 * enough sound buffer for this pipe)
	 */
	if (state) {
		for (i = 0 ; i < MAX_WAIT_FOR_DSP; i++) {
			err = vx_pipe_can_start(chip, pipe);
			if (err > 0)
				break;
			/* Wait for a few, before asking again
			 * to avoid flooding the DSP with our requests
			 */
			mdelay(1);
		}
	}
    
	if ((err = vx_conf_pipe(chip, pipe)) < 0)
		return err;

	if ((err = vx_send_irqa(chip)) < 0)
		return err;
    
	/* If it completes successfully, wait for the pipes
	 * reaching the expected state before returning
	 * Check one pipe only (since they are synchronous)
	 */
	for (i = 0; i < MAX_WAIT_FOR_DSP; i++) {
		err = vx_get_pipe_state(chip, pipe, &cur_state);
		if (err < 0 || cur_state == state)
			break;
		err = -EIO;
		mdelay(1);
	}
	return err < 0 ? -EIO : 0;
}

    
/*
 * vx_stop_pipe - stop a pipe
 * @pipe: the pipe to be stopped
 *
 * called from trigger callback only
 */
static int vx_stop_pipe(struct vx_core *chip, struct vx_pipe *pipe)
{
	struct vx_rmh rmh;
	vx_init_rmh(&rmh, CMD_STOP_PIPE);
	vx_set_pipe_cmd_params(&rmh, pipe->is_capture, pipe->number, 0);
	return vx_send_msg_nolock(chip, &rmh); /* no lock needed for trigger */ 
}


/*
 * vx_alloc_pipe - allocate a pipe and initialize the pipe instance
 * @capture: 0 = playback, 1 = capture operation
 * @audioid: the audio id to be assigned
 * @num_audio: number of audio channels
 * @pipep: the returned pipe instance
 *
 * return 0 on success, or a negative error code.
 */
static int vx_alloc_pipe(struct vx_core *chip, int capture,
			 int audioid, int num_audio,
			 struct vx_pipe **pipep)
{
	int err;
	struct vx_pipe *pipe;
	struct vx_rmh rmh;
	int data_mode;

	*pipep = NULL;
	vx_init_rmh(&rmh, CMD_RES_PIPE);
	vx_set_pipe_cmd_params(&rmh, capture, audioid, num_audio);
#if 0	// NYI
	if (underrun_skip_sound)
		rmh.Cmd[0] |= BIT_SKIP_SOUND;
#endif	// NYI
	data_mode = (chip->uer_bits & IEC958_AES0_NONAUDIO) != 0;
	if (! capture && data_mode)
		rmh.Cmd[0] |= BIT_DATA_MODE;
	err = vx_send_msg(chip, &rmh);
	if (err < 0)
		return err;

	/* initialize the pipe record */
	pipe = kzalloc(sizeof(*pipe), GFP_KERNEL);
	if (! pipe) {
		/* release the pipe */
		vx_init_rmh(&rmh, CMD_FREE_PIPE);
		vx_set_pipe_cmd_params(&rmh, capture, audioid, 0);
		vx_send_msg(chip, &rmh);
		return -ENOMEM;
	}

	/* the pipe index should be identical with the audio index */
	pipe->number = audioid;
	pipe->is_capture = capture;
	pipe->channels = num_audio;
	pipe->differed_type = 0;
	pipe->pcx_time = 0;
	pipe->data_mode = data_mode;
	*pipep = pipe;

	return 0;
}


/*
 * vx_free_pipe - release a pipe
 * @pipe: pipe to be released
 */
static int vx_free_pipe(struct vx_core *chip, struct vx_pipe *pipe)
{
	struct vx_rmh rmh;

	vx_init_rmh(&rmh, CMD_FREE_PIPE);
	vx_set_pipe_cmd_params(&rmh, pipe->is_capture, pipe->number, 0);
	vx_send_msg(chip, &rmh);

	kfree(pipe);
	return 0;
}


/*
 * vx_start_stream - start the stream
 *
 * called from trigger callback only
 */
static int vx_start_stream(struct vx_core *chip, struct vx_pipe *pipe)
{
	struct vx_rmh rmh;

	vx_init_rmh(&rmh, CMD_START_ONE_STREAM);
	vx_set_stream_cmd_params(&rmh, pipe->is_capture, pipe->number);
	vx_set_differed_time(chip, &rmh, pipe);
	return vx_send_msg_nolock(chip, &rmh); /* no lock needed for trigger */ 
}


/*
 * vx_stop_stream - stop the stream
 *
 * called from trigger callback only
 */
static int vx_stop_stream(struct vx_core *chip, struct vx_pipe *pipe)
{
	struct vx_rmh rmh;

	vx_init_rmh(&rmh, CMD_STOP_STREAM);
	vx_set_stream_cmd_params(&rmh, pipe->is_capture, pipe->number);
	return vx_send_msg_nolock(chip, &rmh); /* no lock needed for trigger */ 
}


/*
 * playback hw information
 */

static struct snd_pcm_hardware vx_pcm_playback_hw = {
	.info =			(SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
				 SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_MMAP_VALID /*|*/
				 /*SNDRV_PCM_INFO_RESUME*/),
	.formats =		(/*SNDRV_PCM_FMTBIT_U8 |*/
				 SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_3LE),
	.rates =		SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,
	.rate_min =		5000,
	.rate_max =		48000,
	.channels_min =		1,
	.channels_max =		2,
	.buffer_bytes_max =	(128*1024),
	.period_bytes_min =	126,
	.period_bytes_max =	(128*1024),
	.periods_min =		2,
	.periods_max =		VX_MAX_PERIODS,
	.fifo_size =		126,
};


static void vx_pcm_delayed_start(unsigned long arg);

/*
 * vx_pcm_playback_open - open callback for playback
 */
static int vx_pcm_playback_open(struct snd_pcm_substream *subs)
{
	struct snd_pcm_runtime *runtime = subs->runtime;
	struct vx_core *chip = snd_pcm_substream_chip(subs);
	struct vx_pipe *pipe = NULL;
	unsigned int audio;
	int err;

	if (chip->chip_status & VX_STAT_IS_STALE)
		return -EBUSY;

	audio = subs->pcm->device * 2;
	snd_assert(audio < chip->audio_outs, return -EINVAL);
	
	/* playback pipe may have been already allocated for monitoring */
	pipe = chip->playback_pipes[audio];
	if (! pipe) {
		/* not allocated yet */
		err = vx_alloc_pipe(chip, 0, audio, 2, &pipe); /* stereo playback */
		if (err < 0)
			return err;
		chip->playback_pipes[audio] = pipe;
	}
	/* open for playback */
	pipe->references++;

	pipe->substream = subs;
	tasklet_init(&pipe->start_tq, vx_pcm_delayed_start, (unsigned long)subs);
	chip->playback_pipes[audio] = pipe;

	runtime->hw = vx_pcm_playback_hw;
	runtime->hw.period_bytes_min = chip->ibl.size;
	runtime->private_data = pipe;

	/* align to 4 bytes (otherwise will be problematic when 24bit is used) */ 
	snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 4);
	snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 4);

	return 0;
}

/*
 * vx_pcm_playback_close - close callback for playback
 */
static int vx_pcm_playback_close(struct snd_pcm_substream *subs)
{
	struct vx_core *chip = snd_pcm_substream_chip(subs);
	struct vx_pipe *pipe;

	if (! subs->runtime->private_data)
		return -EINVAL;

	pipe = subs->runtime->private_data;

	if (--pipe->references == 0) {
		chip->playback_pipes[pipe->number] = NULL;
		vx_free_pipe(chip, pipe);
	}

	return 0;

}


/*
 * vx_notify_end_of_buffer - send "end-of-buffer" notifier at the given pipe
 * @pipe: the pipe to notify
 *
 * NB: call with a certain lock.
 */
static int vx_notify_end_of_buffer(struct vx_core *chip, struct vx_pipe *pipe)
{
	int err;
	struct vx_rmh rmh;  /* use a temporary rmh here */

	/* Toggle Dsp Host Interface into Message mode */
	vx_send_rih_nolock(chip, IRQ_PAUSE_START_CONNECT);
	vx_init_rmh(&rmh, CMD_NOTIFY_END_OF_BUFFER);
	vx_set_stream_cmd_params(&rmh, 0, pipe->number);
	err = vx_send_msg_nolock(chip, &rmh);
	if (err < 0)
		return err;
	/* Toggle Dsp Host Interface back to sound transfer mode */
	vx_send_rih_nolock(chip, IRQ_PAUSE_START_CONNECT);
	return 0;
}

/*
 * vx_pcm_playback_transfer_chunk - transfer a single chunk
 * @subs: substream
 * @pipe: the pipe to transfer
 * @size: chunk size in bytes
 *
 * transfer a single buffer chunk.  EOB notificaton is added after that.
 * called from the interrupt handler, too.
 *
 * return 0 if ok.
 */
static int vx_pcm_playback_transfer_chunk(struct vx_core *chip,
					  struct snd_pcm_runtime *runtime,
					  struct vx_pipe *pipe, int size)
{
	int space, err = 0;

	space = vx_query_hbuffer_size(chip, pipe);
	if (space < 0) {
		/* disconnect the host, SIZE_HBUF command always switches to the stream mode */
		vx_send_rih(chip, IRQ_CONNECT_STREAM_NEXT);
		snd_printd("error hbuffer\n");
		return space;
	}
	if (space < size) {
		vx_send_rih(chip, IRQ_CONNECT_STREAM_NEXT);
		snd_printd("no enough hbuffer space %d\n", space);
		return -EIO; /* XRUN */
	}
		
	/* we don't need irqsave here, because this function
	 * is called from either trigger callback or irq handler
	 */
	spin_lock(&chip->lock); 
	vx_pseudo_dma_write(chip, runtime, pipe, size);
	err = vx_notify_end_of_buffer(chip, pipe);
	/* disconnect the host, SIZE_HBUF command always switches to the stream mode */
	vx_send_rih_nolock(chip, IRQ_CONNECT_STREAM_NEXT);
	spin_unlock(&chip->lock);
	return err;
}

/*
 * update the position of the given pipe.
 * pipe->position is updated and wrapped within the buffer size.
 * pipe->transferred is updated, too, but the size is not wrapped,
 * so that the caller can check the total transferred size later
 * (to call snd_pcm_period_elapsed).
 */
static int vx_update_pipe_position(struct vx_core *chip,
				   struct snd_pcm_runtime *runtime,
				   struct vx_pipe *pipe)
{
	struct vx_rmh rmh;
	int err, update;
	u64 count;

	vx_init_rmh(&rmh, CMD_STREAM_SAMPLE_COUNT);
	vx_set_pipe_cmd_params(&rmh, pipe->is_capture, pipe->number, 0);
	err = vx_send_msg(chip, &rmh);
	if (err < 0)
		return err;

	count = ((u64)(rmh.Stat[0] & 0xfffff) << 24) | (u64)rmh.Stat[1];
	update = (int)(count - pipe->cur_count);
	pipe->cur_count = count;
	pipe->position += update;
	if (pipe->position >= (int)runtime->buffer_size)
		pipe->position %= runtime->buffer_size;
	pipe->transferred += update;
	return 0;
}

/*
 * transfer the pending playback buffer data to DSP
 * called from interrupt handler
 */
static void vx_pcm_playback_transfer(struct vx_core *chip,
				     struct snd_pcm_substream *subs,
				     struct vx_pipe *pipe, int nchunks)
{
	int i, err;
	struct snd_pcm_runtime *runtime = subs->runtime;

	if (! pipe->prepared || (chip->chip_status & VX_STAT_IS_STALE))
		return;
	for (i = 0; i < nchunks; i++) {
		if ((err = vx_pcm_playback_transfer_chunk(chip, runtime, pipe,
							  chip->ibl.size)) < 0)
			return;
	}
}

/*
 * update the playback position and call snd_pcm_period_elapsed() if necessary
 * called from interrupt handler
 */
static void vx_pcm_playback_update(struct vx_core *chip,
				   struct snd_pcm_substream *subs,
				   struct vx_pipe *pipe)
{
	int err;
	struct snd_pcm_runtime *runtime = subs->runtime;

	if (pipe->running && ! (chip->chip_status & VX_STAT_IS_STALE)) {
		if ((err = vx_update_pipe_position(chip, runtime, pipe)) < 0)
			return;
		if (pipe->transferred >= (int)runtime->period_size) {
			pipe->transferred %= runtime->period_size;
			snd_pcm_period_elapsed(subs);
		}
	}
}

/*
 * start the stream and pipe.
 * this function is called from tasklet, which is invoked by the trigger
 * START callback.
 */
static void vx_pcm_delayed_start(unsigned long arg)
{
	struct snd_pcm_substream *subs = (struct snd_pcm_substream *)arg;
	struct vx_core *chip = subs->pcm->private_data;
	struct vx_pipe *pipe = subs->runtime->private_data;
	int err;

	/*  printk( KERN_DEBUG "DDDD tasklet delayed start jiffies = %ld\n", jiffies);*/

	if ((err = vx_start_stream(chip, pipe)) < 0) {
		snd_printk(KERN_ERR "vx: cannot start stream\n");
		return;
	}
	if ((err = vx_toggle_pipe(chip, pipe, 1)) < 0) {
		snd_printk(KERN_ERR "vx: cannot start pipe\n");
		return;
	}
	/*   printk( KERN_DEBUG "dddd tasklet delayed start jiffies = %ld \n", jiffies);*/
}

/*
 * vx_pcm_playback_trigger - trigger callback for playback
 */
static int vx_pcm_trigger(struct snd_pcm_substream *subs, int cmd)
{
	struct vx_core *chip = snd_pcm_substream_chip(subs);
	struct vx_pipe *pipe = subs->runtime->private_data;
	int err;

	if (chip->chip_status & VX_STAT_IS_STALE)
		return -EBUSY;
		
	switch (cmd) {
	case SNDRV_PCM_TRIGGER_START:
	case SNDRV_PCM_TRIGGER_RESUME:
		if (! pipe->is_capture)
			vx_pcm_playback_transfer(chip, subs, pipe, 2);
		/* FIXME:
		 * we trigger the pipe using tasklet, so that the interrupts are
		 * issued surely after the trigger is completed.
		 */ 
		tasklet_hi_schedule(&pipe->start_tq);
		chip->pcm_running++;
		pipe->running = 1;
		break;
	case SNDRV_PCM_TRIGGER_STOP:
	case SNDRV_PCM_TRIGGER_SUSPEND:
		vx_toggle_pipe(chip, pipe, 0);
		vx_stop_pipe(chip, pipe);
		vx_stop_stream(chip, pipe);
		chip->pcm_running--;
		pipe->running = 0;
		break;
	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
		if ((err = vx_toggle_pipe(chip, pipe, 0)) < 0)
			return err;
		break;
	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
		if ((err = vx_toggle_pipe(chip, pipe, 1)) < 0)
			return err;
		break;
	default:
		return -EINVAL;
	}
	return 0;
}

/*
 * vx_pcm_playback_pointer - pointer callback for playback
 */
static snd_pcm_uframes_t vx_pcm_playback_pointer(struct snd_pcm_substream *subs)
{
	struct snd_pcm_runtime *runtime = subs->runtime;
	struct vx_pipe *pipe = runtime->private_data;
	return pipe->position;
}

/*
 * vx_pcm_hw_params - hw_params callback for playback and capture
 */
static int vx_pcm_hw_params(struct snd_pcm_substream *subs,
				     struct snd_pcm_hw_params *hw_params)
{
	return snd_pcm_alloc_vmalloc_buffer(subs, params_buffer_bytes(hw_params));
}

/*
 * vx_pcm_hw_free - hw_free callback for playback and capture
 */
static int vx_pcm_hw_free(struct snd_pcm_substream *subs)
{
	return snd_pcm_free_vmalloc_buffer(subs);
}

/*
 * vx_pcm_prepare - prepare callback for playback and capture
 */
static int vx_pcm_prepare(struct snd_pcm_substream *subs)
{
	struct vx_core *chip = snd_pcm_substream_chip(subs);
	struct snd_pcm_runtime *runtime = subs->runtime;
	struct vx_pipe *pipe = runtime->private_data;
	int err, data_mode;
	// int max_size, nchunks;

	if (chip->chip_status & VX_STAT_IS_STALE)
		return -EBUSY;

	data_mode = (chip->uer_bits & IEC958_AES0_NONAUDIO) != 0;
	if (data_mode != pipe->data_mode && ! pipe->is_capture) {
		/* IEC958 status (raw-mode) was changed */
		/* we reopen the pipe */
		struct vx_rmh rmh;
		snd_printdd(KERN_DEBUG "reopen the pipe with data_mode = %d\n", data_mode);
		vx_init_rmh(&rmh, CMD_FREE_PIPE);
		vx_set_pipe_cmd_params(&rmh, 0, pipe->number, 0);
		if ((err = vx_send_msg(chip, &rmh)) < 0)
			return err;
		vx_init_rmh(&rmh, CMD_RES_PIPE);
		vx_set_pipe_cmd_params(&rmh, 0, pipe->number, pipe->channels);
		if (data_mode)
			rmh.Cmd[0] |= BIT_DATA_MODE;
		if ((err = vx_send_msg(chip, &rmh)) < 0)
			return err;
		pipe->data_mode = data_mode;
	}

	if (chip->pcm_running && chip->freq != runtime->rate) {
		snd_printk(KERN_ERR "vx: cannot set different clock %d "
			   "from the current %d\n", runtime->rate, chip->freq);
		return -EINVAL;
	}
	vx_set_clock(chip, runtime->rate);

	if ((err = vx_set_format(chip, pipe, runtime)) < 0)
		return err;

	if (vx_is_pcmcia(chip)) {
		pipe->align = 2; /* 16bit word */
	} else {
		pipe->align = 4; /* 32bit word */
	}

	pipe->buffer_bytes = frames_to_bytes(runtime, runtime->buffer_size);
	pipe->period_bytes = frames_to_bytes(runtime, runtime->period_size);
	pipe->hw_ptr = 0;

	/* set the timestamp */
	vx_update_pipe_position(chip, runtime, pipe);
	/* clear again */
	pipe->transferred = 0;
	pipe->position = 0;

	pipe->prepared = 1;

	return 0;
}


/*
 * operators for PCM playback
 */
static struct snd_pcm_ops vx_pcm_playback_ops = {
	.open =		vx_pcm_playback_open,
	.close =	vx_pcm_playback_close,
	.ioctl =	snd_pcm_lib_ioctl,
	.hw_params =	vx_pcm_hw_params,
	.hw_free =	vx_pcm_hw_free,
	.prepare =	vx_pcm_prepare,
	.trigger =	vx_pcm_trigger,
	.pointer =	vx_pcm_playback_pointer,
	.page =		snd_pcm_get_vmalloc_page,
};


/*
 * playback hw information
 */

static struct snd_pcm_hardware vx_pcm_capture_hw = {
	.info =			(SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
				 SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_MMAP_VALID /*|*/
				 /*SNDRV_PCM_INFO_RESUME*/),
	.formats =		(/*SNDRV_PCM_FMTBIT_U8 |*/
				 SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_3LE),
	.rates =		SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,
	.rate_min =		5000,
	.rate_max =		48000,
	.channels_min =		1,
	.channels_max =		2,
	.buffer_bytes_max =	(128*1024),
	.period_bytes_min =	126,
	.period_bytes_max =	(128*1024),
	.periods_min =		2,
	.periods_max =		VX_MAX_PERIODS,
	.fifo_size =		126,
};


/*
 * vx_pcm_capture_open - open callback for capture
 */
static int vx_pcm_capture_open(struct snd_pcm_substream *subs)
{
	struct snd_pcm_runtime *runtime = subs->runtime;
	struct vx_core *chip = snd_pcm_substream_chip(subs);
	struct vx_pipe *pipe;
	struct vx_pipe *pipe_out_monitoring = NULL;
	unsigned int audio;
	int err;

	if (chip->chip_status & VX_STAT_IS_STALE)
		return -EBUSY;

	audio = subs->pcm->device * 2;
	snd_assert(audio < chip->audio_ins, return -EINVAL);
	err = vx_alloc_pipe(chip, 1, audio, 2, &pipe);
	if (err < 0)
		return err;
	pipe->substream = subs;
	tasklet_init(&pipe->start_tq, vx_pcm_delayed_start, (unsigned long)subs);
	chip->capture_pipes[audio] = pipe;

	/* check if monitoring is needed */
	if (chip->audio_monitor_active[audio]) {
		pipe_out_monitoring = chip->playback_pipes[audio];
		if (! pipe_out_monitoring) {
			/* allocate a pipe */
			err = vx_alloc_pipe(chip, 0, audio, 2, &pipe_out_monitoring);
			if (err < 0)
				return err;
			chip->playback_pipes[audio] = pipe_out_monitoring;
		}
		pipe_out_monitoring->references++;
		/* 
		   if an output pipe is available, it's audios still may need to be 
		   unmuted. hence we'll have to call a mixer entry point.
		*/
		vx_set_monitor_level(chip, audio, chip->audio_monitor[audio],
				     chip->audio_monitor_active[audio]);
		/* assuming stereo */
		vx_set_monitor_level(chip, audio+1, chip->audio_monitor[audio+1],
				     chip->audio_monitor_active[audio+1]); 
	}

	pipe->monitoring_pipe = pipe_out_monitoring; /* default value NULL */

	runtime->hw = vx_pcm_capture_hw;
	runtime->hw.period_bytes_min = chip->ibl.size;
	runtime->private_data = pipe;

	/* align to 4 bytes (otherwise will be problematic when 24bit is used) */ 
	snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 4);
	snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 4);

	return 0;
}

/*
 * vx_pcm_capture_close - close callback for capture
 */
static int vx_pcm_capture_close(struct snd_pcm_substream *subs)
{
	struct vx_core *chip = snd_pcm_substream_chip(subs);
	struct vx_pipe *pipe;
	struct vx_pipe *pipe_out_monitoring;
	
	if (! subs->runtime->private_data)
		return -EINVAL;
	pipe = subs->runtime->private_data;
	chip->capture_pipes[pipe->number] = NULL;

	pipe_out_monitoring = pipe->monitoring_pipe;

	/*
	  if an output pipe is attached to this input, 
	  check if it needs to be released.
	*/
	if (pipe_out_monitoring) {
		if (--pipe_out_monitoring->references == 0) {
			vx_free_pipe(chip, pipe_out_monitoring);
			chip->playback_pipes[pipe->number] = NULL;
			pipe->monitoring_pipe = NULL;
		}
	}
	
	vx_free_pipe(chip, pipe);
	return 0;
}



#define DMA_READ_ALIGN	6	/* hardware alignment for read */

/*
 * vx_pcm_capture_update - update the capture buffer
 */
static void vx_pcm_capture_update(struct vx_core *chip, struct snd_pcm_substream *subs,
				  struct vx_pipe *pipe)
{
	int size, space, count;
	struct snd_pcm_runtime *runtime = subs->runtime;

	if (! pipe->prepared || (chip->chip_status & VX_STAT_IS_STALE))
		return;

	size = runtime->buffer_size - snd_pcm_capture_avail(runtime);
	if (! size)
		return;
	size = frames_to_bytes(runtime, size);
	space = vx_query_hbuffer_size(chip, pipe);
	if (space < 0)
		goto _error;
	if (size > space)
		size = space;
	size = (size / 3) * 3; /* align to 3 bytes */
	if (size < DMA_READ_ALIGN)
		goto _error;

	/* keep the last 6 bytes, they will be read after disconnection */
	count = size - DMA_READ_ALIGN;
	/* read bytes until the current pointer reaches to the aligned position
	 * for word-transfer
	 */
	while (count > 0) {
		if ((pipe->hw_ptr % pipe->align) == 0)
			break;
		if (vx_wait_for_rx_full(chip) < 0)
			goto _error;
		vx_pcm_read_per_bytes(chip, runtime, pipe);
		count -= 3;
	}
	if (count > 0) {
		/* ok, let's accelerate! */
		int align = pipe->align * 3;
		space = (count / align) * align;
		vx_pseudo_dma_read(chip, runtime, pipe, space);
		count -= space;
	}
	/* read the rest of bytes */
	while (count > 0) {
		if (vx_wait_for_rx_full(chip) < 0)
			goto _error;
		vx_pcm_read_per_bytes(chip, runtime, pipe);
		count -= 3;
	}
	/* disconnect the host, SIZE_HBUF command always switches to the stream mode */
	vx_send_rih_nolock(chip, IRQ_CONNECT_STREAM_NEXT);
	/* read the last pending 6 bytes */
	count = DMA_READ_ALIGN;
	while (count > 0) {
		vx_pcm_read_per_bytes(chip, runtime, pipe);
		count -= 3;
	}
	/* update the position */
	pipe->transferred += size;
	if (pipe->transferred >= pipe->period_bytes) {
		pipe->transferred %= pipe->period_bytes;
		snd_pcm_period_elapsed(subs);
	}
	return;

 _error:
	/* disconnect the host, SIZE_HBUF command always switches to the stream mode */
	vx_send_rih_nolock(chip, IRQ_CONNECT_STREAM_NEXT);
	return;
}

/*
 * vx_pcm_capture_pointer - pointer callback for capture
 */
static snd_pcm_uframes_t vx_pcm_capture_pointer(struct snd_pcm_substream *subs)
{
	struct snd_pcm_runtime *runtime = subs->runtime;
	struct vx_pipe *pipe = runtime->private_data;
	return bytes_to_frames(runtime, pipe->hw_ptr);
}

/*
 * operators for PCM capture
 */
static struct snd_pcm_ops vx_pcm_capture_ops = {
	.open =		vx_pcm_capture_open,
	.close =	vx_pcm_capture_close,
	.ioctl =	snd_pcm_lib_ioctl,
	.hw_params =	vx_pcm_hw_params,
	.hw_free =	vx_pcm_hw_free,
	.prepare =	vx_pcm_prepare,
	.trigger =	vx_pcm_trigger,
	.pointer =	vx_pcm_capture_pointer,
	.page =		snd_pcm_get_vmalloc_page,
};


/*
 * interrupt handler for pcm streams
 */
void vx_pcm_update_intr(struct vx_core *chip, unsigned int events)
{
	unsigned int i;
	struct vx_pipe *pipe;

#define EVENT_MASK	(END_OF_BUFFER_EVENTS_PENDING|ASYNC_EVENTS_PENDING)

	if (events & EVENT_MASK) {
		vx_init_rmh(&chip->irq_rmh, CMD_ASYNC);
		if (events & ASYNC_EVENTS_PENDING)
			chip->irq_rmh.Cmd[0] |= 0x00000001;	/* SEL_ASYNC_EVENTS */
		if (events & END_OF_BUFFER_EVENTS_PENDING)
			chip->irq_rmh.Cmd[0] |= 0x00000002;	/* SEL_END_OF_BUF_EVENTS */

		if (vx_send_msg(chip, &chip->irq_rmh) < 0) {
			snd_printdd(KERN_ERR "msg send error!!\n");
			return;
		}

		i = 1;
		while (i < chip->irq_rmh.LgStat) {
			int p, buf, capture, eob;
			p = chip->irq_rmh.Stat[i] & MASK_FIRST_FIELD;
			capture = (chip->irq_rmh.Stat[i] & 0x400000) ? 1 : 0;
			eob = (chip->irq_rmh.Stat[i] & 0x800000) ? 1 : 0;
			i++;
			if (events & ASYNC_EVENTS_PENDING)
				i++;
			buf = 1; /* force to transfer */
			if (events & END_OF_BUFFER_EVENTS_PENDING) {
				if (eob)
					buf = chip->irq_rmh.Stat[i];
				i++;
			}
			if (capture)
				continue;
			snd_assert(p >= 0 && (unsigned int)p < chip->audio_outs,);
			pipe = chip->playback_pipes[p];
			if (pipe && pipe->substream) {
				vx_pcm_playback_update(chip, pipe->substream, pipe);
				vx_pcm_playback_transfer(chip, pipe->substream, pipe, buf);
			}
		}
	}

	/* update the capture pcm pointers as frequently as possible */
	for (i = 0; i < chip->audio_ins; i++) {
		pipe = chip->capture_pipes[i];
		if (pipe && pipe->substream)
			vx_pcm_capture_update(chip, pipe->substream, pipe);
	}
}


/*
 * vx_init_audio_io - check the availabe audio i/o and allocate pipe arrays
 */
static int vx_init_audio_io(struct vx_core *chip)
{
	struct vx_rmh rmh;
	int preferred;

	vx_init_rmh(&rmh, CMD_SUPPORTED);
	if (vx_send_msg(chip, &rmh) < 0) {
		snd_printk(KERN_ERR "vx: cannot get the supported audio data\n");
		return -ENXIO;
	}

	chip->audio_outs = rmh.Stat[0] & MASK_FIRST_FIELD;
	chip->audio_ins = (rmh.Stat[0] >> (FIELD_SIZE*2)) & MASK_FIRST_FIELD;
	chip->audio_info = rmh.Stat[1];

	/* allocate pipes */
	chip->playback_pipes = kcalloc(chip->audio_outs, sizeof(struct vx_pipe *), GFP_KERNEL);
	if (!chip->playback_pipes)
		return -ENOMEM;
	chip->capture_pipes = kcalloc(chip->audio_ins, sizeof(struct vx_pipe *), GFP_KERNEL);
	if (!chip->capture_pipes) {
		kfree(chip->playback_pipes);
		return -ENOMEM;
	}

	preferred = chip->ibl.size;
	chip->ibl.size = 0;
	vx_set_ibl(chip, &chip->ibl); /* query the info */
	if (preferred > 0) {
		chip->ibl.size = ((preferred + chip->ibl.granularity - 1) /
				  chip->ibl.granularity) * chip->ibl.granularity;
		if (chip->ibl.size > chip->ibl.max_size)
			chip->ibl.size = chip->ibl.max_size;
	} else
		chip->ibl.size = chip->ibl.min_size; /* set to the minimum */
	vx_set_ibl(chip, &chip->ibl);

	return 0;
}


/*
 * free callback for pcm
 */
static void snd_vx_pcm_free(struct snd_pcm *pcm)
{
	struct vx_core *chip = pcm->private_data;
	chip->pcm[pcm->device] = NULL;
	kfree(chip->playback_pipes);
	chip->playback_pipes = NULL;
	kfree(chip->capture_pipes);
	chip->capture_pipes = NULL;
}

/*
 * snd_vx_pcm_new - create and initialize a pcm
 */
int snd_vx_pcm_new(struct vx_core *chip)
{
	struct snd_pcm *pcm;
	unsigned int i;
	int err;

	if ((err = vx_init_audio_io(chip)) < 0)
		return err;

	for (i = 0; i < chip->hw->num_codecs; i++) {
		unsigned int outs, ins;
		outs = chip->audio_outs > i * 2 ? 1 : 0;
		ins = chip->audio_ins > i * 2 ? 1 : 0;
		if (! outs && ! ins)
			break;
		err = snd_pcm_new(chip->card, "VX PCM", i,
				  outs, ins, &pcm);
		if (err < 0)
			return err;
		if (outs)
			snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &vx_pcm_playback_ops);
		if (ins)
			snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &vx_pcm_capture_ops);

		pcm->private_data = chip;
		pcm->private_free = snd_vx_pcm_free;
		pcm->info_flags = 0;
		strcpy(pcm->name, chip->card->shortname);
		chip->pcm[i] = pcm;
	}

	return 0;
}
