diff options
Diffstat (limited to 'drivers/media/video/hdpvr')
-rw-r--r-- | drivers/media/video/hdpvr/Kconfig | 10 | ||||
-rw-r--r-- | drivers/media/video/hdpvr/Makefile | 7 | ||||
-rw-r--r-- | drivers/media/video/hdpvr/hdpvr-control.c | 200 | ||||
-rw-r--r-- | drivers/media/video/hdpvr/hdpvr-core.c | 472 | ||||
-rw-r--r-- | drivers/media/video/hdpvr/hdpvr-i2c.c | 231 | ||||
-rw-r--r-- | drivers/media/video/hdpvr/hdpvr-video.c | 1289 | ||||
-rw-r--r-- | drivers/media/video/hdpvr/hdpvr.h | 317 |
7 files changed, 0 insertions, 2526 deletions
diff --git a/drivers/media/video/hdpvr/Kconfig b/drivers/media/video/hdpvr/Kconfig deleted file mode 100644 index de247f3c7d05..000000000000 --- a/drivers/media/video/hdpvr/Kconfig +++ /dev/null @@ -1,10 +0,0 @@ - -config VIDEO_HDPVR - tristate "Hauppauge HD PVR support" - depends on VIDEO_DEV - ---help--- - This is a video4linux driver for Hauppauge's HD PVR USB device. - - To compile this driver as a module, choose M here: the - module will be called hdpvr - diff --git a/drivers/media/video/hdpvr/Makefile b/drivers/media/video/hdpvr/Makefile deleted file mode 100644 index 52f057f24e39..000000000000 --- a/drivers/media/video/hdpvr/Makefile +++ /dev/null @@ -1,7 +0,0 @@ -hdpvr-objs := hdpvr-control.o hdpvr-core.o hdpvr-video.o hdpvr-i2c.o - -obj-$(CONFIG_VIDEO_HDPVR) += hdpvr.o - -ccflags-y += -Idrivers/media/video - -ccflags-y += $(extra-cflags-y) $(extra-cflags-m) diff --git a/drivers/media/video/hdpvr/hdpvr-control.c b/drivers/media/video/hdpvr/hdpvr-control.c deleted file mode 100644 index ae8f229d1141..000000000000 --- a/drivers/media/video/hdpvr/hdpvr-control.c +++ /dev/null @@ -1,200 +0,0 @@ -/* - * Hauppauge HD PVR USB driver - video 4 linux 2 interface - * - * Copyright (C) 2008 Janne Grunau (j@jannau.net) - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation, version 2. - * - */ - -#include <linux/kernel.h> -#include <linux/errno.h> -#include <linux/init.h> -#include <linux/slab.h> -#include <linux/module.h> -#include <linux/usb.h> -#include <linux/mutex.h> - -#include <linux/videodev2.h> - -#include <media/v4l2-common.h> - -#include "hdpvr.h" - - -int hdpvr_config_call(struct hdpvr_device *dev, uint value, u8 valbuf) -{ - int ret; - char request_type = 0x38, snd_request = 0x01; - - mutex_lock(&dev->usbc_mutex); - dev->usbc_buf[0] = valbuf; - ret = usb_control_msg(dev->udev, - usb_sndctrlpipe(dev->udev, 0), - snd_request, 0x00 | request_type, - value, CTRL_DEFAULT_INDEX, - dev->usbc_buf, 1, 10000); - - mutex_unlock(&dev->usbc_mutex); - v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev, - "config call request for value 0x%x returned %d\n", value, - ret); - - return ret < 0 ? ret : 0; -} - -struct hdpvr_video_info *get_video_info(struct hdpvr_device *dev) -{ - struct hdpvr_video_info *vidinf = NULL; -#ifdef HDPVR_DEBUG - char print_buf[15]; -#endif - int ret; - - vidinf = kzalloc(sizeof(struct hdpvr_video_info), GFP_KERNEL); - if (!vidinf) { - v4l2_err(&dev->v4l2_dev, "out of memory\n"); - goto err; - } - - mutex_lock(&dev->usbc_mutex); - ret = usb_control_msg(dev->udev, - usb_rcvctrlpipe(dev->udev, 0), - 0x81, 0x80 | 0x38, - 0x1400, 0x0003, - dev->usbc_buf, 5, - 1000); - if (ret == 5) { - vidinf->width = dev->usbc_buf[1] << 8 | dev->usbc_buf[0]; - vidinf->height = dev->usbc_buf[3] << 8 | dev->usbc_buf[2]; - vidinf->fps = dev->usbc_buf[4]; - } - -#ifdef HDPVR_DEBUG - if (hdpvr_debug & MSG_INFO) { - hex_dump_to_buffer(dev->usbc_buf, 5, 16, 1, print_buf, - sizeof(print_buf), 0); - v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev, - "get video info returned: %d, %s\n", ret, print_buf); - } -#endif - mutex_unlock(&dev->usbc_mutex); - - if (!vidinf->width || !vidinf->height || !vidinf->fps) { - kfree(vidinf); - vidinf = NULL; - } -err: - return vidinf; -} - -int get_input_lines_info(struct hdpvr_device *dev) -{ -#ifdef HDPVR_DEBUG - char print_buf[9]; -#endif - int ret, lines; - - mutex_lock(&dev->usbc_mutex); - ret = usb_control_msg(dev->udev, - usb_rcvctrlpipe(dev->udev, 0), - 0x81, 0x80 | 0x38, - 0x1800, 0x0003, - dev->usbc_buf, 3, - 1000); - -#ifdef HDPVR_DEBUG - if (hdpvr_debug & MSG_INFO) { - hex_dump_to_buffer(dev->usbc_buf, 3, 16, 1, print_buf, - sizeof(print_buf), 0); - v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev, - "get input lines info returned: %d, %s\n", ret, - print_buf); - } -#else - (void)ret; /* suppress compiler warning */ -#endif - lines = dev->usbc_buf[1] << 8 | dev->usbc_buf[0]; - mutex_unlock(&dev->usbc_mutex); - return lines; -} - - -int hdpvr_set_bitrate(struct hdpvr_device *dev) -{ - int ret; - - mutex_lock(&dev->usbc_mutex); - memset(dev->usbc_buf, 0, 4); - dev->usbc_buf[0] = dev->options.bitrate; - dev->usbc_buf[2] = dev->options.peak_bitrate; - - ret = usb_control_msg(dev->udev, - usb_sndctrlpipe(dev->udev, 0), - 0x01, 0x38, CTRL_BITRATE_VALUE, - CTRL_DEFAULT_INDEX, dev->usbc_buf, 4, 1000); - mutex_unlock(&dev->usbc_mutex); - - return ret; -} - -int hdpvr_set_audio(struct hdpvr_device *dev, u8 input, - enum v4l2_mpeg_audio_encoding codec) -{ - int ret = 0; - - if (dev->flags & HDPVR_FLAG_AC3_CAP) { - mutex_lock(&dev->usbc_mutex); - memset(dev->usbc_buf, 0, 2); - dev->usbc_buf[0] = input; - if (codec == V4L2_MPEG_AUDIO_ENCODING_AAC) - dev->usbc_buf[1] = 0; - else if (codec == V4L2_MPEG_AUDIO_ENCODING_AC3) - dev->usbc_buf[1] = 1; - else { - mutex_unlock(&dev->usbc_mutex); - v4l2_err(&dev->v4l2_dev, "invalid audio codec %d\n", - codec); - ret = -EINVAL; - goto error; - } - - ret = usb_control_msg(dev->udev, - usb_sndctrlpipe(dev->udev, 0), - 0x01, 0x38, CTRL_AUDIO_INPUT_VALUE, - CTRL_DEFAULT_INDEX, dev->usbc_buf, 2, - 1000); - mutex_unlock(&dev->usbc_mutex); - if (ret == 2) - ret = 0; - } else - ret = hdpvr_config_call(dev, CTRL_AUDIO_INPUT_VALUE, input); -error: - return ret; -} - -int hdpvr_set_options(struct hdpvr_device *dev) -{ - hdpvr_config_call(dev, CTRL_VIDEO_STD_TYPE, dev->options.video_std); - - hdpvr_config_call(dev, CTRL_VIDEO_INPUT_VALUE, - dev->options.video_input+1); - - hdpvr_set_audio(dev, dev->options.audio_input+1, - dev->options.audio_codec); - - hdpvr_set_bitrate(dev); - hdpvr_config_call(dev, CTRL_BITRATE_MODE_VALUE, - dev->options.bitrate_mode); - hdpvr_config_call(dev, CTRL_GOP_MODE_VALUE, dev->options.gop_mode); - - hdpvr_config_call(dev, CTRL_BRIGHTNESS, dev->options.brightness); - hdpvr_config_call(dev, CTRL_CONTRAST, dev->options.contrast); - hdpvr_config_call(dev, CTRL_HUE, dev->options.hue); - hdpvr_config_call(dev, CTRL_SATURATION, dev->options.saturation); - hdpvr_config_call(dev, CTRL_SHARPNESS, dev->options.sharpness); - - return 0; -} diff --git a/drivers/media/video/hdpvr/hdpvr-core.c b/drivers/media/video/hdpvr/hdpvr-core.c deleted file mode 100644 index 304f43ef59eb..000000000000 --- a/drivers/media/video/hdpvr/hdpvr-core.c +++ /dev/null @@ -1,472 +0,0 @@ -/* - * Hauppauge HD PVR USB driver - * - * Copyright (C) 2001-2004 Greg Kroah-Hartman (greg@kroah.com) - * Copyright (C) 2008 Janne Grunau (j@jannau.net) - * Copyright (C) 2008 John Poet - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation, version 2. - * - */ - -#include <linux/kernel.h> -#include <linux/errno.h> -#include <linux/init.h> -#include <linux/slab.h> -#include <linux/module.h> -#include <linux/uaccess.h> -#include <linux/atomic.h> -#include <linux/usb.h> -#include <linux/mutex.h> -#include <linux/i2c.h> - -#include <linux/videodev2.h> -#include <media/v4l2-dev.h> -#include <media/v4l2-common.h> - -#include "hdpvr.h" - -static int video_nr[HDPVR_MAX] = {[0 ... (HDPVR_MAX - 1)] = UNSET}; -module_param_array(video_nr, int, NULL, 0); -MODULE_PARM_DESC(video_nr, "video device number (-1=Auto)"); - -/* holds the number of currently registered devices */ -static atomic_t dev_nr = ATOMIC_INIT(-1); - -int hdpvr_debug; -module_param(hdpvr_debug, int, S_IRUGO|S_IWUSR); -MODULE_PARM_DESC(hdpvr_debug, "enable debugging output"); - -static uint default_video_input = HDPVR_VIDEO_INPUTS; -module_param(default_video_input, uint, S_IRUGO|S_IWUSR); -MODULE_PARM_DESC(default_video_input, "default video input: 0=Component / " - "1=S-Video / 2=Composite"); - -static uint default_audio_input = HDPVR_AUDIO_INPUTS; -module_param(default_audio_input, uint, S_IRUGO|S_IWUSR); -MODULE_PARM_DESC(default_audio_input, "default audio input: 0=RCA back / " - "1=RCA front / 2=S/PDIF"); - -static bool boost_audio; -module_param(boost_audio, bool, S_IRUGO|S_IWUSR); -MODULE_PARM_DESC(boost_audio, "boost the audio signal"); - - -/* table of devices that work with this driver */ -static struct usb_device_id hdpvr_table[] = { - { USB_DEVICE(HD_PVR_VENDOR_ID, HD_PVR_PRODUCT_ID) }, - { USB_DEVICE(HD_PVR_VENDOR_ID, HD_PVR_PRODUCT_ID1) }, - { USB_DEVICE(HD_PVR_VENDOR_ID, HD_PVR_PRODUCT_ID2) }, - { USB_DEVICE(HD_PVR_VENDOR_ID, HD_PVR_PRODUCT_ID3) }, - { USB_DEVICE(HD_PVR_VENDOR_ID, HD_PVR_PRODUCT_ID4) }, - { } /* Terminating entry */ -}; -MODULE_DEVICE_TABLE(usb, hdpvr_table); - - -void hdpvr_delete(struct hdpvr_device *dev) -{ - hdpvr_free_buffers(dev); - - if (dev->video_dev) - video_device_release(dev->video_dev); - - usb_put_dev(dev->udev); -} - -static void challenge(u8 *bytes) -{ - u64 *i64P, tmp64; - uint i, idx; - - for (idx = 0; idx < 32; ++idx) { - - if (idx & 0x3) - bytes[(idx >> 3) + 3] = bytes[(idx >> 2) & 0x3]; - - switch (idx & 0x3) { - case 0x3: - bytes[2] += bytes[3] * 4 + bytes[4] + bytes[5]; - bytes[4] += bytes[(idx & 0x1) * 2] * 9 + 9; - break; - case 0x1: - bytes[0] *= 8; - bytes[0] += 7*idx + 4; - bytes[6] += bytes[3] * 3; - break; - case 0x0: - bytes[3 - (idx >> 3)] = bytes[idx >> 2]; - bytes[5] += bytes[6] * 3; - for (i = 0; i < 3; i++) - bytes[3] *= bytes[3] + 1; - break; - case 0x2: - for (i = 0; i < 3; i++) - bytes[1] *= bytes[6] + 1; - for (i = 0; i < 3; i++) { - i64P = (u64 *)bytes; - tmp64 = le64_to_cpup(i64P); - tmp64 <<= bytes[7] & 0x0f; - *i64P += cpu_to_le64(tmp64); - } - break; - } - } -} - -/* try to init the device like the windows driver */ -static int device_authorization(struct hdpvr_device *dev) -{ - - int ret, retval = -ENOMEM; - char request_type = 0x38, rcv_request = 0x81; - char *response; -#ifdef HDPVR_DEBUG - size_t buf_size = 46; - char *print_buf = kzalloc(5*buf_size+1, GFP_KERNEL); - if (!print_buf) { - v4l2_err(&dev->v4l2_dev, "Out of memory\n"); - return retval; - } -#endif - - mutex_lock(&dev->usbc_mutex); - ret = usb_control_msg(dev->udev, - usb_rcvctrlpipe(dev->udev, 0), - rcv_request, 0x80 | request_type, - 0x0400, 0x0003, - dev->usbc_buf, 46, - 10000); - if (ret != 46) { - v4l2_err(&dev->v4l2_dev, - "unexpected answer of status request, len %d\n", ret); - goto unlock; - } -#ifdef HDPVR_DEBUG - else { - hex_dump_to_buffer(dev->usbc_buf, 46, 16, 1, print_buf, - 5*buf_size+1, 0); - v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev, - "Status request returned, len %d: %s\n", - ret, print_buf); - } -#endif - - dev->fw_ver = dev->usbc_buf[1]; - - v4l2_info(&dev->v4l2_dev, "firmware version 0x%x dated %s\n", - dev->fw_ver, &dev->usbc_buf[2]); - - if (dev->fw_ver > 0x15) { - dev->options.brightness = 0x80; - dev->options.contrast = 0x40; - dev->options.hue = 0xf; - dev->options.saturation = 0x40; - dev->options.sharpness = 0x80; - } - - switch (dev->fw_ver) { - case HDPVR_FIRMWARE_VERSION: - dev->flags &= ~HDPVR_FLAG_AC3_CAP; - break; - case HDPVR_FIRMWARE_VERSION_AC3: - case HDPVR_FIRMWARE_VERSION_0X12: - case HDPVR_FIRMWARE_VERSION_0X15: - dev->flags |= HDPVR_FLAG_AC3_CAP; - break; - default: - v4l2_info(&dev->v4l2_dev, "untested firmware, the driver might" - " not work.\n"); - if (dev->fw_ver >= HDPVR_FIRMWARE_VERSION_AC3) - dev->flags |= HDPVR_FLAG_AC3_CAP; - else - dev->flags &= ~HDPVR_FLAG_AC3_CAP; - } - - response = dev->usbc_buf+38; -#ifdef HDPVR_DEBUG - hex_dump_to_buffer(response, 8, 16, 1, print_buf, 5*buf_size+1, 0); - v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev, "challenge: %s\n", - print_buf); -#endif - challenge(response); -#ifdef HDPVR_DEBUG - hex_dump_to_buffer(response, 8, 16, 1, print_buf, 5*buf_size+1, 0); - v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev, " response: %s\n", - print_buf); -#endif - - msleep(100); - ret = usb_control_msg(dev->udev, - usb_sndctrlpipe(dev->udev, 0), - 0xd1, 0x00 | request_type, - 0x0000, 0x0000, - response, 8, - 10000); - v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev, - "magic request returned %d\n", ret); - - retval = ret != 8; -unlock: - mutex_unlock(&dev->usbc_mutex); - return retval; -} - -static int hdpvr_device_init(struct hdpvr_device *dev) -{ - int ret; - u8 *buf; - struct hdpvr_video_info *vidinf; - - if (device_authorization(dev)) - return -EACCES; - - /* default options for init */ - hdpvr_set_options(dev); - - /* set filter options */ - mutex_lock(&dev->usbc_mutex); - buf = dev->usbc_buf; - buf[0] = 0x03; buf[1] = 0x03; buf[2] = 0x00; buf[3] = 0x00; - ret = usb_control_msg(dev->udev, - usb_sndctrlpipe(dev->udev, 0), - 0x01, 0x38, - CTRL_LOW_PASS_FILTER_VALUE, CTRL_DEFAULT_INDEX, - buf, 4, - 1000); - v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev, - "control request returned %d\n", ret); - mutex_unlock(&dev->usbc_mutex); - - vidinf = get_video_info(dev); - if (!vidinf) - v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev, - "no valid video signal or device init failed\n"); - else - kfree(vidinf); - - /* enable fan and bling leds */ - mutex_lock(&dev->usbc_mutex); - buf[0] = 0x1; - ret = usb_control_msg(dev->udev, - usb_sndctrlpipe(dev->udev, 0), - 0xd4, 0x38, 0, 0, buf, 1, - 1000); - v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev, - "control request returned %d\n", ret); - - /* boost analog audio */ - buf[0] = boost_audio; - ret = usb_control_msg(dev->udev, - usb_sndctrlpipe(dev->udev, 0), - 0xd5, 0x38, 0, 0, buf, 1, - 1000); - v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev, - "control request returned %d\n", ret); - mutex_unlock(&dev->usbc_mutex); - - dev->status = STATUS_IDLE; - return 0; -} - -static const struct hdpvr_options hdpvr_default_options = { - .video_std = HDPVR_60HZ, - .video_input = HDPVR_COMPONENT, - .audio_input = HDPVR_RCA_BACK, - .bitrate = 65, /* 6 mbps */ - .peak_bitrate = 90, /* 9 mbps */ - .bitrate_mode = HDPVR_CONSTANT, - .gop_mode = HDPVR_SIMPLE_IDR_GOP, - .audio_codec = V4L2_MPEG_AUDIO_ENCODING_AAC, - /* original picture controls for firmware version <= 0x15 */ - /* updated in device_authorization() for newer firmware */ - .brightness = 0x86, - .contrast = 0x80, - .hue = 0x80, - .saturation = 0x80, - .sharpness = 0x80, -}; - -static int hdpvr_probe(struct usb_interface *interface, - const struct usb_device_id *id) -{ - struct hdpvr_device *dev; - struct usb_host_interface *iface_desc; - struct usb_endpoint_descriptor *endpoint; - struct i2c_client *client; - size_t buffer_size; - int i; - int retval = -ENOMEM; - - /* allocate memory for our device state and initialize it */ - dev = kzalloc(sizeof(*dev), GFP_KERNEL); - if (!dev) { - dev_err(&interface->dev, "Out of memory\n"); - goto error; - } - - dev->workqueue = 0; - - /* register v4l2_device early so it can be used for printks */ - if (v4l2_device_register(&interface->dev, &dev->v4l2_dev)) { - dev_err(&interface->dev, "v4l2_device_register failed\n"); - goto error; - } - - mutex_init(&dev->io_mutex); - mutex_init(&dev->i2c_mutex); - mutex_init(&dev->usbc_mutex); - dev->usbc_buf = kmalloc(64, GFP_KERNEL); - if (!dev->usbc_buf) { - v4l2_err(&dev->v4l2_dev, "Out of memory\n"); - goto error; - } - - init_waitqueue_head(&dev->wait_buffer); - init_waitqueue_head(&dev->wait_data); - - dev->workqueue = create_singlethread_workqueue("hdpvr_buffer"); - if (!dev->workqueue) - goto error; - - /* init video transfer queues */ - INIT_LIST_HEAD(&dev->free_buff_list); - INIT_LIST_HEAD(&dev->rec_buff_list); - - dev->options = hdpvr_default_options; - - if (default_video_input < HDPVR_VIDEO_INPUTS) - dev->options.video_input = default_video_input; - - if (default_audio_input < HDPVR_AUDIO_INPUTS) { - dev->options.audio_input = default_audio_input; - if (default_audio_input == HDPVR_SPDIF) - dev->options.audio_codec = - V4L2_MPEG_AUDIO_ENCODING_AC3; - } - - dev->udev = usb_get_dev(interface_to_usbdev(interface)); - - /* set up the endpoint information */ - /* use only the first bulk-in and bulk-out endpoints */ - iface_desc = interface->cur_altsetting; - for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) { - endpoint = &iface_desc->endpoint[i].desc; - - if (!dev->bulk_in_endpointAddr && - usb_endpoint_is_bulk_in(endpoint)) { - /* USB interface description is buggy, reported max - * packet size is 512 bytes, windows driver uses 8192 */ - buffer_size = 8192; - dev->bulk_in_size = buffer_size; - dev->bulk_in_endpointAddr = endpoint->bEndpointAddress; - } - - } - if (!dev->bulk_in_endpointAddr) { - v4l2_err(&dev->v4l2_dev, "Could not find bulk-in endpoint\n"); - goto error; - } - - /* init the device */ - if (hdpvr_device_init(dev)) { - v4l2_err(&dev->v4l2_dev, "device init failed\n"); - goto error; - } - - mutex_lock(&dev->io_mutex); - if (hdpvr_alloc_buffers(dev, NUM_BUFFERS)) { - mutex_unlock(&dev->io_mutex); - v4l2_err(&dev->v4l2_dev, - "allocating transfer buffers failed\n"); - goto error; - } - mutex_unlock(&dev->io_mutex); - - if (hdpvr_register_videodev(dev, &interface->dev, - video_nr[atomic_inc_return(&dev_nr)])) { - v4l2_err(&dev->v4l2_dev, "registering videodev failed\n"); - goto error; - } - -#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) - retval = hdpvr_register_i2c_adapter(dev); - if (retval < 0) { - v4l2_err(&dev->v4l2_dev, "i2c adapter register failed\n"); - goto error; - } - - client = hdpvr_register_ir_rx_i2c(dev); - if (!client) { - v4l2_err(&dev->v4l2_dev, "i2c IR RX device register failed\n"); - goto reg_fail; - } - - client = hdpvr_register_ir_tx_i2c(dev); - if (!client) { - v4l2_err(&dev->v4l2_dev, "i2c IR TX device register failed\n"); - goto reg_fail; - } -#endif - - /* let the user know what node this device is now attached to */ - v4l2_info(&dev->v4l2_dev, "device now attached to %s\n", - video_device_node_name(dev->video_dev)); - return 0; - -reg_fail: -#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) - i2c_del_adapter(&dev->i2c_adapter); -#endif -error: - if (dev) { - /* Destroy single thread */ - if (dev->workqueue) - destroy_workqueue(dev->workqueue); - /* this frees allocated memory */ - hdpvr_delete(dev); - } - return retval; -} - -static void hdpvr_disconnect(struct usb_interface *interface) -{ - struct hdpvr_device *dev = to_hdpvr_dev(usb_get_intfdata(interface)); - - v4l2_info(&dev->v4l2_dev, "device %s disconnected\n", - video_device_node_name(dev->video_dev)); - /* prevent more I/O from starting and stop any ongoing */ - mutex_lock(&dev->io_mutex); - dev->status = STATUS_DISCONNECTED; - wake_up_interruptible(&dev->wait_data); - wake_up_interruptible(&dev->wait_buffer); - mutex_unlock(&dev->io_mutex); - v4l2_device_disconnect(&dev->v4l2_dev); - msleep(100); - flush_workqueue(dev->workqueue); - mutex_lock(&dev->io_mutex); - hdpvr_cancel_queue(dev); - mutex_unlock(&dev->io_mutex); -#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) - i2c_del_adapter(&dev->i2c_adapter); -#endif - video_unregister_device(dev->video_dev); - atomic_dec(&dev_nr); -} - - -static struct usb_driver hdpvr_usb_driver = { - .name = "hdpvr", - .probe = hdpvr_probe, - .disconnect = hdpvr_disconnect, - .id_table = hdpvr_table, -}; - -module_usb_driver(hdpvr_usb_driver); - -MODULE_LICENSE("GPL"); -MODULE_VERSION("0.2.1"); -MODULE_AUTHOR("Janne Grunau"); -MODULE_DESCRIPTION("Hauppauge HD PVR driver"); diff --git a/drivers/media/video/hdpvr/hdpvr-i2c.c b/drivers/media/video/hdpvr/hdpvr-i2c.c deleted file mode 100644 index 82e819fa91c0..000000000000 --- a/drivers/media/video/hdpvr/hdpvr-i2c.c +++ /dev/null @@ -1,231 +0,0 @@ - -/* - * Hauppauge HD PVR USB driver - * - * Copyright (C) 2008 Janne Grunau (j@jannau.net) - * - * IR device registration code is - * Copyright (C) 2010 Andy Walls <awalls@md.metrocast.net> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation, version 2. - * - */ - -#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) - -#include <linux/i2c.h> -#include <linux/slab.h> -#include <linux/export.h> - -#include "hdpvr.h" - -#define CTRL_READ_REQUEST 0xb8 -#define CTRL_WRITE_REQUEST 0x38 - -#define REQTYPE_I2C_READ 0xb1 -#define REQTYPE_I2C_WRITE 0xb0 -#define REQTYPE_I2C_WRITE_STATT 0xd0 - -#define Z8F0811_IR_TX_I2C_ADDR 0x70 -#define Z8F0811_IR_RX_I2C_ADDR 0x71 - - -struct i2c_client *hdpvr_register_ir_tx_i2c(struct hdpvr_device *dev) -{ - struct IR_i2c_init_data *init_data = &dev->ir_i2c_init_data; - struct i2c_board_info hdpvr_ir_tx_i2c_board_info = { - I2C_BOARD_INFO("ir_tx_z8f0811_hdpvr", Z8F0811_IR_TX_I2C_ADDR), - }; - - init_data->name = "HD-PVR"; - hdpvr_ir_tx_i2c_board_info.platform_data = init_data; - - return i2c_new_device(&dev->i2c_adapter, &hdpvr_ir_tx_i2c_board_info); -} - -struct i2c_client *hdpvr_register_ir_rx_i2c(struct hdpvr_device *dev) -{ - struct IR_i2c_init_data *init_data = &dev->ir_i2c_init_data; - struct i2c_board_info hdpvr_ir_rx_i2c_board_info = { - I2C_BOARD_INFO("ir_rx_z8f0811_hdpvr", Z8F0811_IR_RX_I2C_ADDR), - }; - - /* Our default information for ir-kbd-i2c.c to use */ - init_data->ir_codes = RC_MAP_HAUPPAUGE; - init_data->internal_get_key_func = IR_KBD_GET_KEY_HAUP_XVR; - init_data->type = RC_TYPE_RC5; - init_data->name = "HD-PVR"; - init_data->polling_interval = 405; /* ms, duplicated from Windows */ - hdpvr_ir_rx_i2c_board_info.platform_data = init_data; - - return i2c_new_device(&dev->i2c_adapter, &hdpvr_ir_rx_i2c_board_info); -} - -static int hdpvr_i2c_read(struct hdpvr_device *dev, int bus, - unsigned char addr, char *wdata, int wlen, - char *data, int len) -{ - int ret; - - if ((len > sizeof(dev->i2c_buf)) || (wlen > sizeof(dev->i2c_buf))) - return -EINVAL; - - if (wlen) { - memcpy(&dev->i2c_buf, wdata, wlen); - ret = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0), - REQTYPE_I2C_WRITE, CTRL_WRITE_REQUEST, - (bus << 8) | addr, 0, &dev->i2c_buf, - wlen, 1000); - if (ret < 0) - return ret; - } - - ret = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0), - REQTYPE_I2C_READ, CTRL_READ_REQUEST, - (bus << 8) | addr, 0, &dev->i2c_buf, len, 1000); - - if (ret == len) { - memcpy(data, &dev->i2c_buf, len); - ret = 0; - } else if (ret >= 0) - ret = -EIO; - - return ret; -} - -static int hdpvr_i2c_write(struct hdpvr_device *dev, int bus, - unsigned char addr, char *data, int len) -{ - int ret; - - if (len > sizeof(dev->i2c_buf)) - return -EINVAL; - - memcpy(&dev->i2c_buf, data, len); - ret = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0), - REQTYPE_I2C_WRITE, CTRL_WRITE_REQUEST, - (bus << 8) | addr, 0, &dev->i2c_buf, len, 1000); - - if (ret < 0) - return ret; - - ret = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0), - REQTYPE_I2C_WRITE_STATT, CTRL_READ_REQUEST, - 0, 0, &dev->i2c_buf, 2, 1000); - - if ((ret == 2) && (dev->i2c_buf[1] == (len - 1))) - ret = 0; - else if (ret >= 0) - ret = -EIO; - - return ret; -} - -static int hdpvr_transfer(struct i2c_adapter *i2c_adapter, struct i2c_msg *msgs, - int num) -{ - struct hdpvr_device *dev = i2c_get_adapdata(i2c_adapter); - int retval = 0, addr; - - if (num <= 0) - return 0; - - mutex_lock(&dev->i2c_mutex); - - addr = msgs[0].addr << 1; - - if (num == 1) { - if (msgs[0].flags & I2C_M_RD) - retval = hdpvr_i2c_read(dev, 1, addr, NULL, 0, - msgs[0].buf, msgs[0].len); - else - retval = hdpvr_i2c_write(dev, 1, addr, msgs[0].buf, - msgs[0].len); - } else if (num == 2) { - if (msgs[0].addr != msgs[1].addr) { - v4l2_warn(&dev->v4l2_dev, "refusing 2-phase i2c xfer " - "with conflicting target addresses\n"); - retval = -EINVAL; - goto out; - } - - if ((msgs[0].flags & I2C_M_RD) || !(msgs[1].flags & I2C_M_RD)) { - v4l2_warn(&dev->v4l2_dev, "refusing complex xfer with " - "r0=%d, r1=%d\n", msgs[0].flags & I2C_M_RD, - msgs[1].flags & I2C_M_RD); - retval = -EINVAL; - goto out; - } - - /* - * Write followed by atomic read is the only complex xfer that - * we actually support here. - */ - retval = hdpvr_i2c_read(dev, 1, addr, msgs[0].buf, msgs[0].len, - msgs[1].buf, msgs[1].len); - } else { - v4l2_warn(&dev->v4l2_dev, "refusing %d-phase i2c xfer\n", num); - } - -out: - mutex_unlock(&dev->i2c_mutex); - - return retval ? retval : num; -} - -static u32 hdpvr_functionality(struct i2c_adapter *adapter) -{ - return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; -} - -static struct i2c_algorithm hdpvr_algo = { - .master_xfer = hdpvr_transfer, - .functionality = hdpvr_functionality, -}; - -static struct i2c_adapter hdpvr_i2c_adapter_template = { - .name = "Hauppage HD PVR I2C", - .owner = THIS_MODULE, - .algo = &hdpvr_algo, -}; - -static int hdpvr_activate_ir(struct hdpvr_device *dev) -{ - char buffer[2]; - - mutex_lock(&dev->i2c_mutex); - - hdpvr_i2c_read(dev, 0, 0x54, NULL, 0, buffer, 1); - - buffer[0] = 0; - buffer[1] = 0x8; - hdpvr_i2c_write(dev, 1, 0x54, buffer, 2); - - buffer[1] = 0x18; - hdpvr_i2c_write(dev, 1, 0x54, buffer, 2); - - mutex_unlock(&dev->i2c_mutex); - - return 0; -} - -int hdpvr_register_i2c_adapter(struct hdpvr_device *dev) -{ - int retval = -ENOMEM; - - hdpvr_activate_ir(dev); - - memcpy(&dev->i2c_adapter, &hdpvr_i2c_adapter_template, - sizeof(struct i2c_adapter)); - dev->i2c_adapter.dev.parent = &dev->udev->dev; - - i2c_set_adapdata(&dev->i2c_adapter, dev); - - retval = i2c_add_adapter(&dev->i2c_adapter); - - return retval; -} - -#endif diff --git a/drivers/media/video/hdpvr/hdpvr-video.c b/drivers/media/video/hdpvr/hdpvr-video.c deleted file mode 100644 index 0e9e156bb2aa..000000000000 --- a/drivers/media/video/hdpvr/hdpvr-video.c +++ /dev/null @@ -1,1289 +0,0 @@ -/* - * Hauppauge HD PVR USB driver - video 4 linux 2 interface - * - * Copyright (C) 2008 Janne Grunau (j@jannau.net) - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation, version 2. - * - */ - -#include <linux/kernel.h> -#include <linux/errno.h> -#include <linux/init.h> -#include <linux/slab.h> -#include <linux/module.h> -#include <linux/uaccess.h> -#include <linux/usb.h> -#include <linux/mutex.h> -#include <linux/workqueue.h> - -#include <linux/videodev2.h> -#include <media/v4l2-dev.h> -#include <media/v4l2-common.h> -#include <media/v4l2-ioctl.h> -#include "hdpvr.h" - -#define BULK_URB_TIMEOUT 90 /* 0.09 seconds */ - -#define print_buffer_status() { \ - v4l2_dbg(MSG_BUFFER, hdpvr_debug, &dev->v4l2_dev, \ - "%s:%d buffer stat: %d free, %d proc\n", \ - __func__, __LINE__, \ - list_size(&dev->free_buff_list), \ - list_size(&dev->rec_buff_list)); } - -struct hdpvr_fh { - struct hdpvr_device *dev; -}; - -static uint list_size(struct list_head *list) -{ - struct list_head *tmp; - uint count = 0; - - list_for_each(tmp, list) { - count++; - } - - return count; -} - -/*=========================================================================*/ -/* urb callback */ -static void hdpvr_read_bulk_callback(struct urb *urb) -{ - struct hdpvr_buffer *buf = (struct hdpvr_buffer *)urb->context; - struct hdpvr_device *dev = buf->dev; - - /* marking buffer as received and wake waiting */ - buf->status = BUFSTAT_READY; - wake_up_interruptible(&dev->wait_data); -} - -/*=========================================================================*/ -/* bufffer bits */ - -/* function expects dev->io_mutex to be hold by caller */ -int hdpvr_cancel_queue(struct hdpvr_device *dev) -{ - struct hdpvr_buffer *buf; - - list_for_each_entry(buf, &dev->rec_buff_list, buff_list) { - usb_kill_urb(buf->urb); - buf->status = BUFSTAT_AVAILABLE; - } - - list_splice_init(&dev->rec_buff_list, dev->free_buff_list.prev); - - return 0; -} - -static int hdpvr_free_queue(struct list_head *q) -{ - struct list_head *tmp; - struct list_head *p; - struct hdpvr_buffer *buf; - struct urb *urb; - - for (p = q->next; p != q;) { - buf = list_entry(p, struct hdpvr_buffer, buff_list); - - urb = buf->urb; - usb_free_coherent(urb->dev, urb->transfer_buffer_length, - urb->transfer_buffer, urb->transfer_dma); - usb_free_urb(urb); - tmp = p->next; - list_del(p); - kfree(buf); - p = tmp; - } - - return 0; -} - -/* function expects dev->io_mutex to be hold by caller */ -int hdpvr_free_buffers(struct hdpvr_device *dev) -{ - hdpvr_cancel_queue(dev); - - hdpvr_free_queue(&dev->free_buff_list); - hdpvr_free_queue(&dev->rec_buff_list); - - return 0; -} - -/* function expects dev->io_mutex to be hold by caller */ -int hdpvr_alloc_buffers(struct hdpvr_device *dev, uint count) -{ - uint i; - int retval = -ENOMEM; - u8 *mem; - struct hdpvr_buffer *buf; - struct urb *urb; - - v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev, - "allocating %u buffers\n", count); - - for (i = 0; i < count; i++) { - - buf = kzalloc(sizeof(struct hdpvr_buffer), GFP_KERNEL); - if (!buf) { - v4l2_err(&dev->v4l2_dev, "cannot allocate buffer\n"); - goto exit; - } - buf->dev = dev; - - urb = usb_alloc_urb(0, GFP_KERNEL); - if (!urb) { - v4l2_err(&dev->v4l2_dev, "cannot allocate urb\n"); - goto exit_urb; - } - buf->urb = urb; - - mem = usb_alloc_coherent(dev->udev, dev->bulk_in_size, GFP_KERNEL, - &urb->transfer_dma); - if (!mem) { - v4l2_err(&dev->v4l2_dev, - "cannot allocate usb transfer buffer\n"); - goto exit_urb_buffer; - } - - usb_fill_bulk_urb(buf->urb, dev->udev, - usb_rcvbulkpipe(dev->udev, - dev->bulk_in_endpointAddr), - mem, dev->bulk_in_size, - hdpvr_read_bulk_callback, buf); - - buf->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; - buf->status = BUFSTAT_AVAILABLE; - list_add_tail(&buf->buff_list, &dev->free_buff_list); - } - return 0; -exit_urb_buffer: - usb_free_urb(urb); -exit_urb: - kfree(buf); -exit: - hdpvr_free_buffers(dev); - return retval; -} - -static int hdpvr_submit_buffers(struct hdpvr_device *dev) -{ - struct hdpvr_buffer *buf; - struct urb *urb; - int ret = 0, err_count = 0; - - mutex_lock(&dev->io_mutex); - - while (dev->status == STATUS_STREAMING && - !list_empty(&dev->free_buff_list)) { - - buf = list_entry(dev->free_buff_list.next, struct hdpvr_buffer, - buff_list); - if (buf->status != BUFSTAT_AVAILABLE) { - v4l2_err(&dev->v4l2_dev, - "buffer not marked as available\n"); - ret = -EFAULT; - goto err; - } - - urb = buf->urb; - urb->status = 0; - urb->actual_length = 0; - ret = usb_submit_urb(urb, GFP_KERNEL); - if (ret) { - v4l2_err(&dev->v4l2_dev, - "usb_submit_urb in %s returned %d\n", - __func__, ret); - if (++err_count > 2) - break; - continue; - } - buf->status = BUFSTAT_INPROGRESS; - list_move_tail(&buf->buff_list, &dev->rec_buff_list); - } -err: - print_buffer_status(); - mutex_unlock(&dev->io_mutex); - return ret; -} - -static struct hdpvr_buffer *hdpvr_get_next_buffer(struct hdpvr_device *dev) -{ - struct hdpvr_buffer *buf; - - mutex_lock(&dev->io_mutex); - - if (list_empty(&dev->rec_buff_list)) { - mutex_unlock(&dev->io_mutex); - return NULL; - } - - buf = list_entry(dev->rec_buff_list.next, struct hdpvr_buffer, - buff_list); - mutex_unlock(&dev->io_mutex); - - return buf; -} - -static void hdpvr_transmit_buffers(struct work_struct *work) -{ - struct hdpvr_device *dev = container_of(work, struct hdpvr_device, - worker); - - while (dev->status == STATUS_STREAMING) { - - if (hdpvr_submit_buffers(dev)) { - v4l2_err(&dev->v4l2_dev, "couldn't submit buffers\n"); - goto error; - } - if (wait_event_interruptible(dev->wait_buffer, - !list_empty(&dev->free_buff_list) || - dev->status != STATUS_STREAMING)) - goto error; - } - - v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev, - "transmit worker exited\n"); - return; -error: - v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev, - "transmit buffers errored\n"); - dev->status = STATUS_ERROR; -} - -/* function expects dev->io_mutex to be hold by caller */ -static int hdpvr_start_streaming(struct hdpvr_device *dev) -{ - int ret; - struct hdpvr_video_info *vidinf; - - if (dev->status == STATUS_STREAMING) - return 0; - else if (dev->status != STATUS_IDLE) - return -EAGAIN; - - vidinf = get_video_info(dev); - - if (vidinf) { - v4l2_dbg(MSG_BUFFER, hdpvr_debug, &dev->v4l2_dev, - "video signal: %dx%d@%dhz\n", vidinf->width, - vidinf->height, vidinf->fps); - kfree(vidinf); - - /* start streaming 2 request */ - ret = usb_control_msg(dev->udev, - usb_sndctrlpipe(dev->udev, 0), - 0xb8, 0x38, 0x1, 0, NULL, 0, 8000); - v4l2_dbg(MSG_BUFFER, hdpvr_debug, &dev->v4l2_dev, - "encoder start control request returned %d\n", ret); - - hdpvr_config_call(dev, CTRL_START_STREAMING_VALUE, 0x00); - - dev->status = STATUS_STREAMING; - - INIT_WORK(&dev->worker, hdpvr_transmit_buffers); - queue_work(dev->workqueue, &dev->worker); - - v4l2_dbg(MSG_BUFFER, hdpvr_debug, &dev->v4l2_dev, - "streaming started\n"); - - return 0; - } - msleep(250); - v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev, - "no video signal at input %d\n", dev->options.video_input); - return -EAGAIN; -} - - -/* function expects dev->io_mutex to be hold by caller */ -static int hdpvr_stop_streaming(struct hdpvr_device *dev) -{ - int actual_length; - uint c = 0; - u8 *buf; - - if (dev->status == STATUS_IDLE) - return 0; - else if (dev->status != STATUS_STREAMING) - return -EAGAIN; - - buf = kmalloc(dev->bulk_in_size, GFP_KERNEL); - if (!buf) - v4l2_err(&dev->v4l2_dev, "failed to allocate temporary buffer " - "for emptying the internal device buffer. " - "Next capture start will be slow\n"); - - dev->status = STATUS_SHUTTING_DOWN; - hdpvr_config_call(dev, CTRL_STOP_STREAMING_VALUE, 0x00); - mutex_unlock(&dev->io_mutex); - - wake_up_interruptible(&dev->wait_buffer); - msleep(50); - - flush_workqueue(dev->workqueue); - - mutex_lock(&dev->io_mutex); - /* kill the still outstanding urbs */ - hdpvr_cancel_queue(dev); - - /* emptying the device buffer beforeshutting it down */ - while (buf && ++c < 500 && - !usb_bulk_msg(dev->udev, - usb_rcvbulkpipe(dev->udev, - dev->bulk_in_endpointAddr), - buf, dev->bulk_in_size, &actual_length, - BULK_URB_TIMEOUT)) { - v4l2_dbg(MSG_BUFFER, hdpvr_debug, &dev->v4l2_dev, - "%2d: got %d bytes\n", c, actual_length); - } - kfree(buf); - v4l2_dbg(MSG_BUFFER, hdpvr_debug, &dev->v4l2_dev, - "used %d urbs to empty device buffers\n", c-1); - msleep(10); - - dev->status = STATUS_IDLE; - - return 0; -} - - -/*=======================================================================*/ -/* - * video 4 linux 2 file operations - */ - -static int hdpvr_open(struct file *file) -{ - struct hdpvr_device *dev; - struct hdpvr_fh *fh; - int retval = -ENOMEM; - - dev = (struct hdpvr_device *)video_get_drvdata(video_devdata(file)); - if (!dev) { - pr_err("open failing with with ENODEV\n"); - retval = -ENODEV; - goto err; - } - - fh = kzalloc(sizeof(struct hdpvr_fh), GFP_KERNEL); - if (!fh) { - v4l2_err(&dev->v4l2_dev, "Out of memory\n"); - goto err; - } - /* lock the device to allow correctly handling errors - * in resumption */ - mutex_lock(&dev->io_mutex); - dev->open_count++; - mutex_unlock(&dev->io_mutex); - - fh->dev = dev; - - /* save our object in the file's private structure */ - file->private_data = fh; - - retval = 0; -err: - return retval; -} - -static int hdpvr_release(struct file *file) -{ - struct hdpvr_fh *fh = file->private_data; - struct hdpvr_device *dev = fh->dev; - - if (!dev) - return -ENODEV; - - mutex_lock(&dev->io_mutex); - if (!(--dev->open_count) && dev->status == STATUS_STREAMING) - hdpvr_stop_streaming(dev); - - mutex_unlock(&dev->io_mutex); - - return 0; -} - -/* - * hdpvr_v4l2_read() - * will allocate buffers when called for the first time - */ -static ssize_t hdpvr_read(struct file *file, char __user *buffer, size_t count, - loff_t *pos) -{ - struct hdpvr_fh *fh = file->private_data; - struct hdpvr_device *dev = fh->dev; - struct hdpvr_buffer *buf = NULL; - struct urb *urb; - unsigned int ret = 0; - int rem, cnt; - - if (*pos) - return -ESPIPE; - - if (!dev) - return -ENODEV; - - mutex_lock(&dev->io_mutex); - if (dev->status == STATUS_IDLE) { - if (hdpvr_start_streaming(dev)) { - v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev, - "start_streaming failed\n"); - ret = -EIO; - msleep(200); - dev->status = STATUS_IDLE; - mutex_unlock(&dev->io_mutex); - goto err; - } - print_buffer_status(); - } - mutex_unlock(&dev->io_mutex); - - /* wait for the first buffer */ - if (!(file->f_flags & O_NONBLOCK)) { - if (wait_event_interruptible(dev->wait_data, - hdpvr_get_next_buffer(dev))) - return -ERESTARTSYS; - } - - buf = hdpvr_get_next_buffer(dev); - - while (count > 0 && buf) { - - if (buf->status != BUFSTAT_READY && - dev->status != STATUS_DISCONNECTED) { - /* return nonblocking */ - if (file->f_flags & O_NONBLOCK) { - if (!ret) - ret = -EAGAIN; - goto err; - } - - if (wait_event_interruptible(dev->wait_data, - buf->status == BUFSTAT_READY)) { - ret = -ERESTARTSYS; - goto err; - } - } - - if (buf->status != BUFSTAT_READY) - break; - - /* set remaining bytes to copy */ - urb = buf->urb; - rem = urb->actual_length - buf->pos; - cnt = rem > count ? count : rem; - - if (copy_to_user(buffer, urb->transfer_buffer + buf->pos, - cnt)) { - v4l2_err(&dev->v4l2_dev, "read: copy_to_user failed\n"); - if (!ret) - ret = -EFAULT; - goto err; - } - - buf->pos += cnt; - count -= cnt; - buffer += cnt; - ret += cnt; - - /* finished, take next buffer */ - if (buf->pos == urb->actual_length) { - mutex_lock(&dev->io_mutex); - buf->pos = 0; - buf->status = BUFSTAT_AVAILABLE; - - list_move_tail(&buf->buff_list, &dev->free_buff_list); - - print_buffer_status(); - - mutex_unlock(&dev->io_mutex); - - wake_up_interruptible(&dev->wait_buffer); - - buf = hdpvr_get_next_buffer(dev); - } - } -err: - if (!ret && !buf) - ret = -EAGAIN; - return ret; -} - -static unsigned int hdpvr_poll(struct file *filp, poll_table *wait) -{ - struct hdpvr_buffer *buf = NULL; - struct hdpvr_fh *fh = filp->private_data; - struct hdpvr_device *dev = fh->dev; - unsigned int mask = 0; - - mutex_lock(&dev->io_mutex); - - if (!video_is_registered(dev->video_dev)) { - mutex_unlock(&dev->io_mutex); - return -EIO; - } - - if (dev->status == STATUS_IDLE) { - if (hdpvr_start_streaming(dev)) { - v4l2_dbg(MSG_BUFFER, hdpvr_debug, &dev->v4l2_dev, - "start_streaming failed\n"); - dev->status = STATUS_IDLE; - } - - print_buffer_status(); - } - mutex_unlock(&dev->io_mutex); - - buf = hdpvr_get_next_buffer(dev); - /* only wait if no data is available */ - if (!buf || buf->status != BUFSTAT_READY) { - poll_wait(filp, &dev->wait_data, wait); - buf = hdpvr_get_next_buffer(dev); - } - if (buf && buf->status == BUFSTAT_READY) - mask |= POLLIN | POLLRDNORM; - - return mask; -} - - -static const struct v4l2_file_operations hdpvr_fops = { - .owner = THIS_MODULE, - .open = hdpvr_open, - .release = hdpvr_release, - .read = hdpvr_read, - .poll = hdpvr_poll, - .unlocked_ioctl = video_ioctl2, -}; - -/*=======================================================================*/ -/* - * V4L2 ioctl handling - */ - -static int vidioc_querycap(struct file *file, void *priv, - struct v4l2_capability *cap) -{ - struct hdpvr_device *dev = video_drvdata(file); - - strcpy(cap->driver, "hdpvr"); - strcpy(cap->card, "Hauppauge HD PVR"); - usb_make_path(dev->udev, cap->bus_info, sizeof(cap->bus_info)); - cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | - V4L2_CAP_AUDIO | - V4L2_CAP_READWRITE; - return 0; -} - -static int vidioc_s_std(struct file *file, void *private_data, - v4l2_std_id *std) -{ - struct hdpvr_fh *fh = file->private_data; - struct hdpvr_device *dev = fh->dev; - u8 std_type = 1; - - if (*std & (V4L2_STD_NTSC | V4L2_STD_PAL_60)) - std_type = 0; - - return hdpvr_config_call(dev, CTRL_VIDEO_STD_TYPE, std_type); -} - -static const char *iname[] = { - [HDPVR_COMPONENT] = "Component", - [HDPVR_SVIDEO] = "S-Video", - [HDPVR_COMPOSITE] = "Composite", -}; - -static int vidioc_enum_input(struct file *file, void *priv, - struct v4l2_input *i) -{ - struct hdpvr_fh *fh = file->private_data; - struct hdpvr_device *dev = fh->dev; - unsigned int n; - - n = i->index; - if (n >= HDPVR_VIDEO_INPUTS) - return -EINVAL; - - i->type = V4L2_INPUT_TYPE_CAMERA; - - strncpy(i->name, iname[n], sizeof(i->name) - 1); - i->name[sizeof(i->name) - 1] = '\0'; - - i->audioset = 1<<HDPVR_RCA_FRONT | 1<<HDPVR_RCA_BACK | 1<<HDPVR_SPDIF; - - i->std = dev->video_dev->tvnorms; - - return 0; -} - -static int vidioc_s_input(struct file *file, void *private_data, - unsigned int index) -{ - struct hdpvr_fh *fh = file->private_data; - struct hdpvr_device *dev = fh->dev; - int retval; - - if (index >= HDPVR_VIDEO_INPUTS) - return -EINVAL; - - if (dev->status != STATUS_IDLE) - return -EAGAIN; - - retval = hdpvr_config_call(dev, CTRL_VIDEO_INPUT_VALUE, index+1); - if (!retval) - dev->options.video_input = index; - - return retval; -} - -static int vidioc_g_input(struct file *file, void *private_data, - unsigned int *index) -{ - struct hdpvr_fh *fh = file->private_data; - struct hdpvr_device *dev = fh->dev; - - *index = dev->options.video_input; - return 0; -} - - -static const char *audio_iname[] = { - [HDPVR_RCA_FRONT] = "RCA front", - [HDPVR_RCA_BACK] = "RCA back", - [HDPVR_SPDIF] = "SPDIF", -}; - -static int vidioc_enumaudio(struct file *file, void *priv, - struct v4l2_audio *audio) -{ - unsigned int n; - - n = audio->index; - if (n >= HDPVR_AUDIO_INPUTS) - return -EINVAL; - - audio->capability = V4L2_AUDCAP_STEREO; - - strncpy(audio->name, audio_iname[n], sizeof(audio->name) - 1); - audio->name[sizeof(audio->name) - 1] = '\0'; - - return 0; -} - -static int vidioc_s_audio(struct file *file, void *private_data, - struct v4l2_audio *audio) -{ - struct hdpvr_fh *fh = file->private_data; - struct hdpvr_device *dev = fh->dev; - int retval; - - if (audio->index >= HDPVR_AUDIO_INPUTS) - return -EINVAL; - - if (dev->status != STATUS_IDLE) - return -EAGAIN; - - retval = hdpvr_set_audio(dev, audio->index+1, dev->options.audio_codec); - if (!retval) - dev->options.audio_input = audio->index; - - return retval; -} - -static int vidioc_g_audio(struct file *file, void *private_data, - struct v4l2_audio *audio) -{ - struct hdpvr_fh *fh = file->private_data; - struct hdpvr_device *dev = fh->dev; - - audio->index = dev->options.audio_input; - audio->capability = V4L2_AUDCAP_STEREO; - strncpy(audio->name, audio_iname[audio->index], sizeof(audio->name)); - audio->name[sizeof(audio->name) - 1] = '\0'; - return 0; -} - -static const s32 supported_v4l2_ctrls[] = { - V4L2_CID_BRIGHTNESS, - V4L2_CID_CONTRAST, - V4L2_CID_SATURATION, - V4L2_CID_HUE, - V4L2_CID_SHARPNESS, - V4L2_CID_MPEG_AUDIO_ENCODING, - V4L2_CID_MPEG_VIDEO_ENCODING, - V4L2_CID_MPEG_VIDEO_BITRATE_MODE, - V4L2_CID_MPEG_VIDEO_BITRATE, - V4L2_CID_MPEG_VIDEO_BITRATE_PEAK, -}; - -static int fill_queryctrl(struct hdpvr_options *opt, struct v4l2_queryctrl *qc, - int ac3, int fw_ver) -{ - int err; - - if (fw_ver > 0x15) { - switch (qc->id) { - case V4L2_CID_BRIGHTNESS: - return v4l2_ctrl_query_fill(qc, 0x0, 0xff, 1, 0x80); - case V4L2_CID_CONTRAST: - return v4l2_ctrl_query_fill(qc, 0x0, 0xff, 1, 0x40); - case V4L2_CID_SATURATION: - return v4l2_ctrl_query_fill(qc, 0x0, 0xff, 1, 0x40); - case V4L2_CID_HUE: - return v4l2_ctrl_query_fill(qc, 0x0, 0x1e, 1, 0xf); - case V4L2_CID_SHARPNESS: - return v4l2_ctrl_query_fill(qc, 0x0, 0xff, 1, 0x80); - } - } else { - switch (qc->id) { - case V4L2_CID_BRIGHTNESS: - return v4l2_ctrl_query_fill(qc, 0x0, 0xff, 1, 0x86); - case V4L2_CID_CONTRAST: - return v4l2_ctrl_query_fill(qc, 0x0, 0xff, 1, 0x80); - case V4L2_CID_SATURATION: - return v4l2_ctrl_query_fill(qc, 0x0, 0xff, 1, 0x80); - case V4L2_CID_HUE: - return v4l2_ctrl_query_fill(qc, 0x0, 0xff, 1, 0x80); - case V4L2_CID_SHARPNESS: - return v4l2_ctrl_query_fill(qc, 0x0, 0xff, 1, 0x80); - } - } - - switch (qc->id) { - case V4L2_CID_MPEG_AUDIO_ENCODING: - return v4l2_ctrl_query_fill( - qc, V4L2_MPEG_AUDIO_ENCODING_AAC, - ac3 ? V4L2_MPEG_AUDIO_ENCODING_AC3 - : V4L2_MPEG_AUDIO_ENCODING_AAC, - 1, V4L2_MPEG_AUDIO_ENCODING_AAC); - case V4L2_CID_MPEG_VIDEO_ENCODING: - return v4l2_ctrl_query_fill( - qc, V4L2_MPEG_VIDEO_ENCODING_MPEG_4_AVC, - V4L2_MPEG_VIDEO_ENCODING_MPEG_4_AVC, 1, - V4L2_MPEG_VIDEO_ENCODING_MPEG_4_AVC); - -/* case V4L2_CID_MPEG_VIDEO_? maybe keyframe interval: */ -/* return v4l2_ctrl_query_fill(qc, 0, 128, 128, 0); */ - case V4L2_CID_MPEG_VIDEO_BITRATE_MODE: - return v4l2_ctrl_query_fill( - qc, V4L2_MPEG_VIDEO_BITRATE_MODE_VBR, - V4L2_MPEG_VIDEO_BITRATE_MODE_CBR, 1, - V4L2_MPEG_VIDEO_BITRATE_MODE_CBR); - - case V4L2_CID_MPEG_VIDEO_BITRATE: - return v4l2_ctrl_query_fill(qc, 1000000, 13500000, 100000, - 6500000); - case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK: - err = v4l2_ctrl_query_fill(qc, 1100000, 20200000, 100000, - 9000000); - if (!err && opt->bitrate_mode == HDPVR_CONSTANT) - qc->flags |= V4L2_CTRL_FLAG_INACTIVE; - return err; - default: - return -EINVAL; - } -} - -static int vidioc_queryctrl(struct file *file, void *private_data, - struct v4l2_queryctrl *qc) -{ - struct hdpvr_fh *fh = file->private_data; - struct hdpvr_device *dev = fh->dev; - int i, next; - u32 id = qc->id; - - memset(qc, 0, sizeof(*qc)); - - next = !!(id & V4L2_CTRL_FLAG_NEXT_CTRL); - qc->id = id & ~V4L2_CTRL_FLAG_NEXT_CTRL; - - for (i = 0; i < ARRAY_SIZE(supported_v4l2_ctrls); i++) { - if (next) { - if (qc->id < supported_v4l2_ctrls[i]) - qc->id = supported_v4l2_ctrls[i]; - else - continue; - } - - if (qc->id == supported_v4l2_ctrls[i]) - return fill_queryctrl(&dev->options, qc, - dev->flags & HDPVR_FLAG_AC3_CAP, - dev->fw_ver); - - if (qc->id < supported_v4l2_ctrls[i]) - break; - } - - return -EINVAL; -} - -static int vidioc_g_ctrl(struct file *file, void *private_data, - struct v4l2_control *ctrl) -{ - struct hdpvr_fh *fh = file->private_data; - struct hdpvr_device *dev = fh->dev; - - switch (ctrl->id) { - case V4L2_CID_BRIGHTNESS: - ctrl->value = dev->options.brightness; - break; - case V4L2_CID_CONTRAST: - ctrl->value = dev->options.contrast; - break; - case V4L2_CID_SATURATION: - ctrl->value = dev->options.saturation; - break; - case V4L2_CID_HUE: - ctrl->value = dev->options.hue; - break; - case V4L2_CID_SHARPNESS: - ctrl->value = dev->options.sharpness; - break; - default: - return -EINVAL; - } - return 0; -} - -static int vidioc_s_ctrl(struct file *file, void *private_data, - struct v4l2_control *ctrl) -{ - struct hdpvr_fh *fh = file->private_data; - struct hdpvr_device *dev = fh->dev; - int retval; - - switch (ctrl->id) { - case V4L2_CID_BRIGHTNESS: - retval = hdpvr_config_call(dev, CTRL_BRIGHTNESS, ctrl->value); - if (!retval) - dev->options.brightness = ctrl->value; - break; - case V4L2_CID_CONTRAST: - retval = hdpvr_config_call(dev, CTRL_CONTRAST, ctrl->value); - if (!retval) - dev->options.contrast = ctrl->value; - break; - case V4L2_CID_SATURATION: - retval = hdpvr_config_call(dev, CTRL_SATURATION, ctrl->value); - if (!retval) - dev->options.saturation = ctrl->value; - break; - case V4L2_CID_HUE: - retval = hdpvr_config_call(dev, CTRL_HUE, ctrl->value); - if (!retval) - dev->options.hue = ctrl->value; - break; - case V4L2_CID_SHARPNESS: - retval = hdpvr_config_call(dev, CTRL_SHARPNESS, ctrl->value); - if (!retval) - dev->options.sharpness = ctrl->value; - break; - default: - return -EINVAL; - } - - return retval; -} - - -static int hdpvr_get_ctrl(struct hdpvr_options *opt, - struct v4l2_ext_control *ctrl) -{ - switch (ctrl->id) { - case V4L2_CID_MPEG_AUDIO_ENCODING: - ctrl->value = opt->audio_codec; - break; - case V4L2_CID_MPEG_VIDEO_ENCODING: - ctrl->value = V4L2_MPEG_VIDEO_ENCODING_MPEG_4_AVC; - break; -/* case V4L2_CID_MPEG_VIDEO_B_FRAMES: */ -/* ctrl->value = (opt->gop_mode & 0x2) ? 0 : 128; */ -/* break; */ - case V4L2_CID_MPEG_VIDEO_BITRATE_MODE: - ctrl->value = opt->bitrate_mode == HDPVR_CONSTANT - ? V4L2_MPEG_VIDEO_BITRATE_MODE_CBR - : V4L2_MPEG_VIDEO_BITRATE_MODE_VBR; - break; - case V4L2_CID_MPEG_VIDEO_BITRATE: - ctrl->value = opt->bitrate * 100000; - break; - case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK: - ctrl->value = opt->peak_bitrate * 100000; - break; - case V4L2_CID_MPEG_STREAM_TYPE: - ctrl->value = V4L2_MPEG_STREAM_TYPE_MPEG2_TS; - break; - default: - return -EINVAL; - } - return 0; -} - -static int vidioc_g_ext_ctrls(struct file *file, void *priv, - struct v4l2_ext_controls *ctrls) -{ - struct hdpvr_fh *fh = file->private_data; - struct hdpvr_device *dev = fh->dev; - int i, err = 0; - - if (ctrls->ctrl_class == V4L2_CTRL_CLASS_MPEG) { - for (i = 0; i < ctrls->count; i++) { - struct v4l2_ext_control *ctrl = ctrls->controls + i; - - err = hdpvr_get_ctrl(&dev->options, ctrl); - if (err) { - ctrls->error_idx = i; - break; - } - } - return err; - - } - - return -EINVAL; -} - - -static int hdpvr_try_ctrl(struct v4l2_ext_control *ctrl, int ac3) -{ - int ret = -EINVAL; - - switch (ctrl->id) { - case V4L2_CID_MPEG_AUDIO_ENCODING: - if (ctrl->value == V4L2_MPEG_AUDIO_ENCODING_AAC || - (ac3 && ctrl->value == V4L2_MPEG_AUDIO_ENCODING_AC3)) - ret = 0; - break; - case V4L2_CID_MPEG_VIDEO_ENCODING: - if (ctrl->value == V4L2_MPEG_VIDEO_ENCODING_MPEG_4_AVC) - ret = 0; - break; -/* case V4L2_CID_MPEG_VIDEO_B_FRAMES: */ -/* if (ctrl->value == 0 || ctrl->value == 128) */ -/* ret = 0; */ -/* break; */ - case V4L2_CID_MPEG_VIDEO_BITRATE_MODE: - if (ctrl->value == V4L2_MPEG_VIDEO_BITRATE_MODE_CBR || - ctrl->value == V4L2_MPEG_VIDEO_BITRATE_MODE_VBR) - ret = 0; - break; - case V4L2_CID_MPEG_VIDEO_BITRATE: - { - uint bitrate = ctrl->value / 100000; - if (bitrate >= 10 && bitrate <= 135) - ret = 0; - break; - } - case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK: - { - uint peak_bitrate = ctrl->value / 100000; - if (peak_bitrate >= 10 && peak_bitrate <= 202) - ret = 0; - break; - } - case V4L2_CID_MPEG_STREAM_TYPE: - if (ctrl->value == V4L2_MPEG_STREAM_TYPE_MPEG2_TS) - ret = 0; - break; - default: - return -EINVAL; - } - return ret; -} - -static int vidioc_try_ext_ctrls(struct file *file, void *priv, - struct v4l2_ext_controls *ctrls) -{ - struct hdpvr_fh *fh = file->private_data; - struct hdpvr_device *dev = fh->dev; - int i, err = 0; - - if (ctrls->ctrl_class == V4L2_CTRL_CLASS_MPEG) { - for (i = 0; i < ctrls->count; i++) { - struct v4l2_ext_control *ctrl = ctrls->controls + i; - - err = hdpvr_try_ctrl(ctrl, - dev->flags & HDPVR_FLAG_AC3_CAP); - if (err) { - ctrls->error_idx = i; - break; - } - } - return err; - } - - return -EINVAL; -} - - -static int hdpvr_set_ctrl(struct hdpvr_device *dev, - struct v4l2_ext_control *ctrl) -{ - struct hdpvr_options *opt = &dev->options; - int ret = 0; - - switch (ctrl->id) { - case V4L2_CID_MPEG_AUDIO_ENCODING: - if (dev->flags & HDPVR_FLAG_AC3_CAP) { - opt->audio_codec = ctrl->value; - ret = hdpvr_set_audio(dev, opt->audio_input, - opt->audio_codec); - } - break; - case V4L2_CID_MPEG_VIDEO_ENCODING: - break; -/* case V4L2_CID_MPEG_VIDEO_B_FRAMES: */ -/* if (ctrl->value == 0 && !(opt->gop_mode & 0x2)) { */ -/* opt->gop_mode |= 0x2; */ -/* hdpvr_config_call(dev, CTRL_GOP_MODE_VALUE, */ -/* opt->gop_mode); */ -/* } */ -/* if (ctrl->value == 128 && opt->gop_mode & 0x2) { */ -/* opt->gop_mode &= ~0x2; */ -/* hdpvr_config_call(dev, CTRL_GOP_MODE_VALUE, */ -/* opt->gop_mode); */ -/* } */ -/* break; */ - case V4L2_CID_MPEG_VIDEO_BITRATE_MODE: - if (ctrl->value == V4L2_MPEG_VIDEO_BITRATE_MODE_CBR && - opt->bitrate_mode != HDPVR_CONSTANT) { - opt->bitrate_mode = HDPVR_CONSTANT; - hdpvr_config_call(dev, CTRL_BITRATE_MODE_VALUE, - opt->bitrate_mode); - } - if (ctrl->value == V4L2_MPEG_VIDEO_BITRATE_MODE_VBR && - opt->bitrate_mode == HDPVR_CONSTANT) { - opt->bitrate_mode = HDPVR_VARIABLE_AVERAGE; - hdpvr_config_call(dev, CTRL_BITRATE_MODE_VALUE, - opt->bitrate_mode); - } - break; - case V4L2_CID_MPEG_VIDEO_BITRATE: { - uint bitrate = ctrl->value / 100000; - - opt->bitrate = bitrate; - if (bitrate >= opt->peak_bitrate) - opt->peak_bitrate = bitrate+1; - - hdpvr_set_bitrate(dev); - break; - } - case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK: { - uint peak_bitrate = ctrl->value / 100000; - - if (opt->bitrate_mode == HDPVR_CONSTANT) - break; - - if (opt->bitrate < peak_bitrate) { - opt->peak_bitrate = peak_bitrate; - hdpvr_set_bitrate(dev); - } else - ret = -EINVAL; - break; - } - case V4L2_CID_MPEG_STREAM_TYPE: - break; - default: - return -EINVAL; - } - return ret; -} - -static int vidioc_s_ext_ctrls(struct file *file, void *priv, - struct v4l2_ext_controls *ctrls) -{ - struct hdpvr_fh *fh = file->private_data; - struct hdpvr_device *dev = fh->dev; - int i, err = 0; - - if (ctrls->ctrl_class == V4L2_CTRL_CLASS_MPEG) { - for (i = 0; i < ctrls->count; i++) { - struct v4l2_ext_control *ctrl = ctrls->controls + i; - - err = hdpvr_try_ctrl(ctrl, - dev->flags & HDPVR_FLAG_AC3_CAP); - if (err) { - ctrls->error_idx = i; - break; - } - err = hdpvr_set_ctrl(dev, ctrl); - if (err) { - ctrls->error_idx = i; - break; - } - } - return err; - - } - - return -EINVAL; -} - -static int vidioc_enum_fmt_vid_cap(struct file *file, void *private_data, - struct v4l2_fmtdesc *f) -{ - - if (f->index != 0 || f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) - return -EINVAL; - - f->flags = V4L2_FMT_FLAG_COMPRESSED; - strncpy(f->description, "MPEG2-TS with AVC/AAC streams", 32); - f->pixelformat = V4L2_PIX_FMT_MPEG; - - return 0; -} - -static int vidioc_g_fmt_vid_cap(struct file *file, void *private_data, - struct v4l2_format *f) -{ - struct hdpvr_fh *fh = file->private_data; - struct hdpvr_device *dev = fh->dev; - struct hdpvr_video_info *vid_info; - - if (!dev) - return -ENODEV; - - vid_info = get_video_info(dev); - if (!vid_info) - return -EFAULT; - - f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG; - f->fmt.pix.width = vid_info->width; - f->fmt.pix.height = vid_info->height; - f->fmt.pix.sizeimage = dev->bulk_in_size; - f->fmt.pix.colorspace = 0; - f->fmt.pix.bytesperline = 0; - f->fmt.pix.field = V4L2_FIELD_ANY; - - kfree(vid_info); - return 0; -} - -static int vidioc_encoder_cmd(struct file *filp, void *priv, - struct v4l2_encoder_cmd *a) -{ - struct hdpvr_fh *fh = filp->private_data; - struct hdpvr_device *dev = fh->dev; - int res; - - mutex_lock(&dev->io_mutex); - - memset(&a->raw, 0, sizeof(a->raw)); - switch (a->cmd) { - case V4L2_ENC_CMD_START: - a->flags = 0; - res = hdpvr_start_streaming(dev); - break; - case V4L2_ENC_CMD_STOP: - res = hdpvr_stop_streaming(dev); - break; - default: - v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev, - "Unsupported encoder cmd %d\n", a->cmd); - res = -EINVAL; - } - mutex_unlock(&dev->io_mutex); - return res; -} - -static int vidioc_try_encoder_cmd(struct file *filp, void *priv, - struct v4l2_encoder_cmd *a) -{ - switch (a->cmd) { - case V4L2_ENC_CMD_START: - case V4L2_ENC_CMD_STOP: - return 0; - default: - return -EINVAL; - } -} - -static const struct v4l2_ioctl_ops hdpvr_ioctl_ops = { - .vidioc_querycap = vidioc_querycap, - .vidioc_s_std = vidioc_s_std, - .vidioc_enum_input = vidioc_enum_input, - .vidioc_g_input = vidioc_g_input, - .vidioc_s_input = vidioc_s_input, - .vidioc_enumaudio = vidioc_enumaudio, - .vidioc_g_audio = vidioc_g_audio, - .vidioc_s_audio = vidioc_s_audio, - .vidioc_queryctrl = vidioc_queryctrl, - .vidioc_g_ctrl = vidioc_g_ctrl, - .vidioc_s_ctrl = vidioc_s_ctrl, - .vidioc_g_ext_ctrls = vidioc_g_ext_ctrls, - .vidioc_s_ext_ctrls = vidioc_s_ext_ctrls, - .vidioc_try_ext_ctrls = vidioc_try_ext_ctrls, - .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap, - .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap, - .vidioc_encoder_cmd = vidioc_encoder_cmd, - .vidioc_try_encoder_cmd = vidioc_try_encoder_cmd, -}; - -static void hdpvr_device_release(struct video_device *vdev) -{ - struct hdpvr_device *dev = video_get_drvdata(vdev); - - hdpvr_delete(dev); - mutex_lock(&dev->io_mutex); - destroy_workqueue(dev->workqueue); - mutex_unlock(&dev->io_mutex); - - v4l2_device_unregister(&dev->v4l2_dev); - - /* deregister I2C adapter */ -#if defined(CONFIG_I2C) || (CONFIG_I2C_MODULE) - mutex_lock(&dev->i2c_mutex); - i2c_del_adapter(&dev->i2c_adapter); - mutex_unlock(&dev->i2c_mutex); -#endif /* CONFIG_I2C */ - - kfree(dev->usbc_buf); - kfree(dev); -} - -static const struct video_device hdpvr_video_template = { -/* .type = VFL_TYPE_GRABBER, */ -/* .type2 = VID_TYPE_CAPTURE | VID_TYPE_MPEG_ENCODER, */ - .fops = &hdpvr_fops, - .release = hdpvr_device_release, - .ioctl_ops = &hdpvr_ioctl_ops, - .tvnorms = - V4L2_STD_NTSC | V4L2_STD_SECAM | V4L2_STD_PAL_B | - V4L2_STD_PAL_G | V4L2_STD_PAL_H | V4L2_STD_PAL_I | - V4L2_STD_PAL_D | V4L2_STD_PAL_M | V4L2_STD_PAL_N | - V4L2_STD_PAL_60, - .current_norm = V4L2_STD_NTSC | V4L2_STD_PAL_M | - V4L2_STD_PAL_60, -}; - -int hdpvr_register_videodev(struct hdpvr_device *dev, struct device *parent, - int devnum) -{ - /* setup and register video device */ - dev->video_dev = video_device_alloc(); - if (!dev->video_dev) { - v4l2_err(&dev->v4l2_dev, "video_device_alloc() failed\n"); - goto error; - } - - *(dev->video_dev) = hdpvr_video_template; - strcpy(dev->video_dev->name, "Hauppauge HD PVR"); - dev->video_dev->parent = parent; - video_set_drvdata(dev->video_dev, dev); - - if (video_register_device(dev->video_dev, VFL_TYPE_GRABBER, devnum)) { - v4l2_err(&dev->v4l2_dev, "video_device registration failed\n"); - goto error; - } - - return 0; -error: - return -ENOMEM; -} diff --git a/drivers/media/video/hdpvr/hdpvr.h b/drivers/media/video/hdpvr/hdpvr.h deleted file mode 100644 index fea3c6926997..000000000000 --- a/drivers/media/video/hdpvr/hdpvr.h +++ /dev/null @@ -1,317 +0,0 @@ -/* - * Hauppauge HD PVR USB driver - * - * Copyright (C) 2008 Janne Grunau (j@jannau.net) - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation, version 2. - * - */ - -#include <linux/usb.h> -#include <linux/i2c.h> -#include <linux/mutex.h> -#include <linux/workqueue.h> -#include <linux/videodev2.h> - -#include <media/v4l2-device.h> -#include <media/ir-kbd-i2c.h> - -#define HDPVR_MAX 8 -#define HDPVR_I2C_MAX_SIZE 128 - -/* Define these values to match your devices */ -#define HD_PVR_VENDOR_ID 0x2040 -#define HD_PVR_PRODUCT_ID 0x4900 -#define HD_PVR_PRODUCT_ID1 0x4901 -#define HD_PVR_PRODUCT_ID2 0x4902 -#define HD_PVR_PRODUCT_ID4 0x4903 -#define HD_PVR_PRODUCT_ID3 0x4982 - -#define UNSET (-1U) - -#define NUM_BUFFERS 64 - -#define HDPVR_FIRMWARE_VERSION 0x08 -#define HDPVR_FIRMWARE_VERSION_AC3 0x0d -#define HDPVR_FIRMWARE_VERSION_0X12 0x12 -#define HDPVR_FIRMWARE_VERSION_0X15 0x15 - -/* #define HDPVR_DEBUG */ - -extern int hdpvr_debug; - -#define MSG_INFO 1 -#define MSG_BUFFER 2 - -struct hdpvr_options { - u8 video_std; - u8 video_input; - u8 audio_input; - u8 bitrate; /* in 100kbps */ - u8 peak_bitrate; /* in 100kbps */ - u8 bitrate_mode; - u8 gop_mode; - enum v4l2_mpeg_audio_encoding audio_codec; - u8 brightness; - u8 contrast; - u8 hue; - u8 saturation; - u8 sharpness; -}; - -/* Structure to hold all of our device specific stuff */ -struct hdpvr_device { - /* the v4l device for this device */ - struct video_device *video_dev; - /* the usb device for this device */ - struct usb_device *udev; - /* v4l2-device unused */ - struct v4l2_device v4l2_dev; - - /* the max packet size of the bulk endpoint */ - size_t bulk_in_size; - /* the address of the bulk in endpoint */ - __u8 bulk_in_endpointAddr; - - /* holds the current device status */ - __u8 status; - /* count the number of openers */ - uint open_count; - - /* holds the cureent set options */ - struct hdpvr_options options; - - uint flags; - - /* synchronize I/O */ - struct mutex io_mutex; - /* available buffers */ - struct list_head free_buff_list; - /* in progress buffers */ - struct list_head rec_buff_list; - /* waitqueue for buffers */ - wait_queue_head_t wait_buffer; - /* waitqueue for data */ - wait_queue_head_t wait_data; - /**/ - struct workqueue_struct *workqueue; - /**/ - struct work_struct worker; - - /* I2C adapter */ - struct i2c_adapter i2c_adapter; - /* I2C lock */ - struct mutex i2c_mutex; - /* I2C message buffer space */ - char i2c_buf[HDPVR_I2C_MAX_SIZE]; - - /* For passing data to ir-kbd-i2c */ - struct IR_i2c_init_data ir_i2c_init_data; - - /* usb control transfer buffer and lock */ - struct mutex usbc_mutex; - u8 *usbc_buf; - u8 fw_ver; -}; - -static inline struct hdpvr_device *to_hdpvr_dev(struct v4l2_device *v4l2_dev) -{ - return container_of(v4l2_dev, struct hdpvr_device, v4l2_dev); -} - - -/* buffer one bulk urb of data */ -struct hdpvr_buffer { - struct list_head buff_list; - - struct urb *urb; - - struct hdpvr_device *dev; - - uint pos; - - __u8 status; -}; - -/* */ - -struct hdpvr_video_info { - u16 width; - u16 height; - u8 fps; -}; - -enum { - STATUS_UNINITIALIZED = 0, - STATUS_IDLE, - STATUS_STARTING, - STATUS_SHUTTING_DOWN, - STATUS_STREAMING, - STATUS_ERROR, - STATUS_DISCONNECTED, -}; - -enum { - HDPVR_FLAG_AC3_CAP = 1, -}; - -enum { - BUFSTAT_UNINITIALIZED = 0, - BUFSTAT_AVAILABLE, - BUFSTAT_INPROGRESS, - BUFSTAT_READY, -}; - -#define CTRL_START_STREAMING_VALUE 0x0700 -#define CTRL_STOP_STREAMING_VALUE 0x0800 -#define CTRL_BITRATE_VALUE 0x1000 -#define CTRL_BITRATE_MODE_VALUE 0x1200 -#define CTRL_GOP_MODE_VALUE 0x1300 -#define CTRL_VIDEO_INPUT_VALUE 0x1500 -#define CTRL_VIDEO_STD_TYPE 0x1700 -#define CTRL_AUDIO_INPUT_VALUE 0x2500 -#define CTRL_BRIGHTNESS 0x2900 -#define CTRL_CONTRAST 0x2a00 -#define CTRL_HUE 0x2b00 -#define CTRL_SATURATION 0x2c00 -#define CTRL_SHARPNESS 0x2d00 -#define CTRL_LOW_PASS_FILTER_VALUE 0x3100 - -#define CTRL_DEFAULT_INDEX 0x0003 - - - /* :0 s 38 01 1000 0003 0004 4 = 0a00ca00 - * BITRATE SETTING - * 1st and 2nd byte (little endian): average bitrate in 100 000 bit/s - * min: 1 mbit/s, max: 13.5 mbit/s - * 3rd and 4th byte (little endian): peak bitrate in 100 000 bit/s - * min: average + 100kbit/s, - * max: 20.2 mbit/s - */ - - /* :0 s 38 01 1200 0003 0001 1 = 02 - * BIT RATE MODE - * constant = 1, variable (peak) = 2, variable (average) = 3 - */ - - /* :0 s 38 01 1300 0003 0001 1 = 03 - * GOP MODE (2 bit) - * low bit 0/1: advanced/simple GOP - * high bit 0/1: IDR(4/32/128) / no IDR (4/32/0) - */ - - /* :0 s 38 01 1700 0003 0001 1 = 00 - * VIDEO STANDARD or FREQUNCY 0 = 60hz, 1 = 50hz - */ - - /* :0 s 38 01 3100 0003 0004 4 = 03030000 - * FILTER CONTROL - * 1st byte luma low pass filter strength, - * 2nd byte chroma low pass filter strength, - * 3rd byte MF enable chroma, min=0, max=1 - * 4th byte n - */ - - - /* :0 s 38 b9 0001 0000 0000 0 */ - - - -/* :0 s 38 d3 0000 0000 0001 1 = 00 */ -/* ret = usb_control_msg(dev->udev, */ -/* usb_sndctrlpipe(dev->udev, 0), */ -/* 0xd3, 0x38, */ -/* 0, 0, */ -/* "\0", 1, */ -/* 1000); */ - -/* info("control request returned %d", ret); */ -/* msleep(5000); */ - - - /* :0 s b8 81 1400 0003 0005 5 < - * :0 0 5 = d0024002 19 - * QUERY FRAME SIZE AND RATE - * 1st and 2nd byte (little endian): horizontal resolution - * 3rd and 4th byte (little endian): vertical resolution - * 5th byte: frame rate - */ - - /* :0 s b8 81 1800 0003 0003 3 < - * :0 0 3 = 030104 - * QUERY SIGNAL AND DETECTED LINES, maybe INPUT - */ - -enum hdpvr_video_std { - HDPVR_60HZ = 0, - HDPVR_50HZ, -}; - -enum hdpvr_video_input { - HDPVR_COMPONENT = 0, - HDPVR_SVIDEO, - HDPVR_COMPOSITE, - HDPVR_VIDEO_INPUTS -}; - -enum hdpvr_audio_inputs { - HDPVR_RCA_BACK = 0, - HDPVR_RCA_FRONT, - HDPVR_SPDIF, - HDPVR_AUDIO_INPUTS -}; - -enum hdpvr_bitrate_mode { - HDPVR_CONSTANT = 1, - HDPVR_VARIABLE_PEAK, - HDPVR_VARIABLE_AVERAGE, -}; - -enum hdpvr_gop_mode { - HDPVR_ADVANCED_IDR_GOP = 0, - HDPVR_SIMPLE_IDR_GOP, - HDPVR_ADVANCED_NOIDR_GOP, - HDPVR_SIMPLE_NOIDR_GOP, -}; - -void hdpvr_delete(struct hdpvr_device *dev); - -/*========================================================================*/ -/* hardware control functions */ -int hdpvr_set_options(struct hdpvr_device *dev); - -int hdpvr_set_bitrate(struct hdpvr_device *dev); - -int hdpvr_set_audio(struct hdpvr_device *dev, u8 input, - enum v4l2_mpeg_audio_encoding codec); - -int hdpvr_config_call(struct hdpvr_device *dev, uint value, - unsigned char valbuf); - -struct hdpvr_video_info *get_video_info(struct hdpvr_device *dev); - -/* :0 s b8 81 1800 0003 0003 3 < */ -/* :0 0 3 = 0301ff */ -int get_input_lines_info(struct hdpvr_device *dev); - - -/*========================================================================*/ -/* v4l2 registration */ -int hdpvr_register_videodev(struct hdpvr_device *dev, struct device *parent, - int devnumber); - -int hdpvr_cancel_queue(struct hdpvr_device *dev); - -/*========================================================================*/ -/* i2c adapter registration */ -int hdpvr_register_i2c_adapter(struct hdpvr_device *dev); - -struct i2c_client *hdpvr_register_ir_rx_i2c(struct hdpvr_device *dev); -struct i2c_client *hdpvr_register_ir_tx_i2c(struct hdpvr_device *dev); - -/*========================================================================*/ -/* buffer management */ -int hdpvr_free_buffers(struct hdpvr_device *dev); -int hdpvr_alloc_buffers(struct hdpvr_device *dev, uint count); |