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