aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@infradead.org>2006-12-04 08:30:53 -0300
committerMauro Carvalho Chehab <mchehab@infradead.org>2006-12-10 09:05:39 -0200
commit781aa1d1ab7ba13314af0af6c5d70c0eb0e96bf4 (patch)
tree5342519b3c90b710dbb9f8fca2240147344b70fc
parent2a893dea0f186efc2eb4bcdaee145b20c87d239d (diff)
V4L/DVB (4922): Add usbvision driver
This patch adds usbvision into V4L/DVB HG tree. Usbvision driver is a GPL driver, made by: Joerg Heckenbach <joerg@heckenbach-aw.de> and Dwaine Garden <DwaineGarden@rogers.com> V4L2 migration made by: Thierry Merle <thierry.merle@free.fr> Kconfig/Makefile scripts by: Mauro Carvalho Chehab <mchehab@infradead.org> Signed-off-by: Joerg Heckenbach <joerg@heckenbach-aw.de> Signed-off-by: Dwaine Garden <dwainegarden@rogers.com> Signed-off-by: Thierry Merle <thierry.merle@free.fr> Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
-rw-r--r--drivers/media/video/Kconfig12
-rw-r--r--drivers/media/video/Makefile1
-rw-r--r--drivers/media/video/usbvision/Makefile5
-rw-r--r--drivers/media/video/usbvision/usbvision-core.c5880
-rw-r--r--drivers/media/video/usbvision/usbvision-i2c.c265
-rw-r--r--drivers/media/video/usbvision/usbvision-i2c.h58
-rw-r--r--drivers/media/video/usbvision/usbvision.h594
-rw-r--r--drivers/media/video/usbvision/usbvision_ioctl.h34
8 files changed, 6849 insertions, 0 deletions
diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig
index ef803106b79..9365a8dd44e 100644
--- a/drivers/media/video/Kconfig
+++ b/drivers/media/video/Kconfig
@@ -686,6 +686,18 @@ source "drivers/media/video/pvrusb2/Kconfig"
source "drivers/media/video/em28xx/Kconfig"
+config VIDEO_USBVISION
+ tristate "USB video devices based on NT1003/1005/1005"
+ depends on I2C && VIDEO_V4L2
+ select VIDEO_SAA711X if VIDEO_HELPER_CHIPS_AUTO
+ ---help---
+ There are more than 50 different USB video devices based on
+ NT1003/1004/1005 USB Bridges. This driver enables using those
+ devices.
+
+ To compile this driver as a module, choose M here: the
+ module will be called ovcamchip.
+
source "drivers/media/video/usbvideo/Kconfig"
source "drivers/media/video/et61x251/Kconfig"
diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile
index 20b9cbc144b..9b1f3f06bb7 100644
--- a/drivers/media/video/Makefile
+++ b/drivers/media/video/Makefile
@@ -62,6 +62,7 @@ obj-$(CONFIG_VIDEO_MEYE) += meye.o
obj-$(CONFIG_VIDEO_SAA7134) += ir-kbd-i2c.o saa7134/
obj-$(CONFIG_VIDEO_CX88) += cx88/
obj-$(CONFIG_VIDEO_EM28XX) += em28xx/
+obj-$(CONFIG_VIDEO_USBVISION) += usbvision/
obj-$(CONFIG_VIDEO_TVP5150) += tvp5150.o
obj-$(CONFIG_VIDEO_PVRUSB2) += pvrusb2/
obj-$(CONFIG_VIDEO_MSP3400) += msp3400.o
diff --git a/drivers/media/video/usbvision/Makefile b/drivers/media/video/usbvision/Makefile
new file mode 100644
index 00000000000..bad2eee2dbb
--- /dev/null
+++ b/drivers/media/video/usbvision/Makefile
@@ -0,0 +1,5 @@
+usbvision-objs := usbvision-core.o usbvision-i2c.o
+
+obj-$(CONFIG_VIDEO_USBVISION) += usbvision.o
+
+EXTRA_CFLAGS += -Idrivers/media/video
diff --git a/drivers/media/video/usbvision/usbvision-core.c b/drivers/media/video/usbvision/usbvision-core.c
new file mode 100644
index 00000000000..62699ca020a
--- /dev/null
+++ b/drivers/media/video/usbvision/usbvision-core.c
@@ -0,0 +1,5880 @@
+/*
+ * USB USBVISION Video device driver 0.9.8.3cvs (For Kernel 2.4.19-2.4.32 + 2.6.0-2.6.16)
+ *
+ *
+ *
+ * Copyright (c) 1999-2005 Joerg Heckenbach <joerg@heckenbach-aw.de>
+ *
+ * This module is part of usbvision driver project.
+ *
+ * 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Let's call the version 0.... until compression decoding is completely
+ * implemented.
+ *
+ * This driver is written by Jose Ignacio Gijon and Joerg Heckenbach.
+ * It was based on USB CPiA driver written by Peter Pregler,
+ * Scott J. Bertin and Johannes Erdfelt
+ * Ideas are taken from bttv driver by Ralph Metzler, Marcus Metzler &
+ * Gerd Knorr and zoran 36120/36125 driver by Pauline Middelink
+ * Updates to driver completed by Dwaine P. Garden
+ *
+ * History:
+ *
+ * Mar. 2000 - 15.12.2000: (0.0.0 - 0.2.0)
+ * Several alpha drivers and the first beta.
+ *
+ * Since Dec. 2000: (0.2.1) or (v2.1)
+ * Code changes or updates by Dwaine Garden and every other person.
+ *
+ * Added: New Hauppauge TV device Vendor ID: 0x0573
+ * Product ID: 0x4D01
+ * (Thanks to Giovanni Garberoglio)
+ *
+ * Added: UK Hauppauge WinTV-USB Vendor ID: 0x0573
+ * Product ID: 0x4D02
+ * (Thanks to Derek Freeman-Jones)
+ *
+ * Feb, 2001 - Apr 08, 2001: (0.3.0)
+ * - Some fixes. Driver is now more stable.
+ * - Scratch is organized as ring-buffer now for better performance
+ * - DGA (overlay) is now supported.
+ * !!!!Danger!!!! Clipping is not yet implemented. Your system will
+ * crash if your video window leaves the screen!!!
+ * - Max. Framesize is set to 320x240. There isn't more memory on the
+ * nt1003 video device for the FIFO.
+ * - Supported video palettes: RGB565, RGB555, RGB24, RGB32
+ *
+ *
+ * Apr 15, 2001: (0.3.1-test...)
+ * - Clipping is implemented
+ * - NTSC is now coloured (Thanks to Dwaine Garden)
+ * - Added SECAM colour detection in saa7111-new
+ * - Added: French Hauppauge WinTV USB Vendor ID: 0x0573
+ * Product ID: 0x4D03
+ * (Thanks to Julius Hrivnac)
+ * - Added: US Hauppauge WINTV USB Vendor ID: 0x0573
+ * Product ID: 0x4D00
+ * (Thanks to Derrick J Brashear)
+ * - Changes for adding new devices. There's now a table in usbvision.h.
+ * Adding your devices data to the usbvision_device_data table is all
+ * you need to add a new device.
+ *
+ * May 11, 2001: (0.3.2-test...) (Thanks to Derek Freeman-Jones)
+ * - Support YUV422 raw format for people with hardware scaling.
+ * - Only power on the device when opened (use option PowerOnAtOpen=0 to disable it).
+ * - Turn off audio so we can listen to Line In.
+ *
+ * July 5, 2001 - (Patch the driver to run with Kernel 2.4.6)
+ * - Fixed a problem with the number of parameters passed to video_register_device.
+ *
+ * July 6, 2001 - Added: HAUPPAUGE WINTV-USB FM USA Vendor ID: 0x0573
+ * Product ID: 0x4D10
+ * (Thanks to Braddock Gaskill)
+ * Added: USBGear USBG-V1 resp. HAMA USB
+ * Vendor ID: 0x0573
+ * Product ID: 0x0003
+ * (Thanks to Bradley A. Singletary and Juergen Weigert)
+ *
+ * Jan 24, 2002 - (0.3.3-test...)
+ * - Moved all global variables that are device specific the usb_usbvision struct
+ * - Fixed the 64x48 unchangable image in xawtv when starting it with overlay
+ * - Add VideoNorm and TunerType to the usb_device_data table
+ * - Checked the audio channels and mute for HAUPPAUGE WinTV USB FM
+ * - Implemented the power on when opening the device. But some software opens
+ * the device several times when starting. So the i2c parts are just registered
+ * by an open, when they become deregistered by the next close. You can speed
+ * up tuner detection, when adding "options tuner addr=your_addr" to /etc/modules.conf
+ * - Begin to resize the frame in width and height. So it will be possible to watch i.e.
+ * 384x288 pixels at 23 fps.
+ *
+ * Feb 10, 2002
+ * - Added radio device
+ *
+ *
+ * Jul 30, 2002 - (Thanks Cameron Maxwell)
+ * - Changes to usbvision.h --fixed usbvision device data structure, incorrectly had (0x0573, 0x4d21) for WinTV-USB II, should be 0x4d20.
+ * - Changes for device WinTV-USB II (0x0573. 0x4D21). It does not have a FM tuner.
+ * - Added the real device HAUPPAUGE WINTV-USB II (PAL) to the device structure in usbvision.h.
+ * - Changes to saa7113-new, the video is 8 bit data for the Phillips SAA7113 not 16bit like SAA7111.
+ * - Tuned lots of setup registers for the Phillips SAA7113 video chipset.
+ * - Changes to the supplied makefile. (Dwaine Garden) Still needs to be fixed so it will compile modules on different distrubutions.
+ *
+ *
+ * Aug 10, 2002 - (Thanks Mike Klinke)
+ * - Changes to usbvision.txt -- Fixed instructions on the location to copy the contents of the tgz file.
+ * - Added device WinTV-USB FM Model 621 (0x0573. 0x4D30). There is another device which carries the same name. Kept that device in the device structure.
+ *
+ * Aug 12, 2002 - Dwaine Garden
+ * - Added the ability to read the NT100x chip for the MaxISOPacketLength and USB Bandwidth
+ * Setting of the video device.
+ * - Adjustments to the SAA7113H code for proper video output.
+ * - Changes to usbvision.h, so all the devices with FM tuners are working.
+ *
+ * Feb 10, 2003 - Joerg Heckenbach
+ * - fixed endian bug for Motorola PPC
+ *
+ * Feb 13, 2003 - Joerg Heckenbach
+ * - fixed Vin_Reg setting and presetting from usbvision_device_data()
+ *
+ * Apr 19, 2003 - Dwaine Garden
+ * - Fixed compiling errors under RedHat v9.0. from uvirt_to_kva and usbvision_mmap. (Thanks Cameron Maxwell)
+ * - Changed pte_offset to pte_offset_kernel.
+ * - Changed remap_page_range and added additional parameter to function.
+ * - Change setup parameters for the D-Link V100 USB device
+ * - Added a new device to the usbvision driver. Pinnacle Studio PCTV USB (PAL) 0x2304 0x0110
+ * - Screwed up the sourceforge.net cvs respository! 8*)
+ *
+ * Apr 22, 2002 - Dwaine Garden
+ * - Added a new device to the usbvision driver. Dazzle DVC-80 (PAL) 0x07d0 0x0004. (Thanks Carl Anderson)
+ * - Changes to some of the comments.
+ *
+ * June 06, 2002 - Ivan, Dwaine Garden
+ * - Ivan updates for fine tuning device parameters without driver recompiling. (Ivan)
+ * - Changes to some of the comments. (Dwaine Garden)
+ * - Changes to the makefile - Better CPU settings. (Ivan)
+ * - Changes to device Hauppauge WinTv-USB III (PAL) FM Model 568 - Fine tuning parameters (Ivan)
+ *
+ *
+ * Oct 16, 2003 - 0.9.0 - Joerg Heckenbach
+ * - Implementation of the first part of the decompression algorithm for intra frames.
+ * The resolution has to be 320x240. A dynamic adaption of compression deepth is
+ * missing yet.
+ *
+ * Oct 22, 2003 - 0.9.1 - Joerg Heckenbach
+ * - Implementation of the decompression algorithm for inter frames.
+ * The resolution still has to be 320x240.
+ *
+ * Nov 2003 - Feb 2004 - 0.9.2 to 0.9.3 - Joerg Heckenbach
+ * - Implement last unknown compressed block type. But color is still noisy.
+ * - Finding criteria for adaptive compression adjustment.
+ * - Porting to 2.6 kernels, but still working under 2.4
+ *
+ * Feb 04, 2004 - 0.9.4 Joerg Heckenbach
+ * - Found bug in color decompression. Color is OK now.
+ *
+ * Feb 09, 2004 - 0.9.5 Joerg Heckenbach
+ * - Add auto-recognition of chip type NT1003 or NT1004.
+ * - Add adaptive compression adjustment.
+ * - Patched saa7113 multiplexer switching (Thanks to Orlando F.S. Bordoni)
+ *
+ * Feb 24, 2004 - 0.9.6 Joerg Heckenbach
+ * - Add a timer to wait before poweroff at close, to save start time in
+ * some video applications
+ *
+ * Mar 4, 2004 - 0.9.6 Dwaine Garden
+ * - Added device Global Village GV-007 (NTSC) to usbvision.h (Thanks to Abe Skolnik)
+ * - Forgot to add this device to the driver. 8*)
+ *
+ * June 2, 2004 - 0.9.6 Dwaine Garden
+ * - Fixed sourceforge.net cvs repository.
+ * - Added #if LINUX_VERSION_CODE > KERNEL_VERSION(2,4,26) for .owner to help compiling under kernels 2.4.x which do not have the i2c v2.8.x updates.
+ * - Added device Hauppauge WinTv-USB III (PAL) FM Model 597 to usbvision.h
+ *
+ * July 1, 2004 -0.9.6 Dwaine Garden
+ * - Patch was submitted by Hal Finkel to fix the problem with the tuner not working under kernel 2.6.7.
+ * - Thanks Hal.....
+ *
+ * July 30, 2004 - 0.9.6 Dwaine Garden
+ * - Patch was submitted by Tobias Diaz to fix Model ID mismatch in usbvision.h.
+ * - Thanks.....
+ *
+ * August 12, 2004 - 0.9.6 Dwaine Garden
+ * - Updated the readme file so people could install the driver under the configuration file for kernel 2.6.x recompiles. Now people can use make xconfig!
+ * - Added new device "Camtel Technology Corp TVB330-USB FM".
+ * - Sourceforge.net CVS has been updated with all the changes.
+ *
+ * August 20, 2004 - 0.9.7 Dwaine Garden
+ * - Added Device "Hauppauge USB Live Model 600"
+ * - Fixed up all the devices which did not have a default tuner type in usbvision.h. It's best guess, at least until someone with the device tells me otherwise.
+ * - Sourceforge.net CVS has been updated with all the changes.
+ * - Clean up the driver.
+ *
+ * September 13, 2004 - 0.9.8 Dwaine Garden
+ * - Changed usbvision_muxsel to address the problem with black & white s-video output for NT1004 devices with saa7114 video decoder. Thanks to Emmanuel for the patch and testing.
+ * - Fixed up SECAM devices which could not properly output video. Changes to usbmuxsel. Thanks to Emmanuel for the patch and everyone with a SECAM device which help test.
+ * - Removed some commented out code. Clean up.
+ * - Tried to fix up the annoying empty directories in the sourceforge.net cvs. Fuck it up again. 8*(
+ *
+ * November 15, 2004 - 0.9.8 Dwaine Garden
+ * - Release new tar - 0.9.8 on sourceforge.net
+ * - Added some new devices to usbvision.h WinTV USB Model 602 40201 Rev B282, Hauppague WinTV USB Model 602 40201 Rev B285
+ * - Added better compatibility for 2.6.x kernels.
+ * - Hardware full screen scaling in grabdisplay mode.
+ * - Better support for sysfs. More code to follow for both video device and radio device. Device information is located at /sys/class/video4linux/video0
+ * - Added module_param so loaded module parameters are displayed in sysfs. Driver parameters should show up in /sys/module/usbvision
+ * - Adjusted the SAA7111 registers to match the 2.6.x kernel SAA7111 code. Thanks to the person which helped test.
+ * - Changed to wait_event_interruptible. For all the people running Fedora 2.
+ * - Added some screenshots of actual video captures on sourceforge.net.
+ *
+ * November 24, 2004 - 0.9.8.1cvs Dwaine Garden
+ * - Added patch to check for palette and format in VIDIOCSPICT. Helix Producer should work fine with the driver now. Thanks Jason Simpson
+ * - Two device description changes and two additions for the maintainer of usb.ids.
+ *
+ * December 2, 2004 - 0.9.8.1cvs Dwaine Garden
+ * - Added patch for YUV420P and YUV422P video output. Thanks to Alex Smith.
+ * - Better support for mythtv.
+ *
+ * January 2, 2005 - 0.9.8.1cvs Dwaine Garden
+ * - Setup that you can specify which device is used for video. Default is auto detect next available device number eg. /dev/videoX
+ * - Setup that you can specify which device is used for radio. Default is auto detect next available device number eg. /dev/radioX
+ * - usb_unlink_urb() is deprecated for synchronous unlinks. Using usb_kill_urb instead.
+ * - usbvision_kvirt_to_pa is deprecated. Removed.
+ * - Changes are related to kernel changes for 2.6.10. (Fedora 4)
+ *
+ * February 2, 2005 - 0.9.8.1cvs Dwaine Garden
+ * - Added a new device to usbvision.h Dazzle DVC 50. Thanks to Luiz S.
+ *
+ * March 29, 2005 - 0.9.8.1cvs Dwaine Garden
+ * - Fixed compile error with saa7113 under kernels 2.6.11+
+ * - Added module parameter to help people with Black and White output with using s-video input. Some cables and input device are wired differently.
+ * - Removed the .id from the i2c usbvision template. There was a change to the i2c with kernels 2.6.11+.
+ *
+ * April 9, 2005 - 0.9.8.1cvs Dwaine Garden
+ * - Added in the 2.4 and 2.6 readme files the SwitchSVideoInput parameter information. This will help people setup the right values for the parameter.
+ * If your device experiences Black and White images with the S-Video Input. Set this parameter to 1 when loading the module.
+ * - Replaced the wrong 2.6 readme file. I lost the right version. Someone sent me the right version by e-mail. Thanks.
+ * - Released new module version on sourceforge.net. So everyone can enjoy all the fixes and additional device support.
+ *
+ * April 20, 2005 - 0.9.8.2cvs Dwaine Garden
+ * - Release lock in usbvision_v4l_read_done. -Thanks to nplanel for the patch.
+ * - Additional comments to the driver.
+ * - Fixed some spelling mistakes. 8*)
+ *
+ * April 23, 2005 - 0.9.8.2cvs Joerg Heckenbach
+ * - Found bug in usbvision line counting. Now there should be no spurious lines in the image any longer.
+ * - Swapped usbvision_register_video and usbvision_configure_video to fix problem with PowerOnAtOpen=0.
+ * Thanks to Erwan Velu
+ *
+ * April 26, 2005 - 0.9.8.2cvs Joerg Heckenbach
+ * - Fixed problem with rmmod module and oppses. Replaced vfree(usbvision->overlay_base) with iounmap(usbvision->overlay_base).
+ * - Added function usb_get_dev(dev) and ; To help with unloading the module multiple times without crashing.
+ * (Keep the reference count in kobjects correct)
+ *
+ * June 14, 2005 - 0.9.8.2cvs Dwaine
+ * - Missed a change in saa7113.c for checking kernel version. Added conditional if's.
+ *
+ * June 15, 2005 - 0.9.8.2cvs Dwaine
+ * - Added new device WinTV device VendorId 0573 and ProductId 4d29.
+ * - Hacked some support for newer NT1005 devices. This devices only seem to have one configuration, not multiple configurations like the NT1004.
+ *
+ * June 29, 2005 - 0.9.8.2cvs Dwaine
+ * - Added new device WinTV device VendorId 0573 and ProductId 4d37.
+ * - Because of the first empty entry in usbvision_table, modutils failed to create the necessary entries for modules.usbmap.
+ * This means hotplug won't work for usbvision. Thanks to Gary Ng.
+ * - Sent an e-mail to the maintainer of usb.ids. New devices identified need to be added.
+ * - Fixed compile error with saa7113 under kernel 2.6.12.
+ *
+ * July 6, 2005 - 0.9.8.2cvs Dwaine
+ * - Patch submitted by Gary Ng for two additional procfs entries. Device Input and Frequency setting.
+ *
+ * July 12, 2005 - 0.9.8.2cvs Dwaine
+ * - New tuner identified for some devices it's called TCL_MFPE05. This tuner uses the same API as tuner 38 in tuner.c.
+ * - Thanks to lynx31 for contacting Hauppage and asking them.
+ * - I have no clue as to which devices use this new tuner, so people will have to contact me and tell me.
+ *
+ * July 21, 2005 - 0.9.8.2cvs Dwaine
+ * - Patched usbvision.c with missing ifdef kernversion statement so the module will compile with older kernels and v4l.
+ * - Thanks to cipe007......
+ *
+ * May 19, 2006 - 0.9.8.3cvs Dwaine
+ * - Patched usbvision.c and i2c-algo.c so they will compile with kernel 2.6.16
+ * - Adjust device "Pinnacle Studio PCTV USB (PAL) FM" values in usbvision.h
+ *
+ * May 24, 2006 - 0.9.8.3cvs Dwaine
+ * -Pinnacle Studio PCTV USB (NTSC) FM uses saa7111, not saa7113 like first thought.
+ * -Updated usbvision.h
+ *
+ * Aug 15, 2006 - 0.9.8.3cvs Dwaine
+ * -Added saa711x module into cvs, since the newer saa7115 module in newer kernels is v4l2. The usbvision driver is only v4l.
+ * -Updated makefile to put compiled modules into correct location.
+ *
+ * Aug 21, 2006 - 0.9.8.3cvs Dwaine
+ * -Changed number of bytes for i2c write to 4 as per the NT100X spec sheet. Thanks to Merlum for finding it.
+ * -Remove the radio option for device Hauppauge WinTV USB device Model 40219 Rev E189. This device does not have a FM radio. Thanks to Shadwell.
+ * -Added radio option for device Hauppauge WinTV USB device Model 40219 Rev E189 again. Just got an e-mail indicating their device has one. 8*)
+ *
+ * Aug 27, 2006 - 0.9.8.3cvs Dwaine
+ * -Changed ifdef statement so the usbvision driver will compile with kernels at 2.6.12.
+ * -Updated readme files for new updated tuner list for v4l devices.
+ *
+ *
+ *
+ * TODO:
+ * - use submit_urb for all setup packets
+ * - Fix memory settings for nt1004. It is 4 times as big as the
+ * nt1003 memory.
+ * - Add audio on endpoint 3 for nt1004 chip. Seems impossible, needs a codec interface. Which one?
+ * - Clean up the driver.
+ * - optimization for performance.
+ * - Add Videotext capability (VBI). Working on it.....
+ * - Check audio for other devices
+ * - Add v4l2 interface
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/slab.h>
+#include <linux/mm.h>
+#include <linux/utsname.h>
+#include <linux/highmem.h>
+#include <linux/smp_lock.h>
+#include <linux/videodev.h>
+#include <linux/vmalloc.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/spinlock.h>
+#include <linux/usb.h>
+#include <asm/io.h>
+#include <linux/videodev2.h>
+#include <linux/video_decoder.h>
+#include <linux/i2c.h>
+#include "usbvision-i2c.h"
+
+#define USBVISION_DRIVER_VERSION_MAJOR 0
+#define USBVISION_DRIVER_VERSION_MINOR 8
+#define USBVISION_DRIVER_VERSION_PATCHLEVEL 0
+
+#define USBVISION_VERSION __stringify(USBVISION_DRIVER_VERSION_MAJOR) "." __stringify(USBVISION_DRIVER_VERSION_MINOR) "." __stringify(USBVISION_DRIVER_VERSION_PATCHLEVEL) " " USBVISION_DRIVER_VERSION_COMMENT
+#define USBVISION_DRIVER_VERSION KERNEL_VERSION(USBVISION_DRIVER_VERSION_MAJOR,USBVISION_DRIVER_VERSION_MINOR,USBVISION_DRIVER_VERSION_PATCHLEVEL)
+
+#include <media/saa7115.h>
+#include <media/v4l2-common.h>
+#include <media/tuner.h>
+#include <media/audiochip.h>
+
+ #include <linux/moduleparam.h>
+ #include <linux/workqueue.h>
+
+#ifdef CONFIG_KMOD
+#include <linux/kmod.h>
+#endif
+
+#include "usbvision.h"
+#include "usbvision_ioctl.h"
+
+
+#define DRIVER_VERSION "0.9.8.3cvs for Linux kernels 2.4.19-2.4.32 + 2.6.0-2.6.17, compiled at "__DATE__", "__TIME__
+#define EMAIL "joerg@heckenbach-aw.de"
+#define DRIVER_AUTHOR "Joerg Heckenbach <joerg@heckenbach-aw.de>, Dwaine Garden <DwaineGarden@rogers.com>"
+#define DRIVER_DESC "USBVision USB Video Device Driver for Linux"
+#define DRIVER_LICENSE "GPL"
+#define DRIVER_ALIAS "USBVision"
+
+#define ENABLE_HEXDUMP 0 /* Enable if you need it */
+
+
+#define USBVISION_DEBUG /* Turn on debug messages */
+
+#ifdef USBVISION_DEBUG
+ #define PDEBUG(level, fmt, args...) \
+ if (debug & (level)) info("[%s:%d] " fmt, __PRETTY_FUNCTION__, __LINE__ , ## args)
+#else
+ #define PDEBUG(level, fmt, args...) do {} while(0)
+#endif
+
+#define DBG_IOCTL 1<<3
+#define DBG_IO 1<<4
+#define DBG_RIO 1<<5
+#define DBG_HEADER 1<<7
+#define DBG_PROBE 1<<8
+#define DBG_IRQ 1<<9
+#define DBG_ISOC 1<<10
+#define DBG_PARSE 1<<11
+#define DBG_SCRATCH 1<<12
+#define DBG_FUNC 1<<13
+#define DBG_I2C 1<<14
+
+#define DEBUG(x...) /* General Debug */
+#define IODEBUG(x...) /* Debug IO */
+#define OVDEBUG(x...) /* Debug overlay */
+#define MDEBUG(x...) /* Debug memory management */
+
+//String operations
+#define rmspace(str) while(*str==' ') str++;
+#define goto2next(str) while(*str!=' ') str++; while(*str==' ') str++;
+
+
+static int usbvision_nr = 0; // sequential number of usbvision device
+
+
+static const int max_imgwidth = MAX_FRAME_WIDTH;
+static const int max_imgheight = MAX_FRAME_HEIGHT;
+static const int min_imgwidth = MIN_FRAME_WIDTH;
+static const int min_imgheight = MIN_FRAME_HEIGHT;
+
+#define FRAMERATE_MIN 0
+#define FRAMERATE_MAX 31
+
+
+enum {
+ ISOC_MODE_YUV422 = 0x03,
+ ISOC_MODE_YUV420 = 0x14,
+ ISOC_MODE_COMPRESS = 0x60,
+};
+
+/*
+ * The value of 'scratch_buf_size' affects quality of the picture
+ * in many ways. Shorter buffers may cause loss of data when client
+ * is too slow. Larger buffers are memory-consuming and take longer
+ * to work with. This setting can be adjusted, but the default value
+ * should be OK for most desktop users.
+ */
+#define DEFAULT_SCRATCH_BUF_SIZE (0x20000) // 128kB memory scratch buffer
+static const int scratch_buf_size = DEFAULT_SCRATCH_BUF_SIZE;
+
+static int init_brightness = 128; // Initalize the brightness of the video device
+static int init_contrast = 192; // Initalize the contrast of the video device
+static int init_saturation = 128; // Initalize the staturation mode of the video device
+static int init_hue = 128; // Initalize the Hue settings of the video device
+
+// Function prototypes
+static int usbvision_restart_isoc(struct usb_usbvision *usbvision);
+static int usbvision_begin_streaming(struct usb_usbvision *usbvision);
+static int usbvision_muxsel(struct usb_usbvision *usbvision, int channel, int norm);
+static int usbvision_i2c_write(void *data, unsigned char addr, char *buf, short len);
+static int usbvision_i2c_read(void *data, unsigned char addr, char *buf, short len);
+static int usbvision_read_reg(struct usb_usbvision *usbvision, unsigned char reg);
+static int usbvision_write_reg(struct usb_usbvision *usbvision, unsigned char reg, unsigned char value);
+static int usbvision_request_intra (struct usb_usbvision *usbvision);
+static int usbvision_unrequest_intra (struct usb_usbvision *usbvision);
+static int usbvision_adjust_compression (struct usb_usbvision *usbvision);
+static int usbvision_measure_bandwidth (struct usb_usbvision *usbvision);
+static void usbvision_release(struct usb_usbvision *usbvision);
+static int usbvision_set_input(struct usb_usbvision *usbvision);
+static int usbvision_set_output(struct usb_usbvision *usbvision, int width, int height);
+static void call_i2c_clients(struct usb_usbvision *usbvision, unsigned int cmd, void *arg);
+
+
+// Bit flags (options)
+#define FLAGS_RETRY_VIDIOCSYNC (1 << 0)
+#define FLAGS_MONOCHROME (1 << 1)
+#define FLAGS_DISPLAY_HINTS (1 << 2)
+#define FLAGS_OSD_STATS (1 << 3)
+#define FLAGS_FORCE_TESTPATTERN (1 << 4)
+#define FLAGS_SEPARATE_FRAMES (1 << 5)
+#define FLAGS_CLEAN_FRAMES (1 << 6)
+
+// Default initalization of device driver parameters
+static int flags = 0; // Set the default Overlay Display mode of the device driver
+static int debug = 0; // Set the default Debug Mode of the device driver
+static int isocMode = ISOC_MODE_COMPRESS; // Set the default format for ISOC endpoint
+static int adjustCompression = 1; // Set the compression to be adaptive
+static int dga = 1; // Set the default Direct Graphic Access
+static int PowerOnAtOpen = 1; // Set the default device to power on at startup
+static int SwitchSVideoInput = 0; // To help people with Black and White output with using s-video input. Some cables and input device are wired differently.
+static int video_nr = -1; // Sequential Number of Video Device
+static int radio_nr = -1; // Sequential Number of Radio Device
+static int vbi_nr = -1; // Sequential Number of VBI Device
+static char *CustomDevice=NULL; // Set as nothing....
+
+// Grab parameters for the device driver
+
+#if defined(module_param) // Showing parameters under SYSFS
+module_param(flags, int, 0444);
+module_param(debug, int, 0444);
+module_param(isocMode, int, 0444);
+module_param(adjustCompression, int, 0444);
+module_param(dga, int, 0444);
+module_param(PowerOnAtOpen, int, 0444);
+module_param(SwitchSVideoInput, int, 0444);
+module_param(video_nr, int, 0444);
+module_param(radio_nr, int, 0444);
+module_param(vbi_nr, int, 0444);
+module_param(CustomDevice, charp, 0444);
+#else // Old Style
+MODULE_PARM(flags, "i"); // Grab the Overlay Display mode of the device driver
+MODULE_PARM(debug, "i"); // Grab the Debug Mode of the device driver
+MODULE_PARM(isocMode, "i"); // Grab the video format of the video device
+MODULE_PARM(adjustCompression, "i"); // Grab the compression to be adaptive
+MODULE_PARM(dga, "i"); // Grab the Direct Graphic Access
+MODULE_PARM(PowerOnAtOpen, "i"); // Grab the device to power on at startup
+MODULE_PARM(SwitchSVideoInput, "i"); // To help people with Black and White output with using s-video input. Some cables and input device are wired differently.
+MODULE_PARM(video_nr, "i"); // video_nr option allows to specify a certain /dev/videoX device (like /dev/video0 or /dev/video1 ...)
+MODULE_PARM(radio_nr, "i"); // radio_nr option allows to specify a certain /dev/radioX device (like /dev/radio0 or /dev/radio1 ...)
+MODULE_PARM(vbi_nr, "i"); // vbi_nr option allows to specify a certain /dev/vbiX device (like /dev/vbi0 or /dev/vbi1 ...)
+MODULE_PARM(CustomDevice, "s"); // .... CustomDevice
+#endif
+
+MODULE_PARM_DESC(flags, " Set the default Overlay Display mode of the device driver. Default: 0 (Off)");
+MODULE_PARM_DESC(debug, " Set the default Debug Mode of the device driver. Default: 0 (Off)");
+MODULE_PARM_DESC(isocMode, " Set the default format for ISOC endpoint. Default: 0x60 (Compression On)");
+MODULE_PARM_DESC(adjustCompression, " Set the ADPCM compression for the device. Default: 1 (On)");
+MODULE_PARM_DESC(dga, " Set the Direct Graphic Access for the device. Default: 1 (On)");
+MODULE_PARM_DESC(PowerOnAtOpen, " Set the default device to power on when device is opened. Default: 1 (On)");
+MODULE_PARM_DESC(SwitchSVideoInput, " Set the S-Video input. Some cables and input device are wired differently. Default: 0 (Off)");
+MODULE_PARM_DESC(video_nr, "Set video device number (/dev/videoX). Default: -1 (autodetect)");
+MODULE_PARM_DESC(radio_nr, "Set radio device number (/dev/radioX). Default: -1 (autodetect)");
+MODULE_PARM_DESC(vbi_nr, "Set vbi device number (/dev/vbiX). Default: -1 (autodetect)");
+MODULE_PARM_DESC(CustomDevice, " Define the fine tuning parameters for the device. Default: null");
+
+
+// Misc stuff
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE(DRIVER_LICENSE);
+ MODULE_VERSION(DRIVER_VERSION);
+ MODULE_ALIAS(DRIVER_ALIAS);
+
+#ifdef MODULE
+static unsigned int autoload = 1;
+#else
+static unsigned int autoload = 0;
+#endif
+
+
+/****************************************************************************************/
+/* SYSFS Code - Copied from the stv680.c usb module. */
+/* Device information is located at /sys/class/video4linux/video0 */
+/* Device parameters information is located at /sys/module/usbvision */
+/* Device USB Information is located at /sys/bus/usb/drivers/USBVision Video Grabber */
+/****************************************************************************************/
+
+
+#define YES_NO(x) ((x) ? "Yes" : "No")
+
+static inline struct usb_usbvision *cd_to_usbvision(struct class_device *cd)
+{
+ struct video_device *vdev = to_video_device(cd);
+ return video_get_drvdata(vdev);
+}
+
+static ssize_t show_version(struct class_device *cd, char *buf)
+{
+ return sprintf(buf, "%s\n", DRIVER_VERSION);
+}
+static CLASS_DEVICE_ATTR(version, S_IRUGO, show_version, NULL);
+
+static ssize_t show_model(struct class_device *class_dev, char *buf)
+{
+ struct video_device *vdev = to_video_device(class_dev);
+ struct usb_usbvision *usbvision = video_get_drvdata(vdev);
+ return sprintf(buf, "%s\n", usbvision_device_data[usbvision->DevModel].ModelString);
+}
+static CLASS_DEVICE_ATTR(model, S_IRUGO, show_model, NULL);
+
+static ssize_t show_hue(struct class_device *class_dev, char *buf)
+{
+ struct video_device *vdev = to_video_device(class_dev);
+ struct usb_usbvision *usbvision = video_get_drvdata(vdev);
+ return sprintf(buf, "%d\n", usbvision->hue >> 8);
+}
+static CLASS_DEVICE_ATTR(hue, S_IRUGO, show_hue, NULL);
+
+static ssize_t show_contrast(struct class_device *class_dev, char *buf)
+{
+ struct video_device *vdev = to_video_device(class_dev);
+ struct usb_usbvision *usbvision = video_get_drvdata(vdev);
+ return sprintf(buf, "%d\n", usbvision->contrast >> 8);
+}
+static CLASS_DEVICE_ATTR(contrast, S_IRUGO, show_contrast, NULL);
+
+static ssize_t show_brightness(struct class_device *class_dev, char *buf)
+{
+ struct video_device *vdev = to_video_device(class_dev);
+ struct usb_usbvision *usbvision = video_get_drvdata(vdev);
+ return sprintf(buf, "%d\n", usbvision->brightness >> 8);
+}
+static CLASS_DEVICE_ATTR(brightness, S_IRUGO, show_brightness, NULL);
+
+static ssize_t show_saturation(struct class_device *class_dev, char *buf)
+{
+ struct video_device *vdev = to_video_device(class_dev);
+ struct usb_usbvision *usbvision = video_get_drvdata(vdev);
+ return sprintf(buf, "%d\n", usbvision->saturation >> 8);
+}
+static CLASS_DEVICE_ATTR(saturation, S_IRUGO, show_saturation, NULL);
+
+static ssize_t show_streaming(struct class_device *class_dev, char *buf)
+{
+ struct video_device *vdev = to_video_device(class_dev);
+ struct usb_usbvision *usbvision = video_get_drvdata(vdev);
+ return sprintf(buf, "%s\n", YES_NO(usbvision->streaming));
+}
+static CLASS_DEVICE_ATTR(streaming, S_IRUGO, show_streaming, NULL);
+
+static ssize_t show_overlay(struct class_device *class_dev, char *buf)
+{
+ struct video_device *vdev = to_video_device(class_dev);
+ struct usb_usbvision *usbvision = video_get_drvdata(vdev);
+ return sprintf(buf, "%s\n", YES_NO(usbvision->overlay));
+}
+static CLASS_DEVICE_ATTR(overlay, S_IRUGO, show_overlay, NULL);
+
+static ssize_t show_compression(struct class_device *class_dev, char *buf)
+{
+ struct video_device *vdev = to_video_device(class_dev);
+ struct usb_usbvision *usbvision = video_get_drvdata(vdev);
+ return sprintf(buf, "%s\n", YES_NO(usbvision->isocMode==ISOC_MODE_COMPRESS));
+}
+static CLASS_DEVICE_ATTR(compression, S_IRUGO, show_compression, NULL);
+
+static ssize_t show_device_bridge(struct class_device *class_dev, char *buf)
+{
+ struct video_device *vdev = to_video_device(class_dev);
+ struct usb_usbvision *usbvision = video_get_drvdata(vdev);
+ return sprintf(buf, "%d\n", usbvision->bridgeType);
+}
+static CLASS_DEVICE_ATTR(bridge, S_IRUGO, show_device_bridge, NULL);
+
+static void usbvision_create_sysfs(struct video_device *vdev)
+{
+ if (vdev) {
+ video_device_create_file(vdev, &class_device_attr_version);
+ video_device_create_file(vdev, &class_device_attr_model);
+ video_device_create_file(vdev, &class_device_attr_hue);
+ video_device_create_file(vdev, &class_device_attr_contrast);
+ video_device_create_file(vdev, &class_device_attr_brightness);
+ video_device_create_file(vdev, &class_device_attr_saturation);
+ video_device_create_file(vdev, &class_device_attr_streaming);
+ video_device_create_file(vdev, &class_device_attr_overlay);
+ video_device_create_file(vdev, &class_device_attr_compression);
+ video_device_create_file(vdev, &class_device_attr_bridge);
+ }
+}
+
+static void usbvision_remove_sysfs(struct video_device *vdev)
+{
+ if (vdev) {
+ video_device_remove_file(vdev, &class_device_attr_version);
+ video_device_remove_file(vdev, &class_device_attr_model);
+ video_device_remove_file(vdev, &class_device_attr_hue);
+ video_device_remove_file(vdev, &class_device_attr_contrast);
+ video_device_remove_file(vdev, &class_device_attr_brightness);
+ video_device_remove_file(vdev, &class_device_attr_saturation);
+ video_device_remove_file(vdev, &class_device_attr_streaming);
+ video_device_remove_file(vdev, &class_device_attr_overlay);
+ video_device_remove_file(vdev, &class_device_attr_compression);
+ video_device_remove_file(vdev, &class_device_attr_bridge);
+ }
+}
+
+
+/*******************************/
+/* Memory management functions */
+/*******************************/
+
+/*
+ * Here we want the physical address of the memory.
+ * This is used when initializing the contents of the area.
+ */
+
+
+void *usbvision_rvmalloc(unsigned long size)
+{
+ void *mem;
+ unsigned long adr;
+
+ size = PAGE_ALIGN(size);
+ mem = vmalloc_32(size);
+ if (!mem)
+ return NULL;
+
+ memset(mem, 0, size); /* Clear the ram out, no junk to the user */
+ adr = (unsigned long) mem;
+ while (size > 0) {
+ #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
+ mem_map_reserve(vmalloc_to_page((void *)adr));
+ #else
+ SetPageReserved(vmalloc_to_page((void *)adr));
+ #endif
+ adr += PAGE_SIZE;
+ size -= PAGE_SIZE;
+ }
+
+ return mem;
+}
+
+void usbvision_rvfree(void *mem, unsigned long size)
+{
+ unsigned long adr;
+
+ if (!mem)
+ return;
+
+ adr = (unsigned long) mem;
+ while ((long) size > 0) {
+ #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
+ mem_map_unreserve(vmalloc_to_page((void *)adr));
+ #else
+ ClearPageReserved(vmalloc_to_page((void *)adr));
+ #endif
+ adr += PAGE_SIZE;
+ size -= PAGE_SIZE;
+ }
+ vfree(mem);
+}
+
+
+
+
+
+
+#if ENABLE_HEXDUMP
+static void usbvision_hexdump(const unsigned char *data, int len)
+{
+ char tmp[80];
+ int i, k;
+
+ for (i = k = 0; len > 0; i++, len--) {
+ if (i > 0 && (i % 16 == 0)) {
+ printk("%s\n", tmp);
+ k = 0;
+ }
+ k += sprintf(&tmp[k], "%02x ", data[i]);
+ }
+ if (k > 0)
+ printk("%s\n", tmp);
+}
+#endif
+
+
+/* These procedures handle the scratch ring buffer */
+int scratch_len(struct usb_usbvision *usbvision) /*This returns the amount of data actually in the buffer */
+{
+ int len = usbvision->scratch_write_ptr - usbvision->scratch_read_ptr;
+ if (len < 0) {
+ len += scratch_buf_size;
+ }
+ PDEBUG(DBG_SCRATCH, "scratch_len() = %d\n", len);
+
+ return len;
+}
+
+
+/* This returns the free space left in the buffer */
+int scratch_free(struct usb_usbvision *usbvision)
+