/*
   em2820-video.c - driver for Empia EM2820/2840 USB video capture devices

   Copyright (C) 2005 Markus Rechberger <mrechberger@gmail.com>
                      Ludovico Cavedon <cavedon@sssup.it>
                      Mauro Carvalho Chehab <mchehab@brturbo.com.br>

   Based on the em2800 driver from 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/kernel.h>
#include <linux/usb.h>
#include <linux/i2c.h>
#include <linux/videodev.h>
#include <media/tuner.h>
#include <linux/video_decoder.h>

#include "em2820.h"

#define DRIVER_AUTHOR "Markus Rechberger <mrechberger@gmail.com>, " \
			"Ludovico Cavedon <cavedon@sssup.it>, " \
			"Mauro Carvalho Chehab <mchehab@brturbo.com.br>"

#define DRIVER_NAME         "em2820"
#define DRIVER_DESC         "Empia em2820 based USB video device driver"
#define EM2820_VERSION_CODE  KERNEL_VERSION(0, 0, 1)

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

MODULE_AUTHOR(DRIVER_AUTHOR);
MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE("GPL");

static int tuner = -1;
module_param(tuner, int, 0444);
MODULE_PARM_DESC(tuner, "tuner type");

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

/* supported tv norms */
static struct em2820_tvnorm tvnorms[] = {
	{
		.name = "PAL",
		.id = V4L2_STD_PAL,
		.mode = VIDEO_MODE_PAL,
	 }, {
		.name = "NTSC",
		.id = V4L2_STD_NTSC,
		.mode = VIDEO_MODE_NTSC,
	}, {
		 .name = "SECAM",
		 .id = V4L2_STD_SECAM,
		 .mode = VIDEO_MODE_SECAM,
	}, {
		.name = "PAL-M",
		.id = V4L2_STD_PAL_M,
		.mode = VIDEO_MODE_PAL,
	}
};

#define TVNORMS ARRAY_SIZE(tvnorms)

/* supported controls */
static struct v4l2_queryctrl em2820_qctrl[] = {
	{
		.id = V4L2_CID_BRIGHTNESS,
		.type = V4L2_CTRL_TYPE_INTEGER,
		.name = "Brightness",
		.minimum = -128,
		.maximum = 127,
		.step = 1,
		.default_value = 0,
		.flags = 0,
	},{
		.id = V4L2_CID_CONTRAST,
		.type = V4L2_CTRL_TYPE_INTEGER,
		.name = "Contrast",
		.minimum = 0x0,
		.maximum = 0x1f,
		.step = 0x1,
		.default_value = 0x10,
		.flags = 0,
	},{
		.id = V4L2_CID_SATURATION,
		.type = V4L2_CTRL_TYPE_INTEGER,
		.name = "Saturation",
		.minimum = 0x0,
		.maximum = 0x1f,
		.step = 0x1,
		.default_value = 0x10,
		.flags = 0,
	},{
		.id = V4L2_CID_AUDIO_VOLUME,
		.type = V4L2_CTRL_TYPE_INTEGER,
		.name = "Volume",
		.minimum = 0x0,
		.maximum = 0x1f,
		.step = 0x1,
		.default_value = 0x1f,
		.flags = 0,
	},{
		.id = V4L2_CID_AUDIO_MUTE,
		.type = V4L2_CTRL_TYPE_BOOLEAN,
		.name = "Mute",
		.minimum = 0,
		.maximum = 1,
		.step = 1,
		.default_value = 1,
		.flags = 0,
	},{
		.id = V4L2_CID_RED_BALANCE,
		.type = V4L2_CTRL_TYPE_INTEGER,
		.name = "Red chroma balance",
		.minimum = -128,
		.maximum = 127,
		.step = 1,
		.default_value = 0,
		.flags = 0,
	},{
		.id = V4L2_CID_BLUE_BALANCE,
		.type = V4L2_CTRL_TYPE_INTEGER,
		.name = "Blue chroma balance",
		.minimum = -128,
		.maximum = 127,
		.step = 1,
		.default_value = 0,
		.flags = 0,
	},{
		.id = V4L2_CID_GAMMA,
		.type = V4L2_CTRL_TYPE_INTEGER,
		.name = "Gamma",
		.minimum = 0x0,
		.maximum = 0x3f,
		.step = 0x1,
		.default_value = 0x20,
		.flags = 0,
	 }
};

static struct usb_driver em2820_usb_driver;

static DECLARE_MUTEX(em2820_sysfs_lock);
static DECLARE_RWSEM(em2820_disconnect);

/*********************  v4l2 interface  ******************************************/

static inline unsigned long kvirt_to_pa(unsigned long adr)
{
	unsigned long kva, ret;

	kva = (unsigned long)page_address(vmalloc_to_page((void *)adr));
	kva |= adr & (PAGE_SIZE - 1);
	ret = __pa(kva);
	return ret;
}

/*
 * em2820_config()
 * inits registers with sane defaults
 */
static int em2820_config(struct em2820 *dev)
{

	/* Sets I2C speed to 100 KHz */
	em2820_write_regs_req(dev, 0x00, 0x06, "\x40", 1);

	/* enable vbi capturing */
	em2820_audio_usb_mute(dev, 1);
	dev->mute = 1;		/* maybe not the right place... */
	dev->volume = 0x1f;
	em2820_audio_analog_set(dev);
	em2820_audio_analog_setup(dev);
	em2820_outfmt_set_yuv422(dev);
	em2820_colorlevels_set_default(dev);
	em2820_compression_disable(dev);

	return 0;
}

/*
 * em2820_config_i2c()
 * configure i2c attached devices
 */
void em2820_config_i2c(struct em2820 *dev)
{
	struct v4l2_frequency f;
	struct video_decoder_init em2820_vdi = {.data = NULL };


	/* configure decoder */
	em2820_i2c_call_clients(dev, DECODER_INIT, &em2820_vdi);
	em2820_i2c_call_clients(dev, DECODER_SET_INPUT, &dev->ctl_input);
/*	em2820_i2c_call_clients(dev,DECODER_SET_PICTURE, &dev->vpic); */
/*	em2820_i2c_call_clients(dev,DECODER_SET_NORM,&dev->tvnorm->id); */
/*	em2820_i2c_call_clients(dev,DECODER_ENABLE_OUTPUT,&output); */
/*	em2820_i2c_call_clients(dev,DECODER_DUMP, NULL); */

	/* configure tuner */
	f.tuner = 0;
	f.type = V4L2_TUNER_ANALOG_TV;
	f.frequency = 9076;	/* FIXME:remove magic number */
	dev->ctl_freq = f.frequency;
	em2820_i2c_call_clients(dev, VIDIOC_S_FREQUENCY, &f);

	/* configure tda9887 */

	em2820_i2c_call_clients(dev, TDA9887_SET_CONFIG, &dev->tda9887_conf);

/*	em2820_i2c_call_clients(dev,VIDIOC_S_STD,&dev->tvnorm->id); */
}

/*
 * em2820_empty_framequeues()
 * prepare queues for incoming and outgoing frames
 */
static void em2820_empty_framequeues(struct em2820 *dev)
{
	u32 i;

	INIT_LIST_HEAD(&dev->inqueue);
	INIT_LIST_HEAD(&dev->outqueue);

	for (i = 0; i < EM2820_NUM_FRAMES; i++) {
		dev->frame[i].state = F_UNUSED;
		dev->frame[i].buf.bytesused = 0;
	}
}

/*
 * em2820_v4l2_open()
 * inits the device and starts isoc transfer
 */
static int em2820_v4l2_open(struct inode *inode, struct file *filp)
{
	struct video_device *vdev = video_devdata(filp);
	int minor = iminor(inode);
	struct em2820 *dev = (struct em2820 *)video_get_drvdata(vdev);
	int errCode = 0;

	em2820_videodbg("users=%d", dev->users);

	if (!down_read_trylock(&em2820_disconnect))
		return -ERESTARTSYS;

	if (dev->users) {
		em2820_warn("this driver can be opened only once\n");
		up_read(&em2820_disconnect);
		return -EBUSY;
	}

/*	if(dev->vbi_dev->minor == minor){
		dev->type=V4L2_BUF_TYPE_VBI_CAPTURE;
	}*/
	if (dev->vdev->minor == minor) {
		dev->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
	}

	init_MUTEX(&dev->fileop_lock);	/* to 1 == available */
	spin_lock_init(&dev->queue_lock);
	init_waitqueue_head(&dev->wait_frame);
	init_waitqueue_head(&dev->wait_stream);

	down(&dev->lock);

	em2820_set_alternate(dev);

	dev->width = norm_maxw(dev);
	dev->height = norm_maxh(dev);
	dev->frame_size = dev->width * dev->height * 2;
	dev->field_size = dev->frame_size >> 1;	/*both_fileds ? dev->frame_size>>1 : dev->frame_size; */
	dev->bytesperline = dev->width * 2;
	dev->hscale = 0;
	dev->vscale = 0;

	em2820_capture_start(dev, 1);
	em2820_resolution_set(dev);

	/* start the transfer */
	errCode = em2820_init_isoc(dev);
	if (errCode)
		goto err;

	dev->users++;
	filp->private_data = dev;
	dev->io = IO_NONE;
	dev->stream = STREAM_OFF;
	dev->num_frames = 0;

	/* prepare queues */
	em2820_empty_framequeues(dev);

	dev->state |= DEV_INITIALIZED;

      err:
	up(&dev->lock);
	up_read(&em2820_disconnect);
	return errCode;
}

/*
 * em2820_realease_resources()
 * unregisters the v4l2,i2c and usb devices
 * called when the device gets disconected or at module unload
*/
static void em2820_release_resources(struct em2820 *dev)
{
	down(&em2820_sysfs_lock);

	em2820_info("V4L2 device /dev/video%d deregistered\n",
		    dev->vdev->minor);
	video_set_drvdata(dev->vdev, NULL);
	video_unregister_device(dev->vdev);
/*	video_unregister_device(dev->vbi_dev); */
	em2820_i2c_unregister(dev);
	usb_put_dev(dev->udev);
	up(&em2820_sysfs_lock);
}

/*
 * em2820_v4l2_close()
 * stops streaming and deallocates all resources allocated by the v4l2 calls and ioctls
 */
static int em2820_v4l2_close(struct inode *inode, struct file *file)
{
	struct video_device *vdev = video_devdata(file);
	struct em2820 *dev = (struct em2820 *)video_get_drvdata(vdev);
	int errCode;

	em2820_videodbg("users=%d", dev->users);

	down(&dev->lock);

	em2820_uninit_isoc(dev);

	em2820_release_buffers(dev);

	/* the device is already disconnect, free the remaining resources */
	if (dev->state & DEV_DISCONNECTED) {
		em2820_release_resources(dev);
		up(&dev->lock);
		kfree(dev);
		return 0;
	}

	/* set alternate 0 */
	dev->alt = 0;
	em2820_videodbg("setting alternate 0");
	errCode = usb_set_interface(dev->udev, 0, 0);
	if (errCode < 0) {
		em2820_errdev ("cannot change alternate number to 0 (error=%i)\n",
		     errCode);
	}

	dev->users--;
	wake_up_interruptible_nr(&dev->open, 1);
	up(&dev->lock);
	return 0;
}

/*
 * em2820_v4l2_read()
 * will allocate buffers when called for the first time
 */
static ssize_t
em2820_v4l2_read(struct file *filp, char __user * buf, size_t count,
		 loff_t * f_pos)
{
	struct em2820 *dev = video_get_drvdata(video_devdata(filp));
	struct em2820_frame_t *f, *i;
	unsigned long lock_flags;
	int ret = 0;

	if (down_interruptible(&dev->fileop_lock))
		return -ERESTARTSYS;

	if (dev->state & DEV_DISCONNECTED) {
		em2820_videodbg("device not present");
		up(&dev->fileop_lock);
		return -ENODEV;
	}

	if (dev->state & DEV_MISCONFIGURED) {
		em2820_videodbg("device misconfigured; close and open it again");
		up(&dev->fileop_lock);
		return -EIO;
	}

	if (dev->io == IO_MMAP) {
		em2820_videodbg ("IO method is set to mmap; close and open"
				" the device again to choose the read method");
		up(&dev->fileop_lock);
		return -EINVAL;
	}

	if (dev->io == IO_NONE) {
		if (!em2820_request_buffers(dev, EM2820_NUM_READ_FRAMES)) {
			em2820_errdev("read failed, not enough memory\n");
			up(&dev->fileop_lock);
			return -ENOMEM;
		}
		dev->io = IO_READ;
		dev->stream = STREAM_ON;
		em2820_queue_unusedframes(dev);
	}

	if (!count) {
		up(&dev->fileop_lock);
		return 0;
	}

	if (list_empty(&dev->outqueue)) {
		if (filp->f_flags & O_NONBLOCK) {
			up(&dev->fileop_lock);
			return -EAGAIN;
		}
		ret = wait_event_interruptible
		    (dev->wait_frame,
		     (!list_empty(&dev->outqueue)) ||
		     (dev->state & DEV_DISCONNECTED));
		if (ret) {
			up(&dev->fileop_lock);
			return ret;
		}
		if (dev->state & DEV_DISCONNECTED) {
			up(&dev->fileop_lock);
			return -ENODEV;
		}
	}

	f = list_entry(dev->outqueue.prev, struct em2820_frame_t, frame);

	spin_lock_irqsave(&dev->queue_lock, lock_flags);
	list_for_each_entry(i, &dev->outqueue, frame)
	    i->state = F_UNUSED;
	INIT_LIST_HEAD(&dev->outqueue);
	spin_unlock_irqrestore(&dev->queue_lock, lock_flags);

	em2820_queue_unusedframes(dev);

	if (count > f->buf.length)
		count = f->buf.length;

	if (copy_to_user(buf, f->bufmem, count)) {
		up(&dev->fileop_lock);
		return -EFAULT;
	}
	*f_pos += count;

	up(&dev->fileop_lock);

	return count;
}

/*
 * em2820_v4l2_poll()
 * will allocate buffers when called for the first time
 */
static unsigned int em2820_v4l2_poll(struct file *filp, poll_table * wait)
{
	struct em2820 *dev = video_get_drvdata(video_devdata(filp));
	unsigned int mask = 0;

	if (down_interruptible(&dev->fileop_lock))
		return POLLERR;

	if (dev->state & DEV_DISCONNECTED) {
		em2820_videodbg("device not present");
	} else if (dev->state & DEV_MISCONFIGURED) {
		em2820_videodbg("device is misconfigured; close and open it again");
	} else {
		if (dev->io == IO_NONE) {
			if (!em2820_request_buffers
			    (dev, EM2820_NUM_READ_FRAMES)) {
				em2820_warn
				    ("poll() failed, not enough memory\n");
			} else {
				dev->io = IO_READ;
				dev->stream = STREAM_ON;
			}
		}

		if (dev->io == IO_READ) {
			em2820_queue_unusedframes(dev);
			poll_wait(filp, &dev->wait_frame, wait);

			if (!list_empty(&dev->outqueue))
				mask |= POLLIN | POLLRDNORM;

			up(&dev->fileop_lock);

			return mask;
		}
	}

	up(&dev->fileop_lock);
	return POLLERR;
}

/*
 * em2820_vm_open()
 */
static void em2820_vm_open(struct vm_area_struct *vma)
{
	struct em2820_frame_t *f = vma->vm_private_data;
	f->vma_use_count++;
}

/*
 * em2820_vm_close()
 */
static void em2820_vm_close(struct vm_area_struct *vma)
{
	/* NOTE: buffers are not freed here */
	struct em2820_frame_t *f = vma->vm_private_data;
	f->vma_use_count--;
}

static struct vm_operations_struct em2820_vm_ops = {
	.open = em2820_vm_open,
	.close = em2820_vm_close,
};

/*
 * em2820_v4l2_mmap()
 */
static int em2820_v4l2_mmap(struct file *filp, struct vm_area_struct *vma)
{
	struct em2820 *dev = video_get_drvdata(video_devdata(filp));
	unsigned long size = vma->vm_end - vma->vm_start,
	    start = vma->vm_start, pos, page;
	u32 i;
	if (down_interruptible(&dev->fileop_lock))
		return -ERESTARTSYS;

	if (dev->state & DEV_DISCONNECTED) {
		em2820_videodbg("mmap: device not present");
		up(&dev->fileop_lock);
		return -ENODEV;
	}

	if (dev->state & DEV_MISCONFIGURED) {
		em2820_videodbg ("mmap: Device is misconfigured; close and "
						"open it again");
		up(&dev->fileop_lock);
		return -EIO;
	}

	if (dev->io != IO_MMAP || !(vma->vm_flags & VM_WRITE) ||
	    size != PAGE_ALIGN(dev->frame[0].buf.length)) {
		up(&dev->fileop_lock);
		return -EINVAL;
	}

	for (i = 0; i < dev->num_frames; i++) {
		if ((dev->frame[i].buf.m.offset >> PAGE_SHIFT) == vma->vm_pgoff)
			break;
	}
	if (i == dev->num_frames) {
		em2820_videodbg("mmap: user supplied mapping address is out of range");
		up(&dev->fileop_lock);
		return -EINVAL;
	}

	/* VM_IO is eventually going to replace PageReserved altogether */
	vma->vm_flags |= VM_IO;
	vma->vm_flags |= VM_RESERVED;	/* avoid to swap out this VMA */

	pos = (unsigned long)dev->frame[i].bufmem;
	while (size > 0) {	/* size is page-aligned */
		page = vmalloc_to_pfn((void *)pos);
		if (remap_pfn_range(vma, start, page, PAGE_SIZE,
				    vma->vm_page_prot)) {
			em2820_videodbg("mmap: rename page map failed");
			up(&dev->fileop_lock);
			return -EAGAIN;
		}
		start += PAGE_SIZE;
		pos += PAGE_SIZE;
		size -= PAGE_SIZE;
	}

	vma->vm_ops = &em2820_vm_ops;
	vma->vm_private_data = &dev->frame[i];

	em2820_vm_open(vma);
	up(&dev->fileop_lock);
	return 0;
}

/*
 * em2820_get_ctrl()
 * return the current saturation, brightness or contrast, mute state
 */
static int em2820_get_ctrl(struct em2820 *dev, struct v4l2_control *ctrl)
{
	s32 tmp;
	switch (ctrl->id) {
	case V4L2_CID_AUDIO_MUTE:
		ctrl->value = dev->mute;
		return 0;
	case V4L2_CID_AUDIO_VOLUME:
		ctrl->value = dev->volume;
		return 0;
	case V4L2_CID_BRIGHTNESS:
		if ((tmp = em2820_brightness_get(dev)) < 0)
			return -EIO;
		ctrl->value = (s32) ((s8) tmp);	/* FIXME: clenaer way to extend sign? */
		return 0;
	case V4L2_CID_CONTRAST:
		if ((ctrl->value = em2820_contrast_get(dev)) < 0)
			return -EIO;
		return 0;
	case V4L2_CID_SATURATION:
		if ((ctrl->value = em2820_saturation_get(dev)) < 0)
			return -EIO;
		return 0;
	case V4L2_CID_RED_BALANCE:
		if ((tmp = em2820_v_balance_get(dev)) < 0)
			return -EIO;
		ctrl->value = (s32) ((s8) tmp);	/* FIXME: clenaer way to extend sign? */
		return 0;
	case V4L2_CID_BLUE_BALANCE:
		if ((tmp = em2820_u_balance_get(dev)) < 0)
			return -EIO;
		ctrl->value = (s32) ((s8) tmp);	/* FIXME: clenaer way to extend sign? */
		return 0;
	case V4L2_CID_GAMMA:
		if ((ctrl->value = em2820_gamma_get(dev)) < 0)
			return -EIO;
		return 0;
	default:
		return -EINVAL;
	}
}

/*
 * em2820_set_ctrl()
 * mute or set new saturation, brightness or contrast
 */
static int em2820_set_ctrl(struct em2820 *dev, const struct v4l2_control *ctrl)
{
	switch (ctrl->id) {
	case V4L2_CID_AUDIO_MUTE:
		if (ctrl->value != dev->mute) {
			dev->mute = ctrl->value;
			em2820_audio_usb_mute(dev, ctrl->value);
			return em2820_audio_analog_set(dev);
		}
		return 0;
	case V4L2_CID_AUDIO_VOLUME:
		dev->volume = ctrl->value;
		return em2820_audio_analog_set(dev);
	case V4L2_CID_BRIGHTNESS:
		return em2820_brightness_set(dev, ctrl->value);
	case V4L2_CID_CONTRAST:
		return em2820_contrast_set(dev, ctrl->value);
	case V4L2_CID_SATURATION:
		return em2820_saturation_set(dev, ctrl->value);
	case V4L2_CID_RED_BALANCE:
		return em2820_v_balance_set(dev, ctrl->value);
	case V4L2_CID_BLUE_BALANCE:
		return em2820_u_balance_set(dev, ctrl->value);
	case V4L2_CID_GAMMA:
		return em2820_gamma_set(dev, ctrl->value);
	default:
		return -EINVAL;
	}
}

/*
 * em2820_stream_interrupt()
 * stops streaming
 */
static int em2820_stream_interrupt(struct em2820 *dev)
{
	int ret = 0;

	/* stop reading from the device */

	dev->stream = STREAM_INTERRUPT;
	ret = wait_event_timeout(dev->wait_stream,
				 (dev->stream == STREAM_OFF) ||
				 (dev->state & DEV_DISCONNECTED),
				 EM2820_URB_TIMEOUT);
	if (dev->state & DEV_DISCONNECTED)
		return -ENODEV;
	else if (ret) {
		dev->state |= DEV_MISCONFIGURED;
		em2820_videodbg("device is misconfigured; close and "
			"open /dev/video%d again", dev->vdev->minor);
		return ret;
	}

	return 0;
}

static int em2820_set_norm(struct em2820 *dev, int width, int height)
{
	unsigned int hscale, vscale;
	unsigned int maxh, maxw;

	maxw = norm_maxw(dev);
	maxh = norm_maxh(dev);

	/* width must even because of the YUYV format */
	/* height must be even because of interlacing */
	height &= 0xfffe;
	width &= 0xfffe;

	if (height < 32)
		height = 32;
	if (height > maxh)
		height = maxh;
	if (width < 48)
		width = 48;
	if (width > maxw)
		width = maxw;

	if ((hscale = (((unsigned long)maxw) << 12) / width - 4096L) >= 0x4000)
		hscale = 0x3fff;
	width = (((unsigned long)maxw) << 12) / (hscale + 4096L);

	if ((vscale = (((unsigned long)maxh) << 12) / height - 4096L) >= 0x4000)
		vscale = 0x3fff;
	height = (((unsigned long)maxh) << 12) / (vscale + 4096L);

	/* set new image size */
	dev->width = width;
	dev->height = height;
	dev->frame_size = dev->width * dev->height * 2;
	dev->field_size = dev->frame_size >> 1;	/*both_fileds ? dev->frame_size>>1 : dev->frame_size; */
	dev->bytesperline = dev->width * 2;
	dev->hscale = hscale;
	dev->vscale = vscale;

	em2820_resolution_set(dev);

	return 0;
}

static void video_mux(struct em2820 *dev, int index)
{
	int input, ainput;

	input = INPUT(index)->vmux;
	dev->ctl_input = index;

	em2820_i2c_call_clients(dev, DECODER_SET_INPUT, &input);

	dev->ctl_ainput = INPUT(index)->amux;

	switch (dev->ctl_ainput) {
	case 0:
		ainput = EM2820_AUDIO_SRC_TUNER;
		break;
	default:
		ainput = EM2820_AUDIO_SRC_LINE;
	}

	em2820_audio_source(dev, ainput);
}

/*
 * em2820_v4l2_do_ioctl()
 * This function is _not_ called directly, but from
 * em2820_v4l2_ioctl. Userspace
 * copying is done already, arg is a kernel pointer.
 */
static int em2820_do_ioctl(struct inode *inode, struct file *filp,
			   struct em2820 *dev, unsigned int cmd, void *arg,
			   v4l2_kioctl driver_ioctl)
{
	int ret;

	switch (cmd) {
		/* ---------- tv norms ---------- */
	case VIDIOC_ENUMSTD:
		{
			struct v4l2_standard *e = arg;
			unsigned int i;

			i = e->index;
			if (i >= TVNORMS)
				return -EINVAL;
			ret = v4l2_video_std_construct(e, tvnorms[e->index].id,
						       tvnorms[e->index].name);
			e->index = i;
			if (ret < 0)
				return ret;
			return 0;
		}
	case VIDIOC_G_STD:
		{
			v4l2_std_id *id = arg;

			*id = dev->tvnorm->id;
			return 0;
		}
	case VIDIOC_S_STD:
		{
			v4l2_std_id *id = arg;
			unsigned int i;

			for (i = 0; i < TVNORMS; i++)
				if (*id == tvnorms[i].id)
					break;
			if (i == TVNORMS)
				for (i = 0; i < TVNORMS; i++)
					if (*id & tvnorms[i].id)
						break;
			if (i == TVNORMS)
				return -EINVAL;

			down(&dev->lock);
			dev->tvnorm = &tvnorms[i];

			em2820_set_norm(dev, dev->width, dev->height);

/*
		dev->width=norm_maxw(dev);
		dev->height=norm_maxh(dev);
		dev->frame_size=dev->width*dev->height*2;
		dev->field_size=dev->frame_size>>1;
		dev->bytesperline=dev->width*2;
		dev->hscale=0;
		dev->vscale=0;

		em2820_resolution_set(dev);
*/
/*
		em2820_uninit_isoc(dev);
		em2820_set_alternate(dev);
		em2820_capture_start(dev, 1);
		em2820_resolution_set(dev);
		em2820_init_isoc(dev);
*/
			em2820_i2c_call_clients(dev, DECODER_SET_NORM,
						&tvnorms[i].mode);
			em2820_i2c_call_clients(dev, VIDIOC_S_STD,
						&dev->tvnorm->id);

			up(&dev->lock);

			return 0;
		}

		/* ------ input switching ---------- */
	case VIDIOC_ENUMINPUT:
		{
			struct v4l2_input *i = arg;
			unsigned int n;
			static const char *iname[] = {
				[EM2820_VMUX_COMPOSITE1] = "Composite1",
				[EM2820_VMUX_COMPOSITE2] = "Composite2",
				[EM2820_VMUX_COMPOSITE3] = "Composite3",
				[EM2820_VMUX_COMPOSITE4] = "Composite4",
				[EM2820_VMUX_SVIDEO] = "S-Video",
				[EM2820_VMUX_TELEVISION] = "Television",
				[EM2820_VMUX_CABLE] = "Cable TV",
				[EM2820_VMUX_DVB] = "DVB",
				[EM2820_VMUX_DEBUG] = "for debug only",
			};

			n = i->index;
			if (n >= MAX_EM2820_INPUT)
				return -EINVAL;
			if (0 == INPUT(n)->type)
				return -EINVAL;
			memset(i, 0, sizeof(*i));
			i->index = n;
			i->type = V4L2_INPUT_TYPE_CAMERA;
			strcpy(i->name, iname[INPUT(n)->type]);
			if ((EM2820_VMUX_TELEVISION == INPUT(n)->type) ||
			    (EM2820_VMUX_CABLE == INPUT(n)->type))
				i->type = V4L2_INPUT_TYPE_TUNER;
			for (n = 0; n < ARRAY_SIZE(tvnorms); n++)
				i->std |= tvnorms[n].id;
			return 0;
		}

	case VIDIOC_G_INPUT:
		{
			int *i = arg;
			*i = dev->ctl_input;

			return 0;
		}

	case VIDIOC_S_INPUT:
		{
			int *index = arg;

			if (*index >= MAX_EM2820_INPUT)
				return -EINVAL;
			if (0 == INPUT(*index)->type)
				return -EINVAL;

			down(&dev->lock);
			video_mux(dev, *index);
			up(&dev->lock);

			return 0;
		}

	case VIDIOC_G_AUDIO:
		{
			struct v4l2_audio *a = arg;
			unsigned int index = a->index;

			if (a->index > 1)
				return -EINVAL;
			memset(a, 0, sizeof(*a));
			index = dev->ctl_ainput;

			if (index == 0) {
				strcpy(a->name, "Television");
			} else {
				strcpy(a->name, "Line In");
			}
			a->capability = V4L2_AUDCAP_STEREO;
			a->index = index;
			return 0;
		}

	case VIDIOC_S_AUDIO:
		{
			struct v4l2_audio *a = arg;
			if (a->index != dev->ctl_ainput)
				return -EINVAL;

			return 0;
		}

		/* --- controls ---------------------------------------------- */
	case VIDIOC_QUERYCTRL:
		{
			struct v4l2_queryctrl *qc = arg;
			u8 i, n;
			n = sizeof(em2820_qctrl) / sizeof(em2820_qctrl[0]);
			for (i = 0; i < n; i++)
				if (qc->id && qc->id == em2820_qctrl[i].id) {
					memcpy(qc, &(em2820_qctrl[i]),
					       sizeof(*qc));
					return 0;
				}

			return -EINVAL;
		}

	case VIDIOC_G_CTRL:
		{
			struct v4l2_control *ctrl = arg;


			return em2820_get_ctrl(dev, ctrl);
		}

	case VIDIOC_S_CTRL_OLD:	/* ??? */
	case VIDIOC_S_CTRL:
		{
			struct v4l2_control *ctrl = arg;
			u8 i, n;


			n = sizeof(em2820_qctrl) / sizeof(em2820_qctrl[0]);
			for (i = 0; i < n; i++)
				if (ctrl->id == em2820_qctrl[i].id) {
					if (ctrl->value <
					    em2820_qctrl[i].minimum
					    || ctrl->value >
					    em2820_qctrl[i].maximum)
						return -ERANGE;

					return em2820_set_ctrl(dev, ctrl);
				}
			return -EINVAL;
		}

		/* --- tuner ioctls ------------------------------------------ */
	case VIDIOC_G_TUNER:
		{
			struct v4l2_tuner *t = arg;
			int status = 0;

			if (0 != t->index)
				return -EINVAL;

			memset(t, 0, sizeof(*t));
			strcpy(t->name, "Tuner");
			t->type = V4L2_TUNER_ANALOG_TV;
			t->capability = V4L2_TUNER_CAP_NORM;
			t->rangehigh = 0xffffffffUL;	/* FIXME: set correct range */
/*		t->signal = 0xffff;*/
/*		em2820_i2c_call_clients(dev,VIDIOC_G_TUNER,t);*/
			/* No way to get signal strength? */
			down(&dev->lock);
			em2820_i2c_call_clients(dev, DECODER_GET_STATUS,
						&status);
			up(&dev->lock);
			t->signal =
			    (status & DECODER_STATUS_GOOD) != 0 ? 0xffff : 0;

			em2820_videodbg("VIDIO_G_TUNER: signal=%x, afc=%x", t->signal,
				 t->afc);
			return 0;
		}
	case VIDIOC_S_TUNER:
		{
			struct v4l2_tuner *t = arg;
			int status = 0;

			if (0 != t->index)
				return -EINVAL;
			memset(t, 0, sizeof(*t));
			strcpy(t->name, "Tuner");
			t->type = V4L2_TUNER_ANALOG_TV;
			t->capability = V4L2_TUNER_CAP_NORM;
			t->rangehigh = 0xffffffffUL;	/* FIXME: set correct range */
/*		t->signal = 0xffff; */
			/* No way to get signal strength? */
			down(&dev->lock);
			em2820_i2c_call_clients(dev, DECODER_GET_STATUS,
						&status);
			up(&dev->lock);
			t->signal =
			    (status & DECODER_STATUS_GOOD) != 0 ? 0xffff : 0;

			em2820_videodbg("VIDIO_S_TUNER: signal=%x, afc=%x\n",
				 t->signal, t->afc);
			return 0;
		}
	case VIDIOC_G_FREQUENCY:
		{
			struct v4l2_frequency *f = arg;

			memset(f, 0, sizeof(*f));
			f->type = V4L2_TUNER_ANALOG_TV;
			f->frequency = dev->ctl_freq;

			return 0;
		}
	case VIDIOC_S_FREQUENCY:
		{
			struct v4l2_frequency *f = arg;

			if (0 != f->tuner)
				return -EINVAL;

			if (V4L2_TUNER_ANALOG_TV != f->type)
				return -EINVAL;

			down(&dev->lock);
			dev->ctl_freq = f->frequency;
			em2820_i2c_call_clients(dev, VIDIOC_S_FREQUENCY, f);
			up(&dev->lock);
			return 0;
		}

	case VIDIOC_CROPCAP:
		{
			struct v4l2_cropcap *cc = arg;

			if (cc->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
				return EINVAL;
			cc->bounds.left = 0;
			cc->bounds.top = 0;
			cc->bounds.width = dev->width;
			cc->bounds.height = dev->height;
			cc->defrect = cc->bounds;
			cc->pixelaspect.numerator = 54;	/* 4:3 FIXME: remove magic numbers */
			cc->pixelaspect.denominator = 59;
			return 0;
		}
	case VIDIOC_STREAMON:
		{
			int *type = arg;

			if (*type != V4L2_BUF_TYPE_VIDEO_CAPTURE
			    || dev->io != IO_MMAP)
				return -EINVAL;

			if (list_empty(&dev->inqueue))
				return -EINVAL;

			dev->stream = STREAM_ON;	/* FIXME: Start video capture here? */

			em2820_videodbg("VIDIOC_STREAMON: starting stream");

			return 0;
		}
	case VIDIOC_STREAMOFF:
		{
			int *type = arg;
			int ret;

			if (*type != V4L2_BUF_TYPE_VIDEO_CAPTURE
			    || dev->io != IO_MMAP)
				return -EINVAL;

			if (dev->stream == STREAM_ON) {
				em2820_videodbg ("VIDIOC_STREAMOFF: interrupting stream");
				if ((ret = em2820_stream_interrupt(dev)))
					return ret;
			}
			em2820_empty_framequeues(dev);

			return 0;
		}
	default:
		return v4l_compat_translate_ioctl(inode, filp, cmd, arg,
						  driver_ioctl);
	}
	return 0;
}

/*
 * em2820_v4l2_do_ioctl()
 * This function is _not_ called directly, but from
 * em2820_v4l2_ioctl. Userspace
 * copying is done already, arg is a kernel pointer.
 */
static int em2820_video_do_ioctl(struct inode *inode, struct file *filp,
				 unsigned int cmd, void *arg)
{
	struct em2820 *dev = filp->private_data;

	if (!dev)
		return -ENODEV;

	if (video_debug > 1)
		em2820_print_ioctl(dev->name,cmd);

	switch (cmd) {

		/* --- capabilities ------------------------------------------ */
	case VIDIOC_QUERYCAP:
		{
			struct v4l2_capability *cap = arg;

			memset(cap, 0, sizeof(*cap));
			strlcpy(cap->driver, "em2820", sizeof(cap->driver));
			strlcpy(cap->card, em2820_boards[dev->model].name,
				sizeof(cap->card));
			strlcpy(cap->bus_info, dev->udev->dev.bus_id,
				sizeof(cap->bus_info));
			cap->version = EM2820_VERSION_CODE;
			cap->capabilities =
			    V4L2_CAP_VIDEO_CAPTURE |
			    V4L2_CAP_AUDIO |
			    V4L2_CAP_READWRITE | V4L2_CAP_STREAMING;
			if (dev->has_tuner)
				cap->capabilities |= V4L2_CAP_TUNER;
			return 0;
		}

		/* --- capture ioctls ---------------------------------------- */
	case VIDIOC_ENUM_FMT:
		{
			struct v4l2_fmtdesc *fmtd = arg;

			if (fmtd->index != 0)
				return -EINVAL;
			memset(fmtd, 0, sizeof(*fmtd));
			fmtd->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
			strcpy(fmtd->description, "Packed YUY2");
			fmtd->pixelformat = V4L2_PIX_FMT_YUYV;
			memset(fmtd->reserved, 0, sizeof(fmtd->reserved));
			return 0;
		}

	case VIDIOC_G_FMT:
		{
			struct v4l2_format *format = arg;

			em2820_videodbg("VIDIOC_G_FMT: type=%s",
				 format->type ==
				 V4L2_BUF_TYPE_VIDEO_CAPTURE ?
				 "V4L2_BUF_TYPE_VIDEO_CAPTURE" : format->type ==
				 V4L2_BUF_TYPE_VBI_CAPTURE ?
				 "V4L2_BUF_TYPE_VBI_CAPTURE " :
				 "not supported");

			if (format->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
				return -EINVAL;

			format->fmt.pix.width = dev->width;
			format->fmt.pix.height = dev->height;
			format->fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;
			format->fmt.pix.bytesperline = dev->bytesperline;
			format->fmt.pix.sizeimage = dev->frame_size;
			format->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
			format->fmt.pix.field = dev->interlaced ? V4L2_FIELD_INTERLACED : V4L2_FIELD_TOP;	/* FIXME: TOP? NONE? BOTTOM? ALTENATE? */

			em2820_videodbg("VIDIOC_G_FMT: %dx%d", dev->width,
				 dev->height);
			return 0;
		}

	case VIDIOC_TRY_FMT:
	case VIDIOC_S_FMT:
		{
			struct v4l2_format *format = arg;
			u32 i;
			int ret = 0;
			int width = format->fmt.pix.width;
			int height = format->fmt.pix.height;
			unsigned int hscale, vscale;
			unsigned int maxh, maxw;

			maxw = norm_maxw(dev);
			maxh = norm_maxh(dev);

/*		int both_fields; */

			em2820_videodbg("%s: type=%s",
				 cmd ==
				 VIDIOC_TRY_FMT ? "VIDIOC_TRY_FMT" :
				 "VIDIOC_S_FMT",
				 format->type ==
				 V4L2_BUF_TYPE_VIDEO_CAPTURE ?
				 "V4L2_BUF_TYPE_VIDEO_CAPTURE" : format->type ==
				 V4L2_BUF_TYPE_VBI_CAPTURE ?
				 "V4L2_BUF_TYPE_VBI_CAPTURE " :
				 "not supported");

			if (format->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
				return -EINVAL;

			em2820_videodbg("%s: requested %dx%d",
				 cmd ==
				 VIDIOC_TRY_FMT ? "VIDIOC_TRY_FMT" :
				 "VIDIOC_S_FMT", format->fmt.pix.width,
				 format->fmt.pix.height);

			/* FIXME: Move some code away from here */
			/* width must even because of the YUYV format */
			/* height must be even because of interlacing */
			height &= 0xfffe;
			width &= 0xfffe;

			if (height < 32)
				height = 32;
			if (height > maxh)
				height = maxh;
			if (width < 48)
				width = 48;
			if (width > maxw)
				width = maxw;

			if ((hscale =
			     (((unsigned long)maxw) << 12) / width - 4096L) >=
			    0x4000)
				hscale = 0x3fff;
			width =
			    (((unsigned long)maxw) << 12) / (hscale + 4096L);

			if ((vscale =
			     (((unsigned long)maxh) << 12) / height - 4096L) >=
			    0x4000)
				vscale = 0x3fff;
			height =
			    (((unsigned long)maxh) << 12) / (vscale + 4096L);

			format->fmt.pix.width = width;
			format->fmt.pix.height = height;
			format->fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;
			format->fmt.pix.bytesperline = width * 2;
			format->fmt.pix.sizeimage = width * 2 * height;
			format->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
			format->fmt.pix.field = V4L2_FIELD_INTERLACED;

			em2820_videodbg("%s: returned %dx%d (%d, %d)",
				 cmd ==
				 VIDIOC_TRY_FMT ? "VIDIOC_TRY_FMT" :
				 "VIDIOC_S_FMT", format->fmt.pix.width,
				 format->fmt.pix.height, hscale, vscale);

			if (cmd == VIDIOC_TRY_FMT)
				return 0;

			for (i = 0; i < dev->num_frames; i++)
				if (dev->frame[i].vma_use_count) {
					em2820_videodbg("VIDIOC_S_FMT failed. "
						"Unmap the buffers first.");
					return -EINVAL;
				}

			/* stop io in case it is already in progress */
			if (dev->stream == STREAM_ON) {
				em2820_videodbg("VIDIOC_SET_FMT: interupting stream");
				if ((ret = em2820_stream_interrupt(dev)))
					return ret;
			}

			em2820_release_buffers(dev);
			dev->io = IO_NONE;

			/* set new image size */
			dev->width = width;
			dev->height = height;
			dev->frame_size = dev->width * dev->height * 2;
			dev->field_size = dev->frame_size >> 1;	/*both_fileds ? dev->frame_size>>1 : dev->frame_size; */
			dev->bytesperline = dev->width * 2;
			dev->hscale = hscale;
			dev->vscale = vscale;
/*			dev->both_fileds = both_fileds; */
			em2820_uninit_isoc(dev);
			em2820_set_alternate(dev);
			em2820_capture_start(dev, 1);
			em2820_resolution_set(dev);
			em2820_init_isoc(dev);

			return 0;
		}

		/* --- streaming capture ------------------------------------- */
	case VIDIOC_REQBUFS:
		{
			struct v4l2_requestbuffers *rb = arg;
			u32 i;
			int ret;

			if (rb->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
			    rb->memory != V4L2_MEMORY_MMAP)
				return -EINVAL;

			if (dev->io == IO_READ) {
				em2820_videodbg ("method is set to read;"
					" close and open the device again to"
					" choose the mmap I/O method");
				return -EINVAL;
			}

			for (i = 0; i < dev->num_frames; i++)
				if (dev->frame[i].vma_use_count) {
					em2820_videodbg ("VIDIOC_REQBUFS failed; previous buffers are still mapped");
					return -EINVAL;
				}

			if (dev->stream == STREAM_ON) {
				em2820_videodbg("VIDIOC_REQBUFS: interrupting stream");
				if ((ret = em2820_stream_interrupt(dev)))
					return ret;
			}

			em2820_empty_framequeues(dev);

			em2820_release_buffers(dev);
			if (rb->count)
				rb->count =
				    em2820_request_buffers(dev, rb->count);

			dev->frame_current = NULL;

			em2820_videodbg ("VIDIOC_REQBUFS: setting io method to mmap: num bufs %i",
						     rb->count);
			dev->io = rb->count ? IO_MMAP : IO_NONE;
			return 0;
		}

	case VIDIOC_QUERYBUF:
		{
			struct v4l2_buffer *b = arg;

			if (b->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
			    b->index >= dev->num_frames || dev->io != IO_MMAP)
				return -EINVAL;

			memcpy(b, &dev->frame[b->index].buf, sizeof(*b));

			if (dev->frame[b->index].vma_use_count) {
				b->flags |= V4L2_BUF_FLAG_MAPPED;
			}
			if (dev->frame[b->index].state == F_DONE)
				b->flags |= V4L2_BUF_FLAG_DONE;
			else if (dev->frame[b->index].state != F_UNUSED)
				b->flags |= V4L2_BUF_FLAG_QUEUED;
			return 0;
		}
	case VIDIOC_QBUF:
		{
			struct v4l2_buffer *b = arg;
			unsigned long lock_flags;

			if (b->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
			    b->index >= dev->num_frames || dev->io != IO_MMAP) {
				return -EINVAL;
			}

			if (dev->frame[b->index].state != F_UNUSED) {
				return -EAGAIN;
			}
			dev->frame[b->index].state = F_QUEUED;

			/* add frame to fifo */
			spin_lock_irqsave(&dev->queue_lock, lock_flags);
			list_add_tail(&dev->frame[b->index].frame,
				      &dev->inqueue);
			spin_unlock_irqrestore(&dev->queue_lock, lock_flags);

			return 0;
		}
	case VIDIOC_DQBUF:
		{
			struct v4l2_buffer *b = arg;
			struct em2820_frame_t *f;
			unsigned long lock_flags;
			int ret = 0;

			if (b->type != V4L2_BUF_TYPE_VIDEO_CAPTURE
			    || dev->io != IO_MMAP)
				return -EINVAL;

			if (list_empty(&dev->outqueue)) {
				if (dev->stream == STREAM_OFF)
					return -EINVAL;
				if (filp->f_flags & O_NONBLOCK)
					return -EAGAIN;
				ret = wait_event_interruptible
				    (dev->wait_frame,
				     (!list_empty(&dev->outqueue)) ||
				     (dev->state & DEV_DISCONNECTED));
				if (ret)
					return ret;
				if (dev->state & DEV_DISCONNECTED)
					return -ENODEV;
			}

			spin_lock_irqsave(&dev->queue_lock, lock_flags);
			f = list_entry(dev->outqueue.next,
				       struct em2820_frame_t, frame);
			list_del(dev->outqueue.next);
			spin_unlock_irqrestore(&dev->queue_lock, lock_flags);

			f->state = F_UNUSED;
			memcpy(b, &f->buf, sizeof(*b));

			if (f->vma_use_count)
				b->flags |= V4L2_BUF_FLAG_MAPPED;

			return 0;
		}
	default:
		return em2820_do_ioctl(inode, filp, dev, cmd, arg,
				       em2820_video_do_ioctl);
	}
	return 0;
}

/*
 * em2820_v4l2_ioctl()
 * handle v4l2 ioctl the main action happens in em2820_v4l2_do_ioctl()
 */
static int em2820_v4l2_ioctl(struct inode *inode, struct file *filp,
			     unsigned int cmd, unsigned long arg)
{
	struct em2820 *dev = video_get_drvdata(video_devdata(filp));
	int ret = 0;

	if (down_interruptible(&dev->fileop_lock))
		return -ERESTARTSYS;

	if (dev->state & DEV_DISCONNECTED) {
		em2820_errdev("v4l2 ioctl: device not present\n");
		up(&dev->fileop_lock);
		return -ENODEV;
	}

	if (dev->state & DEV_MISCONFIGURED) {
		em2820_errdev
		    ("v4l2 ioctl: device is misconfigured; close and open it again\n");
		up(&dev->fileop_lock);
		return -EIO;
	}

	ret = video_usercopy(inode, filp, cmd, arg, em2820_video_do_ioctl);

	up(&dev->fileop_lock);

	return ret;
}

static struct file_operations em2820_v4l_fops = {
	.owner = THIS_MODULE,
	.open = em2820_v4l2_open,
	.release = em2820_v4l2_close,
	.ioctl = em2820_v4l2_ioctl,
	.read = em2820_v4l2_read,
	.poll = em2820_v4l2_poll,
	.mmap = em2820_v4l2_mmap,
	.llseek = no_llseek,
};

/******************************** usb interface *****************************************/

/*
 * em2820_init_dev()
 * allocates and inits the device structs, registers i2c bus and v4l device
 */
static int em2820_init_dev(struct em2820 **devhandle, struct usb_device *udev,
			   int minor, int model)
{
	struct em2820 *dev;
	int retval = -ENOMEM;
	int errCode, i;
	unsigned int maxh, maxw;
	struct usb_interface *uif;

	/* allocate memory for our device state and initialize it */
	dev = kmalloc(sizeof(*dev), GFP_KERNEL);
	if (dev == NULL) {
		em2820_err(DRIVER_NAME ": out of memory!\n");
		return -ENOMEM;
	}
	memset(dev, 0x00, sizeof(*dev));

	snprintf(dev->name, 29, "em2820 #%d", minor);
	dev->udev = udev;
	dev->model = model;
	init_MUTEX(&dev->lock);
	init_waitqueue_head(&dev->open);

	dev->em2820_write_regs = em2820_write_regs;
	dev->em2820_read_reg = em2820_read_reg;
	dev->em2820_read_reg_req_len = em2820_read_reg_req_len;
	dev->em2820_write_regs_req = em2820_write_regs_req;
	dev->em2820_read_reg_req = em2820_read_reg_req;
	dev->has_tuner = em2820_boards[model].has_tuner;
	dev->has_msp34xx = em2820_boards[model].has_msp34xx;
	dev->tda9887_conf = em2820_boards[model].tda9887_conf;
	dev->decoder = em2820_boards[model].decoder;

	if (tuner >= 0)
		dev->tuner_type = tuner;
	else
		dev->tuner_type = em2820_boards[model].tuner_type;

	dev->video_inputs = em2820_boards[model].vchannels;

	for (i = 0; i < TVNORMS; i++)
		if (em2820_boards[model].norm == tvnorms[i].mode)
			break;
	if (i == TVNORMS)
		i = 0;

	dev->tvnorm = &tvnorms[i];	/* set default norm */

	em2820_videodbg("tvnorm=%s\n", dev->tvnorm->name);

	maxw = norm_maxw(dev);
	maxh = norm_maxh(dev);

	/* set default image size */
	dev->width = maxw;
	dev->height = maxh;
	dev->interlaced = EM2820_INTERLACED_DEFAULT;
	dev->field_size = dev->width * dev->height;
	dev->frame_size =
	    dev->interlaced ? dev->field_size << 1 : dev->field_size;
	dev->bytesperline = dev->width * 2;
	dev->hscale = 0;
	dev->vscale = 0;
	dev->ctl_input = 2;

	/* setup video picture settings for saa7113h */
	memset(&dev->vpic, 0, sizeof(dev->vpic));
	dev->vpic.colour = 128 << 8;
	dev->vpic.hue = 128 << 8;
	dev->vpic.brightness = 128 << 8;
	dev->vpic.contrast = 192 << 8;
	dev->vpic.whiteness = 128 << 8;	/* This one isn't used */
	dev->vpic.depth = 16;
	dev->vpic.palette = VIDEO_PALETTE_YUV422;

	/* compute alternate max packet sizes */
	uif = dev->udev->actconfig->interface[0];
	dev->alt_max_pkt_size[0] = 0;
	for (i = 1; i <= EM2820_MAX_ALT; i++) {
		u16 tmp =
		    le16_to_cpu(uif->altsetting[i].endpoint[1].desc.
				wMaxPacketSize);
		dev->alt_max_pkt_size[i] =
		    (tmp & 0x07ff) * (((tmp & 0x1800) >> 11) + 1);
	}

#ifdef CONFIG_MODULES
	/* request some modules */
	if (dev->decoder == EM2820_SAA7113)
		request_module("saa7113");
	if (dev->decoder == EM2820_SAA7114)
		request_module("saa7114");
	if (dev->decoder == EM2820_TVP5150)
		request_module("tvp5150");
	if (dev->has_tuner)
		request_module("tuner");
	if (dev->tda9887_conf)
		request_module("tda9887");
#endif
	errCode = em2820_config(dev);
	if (errCode) {
		em2820_errdev("error configuring device\n");
		kfree(dev);
		return -ENOMEM;
	}

	down(&dev->lock);
	/* register i2c bus */
	em2820_i2c_register(dev);

	/* Do board specific init and eeprom reading */
	em2820_card_setup(dev);

	/* configure the device */
	em2820_config_i2c(dev);

	up(&dev->lock);

	errCode = em2820_config(dev);

#ifdef CONFIG_MODULES
	if (dev->has_msp34xx)
		request_module("msp3400");
#endif
	/* allocate and fill v4l2 device struct */
	dev->vdev = video_device_alloc();
	if (NULL == dev->vdev) {
		em2820_errdev("cannot allocate video_device.\n");
		kfree(dev);
		return -ENOMEM;
	}

	dev->vdev->owner = THIS_MODULE;
	dev->vdev->type = VID_TYPE_CAPTURE;
	if (dev->has_tuner)
		dev->vdev->type |= VID_TYPE_TUNER;
	dev->vdev->hardware = 0;
	dev->vdev->fops = &em2820_v4l_fops;
	dev->vdev->minor = -1;
	dev->vdev->dev = &dev->udev->dev;
	dev->vdev->release = video_device_release;
	snprintf(dev->vdev->name, sizeof(dev->vdev->name), "%s",
		 "em2820 video");
	video_set_drvdata(dev->vdev, dev);

	/* register v4l2 device */
	down(&dev->lock);
	if ((retval = video_register_device(dev->vdev, VFL_TYPE_GRABBER, -1))) {
		em2820_errdev("unable to register video device (error=%i).\n",
			      retval);
		up(&dev->lock);
		video_set_drvdata(dev->vdev, NULL);
		video_device_release(dev->vdev);
		kfree(dev);
		return -ENODEV;
	}
	if (dev->has_msp34xx) {
		/* Send a reset to other chips via gpio */
		em2820_write_regs_req(dev, 0x00, 0x08, "\xf7", 1);
		udelay(2500);
		em2820_write_regs_req(dev, 0x00, 0x08, "\xff", 1);
		udelay(2500);

	}
	video_mux(dev, 0);

	up(&dev->lock);

	em2820_info("V4L2 device registered as /dev/video%d\n",
		    dev->vdev->minor);

	*devhandle = dev;
	return 0;
}

/*
 * em2820_usb_probe()
 * checks for supported devices
 */
static int em2820_usb_probe(struct usb_interface *interface,
			    const struct usb_device_id *id)
{
	const struct usb_endpoint_descriptor *endpoint;
	struct usb_device *udev;
	struct em2820 *dev = NULL;
	int retval = -ENODEV;

	udev = usb_get_dev(interface_to_usbdev(interface));
	endpoint = &interface->cur_altsetting->endpoint[1].desc;

	/* check if the the device has the iso in endpoint at the correct place */
	if ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) !=
	    USB_ENDPOINT_XFER_ISOC) {
/*		em2820_err(DRIVER_NAME " probing error: endpoint is non-ISO endpoint!\n"); */
		return -ENODEV;
	}
	if ((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT) {
/*		em2820_err(DRIVER_NAME " probing error: endpoint is ISO OUT endpoint!\n"); */
		return -ENODEV;
	}

	/* allocate device struct */
	retval = em2820_init_dev(&dev, udev, interface->minor, id->driver_info);
	if (retval)
		return retval;

	em2820_info("Found %s\n", em2820_boards[id->driver_info].name);

	/* save our data pointer in this interface device */
	usb_set_intfdata(interface, dev);
	return 0;
}

/*
 * em2820_usb_disconnect()
 * called when the device gets diconencted
 * video device will be unregistered on v4l2_close in case it is still open
 */
static void em2820_usb_disconnect(struct usb_interface *interface)
{
	struct em2820 *dev = usb_get_intfdata(interface);
	usb_set_intfdata(interface, NULL);

	if (!dev)
		return;

	down_write(&em2820_disconnect);

	down(&dev->lock);

	em2820_info("disconnecting %s\n", dev->vdev->name);

	wake_up_interruptible_all(&dev->open);

	if (dev->users) {
		em2820_warn
		    ("device /dev/video%d is open! Deregistration and memory "
		     "deallocation are deferred on close.\n", dev->vdev->minor);
		dev->state |= DEV_MISCONFIGURED;
		em2820_uninit_isoc(dev);
		dev->state |= DEV_DISCONNECTED;
		wake_up_interruptible(&dev->wait_frame);
		wake_up_interruptible(&dev->wait_stream);
	} else {
		dev->state |= DEV_DISCONNECTED;
		em2820_release_resources(dev);
	}

	up(&dev->lock);

	if (!dev->users)
		kfree(dev);

	up_write(&em2820_disconnect);

}

static struct usb_driver em2820_usb_driver = {
	.owner = THIS_MODULE,
	.name = "em2820",
	.probe = em2820_usb_probe,
	.disconnect = em2820_usb_disconnect,
	.id_table = em2820_id_table,
};

static int __init em2820_module_init(void)
{
	int result;

	printk(KERN_INFO DRIVER_NAME " v4l2 driver version %d.%d.%d loaded\n",
	       (EM2820_VERSION_CODE >> 16) & 0xff,
	       (EM2820_VERSION_CODE >> 8) & 0xff, EM2820_VERSION_CODE & 0xff);
#ifdef SNAPSHOT
	printk(KERN_INFO DRIVER_NAME " snapshot date %04d-%02d-%02d\n",
	       SNAPSHOT / 10000, (SNAPSHOT / 100) % 100, SNAPSHOT % 100);
#endif

	/* register this driver with the USB subsystem */
	result = usb_register(&em2820_usb_driver);
	if (result)
		em2820_err(DRIVER_NAME
			   " usb_register failed. Error number %d.\n", result);

	return result;
}

static void __exit em2820_module_exit(void)
{
	/* deregister this driver with the USB subsystem */
	usb_deregister(&em2820_usb_driver);
}

module_init(em2820_module_init);
module_exit(em2820_module_exit);
