hdpvr-video.c revision 76717b887cccc77d04357fc0d6ac98f894e3eb3c
19aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau/*
29aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau * Hauppage HD PVR USB driver - video 4 linux 2 interface
39aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau *
49aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau * Copyright (C) 2008      Janne Grunau (j@jannau.net)
59aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau *
69aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau *	This program is free software; you can redistribute it and/or
79aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau *	modify it under the terms of the GNU General Public License as
89aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau *	published by the Free Software Foundation, version 2.
99aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau *
109aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau */
119aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
129aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau#include <linux/kernel.h>
139aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau#include <linux/errno.h>
149aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau#include <linux/init.h>
159aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau#include <linux/slab.h>
169aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau#include <linux/module.h>
179aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau#include <linux/uaccess.h>
189aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau#include <linux/usb.h>
199aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau#include <linux/mutex.h>
209aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau#include <linux/version.h>
219aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau#include <linux/workqueue.h>
229aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
239aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau#include <linux/videodev2.h>
249aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau#include <media/v4l2-dev.h>
259aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau#include <media/v4l2-common.h>
269aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau#include <media/v4l2-ioctl.h>
279aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau#include "hdpvr.h"
289aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
299aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau#define BULK_URB_TIMEOUT 1250 /* 1.25 seconds */
309aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
319aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunaustruct hdpvr_fh {
329aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	struct hdpvr_device	*dev;
339aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau};
349aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
359aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunaustatic uint list_size(struct list_head *list)
369aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau{
379aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	struct list_head *tmp;
389aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	uint count = 0;
399aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
409aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	list_for_each(tmp, list) {
419aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		count++;
429aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	}
439aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
449aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	return count;
459aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau}
469aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
479aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau/*=========================================================================*/
489aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau/* urb callback */
499aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunaustatic void hdpvr_read_bulk_callback(struct urb *urb)
509aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau{
519aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	struct hdpvr_buffer *buf = (struct hdpvr_buffer *)urb->context;
529aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	struct hdpvr_device *dev = buf->dev;
539aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
549aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	/* marking buffer as received and wake waiting */
559aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	buf->status = BUFSTAT_READY;
569aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	wake_up_interruptible(&dev->wait_data);
579aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau}
589aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
599aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau/*=========================================================================*/
609aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau/* bufffer bits */
619aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
629aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau/* function expects dev->io_mutex to be hold by caller */
639aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunauint hdpvr_cancel_queue(struct hdpvr_device *dev)
649aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau{
659aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	struct hdpvr_buffer *buf;
669aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
679aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	list_for_each_entry(buf, &dev->rec_buff_list, buff_list) {
689aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		usb_kill_urb(buf->urb);
699aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		buf->status = BUFSTAT_AVAILABLE;
709aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	}
719aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
729aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	list_splice_init(&dev->rec_buff_list, dev->free_buff_list.prev);
739aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
749aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	return 0;
759aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau}
769aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
779aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunaustatic int hdpvr_free_queue(struct list_head *q)
789aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau{
799aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	struct list_head *tmp;
809aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	struct list_head *p;
819aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	struct hdpvr_buffer *buf;
829aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	struct urb *urb;
839aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
849aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	for (p = q->next; p != q;) {
859aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		buf = list_entry(p, struct hdpvr_buffer, buff_list);
869aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
879aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		urb = buf->urb;
889aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		usb_buffer_free(urb->dev, urb->transfer_buffer_length,
899aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau				urb->transfer_buffer, urb->transfer_dma);
909aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		usb_free_urb(urb);
919aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		tmp = p->next;
929aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		list_del(p);
939aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		kfree(buf);
949aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		p = tmp;
959aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	}
969aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
979aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	return 0;
989aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau}
999aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
1009aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau/* function expects dev->io_mutex to be hold by caller */
1019aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunauint hdpvr_free_buffers(struct hdpvr_device *dev)
1029aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau{
1039aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	hdpvr_cancel_queue(dev);
1049aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
1059aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	hdpvr_free_queue(&dev->free_buff_list);
1069aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	hdpvr_free_queue(&dev->rec_buff_list);
1079aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
1089aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	return 0;
1099aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau}
1109aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
1119aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau/* function expects dev->io_mutex to be hold by caller */
1129aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunauint hdpvr_alloc_buffers(struct hdpvr_device *dev, uint count)
1139aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau{
1149aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	uint i;
1159aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	int retval = -ENOMEM;
1169aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	u8 *mem;
1179aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	struct hdpvr_buffer *buf;
1189aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	struct urb *urb;
1199aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
1209aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	v4l2_dbg(MSG_INFO, hdpvr_debug, dev->video_dev,
1219aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		 "allocating %u buffers\n", count);
1229aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
1239aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	for (i = 0; i < count; i++) {
1249aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
1259aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		buf = kzalloc(sizeof(struct hdpvr_buffer), GFP_KERNEL);
1269aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		if (!buf) {
1279aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			err("cannot allocate buffer");
1289aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			goto exit;
1299aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		}
1309aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		buf->dev = dev;
1319aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
1329aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		urb = usb_alloc_urb(0, GFP_KERNEL);
1339aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		if (!urb) {
1349aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			err("cannot allocate urb");
1359aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			goto exit;
1369aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		}
1379aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		buf->urb = urb;
1389aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
1399aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		mem = usb_buffer_alloc(dev->udev, dev->bulk_in_size, GFP_KERNEL,
1409aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau				       &urb->transfer_dma);
1419aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		if (!mem) {
1429aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			err("cannot allocate usb transfer buffer");
1439aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			goto exit;
1449aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		}
1459aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
1469aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		usb_fill_bulk_urb(buf->urb, dev->udev,
1479aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau				  usb_rcvbulkpipe(dev->udev,
1489aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau						  dev->bulk_in_endpointAddr),
1499aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau				  mem, dev->bulk_in_size,
1509aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau				  hdpvr_read_bulk_callback, buf);
1519aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
1529aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		buf->status = BUFSTAT_AVAILABLE;
1539aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		list_add_tail(&buf->buff_list, &dev->free_buff_list);
1549aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	}
1559aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	return 0;
1569aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunauexit:
1579aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	hdpvr_free_buffers(dev);
1589aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	return retval;
1599aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau}
1609aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
1619aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunaustatic int hdpvr_submit_buffers(struct hdpvr_device *dev)
1629aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau{
1639aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	struct hdpvr_buffer *buf;
1649aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	struct urb *urb;
1659aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	int ret = 0, err_count = 0;
1669aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
1679aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	mutex_lock(&dev->io_mutex);
1689aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
1699aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	while (dev->status == STATUS_STREAMING &&
1709aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	       !list_empty(&dev->free_buff_list)) {
1719aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
1729aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		buf = list_entry(dev->free_buff_list.next, struct hdpvr_buffer,
1739aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau				 buff_list);
1749aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		if (buf->status != BUFSTAT_AVAILABLE) {
1759aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			err("buffer not marked as availbale");
1769aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			ret = -EFAULT;
1779aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			goto err;
1789aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		}
1799aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
1809aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		urb = buf->urb;
1819aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		urb->status = 0;
1829aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		urb->actual_length = 0;
1839aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		ret = usb_submit_urb(urb, GFP_KERNEL);
1849aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		if (ret) {
1859aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			err("usb_submit_urb in %s returned %d", __func__, ret);
1869aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			if (++err_count > 2)
1879aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau				break;
1889aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			continue;
1899aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		}
1909aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		buf->status = BUFSTAT_INPROGRESS;
1919aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		list_move_tail(&buf->buff_list, &dev->rec_buff_list);
1929aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	}
1939aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunauerr:
1949aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	v4l2_dbg(MSG_BUFFER, hdpvr_debug, dev->video_dev,
1959aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		 "buffer queue stat: %d free, %d proc\n",
1969aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		 list_size(&dev->free_buff_list),
1979aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		 list_size(&dev->rec_buff_list));
1989aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	mutex_unlock(&dev->io_mutex);
1999aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	return ret;
2009aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau}
2019aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
2029aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunaustatic struct hdpvr_buffer *hdpvr_get_next_buffer(struct hdpvr_device *dev)
2039aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau{
2049aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	struct hdpvr_buffer *buf;
2059aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
2069aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	mutex_lock(&dev->io_mutex);
2079aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
2089aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	if (list_empty(&dev->rec_buff_list)) {
2099aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		mutex_unlock(&dev->io_mutex);
2109aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		return NULL;
2119aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	}
2129aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
2139aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	buf = list_entry(dev->rec_buff_list.next, struct hdpvr_buffer,
2149aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			 buff_list);
2159aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	mutex_unlock(&dev->io_mutex);
2169aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
2179aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	return buf;
2189aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau}
2199aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
2209aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunaustatic void hdpvr_transmit_buffers(struct work_struct *work)
2219aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau{
2229aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	struct hdpvr_device *dev = container_of(work, struct hdpvr_device,
2239aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau						worker);
2249aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
2259aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	while (dev->status == STATUS_STREAMING) {
2269aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
2279aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		if (hdpvr_submit_buffers(dev)) {
2289aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			v4l2_err(dev->video_dev, "couldn't submit buffers\n");
2299aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			goto error;
2309aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		}
2319aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		if (wait_event_interruptible(dev->wait_buffer,
2329aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau				!list_empty(&dev->free_buff_list) ||
2339aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau					     dev->status != STATUS_STREAMING))
2349aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			goto error;
2359aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	}
2369aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
2379aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	v4l2_dbg(MSG_INFO, hdpvr_debug, dev->video_dev,
2389aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		 "transmit worker exited\n");
2399aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	return;
2409aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunauerror:
2419aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	v4l2_dbg(MSG_INFO, hdpvr_debug, dev->video_dev,
2429aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		 "transmit buffers errored\n");
2439aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	dev->status = STATUS_ERROR;
2449aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau}
2459aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
2469aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau/* function expects dev->io_mutex to be hold by caller */
2479aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunaustatic int hdpvr_start_streaming(struct hdpvr_device *dev)
2489aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau{
2499aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	int ret;
2509aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	struct hdpvr_video_info *vidinf;
2519aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
2529aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	if (dev->status == STATUS_STREAMING)
2539aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		return 0;
2549aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	else if (dev->status != STATUS_IDLE)
2559aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		return -EAGAIN;
2569aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
2579aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	vidinf = get_video_info(dev);
2589aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
2599aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	if (vidinf) {
2609aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		v4l2_dbg(MSG_BUFFER, hdpvr_debug, dev->video_dev,
2619aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			 "video signal: %dx%d@%dhz\n", vidinf->width,
2629aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			 vidinf->height, vidinf->fps);
2639aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		kfree(vidinf);
2649aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
2659aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		/* start streaming 2 request */
2669aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		ret = usb_control_msg(dev->udev,
2679aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau				      usb_sndctrlpipe(dev->udev, 0),
2689aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau				      0xb8, 0x38, 0x1, 0, NULL, 0, 8000);
2699aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		v4l2_dbg(MSG_BUFFER, hdpvr_debug, dev->video_dev,
2709aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			 "encoder start control request returned %d\n", ret);
2719aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
2729aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		hdpvr_config_call(dev, CTRL_START_STREAMING_VALUE, 0x00);
2739aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
2749aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		INIT_WORK(&dev->worker, hdpvr_transmit_buffers);
2759aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		queue_work(dev->workqueue, &dev->worker);
2769aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
2779aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		v4l2_dbg(MSG_BUFFER, hdpvr_debug, dev->video_dev,
2789aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			 "streaming started\n");
2799aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		dev->status = STATUS_STREAMING;
2809aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
2819aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		return 0;
2829aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	}
2839aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	msleep(250);
2849aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	v4l2_dbg(MSG_INFO, hdpvr_debug, dev->video_dev,
2859aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		 "no video signal at input %d\n", dev->options.video_input);
2869aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	return -EAGAIN;
2879aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau}
2889aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
2899aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
2909aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau/* function expects dev->io_mutex to be hold by caller */
2919aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunaustatic int hdpvr_stop_streaming(struct hdpvr_device *dev)
2929aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau{
2939aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	if (dev->status == STATUS_IDLE)
2949aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		return 0;
2959aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	else if (dev->status != STATUS_STREAMING)
2969aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		return -EAGAIN;
2979aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
2989aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	dev->status = STATUS_SHUTTING_DOWN;
2999aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	hdpvr_config_call(dev, CTRL_STOP_STREAMING_VALUE, 0x00);
3009aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
3019aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	wake_up_interruptible(&dev->wait_buffer);
3029aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	msleep(50);
3039aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
3049aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	flush_workqueue(dev->workqueue);
3059aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
3069aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	/* kill the still outstanding urbs */
3079aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	hdpvr_cancel_queue(dev);
3089aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
3099aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	dev->status = STATUS_IDLE;
3109aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
3119aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	return 0;
3129aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau}
3139aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
3149aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
3159aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau/*=======================================================================*/
3169aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau/*
3179aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau * video 4 linux 2 file operations
3189aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau */
3199aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
3209aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunaustatic int hdpvr_open(struct file *file)
3219aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau{
3229aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	struct hdpvr_device *dev;
3239aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	struct hdpvr_fh *fh;
3249aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	int retval = -ENOMEM;
3259aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
3269aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	dev = (struct hdpvr_device *)video_get_drvdata(video_devdata(file));
3279aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	if (!dev) {
3289aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		err("open failing with with ENODEV");
3299aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		retval = -ENODEV;
3309aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		goto err;
3319aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	}
3329aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
3339aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	fh = kzalloc(sizeof(struct hdpvr_fh), GFP_KERNEL);
3349aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	if (!fh) {
3359aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		err("Out of memory?");
3369aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		goto err;
3379aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	}
3389aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	/* lock the device to allow correctly handling errors
3399aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	 * in resumption */
3409aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	mutex_lock(&dev->io_mutex);
3419aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	dev->open_count++;
3429aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
3439aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	fh->dev = dev;
3449aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
3459aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	/* save our object in the file's private structure */
3469aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	file->private_data = fh;
3479aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
3489aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	retval = 0;
3499aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunauerr:
3509aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	mutex_unlock(&dev->io_mutex);
3519aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	return retval;
3529aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau}
3539aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
3549aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunaustatic int hdpvr_release(struct file *file)
3559aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau{
3569aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	struct hdpvr_fh		*fh  = (struct hdpvr_fh *)file->private_data;
3579aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	struct hdpvr_device	*dev = fh->dev;
3589aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
3599aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	if (!dev)
3609aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		return -ENODEV;
3619aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
3629aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	mutex_lock(&dev->io_mutex);
3639aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	if (!(--dev->open_count) && dev->status == STATUS_STREAMING)
3649aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		hdpvr_stop_streaming(dev);
3659aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
3669aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	mutex_unlock(&dev->io_mutex);
3679aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
3689aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	return 0;
3699aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau}
3709aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
3719aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau/*
3729aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau * hdpvr_v4l2_read()
3739aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau * will allocate buffers when called for the first time
3749aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau */
3759aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunaustatic ssize_t hdpvr_read(struct file *file, char __user *buffer, size_t count,
3769aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			  loff_t *pos)
3779aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau{
3789aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	struct hdpvr_fh *fh = file->private_data;
3799aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	struct hdpvr_device *dev = fh->dev;
3809aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	struct hdpvr_buffer *buf = NULL;
3819aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	struct urb *urb;
3829aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	unsigned int ret = 0;
3839aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	int rem, cnt;
3849aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
3859aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	if (*pos)
3869aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		return -ESPIPE;
3879aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
3889aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	if (!dev)
3899aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		return -ENODEV;
3909aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
3919aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	mutex_lock(&dev->io_mutex);
3929aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	if (dev->status == STATUS_IDLE) {
3939aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		if (hdpvr_start_streaming(dev)) {
3949aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			v4l2_dbg(MSG_INFO, hdpvr_debug, dev->video_dev,
3959aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau				 "start_streaming failed");
3969aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			ret = -EIO;
3979aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			msleep(200);
3989aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			dev->status = STATUS_IDLE;
3999aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			mutex_unlock(&dev->io_mutex);
4009aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			goto err;
4019aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		}
4029aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
4039aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		v4l2_dbg(MSG_BUFFER, hdpvr_debug, dev->video_dev,
4049aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			 "buffer queue stat: %d free, %d proc\n",
4059aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			 list_size(&dev->free_buff_list),
4069aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			 list_size(&dev->rec_buff_list));
4079aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	}
4089aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	mutex_unlock(&dev->io_mutex);
4099aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
4109aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	/* wait for the first buffer */
4119aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	if (!(file->f_flags & O_NONBLOCK)) {
4129aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		if (wait_event_interruptible(dev->wait_data,
4139aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau					     hdpvr_get_next_buffer(dev)))
4149aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			return -ERESTARTSYS;
4159aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	}
4169aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
4179aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	buf = hdpvr_get_next_buffer(dev);
4189aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
4199aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	while (count > 0 && buf) {
4209aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
4219aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		if (buf->status != BUFSTAT_READY &&
4229aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		    dev->status != STATUS_DISCONNECTED) {
4239aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			/* return nonblocking */
4249aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			if (file->f_flags & O_NONBLOCK) {
4259aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau				if (!ret)
4269aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau					ret = -EAGAIN;
4279aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau				goto err;
4289aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			}
4299aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
4309aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			if (wait_event_interruptible(dev->wait_data,
4319aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau					      buf->status == BUFSTAT_READY)) {
4329aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau				ret = -ERESTARTSYS;
4339aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau				goto err;
4349aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			}
4359aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		}
4369aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
4379aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		if (buf->status != BUFSTAT_READY)
4389aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			break;
4399aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
4409aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		/* set remaining bytes to copy */
4419aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		urb = buf->urb;
4429aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		rem = urb->actual_length - buf->pos;
4439aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		cnt = rem > count ? count : rem;
4449aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
4459aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		if (copy_to_user(buffer, urb->transfer_buffer + buf->pos,
4469aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau				 cnt)) {
4479aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			err("read: copy_to_user failed");
4489aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			if (!ret)
4499aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau				ret = -EFAULT;
4509aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			goto err;
4519aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		}
4529aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
4539aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		buf->pos += cnt;
4549aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		count -= cnt;
4559aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		buffer += cnt;
4569aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		ret += cnt;
4579aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
4589aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		/* finished, take next buffer */
4599aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		if (buf->pos == urb->actual_length) {
4609aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			mutex_lock(&dev->io_mutex);
4619aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			buf->pos = 0;
4629aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			buf->status = BUFSTAT_AVAILABLE;
4639aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
4649aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			list_move_tail(&buf->buff_list, &dev->free_buff_list);
4659aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
4669aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			v4l2_dbg(MSG_BUFFER, hdpvr_debug, dev->video_dev,
4679aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau				 "buffer queue stat: %d free, %d proc\n",
4689aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau				 list_size(&dev->free_buff_list),
4699aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau				 list_size(&dev->rec_buff_list));
4709aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
4719aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			mutex_unlock(&dev->io_mutex);
4729aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
4739aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			wake_up_interruptible(&dev->wait_buffer);
4749aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
4759aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			buf = hdpvr_get_next_buffer(dev);
4769aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		}
4779aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	}
4789aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunauerr:
4799aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	if (!ret && !buf)
4809aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		ret = -EAGAIN;
4819aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	return ret;
4829aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau}
4839aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
4849aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunaustatic unsigned int hdpvr_poll(struct file *filp, poll_table *wait)
4859aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau{
4869aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	struct hdpvr_fh *fh = (struct hdpvr_fh *)filp->private_data;
4879aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	struct hdpvr_device *dev = fh->dev;
4889aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	unsigned int mask = 0;
4899aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
4909aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	mutex_lock(&dev->io_mutex);
4919aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
4929aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	if (video_is_unregistered(dev->video_dev))
4939aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		return -EIO;
4949aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
4959aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	if (dev->status == STATUS_IDLE) {
4969aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		if (hdpvr_start_streaming(dev)) {
4979aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			v4l2_dbg(MSG_BUFFER, hdpvr_debug, dev->video_dev,
4989aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau				 "start_streaming failed");
4999aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			dev->status = STATUS_IDLE;
5009aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		}
5019aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
5029aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		v4l2_dbg(MSG_BUFFER, hdpvr_debug, dev->video_dev,
5039aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			 "buffer queue stat: %d free, %d proc\n",
5049aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			 list_size(&dev->free_buff_list),
5059aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			 list_size(&dev->rec_buff_list));
5069aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	}
5079aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	mutex_unlock(&dev->io_mutex);
5089aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
5099aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	poll_wait(filp, &dev->wait_data, wait);
5109aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
5119aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	mutex_lock(&dev->io_mutex);
5129aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	if (!list_empty(&dev->rec_buff_list)) {
5139aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
5149aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		struct hdpvr_buffer *buf = list_entry(dev->rec_buff_list.next,
5159aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau						      struct hdpvr_buffer,
5169aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau						      buff_list);
5179aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
5189aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		if (buf->status == BUFSTAT_READY)
5199aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			mask |= POLLIN | POLLRDNORM;
5209aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	}
5219aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	mutex_unlock(&dev->io_mutex);
5229aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
5239aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	return mask;
5249aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau}
5259aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
5269aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
5279aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunaustatic const struct v4l2_file_operations hdpvr_fops = {
5289aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	.owner		= THIS_MODULE,
5299aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	.open		= hdpvr_open,
5309aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	.release	= hdpvr_release,
5319aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	.read		= hdpvr_read,
5329aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	.poll		= hdpvr_poll,
53376717b887cccc77d04357fc0d6ac98f894e3eb3cJanne Grunau	.unlocked_ioctl	= video_ioctl2,
5349aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau};
5359aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
5369aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau/*=======================================================================*/
5379aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau/*
5389aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau * V4L2 ioctl handling
5399aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau */
5409aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
5419aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunaustatic int vidioc_querycap(struct file *file, void  *priv,
5429aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			   struct v4l2_capability *cap)
5439aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau{
5449aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	struct hdpvr_device *dev = video_drvdata(file);
5459aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
5469aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	strcpy(cap->driver, "hdpvr");
5479aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	strcpy(cap->card, "Haupauge HD PVR");
5489aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	usb_make_path(dev->udev, cap->bus_info, sizeof(cap->bus_info));
5499aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	cap->version = HDPVR_VERSION;
5509aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	cap->capabilities =     V4L2_CAP_VIDEO_CAPTURE |
5519aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau				V4L2_CAP_AUDIO         |
5529aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau				V4L2_CAP_READWRITE;
5539aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	return 0;
5549aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau}
5559aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
5569aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunaustatic int vidioc_s_std(struct file *file, void *private_data,
5579aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			v4l2_std_id *std)
5589aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau{
5599aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	struct hdpvr_fh *fh = file->private_data;
5609aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	struct hdpvr_device *dev = fh->dev;
5619aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	u8 std_type = 1;
5629aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
5639aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	if (*std & (V4L2_STD_NTSC | V4L2_STD_PAL_60))
5649aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		std_type = 0;
5659aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
5669aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	return hdpvr_config_call(dev, CTRL_VIDEO_STD_TYPE, std_type);
5679aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau}
5689aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
5699aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunaustatic const char *iname[] = {
5709aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	[HDPVR_COMPONENT] = "Component",
5719aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	[HDPVR_SVIDEO]    = "S-Video",
5729aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	[HDPVR_COMPOSITE] = "Composite",
5739aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau};
5749aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
5759aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunaustatic int vidioc_enum_input(struct file *file, void *priv,
5769aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau				struct v4l2_input *i)
5779aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau{
5789aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	struct hdpvr_fh *fh = file->private_data;
5799aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	struct hdpvr_device *dev = fh->dev;
5809aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	unsigned int n;
5819aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
5829aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	n = i->index;
5839aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	if (n >= HDPVR_VIDEO_INPUTS)
5849aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		return -EINVAL;
5859aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
5869aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	i->type = V4L2_INPUT_TYPE_CAMERA;
5879aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
5889aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	strncpy(i->name, iname[n], sizeof(i->name) - 1);
5899aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	i->name[sizeof(i->name) - 1] = '\0';
5909aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
5919aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	i->audioset = 1<<HDPVR_RCA_FRONT | 1<<HDPVR_RCA_BACK | 1<<HDPVR_SPDIF;
5929aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
5939aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	i->std = dev->video_dev->tvnorms;
5949aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
5959aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	return 0;
5969aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau}
5979aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
5989aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunaustatic int vidioc_s_input(struct file *file, void *private_data,
5999aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			  unsigned int index)
6009aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau{
6019aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	struct hdpvr_fh *fh = file->private_data;
6029aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	struct hdpvr_device *dev = fh->dev;
6039aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	int retval;
6049aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
6059aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	if (index >= HDPVR_VIDEO_INPUTS)
6069aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		return -EINVAL;
6079aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
6089aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	if (dev->status != STATUS_IDLE)
6099aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		return -EAGAIN;
6109aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
6119aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	retval = hdpvr_config_call(dev, CTRL_VIDEO_INPUT_VALUE, index+1);
6129aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	if (!retval)
6139aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		dev->options.video_input = index;
6149aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
6159aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	return retval;
6169aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau}
6179aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
6189aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunaustatic int vidioc_g_input(struct file *file, void *private_data,
6199aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			  unsigned int *index)
6209aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau{
6219aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	struct hdpvr_fh *fh = file->private_data;
6229aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	struct hdpvr_device *dev = fh->dev;
6239aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
6249aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	*index = dev->options.video_input;
6259aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	return 0;
6269aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau}
6279aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
6289aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
6299aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunaustatic const char *audio_iname[] = {
6309aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	[HDPVR_RCA_FRONT] = "RCA front",
6319aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	[HDPVR_RCA_BACK]  = "RCA back",
6329aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	[HDPVR_SPDIF]     = "SPDIF",
6339aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau};
6349aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
6359aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunaustatic int vidioc_enumaudio(struct file *file, void *priv,
6369aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau				struct v4l2_audio *audio)
6379aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau{
6389aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	unsigned int n;
6399aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
6409aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	n = audio->index;
6419aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	if (n >= HDPVR_AUDIO_INPUTS)
6429aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		return -EINVAL;
6439aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
6449aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	audio->capability = V4L2_AUDCAP_STEREO;
6459aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
6469aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	strncpy(audio->name, audio_iname[n], sizeof(audio->name) - 1);
6479aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	audio->name[sizeof(audio->name) - 1] = '\0';
6489aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
6499aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	return 0;
6509aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau}
6519aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
6529aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunaustatic int vidioc_s_audio(struct file *file, void *private_data,
6539aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			  struct v4l2_audio *audio)
6549aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau{
6559aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	struct hdpvr_fh *fh = file->private_data;
6569aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	struct hdpvr_device *dev = fh->dev;
6579aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	int retval;
6589aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
6599aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	if (audio->index >= HDPVR_AUDIO_INPUTS)
6609aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		return -EINVAL;
6619aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
6629aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	if (dev->status != STATUS_IDLE)
6639aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		return -EAGAIN;
6649aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
6659aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	retval = hdpvr_set_audio(dev, audio->index+1, dev->options.audio_codec);
6669aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	if (!retval)
6679aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		dev->options.audio_input = audio->index;
6689aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
6699aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	return retval;
6709aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau}
6719aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
6729aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunaustatic int vidioc_g_audio(struct file *file, void *private_data,
6739aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			  struct v4l2_audio *audio)
6749aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau{
6759aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	struct hdpvr_fh *fh = file->private_data;
6769aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	struct hdpvr_device *dev = fh->dev;
6779aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
6789aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	audio->index = dev->options.audio_input;
6799aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	audio->capability = V4L2_AUDCAP_STEREO;
6809aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	strncpy(audio->name, audio_iname[audio->index], sizeof(audio->name));
6819aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	audio->name[sizeof(audio->name) - 1] = '\0';
6829aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	return 0;
6839aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau}
6849aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
6859aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunaustatic const s32 supported_v4l2_ctrls[] = {
6869aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	V4L2_CID_BRIGHTNESS,
6879aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	V4L2_CID_CONTRAST,
6889aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	V4L2_CID_SATURATION,
6899aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	V4L2_CID_HUE,
6909aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	V4L2_CID_SHARPNESS,
6919aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	V4L2_CID_MPEG_AUDIO_ENCODING,
6929aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	V4L2_CID_MPEG_VIDEO_ENCODING,
6939aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	V4L2_CID_MPEG_VIDEO_BITRATE_MODE,
6949aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	V4L2_CID_MPEG_VIDEO_BITRATE,
6959aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	V4L2_CID_MPEG_VIDEO_BITRATE_PEAK,
6969aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau};
6979aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
6989aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunaustatic int fill_queryctrl(struct hdpvr_options *opt, struct v4l2_queryctrl *qc,
6999aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			  int ac3)
7009aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau{
7019aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	int err;
7029aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
7039aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	switch (qc->id) {
7049aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	case V4L2_CID_BRIGHTNESS:
7059aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		return v4l2_ctrl_query_fill(qc, 0x0, 0xff, 1, 0x86);
7069aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	case V4L2_CID_CONTRAST:
7079aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		return v4l2_ctrl_query_fill(qc, 0x0, 0xff, 1, 0x80);
7089aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	case V4L2_CID_SATURATION:
7099aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		return v4l2_ctrl_query_fill(qc, 0x0, 0xff, 1, 0x80);
7109aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	case V4L2_CID_HUE:
7119aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		return v4l2_ctrl_query_fill(qc, 0x0, 0xff, 1, 0x80);
7129aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	case V4L2_CID_SHARPNESS:
7139aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		return v4l2_ctrl_query_fill(qc, 0x0, 0xff, 1, 0x80);
7149aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	case V4L2_CID_MPEG_AUDIO_ENCODING:
7159aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		return v4l2_ctrl_query_fill(
7169aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			qc, V4L2_MPEG_AUDIO_ENCODING_AAC,
7179aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			ac3 ? V4L2_MPEG_AUDIO_ENCODING_AC3
7189aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			: V4L2_MPEG_AUDIO_ENCODING_AAC,
7199aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			1, V4L2_MPEG_AUDIO_ENCODING_AAC);
7209aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	case V4L2_CID_MPEG_VIDEO_ENCODING:
7219aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		return v4l2_ctrl_query_fill(
7229aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			qc, V4L2_MPEG_VIDEO_ENCODING_MPEG_4_AVC,
7239aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			V4L2_MPEG_VIDEO_ENCODING_MPEG_4_AVC, 1,
7249aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			V4L2_MPEG_VIDEO_ENCODING_MPEG_4_AVC);
7259aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
7269aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau/* 	case V4L2_CID_MPEG_VIDEO_? maybe keyframe interval: */
7279aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau/* 		return v4l2_ctrl_query_fill(qc, 0, 128, 128, 0); */
7289aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
7299aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		return v4l2_ctrl_query_fill(
7309aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			qc, V4L2_MPEG_VIDEO_BITRATE_MODE_VBR,
7319aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			V4L2_MPEG_VIDEO_BITRATE_MODE_CBR, 1,
7329aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			V4L2_MPEG_VIDEO_BITRATE_MODE_CBR);
7339aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
7349aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	case V4L2_CID_MPEG_VIDEO_BITRATE:
7359aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		return v4l2_ctrl_query_fill(qc, 1000000, 13500000, 100000,
7369aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau					    6500000);
7379aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK:
7389aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		err = v4l2_ctrl_query_fill(qc, 1100000, 20200000, 100000,
7399aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau					   9000000);
7409aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		if (!err && opt->bitrate_mode == HDPVR_CONSTANT)
7419aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			qc->flags |= V4L2_CTRL_FLAG_INACTIVE;
7429aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		return err;
7439aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	default:
7449aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		return -EINVAL;
7459aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	}
7469aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau}
7479aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
7489aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunaustatic int vidioc_queryctrl(struct file *file, void *private_data,
7499aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			    struct v4l2_queryctrl *qc)
7509aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau{
7519aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	struct hdpvr_fh *fh = file->private_data;
7529aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	struct hdpvr_device *dev = fh->dev;
7539aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	int i, next;
7549aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	u32 id = qc->id;
7559aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
7569aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	memset(qc, 0, sizeof(*qc));
7579aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
7589aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	next = !!(id &  V4L2_CTRL_FLAG_NEXT_CTRL);
7599aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	qc->id = id & ~V4L2_CTRL_FLAG_NEXT_CTRL;
7609aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
7619aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	for (i = 0; i < ARRAY_SIZE(supported_v4l2_ctrls); i++) {
7629aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		if (next) {
7639aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			if (qc->id < supported_v4l2_ctrls[i])
7649aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau				qc->id = supported_v4l2_ctrls[i];
7659aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			else
7669aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau				continue;
7679aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		}
7689aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
7699aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		if (qc->id == supported_v4l2_ctrls[i])
7709aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			return fill_queryctrl(&dev->options, qc,
7719aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau					      dev->flags & HDPVR_FLAG_AC3_CAP);
7729aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
7739aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		if (qc->id < supported_v4l2_ctrls[i])
7749aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			break;
7759aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	}
7769aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
7779aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	return -EINVAL;
7789aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau}
7799aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
7809aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunaustatic int vidioc_g_ctrl(struct file *file, void *private_data,
7819aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			 struct v4l2_control *ctrl)
7829aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau{
7839aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	struct hdpvr_fh *fh = file->private_data;
7849aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	struct hdpvr_device *dev = fh->dev;
7859aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
7869aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	switch (ctrl->id) {
7879aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	case V4L2_CID_BRIGHTNESS:
7889aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		ctrl->value = dev->options.brightness;
7899aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		break;
7909aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	case V4L2_CID_CONTRAST:
7919aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		ctrl->value = dev->options.contrast;
7929aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		break;
7939aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	case V4L2_CID_SATURATION:
7949aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		ctrl->value = dev->options.saturation;
7959aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		break;
7969aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	case V4L2_CID_HUE:
7979aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		ctrl->value = dev->options.hue;
7989aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		break;
7999aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	case V4L2_CID_SHARPNESS:
8009aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		ctrl->value = dev->options.sharpness;
8019aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		break;
8029aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	default:
8039aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		return -EINVAL;
8049aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	}
8059aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	return 0;
8069aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau}
8079aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
8089aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunaustatic int vidioc_s_ctrl(struct file *file, void *private_data,
8099aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			 struct v4l2_control *ctrl)
8109aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau{
8119aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	struct hdpvr_fh *fh = file->private_data;
8129aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	struct hdpvr_device *dev = fh->dev;
8139aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	int retval;
8149aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
8159aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	switch (ctrl->id) {
8169aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	case V4L2_CID_BRIGHTNESS:
8179aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		retval = hdpvr_config_call(dev, CTRL_BRIGHTNESS, ctrl->value);
8189aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		if (!retval)
8199aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			dev->options.brightness = ctrl->value;
8209aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		break;
8219aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	case V4L2_CID_CONTRAST:
8229aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		retval = hdpvr_config_call(dev, CTRL_CONTRAST, ctrl->value);
8239aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		if (!retval)
8249aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			dev->options.contrast = ctrl->value;
8259aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		break;
8269aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	case V4L2_CID_SATURATION:
8279aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		retval = hdpvr_config_call(dev, CTRL_SATURATION, ctrl->value);
8289aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		if (!retval)
8299aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			dev->options.saturation = ctrl->value;
8309aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		break;
8319aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	case V4L2_CID_HUE:
8329aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		retval = hdpvr_config_call(dev, CTRL_HUE, ctrl->value);
8339aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		if (!retval)
8349aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			dev->options.hue = ctrl->value;
8359aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		break;
8369aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	case V4L2_CID_SHARPNESS:
8379aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		retval = hdpvr_config_call(dev, CTRL_SHARPNESS, ctrl->value);
8389aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		if (!retval)
8399aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			dev->options.sharpness = ctrl->value;
8409aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		break;
8419aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	default:
8429aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		return -EINVAL;
8439aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	}
8449aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
8459aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	return retval;
8469aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau}
8479aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
8489aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
8499aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunaustatic int hdpvr_get_ctrl(struct hdpvr_options *opt,
8509aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			  struct v4l2_ext_control *ctrl)
8519aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau{
8529aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	switch (ctrl->id) {
8539aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	case V4L2_CID_MPEG_AUDIO_ENCODING:
8549aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		ctrl->value = opt->audio_codec;
8559aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		break;
8569aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	case V4L2_CID_MPEG_VIDEO_ENCODING:
8579aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		ctrl->value = V4L2_MPEG_VIDEO_ENCODING_MPEG_4_AVC;
8589aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		break;
8599aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau/* 	case V4L2_CID_MPEG_VIDEO_B_FRAMES: */
8609aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau/* 		ctrl->value = (opt->gop_mode & 0x2) ? 0 : 128; */
8619aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau/* 		break; */
8629aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
8639aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		ctrl->value = opt->bitrate_mode == HDPVR_CONSTANT
8649aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			? V4L2_MPEG_VIDEO_BITRATE_MODE_CBR
8659aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			: V4L2_MPEG_VIDEO_BITRATE_MODE_VBR;
8669aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		break;
8679aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	case V4L2_CID_MPEG_VIDEO_BITRATE:
8689aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		ctrl->value = opt->bitrate * 100000;
8699aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		break;
8709aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK:
8719aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		ctrl->value = opt->peak_bitrate * 100000;
8729aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		break;
8739aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	case V4L2_CID_MPEG_STREAM_TYPE:
8749aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		ctrl->value = V4L2_MPEG_STREAM_TYPE_MPEG2_TS;
8759aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		break;
8769aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	default:
8779aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		return -EINVAL;
8789aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	}
8799aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	return 0;
8809aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau}
8819aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
8829aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunaustatic int vidioc_g_ext_ctrls(struct file *file, void *priv,
8839aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			      struct v4l2_ext_controls *ctrls)
8849aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau{
8859aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	struct hdpvr_fh *fh = file->private_data;
8869aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	struct hdpvr_device *dev = fh->dev;
8879aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	int i, err = 0;
8889aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
8899aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	if (ctrls->ctrl_class == V4L2_CTRL_CLASS_MPEG) {
8909aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		for (i = 0; i < ctrls->count; i++) {
8919aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			struct v4l2_ext_control *ctrl = ctrls->controls + i;
8929aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
8939aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			err = hdpvr_get_ctrl(&dev->options, ctrl);
8949aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			if (err) {
8959aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau				ctrls->error_idx = i;
8969aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau				break;
8979aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			}
8989aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		}
8999aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		return err;
9009aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
9019aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	}
9029aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
9039aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	return -EINVAL;
9049aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau}
9059aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
9069aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
9079aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunaustatic int hdpvr_try_ctrl(struct v4l2_ext_control *ctrl, int ac3)
9089aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau{
9099aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	int ret = -EINVAL;
9109aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
9119aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	switch (ctrl->id) {
9129aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	case V4L2_CID_MPEG_AUDIO_ENCODING:
9139aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		if (ctrl->value == V4L2_MPEG_AUDIO_ENCODING_AAC ||
9149aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		    (ac3 && ctrl->value == V4L2_MPEG_AUDIO_ENCODING_AC3))
9159aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			ret = 0;
9169aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		break;
9179aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	case V4L2_CID_MPEG_VIDEO_ENCODING:
9189aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		if (ctrl->value == V4L2_MPEG_VIDEO_ENCODING_MPEG_4_AVC)
9199aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			ret = 0;
9209aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		break;
9219aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau/* 	case V4L2_CID_MPEG_VIDEO_B_FRAMES: */
9229aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau/* 		if (ctrl->value == 0 || ctrl->value == 128) */
9239aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau/* 			ret = 0; */
9249aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau/* 		break; */
9259aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
9269aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		if (ctrl->value == V4L2_MPEG_VIDEO_BITRATE_MODE_CBR ||
9279aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		    ctrl->value == V4L2_MPEG_VIDEO_BITRATE_MODE_VBR)
9289aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			ret = 0;
9299aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		break;
9309aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	case V4L2_CID_MPEG_VIDEO_BITRATE:
9319aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	{
9329aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		uint bitrate = ctrl->value / 100000;
9339aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		if (bitrate >= 10 && bitrate <= 135)
9349aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			ret = 0;
9359aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		break;
9369aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	}
9379aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK:
9389aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	{
9399aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		uint peak_bitrate = ctrl->value / 100000;
9409aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		if (peak_bitrate >= 10 && peak_bitrate <= 202)
9419aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			ret = 0;
9429aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		break;
9439aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	}
9449aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	case V4L2_CID_MPEG_STREAM_TYPE:
9459aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		if (ctrl->value == V4L2_MPEG_STREAM_TYPE_MPEG2_TS)
9469aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			ret = 0;
9479aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		break;
9489aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	default:
9499aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		return -EINVAL;
9509aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	}
9519aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	return 0;
9529aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau}
9539aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
9549aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunaustatic int vidioc_try_ext_ctrls(struct file *file, void *priv,
9559aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau				struct v4l2_ext_controls *ctrls)
9569aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau{
9579aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	struct hdpvr_fh *fh = file->private_data;
9589aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	struct hdpvr_device *dev = fh->dev;
9599aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	int i, err = 0;
9609aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
9619aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	if (ctrls->ctrl_class == V4L2_CTRL_CLASS_MPEG) {
9629aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		for (i = 0; i < ctrls->count; i++) {
9639aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			struct v4l2_ext_control *ctrl = ctrls->controls + i;
9649aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
9659aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			err = hdpvr_try_ctrl(ctrl,
9669aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau					     dev->flags & HDPVR_FLAG_AC3_CAP);
9679aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			if (err) {
9689aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau				ctrls->error_idx = i;
9699aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau				break;
9709aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			}
9719aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		}
9729aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		return err;
9739aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	}
9749aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
9759aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	return -EINVAL;
9769aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau}
9779aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
9789aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
9799aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunaustatic int hdpvr_set_ctrl(struct hdpvr_device *dev,
9809aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			  struct v4l2_ext_control *ctrl)
9819aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau{
9829aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	struct hdpvr_options *opt = &dev->options;
9839aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	int ret = 0;
9849aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
9859aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	switch (ctrl->id) {
9869aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	case V4L2_CID_MPEG_AUDIO_ENCODING:
9879aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		if (dev->flags & HDPVR_FLAG_AC3_CAP) {
9889aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			opt->audio_codec = ctrl->value;
9899aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			ret = hdpvr_set_audio(dev, opt->audio_input,
9909aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau					      opt->audio_codec);
9919aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		}
9929aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		break;
9939aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	case V4L2_CID_MPEG_VIDEO_ENCODING:
9949aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		break;
9959aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau/* 	case V4L2_CID_MPEG_VIDEO_B_FRAMES: */
9969aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau/* 		if (ctrl->value == 0 && !(opt->gop_mode & 0x2)) { */
9979aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau/* 			opt->gop_mode |= 0x2; */
9989aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau/* 			hdpvr_config_call(dev, CTRL_GOP_MODE_VALUE, */
9999aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau/* 					  opt->gop_mode); */
10009aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau/* 		} */
10019aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau/* 		if (ctrl->value == 128 && opt->gop_mode & 0x2) { */
10029aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau/* 			opt->gop_mode &= ~0x2; */
10039aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau/* 			hdpvr_config_call(dev, CTRL_GOP_MODE_VALUE, */
10049aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau/* 					  opt->gop_mode); */
10059aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau/* 		} */
10069aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau/* 		break; */
10079aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
10089aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		if (ctrl->value == V4L2_MPEG_VIDEO_BITRATE_MODE_CBR &&
10099aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		    opt->bitrate_mode != HDPVR_CONSTANT) {
10109aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			opt->bitrate_mode = HDPVR_CONSTANT;
10119aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			hdpvr_config_call(dev, CTRL_BITRATE_MODE_VALUE,
10129aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau					  opt->bitrate_mode);
10139aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		}
10149aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		if (ctrl->value == V4L2_MPEG_VIDEO_BITRATE_MODE_VBR &&
10159aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		    opt->bitrate_mode == HDPVR_CONSTANT) {
10169aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			opt->bitrate_mode = HDPVR_VARIABLE_AVERAGE;
10179aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			hdpvr_config_call(dev, CTRL_BITRATE_MODE_VALUE,
10189aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau					  opt->bitrate_mode);
10199aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		}
10209aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		break;
10219aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	case V4L2_CID_MPEG_VIDEO_BITRATE: {
10229aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		uint bitrate = ctrl->value / 100000;
10239aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
10249aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		opt->bitrate = bitrate;
10259aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		if (bitrate >= opt->peak_bitrate)
10269aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			opt->peak_bitrate = bitrate+1;
10279aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
10289aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		hdpvr_set_bitrate(dev);
10299aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		break;
10309aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	}
10319aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK: {
10329aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		uint peak_bitrate = ctrl->value / 100000;
10339aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
10349aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		if (opt->bitrate_mode == HDPVR_CONSTANT)
10359aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			break;
10369aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
10379aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		if (opt->bitrate < peak_bitrate) {
10389aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			opt->peak_bitrate = peak_bitrate;
10399aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			hdpvr_set_bitrate(dev);
10409aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		} else
10419aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			ret = -EINVAL;
10429aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		break;
10439aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	}
10449aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	case V4L2_CID_MPEG_STREAM_TYPE:
10459aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		break;
10469aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	default:
10479aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		return -EINVAL;
10489aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	}
10499aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	return ret;
10509aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau}
10519aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
10529aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunaustatic int vidioc_s_ext_ctrls(struct file *file, void *priv,
10539aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			      struct v4l2_ext_controls *ctrls)
10549aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau{
10559aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	struct hdpvr_fh *fh = file->private_data;
10569aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	struct hdpvr_device *dev = fh->dev;
10579aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	int i, err = 0;
10589aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
10599aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	if (ctrls->ctrl_class == V4L2_CTRL_CLASS_MPEG) {
10609aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		for (i = 0; i < ctrls->count; i++) {
10619aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			struct v4l2_ext_control *ctrl = ctrls->controls + i;
10629aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
10639aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			err = hdpvr_try_ctrl(ctrl,
10649aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau					     dev->flags & HDPVR_FLAG_AC3_CAP);
10659aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			if (err) {
10669aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau				ctrls->error_idx = i;
10679aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau				break;
10689aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			}
10699aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			err = hdpvr_set_ctrl(dev, ctrl);
10709aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			if (err) {
10719aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau				ctrls->error_idx = i;
10729aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau				break;
10739aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			}
10749aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		}
10759aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		return err;
10769aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
10779aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	}
10789aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
10799aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	return -EINVAL;
10809aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau}
10819aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
10829aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunaustatic int vidioc_enum_fmt_vid_cap(struct file *file, void *private_data,
10839aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau				    struct v4l2_fmtdesc *f)
10849aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau{
10859aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
10869aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	if (f->index != 0 || f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
10879aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		return -EINVAL;
10889aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
10899aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	f->flags = V4L2_FMT_FLAG_COMPRESSED;
10909aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	strncpy(f->description, "MPEG2-TS with AVC/AAC streams", 32);
10919aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	f->pixelformat = V4L2_PIX_FMT_MPEG;
10929aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
10939aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	return 0;
10949aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau}
10959aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
10969aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunaustatic int vidioc_g_fmt_vid_cap(struct file *file, void *private_data,
10979aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau				struct v4l2_format *f)
10989aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau{
10999aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	struct hdpvr_fh *fh = file->private_data;
11009aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	struct hdpvr_device *dev = fh->dev;
11019aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	struct hdpvr_video_info *vid_info;
11029aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
11039aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	if (!dev)
11049aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		return -ENODEV;
11059aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
11069aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	vid_info = get_video_info(dev);
11079aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	if (!vid_info)
11089aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		return -EFAULT;
11099aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
11109aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
11119aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	f->fmt.pix.pixelformat	= V4L2_PIX_FMT_MPEG;
11129aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	f->fmt.pix.width	= vid_info->width;
11139aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	f->fmt.pix.height	= vid_info->height;
11149aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	f->fmt.pix.sizeimage	= dev->bulk_in_size;
11159aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	f->fmt.pix.colorspace	= 0;
11169aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	f->fmt.pix.bytesperline	= 0;
11179aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	f->fmt.pix.field	= V4L2_FIELD_ANY;
11189aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
11199aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	kfree(vid_info);
11209aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	return 0;
11219aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau}
11229aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
112376717b887cccc77d04357fc0d6ac98f894e3eb3cJanne Grunaustatic int vidioc_encoder_cmd(struct file *filp, void *priv,
112476717b887cccc77d04357fc0d6ac98f894e3eb3cJanne Grunau			       struct v4l2_encoder_cmd *a)
112576717b887cccc77d04357fc0d6ac98f894e3eb3cJanne Grunau{
112676717b887cccc77d04357fc0d6ac98f894e3eb3cJanne Grunau	struct hdpvr_fh *fh = filp->private_data;
112776717b887cccc77d04357fc0d6ac98f894e3eb3cJanne Grunau	struct hdpvr_device *dev = fh->dev;
112876717b887cccc77d04357fc0d6ac98f894e3eb3cJanne Grunau	int res;
112976717b887cccc77d04357fc0d6ac98f894e3eb3cJanne Grunau
113076717b887cccc77d04357fc0d6ac98f894e3eb3cJanne Grunau	mutex_lock(&dev->io_mutex);
113176717b887cccc77d04357fc0d6ac98f894e3eb3cJanne Grunau
113276717b887cccc77d04357fc0d6ac98f894e3eb3cJanne Grunau	memset(&a->raw, 0, sizeof(a->raw));
113376717b887cccc77d04357fc0d6ac98f894e3eb3cJanne Grunau	switch (a->cmd) {
113476717b887cccc77d04357fc0d6ac98f894e3eb3cJanne Grunau	case V4L2_ENC_CMD_START:
113576717b887cccc77d04357fc0d6ac98f894e3eb3cJanne Grunau		a->flags = 0;
113676717b887cccc77d04357fc0d6ac98f894e3eb3cJanne Grunau		res = hdpvr_start_streaming(dev);
113776717b887cccc77d04357fc0d6ac98f894e3eb3cJanne Grunau		break;
113876717b887cccc77d04357fc0d6ac98f894e3eb3cJanne Grunau	case V4L2_ENC_CMD_STOP:
113976717b887cccc77d04357fc0d6ac98f894e3eb3cJanne Grunau		res = hdpvr_stop_streaming(dev);
114076717b887cccc77d04357fc0d6ac98f894e3eb3cJanne Grunau		break;
114176717b887cccc77d04357fc0d6ac98f894e3eb3cJanne Grunau	default:
114276717b887cccc77d04357fc0d6ac98f894e3eb3cJanne Grunau		v4l2_dbg(MSG_INFO, hdpvr_debug, dev->video_dev,
114376717b887cccc77d04357fc0d6ac98f894e3eb3cJanne Grunau			 "Unsupported encoder cmd %d\n", a->cmd);
114476717b887cccc77d04357fc0d6ac98f894e3eb3cJanne Grunau		return -EINVAL;
114576717b887cccc77d04357fc0d6ac98f894e3eb3cJanne Grunau	}
114676717b887cccc77d04357fc0d6ac98f894e3eb3cJanne Grunau	mutex_unlock(&dev->io_mutex);
114776717b887cccc77d04357fc0d6ac98f894e3eb3cJanne Grunau	return res;
114876717b887cccc77d04357fc0d6ac98f894e3eb3cJanne Grunau}
114976717b887cccc77d04357fc0d6ac98f894e3eb3cJanne Grunau
115076717b887cccc77d04357fc0d6ac98f894e3eb3cJanne Grunaustatic int vidioc_try_encoder_cmd(struct file *filp, void *priv,
115176717b887cccc77d04357fc0d6ac98f894e3eb3cJanne Grunau					struct v4l2_encoder_cmd *a)
115276717b887cccc77d04357fc0d6ac98f894e3eb3cJanne Grunau{
115376717b887cccc77d04357fc0d6ac98f894e3eb3cJanne Grunau	switch (a->cmd) {
115476717b887cccc77d04357fc0d6ac98f894e3eb3cJanne Grunau	case V4L2_ENC_CMD_START:
115576717b887cccc77d04357fc0d6ac98f894e3eb3cJanne Grunau	case V4L2_ENC_CMD_STOP:
115676717b887cccc77d04357fc0d6ac98f894e3eb3cJanne Grunau		return 0;
115776717b887cccc77d04357fc0d6ac98f894e3eb3cJanne Grunau	default:
115876717b887cccc77d04357fc0d6ac98f894e3eb3cJanne Grunau		return -EINVAL;
115976717b887cccc77d04357fc0d6ac98f894e3eb3cJanne Grunau	}
116076717b887cccc77d04357fc0d6ac98f894e3eb3cJanne Grunau}
11619aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
11629aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunaustatic const struct v4l2_ioctl_ops hdpvr_ioctl_ops = {
11639aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	.vidioc_querycap	= vidioc_querycap,
11649aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	.vidioc_s_std		= vidioc_s_std,
11659aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	.vidioc_enum_input	= vidioc_enum_input,
11669aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	.vidioc_g_input		= vidioc_g_input,
11679aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	.vidioc_s_input		= vidioc_s_input,
11689aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	.vidioc_enumaudio	= vidioc_enumaudio,
11699aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	.vidioc_g_audio		= vidioc_g_audio,
11709aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	.vidioc_s_audio		= vidioc_s_audio,
11719aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	.vidioc_queryctrl	= vidioc_queryctrl,
11729aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	.vidioc_g_ctrl		= vidioc_g_ctrl,
11739aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	.vidioc_s_ctrl		= vidioc_s_ctrl,
11749aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	.vidioc_g_ext_ctrls	= vidioc_g_ext_ctrls,
11759aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	.vidioc_s_ext_ctrls	= vidioc_s_ext_ctrls,
11769aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	.vidioc_try_ext_ctrls	= vidioc_try_ext_ctrls,
11779aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	.vidioc_enum_fmt_vid_cap	= vidioc_enum_fmt_vid_cap,
11789aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	.vidioc_g_fmt_vid_cap		= vidioc_g_fmt_vid_cap,
117976717b887cccc77d04357fc0d6ac98f894e3eb3cJanne Grunau	.vidioc_encoder_cmd	= vidioc_encoder_cmd,
118076717b887cccc77d04357fc0d6ac98f894e3eb3cJanne Grunau	.vidioc_try_encoder_cmd	= vidioc_try_encoder_cmd,
11819aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau};
11829aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
11839aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunaustatic void hdpvr_device_release(struct video_device *vdev)
11849aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau{
11859aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	struct hdpvr_device *dev = video_get_drvdata(vdev);
11869aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
11879aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	hdpvr_delete(dev);
11889aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau}
11899aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
11909aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunaustatic const struct video_device hdpvr_video_template = {
11919aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau/* 	.type			= VFL_TYPE_GRABBER, */
11929aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau/* 	.type2			= VID_TYPE_CAPTURE | VID_TYPE_MPEG_ENCODER, */
11939aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	.fops			= &hdpvr_fops,
11949aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	.release		= hdpvr_device_release,
11959aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	.ioctl_ops 		= &hdpvr_ioctl_ops,
11969aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	.tvnorms 		=
11979aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		V4L2_STD_NTSC  | V4L2_STD_SECAM | V4L2_STD_PAL_B |
11989aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		V4L2_STD_PAL_G | V4L2_STD_PAL_H | V4L2_STD_PAL_I |
11999aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		V4L2_STD_PAL_D | V4L2_STD_PAL_M | V4L2_STD_PAL_N |
12009aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		V4L2_STD_PAL_60,
12019aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau};
12029aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
12039aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunauint hdpvr_register_videodev(struct hdpvr_device *dev, int devnum)
12049aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau{
12059aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	/* setup and register video device */
12069aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	dev->video_dev = video_device_alloc();
12079aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	if (!dev->video_dev) {
12089aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		err("video_device_alloc() failed");
12099aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		goto error;
12109aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	}
12119aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
12129aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	*(dev->video_dev) = hdpvr_video_template;
12139aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	strcpy(dev->video_dev->name, "Hauppauge HD PVR");
12149aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	dev->video_dev->parent = &dev->udev->dev;
12159aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	video_set_drvdata(dev->video_dev, dev);
12169aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
12179aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	if (video_register_device(dev->video_dev, VFL_TYPE_GRABBER, devnum)) {
12189aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		err("V4L2 device registration failed");
12199aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		goto error;
12209aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	}
12219aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
12229aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	return 0;
12239aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunauerror:
12249aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	return -ENOMEM;
12259aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau}
1226