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