/*
 * Hauppauge HD PVR USB driver - video 4 linux 2 interface
 *
 * Copyright (C) 2008      Janne Grunau (j@jannau.net)
 *
 *	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, version 2.
 *
 */

#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/uaccess.h>
#include <linux/usb.h>
#include <linux/mutex.h>
#include <linux/workqueue.h>

#include <linux/videodev2.h>
#include <linux/v4l2-dv-timings.h>
#include <media/v4l2-dev.h>
#include <media/v4l2-common.h>
#include <media/v4l2-dv-timings.h>
#include <media/v4l2-ioctl.h>
#include <media/v4l2-event.h>
#include "hdpvr.h"

#define BULK_URB_TIMEOUT   90 /* 0.09 seconds */

#define print_buffer_status() { \
		v4l2_dbg(MSG_BUFFER, hdpvr_debug, &dev->v4l2_dev,	\
			 "%s:%d buffer stat: %d free, %d proc\n",	\
			 __func__, __LINE__,				\
			 list_size(&dev->free_buff_list),		\
			 list_size(&dev->rec_buff_list)); }

static const struct v4l2_dv_timings hdpvr_dv_timings[] = {
	V4L2_DV_BT_CEA_720X480I59_94,
	V4L2_DV_BT_CEA_720X576I50,
	V4L2_DV_BT_CEA_720X480P59_94,
	V4L2_DV_BT_CEA_720X576P50,
	V4L2_DV_BT_CEA_1280X720P50,
	V4L2_DV_BT_CEA_1280X720P60,
	V4L2_DV_BT_CEA_1920X1080I50,
	V4L2_DV_BT_CEA_1920X1080I60,
};

/* Use 480i59 as the default timings */
#define HDPVR_DEF_DV_TIMINGS_IDX (0)

struct hdpvr_fh {
	struct v4l2_fh fh;
	bool legacy_mode;
};

static uint list_size(struct list_head *list)
{
	struct list_head *tmp;
	uint count = 0;

	list_for_each(tmp, list) {
		count++;
	}

	return count;
}

/*=========================================================================*/
/* urb callback */
static void hdpvr_read_bulk_callback(struct urb *urb)
{
	struct hdpvr_buffer *buf = (struct hdpvr_buffer *)urb->context;
	struct hdpvr_device *dev = buf->dev;

	/* marking buffer as received and wake waiting */
	buf->status = BUFSTAT_READY;
	wake_up_interruptible(&dev->wait_data);
}

/*=========================================================================*/
/* buffer bits */

/* function expects dev->io_mutex to be hold by caller */
int hdpvr_cancel_queue(struct hdpvr_device *dev)
{
	struct hdpvr_buffer *buf;

	list_for_each_entry(buf, &dev->rec_buff_list, buff_list) {
		usb_kill_urb(buf->urb);
		buf->status = BUFSTAT_AVAILABLE;
	}

	list_splice_init(&dev->rec_buff_list, dev->free_buff_list.prev);

	return 0;
}

static int hdpvr_free_queue(struct list_head *q)
{
	struct list_head *tmp;
	struct list_head *p;
	struct hdpvr_buffer *buf;
	struct urb *urb;

	for (p = q->next; p != q;) {
		buf = list_entry(p, struct hdpvr_buffer, buff_list);

		urb = buf->urb;
		usb_free_coherent(urb->dev, urb->transfer_buffer_length,
				  urb->transfer_buffer, urb->transfer_dma);
		usb_free_urb(urb);
		tmp = p->next;
		list_del(p);
		kfree(buf);
		p = tmp;
	}

	return 0;
}

/* function expects dev->io_mutex to be hold by caller */
int hdpvr_free_buffers(struct hdpvr_device *dev)
{
	hdpvr_cancel_queue(dev);

	hdpvr_free_queue(&dev->free_buff_list);
	hdpvr_free_queue(&dev->rec_buff_list);

	return 0;
}

/* function expects dev->io_mutex to be hold by caller */
int hdpvr_alloc_buffers(struct hdpvr_device *dev, uint count)
{
	uint i;
	int retval = -ENOMEM;
	u8 *mem;
	struct hdpvr_buffer *buf;
	struct urb *urb;

	v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev,
		 "allocating %u buffers\n", count);

	for (i = 0; i < count; i++) {

		buf = kzalloc(sizeof(struct hdpvr_buffer), GFP_KERNEL);
		if (!buf) {
			v4l2_err(&dev->v4l2_dev, "cannot allocate buffer\n");
			goto exit;
		}
		buf->dev = dev;

		urb = usb_alloc_urb(0, GFP_KERNEL);
		if (!urb)
			goto exit_urb;
		buf->urb = urb;

		mem = usb_alloc_coherent(dev->udev, dev->bulk_in_size, GFP_KERNEL,
					 &urb->transfer_dma);
		if (!mem) {
			v4l2_err(&dev->v4l2_dev,
				 "cannot allocate usb transfer buffer\n");
			goto exit_urb_buffer;
		}

		usb_fill_bulk_urb(buf->urb, dev->udev,
				  usb_rcvbulkpipe(dev->udev,
						  dev->bulk_in_endpointAddr),
				  mem, dev->bulk_in_size,
				  hdpvr_read_bulk_callback, buf);

		buf->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
		buf->status = BUFSTAT_AVAILABLE;
		list_add_tail(&buf->buff_list, &dev->free_buff_list);
	}
	return 0;
exit_urb_buffer:
	usb_free_urb(urb);
exit_urb:
	kfree(buf);
exit:
	hdpvr_free_buffers(dev);
	return retval;
}

static int hdpvr_submit_buffers(struct hdpvr_device *dev)
{
	struct hdpvr_buffer *buf;
	struct urb *urb;
	int ret = 0, err_count = 0;

	mutex_lock(&dev->io_mutex);

	while (dev->status == STATUS_STREAMING &&
	       !list_empty(&dev->free_buff_list)) {

		buf = list_entry(dev->free_buff_list.next, struct hdpvr_buffer,
				 buff_list);
		if (buf->status != BUFSTAT_AVAILABLE) {
			v4l2_err(&dev->v4l2_dev,
				 "buffer not marked as available\n");
			ret = -EFAULT;
			goto err;
		}

		urb = buf->urb;
		urb->status = 0;
		urb->actual_length = 0;
		ret = usb_submit_urb(urb, GFP_KERNEL);
		if (ret) {
			v4l2_err(&dev->v4l2_dev,
				 "usb_submit_urb in %s returned %d\n",
				 __func__, ret);
			if (++err_count > 2)
				break;
			continue;
		}
		buf->status = BUFSTAT_INPROGRESS;
		list_move_tail(&buf->buff_list, &dev->rec_buff_list);
	}
err:
	print_buffer_status();
	mutex_unlock(&dev->io_mutex);
	return ret;
}

static struct hdpvr_buffer *hdpvr_get_next_buffer(struct hdpvr_device *dev)
{
	struct hdpvr_buffer *buf;

	mutex_lock(&dev->io_mutex);

	if (list_empty(&dev->rec_buff_list)) {
		mutex_unlock(&dev->io_mutex);
		return NULL;
	}

	buf = list_entry(dev->rec_buff_list.next, struct hdpvr_buffer,
			 buff_list);
	mutex_unlock(&dev->io_mutex);

	return buf;
}

static void hdpvr_transmit_buffers(struct work_struct *work)
{
	struct hdpvr_device *dev = container_of(work, struct hdpvr_device,
						worker);

	while (dev->status == STATUS_STREAMING) {

		if (hdpvr_submit_buffers(dev)) {
			v4l2_err(&dev->v4l2_dev, "couldn't submit buffers\n");
			goto error;
		}
		if (wait_event_interruptible(dev->wait_buffer,
				!list_empty(&dev->free_buff_list) ||
					     dev->status != STATUS_STREAMING))
			goto error;
	}

	v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev,
		 "transmit worker exited\n");
	return;
error:
	v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev,
		 "transmit buffers errored\n");
	dev->status = STATUS_ERROR;
}

/* function expects dev->io_mutex to be hold by caller */
static int hdpvr_start_streaming(struct hdpvr_device *dev)
{
	int ret;
	struct hdpvr_video_info vidinf;

	if (dev->status == STATUS_STREAMING)
		return 0;
	if (dev->status != STATUS_IDLE)
		return -EAGAIN;

	ret = get_video_info(dev, &vidinf);
	if (ret < 0)
		return ret;

	if (!vidinf.valid) {
		msleep(250);
		v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev,
				"no video signal at input %d\n", dev->options.video_input);
		return -EAGAIN;
	}

	v4l2_dbg(MSG_BUFFER, hdpvr_debug, &dev->v4l2_dev,
			"video signal: %dx%d@%dhz\n", vidinf.width,
			vidinf.height, vidinf.fps);

	/* start streaming 2 request */
	ret = usb_control_msg(dev->udev,
			usb_sndctrlpipe(dev->udev, 0),
			0xb8, 0x38, 0x1, 0, NULL, 0, 8000);
	v4l2_dbg(MSG_BUFFER, hdpvr_debug, &dev->v4l2_dev,
			"encoder start control request returned %d\n", ret);
	if (ret < 0)
		return ret;

	ret = hdpvr_config_call(dev, CTRL_START_STREAMING_VALUE, 0x00);
	if (ret)
		return ret;

	dev->status = STATUS_STREAMING;

	INIT_WORK(&dev->worker, hdpvr_transmit_buffers);
	schedule_work(&dev->worker);

	v4l2_dbg(MSG_BUFFER, hdpvr_debug, &dev->v4l2_dev,
			"streaming started\n");

	return 0;
}


/* function expects dev->io_mutex to be hold by caller */
static int hdpvr_stop_streaming(struct hdpvr_device *dev)
{
	int actual_length;
	uint c = 0;
	u8 *buf;

	if (dev->status == STATUS_IDLE)
		return 0;
	else if (dev->status != STATUS_STREAMING)
		return -EAGAIN;

	buf = kmalloc(dev->bulk_in_size, GFP_KERNEL);
	if (!buf)
		v4l2_err(&dev->v4l2_dev, "failed to allocate temporary buffer for emptying the internal device buffer. Next capture start will be slow\n");

	dev->status = STATUS_SHUTTING_DOWN;
	hdpvr_config_call(dev, CTRL_STOP_STREAMING_VALUE, 0x00);
	mutex_unlock(&dev->io_mutex);

	wake_up_interruptible(&dev->wait_buffer);
	msleep(50);

	flush_work(&dev->worker);

	mutex_lock(&dev->io_mutex);
	/* kill the still outstanding urbs */
	hdpvr_cancel_queue(dev);

	/* emptying the device buffer beforeshutting it down */
	while (buf && ++c < 500 &&
	       !usb_bulk_msg(dev->udev,
			     usb_rcvbulkpipe(dev->udev,
					     dev->bulk_in_endpointAddr),
			     buf, dev->bulk_in_size, &actual_length,
			     BULK_URB_TIMEOUT)) {
		v4l2_dbg(MSG_BUFFER, hdpvr_debug, &dev->v4l2_dev,
			 "%2d: got %d bytes\n", c, actual_length);
	}
	kfree(buf);
	v4l2_dbg(MSG_BUFFER, hdpvr_debug, &dev->v4l2_dev,
		 "used %d urbs to empty device buffers\n", c-1);
	msleep(10);

	dev->status = STATUS_IDLE;

	return 0;
}


/*=======================================================================*/
/*
 * video 4 linux 2 file operations
 */

static int hdpvr_open(struct file *file)
{
	struct hdpvr_fh *fh = kzalloc(sizeof(*fh), GFP_KERNEL);

	if (fh == NULL)
		return -ENOMEM;
	fh->legacy_mode = true;
	v4l2_fh_init(&fh->fh, video_devdata(file));
	v4l2_fh_add(&fh->fh);
	file->private_data = fh;
	return 0;
}

static int hdpvr_release(struct file *file)
{
	struct hdpvr_device *dev = video_drvdata(file);

	mutex_lock(&dev->io_mutex);
	if (file->private_data == dev->owner) {
		hdpvr_stop_streaming(dev);
		dev->owner = NULL;
	}
	mutex_unlock(&dev->io_mutex);

	return v4l2_fh_release(file);
}

/*
 * hdpvr_v4l2_read()
 * will allocate buffers when called for the first time
 */
static ssize_t hdpvr_read(struct file *file, char __user *buffer, size_t count,
			  loff_t *pos)
{
	struct hdpvr_device *dev = video_drvdata(file);
	struct hdpvr_buffer *buf = NULL;
	struct urb *urb;
	unsigned int ret = 0;
	int rem, cnt;

	if (*pos)
		return -ESPIPE;

	mutex_lock(&dev->io_mutex);
	if (dev->status == STATUS_IDLE) {
		if (hdpvr_start_streaming(dev)) {
			v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev,
				 "start_streaming failed\n");
			ret = -EIO;
			msleep(200);
			dev->status = STATUS_IDLE;
			mutex_unlock(&dev->io_mutex);
			goto err;
		}
		dev->owner = file->private_data;
		print_buffer_status();
	}
	mutex_unlock(&dev->io_mutex);

	/* wait for the first buffer */
	if (!(file->f_flags & O_NONBLOCK)) {
		if (wait_event_interruptible(dev->wait_data,
					     !list_empty_careful(&dev->rec_buff_list)))
			return -ERESTARTSYS;
	}

	buf = hdpvr_get_next_buffer(dev);

	while (count > 0 && buf) {

		if (buf->status != BUFSTAT_READY &&
		    dev->status != STATUS_DISCONNECTED) {
			int err;
			/* return nonblocking */
			if (file->f_flags & O_NONBLOCK) {
				if (!ret)
					ret = -EAGAIN;
				goto err;
			}

			err = wait_event_interruptible_timeout(dev->wait_data,
				buf->status == BUFSTAT_READY,
				msecs_to_jiffies(1000));
			if (err < 0) {
				ret = err;
				goto err;
			}
			if (!err) {
				v4l2_info(&dev->v4l2_dev,
					  "timeout: restart streaming\n");
				mutex_lock(&dev->io_mutex);
				hdpvr_stop_streaming(dev);
				mutex_unlock(&dev->io_mutex);
				/*
				 * The FW needs about 4 seconds after streaming
				 * stopped before it is ready to restart
				 * streaming.
				 */
				msleep(4000);
				err = hdpvr_start_streaming(dev);
				if (err) {
					ret = err;
					goto err;
				}
			}
		}

		if (buf->status != BUFSTAT_READY)
			break;

		/* set remaining bytes to copy */
		urb = buf->urb;
		rem = urb->actual_length - buf->pos;
		cnt = rem > count ? count : rem;

		if (copy_to_user(buffer, urb->transfer_buffer + buf->pos,
				 cnt)) {
			v4l2_err(&dev->v4l2_dev, "read: copy_to_user failed\n");
			if (!ret)
				ret = -EFAULT;
			goto err;
		}

		buf->pos += cnt;
		count -= cnt;
		buffer += cnt;
		ret += cnt;

		/* finished, take next buffer */
		if (buf->pos == urb->actual_length) {
			mutex_lock(&dev->io_mutex);
			buf->pos = 0;
			buf->status = BUFSTAT_AVAILABLE;

			list_move_tail(&buf->buff_list, &dev->free_buff_list);

			print_buffer_status();

			mutex_unlock(&dev->io_mutex);

			wake_up_interruptible(&dev->wait_buffer);

			buf = hdpvr_get_next_buffer(dev);
		}
	}
err:
	if (!ret && !buf)
		ret = -EAGAIN;
	return ret;
}

static __poll_t hdpvr_poll(struct file *filp, poll_table *wait)
{
	__poll_t req_events = poll_requested_events(wait);
	struct hdpvr_buffer *buf = NULL;
	struct hdpvr_device *dev = video_drvdata(filp);
	__poll_t mask = v4l2_ctrl_poll(filp, wait);

	if (!(req_events & (EPOLLIN | EPOLLRDNORM)))
		return mask;

	mutex_lock(&dev->io_mutex);

	if (dev->status == STATUS_IDLE) {
		if (hdpvr_start_streaming(dev)) {
			v4l2_dbg(MSG_BUFFER, hdpvr_debug, &dev->v4l2_dev,
				 "start_streaming failed\n");
			dev->status = STATUS_IDLE;
		} else {
			dev->owner = filp->private_data;
		}

		print_buffer_status();
	}
	mutex_unlock(&dev->io_mutex);

	buf = hdpvr_get_next_buffer(dev);
	/* only wait if no data is available */
	if (!buf || buf->status != BUFSTAT_READY) {
		poll_wait(filp, &dev->wait_data, wait);
		buf = hdpvr_get_next_buffer(dev);
	}
	if (buf && buf->status == BUFSTAT_READY)
		mask |= EPOLLIN | EPOLLRDNORM;

	return mask;
}


static const struct v4l2_file_operations hdpvr_fops = {
	.owner		= THIS_MODULE,
	.open		= hdpvr_open,
	.release	= hdpvr_release,
	.read		= hdpvr_read,
	.poll		= hdpvr_poll,
	.unlocked_ioctl	= video_ioctl2,
};

/*=======================================================================*/
/*
 * V4L2 ioctl handling
 */

static int vidioc_querycap(struct file *file, void  *priv,
			   struct v4l2_capability *cap)
{
	struct hdpvr_device *dev = video_drvdata(file);

	strcpy(cap->driver, "hdpvr");
	strcpy(cap->card, "Hauppauge HD PVR");
	usb_make_path(dev->udev, cap->bus_info, sizeof(cap->bus_info));
	cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_AUDIO |
			    V4L2_CAP_READWRITE;
	cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
	return 0;
}

static int vidioc_s_std(struct file *file, void *_fh,
			v4l2_std_id std)
{
	struct hdpvr_device *dev = video_drvdata(file);
	struct hdpvr_fh *fh = _fh;
	u8 std_type = 1;

	if (!fh->legacy_mode && dev->options.video_input == HDPVR_COMPONENT)
		return -ENODATA;
	if (dev->status != STATUS_IDLE)
		return -EBUSY;
	if (std & V4L2_STD_525_60)
		std_type = 0;
	dev->cur_std = std;
	dev->width = 720;
	dev->height = std_type ? 576 : 480;

	return hdpvr_config_call(dev, CTRL_VIDEO_STD_TYPE, std_type);
}

static int vidioc_g_std(struct file *file, void *_fh,
			v4l2_std_id *std)
{
	struct hdpvr_device *dev = video_drvdata(file);
	struct hdpvr_fh *fh = _fh;

	if (!fh->legacy_mode && dev->options.video_input == HDPVR_COMPONENT)
		return -ENODATA;
	*std = dev->cur_std;
	return 0;
}

static int vidioc_querystd(struct file *file, void *_fh, v4l2_std_id *a)
{
	struct hdpvr_device *dev = video_drvdata(file);
	struct hdpvr_video_info vid_info;
	struct hdpvr_fh *fh = _fh;
	int ret;

	*a = V4L2_STD_UNKNOWN;
	if (dev->options.video_input == HDPVR_COMPONENT)
		return fh->legacy_mode ? 0 : -ENODATA;
	ret = get_video_info(dev, &vid_info);
	if (vid_info.valid && vid_info.width == 720 &&
	    (vid_info.height == 480 || vid_info.height == 576)) {
		*a = (vid_info.height == 480) ?
			V4L2_STD_525_60 : V4L2_STD_625_50;
	}
	return ret;
}

static int vidioc_s_dv_timings(struct file *file, void *_fh,
				    struct v4l2_dv_timings *timings)
{
	struct hdpvr_device *dev = video_drvdata(file);
	struct hdpvr_fh *fh = _fh;
	int i;

	fh->legacy_mode = false;
	if (dev->options.video_input)
		return -ENODATA;
	if (dev->status != STATUS_IDLE)
		return -EBUSY;
	for (i = 0; i < ARRAY_SIZE(hdpvr_dv_timings); i++)
		if (v4l2_match_dv_timings(timings, hdpvr_dv_timings + i, 0, false))
			break;
	if (i == ARRAY_SIZE(hdpvr_dv_timings))
		return -EINVAL;
	dev->cur_dv_timings = hdpvr_dv_timings[i];
	dev->width = hdpvr_dv_timings[i].bt.width;
	dev->height = hdpvr_dv_timings[i].bt.height;
	return 0;
}

static int vidioc_g_dv_timings(struct file *file, void *_fh,
				    struct v4l2_dv_timings *timings)
{
	struct hdpvr_device *dev = video_drvdata(file);
	struct hdpvr_fh *fh = _fh;

	fh->legacy_mode = false;
	if (dev->options.video_input)
		return -ENODATA;
	*timings = dev->cur_dv_timings;
	return 0;
}

static int vidioc_query_dv_timings(struct file *file, void *_fh,
				    struct v4l2_dv_timings *timings)
{
	struct hdpvr_device *dev = video_drvdata(file);
	struct hdpvr_fh *fh = _fh;
	struct hdpvr_video_info vid_info;
	bool interlaced;
	int ret = 0;
	int i;

	fh->legacy_mode = false;
	if (dev->options.video_input)
		return -ENODATA;
	ret = get_video_info(dev, &vid_info);
	if (ret)
		return ret;
	if (!vid_info.valid)
		return -ENOLCK;
	interlaced = vid_info.fps <= 30;
	for (i = 0; i < ARRAY_SIZE(hdpvr_dv_timings); i++) {
		const struct v4l2_bt_timings *bt = &hdpvr_dv_timings[i].bt;
		unsigned hsize;
		unsigned vsize;
		unsigned fps;

		hsize = V4L2_DV_BT_FRAME_WIDTH(bt);
		vsize = V4L2_DV_BT_FRAME_HEIGHT(bt);
		fps = (unsigned)bt->pixelclock / (hsize * vsize);
		if (bt->width != vid_info.width ||
		    bt->height != vid_info.height ||
		    bt->interlaced != interlaced ||
		    (fps != vid_info.fps && fps + 1 != vid_info.fps))
			continue;
		*timings = hdpvr_dv_timings[i];
		break;
	}
	if (i == ARRAY_SIZE(hdpvr_dv_timings))
		ret = -ERANGE;

	return ret;
}

static int vidioc_enum_dv_timings(struct file *file, void *_fh,
				    struct v4l2_enum_dv_timings *timings)
{
	struct hdpvr_device *dev = video_drvdata(file);
	struct hdpvr_fh *fh = _fh;

	fh->legacy_mode = false;
	memset(timings->reserved, 0, sizeof(timings->reserved));
	if (dev->options.video_input)
		return -ENODATA;
	if (timings->index >= ARRAY_SIZE(hdpvr_dv_timings))
		return -EINVAL;
	timings->timings = hdpvr_dv_timings[timings->index];
	return 0;
}

static int vidioc_dv_timings_cap(struct file *file, void *_fh,
				    struct v4l2_dv_timings_cap *cap)
{
	struct hdpvr_device *dev = video_drvdata(file);
	struct hdpvr_fh *fh = _fh;

	fh->legacy_mode = false;
	if (dev->options.video_input)
		return -ENODATA;
	cap->type = V4L2_DV_BT_656_1120;
	cap->bt.min_width = 720;
	cap->bt.max_width = 1920;
	cap->bt.min_height = 480;
	cap->bt.max_height = 1080;
	cap->bt.min_pixelclock = 27000000;
	cap->bt.max_pixelclock = 74250000;
	cap->bt.standards = V4L2_DV_BT_STD_CEA861;
	cap->bt.capabilities = V4L2_DV_BT_CAP_INTERLACED | V4L2_DV_BT_CAP_PROGRESSIVE;
	return 0;
}

static const char *iname[] = {
	[HDPVR_COMPONENT] = "Component",
	[HDPVR_SVIDEO]    = "S-Video",
	[HDPVR_COMPOSITE] = "Composite",
};

static int vidioc_enum_input(struct file *file, void *_fh, struct v4l2_input *i)
{
	unsigned int n;

	n = i->index;
	if (n >= HDPVR_VIDEO_INPUTS)
		return -EINVAL;

	i->type = V4L2_INPUT_TYPE_CAMERA;

	strncpy(i->name, iname[n], sizeof(i->name) - 1);
	i->name[sizeof(i->name) - 1] = '\0';

	i->audioset = 1<<HDPVR_RCA_FRONT | 1<<HDPVR_RCA_BACK | 1<<HDPVR_SPDIF;

	i->capabilities = n ? V4L2_IN_CAP_STD : V4L2_IN_CAP_DV_TIMINGS;
	i->std = n ? V4L2_STD_ALL : 0;

	return 0;
}

static int vidioc_s_input(struct file *file, void *_fh,
			  unsigned int index)
{
	struct hdpvr_device *dev = video_drvdata(file);
	int retval;

	if (index >= HDPVR_VIDEO_INPUTS)
		return -EINVAL;

	if (dev->status != STATUS_IDLE)
		return -EBUSY;

	retval = hdpvr_config_call(dev, CTRL_VIDEO_INPUT_VALUE, index+1);
	if (!retval) {
		dev->options.video_input = index;
		/*
		 * Unfortunately gstreamer calls ENUMSTD and bails out if it
		 * won't find any formats, even though component input is
		 * selected. This means that we have to leave tvnorms at
		 * V4L2_STD_ALL. We cannot use the 'legacy' trick since
		 * tvnorms is set at the device node level and not at the
		 * filehandle level.
		 *
		 * Comment this out for now, but if the legacy mode can be
		 * removed in the future, then this code should be enabled
		 * again.
		dev->video_dev.tvnorms =
			(index != HDPVR_COMPONENT) ? V4L2_STD_ALL : 0;
		 */
	}

	return retval;
}

static int vidioc_g_input(struct file *file, void *private_data,
			  unsigned int *index)
{
	struct hdpvr_device *dev = video_drvdata(file);

	*index = dev->options.video_input;
	return 0;
}


static const char *audio_iname[] = {
	[HDPVR_RCA_FRONT] = "RCA front",
	[HDPVR_RCA_BACK]  = "RCA back",
	[HDPVR_SPDIF]     = "SPDIF",
};

static int vidioc_enumaudio(struct file *file, void *priv,
				struct v4l2_audio *audio)
{
	unsigned int n;

	n = audio->index;
	if (n >= HDPVR_AUDIO_INPUTS)
		return -EINVAL;

	audio->capability = V4L2_AUDCAP_STEREO;

	strncpy(audio->name, audio_iname[n], sizeof(audio->name) - 1);
	audio->name[sizeof(audio->name) - 1] = '\0';

	return 0;
}

static int vidioc_s_audio(struct file *file, void *private_data,
			  const struct v4l2_audio *audio)
{
	struct hdpvr_device *dev = video_drvdata(file);
	int retval;

	if (audio->index >= HDPVR_AUDIO_INPUTS)
		return -EINVAL;

	if (dev->status != STATUS_IDLE)
		return -EBUSY;

	retval = hdpvr_set_audio(dev, audio->index+1, dev->options.audio_codec);
	if (!retval)
		dev->options.audio_input = audio->index;

	return retval;
}

static int vidioc_g_audio(struct file *file, void *private_data,
			  struct v4l2_audio *audio)
{
	struct hdpvr_device *dev = video_drvdata(file);

	audio->index = dev->options.audio_input;
	audio->capability = V4L2_AUDCAP_STEREO;
	strlcpy(audio->name, audio_iname[audio->index], sizeof(audio->name));
	audio->name[sizeof(audio->name) - 1] = '\0';
	return 0;
}

static int hdpvr_try_ctrl(struct v4l2_ctrl *ctrl)
{
	struct hdpvr_device *dev =
		container_of(ctrl->handler, struct hdpvr_device, hdl);

	switch (ctrl->id) {
	case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
		if (ctrl->val == V4L2_MPEG_VIDEO_BITRATE_MODE_VBR &&
		    dev->video_bitrate->val >= dev->video_bitrate_peak->val)
			dev->video_bitrate_peak->val =
					dev->video_bitrate->val + 100000;
		break;
	}
	return 0;
}

static int hdpvr_s_ctrl(struct v4l2_ctrl *ctrl)
{
	struct hdpvr_device *dev =
		container_of(ctrl->handler, struct hdpvr_device, hdl);
	struct hdpvr_options *opt = &dev->options;
	int ret = -EINVAL;

	switch (ctrl->id) {
	case V4L2_CID_BRIGHTNESS:
		ret = hdpvr_config_call(dev, CTRL_BRIGHTNESS, ctrl->val);
		if (ret)
			break;
		dev->options.brightness = ctrl->val;
		return 0;
	case V4L2_CID_CONTRAST:
		ret = hdpvr_config_call(dev, CTRL_CONTRAST, ctrl->val);
		if (ret)
			break;
		dev->options.contrast = ctrl->val;
		return 0;
	case V4L2_CID_SATURATION:
		ret = hdpvr_config_call(dev, CTRL_SATURATION, ctrl->val);
		if (ret)
			break;
		dev->options.saturation = ctrl->val;
		return 0;
	case V4L2_CID_HUE:
		ret = hdpvr_config_call(dev, CTRL_HUE, ctrl->val);
		if (ret)
			break;
		dev->options.hue = ctrl->val;
		return 0;
	case V4L2_CID_SHARPNESS:
		ret = hdpvr_config_call(dev, CTRL_SHARPNESS, ctrl->val);
		if (ret)
			break;
		dev->options.sharpness = ctrl->val;
		return 0;
	case V4L2_CID_MPEG_AUDIO_ENCODING:
		if (dev->flags & HDPVR_FLAG_AC3_CAP) {
			opt->audio_codec = ctrl->val;
			return hdpvr_set_audio(dev, opt->audio_input + 1,
					      opt->audio_codec);
		}
		return 0;
	case V4L2_CID_MPEG_VIDEO_ENCODING:
		return 0;
/*	case V4L2_CID_MPEG_VIDEO_B_FRAMES: */
/*		if (ctrl->value == 0 && !(opt->gop_mode & 0x2)) { */
/*			opt->gop_mode |= 0x2; */
/*			hdpvr_config_call(dev, CTRL_GOP_MODE_VALUE, */
/*					  opt->gop_mode); */
/*		} */
/*		if (ctrl->value == 128 && opt->gop_mode & 0x2) { */
/*			opt->gop_mode &= ~0x2; */
/*			hdpvr_config_call(dev, CTRL_GOP_MODE_VALUE, */
/*					  opt->gop_mode); */
/*		} */
/*		break; */
	case V4L2_CID_MPEG_VIDEO_BITRATE_MODE: {
		uint peak_bitrate = dev->video_bitrate_peak->val / 100000;
		uint bitrate = dev->video_bitrate->val / 100000;

		if (ctrl->is_new) {
			if (ctrl->val == V4L2_MPEG_VIDEO_BITRATE_MODE_CBR)
				opt->bitrate_mode = HDPVR_CONSTANT;
			else
				opt->bitrate_mode = HDPVR_VARIABLE_AVERAGE;
			hdpvr_config_call(dev, CTRL_BITRATE_MODE_VALUE,
					  opt->bitrate_mode);
			v4l2_ctrl_activate(dev->video_bitrate_peak,
				ctrl->val != V4L2_MPEG_VIDEO_BITRATE_MODE_CBR);
		}

		if (dev->video_bitrate_peak->is_new ||
		    dev->video_bitrate->is_new) {
			opt->bitrate = bitrate;
			opt->peak_bitrate = peak_bitrate;
			hdpvr_set_bitrate(dev);
		}
		return 0;
	}
	case V4L2_CID_MPEG_STREAM_TYPE:
		return 0;
	default:
		break;
	}
	return ret;
}

static int vidioc_enum_fmt_vid_cap(struct file *file, void *private_data,
				    struct v4l2_fmtdesc *f)
{
	if (f->index != 0)
		return -EINVAL;

	f->flags = V4L2_FMT_FLAG_COMPRESSED;
	strncpy(f->description, "MPEG2-TS with AVC/AAC streams", 32);
	f->pixelformat = V4L2_PIX_FMT_MPEG;

	return 0;
}

static int vidioc_g_fmt_vid_cap(struct file *file, void *_fh,
				struct v4l2_format *f)
{
	struct hdpvr_device *dev = video_drvdata(file);
	struct hdpvr_fh *fh = _fh;
	int ret;

	/*
	 * The original driver would always returns the current detected
	 * resolution as the format (and EFAULT if it couldn't be detected).
	 * With the introduction of VIDIOC_QUERY_DV_TIMINGS there is now a
	 * better way of doing this, but to stay compatible with existing
	 * applications we assume legacy mode every time an application opens
	 * the device. Only if one of the new DV_TIMINGS ioctls is called
	 * will the filehandle go into 'normal' mode where g_fmt returns the
	 * last set format.
	 */
	if (fh->legacy_mode) {
		struct hdpvr_video_info vid_info;

		ret = get_video_info(dev, &vid_info);
		if (ret < 0)
			return ret;
		if (!vid_info.valid)
			return -EFAULT;
		f->fmt.pix.width = vid_info.width;
		f->fmt.pix.height = vid_info.height;
	} else {
		f->fmt.pix.width = dev->width;
		f->fmt.pix.height = dev->height;
	}
	f->fmt.pix.pixelformat	= V4L2_PIX_FMT_MPEG;
	f->fmt.pix.sizeimage	= dev->bulk_in_size;
	f->fmt.pix.bytesperline	= 0;
	if (f->fmt.pix.width == 720) {
		/* SDTV formats */
		f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
		f->fmt.pix.field = V4L2_FIELD_INTERLACED;
	} else {
		/* HDTV formats */
		f->fmt.pix.colorspace = V4L2_COLORSPACE_REC709;
		f->fmt.pix.field = V4L2_FIELD_NONE;
	}
	return 0;
}

static int vidioc_encoder_cmd(struct file *filp, void *priv,
			       struct v4l2_encoder_cmd *a)
{
	struct hdpvr_device *dev = video_drvdata(filp);
	int res = 0;

	mutex_lock(&dev->io_mutex);
	a->flags = 0;

	switch (a->cmd) {
	case V4L2_ENC_CMD_START:
		if (dev->owner && filp->private_data != dev->owner) {
			res = -EBUSY;
			break;
		}
		if (dev->status == STATUS_STREAMING)
			break;
		res = hdpvr_start_streaming(dev);
		if (!res)
			dev->owner = filp->private_data;
		else
			dev->status = STATUS_IDLE;
		break;
	case V4L2_ENC_CMD_STOP:
		if (dev->owner && filp->private_data != dev->owner) {
			res = -EBUSY;
			break;
		}
		if (dev->status == STATUS_IDLE)
			break;
		res = hdpvr_stop_streaming(dev);
		if (!res)
			dev->owner = NULL;
		break;
	default:
		v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev,
			 "Unsupported encoder cmd %d\n", a->cmd);
		res = -EINVAL;
		break;
	}

	mutex_unlock(&dev->io_mutex);
	return res;
}

static int vidioc_try_encoder_cmd(struct file *filp, void *priv,
					struct v4l2_encoder_cmd *a)
{
	a->flags = 0;
	switch (a->cmd) {
	case V4L2_ENC_CMD_START:
	case V4L2_ENC_CMD_STOP:
		return 0;
	default:
		return -EINVAL;
	}
}

static const struct v4l2_ioctl_ops hdpvr_ioctl_ops = {
	.vidioc_querycap	= vidioc_querycap,
	.vidioc_s_std		= vidioc_s_std,
	.vidioc_g_std		= vidioc_g_std,
	.vidioc_querystd	= vidioc_querystd,
	.vidioc_s_dv_timings	= vidioc_s_dv_timings,
	.vidioc_g_dv_timings	= vidioc_g_dv_timings,
	.vidioc_query_dv_timings= vidioc_query_dv_timings,
	.vidioc_enum_dv_timings	= vidioc_enum_dv_timings,
	.vidioc_dv_timings_cap	= vidioc_dv_timings_cap,
	.vidioc_enum_input	= vidioc_enum_input,
	.vidioc_g_input		= vidioc_g_input,
	.vidioc_s_input		= vidioc_s_input,
	.vidioc_enumaudio	= vidioc_enumaudio,
	.vidioc_g_audio		= vidioc_g_audio,
	.vidioc_s_audio		= vidioc_s_audio,
	.vidioc_enum_fmt_vid_cap= vidioc_enum_fmt_vid_cap,
	.vidioc_g_fmt_vid_cap	= vidioc_g_fmt_vid_cap,
	.vidioc_s_fmt_vid_cap	= vidioc_g_fmt_vid_cap,
	.vidioc_try_fmt_vid_cap	= vidioc_g_fmt_vid_cap,
	.vidioc_encoder_cmd	= vidioc_encoder_cmd,
	.vidioc_try_encoder_cmd	= vidioc_try_encoder_cmd,
	.vidioc_log_status	= v4l2_ctrl_log_status,
	.vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
	.vidioc_unsubscribe_event = v4l2_event_unsubscribe,
};

static void hdpvr_device_release(struct video_device *vdev)
{
	struct hdpvr_device *dev = video_get_drvdata(vdev);

	hdpvr_delete(dev);
	flush_work(&dev->worker);

	v4l2_device_unregister(&dev->v4l2_dev);
	v4l2_ctrl_handler_free(&dev->hdl);

	/* deregister I2C adapter */
#if IS_ENABLED(CONFIG_I2C)
	mutex_lock(&dev->i2c_mutex);
	i2c_del_adapter(&dev->i2c_adapter);
	mutex_unlock(&dev->i2c_mutex);
#endif /* CONFIG_I2C */

	kfree(dev->usbc_buf);
	kfree(dev);
}

static const struct video_device hdpvr_video_template = {
	.fops			= &hdpvr_fops,
	.release		= hdpvr_device_release,
	.ioctl_ops		= &hdpvr_ioctl_ops,
	.tvnorms		= V4L2_STD_ALL,
};

static const struct v4l2_ctrl_ops hdpvr_ctrl_ops = {
	.try_ctrl = hdpvr_try_ctrl,
	.s_ctrl = hdpvr_s_ctrl,
};

int hdpvr_register_videodev(struct hdpvr_device *dev, struct device *parent,
			    int devnum)
{
	struct v4l2_ctrl_handler *hdl = &dev->hdl;
	bool ac3 = dev->flags & HDPVR_FLAG_AC3_CAP;
	int res;

	dev->cur_std = V4L2_STD_525_60;
	dev->width = 720;
	dev->height = 480;
	dev->cur_dv_timings = hdpvr_dv_timings[HDPVR_DEF_DV_TIMINGS_IDX];
	v4l2_ctrl_handler_init(hdl, 11);
	if (dev->fw_ver > 0x15) {
		v4l2_ctrl_new_std(hdl, &hdpvr_ctrl_ops,
			V4L2_CID_BRIGHTNESS, 0x0, 0xff, 1, 0x80);
		v4l2_ctrl_new_std(hdl, &hdpvr_ctrl_ops,
			V4L2_CID_CONTRAST, 0x0, 0xff, 1, 0x40);
		v4l2_ctrl_new_std(hdl, &hdpvr_ctrl_ops,
			V4L2_CID_SATURATION, 0x0, 0xff, 1, 0x40);
		v4l2_ctrl_new_std(hdl, &hdpvr_ctrl_ops,
			V4L2_CID_HUE, 0x0, 0x1e, 1, 0xf);
		v4l2_ctrl_new_std(hdl, &hdpvr_ctrl_ops,
			V4L2_CID_SHARPNESS, 0x0, 0xff, 1, 0x80);
	} else {
		v4l2_ctrl_new_std(hdl, &hdpvr_ctrl_ops,
			V4L2_CID_BRIGHTNESS, 0x0, 0xff, 1, 0x86);
		v4l2_ctrl_new_std(hdl, &hdpvr_ctrl_ops,
			V4L2_CID_CONTRAST, 0x0, 0xff, 1, 0x80);
		v4l2_ctrl_new_std(hdl, &hdpvr_ctrl_ops,
			V4L2_CID_SATURATION, 0x0, 0xff, 1, 0x80);
		v4l2_ctrl_new_std(hdl, &hdpvr_ctrl_ops,
			V4L2_CID_HUE, 0x0, 0xff, 1, 0x80);
		v4l2_ctrl_new_std(hdl, &hdpvr_ctrl_ops,
			V4L2_CID_SHARPNESS, 0x0, 0xff, 1, 0x80);
	}

	v4l2_ctrl_new_std_menu(hdl, &hdpvr_ctrl_ops,
		V4L2_CID_MPEG_STREAM_TYPE,
		V4L2_MPEG_STREAM_TYPE_MPEG2_TS,
		0x1, V4L2_MPEG_STREAM_TYPE_MPEG2_TS);
	v4l2_ctrl_new_std_menu(hdl, &hdpvr_ctrl_ops,
		V4L2_CID_MPEG_AUDIO_ENCODING,
		ac3 ? V4L2_MPEG_AUDIO_ENCODING_AC3 : V4L2_MPEG_AUDIO_ENCODING_AAC,
		0x7, ac3 ? dev->options.audio_codec : V4L2_MPEG_AUDIO_ENCODING_AAC);
	v4l2_ctrl_new_std_menu(hdl, &hdpvr_ctrl_ops,
		V4L2_CID_MPEG_VIDEO_ENCODING,
		V4L2_MPEG_VIDEO_ENCODING_MPEG_4_AVC, 0x3,
		V4L2_MPEG_VIDEO_ENCODING_MPEG_4_AVC);

	dev->video_mode = v4l2_ctrl_new_std_menu(hdl, &hdpvr_ctrl_ops,
		V4L2_CID_MPEG_VIDEO_BITRATE_MODE,
		V4L2_MPEG_VIDEO_BITRATE_MODE_CBR, 0,
		V4L2_MPEG_VIDEO_BITRATE_MODE_CBR);

	dev->video_bitrate = v4l2_ctrl_new_std(hdl, &hdpvr_ctrl_ops,
		V4L2_CID_MPEG_VIDEO_BITRATE,
		1000000, 13500000, 100000, 6500000);
	dev->video_bitrate_peak = v4l2_ctrl_new_std(hdl, &hdpvr_ctrl_ops,
		V4L2_CID_MPEG_VIDEO_BITRATE_PEAK,
		1100000, 20200000, 100000, 9000000);
	dev->v4l2_dev.ctrl_handler = hdl;
	if (hdl->error) {
		res = hdl->error;
		v4l2_err(&dev->v4l2_dev, "Could not register controls\n");
		goto error;
	}
	v4l2_ctrl_cluster(3, &dev->video_mode);
	res = v4l2_ctrl_handler_setup(hdl);
	if (res < 0) {
		v4l2_err(&dev->v4l2_dev, "Could not setup controls\n");
		goto error;
	}

	/* setup and register video device */
	dev->video_dev = hdpvr_video_template;
	strcpy(dev->video_dev.name, "Hauppauge HD PVR");
	dev->video_dev.v4l2_dev = &dev->v4l2_dev;
	video_set_drvdata(&dev->video_dev, dev);

	res = video_register_device(&dev->video_dev, VFL_TYPE_GRABBER, devnum);
	if (res < 0) {
		v4l2_err(&dev->v4l2_dev, "video_device registration failed\n");
		goto error;
	}

	return 0;
error:
	v4l2_ctrl_handler_free(hdl);
	return res;
}
