Commit 95f530f9 authored by Luca Risolia's avatar Luca Risolia Committed by Greg Kroah-Hartman

[PATCH] USB: add W996[87]CF driver

parent d0a2fba8
......@@ -2669,6 +2669,13 @@ S: Kasarmikatu 11 A4
S: 70110 Kuopio
S: Finland
N: Luca Risolia
E: luca_ing@libero.it
D: V4L driver for W996[87]CF JPEG USB Dual Mode Camera Chip
S: Via Libertà 41/a
S: Osio Sotto, 24046, Bergamo
S: Italy
N: William E. Roadcap
E: roadcapw@cfw.com
W: http://www.cfw.com/~roadcapw
......
W996[87]CF JPEG USB Dual Mode Camera Chip driver for Linux 2.6
==============================================================
- Documentation -
Index
=====
1. Copyright
2. License
3. Overview
4. Supported devices
5. Kernel configuration and third-part module compilation
6. Module loading
7. Module paramaters
8. Credits
1. Copyright
============
Copyright (C) 2002 2003 by Luca Risolia <luca_ing@libero.it>
2. License
==========
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.
3. Overview
===========
This driver supports the video streaming capabilities of the devices mounting
Winbond W9967CF and Winbond W9968CF JPEG USB Dual Mode Camera Chips, when they
are being commanded by USB.
The driver relies on the Video4Linux, USB and I2C core modules of the Linux
kernel, version 2.6.0 or greater, and is not compatible in any way with
previous versions. It has been designed to run properly on SMP systems
as well. At the moment, an additional module, "ovcamchip", is mandatory; it
provides support for some OmniVision CMOS sensors connected to the W996[87]CF
chips.
The driver is split into two modules: the basic one, "w9968cf", is needed for
the supported devices to work; the second one, "w9968cf-vpp", is an optional
module, which provides some useful video post-processing functions like video
decoding, up-scaling and colour conversions. These routines can't be included
into official kernels for performance purposes. Once the driver is installed,
every time an application tries to open a recognized device, "w9968cf" checks
the presence of the "w9968cf-vpp" module and loads it automatically by default.
Up to 32 cameras can be handled at the same time. They can be connected and
disconnected from the host many times without turning off the computer, if
your system supports the hotplug facility.
To change the default settings for each camera, many paramaters can be passed
through command line when the module is loaded into memory.
The latest and full featured version of the W996[87]CF driver can be found at:
http://go.lamarinapunto.com/
The "ovcamchip" module is part of the OV511 driver, version 2.25, which can be
downloaded from internet:
http://alpha.dyndns.org/ov511/
To know how to patch, compile and load it, read the paragraphs below.
4. Supported devices
====================
At the moment, known W996[87]CF based devices are:
- Aroma Digi Pen ADG-5000 Refurbished
- AVerTV USB
- Creative Labs Video Blaster WebCam Go
- Creative Labs Video Blaster WebCam Go Plus
- Die Lebon LDC-D35A Digital Kamera
- Ezonics EZ-802 EZMega Cam
- OPCOM Digi Pen VGA Dual Mode Pen Camera
If you know any other W996[87]CF based cameras, please contact me.
The list above does NOT imply that all those devices work with this driver: up
until now only webcams that have a CMOS sensor supported by the "ovcamchip"
module work.
For a list of supported CMOS sensors, please visit the module author homepage:
http://alpha.dyndns.org/ov511/
Possible external microcontrollers of those webcams are not supported: this
means that still images can't be downloaded from the device memory.
Furthermore, it's worth to note that I was only able to run tests on my
"Creative Labs Video Blaster WebCam Go". Donations of other models, for
additional testing and full support, would be much appreciated.
5. Kernel configuration and third-part module compilation
=========================================================
As noted above, kernel 2.6.0 is the minimum for this driver; for it to work
properly, the driver needs kernel support for Video4Linux, USB and I2C, and a
third-part module for the CMOS sensor.
The following options of the kernel configuration file must be enabled and
corresponding modules must be compiled:
# Multimedia devices
#
CONFIG_VIDEO_DEV=m
# I2C support
#
CONFIG_I2C=m
The I2C core module can be compiled statically in the kernel as well.
# USB support
#
CONFIG_USB=m
In addition, depending on the hardware being used, just one of the modules
below is necessary:
# USB Host Controller Drivers
#
CONFIG_USB_EHCI_HCD=m
CONFIG_USB_UHCI_HCD=m
CONFIG_USB_OHCI_HCD=m
Also, make sure "Enforce bandwidth allocation" is NOT enabled.
# USB Multimedia devices
#
CONFIG_USB_W9968CF=m
The last module we need is "ovcamchip.o". To obtain it, you have to download
the OV511 driver, version 2.25 - don't use other versions - which is available
at http://alpha.dyndns.org/ov511/ . Then you have to download the latest
version of the full featured W996[87]CF driver, which contains a patch for the
"ovcamchip" module; it is available at http://go.lamarinapunto.com .
Once you have obtained the packages, decompress, patch and compile the
"ovcamchip" module. In other words:
[user@localhost home]$ tar xvzf w9968cf-x.x.tar.gz
[user@localhost home]$ tar xvjf ov511-2.25.tar.bz2
[user@localhost home]$ cd ov511-2.25
[user@localhost ov511-2.25]$ patch -p1 < \
/path/to/w9968cf-x.x/ov511-2.25.patch
[user@localhost ov511-2.25]$ make
It's worth to note that the full featured version of the W996[87]CF driver
can also be installed overwriting the one in the kernel; in this case, read the
documentation included in the package.
If everything went well, the W996[87]CF driver can be immediatly used (see next
paragraph).
6. Module loading
=================
To use the driver, it is necessary to load the "w9968cf" module into memory
after every other module required.
For example, loading can be done this way, as root:
[root@localhost home]# modprobe usbcore
[root@localhost home]# modprobe i2c-core
[root@localhost ov511-x.xx]# insmod ./ovcamchip.ko
[root@localhost home]# modprobe w9968cf
At this point the devices should be recognized: "dmesg" can be used to analyze
kernel messages:
[user@localhost home]$ dmesg
There are a lot of parameters the module can use to change the default
settings for each device. To list every possible parameter with a brief
explanation about them and which syntax to use, it is recommended to run the
"modinfo" command:
[root@locahost home]# modinfo w9968cf
7. Module paramaters
====================
Module paramaters are listed below:
-------------------------------------------------------------------------------
Name: vppmod_load
Type: int
Syntax: <0|1>
Description: Automatic 'w9968cf-vpp' module loading: 0 disabled, 1 enabled.
If enabled, every time an application attempts to open a
camera, 'insmod' searches for the video post-processing module
in the system and loads it automatically (if present).
The 'w9968cf-vpp' module adds extra image manipulation
capabilities to the 'w9968cf' module,like software up-scaling,
colour conversions and video decoding.
Default: 1
-------------------------------------------------------------------------------
Name: simcams
Type: int
Syntax: <n>
Description: Number of cameras allowed to stream simultaneously.
n may vary from 0 to 32.
Default: 32
-------------------------------------------------------------------------------
Name: video_nr
Type: int array (min = 0, max = 32)
Syntax: <-1|n[,...]>
Description: Specify V4L minor mode number.
-1 = use next available
n = use minor number n
You can specify 32 cameras this way.
For example:
video_nr=-1,2,-1 would assign minor number 2 to the second
recognized camera and use auto for the first one and for every
other camera.
Default: -1
-------------------------------------------------------------------------------
Name: packet_size
Type: int array (min = 0, max = 32)
Syntax: <n[,...]>
Description: Specify the maximum data payload size in bytes for alternate
settings, for each device. n is scaled between 63 and 1023.
Default: 1023
-------------------------------------------------------------------------------
Name: max_buffers
Type: int array (min = 0, max = 32)
Syntax: <n[,...]>
Description: Only for advanced users.
Specify the maximum number of video frame buffers to allocate
for each device, from 2 to 32.
Default: 2
-------------------------------------------------------------------------------
Name: double_buffer
Type: int array (min = 0, max = 32)
Syntax: <0|1[,...]>
Description: Hardware double buffering: 0 disabled, 1 enabled.
It should be enabled if you want smooth video output: if you
obtain out of sync. video, disable it at all, or try to
decrease the 'clockdiv' module paramater value.
Default: 1 for every device.
-------------------------------------------------------------------------------
Name: clamping
Type: int array (min = 0, max = 32)
Syntax: <0|1[,...]>
Description: Video data clamping: 0 disabled, 1 enabled.
Default: 0 for every device.
-------------------------------------------------------------------------------
Name: filter_type
Type: int array (min = 0, max = 32)
Syntax: <0|1|2[,...]>
Description: Video filter type.
0 none, 1 (1-2-1) 3-tap filter, 2 (2-3-6-3-2) 5-tap filter.
The filter is used to reduce noise and aliasing artifacts
produced by the CCD or CMOS sensor.
Default: 0 for every device.
-------------------------------------------------------------------------------
Name: largeview
Type: int array (min = 0, max = 32)
Syntax: <0|1[,...]>
Description: Large view: 0 disabled, 1 enabled.
Default: 1 for every device.
-------------------------------------------------------------------------------
Name: upscaling
Type: int array (min = 0, max = 32)
Syntax: <0|1[,...]>
Description: Software scaling (for non-compressed video only):
0 disabled, 1 enabled.
Disable it if you have a slow CPU or you don't have enough
memory.
Default: 0 for every device.
Note: If 'w9968cf-vpp' is not loaded, this paramater is set to 0.
-------------------------------------------------------------------------------
Name: decompression
Type: int array (min = 0, max = 32)
Syntax: <0|1|2[,...]>
Description: Software video decompression:
0 = disables decompression
(doesn't allow formats needing decompression).
1 = forces decompression
(allows formats needing decompression only).
2 = allows any permitted formats.
Formats supporting (de)compressed video are YUV422P and
YUV420P/YUV420 in any resolutions where width and height are
multiples of 16.
Default: 2 for every device.
Note: If 'w9968cf-vpp' is not loaded, forcing decompression is not
allowed; in this case this paramater is set to 2.
-------------------------------------------------------------------------------
Name: force_palette
Type: int array (min = 0, max = 32)
Syntax: <0|9|10|13|15|8|7|1|6|3|4|5[,...]>
Description: Force picture palette.
In order:
0 = Off - allows any of the following formats:
9 = UYVY 16 bpp - Original video, compression disabled
10 = YUV420 12 bpp - Original video, compression enabled
13 = YUV422P 16 bpp - Original video, compression enabled
15 = YUV420P 12 bpp - Original video, compression enabled
8 = YUVY 16 bpp - Software conversion from UYVY
7 = YUV422 16 bpp - Software conversion from UYVY
1 = GREY 8 bpp - Software conversion from UYVY
6 = RGB555 16 bpp - Software conversion from UYVY
3 = RGB565 16 bpp - Software conversion from UYVY
4 = RGB24 24 bpp - Software conversion from UYVY
5 = RGB32 32 bpp - Software conversion from UYVY
When not 0, this paramater will override 'decompression'.
Default: 0 for every device. Initial palette is 9 (UYVY).
Note: If 'w9968cf-vpp' is not loaded, this paramater is set to 9.
-------------------------------------------------------------------------------
Name: force_rgb
Type: int array (min = 0, max = 32)
Syntax: <0|1[,...]>
Description: Read RGB video data instead of BGR:
1 = use RGB component ordering.
0 = use BGR component ordering.
This parameter has effect when using RGBX palettes only.
Default: 0 for every device.
-------------------------------------------------------------------------------
Name: autobright
Type: long array (min = 0, max = 32)
Syntax: <0|1[,...]>
Description: CMOS sensor automatically changes brightness:
0 = no, 1 = yes
Default: 0 for every device.
-------------------------------------------------------------------------------
Name: autoexp
Type: long array (min = 0, max = 32)
Syntax: <0|1[,...]>
Description: CMOS sensor automatically changes exposure:
0 = no, 1 = yes
Default: 1 for every device.
-------------------------------------------------------------------------------
Name: lightfreq
Type: long array (min = 0, max = 32)
Syntax: <50|60[,...]>
Description: Light frequency in Hz:
50 for European and Asian lighting, 60 for American lighting.
Default: 50 for every device.
-------------------------------------------------------------------------------
Name: bandingfilter
Type: long array (min = 0, max = 32)
Syntax: <0|1[,...]>
Description: Banding filter to reduce effects of fluorescent
lighting:
0 disabled, 1 enabled.
This filter tries to reduce the pattern of horizontal
light/dark bands caused by some (usually fluorescent) lighting.
Default: 0 for every device.
-------------------------------------------------------------------------------
Name: clockdiv
Type: long array (min = 0, max = 32)
Syntax: <-1|n[,...]>
Description: Force pixel clock divisor to a specific value (for experts):
n may vary from 0 to 127.
-1 for automatic value.
See also the 'double_buffer' module paramater.
Default: -1 for every device.
-------------------------------------------------------------------------------
Name: backlight
Type: long array (min = 0, max = 32)
Syntax: <0|1[,...]>
Description: Objects are lit from behind:
0 = no, 1 = yes
Default: 0 for every device.
-------------------------------------------------------------------------------
Name: mirror
Type: long array (min = 0, max = 32)
Syntax: <0|1[,...]>
Description: Reverse image horizontally:
0 = no, 1 = yes
Default: 0 for every device.
-------------------------------------------------------------------------------
Name: sensor_mono
Type: long array (min = 0, max = 32)
Syntax: <0|1[,...]>
Description: The CMOS sensor is monochrome:
0 = no, 1 = yes
Default: 0 for every device.
-------------------------------------------------------------------------------
Name: brightness
Type: long array (min = 0, max = 32)
Syntax: <n[,...]>
Description: Set picture brightness (0-65535).
This parameter has no effect if 'autobright' is enabled.
Default: 31000 for every device.
-------------------------------------------------------------------------------
Name: hue
Type: long array (min = 0, max = 32)
Syntax: <n[,...]>
Description: Set picture hue (0-65535).
Default: 32768 for every device.
-------------------------------------------------------------------------------
Name: colour
Type: long array (min = 0, max = 32)
Syntax: <n[,...]>
Description: Set picture saturation (0-65535).
Default: 32768 for every device.
-------------------------------------------------------------------------------
Name: contrast
Type: long array (min = 0, max = 32)
Syntax: <n[,...]>
Description: Set picture contrast (0-65535).
Default: 50000 for every device.
-------------------------------------------------------------------------------
Name: whiteness
Type: long array (min = 0, max = 32)
Syntax: <n[,...]>
Description: Set picture whiteness (0-65535).
Default: 32768 for every device.
-------------------------------------------------------------------------------
Name: debug
Type: int
Syntax: <n>
Description: Debugging information level, from 0 to 6:
0 = none (be cautious)
1 = critical errors
2 = significant informations
3 = configuration or general messages
4 = warnings
5 = called functions
6 = function internals
Level 5 and 6 are useful for testing only, when just one
device is used.
Default: 2
-------------------------------------------------------------------------------
Name: specific_debug
Type: int
Syntax: <0|1>
Description: Enable or disable specific debugging messages:
0 = print messages concerning every level <= 'debug' level.
1 = print messages concerning the level indicated by 'debug'.
Default: 0
-------------------------------------------------------------------------------
8. Credits
==========
The development would not have proceed much further without having looked at
the source code of other drivers and without the help of several persons; in
particular:
- the I2C interface to kernel and high-level CMOS sensor control routines have
been taken from the OV511 driver by Mark McClelland;
- memory management code has been copied from the bttv driver by Ralph Metzler,
Marcus Metzler and Gerd Knorr;
- the low-level I2C read function has been written by Frédéric Jouault, who
also gave me commented logs about sniffed USB traffic taken from another
driver for another system;
- the low-level I2C fast write function has been written by Piotr Czerczak;
......@@ -2207,6 +2207,13 @@ M: dbrownell@users.sourceforge.net
L: linux-usb-devel@lists.sourceforge.net
S: Maintained
USB W996[87]CF DRIVER
P: Luca Risolia
M: luca_ing@libero.it
L: linux-usb-devel@lists.sourceforge.net
W: http://go.lamarinapunto.com
S: Maintained
USER-MODE LINUX
P: Jeff Dike
M: jdike@karaya.com
......
......@@ -34,6 +34,7 @@ obj-$(CONFIG_USB_PWC) += media/
obj-$(CONFIG_USB_SE401) += media/
obj-$(CONFIG_USB_STV680) += media/
obj-$(CONFIG_USB_VICAM) += media/
obj-$(CONFIG_USB_W9968CF) += media/
obj-$(CONFIG_USB_CATC) += net/
obj-$(CONFIG_USB_KAWETH) += net/
......@@ -58,4 +59,3 @@ obj-$(CONFIG_USB_SPEEDTOUCH) += misc/
obj-$(CONFIG_USB_TEST) += misc/
obj-$(CONFIG_USB_TIGL) += misc/
obj-$(CONFIG_USB_USS720) += misc/
......@@ -177,3 +177,30 @@ config USB_STV680
To compile this driver as a module, choose M here: the
module will be called stv680.
config USB_W9968CF
tristate "USB W996[87]CF JPEG Dual Mode Camera support"
depends on USB && VIDEO_DEV && I2C
---help---
Say Y here if you want support for cameras based on
Winbond W9967CF/W9968CF JPEG USB Dual Mode Camera Chips.
This driver has an optional plugin, which is distributed as a
separate module only (released under GPL). It contains code that
allows you to use higher resolutions and framerates, and can't
be included into the official Linux kernel for performance
purposes.
At the moment the driver needs a third-part module for the CMOS
sensors, which is available on internet: it is recommended to read
<file:Documentation/usb/w9968cf.txt> for more informations and for
a list of supported cameras.
This driver uses the Video For Linux and the I2C APIs.
You must say Y or M to both "Video For Linux" and
"I2C Support" to use this driver.
Information on this API and pointers to "v4l" programs may be found
on the WWW at <http://roadrunner.swansea.uk.linux.org/v4l.shtml>.
This code is also available as a module ( = code which can be
inserted in and removed from the running kernel whenever you want).
The module will be called w9968cf.o. If you want to compile it as a
module, say M here and read <file:Documentation/modules.txt>.
......@@ -13,3 +13,4 @@ obj-$(CONFIG_USB_PWC) += pwc.o
obj-$(CONFIG_USB_SE401) += se401.o
obj-$(CONFIG_USB_STV680) += stv680.o
obj-$(CONFIG_USB_VICAM) += vicam.o usbvideo.o
obj-$(CONFIG_USB_W9968CF) += w9968cf.o
This source diff could not be displayed because it is too large. You can view the blob instead.
/***************************************************************************
* Video4Linux driver for W996[87]CF JPEG USB Dual Mode Camera Chip. *
* *
* Copyright (C) 2002 2003 by Luca Risolia <luca_ing@libero.it> *
* *
* 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. *
***************************************************************************/
#ifndef _W9968CF_H_
#define _W9968CF_H_
#include <linux/videodev.h>
#include <linux/usb.h>
#include <linux/i2c.h>
#include <linux/spinlock.h>
#include <linux/list.h>
#include <linux/wait.h>
#include <linux/config.h>
#include <asm/semaphore.h>
#include <asm/types.h>
#include "w9968cf_externaldef.h"
/****************************************************************************
* Default values *
****************************************************************************/
#define W9968CF_VPPMOD_LOAD 1 /* automatic 'w9968cf-vpp' module loading */
/* Comment/uncomment the following line to enable/disable debugging messages */
#define W9968CF_DEBUG
/* These have effect only if W9968CF_DEBUG is defined */
#define W9968CF_DEBUG_LEVEL 2 /* from 0 to 6. 0 for no debug informations */
#define W9968CF_SPECIFIC_DEBUG 0 /* 0 or 1 */
#define W9968CF_MAX_DEVICES 32
#define W9968CF_SIMCAMS W9968CF_MAX_DEVICES /* simultaneous cameras */
#define W9968CF_MAX_BUFFERS 32
#define W9968CF_BUFFERS 2 /* n. of frame buffers from 2 to MAX_BUFFERS */
/* Maximum data payload sizes in bytes for alternate settings */
static const u16 wMaxPacketSize[] = {1023, 959, 895, 831, 767, 703, 639, 575,
511, 447, 383, 319, 255, 191, 127, 63};
#define W9968CF_PACKET_SIZE 1023 /* according to wMaxPacketSizes[] */
#define W9968CF_MIN_PACKET_SIZE 63 /* minimum value */
#define W9968CF_ISO_PACKETS 5 /* n.of packets for isochronous transfers */
#define W9968CF_USB_CTRL_TIMEOUT HZ /* timeout for usb control commands */
#define W9968CF_URBS 2 /* n. of scheduled URBs for ISO transfer */
#define W9968CF_I2C_BUS_DELAY 4 /* delay in us for I2C bit r/w operations */
#define W9968CF_I2C_RW_RETRIES 15 /* number of max I2C r/w retries */
/* Available video formats */
struct w9968cf_format {
const u16 palette;
const u16 depth;
const u8 compression;
};
static const struct w9968cf_format w9968cf_formatlist[] = {
{ VIDEO_PALETTE_UYVY, 16, 0 }, /* original video */
{ VIDEO_PALETTE_YUV422P, 16, 1 }, /* with JPEG compression */
{ VIDEO_PALETTE_YUV420P, 12, 1 }, /* with JPEG compression */
{ VIDEO_PALETTE_YUV420, 12, 1 }, /* same as YUV420P */
{ VIDEO_PALETTE_YUYV, 16, 0 }, /* software conversion */
{ VIDEO_PALETTE_YUV422, 16, 0 }, /* software conversion */
{ VIDEO_PALETTE_GREY, 8, 0 }, /* software conversion */
{ VIDEO_PALETTE_RGB555, 16, 0 }, /* software conversion */
{ VIDEO_PALETTE_RGB565, 16, 0 }, /* software conversion */
{ VIDEO_PALETTE_RGB24, 24, 0 }, /* software conversion */
{ VIDEO_PALETTE_RGB32, 32, 0 }, /* software conversion */
{ 0, 0, 0 } /* 0 is a terminating entry */
};
#define W9968CF_DECOMPRESSION 2 /* decomp:0=disable,1=force,2=any formats */
#define W9968CF_PALETTE_DECOMP_OFF VIDEO_PALETTE_UYVY /* when decomp=0 */
#define W9968CF_PALETTE_DECOMP_FORCE VIDEO_PALETTE_YUV420P /* when decomp=1 */
#define W9968CF_PALETTE_DECOMP_ON VIDEO_PALETTE_UYVY /* when decomp=2 */
#define W9968CF_FORCE_RGB 0 /* read RGB instead of BGR, yes=1/no=0 */
#define W9968CF_MAX_WIDTH 800 /* should be >= 640 */
#define W9968CF_MAX_HEIGHT 600 /* should be >= 480 */
#define W9968CF_WIDTH 320 /* from 128 to 352, multiple of 16 */
#define W9968CF_HEIGHT 240 /* from 96 to 288, multiple of 16 */
#define W9968CF_CLAMPING 0 /* 0 disable, 1 enable video data clamping */
#define W9968CF_FILTER_TYPE 0 /* 0 disable 1 (1-2-1), 2 (2-3-6-3-2) */
#define W9968CF_DOUBLE_BUFFER 1 /* 0 disable, 1 enable double buffer */
#define W9968CF_LARGEVIEW 1 /* 0 disable, 1 enable */
#define W9968CF_UPSCALING 0 /* 0 disable, 1 enable */
#define W9968CF_SENSOR_MONO 0 /* 0 not monochrome, 1 monochrome sensor */
#define W9968CF_BRIGHTNESS 31000 /* from 0 to 65535 */
#define W9968CF_HUE 32768 /* from 0 to 65535 */
#define W9968CF_COLOUR 32768 /* from 0 to 65535 */
#define W9968CF_CONTRAST 50000 /* from 0 to 65535 */
#define W9968CF_WHITENESS 32768 /* from 0 to 65535 */
#define W9968CF_AUTOBRIGHT 0 /* 0 disable, 1 enable automatic brightness */
#define W9968CF_AUTOEXP 1 /* 0 disable, 1 enable automatic exposure */
#define W9968CF_LIGHTFREQ 50 /* light frequency. 50Hz (Europe) or 60Hz */
#define W9968CF_BANDINGFILTER 0 /* 0 disable, 1 enable banding filter */
#define W9968CF_BACKLIGHT 0 /* 0 or 1, 1=object is lit from behind */
#define W9968CF_MIRROR 0 /* 0 or 1 [don't] reverse image horizontally*/
#define W9968CF_CLOCKDIV -1 /* -1 = automatic clock divisor */
#define W9968CF_DEF_CLOCKDIVISOR 0 /* default sensor clock divisor value */
/****************************************************************************
* Globals *
****************************************************************************/
#define W9968CF_MODULE_NAME "V4L driver for W996[87]CF JPEG USB " \
"Dual Mode Camera Chip"
#define W9968CF_MODULE_VERSION "v1.22"
#define W9968CF_MODULE_AUTHOR "(C) 2002 2003 Luca Risolia"
#define W9968CF_AUTHOR_EMAIL "<luca_ing@libero.it>"
static u8 w9968cf_vppmod_present; /* status flag: yes=1, no=0 */
static const struct usb_device_id winbond_id_table[] = {
{
/* Creative Labs Video Blaster WebCam Go Plus */
USB_DEVICE(0x041e, 0x4003),
.driver_info = (unsigned long)"w9968cf",
},
{
/* Generic W996[87]CF JPEG USB Dual Mode Camera */
USB_DEVICE(0x1046, 0x9967),
.driver_info = (unsigned long)"w9968cf",
},
{ } /* terminating entry */
};
MODULE_DEVICE_TABLE(usb, winbond_id_table);
/* W996[87]CF camera models, internal ids: */
enum w9968cf_model_id {
W9968CF_MOD_GENERIC = 1, /* Generic W996[87]CF based device */
W9968CF_MOD_CLVBWGP = 11,/*Creative Labs Video Blaster WebCam Go Plus*/
W9968CF_MOD_ADPA5R = 21, /* Aroma Digi Pen ADG-5000 Refurbished */
W9986CF_MOD_AU = 31, /* AVerTV USB */
W9968CF_MOD_CLVBWG = 34, /* Creative Labs Video Blaster WebCam Go */
W9968CF_MOD_DLLDK = 37, /* Die Lebon LDC-D35A Digital Kamera */
W9968CF_MOD_EEEMC = 40, /* Ezonics EZ-802 EZMega Cam */
W9968CF_MOD_ODPVDMPC = 43,/* OPCOM Digi Pen VGA Dual Mode Pen Camera */
};
enum w9968cf_frame_status {
F_READY, /* finished grabbing & ready to be read/synced */
F_GRABBING, /* in the process of being grabbed into */
F_ERROR, /* something bad happened while processing */
F_UNUSED /* unused (no VIDIOCMCAPTURE) */
};
struct w9968cf_frame_t {
void* buffer;
u32 length;
enum w9968cf_frame_status status;
struct w9968cf_frame_t* next;
u8 queued;
};
enum w9968cf_vpp_flag {
VPP_NONE = 0x00,
VPP_UPSCALE = 0x01,
VPP_SWAP_YUV_BYTES = 0x02,
VPP_DECOMPRESSION = 0x04,
VPP_UYVY_TO_RGBX = 0x08,
};
struct list_head w9968cf_dev_list; /* head of V4L registered cameras list */
LIST_HEAD(w9968cf_dev_list);
struct semaphore w9968cf_devlist_sem; /* semaphore for list traversal */
/* Main device driver structure */
struct w9968cf_device {
enum w9968cf_model_id id; /* private device identifier */
struct video_device v4ldev; /* V4L structure */
struct list_head v4llist; /* entry of the list of V4L cameras */
struct usb_device* usbdev; /* -> main USB structure */
struct urb* urb[W9968CF_URBS]; /* -> USB request block structs */
void* transfer_buffer[W9968CF_URBS]; /* -> ISO transfer buffers */
u16* control_buffer; /* -> buffer for control req.*/
u16* data_buffer; /* -> data to send to the FSB */
struct w9968cf_frame_t frame[W9968CF_MAX_BUFFERS];
struct w9968cf_frame_t frame_tmp; /* temporary frame */
struct w9968cf_frame_t* frame_current; /* -> frame being grabbed */
struct w9968cf_frame_t* requested_frame[W9968CF_MAX_BUFFERS];
void* vpp_buffer; /* -> helper buffer for post-processing routines */
u8 max_buffers, /* number of requested buffers */
force_palette, /* yes=1/no=0 */
force_rgb, /* read RGB instead of BGR, yes=1, no=0 */
double_buffer, /* hardware double buffering yes=1/no=0 */
clamping, /* video data clamping yes=1/no=0 */
filter_type, /* 0=disabled, 1=3 tap, 2=5 tap filter */
capture, /* 0=disabled, 1=enabled */
largeview, /* 0=disabled, 1=enabled */
decompression, /* 0=disabled, 1=forced, 2=allowed */
upscaling; /* software image scaling, 0=enabled, 1=disabled */
struct video_picture picture; /* current window settings */
struct video_window window; /* current picture settings */
u16 hw_depth, /* depth (used by the chip) */
hw_palette, /* palette (used by the chip) */
hw_width, /* width (used by the chip) */
hw_height, /* height (used by the chip) */
hs_polarity, /* 0=negative sync pulse, 1=positive sync pulse */
vs_polarity; /* 0=negative sync pulse, 1=positive sync pulse */
enum w9968cf_vpp_flag vpp_flag; /* post-processing routines in use */
u8 nbuffers, /* number of allocated frame buffers */
altsetting, /* camera alternate setting */
disconnected, /* flag: yes=1, no=0 */
misconfigured, /* flag: yes=1, no=0 */
users, /* flag: number of users holding the device */
streaming; /* flag: yes=1, no=0 */
int sensor; /* type of image CMOS sensor chip (CC_*) */
/* Determined by CMOS sensor type */
u16 maxwidth,
maxheight,
minwidth,
minheight,
start_cropx,
start_cropy;
u8 auto_brt, /* auto brightness enabled flag */
auto_exp, /* auto exposure enabled flag */
backlight, /* backlight exposure algorithm flag */
mirror, /* image is reversed horizontally */
lightfreq, /* power (lighting) frequency */
bandfilt; /* banding filter enabled flag */
s8 clockdiv; /* clock divisor */
int sensor_mono; /* CMOS sensor is (probably) monochrome */
/* I2C interface to kernel */
struct i2c_adapter i2c_adapter;
struct i2c_client* sensor_client;
/* Locks */
struct semaphore dev_sem, /* for probe, disconnect,open and close */
fileop_sem; /* for read and ioctl */
spinlock_t urb_lock, /* for submit_urb() and unlink_urb() */
flist_lock; /* for requested frame list accesses */
char command[16]; /* name of the program holding the device */
wait_queue_head_t open, wait_queue;
};
#define W9968CF_HW_BUF_SIZE 640*480*2 /* buf. size for original video frames */
#define SENSOR_FORMAT VIDEO_PALETTE_UYVY
#define SENSOR_FATAL_ERROR(rc) ((rc) < 0 && (rc) != -EPERM)
/****************************************************************************
* Macros and other constants *
****************************************************************************/
#undef DBG
#ifdef W9968CF_DEBUG
# define DBG(level, fmt, args...) \
{ \
if ( ((specific_debug) && (debug == (level))) || \
((!specific_debug) && (debug >= (level))) ) { \
if ((level) == 1) \
err(fmt, ## args); \
else if ((level) == 2 || (level) == 3) \
info(fmt, ## args); \
else if ((level) == 4) \
warn(fmt, ## args); \
else if ((level) >= 5) \
info("[%s,%d] " fmt, \
__PRETTY_FUNCTION__, __LINE__ , ## args); \
} \
}
#else
/* Not debugging: nothing */
# define DBG(level, fmt, args...) do {;} while(0);
#endif
#undef PDBG
#undef PDBGG
#define PDBG(fmt, args...) info("[%s, %d] "fmt, \
__PRETTY_FUNCTION__, __LINE__ , ## args);
#define PDBGG(fmt, args...) do {;} while(0); /* nothing: it's a placeholder */
#endif /* _W9968CF_H_ */
/***************************************************************************
* Video decoder for the W996[87]CF driver for Linux. *
* *
* Copyright (C) 2003 by Luca Risolia <luca_ing@libero.it> *
* *
* 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. *
***************************************************************************/
#ifndef _W9968CF_DECODER_H_
#define _W9968CF_DECODER_H_
/* Comment/uncomment this for high/low quality of compressed video */
#define W9968CF_DEC_FAST_LOWQUALITY_VIDEO
#ifdef W9968CF_DEC_FAST_LOWQUALITY_VIDEO
static const unsigned char Y_QUANTABLE[64] = {
16, 11, 10, 16, 24, 40, 51, 61,
12, 12, 14, 19, 26, 58, 60, 55,
14, 13, 16, 24, 40, 57, 69, 56,
14, 17, 22, 29, 51, 87, 80, 62,
18, 22, 37, 56, 68, 109, 103, 77,
24, 35, 55, 64, 81, 104, 113, 92,
49, 64, 78, 87, 103, 121, 120, 101,
72, 92, 95, 98, 112, 100, 103, 99
};
static const unsigned char UV_QUANTABLE[64] = {
17, 18, 24, 47, 99, 99, 99, 99,
18, 21, 26, 66, 99, 99, 99, 99,
24, 26, 56, 99, 99, 99, 99, 99,
47, 66, 99, 99, 99, 99, 99, 99,
99, 99, 99, 99, 99, 99, 99, 99,
99, 99, 99, 99, 99, 99, 99, 99,
99, 99, 99, 99, 99, 99, 99, 99,
99, 99, 99, 99, 99, 99, 99, 99
};
#else
static const unsigned char Y_QUANTABLE[64] = {
8, 5, 5, 8, 12, 20, 25, 30,
6, 6, 7, 9, 13, 29, 30, 27,
7, 6, 8, 12, 20, 28, 34, 28,
7, 8, 11, 14, 25, 43, 40, 31,
9, 11, 18, 28, 34, 54, 51, 38,
12, 17, 27, 32, 40, 52, 56, 46,
24, 32, 39, 43, 51, 60, 60, 50,
36, 46, 47, 49, 56, 50, 51, 49
};
static const unsigned char UV_QUANTABLE[64] = {
8, 9, 12, 23, 49, 49, 49, 49,
9, 10, 13, 33, 49, 49, 49, 49,
12, 13, 28, 49, 49, 49, 49, 49,
23, 33, 49, 49, 49, 49, 49, 49,
49, 49, 49, 49, 49, 49, 49, 49,
49, 49, 49, 49, 49, 49, 49, 49,
49, 49, 49, 49, 49, 49, 49, 49,
49, 49, 49, 49, 49, 49, 49, 49
};
#endif
#define W9968CF_DEC_ERR_CORRUPTED_DATA -1
#define W9968CF_DEC_ERR_BUF_OVERFLOW -2
#define W9968CF_DEC_ERR_NO_SOI -3
#define W9968CF_DEC_ERR_NO_SOF0 -4
#define W9968CF_DEC_ERR_NO_SOS -5
#define W9968CF_DEC_ERR_NO_EOI -6
extern void w9968cf_init_decoder(void);
extern int w9968cf_check_headers(const unsigned char* Pin,
const unsigned long BUF_SIZE);
extern int w9968cf_decode(const char* Pin, const unsigned long BUF_SIZE,
const unsigned W, const unsigned H, char* Pout);
#endif /* _W9968CF_DECODER_H_ */
/***************************************************************************
* Various definitions for compatibility with external modules. *
* This file is part of the W996[87]CF driver for Linux. *
* *
* Copyright (C) 2002 2003 by Luca Risolia <luca_ing@libero.it> *
* *
* 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. *
***************************************************************************/
#ifndef _W9968CF_EXTERNALDEF_H_
#define _W9968CF_EXTERNALDEF_H_
#include <linux/videodev.h>
#include <linux/i2c.h>
#include <asm/ioctl.h>
#include <asm/types.h>
/* The following values have been copied from the "ovcamchip" module. */
#ifndef I2C_DRIVERID_OVCAMCHIP
# define I2C_DRIVERID_OVCAMCHIP 0xf00f
#endif
/* Controls */
enum {
OVCAMCHIP_CID_CONT, /* Contrast */
OVCAMCHIP_CID_BRIGHT, /* Brightness */
OVCAMCHIP_CID_SAT, /* Saturation */
OVCAMCHIP_CID_HUE, /* Hue */
OVCAMCHIP_CID_EXP, /* Exposure */
OVCAMCHIP_CID_FREQ, /* Light frequency */
OVCAMCHIP_CID_BANDFILT, /* Banding filter */
OVCAMCHIP_CID_AUTOBRIGHT, /* Auto brightness */
OVCAMCHIP_CID_AUTOEXP, /* Auto exposure */
OVCAMCHIP_CID_BACKLIGHT, /* Back light compensation */
OVCAMCHIP_CID_MIRROR, /* Mirror horizontally */
};
/* I2C addresses */
#define OV7xx0_SID (0x42 >> 1)
#define OV6xx0_SID (0xC0 >> 1)
/* Sensor types */
enum {
CC_UNKNOWN,
CC_OV76BE,
CC_OV7610,
CC_OV7620,
CC_OV7620AE,
CC_OV6620,
CC_OV6630,
CC_OV6630AE,
CC_OV6630AF,
};
/* API */
struct ovcamchip_control {
__u32 id;
__s32 value;
};
struct ovcamchip_window {
int x;
int y;
int width;
int height;
int format;
int quarter; /* Scale width and height down 2x */
/* This stuff will be removed eventually */
int clockdiv; /* Clock divisor setting */
};
/* Commands.
You must call OVCAMCHIP_CMD_INITIALIZE before any of other commands */
#define OVCAMCHIP_CMD_Q_SUBTYPE _IOR (0x88, 0x00, int)
#define OVCAMCHIP_CMD_INITIALIZE _IOW (0x88, 0x01, int)
#define OVCAMCHIP_CMD_S_CTRL _IOW (0x88, 0x02, struct ovcamchip_control)
#define OVCAMCHIP_CMD_G_CTRL _IOWR (0x88, 0x03, struct ovcamchip_control)
#define OVCAMCHIP_CMD_S_MODE _IOW (0x88, 0x04, struct ovcamchip_window)
#define OVCAMCHIP_MAX_CMD _IO (0x88, 0x3f)
#endif /* _W9968CF_EXTERNALDEF_H_ */
......@@ -258,6 +258,7 @@
#define I2C_HW_SMBUS_AMD8111 0x0a
#define I2C_HW_SMBUS_SCX200 0x0b
#define I2C_HW_SMBUS_NFORCE2 0x0c
#define I2C_HW_SMBUS_W9968CF 0x0d
/* --- ISA pseudo-adapter */
#define I2C_HW_ISA 0x00
......
......@@ -429,6 +429,7 @@ struct video_code
#define VID_HARDWARE_CPIA2 33
#define VID_HARDWARE_VICAM 34
#define VID_HARDWARE_SF16FMR2 35
#define VID_HARDWARE_W9968CF 36 /* W996[87]CF JPEG USB Dual Mode Cam */
#endif /* __LINUX_VIDEODEV_H */
/*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment