/*
 *   US-X2Y AUDIO
 *   Copyright (c) 2002-2004 by Karsten Wiese
 *
 *   based on
 *
 *   (Tentative) USB Audio Driver for ALSA
 *
 *   Main and PCM part
 *
 *   Copyright (c) 2002 by Takashi Iwai <tiwai@suse.de>
 *
 *   Many codes borrowed from audio.c by 
 *	    Alan Cox (alan@lxorguk.ukuu.org.uk)
 *	    Thomas Sailer (sailer@ife.ee.ethz.ch)
 *
 *
 *   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 <sound/driver.h>
#include <linux/interrupt.h>
#include <linux/usb.h>
#include <sound/core.h>
#include <sound/info.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include "usx2y.h"
#include "usbusx2y.h"

#define USX2Y_NRPACKS 4			/* Default value used for nr of packs per urb.
					  1 to 4 have been tested ok on uhci.
					  To use 3 on ohci, you'd need a patch:
					  look for "0000425-linux-2.6.9-rc4-mm1_ohci-hcd.patch.gz" on
					  "https://bugtrack.alsa-project.org/alsa-bug/bug_view_page.php?bug_id=0000425"
					  .
					  1, 2 and 4 work out of the box on ohci, if I recall correctly.
					  Bigger is safer operation,
					  smaller gives lower latencies.
					*/
#define USX2Y_NRPACKS_VARIABLE y	/* If your system works ok with this module's parameter
					   nrpacks set to 1, you might as well comment 
					   this #define out, and thereby produce smaller, faster code.
					   You'd also set USX2Y_NRPACKS to 1 then.
					*/

#ifdef USX2Y_NRPACKS_VARIABLE
 static int nrpacks = USX2Y_NRPACKS; /* number of packets per urb */
 #define  nr_of_packs() nrpacks
 module_param(nrpacks, int, 0444);
 MODULE_PARM_DESC(nrpacks, "Number of packets per URB.");
#else
 #define nr_of_packs() USX2Y_NRPACKS
#endif


static int usX2Y_urb_capt_retire(snd_usX2Y_substream_t *subs)
{
	struct urb	*urb = subs->completed_urb;
	snd_pcm_runtime_t *runtime = subs->pcm_substream->runtime;
	unsigned char	*cp;
	int 		i, len, lens = 0, hwptr_done = subs->hwptr_done;
	usX2Ydev_t	*usX2Y = subs->usX2Y;

	for (i = 0; i < nr_of_packs(); i++) {
		cp = (unsigned char*)urb->transfer_buffer + urb->iso_frame_desc[i].offset;
		if (urb->iso_frame_desc[i].status) { /* active? hmm, skip this */
			snd_printk("activ frame status %i. Most propably some hardware problem.\n", urb->iso_frame_desc[i].status);
			return urb->iso_frame_desc[i].status;
		}
		len = urb->iso_frame_desc[i].actual_length / usX2Y->stride;
		if (! len) {
			snd_printd("0 == len ERROR!\n");
			continue;
		}

		/* copy a data chunk */
		if ((hwptr_done + len) > runtime->buffer_size) {
			int cnt = runtime->buffer_size - hwptr_done;
			int blen = cnt * usX2Y->stride;
			memcpy(runtime->dma_area + hwptr_done * usX2Y->stride, cp, blen);
			memcpy(runtime->dma_area, cp + blen, len * usX2Y->stride - blen);
		} else {
			memcpy(runtime->dma_area + hwptr_done * usX2Y->stride, cp, len * usX2Y->stride);
		}
		lens += len;
		if ((hwptr_done += len) >= runtime->buffer_size)
			hwptr_done -= runtime->buffer_size;
	}

	subs->hwptr_done = hwptr_done;
	subs->transfer_done += lens;
	/* update the pointer, call callback if necessary */
	if (subs->transfer_done >= runtime->period_size) {
		subs->transfer_done -= runtime->period_size;
		snd_pcm_period_elapsed(subs->pcm_substream);
	}
	return 0;
}
/*
 * prepare urb for playback data pipe
 *
 * we copy the data directly from the pcm buffer.
 * the current position to be copied is held in hwptr field.
 * since a urb can handle only a single linear buffer, if the total
 * transferred area overflows the buffer boundary, we cannot send
 * it directly from the buffer.  thus the data is once copied to
 * a temporary buffer and urb points to that.
 */
static int usX2Y_urb_play_prepare(snd_usX2Y_substream_t *subs,
				  struct urb *cap_urb,
				  struct urb *urb)
{
	int count, counts, pack;
	usX2Ydev_t* usX2Y = subs->usX2Y;
	snd_pcm_runtime_t *runtime = subs->pcm_substream->runtime;

	count = 0;
	for (pack = 0; pack <  nr_of_packs(); pack++) {
		/* calculate the size of a packet */
		counts = cap_urb->iso_frame_desc[pack].actual_length / usX2Y->stride;
		count += counts;
		if (counts < 43 || counts > 50) {
			snd_printk("should not be here with counts=%i\n", counts);
			return -EPIPE;
		}
		/* set up descriptor */
		urb->iso_frame_desc[pack].offset = pack ?
			urb->iso_frame_desc[pack - 1].offset + urb->iso_frame_desc[pack - 1].length :
			0;
		urb->iso_frame_desc[pack].length = cap_urb->iso_frame_desc[pack].actual_length;
	}
	if (atomic_read(&subs->state) >= state_PRERUNNING)
		if (subs->hwptr + count > runtime->buffer_size) {
			/* err, the transferred area goes over buffer boundary.
			 * copy the data to the temp buffer.
			 */
			int len;
			len = runtime->buffer_size - subs->hwptr;
			urb->transfer_buffer = subs->tmpbuf;
			memcpy(subs->tmpbuf, runtime->dma_area + subs->hwptr * usX2Y->stride, len * usX2Y->stride);
			memcpy(subs->tmpbuf + len * usX2Y->stride, runtime->dma_area, (count - len) * usX2Y->stride);
			subs->hwptr += count;
			subs->hwptr -= runtime->buffer_size;
		} else {
			/* set the buffer pointer */
			urb->transfer_buffer = runtime->dma_area + subs->hwptr * usX2Y->stride;
			if ((subs->hwptr += count) >= runtime->buffer_size)
			subs->hwptr -= runtime->buffer_size;			
		}
	else
		urb->transfer_buffer = subs->tmpbuf;
	urb->transfer_buffer_length = count * usX2Y->stride;
	return 0;
}

/*
 * process after playback data complete
 *
 * update the current position and call callback if a period is processed.
 */
static void usX2Y_urb_play_retire(snd_usX2Y_substream_t *subs, struct urb *urb)
{
	snd_pcm_runtime_t *runtime = subs->pcm_substream->runtime;
	int		len = urb->actual_length / subs->usX2Y->stride;

	subs->transfer_done += len;
	subs->hwptr_done +=  len;
	if (subs->hwptr_done >= runtime->buffer_size)
		subs->hwptr_done -= runtime->buffer_size;
	if (subs->transfer_done >= runtime->period_size) {
		subs->transfer_done -= runtime->period_size;
		snd_pcm_period_elapsed(subs->pcm_substream);
	}
}

static int usX2Y_urb_submit(snd_usX2Y_substream_t *subs, struct urb *urb, int frame)
{
	int err;
	if (!urb)
		return -ENODEV;
	urb->start_frame = (frame + NRURBS * nr_of_packs());  // let hcd do rollover sanity checks
	urb->hcpriv = NULL;
	urb->dev = subs->usX2Y->chip.dev; /* we need to set this at each time */
	if ((err = usb_submit_urb(urb, GFP_ATOMIC)) < 0) {
		snd_printk("usb_submit_urb() returned %i\n", err);
		return err;
	}
	return 0;
}

static inline int usX2Y_usbframe_complete(snd_usX2Y_substream_t *capsubs, snd_usX2Y_substream_t *playbacksubs, int frame)
{
	int err, state;
	{
		struct urb *urb = playbacksubs->completed_urb;

		state = atomic_read(&playbacksubs->state);
		if (NULL != urb) {
			if (state == state_RUNNING)
				usX2Y_urb_play_retire(playbacksubs, urb);
			else
				if (state >= state_PRERUNNING) {
					atomic_inc(&playbacksubs->state);
				}
		} else {
			switch (state) {
			case state_STARTING1:
				urb = playbacksubs->urb[0];
				atomic_inc(&playbacksubs->state);
				break;
			case state_STARTING2:
				urb = playbacksubs->urb[1];
				atomic_inc(&playbacksubs->state);
				break;
			}
		}
		if (urb) {
			if ((err = usX2Y_urb_play_prepare(playbacksubs, capsubs->completed_urb, urb)) ||
			    (err = usX2Y_urb_submit(playbacksubs, urb, frame))) {
				return err;
			}
		}

		playbacksubs->completed_urb = NULL;
	}
	state = atomic_read(&capsubs->state);
	if (state >= state_PREPARED) {
		if (state == state_RUNNING) {
			if ((err = usX2Y_urb_capt_retire(capsubs)))
				return err;
		} else
			if (state >= state_PRERUNNING) {
				atomic_inc(&capsubs->state);
			}
		if ((err = usX2Y_urb_submit(capsubs, capsubs->completed_urb, frame)))
			return err;
	}
	capsubs->completed_urb = NULL;
	return 0;
}


static void usX2Y_clients_stop(usX2Ydev_t *usX2Y)
{
	int s, u;
	for (s = 0; s < 4; s++) {
		snd_usX2Y_substream_t *subs = usX2Y->subs[s];
		if (subs) {
			snd_printdd("%i %p state=%i\n", s, subs, atomic_read(&subs->state));
			atomic_set(&subs->state, state_STOPPED);
		}
	}
	for (s = 0; s < 4; s++) {
		snd_usX2Y_substream_t *subs = usX2Y->subs[s];
		if (subs) {
			if (atomic_read(&subs->state) >= state_PRERUNNING) {
				snd_pcm_stop(subs->pcm_substream, SNDRV_PCM_STATE_XRUN);
			}
			for (u = 0; u < NRURBS; u++) {
				struct urb *urb = subs->urb[u];
				if (NULL != urb)
					snd_printdd("%i status=%i start_frame=%i\n", u, urb->status, urb->start_frame);
			}
		}
	}
	usX2Y->prepare_subs = NULL;
	wake_up(&usX2Y->prepare_wait_queue);
}

static void usX2Y_error_urb_status(usX2Ydev_t *usX2Y, snd_usX2Y_substream_t *subs, struct urb *urb)
{
	snd_printk("ep=%i stalled with status=%i\n", subs->endpoint, urb->status);
	urb->status = 0;
	usX2Y_clients_stop(usX2Y);
}

static void usX2Y_error_sequence(usX2Ydev_t *usX2Y, snd_usX2Y_substream_t *subs, struct urb *urb)
{
	snd_printk("Sequence Error!(hcd_frame=%i ep=%i%s;wait=%i,frame=%i).\n"
		   "Most propably some urb of usb-frame %i is still missing.\n"
		   "Cause could be too long delays in usb-hcd interrupt handling.\n",
		   usb_get_current_frame_number(usX2Y->chip.dev),
		   subs->endpoint, usb_pipein(urb->pipe) ? "in" : "out", usX2Y->wait_iso_frame, urb->start_frame, usX2Y->wait_iso_frame);
	usX2Y_clients_stop(usX2Y);
}

static void i_usX2Y_urb_complete(struct urb *urb, struct pt_regs *regs)
{
	snd_usX2Y_substream_t *subs = (snd_usX2Y_substream_t*)urb->context;
	usX2Ydev_t *usX2Y = subs->usX2Y;

	if (unlikely(atomic_read(&subs->state) < state_PREPARED)) {
		snd_printdd("hcd_frame=%i ep=%i%s status=%i start_frame=%i\n", usb_get_current_frame_number(usX2Y->chip.dev), subs->endpoint, usb_pipein(urb->pipe) ? "in" : "out", urb->status, urb->start_frame);
		return;
	}
	if (unlikely(urb->status)) {
		usX2Y_error_urb_status(usX2Y, subs, urb);
		return;
	}
	if (likely((0xFFFF & urb->start_frame) == usX2Y->wait_iso_frame))
		subs->completed_urb = urb;
	else {
		usX2Y_error_sequence(usX2Y, subs, urb);
		return;
	}
	{
		snd_usX2Y_substream_t *capsubs = usX2Y->subs[SNDRV_PCM_STREAM_CAPTURE],
			*playbacksubs = usX2Y->subs[SNDRV_PCM_STREAM_PLAYBACK];
		if (capsubs->completed_urb && atomic_read(&capsubs->state) >= state_PREPARED &&
		    (playbacksubs->completed_urb || atomic_read(&playbacksubs->state) < state_PREPARED)) {
			if (!usX2Y_usbframe_complete(capsubs, playbacksubs, urb->start_frame)) {
				if (nr_of_packs() <= urb->start_frame &&
				    urb->start_frame <= (2 * nr_of_packs() - 1))	// uhci and ohci
					usX2Y->wait_iso_frame = urb->start_frame - nr_of_packs();
				else
					usX2Y->wait_iso_frame +=  nr_of_packs();
			} else {
				snd_printdd("\n");
				usX2Y_clients_stop(usX2Y);
			}
		}
	}
}

static void usX2Y_urbs_set_complete(usX2Ydev_t * usX2Y, void (*complete)(struct urb *, struct pt_regs *))
{
	int s, u;
	for (s = 0; s < 4; s++) {
		snd_usX2Y_substream_t *subs = usX2Y->subs[s];
		if (NULL != subs)
			for (u = 0; u < NRURBS; u++) {
				struct urb * urb = subs->urb[u];
				if (NULL != urb)
					urb->complete = complete;
			}
	}
}

static void usX2Y_subs_startup_finish(usX2Ydev_t * usX2Y)
{
	usX2Y_urbs_set_complete(usX2Y, i_usX2Y_urb_complete);
	usX2Y->prepare_subs = NULL;
}

static void i_usX2Y_subs_startup(struct urb *urb, struct pt_regs *regs)
{
	snd_usX2Y_substream_t *subs = (snd_usX2Y_substream_t*)urb->context;
	usX2Ydev_t *usX2Y = subs->usX2Y;
	snd_usX2Y_substream_t *prepare_subs = usX2Y->prepare_subs;
	if (NULL != prepare_subs)
		if (urb->start_frame == prepare_subs->urb[0]->start_frame) {
			usX2Y_subs_startup_finish(usX2Y);
			atomic_inc(&prepare_subs->state);
			wake_up(&usX2Y->prepare_wait_queue);
		}

	i_usX2Y_urb_complete(urb, regs);
}

static void usX2Y_subs_prepare(snd_usX2Y_substream_t *subs)
{
	snd_printdd("usX2Y_substream_prepare(%p) ep=%i urb0=%p urb1=%p\n", subs, subs->endpoint, subs->urb[0], subs->urb[1]);
	/* reset the pointer */
	subs->hwptr = 0;
	subs->hwptr_done = 0;
	subs->transfer_done = 0;
}


static void usX2Y_urb_release(struct urb** urb, int free_tb)
{
	if (*urb) {
		usb_kill_urb(*urb);
		if (free_tb)
			kfree((*urb)->transfer_buffer);
		usb_free_urb(*urb);
		*urb = NULL;
	}
}
/*
 * release a substreams urbs
 */
static void usX2Y_urbs_release(snd_usX2Y_substream_t *subs)
{
	int i;
	snd_printdd("usX2Y_urbs_release() %i\n", subs->endpoint);
	for (i = 0; i < NRURBS; i++)
		usX2Y_urb_release(subs->urb + i, subs != subs->usX2Y->subs[SNDRV_PCM_STREAM_PLAYBACK]);

	if (subs->tmpbuf) {
		kfree(subs->tmpbuf);
		subs->tmpbuf = NULL;
	}
}
/*
 * initialize a substream's urbs
 */
static int usX2Y_urbs_allocate(snd_usX2Y_substream_t *subs)
{
	int i;
	unsigned int pipe;
	int is_playback = subs == subs->usX2Y->subs[SNDRV_PCM_STREAM_PLAYBACK];
	struct usb_device *dev = subs->usX2Y->chip.dev;

	pipe = is_playback ? usb_sndisocpipe(dev, subs->endpoint) :
			usb_rcvisocpipe(dev, subs->endpoint);
	subs->maxpacksize = usb_maxpacket(dev, pipe, is_playback);
	if (!subs->maxpacksize)
		return -EINVAL;

	if (is_playback && NULL == subs->tmpbuf) {	/* allocate a temporary buffer for playback */
		subs->tmpbuf = kcalloc(nr_of_packs(), subs->maxpacksize, GFP_KERNEL);
		if (NULL == subs->tmpbuf) {
			snd_printk(KERN_ERR "cannot malloc tmpbuf\n");
			return -ENOMEM;
		}
	}
	/* allocate and initialize data urbs */
	for (i = 0; i < NRURBS; i++) {
		struct urb** purb = subs->urb + i;
		if (*purb) {
			usb_kill_urb(*purb);
			continue;
		}
		*purb = usb_alloc_urb(nr_of_packs(), GFP_KERNEL);
		if (NULL == *purb) {
			usX2Y_urbs_release(subs);
			return -ENOMEM;
		}
		if (!is_playback && !(*purb)->transfer_buffer) {
			/* allocate a capture buffer per urb */
			(*purb)->transfer_buffer = kmalloc(subs->maxpacksize * nr_of_packs(), GFP_KERNEL);
			if (NULL == (*purb)->transfer_buffer) {
				usX2Y_urbs_release(subs);
				return -ENOMEM;
			}
		}
		(*purb)->dev = dev;
		(*purb)->pipe = pipe;
		(*purb)->number_of_packets = nr_of_packs();
		(*purb)->context = subs;
		(*purb)->interval = 1;
		(*purb)->complete = i_usX2Y_subs_startup;
	}
	return 0;
}

static void usX2Y_subs_startup(snd_usX2Y_substream_t *subs)
{
	usX2Ydev_t *usX2Y = subs->usX2Y;
	usX2Y->prepare_subs = subs;
	subs->urb[0]->start_frame = -1;
	wmb();
	usX2Y_urbs_set_complete(usX2Y, i_usX2Y_subs_startup);
}

static int usX2Y_urbs_start(snd_usX2Y_substream_t *subs)
{
	int i, err;
	usX2Ydev_t *usX2Y = subs->usX2Y;

	if ((err = usX2Y_urbs_allocate(subs)) < 0)
		return err;
	subs->completed_urb = NULL;
	for (i = 0; i < 4; i++) {
		snd_usX2Y_substream_t *subs = usX2Y->subs[i];
		if (subs != NULL && atomic_read(&subs->state) >= state_PREPARED)
			goto start;
	}
	usX2Y->wait_iso_frame = -1;
 start:
	{
		usX2Y_subs_startup(subs);
		for (i = 0; i < NRURBS; i++) {
			struct urb *urb = subs->urb[i];
			if (usb_pipein(urb->pipe)) {
				unsigned long pack;
				if (0 == i)
					atomic_set(&subs->state, state_STARTING3);
				urb->dev = usX2Y->chip.dev;
				urb->transfer_flags = URB_ISO_ASAP;
				for (pack = 0; pack < nr_of_packs(); pack++) {
					urb->iso_frame_desc[pack].offset = subs->maxpacksize * pack;
					urb->iso_frame_desc[pack].length = subs->maxpacksize;
				}
				urb->transfer_buffer_length = subs->maxpacksize * nr_of_packs(); 
				if ((err = usb_submit_urb(urb, GFP_ATOMIC)) < 0) {
					snd_printk (KERN_ERR "cannot submit datapipe for urb %d, err = %d\n", i, err);
					err = -EPIPE;
					goto cleanup;
				} else {
					if (0 > usX2Y->wait_iso_frame)
						usX2Y->wait_iso_frame = urb->start_frame;
				}
				urb->transfer_flags = 0;
			} else {
				atomic_set(&subs->state, state_STARTING1);
				break;
			}
		}
		err = 0;
		wait_event(usX2Y->prepare_wait_queue, NULL == usX2Y->prepare_subs);
		if (atomic_read(&subs->state) != state_PREPARED) {
			err = -EPIPE;
		}

	cleanup:
		if (err) {
			usX2Y_subs_startup_finish(usX2Y);
			usX2Y_clients_stop(usX2Y);		// something is completely wroong > stop evrything
		}
	}
	return err;
}

/*
 * return the current pcm pointer.  just return the hwptr_done value.
 */
static snd_pcm_uframes_t snd_usX2Y_pcm_pointer(snd_pcm_substream_t *substream)
{
	snd_usX2Y_substream_t *subs = (snd_usX2Y_substream_t *)substream->runtime->private_data;
	return subs->hwptr_done;
}
/*
 * start/stop substream
 */
static int snd_usX2Y_pcm_trigger(snd_pcm_substream_t *substream, int cmd)
{
	snd_usX2Y_substream_t *subs = (snd_usX2Y_substream_t *)substream->runtime->private_data;

	switch (cmd) {
	case SNDRV_PCM_TRIGGER_START:
		snd_printdd("snd_usX2Y_pcm_trigger(START)\n");
		if (atomic_read(&subs->state) == state_PREPARED &&
		    atomic_read(&subs->usX2Y->subs[SNDRV_PCM_STREAM_CAPTURE]->state) >= state_PREPARED) {
			atomic_set(&subs->state, state_PRERUNNING);
		} else {
			snd_printdd("\n");
			return -EPIPE;
		}
		break;
	case SNDRV_PCM_TRIGGER_STOP:
		snd_printdd("snd_usX2Y_pcm_trigger(STOP)\n");
		if (atomic_read(&subs->state) >= state_PRERUNNING)
			atomic_set(&subs->state, state_PREPARED);
		break;
	default:
		return -EINVAL;
	}
	return 0;
}


/*
 * allocate a buffer, setup samplerate
 *
 * so far we use a physically linear buffer although packetize transfer
 * doesn't need a continuous area.
 * if sg buffer is supported on the later version of alsa, we'll follow
 * that.
 */
static struct s_c2
{
	char c1, c2;
}
	SetRate44100[] =
{
	{ 0x14, 0x08},	// this line sets 44100, well actually a little less
	{ 0x18, 0x40},	// only tascam / frontier design knows the further lines .......
	{ 0x18, 0x42},
	{ 0x18, 0x45},
	{ 0x18, 0x46},
	{ 0x18, 0x48},
	{ 0x18, 0x4A},
	{ 0x18, 0x4C},
	{ 0x18, 0x4E},
	{ 0x18, 0x50},
	{ 0x18, 0x52},
	{ 0x18, 0x54},
	{ 0x18, 0x56},
	{ 0x18, 0x58},
	{ 0x18, 0x5A},
	{ 0x18, 0x5C},
	{ 0x18, 0x5E},
	{ 0x18, 0x60},
	{ 0x18, 0x62},
	{ 0x18, 0x64},
	{ 0x18, 0x66},
	{ 0x18, 0x68},
	{ 0x18, 0x6A},
	{ 0x18, 0x6C},
	{ 0x18, 0x6E},
	{ 0x18, 0x70},
	{ 0x18, 0x72},
	{ 0x18, 0x74},
	{ 0x18, 0x76},
	{ 0x18, 0x78},
	{ 0x18, 0x7A},
	{ 0x18, 0x7C},
	{ 0x18, 0x7E}
};
static struct s_c2 SetRate48000[] =
{
	{ 0x14, 0x09},	// this line sets 48000, well actually a little less
	{ 0x18, 0x40},	// only tascam / frontier design knows the further lines .......
	{ 0x18, 0x42},
	{ 0x18, 0x45},
	{ 0x18, 0x46},
	{ 0x18, 0x48},
	{ 0x18, 0x4A},
	{ 0x18, 0x4C},
	{ 0x18, 0x4E},
	{ 0x18, 0x50},
	{ 0x18, 0x52},
	{ 0x18, 0x54},
	{ 0x18, 0x56},
	{ 0x18, 0x58},
	{ 0x18, 0x5A},
	{ 0x18, 0x5C},
	{ 0x18, 0x5E},
	{ 0x18, 0x60},
	{ 0x18, 0x62},
	{ 0x18, 0x64},
	{ 0x18, 0x66},
	{ 0x18, 0x68},
	{ 0x18, 0x6A},
	{ 0x18, 0x6C},
	{ 0x18, 0x6E},
	{ 0x18, 0x70},
	{ 0x18, 0x73},
	{ 0x18, 0x74},
	{ 0x18, 0x76},
	{ 0x18, 0x78},
	{ 0x18, 0x7A},
	{ 0x18, 0x7C},
	{ 0x18, 0x7E}
};
#define NOOF_SETRATE_URBS ARRAY_SIZE(SetRate48000)

static void i_usX2Y_04Int(struct urb* urb, struct pt_regs *regs)
{
	usX2Ydev_t*	usX2Y = urb->context;
	
	if (urb->status) {
		snd_printk("snd_usX2Y_04Int() urb->status=%i\n", urb->status);
	}
	if (0 == --usX2Y->US04->len)
		wake_up(&usX2Y->In04WaitQueue);
}

static int usX2Y_rate_set(usX2Ydev_t *usX2Y, int rate)
{
	int			err = 0, i;
	snd_usX2Y_urbSeq_t	*us = NULL;
	int			*usbdata = NULL;
	struct s_c2		*ra = rate == 48000 ? SetRate48000 : SetRate44100;

	if (usX2Y->rate != rate) {
		us = kmalloc(sizeof(*us) + sizeof(struct urb*) * NOOF_SETRATE_URBS, GFP_KERNEL);
		if (NULL == us) {
			err = -ENOMEM;
			goto cleanup;
		}
		memset(us, 0, sizeof(*us) + sizeof(struct urb*) * NOOF_SETRATE_URBS); 
		usbdata = kmalloc(sizeof(int)*NOOF_SETRATE_URBS, GFP_KERNEL);
		if (NULL == usbdata) {
			err = -ENOMEM;
			goto cleanup;
		}
		for (i = 0; i < NOOF_SETRATE_URBS; ++i) {
			if (NULL == (us->urb[i] = usb_alloc_urb(0, GFP_KERNEL))) {
				err = -ENOMEM;
				goto cleanup;
			}
			((char*)(usbdata + i))[0] = ra[i].c1;
			((char*)(usbdata + i))[1] = ra[i].c2;
			usb_fill_bulk_urb(us->urb[i], usX2Y->chip.dev, usb_sndbulkpipe(usX2Y->chip.dev, 4),
					  usbdata + i, 2, i_usX2Y_04Int, usX2Y);
#ifdef OLD_USB
			us->urb[i]->transfer_flags = USB_QUEUE_BULK;
#endif
		}
		us->submitted =	0;
		us->len =	NOOF_SETRATE_URBS;
		usX2Y->US04 =	us;
		wait_event_timeout(usX2Y->In04WaitQueue, 0 == us->len, HZ);
		usX2Y->US04 =	NULL;
		if (us->len)
			err = -ENODEV;
	cleanup:
		if (us) {
			us->submitted =	2*NOOF_SETRATE_URBS;
			for (i = 0; i < NOOF_SETRATE_URBS; ++i) {
				struct urb *urb = us->urb[i];
				if (urb->status) {
					if (!err)
						err = -ENODEV;
					usb_kill_urb(urb);
				}
				usb_free_urb(urb);
			}
			usX2Y->US04 = NULL;
			kfree(usbdata);
			kfree(us);
			if (!err) {
				usX2Y->rate = rate;
			}
		}
	}

	return err;
}


static int usX2Y_format_set(usX2Ydev_t *usX2Y, snd_pcm_format_t format)
{
	int alternate, err;
	struct list_head* p;
	if (format == SNDRV_PCM_FORMAT_S24_3LE) {
		alternate = 2;
		usX2Y->stride = 6;
	} else {
		alternate = 1;
		usX2Y->stride = 4;
	}
	list_for_each(p, &usX2Y->chip.midi_list) {
		snd_usbmidi_input_stop(p);
	}
	usb_kill_urb(usX2Y->In04urb);
	if ((err = usb_set_interface(usX2Y->chip.dev, 0, alternate))) {
		snd_printk("usb_set_interface error \n");
		return err;
	}
	usX2Y->In04urb->dev = usX2Y->chip.dev;
	err = usb_submit_urb(usX2Y->In04urb, GFP_KERNEL);
	list_for_each(p, &usX2Y->chip.midi_list) {
		snd_usbmidi_input_start(p);
	}
	usX2Y->format = format;
	usX2Y->rate = 0;
	return err;
}


static int snd_usX2Y_pcm_hw_params(snd_pcm_substream_t *substream,
				   snd_pcm_hw_params_t *hw_params)
{
	int			err = 0;
	unsigned int		rate = params_rate(hw_params);
	snd_pcm_format_t	format = params_format(hw_params);
	snd_printdd("snd_usX2Y_hw_params(%p, %p)\n", substream, hw_params);

	{	// all pcm substreams off one usX2Y have to operate at the same rate & format
		snd_card_t *card = substream->pstr->pcm->card;
		struct list_head *list;
		list_for_each(list, &card->devices) {
			snd_device_t *dev;
			snd_pcm_t *pcm;
			int s;
			dev = snd_device(list);
			if (dev->type != SNDRV_DEV_PCM)
				continue;
			pcm = dev->device_data;
			for (s = 0; s < 2; ++s) {
				snd_pcm_substream_t *test_substream;
				test_substream = pcm->streams[s].substream;
				if (test_substream && test_substream != substream  &&
				    test_substream->runtime &&
				    ((test_substream->runtime->format &&
				      test_substream->runtime->format != format) ||
				     (test_substream->runtime->rate &&
				      test_substream->runtime->rate != rate)))
					return -EINVAL;
			}
		}
	}
	if (0 > (err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params)))) {
		snd_printk("snd_pcm_lib_malloc_pages(%p, %i) returned %i\n", substream, params_buffer_bytes(hw_params), err);
		return err;
	}
	return 0;
}

/*
 * free the buffer
 */
static int snd_usX2Y_pcm_hw_free(snd_pcm_substream_t *substream)
{
	snd_pcm_runtime_t *runtime = substream->runtime;
	snd_usX2Y_substream_t *subs = (snd_usX2Y_substream_t *)runtime->private_data;
	down(&subs->usX2Y->prepare_mutex);
	snd_printdd("snd_usX2Y_hw_free(%p)\n", substream);

	if (SNDRV_PCM_STREAM_PLAYBACK == substream->stream) {
		snd_usX2Y_substream_t *cap_subs = subs->usX2Y->subs[SNDRV_PCM_STREAM_CAPTURE];
		atomic_set(&subs->state, state_STOPPED);
		usX2Y_urbs_release(subs);
		if (!cap_subs->pcm_substream ||
		    !cap_subs->pcm_substream->runtime ||
		    !cap_subs->pcm_substream->runtime->status ||
		    cap_subs->pcm_substream->runtime->status->state < SNDRV_PCM_STATE_PREPARED) {
			atomic_set(&cap_subs->state, state_STOPPED);
			usX2Y_urbs_release(cap_subs);
		}
	} else {
		snd_usX2Y_substream_t *playback_subs = subs->usX2Y->subs[SNDRV_PCM_STREAM_PLAYBACK];
		if (atomic_read(&playback_subs->state) < state_PREPARED) {
			atomic_set(&subs->state, state_STOPPED);
			usX2Y_urbs_release(subs);
		}
	}
	up(&subs->usX2Y->prepare_mutex);
	return snd_pcm_lib_free_pages(substream);
}
/*
 * prepare callback
 *
 * set format and initialize urbs
 */
static int snd_usX2Y_pcm_prepare(snd_pcm_substream_t *substream)
{
	snd_pcm_runtime_t *runtime = substream->runtime;
	snd_usX2Y_substream_t *subs = (snd_usX2Y_substream_t *)runtime->private_data;
	usX2Ydev_t *usX2Y = subs->usX2Y;
	snd_usX2Y_substream_t *capsubs = subs->usX2Y->subs[SNDRV_PCM_STREAM_CAPTURE];
	int err = 0;
	snd_printdd("snd_usX2Y_pcm_prepare(%p)\n", substream);

	down(&usX2Y->prepare_mutex);
	usX2Y_subs_prepare(subs);
// Start hardware streams
// SyncStream first....
	if (atomic_read(&capsubs->state) < state_PREPARED) {
		if (usX2Y->format != runtime->format)
			if ((err = usX2Y_format_set(usX2Y, runtime->format)) < 0)
				goto up_prepare_mutex;
		if (usX2Y->rate != runtime->rate)
			if ((err = usX2Y_rate_set(usX2Y, runtime->rate)) < 0)
				goto up_prepare_mutex;
		snd_printdd("starting capture pipe for %s\n", subs == capsubs ? "self" : "playpipe");
		if (0 > (err = usX2Y_urbs_start(capsubs)))
			goto up_prepare_mutex;
	}

	if (subs != capsubs && atomic_read(&subs->state) < state_PREPARED)
		err = usX2Y_urbs_start(subs);

 up_prepare_mutex:
	up(&usX2Y->prepare_mutex);
	return err;
}

static snd_pcm_hardware_t snd_usX2Y_2c =
{
	.info =			(SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
				 SNDRV_PCM_INFO_BLOCK_TRANSFER |
				 SNDRV_PCM_INFO_MMAP_VALID),
	.formats =                 SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_3LE,
	.rates =                   SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000,
	.rate_min =                44100,
	.rate_max =                48000,
	.channels_min =            2,
	.channels_max =            2,
	.buffer_bytes_max =	(2*128*1024),
	.period_bytes_min =	64,
	.period_bytes_max =	(128*1024),
	.periods_min =		2,
	.periods_max =		1024,
	.fifo_size =              0
};



static int snd_usX2Y_pcm_open(snd_pcm_substream_t *substream)
{
	snd_usX2Y_substream_t	*subs = ((snd_usX2Y_substream_t **)
					 snd_pcm_substream_chip(substream))[substream->stream];
	snd_pcm_runtime_t	*runtime = substream->runtime;

	if (subs->usX2Y->chip_status & USX2Y_STAT_CHIP_MMAP_PCM_URBS)
		return -EBUSY;

	runtime->hw = snd_usX2Y_2c;
	runtime->private_data = subs;
	subs->pcm_substream = substream;
	snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIOD_TIME, 1000, 200000);
	return 0;
}



static int snd_usX2Y_pcm_close(snd_pcm_substream_t *substream)
{
	snd_pcm_runtime_t *runtime = substream->runtime;
	snd_usX2Y_substream_t *subs = (snd_usX2Y_substream_t *)runtime->private_data;
	int err = 0;

	subs->pcm_substream = NULL;

	return err;
}


static snd_pcm_ops_t snd_usX2Y_pcm_ops = 
{
	.open =		snd_usX2Y_pcm_open,
	.close =	snd_usX2Y_pcm_close,
	.ioctl =	snd_pcm_lib_ioctl,
	.hw_params =	snd_usX2Y_pcm_hw_params,
	.hw_free =	snd_usX2Y_pcm_hw_free,
	.prepare =	snd_usX2Y_pcm_prepare,
	.trigger =	snd_usX2Y_pcm_trigger,
	.pointer =	snd_usX2Y_pcm_pointer,
};


/*
 * free a usb stream instance
 */
static void usX2Y_audio_stream_free(snd_usX2Y_substream_t **usX2Y_substream)
{
	if (NULL != usX2Y_substream[SNDRV_PCM_STREAM_PLAYBACK]) {
		kfree(usX2Y_substream[SNDRV_PCM_STREAM_PLAYBACK]);
		usX2Y_substream[SNDRV_PCM_STREAM_PLAYBACK] = NULL;
	}
	kfree(usX2Y_substream[SNDRV_PCM_STREAM_CAPTURE]);
	usX2Y_substream[SNDRV_PCM_STREAM_CAPTURE] = NULL;
}

static void snd_usX2Y_pcm_private_free(snd_pcm_t *pcm)
{
	snd_usX2Y_substream_t **usX2Y_stream = pcm->private_data;
	if (usX2Y_stream) {
		snd_pcm_lib_preallocate_free_for_all(pcm);
		usX2Y_audio_stream_free(usX2Y_stream);
	}
}

static int usX2Y_audio_stream_new(snd_card_t *card, int playback_endpoint, int capture_endpoint)
{
	snd_pcm_t *pcm;
	int err, i;
	snd_usX2Y_substream_t **usX2Y_substream =
		usX2Y(card)->subs + 2 * usX2Y(card)->chip.pcm_devs;

	for (i = playback_endpoint ? SNDRV_PCM_STREAM_PLAYBACK : SNDRV_PCM_STREAM_CAPTURE;
	     i <= SNDRV_PCM_STREAM_CAPTURE; ++i) {
		usX2Y_substream[i] = kcalloc(1, sizeof(snd_usX2Y_substream_t), GFP_KERNEL);
		if (NULL == usX2Y_substream[i]) {
			snd_printk(KERN_ERR "cannot malloc\n");
			return -ENOMEM;
		}
		usX2Y_substream[i]->usX2Y = usX2Y(card);
	}

	if (playback_endpoint)
		usX2Y_substream[SNDRV_PCM_STREAM_PLAYBACK]->endpoint = playback_endpoint;
	usX2Y_substream[SNDRV_PCM_STREAM_CAPTURE]->endpoint = capture_endpoint;

	err = snd_pcm_new(card, NAME_ALLCAPS" Audio", usX2Y(card)->chip.pcm_devs,
			  playback_endpoint ? 1 : 0, 1,
			  &pcm);
	if (err < 0) {
		usX2Y_audio_stream_free(usX2Y_substream);
		return err;
	}

	if (playback_endpoint)
		snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_usX2Y_pcm_ops);
	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_usX2Y_pcm_ops);

	pcm->private_data = usX2Y_substream;
	pcm->private_free = snd_usX2Y_pcm_private_free;
	pcm->info_flags = 0;

	sprintf(pcm->name, NAME_ALLCAPS" Audio #%d", usX2Y(card)->chip.pcm_devs);

	if ((playback_endpoint &&
	     0 > (err = snd_pcm_lib_preallocate_pages(pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream,
						     SNDRV_DMA_TYPE_CONTINUOUS,
						     snd_dma_continuous_data(GFP_KERNEL),
						     64*1024, 128*1024))) ||
	    0 > (err = snd_pcm_lib_preallocate_pages(pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream,
	    					     SNDRV_DMA_TYPE_CONTINUOUS,
	    					     snd_dma_continuous_data(GFP_KERNEL),
						     64*1024, 128*1024))) {
		snd_usX2Y_pcm_private_free(pcm);
		return err;
	}
	usX2Y(card)->chip.pcm_devs++;

	return 0;
}

/*
 * create a chip instance and set its names.
 */
int usX2Y_audio_create(snd_card_t* card)
{
	int err = 0;
	
	INIT_LIST_HEAD(&usX2Y(card)->chip.pcm_list);

	if (0 > (err = usX2Y_audio_stream_new(card, 0xA, 0x8)))
		return err;
	if (le16_to_cpu(usX2Y(card)->chip.dev->descriptor.idProduct) == USB_ID_US428)
	     if (0 > (err = usX2Y_audio_stream_new(card, 0, 0xA)))
		     return err;
	if (le16_to_cpu(usX2Y(card)->chip.dev->descriptor.idProduct) != USB_ID_US122)
		err = usX2Y_rate_set(usX2Y(card), 44100);	// Lets us428 recognize output-volume settings, disturbs us122.
	return err;
}
