aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/media/pwc
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 18:20:36 -0400
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 18:20:36 -0400
commit1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch)
tree0bba044c4ce775e45a88a51686b5d9f90697ea9d /drivers/usb/media/pwc
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history, even though we have it. We can create a separate "historical" git archive of that later if we want to, and in the meantime it's about 3.2GB when imported into git - space that would just make the early git days unnecessarily complicated, when we don't have a lot of good infrastructure for it. Let it rip!
Diffstat (limited to 'drivers/usb/media/pwc')
-rw-r--r--drivers/usb/media/pwc/ChangeLog143
-rw-r--r--drivers/usb/media/pwc/Makefile20
-rw-r--r--drivers/usb/media/pwc/philips.txt236
-rw-r--r--drivers/usb/media/pwc/pwc-ctrl.c1630
-rw-r--r--drivers/usb/media/pwc/pwc-dec1.c42
-rw-r--r--drivers/usb/media/pwc/pwc-dec1.h36
-rw-r--r--drivers/usb/media/pwc/pwc-dec23.c623
-rw-r--r--drivers/usb/media/pwc/pwc-dec23.h58
-rw-r--r--drivers/usb/media/pwc/pwc-if.c2212
-rw-r--r--drivers/usb/media/pwc/pwc-ioctl.h292
-rw-r--r--drivers/usb/media/pwc/pwc-kiara.c891
-rw-r--r--drivers/usb/media/pwc/pwc-kiara.h45
-rw-r--r--drivers/usb/media/pwc/pwc-misc.c140
-rw-r--r--drivers/usb/media/pwc/pwc-nala.h66
-rw-r--r--drivers/usb/media/pwc/pwc-timon.c1446
-rw-r--r--drivers/usb/media/pwc/pwc-timon.h61
-rw-r--r--drivers/usb/media/pwc/pwc-uncompress.c147
-rw-r--r--drivers/usb/media/pwc/pwc-uncompress.h41
-rw-r--r--drivers/usb/media/pwc/pwc.h278
19 files changed, 8407 insertions, 0 deletions
diff --git a/drivers/usb/media/pwc/ChangeLog b/drivers/usb/media/pwc/ChangeLog
new file mode 100644
index 000000000000..b2eb71a9afb5
--- /dev/null
+++ b/drivers/usb/media/pwc/ChangeLog
@@ -0,0 +1,143 @@
19.0.2
2
3* Adding #ifdef to compile PWC before and after 2.6.5
4
59.0.1
6
79.0
8
9
108.12
11
12* Implement motorized pan/tilt feature for Logitech QuickCam Orbit/Spere.
13
148.11.1
15
16* Fix for PCVC720/40, would not be able to set videomode
17* Fix for Samsung MPC models, appearantly they are based on a newer chipset
18
198.11
20
21* 20 dev_hints (per request)
22* Hot unplugging should be better, no more dangling pointers or memory leaks
23* Added reserved Logitech webcam IDs
24* Device now remembers size & fps between close()/open()
25* Removed palette stuff altogether
26
278.10.1
28
29* Added IDs for PCVC720K/40 and Creative Labs Webcam Pro
30
318.10
32
33* Fixed ID for QuickCam Notebook pro
34* Added GREALSIZE ioctl() call
35* Fixed bug in case PWCX was not loaded and invalid size was set
36
378.9
38
39* Merging with kernel 2.5.49
40* Adding IDs for QuickCam Zoom & QuickCam Notebook
41
428.8
43
44* Fixing 'leds' parameter
45* Adding IDs for Logitech QuickCam Pro 4000
46* Making URB init/cleanup a little nicer
47
488.7
49
50* Incorporating changes in ioctl() parameter passing
51* Also changes to URB mechanism
52
538.6
54
55* Added ID's for Visionite VCS UM100 and UC300
56* Removed YUV420-interlaced palette altogether (was confusing)
57* Removed MIRROR stuff as it didn't work anyway
58* Fixed a problem with the 'leds' parameter (wouldn't blink)
59* Added ioctl()s for advanced features: 'extended' whitebalance ioctl()s,
60 CONTOUR, BACKLIGHT, FLICKER, DYNNOISE.
61* VIDIOCGCAP.name now contains real camera model name instead of
62 'Philips xxx webcam'
63* Added PROBE ioctl (see previous point & API doc)
64
658.5
66
67* Adding IDs for Creative Labs Webcam 5
68* Adding IDs for SOTEC CMS-001 webcam
69* Solving possible hang in VIDIOCSYNC when unplugging the cam
70* Forgot to return structure in VIDIOCPWCGAWB, oops
71* Time interval for the LEDs are now in milliseconds
72
738.4
74
75* Fixing power_save option for Vesta range
76* Handling new error codes in ISOC callback
77* Adding dev_hint module parameter, to specify /dev/videoX device nodes
78
798.3
80
81* Adding Samsung C10 and C30 cameras
82* Removing palette module parameter
83* Fixed typo in ID of QuickCam 3000 Pro
84* Adding LED settings (blinking while in use) for ToUCam cameras.
85* Turns LED off when camera is not in use.
86
878.2
88
89* Making module more silent when trace = 0
90* Adding QuickCam 3000 Pro IDs
91* Chrominance control for the Vesta cameras
92* Hopefully fixed problems on machines with BIGMEM and > 1GB of RAM
93* Included Oliver Neukem's lock_kernel() patch
94* Allocates less memory for image buffers
95* Adds ioctl()s for the whitebalancing
96
978.1
98
99* Adding support for 750
100* Adding V4L GAUDIO/SAUDIO/UNIT ioctl() calls
101
1028.0
103* 'damage control' after inclusion in 2.4.5.
104* Changed wait-queue mechanism in read/mmap/poll according to the book.
105* Included YUV420P palette.
106* Changed interface to decompressor module.
107* Cleaned up pwc structure a bit.
108
1097.0
110
111* Fixed bug in vcvt_420i_yuyv; extra variables on stack were misaligned.
112* There is now a clear error message when an image size is selected that
113 is only supported using the decompressor, and the decompressor isn't
114 loaded.
115* When the decompressor wasn't loaded, selecting large image size
116 would create skewed or double images.
117
1186.3
119
120* Introduced spinlocks for the buffer pointer manipulation; a number of
121 reports seem to suggest the down()/up() semaphores were the cause of
122 lockups, since they are not suitable for interrupt/user locking.
123* Separated decompressor and core code into 2 modules.
124
1256.2
126
127* Non-integral image sizes are now padded with gray or black.
128* Added SHUTTERSPEED ioctl().
129* Fixed buglet in VIDIOCPWCSAGC; the function would always return an error,
130 even though the call succeeded.
131* Added hotplug support for 2.4.*.
132* Memory: the 645/646 uses less memory now.
133
1346.1
135
136* VIDIOCSPICT returns -EINVAL with invalid palettes.
137* Added saturation control.
138* Split decompressors from rest.
139* Fixed bug that would reset the framerate to the default framerate if
140 the rate field was set to 0 (which is not what I intended, nl. do not
141 change the framerate!).
142* VIDIOCPWCSCQUAL (setting compression quality) now takes effect immediately.
143* Workaround for a bug in the 730 sensor.
diff --git a/drivers/usb/media/pwc/Makefile b/drivers/usb/media/pwc/Makefile
new file mode 100644
index 000000000000..e0b41ed4407f
--- /dev/null
+++ b/drivers/usb/media/pwc/Makefile
@@ -0,0 +1,20 @@
1ifneq ($(KERNELRELEASE),)
2
3pwc-objs := pwc-if.o pwc-misc.o pwc-ctrl.o pwc-uncompress.o pwc-dec1.o pwc-dec23.o pwc-kiara.o pwc-timon.o
4
5obj-$(CONFIG_USB_PWC) += pwc.o
6
7else
8
9KDIR := /lib/modules/$(shell uname -r)/build
10PWD := $(shell pwd)
11
12default:
13 $(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules
14
15endif
16
17clean:
18 rm -f *.[oas] .*.flags *.ko .*.cmd .*.d .*.tmp *.mod.c
19 rm -rf .tmp_versions
20
diff --git a/drivers/usb/media/pwc/philips.txt b/drivers/usb/media/pwc/philips.txt
new file mode 100644
index 000000000000..04a640d723ed
--- /dev/null
+++ b/drivers/usb/media/pwc/philips.txt
@@ -0,0 +1,236 @@
1This file contains some additional information for the Philips and OEM webcams.
2E-mail: webcam@smcc.demon.nl Last updated: 2004-01-19
3Site: http://www.smcc.demon.nl/webcam/
4
5As of this moment, the following cameras are supported:
6 * Philips PCA645
7 * Philips PCA646
8 * Philips PCVC675
9 * Philips PCVC680
10 * Philips PCVC690
11 * Philips PCVC720/40
12 * Philips PCVC730
13 * Philips PCVC740
14 * Philips PCVC750
15 * Askey VC010
16 * Creative Labs Webcam 5
17 * Creative Labs Webcam Pro Ex
18 * Logitech QuickCam 3000 Pro
19 * Logitech QuickCam 4000 Pro
20 * Logitech QuickCam Notebook Pro
21 * Logitech QuickCam Zoom
22 * Logitech QuickCam Orbit
23 * Logitech QuickCam Sphere
24 * Samsung MPC-C10
25 * Samsung MPC-C30
26 * Sotec Afina Eye
27 * AME CU-001
28 * Visionite VCS-UM100
29 * Visionite VCS-UC300
30
31The main webpage for the Philips driver is at the address above. It contains
32a lot of extra information, a FAQ, and the binary plugin 'PWCX'. This plugin
33contains decompression routines that allow you to use higher image sizes and
34framerates; in addition the webcam uses less bandwidth on the USB bus (handy
35if you want to run more than 1 camera simultaneously). These routines fall
36under a NDA, and may therefor not be distributed as source; however, its use
37is completely optional.
38
39You can build this code either into your kernel, or as a module. I recommend
40the latter, since it makes troubleshooting a lot easier. The built-in
41microphone is supported through the USB Audio class.
42
43When you load the module you can set some default settings for the
44camera; some programs depend on a particular image-size or -format and
45don't know how to set it properly in the driver. The options are:
46
47size
48 Can be one of 'sqcif', 'qsif', 'qcif', 'sif', 'cif' or
49 'vga', for an image size of resp. 128x96, 160x120, 176x144,
50 320x240, 352x288 and 640x480 (of course, only for those cameras that
51 support these resolutions).
52
53fps
54 Specifies the desired framerate. Is an integer in the range of 4-30.
55
56fbufs
57 This paramter specifies the number of internal buffers to use for storing
58 frames from the cam. This will help if the process that reads images from
59 the cam is a bit slow or momentarely busy. However, on slow machines it
60 only introduces lag, so choose carefully. The default is 3, which is
61 reasonable. You can set it between 2 and 5.
62
63mbufs
64 This is an integer between 1 and 10. It will tell the module the number of
65 buffers to reserve for mmap(), VIDIOCCGMBUF, VIDIOCMCAPTURE and friends.
66 The default is 2, which is adequate for most applications (double
67 buffering).
68
69 Should you experience a lot of 'Dumping frame...' messages during
70 grabbing with a tool that uses mmap(), you might want to increase if.
71 However, it doesn't really buffer images, it just gives you a bit more
72 slack when your program is behind. But you need a multi-threaded or
73 forked program to really take advantage of these buffers.
74
75 The absolute maximum is 10, but don't set it too high! Every buffer takes
76 up 460 KB of RAM, so unless you have a lot of memory setting this to
77 something more than 4 is an absolute waste. This memory is only
78 allocated during open(), so nothing is wasted when the camera is not in
79 use.
80
81power_save
82 When power_save is enabled (set to 1), the module will try to shut down
83 the cam on close() and re-activate on open(). This will save power and
84 turn off the LED. Not all cameras support this though (the 645 and 646
85 don't have power saving at all), and some models don't work either (they
86 will shut down, but never wake up). Consider this experimental. By
87 default this option is disabled.
88
89compression (only useful with the plugin)
90 With this option you can control the compression factor that the camera
91 uses to squeeze the image through the USB bus. You can set the
92 parameter between 0 and 3:
93 0 = prefer uncompressed images; if the requested mode is not available
94 in an uncompressed format, the driver will silently switch to low
95 compression.
96 1 = low compression.
97 2 = medium compression.
98 3 = high compression.
99
100 High compression takes less bandwidth of course, but it could also
101 introduce some unwanted artefacts. The default is 2, medium compression.
102 See the FAQ on the website for an overview of which modes require
103 compression.
104
105 The compression parameter does not apply to the 645 and 646 cameras
106 and OEM models derived from those (only a few). Most cams honour this
107 parameter.
108
109leds
110 This settings takes 2 integers, that define the on/off time for the LED
111 (in milliseconds). One of the interesting things that you can do with
112 this is let the LED blink while the camera is in use. This:
113
114 leds=500,500
115
116 will blink the LED once every second. But with:
117
118 leds=0,0
119
120 the LED never goes on, making it suitable for silent surveillance.
121
122 By default the camera's LED is on solid while in use, and turned off
123 when the camera is not used anymore.
124
125 This parameter works only with the ToUCam range of cameras (720, 730, 740,
126 750) and OEMs. For other cameras this command is silently ignored, and
127 the LED cannot be controlled.
128
129 Finally: this parameters does not take effect UNTIL the first time you
130 open the camera device. Until then, the LED remains on.
131
132dev_hint
133 A long standing problem with USB devices is their dynamic nature: you
134 never know what device a camera gets assigned; it depends on module load
135 order, the hub configuration, the order in which devices are plugged in,
136 and the phase of the moon (i.e. it can be random). With this option you
137 can give the driver a hint as to what video device node (/dev/videoX) it
138 should use with a specific camera. This is also handy if you have two
139 cameras of the same model.
140
141 A camera is specified by its type (the number from the camera model,
142 like PCA645, PCVC750VC, etc) and optionally the serial number (visible
143 in /proc/bus/usb/devices). A hint consists of a string with the following
144 format:
145
146 [type[.serialnumber]:]node
147
148 The square brackets mean that both the type and the serialnumber are
149 optional, but a serialnumber cannot be specified without a type (which
150 would be rather pointless). The serialnumber is separated from the type
151 by a '.'; the node number by a ':'.
152
153 This somewhat cryptic syntax is best explained by a few examples:
154
155 dev_hint=3,5 The first detected cam gets assigned
156 /dev/video3, the second /dev/video5. Any
157 other cameras will get the first free
158 available slot (see below).
159
160 dev_hint=645:1,680:2 The PCA645 camera will get /dev/video1,
161 and a PCVC680 /dev/video2.
162
163 dev_hint=645.0123:3,645.4567:0 The PCA645 camera with serialnumber
164 0123 goes to /dev/video3, the same
165 camera model with the 4567 serial
166 gets /dev/video0.
167
168 dev_hint=750:1,4,5,6 The PCVC750 camera will get /dev/video1, the
169 next 3 Philips cams will use /dev/video4
170 through /dev/video6.
171
172 Some points worth knowing:
173 - Serialnumbers are case sensitive and must be written full, including
174 leading zeroes (it's treated as a string).
175 - If a device node is already occupied, registration will fail and
176 the webcam is not available.
177 - You can have up to 64 video devices; be sure to make enough device
178 nodes in /dev if you want to spread the numbers (this does not apply
179 to devfs). After /dev/video9 comes /dev/video10 (not /dev/videoA).
180 - If a camera does not match any dev_hint, it will simply get assigned
181 the first available device node, just as it used to be.
182
183trace
184 In order to better detect problems, it is now possible to turn on a
185 'trace' of some of the calls the module makes; it logs all items in your
186 kernel log at debug level.
187
188 The trace variable is a bitmask; each bit represents a certain feature.
189 If you want to trace something, look up the bit value(s) in the table
190 below, add the values together and supply that to the trace variable.
191
192 Value Value Description Default
193 (dec) (hex)
194 1 0x1 Module initialization; this will log messages On
195 while loading and unloading the module
196
197 2 0x2 probe() and disconnect() traces On
198
199 4 0x4 Trace open() and close() calls Off
200
201 8 0x8 read(), mmap() and associated ioctl() calls Off
202
203 16 0x10 Memory allocation of buffers, etc. Off
204
205 32 0x20 Showing underflow, overflow and Dumping frame On
206 messages
207
208 64 0x40 Show viewport and image sizes Off
209
210 128 0x80 PWCX debugging Off
211
212 For example, to trace the open() & read() fuctions, sum 8 + 4 = 12,
213 so you would supply trace=12 during insmod or modprobe. If
214 you want to turn the initialization and probing tracing off, set trace=0.
215 The default value for trace is 35 (0x23).
216
217
218
219Example:
220
221 # modprobe pwc size=cif fps=15 power_save=1
222
223The fbufs, mbufs and trace parameters are global and apply to all connected
224cameras. Each camera has its own set of buffers.
225
226size and fps only specify defaults when you open() the device; this is to
227accommodate some tools that don't set the size. You can change these
228settings after open() with the Video4Linux ioctl() calls. The default of
229defaults is QCIF size at 10 fps.
230
231The compression parameter is semiglobal; it sets the initial compression
232preference for all camera's, but this parameter can be set per camera with
233the VIDIOCPWCSCQUAL ioctl() call.
234
235All parameters are optional.
236
diff --git a/drivers/usb/media/pwc/pwc-ctrl.c b/drivers/usb/media/pwc/pwc-ctrl.c
new file mode 100644
index 000000000000..26aa914bc541
--- /dev/null
+++ b/drivers/usb/media/pwc/pwc-ctrl.c
@@ -0,0 +1,1630 @@
1/* Driver for Philips webcam
2 Functions that send various control messages to the webcam, including
3 video modes.
4 (C) 1999-2003 Nemosoft Unv.
5 (C) 2004 Luc Saillard (luc@saillard.org)
6
7 NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx
8 driver and thus may have bugs that are not present in the original version.
9 Please send bug reports and support requests to <luc@saillard.org>.
10
11 NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx
12 driver and thus may have bugs that are not present in the original version.
13 Please send bug reports and support requests to <luc@saillard.org>.
14 The decompression routines have been implemented by reverse-engineering the
15 Nemosoft binary pwcx module. Caveat emptor.
16
17 This program is free software; you can redistribute it and/or modify
18 it under the terms of the GNU General Public License as published by
19 the Free Software Foundation; either version 2 of the License, or
20 (at your option) any later version.
21
22 This program is distributed in the hope that it will be useful,
23 but WITHOUT ANY WARRANTY; without even the implied warranty of
24 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 GNU General Public License for more details.
26
27 You should have received a copy of the GNU General Public License
28 along with this program; if not, write to the Free Software
29 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
30*/
31
32/*
33 Changes
34 2001/08/03 Alvarado Added methods for changing white balance and
35 red/green gains
36 */
37
38/* Control functions for the cam; brightness, contrast, video mode, etc. */
39
40#ifdef __KERNEL__
41#include <asm/uaccess.h>
42#endif
43#include <asm/errno.h>
44#include <linux/version.h>
45
46#include "pwc.h"
47#include "pwc-ioctl.h"
48#include "pwc-uncompress.h"
49#include "pwc-kiara.h"
50#include "pwc-timon.h"
51#include "pwc-dec1.h"
52#include "pwc-dec23.h"
53
54/* Request types: video */
55#define SET_LUM_CTL 0x01
56#define GET_LUM_CTL 0x02
57#define SET_CHROM_CTL 0x03
58#define GET_CHROM_CTL 0x04
59#define SET_STATUS_CTL 0x05
60#define GET_STATUS_CTL 0x06
61#define SET_EP_STREAM_CTL 0x07
62#define GET_EP_STREAM_CTL 0x08
63#define SET_MPT_CTL 0x0D
64#define GET_MPT_CTL 0x0E
65
66/* Selectors for the Luminance controls [GS]ET_LUM_CTL */
67#define AGC_MODE_FORMATTER 0x2000
68#define PRESET_AGC_FORMATTER 0x2100
69#define SHUTTER_MODE_FORMATTER 0x2200
70#define PRESET_SHUTTER_FORMATTER 0x2300
71#define PRESET_CONTOUR_FORMATTER 0x2400
72#define AUTO_CONTOUR_FORMATTER 0x2500
73#define BACK_LIGHT_COMPENSATION_FORMATTER 0x2600
74#define CONTRAST_FORMATTER 0x2700
75#define DYNAMIC_NOISE_CONTROL_FORMATTER 0x2800
76#define FLICKERLESS_MODE_FORMATTER 0x2900
77#define AE_CONTROL_SPEED 0x2A00
78#define BRIGHTNESS_FORMATTER 0x2B00
79#define GAMMA_FORMATTER 0x2C00
80
81/* Selectors for the Chrominance controls [GS]ET_CHROM_CTL */
82#define WB_MODE_FORMATTER 0x1000
83#define AWB_CONTROL_SPEED_FORMATTER 0x1100
84#define AWB_CONTROL_DELAY_FORMATTER 0x1200
85#define PRESET_MANUAL_RED_GAIN_FORMATTER 0x1300
86#define PRESET_MANUAL_BLUE_GAIN_FORMATTER 0x1400
87#define COLOUR_MODE_FORMATTER 0x1500
88#define SATURATION_MODE_FORMATTER1 0x1600
89#define SATURATION_MODE_FORMATTER2 0x1700
90
91/* Selectors for the Status controls [GS]ET_STATUS_CTL */
92#define SAVE_USER_DEFAULTS_FORMATTER 0x0200
93#define RESTORE_USER_DEFAULTS_FORMATTER 0x0300
94#define RESTORE_FACTORY_DEFAULTS_FORMATTER 0x0400
95#define READ_AGC_FORMATTER 0x0500
96#define READ_SHUTTER_FORMATTER 0x0600
97#define READ_RED_GAIN_FORMATTER 0x0700
98#define READ_BLUE_GAIN_FORMATTER 0x0800
99#define SENSOR_TYPE_FORMATTER1 0x0C00
100#define READ_RAW_Y_MEAN_FORMATTER 0x3100
101#define SET_POWER_SAVE_MODE_FORMATTER 0x3200
102#define MIRROR_IMAGE_FORMATTER 0x3300
103#define LED_FORMATTER 0x3400
104#define SENSOR_TYPE_FORMATTER2 0x3700
105
106/* Formatters for the Video Endpoint controls [GS]ET_EP_STREAM_CTL */
107#define VIDEO_OUTPUT_CONTROL_FORMATTER 0x0100
108
109/* Formatters for the motorized pan & tilt [GS]ET_MPT_CTL */
110#define PT_RELATIVE_CONTROL_FORMATTER 0x01
111#define PT_RESET_CONTROL_FORMATTER 0x02
112#define PT_STATUS_FORMATTER 0x03
113
114static char *size2name[PSZ_MAX] =
115{
116 "subQCIF",
117 "QSIF",
118 "QCIF",
119 "SIF",
120 "CIF",
121 "VGA",
122};
123
124/********/
125
126/* Entries for the Nala (645/646) camera; the Nala doesn't have compression
127 preferences, so you either get compressed or non-compressed streams.
128
129 An alternate value of 0 means this mode is not available at all.
130 */
131
132struct Nala_table_entry {
133 char alternate; /* USB alternate setting */
134 int compressed; /* Compressed yes/no */
135
136 unsigned char mode[3]; /* precomputed mode table */
137};
138
139static struct Nala_table_entry Nala_table[PSZ_MAX][8] =
140{
141#include "pwc-nala.h"
142};
143
144
145/****************************************************************************/
146
147
148#define SendControlMsg(request, value, buflen) \
149 usb_control_msg(pdev->udev, usb_sndctrlpipe(pdev->udev, 0), \
150 request, \
151 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, \
152 value, \
153 pdev->vcinterface, \
154 &buf, buflen, 500)
155
156#define RecvControlMsg(request, value, buflen) \
157 usb_control_msg(pdev->udev, usb_rcvctrlpipe(pdev->udev, 0), \
158 request, \
159 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, \
160 value, \
161 pdev->vcinterface, \
162 &buf, buflen, 500)
163
164
165#if PWC_DEBUG
166void pwc_hexdump(void *p, int len)
167{
168 int i;
169 unsigned char *s;
170 char buf[100], *d;
171
172 s = (unsigned char *)p;
173 d = buf;
174 *d = '\0';
175 Debug("Doing hexdump @ %p, %d bytes.\n", p, len);
176 for (i = 0; i < len; i++) {
177 d += sprintf(d, "%02X ", *s++);
178 if ((i & 0xF) == 0xF) {
179 Debug("%s\n", buf);
180 d = buf;
181 *d = '\0';
182 }
183 }
184 if ((i & 0xF) != 0)
185 Debug("%s\n", buf);
186}
187#endif
188
189static inline int send_video_command(struct usb_device *udev, int index, void *buf, int buflen)
190{
191 return usb_control_msg(udev,
192 usb_sndctrlpipe(udev, 0),
193 SET_EP_STREAM_CTL,
194 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
195 VIDEO_OUTPUT_CONTROL_FORMATTER,
196 index,
197 buf, buflen, 1000);
198}
199
200
201
202static inline int set_video_mode_Nala(struct pwc_device *pdev, int size, int frames)
203{
204 unsigned char buf[3];
205 int ret, fps;
206 struct Nala_table_entry *pEntry;
207 int frames2frames[31] =
208 { /* closest match of framerate */
209 0, 0, 0, 0, 4, /* 0-4 */
210 5, 5, 7, 7, 10, /* 5-9 */
211 10, 10, 12, 12, 15, /* 10-14 */
212 15, 15, 15, 20, 20, /* 15-19 */
213 20, 20, 20, 24, 24, /* 20-24 */
214 24, 24, 24, 24, 24, /* 25-29 */
215 24 /* 30 */
216 };
217 int frames2table[31] =
218 { 0, 0, 0, 0, 0, /* 0-4 */
219 1, 1, 1, 2, 2, /* 5-9 */
220 3, 3, 4, 4, 4, /* 10-14 */
221 5, 5, 5, 5, 5, /* 15-19 */
222 6, 6, 6, 6, 7, /* 20-24 */
223 7, 7, 7, 7, 7, /* 25-29 */
224 7 /* 30 */
225 };
226
227 if (size < 0 || size > PSZ_CIF || frames < 4 || frames > 25)
228 return -EINVAL;
229 frames = frames2frames[frames];
230 fps = frames2table[frames];
231 pEntry = &Nala_table[size][fps];
232 if (pEntry->alternate == 0)
233 return -EINVAL;
234
235 if (pEntry->compressed)
236 return -ENOENT; /* Not supported. */
237
238 memcpy(buf, pEntry->mode, 3);
239 ret = send_video_command(pdev->udev, pdev->vendpoint, buf, 3);
240 if (ret < 0) {
241 Debug("Failed to send video command... %d\n", ret);
242 return ret;
243 }
244 if (pEntry->compressed && pdev->vpalette != VIDEO_PALETTE_RAW)
245 {
246 switch(pdev->type) {
247 case 645:
248 case 646:
249 pwc_dec1_init(pdev->type, pdev->release, buf, pdev->decompress_data);
250 break;
251
252 case 675:
253 case 680:
254 case 690:
255 case 720:
256 case 730:
257 case 740:
258 case 750:
259 pwc_dec23_init(pdev->type, pdev->release, buf, pdev->decompress_data);
260 break;
261 }
262 }
263
264 pdev->cmd_len = 3;
265 memcpy(pdev->cmd_buf, buf, 3);
266
267 /* Set various parameters */
268 pdev->vframes = frames;
269 pdev->vsize = size;
270 pdev->valternate = pEntry->alternate;
271 pdev->image = pwc_image_sizes[size];
272 pdev->frame_size = (pdev->image.x * pdev->image.y * 3) / 2;
273 if (pEntry->compressed) {
274 if (pdev->release < 5) { /* 4 fold compression */
275 pdev->vbandlength = 528;
276 pdev->frame_size /= 4;
277 }
278 else {
279 pdev->vbandlength = 704;
280 pdev->frame_size /= 3;
281 }
282 }
283 else
284 pdev->vbandlength = 0;
285 return 0;
286}
287
288
289static inline int set_video_mode_Timon(struct pwc_device *pdev, int size, int frames, int compression, int snapshot)
290{
291 unsigned char buf[13];
292 const struct Timon_table_entry *pChoose;
293 int ret, fps;
294
295 if (size >= PSZ_MAX || frames < 5 || frames > 30 || compression < 0 || compression > 3)
296 return -EINVAL;
297 if (size == PSZ_VGA && frames > 15)
298 return -EINVAL;
299 fps = (frames / 5) - 1;
300
301 /* Find a supported framerate with progressively higher compression ratios
302 if the preferred ratio is not available.
303 */
304 pChoose = NULL;
305 while (compression <= 3) {
306 pChoose = &Timon_table[size][fps][compression];
307 if (pChoose->alternate != 0)
308 break;
309 compression++;
310 }
311 if (pChoose == NULL || pChoose->alternate == 0)
312 return -ENOENT; /* Not supported. */
313
314 memcpy(buf, pChoose->mode, 13);
315 if (snapshot)
316 buf[0] |= 0x80;
317 ret = send_video_command(pdev->udev, pdev->vendpoint, buf, 13);
318 if (ret < 0)
319 return ret;
320
321 if (pChoose->bandlength > 0 && pdev->vpalette != VIDEO_PALETTE_RAW)
322 pwc_dec23_init(pdev->type, pdev->release, buf, pdev->decompress_data);
323
324 pdev->cmd_len = 13;
325 memcpy(pdev->cmd_buf, buf, 13);
326
327 /* Set various parameters */
328 pdev->vframes = frames;
329 pdev->vsize = size;
330 pdev->vsnapshot = snapshot;
331 pdev->valternate = pChoose->alternate;
332 pdev->image = pwc_image_sizes[size];
333 pdev->vbandlength = pChoose->bandlength;
334 if (pChoose->bandlength > 0)
335 pdev->frame_size = (pChoose->bandlength * pdev->image.y) / 4;
336 else
337 pdev->frame_size = (pdev->image.x * pdev->image.y * 12) / 8;
338 return 0;
339}
340
341
342static inline int set_video_mode_Kiara(struct pwc_device *pdev, int size, int frames, int compression, int snapshot)
343{
344 const struct Kiara_table_entry *pChoose = NULL;
345 int fps, ret;
346 unsigned char buf[12];
347 struct Kiara_table_entry RawEntry = {6, 773, 1272, {0xAD, 0xF4, 0x10, 0x27, 0xB6, 0x24, 0x96, 0x02, 0x30, 0x05, 0x03, 0x80}};
348
349 if (size >= PSZ_MAX || frames < 5 || frames > 30 || compression < 0 || compression > 3)
350 return -EINVAL;
351 if (size == PSZ_VGA && frames > 15)
352 return -EINVAL;
353 fps = (frames / 5) - 1;
354
355 /* special case: VGA @ 5 fps and snapshot is raw bayer mode */
356 if (size == PSZ_VGA && frames == 5 && snapshot)
357 {
358 /* Only available in case the raw palette is selected or
359 we have the decompressor available. This mode is
360 only available in compressed form
361 */
362 if (pdev->vpalette == VIDEO_PALETTE_RAW)
363 {
364 Info("Choosing VGA/5 BAYER mode (%d).\n", pdev->vpalette);
365 pChoose = &RawEntry;
366 }
367 else
368 {
369 Info("VGA/5 BAYER mode _must_ have a decompressor available, or use RAW palette.\n");
370 }
371 }
372 else
373 {
374 /* Find a supported framerate with progressively higher compression ratios
375 if the preferred ratio is not available.
376 Skip this step when using RAW modes.
377 */
378 while (compression <= 3) {
379 pChoose = &Kiara_table[size][fps][compression];
380 if (pChoose->alternate != 0)
381 break;
382 compression++;
383 }
384 }
385 if (pChoose == NULL || pChoose->alternate == 0)
386 return -ENOENT; /* Not supported. */
387
388 Debug("Using alternate setting %d.\n", pChoose->alternate);
389
390 /* usb_control_msg won't take staticly allocated arrays as argument?? */
391 memcpy(buf, pChoose->mode, 12);
392 if (snapshot)
393 buf[0] |= 0x80;
394
395 /* Firmware bug: video endpoint is 5, but commands are sent to endpoint 4 */
396 ret = send_video_command(pdev->udev, 4 /* pdev->vendpoint */, buf, 12);
397 if (ret < 0)
398 return ret;
399
400 if (pChoose->bandlength > 0 && pdev->vpalette != VIDEO_PALETTE_RAW)
401 pwc_dec23_init(pdev->type, pdev->release, buf, pdev->decompress_data);
402
403 pdev->cmd_len = 12;
404 memcpy(pdev->cmd_buf, buf, 12);
405 /* All set and go */
406 pdev->vframes = frames;
407 pdev->vsize = size;
408 pdev->vsnapshot = snapshot;
409 pdev->valternate = pChoose->alternate;
410 pdev->image = pwc_image_sizes[size];
411 pdev->vbandlength = pChoose->bandlength;
412 if (pdev->vbandlength > 0)
413 pdev->frame_size = (pdev->vbandlength * pdev->image.y) / 4;
414 else
415 pdev->frame_size = (pdev->image.x * pdev->image.y * 12) / 8;
416 return 0;
417}
418
419
420
421/**
422 @pdev: device structure
423 @width: viewport width
424 @height: viewport height
425 @frame: framerate, in fps
426 @compression: preferred compression ratio
427 @snapshot: snapshot mode or streaming
428 */
429int pwc_set_video_mode(struct pwc_device *pdev, int width, int height, int frames, int compression, int snapshot)
430{
431 int ret, size;
432
433 Trace(TRACE_FLOW, "set_video_mode(%dx%d @ %d, palette %d).\n", width, height, frames, pdev->vpalette);
434 size = pwc_decode_size(pdev, width, height);
435 if (size < 0) {
436 Debug("Could not find suitable size.\n");
437 return -ERANGE;
438 }
439 Debug("decode_size = %d.\n", size);
440
441 ret = -EINVAL;
442 switch(pdev->type) {
443 case 645:
444 case 646:
445 ret = set_video_mode_Nala(pdev, size, frames);
446 break;
447
448 case 675:
449 case 680:
450 case 690:
451 ret = set_video_mode_Timon(pdev, size, frames, compression, snapshot);
452 break;
453
454 case 720:
455 case 730:
456 case 740:
457 case 750:
458 ret = set_video_mode_Kiara(pdev, size, frames, compression, snapshot);
459 break;
460 }
461 if (ret < 0) {
462 if (ret == -ENOENT)
463 Info("Video mode %s@%d fps is only supported with the decompressor module (pwcx).\n", size2name[size], frames);
464 else {
465 Err("Failed to set video mode %s@%d fps; return code = %d\n", size2name[size], frames, ret);
466 }
467 return ret;
468 }
469 pdev->view.x = width;
470 pdev->view.y = height;
471 pdev->frame_total_size = pdev->frame_size + pdev->frame_header_size + pdev->frame_trailer_size;
472 pwc_set_image_buffer_size(pdev);
473 Trace(TRACE_SIZE, "Set viewport to %dx%d, image size is %dx%d.\n", width, height, pwc_image_sizes[size].x, pwc_image_sizes[size].y);
474 return 0;
475}
476
477
478void pwc_set_image_buffer_size(struct pwc_device *pdev)
479{
480 int i, factor = 0, filler = 0;
481
482 /* for PALETTE_YUV420P */
483 switch(pdev->vpalette)
484 {
485 case VIDEO_PALETTE_YUV420P:
486 factor = 6;
487 filler = 128;
488 break;
489 case VIDEO_PALETTE_RAW:
490 factor = 6; /* can be uncompressed YUV420P */
491 filler = 0;
492 break;
493 }
494
495 /* Set sizes in bytes */
496 pdev->image.size = pdev->image.x * pdev->image.y * factor / 4;
497 pdev->view.size = pdev->view.x * pdev->view.y * factor / 4;
498
499 /* Align offset, or you'll get some very weird results in
500 YUV420 mode... x must be multiple of 4 (to get the Y's in
501 place), and y even (or you'll mixup U & V). This is less of a
502 problem for YUV420P.
503 */
504 pdev->offset.x = ((pdev->view.x - pdev->image.x) / 2) & 0xFFFC;
505 pdev->offset.y = ((pdev->view.y - pdev->image.y) / 2) & 0xFFFE;
506
507 /* Fill buffers with gray or black */
508 for (i = 0; i < MAX_IMAGES; i++) {
509 if (pdev->image_ptr[i] != NULL)
510 memset(pdev->image_ptr[i], filler, pdev->view.size);
511 }
512}
513
514
515
516/* BRIGHTNESS */
517
518int pwc_get_brightness(struct pwc_device *pdev)
519{
520 char buf;
521 int ret;
522
523 ret = RecvControlMsg(GET_LUM_CTL, BRIGHTNESS_FORMATTER, 1);
524 if (ret < 0)
525 return ret;
526 return buf << 9;
527}
528
529int pwc_set_brightness(struct pwc_device *pdev, int value)
530{
531 char buf;
532
533 if (value < 0)
534 value = 0;
535 if (value > 0xffff)
536 value = 0xffff;
537 buf = (value >> 9) & 0x7f;
538 return SendControlMsg(SET_LUM_CTL, BRIGHTNESS_FORMATTER, 1);
539}
540
541/* CONTRAST */
542
543int pwc_get_contrast(struct pwc_device *pdev)
544{
545 char buf;
546 int ret;
547
548 ret = RecvControlMsg(GET_LUM_CTL, CONTRAST_FORMATTER, 1);
549 if (ret < 0)
550 return ret;
551 return buf << 10;
552}
553
554int pwc_set_contrast(struct pwc_device *pdev, int value)
555{
556 char buf;
557
558 if (value < 0)
559 value = 0;
560 if (value > 0xffff)
561 value = 0xffff;
562 buf = (value >> 10) & 0x3f;
563 return SendControlMsg(SET_LUM_CTL, CONTRAST_FORMATTER, 1);
564}
565
566/* GAMMA */
567
568int pwc_get_gamma(struct pwc_device *pdev)
569{
570 char buf;
571 int ret;
572
573 ret = RecvControlMsg(GET_LUM_CTL, GAMMA_FORMATTER, 1);
574 if (ret < 0)
575 return ret;
576 return buf << 11;
577}
578
579int pwc_set_gamma(struct pwc_device *pdev, int value)
580{
581 char buf;
582
583 if (value < 0)
584 value = 0;
585 if (value > 0xffff)
586 value = 0xffff;
587 buf = (value >> 11) & 0x1f;
588 return SendControlMsg(SET_LUM_CTL, GAMMA_FORMATTER, 1);
589}
590
591
592/* SATURATION */
593
594int pwc_get_saturation(struct pwc_device *pdev)
595{
596 char buf;
597 int ret;
598
599 if (pdev->type < 675)
600 return -1;
601 ret = RecvControlMsg(GET_CHROM_CTL, pdev->type < 730 ? SATURATION_MODE_FORMATTER2 : SATURATION_MODE_FORMATTER1, 1);
602 if (ret < 0)
603 return ret;
604 return 32768 + buf * 327;
605}
606
607int pwc_set_saturation(struct pwc_device *pdev, int value)
608{
609 char buf;
610
611 if (pdev->type < 675)
612 return -EINVAL;
613 if (value < 0)
614 value = 0;
615 if (value > 0xffff)
616 value = 0xffff;
617 /* saturation ranges from -100 to +100 */
618 buf = (value - 32768) / 327;
619 return SendControlMsg(SET_CHROM_CTL, pdev->type < 730 ? SATURATION_MODE_FORMATTER2 : SATURATION_MODE_FORMATTER1, 1);
620}
621
622/* AGC */
623
624static inline int pwc_set_agc(struct pwc_device *pdev, int mode, int value)
625{
626 char buf;
627 int ret;
628
629 if (mode)
630 buf = 0x0; /* auto */
631 else
632 buf = 0xff; /* fixed */
633
634 ret = SendControlMsg(SET_LUM_CTL, AGC_MODE_FORMATTER, 1);
635
636 if (!mode && ret >= 0) {
637 if (value < 0)
638 value = 0;
639 if (value > 0xffff)
640 value = 0xffff;
641 buf = (value >> 10) & 0x3F;
642 ret = SendControlMsg(SET_LUM_CTL, PRESET_AGC_FORMATTER, 1);
643 }
644 if (ret < 0)
645 return ret;
646 return 0;
647}
648
649static inline int pwc_get_agc(struct pwc_device *pdev, int *value)
650{
651 unsigned char buf;
652 int ret;
653
654 ret = RecvControlMsg(GET_LUM_CTL, AGC_MODE_FORMATTER, 1);
655 if (ret < 0)
656 return ret;
657
658 if (buf != 0) { /* fixed */
659 ret = RecvControlMsg(GET_LUM_CTL, PRESET_AGC_FORMATTER, 1);
660 if (ret < 0)
661 return ret;
662 if (buf > 0x3F)
663 buf = 0x3F;
664 *value = (buf << 10);
665 }
666 else { /* auto */
667 ret = RecvControlMsg(GET_STATUS_CTL, READ_AGC_FORMATTER, 1);
668 if (ret < 0)
669 return ret;
670 /* Gah... this value ranges from 0x00 ... 0x9F */
671 if (buf > 0x9F)
672 buf = 0x9F;
673 *value = -(48 + buf * 409);
674 }
675
676 return 0;
677}
678
679static inline int pwc_set_shutter_speed(struct pwc_device *pdev, int mode, int value)
680{
681 char buf[2];
682 int speed, ret;
683
684
685 if (mode)
686 buf[0] = 0x0; /* auto */
687 else
688 buf[0] = 0xff; /* fixed */
689
690 ret = SendControlMsg(SET_LUM_CTL, SHUTTER_MODE_FORMATTER, 1);
691
692 if (!mode && ret >= 0) {
693 if (value < 0)
694 value = 0;
695 if (value > 0xffff)
696 value = 0xffff;
697 switch(pdev->type) {
698 case 675:
699 case 680:
700 case 690:
701 /* speed ranges from 0x0 to 0x290 (656) */
702 speed = (value / 100);
703 buf[1] = speed >> 8;
704 buf[0] = speed & 0xff;
705 break;
706 case 720:
707 case 730:
708 case 740:
709 case 750:
710 /* speed seems to range from 0x0 to 0xff */
711 buf[1] = 0;
712 buf[0] = value >> 8;
713 break;
714 }
715
716 ret = SendControlMsg(SET_LUM_CTL, PRESET_SHUTTER_FORMATTER, 2);
717 }
718 return ret;
719}
720
721
722/* POWER */
723
724int pwc_camera_power(struct pwc_device *pdev, int power)
725{
726 char buf;
727
728 if (pdev->type < 675 || (pdev->type < 730 && pdev->release < 6))
729 return 0; /* Not supported by Nala or Timon < release 6 */
730
731 if (power)
732 buf = 0x00; /* active */
733 else
734 buf = 0xFF; /* power save */
735 return SendControlMsg(SET_STATUS_CTL, SET_POWER_SAVE_MODE_FORMATTER, 1);
736}
737
738
739
740/* private calls */
741
742static inline int pwc_restore_user(struct pwc_device *pdev)
743{
744 char buf; /* dummy */
745 return SendControlMsg(SET_STATUS_CTL, RESTORE_USER_DEFAULTS_FORMATTER, 0);
746}
747
748static inline int pwc_save_user(struct pwc_device *pdev)
749{
750 char buf; /* dummy */
751 return SendControlMsg(SET_STATUS_CTL, SAVE_USER_DEFAULTS_FORMATTER, 0);
752}
753
754static inline int pwc_restore_factory(struct pwc_device *pdev)
755{
756 char buf; /* dummy */
757 return SendControlMsg(SET_STATUS_CTL, RESTORE_FACTORY_DEFAULTS_FORMATTER, 0);
758}
759
760 /* ************************************************* */
761 /* Patch by Alvarado: (not in the original version */
762
763 /*
764 * the camera recognizes modes from 0 to 4:
765 *
766 * 00: indoor (incandescant lighting)
767 * 01: outdoor (sunlight)
768 * 02: fluorescent lighting
769 * 03: manual
770 * 04: auto
771 */
772static inline int pwc_set_awb(struct pwc_device *pdev, int mode)
773{
774 char buf;
775 int ret;
776
777 if (mode < 0)
778 mode = 0;
779
780 if (mode > 4)
781 mode = 4;
782
783 buf = mode & 0x07; /* just the lowest three bits */
784
785 ret = SendControlMsg(SET_CHROM_CTL, WB_MODE_FORMATTER, 1);
786
787 if (ret < 0)
788 return ret;
789 return 0;
790}
791
792static inline int pwc_get_awb(struct pwc_device *pdev)
793{
794 unsigned char buf;
795 int ret;
796
797 ret = RecvControlMsg(GET_CHROM_CTL, WB_MODE_FORMATTER, 1);
798
799 if (ret < 0)
800 return ret;
801 return buf;
802}
803
804static inline int pwc_set_red_gain(struct pwc_device *pdev, int value)
805{
806 unsigned char buf;
807
808 if (value < 0)
809 value = 0;
810 if (value > 0xffff)
811 value = 0xffff;
812 /* only the msb is considered */
813 buf = value >> 8;
814 return SendControlMsg(SET_CHROM_CTL, PRESET_MANUAL_RED_GAIN_FORMATTER, 1);
815}
816
817static inline int pwc_get_red_gain(struct pwc_device *pdev, int *value)
818{
819 unsigned char buf;
820 int ret;
821
822 ret = RecvControlMsg(GET_CHROM_CTL, PRESET_MANUAL_RED_GAIN_FORMATTER, 1);
823 if (ret < 0)
824 return ret;
825 *value = buf << 8;
826 return 0;
827}
828
829
830static inline int pwc_set_blue_gain(struct pwc_device *pdev, int value)
831{
832 unsigned char buf;
833
834 if (value < 0)
835 value = 0;
836 if (value > 0xffff)
837 value = 0xffff;
838 /* only the msb is considered */
839 buf = value >> 8;
840 return SendControlMsg(SET_CHROM_CTL, PRESET_MANUAL_BLUE_GAIN_FORMATTER, 1);
841}
842
843static inline int pwc_get_blue_gain(struct pwc_device *pdev, int *value)
844{
845 unsigned char buf;
846 int ret;
847
848 ret = RecvControlMsg(GET_CHROM_CTL, PRESET_MANUAL_BLUE_GAIN_FORMATTER, 1);
849 if (ret < 0)
850 return ret;
851 *value = buf << 8;
852 return 0;
853}
854
855
856/* The following two functions are different, since they only read the
857 internal red/blue gains, which may be different from the manual
858 gains set or read above.
859 */
860static inline int pwc_read_red_gain(struct pwc_device *pdev, int *value)
861{
862 unsigned char buf;
863 int ret;
864
865 ret = RecvControlMsg(GET_STATUS_CTL, READ_RED_GAIN_FORMATTER, 1);
866 if (ret < 0)
867 return ret;
868 *value = buf << 8;
869 return 0;
870}
871
872static inline int pwc_read_blue_gain(struct pwc_device *pdev, int *value)
873{
874 unsigned char buf;
875 int ret;
876
877 ret = RecvControlMsg(GET_STATUS_CTL, READ_BLUE_GAIN_FORMATTER, 1);
878 if (ret < 0)
879 return ret;
880 *value = buf << 8;
881 return 0;
882}
883
884
885static inline int pwc_set_wb_speed(struct pwc_device *pdev, int speed)
886{
887 unsigned char buf;
888
889 /* useful range is 0x01..0x20 */
890 buf = speed / 0x7f0;
891 return SendControlMsg(SET_CHROM_CTL, AWB_CONTROL_SPEED_FORMATTER, 1);
892}
893
894static inline int pwc_get_wb_speed(struct pwc_device *pdev, int *value)
895{
896 unsigned char buf;
897 int ret;
898
899 ret = RecvControlMsg(GET_CHROM_CTL, AWB_CONTROL_SPEED_FORMATTER, 1);
900 if (ret < 0)
901 return ret;
902 *value = buf * 0x7f0;
903 return 0;
904}
905
906
907static inline int pwc_set_wb_delay(struct pwc_device *pdev, int delay)
908{
909 unsigned char buf;
910
911 /* useful range is 0x01..0x3F */
912 buf = (delay >> 10);
913 return SendControlMsg(SET_CHROM_CTL, AWB_CONTROL_DELAY_FORMATTER, 1);
914}
915
916static inline int pwc_get_wb_delay(struct pwc_device *pdev, int *value)
917{
918 unsigned char buf;
919 int ret;
920
921 ret = RecvControlMsg(GET_CHROM_CTL, AWB_CONTROL_DELAY_FORMATTER, 1);
922 if (ret < 0)
923 return ret;
924 *value = buf << 10;
925 return 0;
926}
927
928
929int pwc_set_leds(struct pwc_device *pdev, int on_value, int off_value)
930{
931 unsigned char buf[2];
932
933 if (pdev->type < 730)
934 return 0;
935 on_value /= 100;
936 off_value /= 100;
937 if (on_value < 0)
938 on_value = 0;
939 if (on_value > 0xff)
940 on_value = 0xff;
941 if (off_value < 0)
942 off_value = 0;
943 if (off_value > 0xff)
944 off_value = 0xff;
945
946 buf[0] = on_value;
947 buf[1] = off_value;
948
949 return SendControlMsg(SET_STATUS_CTL, LED_FORMATTER, 2);
950}
951
952int pwc_get_leds(struct pwc_device *pdev, int *on_value, int *off_value)
953{
954 unsigned char buf[2];
955 int ret;
956
957 if (pdev->type < 730) {
958 *on_value = -1;
959 *off_value = -1;
960 return 0;
961 }
962
963 ret = RecvControlMsg(GET_STATUS_CTL, LED_FORMATTER, 2);
964 if (ret < 0)
965 return ret;
966 *on_value = buf[0] * 100;
967 *off_value = buf[1] * 100;
968 return 0;
969}
970
971static inline int pwc_set_contour(struct pwc_device *pdev, int contour)
972{
973 unsigned char buf;
974 int ret;
975
976 if (contour < 0)
977 buf = 0xff; /* auto contour on */
978 else
979 buf = 0x0; /* auto contour off */
980 ret = SendControlMsg(SET_LUM_CTL, AUTO_CONTOUR_FORMATTER, 1);
981 if (ret < 0)
982 return ret;
983
984 if (contour < 0)
985 return 0;
986 if (contour > 0xffff)
987 contour = 0xffff;
988
989 buf = (contour >> 10); /* contour preset is [0..3f] */
990 ret = SendControlMsg(SET_LUM_CTL, PRESET_CONTOUR_FORMATTER, 1);
991 if (ret < 0)
992 return ret;
993 return 0;
994}
995
996static inline int pwc_get_contour(struct pwc_device *pdev, int *contour)
997{
998 unsigned char buf;
999 int ret;
1000
1001 ret = RecvControlMsg(GET_LUM_CTL, AUTO_CONTOUR_FORMATTER, 1);
1002 if (ret < 0)
1003 return ret;
1004
1005 if (buf == 0) {
1006 /* auto mode off, query current preset value */
1007 ret = RecvControlMsg(GET_LUM_CTL, PRESET_CONTOUR_FORMATTER, 1);
1008 if (ret < 0)
1009 return ret;
1010 *contour = buf << 10;
1011 }
1012 else
1013 *contour = -1;
1014 return 0;
1015}
1016
1017
1018static inline int pwc_set_backlight(struct pwc_device *pdev, int backlight)
1019{
1020 unsigned char buf;
1021
1022 if (backlight)
1023 buf = 0xff;
1024 else
1025 buf = 0x0;
1026 return SendControlMsg(SET_LUM_CTL, BACK_LIGHT_COMPENSATION_FORMATTER, 1);
1027}
1028
1029static inline int pwc_get_backlight(struct pwc_device *pdev, int *backlight)
1030{
1031 int ret;
1032 unsigned char buf;
1033
1034 ret = RecvControlMsg(GET_LUM_CTL, BACK_LIGHT_COMPENSATION_FORMATTER, 1);
1035 if (ret < 0)
1036 return ret;
1037 *backlight = buf;
1038 return 0;
1039}
1040
1041
1042static inline int pwc_set_flicker(struct pwc_device *pdev, int flicker)
1043{
1044 unsigned char buf;
1045
1046 if (flicker)
1047 buf = 0xff;
1048 else
1049 buf = 0x0;
1050 return SendControlMsg(SET_LUM_CTL, FLICKERLESS_MODE_FORMATTER, 1);
1051}
1052
1053static inline int pwc_get_flicker(struct pwc_device *pdev, int *flicker)
1054{
1055 int ret;
1056 unsigned char buf;
1057
1058 ret = RecvControlMsg(GET_LUM_CTL, FLICKERLESS_MODE_FORMATTER, 1);
1059 if (ret < 0)
1060 return ret;
1061 *flicker = buf;
1062 return 0;
1063}
1064
1065
1066static inline int pwc_set_dynamic_noise(struct pwc_device *pdev, int noise)
1067{
1068 unsigned char buf;
1069
1070 if (noise < 0)
1071 noise = 0;
1072 if (noise > 3)
1073 noise = 3;
1074 buf = noise;
1075 return SendControlMsg(SET_LUM_CTL, DYNAMIC_NOISE_CONTROL_FORMATTER, 1);
1076}
1077
1078static inline int pwc_get_dynamic_noise(struct pwc_device *pdev, int *noise)
1079{
1080 int ret;
1081 unsigned char buf;
1082
1083 ret = RecvControlMsg(GET_LUM_CTL, DYNAMIC_NOISE_CONTROL_FORMATTER, 1);
1084 if (ret < 0)
1085 return ret;
1086 *noise = buf;
1087 return 0;
1088}
1089
1090static int pwc_mpt_reset(struct pwc_device *pdev, int flags)
1091{
1092 unsigned char buf;
1093
1094 buf = flags & 0x03; // only lower two bits are currently used
1095 return SendControlMsg(SET_MPT_CTL, PT_RESET_CONTROL_FORMATTER, 1);
1096}
1097
1098static inline int pwc_mpt_set_angle(struct pwc_device *pdev, int pan, int tilt)
1099{
1100 unsigned char buf[4];
1101
1102 /* set new relative angle; angles are expressed in degrees * 100,
1103 but cam as .5 degree resolution, hence devide by 200. Also
1104 the angle must be multiplied by 64 before it's send to
1105 the cam (??)
1106 */
1107 pan = 64 * pan / 100;
1108 tilt = -64 * tilt / 100; /* positive tilt is down, which is not what the user would expect */
1109 buf[0] = pan & 0xFF;
1110 buf[1] = (pan >> 8) & 0xFF;
1111 buf[2] = tilt & 0xFF;
1112 buf[3] = (tilt >> 8) & 0xFF;
1113 return SendControlMsg(SET_MPT_CTL, PT_RELATIVE_CONTROL_FORMATTER, 4);
1114}
1115
1116static inline int pwc_mpt_get_status(struct pwc_device *pdev, struct pwc_mpt_status *status)
1117{
1118 int ret;
1119 unsigned char buf[5];
1120
1121 ret = RecvControlMsg(GET_MPT_CTL, PT_STATUS_FORMATTER, 5);
1122 if (ret < 0)
1123 return ret;
1124 status->status = buf[0] & 0x7; // 3 bits are used for reporting
1125 status->time_pan = (buf[1] << 8) + buf[2];
1126 status->time_tilt = (buf[3] << 8) + buf[4];
1127 return 0;
1128}
1129
1130
1131int pwc_get_cmos_sensor(struct pwc_device *pdev, int *sensor)
1132{
1133 unsigned char buf;
1134 int ret = -1, request;
1135
1136 if (pdev->type < 675)
1137 request = SENSOR_TYPE_FORMATTER1;
1138 else if (pdev->type < 730)
1139 return -1; /* The Vesta series doesn't have this call */
1140 else
1141 request = SENSOR_TYPE_FORMATTER2;
1142
1143 ret = RecvControlMsg(GET_STATUS_CTL, request, 1);
1144 if (ret < 0)
1145 return ret;
1146 if (pdev->type < 675)
1147 *sensor = buf | 0x100;
1148 else
1149 *sensor = buf;
1150 return 0;
1151}
1152
1153
1154 /* End of Add-Ons */
1155 /* ************************************************* */
1156
1157/* Linux 2.5.something and 2.6 pass direct pointers to arguments of
1158 ioctl() calls. With 2.4, you have to do tedious copy_from_user()
1159 and copy_to_user() calls. With these macros we circumvent this,
1160 and let me maintain only one source file. The functionality is
1161 exactly the same otherwise.
1162 */
1163
1164#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)
1165
1166/* define local variable for arg */
1167#define ARG_DEF(ARG_type, ARG_name)\
1168 ARG_type *ARG_name = arg;
1169/* copy arg to local variable */
1170#define ARG_IN(ARG_name) /* nothing */
1171/* argument itself (referenced) */
1172#define ARGR(ARG_name) (*ARG_name)
1173/* argument address */
1174#define ARGA(ARG_name) ARG_name
1175/* copy local variable to arg */
1176#define ARG_OUT(ARG_name) /* nothing */
1177
1178#else
1179
1180#define ARG_DEF(ARG_type, ARG_name)\
1181 ARG_type ARG_name;
1182#define ARG_IN(ARG_name)\
1183 if (copy_from_user(&ARG_name, arg, sizeof(ARG_name))) {\
1184 ret = -EFAULT;\
1185 break;\
1186 }
1187#define ARGR(ARG_name) ARG_name
1188#define ARGA(ARG_name) &ARG_name
1189#define ARG_OUT(ARG_name)\
1190 if (copy_to_user(arg, &ARG_name, sizeof(ARG_name))) {\
1191 ret = -EFAULT;\
1192 break;\
1193 }
1194
1195#endif
1196
1197int pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg)
1198{
1199 int ret = 0;
1200
1201 switch(cmd) {
1202 case VIDIOCPWCRUSER:
1203 {
1204 if (pwc_restore_user(pdev))
1205 ret = -EINVAL;
1206 break;
1207 }
1208
1209 case VIDIOCPWCSUSER:
1210 {
1211 if (pwc_save_user(pdev))
1212 ret = -EINVAL;
1213 break;
1214 }
1215
1216 case VIDIOCPWCFACTORY:
1217 {
1218 if (pwc_restore_factory(pdev))
1219 ret = -EINVAL;
1220 break;
1221 }
1222
1223 case VIDIOCPWCSCQUAL:
1224 {
1225 ARG_DEF(int, qual)
1226
1227 ARG_IN(qual)
1228 if (ARGR(qual) < 0 || ARGR(qual) > 3)
1229 ret = -EINVAL;
1230 else
1231 ret = pwc_try_video_mode(pdev, pdev->view.x, pdev->view.y, pdev->vframes, ARGR(qual), pdev->vsnapshot);
1232 if (ret >= 0)
1233 pdev->vcompression = ARGR(qual);
1234 break;
1235 }
1236
1237 case VIDIOCPWCGCQUAL:
1238 {
1239 ARG_DEF(int, qual)
1240
1241 ARGR(qual) = pdev->vcompression;
1242 ARG_OUT(qual)
1243 break;
1244 }
1245
1246 case VIDIOCPWCPROBE:
1247 {
1248 ARG_DEF(struct pwc_probe, probe)
1249
1250 strcpy(ARGR(probe).name, pdev->vdev->name);
1251 ARGR(probe).type = pdev->type;
1252 ARG_OUT(probe)
1253 break;
1254 }
1255
1256 case VIDIOCPWCGSERIAL:
1257 {
1258 ARG_DEF(struct pwc_serial, serial)
1259
1260 strcpy(ARGR(serial).serial, pdev->serial);
1261 ARG_OUT(serial)
1262 break;
1263 }
1264
1265 case VIDIOCPWCSAGC:
1266 {
1267 ARG_DEF(int, agc)
1268
1269 ARG_IN(agc)
1270 if (pwc_set_agc(pdev, ARGR(agc) < 0 ? 1 : 0, ARGR(agc)))
1271 ret = -EINVAL;
1272 break;
1273 }
1274
1275 case VIDIOCPWCGAGC:
1276 {
1277 ARG_DEF(int, agc)
1278
1279 if (pwc_get_agc(pdev, ARGA(agc)))
1280 ret = -EINVAL;
1281 ARG_OUT(agc)
1282 break;
1283 }
1284
1285 case VIDIOCPWCSSHUTTER:
1286 {
1287 ARG_DEF(int, shutter_speed)
1288
1289 ARG_IN(shutter_speed)
1290 ret = pwc_set_shutter_speed(pdev, ARGR(shutter_speed) < 0 ? 1 : 0, ARGR(shutter_speed));
1291 break;
1292 }
1293
1294 case VIDIOCPWCSAWB:
1295 {
1296 ARG_DEF(struct pwc_whitebalance, wb)
1297
1298 ARG_IN(wb)
1299 ret = pwc_set_awb(pdev, ARGR(wb).mode);
1300 if (ret >= 0 && ARGR(wb).mode == PWC_WB_MANUAL) {
1301 pwc_set_red_gain(pdev, ARGR(wb).manual_red);
1302 pwc_set_blue_gain(pdev, ARGR(wb).manual_blue);
1303 }
1304 break;
1305 }
1306
1307 case VIDIOCPWCGAWB:
1308 {
1309 ARG_DEF(struct pwc_whitebalance, wb)
1310
1311 memset(ARGA(wb), 0, sizeof(struct pwc_whitebalance));
1312 ARGR(wb).mode = pwc_get_awb(pdev);
1313 if (ARGR(wb).mode < 0)
1314 ret = -EINVAL;
1315 else {
1316 if (ARGR(wb).mode == PWC_WB_MANUAL) {
1317 ret = pwc_get_red_gain(pdev, &ARGR(wb).manual_red);
1318 if (ret < 0)
1319 break;
1320 ret = pwc_get_blue_gain(pdev, &ARGR(wb).manual_blue);
1321 if (ret < 0)
1322 break;
1323 }
1324 if (ARGR(wb).mode == PWC_WB_AUTO) {
1325 ret = pwc_read_red_gain(pdev, &ARGR(wb).read_red);
1326 if (ret < 0)
1327 break;
1328 ret =pwc_read_blue_gain(pdev, &ARGR(wb).read_blue);
1329 if (ret < 0)
1330 break;
1331 }
1332 }
1333 ARG_OUT(wb)
1334 break;
1335 }
1336
1337 case VIDIOCPWCSAWBSPEED:
1338 {
1339 ARG_DEF(struct pwc_wb_speed, wbs)
1340
1341 if (ARGR(wbs).control_speed > 0) {
1342 ret = pwc_set_wb_speed(pdev, ARGR(wbs).control_speed);
1343 }
1344 if (ARGR(wbs).control_delay > 0) {
1345 ret = pwc_set_wb_delay(pdev, ARGR(wbs).control_delay);
1346 }
1347 break;
1348 }
1349
1350 case VIDIOCPWCGAWBSPEED:
1351 {
1352 ARG_DEF(struct pwc_wb_speed, wbs)
1353
1354 ret = pwc_get_wb_speed(pdev, &ARGR(wbs).control_speed);
1355 if (ret < 0)
1356 break;
1357 ret = pwc_get_wb_delay(pdev, &ARGR(wbs).control_delay);
1358 if (ret < 0)
1359 break;
1360 ARG_OUT(wbs)
1361 break;
1362 }
1363
1364 case VIDIOCPWCSLED:
1365 {
1366 ARG_DEF(struct pwc_leds, leds)
1367
1368 ARG_IN(leds)
1369 ret = pwc_set_leds(pdev, ARGR(leds).led_on, ARGR(leds).led_off);
1370 break;
1371 }
1372
1373
1374 case VIDIOCPWCGLED:
1375 {
1376 ARG_DEF(struct pwc_leds, leds)
1377
1378 ret = pwc_get_leds(pdev, &ARGR(leds).led_on, &ARGR(leds).led_off);
1379 ARG_OUT(leds)
1380 break;
1381 }
1382
1383 case VIDIOCPWCSCONTOUR:
1384 {
1385 ARG_DEF(int, contour)
1386
1387 ARG_IN(contour)
1388 ret = pwc_set_contour(pdev, ARGR(contour));
1389 break;
1390 }
1391
1392 case VIDIOCPWCGCONTOUR:
1393 {
1394 ARG_DEF(int, contour)
1395
1396 ret = pwc_get_contour(pdev, ARGA(contour));
1397 ARG_OUT(contour)
1398 break;
1399 }
1400
1401 case VIDIOCPWCSBACKLIGHT:
1402 {
1403 ARG_DEF(int, backlight)
1404
1405 ARG_IN(backlight)
1406 ret = pwc_set_backlight(pdev, ARGR(backlight));
1407 break;
1408 }
1409
1410 case VIDIOCPWCGBACKLIGHT:
1411 {
1412 ARG_DEF(int, backlight)
1413
1414 ret = pwc_get_backlight(pdev, ARGA(backlight));
1415 ARG_OUT(backlight)
1416 break;
1417 }
1418
1419 case VIDIOCPWCSFLICKER:
1420 {
1421 ARG_DEF(int, flicker)
1422
1423 ARG_IN(flicker)
1424 ret = pwc_set_flicker(pdev, ARGR(flicker));
1425 break;
1426 }
1427
1428 case VIDIOCPWCGFLICKER:
1429 {
1430 ARG_DEF(int, flicker)
1431
1432 ret = pwc_get_flicker(pdev, ARGA(flicker));
1433 ARG_OUT(flicker)
1434 break;
1435 }
1436
1437 case VIDIOCPWCSDYNNOISE:
1438 {
1439 ARG_DEF(int, dynnoise)
1440
1441 ARG_IN(dynnoise)
1442 ret = pwc_set_dynamic_noise(pdev, ARGR(dynnoise));
1443 break;
1444 }
1445
1446 case VIDIOCPWCGDYNNOISE:
1447 {
1448 ARG_DEF(int, dynnoise)
1449
1450 ret = pwc_get_dynamic_noise(pdev, ARGA(dynnoise));
1451 ARG_OUT(dynnoise);
1452 break;
1453 }
1454
1455 case VIDIOCPWCGREALSIZE:
1456 {
1457 ARG_DEF(struct pwc_imagesize, size)
1458
1459 ARGR(size).width = pdev->image.x;
1460 ARGR(size).height = pdev->image.y;
1461 ARG_OUT(size)
1462 break;
1463 }
1464
1465 case VIDIOCPWCMPTRESET:
1466 {
1467 if (pdev->features & FEATURE_MOTOR_PANTILT)
1468 {
1469 ARG_DEF(int, flags)
1470
1471 ARG_IN(flags)
1472 ret = pwc_mpt_reset(pdev, ARGR(flags));
1473 if (ret >= 0)
1474 {
1475 pdev->pan_angle = 0;
1476 pdev->tilt_angle = 0;
1477 }
1478 }
1479 else
1480 {
1481 ret = -ENXIO;
1482 }
1483 break;
1484 }
1485
1486 case VIDIOCPWCMPTGRANGE:
1487 {
1488 if (pdev->features & FEATURE_MOTOR_PANTILT)
1489 {
1490 ARG_DEF(struct pwc_mpt_range, range)
1491
1492 ARGR(range) = pdev->angle_range;
1493 ARG_OUT(range)
1494 }
1495 else
1496 {
1497 ret = -ENXIO;
1498 }
1499 break;
1500 }
1501
1502 case VIDIOCPWCMPTSANGLE:
1503 {
1504 int new_pan, new_tilt;
1505
1506 if (pdev->features & FEATURE_MOTOR_PANTILT)
1507 {
1508 ARG_DEF(struct pwc_mpt_angles, angles)
1509
1510 ARG_IN(angles)
1511 /* The camera can only set relative angles, so
1512 do some calculations when getting an absolute angle .
1513 */
1514 if (ARGR(angles).absolute)
1515 {
1516 new_pan = ARGR(angles).pan;
1517 new_tilt = ARGR(angles).tilt;
1518 }
1519 else
1520 {
1521 new_pan = pdev->pan_angle + ARGR(angles).pan;
1522 new_tilt = pdev->tilt_angle + ARGR(angles).tilt;
1523 }
1524 /* check absolute ranges */
1525 if (new_pan < pdev->angle_range.pan_min ||
1526 new_pan > pdev->angle_range.pan_max ||
1527 new_tilt < pdev->angle_range.tilt_min ||
1528 new_tilt > pdev->angle_range.tilt_max)
1529 {
1530 ret = -ERANGE;
1531 }
1532 else
1533 {
1534 /* go to relative range, check again */
1535 new_pan -= pdev->pan_angle;
1536 new_tilt -= pdev->tilt_angle;
1537 /* angles are specified in degrees * 100, thus the limit = 36000 */
1538 if (new_pan < -36000 || new_pan > 36000 || new_tilt < -36000 || new_tilt > 36000)
1539 ret = -ERANGE;
1540 }
1541 if (ret == 0) /* no errors so far */
1542 {
1543 ret = pwc_mpt_set_angle(pdev, new_pan, new_tilt);
1544 if (ret >= 0)
1545 {
1546 pdev->pan_angle += new_pan;
1547 pdev->tilt_angle += new_tilt;
1548 }
1549 if (ret == -EPIPE) /* stall -> out of range */
1550 ret = -ERANGE;
1551 }
1552 }
1553 else
1554 {
1555 ret = -ENXIO;
1556 }
1557 break;
1558 }
1559
1560 case VIDIOCPWCMPTGANGLE:
1561 {
1562
1563 if (pdev->features & FEATURE_MOTOR_PANTILT)
1564 {
1565 ARG_DEF(struct pwc_mpt_angles, angles)
1566
1567 ARGR(angles).absolute = 1;
1568 ARGR(angles).pan = pdev->pan_angle;
1569 ARGR(angles).tilt = pdev->tilt_angle;
1570 ARG_OUT(angles)
1571 }
1572 else
1573 {
1574 ret = -ENXIO;
1575 }
1576 break;
1577 }
1578
1579 case VIDIOCPWCMPTSTATUS:
1580 {
1581 if (pdev->features & FEATURE_MOTOR_PANTILT)
1582 {
1583 ARG_DEF(struct pwc_mpt_status, status)
1584
1585 ret = pwc_mpt_get_status(pdev, ARGA(status));
1586 ARG_OUT(status)
1587 }
1588 else
1589 {
1590 ret = -ENXIO;
1591 }
1592 break;
1593 }
1594
1595 case VIDIOCPWCGVIDCMD:
1596 {
1597 ARG_DEF(struct pwc_video_command, cmd);
1598
1599 ARGR(cmd).type = pdev->type;
1600 ARGR(cmd).release = pdev->release;
1601 ARGR(cmd).command_len = pdev->cmd_len;
1602 memcpy(&ARGR(cmd).command_buf, pdev->cmd_buf, pdev->cmd_len);
1603 ARGR(cmd).bandlength = pdev->vbandlength;
1604 ARGR(cmd).frame_size = pdev->frame_size;
1605 ARG_OUT(cmd)
1606 break;
1607 }
1608 /*
1609 case VIDIOCPWCGVIDTABLE:
1610 {
1611 ARG_DEF(struct pwc_table_init_buffer, table);
1612 ARGR(table).len = pdev->cmd_len;
1613 memcpy(&ARGR(table).buffer, pdev->decompress_data, pdev->decompressor->table_size);
1614 ARG_OUT(table)
1615 break;
1616 }
1617 */
1618
1619 default:
1620 ret = -ENOIOCTLCMD;
1621 break;
1622 }
1623
1624 if (ret > 0)
1625 return 0;
1626 return ret;
1627}
1628
1629
1630
diff --git a/drivers/usb/media/pwc/pwc-dec1.c b/drivers/usb/media/pwc/pwc-dec1.c
new file mode 100644
index 000000000000..57d03d9178f6
--- /dev/null
+++ b/drivers/usb/media/pwc/pwc-dec1.c
@@ -0,0 +1,42 @@
1/* Linux driver for Philips webcam
2 Decompression for chipset version 1
3 (C) 2004 Luc Saillard (luc@saillard.org)
4
5 NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx
6 driver and thus may have bugs that are not present in the original version.
7 Please send bug reports and support requests to <luc@saillard.org>.
8 The decompression routines have been implemented by reverse-engineering the
9 Nemosoft binary pwcx module. Caveat emptor.
10
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 2 of the License, or
14 (at your option) any later version.
15
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
20
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software
23 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24*/
25
26
27
28#include "pwc-dec1.h"
29
30
31void pwc_dec1_init(int type, int release, void *buffer, void *table)
32{
33
34}
35
36void pwc_dec1_exit(void)
37{
38
39
40
41}
42
diff --git a/drivers/usb/media/pwc/pwc-dec1.h b/drivers/usb/media/pwc/pwc-dec1.h
new file mode 100644
index 000000000000..a7ffd9c45a2c
--- /dev/null
+++ b/drivers/usb/media/pwc/pwc-dec1.h
@@ -0,0 +1,36 @@
1/* Linux driver for Philips webcam
2 (C) 2004 Luc Saillard (luc@saillard.org)
3
4 NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx
5 driver and thus may have bugs that are not present in the original version.
6 Please send bug reports and support requests to <luc@saillard.org>.
7 The decompression routines have been implemented by reverse-engineering the
8 Nemosoft binary pwcx module. Caveat emptor.
9
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2 of the License, or
13 (at your option) any later version.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23*/
24
25
26
27#ifndef PWC_DEC1_H
28#define PWC_DEC1_H
29
30void pwc_dec1_init(int type, int release, void *buffer, void *private_data);
31void pwc_dec1_exit(void);
32
33#endif
34
35
36
diff --git a/drivers/usb/media/pwc/pwc-dec23.c b/drivers/usb/media/pwc/pwc-dec23.c
new file mode 100644
index 000000000000..98fa3f7a9eff
--- /dev/null
+++ b/drivers/usb/media/pwc/pwc-dec23.c
@@ -0,0 +1,623 @@
1/* Linux driver for Philips webcam
2 Decompression for chipset version 2 et 3
3 (C) 2004 Luc Saillard (luc@saillard.org)
4
5 NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx
6 driver and thus may have bugs that are not present in the original version.
7 Please send bug reports and support requests to <luc@saillard.org>.
8 The decompression routines have been implemented by reverse-engineering the
9 Nemosoft binary pwcx module. Caveat emptor.
10
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 2 of the License, or
14 (at your option) any later version.
15
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
20
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software
23 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24*/
25
26#include "pwc-timon.h"
27#include "pwc-kiara.h"
28#include "pwc-dec23.h"
29#include "pwc-ioctl.h"
30
31#include <linux/string.h>
32
33/****
34 *
35 *
36 *
37 */
38
39
40static void fill_table_a000(unsigned int *p)
41{
42 static unsigned int initial_values[12] = {
43 0xFFAD9B00, 0xFFDDEE00, 0x00221200, 0x00526500,
44 0xFFC21E00, 0x003DE200, 0xFF924B80, 0xFFD2A300,
45 0x002D5D00, 0x006DB480, 0xFFED3E00, 0x0012C200
46 };
47 static unsigned int values_derivated[12] = {
48 0x0000A4CA, 0x00004424, 0xFFFFBBDC, 0xFFFF5B36,
49 0x00007BC4, 0xFFFF843C, 0x0000DB69, 0x00005ABA,
50 0xFFFFA546, 0xFFFF2497, 0x00002584, 0xFFFFDA7C
51 };
52 unsigned int temp_values[12];
53 int i,j;
54
55 memcpy(temp_values,initial_values,sizeof(initial_values));
56 for (i=0;i<256;i++)
57 {
58 for (j=0;j<12;j++)
59 {
60 *p++ = temp_values[j];
61 temp_values[j] += values_derivated[j];
62 }
63 }
64}
65
66static void fill_table_d000(unsigned char *p)
67{
68 int bit,byte;
69
70 for (bit=0; bit<8; bit++)
71 {
72 unsigned char bitpower = 1<<bit;
73 unsigned char mask = bitpower-1;
74 for (byte=0; byte<256; byte++)
75 {
76 if (byte & bitpower)
77 *p++ = -(byte & mask);
78 else
79 *p++ = (byte & mask);
80 }
81 }
82}
83
84/*
85 *
86 * Kiara: 0 <= ver <= 7
87 * Timon: 0 <= ver <= 15
88 *
89 */
90static void fill_table_color(unsigned int version, const unsigned int *romtable,
91 unsigned char *p0004,
92 unsigned char *p8004)
93{
94 const unsigned int *table;
95 unsigned char *p0, *p8;
96 int i,j,k;
97 int dl,bit,pw;
98
99 romtable += version*256;
100
101 for (i=0; i<2; i++)
102 {
103 table = romtable + i*128;
104
105 for (dl=0; dl<16; dl++)
106 {
107 p0 = p0004 + (i<<14) + (dl<<10);
108 p8 = p8004 + (i<<12) + (dl<<8);
109
110 for (j=0; j<8; j++ , table++, p0+=128)
111 {
112 for (k=0; k<16; k++)
113 {
114 if (k==0)
115 bit=1;
116 else if (k>=1 && k<3)
117 bit=(table[0]>>15)&7;
118 else if (k>=3 && k<6)
119 bit=(table[0]>>12)&7;
120 else if (k>=6 && k<10)
121 bit=(table[0]>>9)&7;
122 else if (k>=10 && k<13)
123 bit=(table[0]>>6)&7;
124 else if (k>=13 && k<15)
125 bit=(table[0]>>3)&7;
126 else
127 bit=(table[0])&7;
128 if (k == 0)
129 *(unsigned char *)p8++ = 8;
130 else
131 *(unsigned char *)p8++ = j - bit;
132 *(unsigned char *)p8++ = bit;
133
134 pw = 1<<bit;
135 p0[k+0x00] = (1*pw) + 0x80;
136 p0[k+0x10] = (2*pw) + 0x80;
137 p0[k+0x20] = (3*pw) + 0x80;
138 p0[k+0x30] = (4*pw) + 0x80;
139 p0[k+0x40] = (-pw) + 0x80;
140 p0[k+0x50] = (2*-pw) + 0x80;
141 p0[k+0x60] = (3*-pw) + 0x80;
142 p0[k+0x70] = (4*-pw) + 0x80;
143 } /* end of for (k=0; k<16; k++, p8++) */
144 } /* end of for (j=0; j<8; j++ , table++) */
145 } /* end of for (dl=0; dl<16; dl++) */
146 } /* end of for (i=0; i<2; i++) */
147}
148
149/*
150 * precision = (pdev->xx + pdev->yy)
151 *
152 */
153static void fill_table_dc00_d800(unsigned int precision, unsigned int *pdc00, unsigned int *pd800)
154{
155 int i;
156 unsigned int offset1, offset2;
157
158 for(i=0,offset1=0x4000, offset2=0; i<256 ; i++,offset1+=0x7BC4, offset2+=0x7BC4)
159 {
160 unsigned int msb = offset1 >> 15;
161
162 if ( msb > 255)
163 {
164 if (msb)
165 msb=0;
166 else
167 msb=255;
168 }
169
170 *pdc00++ = msb << precision;
171 *pd800++ = offset2;
172 }
173
174}
175
176/*
177 * struct {
178 * unsigned char op; // operation to execute
179 * unsigned char bits; // bits use to perform operation
180 * unsigned char offset1; // offset to add to access in the table_0004 % 16
181 * unsigned char offset2; // offset to add to access in the table_0004
182 * }
183 *
184 */
185static unsigned int table_ops[] = {
1860x02,0x00,0x00,0x00, 0x00,0x03,0x01,0x00, 0x00,0x04,0x01,0x10, 0x00,0x06,0x01,0x30,
1870x02,0x00,0x00,0x00, 0x00,0x03,0x01,0x40, 0x00,0x05,0x01,0x20, 0x01,0x00,0x00,0x00,
1880x02,0x00,0x00,0x00, 0x00,0x03,0x01,0x00, 0x00,0x04,0x01,0x50, 0x00,0x05,0x02,0x00,
1890x02,0x00,0x00,0x00, 0x00,0x03,0x01,0x40, 0x00,0x05,0x03,0x00, 0x01,0x00,0x00,0x00,
1900x02,0x00,0x00,0x00, 0x00,0x03,0x01,0x00, 0x00,0x04,0x01,0x10, 0x00,0x06,0x02,0x10,
1910x02,0x00,0x00,0x00, 0x00,0x03,0x01,0x40, 0x00,0x05,0x01,0x60, 0x01,0x00,0x00,0x00,
1920x02,0x00,0x00,0x00, 0x00,0x03,0x01,0x00, 0x00,0x04,0x01,0x50, 0x00,0x05,0x02,0x40,
1930x02,0x00,0x00,0x00, 0x00,0x03,0x01,0x40, 0x00,0x05,0x03,0x40, 0x01,0x00,0x00,0x00,
1940x02,0x00,0x00,0x00, 0x00,0x03,0x01,0x00, 0x00,0x04,0x01,0x10, 0x00,0x06,0x01,0x70,
1950x02,0x00,0x00,0x00, 0x00,0x03,0x01,0x40, 0x00,0x05,0x01,0x20, 0x01,0x00,0x00,0x00,
1960x02,0x00,0x00,0x00, 0x00,0x03,0x01,0x00, 0x00,0x04,0x01,0x50, 0x00,0x05,0x02,0x00,
1970x02,0x00,0x00,0x00, 0x00,0x03,0x01,0x40, 0x00,0x05,0x03,0x00, 0x01,0x00,0x00,0x00,
1980x02,0x00,0x00,0x00, 0x00,0x03,0x01,0x00, 0x00,0x04,0x01,0x10, 0x00,0x06,0x02,0x50,
1990x02,0x00,0x00,0x00, 0x00,0x03,0x01,0x40, 0x00,0x05,0x01,0x60, 0x01,0x00,0x00,0x00,
2000x02,0x00,0x00,0x00, 0x00,0x03,0x01,0x00, 0x00,0x04,0x01,0x50, 0x00,0x05,0x02,0x40,
2010x02,0x00,0x00,0x00, 0x00,0x03,0x01,0x40, 0x00,0x05,0x03,0x40, 0x01,0x00,0x00,0x00
202};
203
204/*
205 * TODO: multiply by 4 all values
206 *
207 */
208static unsigned int MulIdx[256] = {
209 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
210 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3,
211 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3,
212 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 4, 4, 4, 4,
213 6, 7, 8, 9, 7,10,11, 8, 8,11,10, 7, 9, 8, 7, 6,
214 4, 5, 5, 4, 4, 5, 5, 4, 4, 5, 5, 4, 4, 5, 5, 4,
215 1, 3, 0, 2, 1, 3, 0, 2, 1, 3, 0, 2, 1, 3, 0, 2,
216 0, 3, 3, 0, 1, 2, 2, 1, 2, 1, 1, 2, 3, 0, 0, 3,
217 0, 1, 2, 3, 3, 2, 1, 0, 3, 2, 1, 0, 0, 1, 2, 3,
218 1, 1, 1, 1, 3, 3, 3, 3, 0, 0, 0, 0, 2, 2, 2, 2,
219 7,10,11, 8, 9, 8, 7, 6, 6, 7, 8, 9, 8,11,10, 7,
220 4, 5, 5, 4, 5, 4, 4, 5, 5, 4, 4, 5, 4, 5, 5, 4,
221 7, 9, 6, 8,10, 8, 7,11,11, 7, 8,10, 8, 6, 9, 7,
222 1, 3, 0, 2, 2, 0, 3, 1, 2, 0, 3, 1, 1, 3, 0, 2,
223 1, 2, 2, 1, 3, 0, 0, 3, 0, 3, 3, 0, 2, 1, 1, 2,
22410, 8, 7,11, 8, 6, 9, 7, 7, 9, 6, 8,11, 7, 8,10
225};
226
227
228
229void pwc_dec23_init(int type, int release, unsigned char *mode, void *data)
230{
231 int flags;
232 struct pwc_dec23_private *pdev = data;
233 release = release;
234
235 switch (type)
236 {
237 case 720:
238 case 730:
239 case 740:
240 case 750:
241 flags = mode[2]&0x18; /* our: flags = 8, mode[2]==e8 */
242 if (flags==8)
243 pdev->zz = 7;
244 else if (flags==0x10)
245 pdev->zz = 8;
246 else
247 pdev->zz = 6;
248 flags = mode[2]>>5; /* our: 7 */
249
250 fill_table_color(flags, (unsigned int *)KiaraRomTable, pdev->table_0004, pdev->table_8004);
251 break;
252
253
254 case 675:
255 case 680:
256 case 690:
257 flags = mode[2]&6;
258 if (flags==2)
259 pdev->zz = 7;
260 else if (flags==4)
261 pdev->zz = 8;
262 else
263 pdev->zz = 6;
264 flags = mode[2]>>3;
265
266 fill_table_color(flags, (unsigned int *)TimonRomTable, pdev->table_0004, pdev->table_8004);
267 break;
268
269 default:
270 /* Not supported */
271 return;
272 }
273
274 /* * * * ** */
275 pdev->xx = 8 - pdev->zz;
276 pdev->yy = 15 - pdev->xx;
277 pdev->zzmask = 0xFF>>pdev->xx;
278 //pdev->zzmask = (1U<<pdev->zz)-1;
279
280
281 fill_table_dc00_d800(pdev->xx + pdev->yy, pdev->table_dc00, pdev->table_d800);
282 fill_table_a000(pdev->table_a004);
283 fill_table_d000(pdev->table_d004);
284}
285
286
287/*
288 * To manage the stream, we keep in a 32 bits variables,
289 * the next bits in the stream. fill_reservoir() add to
290 * the reservoir at least wanted nbits.
291 *
292 *
293 */
294#define fill_nbits(reservoir,nbits_in_reservoir,stream,nbits_wanted) do { \
295 while (nbits_in_reservoir<nbits_wanted) \
296 { \
297 reservoir |= (*(stream)++) << nbits_in_reservoir; \
298 nbits_in_reservoir+=8; \
299 } \
300} while(0);
301
302#define get_nbits(reservoir,nbits_in_reservoir,stream,nbits_wanted,result) do { \
303 fill_nbits(reservoir,nbits_in_reservoir,stream,nbits_wanted); \
304 result = (reservoir) & ((1U<<nbits_wanted)-1); \
305 reservoir >>= nbits_wanted; \
306 nbits_in_reservoir -= nbits_wanted; \
307} while(0);
308
309
310
311static void DecompressBand23(const struct pwc_dec23_private *pdev,
312 const unsigned char *rawyuv,
313 unsigned char *planar_y,
314 unsigned char *planar_u,
315 unsigned char *planar_v,
316 unsigned int image_x, /* aka number of pixels wanted ??? */
317 unsigned int pixels_per_line, /* aka number of pixels per line */
318 int flags)
319{
320
321
322 unsigned int reservoir, nbits_in_reservoir;
323 int first_4_bits;
324 unsigned int bytes_per_channel;
325 int line_size; /* size of the line (4Y+U+V) */
326 int passes;
327 const unsigned char *ptable0004, *ptable8004;
328
329 int even_line;
330 unsigned int temp_colors[16];
331 int nblocks;
332
333 const unsigned char *stream;
334 unsigned char *dest_y, *dest_u=NULL, *dest_v=NULL;
335 unsigned int offset_to_plane_u, offset_to_plane_v;
336
337 int i;
338
339
340 reservoir = 0;
341 nbits_in_reservoir = 0;
342 stream = rawyuv+1; /* The first byte of the stream is skipped */
343 even_line = 1;
344
345 get_nbits(reservoir,nbits_in_reservoir,stream,4,first_4_bits);
346
347 line_size = pixels_per_line*3;
348
349 for (passes=0;passes<2;passes++)
350 {
351 if (passes==0)
352 {
353 bytes_per_channel = pixels_per_line;
354 dest_y = planar_y;
355 nblocks = image_x/4;
356 }
357 else
358 {
359 /* Format planar: All Y, then all U, then all V */
360 bytes_per_channel = pixels_per_line/2;
361 dest_u = planar_u;
362 dest_v = planar_v;
363 dest_y = dest_u;
364 nblocks = image_x/8;
365 }
366
367 offset_to_plane_u = bytes_per_channel*2;
368 offset_to_plane_v = bytes_per_channel*3;
369 /*
370 printf("bytes_per_channel = %d\n",bytes_per_channel);
371 printf("offset_to_plane_u = %d\n",offset_to_plane_u);
372 printf("offset_to_plane_v = %d\n",offset_to_plane_v);
373 */
374
375 while (nblocks-->0)
376 {
377 unsigned int gray_index;
378
379 fill_nbits(reservoir,nbits_in_reservoir,stream,16);
380 gray_index = reservoir & pdev->zzmask;
381 reservoir >>= pdev->zz;
382 nbits_in_reservoir -= pdev->zz;
383
384 fill_nbits(reservoir,nbits_in_reservoir,stream,2);
385
386 if ( (reservoir & 3) == 0)
387 {
388 reservoir>>=2;
389 nbits_in_reservoir-=2;
390 for (i=0;i<16;i++)
391 temp_colors[i] = pdev->table_dc00[gray_index];
392
393 }
394 else
395 {
396 unsigned int channel_v, offset1;
397
398 /* swap bit 0 and 2 of offset_OR */
399 channel_v = ((reservoir & 1) << 2) | (reservoir & 2) | ((reservoir & 4)>>2);
400 reservoir>>=3;
401 nbits_in_reservoir-=3;
402
403 for (i=0;i<16;i++)
404 temp_colors[i] = pdev->table_d800[gray_index];
405
406 ptable0004 = pdev->table_0004 + (passes*16384) + (first_4_bits*1024) + (channel_v*128);
407 ptable8004 = pdev->table_8004 + (passes*4096) + (first_4_bits*256) + (channel_v*32);
408
409 offset1 = 0;
410 while(1)
411 {
412 unsigned int index_in_table_ops, op, rows=0;
413 fill_nbits(reservoir,nbits_in_reservoir,stream,16);
414
415 /* mode is 0,1 or 2 */
416 index_in_table_ops = (reservoir&0x3F);
417 op = table_ops[ index_in_table_ops*4 ];
418 if (op == 2)
419 {
420 reservoir >>= 2;
421 nbits_in_reservoir -= 2;
422 break; /* exit the while(1) */
423 }
424 if (op == 0)
425 {
426 unsigned int shift;
427
428 offset1 = (offset1 + table_ops[index_in_table_ops*4+2]) & 0x0F;
429 shift = table_ops[ index_in_table_ops*4+1 ];
430 reservoir >>= shift;
431 nbits_in_reservoir -= shift;
432 rows = ptable0004[ offset1 + table_ops[index_in_table_ops*4+3] ];
433 }
434 if (op == 1)
435 {
436 /* 10bits [ xxxx xxxx yyyy 000 ]
437 * yyy => offset in the table8004
438 * xxx => offset in the tabled004
439 */
440 unsigned int mask, shift;
441 unsigned int col1, row1, total_bits;
442
443 offset1 = (offset1 + ((reservoir>>3)&0x0F)+1) & 0x0F;
444
445 col1 = (reservoir>>7) & 0xFF;
446 row1 = ptable8004 [ offset1*2 ];
447
448 /* Bit mask table */
449 mask = pdev->table_d004[ (row1<<8) + col1 ];
450 shift = ptable8004 [ offset1*2 + 1];
451 rows = ((mask << shift) + 0x80) & 0xFF;
452
453 total_bits = row1 + 8;
454 reservoir >>= total_bits;
455 nbits_in_reservoir -= total_bits;
456 }
457 {
458 const unsigned int *table_a004 = pdev->table_a004 + rows*12;
459 unsigned int *poffset = MulIdx + offset1*16; /* 64/4 (int) */
460 for (i=0;i<16;i++)
461 {
462 temp_colors[i] += table_a004[ *poffset ];
463 poffset++;
464 }
465 }
466 }
467 }
468#define USE_SIGNED_INT_FOR_COLOR
469#ifdef USE_SIGNED_INT_FOR_COLOR
470# define CLAMP(x) ((x)>255?255:((x)<0?0:x))
471#else
472# define CLAMP(x) ((x)>255?255:x)
473#endif
474
475 if (passes == 0)
476 {
477#ifdef USE_SIGNED_INT_FOR_COLOR
478 const int *c = temp_colors;
479#else
480 const unsigned int *c = temp_colors;
481#endif
482 unsigned char *d;
483
484 d = dest_y;
485 for (i=0;i<4;i++,c++)
486 *d++ = CLAMP((*c) >> pdev->yy);
487
488 d = dest_y + bytes_per_channel;
489 for (i=0;i<4;i++,c++)
490 *d++ = CLAMP((*c) >> pdev->yy);
491
492 d = dest_y + offset_to_plane_u;
493 for (i=0;i<4;i++,c++)
494 *d++ = CLAMP((*c) >> pdev->yy);
495
496 d = dest_y + offset_to_plane_v;
497 for (i=0;i<4;i++,c++)
498 *d++ = CLAMP((*c) >> pdev->yy);
499
500 dest_y += 4;
501 }
502 else if (passes == 1)
503 {
504#ifdef USE_SIGNED_INT_FOR_COLOR
505 int *c1 = temp_colors;
506 int *c2 = temp_colors+4;
507#else
508 unsigned int *c1 = temp_colors;
509 unsigned int *c2 = temp_colors+4;
510#endif
511 unsigned char *d;
512
513 d = dest_y;
514 for (i=0;i<4;i++,c1++,c2++)
515 {
516 *d++ = CLAMP((*c1) >> pdev->yy);
517 *d++ = CLAMP((*c2) >> pdev->yy);
518 }
519 c1 = temp_colors+12;
520 //c2 = temp_colors+8;
521 d = dest_y + bytes_per_channel;
522 for (i=0;i<4;i++,c1++,c2++)
523 {
524 *d++ = CLAMP((*c1) >> pdev->yy);
525 *d++ = CLAMP((*c2) >> pdev->yy);
526 }
527
528 if (even_line) /* Each line, swap u/v */
529 {
530 even_line=0;
531 dest_y = dest_v;
532 dest_u += 8;
533 }
534 else
535 {
536 even_line=1;
537 dest_y = dest_u;
538 dest_v += 8;
539 }
540 }
541
542 } /* end of while (nblocks-->0) */
543
544 } /* end of for (passes=0;passes<2;passes++) */
545
546}
547
548
549/**
550 *
551 * image: size of the image wanted
552 * view : size of the image returned by the camera
553 * offset: (x,y) to displayer image in the view
554 *
555 * src: raw data
556 * dst: image output
557 * flags: PWCX_FLAG_PLANAR
558 * pdev: private buffer
559 * bandlength:
560 *
561 */
562void pwc_dec23_decompress(const struct pwc_coord *image,
563 const struct pwc_coord *view,
564 const struct pwc_coord *offset,
565 const void *src,
566 void *dst,
567 int flags,
568 const void *data,
569 int bandlength)
570{
571 const struct pwc_dec23_private *pdev = data;
572 unsigned char *pout, *pout_planar_y=NULL, *pout_planar_u=NULL, *pout_planar_v=NULL;
573 int i,n,stride,pixel_size;
574
575
576 if (flags & PWCX_FLAG_BAYER)
577 {
578 pout = dst + (view->x * offset->y) + offset->x;
579 pixel_size = view->x * 4;
580 }
581 else
582 {
583 n = view->x * view->y;
584
585 /* offset in Y plane */
586 stride = view->x * offset->y;
587 pout_planar_y = dst + stride + offset->x;
588
589 /* offsets in U/V planes */
590 stride = (view->x * offset->y)/4 + offset->x/2;
591 pout_planar_u = dst + n + + stride;
592 pout_planar_v = dst + n + n/4 + stride;
593
594 pixel_size = view->x * 4;
595 }
596
597
598 for (i=0;i<image->y;i+=4)
599 {
600 if (flags & PWCX_FLAG_BAYER)
601 {
602 //TODO:
603 //DecompressBandBayer(pdev,src,pout,image.x,view->x,flags);
604 src += bandlength;
605 pout += pixel_size;
606 }
607 else
608 {
609 DecompressBand23(pdev,src,pout_planar_y,pout_planar_u,pout_planar_v,image->x,view->x,flags);
610 src += bandlength;
611 pout_planar_y += pixel_size;
612 pout_planar_u += view->x;
613 pout_planar_v += view->x;
614 }
615 }
616}
617
618void pwc_dec23_exit(void)
619{
620 /* Do nothing */
621
622}
623
diff --git a/drivers/usb/media/pwc/pwc-dec23.h b/drivers/usb/media/pwc/pwc-dec23.h
new file mode 100644
index 000000000000..5b2aacdefa6c
--- /dev/null
+++ b/drivers/usb/media/pwc/pwc-dec23.h
@@ -0,0 +1,58 @@
1/* Linux driver for Philips webcam
2 (C) 2004 Luc Saillard (luc@saillard.org)
3
4 NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx
5 driver and thus may have bugs that are not present in the original version.
6 Please send bug reports and support requests to <luc@saillard.org>.
7 The decompression routines have been implemented by reverse-engineering the
8 Nemosoft binary pwcx module. Caveat emptor.
9
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2 of the License, or
13 (at your option) any later version.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23*/
24
25#ifndef PWC_DEC23_H
26#define PWC_DEC23_H
27
28struct pwc_dec23_private
29{
30 unsigned char xx,yy,zz,zzmask;
31
32 unsigned char table_0004[2*0x4000];
33 unsigned char table_8004[2*0x1000];
34 unsigned int table_a004[256*12];
35
36 unsigned char table_d004[8*256];
37 unsigned int table_d800[256];
38 unsigned int table_dc00[256];
39};
40
41
42void pwc_dec23_init(int type, int release, unsigned char *buffer, void *private_data);
43void pwc_dec23_exit(void);
44void pwc_dec23_decompress(const struct pwc_coord *image,
45 const struct pwc_coord *view,
46 const struct pwc_coord *offset,
47 const void *src,
48 void *dst,
49 int flags,
50 const void *data,
51 int bandlength);
52
53
54
55#endif
56
57
58
diff --git a/drivers/usb/media/pwc/pwc-if.c b/drivers/usb/media/pwc/pwc-if.c
new file mode 100644
index 000000000000..100a5a4f03a3
--- /dev/null
+++ b/drivers/usb/media/pwc/pwc-if.c
@@ -0,0 +1,2212 @@
1/* Linux driver for Philips webcam
2 USB and Video4Linux interface part.
3 (C) 1999-2004 Nemosoft Unv.
4 (C) 2004 Luc Saillard (luc@saillard.org)
5
6 NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx
7 driver and thus may have bugs that are not present in the original version.
8 Please send bug reports and support requests to <luc@saillard.org>.
9 The decompression routines have been implemented by reverse-engineering the
10 Nemosoft binary pwcx module. Caveat emptor.
11
12 This program is free software; you can redistribute it and/or modify
13 it under the terms of the GNU General Public License as published by
14 the Free Software Foundation; either version 2 of the License, or
15 (at your option) any later version.
16
17 This program is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 GNU General Public License for more details.
21
22 You should have received a copy of the GNU General Public License
23 along with this program; if not, write to the Free Software
24 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25
26*/
27
28/*
29 This code forms the interface between the USB layers and the Philips
30 specific stuff. Some adanved stuff of the driver falls under an
31 NDA, signed between me and Philips B.V., Eindhoven, the Netherlands, and
32 is thus not distributed in source form. The binary pwcx.o module
33 contains the code that falls under the NDA.
34
35 In case you're wondering: 'pwc' stands for "Philips WebCam", but
36 I really didn't want to type 'philips_web_cam' every time (I'm lazy as
37 any Linux kernel hacker, but I don't like uncomprehensible abbreviations
38 without explanation).
39
40 Oh yes, convention: to disctinguish between all the various pointers to
41 device-structures, I use these names for the pointer variables:
42 udev: struct usb_device *
43 vdev: struct video_device *
44 pdev: struct pwc_devive *
45*/
46
47/* Contributors:
48 - Alvarado: adding whitebalance code
49 - Alistar Moire: QuickCam 3000 Pro device/product ID
50 - Tony Hoyle: Creative Labs Webcam 5 device/product ID
51 - Mark Burazin: solving hang in VIDIOCSYNC when camera gets unplugged
52 - Jk Fang: Sotec Afina Eye ID
53 - Xavier Roche: QuickCam Pro 4000 ID
54 - Jens Knudsen: QuickCam Zoom ID
55 - J. Debert: QuickCam for Notebooks ID
56*/
57
58#include <linux/errno.h>
59#include <linux/init.h>
60#include <linux/mm.h>
61#include <linux/module.h>
62#include <linux/poll.h>
63#include <linux/slab.h>
64#include <linux/vmalloc.h>
65#include <asm/io.h>
66
67#include "pwc.h"
68#include "pwc-ioctl.h"
69#include "pwc-kiara.h"
70#include "pwc-timon.h"
71#include "pwc-dec23.h"
72#include "pwc-dec1.h"
73#include "pwc-uncompress.h"
74
75/* Function prototypes and driver templates */
76
77/* hotplug device table support */
78static struct usb_device_id pwc_device_table [] = {
79 { USB_DEVICE(0x0471, 0x0302) }, /* Philips models */
80 { USB_DEVICE(0x0471, 0x0303) },
81 { USB_DEVICE(0x0471, 0x0304) },
82 { USB_DEVICE(0x0471, 0x0307) },
83 { USB_DEVICE(0x0471, 0x0308) },
84 { USB_DEVICE(0x0471, 0x030C) },
85 { USB_DEVICE(0x0471, 0x0310) },
86 { USB_DEVICE(0x0471, 0x0311) },
87 { USB_DEVICE(0x0471, 0x0312) },
88 { USB_DEVICE(0x0471, 0x0313) }, /* the 'new' 720K */
89 { USB_DEVICE(0x069A, 0x0001) }, /* Askey */
90 { USB_DEVICE(0x046D, 0x08B0) }, /* Logitech QuickCam Pro 3000 */
91 { USB_DEVICE(0x046D, 0x08B1) }, /* Logitech QuickCam Notebook Pro */
92 { USB_DEVICE(0x046D, 0x08B2) }, /* Logitech QuickCam Pro 4000 */
93 { USB_DEVICE(0x046D, 0x08B3) }, /* Logitech QuickCam Zoom (old model) */
94 { USB_DEVICE(0x046D, 0x08B4) }, /* Logitech QuickCam Zoom (new model) */
95 { USB_DEVICE(0x046D, 0x08B5) }, /* Logitech QuickCam Orbit/Sphere */
96 { USB_DEVICE(0x046D, 0x08B6) }, /* Logitech (reserved) */
97 { USB_DEVICE(0x046D, 0x08B7) }, /* Logitech (reserved) */
98 { USB_DEVICE(0x046D, 0x08B8) }, /* Logitech (reserved) */
99 { USB_DEVICE(0x055D, 0x9000) }, /* Samsung */
100 { USB_DEVICE(0x055D, 0x9001) },
101 { USB_DEVICE(0x041E, 0x400C) }, /* Creative Webcam 5 */
102 { USB_DEVICE(0x041E, 0x4011) }, /* Creative Webcam Pro Ex */
103 { USB_DEVICE(0x04CC, 0x8116) }, /* Afina Eye */
104 { USB_DEVICE(0x06BE, 0x8116) }, /* new Afina Eye */
105 { USB_DEVICE(0x0d81, 0x1910) }, /* Visionite */
106 { USB_DEVICE(0x0d81, 0x1900) },
107 { }
108};
109MODULE_DEVICE_TABLE(usb, pwc_device_table);
110
111static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id *id);
112static void usb_pwc_disconnect(struct usb_interface *intf);
113
114static struct usb_driver pwc_driver = {
115 .owner = THIS_MODULE,
116 .name = "Philips webcam", /* name */
117 .id_table = pwc_device_table,
118 .probe = usb_pwc_probe, /* probe() */
119 .disconnect = usb_pwc_disconnect, /* disconnect() */
120};
121
122#define MAX_DEV_HINTS 20
123#define MAX_ISOC_ERRORS 20
124
125static int default_size = PSZ_QCIF;
126static int default_fps = 10;
127static int default_fbufs = 3; /* Default number of frame buffers */
128static int default_mbufs = 2; /* Default number of mmap() buffers */
129 int pwc_trace = TRACE_MODULE | TRACE_FLOW | TRACE_PWCX;
130static int power_save = 0;
131static int led_on = 100, led_off = 0; /* defaults to LED that is on while in use */
132 int pwc_preferred_compression = 2; /* 0..3 = uncompressed..high */
133static struct {
134 int type;
135 char serial_number[30];
136 int device_node;
137 struct pwc_device *pdev;
138} device_hint[MAX_DEV_HINTS];
139
140/***/
141
142static int pwc_video_open(struct inode *inode, struct file *file);
143static int pwc_video_close(struct inode *inode, struct file *file);
144static ssize_t pwc_video_read(struct file *file, char __user * buf,
145 size_t count, loff_t *ppos);
146static unsigned int pwc_video_poll(struct file *file, poll_table *wait);
147static int pwc_video_ioctl(struct inode *inode, struct file *file,
148 unsigned int ioctlnr, unsigned long arg);
149static int pwc_video_mmap(struct file *file, struct vm_area_struct *vma);
150
151static struct file_operations pwc_fops = {
152 .owner = THIS_MODULE,
153 .open = pwc_video_open,
154 .release = pwc_video_close,
155 .read = pwc_video_read,
156 .poll = pwc_video_poll,
157 .mmap = pwc_video_mmap,
158 .ioctl = pwc_video_ioctl,
159 .llseek = no_llseek,
160};
161static struct video_device pwc_template = {
162 .owner = THIS_MODULE,
163 .name = "Philips Webcam", /* Filled in later */
164 .type = VID_TYPE_CAPTURE,
165 .hardware = VID_HARDWARE_PWC,
166 .release = video_device_release,
167 .fops = &pwc_fops,
168 .minor = -1,
169};
170
171/***************************************************************************/
172
173/* Okay, this is some magic that I worked out and the reasoning behind it...
174
175 The biggest problem with any USB device is of course: "what to do
176 when the user unplugs the device while it is in use by an application?"
177 We have several options:
178 1) Curse them with the 7 plagues when they do (requires divine intervention)
179 2) Tell them not to (won't work: they'll do it anyway)
180 3) Oops the kernel (this will have a negative effect on a user's uptime)
181 4) Do something sensible.
182
183 Of course, we go for option 4.
184
185 It happens that this device will be linked to two times, once from
186 usb_device and once from the video_device in their respective 'private'
187 pointers. This is done when the device is probed() and all initialization
188 succeeded. The pwc_device struct links back to both structures.
189
190 When a device is unplugged while in use it will be removed from the
191 list of known USB devices; I also de-register it as a V4L device, but
192 unfortunately I can't free the memory since the struct is still in use
193 by the file descriptor. This free-ing is then deferend until the first
194 opportunity. Crude, but it works.
195
196 A small 'advantage' is that if a user unplugs the cam and plugs it back
197 in, it should get assigned the same video device minor, but unfortunately
198 it's non-trivial to re-link the cam back to the video device... (that
199 would surely be magic! :))
200*/
201
202/***************************************************************************/
203/* Private functions */
204
205/* Here we want the physical address of the memory.
206 * This is used when initializing the contents of the area.
207 */
208static inline unsigned long kvirt_to_pa(unsigned long adr)
209{
210 unsigned long kva, ret;
211
212 kva = (unsigned long) page_address(vmalloc_to_page((void *)adr));
213 kva |= adr & (PAGE_SIZE-1); /* restore the offset */
214 ret = __pa(kva);
215 return ret;
216}
217
218static void * rvmalloc(unsigned long size)
219{
220 void * mem;
221 unsigned long adr;
222
223 size=PAGE_ALIGN(size);
224 mem=vmalloc_32(size);
225 if (mem)
226 {
227 memset(mem, 0, size); /* Clear the ram out, no junk to the user */
228 adr=(unsigned long) mem;
229 while (size > 0)
230 {
231 SetPageReserved(vmalloc_to_page((void *)adr));
232 adr+=PAGE_SIZE;
233 size-=PAGE_SIZE;
234 }
235 }
236 return mem;
237}
238
239static void rvfree(void * mem, unsigned long size)
240{
241 unsigned long adr;
242
243 if (mem)
244 {
245 adr=(unsigned long) mem;
246 while ((long) size > 0)
247 {
248 ClearPageReserved(vmalloc_to_page((void *)adr));
249 adr+=PAGE_SIZE;
250 size-=PAGE_SIZE;
251 }
252 vfree(mem);
253 }
254}
255
256
257
258
259static int pwc_allocate_buffers(struct pwc_device *pdev)
260{
261 int i;
262 void *kbuf;
263
264 Trace(TRACE_MEMORY, ">> pwc_allocate_buffers(pdev = 0x%p)\n", pdev);
265
266 if (pdev == NULL)
267 return -ENXIO;
268
269#ifdef PWC_MAGIC
270 if (pdev->magic != PWC_MAGIC) {
271 Err("allocate_buffers(): magic failed.\n");
272 return -ENXIO;
273 }
274#endif
275 /* Allocate Isochronuous pipe buffers */
276 for (i = 0; i < MAX_ISO_BUFS; i++) {
277 if (pdev->sbuf[i].data == NULL) {
278 kbuf = kmalloc(ISO_BUFFER_SIZE, GFP_KERNEL);
279 if (kbuf == NULL) {
280 Err("Failed to allocate iso buffer %d.\n", i);
281 return -ENOMEM;
282 }
283 Trace(TRACE_MEMORY, "Allocated iso buffer at %p.\n", kbuf);
284 pdev->sbuf[i].data = kbuf;
285 memset(kbuf, 0, ISO_BUFFER_SIZE);
286 }
287 }
288
289 /* Allocate frame buffer structure */
290 if (pdev->fbuf == NULL) {
291 kbuf = kmalloc(default_fbufs * sizeof(struct pwc_frame_buf), GFP_KERNEL);
292 if (kbuf == NULL) {
293 Err("Failed to allocate frame buffer structure.\n");
294 return -ENOMEM;
295 }
296 Trace(TRACE_MEMORY, "Allocated frame buffer structure at %p.\n", kbuf);
297 pdev->fbuf = kbuf;
298 memset(kbuf, 0, default_fbufs * sizeof(struct pwc_frame_buf));
299 }
300 /* create frame buffers, and make circular ring */
301 for (i = 0; i < default_fbufs; i++) {
302 if (pdev->fbuf[i].data == NULL) {
303 kbuf = vmalloc(PWC_FRAME_SIZE); /* need vmalloc since frame buffer > 128K */
304 if (kbuf == NULL) {
305 Err("Failed to allocate frame buffer %d.\n", i);
306 return -ENOMEM;
307 }
308 Trace(TRACE_MEMORY, "Allocated frame buffer %d at %p.\n", i, kbuf);
309 pdev->fbuf[i].data = kbuf;
310 memset(kbuf, 128, PWC_FRAME_SIZE);
311 }
312 }
313
314 /* Allocate decompressor table space */
315 kbuf = NULL;
316 switch (pdev->type)
317 {
318 case 675:
319 case 680:
320 case 690:
321 case 720:
322 case 730:
323 case 740:
324 case 750:
325 Trace(TRACE_MEMORY,"private_data(%Zd)\n",sizeof(struct pwc_dec23_private));
326 kbuf = kmalloc(sizeof(struct pwc_dec23_private), GFP_KERNEL); /* Timon & Kiara */
327 break;
328 case 645:
329 case 646:
330 /* TODO & FIXME */
331 kbuf = kmalloc(sizeof(struct pwc_dec23_private), GFP_KERNEL);
332 break;
333 }
334 if (kbuf == NULL) {
335 Err("Failed to allocate decompress table.\n");
336 return -ENOMEM;
337 }
338 pdev->decompress_data = kbuf;
339
340 /* Allocate image buffer; double buffer for mmap() */
341 kbuf = rvmalloc(default_mbufs * pdev->len_per_image);
342 if (kbuf == NULL) {
343 Err("Failed to allocate image buffer(s). needed (%d)\n",default_mbufs * pdev->len_per_image);
344 return -ENOMEM;
345 }
346 Trace(TRACE_MEMORY, "Allocated image buffer at %p.\n", kbuf);
347 pdev->image_data = kbuf;
348 for (i = 0; i < default_mbufs; i++)
349 pdev->image_ptr[i] = kbuf + i * pdev->len_per_image;
350 for (; i < MAX_IMAGES; i++)
351 pdev->image_ptr[i] = NULL;
352
353 kbuf = NULL;
354
355 Trace(TRACE_MEMORY, "<< pwc_allocate_buffers()\n");
356 return 0;
357}
358
359static void pwc_free_buffers(struct pwc_device *pdev)
360{
361 int i;
362
363 Trace(TRACE_MEMORY, "Entering free_buffers(%p).\n", pdev);
364
365 if (pdev == NULL)
366 return;
367#ifdef PWC_MAGIC
368 if (pdev->magic != PWC_MAGIC) {
369 Err("free_buffers(): magic failed.\n");
370 return;
371 }
372#endif
373
374 /* Release Iso-pipe buffers */
375 for (i = 0; i < MAX_ISO_BUFS; i++)
376 if (pdev->sbuf[i].data != NULL) {
377 Trace(TRACE_MEMORY, "Freeing ISO buffer at %p.\n", pdev->sbuf[i].data);
378 kfree(pdev->sbuf[i].data);
379 pdev->sbuf[i].data = NULL;
380 }
381
382 /* The same for frame buffers */
383 if (pdev->fbuf != NULL) {
384 for (i = 0; i < default_fbufs; i++) {
385 if (pdev->fbuf[i].data != NULL) {
386 Trace(TRACE_MEMORY, "Freeing frame buffer %d at %p.\n", i, pdev->fbuf[i].data);
387 vfree(pdev->fbuf[i].data);
388 pdev->fbuf[i].data = NULL;
389 }
390 }
391 kfree(pdev->fbuf);
392 pdev->fbuf = NULL;
393 }
394
395 /* Intermediate decompression buffer & tables */
396 if (pdev->decompress_data != NULL) {
397 Trace(TRACE_MEMORY, "Freeing decompression buffer at %p.\n", pdev->decompress_data);
398 kfree(pdev->decompress_data);
399 pdev->decompress_data = NULL;
400 }
401 pdev->decompressor = NULL;
402
403 /* Release image buffers */
404 if (pdev->image_data != NULL) {
405 Trace(TRACE_MEMORY, "Freeing image buffer at %p.\n", pdev->image_data);
406 rvfree(pdev->image_data, default_mbufs * pdev->len_per_image);
407 }
408 pdev->image_data = NULL;
409
410 Trace(TRACE_MEMORY, "Leaving free_buffers().\n");
411}
412
413/* The frame & image buffer mess.
414
415 Yes, this is a mess. Well, it used to be simple, but alas... In this
416 module, 3 buffers schemes are used to get the data from the USB bus to
417 the user program. The first scheme involves the ISO buffers (called thus
418 since they transport ISO data from the USB controller), and not really
419 interesting. Suffices to say the data from this buffer is quickly
420 gathered in an interrupt handler (pwc_isoc_handler) and placed into the
421 frame buffer.
422
423 The frame buffer is the second scheme, and is the central element here.
424 It collects the data from a single frame from the camera (hence, the
425 name). Frames are delimited by the USB camera with a short USB packet,
426 so that's easy to detect. The frame buffers form a list that is filled
427 by the camera+USB controller and drained by the user process through
428 either read() or mmap().
429
430 The image buffer is the third scheme, in which frames are decompressed
431 and converted into planar format. For mmap() there is more than
432 one image buffer available.
433
434 The frame buffers provide the image buffering. In case the user process
435 is a bit slow, this introduces lag and some undesired side-effects.
436 The problem arises when the frame buffer is full. I used to drop the last
437 frame, which makes the data in the queue stale very quickly. But dropping
438 the frame at the head of the queue proved to be a litte bit more difficult.
439 I tried a circular linked scheme, but this introduced more problems than
440 it solved.
441
442 Because filling and draining are completely asynchronous processes, this
443 requires some fiddling with pointers and mutexes.
444
445 Eventually, I came up with a system with 2 lists: an 'empty' frame list
446 and a 'full' frame list:
447 * Initially, all frame buffers but one are on the 'empty' list; the one
448 remaining buffer is our initial fill frame.
449 * If a frame is needed for filling, we try to take it from the 'empty'
450 list, unless that list is empty, in which case we take the buffer at
451 the head of the 'full' list.
452 * When our fill buffer has been filled, it is appended to the 'full'
453 list.
454 * If a frame is needed by read() or mmap(), it is taken from the head of
455 the 'full' list, handled, and then appended to the 'empty' list. If no
456 buffer is present on the 'full' list, we wait.
457 The advantage is that the buffer that is currently being decompressed/
458 converted, is on neither list, and thus not in our way (any other scheme
459 I tried had the problem of old data lingering in the queue).
460
461 Whatever strategy you choose, it always remains a tradeoff: with more
462 frame buffers the chances of a missed frame are reduced. On the other
463 hand, on slower machines it introduces lag because the queue will
464 always be full.
465 */
466
467/**
468 \brief Find next frame buffer to fill. Take from empty or full list, whichever comes first.
469 */
470static inline int pwc_next_fill_frame(struct pwc_device *pdev)
471{
472 int ret;
473 unsigned long flags;
474
475 ret = 0;
476 spin_lock_irqsave(&pdev->ptrlock, flags);
477 if (pdev->fill_frame != NULL) {
478 /* append to 'full' list */
479 if (pdev->full_frames == NULL) {
480 pdev->full_frames = pdev->fill_frame;
481 pdev->full_frames_tail = pdev->full_frames;
482 }
483 else {
484 pdev->full_frames_tail->next = pdev->fill_frame;
485 pdev->full_frames_tail = pdev->fill_frame;
486 }
487 }
488 if (pdev->empty_frames != NULL) {
489 /* We have empty frames available. That's easy */
490 pdev->fill_frame = pdev->empty_frames;
491 pdev->empty_frames = pdev->empty_frames->next;
492 }
493 else {
494 /* Hmm. Take it from the full list */
495#if PWC_DEBUG
496 /* sanity check */
497 if (pdev->full_frames == NULL) {
498 Err("Neither empty or full frames available!\n");
499 spin_unlock_irqrestore(&pdev->ptrlock, flags);
500 return -EINVAL;
501 }
502#endif
503 pdev->fill_frame = pdev->full_frames;
504 pdev->full_frames = pdev->full_frames->next;
505 ret = 1;
506 }
507 pdev->fill_frame->next = NULL;
508#if PWC_DEBUG
509 Trace(TRACE_SEQUENCE, "Assigning sequence number %d.\n", pdev->sequence);
510 pdev->fill_frame->sequence = pdev->sequence++;
511#endif
512 spin_unlock_irqrestore(&pdev->ptrlock, flags);
513 return ret;
514}
515
516
517/**
518 \brief Reset all buffers, pointers and lists, except for the image_used[] buffer.
519
520 If the image_used[] buffer is cleared too, mmap()/VIDIOCSYNC will run into trouble.
521 */
522static void pwc_reset_buffers(struct pwc_device *pdev)
523{
524 int i;
525 unsigned long flags;
526
527 spin_lock_irqsave(&pdev->ptrlock, flags);
528 pdev->full_frames = NULL;
529 pdev->full_frames_tail = NULL;
530 for (i = 0; i < default_fbufs; i++) {
531 pdev->fbuf[i].filled = 0;
532 if (i > 0)
533 pdev->fbuf[i].next = &pdev->fbuf[i - 1];
534 else
535 pdev->fbuf->next = NULL;
536 }
537 pdev->empty_frames = &pdev->fbuf[default_fbufs - 1];
538 pdev->empty_frames_tail = pdev->fbuf;
539 pdev->read_frame = NULL;
540 pdev->fill_frame = pdev->empty_frames;
541 pdev->empty_frames = pdev->empty_frames->next;
542
543 pdev->image_read_pos = 0;
544 pdev->fill_image = 0;
545 spin_unlock_irqrestore(&pdev->ptrlock, flags);
546}
547
548
549/**
550 \brief Do all the handling for getting one frame: get pointer, decompress, advance pointers.
551 */
552static int pwc_handle_frame(struct pwc_device *pdev)
553{
554 int ret = 0;
555 unsigned long flags;
556
557 spin_lock_irqsave(&pdev->ptrlock, flags);
558 /* First grab our read_frame; this is removed from all lists, so
559 we can release the lock after this without problems */
560 if (pdev->read_frame != NULL) {
561 /* This can't theoretically happen */
562 Err("Huh? Read frame still in use?\n");
563 }
564 else {
565 if (pdev->full_frames == NULL) {
566 Err("Woops. No frames ready.\n");
567 }
568 else {
569 pdev->read_frame = pdev->full_frames;
570 pdev->full_frames = pdev->full_frames->next;
571 pdev->read_frame->next = NULL;
572 }
573
574 if (pdev->read_frame != NULL) {
575#if PWC_DEBUG
576 Trace(TRACE_SEQUENCE, "Decompressing frame %d\n", pdev->read_frame->sequence);
577#endif
578 /* Decompression is a lenghty process, so it's outside of the lock.
579 This gives the isoc_handler the opportunity to fill more frames
580 in the mean time.
581 */
582 spin_unlock_irqrestore(&pdev->ptrlock, flags);
583 ret = pwc_decompress(pdev);
584 spin_lock_irqsave(&pdev->ptrlock, flags);
585
586 /* We're done with read_buffer, tack it to the end of the empty buffer list */
587 if (pdev->empty_frames == NULL) {
588 pdev->empty_frames = pdev->read_frame;
589 pdev->empty_frames_tail = pdev->empty_frames;
590 }
591 else {
592 pdev->empty_frames_tail->next = pdev->read_frame;
593 pdev->empty_frames_tail = pdev->read_frame;
594 }
595 pdev->read_frame = NULL;
596 }
597 }
598 spin_unlock_irqrestore(&pdev->ptrlock, flags);
599 return ret;
600}
601
602/**
603 \brief Advance pointers of image buffer (after each user request)
604*/
605static inline void pwc_next_image(struct pwc_device *pdev)
606{
607 pdev->image_used[pdev->fill_image] = 0;
608 pdev->fill_image = (pdev->fill_image + 1) % default_mbufs;
609}
610
611
612/* This gets called for the Isochronous pipe (video). This is done in
613 * interrupt time, so it has to be fast, not crash, and not stall. Neat.
614 */
615static void pwc_isoc_handler(struct urb *urb, struct pt_regs *regs)
616{
617 struct pwc_device *pdev;
618 int i, fst, flen;
619 int awake;
620 struct pwc_frame_buf *fbuf;
621 unsigned char *fillptr = NULL, *iso_buf = NULL;
622
623 awake = 0;
624 pdev = (struct pwc_device *)urb->context;
625 if (pdev == NULL) {
626 Err("isoc_handler() called with NULL device?!\n");
627 return;
628 }
629#ifdef PWC_MAGIC
630 if (pdev->magic != PWC_MAGIC) {
631 Err("isoc_handler() called with bad magic!\n");
632 return;
633 }
634#endif
635 if (urb->status == -ENOENT || urb->status == -ECONNRESET) {
636 Trace(TRACE_OPEN, "pwc_isoc_handler(): URB (%p) unlinked %ssynchronuously.\n", urb, urb->status == -ENOENT ? "" : "a");
637 return;
638 }
639 if (urb->status != -EINPROGRESS && urb->status != 0) {
640 const char *errmsg;
641
642 errmsg = "Unknown";
643 switch(urb->status) {
644 case -ENOSR: errmsg = "Buffer error (overrun)"; break;
645 case -EPIPE: errmsg = "Stalled (device not responding)"; break;
646 case -EOVERFLOW: errmsg = "Babble (bad cable?)"; break;
647 case -EPROTO: errmsg = "Bit-stuff error (bad cable?)"; break;
648 case -EILSEQ: errmsg = "CRC/Timeout (could be anything)"; break;
649 case -ETIMEDOUT: errmsg = "NAK (device does not respond)"; break;
650 }
651 Trace(TRACE_FLOW, "pwc_isoc_handler() called with status %d [%s].\n", urb->status, errmsg);
652 /* Give up after a number of contiguous errors on the USB bus.
653 Appearantly something is wrong so we simulate an unplug event.
654 */
655 if (++pdev->visoc_errors > MAX_ISOC_ERRORS)
656 {
657 Info("Too many ISOC errors, bailing out.\n");
658 pdev->error_status = EIO;
659 awake = 1;
660 wake_up_interruptible(&pdev->frameq);
661 }
662 goto handler_end; // ugly, but practical
663 }
664
665 fbuf = pdev->fill_frame;
666 if (fbuf == NULL) {
667 Err("pwc_isoc_handler without valid fill frame.\n");
668 awake = 1;
669 goto handler_end;
670 }
671 else {
672 fillptr = fbuf->data + fbuf->filled;
673 }
674
675 /* Reset ISOC error counter. We did get here, after all. */
676 pdev->visoc_errors = 0;
677
678 /* vsync: 0 = don't copy data
679 1 = sync-hunt
680 2 = synched
681 */
682 /* Compact data */
683 for (i = 0; i < urb->number_of_packets; i++) {
684 fst = urb->iso_frame_desc[i].status;
685 flen = urb->iso_frame_desc[i].actual_length;
686 iso_buf = urb->transfer_buffer + urb->iso_frame_desc[i].offset;
687 if (fst == 0) {
688 if (flen > 0) { /* if valid data... */
689 if (pdev->vsync > 0) { /* ...and we are not sync-hunting... */
690 pdev->vsync = 2;
691
692 /* ...copy data to frame buffer, if possible */
693 if (flen + fbuf->filled > pdev->frame_total_size) {
694 Trace(TRACE_FLOW, "Frame buffer overflow (flen = %d, frame_total_size = %d).\n", flen, pdev->frame_total_size);
695 pdev->vsync = 0; /* Hmm, let's wait for an EOF (end-of-frame) */
696 pdev->vframes_error++;
697 }
698 else {
699 memmove(fillptr, iso_buf, flen);
700 fillptr += flen;
701 }
702 }
703 fbuf->filled += flen;
704 } /* ..flen > 0 */
705
706 if (flen < pdev->vlast_packet_size) {
707 /* Shorter packet... We probably have the end of an image-frame;
708 wake up read() process and let select()/poll() do something.
709 Decompression is done in user time over there.
710 */
711 if (pdev->vsync == 2) {
712 /* The ToUCam Fun CMOS sensor causes the firmware to send 2 or 3 bogus
713 frames on the USB wire after an exposure change. This conditition is
714 however detected in the cam and a bit is set in the header.
715 */
716 if (pdev->type == 730) {
717 unsigned char *ptr = (unsigned char *)fbuf->data;
718
719 if (ptr[1] == 1 && ptr[0] & 0x10) {
720#if PWC_DEBUG
721 Debug("Hyundai CMOS sensor bug. Dropping frame %d.\n", fbuf->sequence);
722#endif
723 pdev->drop_frames += 2;
724 pdev->vframes_error++;
725 }
726 if ((ptr[0] ^ pdev->vmirror) & 0x01) {
727 if (ptr[0] & 0x01)
728 Info("Snapshot button pressed.\n");
729 else
730 Info("Snapshot button released.\n");
731 }
732 if ((ptr[0] ^ pdev->vmirror) & 0x02) {
733 if (ptr[0] & 0x02)
734 Info("Image is mirrored.\n");
735 else
736 Info("Image is normal.\n");
737 }
738 pdev->vmirror = ptr[0] & 0x03;
739 /* Sometimes the trailer of the 730 is still sent as a 4 byte packet
740 after a short frame; this condition is filtered out specifically. A 4 byte
741 frame doesn't make sense anyway.
742 So we get either this sequence:
743 drop_bit set -> 4 byte frame -> short frame -> good frame
744 Or this one:
745 drop_bit set -> short frame -> good frame
746 So we drop either 3 or 2 frames in all!
747 */
748 if (fbuf->filled == 4)
749 pdev->drop_frames++;
750 }
751
752 /* In case we were instructed to drop the frame, do so silently.
753 The buffer pointers are not updated either (but the counters are reset below).
754 */
755 if (pdev->drop_frames > 0)
756 pdev->drop_frames--;
757 else {
758 /* Check for underflow first */
759 if (fbuf->filled < pdev->frame_total_size) {
760 Trace(TRACE_FLOW, "Frame buffer underflow (%d bytes); discarded.\n", fbuf->filled);
761 pdev->vframes_error++;
762 }
763 else {
764 /* Send only once per EOF */
765 awake = 1; /* delay wake_ups */
766
767 /* Find our next frame to fill. This will always succeed, since we
768 * nick a frame from either empty or full list, but if we had to
769 * take it from the full list, it means a frame got dropped.
770 */
771 if (pwc_next_fill_frame(pdev)) {
772 pdev->vframes_dumped++;
773 if ((pdev->vframe_count > FRAME_LOWMARK) && (pwc_trace & TRACE_FLOW)) {
774 if (pdev->vframes_dumped < 20)
775 Trace(TRACE_FLOW, "Dumping frame %d.\n", pdev->vframe_count);
776 if (pdev->vframes_dumped == 20)
777 Trace(TRACE_FLOW, "Dumping frame %d (last message).\n", pdev->vframe_count);
778 }
779 }
780 fbuf = pdev->fill_frame;
781 }
782 } /* !drop_frames */
783 pdev->vframe_count++;
784 }
785 fbuf->filled = 0;
786 fillptr = fbuf->data;
787 pdev->vsync = 1;
788 } /* .. flen < last_packet_size */
789 pdev->vlast_packet_size = flen;
790 } /* ..status == 0 */
791#if PWC_DEBUG
792 /* This is normally not interesting to the user, unless you are really debugging something */
793 else {
794 static int iso_error = 0;
795 iso_error++;
796 if (iso_error < 20)
797 Trace(TRACE_FLOW, "Iso frame %d of USB has error %d\n", i, fst);
798 }
799#endif
800 }
801
802handler_end:
803 if (awake)
804 wake_up_interruptible(&pdev->frameq);
805
806 urb->dev = pdev->udev;
807 i = usb_submit_urb(urb, GFP_ATOMIC);
808 if (i != 0)
809 Err("Error (%d) re-submitting urb in pwc_isoc_handler.\n", i);
810}
811
812
813static int pwc_isoc_init(struct pwc_device *pdev)
814{
815 struct usb_device *udev;
816 struct urb *urb;
817 int i, j, ret;
818
819 struct usb_interface *intf;
820 struct usb_host_interface *idesc = NULL;
821
822 if (pdev == NULL)
823 return -EFAULT;
824 if (pdev->iso_init)
825 return 0;
826 pdev->vsync = 0;
827 udev = pdev->udev;
828
829 /* Get the current alternate interface, adjust packet size */
830 if (!udev->actconfig)
831 return -EFAULT;
832#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,5)
833 idesc = &udev->actconfig->interface[0]->altsetting[pdev->valternate];
834#else
835 intf = usb_ifnum_to_if(udev, 0);
836 if (intf)
837 idesc = usb_altnum_to_altsetting(intf, pdev->valternate);
838#endif
839
840 if (!idesc)
841 return -EFAULT;
842
843 /* Search video endpoint */
844 pdev->vmax_packet_size = -1;
845 for (i = 0; i < idesc->desc.bNumEndpoints; i++)
846 if ((idesc->endpoint[i].desc.bEndpointAddress & 0xF) == pdev->vendpoint) {
847 pdev->vmax_packet_size = le16_to_cpu(idesc->endpoint[i].desc.wMaxPacketSize);
848 break;
849 }
850
851 if (pdev->vmax_packet_size < 0 || pdev->vmax_packet_size > ISO_MAX_FRAME_SIZE) {
852 Err("Failed to find packet size for video endpoint in current alternate setting.\n");
853 return -ENFILE; /* Odd error, that should be noticable */
854 }
855
856 /* Set alternate interface */
857 ret = 0;
858 Trace(TRACE_OPEN, "Setting alternate interface %d\n", pdev->valternate);
859 ret = usb_set_interface(pdev->udev, 0, pdev->valternate);
860 if (ret < 0)
861 return ret;
862
863 for (i = 0; i < MAX_ISO_BUFS; i++) {
864 urb = usb_alloc_urb(ISO_FRAMES_PER_DESC, GFP_KERNEL);
865 if (urb == NULL) {
866 Err("Failed to allocate urb %d\n", i);
867 ret = -ENOMEM;
868 break;
869 }
870 pdev->sbuf[i].urb = urb;
871 Trace(TRACE_MEMORY, "Allocated URB at 0x%p\n", urb);
872 }
873 if (ret) {
874 /* De-allocate in reverse order */
875 while (i >= 0) {
876 if (pdev->sbuf[i].urb != NULL)
877 usb_free_urb(pdev->sbuf[i].urb);
878 pdev->sbuf[i].urb = NULL;
879 i--;
880 }
881 return ret;
882 }
883
884 /* init URB structure */
885 for (i = 0; i < MAX_ISO_BUFS; i++) {
886 urb = pdev->sbuf[i].urb;
887
888 urb->interval = 1; // devik
889 urb->dev = udev;
890 urb->pipe = usb_rcvisocpipe(udev, pdev->vendpoint);
891 urb->transfer_flags = URB_ISO_ASAP;
892 urb->transfer_buffer = pdev->sbuf[i].data;
893 urb->transfer_buffer_length = ISO_BUFFER_SIZE;
894 urb->complete = pwc_isoc_handler;
895 urb->context = pdev;
896 urb->start_frame = 0;
897 urb->number_of_packets = ISO_FRAMES_PER_DESC;
898 for (j = 0; j < ISO_FRAMES_PER_DESC; j++) {
899 urb->iso_frame_desc[j].offset = j * ISO_MAX_FRAME_SIZE;
900 urb->iso_frame_desc[j].length = pdev->vmax_packet_size;
901 }
902 }
903
904 /* link */
905 for (i = 0; i < MAX_ISO_BUFS; i++) {
906 ret = usb_submit_urb(pdev->sbuf[i].urb, GFP_KERNEL);
907 if (ret)
908 Err("isoc_init() submit_urb %d failed with error %d\n", i, ret);
909 else
910 Trace(TRACE_MEMORY, "URB 0x%p submitted.\n", pdev->sbuf[i].urb);
911 }
912
913 /* All is done... */
914 pdev->iso_init = 1;
915 Trace(TRACE_OPEN, "<< pwc_isoc_init()\n");
916 return 0;
917}
918
919static void pwc_isoc_cleanup(struct pwc_device *pdev)
920{
921 int i;
922
923 Trace(TRACE_OPEN, ">> pwc_isoc_cleanup()\n");
924 if (pdev == NULL)
925 return;
926
927 /* Unlinking ISOC buffers one by one */
928 for (i = 0; i < MAX_ISO_BUFS; i++) {
929 struct urb *urb;
930
931 urb = pdev->sbuf[i].urb;
932 if (urb != 0) {
933 if (pdev->iso_init) {
934 Trace(TRACE_MEMORY, "Unlinking URB %p\n", urb);
935 usb_kill_urb(urb);
936 }
937 Trace(TRACE_MEMORY, "Freeing URB\n");
938 usb_free_urb(urb);
939 pdev->sbuf[i].urb = NULL;
940 }
941 }
942
943 /* Stop camera, but only if we are sure the camera is still there (unplug
944 is signalled by EPIPE)
945 */
946 if (pdev->error_status && pdev->error_status != EPIPE) {
947 Trace(TRACE_OPEN, "Setting alternate interface 0.\n");
948 usb_set_interface(pdev->udev, 0, 0);
949 }
950
951 pdev->iso_init = 0;
952 Trace(TRACE_OPEN, "<< pwc_isoc_cleanup()\n");
953}
954
955int pwc_try_video_mode(struct pwc_device *pdev, int width, int height, int new_fps, int new_compression, int new_snapshot)
956{
957 int ret, start;
958
959 /* Stop isoc stuff */
960 pwc_isoc_cleanup(pdev);
961 /* Reset parameters */
962 pwc_reset_buffers(pdev);
963 /* Try to set video mode... */
964 start = ret = pwc_set_video_mode(pdev, width, height, new_fps, new_compression, new_snapshot);
965 if (ret) {
966 Trace(TRACE_FLOW, "pwc_set_video_mode attempt 1 failed.\n");
967 /* That failed... restore old mode (we know that worked) */
968 start = pwc_set_video_mode(pdev, pdev->view.x, pdev->view.y, pdev->vframes, pdev->vcompression, pdev->vsnapshot);
969 if (start) {
970 Trace(TRACE_FLOW, "pwc_set_video_mode attempt 2 failed.\n");
971 }
972 }
973 if (start == 0)
974 {
975 if (pwc_isoc_init(pdev) < 0)
976 {
977 Info("Failed to restart ISOC transfers in pwc_try_video_mode.\n");
978 ret = -EAGAIN; /* let's try again, who knows if it works a second time */
979 }
980 }
981 pdev->drop_frames++; /* try to avoid garbage during switch */
982 return ret; /* Return original error code */
983}
984
985
986/***************************************************************************/
987/* Video4Linux functions */
988
989static int pwc_video_open(struct inode *inode, struct file *file)
990{
991 int i;
992 struct video_device *vdev = video_devdata(file);
993 struct pwc_device *pdev;
994
995 Trace(TRACE_OPEN, ">> video_open called(vdev = 0x%p).\n", vdev);
996
997 pdev = (struct pwc_device *)vdev->priv;
998 if (pdev == NULL)
999 BUG();
1000 if (pdev->vopen)
1001 return -EBUSY;
1002
1003 down(&pdev->modlock);
1004 if (!pdev->usb_init) {
1005 Trace(TRACE_OPEN, "Doing first time initialization.\n");
1006 pdev->usb_init = 1;
1007
1008 if (pwc_trace & TRACE_OPEN)
1009 {
1010 /* Query sensor type */
1011 const char *sensor_type = NULL;
1012 int ret;
1013
1014 ret = pwc_get_cmos_sensor(pdev, &i);
1015 if (ret >= 0)
1016 {
1017 switch(i) {
1018 case 0x00: sensor_type = "Hyundai CMOS sensor"; break;
1019 case 0x20: sensor_type = "Sony CCD sensor + TDA8787"; break;
1020 case 0x2E: sensor_type = "Sony CCD sensor + Exas 98L59"; break;
1021 case 0x2F: sensor_type = "Sony CCD sensor + ADI 9804"; break;
1022 case 0x30: sensor_type = "Sharp CCD sensor + TDA8787"; break;
1023 case 0x3E: sensor_type = "Sharp CCD sensor + Exas 98L59"; break;
1024 case 0x3F: sensor_type = "Sharp CCD sensor + ADI 9804"; break;
1025 case 0x40: sensor_type = "UPA 1021 sensor"; break;
1026 case 0x100: sensor_type = "VGA sensor"; break;
1027 case 0x101: sensor_type = "PAL MR sensor"; break;
1028 default: sensor_type = "unknown type of sensor"; break;
1029 }
1030 }
1031 if (sensor_type != NULL)
1032 Info("This %s camera is equipped with a %s (%d).\n", pdev->vdev->name, sensor_type, i);
1033 }
1034 }
1035
1036 /* Turn on camera */
1037 if (power_save) {
1038 i = pwc_camera_power(pdev, 1);
1039 if (i < 0)
1040 Info("Failed to restore power to the camera! (%d)\n", i);
1041 }
1042 /* Set LED on/off time */
1043 if (pwc_set_leds(pdev, led_on, led_off) < 0)
1044 Info("Failed to set LED on/off time.\n");
1045
1046 pwc_construct(pdev); /* set min/max sizes correct */
1047
1048 /* So far, so good. Allocate memory. */
1049 i = pwc_allocate_buffers(pdev);
1050 if (i < 0) {
1051 Trace(TRACE_OPEN, "Failed to allocate buffer memory.\n");
1052 up(&pdev->modlock);
1053 return i;
1054 }
1055
1056 /* Reset buffers & parameters */
1057 pwc_reset_buffers(pdev);
1058 for (i = 0; i < default_mbufs; i++)
1059 pdev->image_used[i] = 0;
1060 pdev->vframe_count = 0;
1061 pdev->vframes_dumped = 0;
1062 pdev->vframes_error = 0;
1063 pdev->visoc_errors = 0;
1064 pdev->error_status = 0;
1065#if PWC_DEBUG
1066 pdev->sequence = 0;
1067#endif
1068 pwc_construct(pdev); /* set min/max sizes correct */
1069
1070 /* Set some defaults */
1071 pdev->vsnapshot = 0;
1072
1073 /* Start iso pipe for video; first try the last used video size
1074 (or the default one); if that fails try QCIF/10 or QSIF/10;
1075 it that fails too, give up.
1076 */
1077 i = pwc_set_video_mode(pdev, pwc_image_sizes[pdev->vsize].x, pwc_image_sizes[pdev->vsize].y, pdev->vframes, pdev->vcompression, 0);
1078 if (i) {
1079 Trace(TRACE_OPEN, "First attempt at set_video_mode failed.\n");
1080 if (pdev->type == 730 || pdev->type == 740 || pdev->type == 750)
1081 i = pwc_set_video_mode(pdev, pwc_image_sizes[PSZ_QSIF].x, pwc_image_sizes[PSZ_QSIF].y, 10, pdev->vcompression, 0);
1082 else
1083 i = pwc_set_video_mode(pdev, pwc_image_sizes[PSZ_QCIF].x, pwc_image_sizes[PSZ_QCIF].y, 10, pdev->vcompression, 0);
1084 }
1085 if (i) {
1086 Trace(TRACE_OPEN, "Second attempt at set_video_mode failed.\n");
1087 up(&pdev->modlock);
1088 return i;
1089 }
1090
1091 i = pwc_isoc_init(pdev);
1092 if (i) {
1093 Trace(TRACE_OPEN, "Failed to init ISOC stuff = %d.\n", i);
1094 up(&pdev->modlock);
1095 return i;
1096 }
1097
1098 pdev->vopen++;
1099 file->private_data = vdev;
1100 up(&pdev->modlock);
1101 Trace(TRACE_OPEN, "<< video_open() returns 0.\n");
1102 return 0;
1103}
1104
1105/* Note that all cleanup is done in the reverse order as in _open */
1106static int pwc_video_close(struct inode *inode, struct file *file)
1107{
1108 struct video_device *vdev = file->private_data;
1109 struct pwc_device *pdev;
1110 int i;
1111
1112 Trace(TRACE_OPEN, ">> video_close called(vdev = 0x%p).\n", vdev);
1113
1114 pdev = (struct pwc_device *)vdev->priv;
1115 if (pdev->vopen == 0)
1116 Info("video_close() called on closed device?\n");
1117
1118 /* Dump statistics, but only if a reasonable amount of frames were
1119 processed (to prevent endless log-entries in case of snap-shot
1120 programs)
1121 */
1122 if (pdev->vframe_count > 20)
1123 Info("Closing video device: %d frames received, dumped %d frames, %d frames with errors.\n", pdev->vframe_count, pdev->vframes_dumped, pdev->vframes_error);
1124
1125 switch (pdev->type)
1126 {
1127 case 675:
1128 case 680:
1129 case 690:
1130 case 720:
1131 case 730:
1132 case 740:
1133 case 750:
1134 pwc_dec23_exit(); /* Timon & Kiara */
1135 break;
1136 case 645:
1137 case 646:
1138 pwc_dec1_exit();
1139 break;
1140 }
1141
1142 pwc_isoc_cleanup(pdev);
1143 pwc_free_buffers(pdev);
1144
1145 /* Turn off LEDS and power down camera, but only when not unplugged */
1146 if (pdev->error_status != EPIPE) {
1147 /* Turn LEDs off */
1148 if (pwc_set_leds(pdev, 0, 0) < 0)
1149 Info("Failed to set LED on/off time.\n");
1150 if (power_save) {
1151 i = pwc_camera_power(pdev, 0);
1152 if (i < 0)
1153 Err("Failed to power down camera (%d)\n", i);
1154 }
1155 }
1156 pdev->vopen = 0;
1157 Trace(TRACE_OPEN, "<< video_close()\n");
1158 return 0;
1159}
1160
1161/*
1162 * FIXME: what about two parallel reads ????
1163 * ANSWER: Not supported. You can't open the device more than once,
1164 despite what the V4L1 interface says. First, I don't see
1165 the need, second there's no mechanism of alerting the
1166 2nd/3rd/... process of events like changing image size.
1167 And I don't see the point of blocking that for the
1168 2nd/3rd/... process.
1169 In multi-threaded environments reading parallel from any
1170 device is tricky anyhow.
1171 */
1172
1173static ssize_t pwc_video_read(struct file *file, char __user * buf,
1174 size_t count, loff_t *ppos)
1175{
1176 struct video_device *vdev = file->private_data;
1177 struct pwc_device *pdev;
1178 int noblock = file->f_flags & O_NONBLOCK;
1179 DECLARE_WAITQUEUE(wait, current);
1180 int bytes_to_read;
1181
1182 Trace(TRACE_READ, "video_read(0x%p, %p, %Zd) called.\n", vdev, buf, count);
1183 if (vdev == NULL)
1184 return -EFAULT;
1185 pdev = vdev->priv;
1186 if (pdev == NULL)
1187 return -EFAULT;
1188 if (pdev->error_status)
1189 return -pdev->error_status; /* Something happened, report what. */
1190
1191 /* In case we're doing partial reads, we don't have to wait for a frame */
1192 if (pdev->image_read_pos == 0) {
1193 /* Do wait queueing according to the (doc)book */
1194 add_wait_queue(&pdev->frameq, &wait);
1195 while (pdev->full_frames == NULL) {
1196 /* Check for unplugged/etc. here */
1197 if (pdev->error_status) {
1198 remove_wait_queue(&pdev->frameq, &wait);
1199 set_current_state(TASK_RUNNING);
1200 return -pdev->error_status ;
1201 }
1202 if (noblock) {
1203 remove_wait_queue(&pdev->frameq, &wait);
1204 set_current_state(TASK_RUNNING);
1205 return -EWOULDBLOCK;
1206 }
1207 if (signal_pending(current)) {
1208 remove_wait_queue(&pdev->frameq, &wait);
1209 set_current_state(TASK_RUNNING);
1210 return -ERESTARTSYS;
1211 }
1212 schedule();
1213 set_current_state(TASK_INTERRUPTIBLE);
1214 }
1215 remove_wait_queue(&pdev->frameq, &wait);
1216 set_current_state(TASK_RUNNING);
1217
1218 /* Decompress and release frame */
1219 if (pwc_handle_frame(pdev))
1220 return -EFAULT;
1221 }
1222
1223 Trace(TRACE_READ, "Copying data to user space.\n");
1224 if (pdev->vpalette == VIDEO_PALETTE_RAW)
1225 bytes_to_read = pdev->frame_size;
1226 else
1227 bytes_to_read = pdev->view.size;
1228
1229 /* copy bytes to user space; we allow for partial reads */
1230 if (count + pdev->image_read_pos > bytes_to_read)
1231 count = bytes_to_read - pdev->image_read_pos;
1232 if (copy_to_user(buf, pdev->image_ptr[pdev->fill_image] + pdev->image_read_pos, count))
1233 return -EFAULT;
1234 pdev->image_read_pos += count;
1235 if (pdev->image_read_pos >= bytes_to_read) { /* All data has been read */
1236 pdev->image_read_pos = 0;
1237 pwc_next_image(pdev);
1238 }
1239 return count;
1240}
1241
1242static unsigned int pwc_video_poll(struct file *file, poll_table *wait)
1243{
1244 struct video_device *vdev = file->private_data;
1245 struct pwc_device *pdev;
1246
1247 if (vdev == NULL)
1248 return -EFAULT;
1249 pdev = vdev->priv;
1250 if (pdev == NULL)
1251 return -EFAULT;
1252
1253 poll_wait(file, &pdev->frameq, wait);
1254 if (pdev->error_status)
1255 return POLLERR;
1256 if (pdev->full_frames != NULL) /* we have frames waiting */
1257 return (POLLIN | POLLRDNORM);
1258
1259 return 0;
1260}
1261
1262static int pwc_video_do_ioctl(struct inode *inode, struct file *file,
1263 unsigned int cmd, void *arg)
1264{
1265 struct video_device *vdev = file->private_data;
1266 struct pwc_device *pdev;
1267 DECLARE_WAITQUEUE(wait, current);
1268
1269 if (vdev == NULL)
1270 return -EFAULT;
1271 pdev = vdev->priv;
1272 if (pdev == NULL)
1273 return -EFAULT;
1274
1275 switch (cmd) {
1276 /* Query cabapilities */
1277 case VIDIOCGCAP:
1278 {
1279 struct video_capability *caps = arg;
1280
1281 strcpy(caps->name, vdev->name);
1282 caps->type = VID_TYPE_CAPTURE;
1283 caps->channels = 1;
1284 caps->audios = 1;
1285 caps->minwidth = pdev->view_min.x;
1286 caps->minheight = pdev->view_min.y;
1287 caps->maxwidth = pdev->view_max.x;
1288 caps->maxheight = pdev->view_max.y;
1289 break;
1290 }
1291
1292 /* Channel functions (simulate 1 channel) */
1293 case VIDIOCGCHAN:
1294 {
1295 struct video_channel *v = arg;
1296
1297 if (v->channel != 0)
1298 return -EINVAL;
1299 v->flags = 0;
1300 v->tuners = 0;
1301 v->type = VIDEO_TYPE_CAMERA;
1302 strcpy(v->name, "Webcam");
1303 return 0;
1304 }
1305
1306 case VIDIOCSCHAN:
1307 {
1308 /* The spec says the argument is an integer, but
1309 the bttv driver uses a video_channel arg, which
1310 makes sense becasue it also has the norm flag.
1311 */
1312 struct video_channel *v = arg;
1313 if (v->channel != 0)
1314 return -EINVAL;
1315 return 0;
1316 }
1317
1318
1319 /* Picture functions; contrast etc. */
1320 case VIDIOCGPICT:
1321 {
1322 struct video_picture *p = arg;
1323 int val;
1324
1325 val = pwc_get_brightness(pdev);
1326 if (val >= 0)
1327 p->brightness = val;
1328 else
1329 p->brightness = 0xffff;
1330 val = pwc_get_contrast(pdev);
1331 if (val >= 0)
1332 p->contrast = val;
1333 else
1334 p->contrast = 0xffff;
1335 /* Gamma, Whiteness, what's the difference? :) */
1336 val = pwc_get_gamma(pdev);
1337 if (val >= 0)
1338 p->whiteness = val;
1339 else
1340 p->whiteness = 0xffff;
1341 val = pwc_get_saturation(pdev);
1342 if (val >= 0)
1343 p->colour = val;
1344 else
1345 p->colour = 0xffff;
1346 p->depth = 24;
1347 p->palette = pdev->vpalette;
1348 p->hue = 0xFFFF; /* N/A */
1349 break;
1350 }
1351
1352 case VIDIOCSPICT:
1353 {
1354 struct video_picture *p = arg;
1355 /*
1356 * FIXME: Suppose we are mid read
1357 ANSWER: No problem: the firmware of the camera
1358 can handle brightness/contrast/etc
1359 changes at _any_ time, and the palette
1360 is used exactly once in the uncompress
1361 routine.
1362 */
1363 pwc_set_brightness(pdev, p->brightness);
1364 pwc_set_contrast(pdev, p->contrast);
1365 pwc_set_gamma(pdev, p->whiteness);
1366 pwc_set_saturation(pdev, p->colour);
1367 if (p->palette && p->palette != pdev->vpalette) {
1368 switch (p->palette) {
1369 case VIDEO_PALETTE_YUV420P:
1370 case VIDEO_PALETTE_RAW:
1371 pdev->vpalette = p->palette;
1372 return pwc_try_video_mode(pdev, pdev->image.x, pdev->image.y, pdev->vframes, pdev->vcompression, pdev->vsnapshot);
1373 break;
1374 default:
1375 return -EINVAL;
1376 break;
1377 }
1378 }
1379 break;
1380 }
1381
1382 /* Window/size parameters */
1383 case VIDIOCGWIN:
1384 {
1385 struct video_window *vw = arg;
1386
1387 vw->x = 0;
1388 vw->y = 0;
1389 vw->width = pdev->view.x;
1390 vw->height = pdev->view.y;
1391 vw->chromakey = 0;
1392 vw->flags = (pdev->vframes << PWC_FPS_SHIFT) |
1393 (pdev->vsnapshot ? PWC_FPS_SNAPSHOT : 0);
1394 break;
1395 }
1396
1397 case VIDIOCSWIN:
1398 {
1399 struct video_window *vw = arg;
1400 int fps, snapshot, ret;
1401
1402 fps = (vw->flags & PWC_FPS_FRMASK) >> PWC_FPS_SHIFT;
1403 snapshot = vw->flags & PWC_FPS_SNAPSHOT;
1404 if (fps == 0)
1405 fps = pdev->vframes;
1406 if (pdev->view.x == vw->width && pdev->view.y && fps == pdev->vframes && snapshot == pdev->vsnapshot)
1407 return 0;
1408 ret = pwc_try_video_mode(pdev, vw->width, vw->height, fps, pdev->vcompression, snapshot);
1409 if (ret)
1410 return ret;
1411 break;
1412 }
1413
1414 /* We don't have overlay support (yet) */
1415 case VIDIOCGFBUF:
1416 {
1417 struct video_buffer *vb = arg;
1418
1419 memset(vb,0,sizeof(*vb));
1420 break;
1421 }
1422
1423 /* mmap() functions */
1424 case VIDIOCGMBUF:
1425 {
1426 /* Tell the user program how much memory is needed for a mmap() */
1427 struct video_mbuf *vm = arg;
1428 int i;
1429
1430 memset(vm, 0, sizeof(*vm));
1431 vm->size = default_mbufs * pdev->len_per_image;
1432 vm->frames = default_mbufs; /* double buffering should be enough for most applications */
1433 for (i = 0; i < default_mbufs; i++)
1434 vm->offsets[i] = i * pdev->len_per_image;
1435 break;
1436 }
1437
1438 case VIDIOCMCAPTURE:
1439 {
1440 /* Start capture into a given image buffer (called 'frame' in video_mmap structure) */
1441 struct video_mmap *vm = arg;
1442
1443 Trace(TRACE_READ, "VIDIOCMCAPTURE: %dx%d, frame %d, format %d\n", vm->width, vm->height, vm->frame, vm->format);
1444 if (vm->frame < 0 || vm->frame >= default_mbufs)
1445 return -EINVAL;
1446
1447 /* xawtv is nasty. It probes the available palettes
1448 by setting a very small image size and trying
1449 various palettes... The driver doesn't support
1450 such small images, so I'm working around it.
1451 */
1452 if (vm->format)
1453 {
1454 switch (vm->format)
1455 {
1456 case VIDEO_PALETTE_YUV420P:
1457 case VIDEO_PALETTE_RAW:
1458 break;
1459 default:
1460 return -EINVAL;
1461 break;
1462 }
1463 }
1464
1465 if ((vm->width != pdev->view.x || vm->height != pdev->view.y) &&
1466 (vm->width >= pdev->view_min.x && vm->height >= pdev->view_min.y)) {
1467 int ret;
1468
1469 Trace(TRACE_OPEN, "VIDIOCMCAPTURE: changing size to please xawtv :-(.\n");
1470 ret = pwc_try_video_mode(pdev, vm->width, vm->height, pdev->vframes, pdev->vcompression, pdev->vsnapshot);
1471 if (ret)
1472 return ret;
1473 } /* ... size mismatch */
1474
1475 /* FIXME: should we lock here? */
1476 if (pdev->image_used[vm->frame])
1477 return -EBUSY; /* buffer wasn't available. Bummer */
1478 pdev->image_used[vm->frame] = 1;
1479
1480 /* Okay, we're done here. In the SYNC call we wait until a
1481 frame comes available, then expand image into the given
1482 buffer.
1483 In contrast to the CPiA cam the Philips cams deliver a
1484 constant stream, almost like a grabber card. Also,
1485 we have separate buffers for the rawdata and the image,
1486 meaning we can nearly always expand into the requested buffer.
1487 */
1488 Trace(TRACE_READ, "VIDIOCMCAPTURE done.\n");
1489 break;
1490 }
1491
1492 case VIDIOCSYNC:
1493 {
1494 /* The doc says: "Whenever a buffer is used it should
1495 call VIDIOCSYNC to free this frame up and continue."
1496
1497 The only odd thing about this whole procedure is
1498 that MCAPTURE flags the buffer as "in use", and
1499 SYNC immediately unmarks it, while it isn't
1500 after SYNC that you know that the buffer actually
1501 got filled! So you better not start a CAPTURE in
1502 the same frame immediately (use double buffering).
1503 This is not a problem for this cam, since it has
1504 extra intermediate buffers, but a hardware
1505 grabber card will then overwrite the buffer
1506 you're working on.
1507 */
1508 int *mbuf = arg;
1509 int ret;
1510
1511 Trace(TRACE_READ, "VIDIOCSYNC called (%d).\n", *mbuf);
1512
1513 /* bounds check */
1514 if (*mbuf < 0 || *mbuf >= default_mbufs)
1515 return -EINVAL;
1516 /* check if this buffer was requested anyway */
1517 if (pdev->image_used[*mbuf] == 0)
1518 return -EINVAL;
1519
1520 /* Add ourselves to the frame wait-queue.
1521
1522 FIXME: needs auditing for safety.
1523 QUESTION: In what respect? I think that using the
1524 frameq is safe now.
1525 */
1526 add_wait_queue(&pdev->frameq, &wait);
1527 while (pdev->full_frames == NULL) {
1528 if (pdev->error_status) {
1529 remove_wait_queue(&pdev->frameq, &wait);
1530 set_current_state(TASK_RUNNING);
1531 return -pdev->error_status;
1532 }
1533
1534 if (signal_pending(current)) {
1535 remove_wait_queue(&pdev->frameq, &wait);
1536 set_current_state(TASK_RUNNING);
1537 return -ERESTARTSYS;
1538 }
1539 schedule();
1540 set_current_state(TASK_INTERRUPTIBLE);
1541 }
1542 remove_wait_queue(&pdev->frameq, &wait);
1543 set_current_state(TASK_RUNNING);
1544
1545 /* The frame is ready. Expand in the image buffer
1546 requested by the user. I don't care if you
1547 mmap() 5 buffers and request data in this order:
1548 buffer 4 2 3 0 1 2 3 0 4 3 1 . . .
1549 Grabber hardware may not be so forgiving.
1550 */
1551 Trace(TRACE_READ, "VIDIOCSYNC: frame ready.\n");
1552 pdev->fill_image = *mbuf; /* tell in which buffer we want the image to be expanded */
1553 /* Decompress, etc */
1554 ret = pwc_handle_frame(pdev);
1555 pdev->image_used[*mbuf] = 0;
1556 if (ret)
1557 return -EFAULT;
1558 break;
1559 }
1560
1561 case VIDIOCGAUDIO:
1562 {
1563 struct video_audio *v = arg;
1564
1565 strcpy(v->name, "Microphone");
1566 v->audio = -1; /* unknown audio minor */
1567 v->flags = 0;
1568 v->mode = VIDEO_SOUND_MONO;
1569 v->volume = 0;
1570 v->bass = 0;
1571 v->treble = 0;
1572 v->balance = 0x8000;
1573 v->step = 1;
1574 break;
1575 }
1576
1577 case VIDIOCSAUDIO:
1578 {
1579 /* Dummy: nothing can be set */
1580 break;
1581 }
1582
1583 case VIDIOCGUNIT:
1584 {
1585 struct video_unit *vu = arg;
1586
1587 vu->video = pdev->vdev->minor & 0x3F;
1588 vu->audio = -1; /* not known yet */
1589 vu->vbi = -1;
1590 vu->radio = -1;
1591 vu->teletext = -1;
1592 break;
1593 }
1594 default:
1595 return pwc_ioctl(pdev, cmd, arg);
1596 } /* ..switch */
1597 return 0;
1598}
1599
1600static int pwc_video_ioctl(struct inode *inode, struct file *file,
1601 unsigned int cmd, unsigned long arg)
1602{
1603 return video_usercopy(inode, file, cmd, arg, pwc_video_do_ioctl);
1604}
1605
1606
1607static int pwc_video_mmap(struct file *file, struct vm_area_struct *vma)
1608{
1609 struct video_device *vdev = file->private_data;
1610 struct pwc_device *pdev;
1611 unsigned long start = vma->vm_start;
1612 unsigned long size = vma->vm_end-vma->vm_start;
1613 unsigned long page, pos;
1614
1615 Trace(TRACE_MEMORY, "mmap(0x%p, 0x%lx, %lu) called.\n", vdev, start, size);
1616 pdev = vdev->priv;
1617
1618 vma->vm_flags |= VM_IO;
1619
1620 pos = (unsigned long)pdev->image_data;
1621 while (size > 0) {
1622 page = vmalloc_to_pfn((void *)pos);
1623 if (remap_pfn_range(vma, start, page, PAGE_SIZE, PAGE_SHARED))
1624 return -EAGAIN;
1625
1626 start += PAGE_SIZE;
1627 pos += PAGE_SIZE;
1628 if (size > PAGE_SIZE)
1629 size -= PAGE_SIZE;
1630 else
1631 size = 0;
1632 }
1633
1634 return 0;
1635}
1636
1637/***************************************************************************/
1638/* USB functions */
1639
1640/* This function gets called when a new device is plugged in or the usb core
1641 * is loaded.
1642 */
1643
1644static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id *id)
1645{
1646 struct usb_device *udev = interface_to_usbdev(intf);
1647 struct pwc_device *pdev = NULL;
1648 int vendor_id, product_id, type_id;
1649 int i, hint;
1650 int features = 0;
1651 int video_nr = -1; /* default: use next available device */
1652 char serial_number[30], *name;
1653
1654 /* Check if we can handle this device */
1655 Trace(TRACE_PROBE, "probe() called [%04X %04X], if %d\n",
1656 le16_to_cpu(udev->descriptor.idVendor),
1657 le16_to_cpu(udev->descriptor.idProduct),
1658 intf->altsetting->desc.bInterfaceNumber);
1659
1660 /* the interfaces are probed one by one. We are only interested in the
1661 video interface (0) now.
1662 Interface 1 is the Audio Control, and interface 2 Audio itself.
1663 */
1664 if (intf->altsetting->desc.bInterfaceNumber > 0)
1665 return -ENODEV;
1666
1667 vendor_id = le16_to_cpu(udev->descriptor.idVendor);
1668 product_id = le16_to_cpu(udev->descriptor.idProduct);
1669
1670 if (vendor_id == 0x0471) {
1671 switch (product_id) {
1672 case 0x0302:
1673 Info("Philips PCA645VC USB webcam detected.\n");
1674 name = "Philips 645 webcam";
1675 type_id = 645;
1676 break;
1677 case 0x0303:
1678 Info("Philips PCA646VC USB webcam detected.\n");
1679 name = "Philips 646 webcam";
1680 type_id = 646;
1681 break;
1682 case 0x0304:
1683 Info("Askey VC010 type 2 USB webcam detected.\n");
1684 name = "Askey VC010 webcam";
1685 type_id = 646;
1686 break;
1687 case 0x0307:
1688 Info("Philips PCVC675K (Vesta) USB webcam detected.\n");
1689 name = "Philips 675 webcam";
1690 type_id = 675;
1691 break;
1692 case 0x0308:
1693 Info("Philips PCVC680K (Vesta Pro) USB webcam detected.\n");
1694 name = "Philips 680 webcam";
1695 type_id = 680;
1696 break;
1697 case 0x030C:
1698 Info("Philips PCVC690K (Vesta Pro Scan) USB webcam detected.\n");
1699 name = "Philips 690 webcam";
1700 type_id = 690;
1701 break;
1702 case 0x0310:
1703 Info("Philips PCVC730K (ToUCam Fun)/PCVC830 (ToUCam II) USB webcam detected.\n");
1704 name = "Philips 730 webcam";
1705 type_id = 730;
1706 break;
1707 case 0x0311:
1708 Info("Philips PCVC740K (ToUCam Pro)/PCVC840 (ToUCam II) USB webcam detected.\n");
1709 name = "Philips 740 webcam";
1710 type_id = 740;
1711 break;
1712 case 0x0312:
1713 Info("Philips PCVC750K (ToUCam Pro Scan) USB webcam detected.\n");
1714 name = "Philips 750 webcam";
1715 type_id = 750;
1716 break;
1717 case 0x0313:
1718 Info("Philips PCVC720K/40 (ToUCam XS) USB webcam detected.\n");
1719 name = "Philips 720K/40 webcam";
1720 type_id = 720;
1721 break;
1722 default:
1723 return -ENODEV;
1724 break;
1725 }
1726 }
1727 else if (vendor_id == 0x069A) {
1728 switch(product_id) {
1729 case 0x0001:
1730 Info("Askey VC010 type 1 USB webcam detected.\n");
1731 name = "Askey VC010 webcam";
1732 type_id = 645;
1733 break;
1734 default:
1735 return -ENODEV;
1736 break;
1737 }
1738 }
1739 else if (vendor_id == 0x046d) {
1740 switch(product_id) {
1741 case 0x08b0:
1742 Info("Logitech QuickCam Pro 3000 USB webcam detected.\n");
1743 name = "Logitech QuickCam Pro 3000";
1744 type_id = 740; /* CCD sensor */
1745 break;
1746 case 0x08b1:
1747 Info("Logitech QuickCam Notebook Pro USB webcam detected.\n");
1748 name = "Logitech QuickCam Notebook Pro";
1749 type_id = 740; /* CCD sensor */
1750 break;
1751 case 0x08b2:
1752 Info("Logitech QuickCam 4000 Pro USB webcam detected.\n");
1753 name = "Logitech QuickCam Pro 4000";
1754 type_id = 740; /* CCD sensor */
1755 break;
1756 case 0x08b3:
1757 Info("Logitech QuickCam Zoom USB webcam detected.\n");
1758 name = "Logitech QuickCam Zoom";
1759 type_id = 740; /* CCD sensor */
1760 break;
1761 case 0x08B4:
1762 Info("Logitech QuickCam Zoom (new model) USB webcam detected.\n");
1763 name = "Logitech QuickCam Zoom";
1764 type_id = 740; /* CCD sensor */
1765 break;
1766 case 0x08b5:
1767 Info("Logitech QuickCam Orbit/Sphere USB webcam detected.\n");
1768 name = "Logitech QuickCam Orbit";
1769 type_id = 740; /* CCD sensor */
1770 features |= FEATURE_MOTOR_PANTILT;
1771 break;
1772 case 0x08b6:
1773 case 0x08b7:
1774 case 0x08b8:
1775 Info("Logitech QuickCam detected (reserved ID).\n");
1776 name = "Logitech QuickCam (res.)";
1777 type_id = 730; /* Assuming CMOS */
1778 break;
1779 default:
1780 return -ENODEV;
1781 break;
1782 }
1783 }
1784 else if (vendor_id == 0x055d) {
1785 /* I don't know the difference between the C10 and the C30;
1786 I suppose the difference is the sensor, but both cameras
1787 work equally well with a type_id of 675
1788 */
1789 switch(product_id) {
1790 case 0x9000:
1791 Info("Samsung MPC-C10 USB webcam detected.\n");
1792 name = "Samsung MPC-C10";
1793 type_id = 675;
1794 break;
1795 case 0x9001:
1796 Info("Samsung MPC-C30 USB webcam detected.\n");
1797 name = "Samsung MPC-C30";
1798 type_id = 675;
1799 break;
1800 default:
1801 return -ENODEV;
1802 break;
1803 }
1804 }
1805 else if (vendor_id == 0x041e) {
1806 switch(product_id) {
1807 case 0x400c:
1808 Info("Creative Labs Webcam 5 detected.\n");
1809 name = "Creative Labs Webcam 5";
1810 type_id = 730;
1811 break;
1812 case 0x4011:
1813 Info("Creative Labs Webcam Pro Ex detected.\n");
1814 name = "Creative Labs Webcam Pro Ex";
1815 type_id = 740;
1816 break;
1817 default:
1818 return -ENODEV;
1819 break;
1820 }
1821 }
1822 else if (vendor_id == 0x04cc) {
1823 switch(product_id) {
1824 case 0x8116:
1825 Info("Sotec Afina Eye USB webcam detected.\n");
1826 name = "Sotec Afina Eye";
1827 type_id = 730;
1828 break;
1829 default:
1830 return -ENODEV;
1831 break;
1832 }
1833 }
1834 else if (vendor_id == 0x06be) {
1835 switch(product_id) {
1836 case 0x8116:
1837 /* This is essentially the same cam as the Sotec Afina Eye */
1838 Info("AME Co. Afina Eye USB webcam detected.\n");
1839 name = "AME Co. Afina Eye";
1840 type_id = 750;
1841 break;
1842 default:
1843 return -ENODEV;
1844 break;
1845 }
1846
1847 }
1848 else if (vendor_id == 0x0d81) {
1849 switch(product_id) {
1850 case 0x1900:
1851 Info("Visionite VCS-UC300 USB webcam detected.\n");
1852 name = "Visionite VCS-UC300";
1853 type_id = 740; /* CCD sensor */
1854 break;
1855 case 0x1910:
1856 Info("Visionite VCS-UM100 USB webcam detected.\n");
1857 name = "Visionite VCS-UM100";
1858 type_id = 730; /* CMOS sensor */
1859 break;
1860 default:
1861 return -ENODEV;
1862 break;
1863 }
1864 }
1865 else
1866 return -ENODEV; /* Not any of the know types; but the list keeps growing. */
1867
1868 memset(serial_number, 0, 30);
1869 usb_string(udev, udev->descriptor.iSerialNumber, serial_number, 29);
1870 Trace(TRACE_PROBE, "Device serial number is %s\n", serial_number);
1871
1872 if (udev->descriptor.bNumConfigurations > 1)
1873 Info("Warning: more than 1 configuration available.\n");
1874
1875 /* Allocate structure, initialize pointers, mutexes, etc. and link it to the usb_device */
1876 pdev = kmalloc(sizeof(struct pwc_device), GFP_KERNEL);
1877 if (pdev == NULL) {
1878 Err("Oops, could not allocate memory for pwc_device.\n");
1879 return -ENOMEM;
1880 }
1881 memset(pdev, 0, sizeof(struct pwc_device));
1882 pdev->type = type_id;
1883 pdev->vsize = default_size;
1884 pdev->vframes = default_fps;
1885 strcpy(pdev->serial, serial_number);
1886 pdev->features = features;
1887 if (vendor_id == 0x046D && product_id == 0x08B5)
1888 {
1889 /* Logitech QuickCam Orbit
1890 The ranges have been determined experimentally; they may differ from cam to cam.
1891 Also, the exact ranges left-right and up-down are different for my cam
1892 */
1893 pdev->angle_range.pan_min = -7000;
1894 pdev->angle_range.pan_max = 7000;
1895 pdev->angle_range.tilt_min = -3000;
1896 pdev->angle_range.tilt_max = 2500;
1897 }
1898
1899 init_MUTEX(&pdev->modlock);
1900 spin_lock_init(&pdev->ptrlock);
1901
1902 pdev->udev = udev;
1903 init_waitqueue_head(&pdev->frameq);
1904 pdev->vcompression = pwc_preferred_compression;
1905
1906 /* Allocate video_device structure */
1907 pdev->vdev = video_device_alloc();
1908 if (pdev->vdev == 0)
1909 {
1910 Err("Err, cannot allocate video_device struture. Failing probe.");
1911 kfree(pdev);
1912 return -ENOMEM;
1913 }
1914 memcpy(pdev->vdev, &pwc_template, sizeof(pwc_template));
1915 strcpy(pdev->vdev->name, name);
1916 pdev->vdev->owner = THIS_MODULE;
1917 video_set_drvdata(pdev->vdev, pdev);
1918
1919 pdev->release = le16_to_cpu(udev->descriptor.bcdDevice);
1920 Trace(TRACE_PROBE, "Release: %04x\n", pdev->release);
1921
1922 /* Now search device_hint[] table for a match, so we can hint a node number. */
1923 for (hint = 0; hint < MAX_DEV_HINTS; hint++) {
1924 if (((device_hint[hint].type == -1) || (device_hint[hint].type == pdev->type)) &&
1925 (device_hint[hint].pdev == NULL)) {
1926 /* so far, so good... try serial number */
1927 if ((device_hint[hint].serial_number[0] == '*') || !strcmp(device_hint[hint].serial_number, serial_number)) {
1928 /* match! */
1929 video_nr = device_hint[hint].device_node;
1930 Trace(TRACE_PROBE, "Found hint, will try to register as /dev/video%d\n", video_nr);
1931 break;
1932 }
1933 }
1934 }
1935
1936 pdev->vdev->release = video_device_release;
1937 i = video_register_device(pdev->vdev, VFL_TYPE_GRABBER, video_nr);
1938 if (i < 0) {
1939 Err("Failed to register as video device (%d).\n", i);
1940 video_device_release(pdev->vdev); /* Drip... drip... drip... */
1941 kfree(pdev); /* Oops, no memory leaks please */
1942 return -EIO;
1943 }
1944 else {
1945 Info("Registered as /dev/video%d.\n", pdev->vdev->minor & 0x3F);
1946 }
1947
1948 /* occupy slot */
1949 if (hint < MAX_DEV_HINTS)
1950 device_hint[hint].pdev = pdev;
1951
1952 Trace(TRACE_PROBE, "probe() function returning struct at 0x%p.\n", pdev);
1953 usb_set_intfdata (intf, pdev);
1954 return 0;
1955}
1956
1957/* The user janked out the cable... */
1958static void usb_pwc_disconnect(struct usb_interface *intf)
1959{
1960 struct pwc_device *pdev;
1961 int hint;
1962
1963 lock_kernel();
1964 pdev = usb_get_intfdata (intf);
1965 usb_set_intfdata (intf, NULL);
1966 if (pdev == NULL) {
1967 Err("pwc_disconnect() Called without private pointer.\n");
1968 goto disconnect_out;
1969 }
1970 if (pdev->udev == NULL) {
1971 Err("pwc_disconnect() already called for %p\n", pdev);
1972 goto disconnect_out;
1973 }
1974 if (pdev->udev != interface_to_usbdev(intf)) {
1975 Err("pwc_disconnect() Woops: pointer mismatch udev/pdev.\n");
1976 goto disconnect_out;
1977 }
1978#ifdef PWC_MAGIC
1979 if (pdev->magic != PWC_MAGIC) {
1980 Err("pwc_disconnect() Magic number failed. Consult your scrolls and try again.\n");
1981 goto disconnect_out;
1982 }
1983#endif
1984
1985 /* We got unplugged; this is signalled by an EPIPE error code */
1986 if (pdev->vopen) {
1987 Info("Disconnected while webcam is in use!\n");
1988 pdev->error_status = EPIPE;
1989 }
1990
1991 /* Alert waiting processes */
1992 wake_up_interruptible(&pdev->frameq);
1993 /* Wait until device is closed */
1994 while (pdev->vopen)
1995 schedule();
1996 /* Device is now closed, so we can safely unregister it */
1997 Trace(TRACE_PROBE, "Unregistering video device in disconnect().\n");
1998 video_unregister_device(pdev->vdev);
1999
2000 /* Free memory (don't set pdev to 0 just yet) */
2001 kfree(pdev);
2002
2003disconnect_out:
2004 /* search device_hint[] table if we occupy a slot, by any chance */
2005 for (hint = 0; hint < MAX_DEV_HINTS; hint++)
2006 if (device_hint[hint].pdev == pdev)
2007 device_hint[hint].pdev = NULL;
2008
2009 unlock_kernel();
2010}
2011
2012
2013/* *grunt* We have to do atoi ourselves :-( */
2014static int pwc_atoi(const char *s)
2015{
2016 int k = 0;
2017
2018 k = 0;
2019 while (*s != '\0' && *s >= '0' && *s <= '9') {
2020 k = 10 * k + (*s - '0');
2021 s++;
2022 }
2023 return k;
2024}
2025
2026
2027/*
2028 * Initialization code & module stuff
2029 */
2030
2031static char size[10];
2032static int fps = 0;
2033static int fbufs = 0;
2034static int mbufs = 0;
2035static int trace = -1;
2036static int compression = -1;
2037static int leds[2] = { -1, -1 };
2038static char *dev_hint[MAX_DEV_HINTS] = { };
2039
2040module_param_string(size, size, sizeof(size), 0);
2041MODULE_PARM_DESC(size, "Initial image size. One of sqcif, qsif, qcif, sif, cif, vga");
2042module_param(fps, int, 0000);
2043MODULE_PARM_DESC(fps, "Initial frames per second. Varies with model, useful range 5-30");
2044module_param(fbufs, int, 0000);
2045MODULE_PARM_DESC(fbufs, "Number of internal frame buffers to reserve");
2046module_param(mbufs, int, 0000);
2047MODULE_PARM_DESC(mbufs, "Number of external (mmap()ed) image buffers");
2048module_param(trace, int, 0000);
2049MODULE_PARM_DESC(trace, "For debugging purposes");
2050module_param(power_save, bool, 0000);
2051MODULE_PARM_DESC(power_save, "Turn power save feature in camera on or off");
2052module_param(compression, int, 0000);
2053MODULE_PARM_DESC(compression, "Preferred compression quality. Range 0 (uncompressed) to 3 (high compression)");
2054module_param_array(leds, int, NULL, 0000);
2055MODULE_PARM_DESC(leds, "LED on,off time in milliseconds");
2056module_param_array(dev_hint, charp, NULL, 0000);
2057MODULE_PARM_DESC(dev_hint, "Device node hints");
2058
2059MODULE_DESCRIPTION("Philips & OEM USB webcam driver");
2060MODULE_AUTHOR("Luc Saillard <luc@saillard.org>");
2061MODULE_LICENSE("GPL");
2062
2063static int __init usb_pwc_init(void)
2064{
2065 int i, sz;
2066 char *sizenames[PSZ_MAX] = { "sqcif", "qsif", "qcif", "sif", "cif", "vga" };
2067
2068 Info("Philips webcam module version " PWC_VERSION " loaded.\n");
2069 Info("Supports Philips PCA645/646, PCVC675/680/690, PCVC720[40]/730/740/750 & PCVC830/840.\n");
2070 Info("Also supports the Askey VC010, various Logitech Quickcams, Samsung MPC-C10 and MPC-C30,\n");
2071 Info("the Creative WebCam 5 & Pro Ex, SOTEC Afina Eye and Visionite VCS-UC300 and VCS-UM100.\n");
2072
2073 if (fps) {
2074 if (fps < 4 || fps > 30) {
2075 Err("Framerate out of bounds (4-30).\n");
2076 return -EINVAL;
2077 }
2078 default_fps = fps;
2079 Info("Default framerate set to %d.\n", default_fps);
2080 }
2081
2082 if (size[0]) {
2083 /* string; try matching with array */
2084 for (sz = 0; sz < PSZ_MAX; sz++) {
2085 if (!strcmp(sizenames[sz], size)) { /* Found! */
2086 default_size = sz;
2087 break;
2088 }
2089 }
2090 if (sz == PSZ_MAX) {
2091 Err("Size not recognized; try size=[sqcif | qsif | qcif | sif | cif | vga].\n");
2092 return -EINVAL;
2093 }
2094 Info("Default image size set to %s [%dx%d].\n", sizenames[default_size], pwc_image_sizes[default_size].x, pwc_image_sizes[default_size].y);
2095 }
2096 if (mbufs) {
2097 if (mbufs < 1 || mbufs > MAX_IMAGES) {
2098 Err("Illegal number of mmap() buffers; use a number between 1 and %d.\n", MAX_IMAGES);
2099 return -EINVAL;
2100 }
2101 default_mbufs = mbufs;
2102 Info("Number of image buffers set to %d.\n", default_mbufs);
2103 }
2104 if (fbufs) {
2105 if (fbufs < 2 || fbufs > MAX_FRAMES) {
2106 Err("Illegal number of frame buffers; use a number between 2 and %d.\n", MAX_FRAMES);
2107 return -EINVAL;
2108 }
2109 default_fbufs = fbufs;
2110 Info("Number of frame buffers set to %d.\n", default_fbufs);
2111 }
2112 if (trace >= 0) {
2113 Info("Trace options: 0x%04x\n", trace);
2114 pwc_trace = trace;
2115 }
2116 if (compression >= 0) {
2117 if (compression > 3) {
2118 Err("Invalid compression setting; use a number between 0 (uncompressed) and 3 (high).\n");
2119 return -EINVAL;
2120 }
2121 pwc_preferred_compression = compression;
2122 Info("Preferred compression set to %d.\n", pwc_preferred_compression);
2123 }
2124 if (power_save)
2125 Info("Enabling power save on open/close.\n");
2126 if (leds[0] >= 0)
2127 led_on = leds[0];
2128 if (leds[1] >= 0)
2129 led_off = leds[1];
2130
2131 /* Big device node whoopla. Basicly, it allows you to assign a
2132 device node (/dev/videoX) to a camera, based on its type
2133 & serial number. The format is [type[.serialnumber]:]node.
2134
2135 Any camera that isn't matched by these rules gets the next
2136 available free device node.
2137 */
2138 for (i = 0; i < MAX_DEV_HINTS; i++) {
2139 char *s, *colon, *dot;
2140
2141 /* This loop also initializes the array */
2142 device_hint[i].pdev = NULL;
2143 s = dev_hint[i];
2144 if (s != NULL && *s != '\0') {
2145 device_hint[i].type = -1; /* wildcard */
2146 strcpy(device_hint[i].serial_number, "*");
2147
2148 /* parse string: chop at ':' & '/' */
2149 colon = dot = s;
2150 while (*colon != '\0' && *colon != ':')
2151 colon++;
2152 while (*dot != '\0' && *dot != '.')
2153 dot++;
2154 /* Few sanity checks */
2155 if (*dot != '\0' && dot > colon) {
2156 Err("Malformed camera hint: the colon must be after the dot.\n");
2157 return -EINVAL;
2158 }
2159
2160 if (*colon == '\0') {
2161 /* No colon */
2162 if (*dot != '\0') {
2163 Err("Malformed camera hint: no colon + device node given.\n");
2164 return -EINVAL;
2165 }
2166 else {
2167 /* No type or serial number specified, just a number. */
2168 device_hint[i].device_node = pwc_atoi(s);
2169 }
2170 }
2171 else {
2172 /* There's a colon, so we have at least a type and a device node */
2173 device_hint[i].type = pwc_atoi(s);
2174 device_hint[i].device_node = pwc_atoi(colon + 1);
2175 if (*dot != '\0') {
2176 /* There's a serial number as well */
2177 int k;
2178
2179 dot++;
2180 k = 0;
2181 while (*dot != ':' && k < 29) {
2182 device_hint[i].serial_number[k++] = *dot;
2183 dot++;
2184 }
2185 device_hint[i].serial_number[k] = '\0';
2186 }
2187 }
2188#if PWC_DEBUG
2189 Debug("device_hint[%d]:\n", i);
2190 Debug(" type : %d\n", device_hint[i].type);
2191 Debug(" serial# : %s\n", device_hint[i].serial_number);
2192 Debug(" node : %d\n", device_hint[i].device_node);
2193#endif
2194 }
2195 else
2196 device_hint[i].type = 0; /* not filled */
2197 } /* ..for MAX_DEV_HINTS */
2198
2199 Trace(TRACE_PROBE, "Registering driver at address 0x%p.\n", &pwc_driver);
2200 return usb_register(&pwc_driver);
2201}
2202
2203static void __exit usb_pwc_exit(void)
2204{
2205 Trace(TRACE_MODULE, "Deregistering driver.\n");
2206 usb_deregister(&pwc_driver);
2207 Info("Philips webcam module removed.\n");
2208}
2209
2210module_init(usb_pwc_init);
2211module_exit(usb_pwc_exit);
2212
diff --git a/drivers/usb/media/pwc/pwc-ioctl.h b/drivers/usb/media/pwc/pwc-ioctl.h
new file mode 100644
index 000000000000..65805eaa9a1c
--- /dev/null
+++ b/drivers/usb/media/pwc/pwc-ioctl.h
@@ -0,0 +1,292 @@
1#ifndef PWC_IOCTL_H
2#define PWC_IOCTL_H
3
4/* (C) 2001-2004 Nemosoft Unv.
5 (C) 2004 Luc Saillard (luc@saillard.org)
6
7 NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx
8 driver and thus may have bugs that are not present in the original version.
9 Please send bug reports and support requests to <luc@saillard.org>.
10 The decompression routines have been implemented by reverse-engineering the
11 Nemosoft binary pwcx module. Caveat emptor.
12
13 This program is free software; you can redistribute it and/or modify
14 it under the terms of the GNU General Public License as published by
15 the Free Software Foundation; either version 2 of the License, or
16 (at your option) any later version.
17
18 This program is distributed in the hope that it will be useful,
19 but WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 GNU General Public License for more details.
22
23 You should have received a copy of the GNU General Public License
24 along with this program; if not, write to the Free Software
25 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26*/
27
28/* This is pwc-ioctl.h belonging to PWC 8.12.1
29 It contains structures and defines to communicate from user space
30 directly to the driver.
31 */
32
33/*
34 Changes
35 2001/08/03 Alvarado Added ioctl constants to access methods for
36 changing white balance and red/blue gains
37 2002/12/15 G. H. Fernandez-Toribio VIDIOCGREALSIZE
38 2003/12/13 Nemosft Unv. Some modifications to make interfacing to
39 PWCX easier
40 */
41
42/* These are private ioctl() commands, specific for the Philips webcams.
43 They contain functions not found in other webcams, and settings not
44 specified in the Video4Linux API.
45
46 The #define names are built up like follows:
47 VIDIOC VIDeo IOCtl prefix
48 PWC Philps WebCam
49 G optional: Get
50 S optional: Set
51 ... the function
52 */
53
54
55 /* Enumeration of image sizes */
56#define PSZ_SQCIF 0x00
57#define PSZ_QSIF 0x01
58#define PSZ_QCIF 0x02
59#define PSZ_SIF 0x03
60#define PSZ_CIF 0x04
61#define PSZ_VGA 0x05
62#define PSZ_MAX 6
63
64
65/* The frame rate is encoded in the video_window.flags parameter using
66 the upper 16 bits, since some flags are defined nowadays. The following
67 defines provide a mask and shift to filter out this value.
68
69 In 'Snapshot' mode the camera freezes its automatic exposure and colour
70 balance controls.
71 */
72#define PWC_FPS_SHIFT 16
73#define PWC_FPS_MASK 0x00FF0000
74#define PWC_FPS_FRMASK 0x003F0000
75#define PWC_FPS_SNAPSHOT 0x00400000
76
77
78/* structure for transfering x & y coordinates */
79struct pwc_coord
80{
81 int x, y; /* guess what */
82 int size; /* size, or offset */
83};
84
85
86/* Used with VIDIOCPWCPROBE */
87struct pwc_probe
88{
89 char name[32];
90 int type;
91};
92
93struct pwc_serial
94{
95 char serial[30]; /* String with serial number. Contains terminating 0 */
96};
97
98/* pwc_whitebalance.mode values */
99#define PWC_WB_INDOOR 0
100#define PWC_WB_OUTDOOR 1
101#define PWC_WB_FL 2
102#define PWC_WB_MANUAL 3
103#define PWC_WB_AUTO 4
104
105/* Used with VIDIOCPWC[SG]AWB (Auto White Balance).
106 Set mode to one of the PWC_WB_* values above.
107 *red and *blue are the respective gains of these colour components inside
108 the camera; range 0..65535
109 When 'mode' == PWC_WB_MANUAL, 'manual_red' and 'manual_blue' are set or read;
110 otherwise undefined.
111 'read_red' and 'read_blue' are read-only.
112*/
113struct pwc_whitebalance
114{
115 int mode;
116 int manual_red, manual_blue; /* R/W */
117 int read_red, read_blue; /* R/O */
118};
119
120/*
121 'control_speed' and 'control_delay' are used in automatic whitebalance mode,
122 and tell the camera how fast it should react to changes in lighting, and
123 with how much delay. Valid values are 0..65535.
124*/
125struct pwc_wb_speed
126{
127 int control_speed;
128 int control_delay;
129
130};
131
132/* Used with VIDIOCPWC[SG]LED */
133struct pwc_leds
134{
135 int led_on; /* Led on-time; range = 0..25000 */
136 int led_off; /* Led off-time; range = 0..25000 */
137};
138
139/* Image size (used with GREALSIZE) */
140struct pwc_imagesize
141{
142 int width;
143 int height;
144};
145
146/* Defines and structures for Motorized Pan & Tilt */
147#define PWC_MPT_PAN 0x01
148#define PWC_MPT_TILT 0x02
149#define PWC_MPT_TIMEOUT 0x04 /* for status */
150
151/* Set angles; when absolute != 0, the angle is absolute and the
152 driver calculates the relative offset for you. This can only
153 be used with VIDIOCPWCSANGLE; VIDIOCPWCGANGLE always returns
154 absolute angles.
155 */
156struct pwc_mpt_angles
157{
158 int absolute; /* write-only */
159 int pan; /* degrees * 100 */
160 int tilt; /* degress * 100 */
161};
162
163/* Range of angles of the camera, both horizontally and vertically.
164 */
165struct pwc_mpt_range
166{
167 int pan_min, pan_max; /* degrees * 100 */
168 int tilt_min, tilt_max;
169};
170
171struct pwc_mpt_status
172{
173 int status;
174 int time_pan;
175 int time_tilt;
176};
177
178
179/* This is used for out-of-kernel decompression. With it, you can get
180 all the necessary information to initialize and use the decompressor
181 routines in standalone applications.
182 */
183struct pwc_video_command
184{
185 int type; /* camera type (645, 675, 730, etc.) */
186 int release; /* release number */
187
188 int size; /* one of PSZ_* */
189 int alternate;
190 int command_len; /* length of USB video command */
191 unsigned char command_buf[13]; /* Actual USB video command */
192 int bandlength; /* >0 = compressed */
193 int frame_size; /* Size of one (un)compressed frame */
194};
195
196/* Flags for PWCX subroutines. Not all modules honour all flags. */
197#define PWCX_FLAG_PLANAR 0x0001
198#define PWCX_FLAG_BAYER 0x0008
199
200
201/* IOCTL definitions */
202
203 /* Restore user settings */
204#define VIDIOCPWCRUSER _IO('v', 192)
205 /* Save user settings */
206#define VIDIOCPWCSUSER _IO('v', 193)
207 /* Restore factory settings */
208#define VIDIOCPWCFACTORY _IO('v', 194)
209
210 /* You can manipulate the compression factor. A compression preference of 0
211 means use uncompressed modes when available; 1 is low compression, 2 is
212 medium and 3 is high compression preferred. Of course, the higher the
213 compression, the lower the bandwidth used but more chance of artefacts
214 in the image. The driver automatically chooses a higher compression when
215 the preferred mode is not available.
216 */
217 /* Set preferred compression quality (0 = uncompressed, 3 = highest compression) */
218#define VIDIOCPWCSCQUAL _IOW('v', 195, int)
219 /* Get preferred compression quality */
220#define VIDIOCPWCGCQUAL _IOR('v', 195, int)
221
222
223/* Retrieve serial number of camera */
224#define VIDIOCPWCGSERIAL _IOR('v', 198, struct pwc_serial)
225
226 /* This is a probe function; since so many devices are supported, it
227 becomes difficult to include all the names in programs that want to
228 check for the enhanced Philips stuff. So in stead, try this PROBE;
229 it returns a structure with the original name, and the corresponding
230 Philips type.
231 To use, fill the structure with zeroes, call PROBE and if that succeeds,
232 compare the name with that returned from VIDIOCGCAP; they should be the
233 same. If so, you can be assured it is a Philips (OEM) cam and the type
234 is valid.
235 */
236#define VIDIOCPWCPROBE _IOR('v', 199, struct pwc_probe)
237
238 /* Set AGC (Automatic Gain Control); int < 0 = auto, 0..65535 = fixed */
239#define VIDIOCPWCSAGC _IOW('v', 200, int)
240 /* Get AGC; int < 0 = auto; >= 0 = fixed, range 0..65535 */
241#define VIDIOCPWCGAGC _IOR('v', 200, int)
242 /* Set shutter speed; int < 0 = auto; >= 0 = fixed, range 0..65535 */
243#define VIDIOCPWCSSHUTTER _IOW('v', 201, int)
244
245 /* Color compensation (Auto White Balance) */
246#define VIDIOCPWCSAWB _IOW('v', 202, struct pwc_whitebalance)
247#define VIDIOCPWCGAWB _IOR('v', 202, struct pwc_whitebalance)
248
249 /* Auto WB speed */
250#define VIDIOCPWCSAWBSPEED _IOW('v', 203, struct pwc_wb_speed)
251#define VIDIOCPWCGAWBSPEED _IOR('v', 203, struct pwc_wb_speed)
252
253 /* LEDs on/off/blink; int range 0..65535 */
254#define VIDIOCPWCSLED _IOW('v', 205, struct pwc_leds)
255#define VIDIOCPWCGLED _IOR('v', 205, struct pwc_leds)
256
257 /* Contour (sharpness); int < 0 = auto, 0..65536 = fixed */
258#define VIDIOCPWCSCONTOUR _IOW('v', 206, int)
259#define VIDIOCPWCGCONTOUR _IOR('v', 206, int)
260
261 /* Backlight compensation; 0 = off, otherwise on */
262#define VIDIOCPWCSBACKLIGHT _IOW('v', 207, int)
263#define VIDIOCPWCGBACKLIGHT _IOR('v', 207, int)
264
265 /* Flickerless mode; = 0 off, otherwise on */
266#define VIDIOCPWCSFLICKER _IOW('v', 208, int)
267#define VIDIOCPWCGFLICKER _IOR('v', 208, int)
268
269 /* Dynamic noise reduction; 0 off, 3 = high noise reduction */
270#define VIDIOCPWCSDYNNOISE _IOW('v', 209, int)
271#define VIDIOCPWCGDYNNOISE _IOR('v', 209, int)
272
273 /* Real image size as used by the camera; tells you whether or not there's a gray border around the image */
274#define VIDIOCPWCGREALSIZE _IOR('v', 210, struct pwc_imagesize)
275
276 /* Motorized pan & tilt functions */
277#define VIDIOCPWCMPTRESET _IOW('v', 211, int)
278#define VIDIOCPWCMPTGRANGE _IOR('v', 211, struct pwc_mpt_range)
279#define VIDIOCPWCMPTSANGLE _IOW('v', 212, struct pwc_mpt_angles)
280#define VIDIOCPWCMPTGANGLE _IOR('v', 212, struct pwc_mpt_angles)
281#define VIDIOCPWCMPTSTATUS _IOR('v', 213, struct pwc_mpt_status)
282
283 /* Get the USB set-video command; needed for initializing libpwcx */
284#define VIDIOCPWCGVIDCMD _IOR('v', 215, struct pwc_video_command)
285struct pwc_table_init_buffer {
286 int len;
287 char *buffer;
288
289};
290#define VIDIOCPWCGVIDTABLE _IOR('v', 216, struct pwc_table_init_buffer)
291
292#endif
diff --git a/drivers/usb/media/pwc/pwc-kiara.c b/drivers/usb/media/pwc/pwc-kiara.c
new file mode 100644
index 000000000000..5485800efd83
--- /dev/null
+++ b/drivers/usb/media/pwc/pwc-kiara.c
@@ -0,0 +1,891 @@
1/* Linux driver for Philips webcam
2 (C) 2004 Luc Saillard (luc@saillard.org)
3
4 NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx
5 driver and thus may have bugs that are not present in the original version.
6 Please send bug reports and support requests to <luc@saillard.org>.
7 The decompression routines have been implemented by reverse-engineering the
8 Nemosoft binary pwcx module. Caveat emptor.
9
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2 of the License, or
13 (at your option) any later version.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23*/
24
25
26/* This tables contains entries for the 730/740/750 (Kiara) camera, with
27 4 different qualities (no compression, low, medium, high).
28 It lists the bandwidth requirements for said mode by its alternate interface
29 number. An alternate of 0 means that the mode is unavailable.
30
31 There are 6 * 4 * 4 entries:
32 6 different resolutions subqcif, qsif, qcif, sif, cif, vga
33 6 framerates: 5, 10, 15, 20, 25, 30
34 4 compression modi: none, low, medium, high
35
36 When an uncompressed mode is not available, the next available compressed mode
37 will be chosen (unless the decompressor is absent). Sometimes there are only
38 1 or 2 compressed modes available; in that case entries are duplicated.
39*/
40
41
42#include "pwc-kiara.h"
43#include "pwc-uncompress.h"
44
45const struct Kiara_table_entry Kiara_table[PSZ_MAX][6][4] =
46{
47 /* SQCIF */
48 {
49 /* 5 fps */
50 {
51 {0, },
52 {0, },
53 {0, },
54 {0, },
55 },
56 /* 10 fps */
57 {
58 {0, },
59 {0, },
60 {0, },
61 {0, },
62 },
63 /* 15 fps */
64 {
65 {0, },
66 {0, },
67 {0, },
68 {0, },
69 },
70 /* 20 fps */
71 {
72 {0, },
73 {0, },
74 {0, },
75 {0, },
76 },
77 /* 25 fps */
78 {
79 {0, },
80 {0, },
81 {0, },
82 {0, },
83 },
84 /* 30 fps */
85 {
86 {0, },
87 {0, },
88 {0, },
89 {0, },
90 },
91 },
92 /* QSIF */
93 {
94 /* 5 fps */
95 {
96 {1, 146, 0, {0x1D, 0xF4, 0x30, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x92, 0x00, 0x80}},
97 {1, 146, 0, {0x1D, 0xF4, 0x30, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x92, 0x00, 0x80}},
98 {1, 146, 0, {0x1D, 0xF4, 0x30, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x92, 0x00, 0x80}},
99 {1, 146, 0, {0x1D, 0xF4, 0x30, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x92, 0x00, 0x80}},
100 },
101 /* 10 fps */
102 {
103 {2, 291, 0, {0x1C, 0xF4, 0x30, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x23, 0x01, 0x80}},
104 {1, 192, 630, {0x14, 0xF4, 0x30, 0x13, 0xA9, 0x12, 0xE1, 0x17, 0x08, 0xC0, 0x00, 0x80}},
105 {1, 192, 630, {0x14, 0xF4, 0x30, 0x13, 0xA9, 0x12, 0xE1, 0x17, 0x08, 0xC0, 0x00, 0x80}},
106 {1, 192, 630, {0x14, 0xF4, 0x30, 0x13, 0xA9, 0x12, 0xE1, 0x17, 0x08, 0xC0, 0x00, 0x80}},
107 },
108 /* 15 fps */
109 {
110 {3, 437, 0, {0x1B, 0xF4, 0x30, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0xB5, 0x01, 0x80}},
111 {2, 292, 640, {0x13, 0xF4, 0x30, 0x13, 0xF7, 0x13, 0x2F, 0x13, 0x20, 0x24, 0x01, 0x80}},
112 {2, 292, 640, {0x13, 0xF4, 0x30, 0x13, 0xF7, 0x13, 0x2F, 0x13, 0x20, 0x24, 0x01, 0x80}},
113 {1, 192, 420, {0x13, 0xF4, 0x30, 0x0D, 0x1B, 0x0C, 0x53, 0x1E, 0x18, 0xC0, 0x00, 0x80}},
114 },
115 /* 20 fps */
116 {
117 {4, 589, 0, {0x1A, 0xF4, 0x30, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x4D, 0x02, 0x80}},
118 {3, 448, 730, {0x12, 0xF4, 0x30, 0x16, 0xC9, 0x16, 0x01, 0x0E, 0x18, 0xC0, 0x01, 0x80}},
119 {2, 292, 476, {0x12, 0xF4, 0x30, 0x0E, 0xD8, 0x0E, 0x10, 0x19, 0x18, 0x24, 0x01, 0x80}},
120 {1, 192, 312, {0x12, 0xF4, 0x50, 0x09, 0xB3, 0x08, 0xEB, 0x1E, 0x18, 0xC0, 0x00, 0x80}},
121 },
122 /* 25 fps */
123 {
124 {5, 703, 0, {0x19, 0xF4, 0x30, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0xBF, 0x02, 0x80}},
125 {3, 447, 610, {0x11, 0xF4, 0x30, 0x13, 0x0B, 0x12, 0x43, 0x14, 0x28, 0xBF, 0x01, 0x80}},
126 {2, 292, 398, {0x11, 0xF4, 0x50, 0x0C, 0x6C, 0x0B, 0xA4, 0x1E, 0x28, 0x24, 0x01, 0x80}},
127 {1, 193, 262, {0x11, 0xF4, 0x50, 0x08, 0x23, 0x07, 0x5B, 0x1E, 0x28, 0xC1, 0x00, 0x80}},
128 },
129 /* 30 fps */
130 {
131 {8, 874, 0, {0x18, 0xF4, 0x30, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x6A, 0x03, 0x80}},
132 {5, 704, 730, {0x10, 0xF4, 0x30, 0x16, 0xC9, 0x16, 0x01, 0x0E, 0x28, 0xC0, 0x02, 0x80}},
133 {3, 448, 492, {0x10, 0xF4, 0x30, 0x0F, 0x5D, 0x0E, 0x95, 0x15, 0x28, 0xC0, 0x01, 0x80}},
134 {2, 292, 320, {0x10, 0xF4, 0x50, 0x09, 0xFB, 0x09, 0x33, 0x1E, 0x28, 0x24, 0x01, 0x80}},
135 },
136 },
137 /* QCIF */
138 {
139 /* 5 fps */
140 {
141 {0, },
142 {0, },
143 {0, },
144 {0, },
145 },
146 /* 10 fps */
147 {
148 {0, },
149 {0, },
150 {0, },
151 {0, },
152 },
153 /* 15 fps */
154 {
155 {0, },
156 {0, },
157 {0, },
158 {0, },
159 },
160 /* 20 fps */
161 {
162 {0, },
163 {0, },
164 {0, },
165 {0, },
166 },
167 /* 25 fps */
168 {
169 {0, },
170 {0, },
171 {0, },
172 {0, },
173 },
174 /* 30 fps */
175 {
176 {0, },
177 {0, },
178 {0, },
179 {0, },
180 },
181 },
182 /* SIF */
183 {
184 /* 5 fps */
185 {
186 {4, 582, 0, {0x0D, 0xF4, 0x30, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x46, 0x02, 0x80}},
187 {3, 387, 1276, {0x05, 0xF4, 0x30, 0x27, 0xD8, 0x26, 0x48, 0x03, 0x10, 0x83, 0x01, 0x80}},
188 {2, 291, 960, {0x05, 0xF4, 0x30, 0x1D, 0xF2, 0x1C, 0x62, 0x04, 0x10, 0x23, 0x01, 0x80}},
189 {1, 191, 630, {0x05, 0xF4, 0x50, 0x13, 0xA9, 0x12, 0x19, 0x05, 0x18, 0xBF, 0x00, 0x80}},
190 },
191 /* 10 fps */
192 {
193 {0, },
194 {6, 775, 1278, {0x04, 0xF4, 0x30, 0x27, 0xE8, 0x26, 0x58, 0x05, 0x30, 0x07, 0x03, 0x80}},
195 {3, 447, 736, {0x04, 0xF4, 0x30, 0x16, 0xFB, 0x15, 0x6B, 0x05, 0x28, 0xBF, 0x01, 0x80}},
196 {2, 292, 480, {0x04, 0xF4, 0x70, 0x0E, 0xF9, 0x0D, 0x69, 0x09, 0x28, 0x24, 0x01, 0x80}},
197 },
198 /* 15 fps */
199 {
200 {0, },
201 {9, 955, 1050, {0x03, 0xF4, 0x30, 0x20, 0xCF, 0x1F, 0x3F, 0x06, 0x48, 0xBB, 0x03, 0x80}},
202 {4, 592, 650, {0x03, 0xF4, 0x30, 0x14, 0x44, 0x12, 0xB4, 0x08, 0x30, 0x50, 0x02, 0x80}},
203 {3, 448, 492, {0x03, 0xF4, 0x50, 0x0F, 0x52, 0x0D, 0xC2, 0x09, 0x38, 0xC0, 0x01, 0x80}},
204 },
205 /* 20 fps */
206 {
207 {0, },
208 {9, 958, 782, {0x02, 0xF4, 0x30, 0x18, 0x6A, 0x16, 0xDA, 0x0B, 0x58, 0xBE, 0x03, 0x80}},
209 {5, 703, 574, {0x02, 0xF4, 0x50, 0x11, 0xE7, 0x10, 0x57, 0x0B, 0x40, 0xBF, 0x02, 0x80}},
210 {3, 446, 364, {0x02, 0xF4, 0x90, 0x0B, 0x5C, 0x09, 0xCC, 0x0E, 0x38, 0xBE, 0x01, 0x80}},
211 },
212 /* 25 fps */
213 {
214 {0, },
215 {9, 958, 654, {0x01, 0xF4, 0x30, 0x14, 0x66, 0x12, 0xD6, 0x0B, 0x50, 0xBE, 0x03, 0x80}},
216 {6, 776, 530, {0x01, 0xF4, 0x50, 0x10, 0x8C, 0x0E, 0xFC, 0x0C, 0x48, 0x08, 0x03, 0x80}},
217 {4, 592, 404, {0x01, 0xF4, 0x70, 0x0C, 0x96, 0x0B, 0x06, 0x0B, 0x48, 0x50, 0x02, 0x80}},
218 },
219 /* 30 fps */
220 {
221 {0, },
222 {9, 957, 526, {0x00, 0xF4, 0x50, 0x10, 0x68, 0x0E, 0xD8, 0x0D, 0x58, 0xBD, 0x03, 0x80}},
223 {6, 775, 426, {0x00, 0xF4, 0x70, 0x0D, 0x48, 0x0B, 0xB8, 0x0F, 0x50, 0x07, 0x03, 0x80}},
224 {4, 590, 324, {0x00, 0x7A, 0x88, 0x0A, 0x1C, 0x08, 0xB4, 0x0E, 0x50, 0x4E, 0x02, 0x80}},
225 },
226 },
227 /* CIF */
228 {
229 /* 5 fps */
230 {
231 {0, },
232 {0, },
233 {0, },
234 {0, },
235 },
236 /* 10 fps */
237 {
238 {0, },
239 {0, },
240 {0, },
241 {0, },
242 },
243 /* 15 fps */
244 {
245 {0, },
246 {0, },
247 {0, },
248 {0, },
249 },
250 /* 20 fps */
251 {
252 {0, },
253 {0, },
254 {0, },
255 {0, },
256 },
257 /* 25 fps */
258 {
259 {0, },
260 {0, },
261 {0, },
262 {0, },
263 },
264 /* 30 fps */
265 {
266 {0, },
267 {0, },
268 {0, },
269 {0, },
270 },
271 },
272 /* VGA */
273 {
274 /* 5 fps */
275 {
276 {0, },
277 {6, 773, 1272, {0x25, 0xF4, 0x30, 0x27, 0xB6, 0x24, 0x96, 0x02, 0x30, 0x05, 0x03, 0x80}},
278 {4, 592, 976, {0x25, 0xF4, 0x50, 0x1E, 0x78, 0x1B, 0x58, 0x03, 0x30, 0x50, 0x02, 0x80}},
279 {3, 448, 738, {0x25, 0xF4, 0x90, 0x17, 0x0C, 0x13, 0xEC, 0x04, 0x30, 0xC0, 0x01, 0x80}},
280 },
281 /* 10 fps */
282 {
283 {0, },
284 {9, 956, 788, {0x24, 0xF4, 0x70, 0x18, 0x9C, 0x15, 0x7C, 0x03, 0x48, 0xBC, 0x03, 0x80}},
285 {6, 776, 640, {0x24, 0xF4, 0xB0, 0x13, 0xFC, 0x11, 0x2C, 0x04, 0x48, 0x08, 0x03, 0x80}},
286 {4, 592, 488, {0x24, 0x7A, 0xE8, 0x0F, 0x3C, 0x0C, 0x6C, 0x06, 0x48, 0x50, 0x02, 0x80}},
287 },
288 /* 15 fps */
289 {
290 {0, },
291 {9, 957, 526, {0x23, 0x7A, 0xE8, 0x10, 0x68, 0x0D, 0x98, 0x06, 0x58, 0xBD, 0x03, 0x80}},
292 {9, 957, 526, {0x23, 0x7A, 0xE8, 0x10, 0x68, 0x0D, 0x98, 0x06, 0x58, 0xBD, 0x03, 0x80}},
293 {8, 895, 492, {0x23, 0x7A, 0xE8, 0x0F, 0x5D, 0x0C, 0x8D, 0x06, 0x58, 0x7F, 0x03, 0x80}},
294 },
295 /* 20 fps */
296 {
297 {0, },
298 {0, },
299 {0, },
300 {0, },
301 },
302 /* 25 fps */
303 {
304 {0, },
305 {0, },
306 {0, },
307 {0, },
308 },
309 /* 30 fps */
310 {
311 {0, },
312 {0, },
313 {0, },
314 {0, },
315 },
316 },
317};
318
319
320/*
321 * Rom table for kiara chips
322 *
323 * 32 roms tables (one for each resolution ?)
324 * 2 tables per roms (one for each passes) (Y, and U&V)
325 * 128 bytes per passes
326 */
327
328const unsigned int KiaraRomTable [8][2][16][8] =
329{
330 { /* version 0 */
331 { /* version 0, passes 0 */
332 {0x00000000,0x00000000,0x00000000,0x00000000,
333 0x00000000,0x00000000,0x00000001,0x00000001},
334 {0x00000000,0x00000000,0x00000009,0x00000009,
335 0x00000009,0x00000009,0x00000009,0x00000009},
336 {0x00000000,0x00000000,0x00000009,0x00000049,
337 0x00000049,0x00000049,0x00000049,0x00000049},
338 {0x00000000,0x00000000,0x00000049,0x00000049,
339 0x00000049,0x00000249,0x0000024a,0x00000049},
340 {0x00000000,0x00000000,0x00000049,0x00000049,
341 0x00000249,0x00000249,0x0000024a,0x0000024a},
342 {0x00000000,0x00000000,0x00000049,0x00000249,
343 0x00000249,0x0000124a,0x0000024a,0x0000024a},
344 {0x00000000,0x00000000,0x00000049,0x00000249,
345 0x0000124a,0x00009252,0x00001252,0x00001252},
346 {0x00000000,0x00000000,0x00000249,0x00000249,
347 0x00009252,0x00009292,0x00009292,0x00009292},
348 {0x00000000,0x00000000,0x00000249,0x00001249,
349 0x00009292,0x00009292,0x00009493,0x000124db},
350 {0x00000000,0x00000000,0x00000249,0x0000924a,
351 0x00009492,0x0000a49b,0x0000a49b,0x000124db},
352 {0x00000000,0x00000000,0x00001249,0x00009252,
353 0x0000a493,0x000124db,0x000124db,0x000126dc},
354 {0x00000000,0x00000000,0x00001249,0x00009493,
355 0x000124db,0x000126dc,0x000136e4,0x000126dc},
356 {0x00000000,0x00000000,0x00009292,0x0000a49b,
357 0x000124db,0x000136e4,0x000136e4,0x000136e4},
358 {0x00000000,0x00000000,0x00009292,0x0000a49b,
359 0x000126dc,0x0001b724,0x0001b92d,0x0001b925},
360 {0x00000000,0x00000000,0x00009492,0x000124db,
361 0x000136e4,0x0001b925,0x0001c96e,0x0001c92d},
362 {0x00000000,0x00000000,0x00000000,0x00000000,
363 0x00000000,0x00000000,0x00000000,0x00000000}
364 },
365 { /* version 0, passes 1 */
366 {0x00000000,0x00000000,0x00000000,0x00000000,
367 0x00000000,0x00000000,0x00000000,0x00000000},
368 {0x00000000,0x00000000,0x00000000,0x00000000,
369 0x00000000,0x00000000,0x00000000,0x00000000},
370 {0x00000000,0x00000000,0x00000001,0x00000009,
371 0x00000009,0x00000009,0x00000009,0x00000001},
372 {0x00000000,0x00000000,0x00000009,0x00000009,
373 0x00000049,0x00000049,0x00000049,0x00000049},
374 {0x00000000,0x00000000,0x00000049,0x00000049,
375 0x00000049,0x00000049,0x0000024a,0x0000024a},
376 {0x00000000,0x00000000,0x00000049,0x00000049,
377 0x00000249,0x00000249,0x0000024a,0x0000024a},
378 {0x00000000,0x00000000,0x00000049,0x00000249,
379 0x00000249,0x00000249,0x0000024a,0x00001252},
380 {0x00000000,0x00000000,0x00000049,0x00001249,
381 0x0000124a,0x0000124a,0x00001252,0x00009292},
382 {0x00000000,0x00000000,0x00000249,0x00001249,
383 0x00009252,0x00009252,0x00009292,0x00009493},
384 {0x00000000,0x00000000,0x00000249,0x0000924a,
385 0x00009292,0x00009292,0x00009292,0x00009493},
386 {0x00000000,0x00000000,0x00000249,0x00009292,
387 0x00009492,0x00009493,0x0000a49b,0x00009493},
388 {0x00000000,0x00000000,0x00001249,0x00009292,
389 0x0000a493,0x000124db,0x000126dc,0x000126dc},
390 {0x00000000,0x00000000,0x0000924a,0x00009493,
391 0x0000a493,0x000126dc,0x000136e4,0x000136e4},
392 {0x00000000,0x00000000,0x00009252,0x00009493,
393 0x000126dc,0x000126dc,0x000136e4,0x000136e4},
394 {0x00000000,0x00000000,0x00009292,0x0000a49b,
395 0x000136e4,0x000136e4,0x0001b725,0x0001b724},
396 {0x00000000,0x00000000,0x00000000,0x00000000,
397 0x00000000,0x00000000,0x00000000,0x00000000}
398 }
399 },
400 { /* version 1 */
401 { /* version 1, passes 0 */
402 {0x00000000,0x00000000,0x00000000,0x00000000,
403 0x00000000,0x00000000,0x00000000,0x00000001},
404 {0x00000000,0x00000000,0x00000009,0x00000009,
405 0x00000009,0x00000009,0x00000009,0x00000009},
406 {0x00000000,0x00000000,0x00000049,0x00000049,
407 0x00000049,0x00000049,0x00000049,0x00000049},
408 {0x00000000,0x00000000,0x00000049,0x00000049,
409 0x00000049,0x00000249,0x0000024a,0x0000024a},
410 {0x00000000,0x00000000,0x00000049,0x00000249,
411 0x00000249,0x00000249,0x0000024a,0x00001252},
412 {0x00000000,0x00000000,0x00000249,0x00000249,
413 0x00000249,0x0000124a,0x00001252,0x00001252},
414 {0x00000000,0x00000000,0x00000249,0x00000249,
415 0x0000124a,0x0000124a,0x00009292,0x00009292},
416 {0x00000000,0x00000000,0x00000249,0x00001249,
417 0x0000124a,0x00009252,0x00009292,0x00009292},
418 {0x00000000,0x00000000,0x00000249,0x00001249,
419 0x00009252,0x00009292,0x00009292,0x00009292},
420 {0x00000000,0x00000000,0x00000249,0x00001249,
421 0x00009252,0x00009292,0x00009493,0x00009493},
422 {0x00000000,0x00000000,0x00000249,0x0000924a,
423 0x00009252,0x00009493,0x00009493,0x00009493},
424 {0x00000000,0x00000000,0x00000249,0x0000924a,
425 0x00009292,0x00009493,0x00009493,0x00009493},
426 {0x00000000,0x00000000,0x00000249,0x00009252,
427 0x00009492,0x00009493,0x0000a49b,0x0000a49b},
428 {0x00000000,0x00000000,0x00001249,0x00009292,
429 0x00009492,0x000124db,0x000124db,0x000124db},
430 {0x00000000,0x00000000,0x0000924a,0x00009493,
431 0x0000a493,0x000126dc,0x000126dc,0x000126dc},
432 {0x00000000,0x00000000,0x00000000,0x00000000,
433 0x00000000,0x00000000,0x00000000,0x00000000}
434 },
435 { /* version 1, passes 1 */
436 {0x00000000,0x00000000,0x00000000,0x00000000,
437 0x00000000,0x00000000,0x00000000,0x00000000},
438 {0x00000000,0x00000000,0x00000049,0x00000009,
439 0x00000049,0x00000009,0x00000001,0x00000000},
440 {0x00000000,0x00000000,0x00000049,0x00000049,
441 0x00000049,0x00000049,0x00000049,0x00000000},
442 {0x00000000,0x00000000,0x00000249,0x00000049,
443 0x00000249,0x00000049,0x0000024a,0x00000001},
444 {0x00000000,0x00000000,0x00000249,0x00000249,
445 0x00000249,0x00000249,0x0000024a,0x00000001},
446 {0x00000000,0x00000000,0x00000249,0x00000249,
447 0x00000249,0x00000249,0x0000024a,0x00000001},
448 {0x00000000,0x00000000,0x00000249,0x00000249,
449 0x00000249,0x00000249,0x0000024a,0x00000009},
450 {0x00000000,0x00000000,0x00000249,0x00000249,
451 0x0000124a,0x0000124a,0x0000024a,0x00000009},
452 {0x00000000,0x00000000,0x00000249,0x00000249,
453 0x0000124a,0x0000124a,0x0000024a,0x00000009},
454 {0x00000000,0x00000000,0x00001249,0x00001249,
455 0x0000124a,0x00009252,0x00001252,0x00000049},
456 {0x00000000,0x00000000,0x00001249,0x00001249,
457 0x0000124a,0x00009292,0x00001252,0x00000049},
458 {0x00000000,0x00000000,0x00001249,0x00001249,
459 0x0000124a,0x00009292,0x00001252,0x00000049},
460 {0x00000000,0x00000000,0x00001249,0x00001249,
461 0x00009252,0x00009292,0x00001252,0x0000024a},
462 {0x00000000,0x00000000,0x00001249,0x00001249,
463 0x00009292,0x00009292,0x00001252,0x0000024a},
464 {0x00000000,0x00000000,0x0000924a,0x0000924a,
465 0x00009492,0x00009493,0x00009292,0x00001252},
466 {0x00000000,0x00000000,0x00000000,0x00000000,
467 0x00000000,0x00000000,0x00000000,0x00000000}
468 }
469 },
470 { /* version 2 */
471 { /* version 2, passes 0 */
472 {0x00000000,0x00000000,0x00000049,0x00000049,
473 0x00000049,0x00000049,0x0000024a,0x0000024a},
474 {0x00000000,0x00000000,0x00000249,0x00000249,
475 0x00000249,0x0000124a,0x00001252,0x00009292},
476 {0x00000000,0x00000000,0x00000249,0x00000249,
477 0x0000124a,0x00009252,0x00009292,0x00009292},
478 {0x00000000,0x00000000,0x00000249,0x00001249,
479 0x0000124a,0x00009292,0x00009493,0x00009493},
480 {0x00000000,0x00000000,0x00000249,0x00001249,
481 0x00009252,0x00009493,0x00009493,0x0000a49b},
482 {0x00000000,0x00000000,0x00000249,0x0000924a,
483 0x00009292,0x00009493,0x0000a49b,0x0000a49b},
484 {0x00000000,0x00000000,0x00001249,0x0000924a,
485 0x00009292,0x00009493,0x0000a49b,0x000124db},
486 {0x00000000,0x00000000,0x00001249,0x00009252,
487 0x00009492,0x0000a49b,0x0000a49b,0x000124db},
488 {0x00000000,0x00000000,0x00001249,0x00009292,
489 0x00009492,0x000124db,0x000124db,0x000126dc},
490 {0x00000000,0x00000000,0x00001249,0x00009292,
491 0x0000a493,0x000124db,0x000126dc,0x000126dc},
492 {0x00000000,0x00000000,0x00001249,0x00009493,
493 0x0000a493,0x000124db,0x000126dc,0x000136e4},
494 {0x00000000,0x00000000,0x00001249,0x00009493,
495 0x0000a493,0x000126dc,0x000136e4,0x000136e4},
496 {0x00000000,0x00000000,0x0000924a,0x00009493,
497 0x0001249b,0x000126dc,0x000136e4,0x000136e4},
498 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
499 0x000124db,0x000136e4,0x000136e4,0x0001b724},
500 {0x00000000,0x00000000,0x00009252,0x000124db,
501 0x000126dc,0x0001b724,0x0001b725,0x0001b925},
502 {0x00000000,0x00000000,0x00000000,0x00000000,
503 0x00000000,0x00000000,0x00000000,0x00000000}
504 },
505 { /* version 2, passes 1 */
506 {0x00000000,0x00000000,0x00000049,0x00000049,
507 0x00000049,0x00000049,0x00000049,0x00000049},
508 {0x00000000,0x00000000,0x00000249,0x00000249,
509 0x00000249,0x00000249,0x0000024a,0x00000049},
510 {0x00000000,0x00000000,0x00001249,0x00000249,
511 0x0000124a,0x0000124a,0x00001252,0x00000049},
512 {0x00000000,0x00000000,0x00001249,0x00001249,
513 0x0000124a,0x0000124a,0x00009292,0x0000024a},
514 {0x00000000,0x00000000,0x00001249,0x00001249,
515 0x00009252,0x00009292,0x00009292,0x0000024a},
516 {0x00000000,0x00000000,0x00001249,0x00001249,
517 0x00009252,0x00009292,0x0000a49b,0x0000024a},
518 {0x00000000,0x00000000,0x00001249,0x00001249,
519 0x00009292,0x00009493,0x0000a49b,0x00001252},
520 {0x00000000,0x00000000,0x00001249,0x00001249,
521 0x00009292,0x00009493,0x0000a49b,0x00001252},
522 {0x00000000,0x00000000,0x00001249,0x0000924a,
523 0x00009492,0x0000a49b,0x0000a49b,0x00001252},
524 {0x00000000,0x00000000,0x00001249,0x00009252,
525 0x00009492,0x0000a49b,0x0000a49b,0x00009292},
526 {0x00000000,0x00000000,0x00001249,0x00009292,
527 0x00009492,0x0000a49b,0x0000a49b,0x00009292},
528 {0x00000000,0x00000000,0x00001249,0x00009493,
529 0x0000a493,0x0000a49b,0x0000a49b,0x00009292},
530 {0x00000000,0x00000000,0x00001249,0x00009493,
531 0x0000a493,0x0000a49b,0x0000a49b,0x00009493},
532 {0x00000000,0x00000000,0x0000924a,0x00009493,
533 0x0000a493,0x000124db,0x0000a49b,0x00009493},
534 {0x00000000,0x00000000,0x00009252,0x0000a49b,
535 0x0001249b,0x000126dc,0x000124db,0x0000a49b},
536 {0x00000000,0x00000000,0x00000000,0x00000000,
537 0x00000000,0x00000000,0x00000000,0x00000000}
538 }
539 },
540 { /* version 3 */
541 { /* version 3, passes 0 */
542 {0x00000000,0x00000000,0x00000249,0x00000249,
543 0x0000124a,0x0000124a,0x00009292,0x00009292},
544 {0x00000000,0x00000000,0x00001249,0x00001249,
545 0x00009292,0x00009493,0x0000a49b,0x0000a49b},
546 {0x00000000,0x00000000,0x00001249,0x0000924a,
547 0x00009492,0x0000a49b,0x0000a49b,0x000124db},
548 {0x00000000,0x00000000,0x00001249,0x00009292,
549 0x00009492,0x000124db,0x000126dc,0x000126dc},
550 {0x00000000,0x00000000,0x00001249,0x00009493,
551 0x0000a493,0x000124db,0x000126dc,0x000126dc},
552 {0x00000000,0x00000000,0x00001249,0x00009493,
553 0x0000a493,0x000126dc,0x000136e4,0x000136e4},
554 {0x00000000,0x00000000,0x00001249,0x00009493,
555 0x0000a493,0x000126dc,0x000136e4,0x0001b724},
556 {0x00000000,0x00000000,0x00001249,0x00009493,
557 0x0001249b,0x000126dc,0x000136e4,0x0001b724},
558 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
559 0x0001249b,0x000126dc,0x000136e4,0x0001b724},
560 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
561 0x0001249b,0x000136e4,0x0001b725,0x0001b724},
562 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
563 0x000124db,0x000136e4,0x0001b725,0x0001b925},
564 {0x00000000,0x00000000,0x00009292,0x0000a49b,
565 0x000126dc,0x000136e4,0x0001b92d,0x0001b925},
566 {0x00000000,0x00000000,0x00009292,0x0000a49b,
567 0x000126dc,0x0001b724,0x0001b92d,0x0001c92d},
568 {0x00000000,0x00000000,0x00009492,0x000124db,
569 0x000126dc,0x0001b724,0x0001c96e,0x0001c92d},
570 {0x00000000,0x00000000,0x0000a492,0x000126db,
571 0x000136e4,0x0001b925,0x00025bb6,0x00024b77},
572 {0x00000000,0x00000000,0x00000000,0x00000000,
573 0x00000000,0x00000000,0x00000000,0x00000000}
574 },
575 { /* version 3, passes 1 */
576 {0x00000000,0x00000000,0x00001249,0x00000249,
577 0x0000124a,0x0000124a,0x00001252,0x00001252},
578 {0x00000000,0x00000000,0x00001249,0x00001249,
579 0x00009252,0x00009292,0x00009292,0x00001252},
580 {0x00000000,0x00000000,0x00001249,0x0000924a,
581 0x00009492,0x00009493,0x0000a49b,0x00001252},
582 {0x00000000,0x00000000,0x00001249,0x00009252,
583 0x00009492,0x0000a49b,0x0000a49b,0x00009292},
584 {0x00000000,0x00000000,0x00001249,0x00009292,
585 0x00009492,0x0000a49b,0x0000a49b,0x00009292},
586 {0x00000000,0x00000000,0x00001249,0x00009493,
587 0x0000a493,0x0000a49b,0x000126dc,0x00009292},
588 {0x00000000,0x00000000,0x0000924a,0x00009493,
589 0x0000a493,0x0000a49b,0x000126dc,0x00009493},
590 {0x00000000,0x00000000,0x0000924a,0x00009493,
591 0x0000a493,0x0000a49b,0x000126dc,0x00009493},
592 {0x00000000,0x00000000,0x0000924a,0x00009493,
593 0x0000a493,0x000124db,0x000126dc,0x00009493},
594 {0x00000000,0x00000000,0x0000924a,0x00009493,
595 0x0000a493,0x000124db,0x000126dc,0x0000a49b},
596 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
597 0x0000a493,0x000124db,0x000126dc,0x0000a49b},
598 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
599 0x0001249b,0x000126dc,0x000126dc,0x0000a49b},
600 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
601 0x000124db,0x000136e4,0x000126dc,0x000124db},
602 {0x00000000,0x00000000,0x00009492,0x0000a49b,
603 0x000136e4,0x000136e4,0x000126dc,0x000124db},
604 {0x00000000,0x00000000,0x0000a492,0x000124db,
605 0x0001b724,0x0001b724,0x000136e4,0x000126dc},
606 {0x00000000,0x00000000,0x00000000,0x00000000,
607 0x00000000,0x00000000,0x00000000,0x00000000}
608 }
609 },
610 { /* version 4 */
611 { /* version 4, passes 0 */
612 {0x00000000,0x00000000,0x00000049,0x00000049,
613 0x00000049,0x00000049,0x00000049,0x00000049},
614 {0x00000000,0x00000000,0x00000249,0x00000049,
615 0x00000249,0x00000249,0x0000024a,0x00000049},
616 {0x00000000,0x00000000,0x00000249,0x00000249,
617 0x0000124a,0x00009252,0x00001252,0x0000024a},
618 {0x00000000,0x00000000,0x00001249,0x00001249,
619 0x00009252,0x00009292,0x00009493,0x00001252},
620 {0x00000000,0x00000000,0x00001249,0x0000924a,
621 0x00009292,0x00009493,0x00009493,0x00001252},
622 {0x00000000,0x00000000,0x00001249,0x00009292,
623 0x00009492,0x0000a49b,0x0000a49b,0x00009292},
624 {0x00000000,0x00000000,0x00001249,0x00009493,
625 0x0000a493,0x000124db,0x000124db,0x00009493},
626 {0x00000000,0x00000000,0x0000924a,0x00009493,
627 0x0000a493,0x000124db,0x000126dc,0x0000a49b},
628 {0x00000000,0x00000000,0x0000924a,0x00009493,
629 0x0000a493,0x000124db,0x000126dc,0x0000a49b},
630 {0x00000000,0x00000000,0x0000924a,0x00009493,
631 0x0001249b,0x000126dc,0x000126dc,0x000124db},
632 {0x00000000,0x00000000,0x00009252,0x00009493,
633 0x000124db,0x000136e4,0x000136e4,0x000126dc},
634 {0x00000000,0x00000000,0x00009252,0x0000a49b,
635 0x000124db,0x000136e4,0x000136e4,0x000126dc},
636 {0x00000000,0x00000000,0x00009292,0x0000a49b,
637 0x000126dc,0x000136e4,0x000136e4,0x000136e4},
638 {0x00000000,0x00000000,0x00009492,0x0000a49b,
639 0x000126dc,0x0001b724,0x0001b725,0x0001b724},
640 {0x00000000,0x00000000,0x0000a492,0x000124db,
641 0x000136e4,0x0001b925,0x0001b92d,0x0001b925},
642 {0x00000000,0x00000000,0x00000000,0x00000000,
643 0x00000000,0x00000000,0x00000000,0x00000000}
644 },
645 { /* version 4, passes 1 */
646 {0x00000000,0x00000000,0x00000249,0x00000049,
647 0x00000009,0x00000009,0x00000009,0x00000009},
648 {0x00000000,0x00000000,0x00000249,0x00000249,
649 0x00000049,0x00000049,0x00000009,0x00000009},
650 {0x00000000,0x00000000,0x00001249,0x00001249,
651 0x0000124a,0x00000249,0x00000049,0x00000049},
652 {0x00000000,0x00000000,0x00001249,0x00001249,
653 0x0000124a,0x0000124a,0x00000049,0x00000049},
654 {0x00000000,0x00000000,0x00001249,0x00001249,
655 0x00009252,0x0000124a,0x0000024a,0x0000024a},
656 {0x00000000,0x00000000,0x00001249,0x0000924a,
657 0x00009252,0x0000124a,0x0000024a,0x0000024a},
658 {0x00000000,0x00000000,0x00001249,0x00009292,
659 0x00009492,0x00009252,0x00001252,0x00001252},
660 {0x00000000,0x00000000,0x00001249,0x00009493,
661 0x0000a493,0x00009292,0x00009292,0x00001252},
662 {0x00000000,0x00000000,0x0000924a,0x00009493,
663 0x0000a493,0x00009292,0x00009292,0x00009292},
664 {0x00000000,0x00000000,0x0000924a,0x00009493,
665 0x0000a493,0x00009493,0x00009493,0x00009292},
666 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
667 0x0000a493,0x0000a49b,0x00009493,0x00009493},
668 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
669 0x0000a493,0x0000a49b,0x0000a49b,0x00009493},
670 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
671 0x0001249b,0x000124db,0x0000a49b,0x0000a49b},
672 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
673 0x000136e4,0x000126dc,0x000124db,0x0000a49b},
674 {0x00000000,0x00000000,0x00009252,0x000124db,
675 0x0001b724,0x000136e4,0x000126dc,0x000124db},
676 {0x00000000,0x00000000,0x00000000,0x00000000,
677 0x00000000,0x00000000,0x00000000,0x00000000}
678 }
679 },
680 { /* version 5 */
681 { /* version 5, passes 0 */
682 {0x00000000,0x00000000,0x00000249,0x00000249,
683 0x00000249,0x00000249,0x00001252,0x00001252},
684 {0x00000000,0x00000000,0x00001249,0x00001249,
685 0x00009252,0x00009292,0x00009292,0x00001252},
686 {0x00000000,0x00000000,0x00001249,0x0000924a,
687 0x00009492,0x0000a49b,0x0000a49b,0x00009292},
688 {0x00000000,0x00000000,0x00001249,0x00009493,
689 0x0000a493,0x0000a49b,0x000124db,0x00009493},
690 {0x00000000,0x00000000,0x00001249,0x00009493,
691 0x0000a493,0x000124db,0x000126dc,0x00009493},
692 {0x00000000,0x00000000,0x0000924a,0x00009493,
693 0x0000a493,0x000126dc,0x000126dc,0x0000a49b},
694 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
695 0x0001249b,0x000126dc,0x000136e4,0x000124db},
696 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
697 0x000126dc,0x000136e4,0x000136e4,0x000126dc},
698 {0x00000000,0x00000000,0x00009292,0x0000a49b,
699 0x000126dc,0x000136e4,0x000136e4,0x000126dc},
700 {0x00000000,0x00000000,0x00009292,0x0000a49b,
701 0x000126dc,0x0001b724,0x0001b725,0x000136e4},
702 {0x00000000,0x00000000,0x00009292,0x0000a49b,
703 0x000136e4,0x0001b724,0x0001b92d,0x0001b724},
704 {0x00000000,0x00000000,0x00009492,0x0000a49b,
705 0x000136e4,0x0001b724,0x0001b92d,0x0001b724},
706 {0x00000000,0x00000000,0x00009492,0x000124db,
707 0x000136e4,0x0001b925,0x0001c96e,0x0001b925},
708 {0x00000000,0x00000000,0x00009492,0x000124db,
709 0x0001b724,0x0001b925,0x0001c96e,0x0001c92d},
710 {0x00000000,0x00000000,0x0000a492,0x000126db,
711 0x0001c924,0x0002496d,0x00025bb6,0x00024b77},
712 {0x00000000,0x00000000,0x00000000,0x00000000,
713 0x00000000,0x00000000,0x00000000,0x00000000}
714 },
715 { /* version 5, passes 1 */
716 {0x00000000,0x00000000,0x00001249,0x00000249,
717 0x00000249,0x00000249,0x0000024a,0x0000024a},
718 {0x00000000,0x00000000,0x00001249,0x00001249,
719 0x0000124a,0x0000124a,0x0000024a,0x0000024a},
720 {0x00000000,0x00000000,0x00001249,0x0000924a,
721 0x00009252,0x00009252,0x0000024a,0x0000024a},
722 {0x00000000,0x00000000,0x00001249,0x00009292,
723 0x00009492,0x0000a49b,0x00001252,0x00001252},
724 {0x00000000,0x00000000,0x0000924a,0x00009493,
725 0x0000a493,0x0000a49b,0x00001252,0x00001252},
726 {0x00000000,0x00000000,0x0000924a,0x00009493,
727 0x0000a493,0x0000a49b,0x00009292,0x00001252},
728 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
729 0x0000a493,0x0000a49b,0x00009292,0x00009292},
730 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
731 0x0000a493,0x0000a49b,0x00009493,0x00009292},
732 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
733 0x0001249b,0x000124db,0x00009493,0x00009292},
734 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
735 0x0001249b,0x000124db,0x00009493,0x00009493},
736 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
737 0x000124db,0x000124db,0x0000a49b,0x00009493},
738 {0x00000000,0x00000000,0x0000924a,0x000124db,
739 0x000126dc,0x000126dc,0x0000a49b,0x00009493},
740 {0x00000000,0x00000000,0x0000924a,0x000124db,
741 0x000136e4,0x000126dc,0x000124db,0x0000a49b},
742 {0x00000000,0x00000000,0x00009292,0x000124db,
743 0x000136e4,0x000126dc,0x000124db,0x0000a49b},
744 {0x00000000,0x00000000,0x00009492,0x000126db,
745 0x0001b724,0x000136e4,0x000126dc,0x000124db},
746 {0x00000000,0x00000000,0x00000000,0x00000000,
747 0x00000000,0x00000000,0x00000000,0x00000000}
748 }
749 },
750 { /* version 6 */
751 { /* version 6, passes 0 */
752 {0x00000000,0x00000000,0x00001249,0x00001249,
753 0x00009252,0x00009292,0x00009493,0x00009493},
754 {0x00000000,0x00000000,0x00001249,0x00009292,
755 0x0000a493,0x0000a49b,0x0000a49b,0x00009493},
756 {0x00000000,0x00000000,0x00001249,0x00009493,
757 0x0000a493,0x000124db,0x000124db,0x0000a49b},
758 {0x00000000,0x00000000,0x0000924a,0x00009493,
759 0x0000a493,0x000126dc,0x000126dc,0x0000a49b},
760 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
761 0x0001249b,0x000126dc,0x000136e4,0x000124db},
762 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
763 0x000126dc,0x000136e4,0x000136e4,0x000126dc},
764 {0x00000000,0x00000000,0x00009292,0x0000a49b,
765 0x000126dc,0x0001b724,0x0001b725,0x000126dc},
766 {0x00000000,0x00000000,0x00009292,0x0000a49b,
767 0x000136e4,0x0001b724,0x0001b92d,0x000136e4},
768 {0x00000000,0x00000000,0x00009492,0x0000a49b,
769 0x000136e4,0x0001b724,0x0001b92d,0x0001b724},
770 {0x00000000,0x00000000,0x00009492,0x000124db,
771 0x000136e4,0x0001b724,0x0001b92d,0x0001b724},
772 {0x00000000,0x00000000,0x00009492,0x000124db,
773 0x000136e4,0x0001b925,0x0001b92d,0x0001b925},
774 {0x00000000,0x00000000,0x00009492,0x000124db,
775 0x0001b724,0x0001b925,0x0001c96e,0x0001c92d},
776 {0x00000000,0x00000000,0x0000a492,0x000124db,
777 0x0001b724,0x0001c92d,0x0001c96e,0x0001c92d},
778 {0x00000000,0x00000000,0x0000a492,0x000124db,
779 0x0001b724,0x0001c92d,0x00024b76,0x0002496e},
780 {0x00000000,0x00000000,0x00012492,0x000126db,
781 0x0001c924,0x00024b6d,0x0002ddb6,0x00025bbf},
782 {0x00000000,0x00000000,0x00000000,0x00000000,
783 0x00000000,0x00000000,0x00000000,0x00000000}
784 },
785 { /* version 6, passes 1 */
786 {0x00000000,0x00000000,0x00001249,0x00001249,
787 0x0000124a,0x0000124a,0x00001252,0x00001252},
788 {0x00000000,0x00000000,0x00001249,0x00009292,
789 0x00009492,0x00009252,0x00001252,0x00001252},
790 {0x00000000,0x00000000,0x0000924a,0x00009493,
791 0x0000a493,0x00009292,0x00001252,0x00001252},
792 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
793 0x0000a493,0x0000a49b,0x00009292,0x00009292},
794 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
795 0x0000a493,0x0000a49b,0x00009292,0x00009292},
796 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
797 0x0001249b,0x0000a49b,0x00009493,0x00009292},
798 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
799 0x000124db,0x000124db,0x00009493,0x00009493},
800 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
801 0x000124db,0x000124db,0x0000a49b,0x00009493},
802 {0x00000000,0x00000000,0x0000924a,0x000124db,
803 0x000126dc,0x000124db,0x0000a49b,0x00009493},
804 {0x00000000,0x00000000,0x0000924a,0x000124db,
805 0x000126dc,0x000126dc,0x0000a49b,0x0000a49b},
806 {0x00000000,0x00000000,0x0000924a,0x000124db,
807 0x000136e4,0x000126dc,0x000124db,0x0000a49b},
808 {0x00000000,0x00000000,0x00009492,0x000126db,
809 0x000136e4,0x000126dc,0x000124db,0x0000a49b},
810 {0x00000000,0x00000000,0x00009492,0x000126db,
811 0x0001b724,0x000136e4,0x000126dc,0x000124db},
812 {0x00000000,0x00000000,0x00009492,0x000126db,
813 0x0001b724,0x000136e4,0x000126dc,0x000124db},
814 {0x00000000,0x00000000,0x0000a492,0x000136db,
815 0x0001c924,0x0001b724,0x000136e4,0x000126dc},
816 {0x00000000,0x00000000,0x00000000,0x00000000,
817 0x00000000,0x00000000,0x00000000,0x00000000}
818 }
819 },
820 { /* version 7 */
821 { /* version 7, passes 0 */
822 {0x00000000,0x00000000,0x00001249,0x00001249,
823 0x00009252,0x00009292,0x00009493,0x00009493},
824 {0x00000000,0x00000000,0x00001249,0x00009493,
825 0x0000a493,0x000124db,0x000126dc,0x00009493},
826 {0x00000000,0x00000000,0x00001249,0x0000a49b,
827 0x0001249b,0x000126dc,0x000126dc,0x0000a49b},
828 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
829 0x0001249b,0x000126dc,0x000136e4,0x0000a49b},
830 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
831 0x000126dc,0x000136e4,0x0001b725,0x000124db},
832 {0x00000000,0x00000000,0x00009292,0x0000a49b,
833 0x000136e4,0x0001b724,0x0001b725,0x000126dc},
834 {0x00000000,0x00000000,0x00009292,0x000124db,
835 0x000136e4,0x0001b724,0x0001b725,0x000126dc},
836 {0x00000000,0x00000000,0x00009492,0x000124db,
837 0x000136e4,0x0001b724,0x0001c96e,0x000136e4},
838 {0x00000000,0x00000000,0x00009492,0x000124db,
839 0x000136e4,0x0001c92d,0x0001c96e,0x0001b724},
840 {0x00000000,0x00000000,0x0000a492,0x000124db,
841 0x000136e4,0x0001c92d,0x0001c96e,0x0001b724},
842 {0x00000000,0x00000000,0x0000a492,0x000124db,
843 0x0001b724,0x0001c92d,0x0001c96e,0x0001b925},
844 {0x00000000,0x00000000,0x0000a492,0x000126db,
845 0x0001b724,0x0001c92d,0x00024b76,0x0001c92d},
846 {0x00000000,0x00000000,0x0000a492,0x000126db,
847 0x0001b924,0x0001c92d,0x00024b76,0x0001c92d},
848 {0x00000000,0x00000000,0x0000a492,0x000126db,
849 0x0001b924,0x0001c92d,0x00024b76,0x0002496e},
850 {0x00000000,0x00000000,0x00012492,0x000136db,
851 0x00024924,0x00024b6d,0x0002ddb6,0x00025bbf},
852 {0x00000000,0x00000000,0x00000000,0x00000000,
853 0x00000000,0x00000000,0x00000000,0x00000000}
854 },
855 { /* version 7, passes 1 */
856 {0x00000000,0x00000000,0x00001249,0x00001249,
857 0x0000124a,0x0000124a,0x00001252,0x00001252},
858 {0x00000000,0x00000000,0x0000924a,0x00009493,
859 0x00009492,0x00009292,0x00001252,0x00001252},
860 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
861 0x0000a493,0x0000a49b,0x00001252,0x00001252},
862 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
863 0x0000a493,0x0000a49b,0x00009292,0x00009292},
864 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
865 0x0000a493,0x0000a49b,0x00009292,0x00009292},
866 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
867 0x000126dc,0x0000a49b,0x00009493,0x00009292},
868 {0x00000000,0x00000000,0x0000924a,0x000124db,
869 0x000126dc,0x000124db,0x00009493,0x00009493},
870 {0x00000000,0x00000000,0x0000924a,0x000124db,
871 0x000136e4,0x000124db,0x0000a49b,0x00009493},
872 {0x00000000,0x00000000,0x0000924a,0x000136db,
873 0x0001b724,0x000124db,0x0000a49b,0x00009493},
874 {0x00000000,0x00000000,0x0000924a,0x000136db,
875 0x0001b724,0x000126dc,0x0000a49b,0x0000a49b},
876 {0x00000000,0x00000000,0x00009292,0x000136db,
877 0x0001b724,0x000126dc,0x000124db,0x0000a49b},
878 {0x00000000,0x00000000,0x00009492,0x000136db,
879 0x0001b724,0x000126dc,0x000124db,0x0000a49b},
880 {0x00000000,0x00000000,0x0000a492,0x000136db,
881 0x0001b724,0x000136e4,0x000126dc,0x000124db},
882 {0x00000000,0x00000000,0x0000a492,0x000136db,
883 0x0001b724,0x000136e4,0x000126dc,0x000124db},
884 {0x00000000,0x00000000,0x00012492,0x0001b6db,
885 0x0001c924,0x0001b724,0x000136e4,0x000126dc},
886 {0x00000000,0x00000000,0x00000000,0x00000000,
887 0x00000000,0x00000000,0x00000000,0x00000000}
888 }
889 }
890};
891
diff --git a/drivers/usb/media/pwc/pwc-kiara.h b/drivers/usb/media/pwc/pwc-kiara.h
new file mode 100644
index 000000000000..12929abbb1f0
--- /dev/null
+++ b/drivers/usb/media/pwc/pwc-kiara.h
@@ -0,0 +1,45 @@
1/* Linux driver for Philips webcam
2 (C) 2004 Luc Saillard (luc@saillard.org)
3
4 NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx
5 driver and thus may have bugs that are not present in the original version.
6 Please send bug reports and support requests to <luc@saillard.org>.
7 The decompression routines have been implemented by reverse-engineering the
8 Nemosoft binary pwcx module. Caveat emptor.
9
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2 of the License, or
13 (at your option) any later version.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23*/
24
25/* Entries for the Kiara (730/740/750) camera */
26
27#ifndef PWC_KIARA_H
28#define PWC_KIARA_H
29
30#include "pwc-ioctl.h"
31
32struct Kiara_table_entry
33{
34 char alternate; /* USB alternate interface */
35 unsigned short packetsize; /* Normal packet size */
36 unsigned short bandlength; /* Bandlength when decompressing */
37 unsigned char mode[12]; /* precomputed mode settings for cam */
38};
39
40const extern struct Kiara_table_entry Kiara_table[PSZ_MAX][6][4];
41const extern unsigned int KiaraRomTable[8][2][16][8];
42
43#endif
44
45
diff --git a/drivers/usb/media/pwc/pwc-misc.c b/drivers/usb/media/pwc/pwc-misc.c
new file mode 100644
index 000000000000..b7a4bd3524c7
--- /dev/null
+++ b/drivers/usb/media/pwc/pwc-misc.c
@@ -0,0 +1,140 @@
1/* Linux driver for Philips webcam
2 Various miscellaneous functions and tables.
3 (C) 1999-2003 Nemosoft Unv.
4 (C) 2004 Luc Saillard (luc@saillard.org)
5
6 NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx
7 driver and thus may have bugs that are not present in the original version.
8 Please send bug reports and support requests to <luc@saillard.org>.
9 The decompression routines have been implemented by reverse-engineering the
10 Nemosoft binary pwcx module. Caveat emptor.
11
12 This program is free software; you can redistribute it and/or modify
13 it under the terms of the GNU General Public License as published by
14 the Free Software Foundation; either version 2 of the License, or
15 (at your option) any later version.
16
17 This program is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 GNU General Public License for more details.
21
22 You should have received a copy of the GNU General Public License
23 along with this program; if not, write to the Free Software
24 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25*/
26
27#include <linux/slab.h>
28
29#include "pwc.h"
30
31struct pwc_coord pwc_image_sizes[PSZ_MAX] =
32{
33 { 128, 96, 0 },
34 { 160, 120, 0 },
35 { 176, 144, 0 },
36 { 320, 240, 0 },
37 { 352, 288, 0 },
38 { 640, 480, 0 },
39};
40
41/* x,y -> PSZ_ */
42int pwc_decode_size(struct pwc_device *pdev, int width, int height)
43{
44 int i, find;
45
46 /* Make sure we don't go beyond our max size.
47 NB: we have different limits for RAW and normal modes. In case
48 you don't have the decompressor loaded or use RAW mode,
49 the maximum viewable size is smaller.
50 */
51 if (pdev->vpalette == VIDEO_PALETTE_RAW)
52 {
53 if (width > pdev->abs_max.x || height > pdev->abs_max.y)
54 {
55 Debug("VIDEO_PALETTE_RAW: going beyond abs_max.\n");
56 return -1;
57 }
58 }
59 else
60 {
61 if (width > pdev->view_max.x || height > pdev->view_max.y)
62 {
63 Debug("VIDEO_PALETTE_ not RAW: going beyond view_max.\n");
64 return -1;
65 }
66 }
67
68 /* Find the largest size supported by the camera that fits into the
69 requested size.
70 */
71 find = -1;
72 for (i = 0; i < PSZ_MAX; i++) {
73 if (pdev->image_mask & (1 << i)) {
74 if (pwc_image_sizes[i].x <= width && pwc_image_sizes[i].y <= height)
75 find = i;
76 }
77 }
78 return find;
79}
80
81/* initialize variables depending on type and decompressor*/
82void pwc_construct(struct pwc_device *pdev)
83{
84 switch(pdev->type) {
85 case 645:
86 case 646:
87 pdev->view_min.x = 128;
88 pdev->view_min.y = 96;
89 pdev->view_max.x = 352;
90 pdev->view_max.y = 288;
91 pdev->abs_max.x = 352;
92 pdev->abs_max.y = 288;
93 pdev->image_mask = 1 << PSZ_SQCIF | 1 << PSZ_QCIF | 1 << PSZ_CIF;
94 pdev->vcinterface = 2;
95 pdev->vendpoint = 4;
96 pdev->frame_header_size = 0;
97 pdev->frame_trailer_size = 0;
98 break;
99 case 675:
100 case 680:
101 case 690:
102 pdev->view_min.x = 128;
103 pdev->view_min.y = 96;
104 /* Anthill bug #38: PWC always reports max size, even without PWCX */
105 pdev->view_max.x = 640;
106 pdev->view_max.y = 480;
107 pdev->image_mask = 1 << PSZ_SQCIF | 1 << PSZ_QSIF | 1 << PSZ_QCIF | 1 << PSZ_SIF | 1 << PSZ_CIF | 1 << PSZ_VGA;
108 pdev->abs_max.x = 640;
109 pdev->abs_max.y = 480;
110 pdev->vcinterface = 3;
111 pdev->vendpoint = 4;
112 pdev->frame_header_size = 0;
113 pdev->frame_trailer_size = 0;
114 break;
115 case 720:
116 case 730:
117 case 740:
118 case 750:
119 pdev->view_min.x = 160;
120 pdev->view_min.y = 120;
121 pdev->view_max.x = 640;
122 pdev->view_max.y = 480;
123 pdev->image_mask = 1 << PSZ_QSIF | 1 << PSZ_SIF | 1 << PSZ_VGA;
124 pdev->abs_max.x = 640;
125 pdev->abs_max.y = 480;
126 pdev->vcinterface = 3;
127 pdev->vendpoint = 5;
128 pdev->frame_header_size = TOUCAM_HEADER_SIZE;
129 pdev->frame_trailer_size = TOUCAM_TRAILER_SIZE;
130 break;
131 }
132 Debug("type = %d\n",pdev->type);
133 pdev->vpalette = VIDEO_PALETTE_YUV420P; /* default */
134 pdev->view_min.size = pdev->view_min.x * pdev->view_min.y;
135 pdev->view_max.size = pdev->view_max.x * pdev->view_max.y;
136 /* length of image, in YUV format; always allocate enough memory. */
137 pdev->len_per_image = (pdev->abs_max.x * pdev->abs_max.y * 3) / 2;
138}
139
140
diff --git a/drivers/usb/media/pwc/pwc-nala.h b/drivers/usb/media/pwc/pwc-nala.h
new file mode 100644
index 000000000000..e6c5cb69d03b
--- /dev/null
+++ b/drivers/usb/media/pwc/pwc-nala.h
@@ -0,0 +1,66 @@
1 /* SQCIF */
2 {
3 {0, 0, {0x04, 0x01, 0x03}},
4 {8, 0, {0x05, 0x01, 0x03}},
5 {7, 0, {0x08, 0x01, 0x03}},
6 {7, 0, {0x0A, 0x01, 0x03}},
7 {6, 0, {0x0C, 0x01, 0x03}},
8 {5, 0, {0x0F, 0x01, 0x03}},
9 {4, 0, {0x14, 0x01, 0x03}},
10 {3, 0, {0x18, 0x01, 0x03}},
11 },
12 /* QSIF */
13 {
14 {0},
15 {0},
16 {0},
17 {0},
18 {0},
19 {0},
20 {0},
21 {0},
22 },
23 /* QCIF */
24 {
25 {0, 0, {0x04, 0x01, 0x02}},
26 {8, 0, {0x05, 0x01, 0x02}},
27 {7, 0, {0x08, 0x01, 0x02}},
28 {6, 0, {0x0A, 0x01, 0x02}},
29 {5, 0, {0x0C, 0x01, 0x02}},
30 {4, 0, {0x0F, 0x01, 0x02}},
31 {1, 0, {0x14, 0x01, 0x02}},
32 {1, 0, {0x18, 0x01, 0x02}},
33 },
34 /* SIF */
35 {
36 {0},
37 {0},
38 {0},
39 {0},
40 {0},
41 {0},
42 {0},
43 {0},
44 },
45 /* CIF */
46 {
47 {4, 0, {0x04, 0x01, 0x01}},
48 {7, 1, {0x05, 0x03, 0x01}},
49 {6, 1, {0x08, 0x03, 0x01}},
50 {4, 1, {0x0A, 0x03, 0x01}},
51 {3, 1, {0x0C, 0x03, 0x01}},
52 {2, 1, {0x0F, 0x03, 0x01}},
53 {0},
54 {0},
55 },
56 /* VGA */
57 {
58 {0},
59 {0},
60 {0},
61 {0},
62 {0},
63 {0},
64 {0},
65 {0},
66 },
diff --git a/drivers/usb/media/pwc/pwc-timon.c b/drivers/usb/media/pwc/pwc-timon.c
new file mode 100644
index 000000000000..f950a4e5ed96
--- /dev/null
+++ b/drivers/usb/media/pwc/pwc-timon.c
@@ -0,0 +1,1446 @@
1/* Linux driver for Philips webcam
2 (C) 2004 Luc Saillard (luc@saillard.org)
3
4 NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx
5 driver and thus may have bugs that are not present in the original version.
6 Please send bug reports and support requests to <luc@saillard.org>.
7 The decompression routines have been implemented by reverse-engineering the
8 Nemosoft binary pwcx module. Caveat emptor.
9
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2 of the License, or
13 (at your option) any later version.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23*/
24
25
26/* This tables contains entries for the 675/680/690 (Timon) camera, with
27 4 different qualities (no compression, low, medium, high).
28 It lists the bandwidth requirements for said mode by its alternate interface
29 number. An alternate of 0 means that the mode is unavailable.
30
31 There are 6 * 4 * 4 entries:
32 6 different resolutions subqcif, qsif, qcif, sif, cif, vga
33 6 framerates: 5, 10, 15, 20, 25, 30
34 4 compression modi: none, low, medium, high
35
36 When an uncompressed mode is not available, the next available compressed mode
37 will be chosen (unless the decompressor is absent). Sometimes there are only
38 1 or 2 compressed modes available; in that case entries are duplicated.
39*/
40
41#include "pwc-timon.h"
42
43const struct Timon_table_entry Timon_table[PSZ_MAX][6][4] =
44{
45 /* SQCIF */
46 {
47 /* 5 fps */
48 {
49 {1, 140, 0, {0x05, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x8C, 0xFC, 0x80, 0x02}},
50 {1, 140, 0, {0x05, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x8C, 0xFC, 0x80, 0x02}},
51 {1, 140, 0, {0x05, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x8C, 0xFC, 0x80, 0x02}},
52 {1, 140, 0, {0x05, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x8C, 0xFC, 0x80, 0x02}},
53 },
54 /* 10 fps */
55 {
56 {2, 280, 0, {0x04, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x18, 0xA9, 0x80, 0x02}},
57 {2, 280, 0, {0x04, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x18, 0xA9, 0x80, 0x02}},
58 {2, 280, 0, {0x04, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x18, 0xA9, 0x80, 0x02}},
59 {2, 280, 0, {0x04, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x18, 0xA9, 0x80, 0x02}},
60 },
61 /* 15 fps */
62 {
63 {3, 410, 0, {0x03, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x9A, 0x71, 0x80, 0x02}},
64 {3, 410, 0, {0x03, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x9A, 0x71, 0x80, 0x02}},
65 {3, 410, 0, {0x03, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x9A, 0x71, 0x80, 0x02}},
66 {3, 410, 0, {0x03, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x9A, 0x71, 0x80, 0x02}},
67 },
68 /* 20 fps */
69 {
70 {4, 559, 0, {0x02, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x2F, 0x56, 0x80, 0x02}},
71 {4, 559, 0, {0x02, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x2F, 0x56, 0x80, 0x02}},
72 {4, 559, 0, {0x02, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x2F, 0x56, 0x80, 0x02}},
73 {4, 559, 0, {0x02, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x2F, 0x56, 0x80, 0x02}},
74 },
75 /* 25 fps */
76 {
77 {5, 659, 0, {0x01, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x93, 0x46, 0x80, 0x02}},
78 {5, 659, 0, {0x01, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x93, 0x46, 0x80, 0x02}},
79 {5, 659, 0, {0x01, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x93, 0x46, 0x80, 0x02}},
80 {5, 659, 0, {0x01, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x93, 0x46, 0x80, 0x02}},
81 },
82 /* 30 fps */
83 {
84 {7, 838, 0, {0x00, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x46, 0x3B, 0x80, 0x02}},
85 {7, 838, 0, {0x00, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x46, 0x3B, 0x80, 0x02}},
86 {7, 838, 0, {0x00, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x46, 0x3B, 0x80, 0x02}},
87 {7, 838, 0, {0x00, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x46, 0x3B, 0x80, 0x02}},
88 },
89 },
90 /* QSIF */
91 {
92 /* 5 fps */
93 {
94 {1, 146, 0, {0x2D, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x92, 0xFC, 0xC0, 0x02}},
95 {1, 146, 0, {0x2D, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x92, 0xFC, 0xC0, 0x02}},
96 {1, 146, 0, {0x2D, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x92, 0xFC, 0xC0, 0x02}},
97 {1, 146, 0, {0x2D, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x92, 0xFC, 0xC0, 0x02}},
98 },
99 /* 10 fps */
100 {
101 {2, 291, 0, {0x2C, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x23, 0xA1, 0xC0, 0x02}},
102 {1, 191, 630, {0x2C, 0xF4, 0x05, 0x13, 0xA9, 0x12, 0xE1, 0x17, 0x08, 0xBF, 0xF4, 0xC0, 0x02}},
103 {1, 191, 630, {0x2C, 0xF4, 0x05, 0x13, 0xA9, 0x12, 0xE1, 0x17, 0x08, 0xBF, 0xF4, 0xC0, 0x02}},
104 {1, 191, 630, {0x2C, 0xF4, 0x05, 0x13, 0xA9, 0x12, 0xE1, 0x17, 0x08, 0xBF, 0xF4, 0xC0, 0x02}},
105 },
106 /* 15 fps */
107 {
108 {3, 437, 0, {0x2B, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0xB5, 0x6D, 0xC0, 0x02}},
109 {2, 291, 640, {0x2B, 0xF4, 0x05, 0x13, 0xF7, 0x13, 0x2F, 0x13, 0x08, 0x23, 0xA1, 0xC0, 0x02}},
110 {2, 291, 640, {0x2B, 0xF4, 0x05, 0x13, 0xF7, 0x13, 0x2F, 0x13, 0x08, 0x23, 0xA1, 0xC0, 0x02}},
111 {1, 191, 420, {0x2B, 0xF4, 0x0D, 0x0D, 0x1B, 0x0C, 0x53, 0x1E, 0x08, 0xBF, 0xF4, 0xC0, 0x02}},
112 },
113 /* 20 fps */
114 {
115 {4, 588, 0, {0x2A, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x4C, 0x52, 0xC0, 0x02}},
116 {3, 447, 730, {0x2A, 0xF4, 0x05, 0x16, 0xC9, 0x16, 0x01, 0x0E, 0x18, 0xBF, 0x69, 0xC0, 0x02}},
117 {2, 292, 476, {0x2A, 0xF4, 0x0D, 0x0E, 0xD8, 0x0E, 0x10, 0x19, 0x18, 0x24, 0xA1, 0xC0, 0x02}},
118 {1, 192, 312, {0x2A, 0xF4, 0x1D, 0x09, 0xB3, 0x08, 0xEB, 0x1E, 0x18, 0xC0, 0xF4, 0xC0, 0x02}},
119 },
120 /* 25 fps */
121 {
122 {5, 703, 0, {0x29, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0xBF, 0x42, 0xC0, 0x02}},
123 {3, 447, 610, {0x29, 0xF4, 0x05, 0x13, 0x0B, 0x12, 0x43, 0x14, 0x18, 0xBF, 0x69, 0xC0, 0x02}},
124 {2, 292, 398, {0x29, 0xF4, 0x0D, 0x0C, 0x6C, 0x0B, 0xA4, 0x1E, 0x18, 0x24, 0xA1, 0xC0, 0x02}},
125 {1, 192, 262, {0x29, 0xF4, 0x25, 0x08, 0x23, 0x07, 0x5B, 0x1E, 0x18, 0xC0, 0xF4, 0xC0, 0x02}},
126 },
127 /* 30 fps */
128 {
129 {8, 873, 0, {0x28, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x69, 0x37, 0xC0, 0x02}},
130 {5, 704, 774, {0x28, 0xF4, 0x05, 0x18, 0x21, 0x17, 0x59, 0x0F, 0x18, 0xC0, 0x42, 0xC0, 0x02}},
131 {3, 448, 492, {0x28, 0xF4, 0x05, 0x0F, 0x5D, 0x0E, 0x95, 0x15, 0x18, 0xC0, 0x69, 0xC0, 0x02}},
132 {2, 291, 320, {0x28, 0xF4, 0x1D, 0x09, 0xFB, 0x09, 0x33, 0x1E, 0x18, 0x23, 0xA1, 0xC0, 0x02}},
133 },
134 },
135 /* QCIF */
136 {
137 /* 5 fps */
138 {
139 {1, 193, 0, {0x0D, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0xC1, 0xF4, 0xC0, 0x02}},
140 {1, 193, 0, {0x0D, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0xC1, 0xF4, 0xC0, 0x02}},
141 {1, 193, 0, {0x0D, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0xC1, 0xF4, 0xC0, 0x02}},
142 {1, 193, 0, {0x0D, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0xC1, 0xF4, 0xC0, 0x02}},
143 },
144 /* 10 fps */
145 {
146 {3, 385, 0, {0x0C, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x81, 0x79, 0xC0, 0x02}},
147 {2, 291, 800, {0x0C, 0xF4, 0x05, 0x18, 0xF4, 0x18, 0x18, 0x11, 0x08, 0x23, 0xA1, 0xC0, 0x02}},
148 {2, 291, 800, {0x0C, 0xF4, 0x05, 0x18, 0xF4, 0x18, 0x18, 0x11, 0x08, 0x23, 0xA1, 0xC0, 0x02}},
149 {1, 194, 532, {0x0C, 0xF4, 0x05, 0x10, 0x9A, 0x0F, 0xBE, 0x1B, 0x08, 0xC2, 0xF0, 0xC0, 0x02}},
150 },
151 /* 15 fps */
152 {
153 {4, 577, 0, {0x0B, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x41, 0x52, 0xC0, 0x02}},
154 {3, 447, 818, {0x0B, 0xF4, 0x05, 0x19, 0x89, 0x18, 0xAD, 0x0F, 0x10, 0xBF, 0x69, 0xC0, 0x02}},
155 {2, 292, 534, {0x0B, 0xF4, 0x05, 0x10, 0xA3, 0x0F, 0xC7, 0x19, 0x10, 0x24, 0xA1, 0xC0, 0x02}},
156 {1, 195, 356, {0x0B, 0xF4, 0x15, 0x0B, 0x11, 0x0A, 0x35, 0x1E, 0x10, 0xC3, 0xF0, 0xC0, 0x02}},
157 },
158 /* 20 fps */
159 {
160 {6, 776, 0, {0x0A, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x08, 0x3F, 0xC0, 0x02}},
161 {4, 591, 804, {0x0A, 0xF4, 0x05, 0x19, 0x1E, 0x18, 0x42, 0x0F, 0x18, 0x4F, 0x4E, 0xC0, 0x02}},
162 {3, 447, 608, {0x0A, 0xF4, 0x05, 0x12, 0xFD, 0x12, 0x21, 0x15, 0x18, 0xBF, 0x69, 0xC0, 0x02}},
163 {2, 291, 396, {0x0A, 0xF4, 0x15, 0x0C, 0x5E, 0x0B, 0x82, 0x1E, 0x18, 0x23, 0xA1, 0xC0, 0x02}},
164 },
165 /* 25 fps */
166 {
167 {9, 928, 0, {0x09, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0xA0, 0x33, 0xC0, 0x02}},
168 {5, 703, 800, {0x09, 0xF4, 0x05, 0x18, 0xF4, 0x18, 0x18, 0x10, 0x18, 0xBF, 0x42, 0xC0, 0x02}},
169 {3, 447, 508, {0x09, 0xF4, 0x0D, 0x0F, 0xD2, 0x0E, 0xF6, 0x1B, 0x18, 0xBF, 0x69, 0xC0, 0x02}},
170 {2, 292, 332, {0x09, 0xF4, 0x1D, 0x0A, 0x5A, 0x09, 0x7E, 0x1E, 0x18, 0x24, 0xA1, 0xC0, 0x02}},
171 },
172 /* 30 fps */
173 {
174 {0, },
175 {9, 956, 876, {0x08, 0xF4, 0x05, 0x1B, 0x58, 0x1A, 0x7C, 0x0E, 0x20, 0xBC, 0x33, 0x10, 0x02}},
176 {4, 592, 542, {0x08, 0xF4, 0x05, 0x10, 0xE4, 0x10, 0x08, 0x17, 0x20, 0x50, 0x4E, 0x10, 0x02}},
177 {2, 291, 266, {0x08, 0xF4, 0x25, 0x08, 0x48, 0x07, 0x6C, 0x1E, 0x20, 0x23, 0xA1, 0x10, 0x02}},
178 },
179 },
180 /* SIF */
181 {
182 /* 5 fps */
183 {
184 {4, 582, 0, {0x35, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x46, 0x52, 0x60, 0x02}},
185 {3, 387, 1276, {0x35, 0xF4, 0x05, 0x27, 0xD8, 0x26, 0x48, 0x03, 0x10, 0x83, 0x79, 0x60, 0x02}},
186 {2, 291, 960, {0x35, 0xF4, 0x0D, 0x1D, 0xF2, 0x1C, 0x62, 0x04, 0x10, 0x23, 0xA1, 0x60, 0x02}},
187 {1, 191, 630, {0x35, 0xF4, 0x1D, 0x13, 0xA9, 0x12, 0x19, 0x05, 0x08, 0xBF, 0xF4, 0x60, 0x02}},
188 },
189 /* 10 fps */
190 {
191 {0, },
192 {6, 775, 1278, {0x34, 0xF4, 0x05, 0x27, 0xE8, 0x26, 0x58, 0x05, 0x30, 0x07, 0x3F, 0x10, 0x02}},
193 {3, 447, 736, {0x34, 0xF4, 0x15, 0x16, 0xFB, 0x15, 0x6B, 0x05, 0x18, 0xBF, 0x69, 0x10, 0x02}},
194 {2, 291, 480, {0x34, 0xF4, 0x2D, 0x0E, 0xF9, 0x0D, 0x69, 0x09, 0x18, 0x23, 0xA1, 0x10, 0x02}},
195 },
196 /* 15 fps */
197 {
198 {0, },
199 {9, 955, 1050, {0x33, 0xF4, 0x05, 0x20, 0xCF, 0x1F, 0x3F, 0x06, 0x48, 0xBB, 0x33, 0x10, 0x02}},
200 {4, 591, 650, {0x33, 0xF4, 0x15, 0x14, 0x44, 0x12, 0xB4, 0x08, 0x30, 0x4F, 0x4E, 0x10, 0x02}},
201 {3, 448, 492, {0x33, 0xF4, 0x25, 0x0F, 0x52, 0x0D, 0xC2, 0x09, 0x28, 0xC0, 0x69, 0x10, 0x02}},
202 },
203 /* 20 fps */
204 {
205 {0, },
206 {9, 958, 782, {0x32, 0xF4, 0x0D, 0x18, 0x6A, 0x16, 0xDA, 0x0B, 0x58, 0xBE, 0x33, 0xD0, 0x02}},
207 {5, 703, 574, {0x32, 0xF4, 0x1D, 0x11, 0xE7, 0x10, 0x57, 0x0B, 0x40, 0xBF, 0x42, 0xD0, 0x02}},
208 {3, 446, 364, {0x32, 0xF4, 0x3D, 0x0B, 0x5C, 0x09, 0xCC, 0x0E, 0x30, 0xBE, 0x69, 0xD0, 0x02}},
209 },
210 /* 25 fps */
211 {
212 {0, },
213 {9, 958, 654, {0x31, 0xF4, 0x15, 0x14, 0x66, 0x12, 0xD6, 0x0B, 0x50, 0xBE, 0x33, 0x90, 0x02}},
214 {6, 776, 530, {0x31, 0xF4, 0x25, 0x10, 0x8C, 0x0E, 0xFC, 0x0C, 0x48, 0x08, 0x3F, 0x90, 0x02}},
215 {4, 592, 404, {0x31, 0xF4, 0x35, 0x0C, 0x96, 0x0B, 0x06, 0x0B, 0x38, 0x50, 0x4E, 0x90, 0x02}},
216 },
217 /* 30 fps */
218 {
219 {0, },
220 {9, 957, 526, {0x30, 0xF4, 0x25, 0x10, 0x68, 0x0E, 0xD8, 0x0D, 0x58, 0xBD, 0x33, 0x60, 0x02}},
221 {6, 775, 426, {0x30, 0xF4, 0x35, 0x0D, 0x48, 0x0B, 0xB8, 0x0F, 0x50, 0x07, 0x3F, 0x60, 0x02}},
222 {4, 590, 324, {0x30, 0x7A, 0x4B, 0x0A, 0x1C, 0x08, 0xB4, 0x0E, 0x40, 0x4E, 0x52, 0x60, 0x02}},
223 },
224 },
225 /* CIF */
226 {
227 /* 5 fps */
228 {
229 {6, 771, 0, {0x15, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x03, 0x3F, 0x80, 0x02}},
230 {4, 465, 1278, {0x15, 0xF4, 0x05, 0x27, 0xEE, 0x26, 0x36, 0x03, 0x18, 0xD1, 0x65, 0x80, 0x02}},
231 {2, 291, 800, {0x15, 0xF4, 0x15, 0x18, 0xF4, 0x17, 0x3C, 0x05, 0x18, 0x23, 0xA1, 0x80, 0x02}},
232 {1, 193, 528, {0x15, 0xF4, 0x2D, 0x10, 0x7E, 0x0E, 0xC6, 0x0A, 0x18, 0xC1, 0xF4, 0x80, 0x02}},
233 },
234 /* 10 fps */
235 {
236 {0, },
237 {9, 932, 1278, {0x14, 0xF4, 0x05, 0x27, 0xEE, 0x26, 0x36, 0x04, 0x30, 0xA4, 0x33, 0x10, 0x02}},
238 {4, 591, 812, {0x14, 0xF4, 0x15, 0x19, 0x56, 0x17, 0x9E, 0x06, 0x28, 0x4F, 0x4E, 0x10, 0x02}},
239 {2, 291, 400, {0x14, 0xF4, 0x3D, 0x0C, 0x7A, 0x0A, 0xC2, 0x0E, 0x28, 0x23, 0xA1, 0x10, 0x02}},
240 },
241 /* 15 fps */
242 {
243 {0, },
244 {9, 956, 876, {0x13, 0xF4, 0x0D, 0x1B, 0x58, 0x19, 0xA0, 0x05, 0x38, 0xBC, 0x33, 0x60, 0x02}},
245 {5, 703, 644, {0x13, 0xF4, 0x1D, 0x14, 0x1C, 0x12, 0x64, 0x08, 0x38, 0xBF, 0x42, 0x60, 0x02}},
246 {3, 448, 410, {0x13, 0xF4, 0x3D, 0x0C, 0xC4, 0x0B, 0x0C, 0x0E, 0x38, 0xC0, 0x69, 0x60, 0x02}},
247 },
248 /* 20 fps */
249 {
250 {0, },
251 {9, 956, 650, {0x12, 0xF4, 0x1D, 0x14, 0x4A, 0x12, 0x92, 0x09, 0x48, 0xBC, 0x33, 0x10, 0x03}},
252 {6, 776, 528, {0x12, 0xF4, 0x2D, 0x10, 0x7E, 0x0E, 0xC6, 0x0A, 0x40, 0x08, 0x3F, 0x10, 0x03}},
253 {4, 591, 402, {0x12, 0xF4, 0x3D, 0x0C, 0x8F, 0x0A, 0xD7, 0x0E, 0x40, 0x4F, 0x4E, 0x10, 0x03}},
254 },
255 /* 25 fps */
256 {
257 {0, },
258 {9, 956, 544, {0x11, 0xF4, 0x25, 0x10, 0xF4, 0x0F, 0x3C, 0x0A, 0x48, 0xBC, 0x33, 0xC0, 0x02}},
259 {7, 840, 478, {0x11, 0xF4, 0x2D, 0x0E, 0xEB, 0x0D, 0x33, 0x0B, 0x48, 0x48, 0x3B, 0xC0, 0x02}},
260 {5, 703, 400, {0x11, 0xF4, 0x3D, 0x0C, 0x7A, 0x0A, 0xC2, 0x0E, 0x48, 0xBF, 0x42, 0xC0, 0x02}},
261 },
262 /* 30 fps */
263 {
264 {0, },
265 {9, 956, 438, {0x10, 0xF4, 0x35, 0x0D, 0xAC, 0x0B, 0xF4, 0x0D, 0x50, 0xBC, 0x33, 0x10, 0x02}},
266 {7, 838, 384, {0x10, 0xF4, 0x45, 0x0B, 0xFD, 0x0A, 0x45, 0x0F, 0x50, 0x46, 0x3B, 0x10, 0x02}},
267 {6, 773, 354, {0x10, 0x7A, 0x4B, 0x0B, 0x0C, 0x09, 0x80, 0x10, 0x50, 0x05, 0x3F, 0x10, 0x02}},
268 },
269 },
270 /* VGA */
271 {
272 /* 5 fps */
273 {
274 {0, },
275 {6, 773, 1272, {0x1D, 0xF4, 0x15, 0x27, 0xB6, 0x24, 0x96, 0x02, 0x30, 0x05, 0x3F, 0x10, 0x02}},
276 {4, 592, 976, {0x1D, 0xF4, 0x25, 0x1E, 0x78, 0x1B, 0x58, 0x03, 0x30, 0x50, 0x4E, 0x10, 0x02}},
277 {3, 448, 738, {0x1D, 0xF4, 0x3D, 0x17, 0x0C, 0x13, 0xEC, 0x04, 0x30, 0xC0, 0x69, 0x10, 0x02}},
278 },
279 /* 10 fps */
280 {
281 {0, },
282 {9, 956, 788, {0x1C, 0xF4, 0x35, 0x18, 0x9C, 0x15, 0x7C, 0x03, 0x48, 0xBC, 0x33, 0x10, 0x02}},
283 {6, 776, 640, {0x1C, 0x7A, 0x53, 0x13, 0xFC, 0x11, 0x2C, 0x04, 0x48, 0x08, 0x3F, 0x10, 0x02}},
284 {4, 592, 488, {0x1C, 0x7A, 0x6B, 0x0F, 0x3C, 0x0C, 0x6C, 0x06, 0x48, 0x50, 0x4E, 0x10, 0x02}},
285 },
286 /* 15 fps */
287 {
288 {0, },
289 {9, 957, 526, {0x1B, 0x7A, 0x63, 0x10, 0x68, 0x0D, 0x98, 0x06, 0x58, 0xBD, 0x33, 0x80, 0x02}},
290 {9, 957, 526, {0x1B, 0x7A, 0x63, 0x10, 0x68, 0x0D, 0x98, 0x06, 0x58, 0xBD, 0x33, 0x80, 0x02}},
291 {8, 895, 492, {0x1B, 0x7A, 0x6B, 0x0F, 0x5D, 0x0C, 0x8D, 0x06, 0x58, 0x7F, 0x37, 0x80, 0x02}},
292 },
293 /* 20 fps */
294 {
295 {0, },
296 {0, },
297 {0, },
298 {0, },
299 },
300 /* 25 fps */
301 {
302 {0, },
303 {0, },
304 {0, },
305 {0, },
306 },
307 /* 30 fps */
308 {
309 {0, },
310 {0, },
311 {0, },
312 {0, },
313 },
314 },
315};
316
317/*
318 * 16 versions:
319 * 2 tables (one for Y, and one for U&V)
320 * 16 levels of details per tables
321 * 8 blocs
322 */
323
324const unsigned int TimonRomTable [16][2][16][8] =
325{
326 { /* version 0 */
327 { /* version 0, passes 0 */
328 {0x00000000,0x00000000,0x00000000,0x00000000,
329 0x00000000,0x00000000,0x00000000,0x00000001},
330 {0x00000000,0x00000000,0x00000001,0x00000001,
331 0x00000001,0x00000001,0x00000001,0x00000001},
332 {0x00000000,0x00000000,0x00000001,0x00000001,
333 0x00000001,0x00000009,0x00000009,0x00000009},
334 {0x00000000,0x00000000,0x00000009,0x00000001,
335 0x00000009,0x00000009,0x00000009,0x00000009},
336 {0x00000000,0x00000000,0x00000009,0x00000009,
337 0x00000009,0x00000009,0x00000049,0x00000009},
338 {0x00000000,0x00000000,0x00000009,0x00000009,
339 0x00000009,0x00000049,0x00000049,0x00000049},
340 {0x00000000,0x00000000,0x00000009,0x00000009,
341 0x00000049,0x00000049,0x00000049,0x00000049},
342 {0x00000000,0x00000000,0x00000009,0x00000049,
343 0x00000049,0x00000049,0x00000049,0x00000049},
344 {0x00000000,0x00000000,0x00000049,0x00000049,
345 0x00000049,0x00000049,0x0000024a,0x0000024a},
346 {0x00000000,0x00000000,0x00000049,0x00000049,
347 0x00000049,0x00000249,0x0000024a,0x0000024a},
348 {0x00000000,0x00000000,0x00000049,0x00000049,
349 0x00000249,0x00000249,0x0000024a,0x0000024a},
350 {0x00000000,0x00000000,0x00000049,0x00000049,
351 0x00000249,0x00000249,0x00001252,0x0000024a},
352 {0x00000000,0x00000000,0x00000049,0x00000049,
353 0x00000249,0x0000124a,0x00001252,0x0000024a},
354 {0x00000000,0x00000000,0x00000049,0x00000249,
355 0x00000249,0x0000124a,0x00001252,0x0000024a},
356 {0x00000000,0x00000000,0x00000249,0x00001249,
357 0x0000124a,0x00009252,0x00009292,0x00001252},
358 {0x00000000,0x00000000,0x00000000,0x00000000,
359 0x00000000,0x00000000,0x00000000,0x00000000}
360 },
361 { /* version 0, passes 1 */
362 {0x00000000,0x00000000,0x00000000,0x00000000,
363 0x00000000,0x00000000,0x00000000,0x00000000},
364 {0x00000000,0x00000000,0x00000001,0x00000001,
365 0x00000001,0x00000001,0x00000000,0x00000000},
366 {0x00000000,0x00000000,0x00000009,0x00000001,
367 0x00000001,0x00000009,0x00000000,0x00000000},
368 {0x00000000,0x00000000,0x00000009,0x00000009,
369 0x00000009,0x00000009,0x00000000,0x00000000},
370 {0x00000000,0x00000000,0x00000009,0x00000009,
371 0x00000009,0x00000009,0x00000001,0x00000000},
372 {0x00000000,0x00000000,0x00000049,0x00000009,
373 0x00000009,0x00000049,0x00000001,0x00000001},
374 {0x00000000,0x00000000,0x00000049,0x00000009,
375 0x00000009,0x00000049,0x00000001,0x00000001},
376 {0x00000000,0x00000000,0x00000049,0x00000049,
377 0x00000049,0x00000049,0x00000009,0x00000001},
378 {0x00000000,0x00000000,0x00000049,0x00000049,
379 0x00000049,0x00000049,0x00000009,0x00000001},
380 {0x00000000,0x00000000,0x00000049,0x00000049,
381 0x00000049,0x00000049,0x00000009,0x00000001},
382 {0x00000000,0x00000000,0x00000049,0x00000049,
383 0x00000049,0x00000049,0x00000009,0x00000009},
384 {0x00000000,0x00000000,0x00000049,0x00000049,
385 0x00000049,0x00000249,0x00000049,0x00000009},
386 {0x00000000,0x00000000,0x00000049,0x00000049,
387 0x00000049,0x00000249,0x00000049,0x00000009},
388 {0x00000000,0x00000000,0x00000249,0x00000049,
389 0x00000249,0x00000249,0x00000049,0x00000009},
390 {0x00000000,0x00000000,0x00001249,0x00000249,
391 0x0000124a,0x0000124a,0x0000024a,0x00000049},
392 {0x00000000,0x00000000,0x00000000,0x00000000,
393 0x00000000,0x00000000,0x00000000,0x00000000}
394 }
395 },
396 { /* version 1 */
397 { /* version 1, passes 0 */
398 {0x00000000,0x00000000,0x00000000,0x00000000,
399 0x00000000,0x00000000,0x00000000,0x00000001},
400 {0x00000000,0x00000000,0x00000001,0x00000001,
401 0x00000001,0x00000009,0x00000009,0x00000009},
402 {0x00000000,0x00000000,0x00000009,0x00000009,
403 0x00000009,0x00000009,0x00000009,0x00000009},
404 {0x00000000,0x00000000,0x00000009,0x00000009,
405 0x00000009,0x00000049,0x00000049,0x00000049},
406 {0x00000000,0x00000000,0x00000009,0x00000049,
407 0x00000049,0x00000049,0x00000049,0x00000049},
408 {0x00000000,0x00000000,0x00000049,0x00000049,
409 0x00000049,0x00000249,0x0000024a,0x0000024a},
410 {0x00000000,0x00000000,0x00000049,0x00000049,
411 0x00000249,0x00000249,0x0000024a,0x0000024a},
412 {0x00000000,0x00000000,0x00000049,0x00000249,
413 0x00000249,0x00000249,0x0000024a,0x00001252},
414 {0x00000000,0x00000000,0x00000049,0x00000249,
415 0x00000249,0x0000124a,0x00001252,0x00001252},
416 {0x00000000,0x00000000,0x00000049,0x00000249,
417 0x0000124a,0x0000124a,0x00001252,0x00001252},
418 {0x00000000,0x00000000,0x00000249,0x00000249,
419 0x0000124a,0x0000124a,0x00009292,0x00009292},
420 {0x00000000,0x00000000,0x00000249,0x00001249,
421 0x0000124a,0x00009252,0x00009292,0x00009292},
422 {0x00000000,0x00000000,0x00000249,0x00001249,
423 0x00009252,0x00009252,0x00009292,0x00009292},
424 {0x00000000,0x00000000,0x00000249,0x0000924a,
425 0x00009292,0x00009493,0x00009493,0x00009493},
426 {0x00000000,0x00000000,0x00001249,0x00009252,
427 0x00009492,0x0000a49b,0x0000a49b,0x0000a49b},
428 {0x00000000,0x00000000,0x00000000,0x00000000,
429 0x00000000,0x00000000,0x00000000,0x00000000}
430 },
431 { /* version 1, passes 1 */
432 {0x00000000,0x00000000,0x00000000,0x00000000,
433 0x00000000,0x00000000,0x00000000,0x00000000},
434 {0x00000000,0x00000000,0x00000009,0x00000009,
435 0x00000009,0x00000001,0x00000001,0x00000000},
436 {0x00000000,0x00000000,0x00000009,0x00000009,
437 0x00000009,0x00000009,0x00000001,0x00000000},
438 {0x00000000,0x00000000,0x00000049,0x00000049,
439 0x00000049,0x00000009,0x00000001,0x00000000},
440 {0x00000000,0x00000000,0x00000049,0x00000049,
441 0x00000049,0x00000049,0x00000001,0x00000001},
442 {0x00000000,0x00000000,0x00000049,0x00000049,
443 0x00000049,0x00000049,0x00000009,0x00000001},
444 {0x00000000,0x00000000,0x00000249,0x00000049,
445 0x00000049,0x00000249,0x00000009,0x00000001},
446 {0x00000000,0x00000000,0x00000249,0x00000049,
447 0x00000249,0x00000249,0x00000009,0x00000009},
448 {0x00000000,0x00000000,0x00000249,0x00000249,
449 0x00000249,0x00000249,0x00000049,0x00000009},
450 {0x00000000,0x00000000,0x00000249,0x00000249,
451 0x00000249,0x0000124a,0x00000049,0x00000009},
452 {0x00000000,0x00000000,0x00000249,0x00000249,
453 0x00000249,0x0000124a,0x00000049,0x00000009},
454 {0x00000000,0x00000000,0x00000249,0x00000249,
455 0x00000249,0x0000124a,0x0000024a,0x00000049},
456 {0x00000000,0x00000000,0x00000249,0x00000249,
457 0x0000124a,0x0000124a,0x0000024a,0x00000049},
458 {0x00000000,0x00000000,0x00000249,0x00000249,
459 0x0000124a,0x0000124a,0x0000024a,0x00000049},
460 {0x00000000,0x00000000,0x00001249,0x00001249,
461 0x00009252,0x00009252,0x00001252,0x0000024a},
462 {0x00000000,0x00000000,0x00000000,0x00000000,
463 0x00000000,0x00000000,0x00000000,0x00000000}
464 }
465 },
466 { /* version 2 */
467 { /* version 2, passes 0 */
468 {0x00000000,0x00000000,0x00000000,0x00000000,
469 0x00000000,0x00000000,0x00000000,0x00000001},
470 {0x00000000,0x00000000,0x00000009,0x00000009,
471 0x00000009,0x00000009,0x00000009,0x00000009},
472 {0x00000000,0x00000000,0x00000049,0x00000049,
473 0x00000049,0x00000049,0x00000049,0x00000049},
474 {0x00000000,0x00000000,0x00000049,0x00000049,
475 0x00000049,0x00000249,0x0000024a,0x0000024a},
476 {0x00000000,0x00000000,0x00000049,0x00000249,
477 0x00000249,0x00000249,0x0000024a,0x00001252},
478 {0x00000000,0x00000000,0x00000249,0x00000249,
479 0x00000249,0x0000124a,0x00001252,0x00001252},
480 {0x00000000,0x00000000,0x00000249,0x00000249,
481 0x0000124a,0x0000124a,0x00009292,0x00009292},
482 {0x00000000,0x00000000,0x00000249,0x00001249,
483 0x0000124a,0x00009252,0x00009292,0x00009292},
484 {0x00000000,0x00000000,0x00000249,0x00001249,
485 0x00009252,0x00009292,0x00009292,0x00009292},
486 {0x00000000,0x00000000,0x00000249,0x00001249,
487 0x00009252,0x00009292,0x00009493,0x00009493},
488 {0x00000000,0x00000000,0x00000249,0x0000924a,
489 0x00009252,0x00009493,0x00009493,0x00009493},
490 {0x00000000,0x00000000,0x00000249,0x0000924a,
491 0x00009292,0x00009493,0x00009493,0x00009493},
492 {0x00000000,0x00000000,0x00000249,0x00009252,
493 0x00009492,0x00009493,0x0000a49b,0x0000a49b},
494 {0x00000000,0x00000000,0x00001249,0x00009292,
495 0x00009492,0x000124db,0x000124db,0x000124db},
496 {0x00000000,0x00000000,0x0000924a,0x00009493,
497 0x0000a493,0x000126dc,0x000126dc,0x000126dc},
498 {0x00000000,0x00000000,0x00000000,0x00000000,
499 0x00000000,0x00000000,0x00000000,0x00000000}
500 },
501 { /* version 2, passes 1 */
502 {0x00000000,0x00000000,0x00000000,0x00000000,
503 0x00000000,0x00000000,0x00000000,0x00000000},
504 {0x00000000,0x00000000,0x00000049,0x00000009,
505 0x00000049,0x00000009,0x00000001,0x00000000},
506 {0x00000000,0x00000000,0x00000049,0x00000049,
507 0x00000049,0x00000049,0x00000049,0x00000000},
508 {0x00000000,0x00000000,0x00000249,0x00000049,
509 0x00000249,0x00000049,0x0000024a,0x00000001},
510 {0x00000000,0x00000000,0x00000249,0x00000249,
511 0x00000249,0x00000249,0x0000024a,0x00000001},
512 {0x00000000,0x00000000,0x00000249,0x00000249,
513 0x00000249,0x00000249,0x0000024a,0x00000001},
514 {0x00000000,0x00000000,0x00000249,0x00000249,
515 0x00000249,0x00000249,0x0000024a,0x00000009},
516 {0x00000000,0x00000000,0x00000249,0x00000249,
517 0x0000124a,0x0000124a,0x0000024a,0x00000009},
518 {0x00000000,0x00000000,0x00000249,0x00000249,
519 0x0000124a,0x0000124a,0x0000024a,0x00000009},
520 {0x00000000,0x00000000,0x00001249,0x00001249,
521 0x0000124a,0x00009252,0x00001252,0x00000049},
522 {0x00000000,0x00000000,0x00001249,0x00001249,
523 0x0000124a,0x00009292,0x00001252,0x00000049},
524 {0x00000000,0x00000000,0x00001249,0x00001249,
525 0x0000124a,0x00009292,0x00001252,0x00000049},
526 {0x00000000,0x00000000,0x00001249,0x00001249,
527 0x00009252,0x00009292,0x00001252,0x0000024a},
528 {0x00000000,0x00000000,0x00001249,0x00001249,
529 0x00009292,0x00009292,0x00001252,0x0000024a},
530 {0x00000000,0x00000000,0x0000924a,0x0000924a,
531 0x00009492,0x00009493,0x00009292,0x00001252},
532 {0x00000000,0x00000000,0x00000000,0x00000000,
533 0x00000000,0x00000000,0x00000000,0x00000000}
534 }
535 },
536 { /* version 3 */
537 { /* version 3, passes 0 */
538 {0x00000000,0x00000000,0x00000000,0x00000000,
539 0x00000000,0x00000000,0x00000000,0x00000001},
540 {0x00000000,0x00000000,0x00000049,0x00000049,
541 0x00000049,0x00000049,0x00000049,0x00000049},
542 {0x00000000,0x00000000,0x00000049,0x00000249,
543 0x00000249,0x00000249,0x00001252,0x0000024a},
544 {0x00000000,0x00000000,0x00000249,0x00000249,
545 0x00000249,0x0000124a,0x00001252,0x00001252},
546 {0x00000000,0x00000000,0x00000249,0x00000249,
547 0x0000124a,0x00009252,0x00009292,0x00009292},
548 {0x00000000,0x00000000,0x00000249,0x00001249,
549 0x0000124a,0x00009292,0x00009292,0x00009493},
550 {0x00000000,0x00000000,0x00000249,0x00001249,
551 0x00009252,0x00009292,0x00009493,0x00009493},
552 {0x00000000,0x00000000,0x00000249,0x00001249,
553 0x00009292,0x00009493,0x00009493,0x00009493},
554 {0x00000000,0x00000000,0x00000249,0x00009252,
555 0x00009292,0x00009493,0x0000a49b,0x0000a49b},
556 {0x00000000,0x00000000,0x00001249,0x00009252,
557 0x00009292,0x0000a49b,0x0000a49b,0x0000a49b},
558 {0x00000000,0x00000000,0x00001249,0x00009252,
559 0x00009492,0x0000a49b,0x0000a49b,0x0000a49b},
560 {0x00000000,0x00000000,0x00001249,0x00009292,
561 0x00009492,0x0000a49b,0x000124db,0x000124db},
562 {0x00000000,0x00000000,0x00001249,0x00009292,
563 0x0000a493,0x0000a49b,0x000124db,0x000124db},
564 {0x00000000,0x00000000,0x00001249,0x00009493,
565 0x0001249b,0x000126dc,0x000136e4,0x000126dc},
566 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
567 0x000124db,0x000136e4,0x0001b725,0x000136e4},
568 {0x00000000,0x00000000,0x00000000,0x00000000,
569 0x00000000,0x00000000,0x00000000,0x00000000}
570 },
571 { /* version 3, passes 1 */
572 {0x00000000,0x00000000,0x00000000,0x00000000,
573 0x00000000,0x00000000,0x00000000,0x00000000},
574 {0x00000000,0x00000000,0x00000049,0x00000049,
575 0x00000049,0x00000049,0x00000001,0x00000000},
576 {0x00000000,0x00000000,0x00000249,0x00000249,
577 0x00000249,0x00000249,0x00000049,0x00000001},
578 {0x00000000,0x00000000,0x00000249,0x00000249,
579 0x00000249,0x0000124a,0x00001252,0x00000001},
580 {0x00000000,0x00000000,0x00000249,0x00000249,
581 0x0000124a,0x0000124a,0x00001252,0x00000009},
582 {0x00000000,0x00000000,0x00000249,0x00001249,
583 0x0000124a,0x00009252,0x00009292,0x00000009},
584 {0x00000000,0x00000000,0x00001249,0x00001249,
585 0x0000124a,0x00009252,0x00009292,0x00000049},
586 {0x00000000,0x00000000,0x00001249,0x00001249,
587 0x00009252,0x00009252,0x00009292,0x00000049},
588 {0x00000000,0x00000000,0x00001249,0x00001249,
589 0x00009252,0x00009493,0x00009292,0x0000024a},
590 {0x00000000,0x00000000,0x00001249,0x00001249,
591 0x00009252,0x00009493,0x00009292,0x0000024a},
592 {0x00000000,0x00000000,0x00001249,0x00001249,
593 0x00009252,0x00009493,0x00009493,0x00001252},
594 {0x00000000,0x00000000,0x00001249,0x0000924a,
595 0x00009292,0x00009493,0x00009493,0x00001252},
596 {0x00000000,0x00000000,0x00001249,0x0000924a,
597 0x00009492,0x00009493,0x00009493,0x00009292},
598 {0x00000000,0x00000000,0x00001249,0x00009252,
599 0x00009492,0x0000a49b,0x00009493,0x00009292},
600 {0x00000000,0x00000000,0x0000924a,0x00009292,
601 0x0000a493,0x000124db,0x0000a49b,0x00009493},
602 {0x00000000,0x00000000,0x00000000,0x00000000,
603 0x00000000,0x00000000,0x00000000,0x00000000}
604 }
605 },
606 { /* version 4 */
607 { /* version 4, passes 0 */
608 {0x00000000,0x00000000,0x00000049,0x00000049,
609 0x00000049,0x00000049,0x0000024a,0x0000024a},
610 {0x00000000,0x00000000,0x00000249,0x00000249,
611 0x00000249,0x0000124a,0x00001252,0x00009292},
612 {0x00000000,0x00000000,0x00000249,0x00000249,
613 0x0000124a,0x00009252,0x00009292,0x00009292},
614 {0x00000000,0x00000000,0x00000249,0x00001249,
615 0x0000124a,0x00009292,0x00009493,0x00009493},
616 {0x00000000,0x00000000,0x00000249,0x00001249,
617 0x00009252,0x00009493,0x00009493,0x0000a49b},
618 {0x00000000,0x00000000,0x00000249,0x0000924a,
619 0x00009292,0x00009493,0x0000a49b,0x0000a49b},
620 {0x00000000,0x00000000,0x00001249,0x0000924a,
621 0x00009292,0x00009493,0x0000a49b,0x000124db},
622 {0x00000000,0x00000000,0x00001249,0x00009252,
623 0x00009492,0x0000a49b,0x0000a49b,0x000124db},
624 {0x00000000,0x00000000,0x00001249,0x00009292,
625 0x00009492,0x000124db,0x000124db,0x000126dc},
626 {0x00000000,0x00000000,0x00001249,0x00009292,
627 0x0000a493,0x000124db,0x000126dc,0x000126dc},
628 {0x00000000,0x00000000,0x00001249,0x00009493,
629 0x0000a493,0x000124db,0x000126dc,0x000136e4},
630 {0x00000000,0x00000000,0x00001249,0x00009493,
631 0x0000a493,0x000126dc,0x000136e4,0x000136e4},
632 {0x00000000,0x00000000,0x0000924a,0x00009493,
633 0x0001249b,0x000126dc,0x000136e4,0x000136e4},
634 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
635 0x000124db,0x000136e4,0x000136e4,0x0001b724},
636 {0x00000000,0x00000000,0x00009252,0x000124db,
637 0x000126dc,0x0001b724,0x0001b725,0x0001b925},
638 {0x00000000,0x00000000,0x00000000,0x00000000,
639 0x00000000,0x00000000,0x00000000,0x00000000}
640 },
641 { /* version 4, passes 1 */
642 {0x00000000,0x00000000,0x00000049,0x00000049,
643 0x00000049,0x00000049,0x00000049,0x00000049},
644 {0x00000000,0x00000000,0x00000249,0x00000249,
645 0x00000249,0x00000249,0x0000024a,0x00000049},
646 {0x00000000,0x00000000,0x00001249,0x00000249,
647 0x0000124a,0x0000124a,0x00001252,0x00000049},
648 {0x00000000,0x00000000,0x00001249,0x00001249,
649 0x0000124a,0x0000124a,0x00009292,0x0000024a},
650 {0x00000000,0x00000000,0x00001249,0x00001249,
651 0x00009252,0x00009292,0x00009292,0x0000024a},
652 {0x00000000,0x00000000,0x00001249,0x00001249,
653 0x00009252,0x00009292,0x0000a49b,0x0000024a},
654 {0x00000000,0x00000000,0x00001249,0x00001249,
655 0x00009292,0x00009493,0x0000a49b,0x00001252},
656 {0x00000000,0x00000000,0x00001249,0x00001249,
657 0x00009292,0x00009493,0x0000a49b,0x00001252},
658 {0x00000000,0x00000000,0x00001249,0x0000924a,
659 0x00009492,0x0000a49b,0x0000a49b,0x00001252},
660 {0x00000000,0x00000000,0x00001249,0x00009252,
661 0x00009492,0x0000a49b,0x0000a49b,0x00009292},
662 {0x00000000,0x00000000,0x00001249,0x00009292,
663 0x00009492,0x0000a49b,0x0000a49b,0x00009292},
664 {0x00000000,0x00000000,0x00001249,0x00009493,
665 0x0000a493,0x0000a49b,0x0000a49b,0x00009292},
666 {0x00000000,0x00000000,0x00001249,0x00009493,
667 0x0000a493,0x0000a49b,0x0000a49b,0x00009493},
668 {0x00000000,0x00000000,0x0000924a,0x00009493,
669 0x0000a493,0x000124db,0x0000a49b,0x00009493},
670 {0x00000000,0x00000000,0x00009252,0x0000a49b,
671 0x0001249b,0x000126dc,0x000124db,0x0000a49b},
672 {0x00000000,0x00000000,0x00000000,0x00000000,
673 0x00000000,0x00000000,0x00000000,0x00000000}
674 }
675 },
676 { /* version 5 */
677 { /* version 5, passes 0 */
678 {0x00000000,0x00000000,0x00000249,0x00000249,
679 0x00000249,0x0000124a,0x00001252,0x00009292},
680 {0x00000000,0x00000000,0x00000249,0x00001249,
681 0x0000124a,0x00009292,0x00009292,0x00009493},
682 {0x00000000,0x00000000,0x00000249,0x0000924a,
683 0x00009292,0x00009493,0x0000a49b,0x0000a49b},
684 {0x00000000,0x00000000,0x00001249,0x0000924a,
685 0x00009292,0x00009493,0x0000a49b,0x0000a49b},
686 {0x00000000,0x00000000,0x00001249,0x0000924a,
687 0x00009492,0x0000a49b,0x0000a49b,0x000124db},
688 {0x00000000,0x00000000,0x00001249,0x00009292,
689 0x00009492,0x0000a49b,0x000124db,0x000124db},
690 {0x00000000,0x00000000,0x00001249,0x00009292,
691 0x0000a493,0x000124db,0x000124db,0x000126dc},
692 {0x00000000,0x00000000,0x00001249,0x00009493,
693 0x0000a493,0x000124db,0x000126dc,0x000126dc},
694 {0x00000000,0x00000000,0x00001249,0x00009493,
695 0x0000a493,0x000126dc,0x000136e4,0x000136e4},
696 {0x00000000,0x00000000,0x00001249,0x00009493,
697 0x0001249b,0x000126dc,0x000136e4,0x000136e4},
698 {0x00000000,0x00000000,0x00001249,0x00009493,
699 0x0001249b,0x000126dc,0x000136e4,0x000136e4},
700 {0x00000000,0x00000000,0x0000924a,0x00009493,
701 0x0001249b,0x000126dc,0x0001b725,0x0001b724},
702 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
703 0x000124db,0x000126dc,0x0001b725,0x0001b724},
704 {0x00000000,0x00000000,0x00009292,0x0000a49b,
705 0x000126dc,0x000136e4,0x0001b92d,0x0001b925},
706 {0x00000000,0x00000000,0x00009492,0x000124db,
707 0x000136e4,0x0001b724,0x0001c96e,0x0001c92d},
708 {0x00000000,0x00000000,0x00000000,0x00000000,
709 0x00000000,0x00000000,0x00000000,0x00000000}
710 },
711 { /* version 5, passes 1 */
712 {0x00000000,0x00000000,0x00000249,0x00000249,
713 0x0000124a,0x00000249,0x0000024a,0x0000024a},
714 {0x00000000,0x00000000,0x00001249,0x00001249,
715 0x0000124a,0x0000124a,0x00001252,0x0000024a},
716 {0x00000000,0x00000000,0x00001249,0x00001249,
717 0x00009292,0x00009493,0x00009493,0x0000024a},
718 {0x00000000,0x00000000,0x00001249,0x00001249,
719 0x00009292,0x00009493,0x00009493,0x00001252},
720 {0x00000000,0x00000000,0x00001249,0x00001249,
721 0x00009292,0x00009493,0x0000a49b,0x00001252},
722 {0x00000000,0x00000000,0x00001249,0x0000924a,
723 0x00009492,0x00009493,0x000124db,0x00001252},
724 {0x00000000,0x00000000,0x00001249,0x00009292,
725 0x00009492,0x00009493,0x000124db,0x00009292},
726 {0x00000000,0x00000000,0x00001249,0x00009292,
727 0x00009492,0x0000a49b,0x000124db,0x00009292},
728 {0x00000000,0x00000000,0x00001249,0x00009493,
729 0x0000a493,0x0000a49b,0x000124db,0x00009292},
730 {0x00000000,0x00000000,0x00001249,0x00009493,
731 0x0000a493,0x000124db,0x000124db,0x00009493},
732 {0x00000000,0x00000000,0x0000924a,0x00009493,
733 0x0000a493,0x000124db,0x000124db,0x00009493},
734 {0x00000000,0x00000000,0x0000924a,0x00009493,
735 0x0000a493,0x000124db,0x000124db,0x00009493},
736 {0x00000000,0x00000000,0x0000924a,0x00009493,
737 0x0000a493,0x000124db,0x000124db,0x0000a49b},
738 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
739 0x000124db,0x000126dc,0x000124db,0x0000a49b},
740 {0x00000000,0x00000000,0x00009252,0x000124db,
741 0x000126dc,0x000136e4,0x000126dc,0x000124db},
742 {0x00000000,0x00000000,0x00000000,0x00000000,
743 0x00000000,0x00000000,0x00000000,0x00000000}
744 }
745 },
746 { /* version 6 */
747 { /* version 6, passes 0 */
748 {0x00000000,0x00000000,0x00000249,0x00000249,
749 0x0000124a,0x0000124a,0x00009292,0x00009292},
750 {0x00000000,0x00000000,0x00001249,0x00001249,
751 0x00009292,0x00009493,0x0000a49b,0x0000a49b},
752 {0x00000000,0x00000000,0x00001249,0x0000924a,
753 0x00009492,0x0000a49b,0x0000a49b,0x000124db},
754 {0x00000000,0x00000000,0x00001249,0x00009292,
755 0x00009492,0x000124db,0x000126dc,0x000126dc},
756 {0x00000000,0x00000000,0x00001249,0x00009493,
757 0x0000a493,0x000124db,0x000126dc,0x000126dc},
758 {0x00000000,0x00000000,0x00001249,0x00009493,
759 0x0000a493,0x000126dc,0x000136e4,0x000136e4},
760 {0x00000000,0x00000000,0x00001249,0x00009493,
761 0x0000a493,0x000126dc,0x000136e4,0x0001b724},
762 {0x00000000,0x00000000,0x00001249,0x00009493,
763 0x0001249b,0x000126dc,0x000136e4,0x0001b724},
764 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
765 0x0001249b,0x000126dc,0x000136e4,0x0001b724},
766 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
767 0x0001249b,0x000136e4,0x0001b725,0x0001b724},
768 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
769 0x000124db,0x000136e4,0x0001b725,0x0001b925},
770 {0x00000000,0x00000000,0x00009292,0x0000a49b,
771 0x000126dc,0x000136e4,0x0001b92d,0x0001b925},
772 {0x00000000,0x00000000,0x00009292,0x0000a49b,
773 0x000126dc,0x0001b724,0x0001b92d,0x0001c92d},
774 {0x00000000,0x00000000,0x00009492,0x000124db,
775 0x000126dc,0x0001b724,0x0001c96e,0x0001c92d},
776 {0x00000000,0x00000000,0x0000a492,0x000126db,
777 0x000136e4,0x0001b925,0x00025bb6,0x00024b77},
778 {0x00000000,0x00000000,0x00000000,0x00000000,
779 0x00000000,0x00000000,0x00000000,0x00000000}
780 },
781 { /* version 6, passes 1 */
782 {0x00000000,0x00000000,0x00001249,0x00000249,
783 0x0000124a,0x0000124a,0x00001252,0x00001252},
784 {0x00000000,0x00000000,0x00001249,0x00001249,
785 0x00009252,0x00009292,0x00009292,0x00001252},
786 {0x00000000,0x00000000,0x00001249,0x0000924a,
787 0x00009492,0x00009493,0x0000a49b,0x00001252},
788 {0x00000000,0x00000000,0x00001249,0x00009252,
789 0x00009492,0x0000a49b,0x0000a49b,0x00009292},
790 {0x00000000,0x00000000,0x00001249,0x00009292,
791 0x00009492,0x0000a49b,0x0000a49b,0x00009292},
792 {0x00000000,0x00000000,0x00001249,0x00009493,
793 0x0000a493,0x0000a49b,0x000126dc,0x00009292},
794 {0x00000000,0x00000000,0x0000924a,0x00009493,
795 0x0000a493,0x0000a49b,0x000126dc,0x00009493},
796 {0x00000000,0x00000000,0x0000924a,0x00009493,
797 0x0000a493,0x0000a49b,0x000126dc,0x00009493},
798 {0x00000000,0x00000000,0x0000924a,0x00009493,
799 0x0000a493,0x000124db,0x000126dc,0x00009493},
800 {0x00000000,0x00000000,0x0000924a,0x00009493,
801 0x0000a493,0x000124db,0x000126dc,0x0000a49b},
802 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
803 0x0000a493,0x000124db,0x000126dc,0x0000a49b},
804 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
805 0x0001249b,0x000126dc,0x000126dc,0x0000a49b},
806 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
807 0x000124db,0x000136e4,0x000126dc,0x000124db},
808 {0x00000000,0x00000000,0x00009492,0x0000a49b,
809 0x000136e4,0x000136e4,0x000126dc,0x000124db},
810 {0x00000000,0x00000000,0x0000a492,0x000124db,
811 0x0001b724,0x0001b724,0x000136e4,0x000126dc},
812 {0x00000000,0x00000000,0x00000000,0x00000000,
813 0x00000000,0x00000000,0x00000000,0x00000000}
814 }
815 },
816 { /* version 7 */
817 { /* version 7, passes 0 */
818 {0x00000000,0x00000000,0x00001249,0x00001249,
819 0x00009292,0x00009493,0x0000a49b,0x000124db},
820 {0x00000000,0x00000000,0x00001249,0x00009292,
821 0x0000a493,0x0000a49b,0x000124db,0x000126dc},
822 {0x00000000,0x00000000,0x00001249,0x00009493,
823 0x0000a493,0x000124db,0x000126dc,0x000136e4},
824 {0x00000000,0x00000000,0x00001249,0x00009493,
825 0x0000a493,0x000124db,0x000136e4,0x000136e4},
826 {0x00000000,0x00000000,0x00001249,0x00009493,
827 0x0001249b,0x000126dc,0x000136e4,0x000136e4},
828 {0x00000000,0x00000000,0x00001249,0x0000a49b,
829 0x0001249b,0x000126dc,0x000136e4,0x0001b724},
830 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
831 0x0001249b,0x000126dc,0x000136e4,0x0001b724},
832 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
833 0x000124db,0x000136e4,0x0001b725,0x0001b724},
834 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
835 0x000126dc,0x000136e4,0x0001b725,0x0001b925},
836 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
837 0x000126dc,0x0001b724,0x0001b92d,0x0001b925},
838 {0x00000000,0x00000000,0x00009292,0x0000a49b,
839 0x000126dc,0x0001b724,0x0001c96e,0x0001c92d},
840 {0x00000000,0x00000000,0x00009292,0x000124db,
841 0x000126dc,0x0001b724,0x0001c96e,0x0001c92d},
842 {0x00000000,0x00000000,0x00009492,0x000124db,
843 0x000136e4,0x0001b724,0x0001c96e,0x0002496e},
844 {0x00000000,0x00000000,0x00009492,0x000126db,
845 0x000136e4,0x0001b925,0x0001c96e,0x0002496e},
846 {0x00000000,0x00000000,0x0000a492,0x000136db,
847 0x0001b724,0x0002496d,0x00025bb6,0x00025bbf},
848 {0x00000000,0x00000000,0x00000000,0x00000000,
849 0x00000000,0x00000000,0x00000000,0x00000000}
850 },
851 { /* version 7, passes 1 */
852 {0x00000000,0x00000000,0x00001249,0x00001249,
853 0x00009252,0x00009292,0x00009292,0x00009292},
854 {0x00000000,0x00000000,0x00001249,0x0000924a,
855 0x00009492,0x00009493,0x00009493,0x00009292},
856 {0x00000000,0x00000000,0x00001249,0x00009493,
857 0x0000a493,0x0000a49b,0x0000a49b,0x00009292},
858 {0x00000000,0x00000000,0x0000924a,0x00009493,
859 0x0000a493,0x0000a49b,0x000124db,0x00009493},
860 {0x00000000,0x00000000,0x0000924a,0x00009493,
861 0x0000a493,0x000124db,0x000124db,0x00009493},
862 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
863 0x0000a493,0x000124db,0x000136e4,0x00009493},
864 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
865 0x0000a493,0x000124db,0x000136e4,0x0000a49b},
866 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
867 0x0001249b,0x000124db,0x000136e4,0x0000a49b},
868 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
869 0x0001249b,0x000126dc,0x000136e4,0x0000a49b},
870 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
871 0x0001249b,0x000126dc,0x000136e4,0x000124db},
872 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
873 0x000126dc,0x000136e4,0x000136e4,0x000124db},
874 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
875 0x000126dc,0x000136e4,0x000136e4,0x000124db},
876 {0x00000000,0x00000000,0x0000924a,0x000124db,
877 0x000136e4,0x000136e4,0x000136e4,0x000126dc},
878 {0x00000000,0x00000000,0x0000a492,0x000124db,
879 0x000136e4,0x0001b724,0x000136e4,0x000126dc},
880 {0x00000000,0x00000000,0x00012492,0x000126db,
881 0x0001b724,0x0001b925,0x0001b725,0x000136e4},
882 {0x00000000,0x00000000,0x00000000,0x00000000,
883 0x00000000,0x00000000,0x00000000,0x00000000}
884 }
885 },
886 { /* version 8 */
887 { /* version 8, passes 0 */
888 {0x00000000,0x00000000,0x00001249,0x00001249,
889 0x00009292,0x00009493,0x0000a49b,0x000124db},
890 {0x00000000,0x00000000,0x00001249,0x00009292,
891 0x0000a493,0x000124db,0x000126dc,0x000126dc},
892 {0x00000000,0x00000000,0x00001249,0x00009493,
893 0x0000a493,0x000124db,0x000126dc,0x000136e4},
894 {0x00000000,0x00000000,0x00001249,0x0000a49b,
895 0x0001249b,0x000126dc,0x000136e4,0x0001b724},
896 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
897 0x0001249b,0x000126dc,0x000136e4,0x0001b724},
898 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
899 0x000124db,0x000136e4,0x0001b725,0x0001b724},
900 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
901 0x000126dc,0x000136e4,0x0001b725,0x0001b925},
902 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
903 0x000126dc,0x0001b724,0x0001b92d,0x0001c92d},
904 {0x00000000,0x00000000,0x00009252,0x000124db,
905 0x000126dc,0x0001b724,0x0001b92d,0x0001c92d},
906 {0x00000000,0x00000000,0x00009292,0x000124db,
907 0x000126dc,0x0001b925,0x0001c96e,0x0001c92d},
908 {0x00000000,0x00000000,0x00009492,0x000124db,
909 0x000136e4,0x0001b925,0x0001c96e,0x0001c92d},
910 {0x00000000,0x00000000,0x00009492,0x000124db,
911 0x000136e4,0x0001b925,0x00024b76,0x00024b77},
912 {0x00000000,0x00000000,0x00009492,0x000126db,
913 0x000136e4,0x0001b925,0x00024b76,0x00025bbf},
914 {0x00000000,0x00000000,0x0000a492,0x000126db,
915 0x000136e4,0x0001c92d,0x00024b76,0x00025bbf},
916 {0x00000000,0x00000000,0x00012492,0x000136db,
917 0x0001b724,0x00024b6d,0x0002ddb6,0x0002efff},
918 {0x00000000,0x00000000,0x00000000,0x00000000,
919 0x00000000,0x00000000,0x00000000,0x00000000}
920 },
921 { /* version 8, passes 1 */
922 {0x00000000,0x00000000,0x00001249,0x00001249,
923 0x00009252,0x00009493,0x00009493,0x00009493},
924 {0x00000000,0x00000000,0x00001249,0x00009292,
925 0x0000a493,0x0000a49b,0x0000a49b,0x00009493},
926 {0x00000000,0x00000000,0x0000924a,0x00009493,
927 0x0000a493,0x0000a49b,0x000124db,0x00009493},
928 {0x00000000,0x00000000,0x0000924a,0x00009493,
929 0x0000a493,0x000124db,0x000126dc,0x0000a49b},
930 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
931 0x0000a493,0x000124db,0x000126dc,0x0000a49b},
932 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
933 0x0000a493,0x000124db,0x000136e4,0x000124db},
934 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
935 0x0001249b,0x000126dc,0x000136e4,0x000124db},
936 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
937 0x000126dc,0x000126dc,0x000136e4,0x000126dc},
938 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
939 0x000126dc,0x000136e4,0x000136e4,0x000126dc},
940 {0x00000000,0x00000000,0x0000924a,0x000124db,
941 0x000126dc,0x000136e4,0x000136e4,0x000126dc},
942 {0x00000000,0x00000000,0x0000924a,0x000124db,
943 0x000126dc,0x000136e4,0x000136e4,0x000136e4},
944 {0x00000000,0x00000000,0x00009292,0x000124db,
945 0x000136e4,0x0001b724,0x0001b725,0x000136e4},
946 {0x00000000,0x00000000,0x00009492,0x000126db,
947 0x000136e4,0x0001b925,0x0001b725,0x0001b724},
948 {0x00000000,0x00000000,0x00009492,0x000126db,
949 0x000136e4,0x0001b925,0x0001b725,0x0001b724},
950 {0x00000000,0x00000000,0x0000a492,0x000136db,
951 0x0001b724,0x0002496d,0x0001b92d,0x0001b925},
952 {0x00000000,0x00000000,0x00000000,0x00000000,
953 0x00000000,0x00000000,0x00000000,0x00000000}
954 }
955 },
956 { /* version 9 */
957 { /* version 9, passes 0 */
958 {0x00000000,0x00000000,0x00000049,0x00000049,
959 0x00000049,0x00000049,0x00000049,0x00000049},
960 {0x00000000,0x00000000,0x00000249,0x00000049,
961 0x00000249,0x00000249,0x0000024a,0x00000049},
962 {0x00000000,0x00000000,0x00000249,0x00000249,
963 0x0000124a,0x00009252,0x00001252,0x0000024a},
964 {0x00000000,0x00000000,0x00001249,0x00001249,
965 0x00009252,0x00009292,0x00009493,0x00001252},
966 {0x00000000,0x00000000,0x00001249,0x0000924a,
967 0x00009292,0x00009493,0x00009493,0x00001252},
968 {0x00000000,0x00000000,0x00001249,0x00009292,
969 0x00009492,0x0000a49b,0x0000a49b,0x00009292},
970 {0x00000000,0x00000000,0x00001249,0x00009493,
971 0x0000a493,0x000124db,0x000124db,0x00009493},
972 {0x00000000,0x00000000,0x0000924a,0x00009493,
973 0x0000a493,0x000124db,0x000126dc,0x0000a49b},
974 {0x00000000,0x00000000,0x0000924a,0x00009493,
975 0x0000a493,0x000124db,0x000126dc,0x0000a49b},
976 {0x00000000,0x00000000,0x0000924a,0x00009493,
977 0x0001249b,0x000126dc,0x000126dc,0x000124db},
978 {0x00000000,0x00000000,0x00009252,0x00009493,
979 0x000124db,0x000136e4,0x000136e4,0x000126dc},
980 {0x00000000,0x00000000,0x00009252,0x0000a49b,
981 0x000124db,0x000136e4,0x000136e4,0x000126dc},
982 {0x00000000,0x00000000,0x00009292,0x0000a49b,
983 0x000126dc,0x000136e4,0x000136e4,0x000136e4},
984 {0x00000000,0x00000000,0x00009492,0x0000a49b,
985 0x000126dc,0x0001b724,0x0001b725,0x0001b724},
986 {0x00000000,0x00000000,0x0000a492,0x000124db,
987 0x000136e4,0x0001b925,0x0001b92d,0x0001b925},
988 {0x00000000,0x00000000,0x00000000,0x00000000,
989 0x00000000,0x00000000,0x00000000,0x00000000}
990 },
991 { /* version 9, passes 1 */
992 {0x00000000,0x00000000,0x00000249,0x00000049,
993 0x00000009,0x00000009,0x00000009,0x00000009},
994 {0x00000000,0x00000000,0x00000249,0x00000249,
995 0x00000049,0x00000049,0x00000009,0x00000009},
996 {0x00000000,0x00000000,0x00001249,0x00001249,
997 0x0000124a,0x00000249,0x00000049,0x00000049},
998 {0x00000000,0x00000000,0x00001249,0x00001249,
999 0x0000124a,0x0000124a,0x00000049,0x00000049},
1000 {0x00000000,0x00000000,0x00001249,0x00001249,
1001 0x00009252,0x0000124a,0x0000024a,0x0000024a},
1002 {0x00000000,0x00000000,0x00001249,0x0000924a,
1003 0x00009252,0x0000124a,0x0000024a,0x0000024a},
1004 {0x00000000,0x00000000,0x00001249,0x00009292,
1005 0x00009492,0x00009252,0x00001252,0x00001252},
1006 {0x00000000,0x00000000,0x00001249,0x00009493,
1007 0x0000a493,0x00009292,0x00009292,0x00001252},
1008 {0x00000000,0x00000000,0x0000924a,0x00009493,
1009 0x0000a493,0x00009292,0x00009292,0x00009292},
1010 {0x00000000,0x00000000,0x0000924a,0x00009493,
1011 0x0000a493,0x00009493,0x00009493,0x00009292},
1012 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1013 0x0000a493,0x0000a49b,0x00009493,0x00009493},
1014 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1015 0x0000a493,0x0000a49b,0x0000a49b,0x00009493},
1016 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1017 0x0001249b,0x000124db,0x0000a49b,0x0000a49b},
1018 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1019 0x000136e4,0x000126dc,0x000124db,0x0000a49b},
1020 {0x00000000,0x00000000,0x00009252,0x000124db,
1021 0x0001b724,0x000136e4,0x000126dc,0x000124db},
1022 {0x00000000,0x00000000,0x00000000,0x00000000,
1023 0x00000000,0x00000000,0x00000000,0x00000000}
1024 }
1025 },
1026 { /* version 10 */
1027 { /* version 10, passes 0 */
1028 {0x00000000,0x00000000,0x00000249,0x00000249,
1029 0x00000249,0x00000249,0x0000024a,0x0000024a},
1030 {0x00000000,0x00000000,0x00000249,0x00001249,
1031 0x00009252,0x00009292,0x00009292,0x0000024a},
1032 {0x00000000,0x00000000,0x00001249,0x00001249,
1033 0x00009252,0x00009292,0x00009292,0x00001252},
1034 {0x00000000,0x00000000,0x00001249,0x0000924a,
1035 0x00009492,0x00009493,0x0000a49b,0x00009292},
1036 {0x00000000,0x00000000,0x00001249,0x00009292,
1037 0x00009492,0x000124db,0x000124db,0x00009292},
1038 {0x00000000,0x00000000,0x00001249,0x00009493,
1039 0x0000a493,0x000124db,0x000124db,0x00009493},
1040 {0x00000000,0x00000000,0x00001249,0x00009493,
1041 0x0000a493,0x000124db,0x000126dc,0x0000a49b},
1042 {0x00000000,0x00000000,0x0000924a,0x00009493,
1043 0x0000a493,0x000124db,0x000126dc,0x000124db},
1044 {0x00000000,0x00000000,0x0000924a,0x00009493,
1045 0x0001249b,0x000126dc,0x000126dc,0x000124db},
1046 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1047 0x000124db,0x000126dc,0x000136e4,0x000126dc},
1048 {0x00000000,0x00000000,0x00009252,0x0000a49b,
1049 0x000124db,0x000136e4,0x000136e4,0x000136e4},
1050 {0x00000000,0x00000000,0x00009292,0x0000a49b,
1051 0x000126dc,0x000136e4,0x000136e4,0x000136e4},
1052 {0x00000000,0x00000000,0x00009492,0x0000a49b,
1053 0x000126dc,0x0001b724,0x0001b92d,0x0001b724},
1054 {0x00000000,0x00000000,0x00009492,0x000124db,
1055 0x000126dc,0x0001b925,0x0001b92d,0x0001b925},
1056 {0x00000000,0x00000000,0x0000a492,0x000126db,
1057 0x000136e4,0x0002496d,0x0001c96e,0x0001c92d},
1058 {0x00000000,0x00000000,0x00000000,0x00000000,
1059 0x00000000,0x00000000,0x00000000,0x00000000}
1060 },
1061 { /* version 10, passes 1 */
1062 {0x00000000,0x00000000,0x00000249,0x00000249,
1063 0x00000049,0x00000049,0x00000049,0x00000049},
1064 {0x00000000,0x00000000,0x00001249,0x00001249,
1065 0x0000124a,0x00000249,0x00000049,0x00000049},
1066 {0x00000000,0x00000000,0x00001249,0x00001249,
1067 0x0000124a,0x00009252,0x0000024a,0x00000049},
1068 {0x00000000,0x00000000,0x00001249,0x00001249,
1069 0x00009252,0x00009493,0x0000024a,0x0000024a},
1070 {0x00000000,0x00000000,0x00001249,0x00009252,
1071 0x00009492,0x00009493,0x00001252,0x0000024a},
1072 {0x00000000,0x00000000,0x00001249,0x00009292,
1073 0x00009492,0x00009493,0x00001252,0x00001252},
1074 {0x00000000,0x00000000,0x0000924a,0x00009493,
1075 0x00009492,0x00009493,0x00009292,0x00001252},
1076 {0x00000000,0x00000000,0x0000924a,0x00009493,
1077 0x0000a493,0x00009493,0x00009292,0x00009292},
1078 {0x00000000,0x00000000,0x0000924a,0x00009493,
1079 0x0000a493,0x0000a49b,0x00009493,0x00009292},
1080 {0x00000000,0x00000000,0x0000924a,0x00009493,
1081 0x0000a493,0x0000a49b,0x00009493,0x00009292},
1082 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1083 0x0000a493,0x000124db,0x0000a49b,0x00009493},
1084 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1085 0x0000a493,0x000124db,0x0000a49b,0x00009493},
1086 {0x00000000,0x00000000,0x0000924a,0x000124db,
1087 0x000136e4,0x000126dc,0x000124db,0x0000a49b},
1088 {0x00000000,0x00000000,0x0000924a,0x000124db,
1089 0x000136e4,0x000126dc,0x000124db,0x0000a49b},
1090 {0x00000000,0x00000000,0x00009252,0x000126db,
1091 0x0001b724,0x000136e4,0x000126dc,0x000124db},
1092 {0x00000000,0x00000000,0x00000000,0x00000000,
1093 0x00000000,0x00000000,0x00000000,0x00000000}
1094 }
1095 },
1096 { /* version 11 */
1097 { /* version 11, passes 0 */
1098 {0x00000000,0x00000000,0x00000249,0x00000249,
1099 0x00000249,0x00000249,0x00001252,0x00001252},
1100 {0x00000000,0x00000000,0x00001249,0x00001249,
1101 0x00009252,0x00009292,0x00009292,0x00001252},
1102 {0x00000000,0x00000000,0x00001249,0x0000924a,
1103 0x00009492,0x0000a49b,0x0000a49b,0x00009292},
1104 {0x00000000,0x00000000,0x00001249,0x00009493,
1105 0x0000a493,0x0000a49b,0x000124db,0x00009493},
1106 {0x00000000,0x00000000,0x00001249,0x00009493,
1107 0x0000a493,0x000124db,0x000126dc,0x00009493},
1108 {0x00000000,0x00000000,0x0000924a,0x00009493,
1109 0x0000a493,0x000126dc,0x000126dc,0x0000a49b},
1110 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1111 0x0001249b,0x000126dc,0x000136e4,0x000124db},
1112 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1113 0x000126dc,0x000136e4,0x000136e4,0x000126dc},
1114 {0x00000000,0x00000000,0x00009292,0x0000a49b,
1115 0x000126dc,0x000136e4,0x000136e4,0x000126dc},
1116 {0x00000000,0x00000000,0x00009292,0x0000a49b,
1117 0x000126dc,0x0001b724,0x0001b725,0x000136e4},
1118 {0x00000000,0x00000000,0x00009292,0x0000a49b,
1119 0x000136e4,0x0001b724,0x0001b92d,0x0001b724},
1120 {0x00000000,0x00000000,0x00009492,0x0000a49b,
1121 0x000136e4,0x0001b724,0x0001b92d,0x0001b724},
1122 {0x00000000,0x00000000,0x00009492,0x000124db,
1123 0x000136e4,0x0001b925,0x0001c96e,0x0001b925},
1124 {0x00000000,0x00000000,0x00009492,0x000124db,
1125 0x0001b724,0x0001b925,0x0001c96e,0x0001c92d},
1126 {0x00000000,0x00000000,0x0000a492,0x000126db,
1127 0x0001c924,0x0002496d,0x00025bb6,0x00024b77},
1128 {0x00000000,0x00000000,0x00000000,0x00000000,
1129 0x00000000,0x00000000,0x00000000,0x00000000}
1130 },
1131 { /* version 11, passes 1 */
1132 {0x00000000,0x00000000,0x00001249,0x00000249,
1133 0x00000249,0x00000249,0x0000024a,0x0000024a},
1134 {0x00000000,0x00000000,0x00001249,0x00001249,
1135 0x0000124a,0x0000124a,0x0000024a,0x0000024a},
1136 {0x00000000,0x00000000,0x00001249,0x0000924a,
1137 0x00009252,0x00009252,0x0000024a,0x0000024a},
1138 {0x00000000,0x00000000,0x00001249,0x00009292,
1139 0x00009492,0x0000a49b,0x00001252,0x00001252},
1140 {0x00000000,0x00000000,0x0000924a,0x00009493,
1141 0x0000a493,0x0000a49b,0x00001252,0x00001252},
1142 {0x00000000,0x00000000,0x0000924a,0x00009493,
1143 0x0000a493,0x0000a49b,0x00009292,0x00001252},
1144 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1145 0x0000a493,0x0000a49b,0x00009292,0x00009292},
1146 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1147 0x0000a493,0x0000a49b,0x00009493,0x00009292},
1148 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1149 0x0001249b,0x000124db,0x00009493,0x00009292},
1150 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1151 0x0001249b,0x000124db,0x00009493,0x00009493},
1152 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1153 0x000124db,0x000124db,0x0000a49b,0x00009493},
1154 {0x00000000,0x00000000,0x0000924a,0x000124db,
1155 0x000126dc,0x000126dc,0x0000a49b,0x00009493},
1156 {0x00000000,0x00000000,0x0000924a,0x000124db,
1157 0x000136e4,0x000126dc,0x000124db,0x0000a49b},
1158 {0x00000000,0x00000000,0x00009292,0x000124db,
1159 0x000136e4,0x000126dc,0x000124db,0x0000a49b},
1160 {0x00000000,0x00000000,0x00009492,0x000126db,
1161 0x0001b724,0x000136e4,0x000126dc,0x000124db},
1162 {0x00000000,0x00000000,0x00000000,0x00000000,
1163 0x00000000,0x00000000,0x00000000,0x00000000}
1164 }
1165 },
1166 { /* version 12 */
1167 { /* version 12, passes 0 */
1168 {0x00000000,0x00000000,0x00001249,0x00001249,
1169 0x00009252,0x00009292,0x00009493,0x00009493},
1170 {0x00000000,0x00000000,0x00001249,0x00009292,
1171 0x0000a493,0x0000a49b,0x0000a49b,0x00009493},
1172 {0x00000000,0x00000000,0x00001249,0x00009493,
1173 0x0000a493,0x000124db,0x000124db,0x0000a49b},
1174 {0x00000000,0x00000000,0x0000924a,0x00009493,
1175 0x0000a493,0x000126dc,0x000126dc,0x0000a49b},
1176 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1177 0x0001249b,0x000126dc,0x000136e4,0x000124db},
1178 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1179 0x000126dc,0x000136e4,0x000136e4,0x000126dc},
1180 {0x00000000,0x00000000,0x00009292,0x0000a49b,
1181 0x000126dc,0x0001b724,0x0001b725,0x000126dc},
1182 {0x00000000,0x00000000,0x00009292,0x0000a49b,
1183 0x000136e4,0x0001b724,0x0001b92d,0x000136e4},
1184 {0x00000000,0x00000000,0x00009492,0x0000a49b,
1185 0x000136e4,0x0001b724,0x0001b92d,0x0001b724},
1186 {0x00000000,0x00000000,0x00009492,0x000124db,
1187 0x000136e4,0x0001b724,0x0001b92d,0x0001b724},
1188 {0x00000000,0x00000000,0x00009492,0x000124db,
1189 0x000136e4,0x0001b925,0x0001b92d,0x0001b925},
1190 {0x00000000,0x00000000,0x00009492,0x000124db,
1191 0x0001b724,0x0001b925,0x0001c96e,0x0001c92d},
1192 {0x00000000,0x00000000,0x0000a492,0x000124db,
1193 0x0001b724,0x0001c92d,0x0001c96e,0x0001c92d},
1194 {0x00000000,0x00000000,0x0000a492,0x000124db,
1195 0x0001b724,0x0001c92d,0x00024b76,0x0002496e},
1196 {0x00000000,0x00000000,0x00012492,0x000126db,
1197 0x0001c924,0x00024b6d,0x0002ddb6,0x00025bbf},
1198 {0x00000000,0x00000000,0x00000000,0x00000000,
1199 0x00000000,0x00000000,0x00000000,0x00000000}
1200 },
1201 { /* version 12, passes 1 */
1202 {0x00000000,0x00000000,0x00001249,0x00001249,
1203 0x0000124a,0x0000124a,0x00001252,0x00001252},
1204 {0x00000000,0x00000000,0x00001249,0x00009292,
1205 0x00009492,0x00009252,0x00001252,0x00001252},
1206 {0x00000000,0x00000000,0x0000924a,0x00009493,
1207 0x0000a493,0x00009292,0x00001252,0x00001252},
1208 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1209 0x0000a493,0x0000a49b,0x00009292,0x00009292},
1210 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1211 0x0000a493,0x0000a49b,0x00009292,0x00009292},
1212 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1213 0x0001249b,0x0000a49b,0x00009493,0x00009292},
1214 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1215 0x000124db,0x000124db,0x00009493,0x00009493},
1216 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1217 0x000124db,0x000124db,0x0000a49b,0x00009493},
1218 {0x00000000,0x00000000,0x0000924a,0x000124db,
1219 0x000126dc,0x000124db,0x0000a49b,0x00009493},
1220 {0x00000000,0x00000000,0x0000924a,0x000124db,
1221 0x000126dc,0x000126dc,0x0000a49b,0x0000a49b},
1222 {0x00000000,0x00000000,0x0000924a,0x000124db,
1223 0x000136e4,0x000126dc,0x000124db,0x0000a49b},
1224 {0x00000000,0x00000000,0x00009492,0x000126db,
1225 0x000136e4,0x000126dc,0x000124db,0x0000a49b},
1226 {0x00000000,0x00000000,0x00009492,0x000126db,
1227 0x0001b724,0x000136e4,0x000126dc,0x000124db},
1228 {0x00000000,0x00000000,0x00009492,0x000126db,
1229 0x0001b724,0x000136e4,0x000126dc,0x000124db},
1230 {0x00000000,0x00000000,0x0000a492,0x000136db,
1231 0x0001c924,0x0001b724,0x000136e4,0x000126dc},
1232 {0x00000000,0x00000000,0x00000000,0x00000000,
1233 0x00000000,0x00000000,0x00000000,0x00000000}
1234 }
1235 },
1236 { /* version 13 */
1237 { /* version 13, passes 0 */
1238 {0x00000000,0x00000000,0x00001249,0x00001249,
1239 0x00009252,0x00009292,0x00009493,0x00009493},
1240 {0x00000000,0x00000000,0x00001249,0x00009493,
1241 0x0000a493,0x000124db,0x000126dc,0x00009493},
1242 {0x00000000,0x00000000,0x00001249,0x0000a49b,
1243 0x0001249b,0x000126dc,0x000126dc,0x0000a49b},
1244 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1245 0x0001249b,0x000126dc,0x000136e4,0x0000a49b},
1246 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1247 0x000126dc,0x000136e4,0x0001b725,0x000124db},
1248 {0x00000000,0x00000000,0x00009292,0x0000a49b,
1249 0x000136e4,0x0001b724,0x0001b725,0x000126dc},
1250 {0x00000000,0x00000000,0x00009292,0x000124db,
1251 0x000136e4,0x0001b724,0x0001b725,0x000126dc},
1252 {0x00000000,0x00000000,0x00009492,0x000124db,
1253 0x000136e4,0x0001b724,0x0001c96e,0x000136e4},
1254 {0x00000000,0x00000000,0x00009492,0x000124db,
1255 0x000136e4,0x0001c92d,0x0001c96e,0x0001b724},
1256 {0x00000000,0x00000000,0x0000a492,0x000124db,
1257 0x000136e4,0x0001c92d,0x0001c96e,0x0001b724},
1258 {0x00000000,0x00000000,0x0000a492,0x000124db,
1259 0x0001b724,0x0001c92d,0x0001c96e,0x0001b925},
1260 {0x00000000,0x00000000,0x0000a492,0x000126db,
1261 0x0001b724,0x0001c92d,0x00024b76,0x0001c92d},
1262 {0x00000000,0x00000000,0x0000a492,0x000126db,
1263 0x0001b924,0x0001c92d,0x00024b76,0x0001c92d},
1264 {0x00000000,0x00000000,0x0000a492,0x000126db,
1265 0x0001b924,0x0001c92d,0x00024b76,0x0002496e},
1266 {0x00000000,0x00000000,0x00012492,0x000136db,
1267 0x00024924,0x00024b6d,0x0002ddb6,0x00025bbf},
1268 {0x00000000,0x00000000,0x00000000,0x00000000,
1269 0x00000000,0x00000000,0x00000000,0x00000000}
1270 },
1271 { /* version 13, passes 1 */
1272 {0x00000000,0x00000000,0x00001249,0x00001249,
1273 0x0000124a,0x0000124a,0x00001252,0x00001252},
1274 {0x00000000,0x00000000,0x0000924a,0x00009493,
1275 0x00009492,0x00009292,0x00001252,0x00001252},
1276 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1277 0x0000a493,0x0000a49b,0x00001252,0x00001252},
1278 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1279 0x0000a493,0x0000a49b,0x00009292,0x00009292},
1280 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1281 0x0000a493,0x0000a49b,0x00009292,0x00009292},
1282 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1283 0x000126dc,0x0000a49b,0x00009493,0x00009292},
1284 {0x00000000,0x00000000,0x0000924a,0x000124db,
1285 0x000126dc,0x000124db,0x00009493,0x00009493},
1286 {0x00000000,0x00000000,0x0000924a,0x000124db,
1287 0x000136e4,0x000124db,0x0000a49b,0x00009493},
1288 {0x00000000,0x00000000,0x0000924a,0x000136db,
1289 0x0001b724,0x000124db,0x0000a49b,0x00009493},
1290 {0x00000000,0x00000000,0x0000924a,0x000136db,
1291 0x0001b724,0x000126dc,0x0000a49b,0x0000a49b},
1292 {0x00000000,0x00000000,0x00009292,0x000136db,
1293 0x0001b724,0x000126dc,0x000124db,0x0000a49b},
1294 {0x00000000,0x00000000,0x00009492,0x000136db,
1295 0x0001b724,0x000126dc,0x000124db,0x0000a49b},
1296 {0x00000000,0x00000000,0x0000a492,0x000136db,
1297 0x0001b724,0x000136e4,0x000126dc,0x000124db},
1298 {0x00000000,0x00000000,0x0000a492,0x000136db,
1299 0x0001b724,0x000136e4,0x000126dc,0x000124db},
1300 {0x00000000,0x00000000,0x00012492,0x0001b6db,
1301 0x0001c924,0x0001b724,0x000136e4,0x000126dc},
1302 {0x00000000,0x00000000,0x00000000,0x00000000,
1303 0x00000000,0x00000000,0x00000000,0x00000000}
1304 }
1305 },
1306 { /* version 14 */
1307 { /* version 14, passes 0 */
1308 {0x00000000,0x00000000,0x00001249,0x0000924a,
1309 0x00009292,0x00009493,0x00009493,0x00009493},
1310 {0x00000000,0x00000000,0x00001249,0x0000a49b,
1311 0x0000a493,0x000124db,0x000126dc,0x00009493},
1312 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1313 0x0001249b,0x000126dc,0x000136e4,0x0000a49b},
1314 {0x00000000,0x00000000,0x0000924a,0x000124db,
1315 0x000126dc,0x000136e4,0x0001b725,0x000124db},
1316 {0x00000000,0x00000000,0x00009292,0x000124db,
1317 0x000126dc,0x0001b724,0x0001b92d,0x000126dc},
1318 {0x00000000,0x00000000,0x00009492,0x000124db,
1319 0x000136e4,0x0001b724,0x0001b92d,0x000126dc},
1320 {0x00000000,0x00000000,0x00009492,0x000124db,
1321 0x000136e4,0x0001c92d,0x0001c96e,0x000136e4},
1322 {0x00000000,0x00000000,0x00009492,0x000124db,
1323 0x0001b724,0x0001c92d,0x0001c96e,0x0001b724},
1324 {0x00000000,0x00000000,0x0000a492,0x000124db,
1325 0x0001b724,0x0001c92d,0x00024b76,0x0001b925},
1326 {0x00000000,0x00000000,0x0000a492,0x000126db,
1327 0x0001b724,0x0001c92d,0x00024b76,0x0001c92d},
1328 {0x00000000,0x00000000,0x0000a492,0x000126db,
1329 0x0001b724,0x0001c92d,0x00024b76,0x0001c92d},
1330 {0x00000000,0x00000000,0x0000a492,0x000136db,
1331 0x0001b724,0x0001c92d,0x00024b76,0x0002496e},
1332 {0x00000000,0x00000000,0x0000a492,0x000136db,
1333 0x0001b924,0x0002496d,0x00024b76,0x00024b77},
1334 {0x00000000,0x00000000,0x0000a492,0x000136db,
1335 0x0001b924,0x00024b6d,0x0002ddb6,0x00025bbf},
1336 {0x00000000,0x00000000,0x00012492,0x0001b6db,
1337 0x00024924,0x0002db6d,0x00036db6,0x0002efff},
1338 {0x00000000,0x00000000,0x00000000,0x00000000,
1339 0x00000000,0x00000000,0x00000000,0x00000000}
1340 },
1341 { /* version 14, passes 1 */
1342 {0x00000000,0x00000000,0x00001249,0x00001249,
1343 0x0000124a,0x0000124a,0x00001252,0x00001252},
1344 {0x00000000,0x00000000,0x0000924a,0x00009493,
1345 0x0000a493,0x00009292,0x00001252,0x00001252},
1346 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1347 0x0000a493,0x0000a49b,0x00001252,0x00001252},
1348 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1349 0x0001249b,0x000136e4,0x00009292,0x00009292},
1350 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1351 0x0001249b,0x000136e4,0x00009292,0x00009292},
1352 {0x00000000,0x00000000,0x0000924a,0x000124db,
1353 0x000136e4,0x000136e4,0x00009493,0x00009292},
1354 {0x00000000,0x00000000,0x00009492,0x000136db,
1355 0x0001b724,0x000136e4,0x00009493,0x00009493},
1356 {0x00000000,0x00000000,0x00009492,0x000136db,
1357 0x0001b724,0x000136e4,0x0000a49b,0x00009493},
1358 {0x00000000,0x00000000,0x00009492,0x000136db,
1359 0x0001b724,0x000136e4,0x0000a49b,0x00009493},
1360 {0x00000000,0x00000000,0x00009492,0x000136db,
1361 0x0001b724,0x000136e4,0x0000a49b,0x0000a49b},
1362 {0x00000000,0x00000000,0x0000a492,0x000136db,
1363 0x0001b724,0x000136e4,0x000124db,0x0000a49b},
1364 {0x00000000,0x00000000,0x0000a492,0x000136db,
1365 0x0001b724,0x000136e4,0x000124db,0x0000a49b},
1366 {0x00000000,0x00000000,0x0000a492,0x000136db,
1367 0x0001b724,0x000136e4,0x000126dc,0x000124db},
1368 {0x00000000,0x00000000,0x0000a492,0x000136db,
1369 0x0001b724,0x000136e4,0x000126dc,0x000124db},
1370 {0x00000000,0x00000000,0x00012492,0x0001b6db,
1371 0x0001c924,0x0001b724,0x000136e4,0x000126dc},
1372 {0x00000000,0x00000000,0x00000000,0x00000000,
1373 0x00000000,0x00000000,0x00000000,0x00000000}
1374 }
1375 },
1376 { /* version 15 */
1377 { /* version 15, passes 0 */
1378 {0x00000000,0x00000000,0x00001249,0x00009493,
1379 0x0000a493,0x0000a49b,0x000124db,0x000124db},
1380 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1381 0x0001249b,0x000126dc,0x000136e4,0x000124db},
1382 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1383 0x000126dc,0x0001b724,0x0001b725,0x000126dc},
1384 {0x00000000,0x00000000,0x0000924a,0x000124db,
1385 0x000136e4,0x0001b724,0x0001b92d,0x000126dc},
1386 {0x00000000,0x00000000,0x00009492,0x000124db,
1387 0x000136e4,0x0001b925,0x0001c96e,0x000136e4},
1388 {0x00000000,0x00000000,0x00009492,0x000124db,
1389 0x0001b724,0x0001c92d,0x0001c96e,0x0001b724},
1390 {0x00000000,0x00000000,0x0000a492,0x000124db,
1391 0x0001b724,0x0001c92d,0x0001c96e,0x0001b724},
1392 {0x00000000,0x00000000,0x0000a492,0x000126db,
1393 0x0001b724,0x0001c92d,0x0001c96e,0x0001b925},
1394 {0x00000000,0x00000000,0x0000a492,0x000126db,
1395 0x0001b924,0x0001c92d,0x00024b76,0x0001c92d},
1396 {0x00000000,0x00000000,0x0000a492,0x000136db,
1397 0x0001b924,0x0001c92d,0x00024b76,0x0001c92d},
1398 {0x00000000,0x00000000,0x0000a492,0x000136db,
1399 0x0001b924,0x0002496d,0x00024b76,0x0002496e},
1400 {0x00000000,0x00000000,0x0000a492,0x000136db,
1401 0x0001c924,0x0002496d,0x00025bb6,0x00024b77},
1402 {0x00000000,0x00000000,0x0000a492,0x000136db,
1403 0x0001c924,0x00024b6d,0x00025bb6,0x00024b77},
1404 {0x00000000,0x00000000,0x00012492,0x000136db,
1405 0x0001c924,0x00024b6d,0x0002ddb6,0x00025bbf},
1406 {0x00000000,0x00000000,0x00012492,0x0001b6db,
1407 0x00024924,0x0002db6d,0x00036db6,0x0002efff},
1408 {0x00000000,0x00000000,0x00000000,0x00000000,
1409 0x00000000,0x00000000,0x00000000,0x00000000}
1410 },
1411 { /* version 15, passes 1 */
1412 {0x00000000,0x00000000,0x0000924a,0x0000924a,
1413 0x00009292,0x00009292,0x00009292,0x00009292},
1414 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1415 0x0000a493,0x000124db,0x00009292,0x00009292},
1416 {0x00000000,0x00000000,0x0000924a,0x000124db,
1417 0x000124db,0x0001b724,0x00009493,0x00009493},
1418 {0x00000000,0x00000000,0x0000924a,0x000124db,
1419 0x000126dc,0x0001b724,0x00009493,0x00009493},
1420 {0x00000000,0x00000000,0x0000924a,0x000124db,
1421 0x000136e4,0x0001b724,0x0000a49b,0x0000a49b},
1422 {0x00000000,0x00000000,0x00009292,0x000136db,
1423 0x0001b724,0x0001b724,0x0000a49b,0x0000a49b},
1424 {0x00000000,0x00000000,0x00009492,0x000136db,
1425 0x0001c924,0x0001b724,0x000124db,0x000124db},
1426 {0x00000000,0x00000000,0x00009492,0x000136db,
1427 0x0001c924,0x0001b724,0x000124db,0x000124db},
1428 {0x00000000,0x00000000,0x0000a492,0x000136db,
1429 0x0001c924,0x0001b724,0x000126dc,0x000126dc},
1430 {0x00000000,0x00000000,0x0000a492,0x000136db,
1431 0x0001c924,0x0001b925,0x000126dc,0x000126dc},
1432 {0x00000000,0x00000000,0x0000a492,0x000136db,
1433 0x0001c924,0x0001b925,0x000136e4,0x000136e4},
1434 {0x00000000,0x00000000,0x0000a492,0x000136db,
1435 0x0001c924,0x0001b925,0x000136e4,0x000136e4},
1436 {0x00000000,0x00000000,0x0000a492,0x000136db,
1437 0x0001c924,0x0001b925,0x0001b725,0x0001b724},
1438 {0x00000000,0x00000000,0x00012492,0x000136db,
1439 0x0001c924,0x0001b925,0x0001b725,0x0001b724},
1440 {0x00000000,0x00000000,0x00012492,0x0001b6db,
1441 0x00024924,0x0002496d,0x0001b92d,0x0001b925},
1442 {0x00000000,0x00000000,0x00000000,0x00000000,
1443 0x00000000,0x00000000,0x00000000,0x00000000}
1444 }
1445 }
1446};
diff --git a/drivers/usb/media/pwc/pwc-timon.h b/drivers/usb/media/pwc/pwc-timon.h
new file mode 100644
index 000000000000..a86b3782a081
--- /dev/null
+++ b/drivers/usb/media/pwc/pwc-timon.h
@@ -0,0 +1,61 @@
1/* Linux driver for Philips webcam
2 (C) 2004 Luc Saillard (luc@saillard.org)
3
4 NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx
5 driver and thus may have bugs that are not present in the original version.
6 Please send bug reports and support requests to <luc@saillard.org>.
7 The decompression routines have been implemented by reverse-engineering the
8 Nemosoft binary pwcx module. Caveat emptor.
9
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2 of the License, or
13 (at your option) any later version.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23*/
24
25
26
27/* This tables contains entries for the 675/680/690 (Timon) camera, with
28 4 different qualities (no compression, low, medium, high).
29 It lists the bandwidth requirements for said mode by its alternate interface
30 number. An alternate of 0 means that the mode is unavailable.
31
32 There are 6 * 4 * 4 entries:
33 6 different resolutions subqcif, qsif, qcif, sif, cif, vga
34 6 framerates: 5, 10, 15, 20, 25, 30
35 4 compression modi: none, low, medium, high
36
37 When an uncompressed mode is not available, the next available compressed mode
38 will be chosen (unless the decompressor is absent). Sometimes there are only
39 1 or 2 compressed modes available; in that case entries are duplicated.
40*/
41
42#ifndef PWC_TIMON_H
43#define PWC_TIMON_H
44
45#include "pwc-ioctl.h"
46
47struct Timon_table_entry
48{
49 char alternate; /* USB alternate interface */
50 unsigned short packetsize; /* Normal packet size */
51 unsigned short bandlength; /* Bandlength when decompressing */
52 unsigned char mode[13]; /* precomputed mode settings for cam */
53};
54
55const extern struct Timon_table_entry Timon_table[PSZ_MAX][6][4];
56const extern unsigned int TimonRomTable [16][2][16][8];
57
58
59#endif
60
61
diff --git a/drivers/usb/media/pwc/pwc-uncompress.c b/drivers/usb/media/pwc/pwc-uncompress.c
new file mode 100644
index 000000000000..c062e43b3ac5
--- /dev/null
+++ b/drivers/usb/media/pwc/pwc-uncompress.c
@@ -0,0 +1,147 @@
1/* Linux driver for Philips webcam
2 Decompression frontend.
3 (C) 1999-2003 Nemosoft Unv.
4 (C) 2004 Luc Saillard (luc@saillard.org)
5
6 NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx
7 driver and thus may have bugs that are not present in the original version.
8 Please send bug reports and support requests to <luc@saillard.org>.
9 The decompression routines have been implemented by reverse-engineering the
10 Nemosoft binary pwcx module. Caveat emptor.
11
12 This program is free software; you can redistribute it and/or modify
13 it under the terms of the GNU General Public License as published by
14 the Free Software Foundation; either version 2 of the License, or
15 (at your option) any later version.
16
17 This program is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 GNU General Public License for more details.
21
22 You should have received a copy of the GNU General Public License
23 along with this program; if not, write to the Free Software
24 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25*/
26
27#include <asm/current.h>
28#include <asm/types.h>
29
30#include "pwc.h"
31#include "pwc-uncompress.h"
32#include "pwc-dec1.h"
33#include "pwc-dec23.h"
34
35int pwc_decompress(struct pwc_device *pdev)
36{
37 struct pwc_frame_buf *fbuf;
38 int n, line, col, stride;
39 void *yuv, *image;
40 u16 *src;
41 u16 *dsty, *dstu, *dstv;
42
43 if (pdev == NULL)
44 return -EFAULT;
45#if defined(__KERNEL__) && defined(PWC_MAGIC)
46 if (pdev->magic != PWC_MAGIC) {
47 Err("pwc_decompress(): magic failed.\n");
48 return -EFAULT;
49 }
50#endif
51
52 fbuf = pdev->read_frame;
53 if (fbuf == NULL)
54 return -EFAULT;
55 image = pdev->image_ptr[pdev->fill_image];
56 if (!image)
57 return -EFAULT;
58
59 yuv = fbuf->data + pdev->frame_header_size; /* Skip header */
60
61 /* Raw format; that's easy... */
62 if (pdev->vpalette == VIDEO_PALETTE_RAW)
63 {
64 memcpy(image, yuv, pdev->frame_size);
65 return 0;
66 }
67
68 if (pdev->vbandlength == 0) {
69 /* Uncompressed mode. We copy the data into the output buffer,
70 using the viewport size (which may be larger than the image
71 size). Unfortunately we have to do a bit of byte stuffing
72 to get the desired output format/size.
73 */
74 /*
75 * We do some byte shuffling here to go from the
76 * native format to YUV420P.
77 */
78 src = (u16 *)yuv;
79 n = pdev->view.x * pdev->view.y;
80
81 /* offset in Y plane */
82 stride = pdev->view.x * pdev->offset.y + pdev->offset.x;
83 dsty = (u16 *)(image + stride);
84
85 /* offsets in U/V planes */
86 stride = pdev->view.x * pdev->offset.y / 4 + pdev->offset.x / 2;
87 dstu = (u16 *)(image + n + stride);
88 dstv = (u16 *)(image + n + n / 4 + stride);
89
90 /* increment after each line */
91 stride = (pdev->view.x - pdev->image.x) / 2; /* u16 is 2 bytes */
92
93 for (line = 0; line < pdev->image.y; line++) {
94 for (col = 0; col < pdev->image.x; col += 4) {
95 *dsty++ = *src++;
96 *dsty++ = *src++;
97 if (line & 1)
98 *dstv++ = *src++;
99 else
100 *dstu++ = *src++;
101 }
102 dsty += stride;
103 if (line & 1)
104 dstv += (stride >> 1);
105 else
106 dstu += (stride >> 1);
107 }
108 }
109 else {
110 /* Compressed; the decompressor routines will write the data
111 in planar format immediately.
112 */
113 int flags;
114
115 flags = PWCX_FLAG_PLANAR;
116 if (pdev->vsize == PSZ_VGA && pdev->vframes == 5 && pdev->vsnapshot)
117 {
118 printk(KERN_ERR "pwc: Mode Bayer is not supported for now\n");
119 flags |= PWCX_FLAG_BAYER;
120 return -ENXIO; /* No such device or address: missing decompressor */
121 }
122
123 switch (pdev->type)
124 {
125 case 675:
126 case 680:
127 case 690:
128 case 720:
129 case 730:
130 case 740:
131 case 750:
132 pwc_dec23_decompress(&pdev->image, &pdev->view, &pdev->offset,
133 yuv, image,
134 flags,
135 pdev->decompress_data, pdev->vbandlength);
136 break;
137 case 645:
138 case 646:
139 /* TODO & FIXME */
140 return -ENXIO; /* No such device or address: missing decompressor */
141 break;
142 }
143 }
144 return 0;
145}
146
147
diff --git a/drivers/usb/media/pwc/pwc-uncompress.h b/drivers/usb/media/pwc/pwc-uncompress.h
new file mode 100644
index 000000000000..d3b9250e4ed3
--- /dev/null
+++ b/drivers/usb/media/pwc/pwc-uncompress.h
@@ -0,0 +1,41 @@
1/* (C) 1999-2003 Nemosoft Unv.
2 (C) 2004 Luc Saillard (luc@saillard.org)
3
4 NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx
5 driver and thus may have bugs that are not present in the original version.
6 Please send bug reports and support requests to <luc@saillard.org>.
7 The decompression routines have been implemented by reverse-engineering the
8 Nemosoft binary pwcx module. Caveat emptor.
9
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2 of the License, or
13 (at your option) any later version.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23*/
24
25/* This file is the bridge between the kernel module and the plugin; it
26 describes the structures and datatypes used in both modules. Any
27 significant change should be reflected by increasing the
28 pwc_decompressor_version major number.
29 */
30#ifndef PWC_UNCOMPRESS_H
31#define PWC_UNCOMPRESS_H
32
33#include <linux/config.h>
34
35#include "pwc-ioctl.h"
36
37/* from pwc-dec.h */
38#define PWCX_FLAG_PLANAR 0x0001
39/* */
40
41#endif
diff --git a/drivers/usb/media/pwc/pwc.h b/drivers/usb/media/pwc/pwc.h
new file mode 100644
index 000000000000..53b516d29cf5
--- /dev/null
+++ b/drivers/usb/media/pwc/pwc.h
@@ -0,0 +1,278 @@
1/* (C) 1999-2003 Nemosoft Unv.
2 (C) 2004 Luc Saillard (luc@saillard.org)
3
4 NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx
5 driver and thus may have bugs that are not present in the original version.
6 Please send bug reports and support requests to <luc@saillard.org>.
7 The decompression routines have been implemented by reverse-engineering the
8 Nemosoft binary pwcx module. Caveat emptor.
9
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2 of the License, or
13 (at your option) any later version.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23*/
24
25#ifndef PWC_H
26#define PWC_H
27
28#include <linux/version.h>
29
30#include <linux/config.h>
31#include <linux/module.h>
32#include <linux/usb.h>
33#include <linux/spinlock.h>
34#include <linux/videodev.h>
35#include <linux/wait.h>
36#include <linux/smp_lock.h>
37#include <asm/semaphore.h>
38#include <asm/errno.h>
39
40#include "pwc-uncompress.h"
41#include "pwc-ioctl.h"
42
43/* Defines and structures for the Philips webcam */
44/* Used for checking memory corruption/pointer validation */
45#define PWC_MAGIC 0x89DC10ABUL
46#undef PWC_MAGIC
47
48/* Turn some debugging options on/off */
49#define PWC_DEBUG 0
50
51/* Trace certain actions in the driver */
52#define TRACE_MODULE 0x0001
53#define TRACE_PROBE 0x0002
54#define TRACE_OPEN 0x0004
55#define TRACE_READ 0x0008
56#define TRACE_MEMORY 0x0010
57#define TRACE_FLOW 0x0020
58#define TRACE_SIZE 0x0040
59#define TRACE_PWCX 0x0080
60#define TRACE_SEQUENCE 0x1000
61
62#define Trace(R, A...) if (pwc_trace & R) printk(KERN_DEBUG PWC_NAME " " A)
63#define Debug(A...) printk(KERN_DEBUG PWC_NAME " " A)
64#define Info(A...) printk(KERN_INFO PWC_NAME " " A)
65#define Err(A...) printk(KERN_ERR PWC_NAME " " A)
66
67
68/* Defines for ToUCam cameras */
69#define TOUCAM_HEADER_SIZE 8
70#define TOUCAM_TRAILER_SIZE 4
71
72#define FEATURE_MOTOR_PANTILT 0x0001
73
74/* Version block */
75#define PWC_MAJOR 9
76#define PWC_MINOR 0
77#define PWC_VERSION "9.0.2-unofficial"
78#define PWC_NAME "pwc"
79
80/* Turn certain features on/off */
81#define PWC_INT_PIPE 0
82
83/* Ignore errors in the first N frames, to allow for startup delays */
84#define FRAME_LOWMARK 5
85
86/* Size and number of buffers for the ISO pipe. */
87#define MAX_ISO_BUFS 2
88#define ISO_FRAMES_PER_DESC 10
89#define ISO_MAX_FRAME_SIZE 960
90#define ISO_BUFFER_SIZE (ISO_FRAMES_PER_DESC * ISO_MAX_FRAME_SIZE)
91
92/* Frame buffers: contains compressed or uncompressed video data. */
93#define MAX_FRAMES 5
94/* Maximum size after decompression is 640x480 YUV data, 1.5 * 640 * 480 */
95#define PWC_FRAME_SIZE (460800 + TOUCAM_HEADER_SIZE + TOUCAM_TRAILER_SIZE)
96
97/* Absolute maximum number of buffers available for mmap() */
98#define MAX_IMAGES 10
99
100/* The following structures were based on cpia.h. Why reinvent the wheel? :-) */
101struct pwc_iso_buf
102{
103 void *data;
104 int length;
105 int read;
106 struct urb *urb;
107};
108
109/* intermediate buffers with raw data from the USB cam */
110struct pwc_frame_buf
111{
112 void *data;
113 volatile int filled; /* number of bytes filled */
114 struct pwc_frame_buf *next; /* list */
115#if PWC_DEBUG
116 int sequence; /* Sequence number */
117#endif
118};
119
120struct pwc_device
121{
122 struct video_device *vdev;
123#ifdef PWC_MAGIC
124 int magic;
125#endif
126 /* Pointer to our usb_device */
127 struct usb_device *udev;
128
129 int type; /* type of cam (645, 646, 675, 680, 690, 720, 730, 740, 750) */
130 int release; /* release number */
131 int features; /* feature bits */
132 char serial[30]; /* serial number (string) */
133 int error_status; /* set when something goes wrong with the cam (unplugged, USB errors) */
134 int usb_init; /* set when the cam has been initialized over USB */
135
136 /*** Video data ***/
137 int vopen; /* flag */
138 int vendpoint; /* video isoc endpoint */
139 int vcinterface; /* video control interface */
140 int valternate; /* alternate interface needed */
141 int vframes, vsize; /* frames-per-second & size (see PSZ_*) */
142 int vpalette; /* palette: 420P, RAW or RGBBAYER */
143 int vframe_count; /* received frames */
144 int vframes_dumped; /* counter for dumped frames */
145 int vframes_error; /* frames received in error */
146 int vmax_packet_size; /* USB maxpacket size */
147 int vlast_packet_size; /* for frame synchronisation */
148 int visoc_errors; /* number of contiguous ISOC errors */
149 int vcompression; /* desired compression factor */
150 int vbandlength; /* compressed band length; 0 is uncompressed */
151 char vsnapshot; /* snapshot mode */
152 char vsync; /* used by isoc handler */
153 char vmirror; /* for ToUCaM series */
154
155 int cmd_len;
156 unsigned char cmd_buf[13];
157
158 /* The image acquisition requires 3 to 4 steps:
159 1. data is gathered in short packets from the USB controller
160 2. data is synchronized and packed into a frame buffer
161 3a. in case data is compressed, decompress it directly into image buffer
162 3b. in case data is uncompressed, copy into image buffer with viewport
163 4. data is transferred to the user process
164
165 Note that MAX_ISO_BUFS != MAX_FRAMES != MAX_IMAGES....
166 We have in effect a back-to-back-double-buffer system.
167 */
168 /* 1: isoc */
169 struct pwc_iso_buf sbuf[MAX_ISO_BUFS];
170 char iso_init;
171
172 /* 2: frame */
173 struct pwc_frame_buf *fbuf; /* all frames */
174 struct pwc_frame_buf *empty_frames, *empty_frames_tail; /* all empty frames */
175 struct pwc_frame_buf *full_frames, *full_frames_tail; /* all filled frames */
176 struct pwc_frame_buf *fill_frame; /* frame currently being filled */
177 struct pwc_frame_buf *read_frame; /* frame currently read by user process */
178 int frame_header_size, frame_trailer_size;
179 int frame_size;
180 int frame_total_size; /* including header & trailer */
181 int drop_frames;
182#if PWC_DEBUG
183 int sequence; /* Debugging aid */
184#endif
185
186 /* 3: decompression */
187 struct pwc_decompressor *decompressor; /* function block with decompression routines */
188 void *decompress_data; /* private data for decompression engine */
189
190 /* 4: image */
191 /* We have an 'image' and a 'view', where 'image' is the fixed-size image
192 as delivered by the camera, and 'view' is the size requested by the
193 program. The camera image is centered in this viewport, laced with
194 a gray or black border. view_min <= image <= view <= view_max;
195 */
196 int image_mask; /* bitmask of supported sizes */
197 struct pwc_coord view_min, view_max; /* minimum and maximum viewable sizes */
198 struct pwc_coord abs_max; /* maximum supported size with compression */
199 struct pwc_coord image, view; /* image and viewport size */
200 struct pwc_coord offset; /* offset within the viewport */
201
202 void *image_data; /* total buffer, which is subdivided into ... */
203 void *image_ptr[MAX_IMAGES]; /* ...several images... */
204 int fill_image; /* ...which are rotated. */
205 int len_per_image; /* length per image */
206 int image_read_pos; /* In case we read data in pieces, keep track of were we are in the imagebuffer */
207 int image_used[MAX_IMAGES]; /* For MCAPTURE and SYNC */
208
209 struct semaphore modlock; /* to prevent races in video_open(), etc */
210 spinlock_t ptrlock; /* for manipulating the buffer pointers */
211
212 /*** motorized pan/tilt feature */
213 struct pwc_mpt_range angle_range;
214 int pan_angle; /* in degrees * 100 */
215 int tilt_angle; /* absolute angle; 0,0 is home position */
216
217 /*** Misc. data ***/
218 wait_queue_head_t frameq; /* When waiting for a frame to finish... */
219#if PWC_INT_PIPE
220 void *usb_int_handler; /* for the interrupt endpoint */
221#endif
222};
223
224
225#ifdef __cplusplus
226extern "C" {
227#endif
228
229/* Global variables */
230extern int pwc_trace;
231extern int pwc_preferred_compression;
232
233/** functions in pwc-if.c */
234int pwc_try_video_mode(struct pwc_device *pdev, int width, int height, int new_fps, int new_compression, int new_snapshot);
235
236/** Functions in pwc-misc.c */
237/* sizes in pixels */
238extern struct pwc_coord pwc_image_sizes[PSZ_MAX];
239
240int pwc_decode_size(struct pwc_device *pdev, int width, int height);
241void pwc_construct(struct pwc_device *pdev);
242
243/** Functions in pwc-ctrl.c */
244/* Request a certain video mode. Returns < 0 if not possible */
245extern int pwc_set_video_mode(struct pwc_device *pdev, int width, int height, int frames, int compression, int snapshot);
246/* Calculate the number of bytes per image (not frame) */
247extern void pwc_set_image_buffer_size(struct pwc_device *pdev);
248
249/* Various controls; should be obvious. Value 0..65535, or < 0 on error */
250extern int pwc_get_brightness(struct pwc_device *pdev);
251extern int pwc_set_brightness(struct pwc_device *pdev, int value);
252extern int pwc_get_contrast(struct pwc_device *pdev);
253extern int pwc_set_contrast(struct pwc_device *pdev, int value);
254extern int pwc_get_gamma(struct pwc_device *pdev);
255extern int pwc_set_gamma(struct pwc_device *pdev, int value);
256extern int pwc_get_saturation(struct pwc_device *pdev);
257extern int pwc_set_saturation(struct pwc_device *pdev, int value);
258extern int pwc_set_leds(struct pwc_device *pdev, int on_value, int off_value);
259extern int pwc_get_leds(struct pwc_device *pdev, int *on_value, int *off_value);
260extern int pwc_get_cmos_sensor(struct pwc_device *pdev, int *sensor);
261
262/* Power down or up the camera; not supported by all models */
263extern int pwc_camera_power(struct pwc_device *pdev, int power);
264
265/* Private ioctl()s; see pwc-ioctl.h */
266extern int pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg);
267
268
269/** pwc-uncompress.c */
270/* Expand frame to image, possibly including decompression. Uses read_frame and fill_image */
271extern int pwc_decompress(struct pwc_device *pdev);
272
273#ifdef __cplusplus
274}
275#endif
276
277
278#endif