hdpvr-video.c revision 314527acbbb3f33f72c2ef19d8cfabcada9912a5
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>
249aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau#include <media/v4l2-dev.h>
259aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau#include <media/v4l2-common.h>
269aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau#include <media/v4l2-ioctl.h>
279aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau#include "hdpvr.h"
289aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
2939bcb3ae030b0b64262adf6c5243bf767d8b75dcAlan Young#define BULK_URB_TIMEOUT   90 /* 0.09 seconds */
309aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
319ef77adfb9ac170bcaf449530cf129c48547fd55Janne Grunau#define print_buffer_status() { \
329ef77adfb9ac170bcaf449530cf129c48547fd55Janne Grunau		v4l2_dbg(MSG_BUFFER, hdpvr_debug, &dev->v4l2_dev,	\
339ef77adfb9ac170bcaf449530cf129c48547fd55Janne Grunau			 "%s:%d buffer stat: %d free, %d proc\n",	\
349ef77adfb9ac170bcaf449530cf129c48547fd55Janne Grunau			 __func__, __LINE__,				\
359ef77adfb9ac170bcaf449530cf129c48547fd55Janne Grunau			 list_size(&dev->free_buff_list),		\
369ef77adfb9ac170bcaf449530cf129c48547fd55Janne Grunau			 list_size(&dev->rec_buff_list)); }
37d211bfcbd0f13f1234aaa6e565013dba051a408cJanne Grunau
389aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunaustruct hdpvr_fh {
399aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	struct hdpvr_device	*dev;
409aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau};
419aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
429aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunaustatic uint list_size(struct list_head *list)
439aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau{
449aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	struct list_head *tmp;
459aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	uint count = 0;
469aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
479aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	list_for_each(tmp, list) {
489aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		count++;
499aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	}
509aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
519aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	return count;
529aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau}
539aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
549aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau/*=========================================================================*/
559aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau/* urb callback */
569aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunaustatic void hdpvr_read_bulk_callback(struct urb *urb)
579aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau{
589aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	struct hdpvr_buffer *buf = (struct hdpvr_buffer *)urb->context;
599aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	struct hdpvr_device *dev = buf->dev;
609aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
619aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	/* marking buffer as received and wake waiting */
629aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	buf->status = BUFSTAT_READY;
639aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	wake_up_interruptible(&dev->wait_data);
649aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau}
659aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
669aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau/*=========================================================================*/
679aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau/* bufffer bits */
689aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
699aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau/* function expects dev->io_mutex to be hold by caller */
709aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunauint hdpvr_cancel_queue(struct hdpvr_device *dev)
719aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau{
729aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	struct hdpvr_buffer *buf;
739aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
749aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	list_for_each_entry(buf, &dev->rec_buff_list, buff_list) {
759aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		usb_kill_urb(buf->urb);
769aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		buf->status = BUFSTAT_AVAILABLE;
779aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	}
789aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
799aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	list_splice_init(&dev->rec_buff_list, dev->free_buff_list.prev);
809aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
819aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	return 0;
829aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau}
839aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
849aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunaustatic int hdpvr_free_queue(struct list_head *q)
859aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau{
869aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	struct list_head *tmp;
879aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	struct list_head *p;
889aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	struct hdpvr_buffer *buf;
899aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	struct urb *urb;
909aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
919aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	for (p = q->next; p != q;) {
929aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		buf = list_entry(p, struct hdpvr_buffer, buff_list);
939aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
949aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		urb = buf->urb;
95997ea58eb92f9970b8af7aae48800d0ef43b9423Daniel Mack		usb_free_coherent(urb->dev, urb->transfer_buffer_length,
96997ea58eb92f9970b8af7aae48800d0ef43b9423Daniel Mack				  urb->transfer_buffer, urb->transfer_dma);
979aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		usb_free_urb(urb);
989aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		tmp = p->next;
999aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		list_del(p);
1009aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		kfree(buf);
1019aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		p = tmp;
1029aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	}
1039aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
1049aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	return 0;
1059aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau}
1069aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
1079aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau/* function expects dev->io_mutex to be hold by caller */
1089aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunauint hdpvr_free_buffers(struct hdpvr_device *dev)
1099aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau{
1109aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	hdpvr_cancel_queue(dev);
1119aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
1129aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	hdpvr_free_queue(&dev->free_buff_list);
1139aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	hdpvr_free_queue(&dev->rec_buff_list);
1149aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
1159aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	return 0;
1169aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau}
1179aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
1189aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau/* function expects dev->io_mutex to be hold by caller */
1199aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunauint hdpvr_alloc_buffers(struct hdpvr_device *dev, uint count)
1209aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau{
1219aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	uint i;
1229aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	int retval = -ENOMEM;
1239aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	u8 *mem;
1249aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	struct hdpvr_buffer *buf;
1259aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	struct urb *urb;
1269aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
1279ef77adfb9ac170bcaf449530cf129c48547fd55Janne Grunau	v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev,
1289aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		 "allocating %u buffers\n", count);
1299aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
1309aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	for (i = 0; i < count; i++) {
1319aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
1329aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		buf = kzalloc(sizeof(struct hdpvr_buffer), GFP_KERNEL);
1339aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		if (!buf) {
1349ef77adfb9ac170bcaf449530cf129c48547fd55Janne Grunau			v4l2_err(&dev->v4l2_dev, "cannot allocate buffer\n");
1359aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			goto exit;
1369aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		}
1379aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		buf->dev = dev;
1389aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
1399aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		urb = usb_alloc_urb(0, GFP_KERNEL);
1409aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		if (!urb) {
1419ef77adfb9ac170bcaf449530cf129c48547fd55Janne Grunau			v4l2_err(&dev->v4l2_dev, "cannot allocate urb\n");
142cd0e280f1bbecebcd20ed0ddd4dd8fb03a506b3cJulia Lawall			goto exit_urb;
1439aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		}
1449aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		buf->urb = urb;
1459aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
146997ea58eb92f9970b8af7aae48800d0ef43b9423Daniel Mack		mem = usb_alloc_coherent(dev->udev, dev->bulk_in_size, GFP_KERNEL,
147997ea58eb92f9970b8af7aae48800d0ef43b9423Daniel Mack					 &urb->transfer_dma);
1489aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		if (!mem) {
1499ef77adfb9ac170bcaf449530cf129c48547fd55Janne Grunau			v4l2_err(&dev->v4l2_dev,
1509ef77adfb9ac170bcaf449530cf129c48547fd55Janne Grunau				 "cannot allocate usb transfer buffer\n");
151cd0e280f1bbecebcd20ed0ddd4dd8fb03a506b3cJulia Lawall			goto exit_urb_buffer;
1529aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		}
1539aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
1549aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		usb_fill_bulk_urb(buf->urb, dev->udev,
1559aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau				  usb_rcvbulkpipe(dev->udev,
1569aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau						  dev->bulk_in_endpointAddr),
1579aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau				  mem, dev->bulk_in_size,
1589aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau				  hdpvr_read_bulk_callback, buf);
1599aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
1604f5c933abb34532dc962185c999509b97a97fa1bJames M McLaren		buf->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
1619aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		buf->status = BUFSTAT_AVAILABLE;
1629aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		list_add_tail(&buf->buff_list, &dev->free_buff_list);
1639aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	}
1649aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	return 0;
165cd0e280f1bbecebcd20ed0ddd4dd8fb03a506b3cJulia Lawallexit_urb_buffer:
166cd0e280f1bbecebcd20ed0ddd4dd8fb03a506b3cJulia Lawall	usb_free_urb(urb);
167cd0e280f1bbecebcd20ed0ddd4dd8fb03a506b3cJulia Lawallexit_urb:
168cd0e280f1bbecebcd20ed0ddd4dd8fb03a506b3cJulia Lawall	kfree(buf);
1699aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunauexit:
1709aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	hdpvr_free_buffers(dev);
1719aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	return retval;
1729aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau}
1739aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
1749aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunaustatic int hdpvr_submit_buffers(struct hdpvr_device *dev)
1759aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau{
1769aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	struct hdpvr_buffer *buf;
1779aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	struct urb *urb;
1789aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	int ret = 0, err_count = 0;
1799aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
1809aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	mutex_lock(&dev->io_mutex);
1819aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
1829aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	while (dev->status == STATUS_STREAMING &&
1839aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	       !list_empty(&dev->free_buff_list)) {
1849aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
1859aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		buf = list_entry(dev->free_buff_list.next, struct hdpvr_buffer,
1869aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau				 buff_list);
1879aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		if (buf->status != BUFSTAT_AVAILABLE) {
1889ef77adfb9ac170bcaf449530cf129c48547fd55Janne Grunau			v4l2_err(&dev->v4l2_dev,
1894b512d26f425be1c779c8319249b42ce3c3424d2Thadeu Lima de Souza Cascardo				 "buffer not marked as available\n");
1909aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			ret = -EFAULT;
1919aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			goto err;
1929aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		}
1939aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
1949aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		urb = buf->urb;
1959aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		urb->status = 0;
1969aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		urb->actual_length = 0;
1979aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		ret = usb_submit_urb(urb, GFP_KERNEL);
1989aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		if (ret) {
1999ef77adfb9ac170bcaf449530cf129c48547fd55Janne Grunau			v4l2_err(&dev->v4l2_dev,
2009ef77adfb9ac170bcaf449530cf129c48547fd55Janne Grunau				 "usb_submit_urb in %s returned %d\n",
2019ef77adfb9ac170bcaf449530cf129c48547fd55Janne Grunau				 __func__, ret);
2029aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			if (++err_count > 2)
2039aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau				break;
2049aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			continue;
2059aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		}
2069aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		buf->status = BUFSTAT_INPROGRESS;
2079aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		list_move_tail(&buf->buff_list, &dev->rec_buff_list);
2089aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	}
2099aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunauerr:
210d211bfcbd0f13f1234aaa6e565013dba051a408cJanne Grunau	print_buffer_status();
2119aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	mutex_unlock(&dev->io_mutex);
2129aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	return ret;
2139aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau}
2149aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
2159aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunaustatic struct hdpvr_buffer *hdpvr_get_next_buffer(struct hdpvr_device *dev)
2169aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau{
2179aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	struct hdpvr_buffer *buf;
2189aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
2199aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	mutex_lock(&dev->io_mutex);
2209aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
2219aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	if (list_empty(&dev->rec_buff_list)) {
2229aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		mutex_unlock(&dev->io_mutex);
2239aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		return NULL;
2249aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	}
2259aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
2269aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	buf = list_entry(dev->rec_buff_list.next, struct hdpvr_buffer,
2279aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			 buff_list);
2289aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	mutex_unlock(&dev->io_mutex);
2299aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
2309aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	return buf;
2319aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau}
2329aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
2339aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunaustatic void hdpvr_transmit_buffers(struct work_struct *work)
2349aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau{
2359aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	struct hdpvr_device *dev = container_of(work, struct hdpvr_device,
2369aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau						worker);
2379aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
2389aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	while (dev->status == STATUS_STREAMING) {
2399aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
2409aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		if (hdpvr_submit_buffers(dev)) {
2419ef77adfb9ac170bcaf449530cf129c48547fd55Janne Grunau			v4l2_err(&dev->v4l2_dev, "couldn't submit buffers\n");
2429aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			goto error;
2439aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		}
2449aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		if (wait_event_interruptible(dev->wait_buffer,
2459aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau				!list_empty(&dev->free_buff_list) ||
2469aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau					     dev->status != STATUS_STREAMING))
2479aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			goto error;
2489aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	}
2499aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
2509ef77adfb9ac170bcaf449530cf129c48547fd55Janne Grunau	v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev,
2519aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		 "transmit worker exited\n");
2529aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	return;
2539aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunauerror:
2549ef77adfb9ac170bcaf449530cf129c48547fd55Janne Grunau	v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev,
2559aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		 "transmit buffers errored\n");
2569aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	dev->status = STATUS_ERROR;
2579aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau}
2589aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
2599aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau/* function expects dev->io_mutex to be hold by caller */
2609aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunaustatic int hdpvr_start_streaming(struct hdpvr_device *dev)
2619aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau{
2629aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	int ret;
2639aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	struct hdpvr_video_info *vidinf;
2649aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
2659aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	if (dev->status == STATUS_STREAMING)
2669aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		return 0;
2679aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	else if (dev->status != STATUS_IDLE)
2689aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		return -EAGAIN;
2699aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
2709aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	vidinf = get_video_info(dev);
2719aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
2729aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	if (vidinf) {
2739ef77adfb9ac170bcaf449530cf129c48547fd55Janne Grunau		v4l2_dbg(MSG_BUFFER, hdpvr_debug, &dev->v4l2_dev,
2749aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			 "video signal: %dx%d@%dhz\n", vidinf->width,
2759aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			 vidinf->height, vidinf->fps);
2769aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		kfree(vidinf);
2779aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
2789aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		/* start streaming 2 request */
2799aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		ret = usb_control_msg(dev->udev,
2809aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau				      usb_sndctrlpipe(dev->udev, 0),
2819aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau				      0xb8, 0x38, 0x1, 0, NULL, 0, 8000);
2829ef77adfb9ac170bcaf449530cf129c48547fd55Janne Grunau		v4l2_dbg(MSG_BUFFER, hdpvr_debug, &dev->v4l2_dev,
2839aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			 "encoder start control request returned %d\n", ret);
2849aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
2859aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		hdpvr_config_call(dev, CTRL_START_STREAMING_VALUE, 0x00);
2869aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
287afa159538af61f1a65d48927f4e949fe514fb4fcJanne Grunau		dev->status = STATUS_STREAMING;
288afa159538af61f1a65d48927f4e949fe514fb4fcJanne Grunau
2899aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		INIT_WORK(&dev->worker, hdpvr_transmit_buffers);
2909aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		queue_work(dev->workqueue, &dev->worker);
2919aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
2929ef77adfb9ac170bcaf449530cf129c48547fd55Janne Grunau		v4l2_dbg(MSG_BUFFER, hdpvr_debug, &dev->v4l2_dev,
2939aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			 "streaming started\n");
2949aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
2959aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		return 0;
2969aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	}
2979aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	msleep(250);
2989ef77adfb9ac170bcaf449530cf129c48547fd55Janne Grunau	v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev,
2999aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		 "no video signal at input %d\n", dev->options.video_input);
3009aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	return -EAGAIN;
3019aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau}
3029aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
3039aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
3049aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau/* function expects dev->io_mutex to be hold by caller */
3059aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunaustatic int hdpvr_stop_streaming(struct hdpvr_device *dev)
3069aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau{
30785d682b9ee1a89a82c2a75182558e392749d81fcMárton Németh	int actual_length;
30885d682b9ee1a89a82c2a75182558e392749d81fcMárton Németh	uint c = 0;
3097d771ff0dc3371923db929d9f88932acec3fc8e8Janne Grunau	u8 *buf;
3107d771ff0dc3371923db929d9f88932acec3fc8e8Janne Grunau
3119aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	if (dev->status == STATUS_IDLE)
3129aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		return 0;
3139aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	else if (dev->status != STATUS_STREAMING)
3149aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		return -EAGAIN;
3159aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
3167d771ff0dc3371923db929d9f88932acec3fc8e8Janne Grunau	buf = kmalloc(dev->bulk_in_size, GFP_KERNEL);
3177d771ff0dc3371923db929d9f88932acec3fc8e8Janne Grunau	if (!buf)
3187d771ff0dc3371923db929d9f88932acec3fc8e8Janne Grunau		v4l2_err(&dev->v4l2_dev, "failed to allocate temporary buffer "
3197d771ff0dc3371923db929d9f88932acec3fc8e8Janne Grunau			 "for emptying the internal device buffer. "
3207d771ff0dc3371923db929d9f88932acec3fc8e8Janne Grunau			 "Next capture start will be slow\n");
3217d771ff0dc3371923db929d9f88932acec3fc8e8Janne Grunau
3229aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	dev->status = STATUS_SHUTTING_DOWN;
3239aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	hdpvr_config_call(dev, CTRL_STOP_STREAMING_VALUE, 0x00);
32448f98f7557d35d360470bf6d9fd7b00d04fba828Janne Grunau	mutex_unlock(&dev->io_mutex);
3259aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
3269aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	wake_up_interruptible(&dev->wait_buffer);
3279aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	msleep(50);
3289aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
3299aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	flush_workqueue(dev->workqueue);
3309aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
33148f98f7557d35d360470bf6d9fd7b00d04fba828Janne Grunau	mutex_lock(&dev->io_mutex);
3329aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	/* kill the still outstanding urbs */
3339aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	hdpvr_cancel_queue(dev);
3349aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
3357d771ff0dc3371923db929d9f88932acec3fc8e8Janne Grunau	/* emptying the device buffer beforeshutting it down */
3367d771ff0dc3371923db929d9f88932acec3fc8e8Janne Grunau	while (buf && ++c < 500 &&
3377d771ff0dc3371923db929d9f88932acec3fc8e8Janne Grunau	       !usb_bulk_msg(dev->udev,
3387d771ff0dc3371923db929d9f88932acec3fc8e8Janne Grunau			     usb_rcvbulkpipe(dev->udev,
3397d771ff0dc3371923db929d9f88932acec3fc8e8Janne Grunau					     dev->bulk_in_endpointAddr),
3407d771ff0dc3371923db929d9f88932acec3fc8e8Janne Grunau			     buf, dev->bulk_in_size, &actual_length,
3417d771ff0dc3371923db929d9f88932acec3fc8e8Janne Grunau			     BULK_URB_TIMEOUT)) {
3427d771ff0dc3371923db929d9f88932acec3fc8e8Janne Grunau		v4l2_dbg(MSG_BUFFER, hdpvr_debug, &dev->v4l2_dev,
3437d771ff0dc3371923db929d9f88932acec3fc8e8Janne Grunau			 "%2d: got %d bytes\n", c, actual_length);
3447d771ff0dc3371923db929d9f88932acec3fc8e8Janne Grunau	}
3457d771ff0dc3371923db929d9f88932acec3fc8e8Janne Grunau	kfree(buf);
3467d771ff0dc3371923db929d9f88932acec3fc8e8Janne Grunau	v4l2_dbg(MSG_BUFFER, hdpvr_debug, &dev->v4l2_dev,
3477d771ff0dc3371923db929d9f88932acec3fc8e8Janne Grunau		 "used %d urbs to empty device buffers\n", c-1);
3487d771ff0dc3371923db929d9f88932acec3fc8e8Janne Grunau	msleep(10);
3497d771ff0dc3371923db929d9f88932acec3fc8e8Janne Grunau
3509aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	dev->status = STATUS_IDLE;
3519aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
3529aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	return 0;
3539aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau}
3549aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
3559aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
3569aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau/*=======================================================================*/
3579aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau/*
3589aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau * video 4 linux 2 file operations
3599aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau */
3609aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
3619aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunaustatic int hdpvr_open(struct file *file)
3629aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau{
3639aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	struct hdpvr_device *dev;
3649aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	struct hdpvr_fh *fh;
3659aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	int retval = -ENOMEM;
3669aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
3679aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	dev = (struct hdpvr_device *)video_get_drvdata(video_devdata(file));
3689aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	if (!dev) {
3694202066c6995200b2755a4501ea90f5d4e163e41Julia Lawall		pr_err("open failing with with ENODEV\n");
3709aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		retval = -ENODEV;
3719aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		goto err;
3729aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	}
3739aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
3749aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	fh = kzalloc(sizeof(struct hdpvr_fh), GFP_KERNEL);
3759aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	if (!fh) {
3769ef77adfb9ac170bcaf449530cf129c48547fd55Janne Grunau		v4l2_err(&dev->v4l2_dev, "Out of memory\n");
3779aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		goto err;
3789aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	}
3799aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	/* lock the device to allow correctly handling errors
3809aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	 * in resumption */
3819aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	mutex_lock(&dev->io_mutex);
3829aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	dev->open_count++;
38300c1e2167e3163d2e193644b7d768f06d2a8c279Jiri Slaby	mutex_unlock(&dev->io_mutex);
3849aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
3859aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	fh->dev = dev;
3869aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
3879aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	/* save our object in the file's private structure */
3889aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	file->private_data = fh;
3899aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
3909aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	retval = 0;
3919aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunauerr:
3929aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	return retval;
3939aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau}
3949aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
3959aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunaustatic int hdpvr_release(struct file *file)
3969aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau{
397abf84383ecadc8ada1963f9976e887c6f0b1bad9Joe Perches	struct hdpvr_fh		*fh  = file->private_data;
3989aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	struct hdpvr_device	*dev = fh->dev;
3999aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
4009aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	if (!dev)
4019aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		return -ENODEV;
4029aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
4039aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	mutex_lock(&dev->io_mutex);
4049aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	if (!(--dev->open_count) && dev->status == STATUS_STREAMING)
4059aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		hdpvr_stop_streaming(dev);
4069aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
4079aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	mutex_unlock(&dev->io_mutex);
4089aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
4099aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	return 0;
4109aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau}
4119aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
4129aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau/*
4139aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau * hdpvr_v4l2_read()
4149aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau * will allocate buffers when called for the first time
4159aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau */
4169aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunaustatic ssize_t hdpvr_read(struct file *file, char __user *buffer, size_t count,
4179aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			  loff_t *pos)
4189aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau{
4199aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	struct hdpvr_fh *fh = file->private_data;
4209aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	struct hdpvr_device *dev = fh->dev;
4219aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	struct hdpvr_buffer *buf = NULL;
4229aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	struct urb *urb;
4239aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	unsigned int ret = 0;
4249aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	int rem, cnt;
4259aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
4269aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	if (*pos)
4279aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		return -ESPIPE;
4289aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
4299aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	if (!dev)
4309aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		return -ENODEV;
4319aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
4329aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	mutex_lock(&dev->io_mutex);
4339aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	if (dev->status == STATUS_IDLE) {
4349aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		if (hdpvr_start_streaming(dev)) {
4359ef77adfb9ac170bcaf449530cf129c48547fd55Janne Grunau			v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev,
4369ef77adfb9ac170bcaf449530cf129c48547fd55Janne Grunau				 "start_streaming failed\n");
4379aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			ret = -EIO;
4389aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			msleep(200);
4399aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			dev->status = STATUS_IDLE;
4409aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			mutex_unlock(&dev->io_mutex);
4419aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			goto err;
4429aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		}
443d211bfcbd0f13f1234aaa6e565013dba051a408cJanne Grunau		print_buffer_status();
4449aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	}
4459aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	mutex_unlock(&dev->io_mutex);
4469aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
4479aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	/* wait for the first buffer */
4489aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	if (!(file->f_flags & O_NONBLOCK)) {
4499aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		if (wait_event_interruptible(dev->wait_data,
4509aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau					     hdpvr_get_next_buffer(dev)))
4519aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			return -ERESTARTSYS;
4529aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	}
4539aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
4549aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	buf = hdpvr_get_next_buffer(dev);
4559aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
4569aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	while (count > 0 && buf) {
4579aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
4589aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		if (buf->status != BUFSTAT_READY &&
4599aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		    dev->status != STATUS_DISCONNECTED) {
4609aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			/* return nonblocking */
4619aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			if (file->f_flags & O_NONBLOCK) {
4629aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau				if (!ret)
4639aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau					ret = -EAGAIN;
4649aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau				goto err;
4659aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			}
4669aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
4679aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			if (wait_event_interruptible(dev->wait_data,
4689aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau					      buf->status == BUFSTAT_READY)) {
4699aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau				ret = -ERESTARTSYS;
4709aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau				goto err;
4719aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			}
4729aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		}
4739aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
4749aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		if (buf->status != BUFSTAT_READY)
4759aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			break;
4769aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
4779aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		/* set remaining bytes to copy */
4789aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		urb = buf->urb;
4799aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		rem = urb->actual_length - buf->pos;
4809aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		cnt = rem > count ? count : rem;
4819aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
4829aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		if (copy_to_user(buffer, urb->transfer_buffer + buf->pos,
4839aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau				 cnt)) {
4849ef77adfb9ac170bcaf449530cf129c48547fd55Janne Grunau			v4l2_err(&dev->v4l2_dev, "read: copy_to_user failed\n");
4859aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			if (!ret)
4869aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau				ret = -EFAULT;
4879aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			goto err;
4889aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		}
4899aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
4909aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		buf->pos += cnt;
4919aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		count -= cnt;
4929aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		buffer += cnt;
4939aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		ret += cnt;
4949aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
4959aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		/* finished, take next buffer */
4969aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		if (buf->pos == urb->actual_length) {
4979aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			mutex_lock(&dev->io_mutex);
4989aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			buf->pos = 0;
4999aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			buf->status = BUFSTAT_AVAILABLE;
5009aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
5019aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			list_move_tail(&buf->buff_list, &dev->free_buff_list);
5029aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
503d211bfcbd0f13f1234aaa6e565013dba051a408cJanne Grunau			print_buffer_status();
5049aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
5059aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			mutex_unlock(&dev->io_mutex);
5069aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
5079aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			wake_up_interruptible(&dev->wait_buffer);
5089aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
5099aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			buf = hdpvr_get_next_buffer(dev);
5109aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		}
5119aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	}
5129aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunauerr:
5139aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	if (!ret && !buf)
5149aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		ret = -EAGAIN;
5159aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	return ret;
5169aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau}
5179aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
5189aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunaustatic unsigned int hdpvr_poll(struct file *filp, poll_table *wait)
5199aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau{
520d2ff3ec81628cbf9470c496b3d0c0780165643f5Janne Grunau	struct hdpvr_buffer *buf = NULL;
521abf84383ecadc8ada1963f9976e887c6f0b1bad9Joe Perches	struct hdpvr_fh *fh = filp->private_data;
5229aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	struct hdpvr_device *dev = fh->dev;
5239aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	unsigned int mask = 0;
5249aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
5259aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	mutex_lock(&dev->io_mutex);
5269aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
527957b4aa9f786cf04585a690a2e4c3dc867ce80e9Laurent Pinchart	if (!video_is_registered(dev->video_dev)) {
52800c1e2167e3163d2e193644b7d768f06d2a8c279Jiri Slaby		mutex_unlock(&dev->io_mutex);
5299aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		return -EIO;
53000c1e2167e3163d2e193644b7d768f06d2a8c279Jiri Slaby	}
5319aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
5329aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	if (dev->status == STATUS_IDLE) {
5339aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		if (hdpvr_start_streaming(dev)) {
5349ef77adfb9ac170bcaf449530cf129c48547fd55Janne Grunau			v4l2_dbg(MSG_BUFFER, hdpvr_debug, &dev->v4l2_dev,
5359ef77adfb9ac170bcaf449530cf129c48547fd55Janne Grunau				 "start_streaming failed\n");
5369aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			dev->status = STATUS_IDLE;
5379aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		}
5389aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
539d211bfcbd0f13f1234aaa6e565013dba051a408cJanne Grunau		print_buffer_status();
5409aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	}
5419aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	mutex_unlock(&dev->io_mutex);
5429aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
543d2ff3ec81628cbf9470c496b3d0c0780165643f5Janne Grunau	buf = hdpvr_get_next_buffer(dev);
544d2ff3ec81628cbf9470c496b3d0c0780165643f5Janne Grunau	/* only wait if no data is available */
545d2ff3ec81628cbf9470c496b3d0c0780165643f5Janne Grunau	if (!buf || buf->status != BUFSTAT_READY) {
546d2ff3ec81628cbf9470c496b3d0c0780165643f5Janne Grunau		poll_wait(filp, &dev->wait_data, wait);
547d2ff3ec81628cbf9470c496b3d0c0780165643f5Janne Grunau		buf = hdpvr_get_next_buffer(dev);
5489aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	}
549d2ff3ec81628cbf9470c496b3d0c0780165643f5Janne Grunau	if (buf && buf->status == BUFSTAT_READY)
550d2ff3ec81628cbf9470c496b3d0c0780165643f5Janne Grunau		mask |= POLLIN | POLLRDNORM;
5519aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
5529aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	return mask;
5539aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau}
5549aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
5559aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
5569aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunaustatic const struct v4l2_file_operations hdpvr_fops = {
5579aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	.owner		= THIS_MODULE,
5589aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	.open		= hdpvr_open,
5599aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	.release	= hdpvr_release,
5609aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	.read		= hdpvr_read,
5619aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	.poll		= hdpvr_poll,
56276717b887cccc77d04357fc0d6ac98f894e3eb3cJanne Grunau	.unlocked_ioctl	= video_ioctl2,
5639aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau};
5649aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
5659aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau/*=======================================================================*/
5669aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau/*
5679aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau * V4L2 ioctl handling
5689aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau */
5699aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
5709aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunaustatic int vidioc_querycap(struct file *file, void  *priv,
5719aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			   struct v4l2_capability *cap)
5729aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau{
5739aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	struct hdpvr_device *dev = video_drvdata(file);
5749aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
5759aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	strcpy(cap->driver, "hdpvr");
576fdd70c3399fc448a87487b287f4f0dcfb2e9c52cLars Hanisch	strcpy(cap->card, "Hauppauge HD PVR");
5779aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	usb_make_path(dev->udev, cap->bus_info, sizeof(cap->bus_info));
5789aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	cap->capabilities =     V4L2_CAP_VIDEO_CAPTURE |
5799aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau				V4L2_CAP_AUDIO         |
5809aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau				V4L2_CAP_READWRITE;
5819aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	return 0;
5829aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau}
5839aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
5849aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunaustatic int vidioc_s_std(struct file *file, void *private_data,
585314527acbbb3f33f72c2ef19d8cfabcada9912a5Hans Verkuil			v4l2_std_id std)
5869aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau{
5879aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	struct hdpvr_fh *fh = file->private_data;
5889aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	struct hdpvr_device *dev = fh->dev;
5899aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	u8 std_type = 1;
5909aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
591314527acbbb3f33f72c2ef19d8cfabcada9912a5Hans Verkuil	if (std & (V4L2_STD_NTSC | V4L2_STD_PAL_60))
5929aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		std_type = 0;
5939aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
5949aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	return hdpvr_config_call(dev, CTRL_VIDEO_STD_TYPE, std_type);
5959aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau}
5969aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
5979aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunaustatic const char *iname[] = {
5989aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	[HDPVR_COMPONENT] = "Component",
5999aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	[HDPVR_SVIDEO]    = "S-Video",
6009aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	[HDPVR_COMPOSITE] = "Composite",
6019aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau};
6029aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
6039aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunaustatic int vidioc_enum_input(struct file *file, void *priv,
6049aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau				struct v4l2_input *i)
6059aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau{
6069aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	struct hdpvr_fh *fh = file->private_data;
6079aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	struct hdpvr_device *dev = fh->dev;
6089aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	unsigned int n;
6099aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
6109aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	n = i->index;
6119aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	if (n >= HDPVR_VIDEO_INPUTS)
6129aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		return -EINVAL;
6139aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
6149aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	i->type = V4L2_INPUT_TYPE_CAMERA;
6159aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
6169aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	strncpy(i->name, iname[n], sizeof(i->name) - 1);
6179aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	i->name[sizeof(i->name) - 1] = '\0';
6189aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
6199aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	i->audioset = 1<<HDPVR_RCA_FRONT | 1<<HDPVR_RCA_BACK | 1<<HDPVR_SPDIF;
6209aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
6219aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	i->std = dev->video_dev->tvnorms;
6229aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
6239aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	return 0;
6249aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau}
6259aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
6269aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunaustatic int vidioc_s_input(struct file *file, void *private_data,
6279aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			  unsigned int index)
6289aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau{
6299aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	struct hdpvr_fh *fh = file->private_data;
6309aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	struct hdpvr_device *dev = fh->dev;
6319aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	int retval;
6329aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
6339aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	if (index >= HDPVR_VIDEO_INPUTS)
6349aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		return -EINVAL;
6359aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
6369aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	if (dev->status != STATUS_IDLE)
6379aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		return -EAGAIN;
6389aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
6399aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	retval = hdpvr_config_call(dev, CTRL_VIDEO_INPUT_VALUE, index+1);
6409aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	if (!retval)
6419aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		dev->options.video_input = index;
6429aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
6439aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	return retval;
6449aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau}
6459aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
6469aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunaustatic int vidioc_g_input(struct file *file, void *private_data,
6479aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			  unsigned int *index)
6489aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau{
6499aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	struct hdpvr_fh *fh = file->private_data;
6509aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	struct hdpvr_device *dev = fh->dev;
6519aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
6529aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	*index = dev->options.video_input;
6539aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	return 0;
6549aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau}
6559aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
6569aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
6579aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunaustatic const char *audio_iname[] = {
6589aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	[HDPVR_RCA_FRONT] = "RCA front",
6599aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	[HDPVR_RCA_BACK]  = "RCA back",
6609aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	[HDPVR_SPDIF]     = "SPDIF",
6619aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau};
6629aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
6639aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunaustatic int vidioc_enumaudio(struct file *file, void *priv,
6649aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau				struct v4l2_audio *audio)
6659aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau{
6669aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	unsigned int n;
6679aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
6689aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	n = audio->index;
6699aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	if (n >= HDPVR_AUDIO_INPUTS)
6709aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		return -EINVAL;
6719aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
6729aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	audio->capability = V4L2_AUDCAP_STEREO;
6739aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
6749aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	strncpy(audio->name, audio_iname[n], sizeof(audio->name) - 1);
6759aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	audio->name[sizeof(audio->name) - 1] = '\0';
6769aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
6779aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	return 0;
6789aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau}
6799aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
6809aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunaustatic int vidioc_s_audio(struct file *file, void *private_data,
6810e8025b9f6011a6bd69d01080d584bc95a89d02eHans Verkuil			  const struct v4l2_audio *audio)
6829aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau{
6839aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	struct hdpvr_fh *fh = file->private_data;
6849aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	struct hdpvr_device *dev = fh->dev;
6859aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	int retval;
6869aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
6879aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	if (audio->index >= HDPVR_AUDIO_INPUTS)
6889aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		return -EINVAL;
6899aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
6909aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	if (dev->status != STATUS_IDLE)
6919aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		return -EAGAIN;
6929aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
6939aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	retval = hdpvr_set_audio(dev, audio->index+1, dev->options.audio_codec);
6949aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	if (!retval)
6959aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		dev->options.audio_input = audio->index;
6969aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
6979aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	return retval;
6989aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau}
6999aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
7009aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunaustatic int vidioc_g_audio(struct file *file, void *private_data,
7019aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			  struct v4l2_audio *audio)
7029aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau{
7039aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	struct hdpvr_fh *fh = file->private_data;
7049aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	struct hdpvr_device *dev = fh->dev;
7059aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
7069aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	audio->index = dev->options.audio_input;
7079aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	audio->capability = V4L2_AUDCAP_STEREO;
7089aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	strncpy(audio->name, audio_iname[audio->index], sizeof(audio->name));
7099aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	audio->name[sizeof(audio->name) - 1] = '\0';
7109aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	return 0;
7119aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau}
7129aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
7139aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunaustatic const s32 supported_v4l2_ctrls[] = {
7149aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	V4L2_CID_BRIGHTNESS,
7159aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	V4L2_CID_CONTRAST,
7169aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	V4L2_CID_SATURATION,
7179aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	V4L2_CID_HUE,
7189aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	V4L2_CID_SHARPNESS,
7199aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	V4L2_CID_MPEG_AUDIO_ENCODING,
7209aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	V4L2_CID_MPEG_VIDEO_ENCODING,
7219aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	V4L2_CID_MPEG_VIDEO_BITRATE_MODE,
7229aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	V4L2_CID_MPEG_VIDEO_BITRATE,
7239aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	V4L2_CID_MPEG_VIDEO_BITRATE_PEAK,
7249aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau};
7259aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
7269aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunaustatic int fill_queryctrl(struct hdpvr_options *opt, struct v4l2_queryctrl *qc,
727fda27874de91d5a8b9a018b3bc74b14578994908Taylor Ralph			  int ac3, int fw_ver)
7289aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau{
7299aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	int err;
7309aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
731fda27874de91d5a8b9a018b3bc74b14578994908Taylor Ralph	if (fw_ver > 0x15) {
732fda27874de91d5a8b9a018b3bc74b14578994908Taylor Ralph		switch (qc->id) {
733fda27874de91d5a8b9a018b3bc74b14578994908Taylor Ralph		case V4L2_CID_BRIGHTNESS:
734fda27874de91d5a8b9a018b3bc74b14578994908Taylor Ralph			return v4l2_ctrl_query_fill(qc, 0x0, 0xff, 1, 0x80);
735fda27874de91d5a8b9a018b3bc74b14578994908Taylor Ralph		case V4L2_CID_CONTRAST:
736fda27874de91d5a8b9a018b3bc74b14578994908Taylor Ralph			return v4l2_ctrl_query_fill(qc, 0x0, 0xff, 1, 0x40);
737fda27874de91d5a8b9a018b3bc74b14578994908Taylor Ralph		case V4L2_CID_SATURATION:
738fda27874de91d5a8b9a018b3bc74b14578994908Taylor Ralph			return v4l2_ctrl_query_fill(qc, 0x0, 0xff, 1, 0x40);
739fda27874de91d5a8b9a018b3bc74b14578994908Taylor Ralph		case V4L2_CID_HUE:
740fda27874de91d5a8b9a018b3bc74b14578994908Taylor Ralph			return v4l2_ctrl_query_fill(qc, 0x0, 0x1e, 1, 0xf);
741fda27874de91d5a8b9a018b3bc74b14578994908Taylor Ralph		case V4L2_CID_SHARPNESS:
742fda27874de91d5a8b9a018b3bc74b14578994908Taylor Ralph			return v4l2_ctrl_query_fill(qc, 0x0, 0xff, 1, 0x80);
743fda27874de91d5a8b9a018b3bc74b14578994908Taylor Ralph		}
744fda27874de91d5a8b9a018b3bc74b14578994908Taylor Ralph	} else {
745fda27874de91d5a8b9a018b3bc74b14578994908Taylor Ralph		switch (qc->id) {
746fda27874de91d5a8b9a018b3bc74b14578994908Taylor Ralph		case V4L2_CID_BRIGHTNESS:
747fda27874de91d5a8b9a018b3bc74b14578994908Taylor Ralph			return v4l2_ctrl_query_fill(qc, 0x0, 0xff, 1, 0x86);
748fda27874de91d5a8b9a018b3bc74b14578994908Taylor Ralph		case V4L2_CID_CONTRAST:
749fda27874de91d5a8b9a018b3bc74b14578994908Taylor Ralph			return v4l2_ctrl_query_fill(qc, 0x0, 0xff, 1, 0x80);
750fda27874de91d5a8b9a018b3bc74b14578994908Taylor Ralph		case V4L2_CID_SATURATION:
751fda27874de91d5a8b9a018b3bc74b14578994908Taylor Ralph			return v4l2_ctrl_query_fill(qc, 0x0, 0xff, 1, 0x80);
752fda27874de91d5a8b9a018b3bc74b14578994908Taylor Ralph		case V4L2_CID_HUE:
753fda27874de91d5a8b9a018b3bc74b14578994908Taylor Ralph			return v4l2_ctrl_query_fill(qc, 0x0, 0xff, 1, 0x80);
754fda27874de91d5a8b9a018b3bc74b14578994908Taylor Ralph		case V4L2_CID_SHARPNESS:
755fda27874de91d5a8b9a018b3bc74b14578994908Taylor Ralph			return v4l2_ctrl_query_fill(qc, 0x0, 0xff, 1, 0x80);
756fda27874de91d5a8b9a018b3bc74b14578994908Taylor Ralph		}
757fda27874de91d5a8b9a018b3bc74b14578994908Taylor Ralph	}
758fda27874de91d5a8b9a018b3bc74b14578994908Taylor Ralph
7599aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	switch (qc->id) {
7609aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	case V4L2_CID_MPEG_AUDIO_ENCODING:
7619aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		return v4l2_ctrl_query_fill(
7629aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			qc, V4L2_MPEG_AUDIO_ENCODING_AAC,
7639aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			ac3 ? V4L2_MPEG_AUDIO_ENCODING_AC3
7649aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			: V4L2_MPEG_AUDIO_ENCODING_AAC,
7659aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			1, V4L2_MPEG_AUDIO_ENCODING_AAC);
7669aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	case V4L2_CID_MPEG_VIDEO_ENCODING:
7679aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		return v4l2_ctrl_query_fill(
7689aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			qc, V4L2_MPEG_VIDEO_ENCODING_MPEG_4_AVC,
7699aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			V4L2_MPEG_VIDEO_ENCODING_MPEG_4_AVC, 1,
7709aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			V4L2_MPEG_VIDEO_ENCODING_MPEG_4_AVC);
7719aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
7729aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau/* 	case V4L2_CID_MPEG_VIDEO_? maybe keyframe interval: */
7739aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau/* 		return v4l2_ctrl_query_fill(qc, 0, 128, 128, 0); */
7749aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
7759aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		return v4l2_ctrl_query_fill(
7769aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			qc, V4L2_MPEG_VIDEO_BITRATE_MODE_VBR,
7779aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			V4L2_MPEG_VIDEO_BITRATE_MODE_CBR, 1,
7789aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			V4L2_MPEG_VIDEO_BITRATE_MODE_CBR);
7799aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
7809aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	case V4L2_CID_MPEG_VIDEO_BITRATE:
7819aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		return v4l2_ctrl_query_fill(qc, 1000000, 13500000, 100000,
7829aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau					    6500000);
7839aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK:
7849aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		err = v4l2_ctrl_query_fill(qc, 1100000, 20200000, 100000,
7859aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau					   9000000);
7869aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		if (!err && opt->bitrate_mode == HDPVR_CONSTANT)
7879aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			qc->flags |= V4L2_CTRL_FLAG_INACTIVE;
7889aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		return err;
7899aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	default:
7909aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		return -EINVAL;
7919aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	}
7929aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau}
7939aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
7949aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunaustatic int vidioc_queryctrl(struct file *file, void *private_data,
7959aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			    struct v4l2_queryctrl *qc)
7969aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau{
7979aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	struct hdpvr_fh *fh = file->private_data;
7989aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	struct hdpvr_device *dev = fh->dev;
7999aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	int i, next;
8009aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	u32 id = qc->id;
8019aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
8029aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	memset(qc, 0, sizeof(*qc));
8039aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
8049aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	next = !!(id &  V4L2_CTRL_FLAG_NEXT_CTRL);
8059aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	qc->id = id & ~V4L2_CTRL_FLAG_NEXT_CTRL;
8069aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
8079aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	for (i = 0; i < ARRAY_SIZE(supported_v4l2_ctrls); i++) {
8089aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		if (next) {
8099aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			if (qc->id < supported_v4l2_ctrls[i])
8109aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau				qc->id = supported_v4l2_ctrls[i];
8119aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			else
8129aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau				continue;
8139aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		}
8149aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
8159aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		if (qc->id == supported_v4l2_ctrls[i])
8169aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			return fill_queryctrl(&dev->options, qc,
817fda27874de91d5a8b9a018b3bc74b14578994908Taylor Ralph					      dev->flags & HDPVR_FLAG_AC3_CAP,
818fda27874de91d5a8b9a018b3bc74b14578994908Taylor Ralph					      dev->fw_ver);
8199aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
8209aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		if (qc->id < supported_v4l2_ctrls[i])
8219aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			break;
8229aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	}
8239aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
8249aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	return -EINVAL;
8259aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau}
8269aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
8279aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunaustatic int vidioc_g_ctrl(struct file *file, void *private_data,
8289aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			 struct v4l2_control *ctrl)
8299aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau{
8309aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	struct hdpvr_fh *fh = file->private_data;
8319aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	struct hdpvr_device *dev = fh->dev;
8329aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
8339aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	switch (ctrl->id) {
8349aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	case V4L2_CID_BRIGHTNESS:
8359aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		ctrl->value = dev->options.brightness;
8369aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		break;
8379aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	case V4L2_CID_CONTRAST:
8389aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		ctrl->value = dev->options.contrast;
8399aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		break;
8409aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	case V4L2_CID_SATURATION:
8419aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		ctrl->value = dev->options.saturation;
8429aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		break;
8439aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	case V4L2_CID_HUE:
8449aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		ctrl->value = dev->options.hue;
8459aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		break;
8469aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	case V4L2_CID_SHARPNESS:
8479aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		ctrl->value = dev->options.sharpness;
8489aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		break;
8499aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	default:
8509aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		return -EINVAL;
8519aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	}
8529aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	return 0;
8539aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau}
8549aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
8559aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunaustatic int vidioc_s_ctrl(struct file *file, void *private_data,
8569aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			 struct v4l2_control *ctrl)
8579aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau{
8589aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	struct hdpvr_fh *fh = file->private_data;
8599aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	struct hdpvr_device *dev = fh->dev;
8609aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	int retval;
8619aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
8629aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	switch (ctrl->id) {
8639aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	case V4L2_CID_BRIGHTNESS:
8649aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		retval = hdpvr_config_call(dev, CTRL_BRIGHTNESS, ctrl->value);
8659aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		if (!retval)
8669aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			dev->options.brightness = ctrl->value;
8679aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		break;
8689aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	case V4L2_CID_CONTRAST:
8699aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		retval = hdpvr_config_call(dev, CTRL_CONTRAST, ctrl->value);
8709aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		if (!retval)
8719aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			dev->options.contrast = ctrl->value;
8729aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		break;
8739aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	case V4L2_CID_SATURATION:
8749aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		retval = hdpvr_config_call(dev, CTRL_SATURATION, ctrl->value);
8759aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		if (!retval)
8769aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			dev->options.saturation = ctrl->value;
8779aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		break;
8789aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	case V4L2_CID_HUE:
8799aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		retval = hdpvr_config_call(dev, CTRL_HUE, ctrl->value);
8809aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		if (!retval)
8819aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			dev->options.hue = ctrl->value;
8829aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		break;
8839aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	case V4L2_CID_SHARPNESS:
8849aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		retval = hdpvr_config_call(dev, CTRL_SHARPNESS, ctrl->value);
8859aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		if (!retval)
8869aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			dev->options.sharpness = ctrl->value;
8879aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		break;
8889aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	default:
8899aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		return -EINVAL;
8909aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	}
8919aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
8929aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	return retval;
8939aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau}
8949aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
8959aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
8969aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunaustatic int hdpvr_get_ctrl(struct hdpvr_options *opt,
8979aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			  struct v4l2_ext_control *ctrl)
8989aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau{
8999aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	switch (ctrl->id) {
9009aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	case V4L2_CID_MPEG_AUDIO_ENCODING:
9019aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		ctrl->value = opt->audio_codec;
9029aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		break;
9039aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	case V4L2_CID_MPEG_VIDEO_ENCODING:
9049aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		ctrl->value = V4L2_MPEG_VIDEO_ENCODING_MPEG_4_AVC;
9059aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		break;
9069aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau/* 	case V4L2_CID_MPEG_VIDEO_B_FRAMES: */
9079aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau/* 		ctrl->value = (opt->gop_mode & 0x2) ? 0 : 128; */
9089aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau/* 		break; */
9099aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
9109aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		ctrl->value = opt->bitrate_mode == HDPVR_CONSTANT
9119aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			? V4L2_MPEG_VIDEO_BITRATE_MODE_CBR
9129aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			: V4L2_MPEG_VIDEO_BITRATE_MODE_VBR;
9139aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		break;
9149aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	case V4L2_CID_MPEG_VIDEO_BITRATE:
9159aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		ctrl->value = opt->bitrate * 100000;
9169aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		break;
9179aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK:
9189aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		ctrl->value = opt->peak_bitrate * 100000;
9199aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		break;
9209aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	case V4L2_CID_MPEG_STREAM_TYPE:
9219aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		ctrl->value = V4L2_MPEG_STREAM_TYPE_MPEG2_TS;
9229aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		break;
9239aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	default:
9249aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		return -EINVAL;
9259aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	}
9269aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	return 0;
9279aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau}
9289aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
9299aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunaustatic int vidioc_g_ext_ctrls(struct file *file, void *priv,
9309aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			      struct v4l2_ext_controls *ctrls)
9319aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau{
9329aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	struct hdpvr_fh *fh = file->private_data;
9339aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	struct hdpvr_device *dev = fh->dev;
9349aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	int i, err = 0;
9359aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
9369aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	if (ctrls->ctrl_class == V4L2_CTRL_CLASS_MPEG) {
9379aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		for (i = 0; i < ctrls->count; i++) {
9389aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			struct v4l2_ext_control *ctrl = ctrls->controls + i;
9399aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
9409aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			err = hdpvr_get_ctrl(&dev->options, ctrl);
9419aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			if (err) {
9429aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau				ctrls->error_idx = i;
9439aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau				break;
9449aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			}
9459aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		}
9469aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		return err;
9479aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
9489aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	}
9499aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
9509aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	return -EINVAL;
9519aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau}
9529aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
9539aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
9549aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunaustatic int hdpvr_try_ctrl(struct v4l2_ext_control *ctrl, int ac3)
9559aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau{
9569aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	int ret = -EINVAL;
9579aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
9589aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	switch (ctrl->id) {
9599aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	case V4L2_CID_MPEG_AUDIO_ENCODING:
9609aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		if (ctrl->value == V4L2_MPEG_AUDIO_ENCODING_AAC ||
9619aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		    (ac3 && ctrl->value == V4L2_MPEG_AUDIO_ENCODING_AC3))
9629aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			ret = 0;
9639aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		break;
9649aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	case V4L2_CID_MPEG_VIDEO_ENCODING:
9659aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		if (ctrl->value == V4L2_MPEG_VIDEO_ENCODING_MPEG_4_AVC)
9669aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			ret = 0;
9679aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		break;
9689aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau/* 	case V4L2_CID_MPEG_VIDEO_B_FRAMES: */
9699aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau/* 		if (ctrl->value == 0 || ctrl->value == 128) */
9709aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau/* 			ret = 0; */
9719aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau/* 		break; */
9729aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
9739aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		if (ctrl->value == V4L2_MPEG_VIDEO_BITRATE_MODE_CBR ||
9749aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		    ctrl->value == V4L2_MPEG_VIDEO_BITRATE_MODE_VBR)
9759aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			ret = 0;
9769aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		break;
9779aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	case V4L2_CID_MPEG_VIDEO_BITRATE:
9789aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	{
9799aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		uint bitrate = ctrl->value / 100000;
9809aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		if (bitrate >= 10 && bitrate <= 135)
9819aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			ret = 0;
9829aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		break;
9839aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	}
9849aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK:
9859aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	{
9869aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		uint peak_bitrate = ctrl->value / 100000;
9879aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		if (peak_bitrate >= 10 && peak_bitrate <= 202)
9889aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			ret = 0;
9899aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		break;
9909aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	}
9919aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	case V4L2_CID_MPEG_STREAM_TYPE:
9929aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		if (ctrl->value == V4L2_MPEG_STREAM_TYPE_MPEG2_TS)
9939aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			ret = 0;
9949aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		break;
9959aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	default:
9969aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		return -EINVAL;
9979aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	}
998e92ba2830b62ba6315d48083bb7f02d3148d77dbHans Verkuil	return ret;
9999aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau}
10009aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
10019aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunaustatic int vidioc_try_ext_ctrls(struct file *file, void *priv,
10029aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau				struct v4l2_ext_controls *ctrls)
10039aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau{
10049aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	struct hdpvr_fh *fh = file->private_data;
10059aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	struct hdpvr_device *dev = fh->dev;
10069aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	int i, err = 0;
10079aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
10089aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	if (ctrls->ctrl_class == V4L2_CTRL_CLASS_MPEG) {
10099aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		for (i = 0; i < ctrls->count; i++) {
10109aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			struct v4l2_ext_control *ctrl = ctrls->controls + i;
10119aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
10129aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			err = hdpvr_try_ctrl(ctrl,
10139aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau					     dev->flags & HDPVR_FLAG_AC3_CAP);
10149aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			if (err) {
10159aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau				ctrls->error_idx = i;
10169aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau				break;
10179aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			}
10189aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		}
10199aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		return err;
10209aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	}
10219aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
10229aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	return -EINVAL;
10239aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau}
10249aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
10259aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
10269aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunaustatic int hdpvr_set_ctrl(struct hdpvr_device *dev,
10279aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			  struct v4l2_ext_control *ctrl)
10289aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau{
10299aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	struct hdpvr_options *opt = &dev->options;
10309aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	int ret = 0;
10319aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
10329aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	switch (ctrl->id) {
10339aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	case V4L2_CID_MPEG_AUDIO_ENCODING:
10349aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		if (dev->flags & HDPVR_FLAG_AC3_CAP) {
10359aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			opt->audio_codec = ctrl->value;
10369aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			ret = hdpvr_set_audio(dev, opt->audio_input,
10379aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau					      opt->audio_codec);
10389aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		}
10399aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		break;
10409aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	case V4L2_CID_MPEG_VIDEO_ENCODING:
10419aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		break;
10429aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau/* 	case V4L2_CID_MPEG_VIDEO_B_FRAMES: */
10439aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau/* 		if (ctrl->value == 0 && !(opt->gop_mode & 0x2)) { */
10449aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau/* 			opt->gop_mode |= 0x2; */
10459aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau/* 			hdpvr_config_call(dev, CTRL_GOP_MODE_VALUE, */
10469aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau/* 					  opt->gop_mode); */
10479aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau/* 		} */
10489aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau/* 		if (ctrl->value == 128 && opt->gop_mode & 0x2) { */
10499aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau/* 			opt->gop_mode &= ~0x2; */
10509aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau/* 			hdpvr_config_call(dev, CTRL_GOP_MODE_VALUE, */
10519aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau/* 					  opt->gop_mode); */
10529aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau/* 		} */
10539aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau/* 		break; */
10549aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
10559aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		if (ctrl->value == V4L2_MPEG_VIDEO_BITRATE_MODE_CBR &&
10569aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		    opt->bitrate_mode != HDPVR_CONSTANT) {
10579aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			opt->bitrate_mode = HDPVR_CONSTANT;
10589aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			hdpvr_config_call(dev, CTRL_BITRATE_MODE_VALUE,
10599aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau					  opt->bitrate_mode);
10609aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		}
10619aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		if (ctrl->value == V4L2_MPEG_VIDEO_BITRATE_MODE_VBR &&
10629aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		    opt->bitrate_mode == HDPVR_CONSTANT) {
10639aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			opt->bitrate_mode = HDPVR_VARIABLE_AVERAGE;
10649aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			hdpvr_config_call(dev, CTRL_BITRATE_MODE_VALUE,
10659aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau					  opt->bitrate_mode);
10669aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		}
10679aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		break;
10689aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	case V4L2_CID_MPEG_VIDEO_BITRATE: {
10699aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		uint bitrate = ctrl->value / 100000;
10709aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
10719aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		opt->bitrate = bitrate;
10729aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		if (bitrate >= opt->peak_bitrate)
10739aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			opt->peak_bitrate = bitrate+1;
10749aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
10759aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		hdpvr_set_bitrate(dev);
10769aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		break;
10779aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	}
10789aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK: {
10799aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		uint peak_bitrate = ctrl->value / 100000;
10809aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
10819aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		if (opt->bitrate_mode == HDPVR_CONSTANT)
10829aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			break;
10839aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
10849aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		if (opt->bitrate < peak_bitrate) {
10859aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			opt->peak_bitrate = peak_bitrate;
10869aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			hdpvr_set_bitrate(dev);
10879aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		} else
10889aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			ret = -EINVAL;
10899aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		break;
10909aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	}
10919aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	case V4L2_CID_MPEG_STREAM_TYPE:
10929aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		break;
10939aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	default:
10949aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		return -EINVAL;
10959aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	}
10969aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	return ret;
10979aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau}
10989aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
10999aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunaustatic int vidioc_s_ext_ctrls(struct file *file, void *priv,
11009aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			      struct v4l2_ext_controls *ctrls)
11019aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau{
11029aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	struct hdpvr_fh *fh = file->private_data;
11039aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	struct hdpvr_device *dev = fh->dev;
11049aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	int i, err = 0;
11059aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
11069aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	if (ctrls->ctrl_class == V4L2_CTRL_CLASS_MPEG) {
11079aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		for (i = 0; i < ctrls->count; i++) {
11089aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			struct v4l2_ext_control *ctrl = ctrls->controls + i;
11099aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
11109aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			err = hdpvr_try_ctrl(ctrl,
11119aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau					     dev->flags & HDPVR_FLAG_AC3_CAP);
11129aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			if (err) {
11139aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau				ctrls->error_idx = i;
11149aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau				break;
11159aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			}
11169aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			err = hdpvr_set_ctrl(dev, ctrl);
11179aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			if (err) {
11189aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau				ctrls->error_idx = i;
11199aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau				break;
11209aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau			}
11219aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		}
11229aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		return err;
11239aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
11249aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	}
11259aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
11269aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	return -EINVAL;
11279aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau}
11289aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
11299aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunaustatic int vidioc_enum_fmt_vid_cap(struct file *file, void *private_data,
11309aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau				    struct v4l2_fmtdesc *f)
11319aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau{
11329aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
11339aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	if (f->index != 0 || f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
11349aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		return -EINVAL;
11359aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
11369aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	f->flags = V4L2_FMT_FLAG_COMPRESSED;
11379aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	strncpy(f->description, "MPEG2-TS with AVC/AAC streams", 32);
11389aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	f->pixelformat = V4L2_PIX_FMT_MPEG;
11399aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
11409aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	return 0;
11419aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau}
11429aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
11439aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunaustatic int vidioc_g_fmt_vid_cap(struct file *file, void *private_data,
11449aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau				struct v4l2_format *f)
11459aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau{
11469aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	struct hdpvr_fh *fh = file->private_data;
11479aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	struct hdpvr_device *dev = fh->dev;
11489aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	struct hdpvr_video_info *vid_info;
11499aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
11509aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	if (!dev)
11519aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		return -ENODEV;
11529aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
11539aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	vid_info = get_video_info(dev);
11549aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	if (!vid_info)
11559aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		return -EFAULT;
11569aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
11579aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
11589aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	f->fmt.pix.pixelformat	= V4L2_PIX_FMT_MPEG;
11599aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	f->fmt.pix.width	= vid_info->width;
11609aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	f->fmt.pix.height	= vid_info->height;
11619aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	f->fmt.pix.sizeimage	= dev->bulk_in_size;
11629aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	f->fmt.pix.colorspace	= 0;
11639aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	f->fmt.pix.bytesperline	= 0;
11649aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	f->fmt.pix.field	= V4L2_FIELD_ANY;
11659aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
11669aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	kfree(vid_info);
11679aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	return 0;
11689aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau}
11699aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
117076717b887cccc77d04357fc0d6ac98f894e3eb3cJanne Grunaustatic int vidioc_encoder_cmd(struct file *filp, void *priv,
117176717b887cccc77d04357fc0d6ac98f894e3eb3cJanne Grunau			       struct v4l2_encoder_cmd *a)
117276717b887cccc77d04357fc0d6ac98f894e3eb3cJanne Grunau{
117376717b887cccc77d04357fc0d6ac98f894e3eb3cJanne Grunau	struct hdpvr_fh *fh = filp->private_data;
117476717b887cccc77d04357fc0d6ac98f894e3eb3cJanne Grunau	struct hdpvr_device *dev = fh->dev;
117576717b887cccc77d04357fc0d6ac98f894e3eb3cJanne Grunau	int res;
117676717b887cccc77d04357fc0d6ac98f894e3eb3cJanne Grunau
117776717b887cccc77d04357fc0d6ac98f894e3eb3cJanne Grunau	mutex_lock(&dev->io_mutex);
117876717b887cccc77d04357fc0d6ac98f894e3eb3cJanne Grunau
117976717b887cccc77d04357fc0d6ac98f894e3eb3cJanne Grunau	memset(&a->raw, 0, sizeof(a->raw));
118076717b887cccc77d04357fc0d6ac98f894e3eb3cJanne Grunau	switch (a->cmd) {
118176717b887cccc77d04357fc0d6ac98f894e3eb3cJanne Grunau	case V4L2_ENC_CMD_START:
118276717b887cccc77d04357fc0d6ac98f894e3eb3cJanne Grunau		a->flags = 0;
118376717b887cccc77d04357fc0d6ac98f894e3eb3cJanne Grunau		res = hdpvr_start_streaming(dev);
118476717b887cccc77d04357fc0d6ac98f894e3eb3cJanne Grunau		break;
118576717b887cccc77d04357fc0d6ac98f894e3eb3cJanne Grunau	case V4L2_ENC_CMD_STOP:
118676717b887cccc77d04357fc0d6ac98f894e3eb3cJanne Grunau		res = hdpvr_stop_streaming(dev);
118776717b887cccc77d04357fc0d6ac98f894e3eb3cJanne Grunau		break;
118876717b887cccc77d04357fc0d6ac98f894e3eb3cJanne Grunau	default:
11899ef77adfb9ac170bcaf449530cf129c48547fd55Janne Grunau		v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev,
119076717b887cccc77d04357fc0d6ac98f894e3eb3cJanne Grunau			 "Unsupported encoder cmd %d\n", a->cmd);
119148f98f7557d35d360470bf6d9fd7b00d04fba828Janne Grunau		res = -EINVAL;
119276717b887cccc77d04357fc0d6ac98f894e3eb3cJanne Grunau	}
119376717b887cccc77d04357fc0d6ac98f894e3eb3cJanne Grunau	mutex_unlock(&dev->io_mutex);
119476717b887cccc77d04357fc0d6ac98f894e3eb3cJanne Grunau	return res;
119576717b887cccc77d04357fc0d6ac98f894e3eb3cJanne Grunau}
119676717b887cccc77d04357fc0d6ac98f894e3eb3cJanne Grunau
119776717b887cccc77d04357fc0d6ac98f894e3eb3cJanne Grunaustatic int vidioc_try_encoder_cmd(struct file *filp, void *priv,
119876717b887cccc77d04357fc0d6ac98f894e3eb3cJanne Grunau					struct v4l2_encoder_cmd *a)
119976717b887cccc77d04357fc0d6ac98f894e3eb3cJanne Grunau{
120076717b887cccc77d04357fc0d6ac98f894e3eb3cJanne Grunau	switch (a->cmd) {
120176717b887cccc77d04357fc0d6ac98f894e3eb3cJanne Grunau	case V4L2_ENC_CMD_START:
120276717b887cccc77d04357fc0d6ac98f894e3eb3cJanne Grunau	case V4L2_ENC_CMD_STOP:
120376717b887cccc77d04357fc0d6ac98f894e3eb3cJanne Grunau		return 0;
120476717b887cccc77d04357fc0d6ac98f894e3eb3cJanne Grunau	default:
120576717b887cccc77d04357fc0d6ac98f894e3eb3cJanne Grunau		return -EINVAL;
120676717b887cccc77d04357fc0d6ac98f894e3eb3cJanne Grunau	}
120776717b887cccc77d04357fc0d6ac98f894e3eb3cJanne Grunau}
12089aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
12099aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunaustatic const struct v4l2_ioctl_ops hdpvr_ioctl_ops = {
12109aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	.vidioc_querycap	= vidioc_querycap,
12119aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	.vidioc_s_std		= vidioc_s_std,
12129aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	.vidioc_enum_input	= vidioc_enum_input,
12139aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	.vidioc_g_input		= vidioc_g_input,
12149aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	.vidioc_s_input		= vidioc_s_input,
12159aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	.vidioc_enumaudio	= vidioc_enumaudio,
12169aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	.vidioc_g_audio		= vidioc_g_audio,
12179aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	.vidioc_s_audio		= vidioc_s_audio,
12189aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	.vidioc_queryctrl	= vidioc_queryctrl,
12199aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	.vidioc_g_ctrl		= vidioc_g_ctrl,
12209aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	.vidioc_s_ctrl		= vidioc_s_ctrl,
12219aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	.vidioc_g_ext_ctrls	= vidioc_g_ext_ctrls,
12229aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	.vidioc_s_ext_ctrls	= vidioc_s_ext_ctrls,
12239aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	.vidioc_try_ext_ctrls	= vidioc_try_ext_ctrls,
12249aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	.vidioc_enum_fmt_vid_cap	= vidioc_enum_fmt_vid_cap,
12259aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	.vidioc_g_fmt_vid_cap		= vidioc_g_fmt_vid_cap,
122676717b887cccc77d04357fc0d6ac98f894e3eb3cJanne Grunau	.vidioc_encoder_cmd	= vidioc_encoder_cmd,
122776717b887cccc77d04357fc0d6ac98f894e3eb3cJanne Grunau	.vidioc_try_encoder_cmd	= vidioc_try_encoder_cmd,
12289aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau};
12299aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
12309aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunaustatic void hdpvr_device_release(struct video_device *vdev)
12319aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau{
12329aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	struct hdpvr_device *dev = video_get_drvdata(vdev);
12339aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
12349aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	hdpvr_delete(dev);
1235f2b305cd6711b7b3ce30db93b50bc5d6312950c8Hans Verkuil	mutex_lock(&dev->io_mutex);
1236f2b305cd6711b7b3ce30db93b50bc5d6312950c8Hans Verkuil	destroy_workqueue(dev->workqueue);
1237f2b305cd6711b7b3ce30db93b50bc5d6312950c8Hans Verkuil	mutex_unlock(&dev->io_mutex);
1238f2b305cd6711b7b3ce30db93b50bc5d6312950c8Hans Verkuil
1239f2b305cd6711b7b3ce30db93b50bc5d6312950c8Hans Verkuil	v4l2_device_unregister(&dev->v4l2_dev);
1240f2b305cd6711b7b3ce30db93b50bc5d6312950c8Hans Verkuil
1241f2b305cd6711b7b3ce30db93b50bc5d6312950c8Hans Verkuil	/* deregister I2C adapter */
124254d80904b4c1f7aa1d569d07ca3e62fba0daf3a2Mauro Carvalho Chehab#if IS_ENABLED(CONFIG_I2C)
1243f2b305cd6711b7b3ce30db93b50bc5d6312950c8Hans Verkuil	mutex_lock(&dev->i2c_mutex);
1244324b04ba5da7918a2409f8113e46843bfbd89e67Jarod Wilson	i2c_del_adapter(&dev->i2c_adapter);
1245f2b305cd6711b7b3ce30db93b50bc5d6312950c8Hans Verkuil	mutex_unlock(&dev->i2c_mutex);
1246f2b305cd6711b7b3ce30db93b50bc5d6312950c8Hans Verkuil#endif /* CONFIG_I2C */
1247f2b305cd6711b7b3ce30db93b50bc5d6312950c8Hans Verkuil
1248f2b305cd6711b7b3ce30db93b50bc5d6312950c8Hans Verkuil	kfree(dev->usbc_buf);
1249f2b305cd6711b7b3ce30db93b50bc5d6312950c8Hans Verkuil	kfree(dev);
12509aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau}
12519aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
12529aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunaustatic const struct video_device hdpvr_video_template = {
12539aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau/* 	.type			= VFL_TYPE_GRABBER, */
12549aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau/* 	.type2			= VID_TYPE_CAPTURE | VID_TYPE_MPEG_ENCODER, */
12559aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	.fops			= &hdpvr_fops,
12569aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	.release		= hdpvr_device_release,
12579aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	.ioctl_ops 		= &hdpvr_ioctl_ops,
12589aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	.tvnorms 		=
12599aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		V4L2_STD_NTSC  | V4L2_STD_SECAM | V4L2_STD_PAL_B |
12609aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		V4L2_STD_PAL_G | V4L2_STD_PAL_H | V4L2_STD_PAL_I |
12619aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		V4L2_STD_PAL_D | V4L2_STD_PAL_M | V4L2_STD_PAL_N |
12629aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		V4L2_STD_PAL_60,
126399362e1ece9f9651af1b849a01d91b9df1e0db2cHans Verkuil	.current_norm 		= V4L2_STD_NTSC | V4L2_STD_PAL_M |
126499362e1ece9f9651af1b849a01d91b9df1e0db2cHans Verkuil		V4L2_STD_PAL_60,
12659aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau};
12669aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
1267a50ab29185a9ec31e5a6999e53add0508653e889Janne Grunauint hdpvr_register_videodev(struct hdpvr_device *dev, struct device *parent,
1268a50ab29185a9ec31e5a6999e53add0508653e889Janne Grunau			    int devnum)
12699aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau{
12709aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	/* setup and register video device */
12719aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	dev->video_dev = video_device_alloc();
12729aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	if (!dev->video_dev) {
12739ef77adfb9ac170bcaf449530cf129c48547fd55Janne Grunau		v4l2_err(&dev->v4l2_dev, "video_device_alloc() failed\n");
12749aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		goto error;
12759aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	}
12769aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
12779aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	*(dev->video_dev) = hdpvr_video_template;
12789aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	strcpy(dev->video_dev->name, "Hauppauge HD PVR");
1279a50ab29185a9ec31e5a6999e53add0508653e889Janne Grunau	dev->video_dev->parent = parent;
12809aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	video_set_drvdata(dev->video_dev, dev);
12819aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
12829aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	if (video_register_device(dev->video_dev, VFL_TYPE_GRABBER, devnum)) {
12839ef77adfb9ac170bcaf449530cf129c48547fd55Janne Grunau		v4l2_err(&dev->v4l2_dev, "video_device registration failed\n");
12849aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau		goto error;
12859aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	}
12869aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau
12879aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	return 0;
12889aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunauerror:
12899aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau	return -ENOMEM;
12909aba42efe85bc7a55e3fed0747ce14abc9ee96e7Janne Grunau}
1291