
                   W996[87]CF JPEG USB Dual Mode Camera Chip 
                         Full-featured driver for Linux
                   =========================================

                               - Documentation -


Index
=====
1.  Copyright
2.  Disclaimer
3.  License
4.  Overview
5.  Supported devices
6.  Driver installation
7.  Module loading
8.  Module paramaters
9.  Device control through "procfs" under Linux 2.4
10. Contact information
11. Credits


1. Copyright
============
Copyright (C) 2002-2005 by Luca Risolia <luca.risolia@studio.unibo.it>


2. Disclaimer
=============
Winbond is a trademark of Winbond Electronics Corporation.
This software is not sponsored or developed by Winbond.


3. 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.


4. Overview
===========
This driver supports the video streaming capabilities of the devices mounting
Winbond W9967CF and Winbond W9968CF JPEG USB Dual Mode Camera Chips. OV681
based cameras should be supported as well.

The driver is divided 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. 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.

Please keep in mind that official kernels do not include the second module for
performance purposes. However it is always recommended to download and install
the latest and complete release of the driver, replacing the existing one, if
present: it will be still even possible not to load the "w9968cf-vpp" module at
all, if you ever want to. Another important missing feature of the version in
the official Linux 2.4 kernels is the writeable /proc filesystem interface.

The latest and full-featured version of the W996[87]CF driver can be found at:
http://www.linux-projects.org/

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 parameters can be passed
through command line when the module is loaded into memory. They can also be
fine-tuned through the /proc filesystem interface (see later).

The driver relies on the Video4Linux, USB and I2C core modules of the official
and stable Linux kernels, version 2.4.20 or greater, and is not compatible in
any way with previous versions. It has been designed to run properly on SMP
systems as well. An additional module, "ovcamchip", is mandatory; it provides
support for some OmniVision image sensors connected to the W996[87]CF chips;
if found in the system, the module will be automatically loaded by default
(provided that the kernel has been compiled with the automatic module loading
option).

Under versions of the Linux kernel prior to 2.6.8, the "ovcamchip" module,
which is part the OV511 project for Linux, has to be downloaded from internet
at http://linux-projects.org/
To know how to compile and install it, read the documentation included in the
package.

On the contrary, make sure you are not actually using any external "ovcamchip"
module under Linux 2.6.8 or higher, given that now the W996[87]CF driver 
depends on the "ovcamchip" module already present in the official kernels.


5. Supported devices
====================
At the moment, known W996[87]CF and OV681 based devices are:
- Aroma Digi Pen VGA Dual Mode ADG-5000 (unknown image sensor)
- AVerMedia AVerTV USB (SAA7111A, Philips FI1216Mk2 tuner, PT2313L audio chip)
- Creative Labs Video Blaster WebCam Go (OmniVision OV7610 sensor)
- Creative Labs Video Blaster WebCam Go Plus (OmniVision OV7620 sensor)
- Lebon LDC-035A (unknown image sensor)
- Ezonics EZ-802 EZMega Cam (OmniVision OV8610C sensor)
- OmniVision OV8610-EDE (OmniVision OV8610 sensor)
- OPCOM Digi Pen VGA Dual Mode Pen Camera (unknown image sensor)
- Pretec Digi Pen-II (OmniVision OV7620 sensor)
- Pretec DigiPen-480 (OmniVision OV8610 sensor)

If you know any other W996[87]CF or OV681 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 an image sensor supported by the "ovcamchip"
module work. Kernel messages will always tell you whether this is case.

Possible external microcontrollers of those webcams are not supported: this
means that still images cannot 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.


6. Driver installation
======================
As noted above, kernel 2.4.20 is the minimum for this driver; for it to work
properly, the driver needs kernel support for Video4Linux, USB and I2C, and the
"ovcamchip" module for the image 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.

From Linux 2.6.8 on, you have to build the "ovcamchip" module included in the
kernel:

	# OmniVision Camera Chip support
	#
	CONFIG_VIDEO_OVCAMCHIP=m

	# USB support
	#
	CONFIG_USB=m

In addition, depending on the hardware being used, only one of the modules
below is necessary:

- for Linux 2.4 series:
	# USB Host Controller Drivers
	#
	CONFIG_USB_EHCI_HCD=m
	CONFIG_USB_UHCI=m
	CONFIG_USB_UHCI_ALT=m
	CONFIG_USB_OHCI=m

- for Linux 2.6 series:
	# USB Host Controller Drivers
	#
	CONFIG_USB_EHCI_HCD=m
	CONFIG_USB_UHCI_HCD=m
	CONFIG_USB_OHCI_HCD=m

Under Linux 2.4, the /proc filesystem can be optionally built into the kernel:

	# File systems
	#
	CONFIG_PROC_FS=y

	# Video For Linux
	#
	CONFIG_VIDEO_PROC_FS=y

For versions of the kernels earlier than 2.6.8, to obtain the required
"ovcamchip" module, you have to download the version of the OV511 package
available at http://www.linux-projects.org/ - do not use other versions - and
compile it according to its documentation.

Moving along to the W996[87]CF driver: after having downloaded the package,
decompress and compile:

	[user@localhost home]$ tar xvzf w9968cf-x.x.tar.gz
	[user@localhost home]$ cd w9968cf-x.x

(where "x.x" has to be substituted with the right version of the module just
downloaded)

Typing "make help" will print a list of available commands.

It is necessary to properly configure your particular kernel source tree before
compiling the driver. Under Linux 2.4, this is accomplished by invoking the
usual "make config dep" as part of the kernel compilation process.
Under Linux 2.6, the modular building process is used; you must have read/write
access to your kernel source tree: if not, log in as root, before building the
modules.


To build the modules, run:

	[user@localhost w9968cf-x.x]$ make

If "make" fails, control the Makefile and change the path to the kernel source
tree or to any other files, according to your system configuration; then run
"make" again.

If everything went well, the W996[87]CF driver can be either immediatly used
(see next paragraph) or be installed.

The driver will be installed in either /lib/modules/x.x.x/kernel/drivers/usb/
or /lib/modules/x.x.x/kernel/drivers/usb/media/ by default, depending on the
series of the kernel you are using (2.4 or 2.6); "x.x.x" is the version of
the kernel, which is shown by the "uname -r" command. If you prefer some other
directory for the installation, you can change its path in the Makefile.

To install the driver, run as root:

	[root@localhost w9968cf-x.x]# make install

Depmod may give you some errors about unresolved symbols, if some dependencies
among the modules were not satisfaied or if the module has been compiled for a
version of the kernel which is not actually being used.


7. Module loading
=================
To use the driver, it is necessary to load the "w9968cf" module into memory
after every other module required: for the 2.4 series of the kernel, they are
named, in order: "videodev", "usbcore", then "ehci-hcd", "usb-uhci", "uhci",
"usb-ohci" (just one), and also "i2c-core" and "ovcamchip".

Loading can be done this way, from root:

	[root@localhost home]# modprobe usbcore
	[root@localhost home]# modprobe i2c-core
	[root@localhost home]# modprobe videodev

If you are using Linux 2.4.x:
	[root@localhost ov511-x.xx]# insmod ./ovcamchip.o

otherwise, if you are using a version of the kernel between 2.6.0 and 2.6.7:
	[root@localhost ov511-x.xx]# insmod ./ovcamchip.ko

otherwise the "ovcamchip" module is likely to be already installed in the
kernel tree; in this case, you don't need to load it by yourself.

If the W996[87]CF driver has been installed as shown in the previous paragraph:

	[root@localhost home]# modprobe w9968cf

otherwise, if you have not installed the driver, but have just compiled it,
run "insmod" indicating the path to the modules (the video post-processing
module is optional and should be loaded after the "w9968cf" module); for
example:

if you are using Linux 2.4.x:
	[root@localhost w9968cf-x.x]# insmod ./w9968cf.o
	[root@localhost w9968cf-x.x]# insmod ./w9968cf-vpp.o

otherwise, if you are using Linux 2.6.x:
	[root@localhost w9968cf-x.x]# insmod ./w9968cf.ko
	[root@localhost w9968cf-x.x]# insmod ./w9968cf-vpp.ko

At this point the pertinent devices should be recognized. There are two ways of
verifying that the loading process has gone well: the first is to analyze
kernel messages:

	[user@localhost home]$ dmesg

A second way is to retrieve informations from the entries that have just been
created in the /proc/video/w9968cf/ directory; this feature works if and only
if the kernel has been built with the /proc filesystem support provided by
Linux 2.4 series only.
As an example, the following command will print the list of registered cameras:

	[user@localhost home]$ cat /proc/video/w9968cf/global

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; that is, supposing the module has been installed:

	[root@locahost home]# modinfo w9968cf


8. Module parameters
====================
Module parameters are listed below:
-------------------------------------------------------------------------------
Name:            ovmod_load
Type:            bool
Syntax:          <0|1>
Description:     Automatic 'ovcamchip' module loading: 0 disabled, 1 enabled.
                 If enabled, 'insmod' searches for the required 'ovcamchip'
                 module in the system, according to its configuration, and
                 loads that module automatically. This action is performed as
                 once soon as the 'w9968cf' module is loaded into memory.
Default:         1
Note:            The kernel must be compiled with the CONFIG_KMOD option
                 enabled for the 'ovcamchip' module to be loaded and for
                 this parameter to be present.
-------------------------------------------------------------------------------
Name:           vppmod_load
Type:           bool
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 optional 'w9968cf-vpp' module adds extra image manipulation
                capabilities to the 'w9968cf' module,like software up-scaling,
                colour conversions and video decompression for very high frame
                rates.
Default:        1
Note:           The kernel must be compiled with the CONFIG_KMOD option
                enabled for the 'w9968cf-vpp' module to be loaded and for
                this parameter to be present.
-------------------------------------------------------------------------------
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 up to 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:    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:           bool 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, or try to
                decrease the 'clockdiv' module parameter value.
Default:        1 for every device.
-------------------------------------------------------------------------------
Name:           clamping
Type:           bool 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 image sensor.
Default:        0 for every device.
-------------------------------------------------------------------------------
Name:           largeview
Type:           bool array (min = 0, max = 32)
Syntax:         <0|1[,...]> 
Description:    Large view: 0 disabled, 1 enabled.
Default:        1 for every device.
-------------------------------------------------------------------------------
Name:           upscaling
Type:           bool 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 present, this parameter 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 present, forcing decompression is not
                allowed; in this case this parameter 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 parameter will override 'decompression'.
Default:        0 for every device. Initial palette is 9 (UYVY).
Note:           If 'w9968cf-vpp' is not present, this parameter is set to 9.
-------------------------------------------------------------------------------
Name:           force_rgb
Type:           bool 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:           bool array (min = 0, max = 32)
Syntax:         <0|1[,...]>
Description:    Image sensor automatically changes brightness:
                0 = no, 1 = yes
Default:        0 for every device.
-------------------------------------------------------------------------------
Name:           autoexp
Type:           bool array (min = 0, max = 32)
Syntax:         <0|1[,...]>
Description:    Image sensor automatically changes exposure:
                0 = no, 1 = yes
Default:        1 for every device.
-------------------------------------------------------------------------------
Name:           lightfreq
Type:           int 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:           bool 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:           int 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 parameter.
Default:        -1 for every device.
-------------------------------------------------------------------------------
Name:           backlight
Type:           bool 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:           bool array (min = 0, max = 32)
Syntax:         <0|1[,...]>
Description:    Reverse image horizontally:
                0 = no, 1 = yes
Default:        0 for every device.
-------------------------------------------------------------------------------
Name:           monochrome
Type:           bool array (min = 0, max = 32)
Syntax:         <0|1[,...]> 
Description:    The image 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 (use carefully)
                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 only one
                device is used.
Default:        2
-------------------------------------------------------------------------------
Name:           specific_debug
Type:           bool
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
-------------------------------------------------------------------------------


9. Device control through "procfs" under Linux 2.4
==================================================
Under Linux 2.4 series only, if the kernel has been built with support for
/proc filesystem, it is also possible to modify some parameters for both the
driver and the camera behaviour whenever you might want to, even when latter
one is in use.

In other words, commands can be sent to the driver by writing into the file
/proc/video/w9968cf/devX (where X corresponds to the number of the device you
want access to).

In order to write into a file in /proc, it is necessary to have root 
priviliges. Recognized commands are strings which follow the following syntax:
<parameter:value[;parameter:value[...]]> (no white spaces are allowed before
or after the ":" colon).

Below is a list of the combinations of possible parameters and values:
------------------------------------------------------------------------------
Paramater           : Possible values              Notes
------------------------------------------------------------------------------
max_buffers         : 2...32                       (1)
decompression       : off|force|on or 0|1|2        (2)
filter_type         : off|3-tap|5-tap or 0|1|2     (3)
video_clamping      : no|yes or 0|1                (3)
hw_double_buffer    : no|yes or 0|1                (3)
large_view          : no|yes or 0|1                (3)
capture             : no|yes or 0|1                (4)
force_rgb           : no|yes or 0|1
auto_brightness     : no|yes or 0|1
auto_exposure       : no|yes or 0|1
banding_filter      : no|yes or 0|1
back_light          : no|yes or 0|1
mirror              : no|yes or 0|1
light_frequency     : 50|60
brightness          : 0...65535
colour              : 0...65535
contrast            : 0...65535
hue                 : 0...65535
whiteness           : 0...65535
hs_polarity         : 0|1                          (3)
vs_polarity         : 0|1                          (3)
debug_level         : 0...6
specific_debug      : no|yes or 0|1
------------------------------------------------------------------------------
Notes:
(1) This change takes effect on next open call.
(2) "off" and "force" are not permitted if the camera is in use; "force" is not
    allowed if the video post-processing module is not loaded.
(3) This change takes effect on next open in the worst case.
(4) The device has to be in use; the change has effect with non-compressed 
    video only.

For example, suppose we were to want to disable the auto-exposure and to use
the 5-tap video filter corresponding to the camera registered as /dev/video0;
then "echo" could be used for this purpose, in the following way:

	[root@locahost home]# echo 'auto_exposure:0;filter_type:5-tap' >      \
	                      /proc/video/w9968cf/dev0

Eventual errors are made evident by the kernel; in every case it is possible to
read the file into which you have just written, obtaining the current values of
the parameters, so that the result of the writing operation can be verified:

	[user@locahost home]$ cat /proc/video/w9968cf/dev0


10. Contact information
=======================
I may be contacted by e-mail at <luca.risolia@studio.unibo.it>.

I can accept GPG/PGP encrypted e-mail. My GPG key ID is 'FCE635A4'.
My public 1024-bit key should be available at your keyserver; the fingerprint
is: '88E8 F32F 7244 68BA 3958  5D40 99DA 5D2A FCE6 35A4'.


11. 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 image 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 Frederic Jouault;

- the low-level I2C fast write function has been written by Piotr Czerczak;

- the colourspace conversion routine has been taken from the CPiA driver by
  Johannes Erdfelt, Scott J. Bertin and Peter Pregler;

- the IDCT function has been initially taken from the 
  "Small JPEG Decoder Library" v0.93b by Rich Geldreich.
