hdpvr-video.c revision 5854bf88599545572ce89fba6c4fa0bf6b6e226c
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>
279aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau#include <media/v4l2-ioctl.h>
2865fe42d6054bb84c4abc4168310bd5d7c462456eHans Verkuil#include <media/v4l2-event.h>
299aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau#include "hdpvr.h"
309aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
3139bcb3ae030b0b64262adf6c5243bf767d8b75dcAlan Young#define BULK_URB_TIMEOUT   90 /* 0.09 seconds */
329aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
339ef77adfb9ac170bcaf449530cf129c48547fd55Janne Grunau#define print_buffer_status() { \
349ef77adfb9ac170bcaf449530cf129c48547fd55Janne Grunau		v4l2_dbg(MSG_BUFFER, hdpvr_debug, &dev->v4l2_dev,	\
359ef77adfb9ac170bcaf449530cf129c48547fd55Janne Grunau			 "%s:%d buffer stat: %d free, %d proc\n",	\
369ef77adfb9ac170bcaf449530cf129c48547fd55Janne Grunau			 __func__, __LINE__,				\
379ef77adfb9ac170bcaf449530cf129c48547fd55Janne Grunau			 list_size(&dev->free_buff_list),		\
389ef77adfb9ac170bcaf449530cf129c48547fd55Janne Grunau			 list_size(&dev->rec_buff_list)); }
39d211bfcbd0f13f1234aaa6e565013dba051a408cJanne Grunau
403315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuilstatic const struct v4l2_dv_timings hdpvr_dv_timings[] = {
413315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	V4L2_DV_BT_CEA_720X480I59_94,
423315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	V4L2_DV_BT_CEA_720X576I50,
433315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	V4L2_DV_BT_CEA_720X480P59_94,
443315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	V4L2_DV_BT_CEA_720X576P50,
453315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	V4L2_DV_BT_CEA_1280X720P50,
463315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	V4L2_DV_BT_CEA_1280X720P60,
473315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	V4L2_DV_BT_CEA_1920X1080I50,
483315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	V4L2_DV_BT_CEA_1920X1080I60,
493315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil};
503315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil
513315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil/* Use 480i59 as the default timings */
523315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil#define HDPVR_DEF_DV_TIMINGS_IDX (0)
533315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil
543315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuilstruct hdpvr_fh {
553315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	struct v4l2_fh fh;
563315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	bool legacy_mode;
573315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil};
583315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil
599aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunaustatic uint list_size(struct list_head *list)
609aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau{
619aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	struct list_head *tmp;
629aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	uint count = 0;
639aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
649aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	list_for_each(tmp, list) {
659aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		count++;
669aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	}
679aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
689aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	return count;
699aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau}
709aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
719aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau/*=========================================================================*/
729aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau/* urb callback */
739aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunaustatic void hdpvr_read_bulk_callback(struct urb *urb)
749aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau{
759aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	struct hdpvr_buffer *buf = (struct hdpvr_buffer *)urb->context;
769aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	struct hdpvr_device *dev = buf->dev;
779aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
789aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	/* marking buffer as received and wake waiting */
799aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	buf->status = BUFSTAT_READY;
809aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	wake_up_interruptible(&dev->wait_data);
819aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau}
829aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
839aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau/*=========================================================================*/
849aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau/* bufffer bits */
859aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
869aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau/* function expects dev->io_mutex to be hold by caller */
879aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunauint hdpvr_cancel_queue(struct hdpvr_device *dev)
889aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau{
899aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	struct hdpvr_buffer *buf;
909aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
919aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	list_for_each_entry(buf, &dev->rec_buff_list, buff_list) {
929aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		usb_kill_urb(buf->urb);
939aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		buf->status = BUFSTAT_AVAILABLE;
949aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	}
959aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
969aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	list_splice_init(&dev->rec_buff_list, dev->free_buff_list.prev);
979aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
989aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	return 0;
999aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau}
1009aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
1019aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunaustatic int hdpvr_free_queue(struct list_head *q)
1029aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau{
1039aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	struct list_head *tmp;
1049aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	struct list_head *p;
1059aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	struct hdpvr_buffer *buf;
1069aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	struct urb *urb;
1079aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
1089aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	for (p = q->next; p != q;) {
1099aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		buf = list_entry(p, struct hdpvr_buffer, buff_list);
1109aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
1119aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		urb = buf->urb;
112997ea58eb92f9970b8af7aae48800d0ef43b9423Daniel Mack		usb_free_coherent(urb->dev, urb->transfer_buffer_length,
113997ea58eb92f9970b8af7aae48800d0ef43b9423Daniel Mack				  urb->transfer_buffer, urb->transfer_dma);
1149aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		usb_free_urb(urb);
1159aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		tmp = p->next;
1169aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		list_del(p);
1179aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		kfree(buf);
1189aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		p = tmp;
1199aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	}
1209aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
1219aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	return 0;
1229aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau}
1239aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
1249aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau/* function expects dev->io_mutex to be hold by caller */
1259aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunauint hdpvr_free_buffers(struct hdpvr_device *dev)
1269aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau{
1279aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	hdpvr_cancel_queue(dev);
1289aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
1299aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	hdpvr_free_queue(&dev->free_buff_list);
1309aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	hdpvr_free_queue(&dev->rec_buff_list);
1319aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
1329aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	return 0;
1339aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau}
1349aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
1359aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau/* function expects dev->io_mutex to be hold by caller */
1369aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunauint hdpvr_alloc_buffers(struct hdpvr_device *dev, uint count)
1379aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau{
1389aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	uint i;
1399aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	int retval = -ENOMEM;
1409aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	u8 *mem;
1419aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	struct hdpvr_buffer *buf;
1429aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	struct urb *urb;
1439aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
1449ef77adfb9ac170bcaf449530cf129c48547fd55Janne Grunau	v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev,
1459aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		 "allocating %u buffers\n", count);
1469aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
1479aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	for (i = 0; i < count; i++) {
1489aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
1499aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		buf = kzalloc(sizeof(struct hdpvr_buffer), GFP_KERNEL);
1509aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		if (!buf) {
1519ef77adfb9ac170bcaf449530cf129c48547fd55Janne Grunau			v4l2_err(&dev->v4l2_dev, "cannot allocate buffer\n");
1529aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			goto exit;
1539aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		}
1549aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		buf->dev = dev;
1559aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
1569aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		urb = usb_alloc_urb(0, GFP_KERNEL);
1579aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		if (!urb) {
1589ef77adfb9ac170bcaf449530cf129c48547fd55Janne Grunau			v4l2_err(&dev->v4l2_dev, "cannot allocate urb\n");
159cd0e280f1bbecebcd20ed0ddd4dd8fb03a506b3cJulia Lawall			goto exit_urb;
1609aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		}
1619aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		buf->urb = urb;
1629aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
163997ea58eb92f9970b8af7aae48800d0ef43b9423Daniel Mack		mem = usb_alloc_coherent(dev->udev, dev->bulk_in_size, GFP_KERNEL,
164997ea58eb92f9970b8af7aae48800d0ef43b9423Daniel Mack					 &urb->transfer_dma);
1659aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		if (!mem) {
1669ef77adfb9ac170bcaf449530cf129c48547fd55Janne Grunau			v4l2_err(&dev->v4l2_dev,
1679ef77adfb9ac170bcaf449530cf129c48547fd55Janne Grunau				 "cannot allocate usb transfer buffer\n");
168cd0e280f1bbecebcd20ed0ddd4dd8fb03a506b3cJulia Lawall			goto exit_urb_buffer;
1699aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		}
1709aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
1719aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		usb_fill_bulk_urb(buf->urb, dev->udev,
1729aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau				  usb_rcvbulkpipe(dev->udev,
1739aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau						  dev->bulk_in_endpointAddr),
1749aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau				  mem, dev->bulk_in_size,
1759aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau				  hdpvr_read_bulk_callback, buf);
1769aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
1774f5c933abb34532dc962185c999509b97a97fa1bJames M McLaren		buf->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
1789aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		buf->status = BUFSTAT_AVAILABLE;
1799aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		list_add_tail(&buf->buff_list, &dev->free_buff_list);
1809aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	}
1819aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	return 0;
182cd0e280f1bbecebcd20ed0ddd4dd8fb03a506b3cJulia Lawallexit_urb_buffer:
183cd0e280f1bbecebcd20ed0ddd4dd8fb03a506b3cJulia Lawall	usb_free_urb(urb);
184cd0e280f1bbecebcd20ed0ddd4dd8fb03a506b3cJulia Lawallexit_urb:
185cd0e280f1bbecebcd20ed0ddd4dd8fb03a506b3cJulia Lawall	kfree(buf);
1869aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunauexit:
1879aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	hdpvr_free_buffers(dev);
1889aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	return retval;
1899aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau}
1909aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
1919aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunaustatic int hdpvr_submit_buffers(struct hdpvr_device *dev)
1929aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau{
1939aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	struct hdpvr_buffer *buf;
1949aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	struct urb *urb;
1959aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	int ret = 0, err_count = 0;
1969aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
1979aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	mutex_lock(&dev->io_mutex);
1989aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
1999aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	while (dev->status == STATUS_STREAMING &&
2009aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	       !list_empty(&dev->free_buff_list)) {
2019aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
2029aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		buf = list_entry(dev->free_buff_list.next, struct hdpvr_buffer,
2039aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau				 buff_list);
2049aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		if (buf->status != BUFSTAT_AVAILABLE) {
2059ef77adfb9ac170bcaf449530cf129c48547fd55Janne Grunau			v4l2_err(&dev->v4l2_dev,
2064b512d26f425be1c779c8319249b42ce3c3424d2Thadeu Lima de Souza Cascardo				 "buffer not marked as available\n");
2079aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			ret = -EFAULT;
2089aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			goto err;
2099aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		}
2109aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
2119aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		urb = buf->urb;
2129aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		urb->status = 0;
2139aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		urb->actual_length = 0;
2149aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		ret = usb_submit_urb(urb, GFP_KERNEL);
2159aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		if (ret) {
2169ef77adfb9ac170bcaf449530cf129c48547fd55Janne Grunau			v4l2_err(&dev->v4l2_dev,
2179ef77adfb9ac170bcaf449530cf129c48547fd55Janne Grunau				 "usb_submit_urb in %s returned %d\n",
2189ef77adfb9ac170bcaf449530cf129c48547fd55Janne Grunau				 __func__, ret);
2199aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			if (++err_count > 2)
2209aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau				break;
2219aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			continue;
2229aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		}
2239aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		buf->status = BUFSTAT_INPROGRESS;
2249aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		list_move_tail(&buf->buff_list, &dev->rec_buff_list);
2259aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	}
2269aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunauerr:
227d211bfcbd0f13f1234aaa6e565013dba051a408cJanne Grunau	print_buffer_status();
2289aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	mutex_unlock(&dev->io_mutex);
2299aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	return ret;
2309aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau}
2319aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
2329aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunaustatic struct hdpvr_buffer *hdpvr_get_next_buffer(struct hdpvr_device *dev)
2339aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau{
2349aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	struct hdpvr_buffer *buf;
2359aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
2369aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	mutex_lock(&dev->io_mutex);
2379aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
2389aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	if (list_empty(&dev->rec_buff_list)) {
2399aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		mutex_unlock(&dev->io_mutex);
2409aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		return NULL;
2419aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	}
2429aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
2439aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	buf = list_entry(dev->rec_buff_list.next, struct hdpvr_buffer,
2449aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			 buff_list);
2459aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	mutex_unlock(&dev->io_mutex);
2469aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
2479aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	return buf;
2489aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau}
2499aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
2509aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunaustatic void hdpvr_transmit_buffers(struct work_struct *work)
2519aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau{
2529aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	struct hdpvr_device *dev = container_of(work, struct hdpvr_device,
2539aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau						worker);
2549aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
2559aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	while (dev->status == STATUS_STREAMING) {
2569aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
2579aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		if (hdpvr_submit_buffers(dev)) {
2589ef77adfb9ac170bcaf449530cf129c48547fd55Janne Grunau			v4l2_err(&dev->v4l2_dev, "couldn't submit buffers\n");
2599aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			goto error;
2609aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		}
2619aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		if (wait_event_interruptible(dev->wait_buffer,
2629aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau				!list_empty(&dev->free_buff_list) ||
2639aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau					     dev->status != STATUS_STREAMING))
2649aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			goto error;
2659aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	}
2669aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
2679ef77adfb9ac170bcaf449530cf129c48547fd55Janne Grunau	v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev,
2689aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		 "transmit worker exited\n");
2699aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	return;
2709aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunauerror:
2719ef77adfb9ac170bcaf449530cf129c48547fd55Janne Grunau	v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev,
2729aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		 "transmit buffers errored\n");
2739aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	dev->status = STATUS_ERROR;
2749aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau}
2759aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
2769aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau/* function expects dev->io_mutex to be hold by caller */
2779aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunaustatic int hdpvr_start_streaming(struct hdpvr_device *dev)
2789aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau{
2799aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	int ret;
2809aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	struct hdpvr_video_info *vidinf;
2819aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
2829aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	if (dev->status == STATUS_STREAMING)
2839aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		return 0;
2849aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	else if (dev->status != STATUS_IDLE)
2859aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		return -EAGAIN;
2869aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
2879aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	vidinf = get_video_info(dev);
2889aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
2899aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	if (vidinf) {
2909ef77adfb9ac170bcaf449530cf129c48547fd55Janne Grunau		v4l2_dbg(MSG_BUFFER, hdpvr_debug, &dev->v4l2_dev,
2919aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			 "video signal: %dx%d@%dhz\n", vidinf->width,
2929aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			 vidinf->height, vidinf->fps);
2939aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		kfree(vidinf);
2949aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
2959aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		/* start streaming 2 request */
2969aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		ret = usb_control_msg(dev->udev,
2979aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau				      usb_sndctrlpipe(dev->udev, 0),
2989aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau				      0xb8, 0x38, 0x1, 0, NULL, 0, 8000);
2999ef77adfb9ac170bcaf449530cf129c48547fd55Janne Grunau		v4l2_dbg(MSG_BUFFER, hdpvr_debug, &dev->v4l2_dev,
3009aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			 "encoder start control request returned %d\n", ret);
3019aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
3029aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		hdpvr_config_call(dev, CTRL_START_STREAMING_VALUE, 0x00);
3039aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
304afa159538af61f1a65d48927f4e949fe514fb4fcJanne Grunau		dev->status = STATUS_STREAMING;
305afa159538af61f1a65d48927f4e949fe514fb4fcJanne Grunau
3069aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		INIT_WORK(&dev->worker, hdpvr_transmit_buffers);
3079aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		queue_work(dev->workqueue, &dev->worker);
3089aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
3099ef77adfb9ac170bcaf449530cf129c48547fd55Janne Grunau		v4l2_dbg(MSG_BUFFER, hdpvr_debug, &dev->v4l2_dev,
3109aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			 "streaming started\n");
3119aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
3129aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		return 0;
3139aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	}
3149aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	msleep(250);
3159ef77adfb9ac170bcaf449530cf129c48547fd55Janne Grunau	v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev,
3169aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		 "no video signal at input %d\n", dev->options.video_input);
3179aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	return -EAGAIN;
3189aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau}
3199aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
3209aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
3219aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau/* function expects dev->io_mutex to be hold by caller */
3229aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunaustatic int hdpvr_stop_streaming(struct hdpvr_device *dev)
3239aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau{
32485d682b9ee1a89a82c2a75182558e392749d81fcMárton Németh	int actual_length;
32585d682b9ee1a89a82c2a75182558e392749d81fcMárton Németh	uint c = 0;
3267d771ff0dc3371923db929d9f88932acec3fc8e8Janne Grunau	u8 *buf;
3277d771ff0dc3371923db929d9f88932acec3fc8e8Janne Grunau
3289aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	if (dev->status == STATUS_IDLE)
3299aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		return 0;
3309aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	else if (dev->status != STATUS_STREAMING)
3319aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		return -EAGAIN;
3329aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
3337d771ff0dc3371923db929d9f88932acec3fc8e8Janne Grunau	buf = kmalloc(dev->bulk_in_size, GFP_KERNEL);
3347d771ff0dc3371923db929d9f88932acec3fc8e8Janne Grunau	if (!buf)
3357d771ff0dc3371923db929d9f88932acec3fc8e8Janne Grunau		v4l2_err(&dev->v4l2_dev, "failed to allocate temporary buffer "
3367d771ff0dc3371923db929d9f88932acec3fc8e8Janne Grunau			 "for emptying the internal device buffer. "
3377d771ff0dc3371923db929d9f88932acec3fc8e8Janne Grunau			 "Next capture start will be slow\n");
3387d771ff0dc3371923db929d9f88932acec3fc8e8Janne Grunau
3399aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	dev->status = STATUS_SHUTTING_DOWN;
3409aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	hdpvr_config_call(dev, CTRL_STOP_STREAMING_VALUE, 0x00);
34148f98f7557d35d360470bf6d9fd7b00d04fba828Janne Grunau	mutex_unlock(&dev->io_mutex);
3429aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
3439aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	wake_up_interruptible(&dev->wait_buffer);
3449aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	msleep(50);
3459aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
3469aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	flush_workqueue(dev->workqueue);
3479aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
34848f98f7557d35d360470bf6d9fd7b00d04fba828Janne Grunau	mutex_lock(&dev->io_mutex);
3499aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	/* kill the still outstanding urbs */
3509aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	hdpvr_cancel_queue(dev);
3519aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
3527d771ff0dc3371923db929d9f88932acec3fc8e8Janne Grunau	/* emptying the device buffer beforeshutting it down */
3537d771ff0dc3371923db929d9f88932acec3fc8e8Janne Grunau	while (buf && ++c < 500 &&
3547d771ff0dc3371923db929d9f88932acec3fc8e8Janne Grunau	       !usb_bulk_msg(dev->udev,
3557d771ff0dc3371923db929d9f88932acec3fc8e8Janne Grunau			     usb_rcvbulkpipe(dev->udev,
3567d771ff0dc3371923db929d9f88932acec3fc8e8Janne Grunau					     dev->bulk_in_endpointAddr),
3577d771ff0dc3371923db929d9f88932acec3fc8e8Janne Grunau			     buf, dev->bulk_in_size, &actual_length,
3587d771ff0dc3371923db929d9f88932acec3fc8e8Janne Grunau			     BULK_URB_TIMEOUT)) {
3597d771ff0dc3371923db929d9f88932acec3fc8e8Janne Grunau		v4l2_dbg(MSG_BUFFER, hdpvr_debug, &dev->v4l2_dev,
3607d771ff0dc3371923db929d9f88932acec3fc8e8Janne Grunau			 "%2d: got %d bytes\n", c, actual_length);
3617d771ff0dc3371923db929d9f88932acec3fc8e8Janne Grunau	}
3627d771ff0dc3371923db929d9f88932acec3fc8e8Janne Grunau	kfree(buf);
3637d771ff0dc3371923db929d9f88932acec3fc8e8Janne Grunau	v4l2_dbg(MSG_BUFFER, hdpvr_debug, &dev->v4l2_dev,
3647d771ff0dc3371923db929d9f88932acec3fc8e8Janne Grunau		 "used %d urbs to empty device buffers\n", c-1);
3657d771ff0dc3371923db929d9f88932acec3fc8e8Janne Grunau	msleep(10);
3667d771ff0dc3371923db929d9f88932acec3fc8e8Janne Grunau
3679aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	dev->status = STATUS_IDLE;
3689aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
3699aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	return 0;
3709aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau}
3719aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
3729aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
3739aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau/*=======================================================================*/
3749aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau/*
3759aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau * video 4 linux 2 file operations
3769aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau */
3779aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
3783315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuilstatic int hdpvr_open(struct file *file)
3793315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil{
3803315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	struct hdpvr_fh *fh = kzalloc(sizeof(*fh), GFP_KERNEL);
3813315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil
3823315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	if (fh == NULL)
3833315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil		return -ENOMEM;
3843315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	fh->legacy_mode = true;
3853315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	v4l2_fh_init(&fh->fh, video_devdata(file));
3863315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	v4l2_fh_add(&fh->fh);
3873315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	file->private_data = fh;
3883315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	return 0;
3893315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil}
3903315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil
3919aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunaustatic int hdpvr_release(struct file *file)
3929aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau{
393ede197aac0c64021a0b2139d19edd8fa066530c2Hans Verkuil	struct hdpvr_device *dev = video_drvdata(file);
3949aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
3959aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	mutex_lock(&dev->io_mutex);
396ede197aac0c64021a0b2139d19edd8fa066530c2Hans Verkuil	if (file->private_data == dev->owner) {
3979aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		hdpvr_stop_streaming(dev);
398ede197aac0c64021a0b2139d19edd8fa066530c2Hans Verkuil		dev->owner = NULL;
399ede197aac0c64021a0b2139d19edd8fa066530c2Hans Verkuil	}
4009aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	mutex_unlock(&dev->io_mutex);
4019aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
402ede197aac0c64021a0b2139d19edd8fa066530c2Hans Verkuil	return v4l2_fh_release(file);
4039aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau}
4049aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
4059aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau/*
4069aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau * hdpvr_v4l2_read()
4079aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau * will allocate buffers when called for the first time
4089aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau */
4099aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunaustatic ssize_t hdpvr_read(struct file *file, char __user *buffer, size_t count,
4109aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			  loff_t *pos)
4119aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau{
412ede197aac0c64021a0b2139d19edd8fa066530c2Hans Verkuil	struct hdpvr_device *dev = video_drvdata(file);
4139aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	struct hdpvr_buffer *buf = NULL;
4149aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	struct urb *urb;
4159aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	unsigned int ret = 0;
4169aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	int rem, cnt;
4179aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
4189aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	if (*pos)
4199aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		return -ESPIPE;
4209aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
4219aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	mutex_lock(&dev->io_mutex);
4229aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	if (dev->status == STATUS_IDLE) {
4239aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		if (hdpvr_start_streaming(dev)) {
4249ef77adfb9ac170bcaf449530cf129c48547fd55Janne Grunau			v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev,
4259ef77adfb9ac170bcaf449530cf129c48547fd55Janne Grunau				 "start_streaming failed\n");
4269aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			ret = -EIO;
4279aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			msleep(200);
4289aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			dev->status = STATUS_IDLE;
4299aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			mutex_unlock(&dev->io_mutex);
4309aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			goto err;
4319aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		}
432ede197aac0c64021a0b2139d19edd8fa066530c2Hans Verkuil		dev->owner = file->private_data;
433d211bfcbd0f13f1234aaa6e565013dba051a408cJanne Grunau		print_buffer_status();
4349aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	}
4359aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	mutex_unlock(&dev->io_mutex);
4369aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
4379aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	/* wait for the first buffer */
4389aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	if (!(file->f_flags & O_NONBLOCK)) {
4399aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		if (wait_event_interruptible(dev->wait_data,
4409aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau					     hdpvr_get_next_buffer(dev)))
4419aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			return -ERESTARTSYS;
4429aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	}
4439aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
4449aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	buf = hdpvr_get_next_buffer(dev);
4459aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
4469aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	while (count > 0 && buf) {
4479aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
4489aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		if (buf->status != BUFSTAT_READY &&
4499aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		    dev->status != STATUS_DISCONNECTED) {
4509aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			/* return nonblocking */
4519aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			if (file->f_flags & O_NONBLOCK) {
4529aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau				if (!ret)
4539aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau					ret = -EAGAIN;
4549aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau				goto err;
4559aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			}
4569aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
4579aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			if (wait_event_interruptible(dev->wait_data,
4589aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau					      buf->status == BUFSTAT_READY)) {
4599aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau				ret = -ERESTARTSYS;
4609aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau				goto err;
4619aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			}
4629aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		}
4639aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
4649aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		if (buf->status != BUFSTAT_READY)
4659aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			break;
4669aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
4679aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		/* set remaining bytes to copy */
4689aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		urb = buf->urb;
4699aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		rem = urb->actual_length - buf->pos;
4709aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		cnt = rem > count ? count : rem;
4719aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
4729aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		if (copy_to_user(buffer, urb->transfer_buffer + buf->pos,
4739aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau				 cnt)) {
4749ef77adfb9ac170bcaf449530cf129c48547fd55Janne Grunau			v4l2_err(&dev->v4l2_dev, "read: copy_to_user failed\n");
4759aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			if (!ret)
4769aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau				ret = -EFAULT;
4779aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			goto err;
4789aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		}
4799aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
4809aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		buf->pos += cnt;
4819aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		count -= cnt;
4829aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		buffer += cnt;
4839aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		ret += cnt;
4849aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
4859aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		/* finished, take next buffer */
4869aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		if (buf->pos == urb->actual_length) {
4879aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			mutex_lock(&dev->io_mutex);
4889aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			buf->pos = 0;
4899aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			buf->status = BUFSTAT_AVAILABLE;
4909aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
4919aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			list_move_tail(&buf->buff_list, &dev->free_buff_list);
4929aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
493d211bfcbd0f13f1234aaa6e565013dba051a408cJanne Grunau			print_buffer_status();
4949aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
4959aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			mutex_unlock(&dev->io_mutex);
4969aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
4979aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			wake_up_interruptible(&dev->wait_buffer);
4989aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
4999aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			buf = hdpvr_get_next_buffer(dev);
5009aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		}
5019aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	}
5029aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunauerr:
5039aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	if (!ret && !buf)
5049aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		ret = -EAGAIN;
5059aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	return ret;
5069aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau}
5079aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
5089aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunaustatic unsigned int hdpvr_poll(struct file *filp, poll_table *wait)
5099aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau{
51065fe42d6054bb84c4abc4168310bd5d7c462456eHans Verkuil	unsigned long req_events = poll_requested_events(wait);
511d2ff3ec81628cbf9470c496b3d0c0780165643f5Janne Grunau	struct hdpvr_buffer *buf = NULL;
512ede197aac0c64021a0b2139d19edd8fa066530c2Hans Verkuil	struct hdpvr_device *dev = video_drvdata(filp);
51365fe42d6054bb84c4abc4168310bd5d7c462456eHans Verkuil	unsigned int mask = v4l2_ctrl_poll(filp, wait);
5149aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
51565fe42d6054bb84c4abc4168310bd5d7c462456eHans Verkuil	if (!(req_events & (POLLIN | POLLRDNORM)))
51665fe42d6054bb84c4abc4168310bd5d7c462456eHans Verkuil		return mask;
5179aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
51865fe42d6054bb84c4abc4168310bd5d7c462456eHans Verkuil	mutex_lock(&dev->io_mutex);
5199aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
5209aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	if (dev->status == STATUS_IDLE) {
5219aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		if (hdpvr_start_streaming(dev)) {
5229ef77adfb9ac170bcaf449530cf129c48547fd55Janne Grunau			v4l2_dbg(MSG_BUFFER, hdpvr_debug, &dev->v4l2_dev,
5239ef77adfb9ac170bcaf449530cf129c48547fd55Janne Grunau				 "start_streaming failed\n");
5249aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			dev->status = STATUS_IDLE;
525ede197aac0c64021a0b2139d19edd8fa066530c2Hans Verkuil		} else {
526ede197aac0c64021a0b2139d19edd8fa066530c2Hans Verkuil			dev->owner = filp->private_data;
5279aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		}
5289aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
529d211bfcbd0f13f1234aaa6e565013dba051a408cJanne Grunau		print_buffer_status();
5309aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	}
5319aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	mutex_unlock(&dev->io_mutex);
5329aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
533d2ff3ec81628cbf9470c496b3d0c0780165643f5Janne Grunau	buf = hdpvr_get_next_buffer(dev);
534d2ff3ec81628cbf9470c496b3d0c0780165643f5Janne Grunau	/* only wait if no data is available */
535d2ff3ec81628cbf9470c496b3d0c0780165643f5Janne Grunau	if (!buf || buf->status != BUFSTAT_READY) {
536d2ff3ec81628cbf9470c496b3d0c0780165643f5Janne Grunau		poll_wait(filp, &dev->wait_data, wait);
537d2ff3ec81628cbf9470c496b3d0c0780165643f5Janne Grunau		buf = hdpvr_get_next_buffer(dev);
5389aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	}
539d2ff3ec81628cbf9470c496b3d0c0780165643f5Janne Grunau	if (buf && buf->status == BUFSTAT_READY)
540d2ff3ec81628cbf9470c496b3d0c0780165643f5Janne Grunau		mask |= POLLIN | POLLRDNORM;
5419aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
5429aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	return mask;
5439aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau}
5449aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
5459aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
5469aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunaustatic const struct v4l2_file_operations hdpvr_fops = {
5479aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	.owner		= THIS_MODULE,
5483315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	.open		= hdpvr_open,
5499aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	.release	= hdpvr_release,
5509aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	.read		= hdpvr_read,
5519aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	.poll		= hdpvr_poll,
55276717b887cccc77d04357fc0d6ac98f894e3eb3cJanne Grunau	.unlocked_ioctl	= video_ioctl2,
5539aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau};
5549aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
5559aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau/*=======================================================================*/
5569aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau/*
5579aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau * V4L2 ioctl handling
5589aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau */
5599aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
5609aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunaustatic int vidioc_querycap(struct file *file, void  *priv,
5619aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			   struct v4l2_capability *cap)
5629aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau{
5639aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	struct hdpvr_device *dev = video_drvdata(file);
5649aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
5659aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	strcpy(cap->driver, "hdpvr");
566fdd70c3399fc448a87487b287f4f0dcfb2e9c52cLars Hanisch	strcpy(cap->card, "Hauppauge HD PVR");
5679aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	usb_make_path(dev->udev, cap->bus_info, sizeof(cap->bus_info));
56841022fcb3db75c9777bbd05da114c7eb597694dfHans Verkuil	cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_AUDIO |
56941022fcb3db75c9777bbd05da114c7eb597694dfHans Verkuil			    V4L2_CAP_READWRITE;
57041022fcb3db75c9777bbd05da114c7eb597694dfHans Verkuil	cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
5719aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	return 0;
5729aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau}
5739aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
5745854bf88599545572ce89fba6c4fa0bf6b6e226cHans Verkuilstatic int vidioc_s_std(struct file *file, void *_fh,
575314527acbbb3f33f72c2ef19d8cfabcada9912a5Hans Verkuil			v4l2_std_id std)
5769aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau{
577ede197aac0c64021a0b2139d19edd8fa066530c2Hans Verkuil	struct hdpvr_device *dev = video_drvdata(file);
5785854bf88599545572ce89fba6c4fa0bf6b6e226cHans Verkuil	struct hdpvr_fh *fh = _fh;
5799aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	u8 std_type = 1;
5809aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
5815854bf88599545572ce89fba6c4fa0bf6b6e226cHans Verkuil	if (!fh->legacy_mode && dev->options.video_input == HDPVR_COMPONENT)
5828f69da955873f5e33b60ff117856a2bf1309a336Hans Verkuil		return -ENODATA;
5838f69da955873f5e33b60ff117856a2bf1309a336Hans Verkuil	if (dev->status != STATUS_IDLE)
5848f69da955873f5e33b60ff117856a2bf1309a336Hans Verkuil		return -EBUSY;
5858f69da955873f5e33b60ff117856a2bf1309a336Hans Verkuil	if (std & V4L2_STD_525_60)
5869aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		std_type = 0;
5878f69da955873f5e33b60ff117856a2bf1309a336Hans Verkuil	dev->cur_std = std;
5888f69da955873f5e33b60ff117856a2bf1309a336Hans Verkuil	dev->width = 720;
5898f69da955873f5e33b60ff117856a2bf1309a336Hans Verkuil	dev->height = std_type ? 576 : 480;
5909aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
5919aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	return hdpvr_config_call(dev, CTRL_VIDEO_STD_TYPE, std_type);
5929aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau}
5939aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
5945854bf88599545572ce89fba6c4fa0bf6b6e226cHans Verkuilstatic int vidioc_g_std(struct file *file, void *_fh,
5958f69da955873f5e33b60ff117856a2bf1309a336Hans Verkuil			v4l2_std_id *std)
5968f69da955873f5e33b60ff117856a2bf1309a336Hans Verkuil{
5978f69da955873f5e33b60ff117856a2bf1309a336Hans Verkuil	struct hdpvr_device *dev = video_drvdata(file);
5985854bf88599545572ce89fba6c4fa0bf6b6e226cHans Verkuil	struct hdpvr_fh *fh = _fh;
5998f69da955873f5e33b60ff117856a2bf1309a336Hans Verkuil
6005854bf88599545572ce89fba6c4fa0bf6b6e226cHans Verkuil	if (!fh->legacy_mode && dev->options.video_input == HDPVR_COMPONENT)
6018f69da955873f5e33b60ff117856a2bf1309a336Hans Verkuil		return -ENODATA;
6028f69da955873f5e33b60ff117856a2bf1309a336Hans Verkuil	*std = dev->cur_std;
6038f69da955873f5e33b60ff117856a2bf1309a336Hans Verkuil	return 0;
6048f69da955873f5e33b60ff117856a2bf1309a336Hans Verkuil}
6058f69da955873f5e33b60ff117856a2bf1309a336Hans Verkuil
6065854bf88599545572ce89fba6c4fa0bf6b6e226cHans Verkuilstatic int vidioc_querystd(struct file *file, void *_fh, v4l2_std_id *a)
6078f69da955873f5e33b60ff117856a2bf1309a336Hans Verkuil{
6088f69da955873f5e33b60ff117856a2bf1309a336Hans Verkuil	struct hdpvr_device *dev = video_drvdata(file);
6098f69da955873f5e33b60ff117856a2bf1309a336Hans Verkuil	struct hdpvr_video_info *vid_info;
6105854bf88599545572ce89fba6c4fa0bf6b6e226cHans Verkuil	struct hdpvr_fh *fh = _fh;
6118f69da955873f5e33b60ff117856a2bf1309a336Hans Verkuil
6128f69da955873f5e33b60ff117856a2bf1309a336Hans Verkuil	*a = V4L2_STD_ALL;
6135854bf88599545572ce89fba6c4fa0bf6b6e226cHans Verkuil	if (dev->options.video_input == HDPVR_COMPONENT)
6145854bf88599545572ce89fba6c4fa0bf6b6e226cHans Verkuil		return fh->legacy_mode ? 0 : -ENODATA;
6158f69da955873f5e33b60ff117856a2bf1309a336Hans Verkuil	vid_info = get_video_info(dev);
6168f69da955873f5e33b60ff117856a2bf1309a336Hans Verkuil	if (vid_info == NULL)
6178f69da955873f5e33b60ff117856a2bf1309a336Hans Verkuil		return 0;
6188f69da955873f5e33b60ff117856a2bf1309a336Hans Verkuil	if (vid_info->width == 720 &&
6198f69da955873f5e33b60ff117856a2bf1309a336Hans Verkuil	    (vid_info->height == 480 || vid_info->height == 576)) {
6208f69da955873f5e33b60ff117856a2bf1309a336Hans Verkuil		*a = (vid_info->height == 480) ?
6218f69da955873f5e33b60ff117856a2bf1309a336Hans Verkuil			V4L2_STD_525_60 : V4L2_STD_625_50;
6228f69da955873f5e33b60ff117856a2bf1309a336Hans Verkuil	}
6238f69da955873f5e33b60ff117856a2bf1309a336Hans Verkuil	kfree(vid_info);
6248f69da955873f5e33b60ff117856a2bf1309a336Hans Verkuil	return 0;
6258f69da955873f5e33b60ff117856a2bf1309a336Hans Verkuil}
6268f69da955873f5e33b60ff117856a2bf1309a336Hans Verkuil
6273315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuilstatic int vidioc_s_dv_timings(struct file *file, void *_fh,
6283315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil				    struct v4l2_dv_timings *timings)
6293315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil{
6303315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	struct hdpvr_device *dev = video_drvdata(file);
6313315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	struct hdpvr_fh *fh = _fh;
6323315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	int i;
6333315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil
6343315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	fh->legacy_mode = false;
6353315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	if (dev->options.video_input)
6363315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil		return -ENODATA;
6373315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	if (dev->status != STATUS_IDLE)
6383315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil		return -EBUSY;
6393315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	for (i = 0; i < ARRAY_SIZE(hdpvr_dv_timings); i++)
6403315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil		if (v4l_match_dv_timings(timings, hdpvr_dv_timings + i, 0))
6413315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil			break;
6423315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	if (i == ARRAY_SIZE(hdpvr_dv_timings))
6433315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil		return -EINVAL;
6443315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	dev->cur_dv_timings = hdpvr_dv_timings[i];
6453315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	dev->width = hdpvr_dv_timings[i].bt.width;
6463315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	dev->height = hdpvr_dv_timings[i].bt.height;
6473315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	return 0;
6483315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil}
6493315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil
6503315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuilstatic int vidioc_g_dv_timings(struct file *file, void *_fh,
6513315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil				    struct v4l2_dv_timings *timings)
6523315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil{
6533315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	struct hdpvr_device *dev = video_drvdata(file);
6543315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	struct hdpvr_fh *fh = _fh;
6553315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil
6563315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	fh->legacy_mode = false;
6573315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	if (dev->options.video_input)
6583315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil		return -ENODATA;
6593315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	*timings = dev->cur_dv_timings;
6603315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	return 0;
6613315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil}
6623315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil
6633315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuilstatic int vidioc_query_dv_timings(struct file *file, void *_fh,
6643315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil				    struct v4l2_dv_timings *timings)
6653315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil{
6663315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	struct hdpvr_device *dev = video_drvdata(file);
6673315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	struct hdpvr_fh *fh = _fh;
6683315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	struct hdpvr_video_info *vid_info;
6693315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	bool interlaced;
6703315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	int ret = 0;
6713315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	int i;
6723315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil
6733315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	fh->legacy_mode = false;
6743315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	if (dev->options.video_input)
6753315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil		return -ENODATA;
6763315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	vid_info = get_video_info(dev);
6773315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	if (vid_info == NULL)
6783315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil		return -ENOLCK;
6793315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	interlaced = vid_info->fps <= 30;
6803315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	for (i = 0; i < ARRAY_SIZE(hdpvr_dv_timings); i++) {
6813315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil		const struct v4l2_bt_timings *bt = &hdpvr_dv_timings[i].bt;
6823315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil		unsigned hsize;
6833315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil		unsigned vsize;
6843315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil		unsigned fps;
6853315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil
6863315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil		hsize = bt->hfrontporch + bt->hsync + bt->hbackporch + bt->width;
6873315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil		vsize = bt->vfrontporch + bt->vsync + bt->vbackporch +
6883315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil			bt->il_vfrontporch + bt->il_vsync + bt->il_vbackporch +
6893315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil			bt->height;
6903315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil		fps = (unsigned)bt->pixelclock / (hsize * vsize);
6913315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil		if (bt->width != vid_info->width ||
6923315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil		    bt->height != vid_info->height ||
6933315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil		    bt->interlaced != interlaced ||
6943315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil		    (fps != vid_info->fps && fps + 1 != vid_info->fps))
6953315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil			continue;
6963315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil		*timings = hdpvr_dv_timings[i];
6973315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil		break;
6983315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	}
6993315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	if (i == ARRAY_SIZE(hdpvr_dv_timings))
7003315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil		ret = -ERANGE;
7013315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	kfree(vid_info);
7023315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	return ret;
7033315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil}
7043315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil
7053315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuilstatic int vidioc_enum_dv_timings(struct file *file, void *_fh,
7063315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil				    struct v4l2_enum_dv_timings *timings)
7073315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil{
7083315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	struct hdpvr_device *dev = video_drvdata(file);
7093315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	struct hdpvr_fh *fh = _fh;
7103315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil
7113315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	fh->legacy_mode = false;
7123315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	memset(timings->reserved, 0, sizeof(timings->reserved));
7133315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	if (dev->options.video_input)
7143315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil		return -ENODATA;
7153315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	if (timings->index >= ARRAY_SIZE(hdpvr_dv_timings))
7163315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil		return -EINVAL;
7173315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	timings->timings = hdpvr_dv_timings[timings->index];
7183315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	return 0;
7193315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil}
7203315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil
7213315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuilstatic int vidioc_dv_timings_cap(struct file *file, void *_fh,
7223315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil				    struct v4l2_dv_timings_cap *cap)
7233315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil{
7243315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	struct hdpvr_device *dev = video_drvdata(file);
7253315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	struct hdpvr_fh *fh = _fh;
7263315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil
7273315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	fh->legacy_mode = false;
7283315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	if (dev->options.video_input)
7293315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil		return -ENODATA;
7303315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	cap->type = V4L2_DV_BT_656_1120;
7313315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	cap->bt.min_width = 720;
7323315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	cap->bt.max_width = 1920;
7333315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	cap->bt.min_height = 480;
7343315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	cap->bt.max_height = 1080;
7353315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	cap->bt.min_pixelclock = 27000000;
7363315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	cap->bt.max_pixelclock = 74250000;
7373315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	cap->bt.standards = V4L2_DV_BT_STD_CEA861;
7383315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	cap->bt.capabilities = V4L2_DV_BT_CAP_INTERLACED | V4L2_DV_BT_CAP_PROGRESSIVE;
7393315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	return 0;
7403315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil}
7413315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil
7429aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunaustatic const char *iname[] = {
7439aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	[HDPVR_COMPONENT] = "Component",
7449aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	[HDPVR_SVIDEO]    = "S-Video",
7459aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	[HDPVR_COMPOSITE] = "Composite",
7469aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau};
7479aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
7485854bf88599545572ce89fba6c4fa0bf6b6e226cHans Verkuilstatic int vidioc_enum_input(struct file *file, void *_fh, struct v4l2_input *i)
7499aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau{
7509aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	unsigned int n;
7519aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
7529aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	n = i->index;
7539aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	if (n >= HDPVR_VIDEO_INPUTS)
7549aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		return -EINVAL;
7559aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
7569aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	i->type = V4L2_INPUT_TYPE_CAMERA;
7579aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
7589aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	strncpy(i->name, iname[n], sizeof(i->name) - 1);
7599aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	i->name[sizeof(i->name) - 1] = '\0';
7609aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
7619aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	i->audioset = 1<<HDPVR_RCA_FRONT | 1<<HDPVR_RCA_BACK | 1<<HDPVR_SPDIF;
7629aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
7638f69da955873f5e33b60ff117856a2bf1309a336Hans Verkuil	i->capabilities = n ? V4L2_IN_CAP_STD : V4L2_IN_CAP_DV_TIMINGS;
7648f69da955873f5e33b60ff117856a2bf1309a336Hans Verkuil	i->std = n ? V4L2_STD_ALL : 0;
7659aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
7669aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	return 0;
7679aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau}
7689aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
7695854bf88599545572ce89fba6c4fa0bf6b6e226cHans Verkuilstatic int vidioc_s_input(struct file *file, void *_fh,
7709aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			  unsigned int index)
7719aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau{
772ede197aac0c64021a0b2139d19edd8fa066530c2Hans Verkuil	struct hdpvr_device *dev = video_drvdata(file);
7739aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	int retval;
7749aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
7759aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	if (index >= HDPVR_VIDEO_INPUTS)
7769aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		return -EINVAL;
7779aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
7789aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	if (dev->status != STATUS_IDLE)
77997caa318b3ced2241cf1eda772a72c9c2ea19abbHans Verkuil		return -EBUSY;
7809aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
7819aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	retval = hdpvr_config_call(dev, CTRL_VIDEO_INPUT_VALUE, index+1);
7828f69da955873f5e33b60ff117856a2bf1309a336Hans Verkuil	if (!retval) {
7839aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		dev->options.video_input = index;
7845854bf88599545572ce89fba6c4fa0bf6b6e226cHans Verkuil		/*
7855854bf88599545572ce89fba6c4fa0bf6b6e226cHans Verkuil		 * Unfortunately gstreamer calls ENUMSTD and bails out if it
7865854bf88599545572ce89fba6c4fa0bf6b6e226cHans Verkuil		 * won't find any formats, even though component input is
7875854bf88599545572ce89fba6c4fa0bf6b6e226cHans Verkuil		 * selected. This means that we have to leave tvnorms at
7885854bf88599545572ce89fba6c4fa0bf6b6e226cHans Verkuil		 * V4L2_STD_ALL. We cannot use the 'legacy' trick since
7895854bf88599545572ce89fba6c4fa0bf6b6e226cHans Verkuil		 * tvnorms is set at the device node level and not at the
7905854bf88599545572ce89fba6c4fa0bf6b6e226cHans Verkuil		 * filehandle level.
7915854bf88599545572ce89fba6c4fa0bf6b6e226cHans Verkuil		 *
7925854bf88599545572ce89fba6c4fa0bf6b6e226cHans Verkuil		 * Comment this out for now, but if the legacy mode can be
7935854bf88599545572ce89fba6c4fa0bf6b6e226cHans Verkuil		 * removed in the future, then this code should be enabled
7945854bf88599545572ce89fba6c4fa0bf6b6e226cHans Verkuil		 * again.
7958f69da955873f5e33b60ff117856a2bf1309a336Hans Verkuil		dev->video_dev->tvnorms =
7965854bf88599545572ce89fba6c4fa0bf6b6e226cHans Verkuil			(index != HDPVR_COMPONENT) ? V4L2_STD_ALL : 0;
7975854bf88599545572ce89fba6c4fa0bf6b6e226cHans Verkuil		 */
7988f69da955873f5e33b60ff117856a2bf1309a336Hans Verkuil	}
7999aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
8009aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	return retval;
8019aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau}
8029aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
8039aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunaustatic int vidioc_g_input(struct file *file, void *private_data,
8049aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			  unsigned int *index)
8059aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau{
806ede197aac0c64021a0b2139d19edd8fa066530c2Hans Verkuil	struct hdpvr_device *dev = video_drvdata(file);
8079aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
8089aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	*index = dev->options.video_input;
8099aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	return 0;
8109aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau}
8119aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
8129aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
8139aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunaustatic const char *audio_iname[] = {
8149aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	[HDPVR_RCA_FRONT] = "RCA front",
8159aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	[HDPVR_RCA_BACK]  = "RCA back",
8169aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	[HDPVR_SPDIF]     = "SPDIF",
8179aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau};
8189aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
8199aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunaustatic int vidioc_enumaudio(struct file *file, void *priv,
8209aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau				struct v4l2_audio *audio)
8219aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau{
8229aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	unsigned int n;
8239aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
8249aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	n = audio->index;
8259aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	if (n >= HDPVR_AUDIO_INPUTS)
8269aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		return -EINVAL;
8279aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
8289aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	audio->capability = V4L2_AUDCAP_STEREO;
8299aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
8309aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	strncpy(audio->name, audio_iname[n], sizeof(audio->name) - 1);
8319aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	audio->name[sizeof(audio->name) - 1] = '\0';
8329aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
8339aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	return 0;
8349aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau}
8359aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
8369aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunaustatic int vidioc_s_audio(struct file *file, void *private_data,
8370e8025b9f6011a6bd69d01080d584bc95a89d02eHans Verkuil			  const struct v4l2_audio *audio)
8389aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau{
839ede197aac0c64021a0b2139d19edd8fa066530c2Hans Verkuil	struct hdpvr_device *dev = video_drvdata(file);
8409aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	int retval;
8419aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
8429aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	if (audio->index >= HDPVR_AUDIO_INPUTS)
8439aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		return -EINVAL;
8449aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
8459aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	if (dev->status != STATUS_IDLE)
84697caa318b3ced2241cf1eda772a72c9c2ea19abbHans Verkuil		return -EBUSY;
8479aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
8489aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	retval = hdpvr_set_audio(dev, audio->index+1, dev->options.audio_codec);
8499aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	if (!retval)
8509aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		dev->options.audio_input = audio->index;
8519aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
8529aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	return retval;
8539aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau}
8549aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
8559aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunaustatic int vidioc_g_audio(struct file *file, void *private_data,
8569aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			  struct v4l2_audio *audio)
8579aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau{
858ede197aac0c64021a0b2139d19edd8fa066530c2Hans Verkuil	struct hdpvr_device *dev = video_drvdata(file);
8599aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
8609aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	audio->index = dev->options.audio_input;
8619aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	audio->capability = V4L2_AUDCAP_STEREO;
8629aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	strncpy(audio->name, audio_iname[audio->index], sizeof(audio->name));
8639aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	audio->name[sizeof(audio->name) - 1] = '\0';
8649aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	return 0;
8659aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau}
8669aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
86799c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuilstatic int hdpvr_try_ctrl(struct v4l2_ctrl *ctrl)
8689aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau{
86999c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil	struct hdpvr_device *dev =
87099c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil		container_of(ctrl->handler, struct hdpvr_device, hdl);
8719aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
8729aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	switch (ctrl->id) {
87399c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil	case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
87499c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil		if (ctrl->val == V4L2_MPEG_VIDEO_BITRATE_MODE_VBR &&
87599c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil		    dev->video_bitrate->val >= dev->video_bitrate_peak->val)
87699c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil			dev->video_bitrate_peak->val =
87799c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil					dev->video_bitrate->val + 100000;
8789aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		break;
8799aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	}
8809aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	return 0;
8819aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau}
8829aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
88399c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuilstatic int hdpvr_s_ctrl(struct v4l2_ctrl *ctrl)
8849aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau{
88599c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil	struct hdpvr_device *dev =
88699c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil		container_of(ctrl->handler, struct hdpvr_device, hdl);
88799c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil	struct hdpvr_options *opt = &dev->options;
88899c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil	int ret = -EINVAL;
8899aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
8909aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	switch (ctrl->id) {
8919aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	case V4L2_CID_BRIGHTNESS:
89299c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil		ret = hdpvr_config_call(dev, CTRL_BRIGHTNESS, ctrl->val);
89399c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil		if (ret)
89499c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil			break;
89599c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil		dev->options.brightness = ctrl->val;
89699c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil		return 0;
8979aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	case V4L2_CID_CONTRAST:
89899c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil		ret = hdpvr_config_call(dev, CTRL_CONTRAST, ctrl->val);
89999c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil		if (ret)
90099c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil			break;
90199c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil		dev->options.contrast = ctrl->val;
90299c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil		return 0;
9039aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	case V4L2_CID_SATURATION:
90499c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil		ret = hdpvr_config_call(dev, CTRL_SATURATION, ctrl->val);
90599c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil		if (ret)
90699c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil			break;
90799c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil		dev->options.saturation = ctrl->val;
90899c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil		return 0;
9099aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	case V4L2_CID_HUE:
91099c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil		ret = hdpvr_config_call(dev, CTRL_HUE, ctrl->val);
91199c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil		if (ret)
91299c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil			break;
91399c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil		dev->options.hue = ctrl->val;
91499c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil		return 0;
9159aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	case V4L2_CID_SHARPNESS:
91699c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil		ret = hdpvr_config_call(dev, CTRL_SHARPNESS, ctrl->val);
91799c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil		if (ret)
91899c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil			break;
91999c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil		dev->options.sharpness = ctrl->val;
92099c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil		return 0;
9219aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	case V4L2_CID_MPEG_AUDIO_ENCODING:
9229aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		if (dev->flags & HDPVR_FLAG_AC3_CAP) {
92399c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil			opt->audio_codec = ctrl->val;
92499c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil			return hdpvr_set_audio(dev, opt->audio_input,
9259aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau					      opt->audio_codec);
9269aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		}
92799c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil		return 0;
9289aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	case V4L2_CID_MPEG_VIDEO_ENCODING:
92999c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil		return 0;
9309aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau/* 	case V4L2_CID_MPEG_VIDEO_B_FRAMES: */
9319aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau/* 		if (ctrl->value == 0 && !(opt->gop_mode & 0x2)) { */
9329aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau/* 			opt->gop_mode |= 0x2; */
9339aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau/* 			hdpvr_config_call(dev, CTRL_GOP_MODE_VALUE, */
9349aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau/* 					  opt->gop_mode); */
9359aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau/* 		} */
9369aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau/* 		if (ctrl->value == 128 && 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/* 		break; */
94299c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil	case V4L2_CID_MPEG_VIDEO_BITRATE_MODE: {
94399c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil		uint peak_bitrate = dev->video_bitrate_peak->val / 100000;
94499c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil		uint bitrate = dev->video_bitrate->val / 100000;
94599c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil
94699c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil		if (ctrl->is_new) {
94799c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil			if (ctrl->val == V4L2_MPEG_VIDEO_BITRATE_MODE_CBR)
94899c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil				opt->bitrate_mode = HDPVR_CONSTANT;
94999c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil			else
95099c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil				opt->bitrate_mode = HDPVR_VARIABLE_AVERAGE;
9519aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			hdpvr_config_call(dev, CTRL_BITRATE_MODE_VALUE,
9529aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau					  opt->bitrate_mode);
95399c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil			v4l2_ctrl_activate(dev->video_bitrate_peak,
95499c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil				ctrl->val != V4L2_MPEG_VIDEO_BITRATE_MODE_CBR);
9559aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		}
9569aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
95799c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil		if (dev->video_bitrate_peak->is_new ||
95899c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil		    dev->video_bitrate->is_new) {
95999c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil			opt->bitrate = bitrate;
9609aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			opt->peak_bitrate = peak_bitrate;
9619aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			hdpvr_set_bitrate(dev);
96299c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil		}
96399c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil		return 0;
9649aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	}
9659aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	case V4L2_CID_MPEG_STREAM_TYPE:
96699c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil		return 0;
9679aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	default:
96899c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil		break;
9699aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	}
9709aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	return ret;
9719aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau}
9729aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
9739aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunaustatic int vidioc_enum_fmt_vid_cap(struct file *file, void *private_data,
9749aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau				    struct v4l2_fmtdesc *f)
9759aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau{
97697caa318b3ced2241cf1eda772a72c9c2ea19abbHans Verkuil	if (f->index != 0)
9779aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		return -EINVAL;
9789aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
9799aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	f->flags = V4L2_FMT_FLAG_COMPRESSED;
9809aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	strncpy(f->description, "MPEG2-TS with AVC/AAC streams", 32);
9819aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	f->pixelformat = V4L2_PIX_FMT_MPEG;
9829aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
9839aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	return 0;
9849aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau}
9859aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
9863315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuilstatic int vidioc_g_fmt_vid_cap(struct file *file, void *_fh,
9879aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau				struct v4l2_format *f)
9889aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau{
989ede197aac0c64021a0b2139d19edd8fa066530c2Hans Verkuil	struct hdpvr_device *dev = video_drvdata(file);
9903315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	struct hdpvr_fh *fh = _fh;
9913315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil
9923315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	/*
9933315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	 * The original driver would always returns the current detected
9943315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	 * resolution as the format (and EFAULT if it couldn't be detected).
9953315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	 * With the introduction of VIDIOC_QUERY_DV_TIMINGS there is now a
9963315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	 * better way of doing this, but to stay compatible with existing
9973315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	 * applications we assume legacy mode every time an application opens
9983315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	 * the device. Only if one of the new DV_TIMINGS ioctls is called
9993315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	 * will the filehandle go into 'normal' mode where g_fmt returns the
10003315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	 * last set format.
10013315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	 */
10023315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	if (fh->legacy_mode) {
10033315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil		struct hdpvr_video_info *vid_info;
10043315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil
10053315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil		vid_info = get_video_info(dev);
10063315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil		if (!vid_info)
10073315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil			return -EFAULT;
10083315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil		f->fmt.pix.width = vid_info->width;
10093315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil		f->fmt.pix.height = vid_info->height;
10103315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil		kfree(vid_info);
10113315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	} else {
10123315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil		f->fmt.pix.width = dev->width;
10133315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil		f->fmt.pix.height = dev->height;
10143315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	}
10159aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	f->fmt.pix.pixelformat	= V4L2_PIX_FMT_MPEG;
10169aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	f->fmt.pix.sizeimage	= dev->bulk_in_size;
10179aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	f->fmt.pix.bytesperline	= 0;
10183315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	f->fmt.pix.priv		= 0;
10193315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	if (f->fmt.pix.width == 720) {
10203315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil		/* SDTV formats */
10213315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil		f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
10223315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil		f->fmt.pix.field = V4L2_FIELD_INTERLACED;
10233315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	} else {
10243315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil		/* HDTV formats */
10253315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil		f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE240M;
10263315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil		f->fmt.pix.field = V4L2_FIELD_NONE;
10273315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	}
10289aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	return 0;
10299aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau}
10309aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
103176717b887cccc77d04357fc0d6ac98f894e3eb3cJanne Grunaustatic int vidioc_encoder_cmd(struct file *filp, void *priv,
103276717b887cccc77d04357fc0d6ac98f894e3eb3cJanne Grunau			       struct v4l2_encoder_cmd *a)
103376717b887cccc77d04357fc0d6ac98f894e3eb3cJanne Grunau{
1034ede197aac0c64021a0b2139d19edd8fa066530c2Hans Verkuil	struct hdpvr_device *dev = video_drvdata(filp);
1035ede197aac0c64021a0b2139d19edd8fa066530c2Hans Verkuil	int res = 0;
103676717b887cccc77d04357fc0d6ac98f894e3eb3cJanne Grunau
103776717b887cccc77d04357fc0d6ac98f894e3eb3cJanne Grunau	mutex_lock(&dev->io_mutex);
1038ede197aac0c64021a0b2139d19edd8fa066530c2Hans Verkuil	a->flags = 0;
103976717b887cccc77d04357fc0d6ac98f894e3eb3cJanne Grunau
104076717b887cccc77d04357fc0d6ac98f894e3eb3cJanne Grunau	switch (a->cmd) {
104176717b887cccc77d04357fc0d6ac98f894e3eb3cJanne Grunau	case V4L2_ENC_CMD_START:
1042ede197aac0c64021a0b2139d19edd8fa066530c2Hans Verkuil		if (dev->owner && filp->private_data != dev->owner) {
1043ede197aac0c64021a0b2139d19edd8fa066530c2Hans Verkuil			res = -EBUSY;
1044ede197aac0c64021a0b2139d19edd8fa066530c2Hans Verkuil			break;
1045ede197aac0c64021a0b2139d19edd8fa066530c2Hans Verkuil		}
1046ede197aac0c64021a0b2139d19edd8fa066530c2Hans Verkuil		if (dev->status == STATUS_STREAMING)
1047ede197aac0c64021a0b2139d19edd8fa066530c2Hans Verkuil			break;
104876717b887cccc77d04357fc0d6ac98f894e3eb3cJanne Grunau		res = hdpvr_start_streaming(dev);
1049ede197aac0c64021a0b2139d19edd8fa066530c2Hans Verkuil		if (!res)
1050ede197aac0c64021a0b2139d19edd8fa066530c2Hans Verkuil			dev->owner = filp->private_data;
1051ede197aac0c64021a0b2139d19edd8fa066530c2Hans Verkuil		else
1052ede197aac0c64021a0b2139d19edd8fa066530c2Hans Verkuil			dev->status = STATUS_IDLE;
105376717b887cccc77d04357fc0d6ac98f894e3eb3cJanne Grunau		break;
105476717b887cccc77d04357fc0d6ac98f894e3eb3cJanne Grunau	case V4L2_ENC_CMD_STOP:
1055ede197aac0c64021a0b2139d19edd8fa066530c2Hans Verkuil		if (dev->owner && filp->private_data != dev->owner) {
1056ede197aac0c64021a0b2139d19edd8fa066530c2Hans Verkuil			res = -EBUSY;
1057ede197aac0c64021a0b2139d19edd8fa066530c2Hans Verkuil			break;
1058ede197aac0c64021a0b2139d19edd8fa066530c2Hans Verkuil		}
1059ede197aac0c64021a0b2139d19edd8fa066530c2Hans Verkuil		if (dev->status == STATUS_IDLE)
1060ede197aac0c64021a0b2139d19edd8fa066530c2Hans Verkuil			break;
106176717b887cccc77d04357fc0d6ac98f894e3eb3cJanne Grunau		res = hdpvr_stop_streaming(dev);
1062ede197aac0c64021a0b2139d19edd8fa066530c2Hans Verkuil		if (!res)
1063ede197aac0c64021a0b2139d19edd8fa066530c2Hans Verkuil			dev->owner = NULL;
106476717b887cccc77d04357fc0d6ac98f894e3eb3cJanne Grunau		break;
106576717b887cccc77d04357fc0d6ac98f894e3eb3cJanne Grunau	default:
10669ef77adfb9ac170bcaf449530cf129c48547fd55Janne Grunau		v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev,
106776717b887cccc77d04357fc0d6ac98f894e3eb3cJanne Grunau			 "Unsupported encoder cmd %d\n", a->cmd);
106848f98f7557d35d360470bf6d9fd7b00d04fba828Janne Grunau		res = -EINVAL;
1069ede197aac0c64021a0b2139d19edd8fa066530c2Hans Verkuil		break;
107076717b887cccc77d04357fc0d6ac98f894e3eb3cJanne Grunau	}
1071ede197aac0c64021a0b2139d19edd8fa066530c2Hans Verkuil
107276717b887cccc77d04357fc0d6ac98f894e3eb3cJanne Grunau	mutex_unlock(&dev->io_mutex);
107376717b887cccc77d04357fc0d6ac98f894e3eb3cJanne Grunau	return res;
107476717b887cccc77d04357fc0d6ac98f894e3eb3cJanne Grunau}
107576717b887cccc77d04357fc0d6ac98f894e3eb3cJanne Grunau
107676717b887cccc77d04357fc0d6ac98f894e3eb3cJanne Grunaustatic int vidioc_try_encoder_cmd(struct file *filp, void *priv,
107776717b887cccc77d04357fc0d6ac98f894e3eb3cJanne Grunau					struct v4l2_encoder_cmd *a)
107876717b887cccc77d04357fc0d6ac98f894e3eb3cJanne Grunau{
1079ede197aac0c64021a0b2139d19edd8fa066530c2Hans Verkuil	a->flags = 0;
108076717b887cccc77d04357fc0d6ac98f894e3eb3cJanne Grunau	switch (a->cmd) {
108176717b887cccc77d04357fc0d6ac98f894e3eb3cJanne Grunau	case V4L2_ENC_CMD_START:
108276717b887cccc77d04357fc0d6ac98f894e3eb3cJanne Grunau	case V4L2_ENC_CMD_STOP:
108376717b887cccc77d04357fc0d6ac98f894e3eb3cJanne Grunau		return 0;
108476717b887cccc77d04357fc0d6ac98f894e3eb3cJanne Grunau	default:
108576717b887cccc77d04357fc0d6ac98f894e3eb3cJanne Grunau		return -EINVAL;
108676717b887cccc77d04357fc0d6ac98f894e3eb3cJanne Grunau	}
108776717b887cccc77d04357fc0d6ac98f894e3eb3cJanne Grunau}
10889aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
10899aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunaustatic const struct v4l2_ioctl_ops hdpvr_ioctl_ops = {
10909aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	.vidioc_querycap	= vidioc_querycap,
10919aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	.vidioc_s_std		= vidioc_s_std,
10928f69da955873f5e33b60ff117856a2bf1309a336Hans Verkuil	.vidioc_g_std		= vidioc_g_std,
10938f69da955873f5e33b60ff117856a2bf1309a336Hans Verkuil	.vidioc_querystd	= vidioc_querystd,
10943315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	.vidioc_s_dv_timings	= vidioc_s_dv_timings,
10953315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	.vidioc_g_dv_timings	= vidioc_g_dv_timings,
10963315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	.vidioc_query_dv_timings= vidioc_query_dv_timings,
10973315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	.vidioc_enum_dv_timings	= vidioc_enum_dv_timings,
10983315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	.vidioc_dv_timings_cap	= vidioc_dv_timings_cap,
10999aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	.vidioc_enum_input	= vidioc_enum_input,
11009aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	.vidioc_g_input		= vidioc_g_input,
11019aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	.vidioc_s_input		= vidioc_s_input,
11029aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	.vidioc_enumaudio	= vidioc_enumaudio,
11039aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	.vidioc_g_audio		= vidioc_g_audio,
11049aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	.vidioc_s_audio		= vidioc_s_audio,
110565fe42d6054bb84c4abc4168310bd5d7c462456eHans Verkuil	.vidioc_enum_fmt_vid_cap= vidioc_enum_fmt_vid_cap,
110665fe42d6054bb84c4abc4168310bd5d7c462456eHans Verkuil	.vidioc_g_fmt_vid_cap	= vidioc_g_fmt_vid_cap,
11073315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	.vidioc_s_fmt_vid_cap	= vidioc_g_fmt_vid_cap,
11083315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	.vidioc_try_fmt_vid_cap	= vidioc_g_fmt_vid_cap,
110976717b887cccc77d04357fc0d6ac98f894e3eb3cJanne Grunau	.vidioc_encoder_cmd	= vidioc_encoder_cmd,
111076717b887cccc77d04357fc0d6ac98f894e3eb3cJanne Grunau	.vidioc_try_encoder_cmd	= vidioc_try_encoder_cmd,
111165fe42d6054bb84c4abc4168310bd5d7c462456eHans Verkuil	.vidioc_log_status	= v4l2_ctrl_log_status,
111265fe42d6054bb84c4abc4168310bd5d7c462456eHans Verkuil	.vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
111365fe42d6054bb84c4abc4168310bd5d7c462456eHans Verkuil	.vidioc_unsubscribe_event = v4l2_event_unsubscribe,
11149aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau};
11159aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
11169aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunaustatic void hdpvr_device_release(struct video_device *vdev)
11179aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau{
11189aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	struct hdpvr_device *dev = video_get_drvdata(vdev);
11199aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
11209aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	hdpvr_delete(dev);
1121f2b305cd6711b7b3ce30db93b50bc5d6312950c8Hans Verkuil	mutex_lock(&dev->io_mutex);
1122f2b305cd6711b7b3ce30db93b50bc5d6312950c8Hans Verkuil	destroy_workqueue(dev->workqueue);
1123f2b305cd6711b7b3ce30db93b50bc5d6312950c8Hans Verkuil	mutex_unlock(&dev->io_mutex);
1124f2b305cd6711b7b3ce30db93b50bc5d6312950c8Hans Verkuil
1125f2b305cd6711b7b3ce30db93b50bc5d6312950c8Hans Verkuil	v4l2_device_unregister(&dev->v4l2_dev);
112699c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil	v4l2_ctrl_handler_free(&dev->hdl);
1127f2b305cd6711b7b3ce30db93b50bc5d6312950c8Hans Verkuil
1128f2b305cd6711b7b3ce30db93b50bc5d6312950c8Hans Verkuil	/* deregister I2C adapter */
112954d80904b4c1f7aa1d569d07ca3e62fba0daf3a2Mauro Carvalho Chehab#if IS_ENABLED(CONFIG_I2C)
1130f2b305cd6711b7b3ce30db93b50bc5d6312950c8Hans Verkuil	mutex_lock(&dev->i2c_mutex);
1131324b04ba5da7918a2409f8113e46843bfbd89e67Jarod Wilson	i2c_del_adapter(&dev->i2c_adapter);
1132f2b305cd6711b7b3ce30db93b50bc5d6312950c8Hans Verkuil	mutex_unlock(&dev->i2c_mutex);
1133f2b305cd6711b7b3ce30db93b50bc5d6312950c8Hans Verkuil#endif /* CONFIG_I2C */
1134f2b305cd6711b7b3ce30db93b50bc5d6312950c8Hans Verkuil
1135f2b305cd6711b7b3ce30db93b50bc5d6312950c8Hans Verkuil	kfree(dev->usbc_buf);
1136f2b305cd6711b7b3ce30db93b50bc5d6312950c8Hans Verkuil	kfree(dev);
11379aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau}
11389aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
11399aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunaustatic const struct video_device hdpvr_video_template = {
11409aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	.fops			= &hdpvr_fops,
11419aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	.release		= hdpvr_device_release,
11429aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	.ioctl_ops 		= &hdpvr_ioctl_ops,
11435854bf88599545572ce89fba6c4fa0bf6b6e226cHans Verkuil	.tvnorms		= V4L2_STD_ALL,
11449aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau};
11459aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
114699c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuilstatic const struct v4l2_ctrl_ops hdpvr_ctrl_ops = {
114799c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil	.try_ctrl = hdpvr_try_ctrl,
114899c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil	.s_ctrl = hdpvr_s_ctrl,
114999c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil};
115099c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil
1151a50ab29185a9ec31e5a6999e53add0508653e889Janne Grunauint hdpvr_register_videodev(struct hdpvr_device *dev, struct device *parent,
1152a50ab29185a9ec31e5a6999e53add0508653e889Janne Grunau			    int devnum)
11539aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau{
115499c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil	struct v4l2_ctrl_handler *hdl = &dev->hdl;
115599c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil	bool ac3 = dev->flags & HDPVR_FLAG_AC3_CAP;
115699c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil	int res;
115799c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil
11588f69da955873f5e33b60ff117856a2bf1309a336Hans Verkuil	dev->cur_std = V4L2_STD_525_60;
11598f69da955873f5e33b60ff117856a2bf1309a336Hans Verkuil	dev->width = 720;
11608f69da955873f5e33b60ff117856a2bf1309a336Hans Verkuil	dev->height = 480;
11613315c59a45d5314c935a7dd82ab3c324c0d01343Hans Verkuil	dev->cur_dv_timings = hdpvr_dv_timings[HDPVR_DEF_DV_TIMINGS_IDX];
116299c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil	v4l2_ctrl_handler_init(hdl, 11);
116399c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil	if (dev->fw_ver > 0x15) {
116499c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil		v4l2_ctrl_new_std(hdl, &hdpvr_ctrl_ops,
116599c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil			V4L2_CID_BRIGHTNESS, 0x0, 0xff, 1, 0x80);
116699c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil		v4l2_ctrl_new_std(hdl, &hdpvr_ctrl_ops,
116799c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil			V4L2_CID_CONTRAST, 0x0, 0xff, 1, 0x40);
116899c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil		v4l2_ctrl_new_std(hdl, &hdpvr_ctrl_ops,
116999c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil			V4L2_CID_SATURATION, 0x0, 0xff, 1, 0x40);
117099c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil		v4l2_ctrl_new_std(hdl, &hdpvr_ctrl_ops,
117199c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil			V4L2_CID_HUE, 0x0, 0x1e, 1, 0xf);
117299c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil		v4l2_ctrl_new_std(hdl, &hdpvr_ctrl_ops,
117399c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil			V4L2_CID_SHARPNESS, 0x0, 0xff, 1, 0x80);
117499c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil	} else {
117599c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil		v4l2_ctrl_new_std(hdl, &hdpvr_ctrl_ops,
117699c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil			V4L2_CID_BRIGHTNESS, 0x0, 0xff, 1, 0x86);
117799c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil		v4l2_ctrl_new_std(hdl, &hdpvr_ctrl_ops,
117899c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil			V4L2_CID_CONTRAST, 0x0, 0xff, 1, 0x80);
117999c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil		v4l2_ctrl_new_std(hdl, &hdpvr_ctrl_ops,
118099c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil			V4L2_CID_SATURATION, 0x0, 0xff, 1, 0x80);
118199c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil		v4l2_ctrl_new_std(hdl, &hdpvr_ctrl_ops,
118299c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil			V4L2_CID_HUE, 0x0, 0xff, 1, 0x80);
118399c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil		v4l2_ctrl_new_std(hdl, &hdpvr_ctrl_ops,
118499c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil			V4L2_CID_SHARPNESS, 0x0, 0xff, 1, 0x80);
118599c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil	}
118699c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil
118799c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil	v4l2_ctrl_new_std_menu(hdl, &hdpvr_ctrl_ops,
118899c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil		V4L2_CID_MPEG_STREAM_TYPE,
118999c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil		V4L2_MPEG_STREAM_TYPE_MPEG2_TS,
119099c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil		0x1, V4L2_MPEG_STREAM_TYPE_MPEG2_TS);
119199c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil	v4l2_ctrl_new_std_menu(hdl, &hdpvr_ctrl_ops,
119299c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil		V4L2_CID_MPEG_AUDIO_ENCODING,
119399c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil		ac3 ? V4L2_MPEG_AUDIO_ENCODING_AC3 : V4L2_MPEG_AUDIO_ENCODING_AAC,
119499c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil		0x7, V4L2_MPEG_AUDIO_ENCODING_AAC);
119599c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil	v4l2_ctrl_new_std_menu(hdl, &hdpvr_ctrl_ops,
119699c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil		V4L2_CID_MPEG_VIDEO_ENCODING,
119799c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil		V4L2_MPEG_VIDEO_ENCODING_MPEG_4_AVC, 0x3,
119899c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil		V4L2_MPEG_VIDEO_ENCODING_MPEG_4_AVC);
119999c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil
120099c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil	dev->video_mode = v4l2_ctrl_new_std_menu(hdl, &hdpvr_ctrl_ops,
120199c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil		V4L2_CID_MPEG_VIDEO_BITRATE_MODE,
120299c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil		V4L2_MPEG_VIDEO_BITRATE_MODE_CBR, 0,
120399c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil		V4L2_MPEG_VIDEO_BITRATE_MODE_CBR);
120499c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil
120599c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil	dev->video_bitrate = v4l2_ctrl_new_std(hdl, &hdpvr_ctrl_ops,
120699c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil		V4L2_CID_MPEG_VIDEO_BITRATE,
120799c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil		1000000, 13500000, 100000, 6500000);
120899c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil	dev->video_bitrate_peak = v4l2_ctrl_new_std(hdl, &hdpvr_ctrl_ops,
120999c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil		V4L2_CID_MPEG_VIDEO_BITRATE_PEAK,
121099c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil		1100000, 20200000, 100000, 9000000);
121199c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil	dev->v4l2_dev.ctrl_handler = hdl;
121299c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil	if (hdl->error) {
121399c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil		res = hdl->error;
121499c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil		v4l2_err(&dev->v4l2_dev, "Could not register controls\n");
121599c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil		goto error;
121699c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil	}
121799c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil	v4l2_ctrl_cluster(3, &dev->video_mode);
121899c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil	res = v4l2_ctrl_handler_setup(hdl);
121999c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil	if (res < 0) {
122099c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil		v4l2_err(&dev->v4l2_dev, "Could not setup controls\n");
122199c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil		goto error;
122299c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil	}
122399c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil
12249aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	/* setup and register video device */
12259aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	dev->video_dev = video_device_alloc();
12269aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	if (!dev->video_dev) {
12279ef77adfb9ac170bcaf449530cf129c48547fd55Janne Grunau		v4l2_err(&dev->v4l2_dev, "video_device_alloc() failed\n");
122899c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil		res = -ENOMEM;
12299aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		goto error;
12309aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	}
12319aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
1232ede197aac0c64021a0b2139d19edd8fa066530c2Hans Verkuil	*dev->video_dev = hdpvr_video_template;
12339aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	strcpy(dev->video_dev->name, "Hauppauge HD PVR");
1234ede197aac0c64021a0b2139d19edd8fa066530c2Hans Verkuil	dev->video_dev->v4l2_dev = &dev->v4l2_dev;
12359aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	video_set_drvdata(dev->video_dev, dev);
123665fe42d6054bb84c4abc4168310bd5d7c462456eHans Verkuil	set_bit(V4L2_FL_USE_FH_PRIO, &dev->video_dev->flags);
12379aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
123899c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil	res = video_register_device(dev->video_dev, VFL_TYPE_GRABBER, devnum);
123999c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil	if (res < 0) {
12409ef77adfb9ac170bcaf449530cf129c48547fd55Janne Grunau		v4l2_err(&dev->v4l2_dev, "video_device registration failed\n");
12419aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		goto error;
12429aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	}
12439aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
12449aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	return 0;
12459aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunauerror:
124699c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil	v4l2_ctrl_handler_free(hdl);
124799c77aa4281c41fab255a4eb25ccc36a8c2e113dHans Verkuil	return res;
12489aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau}
1249