/*
 * Helper functions for indirect PCM data transfer
 *
 *  Copyright (c) by Takashi Iwai <tiwai@suse.de>
 *                   Jaroslav Kysela <perex@perex.cz>
 *
 *   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., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

#ifndef __SOUND_PCM_INDIRECT_H
#define __SOUND_PCM_INDIRECT_H

#include <sound/pcm.h>

struct snd_pcm_indirect {
	unsigned int hw_buffer_size;	/* Byte size of hardware buffer */
	unsigned int hw_queue_size;	/* Max queue size of hw buffer (0 = buffer size) */
	unsigned int hw_data;	/* Offset to next dst (or src) in hw ring buffer */
	unsigned int hw_io;	/* Ring buffer hw pointer */
	int hw_ready;		/* Bytes ready for play (or captured) in hw ring buffer */
	unsigned int sw_buffer_size;	/* Byte size of software buffer */
	unsigned int sw_data;	/* Offset to next dst (or src) in sw ring buffer */
	unsigned int sw_io;	/* Current software pointer in bytes */
	int sw_ready;		/* Bytes ready to be transferred to/from hw */
	snd_pcm_uframes_t appl_ptr;	/* Last seen appl_ptr */
};

typedef void (*snd_pcm_indirect_copy_t)(struct snd_pcm_substream *substream,
					struct snd_pcm_indirect *rec, size_t bytes);

/*
 * helper function for playback ack callback
 */
static inline void
snd_pcm_indirect_playback_transfer(struct snd_pcm_substream *substream,
				   struct snd_pcm_indirect *rec,
				   snd_pcm_indirect_copy_t copy)
{
	struct snd_pcm_runtime *runtime = substream->runtime;
	snd_pcm_uframes_t appl_ptr = runtime->control->appl_ptr;
	snd_pcm_sframes_t diff = appl_ptr - rec->appl_ptr;
	int qsize;

	if (diff) {
		if (diff < -(snd_pcm_sframes_t) (runtime->boundary / 2))
			diff += runtime->boundary;
		rec->sw_ready += (int)frames_to_bytes(runtime, diff);
		rec->appl_ptr = appl_ptr;
	}
	qsize = rec->hw_queue_size ? rec->hw_queue_size : rec->hw_buffer_size;
	while (rec->hw_ready < qsize && rec->sw_ready > 0) {
		unsigned int hw_to_end = rec->hw_buffer_size - rec->hw_data;
		unsigned int sw_to_end = rec->sw_buffer_size - rec->sw_data;
		unsigned int bytes = qsize - rec->hw_ready;
		if (rec->sw_ready < (int)bytes)
			bytes = rec->sw_ready;
		if (hw_to_end < bytes)
			bytes = hw_to_end;
		if (sw_to_end < bytes)
			bytes = sw_to_end;
		if (! bytes)
			break;
		copy(substream, rec, bytes);
		rec->hw_data += bytes;
		if (rec->hw_data == rec->hw_buffer_size)
			rec->hw_data = 0;
		rec->sw_data += bytes;
		if (rec->sw_data == rec->sw_buffer_size)
			rec->sw_data = 0;
		rec->hw_ready += bytes;
		rec->sw_ready -= bytes;
	}
}

/*
 * helper function for playback pointer callback
 * ptr = current byte pointer
 */
static inline snd_pcm_uframes_t
snd_pcm_indirect_playback_pointer(struct snd_pcm_substream *substream,
				  struct snd_pcm_indirect *rec, unsigned int ptr)
{
	int bytes = ptr - rec->hw_io;
	if (bytes < 0)
		bytes += rec->hw_buffer_size;
	rec->hw_io = ptr;
	rec->hw_ready -= bytes;
	rec->sw_io += bytes;
	if (rec->sw_io >= rec->sw_buffer_size)
		rec->sw_io -= rec->sw_buffer_size;
	if (substream->ops->ack)
		substream->ops->ack(substream);
	return bytes_to_frames(substream->runtime, rec->sw_io);
}


/*
 * helper function for capture ack callback
 */
static inline void
snd_pcm_indirect_capture_transfer(struct snd_pcm_substream *substream,
				  struct snd_pcm_indirect *rec,
				  snd_pcm_indirect_copy_t copy)
{
	struct snd_pcm_runtime *runtime = substream->runtime;
	snd_pcm_uframes_t appl_ptr = runtime->control->appl_ptr;
	snd_pcm_sframes_t diff = appl_ptr - rec->appl_ptr;

	if (diff) {
		if (diff < -(snd_pcm_sframes_t) (runtime->boundary / 2))
			diff += runtime->boundary;
		rec->sw_ready -= frames_to_bytes(runtime, diff);
		rec->appl_ptr = appl_ptr;
	}
	while (rec->hw_ready > 0 && 
	       rec->sw_ready < (int)rec->sw_buffer_size) {
		size_t hw_to_end = rec->hw_buffer_size - rec->hw_data;
		size_t sw_to_end = rec->sw_buffer_size - rec->sw_data;
		size_t bytes = rec->sw_buffer_size - rec->sw_ready;
		if (rec->hw_ready < (int)bytes)
			bytes = rec->hw_ready;
		if (hw_to_end < bytes)
			bytes = hw_to_end;
		if (sw_to_end < bytes)
			bytes = sw_to_end;
		if (! bytes)
			break;
		copy(substream, rec, bytes);
		rec->hw_data += bytes;
		if ((int)rec->hw_data == rec->hw_buffer_size)
			rec->hw_data = 0;
		rec->sw_data += bytes;
		if (rec->sw_data == rec->sw_buffer_size)
			rec->sw_data = 0;
		rec->hw_ready -= bytes;
		rec->sw_ready += bytes;
	}
}

/*
 * helper function for capture pointer callback,
 * ptr = current byte pointer
 */
static inline snd_pcm_uframes_t
snd_pcm_indirect_capture_pointer(struct snd_pcm_substream *substream,
				 struct snd_pcm_indirect *rec, unsigned int ptr)
{
	int qsize;
	int bytes = ptr - rec->hw_io;
	if (bytes < 0)
		bytes += rec->hw_buffer_size;
	rec->hw_io = ptr;
	rec->hw_ready += bytes;
	qsize = rec->hw_queue_size ? rec->hw_queue_size : rec->hw_buffer_size;
	if (rec->hw_ready > qsize)
		return SNDRV_PCM_POS_XRUN;
	rec->sw_io += bytes;
	if (rec->sw_io >= rec->sw_buffer_size)
		rec->sw_io -= rec->sw_buffer_size;
	if (substream->ops->ack)
		substream->ops->ack(substream);
	return bytes_to_frames(substream->runtime, rec->sw_io);
}

#endif /* __SOUND_PCM_INDIRECT_H */
