/*
 *   Copyright (c) 2006-2008 Daniel Mack, Karsten Wiese
 *
 *   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
*/

#include <linux/spinlock.h>
#include <linux/slab.h>
#include <linux/init.h>
#include <linux/usb.h>
#include <sound/core.h>
#include <sound/pcm.h>

#include "device.h"
#include "audio.h"

#define N_URBS			32
#define CLOCK_DRIFT_TOLERANCE	5
#define FRAMES_PER_URB		8
#define BYTES_PER_FRAME		512
#define CHANNELS_PER_STREAM	2
#define BYTES_PER_SAMPLE	3
#define BYTES_PER_SAMPLE_USB	4
#define MAX_BUFFER_SIZE		(128*1024)
#define MAX_ENDPOINT_SIZE	512

#define ENDPOINT_CAPTURE	2
#define ENDPOINT_PLAYBACK	6

#define MAKE_CHECKBYTE(dev,stream,i) \
	(stream << 1) | (~(i / (dev->n_streams * BYTES_PER_SAMPLE_USB)) & 1)

static struct snd_pcm_hardware snd_usb_caiaq_pcm_hardware = {
	.info 		= (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
			   SNDRV_PCM_INFO_BLOCK_TRANSFER),
	.formats 	= SNDRV_PCM_FMTBIT_S24_3BE,
	.rates 		= (SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |
			   SNDRV_PCM_RATE_96000),
	.rate_min	= 44100,
	.rate_max	= 0, /* will overwrite later */
	.channels_min	= CHANNELS_PER_STREAM,
	.channels_max	= CHANNELS_PER_STREAM,
	.buffer_bytes_max = MAX_BUFFER_SIZE,
	.period_bytes_min = 128,
	.period_bytes_max = MAX_BUFFER_SIZE,
	.periods_min	= 1,
	.periods_max	= 1024,
};

static void
activate_substream(struct snd_usb_caiaqdev *dev,
	           struct snd_pcm_substream *sub)
{
	spin_lock(&dev->spinlock);

	if (sub->stream == SNDRV_PCM_STREAM_PLAYBACK)
		dev->sub_playback[sub->number] = sub;
	else
		dev->sub_capture[sub->number] = sub;

	spin_unlock(&dev->spinlock);
}

static void
deactivate_substream(struct snd_usb_caiaqdev *dev,
		     struct snd_pcm_substream *sub)
{
	unsigned long flags;
	spin_lock_irqsave(&dev->spinlock, flags);

	if (sub->stream == SNDRV_PCM_STREAM_PLAYBACK)
		dev->sub_playback[sub->number] = NULL;
	else
		dev->sub_capture[sub->number] = NULL;

	spin_unlock_irqrestore(&dev->spinlock, flags);
}

static int
all_substreams_zero(struct snd_pcm_substream **subs)
{
	int i;
	for (i = 0; i < MAX_STREAMS; i++)
		if (subs[i] != NULL)
			return 0;
	return 1;
}

static int stream_start(struct snd_usb_caiaqdev *dev)
{
	int i, ret;

	debug("%s(%p)\n", __func__, dev);

	if (dev->streaming)
		return -EINVAL;

	memset(dev->sub_playback, 0, sizeof(dev->sub_playback));
	memset(dev->sub_capture, 0, sizeof(dev->sub_capture));
	dev->input_panic = 0;
	dev->output_panic = 0;
	dev->first_packet = 4;
	dev->streaming = 1;
	dev->warned = 0;

	for (i = 0; i < N_URBS; i++) {
		ret = usb_submit_urb(dev->data_urbs_in[i], GFP_ATOMIC);
		if (ret) {
			log("unable to trigger read #%d! (ret %d)\n", i, ret);
			dev->streaming = 0;
			return -EPIPE;
		}
	}

	return 0;
}

static void stream_stop(struct snd_usb_caiaqdev *dev)
{
	int i;

	debug("%s(%p)\n", __func__, dev);
	if (!dev->streaming)
		return;

	dev->streaming = 0;

	for (i = 0; i < N_URBS; i++) {
		usb_kill_urb(dev->data_urbs_in[i]);

		if (test_bit(i, &dev->outurb_active_mask))
			usb_kill_urb(dev->data_urbs_out[i]);
	}

	dev->outurb_active_mask = 0;
}

static int snd_usb_caiaq_substream_open(struct snd_pcm_substream *substream)
{
	struct snd_usb_caiaqdev *dev = snd_pcm_substream_chip(substream);
	debug("%s(%p)\n", __func__, substream);
	substream->runtime->hw = dev->pcm_info;
	snd_pcm_limit_hw_rates(substream->runtime);
	return 0;
}

static int snd_usb_caiaq_substream_close(struct snd_pcm_substream *substream)
{
	struct snd_usb_caiaqdev *dev = snd_pcm_substream_chip(substream);

	debug("%s(%p)\n", __func__, substream);
	if (all_substreams_zero(dev->sub_playback) &&
	    all_substreams_zero(dev->sub_capture)) {
		/* when the last client has stopped streaming,
		 * all sample rates are allowed again */
		stream_stop(dev);
		dev->pcm_info.rates = dev->samplerates;
	}

	return 0;
}

static int snd_usb_caiaq_pcm_hw_params(struct snd_pcm_substream *sub,
				       struct snd_pcm_hw_params *hw_params)
{
	debug("%s(%p)\n", __func__, sub);
	return snd_pcm_lib_malloc_pages(sub, params_buffer_bytes(hw_params));
}

static int snd_usb_caiaq_pcm_hw_free(struct snd_pcm_substream *sub)
{
	struct snd_usb_caiaqdev *dev = snd_pcm_substream_chip(sub);
	debug("%s(%p)\n", __func__, sub);
	deactivate_substream(dev, sub);
	return snd_pcm_lib_free_pages(sub);
}

/* this should probably go upstream */
#if SNDRV_PCM_RATE_5512 != 1 << 0 || SNDRV_PCM_RATE_192000 != 1 << 12
#error "Change this table"
#endif

static unsigned int rates[] = { 5512, 8000, 11025, 16000, 22050, 32000, 44100,
				48000, 64000, 88200, 96000, 176400, 192000 };

static int snd_usb_caiaq_pcm_prepare(struct snd_pcm_substream *substream)
{
	int bytes_per_sample, bpp, ret, i;
	int index = substream->number;
	struct snd_usb_caiaqdev *dev = snd_pcm_substream_chip(substream);
	struct snd_pcm_runtime *runtime = substream->runtime;

	debug("%s(%p)\n", __func__, substream);

	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
		int out_pos;

		switch (dev->spec.data_alignment) {
		case 0:
		case 2:
			out_pos = BYTES_PER_SAMPLE + 1;
			break;
		case 3:
		default:
			out_pos = 0;
			break;
		}

		dev->period_out_count[index] = out_pos;
		dev->audio_out_buf_pos[index] = out_pos;
	} else {
		int in_pos;

		switch (dev->spec.data_alignment) {
		case 0:
			in_pos = BYTES_PER_SAMPLE + 2;
			break;
		case 2:
			in_pos = BYTES_PER_SAMPLE;
			break;
		case 3:
		default:
			in_pos = 0;
			break;
		}

		dev->period_in_count[index] = in_pos;
		dev->audio_in_buf_pos[index] = in_pos;
	}

	if (dev->streaming)
		return 0;

	/* the first client that opens a stream defines the sample rate
	 * setting for all subsequent calls, until the last client closed. */
	for (i=0; i < ARRAY_SIZE(rates); i++)
		if (runtime->rate == rates[i])
			dev->pcm_info.rates = 1 << i;

	snd_pcm_limit_hw_rates(runtime);

	bytes_per_sample = BYTES_PER_SAMPLE;
	if (dev->spec.data_alignment >= 2)
		bytes_per_sample++;

	bpp = ((runtime->rate / 8000) + CLOCK_DRIFT_TOLERANCE)
		* bytes_per_sample * CHANNELS_PER_STREAM * dev->n_streams;

	if (bpp > MAX_ENDPOINT_SIZE)
		bpp = MAX_ENDPOINT_SIZE;

	ret = snd_usb_caiaq_set_audio_params(dev, runtime->rate,
					     runtime->sample_bits, bpp);
	if (ret)
		return ret;

	ret = stream_start(dev);
	if (ret)
		return ret;

	dev->output_running = 0;
	wait_event_timeout(dev->prepare_wait_queue, dev->output_running, HZ);
	if (!dev->output_running) {
		stream_stop(dev);
		return -EPIPE;
	}

	return 0;
}

static int snd_usb_caiaq_pcm_trigger(struct snd_pcm_substream *sub, int cmd)
{
	struct snd_usb_caiaqdev *dev = snd_pcm_substream_chip(sub);

	debug("%s(%p) cmd %d\n", __func__, sub, cmd);

	switch (cmd) {
	case SNDRV_PCM_TRIGGER_START:
	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
		activate_substream(dev, sub);
		break;
	case SNDRV_PCM_TRIGGER_STOP:
	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
		deactivate_substream(dev, sub);
		break;
	default:
		return -EINVAL;
	}

	return 0;
}

static snd_pcm_uframes_t
snd_usb_caiaq_pcm_pointer(struct snd_pcm_substream *sub)
{
	int index = sub->number;
	struct snd_usb_caiaqdev *dev = snd_pcm_substream_chip(sub);
	snd_pcm_uframes_t ptr;

	spin_lock(&dev->spinlock);

	if (dev->input_panic || dev->output_panic)
		ptr = SNDRV_PCM_POS_XRUN;

	if (sub->stream == SNDRV_PCM_STREAM_PLAYBACK)
		ptr = bytes_to_frames(sub->runtime,
					dev->audio_out_buf_pos[index]);
	else
		ptr = bytes_to_frames(sub->runtime,
					dev->audio_in_buf_pos[index]);

	spin_unlock(&dev->spinlock);
	return ptr;
}

/* operators for both playback and capture */
static struct snd_pcm_ops snd_usb_caiaq_ops = {
	.open =		snd_usb_caiaq_substream_open,
	.close =	snd_usb_caiaq_substream_close,
	.ioctl =	snd_pcm_lib_ioctl,
	.hw_params =	snd_usb_caiaq_pcm_hw_params,
	.hw_free =	snd_usb_caiaq_pcm_hw_free,
	.prepare =	snd_usb_caiaq_pcm_prepare,
	.trigger =	snd_usb_caiaq_pcm_trigger,
	.pointer =	snd_usb_caiaq_pcm_pointer
};

static void check_for_elapsed_periods(struct snd_usb_caiaqdev *dev,
				      struct snd_pcm_substream **subs)
{
	int stream, pb, *cnt;
	struct snd_pcm_substream *sub;

	for (stream = 0; stream < dev->n_streams; stream++) {
		sub = subs[stream];
		if (!sub)
			continue;

		pb = snd_pcm_lib_period_bytes(sub);
		cnt = (sub->stream == SNDRV_PCM_STREAM_PLAYBACK) ?
					&dev->period_out_count[stream] :
					&dev->period_in_count[stream];

		if (*cnt >= pb) {
			snd_pcm_period_elapsed(sub);
			*cnt %= pb;
		}
	}
}

static void read_in_urb_mode0(struct snd_usb_caiaqdev *dev,
			      const struct urb *urb,
			      const struct usb_iso_packet_descriptor *iso)
{
	unsigned char *usb_buf = urb->transfer_buffer + iso->offset;
	struct snd_pcm_substream *sub;
	int stream, i;

	if (all_substreams_zero(dev->sub_capture))
		return;

	for (i = 0; i < iso->actual_length;) {
		for (stream = 0; stream < dev->n_streams; stream++, i++) {
			sub = dev->sub_capture[stream];
			if (sub) {
				struct snd_pcm_runtime *rt = sub->runtime;
				char *audio_buf = rt->dma_area;
				int sz = frames_to_bytes(rt, rt->buffer_size);
				audio_buf[dev->audio_in_buf_pos[stream]++]
					= usb_buf[i];
				dev->period_in_count[stream]++;
				if (dev->audio_in_buf_pos[stream] == sz)
					dev->audio_in_buf_pos[stream] = 0;
			}
		}
	}
}

static void read_in_urb_mode2(struct snd_usb_caiaqdev *dev,
			      const struct urb *urb,
			      const struct usb_iso_packet_descriptor *iso)
{
	unsigned char *usb_buf = urb->transfer_buffer + iso->offset;
	unsigned char check_byte;
	struct snd_pcm_substream *sub;
	int stream, i;

	for (i = 0; i < iso->actual_length;) {
		if (i % (dev->n_streams * BYTES_PER_SAMPLE_USB) == 0) {
			for (stream = 0;
			     stream < dev->n_streams;
			     stream++, i++) {
				if (dev->first_packet)
					continue;

				check_byte = MAKE_CHECKBYTE(dev, stream, i);

				if ((usb_buf[i] & 0x3f) != check_byte)
					dev->input_panic = 1;

				if (usb_buf[i] & 0x80)
					dev->output_panic = 1;
			}
		}
		dev->first_packet = 0;

		for (stream = 0; stream < dev->n_streams; stream++, i++) {
			sub = dev->sub_capture[stream];
			if (dev->input_panic)
				usb_buf[i] = 0;

			if (sub) {
				struct snd_pcm_runtime *rt = sub->runtime;
				char *audio_buf = rt->dma_area;
				int sz = frames_to_bytes(rt, rt->buffer_size);
				audio_buf[dev->audio_in_buf_pos[stream]++] =
					usb_buf[i];
				dev->period_in_count[stream]++;
				if (dev->audio_in_buf_pos[stream] == sz)
					dev->audio_in_buf_pos[stream] = 0;
			}
		}
	}
}

static void read_in_urb_mode3(struct snd_usb_caiaqdev *dev,
			      const struct urb *urb,
			      const struct usb_iso_packet_descriptor *iso)
{
	unsigned char *usb_buf = urb->transfer_buffer + iso->offset;
	int stream, i;

	/* paranoia check */
	if (iso->actual_length % (BYTES_PER_SAMPLE_USB * CHANNELS_PER_STREAM))
		return;

	for (i = 0; i < iso->actual_length;) {
		for (stream = 0; stream < dev->n_streams; stream++) {
			struct snd_pcm_substream *sub = dev->sub_capture[stream];
			char *audio_buf = NULL;
			int c, n, sz = 0;

			if (sub && !dev->input_panic) {
				struct snd_pcm_runtime *rt = sub->runtime;
				audio_buf = rt->dma_area;
				sz = frames_to_bytes(rt, rt->buffer_size);
			}

			for (c = 0; c < CHANNELS_PER_STREAM; c++) {
				/* 3 audio data bytes, followed by 1 check byte */
				if (audio_buf) {
					for (n = 0; n < BYTES_PER_SAMPLE; n++) {
						audio_buf[dev->audio_in_buf_pos[stream]++] = usb_buf[i+n];

						if (dev->audio_in_buf_pos[stream] == sz)
							dev->audio_in_buf_pos[stream] = 0;
					}

					dev->period_in_count[stream] += BYTES_PER_SAMPLE;
				}

				i += BYTES_PER_SAMPLE;

				if (usb_buf[i] != ((stream << 1) | c) &&
				    !dev->first_packet) {
					if (!dev->input_panic)
						printk(" EXPECTED: %02x got %02x, c %d, stream %d, i %d\n",
							((stream << 1) | c), usb_buf[i], c, stream, i);
					dev->input_panic = 1;
				}

				i++;
			}
		}
	}

	if (dev->first_packet > 0)
		dev->first_packet--;
}

static void read_in_urb(struct snd_usb_caiaqdev *dev,
			const struct urb *urb,
			const struct usb_iso_packet_descriptor *iso)
{
	if (!dev->streaming)
		return;

	if (iso->actual_length < dev->bpp)
		return;

	switch (dev->spec.data_alignment) {
	case 0:
		read_in_urb_mode0(dev, urb, iso);
		break;
	case 2:
		read_in_urb_mode2(dev, urb, iso);
		break;
	case 3:
		read_in_urb_mode3(dev, urb, iso);
		break;
	}

	if ((dev->input_panic || dev->output_panic) && !dev->warned) {
		debug("streaming error detected %s %s\n",
				dev->input_panic ? "(input)" : "",
				dev->output_panic ? "(output)" : "");
		dev->warned = 1;
	}
}

static void fill_out_urb_mode_0(struct snd_usb_caiaqdev *dev,
				struct urb *urb,
				const struct usb_iso_packet_descriptor *iso)
{
	unsigned char *usb_buf = urb->transfer_buffer + iso->offset;
	struct snd_pcm_substream *sub;
	int stream, i;

	for (i = 0; i < iso->length;) {
		for (stream = 0; stream < dev->n_streams; stream++, i++) {
			sub = dev->sub_playback[stream];
			if (sub) {
				struct snd_pcm_runtime *rt = sub->runtime;
				char *audio_buf = rt->dma_area;
				int sz = frames_to_bytes(rt, rt->buffer_size);
				usb_buf[i] =
					audio_buf[dev->audio_out_buf_pos[stream]];
				dev->period_out_count[stream]++;
				dev->audio_out_buf_pos[stream]++;
				if (dev->audio_out_buf_pos[stream] == sz)
					dev->audio_out_buf_pos[stream] = 0;
			} else
				usb_buf[i] = 0;
		}

		/* fill in the check bytes */
		if (dev->spec.data_alignment == 2 &&
		    i % (dev->n_streams * BYTES_PER_SAMPLE_USB) ==
		        (dev->n_streams * CHANNELS_PER_STREAM))
			for (stream = 0; stream < dev->n_streams; stream++, i++)
				usb_buf[i] = MAKE_CHECKBYTE(dev, stream, i);
	}
}

static void fill_out_urb_mode_3(struct snd_usb_caiaqdev *dev,
				struct urb *urb,
				const struct usb_iso_packet_descriptor *iso)
{
	unsigned char *usb_buf = urb->transfer_buffer + iso->offset;
	int stream, i;

	for (i = 0; i < iso->length;) {
		for (stream = 0; stream < dev->n_streams; stream++) {
			struct snd_pcm_substream *sub = dev->sub_playback[stream];
			char *audio_buf = NULL;
			int c, n, sz = 0;

			if (sub) {
				struct snd_pcm_runtime *rt = sub->runtime;
				audio_buf = rt->dma_area;
				sz = frames_to_bytes(rt, rt->buffer_size);
			}

			for (c = 0; c < CHANNELS_PER_STREAM; c++) {
				for (n = 0; n < BYTES_PER_SAMPLE; n++) {
					if (audio_buf) {
						usb_buf[i+n] = audio_buf[dev->audio_out_buf_pos[stream]++];

						if (dev->audio_out_buf_pos[stream] == sz)
							dev->audio_out_buf_pos[stream] = 0;
					} else {
						usb_buf[i+n] = 0;
					}
				}

				if (audio_buf)
					dev->period_out_count[stream] += BYTES_PER_SAMPLE;

				i += BYTES_PER_SAMPLE;

				/* fill in the check byte pattern */
				usb_buf[i++] = (stream << 1) | c;
			}
		}
	}
}

static inline void fill_out_urb(struct snd_usb_caiaqdev *dev,
				struct urb *urb,
				const struct usb_iso_packet_descriptor *iso)
{
	switch (dev->spec.data_alignment) {
	case 0:
	case 2:
		fill_out_urb_mode_0(dev, urb, iso);
		break;
	case 3:
		fill_out_urb_mode_3(dev, urb, iso);
		break;
	}
}

static void read_completed(struct urb *urb)
{
	struct snd_usb_caiaq_cb_info *info = urb->context;
	struct snd_usb_caiaqdev *dev;
	struct urb *out = NULL;
	int i, frame, len, send_it = 0, outframe = 0;
	size_t offset = 0;

	if (urb->status || !info)
		return;

	dev = info->dev;

	if (!dev->streaming)
		return;

	/* find an unused output urb that is unused */
	for (i = 0; i < N_URBS; i++)
		if (test_and_set_bit(i, &dev->outurb_active_mask) == 0) {
			out = dev->data_urbs_out[i];
			break;
		}

	if (!out) {
		log("Unable to find an output urb to use\n");
		goto requeue;
	}

	/* read the recently received packet and send back one which has
	 * the same layout */
	for (frame = 0; frame < FRAMES_PER_URB; frame++) {
		if (urb->iso_frame_desc[frame].status)
			continue;

		len = urb->iso_frame_desc[outframe].actual_length;
		out->iso_frame_desc[outframe].length = len;
		out->iso_frame_desc[outframe].actual_length = 0;
		out->iso_frame_desc[outframe].offset = offset;
		offset += len;

		if (len > 0) {
			spin_lock(&dev->spinlock);
			fill_out_urb(dev, out, &out->iso_frame_desc[outframe]);
			read_in_urb(dev, urb, &urb->iso_frame_desc[frame]);
			spin_unlock(&dev->spinlock);
			check_for_elapsed_periods(dev, dev->sub_playback);
			check_for_elapsed_periods(dev, dev->sub_capture);
			send_it = 1;
		}

		outframe++;
	}

	if (send_it) {
		out->number_of_packets = outframe;
		out->transfer_flags = URB_ISO_ASAP;
		usb_submit_urb(out, GFP_ATOMIC);
	} else {
		struct snd_usb_caiaq_cb_info *oinfo = out->context;
		clear_bit(oinfo->index, &dev->outurb_active_mask);
	}

requeue:
	/* re-submit inbound urb */
	for (frame = 0; frame < FRAMES_PER_URB; frame++) {
		urb->iso_frame_desc[frame].offset = BYTES_PER_FRAME * frame;
		urb->iso_frame_desc[frame].length = BYTES_PER_FRAME;
		urb->iso_frame_desc[frame].actual_length = 0;
	}

	urb->number_of_packets = FRAMES_PER_URB;
	urb->transfer_flags = URB_ISO_ASAP;
	usb_submit_urb(urb, GFP_ATOMIC);
}

static void write_completed(struct urb *urb)
{
	struct snd_usb_caiaq_cb_info *info = urb->context;
	struct snd_usb_caiaqdev *dev = info->dev;

	if (!dev->output_running) {
		dev->output_running = 1;
		wake_up(&dev->prepare_wait_queue);
	}

	clear_bit(info->index, &dev->outurb_active_mask);
}

static struct urb **alloc_urbs(struct snd_usb_caiaqdev *dev, int dir, int *ret)
{
	int i, frame;
	struct urb **urbs;
	struct usb_device *usb_dev = dev->chip.dev;
	unsigned int pipe;

	pipe = (dir == SNDRV_PCM_STREAM_PLAYBACK) ?
		usb_sndisocpipe(usb_dev, ENDPOINT_PLAYBACK) :
		usb_rcvisocpipe(usb_dev, ENDPOINT_CAPTURE);

	urbs = kmalloc(N_URBS * sizeof(*urbs), GFP_KERNEL);
	if (!urbs) {
		log("unable to kmalloc() urbs, OOM!?\n");
		*ret = -ENOMEM;
		return NULL;
	}

	for (i = 0; i < N_URBS; i++) {
		urbs[i] = usb_alloc_urb(FRAMES_PER_URB, GFP_KERNEL);
		if (!urbs[i]) {
			log("unable to usb_alloc_urb(), OOM!?\n");
			*ret = -ENOMEM;
			return urbs;
		}

		urbs[i]->transfer_buffer =
			kmalloc(FRAMES_PER_URB * BYTES_PER_FRAME, GFP_KERNEL);
		if (!urbs[i]->transfer_buffer) {
			log("unable to kmalloc() transfer buffer, OOM!?\n");
			*ret = -ENOMEM;
			return urbs;
		}

		for (frame = 0; frame < FRAMES_PER_URB; frame++) {
			struct usb_iso_packet_descriptor *iso =
				&urbs[i]->iso_frame_desc[frame];

			iso->offset = BYTES_PER_FRAME * frame;
			iso->length = BYTES_PER_FRAME;
		}

		urbs[i]->dev = usb_dev;
		urbs[i]->pipe = pipe;
		urbs[i]->transfer_buffer_length = FRAMES_PER_URB
						* BYTES_PER_FRAME;
		urbs[i]->context = &dev->data_cb_info[i];
		urbs[i]->interval = 1;
		urbs[i]->transfer_flags = URB_ISO_ASAP;
		urbs[i]->number_of_packets = FRAMES_PER_URB;
		urbs[i]->complete = (dir == SNDRV_PCM_STREAM_CAPTURE) ?
					read_completed : write_completed;
	}

	*ret = 0;
	return urbs;
}

static void free_urbs(struct urb **urbs)
{
	int i;

	if (!urbs)
		return;

	for (i = 0; i < N_URBS; i++) {
		if (!urbs[i])
			continue;

		usb_kill_urb(urbs[i]);
		kfree(urbs[i]->transfer_buffer);
		usb_free_urb(urbs[i]);
	}

	kfree(urbs);
}

int snd_usb_caiaq_audio_init(struct snd_usb_caiaqdev *dev)
{
	int i, ret;

	dev->n_audio_in  = max(dev->spec.num_analog_audio_in,
			       dev->spec.num_digital_audio_in) /
				CHANNELS_PER_STREAM;
	dev->n_audio_out = max(dev->spec.num_analog_audio_out,
			       dev->spec.num_digital_audio_out) /
				CHANNELS_PER_STREAM;
	dev->n_streams = max(dev->n_audio_in, dev->n_audio_out);

	debug("dev->n_audio_in = %d\n", dev->n_audio_in);
	debug("dev->n_audio_out = %d\n", dev->n_audio_out);
	debug("dev->n_streams = %d\n", dev->n_streams);

	if (dev->n_streams > MAX_STREAMS) {
		log("unable to initialize device, too many streams.\n");
		return -EINVAL;
	}

	ret = snd_pcm_new(dev->chip.card, dev->product_name, 0,
			dev->n_audio_out, dev->n_audio_in, &dev->pcm);

	if (ret < 0) {
		log("snd_pcm_new() returned %d\n", ret);
		return ret;
	}

	dev->pcm->private_data = dev;
	strlcpy(dev->pcm->name, dev->product_name, sizeof(dev->pcm->name));

	memset(dev->sub_playback, 0, sizeof(dev->sub_playback));
	memset(dev->sub_capture, 0, sizeof(dev->sub_capture));

	memcpy(&dev->pcm_info, &snd_usb_caiaq_pcm_hardware,
			sizeof(snd_usb_caiaq_pcm_hardware));

	/* setup samplerates */
	dev->samplerates = dev->pcm_info.rates;
	switch (dev->chip.usb_id) {
	case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AK1):
	case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_RIGKONTROL3):
	case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_SESSIONIO):
	case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_GUITARRIGMOBILE):
		dev->samplerates |= SNDRV_PCM_RATE_192000;
		/* fall thru */
	case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AUDIO2DJ):
	case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AUDIO4DJ):
	case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AUDIO8DJ):
	case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORAUDIO2):
		dev->samplerates |= SNDRV_PCM_RATE_88200;
		break;
	}

	snd_pcm_set_ops(dev->pcm, SNDRV_PCM_STREAM_PLAYBACK,
				&snd_usb_caiaq_ops);
	snd_pcm_set_ops(dev->pcm, SNDRV_PCM_STREAM_CAPTURE,
				&snd_usb_caiaq_ops);

	snd_pcm_lib_preallocate_pages_for_all(dev->pcm,
					SNDRV_DMA_TYPE_CONTINUOUS,
					snd_dma_continuous_data(GFP_KERNEL),
					MAX_BUFFER_SIZE, MAX_BUFFER_SIZE);

	dev->data_cb_info =
		kmalloc(sizeof(struct snd_usb_caiaq_cb_info) * N_URBS,
					GFP_KERNEL);

	if (!dev->data_cb_info)
		return -ENOMEM;

	dev->outurb_active_mask = 0;
	BUILD_BUG_ON(N_URBS > (sizeof(dev->outurb_active_mask) * 8));

	for (i = 0; i < N_URBS; i++) {
		dev->data_cb_info[i].dev = dev;
		dev->data_cb_info[i].index = i;
	}

	dev->data_urbs_in = alloc_urbs(dev, SNDRV_PCM_STREAM_CAPTURE, &ret);
	if (ret < 0) {
		kfree(dev->data_cb_info);
		free_urbs(dev->data_urbs_in);
		return ret;
	}

	dev->data_urbs_out = alloc_urbs(dev, SNDRV_PCM_STREAM_PLAYBACK, &ret);
	if (ret < 0) {
		kfree(dev->data_cb_info);
		free_urbs(dev->data_urbs_in);
		free_urbs(dev->data_urbs_out);
		return ret;
	}

	return 0;
}

void snd_usb_caiaq_audio_free(struct snd_usb_caiaqdev *dev)
{
	debug("%s(%p)\n", __func__, dev);
	stream_stop(dev);
	free_urbs(dev->data_urbs_in);
	free_urbs(dev->data_urbs_out);
	kfree(dev->data_cb_info);
}

