/*
 * Hauppage 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/version.h>
#include <linux/workqueue.h>

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

#define BULK_URB_TIMEOUT 1250 /* 1.25 seconds */

struct hdpvr_fh {
	struct hdpvr_device	*dev;
};

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);
}

/*=========================================================================*/
/* bufffer 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_buffer_free(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->video_dev,
		 "allocating %u buffers\n", count);

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

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

		urb = usb_alloc_urb(0, GFP_KERNEL);
		if (!urb) {
			err("cannot allocate urb");
			goto exit;
		}
		buf->urb = urb;

		mem = usb_buffer_alloc(dev->udev, dev->bulk_in_size, GFP_KERNEL,
				       &urb->transfer_dma);
		if (!mem) {
			err("cannot allocate usb transfer buffer");
			goto exit;
		}

		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->status = BUFSTAT_AVAILABLE;
		list_add_tail(&buf->buff_list, &dev->free_buff_list);
	}
	return 0;
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) {
			err("buffer not marked as availbale");
			ret = -EFAULT;
			goto err;
		}

		urb = buf->urb;
		urb->status = 0;
		urb->actual_length = 0;
		ret = usb_submit_urb(urb, GFP_KERNEL);
		if (ret) {
			err("usb_submit_urb in %s returned %d", __func__, ret);
			if (++err_count > 2)
				break;
			continue;
		}
		buf->status = BUFSTAT_INPROGRESS;
		list_move_tail(&buf->buff_list, &dev->rec_buff_list);
	}
err:
	v4l2_dbg(MSG_BUFFER, hdpvr_debug, dev->video_dev,
		 "buffer queue stat: %d free, %d proc\n",
		 list_size(&dev->free_buff_list),
		 list_size(&dev->rec_buff_list));
	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->video_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->video_dev,
		 "transmit worker exited\n");
	return;
error:
	v4l2_dbg(MSG_INFO, hdpvr_debug, dev->video_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;
	else if (dev->status != STATUS_IDLE)
		return -EAGAIN;

	vidinf = get_video_info(dev);

	if (vidinf) {
		v4l2_dbg(MSG_BUFFER, hdpvr_debug, dev->video_dev,
			 "video signal: %dx%d@%dhz\n", vidinf->width,
			 vidinf->height, vidinf->fps);
		kfree(vidinf);

		/* 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->video_dev,
			 "encoder start control request returned %d\n", ret);

		hdpvr_config_call(dev, CTRL_START_STREAMING_VALUE, 0x00);

		INIT_WORK(&dev->worker, hdpvr_transmit_buffers);
		queue_work(dev->workqueue, &dev->worker);

		v4l2_dbg(MSG_BUFFER, hdpvr_debug, dev->video_dev,
			 "streaming started\n");
		dev->status = STATUS_STREAMING;

		return 0;
	}
	msleep(250);
	v4l2_dbg(MSG_INFO, hdpvr_debug, dev->video_dev,
		 "no video signal at input %d\n", dev->options.video_input);
	return -EAGAIN;
}


/* function expects dev->io_mutex to be hold by caller */
static int hdpvr_stop_streaming(struct hdpvr_device *dev)
{
	if (dev->status == STATUS_IDLE)
		return 0;
	else if (dev->status != STATUS_STREAMING)
		return -EAGAIN;

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

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

	flush_workqueue(dev->workqueue);

	/* kill the still outstanding urbs */
	hdpvr_cancel_queue(dev);

	dev->status = STATUS_IDLE;

	return 0;
}


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

static int hdpvr_open(struct file *file)
{
	struct hdpvr_device *dev;
	struct hdpvr_fh *fh;
	int retval = -ENOMEM;

	dev = (struct hdpvr_device *)video_get_drvdata(video_devdata(file));
	if (!dev) {
		err("open failing with with ENODEV");
		retval = -ENODEV;
		goto err;
	}

	fh = kzalloc(sizeof(struct hdpvr_fh), GFP_KERNEL);
	if (!fh) {
		err("Out of memory?");
		goto err;
	}
	/* lock the device to allow correctly handling errors
	 * in resumption */
	mutex_lock(&dev->io_mutex);
	dev->open_count++;

	fh->dev = dev;

	/* save our object in the file's private structure */
	file->private_data = fh;

	retval = 0;
err:
	mutex_unlock(&dev->io_mutex);
	return retval;
}

static int hdpvr_release(struct file *file)
{
	struct hdpvr_fh		*fh  = (struct hdpvr_fh *)file->private_data;
	struct hdpvr_device	*dev = fh->dev;

	if (!dev)
		return -ENODEV;

	mutex_lock(&dev->io_mutex);
	if (!(--dev->open_count) && dev->status == STATUS_STREAMING)
		hdpvr_stop_streaming(dev);

	mutex_unlock(&dev->io_mutex);

	return 0;
}

/*
 * 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_fh *fh = file->private_data;
	struct hdpvr_device *dev = fh->dev;
	struct hdpvr_buffer *buf = NULL;
	struct urb *urb;
	unsigned int ret = 0;
	int rem, cnt;

	if (*pos)
		return -ESPIPE;

	if (!dev)
		return -ENODEV;

	mutex_lock(&dev->io_mutex);
	if (dev->status == STATUS_IDLE) {
		if (hdpvr_start_streaming(dev)) {
			v4l2_dbg(MSG_INFO, hdpvr_debug, dev->video_dev,
				 "start_streaming failed");
			ret = -EIO;
			msleep(200);
			dev->status = STATUS_IDLE;
			mutex_unlock(&dev->io_mutex);
			goto err;
		}

		v4l2_dbg(MSG_BUFFER, hdpvr_debug, dev->video_dev,
			 "buffer queue stat: %d free, %d proc\n",
			 list_size(&dev->free_buff_list),
			 list_size(&dev->rec_buff_list));
	}
	mutex_unlock(&dev->io_mutex);

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

	buf = hdpvr_get_next_buffer(dev);

	while (count > 0 && buf) {

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

			if (wait_event_interruptible(dev->wait_data,
					      buf->status == BUFSTAT_READY)) {
				ret = -ERESTARTSYS;
				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)) {
			err("read: copy_to_user failed");
			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);

			v4l2_dbg(MSG_BUFFER, hdpvr_debug, dev->video_dev,
				 "buffer queue stat: %d free, %d proc\n",
				 list_size(&dev->free_buff_list),
				 list_size(&dev->rec_buff_list));

			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 unsigned int hdpvr_poll(struct file *filp, poll_table *wait)
{
	struct hdpvr_fh *fh = (struct hdpvr_fh *)filp->private_data;
	struct hdpvr_device *dev = fh->dev;
	unsigned int mask = 0;

	mutex_lock(&dev->io_mutex);

	if (video_is_unregistered(dev->video_dev))
		return -EIO;

	if (dev->status == STATUS_IDLE) {
		if (hdpvr_start_streaming(dev)) {
			v4l2_dbg(MSG_BUFFER, hdpvr_debug, dev->video_dev,
				 "start_streaming failed");
			dev->status = STATUS_IDLE;
		}

		v4l2_dbg(MSG_BUFFER, hdpvr_debug, dev->video_dev,
			 "buffer queue stat: %d free, %d proc\n",
			 list_size(&dev->free_buff_list),
			 list_size(&dev->rec_buff_list));
	}
	mutex_unlock(&dev->io_mutex);

	poll_wait(filp, &dev->wait_data, wait);

	mutex_lock(&dev->io_mutex);
	if (!list_empty(&dev->rec_buff_list)) {

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

		if (buf->status == BUFSTAT_READY)
			mask |= POLLIN | POLLRDNORM;
	}
	mutex_unlock(&dev->io_mutex);

	return mask;
}


static long hdpvr_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
	struct hdpvr_fh *fh = (struct hdpvr_fh *)filp->private_data;
	struct hdpvr_device *dev = fh->dev;
	int res;

	if (video_is_unregistered(dev->video_dev))
		return -EIO;

	mutex_lock(&dev->io_mutex);
	switch (cmd) {
	case VIDIOC_TRY_ENCODER_CMD:
	case VIDIOC_ENCODER_CMD: {
		struct v4l2_encoder_cmd *enc = (struct v4l2_encoder_cmd *)arg;
		int try = cmd == VIDIOC_TRY_ENCODER_CMD;

		memset(&enc->raw, 0, sizeof(enc->raw));
		switch (enc->cmd) {
		case V4L2_ENC_CMD_START:
			enc->flags = 0;
			if (try)
				return 0;
			res = hdpvr_start_streaming(dev);
			break;
		case V4L2_ENC_CMD_STOP:
			if (try)
				return 0;
			res = hdpvr_stop_streaming(dev);
			break;
		default:
			v4l2_dbg(MSG_INFO, hdpvr_debug, dev->video_dev,
				 "Unsupported encoder cmd %d\n", enc->cmd);
			return -EINVAL;
		}
		break;
	}
	default:
		res = video_ioctl2(filp, cmd, arg);
	}
	mutex_unlock(&dev->io_mutex);
	return res;
}

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	= hdpvr_ioctl,
};

/*=======================================================================*/
/*
 * 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, "Haupauge HD PVR");
	usb_make_path(dev->udev, cap->bus_info, sizeof(cap->bus_info));
	cap->version = HDPVR_VERSION;
	cap->capabilities =     V4L2_CAP_VIDEO_CAPTURE |
				V4L2_CAP_AUDIO         |
				V4L2_CAP_READWRITE;
	return 0;
}

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

	if (*std & (V4L2_STD_NTSC | V4L2_STD_PAL_60))
		std_type = 0;

	return hdpvr_config_call(dev, CTRL_VIDEO_STD_TYPE, std_type);
}

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

static int vidioc_enum_input(struct file *file, void *priv,
				struct v4l2_input *i)
{
	struct hdpvr_fh *fh = file->private_data;
	struct hdpvr_device *dev = fh->dev;
	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->std = dev->video_dev->tvnorms;

	return 0;
}

static int vidioc_s_input(struct file *file, void *private_data,
			  unsigned int index)
{
	struct hdpvr_fh *fh = file->private_data;
	struct hdpvr_device *dev = fh->dev;
	int retval;

	if (index >= HDPVR_VIDEO_INPUTS)
		return -EINVAL;

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

	retval = hdpvr_config_call(dev, CTRL_VIDEO_INPUT_VALUE, index+1);
	if (!retval)
		dev->options.video_input = index;

	return retval;
}

static int vidioc_g_input(struct file *file, void *private_data,
			  unsigned int *index)
{
	struct hdpvr_fh *fh = file->private_data;
	struct hdpvr_device *dev = fh->dev;

	*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,
			  struct v4l2_audio *audio)
{
	struct hdpvr_fh *fh = file->private_data;
	struct hdpvr_device *dev = fh->dev;
	int retval;

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

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

	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_fh *fh = file->private_data;
	struct hdpvr_device *dev = fh->dev;

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

static const s32 supported_v4l2_ctrls[] = {
	V4L2_CID_BRIGHTNESS,
	V4L2_CID_CONTRAST,
	V4L2_CID_SATURATION,
	V4L2_CID_HUE,
	V4L2_CID_SHARPNESS,
	V4L2_CID_MPEG_AUDIO_ENCODING,
	V4L2_CID_MPEG_VIDEO_ENCODING,
	V4L2_CID_MPEG_VIDEO_BITRATE_MODE,
	V4L2_CID_MPEG_VIDEO_BITRATE,
	V4L2_CID_MPEG_VIDEO_BITRATE_PEAK,
};

static int fill_queryctrl(struct hdpvr_options *opt, struct v4l2_queryctrl *qc,
			  int ac3)
{
	int err;

	switch (qc->id) {
	case V4L2_CID_BRIGHTNESS:
		return v4l2_ctrl_query_fill(qc, 0x0, 0xff, 1, 0x86);
	case V4L2_CID_CONTRAST:
		return v4l2_ctrl_query_fill(qc, 0x0, 0xff, 1, 0x80);
	case V4L2_CID_SATURATION:
		return v4l2_ctrl_query_fill(qc, 0x0, 0xff, 1, 0x80);
	case V4L2_CID_HUE:
		return v4l2_ctrl_query_fill(qc, 0x0, 0xff, 1, 0x80);
	case V4L2_CID_SHARPNESS:
		return v4l2_ctrl_query_fill(qc, 0x0, 0xff, 1, 0x80);
	case V4L2_CID_MPEG_AUDIO_ENCODING:
		return v4l2_ctrl_query_fill(
			qc, V4L2_MPEG_AUDIO_ENCODING_AAC,
			ac3 ? V4L2_MPEG_AUDIO_ENCODING_AC3
			: V4L2_MPEG_AUDIO_ENCODING_AAC,
			1, V4L2_MPEG_AUDIO_ENCODING_AAC);
	case V4L2_CID_MPEG_VIDEO_ENCODING:
		return v4l2_ctrl_query_fill(
			qc, V4L2_MPEG_VIDEO_ENCODING_MPEG_4_AVC,
			V4L2_MPEG_VIDEO_ENCODING_MPEG_4_AVC, 1,
			V4L2_MPEG_VIDEO_ENCODING_MPEG_4_AVC);

/* 	case V4L2_CID_MPEG_VIDEO_? maybe keyframe interval: */
/* 		return v4l2_ctrl_query_fill(qc, 0, 128, 128, 0); */
	case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
		return v4l2_ctrl_query_fill(
			qc, V4L2_MPEG_VIDEO_BITRATE_MODE_VBR,
			V4L2_MPEG_VIDEO_BITRATE_MODE_CBR, 1,
			V4L2_MPEG_VIDEO_BITRATE_MODE_CBR);

	case V4L2_CID_MPEG_VIDEO_BITRATE:
		return v4l2_ctrl_query_fill(qc, 1000000, 13500000, 100000,
					    6500000);
	case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK:
		err = v4l2_ctrl_query_fill(qc, 1100000, 20200000, 100000,
					   9000000);
		if (!err && opt->bitrate_mode == HDPVR_CONSTANT)
			qc->flags |= V4L2_CTRL_FLAG_INACTIVE;
		return err;
	default:
		return -EINVAL;
	}
}

static int vidioc_queryctrl(struct file *file, void *private_data,
			    struct v4l2_queryctrl *qc)
{
	struct hdpvr_fh *fh = file->private_data;
	struct hdpvr_device *dev = fh->dev;
	int i, next;
	u32 id = qc->id;

	memset(qc, 0, sizeof(*qc));

	next = !!(id &  V4L2_CTRL_FLAG_NEXT_CTRL);
	qc->id = id & ~V4L2_CTRL_FLAG_NEXT_CTRL;

	for (i = 0; i < ARRAY_SIZE(supported_v4l2_ctrls); i++) {
		if (next) {
			if (qc->id < supported_v4l2_ctrls[i])
				qc->id = supported_v4l2_ctrls[i];
			else
				continue;
		}

		if (qc->id == supported_v4l2_ctrls[i])
			return fill_queryctrl(&dev->options, qc,
					      dev->flags & HDPVR_FLAG_AC3_CAP);

		if (qc->id < supported_v4l2_ctrls[i])
			break;
	}

	return -EINVAL;
}

static int vidioc_g_ctrl(struct file *file, void *private_data,
			 struct v4l2_control *ctrl)
{
	struct hdpvr_fh *fh = file->private_data;
	struct hdpvr_device *dev = fh->dev;

	switch (ctrl->id) {
	case V4L2_CID_BRIGHTNESS:
		ctrl->value = dev->options.brightness;
		break;
	case V4L2_CID_CONTRAST:
		ctrl->value = dev->options.contrast;
		break;
	case V4L2_CID_SATURATION:
		ctrl->value = dev->options.saturation;
		break;
	case V4L2_CID_HUE:
		ctrl->value = dev->options.hue;
		break;
	case V4L2_CID_SHARPNESS:
		ctrl->value = dev->options.sharpness;
		break;
	default:
		return -EINVAL;
	}
	return 0;
}

static int vidioc_s_ctrl(struct file *file, void *private_data,
			 struct v4l2_control *ctrl)
{
	struct hdpvr_fh *fh = file->private_data;
	struct hdpvr_device *dev = fh->dev;
	int retval;

	switch (ctrl->id) {
	case V4L2_CID_BRIGHTNESS:
		retval = hdpvr_config_call(dev, CTRL_BRIGHTNESS, ctrl->value);
		if (!retval)
			dev->options.brightness = ctrl->value;
		break;
	case V4L2_CID_CONTRAST:
		retval = hdpvr_config_call(dev, CTRL_CONTRAST, ctrl->value);
		if (!retval)
			dev->options.contrast = ctrl->value;
		break;
	case V4L2_CID_SATURATION:
		retval = hdpvr_config_call(dev, CTRL_SATURATION, ctrl->value);
		if (!retval)
			dev->options.saturation = ctrl->value;
		break;
	case V4L2_CID_HUE:
		retval = hdpvr_config_call(dev, CTRL_HUE, ctrl->value);
		if (!retval)
			dev->options.hue = ctrl->value;
		break;
	case V4L2_CID_SHARPNESS:
		retval = hdpvr_config_call(dev, CTRL_SHARPNESS, ctrl->value);
		if (!retval)
			dev->options.sharpness = ctrl->value;
		break;
	default:
		return -EINVAL;
	}

	return retval;
}


static int hdpvr_get_ctrl(struct hdpvr_options *opt,
			  struct v4l2_ext_control *ctrl)
{
	switch (ctrl->id) {
	case V4L2_CID_MPEG_AUDIO_ENCODING:
		ctrl->value = opt->audio_codec;
		break;
	case V4L2_CID_MPEG_VIDEO_ENCODING:
		ctrl->value = V4L2_MPEG_VIDEO_ENCODING_MPEG_4_AVC;
		break;
/* 	case V4L2_CID_MPEG_VIDEO_B_FRAMES: */
/* 		ctrl->value = (opt->gop_mode & 0x2) ? 0 : 128; */
/* 		break; */
	case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
		ctrl->value = opt->bitrate_mode == HDPVR_CONSTANT
			? V4L2_MPEG_VIDEO_BITRATE_MODE_CBR
			: V4L2_MPEG_VIDEO_BITRATE_MODE_VBR;
		break;
	case V4L2_CID_MPEG_VIDEO_BITRATE:
		ctrl->value = opt->bitrate * 100000;
		break;
	case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK:
		ctrl->value = opt->peak_bitrate * 100000;
		break;
	case V4L2_CID_MPEG_STREAM_TYPE:
		ctrl->value = V4L2_MPEG_STREAM_TYPE_MPEG2_TS;
		break;
	default:
		return -EINVAL;
	}
	return 0;
}

static int vidioc_g_ext_ctrls(struct file *file, void *priv,
			      struct v4l2_ext_controls *ctrls)
{
	struct hdpvr_fh *fh = file->private_data;
	struct hdpvr_device *dev = fh->dev;
	int i, err = 0;

	if (ctrls->ctrl_class == V4L2_CTRL_CLASS_MPEG) {
		for (i = 0; i < ctrls->count; i++) {
			struct v4l2_ext_control *ctrl = ctrls->controls + i;

			err = hdpvr_get_ctrl(&dev->options, ctrl);
			if (err) {
				ctrls->error_idx = i;
				break;
			}
		}
		return err;

	}

	return -EINVAL;
}


static int hdpvr_try_ctrl(struct v4l2_ext_control *ctrl, int ac3)
{
	int ret = -EINVAL;

	switch (ctrl->id) {
	case V4L2_CID_MPEG_AUDIO_ENCODING:
		if (ctrl->value == V4L2_MPEG_AUDIO_ENCODING_AAC ||
		    (ac3 && ctrl->value == V4L2_MPEG_AUDIO_ENCODING_AC3))
			ret = 0;
		break;
	case V4L2_CID_MPEG_VIDEO_ENCODING:
		if (ctrl->value == V4L2_MPEG_VIDEO_ENCODING_MPEG_4_AVC)
			ret = 0;
		break;
/* 	case V4L2_CID_MPEG_VIDEO_B_FRAMES: */
/* 		if (ctrl->value == 0 || ctrl->value == 128) */
/* 			ret = 0; */
/* 		break; */
	case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
		if (ctrl->value == V4L2_MPEG_VIDEO_BITRATE_MODE_CBR ||
		    ctrl->value == V4L2_MPEG_VIDEO_BITRATE_MODE_VBR)
			ret = 0;
		break;
	case V4L2_CID_MPEG_VIDEO_BITRATE:
	{
		uint bitrate = ctrl->value / 100000;
		if (bitrate >= 10 && bitrate <= 135)
			ret = 0;
		break;
	}
	case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK:
	{
		uint peak_bitrate = ctrl->value / 100000;
		if (peak_bitrate >= 10 && peak_bitrate <= 202)
			ret = 0;
		break;
	}
	case V4L2_CID_MPEG_STREAM_TYPE:
		if (ctrl->value == V4L2_MPEG_STREAM_TYPE_MPEG2_TS)
			ret = 0;
		break;
	default:
		return -EINVAL;
	}
	return 0;
}

static int vidioc_try_ext_ctrls(struct file *file, void *priv,
				struct v4l2_ext_controls *ctrls)
{
	struct hdpvr_fh *fh = file->private_data;
	struct hdpvr_device *dev = fh->dev;
	int i, err = 0;

	if (ctrls->ctrl_class == V4L2_CTRL_CLASS_MPEG) {
		for (i = 0; i < ctrls->count; i++) {
			struct v4l2_ext_control *ctrl = ctrls->controls + i;

			err = hdpvr_try_ctrl(ctrl,
					     dev->flags & HDPVR_FLAG_AC3_CAP);
			if (err) {
				ctrls->error_idx = i;
				break;
			}
		}
		return err;
	}

	return -EINVAL;
}


static int hdpvr_set_ctrl(struct hdpvr_device *dev,
			  struct v4l2_ext_control *ctrl)
{
	struct hdpvr_options *opt = &dev->options;
	int ret = 0;

	switch (ctrl->id) {
	case V4L2_CID_MPEG_AUDIO_ENCODING:
		if (dev->flags & HDPVR_FLAG_AC3_CAP) {
			opt->audio_codec = ctrl->value;
			ret = hdpvr_set_audio(dev, opt->audio_input,
					      opt->audio_codec);
		}
		break;
	case V4L2_CID_MPEG_VIDEO_ENCODING:
		break;
/* 	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:
		if (ctrl->value == V4L2_MPEG_VIDEO_BITRATE_MODE_CBR &&
		    opt->bitrate_mode != HDPVR_CONSTANT) {
			opt->bitrate_mode = HDPVR_CONSTANT;
			hdpvr_config_call(dev, CTRL_BITRATE_MODE_VALUE,
					  opt->bitrate_mode);
		}
		if (ctrl->value == V4L2_MPEG_VIDEO_BITRATE_MODE_VBR &&
		    opt->bitrate_mode == HDPVR_CONSTANT) {
			opt->bitrate_mode = HDPVR_VARIABLE_AVERAGE;
			hdpvr_config_call(dev, CTRL_BITRATE_MODE_VALUE,
					  opt->bitrate_mode);
		}
		break;
	case V4L2_CID_MPEG_VIDEO_BITRATE: {
		uint bitrate = ctrl->value / 100000;

		opt->bitrate = bitrate;
		if (bitrate >= opt->peak_bitrate)
			opt->peak_bitrate = bitrate+1;

		hdpvr_set_bitrate(dev);
		break;
	}
	case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK: {
		uint peak_bitrate = ctrl->value / 100000;

		if (opt->bitrate_mode == HDPVR_CONSTANT)
			break;

		if (opt->bitrate < peak_bitrate) {
			opt->peak_bitrate = peak_bitrate;
			hdpvr_set_bitrate(dev);
		} else
			ret = -EINVAL;
		break;
	}
	case V4L2_CID_MPEG_STREAM_TYPE:
		break;
	default:
		return -EINVAL;
	}
	return ret;
}

static int vidioc_s_ext_ctrls(struct file *file, void *priv,
			      struct v4l2_ext_controls *ctrls)
{
	struct hdpvr_fh *fh = file->private_data;
	struct hdpvr_device *dev = fh->dev;
	int i, err = 0;

	if (ctrls->ctrl_class == V4L2_CTRL_CLASS_MPEG) {
		for (i = 0; i < ctrls->count; i++) {
			struct v4l2_ext_control *ctrl = ctrls->controls + i;

			err = hdpvr_try_ctrl(ctrl,
					     dev->flags & HDPVR_FLAG_AC3_CAP);
			if (err) {
				ctrls->error_idx = i;
				break;
			}
			err = hdpvr_set_ctrl(dev, ctrl);
			if (err) {
				ctrls->error_idx = i;
				break;
			}
		}
		return err;

	}

	return -EINVAL;
}

static int vidioc_enum_fmt_vid_cap(struct file *file, void *private_data,
				    struct v4l2_fmtdesc *f)
{

	if (f->index != 0 || f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
		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 *private_data,
				struct v4l2_format *f)
{
	struct hdpvr_fh *fh = file->private_data;
	struct hdpvr_device *dev = fh->dev;
	struct hdpvr_video_info *vid_info;

	if (!dev)
		return -ENODEV;

	vid_info = get_video_info(dev);
	if (!vid_info)
		return -EFAULT;

	f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
	f->fmt.pix.pixelformat	= V4L2_PIX_FMT_MPEG;
	f->fmt.pix.width	= vid_info->width;
	f->fmt.pix.height	= vid_info->height;
	f->fmt.pix.sizeimage	= dev->bulk_in_size;
	f->fmt.pix.colorspace	= 0;
	f->fmt.pix.bytesperline	= 0;
	f->fmt.pix.field	= V4L2_FIELD_ANY;

	kfree(vid_info);
	return 0;
}


static const struct v4l2_ioctl_ops hdpvr_ioctl_ops = {
	.vidioc_querycap	= vidioc_querycap,
	.vidioc_s_std		= vidioc_s_std,
	.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_queryctrl	= vidioc_queryctrl,
	.vidioc_g_ctrl		= vidioc_g_ctrl,
	.vidioc_s_ctrl		= vidioc_s_ctrl,
	.vidioc_g_ext_ctrls	= vidioc_g_ext_ctrls,
	.vidioc_s_ext_ctrls	= vidioc_s_ext_ctrls,
	.vidioc_try_ext_ctrls	= vidioc_try_ext_ctrls,
	.vidioc_enum_fmt_vid_cap	= vidioc_enum_fmt_vid_cap,
	.vidioc_g_fmt_vid_cap		= vidioc_g_fmt_vid_cap,
};

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

	hdpvr_delete(dev);
}

static const struct video_device hdpvr_video_template = {
/* 	.type			= VFL_TYPE_GRABBER, */
/* 	.type2			= VID_TYPE_CAPTURE | VID_TYPE_MPEG_ENCODER, */
	.fops			= &hdpvr_fops,
	.release		= hdpvr_device_release,
	.ioctl_ops 		= &hdpvr_ioctl_ops,
	.tvnorms 		=
		V4L2_STD_NTSC  | V4L2_STD_SECAM | V4L2_STD_PAL_B |
		V4L2_STD_PAL_G | V4L2_STD_PAL_H | V4L2_STD_PAL_I |
		V4L2_STD_PAL_D | V4L2_STD_PAL_M | V4L2_STD_PAL_N |
		V4L2_STD_PAL_60,
};

int hdpvr_register_videodev(struct hdpvr_device *dev, int devnum)
{
	/* setup and register video device */
	dev->video_dev = video_device_alloc();
	if (!dev->video_dev) {
		err("video_device_alloc() failed");
		goto error;
	}

	*(dev->video_dev) = hdpvr_video_template;
	strcpy(dev->video_dev->name, "Hauppauge HD PVR");
	dev->video_dev->parent = &dev->udev->dev;
	video_set_drvdata(dev->video_dev, dev);

	if (video_register_device(dev->video_dev, VFL_TYPE_GRABBER, devnum)) {
		err("V4L2 device registration failed");
		goto error;
	}

	return 0;
error:
	return -ENOMEM;
}
