19aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau/*
2e86da6f07ed6deebc199368bd0a47b3671829b80Janne Grunau * Hauppauge 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>
1354d80904b4c1f7aa1d569d07ca3e62fba0daf3a2Mauro Carvalho Chehab#include <linux/kconfig.h>
149aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau#include <linux/errno.h>
159aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau#include <linux/init.h>
169aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau#include <linux/slab.h>
179aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau#include <linux/module.h>
189aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau#include <linux/uaccess.h>
199aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau#include <linux/usb.h>
209aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau#include <linux/mutex.h>
219aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau#include <linux/workqueue.h>
229aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
239aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau#include <linux/videodev2.h>
243315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil#include <linux/v4l2-dv-timings.h>
259aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau#include <media/v4l2-dev.h>
269aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau#include <media/v4l2-common.h>
272576415846bcbad3c0a6885fc44f950837106364Hans Verkuil#include <media/v4l2-dv-timings.h>
289aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau#include <media/v4l2-ioctl.h>
2965fe42d6054bb84c4abc4168310bd5d7c462456eHans Verkuil#include <media/v4l2-event.h>
309aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau#include "hdpvr.h"
319aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
3239bcb3ae030b0b64262adf6c5243bf767d8b75dcAlan Young#define BULK_URB_TIMEOUT   90 /* 0.09 seconds */
339aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
349ef77adfb9ac170bcaf449530cf129c48547fd55Janne Grunau#define print_buffer_status() { \
359ef77adfb9ac170bcaf449530cf129c48547fd55Janne Grunau		v4l2_dbg(MSG_BUFFER, hdpvr_debug, &dev->v4l2_dev,	\
369ef77adfb9ac170bcaf449530cf129c48547fd55Janne Grunau			 "%s:%d buffer stat: %d free, %d proc\n",	\
379ef77adfb9ac170bcaf449530cf129c48547fd55Janne Grunau			 __func__, __LINE__,				\
389ef77adfb9ac170bcaf449530cf129c48547fd55Janne Grunau			 list_size(&dev->free_buff_list),		\
399ef77adfb9ac170bcaf449530cf129c48547fd55Janne Grunau			 list_size(&dev->rec_buff_list)); }
40d211bfcbd0f13f1234aaa6e565013dba051a408cJanne Grunau
413315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuilstatic const struct v4l2_dv_timings hdpvr_dv_timings[] = {
423315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	V4L2_DV_BT_CEA_720X480I59_94,
433315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	V4L2_DV_BT_CEA_720X576I50,
443315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	V4L2_DV_BT_CEA_720X480P59_94,
453315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	V4L2_DV_BT_CEA_720X576P50,
463315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	V4L2_DV_BT_CEA_1280X720P50,
473315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	V4L2_DV_BT_CEA_1280X720P60,
483315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	V4L2_DV_BT_CEA_1920X1080I50,
493315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	V4L2_DV_BT_CEA_1920X1080I60,
503315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil};
513315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil
523315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil/* Use 480i59 as the default timings */
533315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil#define HDPVR_DEF_DV_TIMINGS_IDX (0)
543315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil
553315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuilstruct hdpvr_fh {
563315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	struct v4l2_fh fh;
573315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	bool legacy_mode;
583315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil};
593315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil
609aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunaustatic uint list_size(struct list_head *list)
619aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau{
629aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	struct list_head *tmp;
639aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	uint count = 0;
649aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
659aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	list_for_each(tmp, list) {
669aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		count++;
679aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	}
689aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
699aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	return count;
709aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau}
719aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
729aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau/*=========================================================================*/
739aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau/* urb callback */
749aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunaustatic void hdpvr_read_bulk_callback(struct urb *urb)
759aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau{
769aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	struct hdpvr_buffer *buf = (struct hdpvr_buffer *)urb->context;
779aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	struct hdpvr_device *dev = buf->dev;
789aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
799aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	/* marking buffer as received and wake waiting */
809aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	buf->status = BUFSTAT_READY;
819aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	wake_up_interruptible(&dev->wait_data);
829aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau}
839aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
849aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau/*=========================================================================*/
853445857b22eafb70a6ac258979e955b116bfd2c6Hans Verkuil/* buffer bits */
869aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
879aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau/* function expects dev->io_mutex to be hold by caller */
889aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunauint hdpvr_cancel_queue(struct hdpvr_device *dev)
899aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau{
909aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	struct hdpvr_buffer *buf;
919aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
929aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	list_for_each_entry(buf, &dev->rec_buff_list, buff_list) {
939aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		usb_kill_urb(buf->urb);
949aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		buf->status = BUFSTAT_AVAILABLE;
959aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	}
969aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
979aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	list_splice_init(&dev->rec_buff_list, dev->free_buff_list.prev);
989aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
999aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	return 0;
1009aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau}
1019aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
1029aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunaustatic int hdpvr_free_queue(struct list_head *q)
1039aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau{
1049aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	struct list_head *tmp;
1059aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	struct list_head *p;
1069aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	struct hdpvr_buffer *buf;
1079aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	struct urb *urb;
1089aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
1099aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	for (p = q->next; p != q;) {
1109aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		buf = list_entry(p, struct hdpvr_buffer, buff_list);
1119aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
1129aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		urb = buf->urb;
113997ea58eb92f9970b8af7aae48800d0ef43b9423Daniel Mack		usb_free_coherent(urb->dev, urb->transfer_buffer_length,
114997ea58eb92f9970b8af7aae48800d0ef43b9423Daniel Mack				  urb->transfer_buffer, urb->transfer_dma);
1159aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		usb_free_urb(urb);
1169aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		tmp = p->next;
1179aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		list_del(p);
1189aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		kfree(buf);
1199aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		p = tmp;
1209aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	}
1219aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
1229aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	return 0;
1239aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau}
1249aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
1259aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau/* function expects dev->io_mutex to be hold by caller */
1269aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunauint hdpvr_free_buffers(struct hdpvr_device *dev)
1279aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau{
1289aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	hdpvr_cancel_queue(dev);
1299aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
1309aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	hdpvr_free_queue(&dev->free_buff_list);
1319aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	hdpvr_free_queue(&dev->rec_buff_list);
1329aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
1339aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	return 0;
1349aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau}
1359aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
1369aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau/* function expects dev->io_mutex to be hold by caller */
1379aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunauint hdpvr_alloc_buffers(struct hdpvr_device *dev, uint count)
1389aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau{
1399aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	uint i;
1409aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	int retval = -ENOMEM;
1419aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	u8 *mem;
1429aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	struct hdpvr_buffer *buf;
1439aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	struct urb *urb;
1449aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
1459ef77adfb9ac170bcaf449530cf129c48547fd55Janne Grunau	v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev,
1469aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		 "allocating %u buffers\n", count);
1479aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
1489aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	for (i = 0; i < count; i++) {
1499aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
1509aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		buf = kzalloc(sizeof(struct hdpvr_buffer), GFP_KERNEL);
1519aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		if (!buf) {
1529ef77adfb9ac170bcaf449530cf129c48547fd55Janne Grunau			v4l2_err(&dev->v4l2_dev, "cannot allocate buffer\n");
1539aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			goto exit;
1549aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		}
1559aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		buf->dev = dev;
1569aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
1579aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		urb = usb_alloc_urb(0, GFP_KERNEL);
1589aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		if (!urb) {
1599ef77adfb9ac170bcaf449530cf129c48547fd55Janne Grunau			v4l2_err(&dev->v4l2_dev, "cannot allocate urb\n");
160cd0e280f1bbecebcd20ed0ddd4dd8fb03a506b3cJulia Lawall			goto exit_urb;
1619aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		}
1629aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		buf->urb = urb;
1639aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
164997ea58eb92f9970b8af7aae48800d0ef43b9423Daniel Mack		mem = usb_alloc_coherent(dev->udev, dev->bulk_in_size, GFP_KERNEL,
165997ea58eb92f9970b8af7aae48800d0ef43b9423Daniel Mack					 &urb->transfer_dma);
1669aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		if (!mem) {
1679ef77adfb9ac170bcaf449530cf129c48547fd55Janne Grunau			v4l2_err(&dev->v4l2_dev,
1689ef77adfb9ac170bcaf449530cf129c48547fd55Janne Grunau				 "cannot allocate usb transfer buffer\n");
169cd0e280f1bbecebcd20ed0ddd4dd8fb03a506b3cJulia Lawall			goto exit_urb_buffer;
1709aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		}
1719aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
1729aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		usb_fill_bulk_urb(buf->urb, dev->udev,
1739aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau				  usb_rcvbulkpipe(dev->udev,
1749aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau						  dev->bulk_in_endpointAddr),
1759aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau				  mem, dev->bulk_in_size,
1769aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau				  hdpvr_read_bulk_callback, buf);
1779aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
1784f5c933abb34532dc962185c999509b97a97fa1bJames M McLaren		buf->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
1799aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		buf->status = BUFSTAT_AVAILABLE;
1809aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		list_add_tail(&buf->buff_list, &dev->free_buff_list);
1819aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	}
1829aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	return 0;
183cd0e280f1bbecebcd20ed0ddd4dd8fb03a506b3cJulia Lawallexit_urb_buffer:
184cd0e280f1bbecebcd20ed0ddd4dd8fb03a506b3cJulia Lawall	usb_free_urb(urb);
185cd0e280f1bbecebcd20ed0ddd4dd8fb03a506b3cJulia Lawallexit_urb:
186cd0e280f1bbecebcd20ed0ddd4dd8fb03a506b3cJulia Lawall	kfree(buf);
1879aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunauexit:
1889aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	hdpvr_free_buffers(dev);
1899aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	return retval;
1909aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau}
1919aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
1929aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunaustatic int hdpvr_submit_buffers(struct hdpvr_device *dev)
1939aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau{
1949aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	struct hdpvr_buffer *buf;
1959aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	struct urb *urb;
1969aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	int ret = 0, err_count = 0;
1979aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
1989aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	mutex_lock(&dev->io_mutex);
1999aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
2009aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	while (dev->status == STATUS_STREAMING &&
2019aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	       !list_empty(&dev->free_buff_list)) {
2029aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
2039aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		buf = list_entry(dev->free_buff_list.next, struct hdpvr_buffer,
2049aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau				 buff_list);
2059aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		if (buf->status != BUFSTAT_AVAILABLE) {
2069ef77adfb9ac170bcaf449530cf129c48547fd55Janne Grunau			v4l2_err(&dev->v4l2_dev,
2074b512d26f425be1c779c8319249b42ce3c3424d2Thadeu Lima de Souza Cascardo				 "buffer not marked as available\n");
2089aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			ret = -EFAULT;
2099aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			goto err;
2109aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		}
2119aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
2129aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		urb = buf->urb;
2139aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		urb->status = 0;
2149aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		urb->actual_length = 0;
2159aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		ret = usb_submit_urb(urb, GFP_KERNEL);
2169aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		if (ret) {
2179ef77adfb9ac170bcaf449530cf129c48547fd55Janne Grunau			v4l2_err(&dev->v4l2_dev,
2189ef77adfb9ac170bcaf449530cf129c48547fd55Janne Grunau				 "usb_submit_urb in %s returned %d\n",
2199ef77adfb9ac170bcaf449530cf129c48547fd55Janne Grunau				 __func__, ret);
2209aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			if (++err_count > 2)
2219aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau				break;
2229aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			continue;
2239aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		}
2249aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		buf->status = BUFSTAT_INPROGRESS;
2259aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		list_move_tail(&buf->buff_list, &dev->rec_buff_list);
2269aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	}
2279aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunauerr:
228d211bfcbd0f13f1234aaa6e565013dba051a408cJanne Grunau	print_buffer_status();
2299aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	mutex_unlock(&dev->io_mutex);
2309aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	return ret;
2319aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau}
2329aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
2339aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunaustatic struct hdpvr_buffer *hdpvr_get_next_buffer(struct hdpvr_device *dev)
2349aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau{
2359aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	struct hdpvr_buffer *buf;
2369aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
2379aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	mutex_lock(&dev->io_mutex);
2389aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
2399aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	if (list_empty(&dev->rec_buff_list)) {
2409aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		mutex_unlock(&dev->io_mutex);
2419aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		return NULL;
2429aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	}
2439aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
2449aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	buf = list_entry(dev->rec_buff_list.next, struct hdpvr_buffer,
2459aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			 buff_list);
2469aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	mutex_unlock(&dev->io_mutex);
2479aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
2489aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	return buf;
2499aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau}
2509aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
2519aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunaustatic void hdpvr_transmit_buffers(struct work_struct *work)
2529aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau{
2539aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	struct hdpvr_device *dev = container_of(work, struct hdpvr_device,
2549aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau						worker);
2559aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
2569aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	while (dev->status == STATUS_STREAMING) {
2579aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
2589aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		if (hdpvr_submit_buffers(dev)) {
2599ef77adfb9ac170bcaf449530cf129c48547fd55Janne Grunau			v4l2_err(&dev->v4l2_dev, "couldn't submit buffers\n");
2609aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			goto error;
2619aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		}
2629aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		if (wait_event_interruptible(dev->wait_buffer,
2639aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau				!list_empty(&dev->free_buff_list) ||
2649aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau					     dev->status != STATUS_STREAMING))
2659aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			goto error;
2669aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	}
2679aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
2689ef77adfb9ac170bcaf449530cf129c48547fd55Janne Grunau	v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev,
2699aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		 "transmit worker exited\n");
2709aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	return;
2719aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunauerror:
2729ef77adfb9ac170bcaf449530cf129c48547fd55Janne Grunau	v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev,
2739aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		 "transmit buffers errored\n");
2749aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	dev->status = STATUS_ERROR;
2759aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau}
2769aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
2779aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau/* function expects dev->io_mutex to be hold by caller */
2789aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunaustatic int hdpvr_start_streaming(struct hdpvr_device *dev)
2799aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau{
2809aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	int ret;
2814d601c4ca272959ba837b8279f4873b55caaf619Leonid Kegulskiy	struct hdpvr_video_info vidinf;
2829aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
2839aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	if (dev->status == STATUS_STREAMING)
2849aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		return 0;
28579f10b625e5eff93c8fad54ba345e5f35feb8461Hans Verkuil	if (dev->status != STATUS_IDLE)
2869aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		return -EAGAIN;
2879aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
2884d601c4ca272959ba837b8279f4873b55caaf619Leonid Kegulskiy	ret = get_video_info(dev, &vidinf);
2895f454d82e5958e59c16580b9b4531f4bbc7231f7Hans Verkuil	if (ret < 0)
2905f454d82e5958e59c16580b9b4531f4bbc7231f7Hans Verkuil		return ret;
2915f454d82e5958e59c16580b9b4531f4bbc7231f7Hans Verkuil
2925f454d82e5958e59c16580b9b4531f4bbc7231f7Hans Verkuil	if (!vidinf.valid) {
29379f10b625e5eff93c8fad54ba345e5f35feb8461Hans Verkuil		msleep(250);
29479f10b625e5eff93c8fad54ba345e5f35feb8461Hans Verkuil		v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev,
29579f10b625e5eff93c8fad54ba345e5f35feb8461Hans Verkuil				"no video signal at input %d\n", dev->options.video_input);
29679f10b625e5eff93c8fad54ba345e5f35feb8461Hans Verkuil		return -EAGAIN;
29779f10b625e5eff93c8fad54ba345e5f35feb8461Hans Verkuil	}
2989aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
29979f10b625e5eff93c8fad54ba345e5f35feb8461Hans Verkuil	v4l2_dbg(MSG_BUFFER, hdpvr_debug, &dev->v4l2_dev,
30079f10b625e5eff93c8fad54ba345e5f35feb8461Hans Verkuil			"video signal: %dx%d@%dhz\n", vidinf.width,
30179f10b625e5eff93c8fad54ba345e5f35feb8461Hans Verkuil			vidinf.height, vidinf.fps);
3029aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
30379f10b625e5eff93c8fad54ba345e5f35feb8461Hans Verkuil	/* start streaming 2 request */
30479f10b625e5eff93c8fad54ba345e5f35feb8461Hans Verkuil	ret = usb_control_msg(dev->udev,
30579f10b625e5eff93c8fad54ba345e5f35feb8461Hans Verkuil			usb_sndctrlpipe(dev->udev, 0),
30679f10b625e5eff93c8fad54ba345e5f35feb8461Hans Verkuil			0xb8, 0x38, 0x1, 0, NULL, 0, 8000);
30779f10b625e5eff93c8fad54ba345e5f35feb8461Hans Verkuil	v4l2_dbg(MSG_BUFFER, hdpvr_debug, &dev->v4l2_dev,
30879f10b625e5eff93c8fad54ba345e5f35feb8461Hans Verkuil			"encoder start control request returned %d\n", ret);
30979f10b625e5eff93c8fad54ba345e5f35feb8461Hans Verkuil	if (ret < 0)
31079f10b625e5eff93c8fad54ba345e5f35feb8461Hans Verkuil		return ret;
3119aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
31279f10b625e5eff93c8fad54ba345e5f35feb8461Hans Verkuil	ret = hdpvr_config_call(dev, CTRL_START_STREAMING_VALUE, 0x00);
31379f10b625e5eff93c8fad54ba345e5f35feb8461Hans Verkuil	if (ret)
31479f10b625e5eff93c8fad54ba345e5f35feb8461Hans Verkuil		return ret;
3159aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
31679f10b625e5eff93c8fad54ba345e5f35feb8461Hans Verkuil	dev->status = STATUS_STREAMING;
317afa159538af61f1a65d48927f4e949fe514fb4fcJanne Grunau
31879f10b625e5eff93c8fad54ba345e5f35feb8461Hans Verkuil	INIT_WORK(&dev->worker, hdpvr_transmit_buffers);
31979f10b625e5eff93c8fad54ba345e5f35feb8461Hans Verkuil	queue_work(dev->workqueue, &dev->worker);
3209aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
32179f10b625e5eff93c8fad54ba345e5f35feb8461Hans Verkuil	v4l2_dbg(MSG_BUFFER, hdpvr_debug, &dev->v4l2_dev,
32279f10b625e5eff93c8fad54ba345e5f35feb8461Hans Verkuil			"streaming started\n");
3239aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
32479f10b625e5eff93c8fad54ba345e5f35feb8461Hans Verkuil	return 0;
3259aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau}
3269aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
3279aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
3289aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau/* function expects dev->io_mutex to be hold by caller */
3299aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunaustatic int hdpvr_stop_streaming(struct hdpvr_device *dev)
3309aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau{
33185d682b9ee1a89a82c2a75182558e392749d81fcMárton Németh	int actual_length;
33285d682b9ee1a89a82c2a75182558e392749d81fcMárton Németh	uint c = 0;
3337d771ff0dc3371923db929d9f88932acec3fc8e8Janne Grunau	u8 *buf;
3347d771ff0dc3371923db929d9f88932acec3fc8e8Janne Grunau
3359aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	if (dev->status == STATUS_IDLE)
3369aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		return 0;
3379aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	else if (dev->status != STATUS_STREAMING)
3389aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		return -EAGAIN;
3399aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
3407d771ff0dc3371923db929d9f88932acec3fc8e8Janne Grunau	buf = kmalloc(dev->bulk_in_size, GFP_KERNEL);
3417d771ff0dc3371923db929d9f88932acec3fc8e8Janne Grunau	if (!buf)
3427d771ff0dc3371923db929d9f88932acec3fc8e8Janne Grunau		v4l2_err(&dev->v4l2_dev, "failed to allocate temporary buffer "
3437d771ff0dc3371923db929d9f88932acec3fc8e8Janne Grunau			 "for emptying the internal device buffer. "
3447d771ff0dc3371923db929d9f88932acec3fc8e8Janne Grunau			 "Next capture start will be slow\n");
3457d771ff0dc3371923db929d9f88932acec3fc8e8Janne Grunau
3469aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	dev->status = STATUS_SHUTTING_DOWN;
3479aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	hdpvr_config_call(dev, CTRL_STOP_STREAMING_VALUE, 0x00);
34848f98f7557d35d360470bf6d9fd7b00d04fba828Janne Grunau	mutex_unlock(&dev->io_mutex);
3499aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
3509aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	wake_up_interruptible(&dev->wait_buffer);
3519aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	msleep(50);
3529aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
3539aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	flush_workqueue(dev->workqueue);
3549aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
35548f98f7557d35d360470bf6d9fd7b00d04fba828Janne Grunau	mutex_lock(&dev->io_mutex);
3569aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	/* kill the still outstanding urbs */
3579aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	hdpvr_cancel_queue(dev);
3589aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
3597d771ff0dc3371923db929d9f88932acec3fc8e8Janne Grunau	/* emptying the device buffer beforeshutting it down */
3607d771ff0dc3371923db929d9f88932acec3fc8e8Janne Grunau	while (buf && ++c < 500 &&
3617d771ff0dc3371923db929d9f88932acec3fc8e8Janne Grunau	       !usb_bulk_msg(dev->udev,
3627d771ff0dc3371923db929d9f88932acec3fc8e8Janne Grunau			     usb_rcvbulkpipe(dev->udev,
3637d771ff0dc3371923db929d9f88932acec3fc8e8Janne Grunau					     dev->bulk_in_endpointAddr),
3647d771ff0dc3371923db929d9f88932acec3fc8e8Janne Grunau			     buf, dev->bulk_in_size, &actual_length,
3657d771ff0dc3371923db929d9f88932acec3fc8e8Janne Grunau			     BULK_URB_TIMEOUT)) {
3667d771ff0dc3371923db929d9f88932acec3fc8e8Janne Grunau		v4l2_dbg(MSG_BUFFER, hdpvr_debug, &dev->v4l2_dev,
3677d771ff0dc3371923db929d9f88932acec3fc8e8Janne Grunau			 "%2d: got %d bytes\n", c, actual_length);
3687d771ff0dc3371923db929d9f88932acec3fc8e8Janne Grunau	}
3697d771ff0dc3371923db929d9f88932acec3fc8e8Janne Grunau	kfree(buf);
3707d771ff0dc3371923db929d9f88932acec3fc8e8Janne Grunau	v4l2_dbg(MSG_BUFFER, hdpvr_debug, &dev->v4l2_dev,
3717d771ff0dc3371923db929d9f88932acec3fc8e8Janne Grunau		 "used %d urbs to empty device buffers\n", c-1);
3727d771ff0dc3371923db929d9f88932acec3fc8e8Janne Grunau	msleep(10);
3737d771ff0dc3371923db929d9f88932acec3fc8e8Janne Grunau
3749aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	dev->status = STATUS_IDLE;
3759aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
3769aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	return 0;
3779aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau}
3789aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
3799aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
3809aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau/*=======================================================================*/
3819aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau/*
3829aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau * video 4 linux 2 file operations
3839aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau */
3849aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
3853315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuilstatic int hdpvr_open(struct file *file)
3863315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil{
3873315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	struct hdpvr_fh *fh = kzalloc(sizeof(*fh), GFP_KERNEL);
3883315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil
3893315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	if (fh == NULL)
3903315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil		return -ENOMEM;
3913315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	fh->legacy_mode = true;
3923315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	v4l2_fh_init(&fh->fh, video_devdata(file));
3933315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	v4l2_fh_add(&fh->fh);
3943315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	file->private_data = fh;
3953315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	return 0;
3963315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil}
3973315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil
3989aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunaustatic int hdpvr_release(struct file *file)
3999aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau{
400ede197aac0c64021a0b2139d19edd8fa066530c2Hans Verkuil	struct hdpvr_device *dev = video_drvdata(file);
4019aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
4029aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	mutex_lock(&dev->io_mutex);
403ede197aac0c64021a0b2139d19edd8fa066530c2Hans Verkuil	if (file->private_data == dev->owner) {
4049aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		hdpvr_stop_streaming(dev);
405ede197aac0c64021a0b2139d19edd8fa066530c2Hans Verkuil		dev->owner = NULL;
406ede197aac0c64021a0b2139d19edd8fa066530c2Hans Verkuil	}
4079aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	mutex_unlock(&dev->io_mutex);
4089aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
409ede197aac0c64021a0b2139d19edd8fa066530c2Hans Verkuil	return v4l2_fh_release(file);
4109aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau}
4119aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
4129aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau/*
4139aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau * hdpvr_v4l2_read()
4149aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau * will allocate buffers when called for the first time
4159aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau */
4169aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunaustatic ssize_t hdpvr_read(struct file *file, char __user *buffer, size_t count,
4179aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			  loff_t *pos)
4189aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau{
419ede197aac0c64021a0b2139d19edd8fa066530c2Hans Verkuil	struct hdpvr_device *dev = video_drvdata(file);
4209aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	struct hdpvr_buffer *buf = NULL;
4219aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	struct urb *urb;
4229aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	unsigned int ret = 0;
4239aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	int rem, cnt;
4249aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
4259aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	if (*pos)
4269aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		return -ESPIPE;
4279aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
4289aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	mutex_lock(&dev->io_mutex);
4299aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	if (dev->status == STATUS_IDLE) {
4309aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		if (hdpvr_start_streaming(dev)) {
4319ef77adfb9ac170bcaf449530cf129c48547fd55Janne Grunau			v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev,
4329ef77adfb9ac170bcaf449530cf129c48547fd55Janne Grunau				 "start_streaming failed\n");
4339aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			ret = -EIO;
4349aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			msleep(200);
4359aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			dev->status = STATUS_IDLE;
4369aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			mutex_unlock(&dev->io_mutex);
4379aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			goto err;
4389aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		}
439ede197aac0c64021a0b2139d19edd8fa066530c2Hans Verkuil		dev->owner = file->private_data;
440d211bfcbd0f13f1234aaa6e565013dba051a408cJanne Grunau		print_buffer_status();
4419aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	}
4429aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	mutex_unlock(&dev->io_mutex);
4439aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
4449aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	/* wait for the first buffer */
4459aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	if (!(file->f_flags & O_NONBLOCK)) {
4469aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		if (wait_event_interruptible(dev->wait_data,
4479aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau					     hdpvr_get_next_buffer(dev)))
4489aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			return -ERESTARTSYS;
4499aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	}
4509aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
4519aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	buf = hdpvr_get_next_buffer(dev);
4529aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
4539aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	while (count > 0 && buf) {
4549aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
4559aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		if (buf->status != BUFSTAT_READY &&
4569aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		    dev->status != STATUS_DISCONNECTED) {
4579aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			/* return nonblocking */
4589aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			if (file->f_flags & O_NONBLOCK) {
4599aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau				if (!ret)
4609aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau					ret = -EAGAIN;
4619aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau				goto err;
4629aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			}
4639aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
4649aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			if (wait_event_interruptible(dev->wait_data,
4659aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau					      buf->status == BUFSTAT_READY)) {
4669aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau				ret = -ERESTARTSYS;
4679aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau				goto err;
4689aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			}
4699aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		}
4709aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
4719aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		if (buf->status != BUFSTAT_READY)
4729aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			break;
4739aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
4749aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		/* set remaining bytes to copy */
4759aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		urb = buf->urb;
4769aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		rem = urb->actual_length - buf->pos;
4779aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		cnt = rem > count ? count : rem;
4789aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
4799aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		if (copy_to_user(buffer, urb->transfer_buffer + buf->pos,
4809aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau				 cnt)) {
4819ef77adfb9ac170bcaf449530cf129c48547fd55Janne Grunau			v4l2_err(&dev->v4l2_dev, "read: copy_to_user failed\n");
4829aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			if (!ret)
4839aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau				ret = -EFAULT;
4849aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			goto err;
4859aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		}
4869aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
4879aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		buf->pos += cnt;
4889aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		count -= cnt;
4899aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		buffer += cnt;
4909aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		ret += cnt;
4919aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
4929aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		/* finished, take next buffer */
4939aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		if (buf->pos == urb->actual_length) {
4949aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			mutex_lock(&dev->io_mutex);
4959aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			buf->pos = 0;
4969aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			buf->status = BUFSTAT_AVAILABLE;
4979aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
4989aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			list_move_tail(&buf->buff_list, &dev->free_buff_list);
4999aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
500d211bfcbd0f13f1234aaa6e565013dba051a408cJanne Grunau			print_buffer_status();
5019aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
5029aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			mutex_unlock(&dev->io_mutex);
5039aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
5049aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			wake_up_interruptible(&dev->wait_buffer);
5059aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
5069aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			buf = hdpvr_get_next_buffer(dev);
5079aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		}
5089aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	}
5099aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunauerr:
5109aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	if (!ret && !buf)
5119aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		ret = -EAGAIN;
5129aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	return ret;
5139aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau}
5149aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
5159aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunaustatic unsigned int hdpvr_poll(struct file *filp, poll_table *wait)
5169aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau{
51765fe42d6054bb84c4abc4168310bd5d7c462456eHans Verkuil	unsigned long req_events = poll_requested_events(wait);
518d2ff3ec81628cbf9470c496b3d0c0780165643f5Janne Grunau	struct hdpvr_buffer *buf = NULL;
519ede197aac0c64021a0b2139d19edd8fa066530c2Hans Verkuil	struct hdpvr_device *dev = video_drvdata(filp);
52065fe42d6054bb84c4abc4168310bd5d7c462456eHans Verkuil	unsigned int mask = v4l2_ctrl_poll(filp, wait);
5219aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
52265fe42d6054bb84c4abc4168310bd5d7c462456eHans Verkuil	if (!(req_events & (POLLIN | POLLRDNORM)))
52365fe42d6054bb84c4abc4168310bd5d7c462456eHans Verkuil		return mask;
5249aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
52565fe42d6054bb84c4abc4168310bd5d7c462456eHans Verkuil	mutex_lock(&dev->io_mutex);
5269aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
5279aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	if (dev->status == STATUS_IDLE) {
5289aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		if (hdpvr_start_streaming(dev)) {
5299ef77adfb9ac170bcaf449530cf129c48547fd55Janne Grunau			v4l2_dbg(MSG_BUFFER, hdpvr_debug, &dev->v4l2_dev,
5309ef77adfb9ac170bcaf449530cf129c48547fd55Janne Grunau				 "start_streaming failed\n");
5319aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			dev->status = STATUS_IDLE;
532ede197aac0c64021a0b2139d19edd8fa066530c2Hans Verkuil		} else {
533ede197aac0c64021a0b2139d19edd8fa066530c2Hans Verkuil			dev->owner = filp->private_data;
5349aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		}
5359aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
536d211bfcbd0f13f1234aaa6e565013dba051a408cJanne Grunau		print_buffer_status();
5379aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	}
5389aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	mutex_unlock(&dev->io_mutex);
5399aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
540d2ff3ec81628cbf9470c496b3d0c0780165643f5Janne Grunau	buf = hdpvr_get_next_buffer(dev);
541d2ff3ec81628cbf9470c496b3d0c0780165643f5Janne Grunau	/* only wait if no data is available */
542d2ff3ec81628cbf9470c496b3d0c0780165643f5Janne Grunau	if (!buf || buf->status != BUFSTAT_READY) {
543d2ff3ec81628cbf9470c496b3d0c0780165643f5Janne Grunau		poll_wait(filp, &dev->wait_data, wait);
544d2ff3ec81628cbf9470c496b3d0c0780165643f5Janne Grunau		buf = hdpvr_get_next_buffer(dev);
5459aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	}
546d2ff3ec81628cbf9470c496b3d0c0780165643f5Janne Grunau	if (buf && buf->status == BUFSTAT_READY)
547d2ff3ec81628cbf9470c496b3d0c0780165643f5Janne Grunau		mask |= POLLIN | POLLRDNORM;
5489aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
5499aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	return mask;
5509aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau}
5519aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
5529aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
5539aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunaustatic const struct v4l2_file_operations hdpvr_fops = {
5549aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	.owner		= THIS_MODULE,
5553315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	.open		= hdpvr_open,
5569aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	.release	= hdpvr_release,
5579aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	.read		= hdpvr_read,
5589aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	.poll		= hdpvr_poll,
55976717b887cccc77d04357fc0d6ac98f894e3eb3cJanne Grunau	.unlocked_ioctl	= video_ioctl2,
5609aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau};
5619aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
5629aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau/*=======================================================================*/
5639aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau/*
5649aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau * V4L2 ioctl handling
5659aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau */
5669aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
5679aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunaustatic int vidioc_querycap(struct file *file, void  *priv,
5689aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			   struct v4l2_capability *cap)
5699aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau{
5709aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	struct hdpvr_device *dev = video_drvdata(file);
5719aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
5729aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	strcpy(cap->driver, "hdpvr");
573fdd70c3399fc448a87487b287f4f0dcfb2e9c52cLars Hanisch	strcpy(cap->card, "Hauppauge HD PVR");
5749aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	usb_make_path(dev->udev, cap->bus_info, sizeof(cap->bus_info));
57541022fcb3db75c9777bbd05da114c7eb597694dfHans Verkuil	cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_AUDIO |
57641022fcb3db75c9777bbd05da114c7eb597694dfHans Verkuil			    V4L2_CAP_READWRITE;
57741022fcb3db75c9777bbd05da114c7eb597694dfHans Verkuil	cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
5789aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	return 0;
5799aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau}
5809aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
5815854bf88599545572ce89fba6c4fa0bf6b6e226cHans Verkuilstatic int vidioc_s_std(struct file *file, void *_fh,
582314527acbbb3f33f72c2ef19d8cfabcada9912a5Hans Verkuil			v4l2_std_id std)
5839aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau{
584ede197aac0c64021a0b2139d19edd8fa066530c2Hans Verkuil	struct hdpvr_device *dev = video_drvdata(file);
5855854bf88599545572ce89fba6c4fa0bf6b6e226cHans Verkuil	struct hdpvr_fh *fh = _fh;
5869aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	u8 std_type = 1;
5879aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
5885854bf88599545572ce89fba6c4fa0bf6b6e226cHans Verkuil	if (!fh->legacy_mode && dev->options.video_input == HDPVR_COMPONENT)
5898f69da955873f5e33b60ff117856a2bf1309a336Hans Verkuil		return -ENODATA;
5908f69da955873f5e33b60ff117856a2bf1309a336Hans Verkuil	if (dev->status != STATUS_IDLE)
5918f69da955873f5e33b60ff117856a2bf1309a336Hans Verkuil		return -EBUSY;
5928f69da955873f5e33b60ff117856a2bf1309a336Hans Verkuil	if (std & V4L2_STD_525_60)
5939aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		std_type = 0;
5948f69da955873f5e33b60ff117856a2bf1309a336Hans Verkuil	dev->cur_std = std;
5958f69da955873f5e33b60ff117856a2bf1309a336Hans Verkuil	dev->width = 720;
5968f69da955873f5e33b60ff117856a2bf1309a336Hans Verkuil	dev->height = std_type ? 576 : 480;
5979aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
5989aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	return hdpvr_config_call(dev, CTRL_VIDEO_STD_TYPE, std_type);
5999aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau}
6009aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
6015854bf88599545572ce89fba6c4fa0bf6b6e226cHans Verkuilstatic int vidioc_g_std(struct file *file, void *_fh,
6028f69da955873f5e33b60ff117856a2bf1309a336Hans Verkuil			v4l2_std_id *std)
6038f69da955873f5e33b60ff117856a2bf1309a336Hans Verkuil{
6048f69da955873f5e33b60ff117856a2bf1309a336Hans Verkuil	struct hdpvr_device *dev = video_drvdata(file);
6055854bf88599545572ce89fba6c4fa0bf6b6e226cHans Verkuil	struct hdpvr_fh *fh = _fh;
6068f69da955873f5e33b60ff117856a2bf1309a336Hans Verkuil
6075854bf88599545572ce89fba6c4fa0bf6b6e226cHans Verkuil	if (!fh->legacy_mode && dev->options.video_input == HDPVR_COMPONENT)
6088f69da955873f5e33b60ff117856a2bf1309a336Hans Verkuil		return -ENODATA;
6098f69da955873f5e33b60ff117856a2bf1309a336Hans Verkuil	*std = dev->cur_std;
6108f69da955873f5e33b60ff117856a2bf1309a336Hans Verkuil	return 0;
6118f69da955873f5e33b60ff117856a2bf1309a336Hans Verkuil}
6128f69da955873f5e33b60ff117856a2bf1309a336Hans Verkuil
6135854bf88599545572ce89fba6c4fa0bf6b6e226cHans Verkuilstatic int vidioc_querystd(struct file *file, void *_fh, v4l2_std_id *a)
6148f69da955873f5e33b60ff117856a2bf1309a336Hans Verkuil{
6158f69da955873f5e33b60ff117856a2bf1309a336Hans Verkuil	struct hdpvr_device *dev = video_drvdata(file);
6164d601c4ca272959ba837b8279f4873b55caaf619Leonid Kegulskiy	struct hdpvr_video_info vid_info;
6175854bf88599545572ce89fba6c4fa0bf6b6e226cHans Verkuil	struct hdpvr_fh *fh = _fh;
6184d601c4ca272959ba837b8279f4873b55caaf619Leonid Kegulskiy	int ret;
6198f69da955873f5e33b60ff117856a2bf1309a336Hans Verkuil
620ab6e134a48a58b111f28dfb5c8440a56d6be10c5Hans Verkuil	*a = V4L2_STD_UNKNOWN;
6215854bf88599545572ce89fba6c4fa0bf6b6e226cHans Verkuil	if (dev->options.video_input == HDPVR_COMPONENT)
6225854bf88599545572ce89fba6c4fa0bf6b6e226cHans Verkuil		return fh->legacy_mode ? 0 : -ENODATA;
6234d601c4ca272959ba837b8279f4873b55caaf619Leonid Kegulskiy	ret = get_video_info(dev, &vid_info);
6245f454d82e5958e59c16580b9b4531f4bbc7231f7Hans Verkuil	if (vid_info.valid && vid_info.width == 720 &&
6254d601c4ca272959ba837b8279f4873b55caaf619Leonid Kegulskiy	    (vid_info.height == 480 || vid_info.height == 576)) {
6264d601c4ca272959ba837b8279f4873b55caaf619Leonid Kegulskiy		*a = (vid_info.height == 480) ?
6278f69da955873f5e33b60ff117856a2bf1309a336Hans Verkuil			V4L2_STD_525_60 : V4L2_STD_625_50;
6288f69da955873f5e33b60ff117856a2bf1309a336Hans Verkuil	}
6295f454d82e5958e59c16580b9b4531f4bbc7231f7Hans Verkuil	return ret;
6308f69da955873f5e33b60ff117856a2bf1309a336Hans Verkuil}
6318f69da955873f5e33b60ff117856a2bf1309a336Hans Verkuil
6323315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuilstatic int vidioc_s_dv_timings(struct file *file, void *_fh,
6333315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil				    struct v4l2_dv_timings *timings)
6343315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil{
6353315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	struct hdpvr_device *dev = video_drvdata(file);
6363315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	struct hdpvr_fh *fh = _fh;
6373315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	int i;
6383315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil
6393315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	fh->legacy_mode = false;
6403315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	if (dev->options.video_input)
6413315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil		return -ENODATA;
6423315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	if (dev->status != STATUS_IDLE)
6433315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil		return -EBUSY;
6443315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	for (i = 0; i < ARRAY_SIZE(hdpvr_dv_timings); i++)
645ef1ed8f5d366a035e532456bd747d34e5cb01ee5Hans Verkuil		if (v4l2_match_dv_timings(timings, hdpvr_dv_timings + i, 0))
6463315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil			break;
6473315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	if (i == ARRAY_SIZE(hdpvr_dv_timings))
6483315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil		return -EINVAL;
6493315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	dev->cur_dv_timings = hdpvr_dv_timings[i];
6503315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	dev->width = hdpvr_dv_timings[i].bt.width;
6513315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	dev->height = hdpvr_dv_timings[i].bt.height;
6523315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	return 0;
6533315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil}
6543315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil
6553315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuilstatic int vidioc_g_dv_timings(struct file *file, void *_fh,
6563315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil				    struct v4l2_dv_timings *timings)
6573315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil{
6583315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	struct hdpvr_device *dev = video_drvdata(file);
6593315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	struct hdpvr_fh *fh = _fh;
6603315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil
6613315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	fh->legacy_mode = false;
6623315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	if (dev->options.video_input)
6633315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil		return -ENODATA;
6643315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	*timings = dev->cur_dv_timings;
6653315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	return 0;
6663315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil}
6673315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil
6683315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuilstatic int vidioc_query_dv_timings(struct file *file, void *_fh,
6693315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil				    struct v4l2_dv_timings *timings)
6703315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil{
6713315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	struct hdpvr_device *dev = video_drvdata(file);
6723315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	struct hdpvr_fh *fh = _fh;
6734d601c4ca272959ba837b8279f4873b55caaf619Leonid Kegulskiy	struct hdpvr_video_info vid_info;
6743315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	bool interlaced;
6753315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	int ret = 0;
6763315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	int i;
6773315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil
6783315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	fh->legacy_mode = false;
6793315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	if (dev->options.video_input)
6803315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil		return -ENODATA;
6814d601c4ca272959ba837b8279f4873b55caaf619Leonid Kegulskiy	ret = get_video_info(dev, &vid_info);
6824d601c4ca272959ba837b8279f4873b55caaf619Leonid Kegulskiy	if (ret)
6835f454d82e5958e59c16580b9b4531f4bbc7231f7Hans Verkuil		return ret;
6845f454d82e5958e59c16580b9b4531f4bbc7231f7Hans Verkuil	if (!vid_info.valid)
6853315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil		return -ENOLCK;
6864d601c4ca272959ba837b8279f4873b55caaf619Leonid Kegulskiy	interlaced = vid_info.fps <= 30;
6873315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	for (i = 0; i < ARRAY_SIZE(hdpvr_dv_timings); i++) {
6883315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil		const struct v4l2_bt_timings *bt = &hdpvr_dv_timings[i].bt;
6893315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil		unsigned hsize;
6903315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil		unsigned vsize;
6913315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil		unsigned fps;
6923315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil
693eacf8f9aa80e2231af43b589cfc18c054e417220Hans Verkuil		hsize = V4L2_DV_BT_FRAME_WIDTH(bt);
694eacf8f9aa80e2231af43b589cfc18c054e417220Hans Verkuil		vsize = V4L2_DV_BT_FRAME_HEIGHT(bt);
6953315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil		fps = (unsigned)bt->pixelclock / (hsize * vsize);
6964d601c4ca272959ba837b8279f4873b55caaf619Leonid Kegulskiy		if (bt->width != vid_info.width ||
6974d601c4ca272959ba837b8279f4873b55caaf619Leonid Kegulskiy		    bt->height != vid_info.height ||
6983315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil		    bt->interlaced != interlaced ||
6994d601c4ca272959ba837b8279f4873b55caaf619Leonid Kegulskiy		    (fps != vid_info.fps && fps + 1 != vid_info.fps))
7003315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil			continue;
7013315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil		*timings = hdpvr_dv_timings[i];
7023315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil		break;
7033315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	}
7043315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	if (i == ARRAY_SIZE(hdpvr_dv_timings))
7053315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil		ret = -ERANGE;
7064d601c4ca272959ba837b8279f4873b55caaf619Leonid Kegulskiy
7073315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	return ret;
7083315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil}
7093315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil
7103315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuilstatic int vidioc_enum_dv_timings(struct file *file, void *_fh,
7113315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil				    struct v4l2_enum_dv_timings *timings)
7123315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil{
7133315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	struct hdpvr_device *dev = video_drvdata(file);
7143315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	struct hdpvr_fh *fh = _fh;
7153315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil
7163315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	fh->legacy_mode = false;
7173315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	memset(timings->reserved, 0, sizeof(timings->reserved));
7183315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	if (dev->options.video_input)
7193315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil		return -ENODATA;
7203315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	if (timings->index >= ARRAY_SIZE(hdpvr_dv_timings))
7213315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil		return -EINVAL;
7223315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	timings->timings = hdpvr_dv_timings[timings->index];
7233315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	return 0;
7243315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil}
7253315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil
7263315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuilstatic int vidioc_dv_timings_cap(struct file *file, void *_fh,
7273315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil				    struct v4l2_dv_timings_cap *cap)
7283315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil{
7293315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	struct hdpvr_device *dev = video_drvdata(file);
7303315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	struct hdpvr_fh *fh = _fh;
7313315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil
7323315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	fh->legacy_mode = false;
7333315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	if (dev->options.video_input)
7343315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil		return -ENODATA;
7353315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	cap->type = V4L2_DV_BT_656_1120;
7363315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	cap->bt.min_width = 720;
7373315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	cap->bt.max_width = 1920;
7383315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	cap->bt.min_height = 480;
7393315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	cap->bt.max_height = 1080;
7403315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	cap->bt.min_pixelclock = 27000000;
7413315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	cap->bt.max_pixelclock = 74250000;
7423315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	cap->bt.standards = V4L2_DV_BT_STD_CEA861;
7433315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	cap->bt.capabilities = V4L2_DV_BT_CAP_INTERLACED | V4L2_DV_BT_CAP_PROGRESSIVE;
7443315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	return 0;
7453315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil}
7463315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil
7479aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunaustatic const char *iname[] = {
7489aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	[HDPVR_COMPONENT] = "Component",
7499aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	[HDPVR_SVIDEO]    = "S-Video",
7509aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	[HDPVR_COMPOSITE] = "Composite",
7519aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau};
7529aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
7535854bf88599545572ce89fba6c4fa0bf6b6e226cHans Verkuilstatic int vidioc_enum_input(struct file *file, void *_fh, struct v4l2_input *i)
7549aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau{
7559aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	unsigned int n;
7569aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
7579aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	n = i->index;
7589aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	if (n >= HDPVR_VIDEO_INPUTS)
7599aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		return -EINVAL;
7609aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
7619aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	i->type = V4L2_INPUT_TYPE_CAMERA;
7629aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
7639aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	strncpy(i->name, iname[n], sizeof(i->name) - 1);
7649aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	i->name[sizeof(i->name) - 1] = '\0';
7659aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
7669aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	i->audioset = 1<<HDPVR_RCA_FRONT | 1<<HDPVR_RCA_BACK | 1<<HDPVR_SPDIF;
7679aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
7688f69da955873f5e33b60ff117856a2bf1309a336Hans Verkuil	i->capabilities = n ? V4L2_IN_CAP_STD : V4L2_IN_CAP_DV_TIMINGS;
7698f69da955873f5e33b60ff117856a2bf1309a336Hans Verkuil	i->std = n ? V4L2_STD_ALL : 0;
7709aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
7719aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	return 0;
7729aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau}
7739aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
7745854bf88599545572ce89fba6c4fa0bf6b6e226cHans Verkuilstatic int vidioc_s_input(struct file *file, void *_fh,
7759aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			  unsigned int index)
7769aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau{
777ede197aac0c64021a0b2139d19edd8fa066530c2Hans Verkuil	struct hdpvr_device *dev = video_drvdata(file);
7789aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	int retval;
7799aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
7809aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	if (index >= HDPVR_VIDEO_INPUTS)
7819aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		return -EINVAL;
7829aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
7839aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	if (dev->status != STATUS_IDLE)
78497caa318b3ced2241cf1eda772a72c9c2ea19abbHans Verkuil		return -EBUSY;
7859aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
7869aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	retval = hdpvr_config_call(dev, CTRL_VIDEO_INPUT_VALUE, index+1);
7878f69da955873f5e33b60ff117856a2bf1309a336Hans Verkuil	if (!retval) {
7889aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		dev->options.video_input = index;
7895854bf88599545572ce89fba6c4fa0bf6b6e226cHans Verkuil		/*
7905854bf88599545572ce89fba6c4fa0bf6b6e226cHans Verkuil		 * Unfortunately gstreamer calls ENUMSTD and bails out if it
7915854bf88599545572ce89fba6c4fa0bf6b6e226cHans Verkuil		 * won't find any formats, even though component input is
7925854bf88599545572ce89fba6c4fa0bf6b6e226cHans Verkuil		 * selected. This means that we have to leave tvnorms at
7935854bf88599545572ce89fba6c4fa0bf6b6e226cHans Verkuil		 * V4L2_STD_ALL. We cannot use the 'legacy' trick since
7945854bf88599545572ce89fba6c4fa0bf6b6e226cHans Verkuil		 * tvnorms is set at the device node level and not at the
7955854bf88599545572ce89fba6c4fa0bf6b6e226cHans Verkuil		 * filehandle level.
7965854bf88599545572ce89fba6c4fa0bf6b6e226cHans Verkuil		 *
7975854bf88599545572ce89fba6c4fa0bf6b6e226cHans Verkuil		 * Comment this out for now, but if the legacy mode can be
7985854bf88599545572ce89fba6c4fa0bf6b6e226cHans Verkuil		 * removed in the future, then this code should be enabled
7995854bf88599545572ce89fba6c4fa0bf6b6e226cHans Verkuil		 * again.
8008f69da955873f5e33b60ff117856a2bf1309a336Hans Verkuil		dev->video_dev->tvnorms =
8015854bf88599545572ce89fba6c4fa0bf6b6e226cHans Verkuil			(index != HDPVR_COMPONENT) ? V4L2_STD_ALL : 0;
8025854bf88599545572ce89fba6c4fa0bf6b6e226cHans Verkuil		 */
8038f69da955873f5e33b60ff117856a2bf1309a336Hans Verkuil	}
8049aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
8059aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	return retval;
8069aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau}
8079aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
8089aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunaustatic int vidioc_g_input(struct file *file, void *private_data,
8099aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			  unsigned int *index)
8109aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau{
811ede197aac0c64021a0b2139d19edd8fa066530c2Hans Verkuil	struct hdpvr_device *dev = video_drvdata(file);
8129aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
8139aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	*index = dev->options.video_input;
8149aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	return 0;
8159aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau}
8169aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
8179aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
8189aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunaustatic const char *audio_iname[] = {
8199aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	[HDPVR_RCA_FRONT] = "RCA front",
8209aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	[HDPVR_RCA_BACK]  = "RCA back",
8219aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	[HDPVR_SPDIF]     = "SPDIF",
8229aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau};
8239aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
8249aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunaustatic int vidioc_enumaudio(struct file *file, void *priv,
8259aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau				struct v4l2_audio *audio)
8269aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau{
8279aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	unsigned int n;
8289aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
8299aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	n = audio->index;
8309aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	if (n >= HDPVR_AUDIO_INPUTS)
8319aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		return -EINVAL;
8329aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
8339aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	audio->capability = V4L2_AUDCAP_STEREO;
8349aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
8359aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	strncpy(audio->name, audio_iname[n], sizeof(audio->name) - 1);
8369aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	audio->name[sizeof(audio->name) - 1] = '\0';
8379aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
8389aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	return 0;
8399aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau}
8409aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
8419aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunaustatic int vidioc_s_audio(struct file *file, void *private_data,
8420e8025b9f6011a6bd69d01080d584bc95a89d02eHans Verkuil			  const struct v4l2_audio *audio)
8439aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau{
844ede197aac0c64021a0b2139d19edd8fa066530c2Hans Verkuil	struct hdpvr_device *dev = video_drvdata(file);
8459aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	int retval;
8469aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
8479aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	if (audio->index >= HDPVR_AUDIO_INPUTS)
8489aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		return -EINVAL;
8499aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
8509aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	if (dev->status != STATUS_IDLE)
85197caa318b3ced2241cf1eda772a72c9c2ea19abbHans Verkuil		return -EBUSY;
8529aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
8539aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	retval = hdpvr_set_audio(dev, audio->index+1, dev->options.audio_codec);
8549aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	if (!retval)
8559aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		dev->options.audio_input = audio->index;
8569aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
8579aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	return retval;
8589aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau}
8599aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
8609aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunaustatic int vidioc_g_audio(struct file *file, void *private_data,
8619aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			  struct v4l2_audio *audio)
8629aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau{
863ede197aac0c64021a0b2139d19edd8fa066530c2Hans Verkuil	struct hdpvr_device *dev = video_drvdata(file);
8649aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
8659aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	audio->index = dev->options.audio_input;
8669aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	audio->capability = V4L2_AUDCAP_STEREO;
8679aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	strncpy(audio->name, audio_iname[audio->index], sizeof(audio->name));
8689aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	audio->name[sizeof(audio->name) - 1] = '\0';
8699aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	return 0;
8709aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau}
8719aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
87299c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuilstatic int hdpvr_try_ctrl(struct v4l2_ctrl *ctrl)
8739aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau{
87499c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil	struct hdpvr_device *dev =
87599c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil		container_of(ctrl->handler, struct hdpvr_device, hdl);
8769aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
8779aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	switch (ctrl->id) {
87899c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil	case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
87999c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil		if (ctrl->val == V4L2_MPEG_VIDEO_BITRATE_MODE_VBR &&
88099c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil		    dev->video_bitrate->val >= dev->video_bitrate_peak->val)
88199c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil			dev->video_bitrate_peak->val =
88299c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil					dev->video_bitrate->val + 100000;
8839aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		break;
8849aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	}
8859aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	return 0;
8869aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau}
8879aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
88899c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuilstatic int hdpvr_s_ctrl(struct v4l2_ctrl *ctrl)
8899aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau{
89099c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil	struct hdpvr_device *dev =
89199c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil		container_of(ctrl->handler, struct hdpvr_device, hdl);
89299c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil	struct hdpvr_options *opt = &dev->options;
89399c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil	int ret = -EINVAL;
8949aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
8959aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	switch (ctrl->id) {
8969aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	case V4L2_CID_BRIGHTNESS:
89799c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil		ret = hdpvr_config_call(dev, CTRL_BRIGHTNESS, ctrl->val);
89899c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil		if (ret)
89999c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil			break;
90099c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil		dev->options.brightness = ctrl->val;
90199c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil		return 0;
9029aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	case V4L2_CID_CONTRAST:
90399c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil		ret = hdpvr_config_call(dev, CTRL_CONTRAST, ctrl->val);
90499c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil		if (ret)
90599c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil			break;
90699c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil		dev->options.contrast = ctrl->val;
90799c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil		return 0;
9089aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	case V4L2_CID_SATURATION:
90999c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil		ret = hdpvr_config_call(dev, CTRL_SATURATION, ctrl->val);
91099c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil		if (ret)
91199c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil			break;
91299c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil		dev->options.saturation = ctrl->val;
91399c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil		return 0;
9149aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	case V4L2_CID_HUE:
91599c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil		ret = hdpvr_config_call(dev, CTRL_HUE, ctrl->val);
91699c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil		if (ret)
91799c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil			break;
91899c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil		dev->options.hue = ctrl->val;
91999c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil		return 0;
9209aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	case V4L2_CID_SHARPNESS:
92199c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil		ret = hdpvr_config_call(dev, CTRL_SHARPNESS, ctrl->val);
92299c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil		if (ret)
92399c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil			break;
92499c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil		dev->options.sharpness = ctrl->val;
92599c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil		return 0;
9269aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	case V4L2_CID_MPEG_AUDIO_ENCODING:
9279aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		if (dev->flags & HDPVR_FLAG_AC3_CAP) {
92899c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil			opt->audio_codec = ctrl->val;
9293445857b22eafb70a6ac258979e955b116bfd2c6Hans Verkuil			return hdpvr_set_audio(dev, opt->audio_input + 1,
9309aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau					      opt->audio_codec);
9319aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		}
93299c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil		return 0;
9339aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	case V4L2_CID_MPEG_VIDEO_ENCODING:
93499c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil		return 0;
9359aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau/* 	case V4L2_CID_MPEG_VIDEO_B_FRAMES: */
9369aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau/* 		if (ctrl->value == 0 && !(opt->gop_mode & 0x2)) { */
9379aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau/* 			opt->gop_mode |= 0x2; */
9389aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau/* 			hdpvr_config_call(dev, CTRL_GOP_MODE_VALUE, */
9399aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau/* 					  opt->gop_mode); */
9409aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau/* 		} */
9419aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau/* 		if (ctrl->value == 128 && opt->gop_mode & 0x2) { */
9429aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau/* 			opt->gop_mode &= ~0x2; */
9439aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau/* 			hdpvr_config_call(dev, CTRL_GOP_MODE_VALUE, */
9449aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau/* 					  opt->gop_mode); */
9459aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau/* 		} */
9469aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau/* 		break; */
94799c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil	case V4L2_CID_MPEG_VIDEO_BITRATE_MODE: {
94899c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil		uint peak_bitrate = dev->video_bitrate_peak->val / 100000;
94999c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil		uint bitrate = dev->video_bitrate->val / 100000;
95099c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil
95199c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil		if (ctrl->is_new) {
95299c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil			if (ctrl->val == V4L2_MPEG_VIDEO_BITRATE_MODE_CBR)
95399c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil				opt->bitrate_mode = HDPVR_CONSTANT;
95499c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil			else
95599c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil				opt->bitrate_mode = HDPVR_VARIABLE_AVERAGE;
9569aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			hdpvr_config_call(dev, CTRL_BITRATE_MODE_VALUE,
9579aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau					  opt->bitrate_mode);
95899c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil			v4l2_ctrl_activate(dev->video_bitrate_peak,
95999c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil				ctrl->val != V4L2_MPEG_VIDEO_BITRATE_MODE_CBR);
9609aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		}
9619aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
96299c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil		if (dev->video_bitrate_peak->is_new ||
96399c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil		    dev->video_bitrate->is_new) {
96499c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil			opt->bitrate = bitrate;
9659aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			opt->peak_bitrate = peak_bitrate;
9669aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			hdpvr_set_bitrate(dev);
96799c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil		}
96899c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil		return 0;
9699aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	}
9709aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	case V4L2_CID_MPEG_STREAM_TYPE:
97199c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil		return 0;
9729aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	default:
97399c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil		break;
9749aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	}
9759aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	return ret;
9769aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau}
9779aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
9789aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunaustatic int vidioc_enum_fmt_vid_cap(struct file *file, void *private_data,
9799aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau				    struct v4l2_fmtdesc *f)
9809aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau{
98197caa318b3ced2241cf1eda772a72c9c2ea19abbHans Verkuil	if (f->index != 0)
9829aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		return -EINVAL;
9839aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
9849aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	f->flags = V4L2_FMT_FLAG_COMPRESSED;
9859aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	strncpy(f->description, "MPEG2-TS with AVC/AAC streams", 32);
9869aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	f->pixelformat = V4L2_PIX_FMT_MPEG;
9879aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
9889aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	return 0;
9899aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau}
9909aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
9913315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuilstatic int vidioc_g_fmt_vid_cap(struct file *file, void *_fh,
9929aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau				struct v4l2_format *f)
9939aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau{
994ede197aac0c64021a0b2139d19edd8fa066530c2Hans Verkuil	struct hdpvr_device *dev = video_drvdata(file);
9953315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	struct hdpvr_fh *fh = _fh;
9964d601c4ca272959ba837b8279f4873b55caaf619Leonid Kegulskiy	int ret;
9973315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil
9983315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	/*
9993315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	 * The original driver would always returns the current detected
10003315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	 * resolution as the format (and EFAULT if it couldn't be detected).
10013315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	 * With the introduction of VIDIOC_QUERY_DV_TIMINGS there is now a
10023315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	 * better way of doing this, but to stay compatible with existing
10033315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	 * applications we assume legacy mode every time an application opens
10043315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	 * the device. Only if one of the new DV_TIMINGS ioctls is called
10053315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	 * will the filehandle go into 'normal' mode where g_fmt returns the
10063315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	 * last set format.
10073315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	 */
10083315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	if (fh->legacy_mode) {
10094d601c4ca272959ba837b8279f4873b55caaf619Leonid Kegulskiy		struct hdpvr_video_info vid_info;
10103315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil
10114d601c4ca272959ba837b8279f4873b55caaf619Leonid Kegulskiy		ret = get_video_info(dev, &vid_info);
10125f454d82e5958e59c16580b9b4531f4bbc7231f7Hans Verkuil		if (ret < 0)
10135f454d82e5958e59c16580b9b4531f4bbc7231f7Hans Verkuil			return ret;
10145f454d82e5958e59c16580b9b4531f4bbc7231f7Hans Verkuil		if (!vid_info.valid)
10153315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil			return -EFAULT;
10164d601c4ca272959ba837b8279f4873b55caaf619Leonid Kegulskiy		f->fmt.pix.width = vid_info.width;
10174d601c4ca272959ba837b8279f4873b55caaf619Leonid Kegulskiy		f->fmt.pix.height = vid_info.height;
10183315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	} else {
10193315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil		f->fmt.pix.width = dev->width;
10203315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil		f->fmt.pix.height = dev->height;
10213315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	}
10229aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	f->fmt.pix.pixelformat	= V4L2_PIX_FMT_MPEG;
10239aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	f->fmt.pix.sizeimage	= dev->bulk_in_size;
10249aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	f->fmt.pix.bytesperline	= 0;
10253315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	if (f->fmt.pix.width == 720) {
10263315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil		/* SDTV formats */
10273315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil		f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
10283315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil		f->fmt.pix.field = V4L2_FIELD_INTERLACED;
10293315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	} else {
10303315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil		/* HDTV formats */
103193e6a855fff6bbf95486975e193c13faba47775dHans Verkuil		f->fmt.pix.colorspace = V4L2_COLORSPACE_REC709;
10323315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil		f->fmt.pix.field = V4L2_FIELD_NONE;
10333315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	}
10349aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	return 0;
10359aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau}
10369aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
103776717b887cccc77d04357fc0d6ac98f894e3eb3cJanne Grunaustatic int vidioc_encoder_cmd(struct file *filp, void *priv,
103876717b887cccc77d04357fc0d6ac98f894e3eb3cJanne Grunau			       struct v4l2_encoder_cmd *a)
103976717b887cccc77d04357fc0d6ac98f894e3eb3cJanne Grunau{
1040ede197aac0c64021a0b2139d19edd8fa066530c2Hans Verkuil	struct hdpvr_device *dev = video_drvdata(filp);
1041ede197aac0c64021a0b2139d19edd8fa066530c2Hans Verkuil	int res = 0;
104276717b887cccc77d04357fc0d6ac98f894e3eb3cJanne Grunau
104376717b887cccc77d04357fc0d6ac98f894e3eb3cJanne Grunau	mutex_lock(&dev->io_mutex);
1044ede197aac0c64021a0b2139d19edd8fa066530c2Hans Verkuil	a->flags = 0;
104576717b887cccc77d04357fc0d6ac98f894e3eb3cJanne Grunau
104676717b887cccc77d04357fc0d6ac98f894e3eb3cJanne Grunau	switch (a->cmd) {
104776717b887cccc77d04357fc0d6ac98f894e3eb3cJanne Grunau	case V4L2_ENC_CMD_START:
1048ede197aac0c64021a0b2139d19edd8fa066530c2Hans Verkuil		if (dev->owner && filp->private_data != dev->owner) {
1049ede197aac0c64021a0b2139d19edd8fa066530c2Hans Verkuil			res = -EBUSY;
1050ede197aac0c64021a0b2139d19edd8fa066530c2Hans Verkuil			break;
1051ede197aac0c64021a0b2139d19edd8fa066530c2Hans Verkuil		}
1052ede197aac0c64021a0b2139d19edd8fa066530c2Hans Verkuil		if (dev->status == STATUS_STREAMING)
1053ede197aac0c64021a0b2139d19edd8fa066530c2Hans Verkuil			break;
105476717b887cccc77d04357fc0d6ac98f894e3eb3cJanne Grunau		res = hdpvr_start_streaming(dev);
1055ede197aac0c64021a0b2139d19edd8fa066530c2Hans Verkuil		if (!res)
1056ede197aac0c64021a0b2139d19edd8fa066530c2Hans Verkuil			dev->owner = filp->private_data;
1057ede197aac0c64021a0b2139d19edd8fa066530c2Hans Verkuil		else
1058ede197aac0c64021a0b2139d19edd8fa066530c2Hans Verkuil			dev->status = STATUS_IDLE;
105976717b887cccc77d04357fc0d6ac98f894e3eb3cJanne Grunau		break;
106076717b887cccc77d04357fc0d6ac98f894e3eb3cJanne Grunau	case V4L2_ENC_CMD_STOP:
1061ede197aac0c64021a0b2139d19edd8fa066530c2Hans Verkuil		if (dev->owner && filp->private_data != dev->owner) {
1062ede197aac0c64021a0b2139d19edd8fa066530c2Hans Verkuil			res = -EBUSY;
1063ede197aac0c64021a0b2139d19edd8fa066530c2Hans Verkuil			break;
1064ede197aac0c64021a0b2139d19edd8fa066530c2Hans Verkuil		}
1065ede197aac0c64021a0b2139d19edd8fa066530c2Hans Verkuil		if (dev->status == STATUS_IDLE)
1066ede197aac0c64021a0b2139d19edd8fa066530c2Hans Verkuil			break;
106776717b887cccc77d04357fc0d6ac98f894e3eb3cJanne Grunau		res = hdpvr_stop_streaming(dev);
1068ede197aac0c64021a0b2139d19edd8fa066530c2Hans Verkuil		if (!res)
1069ede197aac0c64021a0b2139d19edd8fa066530c2Hans Verkuil			dev->owner = NULL;
107076717b887cccc77d04357fc0d6ac98f894e3eb3cJanne Grunau		break;
107176717b887cccc77d04357fc0d6ac98f894e3eb3cJanne Grunau	default:
10729ef77adfb9ac170bcaf449530cf129c48547fd55Janne Grunau		v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev,
107376717b887cccc77d04357fc0d6ac98f894e3eb3cJanne Grunau			 "Unsupported encoder cmd %d\n", a->cmd);
107448f98f7557d35d360470bf6d9fd7b00d04fba828Janne Grunau		res = -EINVAL;
1075ede197aac0c64021a0b2139d19edd8fa066530c2Hans Verkuil		break;
107676717b887cccc77d04357fc0d6ac98f894e3eb3cJanne Grunau	}
1077ede197aac0c64021a0b2139d19edd8fa066530c2Hans Verkuil
107876717b887cccc77d04357fc0d6ac98f894e3eb3cJanne Grunau	mutex_unlock(&dev->io_mutex);
107976717b887cccc77d04357fc0d6ac98f894e3eb3cJanne Grunau	return res;
108076717b887cccc77d04357fc0d6ac98f894e3eb3cJanne Grunau}
108176717b887cccc77d04357fc0d6ac98f894e3eb3cJanne Grunau
108276717b887cccc77d04357fc0d6ac98f894e3eb3cJanne Grunaustatic int vidioc_try_encoder_cmd(struct file *filp, void *priv,
108376717b887cccc77d04357fc0d6ac98f894e3eb3cJanne Grunau					struct v4l2_encoder_cmd *a)
108476717b887cccc77d04357fc0d6ac98f894e3eb3cJanne Grunau{
1085ede197aac0c64021a0b2139d19edd8fa066530c2Hans Verkuil	a->flags = 0;
108676717b887cccc77d04357fc0d6ac98f894e3eb3cJanne Grunau	switch (a->cmd) {
108776717b887cccc77d04357fc0d6ac98f894e3eb3cJanne Grunau	case V4L2_ENC_CMD_START:
108876717b887cccc77d04357fc0d6ac98f894e3eb3cJanne Grunau	case V4L2_ENC_CMD_STOP:
108976717b887cccc77d04357fc0d6ac98f894e3eb3cJanne Grunau		return 0;
109076717b887cccc77d04357fc0d6ac98f894e3eb3cJanne Grunau	default:
109176717b887cccc77d04357fc0d6ac98f894e3eb3cJanne Grunau		return -EINVAL;
109276717b887cccc77d04357fc0d6ac98f894e3eb3cJanne Grunau	}
109376717b887cccc77d04357fc0d6ac98f894e3eb3cJanne Grunau}
10949aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
10959aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunaustatic const struct v4l2_ioctl_ops hdpvr_ioctl_ops = {
10969aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	.vidioc_querycap	= vidioc_querycap,
10979aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	.vidioc_s_std		= vidioc_s_std,
10988f69da955873f5e33b60ff117856a2bf1309a336Hans Verkuil	.vidioc_g_std		= vidioc_g_std,
10998f69da955873f5e33b60ff117856a2bf1309a336Hans Verkuil	.vidioc_querystd	= vidioc_querystd,
11003315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	.vidioc_s_dv_timings	= vidioc_s_dv_timings,
11013315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	.vidioc_g_dv_timings	= vidioc_g_dv_timings,
11023315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	.vidioc_query_dv_timings= vidioc_query_dv_timings,
11033315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	.vidioc_enum_dv_timings	= vidioc_enum_dv_timings,
11043315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	.vidioc_dv_timings_cap	= vidioc_dv_timings_cap,
11059aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	.vidioc_enum_input	= vidioc_enum_input,
11069aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	.vidioc_g_input		= vidioc_g_input,
11079aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	.vidioc_s_input		= vidioc_s_input,
11089aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	.vidioc_enumaudio	= vidioc_enumaudio,
11099aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	.vidioc_g_audio		= vidioc_g_audio,
11109aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	.vidioc_s_audio		= vidioc_s_audio,
111165fe42d6054bb84c4abc4168310bd5d7c462456eHans Verkuil	.vidioc_enum_fmt_vid_cap= vidioc_enum_fmt_vid_cap,
111265fe42d6054bb84c4abc4168310bd5d7c462456eHans Verkuil	.vidioc_g_fmt_vid_cap	= vidioc_g_fmt_vid_cap,
11133315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	.vidioc_s_fmt_vid_cap	= vidioc_g_fmt_vid_cap,
11143315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	.vidioc_try_fmt_vid_cap	= vidioc_g_fmt_vid_cap,
111576717b887cccc77d04357fc0d6ac98f894e3eb3cJanne Grunau	.vidioc_encoder_cmd	= vidioc_encoder_cmd,
111676717b887cccc77d04357fc0d6ac98f894e3eb3cJanne Grunau	.vidioc_try_encoder_cmd	= vidioc_try_encoder_cmd,
111765fe42d6054bb84c4abc4168310bd5d7c462456eHans Verkuil	.vidioc_log_status	= v4l2_ctrl_log_status,
111865fe42d6054bb84c4abc4168310bd5d7c462456eHans Verkuil	.vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
111965fe42d6054bb84c4abc4168310bd5d7c462456eHans Verkuil	.vidioc_unsubscribe_event = v4l2_event_unsubscribe,
11209aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau};
11219aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
11229aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunaustatic void hdpvr_device_release(struct video_device *vdev)
11239aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau{
11249aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	struct hdpvr_device *dev = video_get_drvdata(vdev);
11259aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
11269aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	hdpvr_delete(dev);
1127f2b305cd6711b7b3ce30db93b50bc5d6312950c8Hans Verkuil	mutex_lock(&dev->io_mutex);
1128f2b305cd6711b7b3ce30db93b50bc5d6312950c8Hans Verkuil	destroy_workqueue(dev->workqueue);
1129f2b305cd6711b7b3ce30db93b50bc5d6312950c8Hans Verkuil	mutex_unlock(&dev->io_mutex);
1130f2b305cd6711b7b3ce30db93b50bc5d6312950c8Hans Verkuil
1131f2b305cd6711b7b3ce30db93b50bc5d6312950c8Hans Verkuil	v4l2_device_unregister(&dev->v4l2_dev);
113299c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil	v4l2_ctrl_handler_free(&dev->hdl);
1133f2b305cd6711b7b3ce30db93b50bc5d6312950c8Hans Verkuil
1134f2b305cd6711b7b3ce30db93b50bc5d6312950c8Hans Verkuil	/* deregister I2C adapter */
113554d80904b4c1f7aa1d569d07ca3e62fba0daf3a2Mauro Carvalho Chehab#if IS_ENABLED(CONFIG_I2C)
1136f2b305cd6711b7b3ce30db93b50bc5d6312950c8Hans Verkuil	mutex_lock(&dev->i2c_mutex);
1137324b04ba5da7918a2409f8113e46843bfbd89e67Jarod Wilson	i2c_del_adapter(&dev->i2c_adapter);
1138f2b305cd6711b7b3ce30db93b50bc5d6312950c8Hans Verkuil	mutex_unlock(&dev->i2c_mutex);
1139f2b305cd6711b7b3ce30db93b50bc5d6312950c8Hans Verkuil#endif /* CONFIG_I2C */
1140f2b305cd6711b7b3ce30db93b50bc5d6312950c8Hans Verkuil
1141f2b305cd6711b7b3ce30db93b50bc5d6312950c8Hans Verkuil	kfree(dev->usbc_buf);
1142f2b305cd6711b7b3ce30db93b50bc5d6312950c8Hans Verkuil	kfree(dev);
11439aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau}
11449aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
11459aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunaustatic const struct video_device hdpvr_video_template = {
11469aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	.fops			= &hdpvr_fops,
11479aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	.release		= hdpvr_device_release,
11489aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	.ioctl_ops 		= &hdpvr_ioctl_ops,
11495854bf88599545572ce89fba6c4fa0bf6b6e226cHans Verkuil	.tvnorms		= V4L2_STD_ALL,
11509aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau};
11519aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
115299c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuilstatic const struct v4l2_ctrl_ops hdpvr_ctrl_ops = {
115399c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil	.try_ctrl = hdpvr_try_ctrl,
115499c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil	.s_ctrl = hdpvr_s_ctrl,
115599c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil};
115699c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil
1157a50ab29185a9ec31e5a6999e53add0508653e889Janne Grunauint hdpvr_register_videodev(struct hdpvr_device *dev, struct device *parent,
1158a50ab29185a9ec31e5a6999e53add0508653e889Janne Grunau			    int devnum)
11599aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau{
116099c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil	struct v4l2_ctrl_handler *hdl = &dev->hdl;
116199c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil	bool ac3 = dev->flags & HDPVR_FLAG_AC3_CAP;
116299c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil	int res;
116399c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil
11648f69da955873f5e33b60ff117856a2bf1309a336Hans Verkuil	dev->cur_std = V4L2_STD_525_60;
11658f69da955873f5e33b60ff117856a2bf1309a336Hans Verkuil	dev->width = 720;
11668f69da955873f5e33b60ff117856a2bf1309a336Hans Verkuil	dev->height = 480;
11673315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	dev->cur_dv_timings = hdpvr_dv_timings[HDPVR_DEF_DV_TIMINGS_IDX];
116899c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil	v4l2_ctrl_handler_init(hdl, 11);
116999c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil	if (dev->fw_ver > 0x15) {
117099c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil		v4l2_ctrl_new_std(hdl, &hdpvr_ctrl_ops,
117199c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil			V4L2_CID_BRIGHTNESS, 0x0, 0xff, 1, 0x80);
117299c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil		v4l2_ctrl_new_std(hdl, &hdpvr_ctrl_ops,
117399c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil			V4L2_CID_CONTRAST, 0x0, 0xff, 1, 0x40);
117499c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil		v4l2_ctrl_new_std(hdl, &hdpvr_ctrl_ops,
117599c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil			V4L2_CID_SATURATION, 0x0, 0xff, 1, 0x40);
117699c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil		v4l2_ctrl_new_std(hdl, &hdpvr_ctrl_ops,
117799c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil			V4L2_CID_HUE, 0x0, 0x1e, 1, 0xf);
117899c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil		v4l2_ctrl_new_std(hdl, &hdpvr_ctrl_ops,
117999c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil			V4L2_CID_SHARPNESS, 0x0, 0xff, 1, 0x80);
118099c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil	} else {
118199c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil		v4l2_ctrl_new_std(hdl, &hdpvr_ctrl_ops,
118299c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil			V4L2_CID_BRIGHTNESS, 0x0, 0xff, 1, 0x86);
118399c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil		v4l2_ctrl_new_std(hdl, &hdpvr_ctrl_ops,
118499c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil			V4L2_CID_CONTRAST, 0x0, 0xff, 1, 0x80);
118599c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil		v4l2_ctrl_new_std(hdl, &hdpvr_ctrl_ops,
118699c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil			V4L2_CID_SATURATION, 0x0, 0xff, 1, 0x80);
118799c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil		v4l2_ctrl_new_std(hdl, &hdpvr_ctrl_ops,
118899c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil			V4L2_CID_HUE, 0x0, 0xff, 1, 0x80);
118999c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil		v4l2_ctrl_new_std(hdl, &hdpvr_ctrl_ops,
119099c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil			V4L2_CID_SHARPNESS, 0x0, 0xff, 1, 0x80);
119199c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil	}
119299c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil
119399c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil	v4l2_ctrl_new_std_menu(hdl, &hdpvr_ctrl_ops,
119499c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil		V4L2_CID_MPEG_STREAM_TYPE,
119599c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil		V4L2_MPEG_STREAM_TYPE_MPEG2_TS,
119699c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil		0x1, V4L2_MPEG_STREAM_TYPE_MPEG2_TS);
119799c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil	v4l2_ctrl_new_std_menu(hdl, &hdpvr_ctrl_ops,
119899c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil		V4L2_CID_MPEG_AUDIO_ENCODING,
119999c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil		ac3 ? V4L2_MPEG_AUDIO_ENCODING_AC3 : V4L2_MPEG_AUDIO_ENCODING_AAC,
12003445857b22eafb70a6ac258979e955b116bfd2c6Hans Verkuil		0x7, ac3 ? dev->options.audio_codec : V4L2_MPEG_AUDIO_ENCODING_AAC);
120199c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil	v4l2_ctrl_new_std_menu(hdl, &hdpvr_ctrl_ops,
120299c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil		V4L2_CID_MPEG_VIDEO_ENCODING,
120399c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil		V4L2_MPEG_VIDEO_ENCODING_MPEG_4_AVC, 0x3,
120499c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil		V4L2_MPEG_VIDEO_ENCODING_MPEG_4_AVC);
120599c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil
120699c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil	dev->video_mode = v4l2_ctrl_new_std_menu(hdl, &hdpvr_ctrl_ops,
120799c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil		V4L2_CID_MPEG_VIDEO_BITRATE_MODE,
120899c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil		V4L2_MPEG_VIDEO_BITRATE_MODE_CBR, 0,
120999c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil		V4L2_MPEG_VIDEO_BITRATE_MODE_CBR);
121099c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil
121199c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil	dev->video_bitrate = v4l2_ctrl_new_std(hdl, &hdpvr_ctrl_ops,
121299c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil		V4L2_CID_MPEG_VIDEO_BITRATE,
121399c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil		1000000, 13500000, 100000, 6500000);
121499c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil	dev->video_bitrate_peak = v4l2_ctrl_new_std(hdl, &hdpvr_ctrl_ops,
121599c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil		V4L2_CID_MPEG_VIDEO_BITRATE_PEAK,
121699c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil		1100000, 20200000, 100000, 9000000);
121799c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil	dev->v4l2_dev.ctrl_handler = hdl;
121899c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil	if (hdl->error) {
121999c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil		res = hdl->error;
122099c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil		v4l2_err(&dev->v4l2_dev, "Could not register controls\n");
122199c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil		goto error;
122299c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil	}
122399c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil	v4l2_ctrl_cluster(3, &dev->video_mode);
122499c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil	res = v4l2_ctrl_handler_setup(hdl);
122599c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil	if (res < 0) {
122699c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil		v4l2_err(&dev->v4l2_dev, "Could not setup controls\n");
122799c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil		goto error;
122899c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil	}
122999c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil
12309aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	/* setup and register video device */
12319aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	dev->video_dev = video_device_alloc();
12329aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	if (!dev->video_dev) {
12339ef77adfb9ac170bcaf449530cf129c48547fd55Janne Grunau		v4l2_err(&dev->v4l2_dev, "video_device_alloc() failed\n");
123499c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil		res = -ENOMEM;
12359aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		goto error;
12369aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	}
12379aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
1238ede197aac0c64021a0b2139d19edd8fa066530c2Hans Verkuil	*dev->video_dev = hdpvr_video_template;
12399aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	strcpy(dev->video_dev->name, "Hauppauge HD PVR");
1240ede197aac0c64021a0b2139d19edd8fa066530c2Hans Verkuil	dev->video_dev->v4l2_dev = &dev->v4l2_dev;
12419aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	video_set_drvdata(dev->video_dev, dev);
12429aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
124399c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil	res = video_register_device(dev->video_dev, VFL_TYPE_GRABBER, devnum);
124499c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil	if (res < 0) {
12459ef77adfb9ac170bcaf449530cf129c48547fd55Janne Grunau		v4l2_err(&dev->v4l2_dev, "video_device registration failed\n");
12469aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		goto error;
12479aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	}
12489aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
12499aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	return 0;
12509aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunauerror:
125199c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil	v4l2_ctrl_handler_free(hdl);
125299c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil	return res;
12539aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau}
1254