/*
   em28xx-core.c - driver for Empia EM2800/EM2820/2840 USB video capture devices

   Copyright (C) 2005 Ludovico Cavedon <cavedon@sssup.it>
		      Markus Rechberger <mrechberger@gmail.com>
		      Mauro Carvalho Chehab <mchehab@infradead.org>
		      Sascha Sommer <saschasommer@freenet.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., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

#include <linux/init.h>
#include <linux/list.h>
#include <linux/module.h>
#include <linux/usb.h>
#include <linux/vmalloc.h>

#include "em28xx.h"

/* #define ENABLE_DEBUG_ISOC_FRAMES */

static unsigned int core_debug = 0;
module_param(core_debug,int,0644);
MODULE_PARM_DESC(core_debug,"enable debug messages [core]");

#define em28xx_coredbg(fmt, arg...) do {\
	if (core_debug) \
		printk(KERN_INFO "%s %s :"fmt, \
			 dev->name, __FUNCTION__ , ##arg); } while (0)

static unsigned int reg_debug = 0;
module_param(reg_debug,int,0644);
MODULE_PARM_DESC(reg_debug,"enable debug messages [URB reg]");

#define em28xx_regdbg(fmt, arg...) do {\
	if (reg_debug) \
		printk(KERN_INFO "%s %s :"fmt, \
			 dev->name, __FUNCTION__ , ##arg); } while (0)

static unsigned int isoc_debug = 0;
module_param(isoc_debug,int,0644);
MODULE_PARM_DESC(isoc_debug,"enable debug messages [isoc transfers]");

#define em28xx_isocdbg(fmt, arg...) do {\
	if (isoc_debug) \
		printk(KERN_INFO "%s %s :"fmt, \
			 dev->name, __FUNCTION__ , ##arg); } while (0)

static int alt = EM28XX_PINOUT;
module_param(alt, int, 0644);
MODULE_PARM_DESC(alt, "alternate setting to use for video endpoint");


/*
 * em28xx_request_buffers()
 * allocate a number of buffers
 */
u32 em28xx_request_buffers(struct em28xx *dev, u32 count)
{
	const size_t imagesize = PAGE_ALIGN(dev->frame_size);	/*needs to be page aligned cause the buffers can be mapped individually! */
	void *buff = NULL;
	u32 i;
	em28xx_coredbg("requested %i buffers with size %zi", count, imagesize);
	if (count > EM28XX_NUM_FRAMES)
		count = EM28XX_NUM_FRAMES;

	dev->num_frames = count;
	while (dev->num_frames > 0) {
		if ((buff = vmalloc_32(dev->num_frames * imagesize))) {
			memset(buff, 0, dev->num_frames * imagesize);
			break;
		}
		dev->num_frames--;
	}

	for (i = 0; i < dev->num_frames; i++) {
		dev->frame[i].bufmem = buff + i * imagesize;
		dev->frame[i].buf.index = i;
		dev->frame[i].buf.m.offset = i * imagesize;
		dev->frame[i].buf.length = dev->frame_size;
		dev->frame[i].buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
		dev->frame[i].buf.sequence = 0;
		dev->frame[i].buf.field = V4L2_FIELD_NONE;
		dev->frame[i].buf.memory = V4L2_MEMORY_MMAP;
		dev->frame[i].buf.flags = 0;
	}
	return dev->num_frames;
}

/*
 * em28xx_queue_unusedframes()
 * add all frames that are not currently in use to the inbuffer queue
 */
void em28xx_queue_unusedframes(struct em28xx *dev)
{
	unsigned long lock_flags;
	u32 i;

	for (i = 0; i < dev->num_frames; i++)
		if (dev->frame[i].state == F_UNUSED) {
			dev->frame[i].state = F_QUEUED;
			spin_lock_irqsave(&dev->queue_lock, lock_flags);
			list_add_tail(&dev->frame[i].frame, &dev->inqueue);
			spin_unlock_irqrestore(&dev->queue_lock, lock_flags);
		}
}

/*
 * em28xx_release_buffers()
 * free frame buffers
 */
void em28xx_release_buffers(struct em28xx *dev)
{
	if (dev->num_frames) {
		vfree(dev->frame[0].bufmem);
		dev->num_frames = 0;
	}
}

/*
 * em28xx_read_reg_req()
 * reads data from the usb device specifying bRequest
 */
int em28xx_read_reg_req_len(struct em28xx *dev, u8 req, u16 reg,
				   char *buf, int len)
{
	int ret, byte;

	if (dev->state & DEV_DISCONNECTED)
		return(-ENODEV);

	em28xx_regdbg("req=%02x, reg=%02x ", req, reg);

	ret = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0), req,
			      USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
			      0x0000, reg, buf, len, HZ);

	if (reg_debug){
		printk(ret < 0 ? " failed!\n" : "%02x values: ", ret);
		for (byte = 0; byte < len; byte++) {
			printk(" %02x", buf[byte]);
		}
		printk("\n");
	}

	return ret;
}

/*
 * em28xx_read_reg_req()
 * reads data from the usb device specifying bRequest
 */
int em28xx_read_reg_req(struct em28xx *dev, u8 req, u16 reg)
{
	u8 val;
	int ret;

	if (dev->state & DEV_DISCONNECTED)
		return(-ENODEV);

	em28xx_regdbg("req=%02x, reg=%02x:", req, reg);

	ret = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0), req,
			      USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
			      0x0000, reg, &val, 1, HZ);

	if (reg_debug)
		printk(ret < 0 ? " failed!\n" : "%02x\n", val);

	if (ret < 0)
		return ret;

	return val;
}

int em28xx_read_reg(struct em28xx *dev, u16 reg)
{
	return em28xx_read_reg_req(dev, USB_REQ_GET_STATUS, reg);
}

/*
 * em28xx_write_regs_req()
 * sends data to the usb device, specifying bRequest
 */
int em28xx_write_regs_req(struct em28xx *dev, u8 req, u16 reg, char *buf,
				 int len)
{
	int ret;

	/*usb_control_msg seems to expect a kmalloced buffer */
	unsigned char *bufs;

	if (dev->state & DEV_DISCONNECTED)
		return(-ENODEV);

	bufs = kmalloc(len, GFP_KERNEL);

	em28xx_regdbg("req=%02x reg=%02x:", req, reg);

	if (reg_debug) {
		int i;
		for (i = 0; i < len; ++i)
			printk (" %02x", (unsigned char)buf[i]);
		printk ("\n");
	}

	if (!bufs)
		return -ENOMEM;
	memcpy(bufs, buf, len);
	ret = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0), req,
			      USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
			      0x0000, reg, bufs, len, HZ);
	msleep(5);		/* FIXME: magic number */
	kfree(bufs);
	return ret;
}

int em28xx_write_regs(struct em28xx *dev, u16 reg, char *buf, int len)
{
	return em28xx_write_regs_req(dev, USB_REQ_GET_STATUS, reg, buf, len);
}

/*
 * em28xx_write_reg_bits()
 * sets only some bits (specified by bitmask) of a register, by first reading
 * the actual value
 */
int em28xx_write_reg_bits(struct em28xx *dev, u16 reg, u8 val,
				 u8 bitmask)
{
	int oldval;
	u8 newval;
	if ((oldval = em28xx_read_reg(dev, reg)) < 0)
		return oldval;
	newval = (((u8) oldval) & ~bitmask) | (val & bitmask);
	return em28xx_write_regs(dev, reg, &newval, 1);
}

/*
 * em28xx_write_ac97()
 * write a 16 bit value to the specified AC97 address (LSB first!)
 */
int em28xx_write_ac97(struct em28xx *dev, u8 reg, u8 * val)
{
	int ret;
	u8 addr = reg & 0x7f;
	if ((ret = em28xx_write_regs(dev, AC97LSB_REG, val, 2)) < 0)
		return ret;
	if ((ret = em28xx_write_regs(dev, AC97ADDR_REG, &addr, 1)) < 0)
		return ret;
	if ((ret = em28xx_read_reg(dev, AC97BUSY_REG)) < 0)
		return ret;
	else if (((u8) ret) & 0x01) {
		em28xx_warn ("AC97 command still being executed: not handled properly!\n");
	}
	return 0;
}

int em28xx_audio_analog_set(struct em28xx *dev)
{
	char s[2] = { 0x00, 0x00 };
	s[0] |= 0x1f - dev->volume;
	s[1] |= 0x1f - dev->volume;
	if (dev->mute)
		s[1] |= 0x80;
	return em28xx_write_ac97(dev, MASTER_AC97, s);
}


int em28xx_colorlevels_set_default(struct em28xx *dev)
{
	em28xx_write_regs(dev, YGAIN_REG, "\x10", 1);	/* contrast */
	em28xx_write_regs(dev, YOFFSET_REG, "\x00", 1);	/* brightness */
	em28xx_write_regs(dev, UVGAIN_REG, "\x10", 1);	/* saturation */
	em28xx_write_regs(dev, UOFFSET_REG, "\x00", 1);
	em28xx_write_regs(dev, VOFFSET_REG, "\x00", 1);
	em28xx_write_regs(dev, SHARPNESS_REG, "\x00", 1);

	em28xx_write_regs(dev, GAMMA_REG, "\x20", 1);
	em28xx_write_regs(dev, RGAIN_REG, "\x20", 1);
	em28xx_write_regs(dev, GGAIN_REG, "\x20", 1);
	em28xx_write_regs(dev, BGAIN_REG, "\x20", 1);
	em28xx_write_regs(dev, ROFFSET_REG, "\x00", 1);
	em28xx_write_regs(dev, GOFFSET_REG, "\x00", 1);
	return em28xx_write_regs(dev, BOFFSET_REG, "\x00", 1);
}

int em28xx_capture_start(struct em28xx *dev, int start)
{
	int ret;
	/* FIXME: which is the best order? */
	/* video registers are sampled by VREF */
	if ((ret = em28xx_write_reg_bits(dev, USBSUSP_REG, start ? 0x10 : 0x00,
					  0x10)) < 0)
		return ret;
	/* enable video capture */
	return em28xx_write_regs(dev, VINENABLE_REG, start ? "\x67" : "\x27", 1);
}

int em28xx_outfmt_set_yuv422(struct em28xx *dev)
{
	em28xx_write_regs(dev, OUTFMT_REG, "\x34", 1);
	em28xx_write_regs(dev, VINMODE_REG, "\x10", 1);
	return em28xx_write_regs(dev, VINCTRL_REG, "\x11", 1);
}

static int em28xx_accumulator_set(struct em28xx *dev, u8 xmin, u8 xmax,
				  u8 ymin, u8 ymax)
{
	em28xx_coredbg("em28xx Scale: (%d,%d)-(%d,%d)\n", xmin, ymin, xmax, ymax);

	em28xx_write_regs(dev, XMIN_REG, &xmin, 1);
	em28xx_write_regs(dev, XMAX_REG, &xmax, 1);
	em28xx_write_regs(dev, YMIN_REG, &ymin, 1);
	return em28xx_write_regs(dev, YMAX_REG, &ymax, 1);
}

static int em28xx_capture_area_set(struct em28xx *dev, u8 hstart, u8 vstart,
				   u16 width, u16 height)
{
	u8 cwidth = width;
	u8 cheight = height;
	u8 overflow = (height >> 7 & 0x02) | (width >> 8 & 0x01);

	em28xx_coredbg("em28xx Area Set: (%d,%d)\n", (width | (overflow & 2) << 7),
			(height | (overflow & 1) << 8));

	em28xx_write_regs(dev, HSTART_REG, &hstart, 1);
	em28xx_write_regs(dev, VSTART_REG, &vstart, 1);
	em28xx_write_regs(dev, CWIDTH_REG, &cwidth, 1);
	em28xx_write_regs(dev, CHEIGHT_REG, &cheight, 1);
	return em28xx_write_regs(dev, OFLOW_REG, &overflow, 1);
}

static int em28xx_scaler_set(struct em28xx *dev, u16 h, u16 v)
{
	u8 mode;
	/* the em2800 scaler only supports scaling down to 50% */
	if(dev->is_em2800)
		mode = (v ? 0x20 : 0x00) | (h ? 0x10 : 0x00);
	else {
		u8 buf[2];
		buf[0] = h;
		buf[1] = h >> 8;
		em28xx_write_regs(dev, HSCALELOW_REG, (char *)buf, 2);
		buf[0] = v;
		buf[1] = v >> 8;
		em28xx_write_regs(dev, VSCALELOW_REG, (char *)buf, 2);
		/* it seems that both H and V scalers must be active to work correctly */
		mode = (h || v)? 0x30: 0x00;
	}
	return em28xx_write_reg_bits(dev, COMPR_REG, mode, 0x30);
}

/* FIXME: this only function read values from dev */
int em28xx_resolution_set(struct em28xx *dev)
{
	int width, height;
	width = norm_maxw(dev);
	height = norm_maxh(dev) >> 1;

	em28xx_outfmt_set_yuv422(dev);
	em28xx_accumulator_set(dev, 1, (width - 4) >> 2, 1, (height - 4) >> 2);
	em28xx_capture_area_set(dev, 0, 0, width >> 2, height >> 2);
	return em28xx_scaler_set(dev, dev->hscale, dev->vscale);
}


/******************* isoc transfer handling ****************************/

#ifdef ENABLE_DEBUG_ISOC_FRAMES
static void em28xx_isoc_dump(struct urb *urb)
{
	int len = 0;
	int ntrans = 0;
	int i;

	printk(KERN_DEBUG "isocIrq: sf=%d np=%d ec=%x\n",
	       urb->start_frame, urb->number_of_packets,
	       urb->error_count);
	for (i = 0; i < urb->number_of_packets; i++) {
		unsigned char *buf =
				urb->transfer_buffer +
				urb->iso_frame_desc[i].offset;
		int alen = urb->iso_frame_desc[i].actual_length;
		if (alen > 0) {
			if (buf[0] == 0x88) {
				ntrans++;
				len += alen;
			} else if (buf[0] == 0x22) {
				printk(KERN_DEBUG
						"= l=%d nt=%d bpp=%d\n",
				len - 4 * ntrans, ntrans,
				ntrans == 0 ? 0 : len / ntrans);
				ntrans = 1;
				len = alen;
			} else
				printk(KERN_DEBUG "!\n");
		}
		printk(KERN_DEBUG "   n=%d s=%d al=%d %x\n", i,
		       urb->iso_frame_desc[i].status,
		       urb->iso_frame_desc[i].actual_length,
		       (unsigned int)
				       *((unsigned char *)(urb->transfer_buffer +
				       urb->iso_frame_desc[i].
				       offset)));
	}
}
#endif

static inline int em28xx_isoc_video(struct em28xx *dev,struct em28xx_frame_t **f,
				    unsigned long *lock_flags, unsigned char buf)
{
	if (!(buf & 0x01)) {
		if ((*f)->state == F_GRABBING) {
			/*previous frame is incomplete */
			if ((*f)->fieldbytesused < dev->field_size) {
				(*f)->state = F_ERROR;
				em28xx_isocdbg ("dropping incomplete bottom field (%i missing bytes)",
					 dev->field_size-(*f)->fieldbytesused);
			} else {
				(*f)->state = F_DONE;
				(*f)->buf.bytesused = dev->frame_size;
			}
		}
		if ((*f)->state == F_DONE || (*f)->state == F_ERROR) {
			/* move current frame to outqueue and get next free buffer from inqueue */
			spin_lock_irqsave(&dev-> queue_lock, *lock_flags);
			list_move_tail(&(*f)->frame, &dev->outqueue);
			if (!list_empty(&dev->inqueue))
				(*f) = list_entry(dev-> inqueue.next,
			struct em28xx_frame_t,frame);
			else
				(*f) = NULL;
			spin_unlock_irqrestore(&dev->queue_lock,*lock_flags);
		}
		if (!(*f)) {
			em28xx_isocdbg ("new frame but no buffer is free");
			return -1;
		}
		do_gettimeofday(&(*f)->buf.timestamp);
		(*f)->buf.sequence = ++dev->frame_count;
		(*f)->buf.field = V4L2_FIELD_INTERLACED;
		(*f)->state = F_GRABBING;
		(*f)->buf.bytesused = 0;
		(*f)->top_field = 1;
		(*f)->fieldbytesused = 0;
	} else {
					/* acquiring bottom field */
		if ((*f)->state == F_GRABBING) {
			if (!(*f)->top_field) {
				(*f)->state = F_ERROR;
				em28xx_isocdbg ("unexpected begin of bottom field; discarding it");
			} else if ((*f)-> fieldbytesused < dev->field_size - 172) {
				(*f)->state = F_ERROR;
				em28xx_isocdbg ("dropping incomplete top field (%i missing bytes)",
					 dev->field_size-(*f)->fieldbytesused);
			} else {
				(*f)->top_field = 0;
				(*f)->fieldbytesused = 0;
			}
		}
	}
	return (0);
}

static inline void em28xx_isoc_video_copy(struct em28xx *dev,
					  struct em28xx_frame_t **f, unsigned char *buf, int len)
{
	void *fieldstart, *startwrite, *startread;
	int linesdone, currlinedone, offset, lencopy,remain;

	if(dev->frame_size != (*f)->buf.length){
		em28xx_err("frame_size %i and buf.length %i are different!!!\n",dev->frame_size,(*f)->buf.length);
		return;
	}

	if ((*f)->fieldbytesused + len > dev->field_size)
		len =dev->field_size - (*f)->fieldbytesused;

	if (buf[0] != 0x88 && buf[0] != 0x22) {
		em28xx_isocdbg("frame is not complete\n");
		startread = buf;
		len+=4;
	} else
		startread = buf + 4;

	remain = len;

	if ((*f)->top_field)
		fieldstart = (*f)->bufmem;
	else
		fieldstart = (*f)->bufmem + dev->bytesperline;

	linesdone = (*f)->fieldbytesused / dev->bytesperline;
	currlinedone = (*f)->fieldbytesused % dev->bytesperline;
	offset = linesdone * dev->bytesperline * 2 + currlinedone;
	startwrite = fieldstart + offset;
	lencopy = dev->bytesperline - currlinedone;
	lencopy = lencopy > remain ? remain : lencopy;

	memcpy(startwrite, startread, lencopy);
	remain -= lencopy;

	while (remain > 0) {
		startwrite += lencopy + dev->bytesperline;
		startread += lencopy;
		if (dev->bytesperline > remain)
			lencopy = remain;
		else
			lencopy = dev->bytesperline;

		memcpy(startwrite, startread, lencopy);
		remain -= lencopy;
	}

	(*f)->fieldbytesused += len;
}

/*
 * em28xx_isoIrq()
 * handles the incoming isoc urbs and fills the frames from our inqueue
 */
static void em28xx_isocIrq(struct urb *urb)
{
	struct em28xx *dev = urb->context;
	int i, status;
	struct em28xx_frame_t **f;
	unsigned long lock_flags;

	if (!dev)
		return;
#ifdef ENABLE_DEBUG_ISOC_FRAMES
	if (isoc_debug>1)
		em28xx_isoc_dump(urb);
#endif

	if (urb->status == -ENOENT)
		return;

	f = &dev->frame_current;

	if (dev->stream == STREAM_INTERRUPT) {
		dev->stream = STREAM_OFF;
		if ((*f))
			(*f)->state = F_QUEUED;
		em28xx_isocdbg("stream interrupted");
		wake_up_interruptible(&dev->wait_stream);
	}

	if ((dev->state & DEV_DISCONNECTED) || (dev->state & DEV_MISCONFIGURED))
		return;

	if (dev->stream == STREAM_ON && !list_empty(&dev->inqueue)) {
		if (!(*f))
			(*f) = list_entry(dev->inqueue.next,
		struct em28xx_frame_t, frame);

		for (i = 0; i < urb->number_of_packets; i++) {
			unsigned char *buf = urb->transfer_buffer +
					urb->iso_frame_desc[i].offset;
			int len = urb->iso_frame_desc[i].actual_length - 4;

			if (urb->iso_frame_desc[i].status) {
				em28xx_isocdbg("data error: [%d] len=%d, status=%d", i,
					urb->iso_frame_desc[i].actual_length,
					urb->iso_frame_desc[i].status);
				if (urb->iso_frame_desc[i].status != -EPROTO)
					continue;
			}
			if (urb->iso_frame_desc[i].actual_length <= 0) {
				em28xx_isocdbg("packet %d is empty",i);
				continue;
			}
			if (urb->iso_frame_desc[i].actual_length >
						 dev->max_pkt_size) {
				em28xx_isocdbg("packet bigger than packet size");
				continue;
			}
			/*new frame */
			if (buf[0] == 0x22 && buf[1] == 0x5a) {
				em28xx_isocdbg("Video frame, length=%i!",len);

				if (em28xx_isoc_video(dev,f,&lock_flags,buf[2]))
				break;
			} else if (buf[0]==0x33 && buf[1]==0x95 && buf[2]==0x00) {
				em28xx_isocdbg("VBI HEADER!!!");
			}

			/* actual copying */
			if ((*f)->state == F_GRABBING) {
				em28xx_isoc_video_copy(dev,f,buf, len);
			}
		}
	}

	for (i = 0; i < urb->number_of_packets; i++) {
		urb->iso_frame_desc[i].status = 0;
		urb->iso_frame_desc[i].actual_length = 0;
	}

	urb->status = 0;
	if ((status = usb_submit_urb(urb, GFP_ATOMIC))) {
		em28xx_errdev("resubmit of urb failed (error=%i)\n", status);
		dev->state |= DEV_MISCONFIGURED;
	}
	wake_up_interruptible(&dev->wait_frame);
	return;
}

/*
 * em28xx_uninit_isoc()
 * deallocates the buffers and urbs allocated during em28xx_init_iosc()
 */
void em28xx_uninit_isoc(struct em28xx *dev)
{
	int i;

	for (i = 0; i < EM28XX_NUM_BUFS; i++) {
		if (dev->urb[i]) {
			usb_kill_urb(dev->urb[i]);
			if (dev->transfer_buffer[i]){
				usb_buffer_free(dev->udev,(EM28XX_NUM_PACKETS*dev->max_pkt_size),dev->transfer_buffer[i],dev->urb[i]->transfer_dma);
			}
			usb_free_urb(dev->urb[i]);
		}
		dev->urb[i] = NULL;
		dev->transfer_buffer[i] = NULL;
	}
	em28xx_capture_start(dev, 0);
}

/*
 * em28xx_init_isoc()
 * allocates transfer buffers and submits the urbs for isoc transfer
 */
int em28xx_init_isoc(struct em28xx *dev)
{
	/* change interface to 3 which allows the biggest packet sizes */
	int i, errCode;
	const int sb_size = EM28XX_NUM_PACKETS * dev->max_pkt_size;

	/* reset streaming vars */
	dev->frame_current = NULL;
	dev->frame_count = 0;

	/* allocate urbs */
	for (i = 0; i < EM28XX_NUM_BUFS; i++) {
		struct urb *urb;
		int j, k;
		/* allocate transfer buffer */
		urb = usb_alloc_urb(EM28XX_NUM_PACKETS, GFP_KERNEL);
		if (!urb){
			em28xx_errdev("cannot alloc urb %i\n", i);
			em28xx_uninit_isoc(dev);
			return -ENOMEM;
		}
		dev->transfer_buffer[i] = usb_buffer_alloc(dev->udev, sb_size, GFP_KERNEL,&urb->transfer_dma);
		if (!dev->transfer_buffer[i]) {
			em28xx_errdev
					("unable to allocate %i bytes for transfer buffer %i\n",
					 sb_size, i);
			em28xx_uninit_isoc(dev);
			usb_free_urb(urb);
			return -ENOMEM;
		}
		memset(dev->transfer_buffer[i], 0, sb_size);
		urb->dev = dev->udev;
		urb->context = dev;
		urb->pipe = usb_rcvisocpipe(dev->udev, 0x82);
		urb->transfer_flags = URB_ISO_ASAP;
		urb->interval = 1;
		urb->transfer_buffer = dev->transfer_buffer[i];
		urb->complete = em28xx_isocIrq;
		urb->number_of_packets = EM28XX_NUM_PACKETS;
		urb->transfer_buffer_length = sb_size;
		for (j = k = 0; j < EM28XX_NUM_PACKETS;
				j++, k += dev->max_pkt_size) {
			urb->iso_frame_desc[j].offset = k;
			urb->iso_frame_desc[j].length =
				dev->max_pkt_size;
		}
		dev->urb[i] = urb;
	}

	/* submit urbs */
	for (i = 0; i < EM28XX_NUM_BUFS; i++) {
		errCode = usb_submit_urb(dev->urb[i], GFP_KERNEL);
		if (errCode) {
			em28xx_errdev("submit of urb %i failed (error=%i)\n", i,
				      errCode);
			em28xx_uninit_isoc(dev);
			return errCode;
		}
	}

	return 0;
}

int em28xx_set_alternate(struct em28xx *dev)
{
	int errCode, prev_alt = dev->alt;
	dev->alt = alt;
	if (dev->alt == 0) {
		int i;
		for(i=0;i< dev->num_alt; i++)
			if(dev->alt_max_pkt_size[i]>dev->alt_max_pkt_size[dev->alt])
				dev->alt=i;
	}

	if (dev->alt != prev_alt) {
		dev->max_pkt_size = dev->alt_max_pkt_size[dev->alt];
		em28xx_coredbg("setting alternate %d with wMaxPacketSize=%u\n", dev->alt,
		       dev->max_pkt_size);
		errCode = usb_set_interface(dev->udev, 0, dev->alt);
		if (errCode < 0) {
			em28xx_errdev ("cannot change alternate number to %d (error=%i)\n",
							dev->alt, errCode);
			return errCode;
		}
	}
	return 0;
}
