aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/pwc
diff options
context:
space:
mode:
authorJonathan Herman <hermanjl@cs.unc.edu>2013-01-22 10:38:37 -0500
committerJonathan Herman <hermanjl@cs.unc.edu>2013-01-22 10:38:37 -0500
commitfcc9d2e5a6c89d22b8b773a64fb4ad21ac318446 (patch)
treea57612d1888735a2ec7972891b68c1ac5ec8faea /drivers/media/video/pwc
parent8dea78da5cee153b8af9c07a2745f6c55057fe12 (diff)
Added missing tegra files.HEADmaster
Diffstat (limited to 'drivers/media/video/pwc')
-rw-r--r--drivers/media/video/pwc/Kconfig48
-rw-r--r--drivers/media/video/pwc/Makefile4
-rw-r--r--drivers/media/video/pwc/philips.txt236
-rw-r--r--drivers/media/video/pwc/pwc-ctrl.c1220
-rw-r--r--drivers/media/video/pwc/pwc-dec1.c40
-rw-r--r--drivers/media/video/pwc/pwc-dec1.h37
-rw-r--r--drivers/media/video/pwc/pwc-dec23.c920
-rw-r--r--drivers/media/video/pwc/pwc-dec23.h57
-rw-r--r--drivers/media/video/pwc/pwc-if.c1483
-rw-r--r--drivers/media/video/pwc/pwc-kiara.c892
-rw-r--r--drivers/media/video/pwc/pwc-kiara.h48
-rw-r--r--drivers/media/video/pwc/pwc-misc.c129
-rw-r--r--drivers/media/video/pwc/pwc-nala.h66
-rw-r--r--drivers/media/video/pwc/pwc-timon.c1448
-rw-r--r--drivers/media/video/pwc/pwc-timon.h63
-rw-r--r--drivers/media/video/pwc/pwc-uncompress.c133
-rw-r--r--drivers/media/video/pwc/pwc-v4l.c1131
-rw-r--r--drivers/media/video/pwc/pwc.h387
18 files changed, 8342 insertions, 0 deletions
diff --git a/drivers/media/video/pwc/Kconfig b/drivers/media/video/pwc/Kconfig
new file mode 100644
index 00000000000..d63d0a85003
--- /dev/null
+++ b/drivers/media/video/pwc/Kconfig
@@ -0,0 +1,48 @@
1config USB_PWC
2 tristate "USB Philips Cameras"
3 depends on VIDEO_V4L2
4 select VIDEOBUF2_VMALLOC
5 ---help---
6 Say Y or M here if you want to use one of these Philips & OEM
7 webcams:
8 * Philips PCA645, PCA646
9 * Philips PCVC675, PCVC680, PCVC690
10 * Philips PCVC720/40, PCVC730, PCVC740, PCVC750
11 * Philips SPC900NC
12 * Askey VC010
13 * Logitech QuickCam Pro 3000, 4000, 'Zoom', 'Notebook Pro'
14 and 'Orbit'/'Sphere'
15 * Samsung MPC-C10, MPC-C30
16 * Creative Webcam 5, Pro Ex
17 * SOTEC Afina Eye
18 * Visionite VCS-UC300, VCS-UM100
19
20 The PCA635, PCVC665 and PCVC720/20 are not supported by this driver
21 and never will be, but the 665 and 720/20 are supported by other
22 drivers.
23
24 Some newer logitech webcams are not handled by this driver but by the
25 Usb Video Class driver (linux-uvc).
26
27 The built-in microphone is enabled by selecting USB Audio support.
28
29 To compile this driver as a module, choose M here: the
30 module will be called pwc.
31
32config USB_PWC_DEBUG
33 bool "USB Philips Cameras verbose debug"
34 depends on USB_PWC
35 help
36 Say Y here in order to have the pwc driver generate verbose debugging
37 messages.
38 A special module options 'trace' is used to control the verbosity.
39
40config USB_PWC_INPUT_EVDEV
41 bool "USB Philips Cameras input events device support"
42 default y
43 depends on USB_PWC && (USB_PWC=INPUT || INPUT=y)
44 ---help---
45 This option makes USB Philips cameras register the snapshot button as
46 an input device to report button events.
47
48 If you are in doubt, say Y.
diff --git a/drivers/media/video/pwc/Makefile b/drivers/media/video/pwc/Makefile
new file mode 100644
index 00000000000..f5c8ec261e8
--- /dev/null
+++ b/drivers/media/video/pwc/Makefile
@@ -0,0 +1,4 @@
1pwc-objs := pwc-if.o pwc-misc.o pwc-ctrl.o pwc-v4l.o pwc-uncompress.o
2pwc-objs += pwc-dec1.o pwc-dec23.o pwc-kiara.o pwc-timon.o
3
4obj-$(CONFIG_USB_PWC) += pwc.o
diff --git a/drivers/media/video/pwc/philips.txt b/drivers/media/video/pwc/philips.txt
new file mode 100644
index 00000000000..d38dd791511
--- /dev/null
+++ b/drivers/media/video/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 therefore 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 parameter 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 momentarily 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.
179 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() functions, 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/media/video/pwc/pwc-ctrl.c b/drivers/media/video/pwc/pwc-ctrl.c
new file mode 100644
index 00000000000..3977addf3ba
--- /dev/null
+++ b/drivers/media/video/pwc/pwc-ctrl.c
@@ -0,0 +1,1220 @@
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-2006 Luc Saillard (luc@saillard.org)
6 (C) 2011 Hans de Goede <hdegoede@redhat.com>
7
8 NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx
9 driver and thus may have bugs that are not present in the original version.
10 Please send bug reports and support requests to <luc@saillard.org>.
11
12 NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx
13 driver and thus may have bugs that are not present in the original version.
14 Please send bug reports and support requests to <luc@saillard.org>.
15 The decompression routines have been implemented by reverse-engineering the
16 Nemosoft binary pwcx module. Caveat emptor.
17
18 This program is free software; you can redistribute it and/or modify
19 it under the terms of the GNU General Public License as published by
20 the Free Software Foundation; either version 2 of the License, or
21 (at your option) any later version.
22
23 This program is distributed in the hope that it will be useful,
24 but WITHOUT ANY WARRANTY; without even the implied warranty of
25 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26 GNU General Public License for more details.
27
28 You should have received a copy of the GNU General Public License
29 along with this program; if not, write to the Free Software
30 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
31*/
32
33/*
34 Changes
35 2001/08/03 Alvarado Added methods for changing white balance and
36 red/green gains
37 */
38
39/* Control functions for the cam; brightness, contrast, video mode, etc. */
40
41#ifdef __KERNEL__
42#include <asm/uaccess.h>
43#endif
44#include <asm/errno.h>
45
46#include "pwc.h"
47#include "pwc-kiara.h"
48#include "pwc-timon.h"
49#include "pwc-dec1.h"
50#include "pwc-dec23.h"
51
52/* Selectors for status controls used only in this file */
53#define GET_STATUS_B00 0x0B00
54#define SENSOR_TYPE_FORMATTER1 0x0C00
55#define GET_STATUS_3000 0x3000
56#define READ_RAW_Y_MEAN_FORMATTER 0x3100
57#define SET_POWER_SAVE_MODE_FORMATTER 0x3200
58#define MIRROR_IMAGE_FORMATTER 0x3300
59#define LED_FORMATTER 0x3400
60#define LOWLIGHT 0x3500
61#define GET_STATUS_3600 0x3600
62#define SENSOR_TYPE_FORMATTER2 0x3700
63#define GET_STATUS_3800 0x3800
64#define GET_STATUS_4000 0x4000
65#define GET_STATUS_4100 0x4100 /* Get */
66#define CTL_STATUS_4200 0x4200 /* [GS] 1 */
67
68/* Formatters for the Video Endpoint controls [GS]ET_EP_STREAM_CTL */
69#define VIDEO_OUTPUT_CONTROL_FORMATTER 0x0100
70
71static const char *size2name[PSZ_MAX] =
72{
73 "subQCIF",
74 "QSIF",
75 "QCIF",
76 "SIF",
77 "CIF",
78 "VGA",
79};
80
81/********/
82
83/* Entries for the Nala (645/646) camera; the Nala doesn't have compression
84 preferences, so you either get compressed or non-compressed streams.
85
86 An alternate value of 0 means this mode is not available at all.
87 */
88
89#define PWC_FPS_MAX_NALA 8
90
91struct Nala_table_entry {
92 char alternate; /* USB alternate setting */
93 int compressed; /* Compressed yes/no */
94
95 unsigned char mode[3]; /* precomputed mode table */
96};
97
98static unsigned int Nala_fps_vector[PWC_FPS_MAX_NALA] = { 4, 5, 7, 10, 12, 15, 20, 24 };
99
100static struct Nala_table_entry Nala_table[PSZ_MAX][PWC_FPS_MAX_NALA] =
101{
102#include "pwc-nala.h"
103};
104
105static void pwc_set_image_buffer_size(struct pwc_device *pdev);
106
107/****************************************************************************/
108
109static int _send_control_msg(struct pwc_device *pdev,
110 u8 request, u16 value, int index, void *buf, int buflen)
111{
112 int rc;
113 void *kbuf = NULL;
114
115 if (buflen) {
116 kbuf = kmalloc(buflen, GFP_KERNEL); /* not allowed on stack */
117 if (kbuf == NULL)
118 return -ENOMEM;
119 memcpy(kbuf, buf, buflen);
120 }
121
122 rc = usb_control_msg(pdev->udev, usb_sndctrlpipe(pdev->udev, 0),
123 request,
124 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
125 value,
126 index,
127 kbuf, buflen, USB_CTRL_SET_TIMEOUT);
128
129 kfree(kbuf);
130 return rc;
131}
132
133static int recv_control_msg(struct pwc_device *pdev,
134 u8 request, u16 value, void *buf, int buflen)
135{
136 int rc;
137 void *kbuf = kmalloc(buflen, GFP_KERNEL); /* not allowed on stack */
138
139 if (kbuf == NULL)
140 return -ENOMEM;
141
142 rc = usb_control_msg(pdev->udev, usb_rcvctrlpipe(pdev->udev, 0),
143 request,
144 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
145 value,
146 pdev->vcinterface,
147 kbuf, buflen, USB_CTRL_GET_TIMEOUT);
148 memcpy(buf, kbuf, buflen);
149 kfree(kbuf);
150
151 if (rc < 0)
152 PWC_ERROR("recv_control_msg error %d req %02x val %04x\n",
153 rc, request, value);
154 return rc;
155}
156
157static inline int send_video_command(struct pwc_device *pdev,
158 int index, void *buf, int buflen)
159{
160 return _send_control_msg(pdev,
161 SET_EP_STREAM_CTL,
162 VIDEO_OUTPUT_CONTROL_FORMATTER,
163 index,
164 buf, buflen);
165}
166
167int send_control_msg(struct pwc_device *pdev,
168 u8 request, u16 value, void *buf, int buflen)
169{
170 return _send_control_msg(pdev,
171 request, value, pdev->vcinterface, buf, buflen);
172}
173
174static int set_video_mode_Nala(struct pwc_device *pdev, int size, int frames)
175{
176 unsigned char buf[3];
177 int ret, fps;
178 struct Nala_table_entry *pEntry;
179 int frames2frames[31] =
180 { /* closest match of framerate */
181 0, 0, 0, 0, 4, /* 0-4 */
182 5, 5, 7, 7, 10, /* 5-9 */
183 10, 10, 12, 12, 15, /* 10-14 */
184 15, 15, 15, 20, 20, /* 15-19 */
185 20, 20, 20, 24, 24, /* 20-24 */
186 24, 24, 24, 24, 24, /* 25-29 */
187 24 /* 30 */
188 };
189 int frames2table[31] =
190 { 0, 0, 0, 0, 0, /* 0-4 */
191 1, 1, 1, 2, 2, /* 5-9 */
192 3, 3, 4, 4, 4, /* 10-14 */
193 5, 5, 5, 5, 5, /* 15-19 */
194 6, 6, 6, 6, 7, /* 20-24 */
195 7, 7, 7, 7, 7, /* 25-29 */
196 7 /* 30 */
197 };
198
199 if (size < 0 || size > PSZ_CIF || frames < 4 || frames > 25)
200 return -EINVAL;
201 frames = frames2frames[frames];
202 fps = frames2table[frames];
203 pEntry = &Nala_table[size][fps];
204 if (pEntry->alternate == 0)
205 return -EINVAL;
206
207 memcpy(buf, pEntry->mode, 3);
208 ret = send_video_command(pdev, pdev->vendpoint, buf, 3);
209 if (ret < 0) {
210 PWC_DEBUG_MODULE("Failed to send video command... %d\n", ret);
211 return ret;
212 }
213 if (pEntry->compressed && pdev->pixfmt == V4L2_PIX_FMT_YUV420) {
214 ret = pwc_dec1_init(pdev, pdev->type, pdev->release, buf);
215 if (ret < 0)
216 return ret;
217 }
218
219 pdev->cmd_len = 3;
220 memcpy(pdev->cmd_buf, buf, 3);
221
222 /* Set various parameters */
223 pdev->vframes = frames;
224 pdev->vsize = size;
225 pdev->valternate = pEntry->alternate;
226 pdev->image = pwc_image_sizes[size];
227 pdev->frame_size = (pdev->image.x * pdev->image.y * 3) / 2;
228 if (pEntry->compressed) {
229 if (pdev->release < 5) { /* 4 fold compression */
230 pdev->vbandlength = 528;
231 pdev->frame_size /= 4;
232 }
233 else {
234 pdev->vbandlength = 704;
235 pdev->frame_size /= 3;
236 }
237 }
238 else
239 pdev->vbandlength = 0;
240 return 0;
241}
242
243
244static int set_video_mode_Timon(struct pwc_device *pdev, int size, int frames, int compression, int snapshot)
245{
246 unsigned char buf[13];
247 const struct Timon_table_entry *pChoose;
248 int ret, fps;
249
250 if (size >= PSZ_MAX || frames < 5 || frames > 30 || compression < 0 || compression > 3)
251 return -EINVAL;
252 if (size == PSZ_VGA && frames > 15)
253 return -EINVAL;
254 fps = (frames / 5) - 1;
255
256 /* Find a supported framerate with progressively higher compression ratios
257 if the preferred ratio is not available.
258 */
259 pChoose = NULL;
260 while (compression <= 3) {
261 pChoose = &Timon_table[size][fps][compression];
262 if (pChoose->alternate != 0)
263 break;
264 compression++;
265 }
266 if (pChoose == NULL || pChoose->alternate == 0)
267 return -ENOENT; /* Not supported. */
268
269 memcpy(buf, pChoose->mode, 13);
270 if (snapshot)
271 buf[0] |= 0x80;
272 ret = send_video_command(pdev, pdev->vendpoint, buf, 13);
273 if (ret < 0)
274 return ret;
275
276 if (pChoose->bandlength > 0 && pdev->pixfmt == V4L2_PIX_FMT_YUV420) {
277 ret = pwc_dec23_init(pdev, pdev->type, buf);
278 if (ret < 0)
279 return ret;
280 }
281
282 pdev->cmd_len = 13;
283 memcpy(pdev->cmd_buf, buf, 13);
284
285 /* Set various parameters */
286 pdev->vframes = frames;
287 pdev->vsize = size;
288 pdev->vsnapshot = snapshot;
289 pdev->valternate = pChoose->alternate;
290 pdev->image = pwc_image_sizes[size];
291 pdev->vbandlength = pChoose->bandlength;
292 if (pChoose->bandlength > 0)
293 pdev->frame_size = (pChoose->bandlength * pdev->image.y) / 4;
294 else
295 pdev->frame_size = (pdev->image.x * pdev->image.y * 12) / 8;
296 return 0;
297}
298
299
300static int set_video_mode_Kiara(struct pwc_device *pdev, int size, int frames, int compression, int snapshot)
301{
302 const struct Kiara_table_entry *pChoose = NULL;
303 int fps, ret;
304 unsigned char buf[12];
305 struct Kiara_table_entry RawEntry = {6, 773, 1272, {0xAD, 0xF4, 0x10, 0x27, 0xB6, 0x24, 0x96, 0x02, 0x30, 0x05, 0x03, 0x80}};
306
307 if (size >= PSZ_MAX || frames < 5 || frames > 30 || compression < 0 || compression > 3)
308 return -EINVAL;
309 if (size == PSZ_VGA && frames > 15)
310 return -EINVAL;
311 fps = (frames / 5) - 1;
312
313 /* special case: VGA @ 5 fps and snapshot is raw bayer mode */
314 if (size == PSZ_VGA && frames == 5 && snapshot && pdev->pixfmt != V4L2_PIX_FMT_YUV420)
315 {
316 /* Only available in case the raw palette is selected or
317 we have the decompressor available. This mode is
318 only available in compressed form
319 */
320 PWC_DEBUG_SIZE("Choosing VGA/5 BAYER mode.\n");
321 pChoose = &RawEntry;
322 }
323 else
324 {
325 /* Find a supported framerate with progressively higher compression ratios
326 if the preferred ratio is not available.
327 Skip this step when using RAW modes.
328 */
329 snapshot = 0;
330 while (compression <= 3) {
331 pChoose = &Kiara_table[size][fps][compression];
332 if (pChoose->alternate != 0)
333 break;
334 compression++;
335 }
336 }
337 if (pChoose == NULL || pChoose->alternate == 0)
338 return -ENOENT; /* Not supported. */
339
340 PWC_TRACE("Using alternate setting %d.\n", pChoose->alternate);
341
342 /* usb_control_msg won't take staticly allocated arrays as argument?? */
343 memcpy(buf, pChoose->mode, 12);
344 if (snapshot)
345 buf[0] |= 0x80;
346
347 /* Firmware bug: video endpoint is 5, but commands are sent to endpoint 4 */
348 ret = send_video_command(pdev, 4 /* pdev->vendpoint */, buf, 12);
349 if (ret < 0)
350 return ret;
351
352 if (pChoose->bandlength > 0 && pdev->pixfmt == V4L2_PIX_FMT_YUV420) {
353 ret = pwc_dec23_init(pdev, pdev->type, buf);
354 if (ret < 0)
355 return ret;
356 }
357
358 pdev->cmd_len = 12;
359 memcpy(pdev->cmd_buf, buf, 12);
360 /* All set and go */
361 pdev->vframes = frames;
362 pdev->vsize = size;
363 pdev->vsnapshot = snapshot;
364 pdev->valternate = pChoose->alternate;
365 pdev->image = pwc_image_sizes[size];
366 pdev->vbandlength = pChoose->bandlength;
367 if (pdev->vbandlength > 0)
368 pdev->frame_size = (pdev->vbandlength * pdev->image.y) / 4;
369 else
370 pdev->frame_size = (pdev->image.x * pdev->image.y * 12) / 8;
371 PWC_TRACE("frame_size=%d, vframes=%d, vsize=%d, vsnapshot=%d, vbandlength=%d\n",
372 pdev->frame_size,pdev->vframes,pdev->vsize,pdev->vsnapshot,pdev->vbandlength);
373 return 0;
374}
375
376
377
378/**
379 @pdev: device structure
380 @width: viewport width
381 @height: viewport height
382 @frame: framerate, in fps
383 @compression: preferred compression ratio
384 @snapshot: snapshot mode or streaming
385 */
386int pwc_set_video_mode(struct pwc_device *pdev, int width, int height, int frames, int compression, int snapshot)
387{
388 int ret, size;
389
390 PWC_DEBUG_FLOW("set_video_mode(%dx%d @ %d, pixfmt %08x).\n", width, height, frames, pdev->pixfmt);
391 size = pwc_decode_size(pdev, width, height);
392 if (size < 0) {
393 PWC_DEBUG_MODULE("Could not find suitable size.\n");
394 return -ERANGE;
395 }
396 PWC_TRACE("decode_size = %d.\n", size);
397
398 if (DEVICE_USE_CODEC1(pdev->type)) {
399 ret = set_video_mode_Nala(pdev, size, frames);
400
401 } else if (DEVICE_USE_CODEC3(pdev->type)) {
402 ret = set_video_mode_Kiara(pdev, size, frames, compression, snapshot);
403
404 } else {
405 ret = set_video_mode_Timon(pdev, size, frames, compression, snapshot);
406 }
407 if (ret < 0) {
408 PWC_ERROR("Failed to set video mode %s@%d fps; return code = %d\n", size2name[size], frames, ret);
409 return ret;
410 }
411 pdev->view.x = width;
412 pdev->view.y = height;
413 pdev->vcompression = compression;
414 pdev->frame_total_size = pdev->frame_size + pdev->frame_header_size + pdev->frame_trailer_size;
415 pwc_set_image_buffer_size(pdev);
416 PWC_DEBUG_SIZE("Set viewport to %dx%d, image size is %dx%d.\n", width, height, pwc_image_sizes[size].x, pwc_image_sizes[size].y);
417 return 0;
418}
419
420static unsigned int pwc_get_fps_Nala(struct pwc_device *pdev, unsigned int index, unsigned int size)
421{
422 unsigned int i;
423
424 for (i = 0; i < PWC_FPS_MAX_NALA; i++) {
425 if (Nala_table[size][i].alternate) {
426 if (index--==0) return Nala_fps_vector[i];
427 }
428 }
429 return 0;
430}
431
432static unsigned int pwc_get_fps_Kiara(struct pwc_device *pdev, unsigned int index, unsigned int size)
433{
434 unsigned int i;
435
436 for (i = 0; i < PWC_FPS_MAX_KIARA; i++) {
437 if (Kiara_table[size][i][3].alternate) {
438 if (index--==0) return Kiara_fps_vector[i];
439 }
440 }
441 return 0;
442}
443
444static unsigned int pwc_get_fps_Timon(struct pwc_device *pdev, unsigned int index, unsigned int size)
445{
446 unsigned int i;
447
448 for (i=0; i < PWC_FPS_MAX_TIMON; i++) {
449 if (Timon_table[size][i][3].alternate) {
450 if (index--==0) return Timon_fps_vector[i];
451 }
452 }
453 return 0;
454}
455
456unsigned int pwc_get_fps(struct pwc_device *pdev, unsigned int index, unsigned int size)
457{
458 unsigned int ret;
459
460 if (DEVICE_USE_CODEC1(pdev->type)) {
461 ret = pwc_get_fps_Nala(pdev, index, size);
462
463 } else if (DEVICE_USE_CODEC3(pdev->type)) {
464 ret = pwc_get_fps_Kiara(pdev, index, size);
465
466 } else {
467 ret = pwc_get_fps_Timon(pdev, index, size);
468 }
469
470 return ret;
471}
472
473static void pwc_set_image_buffer_size(struct pwc_device *pdev)
474{
475 int factor = 0;
476
477 /* for V4L2_PIX_FMT_YUV420 */
478 switch (pdev->pixfmt) {
479 case V4L2_PIX_FMT_YUV420:
480 factor = 6;
481 break;
482 case V4L2_PIX_FMT_PWC1:
483 case V4L2_PIX_FMT_PWC2:
484 factor = 6; /* can be uncompressed YUV420P */
485 break;
486 }
487
488 /* Set sizes in bytes */
489 pdev->image.size = pdev->image.x * pdev->image.y * factor / 4;
490 pdev->view.size = pdev->view.x * pdev->view.y * factor / 4;
491
492 /* Align offset, or you'll get some very weird results in
493 YUV420 mode... x must be multiple of 4 (to get the Y's in
494 place), and y even (or you'll mixup U & V). This is less of a
495 problem for YUV420P.
496 */
497 pdev->offset.x = ((pdev->view.x - pdev->image.x) / 2) & 0xFFFC;
498 pdev->offset.y = ((pdev->view.y - pdev->image.y) / 2) & 0xFFFE;
499}
500
501int pwc_get_u8_ctrl(struct pwc_device *pdev, u8 request, u16 value, int *data)
502{
503 int ret;
504 u8 buf;
505
506 ret = recv_control_msg(pdev, request, value, &buf, sizeof(buf));
507 if (ret < 0)
508 return ret;
509
510 *data = buf;
511 return 0;
512}
513
514int pwc_set_u8_ctrl(struct pwc_device *pdev, u8 request, u16 value, u8 data)
515{
516 int ret;
517
518 ret = send_control_msg(pdev, request, value, &data, sizeof(data));
519 if (ret < 0)
520 return ret;
521
522 return 0;
523}
524
525int pwc_get_s8_ctrl(struct pwc_device *pdev, u8 request, u16 value, int *data)
526{
527 int ret;
528 s8 buf;
529
530 ret = recv_control_msg(pdev, request, value, &buf, sizeof(buf));
531 if (ret < 0)
532 return ret;
533
534 *data = buf;
535 return 0;
536}
537
538int pwc_get_u16_ctrl(struct pwc_device *pdev, u8 request, u16 value, int *data)
539{
540 int ret;
541 u8 buf[2];
542
543 ret = recv_control_msg(pdev, request, value, buf, sizeof(buf));
544 if (ret < 0)
545 return ret;
546
547 *data = (buf[1] << 8) | buf[0];
548 return 0;
549}
550
551int pwc_set_u16_ctrl(struct pwc_device *pdev, u8 request, u16 value, u16 data)
552{
553 int ret;
554 u8 buf[2];
555
556 buf[0] = data & 0xff;
557 buf[1] = data >> 8;
558 ret = send_control_msg(pdev, request, value, buf, sizeof(buf));
559 if (ret < 0)
560 return ret;
561
562 return 0;
563}
564
565int pwc_button_ctrl(struct pwc_device *pdev, u16 value)
566{
567 int ret;
568
569 ret = send_control_msg(pdev, SET_STATUS_CTL, value, NULL, 0);
570 if (ret < 0)
571 return ret;
572
573 return 0;
574}
575
576/* POWER */
577void pwc_camera_power(struct pwc_device *pdev, int power)
578{
579 char buf;
580 int r;
581
582 if (!pdev->power_save)
583 return;
584
585 if (pdev->type < 675 || (pdev->type < 730 && pdev->release < 6))
586 return; /* Not supported by Nala or Timon < release 6 */
587
588 if (power)
589 buf = 0x00; /* active */
590 else
591 buf = 0xFF; /* power save */
592 r = send_control_msg(pdev,
593 SET_STATUS_CTL, SET_POWER_SAVE_MODE_FORMATTER,
594 &buf, sizeof(buf));
595
596 if (r < 0)
597 PWC_ERROR("Failed to power %s camera (%d)\n",
598 power ? "on" : "off", r);
599}
600
601static int pwc_set_wb_speed(struct pwc_device *pdev, int speed)
602{
603 unsigned char buf;
604
605 /* useful range is 0x01..0x20 */
606 buf = speed / 0x7f0;
607 return send_control_msg(pdev,
608 SET_CHROM_CTL, AWB_CONTROL_SPEED_FORMATTER, &buf, sizeof(buf));
609}
610
611static int pwc_get_wb_speed(struct pwc_device *pdev, int *value)
612{
613 unsigned char buf;
614 int ret;
615
616 ret = recv_control_msg(pdev,
617 GET_CHROM_CTL, AWB_CONTROL_SPEED_FORMATTER, &buf, sizeof(buf));
618 if (ret < 0)
619 return ret;
620 *value = buf * 0x7f0;
621 return 0;
622}
623
624
625static int pwc_set_wb_delay(struct pwc_device *pdev, int delay)
626{
627 unsigned char buf;
628
629 /* useful range is 0x01..0x3F */
630 buf = (delay >> 10);
631 return send_control_msg(pdev,
632 SET_CHROM_CTL, AWB_CONTROL_DELAY_FORMATTER, &buf, sizeof(buf));
633}
634
635static int pwc_get_wb_delay(struct pwc_device *pdev, int *value)
636{
637 unsigned char buf;
638 int ret;
639
640 ret = recv_control_msg(pdev,
641 GET_CHROM_CTL, AWB_CONTROL_DELAY_FORMATTER, &buf, sizeof(buf));
642 if (ret < 0)
643 return ret;
644 *value = buf << 10;
645 return 0;
646}
647
648
649int pwc_set_leds(struct pwc_device *pdev, int on_value, int off_value)
650{
651 unsigned char buf[2];
652 int r;
653
654 if (pdev->type < 730)
655 return 0;
656 on_value /= 100;
657 off_value /= 100;
658 if (on_value < 0)
659 on_value = 0;
660 if (on_value > 0xff)
661 on_value = 0xff;
662 if (off_value < 0)
663 off_value = 0;
664 if (off_value > 0xff)
665 off_value = 0xff;
666
667 buf[0] = on_value;
668 buf[1] = off_value;
669
670 r = send_control_msg(pdev,
671 SET_STATUS_CTL, LED_FORMATTER, &buf, sizeof(buf));
672 if (r < 0)
673 PWC_ERROR("Failed to set LED on/off time (%d)\n", r);
674
675 return r;
676}
677
678static int pwc_get_leds(struct pwc_device *pdev, int *on_value, int *off_value)
679{
680 unsigned char buf[2];
681 int ret;
682
683 if (pdev->type < 730) {
684 *on_value = -1;
685 *off_value = -1;
686 return 0;
687 }
688
689 ret = recv_control_msg(pdev,
690 GET_STATUS_CTL, LED_FORMATTER, &buf, sizeof(buf));
691 if (ret < 0)
692 return ret;
693 *on_value = buf[0] * 100;
694 *off_value = buf[1] * 100;
695 return 0;
696}
697
698static int _pwc_mpt_reset(struct pwc_device *pdev, int flags)
699{
700 unsigned char buf;
701
702 buf = flags & 0x03; // only lower two bits are currently used
703 return send_control_msg(pdev,
704 SET_MPT_CTL, PT_RESET_CONTROL_FORMATTER, &buf, sizeof(buf));
705}
706
707int pwc_mpt_reset(struct pwc_device *pdev, int flags)
708{
709 int ret;
710 ret = _pwc_mpt_reset(pdev, flags);
711 if (ret >= 0) {
712 pdev->pan_angle = 0;
713 pdev->tilt_angle = 0;
714 }
715 return ret;
716}
717
718static int _pwc_mpt_set_angle(struct pwc_device *pdev, int pan, int tilt)
719{
720 unsigned char buf[4];
721
722 /* set new relative angle; angles are expressed in degrees * 100,
723 but cam as .5 degree resolution, hence divide by 200. Also
724 the angle must be multiplied by 64 before it's send to
725 the cam (??)
726 */
727 pan = 64 * pan / 100;
728 tilt = -64 * tilt / 100; /* positive tilt is down, which is not what the user would expect */
729 buf[0] = pan & 0xFF;
730 buf[1] = (pan >> 8) & 0xFF;
731 buf[2] = tilt & 0xFF;
732 buf[3] = (tilt >> 8) & 0xFF;
733 return send_control_msg(pdev,
734 SET_MPT_CTL, PT_RELATIVE_CONTROL_FORMATTER, &buf, sizeof(buf));
735}
736
737int pwc_mpt_set_angle(struct pwc_device *pdev, int pan, int tilt)
738{
739 int ret;
740
741 /* check absolute ranges */
742 if (pan < pdev->angle_range.pan_min ||
743 pan > pdev->angle_range.pan_max ||
744 tilt < pdev->angle_range.tilt_min ||
745 tilt > pdev->angle_range.tilt_max)
746 return -ERANGE;
747
748 /* go to relative range, check again */
749 pan -= pdev->pan_angle;
750 tilt -= pdev->tilt_angle;
751 /* angles are specified in degrees * 100, thus the limit = 36000 */
752 if (pan < -36000 || pan > 36000 || tilt < -36000 || tilt > 36000)
753 return -ERANGE;
754
755 ret = _pwc_mpt_set_angle(pdev, pan, tilt);
756 if (ret >= 0) {
757 pdev->pan_angle += pan;
758 pdev->tilt_angle += tilt;
759 }
760 if (ret == -EPIPE) /* stall -> out of range */
761 ret = -ERANGE;
762 return ret;
763}
764
765static int pwc_mpt_get_status(struct pwc_device *pdev, struct pwc_mpt_status *status)
766{
767 int ret;
768 unsigned char buf[5];
769
770 ret = recv_control_msg(pdev,
771 GET_MPT_CTL, PT_STATUS_FORMATTER, &buf, sizeof(buf));
772 if (ret < 0)
773 return ret;
774 status->status = buf[0] & 0x7; // 3 bits are used for reporting
775 status->time_pan = (buf[1] << 8) + buf[2];
776 status->time_tilt = (buf[3] << 8) + buf[4];
777 return 0;
778}
779
780#ifdef CONFIG_USB_PWC_DEBUG
781int pwc_get_cmos_sensor(struct pwc_device *pdev, int *sensor)
782{
783 unsigned char buf;
784 int ret = -1, request;
785
786 if (pdev->type < 675)
787 request = SENSOR_TYPE_FORMATTER1;
788 else if (pdev->type < 730)
789 return -1; /* The Vesta series doesn't have this call */
790 else
791 request = SENSOR_TYPE_FORMATTER2;
792
793 ret = recv_control_msg(pdev,
794 GET_STATUS_CTL, request, &buf, sizeof(buf));
795 if (ret < 0)
796 return ret;
797 if (pdev->type < 675)
798 *sensor = buf | 0x100;
799 else
800 *sensor = buf;
801 return 0;
802}
803#endif
804
805 /* End of Add-Ons */
806 /* ************************************************* */
807
808/* Linux 2.5.something and 2.6 pass direct pointers to arguments of
809 ioctl() calls. With 2.4, you have to do tedious copy_from_user()
810 and copy_to_user() calls. With these macros we circumvent this,
811 and let me maintain only one source file. The functionality is
812 exactly the same otherwise.
813 */
814
815/* define local variable for arg */
816#define ARG_DEF(ARG_type, ARG_name)\
817 ARG_type *ARG_name = arg;
818/* copy arg to local variable */
819#define ARG_IN(ARG_name) /* nothing */
820/* argument itself (referenced) */
821#define ARGR(ARG_name) (*ARG_name)
822/* argument address */
823#define ARGA(ARG_name) ARG_name
824/* copy local variable to arg */
825#define ARG_OUT(ARG_name) /* nothing */
826
827/*
828 * Our ctrls use native values, but the old custom pwc ioctl interface expects
829 * values from 0 - 65535, define 2 helper functions to scale things. */
830static int pwc_ioctl_g_ctrl(struct v4l2_ctrl *ctrl)
831{
832 return v4l2_ctrl_g_ctrl(ctrl) * 65535 / ctrl->maximum;
833}
834
835static int pwc_ioctl_s_ctrl(struct v4l2_ctrl *ctrl, int val)
836{
837 return v4l2_ctrl_s_ctrl(ctrl, val * ctrl->maximum / 65535);
838}
839
840long pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg)
841{
842 long ret = 0;
843
844 switch(cmd) {
845 case VIDIOCPWCRUSER:
846 ret = pwc_button_ctrl(pdev, RESTORE_USER_DEFAULTS_FORMATTER);
847 break;
848
849 case VIDIOCPWCSUSER:
850 ret = pwc_button_ctrl(pdev, SAVE_USER_DEFAULTS_FORMATTER);
851 break;
852
853 case VIDIOCPWCFACTORY:
854 ret = pwc_button_ctrl(pdev, RESTORE_FACTORY_DEFAULTS_FORMATTER);
855 break;
856
857 case VIDIOCPWCSCQUAL:
858 {
859 ARG_DEF(int, qual)
860
861 if (vb2_is_streaming(&pdev->vb_queue)) {
862 ret = -EBUSY;
863 break;
864 }
865
866 ARG_IN(qual)
867 if (ARGR(qual) < 0 || ARGR(qual) > 3)
868 ret = -EINVAL;
869 else
870 ret = pwc_set_video_mode(pdev, pdev->view.x, pdev->view.y, pdev->vframes, ARGR(qual), pdev->vsnapshot);
871 break;
872 }
873
874 case VIDIOCPWCGCQUAL:
875 {
876 ARG_DEF(int, qual)
877
878 ARGR(qual) = pdev->vcompression;
879 ARG_OUT(qual)
880 break;
881 }
882
883 case VIDIOCPWCPROBE:
884 {
885 ARG_DEF(struct pwc_probe, probe)
886
887 strcpy(ARGR(probe).name, pdev->vdev.name);
888 ARGR(probe).type = pdev->type;
889 ARG_OUT(probe)
890 break;
891 }
892
893 case VIDIOCPWCGSERIAL:
894 {
895 ARG_DEF(struct pwc_serial, serial)
896
897 strcpy(ARGR(serial).serial, pdev->serial);
898 ARG_OUT(serial)
899 break;
900 }
901
902 case VIDIOCPWCSAGC:
903 {
904 ARG_DEF(int, agc)
905 ARG_IN(agc)
906 ret = v4l2_ctrl_s_ctrl(pdev->autogain, ARGR(agc) < 0);
907 if (ret == 0 && ARGR(agc) >= 0)
908 ret = pwc_ioctl_s_ctrl(pdev->gain, ARGR(agc));
909 break;
910 }
911
912 case VIDIOCPWCGAGC:
913 {
914 ARG_DEF(int, agc)
915 if (v4l2_ctrl_g_ctrl(pdev->autogain))
916 ARGR(agc) = -1;
917 else
918 ARGR(agc) = pwc_ioctl_g_ctrl(pdev->gain);
919 ARG_OUT(agc)
920 break;
921 }
922
923 case VIDIOCPWCSSHUTTER:
924 {
925 ARG_DEF(int, shutter)
926 ARG_IN(shutter)
927 ret = v4l2_ctrl_s_ctrl(pdev->exposure_auto,
928 /* Menu idx 0 = auto, idx 1 = manual */
929 ARGR(shutter) >= 0);
930 if (ret == 0 && ARGR(shutter) >= 0)
931 ret = pwc_ioctl_s_ctrl(pdev->exposure, ARGR(shutter));
932 break;
933 }
934
935 case VIDIOCPWCSAWB:
936 {
937 ARG_DEF(struct pwc_whitebalance, wb)
938 ARG_IN(wb)
939 ret = v4l2_ctrl_s_ctrl(pdev->auto_white_balance,
940 ARGR(wb).mode);
941 if (ret == 0 && ARGR(wb).mode == PWC_WB_MANUAL)
942 ret = pwc_ioctl_s_ctrl(pdev->red_balance,
943 ARGR(wb).manual_red);
944 if (ret == 0 && ARGR(wb).mode == PWC_WB_MANUAL)
945 ret = pwc_ioctl_s_ctrl(pdev->blue_balance,
946 ARGR(wb).manual_blue);
947 break;
948 }
949
950 case VIDIOCPWCGAWB:
951 {
952 ARG_DEF(struct pwc_whitebalance, wb)
953 ARGR(wb).mode = v4l2_ctrl_g_ctrl(pdev->auto_white_balance);
954 ARGR(wb).manual_red = ARGR(wb).read_red =
955 pwc_ioctl_g_ctrl(pdev->red_balance);
956 ARGR(wb).manual_blue = ARGR(wb).read_blue =
957 pwc_ioctl_g_ctrl(pdev->blue_balance);
958 ARG_OUT(wb)
959 break;
960 }
961
962 case VIDIOCPWCSAWBSPEED:
963 {
964 ARG_DEF(struct pwc_wb_speed, wbs)
965
966 if (ARGR(wbs).control_speed > 0) {
967 ret = pwc_set_wb_speed(pdev, ARGR(wbs).control_speed);
968 }
969 if (ARGR(wbs).control_delay > 0) {
970 ret = pwc_set_wb_delay(pdev, ARGR(wbs).control_delay);
971 }
972 break;
973 }
974
975 case VIDIOCPWCGAWBSPEED:
976 {
977 ARG_DEF(struct pwc_wb_speed, wbs)
978
979 ret = pwc_get_wb_speed(pdev, &ARGR(wbs).control_speed);
980 if (ret < 0)
981 break;
982 ret = pwc_get_wb_delay(pdev, &ARGR(wbs).control_delay);
983 if (ret < 0)
984 break;
985 ARG_OUT(wbs)
986 break;
987 }
988
989 case VIDIOCPWCSLED:
990 {
991 ARG_DEF(struct pwc_leds, leds)
992
993 ARG_IN(leds)
994 ret = pwc_set_leds(pdev, ARGR(leds).led_on, ARGR(leds).led_off);
995 break;
996 }
997
998
999 case VIDIOCPWCGLED:
1000 {
1001 ARG_DEF(struct pwc_leds, leds)
1002
1003 ret = pwc_get_leds(pdev, &ARGR(leds).led_on, &ARGR(leds).led_off);
1004 ARG_OUT(leds)
1005 break;
1006 }
1007
1008 case VIDIOCPWCSCONTOUR:
1009 {
1010 ARG_DEF(int, contour)
1011 ARG_IN(contour)
1012 ret = v4l2_ctrl_s_ctrl(pdev->autocontour, ARGR(contour) < 0);
1013 if (ret == 0 && ARGR(contour) >= 0)
1014 ret = pwc_ioctl_s_ctrl(pdev->contour, ARGR(contour));
1015 break;
1016 }
1017
1018 case VIDIOCPWCGCONTOUR:
1019 {
1020 ARG_DEF(int, contour)
1021 if (v4l2_ctrl_g_ctrl(pdev->autocontour))
1022 ARGR(contour) = -1;
1023 else
1024 ARGR(contour) = pwc_ioctl_g_ctrl(pdev->contour);
1025 ARG_OUT(contour)
1026 break;
1027 }
1028
1029 case VIDIOCPWCSBACKLIGHT:
1030 {
1031 ARG_DEF(int, backlight)
1032 ARG_IN(backlight)
1033 ret = v4l2_ctrl_s_ctrl(pdev->backlight, ARGR(backlight));
1034 break;
1035 }
1036
1037 case VIDIOCPWCGBACKLIGHT:
1038 {
1039 ARG_DEF(int, backlight)
1040 ARGR(backlight) = v4l2_ctrl_g_ctrl(pdev->backlight);
1041 ARG_OUT(backlight)
1042 break;
1043 }
1044
1045 case VIDIOCPWCSFLICKER:
1046 {
1047 ARG_DEF(int, flicker)
1048 ARG_IN(flicker)
1049 ret = v4l2_ctrl_s_ctrl(pdev->flicker, ARGR(flicker));
1050 break;
1051 }
1052
1053 case VIDIOCPWCGFLICKER:
1054 {
1055 ARG_DEF(int, flicker)
1056 ARGR(flicker) = v4l2_ctrl_g_ctrl(pdev->flicker);
1057 ARG_OUT(flicker)
1058 break;
1059 }
1060
1061 case VIDIOCPWCSDYNNOISE:
1062 {
1063 ARG_DEF(int, dynnoise)
1064 ARG_IN(dynnoise)
1065 ret = v4l2_ctrl_s_ctrl(pdev->noise_reduction, ARGR(dynnoise));
1066 break;
1067 }
1068
1069 case VIDIOCPWCGDYNNOISE:
1070 {
1071 ARG_DEF(int, dynnoise)
1072 ARGR(dynnoise) = v4l2_ctrl_g_ctrl(pdev->noise_reduction);
1073 ARG_OUT(dynnoise);
1074 break;
1075 }
1076
1077 case VIDIOCPWCGREALSIZE:
1078 {
1079 ARG_DEF(struct pwc_imagesize, size)
1080
1081 ARGR(size).width = pdev->image.x;
1082 ARGR(size).height = pdev->image.y;
1083 ARG_OUT(size)
1084 break;
1085 }
1086
1087 case VIDIOCPWCMPTRESET:
1088 {
1089 if (pdev->features & FEATURE_MOTOR_PANTILT)
1090 {
1091 ARG_DEF(int, flags)
1092
1093 ARG_IN(flags)
1094 ret = pwc_mpt_reset(pdev, ARGR(flags));
1095 }
1096 else
1097 {
1098 ret = -ENXIO;
1099 }
1100 break;
1101 }
1102
1103 case VIDIOCPWCMPTGRANGE:
1104 {
1105 if (pdev->features & FEATURE_MOTOR_PANTILT)
1106 {
1107 ARG_DEF(struct pwc_mpt_range, range)
1108
1109 ARGR(range) = pdev->angle_range;
1110 ARG_OUT(range)
1111 }
1112 else
1113 {
1114 ret = -ENXIO;
1115 }
1116 break;
1117 }
1118
1119 case VIDIOCPWCMPTSANGLE:
1120 {
1121 int new_pan, new_tilt;
1122
1123 if (pdev->features & FEATURE_MOTOR_PANTILT)
1124 {
1125 ARG_DEF(struct pwc_mpt_angles, angles)
1126
1127 ARG_IN(angles)
1128 /* The camera can only set relative angles, so
1129 do some calculations when getting an absolute angle .
1130 */
1131 if (ARGR(angles).absolute)
1132 {
1133 new_pan = ARGR(angles).pan;
1134 new_tilt = ARGR(angles).tilt;
1135 }
1136 else
1137 {
1138 new_pan = pdev->pan_angle + ARGR(angles).pan;
1139 new_tilt = pdev->tilt_angle + ARGR(angles).tilt;
1140 }
1141 ret = pwc_mpt_set_angle(pdev, new_pan, new_tilt);
1142 }
1143 else
1144 {
1145 ret = -ENXIO;
1146 }
1147 break;
1148 }
1149
1150 case VIDIOCPWCMPTGANGLE:
1151 {
1152
1153 if (pdev->features & FEATURE_MOTOR_PANTILT)
1154 {
1155 ARG_DEF(struct pwc_mpt_angles, angles)
1156
1157 ARGR(angles).absolute = 1;
1158 ARGR(angles).pan = pdev->pan_angle;
1159 ARGR(angles).tilt = pdev->tilt_angle;
1160 ARG_OUT(angles)
1161 }
1162 else
1163 {
1164 ret = -ENXIO;
1165 }
1166 break;
1167 }
1168
1169 case VIDIOCPWCMPTSTATUS:
1170 {
1171 if (pdev->features & FEATURE_MOTOR_PANTILT)
1172 {
1173 ARG_DEF(struct pwc_mpt_status, status)
1174
1175 ret = pwc_mpt_get_status(pdev, ARGA(status));
1176 ARG_OUT(status)
1177 }
1178 else
1179 {
1180 ret = -ENXIO;
1181 }
1182 break;
1183 }
1184
1185 case VIDIOCPWCGVIDCMD:
1186 {
1187 ARG_DEF(struct pwc_video_command, vcmd);
1188
1189 ARGR(vcmd).type = pdev->type;
1190 ARGR(vcmd).release = pdev->release;
1191 ARGR(vcmd).command_len = pdev->cmd_len;
1192 memcpy(&ARGR(vcmd).command_buf, pdev->cmd_buf, pdev->cmd_len);
1193 ARGR(vcmd).bandlength = pdev->vbandlength;
1194 ARGR(vcmd).frame_size = pdev->frame_size;
1195 ARG_OUT(vcmd)
1196 break;
1197 }
1198 /*
1199 case VIDIOCPWCGVIDTABLE:
1200 {
1201 ARG_DEF(struct pwc_table_init_buffer, table);
1202 ARGR(table).len = pdev->cmd_len;
1203 memcpy(&ARGR(table).buffer, pdev->decompress_data, pdev->decompressor->table_size);
1204 ARG_OUT(table)
1205 break;
1206 }
1207 */
1208
1209 default:
1210 ret = -ENOIOCTLCMD;
1211 break;
1212 }
1213
1214 if (ret > 0)
1215 return 0;
1216 return ret;
1217}
1218
1219
1220/* vim: set cinoptions= formatoptions=croql cindent shiftwidth=8 tabstop=8: */
diff --git a/drivers/media/video/pwc/pwc-dec1.c b/drivers/media/video/pwc/pwc-dec1.c
new file mode 100644
index 00000000000..be0e02cb487
--- /dev/null
+++ b/drivers/media/video/pwc/pwc-dec1.c
@@ -0,0 +1,40 @@
1/* Linux driver for Philips webcam
2 Decompression for chipset version 1
3 (C) 2004-2006 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#include "pwc-dec1.h"
26
27int pwc_dec1_init(struct pwc_device *pwc, int type, int release, void *buffer)
28{
29 struct pwc_dec1_private *pdec;
30
31 if (pwc->decompress_data == NULL) {
32 pdec = kmalloc(sizeof(struct pwc_dec1_private), GFP_KERNEL);
33 if (pdec == NULL)
34 return -ENOMEM;
35 pwc->decompress_data = pdec;
36 }
37 pdec = pwc->decompress_data;
38
39 return 0;
40}
diff --git a/drivers/media/video/pwc/pwc-dec1.h b/drivers/media/video/pwc/pwc-dec1.h
new file mode 100644
index 00000000000..a57d8601080
--- /dev/null
+++ b/drivers/media/video/pwc/pwc-dec1.h
@@ -0,0 +1,37 @@
1/* Linux driver for Philips webcam
2 (C) 2004-2006 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_DEC1_H
26#define PWC_DEC1_H
27
28#include "pwc.h"
29
30struct pwc_dec1_private
31{
32 int version;
33};
34
35int pwc_dec1_init(struct pwc_device *pwc, int type, int release, void *buffer);
36
37#endif
diff --git a/drivers/media/video/pwc/pwc-dec23.c b/drivers/media/video/pwc/pwc-dec23.c
new file mode 100644
index 00000000000..06a4e877ba4
--- /dev/null
+++ b/drivers/media/video/pwc/pwc-dec23.c
@@ -0,0 +1,920 @@
1/* Linux driver for Philips webcam
2 Decompression for chipset version 2 et 3
3 (C) 2004-2006 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#include "pwc-timon.h"
28#include "pwc-kiara.h"
29#include "pwc-dec23.h"
30#include <media/pwc-ioctl.h>
31
32#include <linux/string.h>
33#include <linux/slab.h>
34
35/*
36 * USE_LOOKUP_TABLE_TO_CLAMP
37 * 0: use a C version of this tests: { a<0?0:(a>255?255:a) }
38 * 1: use a faster lookup table for cpu with a big cache (intel)
39 */
40#define USE_LOOKUP_TABLE_TO_CLAMP 1
41/*
42 * UNROLL_LOOP_FOR_COPYING_BLOCK
43 * 0: use a loop for a smaller code (but little slower)
44 * 1: when unrolling the loop, gcc produces some faster code (perhaps only
45 * valid for intel processor class). Activating this option, automaticaly
46 * activate USE_LOOKUP_TABLE_TO_CLAMP
47 */
48#define UNROLL_LOOP_FOR_COPY 1
49#if UNROLL_LOOP_FOR_COPY
50# undef USE_LOOKUP_TABLE_TO_CLAMP
51# define USE_LOOKUP_TABLE_TO_CLAMP 1
52#endif
53
54/*
55 * ENABLE_BAYER_DECODER
56 * 0: bayer decoder is not build (save some space)
57 * 1: bayer decoder is build and can be used
58 */
59#define ENABLE_BAYER_DECODER 0
60
61static void build_subblock_pattern(struct pwc_dec23_private *pdec)
62{
63 static const unsigned int initial_values[12] = {
64 -0x526500, -0x221200, 0x221200, 0x526500,
65 -0x3de200, 0x3de200,
66 -0x6db480, -0x2d5d00, 0x2d5d00, 0x6db480,
67 -0x12c200, 0x12c200
68
69 };
70 static const unsigned int values_derivated[12] = {
71 0xa4ca, 0x4424, -0x4424, -0xa4ca,
72 0x7bc4, -0x7bc4,
73 0xdb69, 0x5aba, -0x5aba, -0xdb69,
74 0x2584, -0x2584
75 };
76 unsigned int temp_values[12];
77 int i, j;
78
79 memcpy(temp_values, initial_values, sizeof(initial_values));
80 for (i = 0; i < 256; i++) {
81 for (j = 0; j < 12; j++) {
82 pdec->table_subblock[i][j] = temp_values[j];
83 temp_values[j] += values_derivated[j];
84 }
85 }
86}
87
88static void build_bit_powermask_table(struct pwc_dec23_private *pdec)
89{
90 unsigned char *p;
91 unsigned int bit, byte, mask, val;
92 unsigned int bitpower = 1;
93
94 for (bit = 0; bit < 8; bit++) {
95 mask = bitpower - 1;
96 p = pdec->table_bitpowermask[bit];
97 for (byte = 0; byte < 256; byte++) {
98 val = (byte & mask);
99 if (byte & bitpower)
100 val = -val;
101 *p++ = val;
102 }
103 bitpower<<=1;
104 }
105}
106
107
108static void build_table_color(const unsigned int romtable[16][8],
109 unsigned char p0004[16][1024],
110 unsigned char p8004[16][256])
111{
112 int compression_mode, j, k, bit, pw;
113 unsigned char *p0, *p8;
114 const unsigned int *r;
115
116 /* We have 16 compressions tables */
117 for (compression_mode = 0; compression_mode < 16; compression_mode++) {
118 p0 = p0004[compression_mode];
119 p8 = p8004[compression_mode];
120 r = romtable[compression_mode];
121
122 for (j = 0; j < 8; j++, r++, p0 += 128) {
123
124 for (k = 0; k < 16; k++) {
125 if (k == 0)
126 bit = 1;
127 else if (k >= 1 && k < 3)
128 bit = (r[0] >> 15) & 7;
129 else if (k >= 3 && k < 6)
130 bit = (r[0] >> 12) & 7;
131 else if (k >= 6 && k < 10)
132 bit = (r[0] >> 9) & 7;
133 else if (k >= 10 && k < 13)
134 bit = (r[0] >> 6) & 7;
135 else if (k >= 13 && k < 15)
136 bit = (r[0] >> 3) & 7;
137 else
138 bit = (r[0]) & 7;
139 if (k == 0)
140 *p8++ = 8;
141 else
142 *p8++ = j - bit;
143 *p8++ = bit;
144
145 pw = 1 << bit;
146 p0[k + 0x00] = (1 * pw) + 0x80;
147 p0[k + 0x10] = (2 * pw) + 0x80;
148 p0[k + 0x20] = (3 * pw) + 0x80;
149 p0[k + 0x30] = (4 * pw) + 0x80;
150 p0[k + 0x40] = (-1 * pw) + 0x80;
151 p0[k + 0x50] = (-2 * pw) + 0x80;
152 p0[k + 0x60] = (-3 * pw) + 0x80;
153 p0[k + 0x70] = (-4 * pw) + 0x80;
154 } /* end of for (k=0; k<16; k++, p8++) */
155 } /* end of for (j=0; j<8; j++ , table++) */
156 } /* end of foreach compression_mode */
157}
158
159/*
160 *
161 */
162static void fill_table_dc00_d800(struct pwc_dec23_private *pdec)
163{
164#define SCALEBITS 15
165#define ONE_HALF (1UL << (SCALEBITS - 1))
166 int i;
167 unsigned int offset1 = ONE_HALF;
168 unsigned int offset2 = 0x0000;
169
170 for (i=0; i<256; i++) {
171 pdec->table_dc00[i] = offset1 & ~(ONE_HALF);
172 pdec->table_d800[i] = offset2;
173
174 offset1 += 0x7bc4;
175 offset2 += 0x7bc4;
176 }
177}
178
179/*
180 * To decode the stream:
181 * if look_bits(2) == 0: # op == 2 in the lookup table
182 * skip_bits(2)
183 * end of the stream
184 * elif look_bits(3) == 7: # op == 1 in the lookup table
185 * skip_bits(3)
186 * yyyy = get_bits(4)
187 * xxxx = get_bits(8)
188 * else: # op == 0 in the lookup table
189 * skip_bits(x)
190 *
191 * For speedup processing, we build a lookup table and we takes the first 6 bits.
192 *
193 * struct {
194 * unsigned char op; // operation to execute
195 * unsigned char bits; // bits use to perform operation
196 * unsigned char offset1; // offset to add to access in the table_0004 % 16
197 * unsigned char offset2; // offset to add to access in the table_0004
198 * }
199 *
200 * How to build this table ?
201 * op == 2 when (i%4)==0
202 * op == 1 when (i%8)==7
203 * op == 0 otherwise
204 *
205 */
206static const unsigned char hash_table_ops[64*4] = {
207 0x02, 0x00, 0x00, 0x00,
208 0x00, 0x03, 0x01, 0x00,
209 0x00, 0x04, 0x01, 0x10,
210 0x00, 0x06, 0x01, 0x30,
211 0x02, 0x00, 0x00, 0x00,
212 0x00, 0x03, 0x01, 0x40,
213 0x00, 0x05, 0x01, 0x20,
214 0x01, 0x00, 0x00, 0x00,
215 0x02, 0x00, 0x00, 0x00,
216 0x00, 0x03, 0x01, 0x00,
217 0x00, 0x04, 0x01, 0x50,
218 0x00, 0x05, 0x02, 0x00,
219 0x02, 0x00, 0x00, 0x00,
220 0x00, 0x03, 0x01, 0x40,
221 0x00, 0x05, 0x03, 0x00,
222 0x01, 0x00, 0x00, 0x00,
223 0x02, 0x00, 0x00, 0x00,
224 0x00, 0x03, 0x01, 0x00,
225 0x00, 0x04, 0x01, 0x10,
226 0x00, 0x06, 0x02, 0x10,
227 0x02, 0x00, 0x00, 0x00,
228 0x00, 0x03, 0x01, 0x40,
229 0x00, 0x05, 0x01, 0x60,
230 0x01, 0x00, 0x00, 0x00,
231 0x02, 0x00, 0x00, 0x00,
232 0x00, 0x03, 0x01, 0x00,
233 0x00, 0x04, 0x01, 0x50,
234 0x00, 0x05, 0x02, 0x40,
235 0x02, 0x00, 0x00, 0x00,
236 0x00, 0x03, 0x01, 0x40,
237 0x00, 0x05, 0x03, 0x40,
238 0x01, 0x00, 0x00, 0x00,
239 0x02, 0x00, 0x00, 0x00,
240 0x00, 0x03, 0x01, 0x00,
241 0x00, 0x04, 0x01, 0x10,
242 0x00, 0x06, 0x01, 0x70,
243 0x02, 0x00, 0x00, 0x00,
244 0x00, 0x03, 0x01, 0x40,
245 0x00, 0x05, 0x01, 0x20,
246 0x01, 0x00, 0x00, 0x00,
247 0x02, 0x00, 0x00, 0x00,
248 0x00, 0x03, 0x01, 0x00,
249 0x00, 0x04, 0x01, 0x50,
250 0x00, 0x05, 0x02, 0x00,
251 0x02, 0x00, 0x00, 0x00,
252 0x00, 0x03, 0x01, 0x40,
253 0x00, 0x05, 0x03, 0x00,
254 0x01, 0x00, 0x00, 0x00,
255 0x02, 0x00, 0x00, 0x00,
256 0x00, 0x03, 0x01, 0x00,
257 0x00, 0x04, 0x01, 0x10,
258 0x00, 0x06, 0x02, 0x50,
259 0x02, 0x00, 0x00, 0x00,
260 0x00, 0x03, 0x01, 0x40,
261 0x00, 0x05, 0x01, 0x60,
262 0x01, 0x00, 0x00, 0x00,
263 0x02, 0x00, 0x00, 0x00,
264 0x00, 0x03, 0x01, 0x00,
265 0x00, 0x04, 0x01, 0x50,
266 0x00, 0x05, 0x02, 0x40,
267 0x02, 0x00, 0x00, 0x00,
268 0x00, 0x03, 0x01, 0x40,
269 0x00, 0x05, 0x03, 0x40,
270 0x01, 0x00, 0x00, 0x00
271};
272
273/*
274 *
275 */
276static const unsigned int MulIdx[16][16] = {
277 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,},
278 {0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3,},
279 {0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3,},
280 {4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 4, 4, 4, 4,},
281 {6, 7, 8, 9, 7, 10, 11, 8, 8, 11, 10, 7, 9, 8, 7, 6,},
282 {4, 5, 5, 4, 4, 5, 5, 4, 4, 5, 5, 4, 4, 5, 5, 4,},
283 {1, 3, 0, 2, 1, 3, 0, 2, 1, 3, 0, 2, 1, 3, 0, 2,},
284 {0, 3, 3, 0, 1, 2, 2, 1, 2, 1, 1, 2, 3, 0, 0, 3,},
285 {0, 1, 2, 3, 3, 2, 1, 0, 3, 2, 1, 0, 0, 1, 2, 3,},
286 {1, 1, 1, 1, 3, 3, 3, 3, 0, 0, 0, 0, 2, 2, 2, 2,},
287 {7, 10, 11, 8, 9, 8, 7, 6, 6, 7, 8, 9, 8, 11, 10, 7,},
288 {4, 5, 5, 4, 5, 4, 4, 5, 5, 4, 4, 5, 4, 5, 5, 4,},
289 {7, 9, 6, 8, 10, 8, 7, 11, 11, 7, 8, 10, 8, 6, 9, 7,},
290 {1, 3, 0, 2, 2, 0, 3, 1, 2, 0, 3, 1, 1, 3, 0, 2,},
291 {1, 2, 2, 1, 3, 0, 0, 3, 0, 3, 3, 0, 2, 1, 1, 2,},
292 {10, 8, 7, 11, 8, 6, 9, 7, 7, 9, 6, 8, 11, 7, 8, 10}
293};
294
295#if USE_LOOKUP_TABLE_TO_CLAMP
296#define MAX_OUTER_CROP_VALUE (512)
297static unsigned char pwc_crop_table[256 + 2*MAX_OUTER_CROP_VALUE];
298#define CLAMP(x) (pwc_crop_table[MAX_OUTER_CROP_VALUE+(x)])
299#else
300#define CLAMP(x) ((x)>255?255:((x)<0?0:x))
301#endif
302
303
304/* If the type or the command change, we rebuild the lookup table */
305int pwc_dec23_init(struct pwc_device *pwc, int type, unsigned char *cmd)
306{
307 int flags, version, shift, i;
308 struct pwc_dec23_private *pdec;
309
310 if (pwc->decompress_data == NULL) {
311 pdec = kmalloc(sizeof(struct pwc_dec23_private), GFP_KERNEL);
312 if (pdec == NULL)
313 return -ENOMEM;
314 pwc->decompress_data = pdec;
315 }
316 pdec = pwc->decompress_data;
317
318 if (DEVICE_USE_CODEC3(type)) {
319 flags = cmd[2] & 0x18;
320 if (flags == 8)
321 pdec->nbits = 7; /* More bits, mean more bits to encode the stream, but better quality */
322 else if (flags == 0x10)
323 pdec->nbits = 8;
324 else
325 pdec->nbits = 6;
326
327 version = cmd[2] >> 5;
328 build_table_color(KiaraRomTable[version][0], pdec->table_0004_pass1, pdec->table_8004_pass1);
329 build_table_color(KiaraRomTable[version][1], pdec->table_0004_pass2, pdec->table_8004_pass2);
330
331 } else {
332
333 flags = cmd[2] & 6;
334 if (flags == 2)
335 pdec->nbits = 7;
336 else if (flags == 4)
337 pdec->nbits = 8;
338 else
339 pdec->nbits = 6;
340
341 version = cmd[2] >> 3;
342 build_table_color(TimonRomTable[version][0], pdec->table_0004_pass1, pdec->table_8004_pass1);
343 build_table_color(TimonRomTable[version][1], pdec->table_0004_pass2, pdec->table_8004_pass2);
344 }
345
346 /* Informations can be coded on a variable number of bits but never less than 8 */
347 shift = 8 - pdec->nbits;
348 pdec->scalebits = SCALEBITS - shift;
349 pdec->nbitsmask = 0xFF >> shift;
350
351 fill_table_dc00_d800(pdec);
352 build_subblock_pattern(pdec);
353 build_bit_powermask_table(pdec);
354
355#if USE_LOOKUP_TABLE_TO_CLAMP
356 /* Build the static table to clamp value [0-255] */
357 for (i=0;i<MAX_OUTER_CROP_VALUE;i++)
358 pwc_crop_table[i] = 0;
359 for (i=0; i<256; i++)
360 pwc_crop_table[MAX_OUTER_CROP_VALUE+i] = i;
361 for (i=0; i<MAX_OUTER_CROP_VALUE; i++)
362 pwc_crop_table[MAX_OUTER_CROP_VALUE+256+i] = 255;
363#endif
364
365 return 0;
366}
367
368/*
369 * Copy the 4x4 image block to Y plane buffer
370 */
371static void copy_image_block_Y(const int *src, unsigned char *dst, unsigned int bytes_per_line, unsigned int scalebits)
372{
373#if UNROLL_LOOP_FOR_COPY
374 const unsigned char *cm = pwc_crop_table+MAX_OUTER_CROP_VALUE;
375 const int *c = src;
376 unsigned char *d = dst;
377
378 *d++ = cm[c[0] >> scalebits];
379 *d++ = cm[c[1] >> scalebits];
380 *d++ = cm[c[2] >> scalebits];
381 *d++ = cm[c[3] >> scalebits];
382
383 d = dst + bytes_per_line;
384 *d++ = cm[c[4] >> scalebits];
385 *d++ = cm[c[5] >> scalebits];
386 *d++ = cm[c[6] >> scalebits];
387 *d++ = cm[c[7] >> scalebits];
388
389 d = dst + bytes_per_line*2;
390 *d++ = cm[c[8] >> scalebits];
391 *d++ = cm[c[9] >> scalebits];
392 *d++ = cm[c[10] >> scalebits];
393 *d++ = cm[c[11] >> scalebits];
394
395 d = dst + bytes_per_line*3;
396 *d++ = cm[c[12] >> scalebits];
397 *d++ = cm[c[13] >> scalebits];
398 *d++ = cm[c[14] >> scalebits];
399 *d++ = cm[c[15] >> scalebits];
400#else
401 int i;
402 const int *c = src;
403 unsigned char *d = dst;
404 for (i = 0; i < 4; i++, c++)
405 *d++ = CLAMP((*c) >> scalebits);
406
407 d = dst + bytes_per_line;
408 for (i = 0; i < 4; i++, c++)
409 *d++ = CLAMP((*c) >> scalebits);
410
411 d = dst + bytes_per_line*2;
412 for (i = 0; i < 4; i++, c++)
413 *d++ = CLAMP((*c) >> scalebits);
414
415 d = dst + bytes_per_line*3;
416 for (i = 0; i < 4; i++, c++)
417 *d++ = CLAMP((*c) >> scalebits);
418#endif
419}
420
421/*
422 * Copy the 4x4 image block to a CrCb plane buffer
423 *
424 */
425static void copy_image_block_CrCb(const int *src, unsigned char *dst, unsigned int bytes_per_line, unsigned int scalebits)
426{
427#if UNROLL_LOOP_FOR_COPY
428 /* Unroll all loops */
429 const unsigned char *cm = pwc_crop_table+MAX_OUTER_CROP_VALUE;
430 const int *c = src;
431 unsigned char *d = dst;
432
433 *d++ = cm[c[0] >> scalebits];
434 *d++ = cm[c[4] >> scalebits];
435 *d++ = cm[c[1] >> scalebits];
436 *d++ = cm[c[5] >> scalebits];
437 *d++ = cm[c[2] >> scalebits];
438 *d++ = cm[c[6] >> scalebits];
439 *d++ = cm[c[3] >> scalebits];
440 *d++ = cm[c[7] >> scalebits];
441
442 d = dst + bytes_per_line;
443 *d++ = cm[c[12] >> scalebits];
444 *d++ = cm[c[8] >> scalebits];
445 *d++ = cm[c[13] >> scalebits];
446 *d++ = cm[c[9] >> scalebits];
447 *d++ = cm[c[14] >> scalebits];
448 *d++ = cm[c[10] >> scalebits];
449 *d++ = cm[c[15] >> scalebits];
450 *d++ = cm[c[11] >> scalebits];
451#else
452 int i;
453 const int *c1 = src;
454 const int *c2 = src + 4;
455 unsigned char *d = dst;
456
457 for (i = 0; i < 4; i++, c1++, c2++) {
458 *d++ = CLAMP((*c1) >> scalebits);
459 *d++ = CLAMP((*c2) >> scalebits);
460 }
461 c1 = src + 12;
462 d = dst + bytes_per_line;
463 for (i = 0; i < 4; i++, c1++, c2++) {
464 *d++ = CLAMP((*c1) >> scalebits);
465 *d++ = CLAMP((*c2) >> scalebits);
466 }
467#endif
468}
469
470#if ENABLE_BAYER_DECODER
471/*
472 * Format: 8x2 pixels
473 * . G . G . G . G . G . G . G
474 * . . . . . . . . . . . . . .
475 * . G . G . G . G . G . G . G
476 * . . . . . . . . . . . . . .
477 * or
478 * . . . . . . . . . . . . . .
479 * G . G . G . G . G . G . G .
480 * . . . . . . . . . . . . . .
481 * G . G . G . G . G . G . G .
482*/
483static void copy_image_block_Green(const int *src, unsigned char *dst, unsigned int bytes_per_line, unsigned int scalebits)
484{
485#if UNROLL_LOOP_FOR_COPY
486 /* Unroll all loops */
487 const unsigned char *cm = pwc_crop_table+MAX_OUTER_CROP_VALUE;
488 unsigned char *d = dst;
489 const int *c = src;
490
491 d[0] = cm[c[0] >> scalebits];
492 d[2] = cm[c[1] >> scalebits];
493 d[4] = cm[c[2] >> scalebits];
494 d[6] = cm[c[3] >> scalebits];
495 d[8] = cm[c[4] >> scalebits];
496 d[10] = cm[c[5] >> scalebits];
497 d[12] = cm[c[6] >> scalebits];
498 d[14] = cm[c[7] >> scalebits];
499
500 d = dst + bytes_per_line;
501 d[0] = cm[c[8] >> scalebits];
502 d[2] = cm[c[9] >> scalebits];
503 d[4] = cm[c[10] >> scalebits];
504 d[6] = cm[c[11] >> scalebits];
505 d[8] = cm[c[12] >> scalebits];
506 d[10] = cm[c[13] >> scalebits];
507 d[12] = cm[c[14] >> scalebits];
508 d[14] = cm[c[15] >> scalebits];
509#else
510 int i;
511 unsigned char *d;
512 const int *c = src;
513
514 d = dst;
515 for (i = 0; i < 8; i++, c++)
516 d[i*2] = CLAMP((*c) >> scalebits);
517
518 d = dst + bytes_per_line;
519 for (i = 0; i < 8; i++, c++)
520 d[i*2] = CLAMP((*c) >> scalebits);
521#endif
522}
523#endif
524
525#if ENABLE_BAYER_DECODER
526/*
527 * Format: 4x4 pixels
528 * R . R . R . R
529 * . B . B . B .
530 * R . R . R . R
531 * . B . B . B .
532 */
533static void copy_image_block_RedBlue(const int *src, unsigned char *dst, unsigned int bytes_per_line, unsigned int scalebits)
534{
535#if UNROLL_LOOP_FOR_COPY
536 /* Unroll all loops */
537 const unsigned char *cm = pwc_crop_table+MAX_OUTER_CROP_VALUE;
538 unsigned char *d = dst;
539 const int *c = src;
540
541 d[0] = cm[c[0] >> scalebits];
542 d[2] = cm[c[1] >> scalebits];
543 d[4] = cm[c[2] >> scalebits];
544 d[6] = cm[c[3] >> scalebits];
545
546 d = dst + bytes_per_line;
547 d[1] = cm[c[4] >> scalebits];
548 d[3] = cm[c[5] >> scalebits];
549 d[5] = cm[c[6] >> scalebits];
550 d[7] = cm[c[7] >> scalebits];
551
552 d = dst + bytes_per_line*2;
553 d[0] = cm[c[8] >> scalebits];
554 d[2] = cm[c[9] >> scalebits];
555 d[4] = cm[c[10] >> scalebits];
556 d[6] = cm[c[11] >> scalebits];
557
558 d = dst + bytes_per_line*3;
559 d[1] = cm[c[12] >> scalebits];
560 d[3] = cm[c[13] >> scalebits];
561 d[5] = cm[c[14] >> scalebits];
562 d[7] = cm[c[15] >> scalebits];
563#else
564 int i;
565 unsigned char *d;
566 const int *c = src;
567
568 d = dst;
569 for (i = 0; i < 4; i++, c++)
570 d[i*2] = CLAMP((*c) >> scalebits);
571
572 d = dst + bytes_per_line;
573 for (i = 0; i < 4; i++, c++)
574 d[i*2+1] = CLAMP((*c) >> scalebits);
575
576 d = dst + bytes_per_line*2;
577 for (i = 0; i < 4; i++, c++)
578 d[i*2] = CLAMP((*c) >> scalebits);
579
580 d = dst + bytes_per_line*3;
581 for (i = 0; i < 4; i++, c++)
582 d[i*2+1] = CLAMP((*c) >> scalebits);
583#endif
584}
585#endif
586
587/*
588 * To manage the stream, we keep bits in a 32 bits register.
589 * fill_nbits(n): fill the reservoir with at least n bits
590 * skip_bits(n): discard n bits from the reservoir
591 * get_bits(n): fill the reservoir, returns the first n bits and discard the
592 * bits from the reservoir.
593 * __get_nbits(n): faster version of get_bits(n), but asumes that the reservoir
594 * contains at least n bits. bits returned is discarded.
595 */
596#define fill_nbits(pdec, nbits_wanted) do { \
597 while (pdec->nbits_in_reservoir<(nbits_wanted)) \
598 { \
599 pdec->reservoir |= (*(pdec->stream)++) << (pdec->nbits_in_reservoir); \
600 pdec->nbits_in_reservoir += 8; \
601 } \
602} while(0);
603
604#define skip_nbits(pdec, nbits_to_skip) do { \
605 pdec->reservoir >>= (nbits_to_skip); \
606 pdec->nbits_in_reservoir -= (nbits_to_skip); \
607} while(0);
608
609#define get_nbits(pdec, nbits_wanted, result) do { \
610 fill_nbits(pdec, nbits_wanted); \
611 result = (pdec->reservoir) & ((1U<<(nbits_wanted))-1); \
612 skip_nbits(pdec, nbits_wanted); \
613} while(0);
614
615#define __get_nbits(pdec, nbits_wanted, result) do { \
616 result = (pdec->reservoir) & ((1U<<(nbits_wanted))-1); \
617 skip_nbits(pdec, nbits_wanted); \
618} while(0);
619
620#define look_nbits(pdec, nbits_wanted) \
621 ((pdec->reservoir) & ((1U<<(nbits_wanted))-1))
622
623/*
624 * Decode a 4x4 pixel block
625 */
626static void decode_block(struct pwc_dec23_private *pdec,
627 const unsigned char *ptable0004,
628 const unsigned char *ptable8004)
629{
630 unsigned int primary_color;
631 unsigned int channel_v, offset1, op;
632 int i;
633
634 fill_nbits(pdec, 16);
635 __get_nbits(pdec, pdec->nbits, primary_color);
636
637 if (look_nbits(pdec,2) == 0) {
638 skip_nbits(pdec, 2);
639 /* Very simple, the color is the same for all pixels of the square */
640 for (i = 0; i < 16; i++)
641 pdec->temp_colors[i] = pdec->table_dc00[primary_color];
642
643 return;
644 }
645
646 /* This block is encoded with small pattern */
647 for (i = 0; i < 16; i++)
648 pdec->temp_colors[i] = pdec->table_d800[primary_color];
649
650 __get_nbits(pdec, 3, channel_v);
651 channel_v = ((channel_v & 1) << 2) | (channel_v & 2) | ((channel_v & 4) >> 2);
652
653 ptable0004 += (channel_v * 128);
654 ptable8004 += (channel_v * 32);
655
656 offset1 = 0;
657 do
658 {
659 unsigned int htable_idx, rows = 0;
660 const unsigned int *block;
661
662 /* [ zzzz y x x ]
663 * xx == 00 :=> end of the block def, remove the two bits from the stream
664 * yxx == 111
665 * yxx == any other value
666 *
667 */
668 fill_nbits(pdec, 16);
669 htable_idx = look_nbits(pdec, 6);
670 op = hash_table_ops[htable_idx * 4];
671
672 if (op == 2) {
673 skip_nbits(pdec, 2);
674
675 } else if (op == 1) {
676 /* 15bits [ xxxx xxxx yyyy 111 ]
677 * yyy => offset in the table8004
678 * xxx => offset in the tabled004 (tree)
679 */
680 unsigned int mask, shift;
681 unsigned int nbits, col1;
682 unsigned int yyyy;
683
684 skip_nbits(pdec, 3);
685 /* offset1 += yyyy */
686 __get_nbits(pdec, 4, yyyy);
687 offset1 += 1 + yyyy;
688 offset1 &= 0x0F;
689 nbits = ptable8004[offset1 * 2];
690
691 /* col1 = xxxx xxxx */
692 __get_nbits(pdec, nbits+1, col1);
693
694 /* Bit mask table */
695 mask = pdec->table_bitpowermask[nbits][col1];
696 shift = ptable8004[offset1 * 2 + 1];
697 rows = ((mask << shift) + 0x80) & 0xFF;
698
699 block = pdec->table_subblock[rows];
700 for (i = 0; i < 16; i++)
701 pdec->temp_colors[i] += block[MulIdx[offset1][i]];
702
703 } else {
704 /* op == 0
705 * offset1 is coded on 3 bits
706 */
707 unsigned int shift;
708
709 offset1 += hash_table_ops [htable_idx * 4 + 2];
710 offset1 &= 0x0F;
711
712 rows = ptable0004[offset1 + hash_table_ops [htable_idx * 4 + 3]];
713 block = pdec->table_subblock[rows];
714 for (i = 0; i < 16; i++)
715 pdec->temp_colors[i] += block[MulIdx[offset1][i]];
716
717 shift = hash_table_ops[htable_idx * 4 + 1];
718 skip_nbits(pdec, shift);
719 }
720
721 } while (op != 2);
722
723}
724
725static void DecompressBand23(struct pwc_dec23_private *pdec,
726 const unsigned char *rawyuv,
727 unsigned char *planar_y,
728 unsigned char *planar_u,
729 unsigned char *planar_v,
730 unsigned int compressed_image_width,
731 unsigned int real_image_width)
732{
733 int compression_index, nblocks;
734 const unsigned char *ptable0004;
735 const unsigned char *ptable8004;
736
737 pdec->reservoir = 0;
738 pdec->nbits_in_reservoir = 0;
739 pdec->stream = rawyuv + 1; /* The first byte of the stream is skipped */
740
741 get_nbits(pdec, 4, compression_index);
742
743 /* pass 1: uncompress Y component */
744 nblocks = compressed_image_width / 4;
745
746 ptable0004 = pdec->table_0004_pass1[compression_index];
747 ptable8004 = pdec->table_8004_pass1[compression_index];
748
749 /* Each block decode a square of 4x4 */
750 while (nblocks) {
751 decode_block(pdec, ptable0004, ptable8004);
752 copy_image_block_Y(pdec->temp_colors, planar_y, real_image_width, pdec->scalebits);
753 planar_y += 4;
754 nblocks--;
755 }
756
757 /* pass 2: uncompress UV component */
758 nblocks = compressed_image_width / 8;
759
760 ptable0004 = pdec->table_0004_pass2[compression_index];
761 ptable8004 = pdec->table_8004_pass2[compression_index];
762
763 /* Each block decode a square of 4x4 */
764 while (nblocks) {
765 decode_block(pdec, ptable0004, ptable8004);
766 copy_image_block_CrCb(pdec->temp_colors, planar_u, real_image_width/2, pdec->scalebits);
767
768 decode_block(pdec, ptable0004, ptable8004);
769 copy_image_block_CrCb(pdec->temp_colors, planar_v, real_image_width/2, pdec->scalebits);
770
771 planar_v += 8;
772 planar_u += 8;
773 nblocks -= 2;
774 }
775
776}
777
778#if ENABLE_BAYER_DECODER
779/*
780 * Size need to be a multiple of 8 in width
781 *
782 * Return a block of four line encoded like this:
783 *
784 * G R G R G R G R G R G R G R G R
785 * B G B G B G B G B G B G B G B G
786 * G R G R G R G R G R G R G R G R
787 * B G B G B G B G B G B G B G B G
788 *
789 */
790static void DecompressBandBayer(struct pwc_dec23_private *pdec,
791 const unsigned char *rawyuv,
792 unsigned char *rgbbayer,
793 unsigned int compressed_image_width,
794 unsigned int real_image_width)
795{
796 int compression_index, nblocks;
797 const unsigned char *ptable0004;
798 const unsigned char *ptable8004;
799 unsigned char *dest;
800
801 pdec->reservoir = 0;
802 pdec->nbits_in_reservoir = 0;
803 pdec->stream = rawyuv + 1; /* The first byte of the stream is skipped */
804
805 get_nbits(pdec, 4, compression_index);
806
807 /* pass 1: uncompress RB component */
808 nblocks = compressed_image_width / 4;
809
810 ptable0004 = pdec->table_0004_pass1[compression_index];
811 ptable8004 = pdec->table_8004_pass1[compression_index];
812 dest = rgbbayer;
813
814 /* Each block decode a square of 4x4 */
815 while (nblocks) {
816 decode_block(pdec, ptable0004, ptable8004);
817 copy_image_block_RedBlue(pdec->temp_colors, rgbbayer, real_image_width, pdec->scalebits);
818 dest += 8;
819 nblocks--;
820 }
821
822 /* pass 2: uncompress G component */
823 nblocks = compressed_image_width / 8;
824
825 ptable0004 = pdec->table_0004_pass2[compression_index];
826 ptable8004 = pdec->table_8004_pass2[compression_index];
827
828 /* Each block decode a square of 4x4 */
829 while (nblocks) {
830 decode_block(pdec, ptable0004, ptable8004);
831 copy_image_block_Green(pdec->temp_colors, rgbbayer+1, real_image_width, pdec->scalebits);
832
833 decode_block(pdec, ptable0004, ptable8004);
834 copy_image_block_Green(pdec->temp_colors, rgbbayer+real_image_width, real_image_width, pdec->scalebits);
835
836 rgbbayer += 16;
837 nblocks -= 2;
838 }
839}
840#endif
841
842
843/**
844 *
845 * Uncompress a pwc23 buffer.
846 *
847 * pwc.view: size of the image wanted
848 * pwc.image: size of the image returned by the camera
849 * pwc.offset: (x,y) to displayer image in the view
850 *
851 * src: raw data
852 * dst: image output
853 * flags: PWCX_FLAG_PLANAR or PWCX_FLAG_BAYER
854 */
855void pwc_dec23_decompress(const struct pwc_device *pwc,
856 const void *src,
857 void *dst,
858 int flags)
859{
860 int bandlines_left, stride, bytes_per_block;
861
862 bandlines_left = pwc->image.y / 4;
863 bytes_per_block = pwc->view.x * 4;
864
865 if (flags & PWCX_FLAG_BAYER) {
866#if ENABLE_BAYER_DECODER
867 /* RGB Bayer format */
868 unsigned char *rgbout;
869
870 stride = pwc->view.x * pwc->offset.y;
871 rgbout = dst + stride + pwc->offset.x;
872
873
874 while (bandlines_left--) {
875
876 DecompressBandBayer(pwc->decompress_data,
877 src,
878 rgbout,
879 pwc->image.x, pwc->view.x);
880
881 src += pwc->vbandlength;
882 rgbout += bytes_per_block;
883
884 }
885#else
886 memset(dst, 0, pwc->view.x * pwc->view.y);
887#endif
888
889 } else {
890 /* YUV420P image format */
891 unsigned char *pout_planar_y;
892 unsigned char *pout_planar_u;
893 unsigned char *pout_planar_v;
894 unsigned int plane_size;
895
896 plane_size = pwc->view.x * pwc->view.y;
897
898 /* offset in Y plane */
899 stride = pwc->view.x * pwc->offset.y;
900 pout_planar_y = dst + stride + pwc->offset.x;
901
902 /* offsets in U/V planes */
903 stride = (pwc->view.x * pwc->offset.y) / 4 + pwc->offset.x / 2;
904 pout_planar_u = dst + plane_size + stride;
905 pout_planar_v = dst + plane_size + plane_size / 4 + stride;
906
907 while (bandlines_left--) {
908
909 DecompressBand23(pwc->decompress_data,
910 src,
911 pout_planar_y, pout_planar_u, pout_planar_v,
912 pwc->image.x, pwc->view.x);
913 src += pwc->vbandlength;
914 pout_planar_y += bytes_per_block;
915 pout_planar_u += pwc->view.x;
916 pout_planar_v += pwc->view.x;
917
918 }
919 }
920}
diff --git a/drivers/media/video/pwc/pwc-dec23.h b/drivers/media/video/pwc/pwc-dec23.h
new file mode 100644
index 00000000000..a0ac4f3dff8
--- /dev/null
+++ b/drivers/media/video/pwc/pwc-dec23.h
@@ -0,0 +1,57 @@
1/* Linux driver for Philips webcam
2 (C) 2004-2006 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
28#include "pwc.h"
29
30struct pwc_dec23_private
31{
32 unsigned int scalebits;
33 unsigned int nbitsmask, nbits; /* Number of bits of a color in the compressed stream */
34
35 unsigned int reservoir;
36 unsigned int nbits_in_reservoir;
37 const unsigned char *stream;
38 int temp_colors[16];
39
40 unsigned char table_0004_pass1[16][1024];
41 unsigned char table_0004_pass2[16][1024];
42 unsigned char table_8004_pass1[16][256];
43 unsigned char table_8004_pass2[16][256];
44 unsigned int table_subblock[256][12];
45
46 unsigned char table_bitpowermask[8][256];
47 unsigned int table_d800[256];
48 unsigned int table_dc00[256];
49
50};
51
52int pwc_dec23_init(struct pwc_device *pwc, int type, unsigned char *cmd);
53void pwc_dec23_decompress(const struct pwc_device *pwc,
54 const void *src,
55 void *dst,
56 int flags);
57#endif
diff --git a/drivers/media/video/pwc/pwc-if.c b/drivers/media/video/pwc/pwc-if.c
new file mode 100644
index 00000000000..51ca3589b1b
--- /dev/null
+++ b/drivers/media/video/pwc/pwc-if.c
@@ -0,0 +1,1483 @@
1/* Linux driver for Philips webcam
2 USB and Video4Linux interface part.
3 (C) 1999-2004 Nemosoft Unv.
4 (C) 2004-2006 Luc Saillard (luc@saillard.org)
5 (C) 2011 Hans de Goede <hdegoede@redhat.com>
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
29/*
30 This code forms the interface between the USB layers and the Philips
31 specific stuff. Some adanved stuff of the driver falls under an
32 NDA, signed between me and Philips B.V., Eindhoven, the Netherlands, and
33 is thus not distributed in source form. The binary pwcx.o module
34 contains the code that falls under the NDA.
35
36 In case you're wondering: 'pwc' stands for "Philips WebCam", but
37 I really didn't want to type 'philips_web_cam' every time (I'm lazy as
38 any Linux kernel hacker, but I don't like uncomprehensible abbreviations
39 without explanation).
40
41 Oh yes, convention: to disctinguish between all the various pointers to
42 device-structures, I use these names for the pointer variables:
43 udev: struct usb_device *
44 vdev: struct video_device (member of pwc_dev)
45 pdev: struct pwc_devive *
46*/
47
48/* Contributors:
49 - Alvarado: adding whitebalance code
50 - Alistar Moire: QuickCam 3000 Pro device/product ID
51 - Tony Hoyle: Creative Labs Webcam 5 device/product ID
52 - Mark Burazin: solving hang in VIDIOCSYNC when camera gets unplugged
53 - Jk Fang: Sotec Afina Eye ID
54 - Xavier Roche: QuickCam Pro 4000 ID
55 - Jens Knudsen: QuickCam Zoom ID
56 - J. Debert: QuickCam for Notebooks ID
57 - Pham Thanh Nam: webcam snapshot button as an event input device
58*/
59
60#include <linux/errno.h>
61#include <linux/init.h>
62#include <linux/mm.h>
63#include <linux/module.h>
64#include <linux/poll.h>
65#include <linux/slab.h>
66#ifdef CONFIG_USB_PWC_INPUT_EVDEV
67#include <linux/usb/input.h>
68#endif
69#include <linux/vmalloc.h>
70#include <asm/io.h>
71#include <linux/kernel.h> /* simple_strtol() */
72
73#include "pwc.h"
74#include "pwc-kiara.h"
75#include "pwc-timon.h"
76#include "pwc-dec23.h"
77#include "pwc-dec1.h"
78
79/* Function prototypes and driver templates */
80
81/* hotplug device table support */
82static const struct usb_device_id pwc_device_table [] = {
83 { USB_DEVICE(0x0471, 0x0302) }, /* Philips models */
84 { USB_DEVICE(0x0471, 0x0303) },
85 { USB_DEVICE(0x0471, 0x0304) },
86 { USB_DEVICE(0x0471, 0x0307) },
87 { USB_DEVICE(0x0471, 0x0308) },
88 { USB_DEVICE(0x0471, 0x030C) },
89 { USB_DEVICE(0x0471, 0x0310) },
90 { USB_DEVICE(0x0471, 0x0311) }, /* Philips ToUcam PRO II */
91 { USB_DEVICE(0x0471, 0x0312) },
92 { USB_DEVICE(0x0471, 0x0313) }, /* the 'new' 720K */
93 { USB_DEVICE(0x0471, 0x0329) }, /* Philips SPC 900NC PC Camera */
94 { USB_DEVICE(0x069A, 0x0001) }, /* Askey */
95 { USB_DEVICE(0x046D, 0x08B0) }, /* Logitech QuickCam Pro 3000 */
96 { USB_DEVICE(0x046D, 0x08B1) }, /* Logitech QuickCam Notebook Pro */
97 { USB_DEVICE(0x046D, 0x08B2) }, /* Logitech QuickCam Pro 4000 */
98 { USB_DEVICE(0x046D, 0x08B3) }, /* Logitech QuickCam Zoom (old model) */
99 { USB_DEVICE(0x046D, 0x08B4) }, /* Logitech QuickCam Zoom (new model) */
100 { USB_DEVICE(0x046D, 0x08B5) }, /* Logitech QuickCam Orbit/Sphere */
101 { USB_DEVICE(0x046D, 0x08B6) }, /* Cisco VT Camera */
102 { USB_DEVICE(0x046D, 0x08B7) }, /* Logitech ViewPort AV 100 */
103 { USB_DEVICE(0x046D, 0x08B8) }, /* Logitech (reserved) */
104 { USB_DEVICE(0x055D, 0x9000) }, /* Samsung MPC-C10 */
105 { USB_DEVICE(0x055D, 0x9001) }, /* Samsung MPC-C30 */
106 { USB_DEVICE(0x055D, 0x9002) }, /* Samsung SNC-35E (Ver3.0) */
107 { USB_DEVICE(0x041E, 0x400C) }, /* Creative Webcam 5 */
108 { USB_DEVICE(0x041E, 0x4011) }, /* Creative Webcam Pro Ex */
109 { USB_DEVICE(0x04CC, 0x8116) }, /* Afina Eye */
110 { USB_DEVICE(0x06BE, 0x8116) }, /* new Afina Eye */
111 { USB_DEVICE(0x0d81, 0x1910) }, /* Visionite */
112 { USB_DEVICE(0x0d81, 0x1900) },
113 { }
114};
115MODULE_DEVICE_TABLE(usb, pwc_device_table);
116
117static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id *id);
118static void usb_pwc_disconnect(struct usb_interface *intf);
119static void pwc_isoc_cleanup(struct pwc_device *pdev);
120
121static struct usb_driver pwc_driver = {
122 .name = "Philips webcam", /* name */
123 .id_table = pwc_device_table,
124 .probe = usb_pwc_probe, /* probe() */
125 .disconnect = usb_pwc_disconnect, /* disconnect() */
126};
127
128#define MAX_DEV_HINTS 20
129#define MAX_ISOC_ERRORS 20
130
131static int default_fps = 10;
132#ifdef CONFIG_USB_PWC_DEBUG
133 int pwc_trace = PWC_DEBUG_LEVEL;
134#endif
135static int power_save = -1;
136static int led_on = 100, led_off; /* defaults to LED that is on while in use */
137static int pwc_preferred_compression = 1; /* 0..3 = uncompressed..high */
138static struct {
139 int type;
140 char serial_number[30];
141 int device_node;
142 struct pwc_device *pdev;
143} device_hint[MAX_DEV_HINTS];
144
145/***/
146
147static int pwc_video_open(struct file *file);
148static int pwc_video_close(struct file *file);
149static ssize_t pwc_video_read(struct file *file, char __user *buf,
150 size_t count, loff_t *ppos);
151static unsigned int pwc_video_poll(struct file *file, poll_table *wait);
152static int pwc_video_mmap(struct file *file, struct vm_area_struct *vma);
153static void pwc_video_release(struct video_device *vfd);
154
155static const struct v4l2_file_operations pwc_fops = {
156 .owner = THIS_MODULE,
157 .open = pwc_video_open,
158 .release = pwc_video_close,
159 .read = pwc_video_read,
160 .poll = pwc_video_poll,
161 .mmap = pwc_video_mmap,
162 .unlocked_ioctl = video_ioctl2,
163};
164static struct video_device pwc_template = {
165 .name = "Philips Webcam", /* Filled in later */
166 .release = pwc_video_release,
167 .fops = &pwc_fops,
168 .ioctl_ops = &pwc_ioctl_ops,
169};
170
171/***************************************************************************/
172/* Private functions */
173
174struct pwc_frame_buf *pwc_get_next_fill_buf(struct pwc_device *pdev)
175{
176 unsigned long flags = 0;
177 struct pwc_frame_buf *buf = NULL;
178
179 spin_lock_irqsave(&pdev->queued_bufs_lock, flags);
180 if (list_empty(&pdev->queued_bufs))
181 goto leave;
182
183 buf = list_entry(pdev->queued_bufs.next, struct pwc_frame_buf, list);
184 list_del(&buf->list);
185leave:
186 spin_unlock_irqrestore(&pdev->queued_bufs_lock, flags);
187 return buf;
188}
189
190static void pwc_snapshot_button(struct pwc_device *pdev, int down)
191{
192 if (down) {
193 PWC_TRACE("Snapshot button pressed.\n");
194 pdev->snapshot_button_status = 1;
195 } else {
196 PWC_TRACE("Snapshot button released.\n");
197 }
198
199#ifdef CONFIG_USB_PWC_INPUT_EVDEV
200 if (pdev->button_dev) {
201 input_report_key(pdev->button_dev, KEY_CAMERA, down);
202 input_sync(pdev->button_dev);
203 }
204#endif
205}
206
207static void pwc_frame_complete(struct pwc_device *pdev)
208{
209 struct pwc_frame_buf *fbuf = pdev->fill_buf;
210
211 /* The ToUCam Fun CMOS sensor causes the firmware to send 2 or 3 bogus
212 frames on the USB wire after an exposure change. This conditition is
213 however detected in the cam and a bit is set in the header.
214 */
215 if (pdev->type == 730) {
216 unsigned char *ptr = (unsigned char *)fbuf->data;
217
218 if (ptr[1] == 1 && ptr[0] & 0x10) {
219 PWC_TRACE("Hyundai CMOS sensor bug. Dropping frame.\n");
220 pdev->drop_frames += 2;
221 }
222 if ((ptr[0] ^ pdev->vmirror) & 0x01) {
223 pwc_snapshot_button(pdev, ptr[0] & 0x01);
224 }
225 if ((ptr[0] ^ pdev->vmirror) & 0x02) {
226 if (ptr[0] & 0x02)
227 PWC_TRACE("Image is mirrored.\n");
228 else
229 PWC_TRACE("Image is normal.\n");
230 }
231 pdev->vmirror = ptr[0] & 0x03;
232 /* Sometimes the trailer of the 730 is still sent as a 4 byte packet
233 after a short frame; this condition is filtered out specifically. A 4 byte
234 frame doesn't make sense anyway.
235 So we get either this sequence:
236 drop_bit set -> 4 byte frame -> short frame -> good frame
237 Or this one:
238 drop_bit set -> short frame -> good frame
239 So we drop either 3 or 2 frames in all!
240 */
241 if (fbuf->filled == 4)
242 pdev->drop_frames++;
243 } else if (pdev->type == 740 || pdev->type == 720) {
244 unsigned char *ptr = (unsigned char *)fbuf->data;
245 if ((ptr[0] ^ pdev->vmirror) & 0x01) {
246 pwc_snapshot_button(pdev, ptr[0] & 0x01);
247 }
248 pdev->vmirror = ptr[0] & 0x03;
249 }
250
251 /* In case we were instructed to drop the frame, do so silently. */
252 if (pdev->drop_frames > 0) {
253 pdev->drop_frames--;
254 } else {
255 /* Check for underflow first */
256 if (fbuf->filled < pdev->frame_total_size) {
257 PWC_DEBUG_FLOW("Frame buffer underflow (%d bytes);"
258 " discarded.\n", fbuf->filled);
259 } else {
260 fbuf->vb.v4l2_buf.field = V4L2_FIELD_NONE;
261 fbuf->vb.v4l2_buf.sequence = pdev->vframe_count;
262 vb2_buffer_done(&fbuf->vb, VB2_BUF_STATE_DONE);
263 pdev->fill_buf = NULL;
264 pdev->vsync = 0;
265 }
266 } /* !drop_frames */
267 pdev->vframe_count++;
268}
269
270/* This gets called for the Isochronous pipe (video). This is done in
271 * interrupt time, so it has to be fast, not crash, and not stall. Neat.
272 */
273static void pwc_isoc_handler(struct urb *urb)
274{
275 struct pwc_device *pdev = (struct pwc_device *)urb->context;
276 int i, fst, flen;
277 unsigned char *iso_buf = NULL;
278
279 if (urb->status == -ENOENT || urb->status == -ECONNRESET ||
280 urb->status == -ESHUTDOWN) {
281 PWC_DEBUG_OPEN("URB (%p) unlinked %ssynchronuously.\n", urb, urb->status == -ENOENT ? "" : "a");
282 return;
283 }
284
285 if (pdev->fill_buf == NULL)
286 pdev->fill_buf = pwc_get_next_fill_buf(pdev);
287
288 if (urb->status != 0) {
289 const char *errmsg;
290
291 errmsg = "Unknown";
292 switch(urb->status) {
293 case -ENOSR: errmsg = "Buffer error (overrun)"; break;
294 case -EPIPE: errmsg = "Stalled (device not responding)"; break;
295 case -EOVERFLOW: errmsg = "Babble (bad cable?)"; break;
296 case -EPROTO: errmsg = "Bit-stuff error (bad cable?)"; break;
297 case -EILSEQ: errmsg = "CRC/Timeout (could be anything)"; break;
298 case -ETIME: errmsg = "Device does not respond"; break;
299 }
300 PWC_ERROR("pwc_isoc_handler() called with status %d [%s].\n",
301 urb->status, errmsg);
302 /* Give up after a number of contiguous errors */
303 if (++pdev->visoc_errors > MAX_ISOC_ERRORS)
304 {
305 PWC_ERROR("Too many ISOC errors, bailing out.\n");
306 if (pdev->fill_buf) {
307 vb2_buffer_done(&pdev->fill_buf->vb,
308 VB2_BUF_STATE_ERROR);
309 pdev->fill_buf = NULL;
310 }
311 }
312 pdev->vsync = 0; /* Drop the current frame */
313 goto handler_end;
314 }
315
316 /* Reset ISOC error counter. We did get here, after all. */
317 pdev->visoc_errors = 0;
318
319 /* vsync: 0 = don't copy data
320 1 = sync-hunt
321 2 = synched
322 */
323 /* Compact data */
324 for (i = 0; i < urb->number_of_packets; i++) {
325 fst = urb->iso_frame_desc[i].status;
326 flen = urb->iso_frame_desc[i].actual_length;
327 iso_buf = urb->transfer_buffer + urb->iso_frame_desc[i].offset;
328 if (fst != 0) {
329 PWC_ERROR("Iso frame %d has error %d\n", i, fst);
330 continue;
331 }
332 if (flen > 0 && pdev->vsync) {
333 struct pwc_frame_buf *fbuf = pdev->fill_buf;
334
335 if (pdev->vsync == 1) {
336 do_gettimeofday(&fbuf->vb.v4l2_buf.timestamp);
337 pdev->vsync = 2;
338 }
339
340 if (flen + fbuf->filled > pdev->frame_total_size) {
341 PWC_ERROR("Frame overflow (%d > %d)\n",
342 flen + fbuf->filled,
343 pdev->frame_total_size);
344 pdev->vsync = 0; /* Let's wait for an EOF */
345 } else {
346 memcpy(fbuf->data + fbuf->filled, iso_buf,
347 flen);
348 fbuf->filled += flen;
349 }
350 }
351 if (flen < pdev->vlast_packet_size) {
352 /* Shorter packet... end of frame */
353 if (pdev->vsync == 2)
354 pwc_frame_complete(pdev);
355 if (pdev->fill_buf == NULL)
356 pdev->fill_buf = pwc_get_next_fill_buf(pdev);
357 if (pdev->fill_buf) {
358 pdev->fill_buf->filled = 0;
359 pdev->vsync = 1;
360 }
361 }
362 pdev->vlast_packet_size = flen;
363 }
364
365handler_end:
366 i = usb_submit_urb(urb, GFP_ATOMIC);
367 if (i != 0)
368 PWC_ERROR("Error (%d) re-submitting urb in pwc_isoc_handler.\n", i);
369}
370
371static int pwc_isoc_init(struct pwc_device *pdev)
372{
373 struct usb_device *udev;
374 struct urb *urb;
375 int i, j, ret;
376 struct usb_interface *intf;
377 struct usb_host_interface *idesc = NULL;
378
379 if (pdev->iso_init)
380 return 0;
381
382 pdev->vsync = 0;
383 pdev->vlast_packet_size = 0;
384 pdev->fill_buf = NULL;
385 pdev->vframe_count = 0;
386 pdev->visoc_errors = 0;
387 udev = pdev->udev;
388
389 /* Get the current alternate interface, adjust packet size */
390 intf = usb_ifnum_to_if(udev, 0);
391 if (intf)
392 idesc = usb_altnum_to_altsetting(intf, pdev->valternate);
393 if (!idesc)
394 return -EIO;
395
396 /* Search video endpoint */
397 pdev->vmax_packet_size = -1;
398 for (i = 0; i < idesc->desc.bNumEndpoints; i++) {
399 if ((idesc->endpoint[i].desc.bEndpointAddress & 0xF) == pdev->vendpoint) {
400 pdev->vmax_packet_size = le16_to_cpu(idesc->endpoint[i].desc.wMaxPacketSize);
401 break;
402 }
403 }
404
405 if (pdev->vmax_packet_size < 0 || pdev->vmax_packet_size > ISO_MAX_FRAME_SIZE) {
406 PWC_ERROR("Failed to find packet size for video endpoint in current alternate setting.\n");
407 return -ENFILE; /* Odd error, that should be noticeable */
408 }
409
410 /* Set alternate interface */
411 ret = 0;
412 PWC_DEBUG_OPEN("Setting alternate interface %d\n", pdev->valternate);
413 ret = usb_set_interface(pdev->udev, 0, pdev->valternate);
414 if (ret < 0)
415 return ret;
416
417 /* Allocate and init Isochronuous urbs */
418 for (i = 0; i < MAX_ISO_BUFS; i++) {
419 urb = usb_alloc_urb(ISO_FRAMES_PER_DESC, GFP_KERNEL);
420 if (urb == NULL) {
421 PWC_ERROR("Failed to allocate urb %d\n", i);
422 pdev->iso_init = 1;
423 pwc_isoc_cleanup(pdev);
424 return -ENOMEM;
425 }
426 pdev->urbs[i] = urb;
427 PWC_DEBUG_MEMORY("Allocated URB at 0x%p\n", urb);
428
429 urb->interval = 1; // devik
430 urb->dev = udev;
431 urb->pipe = usb_rcvisocpipe(udev, pdev->vendpoint);
432 urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP;
433 urb->transfer_buffer = usb_alloc_coherent(udev,
434 ISO_BUFFER_SIZE,
435 GFP_KERNEL,
436 &urb->transfer_dma);
437 if (urb->transfer_buffer == NULL) {
438 PWC_ERROR("Failed to allocate urb buffer %d\n", i);
439 pdev->iso_init = 1;
440 pwc_isoc_cleanup(pdev);
441 return -ENOMEM;
442 }
443 urb->transfer_buffer_length = ISO_BUFFER_SIZE;
444 urb->complete = pwc_isoc_handler;
445 urb->context = pdev;
446 urb->start_frame = 0;
447 urb->number_of_packets = ISO_FRAMES_PER_DESC;
448 for (j = 0; j < ISO_FRAMES_PER_DESC; j++) {
449 urb->iso_frame_desc[j].offset = j * ISO_MAX_FRAME_SIZE;
450 urb->iso_frame_desc[j].length = pdev->vmax_packet_size;
451 }
452 }
453
454 /* link */
455 for (i = 0; i < MAX_ISO_BUFS; i++) {
456 ret = usb_submit_urb(pdev->urbs[i], GFP_KERNEL);
457 if (ret) {
458 PWC_ERROR("isoc_init() submit_urb %d failed with error %d\n", i, ret);
459 pdev->iso_init = 1;
460 pwc_isoc_cleanup(pdev);
461 return ret;
462 }
463 PWC_DEBUG_MEMORY("URB 0x%p submitted.\n", pdev->urbs[i]);
464 }
465
466 /* All is done... */
467 pdev->iso_init = 1;
468 PWC_DEBUG_OPEN("<< pwc_isoc_init()\n");
469 return 0;
470}
471
472static void pwc_iso_stop(struct pwc_device *pdev)
473{
474 int i;
475
476 /* Unlinking ISOC buffers one by one */
477 for (i = 0; i < MAX_ISO_BUFS; i++) {
478 if (pdev->urbs[i]) {
479 PWC_DEBUG_MEMORY("Unlinking URB %p\n", pdev->urbs[i]);
480 usb_kill_urb(pdev->urbs[i]);
481 }
482 }
483}
484
485static void pwc_iso_free(struct pwc_device *pdev)
486{
487 int i;
488
489 /* Freeing ISOC buffers one by one */
490 for (i = 0; i < MAX_ISO_BUFS; i++) {
491 if (pdev->urbs[i]) {
492 PWC_DEBUG_MEMORY("Freeing URB\n");
493 if (pdev->urbs[i]->transfer_buffer) {
494 usb_free_coherent(pdev->udev,
495 pdev->urbs[i]->transfer_buffer_length,
496 pdev->urbs[i]->transfer_buffer,
497 pdev->urbs[i]->transfer_dma);
498 }
499 usb_free_urb(pdev->urbs[i]);
500 pdev->urbs[i] = NULL;
501 }
502 }
503}
504
505static void pwc_isoc_cleanup(struct pwc_device *pdev)
506{
507 PWC_DEBUG_OPEN(">> pwc_isoc_cleanup()\n");
508
509 if (pdev->iso_init == 0)
510 return;
511
512 pwc_iso_stop(pdev);
513 pwc_iso_free(pdev);
514 usb_set_interface(pdev->udev, 0, 0);
515
516 pdev->iso_init = 0;
517 PWC_DEBUG_OPEN("<< pwc_isoc_cleanup()\n");
518}
519
520/*
521 * Release all queued buffers, no need to take queued_bufs_lock, since all
522 * iso urbs have been killed when we're called so pwc_isoc_handler won't run.
523 */
524static void pwc_cleanup_queued_bufs(struct pwc_device *pdev)
525{
526 while (!list_empty(&pdev->queued_bufs)) {
527 struct pwc_frame_buf *buf;
528
529 buf = list_entry(pdev->queued_bufs.next, struct pwc_frame_buf,
530 list);
531 list_del(&buf->list);
532 vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
533 }
534}
535
536/*********
537 * sysfs
538 *********/
539static struct pwc_device *cd_to_pwc(struct device *cd)
540{
541 struct video_device *vdev = to_video_device(cd);
542 return video_get_drvdata(vdev);
543}
544
545static ssize_t show_pan_tilt(struct device *class_dev,
546 struct device_attribute *attr, char *buf)
547{
548 struct pwc_device *pdev = cd_to_pwc(class_dev);
549 return sprintf(buf, "%d %d\n", pdev->pan_angle, pdev->tilt_angle);
550}
551
552static ssize_t store_pan_tilt(struct device *class_dev,
553 struct device_attribute *attr,
554 const char *buf, size_t count)
555{
556 struct pwc_device *pdev = cd_to_pwc(class_dev);
557 int pan, tilt;
558 int ret = -EINVAL;
559
560 if (strncmp(buf, "reset", 5) == 0)
561 ret = pwc_mpt_reset(pdev, 0x3);
562
563 else if (sscanf(buf, "%d %d", &pan, &tilt) > 0)
564 ret = pwc_mpt_set_angle(pdev, pan, tilt);
565
566 if (ret < 0)
567 return ret;
568 return strlen(buf);
569}
570static DEVICE_ATTR(pan_tilt, S_IRUGO | S_IWUSR, show_pan_tilt,
571 store_pan_tilt);
572
573static ssize_t show_snapshot_button_status(struct device *class_dev,
574 struct device_attribute *attr, char *buf)
575{
576 struct pwc_device *pdev = cd_to_pwc(class_dev);
577 int status = pdev->snapshot_button_status;
578 pdev->snapshot_button_status = 0;
579 return sprintf(buf, "%d\n", status);
580}
581
582static DEVICE_ATTR(button, S_IRUGO | S_IWUSR, show_snapshot_button_status,
583 NULL);
584
585static int pwc_create_sysfs_files(struct pwc_device *pdev)
586{
587 int rc;
588
589 rc = device_create_file(&pdev->vdev.dev, &dev_attr_button);
590 if (rc)
591 goto err;
592 if (pdev->features & FEATURE_MOTOR_PANTILT) {
593 rc = device_create_file(&pdev->vdev.dev, &dev_attr_pan_tilt);
594 if (rc)
595 goto err_button;
596 }
597
598 return 0;
599
600err_button:
601 device_remove_file(&pdev->vdev.dev, &dev_attr_button);
602err:
603 PWC_ERROR("Could not create sysfs files.\n");
604 return rc;
605}
606
607static void pwc_remove_sysfs_files(struct pwc_device *pdev)
608{
609 if (pdev->features & FEATURE_MOTOR_PANTILT)
610 device_remove_file(&pdev->vdev.dev, &dev_attr_pan_tilt);
611 device_remove_file(&pdev->vdev.dev, &dev_attr_button);
612}
613
614#ifdef CONFIG_USB_PWC_DEBUG
615static const char *pwc_sensor_type_to_string(unsigned int sensor_type)
616{
617 switch(sensor_type) {
618 case 0x00:
619 return "Hyundai CMOS sensor";
620 case 0x20:
621 return "Sony CCD sensor + TDA8787";
622 case 0x2E:
623 return "Sony CCD sensor + Exas 98L59";
624 case 0x2F:
625 return "Sony CCD sensor + ADI 9804";
626 case 0x30:
627 return "Sharp CCD sensor + TDA8787";
628 case 0x3E:
629 return "Sharp CCD sensor + Exas 98L59";
630 case 0x3F:
631 return "Sharp CCD sensor + ADI 9804";
632 case 0x40:
633 return "UPA 1021 sensor";
634 case 0x100:
635 return "VGA sensor";
636 case 0x101:
637 return "PAL MR sensor";
638 default:
639 return "unknown type of sensor";
640 }
641}
642#endif
643
644/***************************************************************************/
645/* Video4Linux functions */
646
647static int pwc_video_open(struct file *file)
648{
649 struct video_device *vdev = video_devdata(file);
650 struct pwc_device *pdev;
651
652 PWC_DEBUG_OPEN(">> video_open called(vdev = 0x%p).\n", vdev);
653
654 pdev = video_get_drvdata(vdev);
655 if (!pdev->udev)
656 return -ENODEV;
657
658 file->private_data = vdev;
659 PWC_DEBUG_OPEN("<< video_open() returns 0.\n");
660 return 0;
661}
662
663static void pwc_video_release(struct video_device *vfd)
664{
665 struct pwc_device *pdev = container_of(vfd, struct pwc_device, vdev);
666 int hint;
667
668 /* search device_hint[] table if we occupy a slot, by any chance */
669 for (hint = 0; hint < MAX_DEV_HINTS; hint++)
670 if (device_hint[hint].pdev == pdev)
671 device_hint[hint].pdev = NULL;
672
673 /* Free intermediate decompression buffer & tables */
674 if (pdev->decompress_data != NULL) {
675 PWC_DEBUG_MEMORY("Freeing decompression buffer at %p.\n",
676 pdev->decompress_data);
677 kfree(pdev->decompress_data);
678 pdev->decompress_data = NULL;
679 }
680
681 v4l2_ctrl_handler_free(&pdev->ctrl_handler);
682
683 kfree(pdev);
684}
685
686static int pwc_video_close(struct file *file)
687{
688 struct video_device *vdev = file->private_data;
689 struct pwc_device *pdev;
690
691 PWC_DEBUG_OPEN(">> video_close called(vdev = 0x%p).\n", vdev);
692
693 pdev = video_get_drvdata(vdev);
694 if (pdev->capt_file == file) {
695 vb2_queue_release(&pdev->vb_queue);
696 pdev->capt_file = NULL;
697 }
698
699 PWC_DEBUG_OPEN("<< video_close()\n");
700 return 0;
701}
702
703static ssize_t pwc_video_read(struct file *file, char __user *buf,
704 size_t count, loff_t *ppos)
705{
706 struct video_device *vdev = file->private_data;
707 struct pwc_device *pdev = video_get_drvdata(vdev);
708
709 if (!pdev->udev)
710 return -ENODEV;
711
712 if (pdev->capt_file != NULL &&
713 pdev->capt_file != file)
714 return -EBUSY;
715
716 pdev->capt_file = file;
717
718 return vb2_read(&pdev->vb_queue, buf, count, ppos,
719 file->f_flags & O_NONBLOCK);
720}
721
722static unsigned int pwc_video_poll(struct file *file, poll_table *wait)
723{
724 struct video_device *vdev = file->private_data;
725 struct pwc_device *pdev = video_get_drvdata(vdev);
726
727 if (!pdev->udev)
728 return POLL_ERR;
729
730 return vb2_poll(&pdev->vb_queue, file, wait);
731}
732
733static int pwc_video_mmap(struct file *file, struct vm_area_struct *vma)
734{
735 struct video_device *vdev = file->private_data;
736 struct pwc_device *pdev = video_get_drvdata(vdev);
737
738 if (pdev->capt_file != file)
739 return -EBUSY;
740
741 return vb2_mmap(&pdev->vb_queue, vma);
742}
743
744/***************************************************************************/
745/* Videobuf2 operations */
746
747static int queue_setup(struct vb2_queue *vq, unsigned int *nbuffers,
748 unsigned int *nplanes, unsigned long sizes[],
749 void *alloc_ctxs[])
750{
751 struct pwc_device *pdev = vb2_get_drv_priv(vq);
752
753 if (*nbuffers < MIN_FRAMES)
754 *nbuffers = MIN_FRAMES;
755 else if (*nbuffers > MAX_FRAMES)
756 *nbuffers = MAX_FRAMES;
757
758 *nplanes = 1;
759
760 sizes[0] = PAGE_ALIGN((pdev->abs_max.x * pdev->abs_max.y * 3) / 2);
761
762 return 0;
763}
764
765static int buffer_init(struct vb2_buffer *vb)
766{
767 struct pwc_frame_buf *buf = container_of(vb, struct pwc_frame_buf, vb);
768
769 /* need vmalloc since frame buffer > 128K */
770 buf->data = vzalloc(PWC_FRAME_SIZE);
771 if (buf->data == NULL)
772 return -ENOMEM;
773
774 return 0;
775}
776
777static int buffer_prepare(struct vb2_buffer *vb)
778{
779 struct pwc_device *pdev = vb2_get_drv_priv(vb->vb2_queue);
780
781 /* Don't allow queing new buffers after device disconnection */
782 if (!pdev->udev)
783 return -ENODEV;
784
785 return 0;
786}
787
788static int buffer_finish(struct vb2_buffer *vb)
789{
790 struct pwc_device *pdev = vb2_get_drv_priv(vb->vb2_queue);
791 struct pwc_frame_buf *buf = container_of(vb, struct pwc_frame_buf, vb);
792
793 /*
794 * Application has called dqbuf and is getting back a buffer we've
795 * filled, take the pwc data we've stored in buf->data and decompress
796 * it into a usable format, storing the result in the vb2_buffer
797 */
798 return pwc_decompress(pdev, buf);
799}
800
801static void buffer_cleanup(struct vb2_buffer *vb)
802{
803 struct pwc_frame_buf *buf = container_of(vb, struct pwc_frame_buf, vb);
804
805 vfree(buf->data);
806}
807
808static void buffer_queue(struct vb2_buffer *vb)
809{
810 struct pwc_device *pdev = vb2_get_drv_priv(vb->vb2_queue);
811 struct pwc_frame_buf *buf = container_of(vb, struct pwc_frame_buf, vb);
812 unsigned long flags = 0;
813
814 spin_lock_irqsave(&pdev->queued_bufs_lock, flags);
815 list_add_tail(&buf->list, &pdev->queued_bufs);
816 spin_unlock_irqrestore(&pdev->queued_bufs_lock, flags);
817}
818
819static int start_streaming(struct vb2_queue *vq)
820{
821 struct pwc_device *pdev = vb2_get_drv_priv(vq);
822
823 if (!pdev->udev)
824 return -ENODEV;
825
826 /* Turn on camera and set LEDS on */
827 pwc_camera_power(pdev, 1);
828 if (pdev->power_save) {
829 /* Restore video mode */
830 pwc_set_video_mode(pdev, pdev->view.x, pdev->view.y,
831 pdev->vframes, pdev->vcompression,
832 pdev->vsnapshot);
833 }
834 pwc_set_leds(pdev, led_on, led_off);
835
836 return pwc_isoc_init(pdev);
837}
838
839static int stop_streaming(struct vb2_queue *vq)
840{
841 struct pwc_device *pdev = vb2_get_drv_priv(vq);
842
843 if (pdev->udev) {
844 pwc_set_leds(pdev, 0, 0);
845 pwc_camera_power(pdev, 0);
846 pwc_isoc_cleanup(pdev);
847 }
848 pwc_cleanup_queued_bufs(pdev);
849
850 return 0;
851}
852
853static void pwc_lock(struct vb2_queue *vq)
854{
855 struct pwc_device *pdev = vb2_get_drv_priv(vq);
856 mutex_lock(&pdev->modlock);
857}
858
859static void pwc_unlock(struct vb2_queue *vq)
860{
861 struct pwc_device *pdev = vb2_get_drv_priv(vq);
862 mutex_unlock(&pdev->modlock);
863}
864
865static struct vb2_ops pwc_vb_queue_ops = {
866 .queue_setup = queue_setup,
867 .buf_init = buffer_init,
868 .buf_prepare = buffer_prepare,
869 .buf_finish = buffer_finish,
870 .buf_cleanup = buffer_cleanup,
871 .buf_queue = buffer_queue,
872 .start_streaming = start_streaming,
873 .stop_streaming = stop_streaming,
874 .wait_prepare = pwc_unlock,
875 .wait_finish = pwc_lock,
876};
877
878/***************************************************************************/
879/* USB functions */
880
881/* This function gets called when a new device is plugged in or the usb core
882 * is loaded.
883 */
884
885static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id *id)
886{
887 struct usb_device *udev = interface_to_usbdev(intf);
888 struct pwc_device *pdev = NULL;
889 int vendor_id, product_id, type_id;
890 int hint, rc;
891 int features = 0;
892 int video_nr = -1; /* default: use next available device */
893 int my_power_save = power_save;
894 char serial_number[30], *name;
895
896 vendor_id = le16_to_cpu(udev->descriptor.idVendor);
897 product_id = le16_to_cpu(udev->descriptor.idProduct);
898
899 /* Check if we can handle this device */
900 PWC_DEBUG_PROBE("probe() called [%04X %04X], if %d\n",
901 vendor_id, product_id,
902 intf->altsetting->desc.bInterfaceNumber);
903
904 /* the interfaces are probed one by one. We are only interested in the
905 video interface (0) now.
906 Interface 1 is the Audio Control, and interface 2 Audio itself.
907 */
908 if (intf->altsetting->desc.bInterfaceNumber > 0)
909 return -ENODEV;
910
911 if (vendor_id == 0x0471) {
912 switch (product_id) {
913 case 0x0302:
914 PWC_INFO("Philips PCA645VC USB webcam detected.\n");
915 name = "Philips 645 webcam";
916 type_id = 645;
917 break;
918 case 0x0303:
919 PWC_INFO("Philips PCA646VC USB webcam detected.\n");
920 name = "Philips 646 webcam";
921 type_id = 646;
922 break;
923 case 0x0304:
924 PWC_INFO("Askey VC010 type 2 USB webcam detected.\n");
925 name = "Askey VC010 webcam";
926 type_id = 646;
927 break;
928 case 0x0307:
929 PWC_INFO("Philips PCVC675K (Vesta) USB webcam detected.\n");
930 name = "Philips 675 webcam";
931 type_id = 675;
932 break;
933 case 0x0308:
934 PWC_INFO("Philips PCVC680K (Vesta Pro) USB webcam detected.\n");
935 name = "Philips 680 webcam";
936 type_id = 680;
937 break;
938 case 0x030C:
939 PWC_INFO("Philips PCVC690K (Vesta Pro Scan) USB webcam detected.\n");
940 name = "Philips 690 webcam";
941 type_id = 690;
942 break;
943 case 0x0310:
944 PWC_INFO("Philips PCVC730K (ToUCam Fun)/PCVC830 (ToUCam II) USB webcam detected.\n");
945 name = "Philips 730 webcam";
946 type_id = 730;
947 break;
948 case 0x0311:
949 PWC_INFO("Philips PCVC740K (ToUCam Pro)/PCVC840 (ToUCam II) USB webcam detected.\n");
950 name = "Philips 740 webcam";
951 type_id = 740;
952 break;
953 case 0x0312:
954 PWC_INFO("Philips PCVC750K (ToUCam Pro Scan) USB webcam detected.\n");
955 name = "Philips 750 webcam";
956 type_id = 750;
957 break;
958 case 0x0313:
959 PWC_INFO("Philips PCVC720K/40 (ToUCam XS) USB webcam detected.\n");
960 name = "Philips 720K/40 webcam";
961 type_id = 720;
962 break;
963 case 0x0329:
964 PWC_INFO("Philips SPC 900NC USB webcam detected.\n");
965 name = "Philips SPC 900NC webcam";
966 type_id = 740;
967 break;
968 default:
969 return -ENODEV;
970 break;
971 }
972 }
973 else if (vendor_id == 0x069A) {
974 switch(product_id) {
975 case 0x0001:
976 PWC_INFO("Askey VC010 type 1 USB webcam detected.\n");
977 name = "Askey VC010 webcam";
978 type_id = 645;
979 break;
980 default:
981 return -ENODEV;
982 break;
983 }
984 }
985 else if (vendor_id == 0x046d) {
986 switch(product_id) {
987 case 0x08b0:
988 PWC_INFO("Logitech QuickCam Pro 3000 USB webcam detected.\n");
989 name = "Logitech QuickCam Pro 3000";
990 type_id = 740; /* CCD sensor */
991 break;
992 case 0x08b1:
993 PWC_INFO("Logitech QuickCam Notebook Pro USB webcam detected.\n");
994 name = "Logitech QuickCam Notebook Pro";
995 type_id = 740; /* CCD sensor */
996 break;
997 case 0x08b2:
998 PWC_INFO("Logitech QuickCam 4000 Pro USB webcam detected.\n");
999 name = "Logitech QuickCam Pro 4000";
1000 type_id = 740; /* CCD sensor */
1001 if (my_power_save == -1)
1002 my_power_save = 1;
1003 break;
1004 case 0x08b3:
1005 PWC_INFO("Logitech QuickCam Zoom USB webcam detected.\n");
1006 name = "Logitech QuickCam Zoom";
1007 type_id = 740; /* CCD sensor */
1008 break;
1009 case 0x08B4:
1010 PWC_INFO("Logitech QuickCam Zoom (new model) USB webcam detected.\n");
1011 name = "Logitech QuickCam Zoom";
1012 type_id = 740; /* CCD sensor */
1013 if (my_power_save == -1)
1014 my_power_save = 1;
1015 break;
1016 case 0x08b5:
1017 PWC_INFO("Logitech QuickCam Orbit/Sphere USB webcam detected.\n");
1018 name = "Logitech QuickCam Orbit";
1019 type_id = 740; /* CCD sensor */
1020 if (my_power_save == -1)
1021 my_power_save = 1;
1022 features |= FEATURE_MOTOR_PANTILT;
1023 break;
1024 case 0x08b6:
1025 PWC_INFO("Logitech/Cisco VT Camera webcam detected.\n");
1026 name = "Cisco VT Camera";
1027 type_id = 740; /* CCD sensor */
1028 break;
1029 case 0x08b7:
1030 PWC_INFO("Logitech ViewPort AV 100 webcam detected.\n");
1031 name = "Logitech ViewPort AV 100";
1032 type_id = 740; /* CCD sensor */
1033 break;
1034 case 0x08b8: /* Where this released? */
1035 PWC_INFO("Logitech QuickCam detected (reserved ID).\n");
1036 name = "Logitech QuickCam (res.)";
1037 type_id = 730; /* Assuming CMOS */
1038 break;
1039 default:
1040 return -ENODEV;
1041 break;
1042 }
1043 }
1044 else if (vendor_id == 0x055d) {
1045 /* I don't know the difference between the C10 and the C30;
1046 I suppose the difference is the sensor, but both cameras
1047 work equally well with a type_id of 675
1048 */
1049 switch(product_id) {
1050 case 0x9000:
1051 PWC_INFO("Samsung MPC-C10 USB webcam detected.\n");
1052 name = "Samsung MPC-C10";
1053 type_id = 675;
1054 break;
1055 case 0x9001:
1056 PWC_INFO("Samsung MPC-C30 USB webcam detected.\n");
1057 name = "Samsung MPC-C30";
1058 type_id = 675;
1059 break;
1060 case 0x9002:
1061 PWC_INFO("Samsung SNC-35E (v3.0) USB webcam detected.\n");
1062 name = "Samsung MPC-C30";
1063 type_id = 740;
1064 break;
1065 default:
1066 return -ENODEV;
1067 break;
1068 }
1069 }
1070 else if (vendor_id == 0x041e) {
1071 switch(product_id) {
1072 case 0x400c:
1073 PWC_INFO("Creative Labs Webcam 5 detected.\n");
1074 name = "Creative Labs Webcam 5";
1075 type_id = 730;
1076 if (my_power_save == -1)
1077 my_power_save = 1;
1078 break;
1079 case 0x4011:
1080 PWC_INFO("Creative Labs Webcam Pro Ex detected.\n");
1081 name = "Creative Labs Webcam Pro Ex";
1082 type_id = 740;
1083 break;
1084 default:
1085 return -ENODEV;
1086 break;
1087 }
1088 }
1089 else if (vendor_id == 0x04cc) {
1090 switch(product_id) {
1091 case 0x8116:
1092 PWC_INFO("Sotec Afina Eye USB webcam detected.\n");
1093 name = "Sotec Afina Eye";
1094 type_id = 730;
1095 break;
1096 default:
1097 return -ENODEV;
1098 break;
1099 }
1100 }
1101 else if (vendor_id == 0x06be) {
1102 switch(product_id) {
1103 case 0x8116:
1104 /* This is essentially the same cam as the Sotec Afina Eye */
1105 PWC_INFO("AME Co. Afina Eye USB webcam detected.\n");
1106 name = "AME Co. Afina Eye";
1107 type_id = 750;
1108 break;
1109 default:
1110 return -ENODEV;
1111 break;
1112 }
1113
1114 }
1115 else if (vendor_id == 0x0d81) {
1116 switch(product_id) {
1117 case 0x1900:
1118 PWC_INFO("Visionite VCS-UC300 USB webcam detected.\n");
1119 name = "Visionite VCS-UC300";
1120 type_id = 740; /* CCD sensor */
1121 break;
1122 case 0x1910:
1123 PWC_INFO("Visionite VCS-UM100 USB webcam detected.\n");
1124 name = "Visionite VCS-UM100";
1125 type_id = 730; /* CMOS sensor */
1126 break;
1127 default:
1128 return -ENODEV;
1129 break;
1130 }
1131 }
1132 else
1133 return -ENODEV; /* Not any of the know types; but the list keeps growing. */
1134
1135 if (my_power_save == -1)
1136 my_power_save = 0;
1137
1138 memset(serial_number, 0, 30);
1139 usb_string(udev, udev->descriptor.iSerialNumber, serial_number, 29);
1140 PWC_DEBUG_PROBE("Device serial number is %s\n", serial_number);
1141
1142 if (udev->descriptor.bNumConfigurations > 1)
1143 PWC_WARNING("Warning: more than 1 configuration available.\n");
1144
1145 /* Allocate structure, initialize pointers, mutexes, etc. and link it to the usb_device */
1146 pdev = kzalloc(sizeof(struct pwc_device), GFP_KERNEL);
1147 if (pdev == NULL) {
1148 PWC_ERROR("Oops, could not allocate memory for pwc_device.\n");
1149 return -ENOMEM;
1150 }
1151 pdev->type = type_id;
1152 pdev->vframes = default_fps;
1153 strcpy(pdev->serial, serial_number);
1154 pdev->features = features;
1155 if (vendor_id == 0x046D && product_id == 0x08B5) {
1156 /* Logitech QuickCam Orbit
1157 The ranges have been determined experimentally; they may differ from cam to cam.
1158 Also, the exact ranges left-right and up-down are different for my cam
1159 */
1160 pdev->angle_range.pan_min = -7000;
1161 pdev->angle_range.pan_max = 7000;
1162 pdev->angle_range.tilt_min = -3000;
1163 pdev->angle_range.tilt_max = 2500;
1164 }
1165 pwc_construct(pdev); /* set min/max sizes correct */
1166
1167 mutex_init(&pdev->modlock);
1168 mutex_init(&pdev->udevlock);
1169 spin_lock_init(&pdev->queued_bufs_lock);
1170 INIT_LIST_HEAD(&pdev->queued_bufs);
1171
1172 pdev->udev = udev;
1173 pdev->vcompression = pwc_preferred_compression;
1174 pdev->power_save = my_power_save;
1175
1176 /* Init videobuf2 queue structure */
1177 memset(&pdev->vb_queue, 0, sizeof(pdev->vb_queue));
1178 pdev->vb_queue.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1179 pdev->vb_queue.io_modes = VB2_MMAP | VB2_USERPTR | VB2_READ;
1180 pdev->vb_queue.drv_priv = pdev;
1181 pdev->vb_queue.buf_struct_size = sizeof(struct pwc_frame_buf);
1182 pdev->vb_queue.ops = &pwc_vb_queue_ops;
1183 pdev->vb_queue.mem_ops = &vb2_vmalloc_memops;
1184 vb2_queue_init(&pdev->vb_queue);
1185
1186 /* Init video_device structure */
1187 memcpy(&pdev->vdev, &pwc_template, sizeof(pwc_template));
1188 pdev->vdev.parent = &intf->dev;
1189 pdev->vdev.lock = &pdev->modlock;
1190 strcpy(pdev->vdev.name, name);
1191 video_set_drvdata(&pdev->vdev, pdev);
1192
1193 pdev->release = le16_to_cpu(udev->descriptor.bcdDevice);
1194 PWC_DEBUG_PROBE("Release: %04x\n", pdev->release);
1195
1196 /* Now search device_hint[] table for a match, so we can hint a node number. */
1197 for (hint = 0; hint < MAX_DEV_HINTS; hint++) {
1198 if (((device_hint[hint].type == -1) || (device_hint[hint].type == pdev->type)) &&
1199 (device_hint[hint].pdev == NULL)) {
1200 /* so far, so good... try serial number */
1201 if ((device_hint[hint].serial_number[0] == '*') || !strcmp(device_hint[hint].serial_number, serial_number)) {
1202 /* match! */
1203 video_nr = device_hint[hint].device_node;
1204 PWC_DEBUG_PROBE("Found hint, will try to register as /dev/video%d\n", video_nr);
1205 break;
1206 }
1207 }
1208 }
1209
1210 /* occupy slot */
1211 if (hint < MAX_DEV_HINTS)
1212 device_hint[hint].pdev = pdev;
1213
1214 PWC_DEBUG_PROBE("probe() function returning struct at 0x%p.\n", pdev);
1215 usb_set_intfdata(intf, pdev);
1216
1217#ifdef CONFIG_USB_PWC_DEBUG
1218 /* Query sensor type */
1219 if (pwc_get_cmos_sensor(pdev, &rc) >= 0) {
1220 PWC_DEBUG_OPEN("This %s camera is equipped with a %s (%d).\n",
1221 pdev->vdev.name,
1222 pwc_sensor_type_to_string(rc), rc);
1223 }
1224#endif
1225
1226 /* Set the leds off */
1227 pwc_set_leds(pdev, 0, 0);
1228
1229 /* Setup intial videomode */
1230 rc = pwc_set_video_mode(pdev, pdev->view_max.x, pdev->view_max.y,
1231 pdev->vframes, pdev->vcompression, 0);
1232 if (rc)
1233 goto err_free_mem;
1234
1235 /* Register controls (and read default values from camera */
1236 rc = pwc_init_controls(pdev);
1237 if (rc) {
1238 PWC_ERROR("Failed to register v4l2 controls (%d).\n", rc);
1239 goto err_free_mem;
1240 }
1241
1242 pdev->vdev.ctrl_handler = &pdev->ctrl_handler;
1243
1244 /* And powerdown the camera until streaming starts */
1245 pwc_camera_power(pdev, 0);
1246
1247 rc = video_register_device(&pdev->vdev, VFL_TYPE_GRABBER, video_nr);
1248 if (rc < 0) {
1249 PWC_ERROR("Failed to register as video device (%d).\n", rc);
1250 goto err_free_controls;
1251 }
1252 rc = pwc_create_sysfs_files(pdev);
1253 if (rc)
1254 goto err_video_unreg;
1255
1256 PWC_INFO("Registered as %s.\n", video_device_node_name(&pdev->vdev));
1257
1258#ifdef CONFIG_USB_PWC_INPUT_EVDEV
1259 /* register webcam snapshot button input device */
1260 pdev->button_dev = input_allocate_device();
1261 if (!pdev->button_dev) {
1262 PWC_ERROR("Err, insufficient memory for webcam snapshot button device.");
1263 rc = -ENOMEM;
1264 pwc_remove_sysfs_files(pdev);
1265 goto err_video_unreg;
1266 }
1267
1268 usb_make_path(udev, pdev->button_phys, sizeof(pdev->button_phys));
1269 strlcat(pdev->button_phys, "/input0", sizeof(pdev->button_phys));
1270
1271 pdev->button_dev->name = "PWC snapshot button";
1272 pdev->button_dev->phys = pdev->button_phys;
1273 usb_to_input_id(pdev->udev, &pdev->button_dev->id);
1274 pdev->button_dev->dev.parent = &pdev->udev->dev;
1275 pdev->button_dev->evbit[0] = BIT_MASK(EV_KEY);
1276 pdev->button_dev->keybit[BIT_WORD(KEY_CAMERA)] = BIT_MASK(KEY_CAMERA);
1277
1278 rc = input_register_device(pdev->button_dev);
1279 if (rc) {
1280 input_free_device(pdev->button_dev);
1281 pdev->button_dev = NULL;
1282 pwc_remove_sysfs_files(pdev);
1283 goto err_video_unreg;
1284 }
1285#endif
1286
1287 return 0;
1288
1289err_video_unreg:
1290 if (hint < MAX_DEV_HINTS)
1291 device_hint[hint].pdev = NULL;
1292 video_unregister_device(&pdev->vdev);
1293err_free_controls:
1294 v4l2_ctrl_handler_free(&pdev->ctrl_handler);
1295err_free_mem:
1296 usb_set_intfdata(intf, NULL);
1297 kfree(pdev);
1298 return rc;
1299}
1300
1301/* The user yanked out the cable... */
1302static void usb_pwc_disconnect(struct usb_interface *intf)
1303{
1304 struct pwc_device *pdev = usb_get_intfdata(intf);
1305
1306 mutex_lock(&pdev->udevlock);
1307 mutex_lock(&pdev->modlock);
1308
1309 usb_set_intfdata(intf, NULL);
1310 /* No need to keep the urbs around after disconnection */
1311 pwc_isoc_cleanup(pdev);
1312 pwc_cleanup_queued_bufs(pdev);
1313 pdev->udev = NULL;
1314
1315 mutex_unlock(&pdev->modlock);
1316 mutex_unlock(&pdev->udevlock);
1317
1318 pwc_remove_sysfs_files(pdev);
1319 video_unregister_device(&pdev->vdev);
1320
1321#ifdef CONFIG_USB_PWC_INPUT_EVDEV
1322 if (pdev->button_dev)
1323 input_unregister_device(pdev->button_dev);
1324#endif
1325}
1326
1327
1328/*
1329 * Initialization code & module stuff
1330 */
1331
1332static int fps;
1333static int compression = -1;
1334static int leds[2] = { -1, -1 };
1335static unsigned int leds_nargs;
1336static char *dev_hint[MAX_DEV_HINTS];
1337static unsigned int dev_hint_nargs;
1338
1339module_param(fps, int, 0444);
1340#ifdef CONFIG_USB_PWC_DEBUG
1341module_param_named(trace, pwc_trace, int, 0644);
1342#endif
1343module_param(power_save, int, 0644);
1344module_param(compression, int, 0444);
1345module_param_array(leds, int, &leds_nargs, 0444);
1346module_param_array(dev_hint, charp, &dev_hint_nargs, 0444);
1347
1348MODULE_PARM_DESC(fps, "Initial frames per second. Varies with model, useful range 5-30");
1349#ifdef CONFIG_USB_PWC_DEBUG
1350MODULE_PARM_DESC(trace, "For debugging purposes");
1351#endif
1352MODULE_PARM_DESC(power_save, "Turn power saving for new cameras on or off");
1353MODULE_PARM_DESC(compression, "Preferred compression quality. Range 0 (uncompressed) to 3 (high compression)");
1354MODULE_PARM_DESC(leds, "LED on,off time in milliseconds");
1355MODULE_PARM_DESC(dev_hint, "Device node hints");
1356
1357MODULE_DESCRIPTION("Philips & OEM USB webcam driver");
1358MODULE_AUTHOR("Luc Saillard <luc@saillard.org>");
1359MODULE_LICENSE("GPL");
1360MODULE_ALIAS("pwcx");
1361MODULE_VERSION( PWC_VERSION );
1362
1363static int __init usb_pwc_init(void)
1364{
1365 int i;
1366
1367#ifdef CONFIG_USB_PWC_DEBUG
1368 PWC_INFO("Philips webcam module version " PWC_VERSION " loaded.\n");
1369 PWC_INFO("Supports Philips PCA645/646, PCVC675/680/690, PCVC720[40]/730/740/750 & PCVC830/840.\n");
1370 PWC_INFO("Also supports the Askey VC010, various Logitech Quickcams, Samsung MPC-C10 and MPC-C30,\n");
1371 PWC_INFO("the Creative WebCam 5 & Pro Ex, SOTEC Afina Eye and Visionite VCS-UC300 and VCS-UM100.\n");
1372
1373 if (pwc_trace >= 0) {
1374 PWC_DEBUG_MODULE("Trace options: 0x%04x\n", pwc_trace);
1375 }
1376#endif
1377
1378 if (fps) {
1379 if (fps < 4 || fps > 30) {
1380 PWC_ERROR("Framerate out of bounds (4-30).\n");
1381 return -EINVAL;
1382 }
1383 default_fps = fps;
1384 PWC_DEBUG_MODULE("Default framerate set to %d.\n", default_fps);
1385 }
1386
1387 if (compression >= 0) {
1388 if (compression > 3) {
1389 PWC_ERROR("Invalid compression setting; use a number between 0 (uncompressed) and 3 (high).\n");
1390 return -EINVAL;
1391 }
1392 pwc_preferred_compression = compression;
1393 PWC_DEBUG_MODULE("Preferred compression set to %d.\n", pwc_preferred_compression);
1394 }
1395 if (leds[0] >= 0)
1396 led_on = leds[0];
1397 if (leds[1] >= 0)
1398 led_off = leds[1];
1399
1400 /* Big device node whoopla. Basically, it allows you to assign a
1401 device node (/dev/videoX) to a camera, based on its type
1402 & serial number. The format is [type[.serialnumber]:]node.
1403
1404 Any camera that isn't matched by these rules gets the next
1405 available free device node.
1406 */
1407 for (i = 0; i < MAX_DEV_HINTS; i++) {
1408 char *s, *colon, *dot;
1409
1410 /* This loop also initializes the array */
1411 device_hint[i].pdev = NULL;
1412 s = dev_hint[i];
1413 if (s != NULL && *s != '\0') {
1414 device_hint[i].type = -1; /* wildcard */
1415 strcpy(device_hint[i].serial_number, "*");
1416
1417 /* parse string: chop at ':' & '/' */
1418 colon = dot = s;
1419 while (*colon != '\0' && *colon != ':')
1420 colon++;
1421 while (*dot != '\0' && *dot != '.')
1422 dot++;
1423 /* Few sanity checks */
1424 if (*dot != '\0' && dot > colon) {
1425 PWC_ERROR("Malformed camera hint: the colon must be after the dot.\n");
1426 return -EINVAL;
1427 }
1428
1429 if (*colon == '\0') {
1430 /* No colon */
1431 if (*dot != '\0') {
1432 PWC_ERROR("Malformed camera hint: no colon + device node given.\n");
1433 return -EINVAL;
1434 }
1435 else {
1436 /* No type or serial number specified, just a number. */
1437 device_hint[i].device_node =
1438 simple_strtol(s, NULL, 10);
1439 }
1440 }
1441 else {
1442 /* There's a colon, so we have at least a type and a device node */
1443 device_hint[i].type =
1444 simple_strtol(s, NULL, 10);
1445 device_hint[i].device_node =
1446 simple_strtol(colon + 1, NULL, 10);
1447 if (*dot != '\0') {
1448 /* There's a serial number as well */
1449 int k;
1450
1451 dot++;
1452 k = 0;
1453 while (*dot != ':' && k < 29) {
1454 device_hint[i].serial_number[k++] = *dot;
1455 dot++;
1456 }
1457 device_hint[i].serial_number[k] = '\0';
1458 }
1459 }
1460 PWC_TRACE("device_hint[%d]:\n", i);
1461 PWC_TRACE(" type : %d\n", device_hint[i].type);
1462 PWC_TRACE(" serial# : %s\n", device_hint[i].serial_number);
1463 PWC_TRACE(" node : %d\n", device_hint[i].device_node);
1464 }
1465 else
1466 device_hint[i].type = 0; /* not filled */
1467 } /* ..for MAX_DEV_HINTS */
1468
1469 PWC_DEBUG_PROBE("Registering driver at address 0x%p.\n", &pwc_driver);
1470 return usb_register(&pwc_driver);
1471}
1472
1473static void __exit usb_pwc_exit(void)
1474{
1475 PWC_DEBUG_MODULE("Deregistering driver.\n");
1476 usb_deregister(&pwc_driver);
1477 PWC_INFO("Philips webcam module removed.\n");
1478}
1479
1480module_init(usb_pwc_init);
1481module_exit(usb_pwc_exit);
1482
1483/* vim: set cino= formatoptions=croql cindent shiftwidth=8 tabstop=8: */
diff --git a/drivers/media/video/pwc/pwc-kiara.c b/drivers/media/video/pwc/pwc-kiara.c
new file mode 100644
index 00000000000..e5f4fd81712
--- /dev/null
+++ b/drivers/media/video/pwc/pwc-kiara.c
@@ -0,0 +1,892 @@
1/* Linux driver for Philips webcam
2 (C) 2004-2006 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
44const unsigned int Kiara_fps_vector[PWC_FPS_MAX_KIARA] = { 5, 10, 15, 20, 25, 30 };
45
46const struct Kiara_table_entry Kiara_table[PSZ_MAX][6][4] =
47{
48 /* SQCIF */
49 {
50 /* 5 fps */
51 {
52 {0, },
53 {0, },
54 {0, },
55 {0, },
56 },
57 /* 10 fps */
58 {
59 {0, },
60 {0, },
61 {0, },
62 {0, },
63 },
64 /* 15 fps */
65 {
66 {0, },
67 {0, },
68 {0, },
69 {0, },
70 },
71 /* 20 fps */
72 {
73 {0, },
74 {0, },
75 {0, },
76 {0, },
77 },
78 /* 25 fps */
79 {
80 {0, },
81 {0, },
82 {0, },
83 {0, },
84 },
85 /* 30 fps */
86 {
87 {0, },
88 {0, },
89 {0, },
90 {0, },
91 },
92 },
93 /* QSIF */
94 {
95 /* 5 fps */
96 {
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 {1, 146, 0, {0x1D, 0xF4, 0x30, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x92, 0x00, 0x80}},
101 },
102 /* 10 fps */
103 {
104 {2, 291, 0, {0x1C, 0xF4, 0x30, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x23, 0x01, 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 {1, 192, 630, {0x14, 0xF4, 0x30, 0x13, 0xA9, 0x12, 0xE1, 0x17, 0x08, 0xC0, 0x00, 0x80}},
108 },
109 /* 15 fps */
110 {
111 {3, 437, 0, {0x1B, 0xF4, 0x30, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0xB5, 0x01, 0x80}},
112 {2, 292, 640, {0x13, 0xF4, 0x30, 0x13, 0xF7, 0x13, 0x2F, 0x13, 0x20, 0x24, 0x01, 0x80}},
113 {2, 292, 640, {0x13, 0xF4, 0x30, 0x13, 0xF7, 0x13, 0x2F, 0x13, 0x20, 0x24, 0x01, 0x80}},
114 {1, 192, 420, {0x13, 0xF4, 0x30, 0x0D, 0x1B, 0x0C, 0x53, 0x1E, 0x18, 0xC0, 0x00, 0x80}},
115 },
116 /* 20 fps */
117 {
118 {4, 589, 0, {0x1A, 0xF4, 0x30, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x4D, 0x02, 0x80}},
119 {3, 448, 730, {0x12, 0xF4, 0x30, 0x16, 0xC9, 0x16, 0x01, 0x0E, 0x18, 0xC0, 0x01, 0x80}},
120 {2, 292, 476, {0x12, 0xF4, 0x30, 0x0E, 0xD8, 0x0E, 0x10, 0x19, 0x18, 0x24, 0x01, 0x80}},
121 {1, 192, 312, {0x12, 0xF4, 0x50, 0x09, 0xB3, 0x08, 0xEB, 0x1E, 0x18, 0xC0, 0x00, 0x80}},
122 },
123 /* 25 fps */
124 {
125 {5, 703, 0, {0x19, 0xF4, 0x30, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0xBF, 0x02, 0x80}},
126 {3, 447, 610, {0x11, 0xF4, 0x30, 0x13, 0x0B, 0x12, 0x43, 0x14, 0x28, 0xBF, 0x01, 0x80}},
127 {2, 292, 398, {0x11, 0xF4, 0x50, 0x0C, 0x6C, 0x0B, 0xA4, 0x1E, 0x28, 0x24, 0x01, 0x80}},
128 {1, 193, 262, {0x11, 0xF4, 0x50, 0x08, 0x23, 0x07, 0x5B, 0x1E, 0x28, 0xC1, 0x00, 0x80}},
129 },
130 /* 30 fps */
131 {
132 {8, 874, 0, {0x18, 0xF4, 0x30, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x6A, 0x03, 0x80}},
133 {5, 704, 730, {0x10, 0xF4, 0x30, 0x16, 0xC9, 0x16, 0x01, 0x0E, 0x28, 0xC0, 0x02, 0x80}},
134 {3, 448, 492, {0x10, 0xF4, 0x30, 0x0F, 0x5D, 0x0E, 0x95, 0x15, 0x28, 0xC0, 0x01, 0x80}},
135 {2, 292, 320, {0x10, 0xF4, 0x50, 0x09, 0xFB, 0x09, 0x33, 0x1E, 0x28, 0x24, 0x01, 0x80}},
136 },
137 },
138 /* QCIF */
139 {
140 /* 5 fps */
141 {
142 {0, },
143 {0, },
144 {0, },
145 {0, },
146 },
147 /* 10 fps */
148 {
149 {0, },
150 {0, },
151 {0, },
152 {0, },
153 },
154 /* 15 fps */
155 {
156 {0, },
157 {0, },
158 {0, },
159 {0, },
160 },
161 /* 20 fps */
162 {
163 {0, },
164 {0, },
165 {0, },
166 {0, },
167 },
168 /* 25 fps */
169 {
170 {0, },
171 {0, },
172 {0, },
173 {0, },
174 },
175 /* 30 fps */
176 {
177 {0, },
178 {0, },
179 {0, },
180 {0, },
181 },
182 },
183 /* SIF */
184 {
185 /* 5 fps */
186 {
187 {4, 582, 0, {0x0D, 0xF4, 0x30, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x46, 0x02, 0x80}},
188 {3, 387, 1276, {0x05, 0xF4, 0x30, 0x27, 0xD8, 0x26, 0x48, 0x03, 0x10, 0x83, 0x01, 0x80}},
189 {2, 291, 960, {0x05, 0xF4, 0x30, 0x1D, 0xF2, 0x1C, 0x62, 0x04, 0x10, 0x23, 0x01, 0x80}},
190 {1, 191, 630, {0x05, 0xF4, 0x50, 0x13, 0xA9, 0x12, 0x19, 0x05, 0x18, 0xBF, 0x00, 0x80}},
191 },
192 /* 10 fps */
193 {
194 {0, },
195 {6, 775, 1278, {0x04, 0xF4, 0x30, 0x27, 0xE8, 0x26, 0x58, 0x05, 0x30, 0x07, 0x03, 0x80}},
196 {3, 447, 736, {0x04, 0xF4, 0x30, 0x16, 0xFB, 0x15, 0x6B, 0x05, 0x28, 0xBF, 0x01, 0x80}},
197 {2, 292, 480, {0x04, 0xF4, 0x70, 0x0E, 0xF9, 0x0D, 0x69, 0x09, 0x28, 0x24, 0x01, 0x80}},
198 },
199 /* 15 fps */
200 {
201 {0, },
202 {9, 955, 1050, {0x03, 0xF4, 0x30, 0x20, 0xCF, 0x1F, 0x3F, 0x06, 0x48, 0xBB, 0x03, 0x80}},
203 {4, 592, 650, {0x03, 0xF4, 0x30, 0x14, 0x44, 0x12, 0xB4, 0x08, 0x30, 0x50, 0x02, 0x80}},
204 {3, 448, 492, {0x03, 0xF4, 0x50, 0x0F, 0x52, 0x0D, 0xC2, 0x09, 0x38, 0xC0, 0x01, 0x80}},
205 },
206 /* 20 fps */
207 {
208 {0, },
209 {9, 958, 782, {0x02, 0xF4, 0x30, 0x18, 0x6A, 0x16, 0xDA, 0x0B, 0x58, 0xBE, 0x03, 0x80}},
210 {5, 703, 574, {0x02, 0xF4, 0x50, 0x11, 0xE7, 0x10, 0x57, 0x0B, 0x40, 0xBF, 0x02, 0x80}},
211 {3, 446, 364, {0x02, 0xF4, 0x90, 0x0B, 0x5C, 0x09, 0xCC, 0x0E, 0x38, 0xBE, 0x01, 0x80}},
212 },
213 /* 25 fps */
214 {
215 {0, },
216 {9, 958, 654, {0x01, 0xF4, 0x30, 0x14, 0x66, 0x12, 0xD6, 0x0B, 0x50, 0xBE, 0x03, 0x80}},
217 {6, 776, 530, {0x01, 0xF4, 0x50, 0x10, 0x8C, 0x0E, 0xFC, 0x0C, 0x48, 0x08, 0x03, 0x80}},
218 {4, 592, 404, {0x01, 0xF4, 0x70, 0x0C, 0x96, 0x0B, 0x06, 0x0B, 0x48, 0x50, 0x02, 0x80}},
219 },
220 /* 30 fps */
221 {
222 {0, },
223 {9, 957, 526, {0x00, 0xF4, 0x50, 0x10, 0x68, 0x0E, 0xD8, 0x0D, 0x58, 0xBD, 0x03, 0x80}},
224 {6, 775, 426, {0x00, 0xF4, 0x70, 0x0D, 0x48, 0x0B, 0xB8, 0x0F, 0x50, 0x07, 0x03, 0x80}},
225 {4, 590, 324, {0x00, 0x7A, 0x88, 0x0A, 0x1C, 0x08, 0xB4, 0x0E, 0x50, 0x4E, 0x02, 0x80}},
226 },
227 },
228 /* CIF */
229 {
230 /* 5 fps */
231 {
232 {0, },
233 {0, },
234 {0, },
235 {0, },
236 },
237 /* 10 fps */
238 {
239 {0, },
240 {0, },
241 {0, },
242 {0, },
243 },
244 /* 15 fps */
245 {
246 {0, },
247 {0, },
248 {0, },
249 {0, },
250 },
251 /* 20 fps */
252 {
253 {0, },
254 {0, },
255 {0, },
256 {0, },
257 },
258 /* 25 fps */
259 {
260 {0, },
261 {0, },
262 {0, },
263 {0, },
264 },
265 /* 30 fps */
266 {
267 {0, },
268 {0, },
269 {0, },
270 {0, },
271 },
272 },
273 /* VGA */
274 {
275 /* 5 fps */
276 {
277 {0, },
278 {6, 773, 1272, {0x25, 0xF4, 0x30, 0x27, 0xB6, 0x24, 0x96, 0x02, 0x30, 0x05, 0x03, 0x80}},
279 {4, 592, 976, {0x25, 0xF4, 0x50, 0x1E, 0x78, 0x1B, 0x58, 0x03, 0x30, 0x50, 0x02, 0x80}},
280 {3, 448, 738, {0x25, 0xF4, 0x90, 0x17, 0x0C, 0x13, 0xEC, 0x04, 0x30, 0xC0, 0x01, 0x80}},
281 },
282 /* 10 fps */
283 {
284 {0, },
285 {9, 956, 788, {0x24, 0xF4, 0x70, 0x18, 0x9C, 0x15, 0x7C, 0x03, 0x48, 0xBC, 0x03, 0x80}},
286 {6, 776, 640, {0x24, 0xF4, 0xB0, 0x13, 0xFC, 0x11, 0x2C, 0x04, 0x48, 0x08, 0x03, 0x80}},
287 {4, 592, 488, {0x24, 0x7A, 0xE8, 0x0F, 0x3C, 0x0C, 0x6C, 0x06, 0x48, 0x50, 0x02, 0x80}},
288 },
289 /* 15 fps */
290 {
291 {0, },
292 {9, 957, 526, {0x23, 0x7A, 0xE8, 0x10, 0x68, 0x0D, 0x98, 0x06, 0x58, 0xBD, 0x03, 0x80}},
293 {9, 957, 526, {0x23, 0x7A, 0xE8, 0x10, 0x68, 0x0D, 0x98, 0x06, 0x58, 0xBD, 0x03, 0x80}},
294 {8, 895, 492, {0x23, 0x7A, 0xE8, 0x0F, 0x5D, 0x0C, 0x8D, 0x06, 0x58, 0x7F, 0x03, 0x80}},
295 },
296 /* 20 fps */
297 {
298 {0, },
299 {0, },
300 {0, },
301 {0, },
302 },
303 /* 25 fps */
304 {
305 {0, },
306 {0, },
307 {0, },
308 {0, },
309 },
310 /* 30 fps */
311 {
312 {0, },
313 {0, },
314 {0, },
315 {0, },
316 },
317 },
318};
319
320
321/*
322 * Rom table for kiara chips
323 *
324 * 32 roms tables (one for each resolution ?)
325 * 2 tables per roms (one for each passes) (Y, and U&V)
326 * 128 bytes per passes
327 */
328
329const unsigned int KiaraRomTable [8][2][16][8] =
330{
331 { /* version 0 */
332 { /* version 0, passes 0 */
333 {0x00000000,0x00000000,0x00000000,0x00000000,
334 0x00000000,0x00000000,0x00000001,0x00000001},
335 {0x00000000,0x00000000,0x00000009,0x00000009,
336 0x00000009,0x00000009,0x00000009,0x00000009},
337 {0x00000000,0x00000000,0x00000009,0x00000049,
338 0x00000049,0x00000049,0x00000049,0x00000049},
339 {0x00000000,0x00000000,0x00000049,0x00000049,
340 0x00000049,0x00000249,0x0000024a,0x00000049},
341 {0x00000000,0x00000000,0x00000049,0x00000049,
342 0x00000249,0x00000249,0x0000024a,0x0000024a},
343 {0x00000000,0x00000000,0x00000049,0x00000249,
344 0x00000249,0x0000124a,0x0000024a,0x0000024a},
345 {0x00000000,0x00000000,0x00000049,0x00000249,
346 0x0000124a,0x00009252,0x00001252,0x00001252},
347 {0x00000000,0x00000000,0x00000249,0x00000249,
348 0x00009252,0x00009292,0x00009292,0x00009292},
349 {0x00000000,0x00000000,0x00000249,0x00001249,
350 0x00009292,0x00009292,0x00009493,0x000124db},
351 {0x00000000,0x00000000,0x00000249,0x0000924a,
352 0x00009492,0x0000a49b,0x0000a49b,0x000124db},
353 {0x00000000,0x00000000,0x00001249,0x00009252,
354 0x0000a493,0x000124db,0x000124db,0x000126dc},
355 {0x00000000,0x00000000,0x00001249,0x00009493,
356 0x000124db,0x000126dc,0x000136e4,0x000126dc},
357 {0x00000000,0x00000000,0x00009292,0x0000a49b,
358 0x000124db,0x000136e4,0x000136e4,0x000136e4},
359 {0x00000000,0x00000000,0x00009292,0x0000a49b,
360 0x000126dc,0x0001b724,0x0001b92d,0x0001b925},
361 {0x00000000,0x00000000,0x00009492,0x000124db,
362 0x000136e4,0x0001b925,0x0001c96e,0x0001c92d},
363 {0x00000000,0x00000000,0x00000000,0x00000000,
364 0x00000000,0x00000000,0x00000000,0x00000000}
365 },
366 { /* version 0, passes 1 */
367 {0x00000000,0x00000000,0x00000000,0x00000000,
368 0x00000000,0x00000000,0x00000000,0x00000000},
369 {0x00000000,0x00000000,0x00000000,0x00000000,
370 0x00000000,0x00000000,0x00000000,0x00000000},
371 {0x00000000,0x00000000,0x00000001,0x00000009,
372 0x00000009,0x00000009,0x00000009,0x00000001},
373 {0x00000000,0x00000000,0x00000009,0x00000009,
374 0x00000049,0x00000049,0x00000049,0x00000049},
375 {0x00000000,0x00000000,0x00000049,0x00000049,
376 0x00000049,0x00000049,0x0000024a,0x0000024a},
377 {0x00000000,0x00000000,0x00000049,0x00000049,
378 0x00000249,0x00000249,0x0000024a,0x0000024a},
379 {0x00000000,0x00000000,0x00000049,0x00000249,
380 0x00000249,0x00000249,0x0000024a,0x00001252},
381 {0x00000000,0x00000000,0x00000049,0x00001249,
382 0x0000124a,0x0000124a,0x00001252,0x00009292},
383 {0x00000000,0x00000000,0x00000249,0x00001249,
384 0x00009252,0x00009252,0x00009292,0x00009493},
385 {0x00000000,0x00000000,0x00000249,0x0000924a,
386 0x00009292,0x00009292,0x00009292,0x00009493},
387 {0x00000000,0x00000000,0x00000249,0x00009292,
388 0x00009492,0x00009493,0x0000a49b,0x00009493},
389 {0x00000000,0x00000000,0x00001249,0x00009292,
390 0x0000a493,0x000124db,0x000126dc,0x000126dc},
391 {0x00000000,0x00000000,0x0000924a,0x00009493,
392 0x0000a493,0x000126dc,0x000136e4,0x000136e4},
393 {0x00000000,0x00000000,0x00009252,0x00009493,
394 0x000126dc,0x000126dc,0x000136e4,0x000136e4},
395 {0x00000000,0x00000000,0x00009292,0x0000a49b,
396 0x000136e4,0x000136e4,0x0001b725,0x0001b724},
397 {0x00000000,0x00000000,0x00000000,0x00000000,
398 0x00000000,0x00000000,0x00000000,0x00000000}
399 }
400 },
401 { /* version 1 */
402 { /* version 1, passes 0 */
403 {0x00000000,0x00000000,0x00000000,0x00000000,
404 0x00000000,0x00000000,0x00000000,0x00000001},
405 {0x00000000,0x00000000,0x00000009,0x00000009,
406 0x00000009,0x00000009,0x00000009,0x00000009},
407 {0x00000000,0x00000000,0x00000049,0x00000049,
408 0x00000049,0x00000049,0x00000049,0x00000049},
409 {0x00000000,0x00000000,0x00000049,0x00000049,
410 0x00000049,0x00000249,0x0000024a,0x0000024a},
411 {0x00000000,0x00000000,0x00000049,0x00000249,
412 0x00000249,0x00000249,0x0000024a,0x00001252},
413 {0x00000000,0x00000000,0x00000249,0x00000249,
414 0x00000249,0x0000124a,0x00001252,0x00001252},
415 {0x00000000,0x00000000,0x00000249,0x00000249,
416 0x0000124a,0x0000124a,0x00009292,0x00009292},
417 {0x00000000,0x00000000,0x00000249,0x00001249,
418 0x0000124a,0x00009252,0x00009292,0x00009292},
419 {0x00000000,0x00000000,0x00000249,0x00001249,
420 0x00009252,0x00009292,0x00009292,0x00009292},
421 {0x00000000,0x00000000,0x00000249,0x00001249,
422 0x00009252,0x00009292,0x00009493,0x00009493},
423 {0x00000000,0x00000000,0x00000249,0x0000924a,
424 0x00009252,0x00009493,0x00009493,0x00009493},
425 {0x00000000,0x00000000,0x00000249,0x0000924a,
426 0x00009292,0x00009493,0x00009493,0x00009493},
427 {0x00000000,0x00000000,0x00000249,0x00009252,
428 0x00009492,0x00009493,0x0000a49b,0x0000a49b},
429 {0x00000000,0x00000000,0x00001249,0x00009292,
430 0x00009492,0x000124db,0x000124db,0x000124db},
431 {0x00000000,0x00000000,0x0000924a,0x00009493,
432 0x0000a493,0x000126dc,0x000126dc,0x000126dc},
433 {0x00000000,0x00000000,0x00000000,0x00000000,
434 0x00000000,0x00000000,0x00000000,0x00000000}
435 },
436 { /* version 1, passes 1 */
437 {0x00000000,0x00000000,0x00000000,0x00000000,
438 0x00000000,0x00000000,0x00000000,0x00000000},
439 {0x00000000,0x00000000,0x00000049,0x00000009,
440 0x00000049,0x00000009,0x00000001,0x00000000},
441 {0x00000000,0x00000000,0x00000049,0x00000049,
442 0x00000049,0x00000049,0x00000049,0x00000000},
443 {0x00000000,0x00000000,0x00000249,0x00000049,
444 0x00000249,0x00000049,0x0000024a,0x00000001},
445 {0x00000000,0x00000000,0x00000249,0x00000249,
446 0x00000249,0x00000249,0x0000024a,0x00000001},
447 {0x00000000,0x00000000,0x00000249,0x00000249,
448 0x00000249,0x00000249,0x0000024a,0x00000001},
449 {0x00000000,0x00000000,0x00000249,0x00000249,
450 0x00000249,0x00000249,0x0000024a,0x00000009},
451 {0x00000000,0x00000000,0x00000249,0x00000249,
452 0x0000124a,0x0000124a,0x0000024a,0x00000009},
453 {0x00000000,0x00000000,0x00000249,0x00000249,
454 0x0000124a,0x0000124a,0x0000024a,0x00000009},
455 {0x00000000,0x00000000,0x00001249,0x00001249,
456 0x0000124a,0x00009252,0x00001252,0x00000049},
457 {0x00000000,0x00000000,0x00001249,0x00001249,
458 0x0000124a,0x00009292,0x00001252,0x00000049},
459 {0x00000000,0x00000000,0x00001249,0x00001249,
460 0x0000124a,0x00009292,0x00001252,0x00000049},
461 {0x00000000,0x00000000,0x00001249,0x00001249,
462 0x00009252,0x00009292,0x00001252,0x0000024a},
463 {0x00000000,0x00000000,0x00001249,0x00001249,
464 0x00009292,0x00009292,0x00001252,0x0000024a},
465 {0x00000000,0x00000000,0x0000924a,0x0000924a,
466 0x00009492,0x00009493,0x00009292,0x00001252},
467 {0x00000000,0x00000000,0x00000000,0x00000000,
468 0x00000000,0x00000000,0x00000000,0x00000000}
469 }
470 },
471 { /* version 2 */
472 { /* version 2, passes 0 */
473 {0x00000000,0x00000000,0x00000049,0x00000049,
474 0x00000049,0x00000049,0x0000024a,0x0000024a},
475 {0x00000000,0x00000000,0x00000249,0x00000249,
476 0x00000249,0x0000124a,0x00001252,0x00009292},
477 {0x00000000,0x00000000,0x00000249,0x00000249,
478 0x0000124a,0x00009252,0x00009292,0x00009292},
479 {0x00000000,0x00000000,0x00000249,0x00001249,
480 0x0000124a,0x00009292,0x00009493,0x00009493},
481 {0x00000000,0x00000000,0x00000249,0x00001249,
482 0x00009252,0x00009493,0x00009493,0x0000a49b},
483 {0x00000000,0x00000000,0x00000249,0x0000924a,
484 0x00009292,0x00009493,0x0000a49b,0x0000a49b},
485 {0x00000000,0x00000000,0x00001249,0x0000924a,
486 0x00009292,0x00009493,0x0000a49b,0x000124db},
487 {0x00000000,0x00000000,0x00001249,0x00009252,
488 0x00009492,0x0000a49b,0x0000a49b,0x000124db},
489 {0x00000000,0x00000000,0x00001249,0x00009292,
490 0x00009492,0x000124db,0x000124db,0x000126dc},
491 {0x00000000,0x00000000,0x00001249,0x00009292,
492 0x0000a493,0x000124db,0x000126dc,0x000126dc},
493 {0x00000000,0x00000000,0x00001249,0x00009493,
494 0x0000a493,0x000124db,0x000126dc,0x000136e4},
495 {0x00000000,0x00000000,0x00001249,0x00009493,
496 0x0000a493,0x000126dc,0x000136e4,0x000136e4},
497 {0x00000000,0x00000000,0x0000924a,0x00009493,
498 0x0001249b,0x000126dc,0x000136e4,0x000136e4},
499 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
500 0x000124db,0x000136e4,0x000136e4,0x0001b724},
501 {0x00000000,0x00000000,0x00009252,0x000124db,
502 0x000126dc,0x0001b724,0x0001b725,0x0001b925},
503 {0x00000000,0x00000000,0x00000000,0x00000000,
504 0x00000000,0x00000000,0x00000000,0x00000000}
505 },
506 { /* version 2, passes 1 */
507 {0x00000000,0x00000000,0x00000049,0x00000049,
508 0x00000049,0x00000049,0x00000049,0x00000049},
509 {0x00000000,0x00000000,0x00000249,0x00000249,
510 0x00000249,0x00000249,0x0000024a,0x00000049},
511 {0x00000000,0x00000000,0x00001249,0x00000249,
512 0x0000124a,0x0000124a,0x00001252,0x00000049},
513 {0x00000000,0x00000000,0x00001249,0x00001249,
514 0x0000124a,0x0000124a,0x00009292,0x0000024a},
515 {0x00000000,0x00000000,0x00001249,0x00001249,
516 0x00009252,0x00009292,0x00009292,0x0000024a},
517 {0x00000000,0x00000000,0x00001249,0x00001249,
518 0x00009252,0x00009292,0x0000a49b,0x0000024a},
519 {0x00000000,0x00000000,0x00001249,0x00001249,
520 0x00009292,0x00009493,0x0000a49b,0x00001252},
521 {0x00000000,0x00000000,0x00001249,0x00001249,
522 0x00009292,0x00009493,0x0000a49b,0x00001252},
523 {0x00000000,0x00000000,0x00001249,0x0000924a,
524 0x00009492,0x0000a49b,0x0000a49b,0x00001252},
525 {0x00000000,0x00000000,0x00001249,0x00009252,
526 0x00009492,0x0000a49b,0x0000a49b,0x00009292},
527 {0x00000000,0x00000000,0x00001249,0x00009292,
528 0x00009492,0x0000a49b,0x0000a49b,0x00009292},
529 {0x00000000,0x00000000,0x00001249,0x00009493,
530 0x0000a493,0x0000a49b,0x0000a49b,0x00009292},
531 {0x00000000,0x00000000,0x00001249,0x00009493,
532 0x0000a493,0x0000a49b,0x0000a49b,0x00009493},
533 {0x00000000,0x00000000,0x0000924a,0x00009493,
534 0x0000a493,0x000124db,0x0000a49b,0x00009493},
535 {0x00000000,0x00000000,0x00009252,0x0000a49b,
536 0x0001249b,0x000126dc,0x000124db,0x0000a49b},
537 {0x00000000,0x00000000,0x00000000,0x00000000,
538 0x00000000,0x00000000,0x00000000,0x00000000}
539 }
540 },
541 { /* version 3 */
542 { /* version 3, passes 0 */
543 {0x00000000,0x00000000,0x00000249,0x00000249,
544 0x0000124a,0x0000124a,0x00009292,0x00009292},
545 {0x00000000,0x00000000,0x00001249,0x00001249,
546 0x00009292,0x00009493,0x0000a49b,0x0000a49b},
547 {0x00000000,0x00000000,0x00001249,0x0000924a,
548 0x00009492,0x0000a49b,0x0000a49b,0x000124db},
549 {0x00000000,0x00000000,0x00001249,0x00009292,
550 0x00009492,0x000124db,0x000126dc,0x000126dc},
551 {0x00000000,0x00000000,0x00001249,0x00009493,
552 0x0000a493,0x000124db,0x000126dc,0x000126dc},
553 {0x00000000,0x00000000,0x00001249,0x00009493,
554 0x0000a493,0x000126dc,0x000136e4,0x000136e4},
555 {0x00000000,0x00000000,0x00001249,0x00009493,
556 0x0000a493,0x000126dc,0x000136e4,0x0001b724},
557 {0x00000000,0x00000000,0x00001249,0x00009493,
558 0x0001249b,0x000126dc,0x000136e4,0x0001b724},
559 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
560 0x0001249b,0x000126dc,0x000136e4,0x0001b724},
561 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
562 0x0001249b,0x000136e4,0x0001b725,0x0001b724},
563 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
564 0x000124db,0x000136e4,0x0001b725,0x0001b925},
565 {0x00000000,0x00000000,0x00009292,0x0000a49b,
566 0x000126dc,0x000136e4,0x0001b92d,0x0001b925},
567 {0x00000000,0x00000000,0x00009292,0x0000a49b,
568 0x000126dc,0x0001b724,0x0001b92d,0x0001c92d},
569 {0x00000000,0x00000000,0x00009492,0x000124db,
570 0x000126dc,0x0001b724,0x0001c96e,0x0001c92d},
571 {0x00000000,0x00000000,0x0000a492,0x000126db,
572 0x000136e4,0x0001b925,0x00025bb6,0x00024b77},
573 {0x00000000,0x00000000,0x00000000,0x00000000,
574 0x00000000,0x00000000,0x00000000,0x00000000}
575 },
576 { /* version 3, passes 1 */
577 {0x00000000,0x00000000,0x00001249,0x00000249,
578 0x0000124a,0x0000124a,0x00001252,0x00001252},
579 {0x00000000,0x00000000,0x00001249,0x00001249,
580 0x00009252,0x00009292,0x00009292,0x00001252},
581 {0x00000000,0x00000000,0x00001249,0x0000924a,
582 0x00009492,0x00009493,0x0000a49b,0x00001252},
583 {0x00000000,0x00000000,0x00001249,0x00009252,
584 0x00009492,0x0000a49b,0x0000a49b,0x00009292},
585 {0x00000000,0x00000000,0x00001249,0x00009292,
586 0x00009492,0x0000a49b,0x0000a49b,0x00009292},
587 {0x00000000,0x00000000,0x00001249,0x00009493,
588 0x0000a493,0x0000a49b,0x000126dc,0x00009292},
589 {0x00000000,0x00000000,0x0000924a,0x00009493,
590 0x0000a493,0x0000a49b,0x000126dc,0x00009493},
591 {0x00000000,0x00000000,0x0000924a,0x00009493,
592 0x0000a493,0x0000a49b,0x000126dc,0x00009493},
593 {0x00000000,0x00000000,0x0000924a,0x00009493,
594 0x0000a493,0x000124db,0x000126dc,0x00009493},
595 {0x00000000,0x00000000,0x0000924a,0x00009493,
596 0x0000a493,0x000124db,0x000126dc,0x0000a49b},
597 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
598 0x0000a493,0x000124db,0x000126dc,0x0000a49b},
599 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
600 0x0001249b,0x000126dc,0x000126dc,0x0000a49b},
601 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
602 0x000124db,0x000136e4,0x000126dc,0x000124db},
603 {0x00000000,0x00000000,0x00009492,0x0000a49b,
604 0x000136e4,0x000136e4,0x000126dc,0x000124db},
605 {0x00000000,0x00000000,0x0000a492,0x000124db,
606 0x0001b724,0x0001b724,0x000136e4,0x000126dc},
607 {0x00000000,0x00000000,0x00000000,0x00000000,
608 0x00000000,0x00000000,0x00000000,0x00000000}
609 }
610 },
611 { /* version 4 */
612 { /* version 4, passes 0 */
613 {0x00000000,0x00000000,0x00000049,0x00000049,
614 0x00000049,0x00000049,0x00000049,0x00000049},
615 {0x00000000,0x00000000,0x00000249,0x00000049,
616 0x00000249,0x00000249,0x0000024a,0x00000049},
617 {0x00000000,0x00000000,0x00000249,0x00000249,
618 0x0000124a,0x00009252,0x00001252,0x0000024a},
619 {0x00000000,0x00000000,0x00001249,0x00001249,
620 0x00009252,0x00009292,0x00009493,0x00001252},
621 {0x00000000,0x00000000,0x00001249,0x0000924a,
622 0x00009292,0x00009493,0x00009493,0x00001252},
623 {0x00000000,0x00000000,0x00001249,0x00009292,
624 0x00009492,0x0000a49b,0x0000a49b,0x00009292},
625 {0x00000000,0x00000000,0x00001249,0x00009493,
626 0x0000a493,0x000124db,0x000124db,0x00009493},
627 {0x00000000,0x00000000,0x0000924a,0x00009493,
628 0x0000a493,0x000124db,0x000126dc,0x0000a49b},
629 {0x00000000,0x00000000,0x0000924a,0x00009493,
630 0x0000a493,0x000124db,0x000126dc,0x0000a49b},
631 {0x00000000,0x00000000,0x0000924a,0x00009493,
632 0x0001249b,0x000126dc,0x000126dc,0x000124db},
633 {0x00000000,0x00000000,0x00009252,0x00009493,
634 0x000124db,0x000136e4,0x000136e4,0x000126dc},
635 {0x00000000,0x00000000,0x00009252,0x0000a49b,
636 0x000124db,0x000136e4,0x000136e4,0x000126dc},
637 {0x00000000,0x00000000,0x00009292,0x0000a49b,
638 0x000126dc,0x000136e4,0x000136e4,0x000136e4},
639 {0x00000000,0x00000000,0x00009492,0x0000a49b,
640 0x000126dc,0x0001b724,0x0001b725,0x0001b724},
641 {0x00000000,0x00000000,0x0000a492,0x000124db,
642 0x000136e4,0x0001b925,0x0001b92d,0x0001b925},
643 {0x00000000,0x00000000,0x00000000,0x00000000,
644 0x00000000,0x00000000,0x00000000,0x00000000}
645 },
646 { /* version 4, passes 1 */
647 {0x00000000,0x00000000,0x00000249,0x00000049,
648 0x00000009,0x00000009,0x00000009,0x00000009},
649 {0x00000000,0x00000000,0x00000249,0x00000249,
650 0x00000049,0x00000049,0x00000009,0x00000009},
651 {0x00000000,0x00000000,0x00001249,0x00001249,
652 0x0000124a,0x00000249,0x00000049,0x00000049},
653 {0x00000000,0x00000000,0x00001249,0x00001249,
654 0x0000124a,0x0000124a,0x00000049,0x00000049},
655 {0x00000000,0x00000000,0x00001249,0x00001249,
656 0x00009252,0x0000124a,0x0000024a,0x0000024a},
657 {0x00000000,0x00000000,0x00001249,0x0000924a,
658 0x00009252,0x0000124a,0x0000024a,0x0000024a},
659 {0x00000000,0x00000000,0x00001249,0x00009292,
660 0x00009492,0x00009252,0x00001252,0x00001252},
661 {0x00000000,0x00000000,0x00001249,0x00009493,
662 0x0000a493,0x00009292,0x00009292,0x00001252},
663 {0x00000000,0x00000000,0x0000924a,0x00009493,
664 0x0000a493,0x00009292,0x00009292,0x00009292},
665 {0x00000000,0x00000000,0x0000924a,0x00009493,
666 0x0000a493,0x00009493,0x00009493,0x00009292},
667 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
668 0x0000a493,0x0000a49b,0x00009493,0x00009493},
669 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
670 0x0000a493,0x0000a49b,0x0000a49b,0x00009493},
671 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
672 0x0001249b,0x000124db,0x0000a49b,0x0000a49b},
673 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
674 0x000136e4,0x000126dc,0x000124db,0x0000a49b},
675 {0x00000000,0x00000000,0x00009252,0x000124db,
676 0x0001b724,0x000136e4,0x000126dc,0x000124db},
677 {0x00000000,0x00000000,0x00000000,0x00000000,
678 0x00000000,0x00000000,0x00000000,0x00000000}
679 }
680 },
681 { /* version 5 */
682 { /* version 5, passes 0 */
683 {0x00000000,0x00000000,0x00000249,0x00000249,
684 0x00000249,0x00000249,0x00001252,0x00001252},
685 {0x00000000,0x00000000,0x00001249,0x00001249,
686 0x00009252,0x00009292,0x00009292,0x00001252},
687 {0x00000000,0x00000000,0x00001249,0x0000924a,
688 0x00009492,0x0000a49b,0x0000a49b,0x00009292},
689 {0x00000000,0x00000000,0x00001249,0x00009493,
690 0x0000a493,0x0000a49b,0x000124db,0x00009493},
691 {0x00000000,0x00000000,0x00001249,0x00009493,
692 0x0000a493,0x000124db,0x000126dc,0x00009493},
693 {0x00000000,0x00000000,0x0000924a,0x00009493,
694 0x0000a493,0x000126dc,0x000126dc,0x0000a49b},
695 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
696 0x0001249b,0x000126dc,0x000136e4,0x000124db},
697 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
698 0x000126dc,0x000136e4,0x000136e4,0x000126dc},
699 {0x00000000,0x00000000,0x00009292,0x0000a49b,
700 0x000126dc,0x000136e4,0x000136e4,0x000126dc},
701 {0x00000000,0x00000000,0x00009292,0x0000a49b,
702 0x000126dc,0x0001b724,0x0001b725,0x000136e4},
703 {0x00000000,0x00000000,0x00009292,0x0000a49b,
704 0x000136e4,0x0001b724,0x0001b92d,0x0001b724},
705 {0x00000000,0x00000000,0x00009492,0x0000a49b,
706 0x000136e4,0x0001b724,0x0001b92d,0x0001b724},
707 {0x00000000,0x00000000,0x00009492,0x000124db,
708 0x000136e4,0x0001b925,0x0001c96e,0x0001b925},
709 {0x00000000,0x00000000,0x00009492,0x000124db,
710 0x0001b724,0x0001b925,0x0001c96e,0x0001c92d},
711 {0x00000000,0x00000000,0x0000a492,0x000126db,
712 0x0001c924,0x0002496d,0x00025bb6,0x00024b77},
713 {0x00000000,0x00000000,0x00000000,0x00000000,
714 0x00000000,0x00000000,0x00000000,0x00000000}
715 },
716 { /* version 5, passes 1 */
717 {0x00000000,0x00000000,0x00001249,0x00000249,
718 0x00000249,0x00000249,0x0000024a,0x0000024a},
719 {0x00000000,0x00000000,0x00001249,0x00001249,
720 0x0000124a,0x0000124a,0x0000024a,0x0000024a},
721 {0x00000000,0x00000000,0x00001249,0x0000924a,
722 0x00009252,0x00009252,0x0000024a,0x0000024a},
723 {0x00000000,0x00000000,0x00001249,0x00009292,
724 0x00009492,0x0000a49b,0x00001252,0x00001252},
725 {0x00000000,0x00000000,0x0000924a,0x00009493,
726 0x0000a493,0x0000a49b,0x00001252,0x00001252},
727 {0x00000000,0x00000000,0x0000924a,0x00009493,
728 0x0000a493,0x0000a49b,0x00009292,0x00001252},
729 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
730 0x0000a493,0x0000a49b,0x00009292,0x00009292},
731 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
732 0x0000a493,0x0000a49b,0x00009493,0x00009292},
733 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
734 0x0001249b,0x000124db,0x00009493,0x00009292},
735 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
736 0x0001249b,0x000124db,0x00009493,0x00009493},
737 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
738 0x000124db,0x000124db,0x0000a49b,0x00009493},
739 {0x00000000,0x00000000,0x0000924a,0x000124db,
740 0x000126dc,0x000126dc,0x0000a49b,0x00009493},
741 {0x00000000,0x00000000,0x0000924a,0x000124db,
742 0x000136e4,0x000126dc,0x000124db,0x0000a49b},
743 {0x00000000,0x00000000,0x00009292,0x000124db,
744 0x000136e4,0x000126dc,0x000124db,0x0000a49b},
745 {0x00000000,0x00000000,0x00009492,0x000126db,
746 0x0001b724,0x000136e4,0x000126dc,0x000124db},
747 {0x00000000,0x00000000,0x00000000,0x00000000,
748 0x00000000,0x00000000,0x00000000,0x00000000}
749 }
750 },
751 { /* version 6 */
752 { /* version 6, passes 0 */
753 {0x00000000,0x00000000,0x00001249,0x00001249,
754 0x00009252,0x00009292,0x00009493,0x00009493},
755 {0x00000000,0x00000000,0x00001249,0x00009292,
756 0x0000a493,0x0000a49b,0x0000a49b,0x00009493},
757 {0x00000000,0x00000000,0x00001249,0x00009493,
758 0x0000a493,0x000124db,0x000124db,0x0000a49b},
759 {0x00000000,0x00000000,0x0000924a,0x00009493,
760 0x0000a493,0x000126dc,0x000126dc,0x0000a49b},
761 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
762 0x0001249b,0x000126dc,0x000136e4,0x000124db},
763 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
764 0x000126dc,0x000136e4,0x000136e4,0x000126dc},
765 {0x00000000,0x00000000,0x00009292,0x0000a49b,
766 0x000126dc,0x0001b724,0x0001b725,0x000126dc},
767 {0x00000000,0x00000000,0x00009292,0x0000a49b,
768 0x000136e4,0x0001b724,0x0001b92d,0x000136e4},
769 {0x00000000,0x00000000,0x00009492,0x0000a49b,
770 0x000136e4,0x0001b724,0x0001b92d,0x0001b724},
771 {0x00000000,0x00000000,0x00009492,0x000124db,
772 0x000136e4,0x0001b724,0x0001b92d,0x0001b724},
773 {0x00000000,0x00000000,0x00009492,0x000124db,
774 0x000136e4,0x0001b925,0x0001b92d,0x0001b925},
775 {0x00000000,0x00000000,0x00009492,0x000124db,
776 0x0001b724,0x0001b925,0x0001c96e,0x0001c92d},
777 {0x00000000,0x00000000,0x0000a492,0x000124db,
778 0x0001b724,0x0001c92d,0x0001c96e,0x0001c92d},
779 {0x00000000,0x00000000,0x0000a492,0x000124db,
780 0x0001b724,0x0001c92d,0x00024b76,0x0002496e},
781 {0x00000000,0x00000000,0x00012492,0x000126db,
782 0x0001c924,0x00024b6d,0x0002ddb6,0x00025bbf},
783 {0x00000000,0x00000000,0x00000000,0x00000000,
784 0x00000000,0x00000000,0x00000000,0x00000000}
785 },
786 { /* version 6, passes 1 */
787 {0x00000000,0x00000000,0x00001249,0x00001249,
788 0x0000124a,0x0000124a,0x00001252,0x00001252},
789 {0x00000000,0x00000000,0x00001249,0x00009292,
790 0x00009492,0x00009252,0x00001252,0x00001252},
791 {0x00000000,0x00000000,0x0000924a,0x00009493,
792 0x0000a493,0x00009292,0x00001252,0x00001252},
793 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
794 0x0000a493,0x0000a49b,0x00009292,0x00009292},
795 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
796 0x0000a493,0x0000a49b,0x00009292,0x00009292},
797 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
798 0x0001249b,0x0000a49b,0x00009493,0x00009292},
799 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
800 0x000124db,0x000124db,0x00009493,0x00009493},
801 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
802 0x000124db,0x000124db,0x0000a49b,0x00009493},
803 {0x00000000,0x00000000,0x0000924a,0x000124db,
804 0x000126dc,0x000124db,0x0000a49b,0x00009493},
805 {0x00000000,0x00000000,0x0000924a,0x000124db,
806 0x000126dc,0x000126dc,0x0000a49b,0x0000a49b},
807 {0x00000000,0x00000000,0x0000924a,0x000124db,
808 0x000136e4,0x000126dc,0x000124db,0x0000a49b},
809 {0x00000000,0x00000000,0x00009492,0x000126db,
810 0x000136e4,0x000126dc,0x000124db,0x0000a49b},
811 {0x00000000,0x00000000,0x00009492,0x000126db,
812 0x0001b724,0x000136e4,0x000126dc,0x000124db},
813 {0x00000000,0x00000000,0x00009492,0x000126db,
814 0x0001b724,0x000136e4,0x000126dc,0x000124db},
815 {0x00000000,0x00000000,0x0000a492,0x000136db,
816 0x0001c924,0x0001b724,0x000136e4,0x000126dc},
817 {0x00000000,0x00000000,0x00000000,0x00000000,
818 0x00000000,0x00000000,0x00000000,0x00000000}
819 }
820 },
821 { /* version 7 */
822 { /* version 7, passes 0 */
823 {0x00000000,0x00000000,0x00001249,0x00001249,
824 0x00009252,0x00009292,0x00009493,0x00009493},
825 {0x00000000,0x00000000,0x00001249,0x00009493,
826 0x0000a493,0x000124db,0x000126dc,0x00009493},
827 {0x00000000,0x00000000,0x00001249,0x0000a49b,
828 0x0001249b,0x000126dc,0x000126dc,0x0000a49b},
829 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
830 0x0001249b,0x000126dc,0x000136e4,0x0000a49b},
831 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
832 0x000126dc,0x000136e4,0x0001b725,0x000124db},
833 {0x00000000,0x00000000,0x00009292,0x0000a49b,
834 0x000136e4,0x0001b724,0x0001b725,0x000126dc},
835 {0x00000000,0x00000000,0x00009292,0x000124db,
836 0x000136e4,0x0001b724,0x0001b725,0x000126dc},
837 {0x00000000,0x00000000,0x00009492,0x000124db,
838 0x000136e4,0x0001b724,0x0001c96e,0x000136e4},
839 {0x00000000,0x00000000,0x00009492,0x000124db,
840 0x000136e4,0x0001c92d,0x0001c96e,0x0001b724},
841 {0x00000000,0x00000000,0x0000a492,0x000124db,
842 0x000136e4,0x0001c92d,0x0001c96e,0x0001b724},
843 {0x00000000,0x00000000,0x0000a492,0x000124db,
844 0x0001b724,0x0001c92d,0x0001c96e,0x0001b925},
845 {0x00000000,0x00000000,0x0000a492,0x000126db,
846 0x0001b724,0x0001c92d,0x00024b76,0x0001c92d},
847 {0x00000000,0x00000000,0x0000a492,0x000126db,
848 0x0001b924,0x0001c92d,0x00024b76,0x0001c92d},
849 {0x00000000,0x00000000,0x0000a492,0x000126db,
850 0x0001b924,0x0001c92d,0x00024b76,0x0002496e},
851 {0x00000000,0x00000000,0x00012492,0x000136db,
852 0x00024924,0x00024b6d,0x0002ddb6,0x00025bbf},
853 {0x00000000,0x00000000,0x00000000,0x00000000,
854 0x00000000,0x00000000,0x00000000,0x00000000}
855 },
856 { /* version 7, passes 1 */
857 {0x00000000,0x00000000,0x00001249,0x00001249,
858 0x0000124a,0x0000124a,0x00001252,0x00001252},
859 {0x00000000,0x00000000,0x0000924a,0x00009493,
860 0x00009492,0x00009292,0x00001252,0x00001252},
861 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
862 0x0000a493,0x0000a49b,0x00001252,0x00001252},
863 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
864 0x0000a493,0x0000a49b,0x00009292,0x00009292},
865 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
866 0x0000a493,0x0000a49b,0x00009292,0x00009292},
867 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
868 0x000126dc,0x0000a49b,0x00009493,0x00009292},
869 {0x00000000,0x00000000,0x0000924a,0x000124db,
870 0x000126dc,0x000124db,0x00009493,0x00009493},
871 {0x00000000,0x00000000,0x0000924a,0x000124db,
872 0x000136e4,0x000124db,0x0000a49b,0x00009493},
873 {0x00000000,0x00000000,0x0000924a,0x000136db,
874 0x0001b724,0x000124db,0x0000a49b,0x00009493},
875 {0x00000000,0x00000000,0x0000924a,0x000136db,
876 0x0001b724,0x000126dc,0x0000a49b,0x0000a49b},
877 {0x00000000,0x00000000,0x00009292,0x000136db,
878 0x0001b724,0x000126dc,0x000124db,0x0000a49b},
879 {0x00000000,0x00000000,0x00009492,0x000136db,
880 0x0001b724,0x000126dc,0x000124db,0x0000a49b},
881 {0x00000000,0x00000000,0x0000a492,0x000136db,
882 0x0001b724,0x000136e4,0x000126dc,0x000124db},
883 {0x00000000,0x00000000,0x0000a492,0x000136db,
884 0x0001b724,0x000136e4,0x000126dc,0x000124db},
885 {0x00000000,0x00000000,0x00012492,0x0001b6db,
886 0x0001c924,0x0001b724,0x000136e4,0x000126dc},
887 {0x00000000,0x00000000,0x00000000,0x00000000,
888 0x00000000,0x00000000,0x00000000,0x00000000}
889 }
890 }
891};
892
diff --git a/drivers/media/video/pwc/pwc-kiara.h b/drivers/media/video/pwc/pwc-kiara.h
new file mode 100644
index 00000000000..047dad8c15f
--- /dev/null
+++ b/drivers/media/video/pwc/pwc-kiara.h
@@ -0,0 +1,48 @@
1/* Linux driver for Philips webcam
2 (C) 2004-2006 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 <media/pwc-ioctl.h>
31
32#define PWC_FPS_MAX_KIARA 6
33
34struct Kiara_table_entry
35{
36 char alternate; /* USB alternate interface */
37 unsigned short packetsize; /* Normal packet size */
38 unsigned short bandlength; /* Bandlength when decompressing */
39 unsigned char mode[12]; /* precomputed mode settings for cam */
40};
41
42extern const struct Kiara_table_entry Kiara_table[PSZ_MAX][PWC_FPS_MAX_KIARA][4];
43extern const unsigned int KiaraRomTable[8][2][16][8];
44extern const unsigned int Kiara_fps_vector[PWC_FPS_MAX_KIARA];
45
46#endif
47
48
diff --git a/drivers/media/video/pwc/pwc-misc.c b/drivers/media/video/pwc/pwc-misc.c
new file mode 100644
index 00000000000..0b031336eab
--- /dev/null
+++ b/drivers/media/video/pwc/pwc-misc.c
@@ -0,0 +1,129 @@
1/* Linux driver for Philips webcam
2 Various miscellaneous functions and tables.
3 (C) 1999-2003 Nemosoft Unv.
4 (C) 2004-2006 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#include "pwc.h"
29
30const struct pwc_coord pwc_image_sizes[PSZ_MAX] =
31{
32 { 128, 96, 0 }, /* sqcif */
33 { 160, 120, 0 }, /* qsif */
34 { 176, 144, 0 }, /* qcif */
35 { 320, 240, 0 }, /* sif */
36 { 352, 288, 0 }, /* cif */
37 { 640, 480, 0 }, /* vga */
38};
39
40/* x,y -> PSZ_ */
41int pwc_decode_size(struct pwc_device *pdev, int width, int height)
42{
43 int i, find;
44
45 /* Make sure we don't go beyond our max size.
46 NB: we have different limits for RAW and normal modes. In case
47 you don't have the decompressor loaded or use RAW mode,
48 the maximum viewable size is smaller.
49 */
50 if (pdev->pixfmt != V4L2_PIX_FMT_YUV420)
51 {
52 if (width > pdev->abs_max.x || height > pdev->abs_max.y)
53 {
54 PWC_DEBUG_SIZE("VIDEO_PALETTE_RAW: going beyond abs_max.\n");
55 return -1;
56 }
57 }
58 else
59 {
60 if (width > pdev->view_max.x || height > pdev->view_max.y)
61 {
62 PWC_DEBUG_SIZE("VIDEO_PALETTE_not RAW: going beyond view_max.\n");
63 return -1;
64 }
65 }
66
67 /* Find the largest size supported by the camera that fits into the
68 requested size.
69 */
70 find = -1;
71 for (i = 0; i < PSZ_MAX; i++) {
72 if (pdev->image_mask & (1 << i)) {
73 if (pwc_image_sizes[i].x <= width && pwc_image_sizes[i].y <= height)
74 find = i;
75 }
76 }
77 return find;
78}
79
80/* initialize variables depending on type and decompressor*/
81void pwc_construct(struct pwc_device *pdev)
82{
83 if (DEVICE_USE_CODEC1(pdev->type)) {
84
85 pdev->view_min.x = 128;
86 pdev->view_min.y = 96;
87 pdev->view_max.x = 352;
88 pdev->view_max.y = 288;
89 pdev->abs_max.x = 352;
90 pdev->abs_max.y = 288;
91 pdev->image_mask = 1 << PSZ_SQCIF | 1 << PSZ_QCIF | 1 << PSZ_CIF;
92 pdev->vcinterface = 2;
93 pdev->vendpoint = 4;
94 pdev->frame_header_size = 0;
95 pdev->frame_trailer_size = 0;
96
97 } else if (DEVICE_USE_CODEC3(pdev->type)) {
98
99 pdev->view_min.x = 160;
100 pdev->view_min.y = 120;
101 pdev->view_max.x = 640;
102 pdev->view_max.y = 480;
103 pdev->image_mask = 1 << PSZ_QSIF | 1 << PSZ_SIF | 1 << PSZ_VGA;
104 pdev->abs_max.x = 640;
105 pdev->abs_max.y = 480;
106 pdev->vcinterface = 3;
107 pdev->vendpoint = 5;
108 pdev->frame_header_size = TOUCAM_HEADER_SIZE;
109 pdev->frame_trailer_size = TOUCAM_TRAILER_SIZE;
110
111 } else /* if (DEVICE_USE_CODEC2(pdev->type)) */ {
112
113 pdev->view_min.x = 128;
114 pdev->view_min.y = 96;
115 /* Anthill bug #38: PWC always reports max size, even without PWCX */
116 pdev->view_max.x = 640;
117 pdev->view_max.y = 480;
118 pdev->image_mask = 1 << PSZ_SQCIF | 1 << PSZ_QSIF | 1 << PSZ_QCIF | 1 << PSZ_SIF | 1 << PSZ_CIF | 1 << PSZ_VGA;
119 pdev->abs_max.x = 640;
120 pdev->abs_max.y = 480;
121 pdev->vcinterface = 3;
122 pdev->vendpoint = 4;
123 pdev->frame_header_size = 0;
124 pdev->frame_trailer_size = 0;
125 }
126 pdev->pixfmt = V4L2_PIX_FMT_YUV420; /* default */
127 pdev->view_min.size = pdev->view_min.x * pdev->view_min.y;
128 pdev->view_max.size = pdev->view_max.x * pdev->view_max.y;
129}
diff --git a/drivers/media/video/pwc/pwc-nala.h b/drivers/media/video/pwc/pwc-nala.h
new file mode 100644
index 00000000000..168c73ef75d
--- /dev/null
+++ b/drivers/media/video/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/media/video/pwc/pwc-timon.c b/drivers/media/video/pwc/pwc-timon.c
new file mode 100644
index 00000000000..c56c174b161
--- /dev/null
+++ b/drivers/media/video/pwc/pwc-timon.c
@@ -0,0 +1,1448 @@
1/* Linux driver for Philips webcam
2 (C) 2004-2006 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 unsigned int Timon_fps_vector[PWC_FPS_MAX_TIMON] = { 5, 10, 15, 20, 25, 30 };
44
45const struct Timon_table_entry Timon_table[PSZ_MAX][PWC_FPS_MAX_TIMON][4] =
46{
47 /* SQCIF */
48 {
49 /* 5 fps */
50 {
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 {1, 140, 0, {0x05, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x8C, 0xFC, 0x80, 0x02}},
54 {1, 140, 0, {0x05, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x8C, 0xFC, 0x80, 0x02}},
55 },
56 /* 10 fps */
57 {
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 {2, 280, 0, {0x04, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x18, 0xA9, 0x80, 0x02}},
61 {2, 280, 0, {0x04, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x18, 0xA9, 0x80, 0x02}},
62 },
63 /* 15 fps */
64 {
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 {3, 410, 0, {0x03, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x9A, 0x71, 0x80, 0x02}},
68 {3, 410, 0, {0x03, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x9A, 0x71, 0x80, 0x02}},
69 },
70 /* 20 fps */
71 {
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 {4, 559, 0, {0x02, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x2F, 0x56, 0x80, 0x02}},
75 {4, 559, 0, {0x02, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x2F, 0x56, 0x80, 0x02}},
76 },
77 /* 25 fps */
78 {
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 {5, 659, 0, {0x01, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x93, 0x46, 0x80, 0x02}},
82 {5, 659, 0, {0x01, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x93, 0x46, 0x80, 0x02}},
83 },
84 /* 30 fps */
85 {
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 {7, 838, 0, {0x00, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x46, 0x3B, 0x80, 0x02}},
89 {7, 838, 0, {0x00, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x46, 0x3B, 0x80, 0x02}},
90 },
91 },
92 /* QSIF */
93 {
94 /* 5 fps */
95 {
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 {1, 146, 0, {0x2D, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x92, 0xFC, 0xC0, 0x02}},
99 {1, 146, 0, {0x2D, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x92, 0xFC, 0xC0, 0x02}},
100 },
101 /* 10 fps */
102 {
103 {2, 291, 0, {0x2C, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x23, 0xA1, 0xC0, 0x02}},
104 {1, 191, 630, {0x2C, 0xF4, 0x05, 0x13, 0xA9, 0x12, 0xE1, 0x17, 0x08, 0xBF, 0xF4, 0xC0, 0x02}},
105 {1, 191, 630, {0x2C, 0xF4, 0x05, 0x13, 0xA9, 0x12, 0xE1, 0x17, 0x08, 0xBF, 0xF4, 0xC0, 0x02}},
106 {1, 191, 630, {0x2C, 0xF4, 0x05, 0x13, 0xA9, 0x12, 0xE1, 0x17, 0x08, 0xBF, 0xF4, 0xC0, 0x02}},
107 },
108 /* 15 fps */
109 {
110 {3, 437, 0, {0x2B, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0xB5, 0x6D, 0xC0, 0x02}},
111 {2, 291, 640, {0x2B, 0xF4, 0x05, 0x13, 0xF7, 0x13, 0x2F, 0x13, 0x08, 0x23, 0xA1, 0xC0, 0x02}},
112 {2, 291, 640, {0x2B, 0xF4, 0x05, 0x13, 0xF7, 0x13, 0x2F, 0x13, 0x08, 0x23, 0xA1, 0xC0, 0x02}},
113 {1, 191, 420, {0x2B, 0xF4, 0x0D, 0x0D, 0x1B, 0x0C, 0x53, 0x1E, 0x08, 0xBF, 0xF4, 0xC0, 0x02}},
114 },
115 /* 20 fps */
116 {
117 {4, 588, 0, {0x2A, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x4C, 0x52, 0xC0, 0x02}},
118 {3, 447, 730, {0x2A, 0xF4, 0x05, 0x16, 0xC9, 0x16, 0x01, 0x0E, 0x18, 0xBF, 0x69, 0xC0, 0x02}},
119 {2, 292, 476, {0x2A, 0xF4, 0x0D, 0x0E, 0xD8, 0x0E, 0x10, 0x19, 0x18, 0x24, 0xA1, 0xC0, 0x02}},
120 {1, 192, 312, {0x2A, 0xF4, 0x1D, 0x09, 0xB3, 0x08, 0xEB, 0x1E, 0x18, 0xC0, 0xF4, 0xC0, 0x02}},
121 },
122 /* 25 fps */
123 {
124 {5, 703, 0, {0x29, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0xBF, 0x42, 0xC0, 0x02}},
125 {3, 447, 610, {0x29, 0xF4, 0x05, 0x13, 0x0B, 0x12, 0x43, 0x14, 0x18, 0xBF, 0x69, 0xC0, 0x02}},
126 {2, 292, 398, {0x29, 0xF4, 0x0D, 0x0C, 0x6C, 0x0B, 0xA4, 0x1E, 0x18, 0x24, 0xA1, 0xC0, 0x02}},
127 {1, 192, 262, {0x29, 0xF4, 0x25, 0x08, 0x23, 0x07, 0x5B, 0x1E, 0x18, 0xC0, 0xF4, 0xC0, 0x02}},
128 },
129 /* 30 fps */
130 {
131 {8, 873, 0, {0x28, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x69, 0x37, 0xC0, 0x02}},
132 {5, 704, 774, {0x28, 0xF4, 0x05, 0x18, 0x21, 0x17, 0x59, 0x0F, 0x18, 0xC0, 0x42, 0xC0, 0x02}},
133 {3, 448, 492, {0x28, 0xF4, 0x05, 0x0F, 0x5D, 0x0E, 0x95, 0x15, 0x18, 0xC0, 0x69, 0xC0, 0x02}},
134 {2, 291, 320, {0x28, 0xF4, 0x1D, 0x09, 0xFB, 0x09, 0x33, 0x1E, 0x18, 0x23, 0xA1, 0xC0, 0x02}},
135 },
136 },
137 /* QCIF */
138 {
139 /* 5 fps */
140 {
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 {1, 193, 0, {0x0D, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0xC1, 0xF4, 0xC0, 0x02}},
144 {1, 193, 0, {0x0D, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0xC1, 0xF4, 0xC0, 0x02}},
145 },
146 /* 10 fps */
147 {
148 {3, 385, 0, {0x0C, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x81, 0x79, 0xC0, 0x02}},
149 {2, 291, 800, {0x0C, 0xF4, 0x05, 0x18, 0xF4, 0x18, 0x18, 0x11, 0x08, 0x23, 0xA1, 0xC0, 0x02}},
150 {2, 291, 800, {0x0C, 0xF4, 0x05, 0x18, 0xF4, 0x18, 0x18, 0x11, 0x08, 0x23, 0xA1, 0xC0, 0x02}},
151 {1, 194, 532, {0x0C, 0xF4, 0x05, 0x10, 0x9A, 0x0F, 0xBE, 0x1B, 0x08, 0xC2, 0xF0, 0xC0, 0x02}},
152 },
153 /* 15 fps */
154 {
155 {4, 577, 0, {0x0B, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x41, 0x52, 0xC0, 0x02}},
156 {3, 447, 818, {0x0B, 0xF4, 0x05, 0x19, 0x89, 0x18, 0xAD, 0x0F, 0x10, 0xBF, 0x69, 0xC0, 0x02}},
157 {2, 292, 534, {0x0B, 0xF4, 0x05, 0x10, 0xA3, 0x0F, 0xC7, 0x19, 0x10, 0x24, 0xA1, 0xC0, 0x02}},
158 {1, 195, 356, {0x0B, 0xF4, 0x15, 0x0B, 0x11, 0x0A, 0x35, 0x1E, 0x10, 0xC3, 0xF0, 0xC0, 0x02}},
159 },
160 /* 20 fps */
161 {
162 {6, 776, 0, {0x0A, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x08, 0x3F, 0xC0, 0x02}},
163 {4, 591, 804, {0x0A, 0xF4, 0x05, 0x19, 0x1E, 0x18, 0x42, 0x0F, 0x18, 0x4F, 0x4E, 0xC0, 0x02}},
164 {3, 447, 608, {0x0A, 0xF4, 0x05, 0x12, 0xFD, 0x12, 0x21, 0x15, 0x18, 0xBF, 0x69, 0xC0, 0x02}},
165 {2, 291, 396, {0x0A, 0xF4, 0x15, 0x0C, 0x5E, 0x0B, 0x82, 0x1E, 0x18, 0x23, 0xA1, 0xC0, 0x02}},
166 },
167 /* 25 fps */
168 {
169 {9, 928, 0, {0x09, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0xA0, 0x33, 0xC0, 0x02}},
170 {5, 703, 800, {0x09, 0xF4, 0x05, 0x18, 0xF4, 0x18, 0x18, 0x10, 0x18, 0xBF, 0x42, 0xC0, 0x02}},
171 {3, 447, 508, {0x09, 0xF4, 0x0D, 0x0F, 0xD2, 0x0E, 0xF6, 0x1B, 0x18, 0xBF, 0x69, 0xC0, 0x02}},
172 {2, 292, 332, {0x09, 0xF4, 0x1D, 0x0A, 0x5A, 0x09, 0x7E, 0x1E, 0x18, 0x24, 0xA1, 0xC0, 0x02}},
173 },
174 /* 30 fps */
175 {
176 {0, },
177 {9, 956, 876, {0x08, 0xF4, 0x05, 0x1B, 0x58, 0x1A, 0x7C, 0x0E, 0x20, 0xBC, 0x33, 0x10, 0x02}},
178 {4, 592, 542, {0x08, 0xF4, 0x05, 0x10, 0xE4, 0x10, 0x08, 0x17, 0x20, 0x50, 0x4E, 0x10, 0x02}},
179 {2, 291, 266, {0x08, 0xF4, 0x25, 0x08, 0x48, 0x07, 0x6C, 0x1E, 0x20, 0x23, 0xA1, 0x10, 0x02}},
180 },
181 },
182 /* SIF */
183 {
184 /* 5 fps */
185 {
186 {4, 582, 0, {0x35, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x46, 0x52, 0x60, 0x02}},
187 {3, 387, 1276, {0x35, 0xF4, 0x05, 0x27, 0xD8, 0x26, 0x48, 0x03, 0x10, 0x83, 0x79, 0x60, 0x02}},
188 {2, 291, 960, {0x35, 0xF4, 0x0D, 0x1D, 0xF2, 0x1C, 0x62, 0x04, 0x10, 0x23, 0xA1, 0x60, 0x02}},
189 {1, 191, 630, {0x35, 0xF4, 0x1D, 0x13, 0xA9, 0x12, 0x19, 0x05, 0x08, 0xBF, 0xF4, 0x60, 0x02}},
190 },
191 /* 10 fps */
192 {
193 {0, },
194 {6, 775, 1278, {0x34, 0xF4, 0x05, 0x27, 0xE8, 0x26, 0x58, 0x05, 0x30, 0x07, 0x3F, 0x10, 0x02}},
195 {3, 447, 736, {0x34, 0xF4, 0x15, 0x16, 0xFB, 0x15, 0x6B, 0x05, 0x18, 0xBF, 0x69, 0x10, 0x02}},
196 {2, 291, 480, {0x34, 0xF4, 0x2D, 0x0E, 0xF9, 0x0D, 0x69, 0x09, 0x18, 0x23, 0xA1, 0x10, 0x02}},
197 },
198 /* 15 fps */
199 {
200 {0, },
201 {9, 955, 1050, {0x33, 0xF4, 0x05, 0x20, 0xCF, 0x1F, 0x3F, 0x06, 0x48, 0xBB, 0x33, 0x10, 0x02}},
202 {4, 591, 650, {0x33, 0xF4, 0x15, 0x14, 0x44, 0x12, 0xB4, 0x08, 0x30, 0x4F, 0x4E, 0x10, 0x02}},
203 {3, 448, 492, {0x33, 0xF4, 0x25, 0x0F, 0x52, 0x0D, 0xC2, 0x09, 0x28, 0xC0, 0x69, 0x10, 0x02}},
204 },
205 /* 20 fps */
206 {
207 {0, },
208 {9, 958, 782, {0x32, 0xF4, 0x0D, 0x18, 0x6A, 0x16, 0xDA, 0x0B, 0x58, 0xBE, 0x33, 0xD0, 0x02}},
209 {5, 703, 574, {0x32, 0xF4, 0x1D, 0x11, 0xE7, 0x10, 0x57, 0x0B, 0x40, 0xBF, 0x42, 0xD0, 0x02}},
210 {3, 446, 364, {0x32, 0xF4, 0x3D, 0x0B, 0x5C, 0x09, 0xCC, 0x0E, 0x30, 0xBE, 0x69, 0xD0, 0x02}},
211 },
212 /* 25 fps */
213 {
214 {0, },
215 {9, 958, 654, {0x31, 0xF4, 0x15, 0x14, 0x66, 0x12, 0xD6, 0x0B, 0x50, 0xBE, 0x33, 0x90, 0x02}},
216 {6, 776, 530, {0x31, 0xF4, 0x25, 0x10, 0x8C, 0x0E, 0xFC, 0x0C, 0x48, 0x08, 0x3F, 0x90, 0x02}},
217 {4, 592, 404, {0x31, 0xF4, 0x35, 0x0C, 0x96, 0x0B, 0x06, 0x0B, 0x38, 0x50, 0x4E, 0x90, 0x02}},
218 },
219 /* 30 fps */
220 {
221 {0, },
222 {9, 957, 526, {0x30, 0xF4, 0x25, 0x10, 0x68, 0x0E, 0xD8, 0x0D, 0x58, 0xBD, 0x33, 0x60, 0x02}},
223 {6, 775, 426, {0x30, 0xF4, 0x35, 0x0D, 0x48, 0x0B, 0xB8, 0x0F, 0x50, 0x07, 0x3F, 0x60, 0x02}},
224 {4, 590, 324, {0x30, 0x7A, 0x4B, 0x0A, 0x1C, 0x08, 0xB4, 0x0E, 0x40, 0x4E, 0x52, 0x60, 0x02}},
225 },
226 },
227 /* CIF */
228 {
229 /* 5 fps */
230 {
231 {6, 771, 0, {0x15, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x03, 0x3F, 0x80, 0x02}},
232 {4, 465, 1278, {0x15, 0xF4, 0x05, 0x27, 0xEE, 0x26, 0x36, 0x03, 0x18, 0xD1, 0x65, 0x80, 0x02}},
233 {2, 291, 800, {0x15, 0xF4, 0x15, 0x18, 0xF4, 0x17, 0x3C, 0x05, 0x18, 0x23, 0xA1, 0x80, 0x02}},
234 {1, 193, 528, {0x15, 0xF4, 0x2D, 0x10, 0x7E, 0x0E, 0xC6, 0x0A, 0x18, 0xC1, 0xF4, 0x80, 0x02}},
235 },
236 /* 10 fps */
237 {
238 {0, },
239 {9, 932, 1278, {0x14, 0xF4, 0x05, 0x27, 0xEE, 0x26, 0x36, 0x04, 0x30, 0xA4, 0x33, 0x10, 0x02}},
240 {4, 591, 812, {0x14, 0xF4, 0x15, 0x19, 0x56, 0x17, 0x9E, 0x06, 0x28, 0x4F, 0x4E, 0x10, 0x02}},
241 {2, 291, 400, {0x14, 0xF4, 0x3D, 0x0C, 0x7A, 0x0A, 0xC2, 0x0E, 0x28, 0x23, 0xA1, 0x10, 0x02}},
242 },
243 /* 15 fps */
244 {
245 {0, },
246 {9, 956, 876, {0x13, 0xF4, 0x0D, 0x1B, 0x58, 0x19, 0xA0, 0x05, 0x38, 0xBC, 0x33, 0x60, 0x02}},
247 {5, 703, 644, {0x13, 0xF4, 0x1D, 0x14, 0x1C, 0x12, 0x64, 0x08, 0x38, 0xBF, 0x42, 0x60, 0x02}},
248 {3, 448, 410, {0x13, 0xF4, 0x3D, 0x0C, 0xC4, 0x0B, 0x0C, 0x0E, 0x38, 0xC0, 0x69, 0x60, 0x02}},
249 },
250 /* 20 fps */
251 {
252 {0, },
253 {9, 956, 650, {0x12, 0xF4, 0x1D, 0x14, 0x4A, 0x12, 0x92, 0x09, 0x48, 0xBC, 0x33, 0x10, 0x03}},
254 {6, 776, 528, {0x12, 0xF4, 0x2D, 0x10, 0x7E, 0x0E, 0xC6, 0x0A, 0x40, 0x08, 0x3F, 0x10, 0x03}},
255 {4, 591, 402, {0x12, 0xF4, 0x3D, 0x0C, 0x8F, 0x0A, 0xD7, 0x0E, 0x40, 0x4F, 0x4E, 0x10, 0x03}},
256 },
257 /* 25 fps */
258 {
259 {0, },
260 {9, 956, 544, {0x11, 0xF4, 0x25, 0x10, 0xF4, 0x0F, 0x3C, 0x0A, 0x48, 0xBC, 0x33, 0xC0, 0x02}},
261 {7, 840, 478, {0x11, 0xF4, 0x2D, 0x0E, 0xEB, 0x0D, 0x33, 0x0B, 0x48, 0x48, 0x3B, 0xC0, 0x02}},
262 {5, 703, 400, {0x11, 0xF4, 0x3D, 0x0C, 0x7A, 0x0A, 0xC2, 0x0E, 0x48, 0xBF, 0x42, 0xC0, 0x02}},
263 },
264 /* 30 fps */
265 {
266 {0, },
267 {9, 956, 438, {0x10, 0xF4, 0x35, 0x0D, 0xAC, 0x0B, 0xF4, 0x0D, 0x50, 0xBC, 0x33, 0x10, 0x02}},
268 {7, 838, 384, {0x10, 0xF4, 0x45, 0x0B, 0xFD, 0x0A, 0x45, 0x0F, 0x50, 0x46, 0x3B, 0x10, 0x02}},
269 {6, 773, 354, {0x10, 0x7A, 0x4B, 0x0B, 0x0C, 0x09, 0x80, 0x10, 0x50, 0x05, 0x3F, 0x10, 0x02}},
270 },
271 },
272 /* VGA */
273 {
274 /* 5 fps */
275 {
276 {0, },
277 {6, 773, 1272, {0x1D, 0xF4, 0x15, 0x27, 0xB6, 0x24, 0x96, 0x02, 0x30, 0x05, 0x3F, 0x10, 0x02}},
278 {4, 592, 976, {0x1D, 0xF4, 0x25, 0x1E, 0x78, 0x1B, 0x58, 0x03, 0x30, 0x50, 0x4E, 0x10, 0x02}},
279 {3, 448, 738, {0x1D, 0xF4, 0x3D, 0x17, 0x0C, 0x13, 0xEC, 0x04, 0x30, 0xC0, 0x69, 0x10, 0x02}},
280 },
281 /* 10 fps */
282 {
283 {0, },
284 {9, 956, 788, {0x1C, 0xF4, 0x35, 0x18, 0x9C, 0x15, 0x7C, 0x03, 0x48, 0xBC, 0x33, 0x10, 0x02}},
285 {6, 776, 640, {0x1C, 0x7A, 0x53, 0x13, 0xFC, 0x11, 0x2C, 0x04, 0x48, 0x08, 0x3F, 0x10, 0x02}},
286 {4, 592, 488, {0x1C, 0x7A, 0x6B, 0x0F, 0x3C, 0x0C, 0x6C, 0x06, 0x48, 0x50, 0x4E, 0x10, 0x02}},
287 },
288 /* 15 fps */
289 {
290 {0, },
291 {9, 957, 526, {0x1B, 0x7A, 0x63, 0x10, 0x68, 0x0D, 0x98, 0x06, 0x58, 0xBD, 0x33, 0x80, 0x02}},
292 {9, 957, 526, {0x1B, 0x7A, 0x63, 0x10, 0x68, 0x0D, 0x98, 0x06, 0x58, 0xBD, 0x33, 0x80, 0x02}},
293 {8, 895, 492, {0x1B, 0x7A, 0x6B, 0x0F, 0x5D, 0x0C, 0x8D, 0x06, 0x58, 0x7F, 0x37, 0x80, 0x02}},
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 * 16 versions:
321 * 2 tables (one for Y, and one for U&V)
322 * 16 levels of details per tables
323 * 8 blocs
324 */
325
326const unsigned int TimonRomTable [16][2][16][8] =
327{
328 { /* version 0 */
329 { /* version 0, passes 0 */
330 {0x00000000,0x00000000,0x00000000,0x00000000,
331 0x00000000,0x00000000,0x00000000,0x00000001},
332 {0x00000000,0x00000000,0x00000001,0x00000001,
333 0x00000001,0x00000001,0x00000001,0x00000001},
334 {0x00000000,0x00000000,0x00000001,0x00000001,
335 0x00000001,0x00000009,0x00000009,0x00000009},
336 {0x00000000,0x00000000,0x00000009,0x00000001,
337 0x00000009,0x00000009,0x00000009,0x00000009},
338 {0x00000000,0x00000000,0x00000009,0x00000009,
339 0x00000009,0x00000009,0x00000049,0x00000009},
340 {0x00000000,0x00000000,0x00000009,0x00000009,
341 0x00000009,0x00000049,0x00000049,0x00000049},
342 {0x00000000,0x00000000,0x00000009,0x00000009,
343 0x00000049,0x00000049,0x00000049,0x00000049},
344 {0x00000000,0x00000000,0x00000009,0x00000049,
345 0x00000049,0x00000049,0x00000049,0x00000049},
346 {0x00000000,0x00000000,0x00000049,0x00000049,
347 0x00000049,0x00000049,0x0000024a,0x0000024a},
348 {0x00000000,0x00000000,0x00000049,0x00000049,
349 0x00000049,0x00000249,0x0000024a,0x0000024a},
350 {0x00000000,0x00000000,0x00000049,0x00000049,
351 0x00000249,0x00000249,0x0000024a,0x0000024a},
352 {0x00000000,0x00000000,0x00000049,0x00000049,
353 0x00000249,0x00000249,0x00001252,0x0000024a},
354 {0x00000000,0x00000000,0x00000049,0x00000049,
355 0x00000249,0x0000124a,0x00001252,0x0000024a},
356 {0x00000000,0x00000000,0x00000049,0x00000249,
357 0x00000249,0x0000124a,0x00001252,0x0000024a},
358 {0x00000000,0x00000000,0x00000249,0x00001249,
359 0x0000124a,0x00009252,0x00009292,0x00001252},
360 {0x00000000,0x00000000,0x00000000,0x00000000,
361 0x00000000,0x00000000,0x00000000,0x00000000}
362 },
363 { /* version 0, passes 1 */
364 {0x00000000,0x00000000,0x00000000,0x00000000,
365 0x00000000,0x00000000,0x00000000,0x00000000},
366 {0x00000000,0x00000000,0x00000001,0x00000001,
367 0x00000001,0x00000001,0x00000000,0x00000000},
368 {0x00000000,0x00000000,0x00000009,0x00000001,
369 0x00000001,0x00000009,0x00000000,0x00000000},
370 {0x00000000,0x00000000,0x00000009,0x00000009,
371 0x00000009,0x00000009,0x00000000,0x00000000},
372 {0x00000000,0x00000000,0x00000009,0x00000009,
373 0x00000009,0x00000009,0x00000001,0x00000000},
374 {0x00000000,0x00000000,0x00000049,0x00000009,
375 0x00000009,0x00000049,0x00000001,0x00000001},
376 {0x00000000,0x00000000,0x00000049,0x00000009,
377 0x00000009,0x00000049,0x00000001,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,0x00000001},
384 {0x00000000,0x00000000,0x00000049,0x00000049,
385 0x00000049,0x00000049,0x00000009,0x00000009},
386 {0x00000000,0x00000000,0x00000049,0x00000049,
387 0x00000049,0x00000249,0x00000049,0x00000009},
388 {0x00000000,0x00000000,0x00000049,0x00000049,
389 0x00000049,0x00000249,0x00000049,0x00000009},
390 {0x00000000,0x00000000,0x00000249,0x00000049,
391 0x00000249,0x00000249,0x00000049,0x00000009},
392 {0x00000000,0x00000000,0x00001249,0x00000249,
393 0x0000124a,0x0000124a,0x0000024a,0x00000049},
394 {0x00000000,0x00000000,0x00000000,0x00000000,
395 0x00000000,0x00000000,0x00000000,0x00000000}
396 }
397 },
398 { /* version 1 */
399 { /* version 1, passes 0 */
400 {0x00000000,0x00000000,0x00000000,0x00000000,
401 0x00000000,0x00000000,0x00000000,0x00000001},
402 {0x00000000,0x00000000,0x00000001,0x00000001,
403 0x00000001,0x00000009,0x00000009,0x00000009},
404 {0x00000000,0x00000000,0x00000009,0x00000009,
405 0x00000009,0x00000009,0x00000009,0x00000009},
406 {0x00000000,0x00000000,0x00000009,0x00000009,
407 0x00000009,0x00000049,0x00000049,0x00000049},
408 {0x00000000,0x00000000,0x00000009,0x00000049,
409 0x00000049,0x00000049,0x00000049,0x00000049},
410 {0x00000000,0x00000000,0x00000049,0x00000049,
411 0x00000049,0x00000249,0x0000024a,0x0000024a},
412 {0x00000000,0x00000000,0x00000049,0x00000049,
413 0x00000249,0x00000249,0x0000024a,0x0000024a},
414 {0x00000000,0x00000000,0x00000049,0x00000249,
415 0x00000249,0x00000249,0x0000024a,0x00001252},
416 {0x00000000,0x00000000,0x00000049,0x00000249,
417 0x00000249,0x0000124a,0x00001252,0x00001252},
418 {0x00000000,0x00000000,0x00000049,0x00000249,
419 0x0000124a,0x0000124a,0x00001252,0x00001252},
420 {0x00000000,0x00000000,0x00000249,0x00000249,
421 0x0000124a,0x0000124a,0x00009292,0x00009292},
422 {0x00000000,0x00000000,0x00000249,0x00001249,
423 0x0000124a,0x00009252,0x00009292,0x00009292},
424 {0x00000000,0x00000000,0x00000249,0x00001249,
425 0x00009252,0x00009252,0x00009292,0x00009292},
426 {0x00000000,0x00000000,0x00000249,0x0000924a,
427 0x00009292,0x00009493,0x00009493,0x00009493},
428 {0x00000000,0x00000000,0x00001249,0x00009252,
429 0x00009492,0x0000a49b,0x0000a49b,0x0000a49b},
430 {0x00000000,0x00000000,0x00000000,0x00000000,
431 0x00000000,0x00000000,0x00000000,0x00000000}
432 },
433 { /* version 1, passes 1 */
434 {0x00000000,0x00000000,0x00000000,0x00000000,
435 0x00000000,0x00000000,0x00000000,0x00000000},
436 {0x00000000,0x00000000,0x00000009,0x00000009,
437 0x00000009,0x00000001,0x00000001,0x00000000},
438 {0x00000000,0x00000000,0x00000009,0x00000009,
439 0x00000009,0x00000009,0x00000001,0x00000000},
440 {0x00000000,0x00000000,0x00000049,0x00000049,
441 0x00000049,0x00000009,0x00000001,0x00000000},
442 {0x00000000,0x00000000,0x00000049,0x00000049,
443 0x00000049,0x00000049,0x00000001,0x00000001},
444 {0x00000000,0x00000000,0x00000049,0x00000049,
445 0x00000049,0x00000049,0x00000009,0x00000001},
446 {0x00000000,0x00000000,0x00000249,0x00000049,
447 0x00000049,0x00000249,0x00000009,0x00000001},
448 {0x00000000,0x00000000,0x00000249,0x00000049,
449 0x00000249,0x00000249,0x00000009,0x00000009},
450 {0x00000000,0x00000000,0x00000249,0x00000249,
451 0x00000249,0x00000249,0x00000049,0x00000009},
452 {0x00000000,0x00000000,0x00000249,0x00000249,
453 0x00000249,0x0000124a,0x00000049,0x00000009},
454 {0x00000000,0x00000000,0x00000249,0x00000249,
455 0x00000249,0x0000124a,0x00000049,0x00000009},
456 {0x00000000,0x00000000,0x00000249,0x00000249,
457 0x00000249,0x0000124a,0x0000024a,0x00000049},
458 {0x00000000,0x00000000,0x00000249,0x00000249,
459 0x0000124a,0x0000124a,0x0000024a,0x00000049},
460 {0x00000000,0x00000000,0x00000249,0x00000249,
461 0x0000124a,0x0000124a,0x0000024a,0x00000049},
462 {0x00000000,0x00000000,0x00001249,0x00001249,
463 0x00009252,0x00009252,0x00001252,0x0000024a},
464 {0x00000000,0x00000000,0x00000000,0x00000000,
465 0x00000000,0x00000000,0x00000000,0x00000000}
466 }
467 },
468 { /* version 2 */
469 { /* version 2, passes 0 */
470 {0x00000000,0x00000000,0x00000000,0x00000000,
471 0x00000000,0x00000000,0x00000000,0x00000001},
472 {0x00000000,0x00000000,0x00000009,0x00000009,
473 0x00000009,0x00000009,0x00000009,0x00000009},
474 {0x00000000,0x00000000,0x00000049,0x00000049,
475 0x00000049,0x00000049,0x00000049,0x00000049},
476 {0x00000000,0x00000000,0x00000049,0x00000049,
477 0x00000049,0x00000249,0x0000024a,0x0000024a},
478 {0x00000000,0x00000000,0x00000049,0x00000249,
479 0x00000249,0x00000249,0x0000024a,0x00001252},
480 {0x00000000,0x00000000,0x00000249,0x00000249,
481 0x00000249,0x0000124a,0x00001252,0x00001252},
482 {0x00000000,0x00000000,0x00000249,0x00000249,
483 0x0000124a,0x0000124a,0x00009292,0x00009292},
484 {0x00000000,0x00000000,0x00000249,0x00001249,
485 0x0000124a,0x00009252,0x00009292,0x00009292},
486 {0x00000000,0x00000000,0x00000249,0x00001249,
487 0x00009252,0x00009292,0x00009292,0x00009292},
488 {0x00000000,0x00000000,0x00000249,0x00001249,
489 0x00009252,0x00009292,0x00009493,0x00009493},
490 {0x00000000,0x00000000,0x00000249,0x0000924a,
491 0x00009252,0x00009493,0x00009493,0x00009493},
492 {0x00000000,0x00000000,0x00000249,0x0000924a,
493 0x00009292,0x00009493,0x00009493,0x00009493},
494 {0x00000000,0x00000000,0x00000249,0x00009252,
495 0x00009492,0x00009493,0x0000a49b,0x0000a49b},
496 {0x00000000,0x00000000,0x00001249,0x00009292,
497 0x00009492,0x000124db,0x000124db,0x000124db},
498 {0x00000000,0x00000000,0x0000924a,0x00009493,
499 0x0000a493,0x000126dc,0x000126dc,0x000126dc},
500 {0x00000000,0x00000000,0x00000000,0x00000000,
501 0x00000000,0x00000000,0x00000000,0x00000000}
502 },
503 { /* version 2, passes 1 */
504 {0x00000000,0x00000000,0x00000000,0x00000000,
505 0x00000000,0x00000000,0x00000000,0x00000000},
506 {0x00000000,0x00000000,0x00000049,0x00000009,
507 0x00000049,0x00000009,0x00000001,0x00000000},
508 {0x00000000,0x00000000,0x00000049,0x00000049,
509 0x00000049,0x00000049,0x00000049,0x00000000},
510 {0x00000000,0x00000000,0x00000249,0x00000049,
511 0x00000249,0x00000049,0x0000024a,0x00000001},
512 {0x00000000,0x00000000,0x00000249,0x00000249,
513 0x00000249,0x00000249,0x0000024a,0x00000001},
514 {0x00000000,0x00000000,0x00000249,0x00000249,
515 0x00000249,0x00000249,0x0000024a,0x00000001},
516 {0x00000000,0x00000000,0x00000249,0x00000249,
517 0x00000249,0x00000249,0x0000024a,0x00000009},
518 {0x00000000,0x00000000,0x00000249,0x00000249,
519 0x0000124a,0x0000124a,0x0000024a,0x00000009},
520 {0x00000000,0x00000000,0x00000249,0x00000249,
521 0x0000124a,0x0000124a,0x0000024a,0x00000009},
522 {0x00000000,0x00000000,0x00001249,0x00001249,
523 0x0000124a,0x00009252,0x00001252,0x00000049},
524 {0x00000000,0x00000000,0x00001249,0x00001249,
525 0x0000124a,0x00009292,0x00001252,0x00000049},
526 {0x00000000,0x00000000,0x00001249,0x00001249,
527 0x0000124a,0x00009292,0x00001252,0x00000049},
528 {0x00000000,0x00000000,0x00001249,0x00001249,
529 0x00009252,0x00009292,0x00001252,0x0000024a},
530 {0x00000000,0x00000000,0x00001249,0x00001249,
531 0x00009292,0x00009292,0x00001252,0x0000024a},
532 {0x00000000,0x00000000,0x0000924a,0x0000924a,
533 0x00009492,0x00009493,0x00009292,0x00001252},
534 {0x00000000,0x00000000,0x00000000,0x00000000,
535 0x00000000,0x00000000,0x00000000,0x00000000}
536 }
537 },
538 { /* version 3 */
539 { /* version 3, passes 0 */
540 {0x00000000,0x00000000,0x00000000,0x00000000,
541 0x00000000,0x00000000,0x00000000,0x00000001},
542 {0x00000000,0x00000000,0x00000049,0x00000049,
543 0x00000049,0x00000049,0x00000049,0x00000049},
544 {0x00000000,0x00000000,0x00000049,0x00000249,
545 0x00000249,0x00000249,0x00001252,0x0000024a},
546 {0x00000000,0x00000000,0x00000249,0x00000249,
547 0x00000249,0x0000124a,0x00001252,0x00001252},
548 {0x00000000,0x00000000,0x00000249,0x00000249,
549 0x0000124a,0x00009252,0x00009292,0x00009292},
550 {0x00000000,0x00000000,0x00000249,0x00001249,
551 0x0000124a,0x00009292,0x00009292,0x00009493},
552 {0x00000000,0x00000000,0x00000249,0x00001249,
553 0x00009252,0x00009292,0x00009493,0x00009493},
554 {0x00000000,0x00000000,0x00000249,0x00001249,
555 0x00009292,0x00009493,0x00009493,0x00009493},
556 {0x00000000,0x00000000,0x00000249,0x00009252,
557 0x00009292,0x00009493,0x0000a49b,0x0000a49b},
558 {0x00000000,0x00000000,0x00001249,0x00009252,
559 0x00009292,0x0000a49b,0x0000a49b,0x0000a49b},
560 {0x00000000,0x00000000,0x00001249,0x00009252,
561 0x00009492,0x0000a49b,0x0000a49b,0x0000a49b},
562 {0x00000000,0x00000000,0x00001249,0x00009292,
563 0x00009492,0x0000a49b,0x000124db,0x000124db},
564 {0x00000000,0x00000000,0x00001249,0x00009292,
565 0x0000a493,0x0000a49b,0x000124db,0x000124db},
566 {0x00000000,0x00000000,0x00001249,0x00009493,
567 0x0001249b,0x000126dc,0x000136e4,0x000126dc},
568 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
569 0x000124db,0x000136e4,0x0001b725,0x000136e4},
570 {0x00000000,0x00000000,0x00000000,0x00000000,
571 0x00000000,0x00000000,0x00000000,0x00000000}
572 },
573 { /* version 3, passes 1 */
574 {0x00000000,0x00000000,0x00000000,0x00000000,
575 0x00000000,0x00000000,0x00000000,0x00000000},
576 {0x00000000,0x00000000,0x00000049,0x00000049,
577 0x00000049,0x00000049,0x00000001,0x00000000},
578 {0x00000000,0x00000000,0x00000249,0x00000249,
579 0x00000249,0x00000249,0x00000049,0x00000001},
580 {0x00000000,0x00000000,0x00000249,0x00000249,
581 0x00000249,0x0000124a,0x00001252,0x00000001},
582 {0x00000000,0x00000000,0x00000249,0x00000249,
583 0x0000124a,0x0000124a,0x00001252,0x00000009},
584 {0x00000000,0x00000000,0x00000249,0x00001249,
585 0x0000124a,0x00009252,0x00009292,0x00000009},
586 {0x00000000,0x00000000,0x00001249,0x00001249,
587 0x0000124a,0x00009252,0x00009292,0x00000049},
588 {0x00000000,0x00000000,0x00001249,0x00001249,
589 0x00009252,0x00009252,0x00009292,0x00000049},
590 {0x00000000,0x00000000,0x00001249,0x00001249,
591 0x00009252,0x00009493,0x00009292,0x0000024a},
592 {0x00000000,0x00000000,0x00001249,0x00001249,
593 0x00009252,0x00009493,0x00009292,0x0000024a},
594 {0x00000000,0x00000000,0x00001249,0x00001249,
595 0x00009252,0x00009493,0x00009493,0x00001252},
596 {0x00000000,0x00000000,0x00001249,0x0000924a,
597 0x00009292,0x00009493,0x00009493,0x00001252},
598 {0x00000000,0x00000000,0x00001249,0x0000924a,
599 0x00009492,0x00009493,0x00009493,0x00009292},
600 {0x00000000,0x00000000,0x00001249,0x00009252,
601 0x00009492,0x0000a49b,0x00009493,0x00009292},
602 {0x00000000,0x00000000,0x0000924a,0x00009292,
603 0x0000a493,0x000124db,0x0000a49b,0x00009493},
604 {0x00000000,0x00000000,0x00000000,0x00000000,
605 0x00000000,0x00000000,0x00000000,0x00000000}
606 }
607 },
608 { /* version 4 */
609 { /* version 4, passes 0 */
610 {0x00000000,0x00000000,0x00000049,0x00000049,
611 0x00000049,0x00000049,0x0000024a,0x0000024a},
612 {0x00000000,0x00000000,0x00000249,0x00000249,
613 0x00000249,0x0000124a,0x00001252,0x00009292},
614 {0x00000000,0x00000000,0x00000249,0x00000249,
615 0x0000124a,0x00009252,0x00009292,0x00009292},
616 {0x00000000,0x00000000,0x00000249,0x00001249,
617 0x0000124a,0x00009292,0x00009493,0x00009493},
618 {0x00000000,0x00000000,0x00000249,0x00001249,
619 0x00009252,0x00009493,0x00009493,0x0000a49b},
620 {0x00000000,0x00000000,0x00000249,0x0000924a,
621 0x00009292,0x00009493,0x0000a49b,0x0000a49b},
622 {0x00000000,0x00000000,0x00001249,0x0000924a,
623 0x00009292,0x00009493,0x0000a49b,0x000124db},
624 {0x00000000,0x00000000,0x00001249,0x00009252,
625 0x00009492,0x0000a49b,0x0000a49b,0x000124db},
626 {0x00000000,0x00000000,0x00001249,0x00009292,
627 0x00009492,0x000124db,0x000124db,0x000126dc},
628 {0x00000000,0x00000000,0x00001249,0x00009292,
629 0x0000a493,0x000124db,0x000126dc,0x000126dc},
630 {0x00000000,0x00000000,0x00001249,0x00009493,
631 0x0000a493,0x000124db,0x000126dc,0x000136e4},
632 {0x00000000,0x00000000,0x00001249,0x00009493,
633 0x0000a493,0x000126dc,0x000136e4,0x000136e4},
634 {0x00000000,0x00000000,0x0000924a,0x00009493,
635 0x0001249b,0x000126dc,0x000136e4,0x000136e4},
636 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
637 0x000124db,0x000136e4,0x000136e4,0x0001b724},
638 {0x00000000,0x00000000,0x00009252,0x000124db,
639 0x000126dc,0x0001b724,0x0001b725,0x0001b925},
640 {0x00000000,0x00000000,0x00000000,0x00000000,
641 0x00000000,0x00000000,0x00000000,0x00000000}
642 },
643 { /* version 4, passes 1 */
644 {0x00000000,0x00000000,0x00000049,0x00000049,
645 0x00000049,0x00000049,0x00000049,0x00000049},
646 {0x00000000,0x00000000,0x00000249,0x00000249,
647 0x00000249,0x00000249,0x0000024a,0x00000049},
648 {0x00000000,0x00000000,0x00001249,0x00000249,
649 0x0000124a,0x0000124a,0x00001252,0x00000049},
650 {0x00000000,0x00000000,0x00001249,0x00001249,
651 0x0000124a,0x0000124a,0x00009292,0x0000024a},
652 {0x00000000,0x00000000,0x00001249,0x00001249,
653 0x00009252,0x00009292,0x00009292,0x0000024a},
654 {0x00000000,0x00000000,0x00001249,0x00001249,
655 0x00009252,0x00009292,0x0000a49b,0x0000024a},
656 {0x00000000,0x00000000,0x00001249,0x00001249,
657 0x00009292,0x00009493,0x0000a49b,0x00001252},
658 {0x00000000,0x00000000,0x00001249,0x00001249,
659 0x00009292,0x00009493,0x0000a49b,0x00001252},
660 {0x00000000,0x00000000,0x00001249,0x0000924a,
661 0x00009492,0x0000a49b,0x0000a49b,0x00001252},
662 {0x00000000,0x00000000,0x00001249,0x00009252,
663 0x00009492,0x0000a49b,0x0000a49b,0x00009292},
664 {0x00000000,0x00000000,0x00001249,0x00009292,
665 0x00009492,0x0000a49b,0x0000a49b,0x00009292},
666 {0x00000000,0x00000000,0x00001249,0x00009493,
667 0x0000a493,0x0000a49b,0x0000a49b,0x00009292},
668 {0x00000000,0x00000000,0x00001249,0x00009493,
669 0x0000a493,0x0000a49b,0x0000a49b,0x00009493},
670 {0x00000000,0x00000000,0x0000924a,0x00009493,
671 0x0000a493,0x000124db,0x0000a49b,0x00009493},
672 {0x00000000,0x00000000,0x00009252,0x0000a49b,
673 0x0001249b,0x000126dc,0x000124db,0x0000a49b},
674 {0x00000000,0x00000000,0x00000000,0x00000000,
675 0x00000000,0x00000000,0x00000000,0x00000000}
676 }
677 },
678 { /* version 5 */
679 { /* version 5, passes 0 */
680 {0x00000000,0x00000000,0x00000249,0x00000249,
681 0x00000249,0x0000124a,0x00001252,0x00009292},
682 {0x00000000,0x00000000,0x00000249,0x00001249,
683 0x0000124a,0x00009292,0x00009292,0x00009493},
684 {0x00000000,0x00000000,0x00000249,0x0000924a,
685 0x00009292,0x00009493,0x0000a49b,0x0000a49b},
686 {0x00000000,0x00000000,0x00001249,0x0000924a,
687 0x00009292,0x00009493,0x0000a49b,0x0000a49b},
688 {0x00000000,0x00000000,0x00001249,0x0000924a,
689 0x00009492,0x0000a49b,0x0000a49b,0x000124db},
690 {0x00000000,0x00000000,0x00001249,0x00009292,
691 0x00009492,0x0000a49b,0x000124db,0x000124db},
692 {0x00000000,0x00000000,0x00001249,0x00009292,
693 0x0000a493,0x000124db,0x000124db,0x000126dc},
694 {0x00000000,0x00000000,0x00001249,0x00009493,
695 0x0000a493,0x000124db,0x000126dc,0x000126dc},
696 {0x00000000,0x00000000,0x00001249,0x00009493,
697 0x0000a493,0x000126dc,0x000136e4,0x000136e4},
698 {0x00000000,0x00000000,0x00001249,0x00009493,
699 0x0001249b,0x000126dc,0x000136e4,0x000136e4},
700 {0x00000000,0x00000000,0x00001249,0x00009493,
701 0x0001249b,0x000126dc,0x000136e4,0x000136e4},
702 {0x00000000,0x00000000,0x0000924a,0x00009493,
703 0x0001249b,0x000126dc,0x0001b725,0x0001b724},
704 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
705 0x000124db,0x000126dc,0x0001b725,0x0001b724},
706 {0x00000000,0x00000000,0x00009292,0x0000a49b,
707 0x000126dc,0x000136e4,0x0001b92d,0x0001b925},
708 {0x00000000,0x00000000,0x00009492,0x000124db,
709 0x000136e4,0x0001b724,0x0001c96e,0x0001c92d},
710 {0x00000000,0x00000000,0x00000000,0x00000000,
711 0x00000000,0x00000000,0x00000000,0x00000000}
712 },
713 { /* version 5, passes 1 */
714 {0x00000000,0x00000000,0x00000249,0x00000249,
715 0x0000124a,0x00000249,0x0000024a,0x0000024a},
716 {0x00000000,0x00000000,0x00001249,0x00001249,
717 0x0000124a,0x0000124a,0x00001252,0x0000024a},
718 {0x00000000,0x00000000,0x00001249,0x00001249,
719 0x00009292,0x00009493,0x00009493,0x0000024a},
720 {0x00000000,0x00000000,0x00001249,0x00001249,
721 0x00009292,0x00009493,0x00009493,0x00001252},
722 {0x00000000,0x00000000,0x00001249,0x00001249,
723 0x00009292,0x00009493,0x0000a49b,0x00001252},
724 {0x00000000,0x00000000,0x00001249,0x0000924a,
725 0x00009492,0x00009493,0x000124db,0x00001252},
726 {0x00000000,0x00000000,0x00001249,0x00009292,
727 0x00009492,0x00009493,0x000124db,0x00009292},
728 {0x00000000,0x00000000,0x00001249,0x00009292,
729 0x00009492,0x0000a49b,0x000124db,0x00009292},
730 {0x00000000,0x00000000,0x00001249,0x00009493,
731 0x0000a493,0x0000a49b,0x000124db,0x00009292},
732 {0x00000000,0x00000000,0x00001249,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,0x00009493},
738 {0x00000000,0x00000000,0x0000924a,0x00009493,
739 0x0000a493,0x000124db,0x000124db,0x0000a49b},
740 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
741 0x000124db,0x000126dc,0x000124db,0x0000a49b},
742 {0x00000000,0x00000000,0x00009252,0x000124db,
743 0x000126dc,0x000136e4,0x000126dc,0x000124db},
744 {0x00000000,0x00000000,0x00000000,0x00000000,
745 0x00000000,0x00000000,0x00000000,0x00000000}
746 }
747 },
748 { /* version 6 */
749 { /* version 6, passes 0 */
750 {0x00000000,0x00000000,0x00000249,0x00000249,
751 0x0000124a,0x0000124a,0x00009292,0x00009292},
752 {0x00000000,0x00000000,0x00001249,0x00001249,
753 0x00009292,0x00009493,0x0000a49b,0x0000a49b},
754 {0x00000000,0x00000000,0x00001249,0x0000924a,
755 0x00009492,0x0000a49b,0x0000a49b,0x000124db},
756 {0x00000000,0x00000000,0x00001249,0x00009292,
757 0x00009492,0x000124db,0x000126dc,0x000126dc},
758 {0x00000000,0x00000000,0x00001249,0x00009493,
759 0x0000a493,0x000124db,0x000126dc,0x000126dc},
760 {0x00000000,0x00000000,0x00001249,0x00009493,
761 0x0000a493,0x000126dc,0x000136e4,0x000136e4},
762 {0x00000000,0x00000000,0x00001249,0x00009493,
763 0x0000a493,0x000126dc,0x000136e4,0x0001b724},
764 {0x00000000,0x00000000,0x00001249,0x00009493,
765 0x0001249b,0x000126dc,0x000136e4,0x0001b724},
766 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
767 0x0001249b,0x000126dc,0x000136e4,0x0001b724},
768 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
769 0x0001249b,0x000136e4,0x0001b725,0x0001b724},
770 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
771 0x000124db,0x000136e4,0x0001b725,0x0001b925},
772 {0x00000000,0x00000000,0x00009292,0x0000a49b,
773 0x000126dc,0x000136e4,0x0001b92d,0x0001b925},
774 {0x00000000,0x00000000,0x00009292,0x0000a49b,
775 0x000126dc,0x0001b724,0x0001b92d,0x0001c92d},
776 {0x00000000,0x00000000,0x00009492,0x000124db,
777 0x000126dc,0x0001b724,0x0001c96e,0x0001c92d},
778 {0x00000000,0x00000000,0x0000a492,0x000126db,
779 0x000136e4,0x0001b925,0x00025bb6,0x00024b77},
780 {0x00000000,0x00000000,0x00000000,0x00000000,
781 0x00000000,0x00000000,0x00000000,0x00000000}
782 },
783 { /* version 6, passes 1 */
784 {0x00000000,0x00000000,0x00001249,0x00000249,
785 0x0000124a,0x0000124a,0x00001252,0x00001252},
786 {0x00000000,0x00000000,0x00001249,0x00001249,
787 0x00009252,0x00009292,0x00009292,0x00001252},
788 {0x00000000,0x00000000,0x00001249,0x0000924a,
789 0x00009492,0x00009493,0x0000a49b,0x00001252},
790 {0x00000000,0x00000000,0x00001249,0x00009252,
791 0x00009492,0x0000a49b,0x0000a49b,0x00009292},
792 {0x00000000,0x00000000,0x00001249,0x00009292,
793 0x00009492,0x0000a49b,0x0000a49b,0x00009292},
794 {0x00000000,0x00000000,0x00001249,0x00009493,
795 0x0000a493,0x0000a49b,0x000126dc,0x00009292},
796 {0x00000000,0x00000000,0x0000924a,0x00009493,
797 0x0000a493,0x0000a49b,0x000126dc,0x00009493},
798 {0x00000000,0x00000000,0x0000924a,0x00009493,
799 0x0000a493,0x0000a49b,0x000126dc,0x00009493},
800 {0x00000000,0x00000000,0x0000924a,0x00009493,
801 0x0000a493,0x000124db,0x000126dc,0x00009493},
802 {0x00000000,0x00000000,0x0000924a,0x00009493,
803 0x0000a493,0x000124db,0x000126dc,0x0000a49b},
804 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
805 0x0000a493,0x000124db,0x000126dc,0x0000a49b},
806 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
807 0x0001249b,0x000126dc,0x000126dc,0x0000a49b},
808 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
809 0x000124db,0x000136e4,0x000126dc,0x000124db},
810 {0x00000000,0x00000000,0x00009492,0x0000a49b,
811 0x000136e4,0x000136e4,0x000126dc,0x000124db},
812 {0x00000000,0x00000000,0x0000a492,0x000124db,
813 0x0001b724,0x0001b724,0x000136e4,0x000126dc},
814 {0x00000000,0x00000000,0x00000000,0x00000000,
815 0x00000000,0x00000000,0x00000000,0x00000000}
816 }
817 },
818 { /* version 7 */
819 { /* version 7, passes 0 */
820 {0x00000000,0x00000000,0x00001249,0x00001249,
821 0x00009292,0x00009493,0x0000a49b,0x000124db},
822 {0x00000000,0x00000000,0x00001249,0x00009292,
823 0x0000a493,0x0000a49b,0x000124db,0x000126dc},
824 {0x00000000,0x00000000,0x00001249,0x00009493,
825 0x0000a493,0x000124db,0x000126dc,0x000136e4},
826 {0x00000000,0x00000000,0x00001249,0x00009493,
827 0x0000a493,0x000124db,0x000136e4,0x000136e4},
828 {0x00000000,0x00000000,0x00001249,0x00009493,
829 0x0001249b,0x000126dc,0x000136e4,0x000136e4},
830 {0x00000000,0x00000000,0x00001249,0x0000a49b,
831 0x0001249b,0x000126dc,0x000136e4,0x0001b724},
832 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
833 0x0001249b,0x000126dc,0x000136e4,0x0001b724},
834 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
835 0x000124db,0x000136e4,0x0001b725,0x0001b724},
836 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
837 0x000126dc,0x000136e4,0x0001b725,0x0001b925},
838 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
839 0x000126dc,0x0001b724,0x0001b92d,0x0001b925},
840 {0x00000000,0x00000000,0x00009292,0x0000a49b,
841 0x000126dc,0x0001b724,0x0001c96e,0x0001c92d},
842 {0x00000000,0x00000000,0x00009292,0x000124db,
843 0x000126dc,0x0001b724,0x0001c96e,0x0001c92d},
844 {0x00000000,0x00000000,0x00009492,0x000124db,
845 0x000136e4,0x0001b724,0x0001c96e,0x0002496e},
846 {0x00000000,0x00000000,0x00009492,0x000126db,
847 0x000136e4,0x0001b925,0x0001c96e,0x0002496e},
848 {0x00000000,0x00000000,0x0000a492,0x000136db,
849 0x0001b724,0x0002496d,0x00025bb6,0x00025bbf},
850 {0x00000000,0x00000000,0x00000000,0x00000000,
851 0x00000000,0x00000000,0x00000000,0x00000000}
852 },
853 { /* version 7, passes 1 */
854 {0x00000000,0x00000000,0x00001249,0x00001249,
855 0x00009252,0x00009292,0x00009292,0x00009292},
856 {0x00000000,0x00000000,0x00001249,0x0000924a,
857 0x00009492,0x00009493,0x00009493,0x00009292},
858 {0x00000000,0x00000000,0x00001249,0x00009493,
859 0x0000a493,0x0000a49b,0x0000a49b,0x00009292},
860 {0x00000000,0x00000000,0x0000924a,0x00009493,
861 0x0000a493,0x0000a49b,0x000124db,0x00009493},
862 {0x00000000,0x00000000,0x0000924a,0x00009493,
863 0x0000a493,0x000124db,0x000124db,0x00009493},
864 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
865 0x0000a493,0x000124db,0x000136e4,0x00009493},
866 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
867 0x0000a493,0x000124db,0x000136e4,0x0000a49b},
868 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
869 0x0001249b,0x000124db,0x000136e4,0x0000a49b},
870 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
871 0x0001249b,0x000126dc,0x000136e4,0x0000a49b},
872 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
873 0x0001249b,0x000126dc,0x000136e4,0x000124db},
874 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
875 0x000126dc,0x000136e4,0x000136e4,0x000124db},
876 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
877 0x000126dc,0x000136e4,0x000136e4,0x000124db},
878 {0x00000000,0x00000000,0x0000924a,0x000124db,
879 0x000136e4,0x000136e4,0x000136e4,0x000126dc},
880 {0x00000000,0x00000000,0x0000a492,0x000124db,
881 0x000136e4,0x0001b724,0x000136e4,0x000126dc},
882 {0x00000000,0x00000000,0x00012492,0x000126db,
883 0x0001b724,0x0001b925,0x0001b725,0x000136e4},
884 {0x00000000,0x00000000,0x00000000,0x00000000,
885 0x00000000,0x00000000,0x00000000,0x00000000}
886 }
887 },
888 { /* version 8 */
889 { /* version 8, passes 0 */
890 {0x00000000,0x00000000,0x00001249,0x00001249,
891 0x00009292,0x00009493,0x0000a49b,0x000124db},
892 {0x00000000,0x00000000,0x00001249,0x00009292,
893 0x0000a493,0x000124db,0x000126dc,0x000126dc},
894 {0x00000000,0x00000000,0x00001249,0x00009493,
895 0x0000a493,0x000124db,0x000126dc,0x000136e4},
896 {0x00000000,0x00000000,0x00001249,0x0000a49b,
897 0x0001249b,0x000126dc,0x000136e4,0x0001b724},
898 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
899 0x0001249b,0x000126dc,0x000136e4,0x0001b724},
900 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
901 0x000124db,0x000136e4,0x0001b725,0x0001b724},
902 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
903 0x000126dc,0x000136e4,0x0001b725,0x0001b925},
904 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
905 0x000126dc,0x0001b724,0x0001b92d,0x0001c92d},
906 {0x00000000,0x00000000,0x00009252,0x000124db,
907 0x000126dc,0x0001b724,0x0001b92d,0x0001c92d},
908 {0x00000000,0x00000000,0x00009292,0x000124db,
909 0x000126dc,0x0001b925,0x0001c96e,0x0001c92d},
910 {0x00000000,0x00000000,0x00009492,0x000124db,
911 0x000136e4,0x0001b925,0x0001c96e,0x0001c92d},
912 {0x00000000,0x00000000,0x00009492,0x000124db,
913 0x000136e4,0x0001b925,0x00024b76,0x00024b77},
914 {0x00000000,0x00000000,0x00009492,0x000126db,
915 0x000136e4,0x0001b925,0x00024b76,0x00025bbf},
916 {0x00000000,0x00000000,0x0000a492,0x000126db,
917 0x000136e4,0x0001c92d,0x00024b76,0x00025bbf},
918 {0x00000000,0x00000000,0x00012492,0x000136db,
919 0x0001b724,0x00024b6d,0x0002ddb6,0x0002efff},
920 {0x00000000,0x00000000,0x00000000,0x00000000,
921 0x00000000,0x00000000,0x00000000,0x00000000}
922 },
923 { /* version 8, passes 1 */
924 {0x00000000,0x00000000,0x00001249,0x00001249,
925 0x00009252,0x00009493,0x00009493,0x00009493},
926 {0x00000000,0x00000000,0x00001249,0x00009292,
927 0x0000a493,0x0000a49b,0x0000a49b,0x00009493},
928 {0x00000000,0x00000000,0x0000924a,0x00009493,
929 0x0000a493,0x0000a49b,0x000124db,0x00009493},
930 {0x00000000,0x00000000,0x0000924a,0x00009493,
931 0x0000a493,0x000124db,0x000126dc,0x0000a49b},
932 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
933 0x0000a493,0x000124db,0x000126dc,0x0000a49b},
934 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
935 0x0000a493,0x000124db,0x000136e4,0x000124db},
936 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
937 0x0001249b,0x000126dc,0x000136e4,0x000124db},
938 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
939 0x000126dc,0x000126dc,0x000136e4,0x000126dc},
940 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
941 0x000126dc,0x000136e4,0x000136e4,0x000126dc},
942 {0x00000000,0x00000000,0x0000924a,0x000124db,
943 0x000126dc,0x000136e4,0x000136e4,0x000126dc},
944 {0x00000000,0x00000000,0x0000924a,0x000124db,
945 0x000126dc,0x000136e4,0x000136e4,0x000136e4},
946 {0x00000000,0x00000000,0x00009292,0x000124db,
947 0x000136e4,0x0001b724,0x0001b725,0x000136e4},
948 {0x00000000,0x00000000,0x00009492,0x000126db,
949 0x000136e4,0x0001b925,0x0001b725,0x0001b724},
950 {0x00000000,0x00000000,0x00009492,0x000126db,
951 0x000136e4,0x0001b925,0x0001b725,0x0001b724},
952 {0x00000000,0x00000000,0x0000a492,0x000136db,
953 0x0001b724,0x0002496d,0x0001b92d,0x0001b925},
954 {0x00000000,0x00000000,0x00000000,0x00000000,
955 0x00000000,0x00000000,0x00000000,0x00000000}
956 }
957 },
958 { /* version 9 */
959 { /* version 9, passes 0 */
960 {0x00000000,0x00000000,0x00000049,0x00000049,
961 0x00000049,0x00000049,0x00000049,0x00000049},
962 {0x00000000,0x00000000,0x00000249,0x00000049,
963 0x00000249,0x00000249,0x0000024a,0x00000049},
964 {0x00000000,0x00000000,0x00000249,0x00000249,
965 0x0000124a,0x00009252,0x00001252,0x0000024a},
966 {0x00000000,0x00000000,0x00001249,0x00001249,
967 0x00009252,0x00009292,0x00009493,0x00001252},
968 {0x00000000,0x00000000,0x00001249,0x0000924a,
969 0x00009292,0x00009493,0x00009493,0x00001252},
970 {0x00000000,0x00000000,0x00001249,0x00009292,
971 0x00009492,0x0000a49b,0x0000a49b,0x00009292},
972 {0x00000000,0x00000000,0x00001249,0x00009493,
973 0x0000a493,0x000124db,0x000124db,0x00009493},
974 {0x00000000,0x00000000,0x0000924a,0x00009493,
975 0x0000a493,0x000124db,0x000126dc,0x0000a49b},
976 {0x00000000,0x00000000,0x0000924a,0x00009493,
977 0x0000a493,0x000124db,0x000126dc,0x0000a49b},
978 {0x00000000,0x00000000,0x0000924a,0x00009493,
979 0x0001249b,0x000126dc,0x000126dc,0x000124db},
980 {0x00000000,0x00000000,0x00009252,0x00009493,
981 0x000124db,0x000136e4,0x000136e4,0x000126dc},
982 {0x00000000,0x00000000,0x00009252,0x0000a49b,
983 0x000124db,0x000136e4,0x000136e4,0x000126dc},
984 {0x00000000,0x00000000,0x00009292,0x0000a49b,
985 0x000126dc,0x000136e4,0x000136e4,0x000136e4},
986 {0x00000000,0x00000000,0x00009492,0x0000a49b,
987 0x000126dc,0x0001b724,0x0001b725,0x0001b724},
988 {0x00000000,0x00000000,0x0000a492,0x000124db,
989 0x000136e4,0x0001b925,0x0001b92d,0x0001b925},
990 {0x00000000,0x00000000,0x00000000,0x00000000,
991 0x00000000,0x00000000,0x00000000,0x00000000}
992 },
993 { /* version 9, passes 1 */
994 {0x00000000,0x00000000,0x00000249,0x00000049,
995 0x00000009,0x00000009,0x00000009,0x00000009},
996 {0x00000000,0x00000000,0x00000249,0x00000249,
997 0x00000049,0x00000049,0x00000009,0x00000009},
998 {0x00000000,0x00000000,0x00001249,0x00001249,
999 0x0000124a,0x00000249,0x00000049,0x00000049},
1000 {0x00000000,0x00000000,0x00001249,0x00001249,
1001 0x0000124a,0x0000124a,0x00000049,0x00000049},
1002 {0x00000000,0x00000000,0x00001249,0x00001249,
1003 0x00009252,0x0000124a,0x0000024a,0x0000024a},
1004 {0x00000000,0x00000000,0x00001249,0x0000924a,
1005 0x00009252,0x0000124a,0x0000024a,0x0000024a},
1006 {0x00000000,0x00000000,0x00001249,0x00009292,
1007 0x00009492,0x00009252,0x00001252,0x00001252},
1008 {0x00000000,0x00000000,0x00001249,0x00009493,
1009 0x0000a493,0x00009292,0x00009292,0x00001252},
1010 {0x00000000,0x00000000,0x0000924a,0x00009493,
1011 0x0000a493,0x00009292,0x00009292,0x00009292},
1012 {0x00000000,0x00000000,0x0000924a,0x00009493,
1013 0x0000a493,0x00009493,0x00009493,0x00009292},
1014 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1015 0x0000a493,0x0000a49b,0x00009493,0x00009493},
1016 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1017 0x0000a493,0x0000a49b,0x0000a49b,0x00009493},
1018 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1019 0x0001249b,0x000124db,0x0000a49b,0x0000a49b},
1020 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1021 0x000136e4,0x000126dc,0x000124db,0x0000a49b},
1022 {0x00000000,0x00000000,0x00009252,0x000124db,
1023 0x0001b724,0x000136e4,0x000126dc,0x000124db},
1024 {0x00000000,0x00000000,0x00000000,0x00000000,
1025 0x00000000,0x00000000,0x00000000,0x00000000}
1026 }
1027 },
1028 { /* version 10 */
1029 { /* version 10, passes 0 */
1030 {0x00000000,0x00000000,0x00000249,0x00000249,
1031 0x00000249,0x00000249,0x0000024a,0x0000024a},
1032 {0x00000000,0x00000000,0x00000249,0x00001249,
1033 0x00009252,0x00009292,0x00009292,0x0000024a},
1034 {0x00000000,0x00000000,0x00001249,0x00001249,
1035 0x00009252,0x00009292,0x00009292,0x00001252},
1036 {0x00000000,0x00000000,0x00001249,0x0000924a,
1037 0x00009492,0x00009493,0x0000a49b,0x00009292},
1038 {0x00000000,0x00000000,0x00001249,0x00009292,
1039 0x00009492,0x000124db,0x000124db,0x00009292},
1040 {0x00000000,0x00000000,0x00001249,0x00009493,
1041 0x0000a493,0x000124db,0x000124db,0x00009493},
1042 {0x00000000,0x00000000,0x00001249,0x00009493,
1043 0x0000a493,0x000124db,0x000126dc,0x0000a49b},
1044 {0x00000000,0x00000000,0x0000924a,0x00009493,
1045 0x0000a493,0x000124db,0x000126dc,0x000124db},
1046 {0x00000000,0x00000000,0x0000924a,0x00009493,
1047 0x0001249b,0x000126dc,0x000126dc,0x000124db},
1048 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1049 0x000124db,0x000126dc,0x000136e4,0x000126dc},
1050 {0x00000000,0x00000000,0x00009252,0x0000a49b,
1051 0x000124db,0x000136e4,0x000136e4,0x000136e4},
1052 {0x00000000,0x00000000,0x00009292,0x0000a49b,
1053 0x000126dc,0x000136e4,0x000136e4,0x000136e4},
1054 {0x00000000,0x00000000,0x00009492,0x0000a49b,
1055 0x000126dc,0x0001b724,0x0001b92d,0x0001b724},
1056 {0x00000000,0x00000000,0x00009492,0x000124db,
1057 0x000126dc,0x0001b925,0x0001b92d,0x0001b925},
1058 {0x00000000,0x00000000,0x0000a492,0x000126db,
1059 0x000136e4,0x0002496d,0x0001c96e,0x0001c92d},
1060 {0x00000000,0x00000000,0x00000000,0x00000000,
1061 0x00000000,0x00000000,0x00000000,0x00000000}
1062 },
1063 { /* version 10, passes 1 */
1064 {0x00000000,0x00000000,0x00000249,0x00000249,
1065 0x00000049,0x00000049,0x00000049,0x00000049},
1066 {0x00000000,0x00000000,0x00001249,0x00001249,
1067 0x0000124a,0x00000249,0x00000049,0x00000049},
1068 {0x00000000,0x00000000,0x00001249,0x00001249,
1069 0x0000124a,0x00009252,0x0000024a,0x00000049},
1070 {0x00000000,0x00000000,0x00001249,0x00001249,
1071 0x00009252,0x00009493,0x0000024a,0x0000024a},
1072 {0x00000000,0x00000000,0x00001249,0x00009252,
1073 0x00009492,0x00009493,0x00001252,0x0000024a},
1074 {0x00000000,0x00000000,0x00001249,0x00009292,
1075 0x00009492,0x00009493,0x00001252,0x00001252},
1076 {0x00000000,0x00000000,0x0000924a,0x00009493,
1077 0x00009492,0x00009493,0x00009292,0x00001252},
1078 {0x00000000,0x00000000,0x0000924a,0x00009493,
1079 0x0000a493,0x00009493,0x00009292,0x00009292},
1080 {0x00000000,0x00000000,0x0000924a,0x00009493,
1081 0x0000a493,0x0000a49b,0x00009493,0x00009292},
1082 {0x00000000,0x00000000,0x0000924a,0x00009493,
1083 0x0000a493,0x0000a49b,0x00009493,0x00009292},
1084 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1085 0x0000a493,0x000124db,0x0000a49b,0x00009493},
1086 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1087 0x0000a493,0x000124db,0x0000a49b,0x00009493},
1088 {0x00000000,0x00000000,0x0000924a,0x000124db,
1089 0x000136e4,0x000126dc,0x000124db,0x0000a49b},
1090 {0x00000000,0x00000000,0x0000924a,0x000124db,
1091 0x000136e4,0x000126dc,0x000124db,0x0000a49b},
1092 {0x00000000,0x00000000,0x00009252,0x000126db,
1093 0x0001b724,0x000136e4,0x000126dc,0x000124db},
1094 {0x00000000,0x00000000,0x00000000,0x00000000,
1095 0x00000000,0x00000000,0x00000000,0x00000000}
1096 }
1097 },
1098 { /* version 11 */
1099 { /* version 11, passes 0 */
1100 {0x00000000,0x00000000,0x00000249,0x00000249,
1101 0x00000249,0x00000249,0x00001252,0x00001252},
1102 {0x00000000,0x00000000,0x00001249,0x00001249,
1103 0x00009252,0x00009292,0x00009292,0x00001252},
1104 {0x00000000,0x00000000,0x00001249,0x0000924a,
1105 0x00009492,0x0000a49b,0x0000a49b,0x00009292},
1106 {0x00000000,0x00000000,0x00001249,0x00009493,
1107 0x0000a493,0x0000a49b,0x000124db,0x00009493},
1108 {0x00000000,0x00000000,0x00001249,0x00009493,
1109 0x0000a493,0x000124db,0x000126dc,0x00009493},
1110 {0x00000000,0x00000000,0x0000924a,0x00009493,
1111 0x0000a493,0x000126dc,0x000126dc,0x0000a49b},
1112 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1113 0x0001249b,0x000126dc,0x000136e4,0x000124db},
1114 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1115 0x000126dc,0x000136e4,0x000136e4,0x000126dc},
1116 {0x00000000,0x00000000,0x00009292,0x0000a49b,
1117 0x000126dc,0x000136e4,0x000136e4,0x000126dc},
1118 {0x00000000,0x00000000,0x00009292,0x0000a49b,
1119 0x000126dc,0x0001b724,0x0001b725,0x000136e4},
1120 {0x00000000,0x00000000,0x00009292,0x0000a49b,
1121 0x000136e4,0x0001b724,0x0001b92d,0x0001b724},
1122 {0x00000000,0x00000000,0x00009492,0x0000a49b,
1123 0x000136e4,0x0001b724,0x0001b92d,0x0001b724},
1124 {0x00000000,0x00000000,0x00009492,0x000124db,
1125 0x000136e4,0x0001b925,0x0001c96e,0x0001b925},
1126 {0x00000000,0x00000000,0x00009492,0x000124db,
1127 0x0001b724,0x0001b925,0x0001c96e,0x0001c92d},
1128 {0x00000000,0x00000000,0x0000a492,0x000126db,
1129 0x0001c924,0x0002496d,0x00025bb6,0x00024b77},
1130 {0x00000000,0x00000000,0x00000000,0x00000000,
1131 0x00000000,0x00000000,0x00000000,0x00000000}
1132 },
1133 { /* version 11, passes 1 */
1134 {0x00000000,0x00000000,0x00001249,0x00000249,
1135 0x00000249,0x00000249,0x0000024a,0x0000024a},
1136 {0x00000000,0x00000000,0x00001249,0x00001249,
1137 0x0000124a,0x0000124a,0x0000024a,0x0000024a},
1138 {0x00000000,0x00000000,0x00001249,0x0000924a,
1139 0x00009252,0x00009252,0x0000024a,0x0000024a},
1140 {0x00000000,0x00000000,0x00001249,0x00009292,
1141 0x00009492,0x0000a49b,0x00001252,0x00001252},
1142 {0x00000000,0x00000000,0x0000924a,0x00009493,
1143 0x0000a493,0x0000a49b,0x00001252,0x00001252},
1144 {0x00000000,0x00000000,0x0000924a,0x00009493,
1145 0x0000a493,0x0000a49b,0x00009292,0x00001252},
1146 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1147 0x0000a493,0x0000a49b,0x00009292,0x00009292},
1148 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1149 0x0000a493,0x0000a49b,0x00009493,0x00009292},
1150 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1151 0x0001249b,0x000124db,0x00009493,0x00009292},
1152 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1153 0x0001249b,0x000124db,0x00009493,0x00009493},
1154 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1155 0x000124db,0x000124db,0x0000a49b,0x00009493},
1156 {0x00000000,0x00000000,0x0000924a,0x000124db,
1157 0x000126dc,0x000126dc,0x0000a49b,0x00009493},
1158 {0x00000000,0x00000000,0x0000924a,0x000124db,
1159 0x000136e4,0x000126dc,0x000124db,0x0000a49b},
1160 {0x00000000,0x00000000,0x00009292,0x000124db,
1161 0x000136e4,0x000126dc,0x000124db,0x0000a49b},
1162 {0x00000000,0x00000000,0x00009492,0x000126db,
1163 0x0001b724,0x000136e4,0x000126dc,0x000124db},
1164 {0x00000000,0x00000000,0x00000000,0x00000000,
1165 0x00000000,0x00000000,0x00000000,0x00000000}
1166 }
1167 },
1168 { /* version 12 */
1169 { /* version 12, passes 0 */
1170 {0x00000000,0x00000000,0x00001249,0x00001249,
1171 0x00009252,0x00009292,0x00009493,0x00009493},
1172 {0x00000000,0x00000000,0x00001249,0x00009292,
1173 0x0000a493,0x0000a49b,0x0000a49b,0x00009493},
1174 {0x00000000,0x00000000,0x00001249,0x00009493,
1175 0x0000a493,0x000124db,0x000124db,0x0000a49b},
1176 {0x00000000,0x00000000,0x0000924a,0x00009493,
1177 0x0000a493,0x000126dc,0x000126dc,0x0000a49b},
1178 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1179 0x0001249b,0x000126dc,0x000136e4,0x000124db},
1180 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1181 0x000126dc,0x000136e4,0x000136e4,0x000126dc},
1182 {0x00000000,0x00000000,0x00009292,0x0000a49b,
1183 0x000126dc,0x0001b724,0x0001b725,0x000126dc},
1184 {0x00000000,0x00000000,0x00009292,0x0000a49b,
1185 0x000136e4,0x0001b724,0x0001b92d,0x000136e4},
1186 {0x00000000,0x00000000,0x00009492,0x0000a49b,
1187 0x000136e4,0x0001b724,0x0001b92d,0x0001b724},
1188 {0x00000000,0x00000000,0x00009492,0x000124db,
1189 0x000136e4,0x0001b724,0x0001b92d,0x0001b724},
1190 {0x00000000,0x00000000,0x00009492,0x000124db,
1191 0x000136e4,0x0001b925,0x0001b92d,0x0001b925},
1192 {0x00000000,0x00000000,0x00009492,0x000124db,
1193 0x0001b724,0x0001b925,0x0001c96e,0x0001c92d},
1194 {0x00000000,0x00000000,0x0000a492,0x000124db,
1195 0x0001b724,0x0001c92d,0x0001c96e,0x0001c92d},
1196 {0x00000000,0x00000000,0x0000a492,0x000124db,
1197 0x0001b724,0x0001c92d,0x00024b76,0x0002496e},
1198 {0x00000000,0x00000000,0x00012492,0x000126db,
1199 0x0001c924,0x00024b6d,0x0002ddb6,0x00025bbf},
1200 {0x00000000,0x00000000,0x00000000,0x00000000,
1201 0x00000000,0x00000000,0x00000000,0x00000000}
1202 },
1203 { /* version 12, passes 1 */
1204 {0x00000000,0x00000000,0x00001249,0x00001249,
1205 0x0000124a,0x0000124a,0x00001252,0x00001252},
1206 {0x00000000,0x00000000,0x00001249,0x00009292,
1207 0x00009492,0x00009252,0x00001252,0x00001252},
1208 {0x00000000,0x00000000,0x0000924a,0x00009493,
1209 0x0000a493,0x00009292,0x00001252,0x00001252},
1210 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1211 0x0000a493,0x0000a49b,0x00009292,0x00009292},
1212 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1213 0x0000a493,0x0000a49b,0x00009292,0x00009292},
1214 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1215 0x0001249b,0x0000a49b,0x00009493,0x00009292},
1216 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1217 0x000124db,0x000124db,0x00009493,0x00009493},
1218 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1219 0x000124db,0x000124db,0x0000a49b,0x00009493},
1220 {0x00000000,0x00000000,0x0000924a,0x000124db,
1221 0x000126dc,0x000124db,0x0000a49b,0x00009493},
1222 {0x00000000,0x00000000,0x0000924a,0x000124db,
1223 0x000126dc,0x000126dc,0x0000a49b,0x0000a49b},
1224 {0x00000000,0x00000000,0x0000924a,0x000124db,
1225 0x000136e4,0x000126dc,0x000124db,0x0000a49b},
1226 {0x00000000,0x00000000,0x00009492,0x000126db,
1227 0x000136e4,0x000126dc,0x000124db,0x0000a49b},
1228 {0x00000000,0x00000000,0x00009492,0x000126db,
1229 0x0001b724,0x000136e4,0x000126dc,0x000124db},
1230 {0x00000000,0x00000000,0x00009492,0x000126db,
1231 0x0001b724,0x000136e4,0x000126dc,0x000124db},
1232 {0x00000000,0x00000000,0x0000a492,0x000136db,
1233 0x0001c924,0x0001b724,0x000136e4,0x000126dc},
1234 {0x00000000,0x00000000,0x00000000,0x00000000,
1235 0x00000000,0x00000000,0x00000000,0x00000000}
1236 }
1237 },
1238 { /* version 13 */
1239 { /* version 13, passes 0 */
1240 {0x00000000,0x00000000,0x00001249,0x00001249,
1241 0x00009252,0x00009292,0x00009493,0x00009493},
1242 {0x00000000,0x00000000,0x00001249,0x00009493,
1243 0x0000a493,0x000124db,0x000126dc,0x00009493},
1244 {0x00000000,0x00000000,0x00001249,0x0000a49b,
1245 0x0001249b,0x000126dc,0x000126dc,0x0000a49b},
1246 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1247 0x0001249b,0x000126dc,0x000136e4,0x0000a49b},
1248 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1249 0x000126dc,0x000136e4,0x0001b725,0x000124db},
1250 {0x00000000,0x00000000,0x00009292,0x0000a49b,
1251 0x000136e4,0x0001b724,0x0001b725,0x000126dc},
1252 {0x00000000,0x00000000,0x00009292,0x000124db,
1253 0x000136e4,0x0001b724,0x0001b725,0x000126dc},
1254 {0x00000000,0x00000000,0x00009492,0x000124db,
1255 0x000136e4,0x0001b724,0x0001c96e,0x000136e4},
1256 {0x00000000,0x00000000,0x00009492,0x000124db,
1257 0x000136e4,0x0001c92d,0x0001c96e,0x0001b724},
1258 {0x00000000,0x00000000,0x0000a492,0x000124db,
1259 0x000136e4,0x0001c92d,0x0001c96e,0x0001b724},
1260 {0x00000000,0x00000000,0x0000a492,0x000124db,
1261 0x0001b724,0x0001c92d,0x0001c96e,0x0001b925},
1262 {0x00000000,0x00000000,0x0000a492,0x000126db,
1263 0x0001b724,0x0001c92d,0x00024b76,0x0001c92d},
1264 {0x00000000,0x00000000,0x0000a492,0x000126db,
1265 0x0001b924,0x0001c92d,0x00024b76,0x0001c92d},
1266 {0x00000000,0x00000000,0x0000a492,0x000126db,
1267 0x0001b924,0x0001c92d,0x00024b76,0x0002496e},
1268 {0x00000000,0x00000000,0x00012492,0x000136db,
1269 0x00024924,0x00024b6d,0x0002ddb6,0x00025bbf},
1270 {0x00000000,0x00000000,0x00000000,0x00000000,
1271 0x00000000,0x00000000,0x00000000,0x00000000}
1272 },
1273 { /* version 13, passes 1 */
1274 {0x00000000,0x00000000,0x00001249,0x00001249,
1275 0x0000124a,0x0000124a,0x00001252,0x00001252},
1276 {0x00000000,0x00000000,0x0000924a,0x00009493,
1277 0x00009492,0x00009292,0x00001252,0x00001252},
1278 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1279 0x0000a493,0x0000a49b,0x00001252,0x00001252},
1280 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1281 0x0000a493,0x0000a49b,0x00009292,0x00009292},
1282 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1283 0x0000a493,0x0000a49b,0x00009292,0x00009292},
1284 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1285 0x000126dc,0x0000a49b,0x00009493,0x00009292},
1286 {0x00000000,0x00000000,0x0000924a,0x000124db,
1287 0x000126dc,0x000124db,0x00009493,0x00009493},
1288 {0x00000000,0x00000000,0x0000924a,0x000124db,
1289 0x000136e4,0x000124db,0x0000a49b,0x00009493},
1290 {0x00000000,0x00000000,0x0000924a,0x000136db,
1291 0x0001b724,0x000124db,0x0000a49b,0x00009493},
1292 {0x00000000,0x00000000,0x0000924a,0x000136db,
1293 0x0001b724,0x000126dc,0x0000a49b,0x0000a49b},
1294 {0x00000000,0x00000000,0x00009292,0x000136db,
1295 0x0001b724,0x000126dc,0x000124db,0x0000a49b},
1296 {0x00000000,0x00000000,0x00009492,0x000136db,
1297 0x0001b724,0x000126dc,0x000124db,0x0000a49b},
1298 {0x00000000,0x00000000,0x0000a492,0x000136db,
1299 0x0001b724,0x000136e4,0x000126dc,0x000124db},
1300 {0x00000000,0x00000000,0x0000a492,0x000136db,
1301 0x0001b724,0x000136e4,0x000126dc,0x000124db},
1302 {0x00000000,0x00000000,0x00012492,0x0001b6db,
1303 0x0001c924,0x0001b724,0x000136e4,0x000126dc},
1304 {0x00000000,0x00000000,0x00000000,0x00000000,
1305 0x00000000,0x00000000,0x00000000,0x00000000}
1306 }
1307 },
1308 { /* version 14 */
1309 { /* version 14, passes 0 */
1310 {0x00000000,0x00000000,0x00001249,0x0000924a,
1311 0x00009292,0x00009493,0x00009493,0x00009493},
1312 {0x00000000,0x00000000,0x00001249,0x0000a49b,
1313 0x0000a493,0x000124db,0x000126dc,0x00009493},
1314 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1315 0x0001249b,0x000126dc,0x000136e4,0x0000a49b},
1316 {0x00000000,0x00000000,0x0000924a,0x000124db,
1317 0x000126dc,0x000136e4,0x0001b725,0x000124db},
1318 {0x00000000,0x00000000,0x00009292,0x000124db,
1319 0x000126dc,0x0001b724,0x0001b92d,0x000126dc},
1320 {0x00000000,0x00000000,0x00009492,0x000124db,
1321 0x000136e4,0x0001b724,0x0001b92d,0x000126dc},
1322 {0x00000000,0x00000000,0x00009492,0x000124db,
1323 0x000136e4,0x0001c92d,0x0001c96e,0x000136e4},
1324 {0x00000000,0x00000000,0x00009492,0x000124db,
1325 0x0001b724,0x0001c92d,0x0001c96e,0x0001b724},
1326 {0x00000000,0x00000000,0x0000a492,0x000124db,
1327 0x0001b724,0x0001c92d,0x00024b76,0x0001b925},
1328 {0x00000000,0x00000000,0x0000a492,0x000126db,
1329 0x0001b724,0x0001c92d,0x00024b76,0x0001c92d},
1330 {0x00000000,0x00000000,0x0000a492,0x000126db,
1331 0x0001b724,0x0001c92d,0x00024b76,0x0001c92d},
1332 {0x00000000,0x00000000,0x0000a492,0x000136db,
1333 0x0001b724,0x0001c92d,0x00024b76,0x0002496e},
1334 {0x00000000,0x00000000,0x0000a492,0x000136db,
1335 0x0001b924,0x0002496d,0x00024b76,0x00024b77},
1336 {0x00000000,0x00000000,0x0000a492,0x000136db,
1337 0x0001b924,0x00024b6d,0x0002ddb6,0x00025bbf},
1338 {0x00000000,0x00000000,0x00012492,0x0001b6db,
1339 0x00024924,0x0002db6d,0x00036db6,0x0002efff},
1340 {0x00000000,0x00000000,0x00000000,0x00000000,
1341 0x00000000,0x00000000,0x00000000,0x00000000}
1342 },
1343 { /* version 14, passes 1 */
1344 {0x00000000,0x00000000,0x00001249,0x00001249,
1345 0x0000124a,0x0000124a,0x00001252,0x00001252},
1346 {0x00000000,0x00000000,0x0000924a,0x00009493,
1347 0x0000a493,0x00009292,0x00001252,0x00001252},
1348 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1349 0x0000a493,0x0000a49b,0x00001252,0x00001252},
1350 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1351 0x0001249b,0x000136e4,0x00009292,0x00009292},
1352 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1353 0x0001249b,0x000136e4,0x00009292,0x00009292},
1354 {0x00000000,0x00000000,0x0000924a,0x000124db,
1355 0x000136e4,0x000136e4,0x00009493,0x00009292},
1356 {0x00000000,0x00000000,0x00009492,0x000136db,
1357 0x0001b724,0x000136e4,0x00009493,0x00009493},
1358 {0x00000000,0x00000000,0x00009492,0x000136db,
1359 0x0001b724,0x000136e4,0x0000a49b,0x00009493},
1360 {0x00000000,0x00000000,0x00009492,0x000136db,
1361 0x0001b724,0x000136e4,0x0000a49b,0x00009493},
1362 {0x00000000,0x00000000,0x00009492,0x000136db,
1363 0x0001b724,0x000136e4,0x0000a49b,0x0000a49b},
1364 {0x00000000,0x00000000,0x0000a492,0x000136db,
1365 0x0001b724,0x000136e4,0x000124db,0x0000a49b},
1366 {0x00000000,0x00000000,0x0000a492,0x000136db,
1367 0x0001b724,0x000136e4,0x000124db,0x0000a49b},
1368 {0x00000000,0x00000000,0x0000a492,0x000136db,
1369 0x0001b724,0x000136e4,0x000126dc,0x000124db},
1370 {0x00000000,0x00000000,0x0000a492,0x000136db,
1371 0x0001b724,0x000136e4,0x000126dc,0x000124db},
1372 {0x00000000,0x00000000,0x00012492,0x0001b6db,
1373 0x0001c924,0x0001b724,0x000136e4,0x000126dc},
1374 {0x00000000,0x00000000,0x00000000,0x00000000,
1375 0x00000000,0x00000000,0x00000000,0x00000000}
1376 }
1377 },
1378 { /* version 15 */
1379 { /* version 15, passes 0 */
1380 {0x00000000,0x00000000,0x00001249,0x00009493,
1381 0x0000a493,0x0000a49b,0x000124db,0x000124db},
1382 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1383 0x0001249b,0x000126dc,0x000136e4,0x000124db},
1384 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1385 0x000126dc,0x0001b724,0x0001b725,0x000126dc},
1386 {0x00000000,0x00000000,0x0000924a,0x000124db,
1387 0x000136e4,0x0001b724,0x0001b92d,0x000126dc},
1388 {0x00000000,0x00000000,0x00009492,0x000124db,
1389 0x000136e4,0x0001b925,0x0001c96e,0x000136e4},
1390 {0x00000000,0x00000000,0x00009492,0x000124db,
1391 0x0001b724,0x0001c92d,0x0001c96e,0x0001b724},
1392 {0x00000000,0x00000000,0x0000a492,0x000124db,
1393 0x0001b724,0x0001c92d,0x0001c96e,0x0001b724},
1394 {0x00000000,0x00000000,0x0000a492,0x000126db,
1395 0x0001b724,0x0001c92d,0x0001c96e,0x0001b925},
1396 {0x00000000,0x00000000,0x0000a492,0x000126db,
1397 0x0001b924,0x0001c92d,0x00024b76,0x0001c92d},
1398 {0x00000000,0x00000000,0x0000a492,0x000136db,
1399 0x0001b924,0x0001c92d,0x00024b76,0x0001c92d},
1400 {0x00000000,0x00000000,0x0000a492,0x000136db,
1401 0x0001b924,0x0002496d,0x00024b76,0x0002496e},
1402 {0x00000000,0x00000000,0x0000a492,0x000136db,
1403 0x0001c924,0x0002496d,0x00025bb6,0x00024b77},
1404 {0x00000000,0x00000000,0x0000a492,0x000136db,
1405 0x0001c924,0x00024b6d,0x00025bb6,0x00024b77},
1406 {0x00000000,0x00000000,0x00012492,0x000136db,
1407 0x0001c924,0x00024b6d,0x0002ddb6,0x00025bbf},
1408 {0x00000000,0x00000000,0x00012492,0x0001b6db,
1409 0x00024924,0x0002db6d,0x00036db6,0x0002efff},
1410 {0x00000000,0x00000000,0x00000000,0x00000000,
1411 0x00000000,0x00000000,0x00000000,0x00000000}
1412 },
1413 { /* version 15, passes 1 */
1414 {0x00000000,0x00000000,0x0000924a,0x0000924a,
1415 0x00009292,0x00009292,0x00009292,0x00009292},
1416 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1417 0x0000a493,0x000124db,0x00009292,0x00009292},
1418 {0x00000000,0x00000000,0x0000924a,0x000124db,
1419 0x000124db,0x0001b724,0x00009493,0x00009493},
1420 {0x00000000,0x00000000,0x0000924a,0x000124db,
1421 0x000126dc,0x0001b724,0x00009493,0x00009493},
1422 {0x00000000,0x00000000,0x0000924a,0x000124db,
1423 0x000136e4,0x0001b724,0x0000a49b,0x0000a49b},
1424 {0x00000000,0x00000000,0x00009292,0x000136db,
1425 0x0001b724,0x0001b724,0x0000a49b,0x0000a49b},
1426 {0x00000000,0x00000000,0x00009492,0x000136db,
1427 0x0001c924,0x0001b724,0x000124db,0x000124db},
1428 {0x00000000,0x00000000,0x00009492,0x000136db,
1429 0x0001c924,0x0001b724,0x000124db,0x000124db},
1430 {0x00000000,0x00000000,0x0000a492,0x000136db,
1431 0x0001c924,0x0001b724,0x000126dc,0x000126dc},
1432 {0x00000000,0x00000000,0x0000a492,0x000136db,
1433 0x0001c924,0x0001b925,0x000126dc,0x000126dc},
1434 {0x00000000,0x00000000,0x0000a492,0x000136db,
1435 0x0001c924,0x0001b925,0x000136e4,0x000136e4},
1436 {0x00000000,0x00000000,0x0000a492,0x000136db,
1437 0x0001c924,0x0001b925,0x000136e4,0x000136e4},
1438 {0x00000000,0x00000000,0x0000a492,0x000136db,
1439 0x0001c924,0x0001b925,0x0001b725,0x0001b724},
1440 {0x00000000,0x00000000,0x00012492,0x000136db,
1441 0x0001c924,0x0001b925,0x0001b725,0x0001b724},
1442 {0x00000000,0x00000000,0x00012492,0x0001b6db,
1443 0x00024924,0x0002496d,0x0001b92d,0x0001b925},
1444 {0x00000000,0x00000000,0x00000000,0x00000000,
1445 0x00000000,0x00000000,0x00000000,0x00000000}
1446 }
1447 }
1448};
diff --git a/drivers/media/video/pwc/pwc-timon.h b/drivers/media/video/pwc/pwc-timon.h
new file mode 100644
index 00000000000..a6e22224c95
--- /dev/null
+++ b/drivers/media/video/pwc/pwc-timon.h
@@ -0,0 +1,63 @@
1/* Linux driver for Philips webcam
2 (C) 2004-2006 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 <media/pwc-ioctl.h>
46
47#define PWC_FPS_MAX_TIMON 6
48
49struct Timon_table_entry
50{
51 char alternate; /* USB alternate interface */
52 unsigned short packetsize; /* Normal packet size */
53 unsigned short bandlength; /* Bandlength when decompressing */
54 unsigned char mode[13]; /* precomputed mode settings for cam */
55};
56
57extern const struct Timon_table_entry Timon_table[PSZ_MAX][PWC_FPS_MAX_TIMON][4];
58extern const unsigned int TimonRomTable [16][2][16][8];
59extern const unsigned int Timon_fps_vector[PWC_FPS_MAX_TIMON];
60
61#endif
62
63
diff --git a/drivers/media/video/pwc/pwc-uncompress.c b/drivers/media/video/pwc/pwc-uncompress.c
new file mode 100644
index 00000000000..51265092bd3
--- /dev/null
+++ b/drivers/media/video/pwc/pwc-uncompress.c
@@ -0,0 +1,133 @@
1/* Linux driver for Philips webcam
2 Decompression frontend.
3 (C) 1999-2003 Nemosoft Unv.
4 (C) 2004-2006 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 vim: set ts=8:
27*/
28
29#include <asm/current.h>
30#include <asm/types.h>
31
32#include "pwc.h"
33#include "pwc-dec1.h"
34#include "pwc-dec23.h"
35
36int pwc_decompress(struct pwc_device *pdev, struct pwc_frame_buf *fbuf)
37{
38 int n, line, col, stride;
39 void *yuv, *image;
40 u16 *src;
41 u16 *dsty, *dstu, *dstv;
42
43 image = vb2_plane_vaddr(&fbuf->vb, 0);
44
45 yuv = fbuf->data + pdev->frame_header_size; /* Skip header */
46
47 /* Raw format; that's easy... */
48 if (pdev->pixfmt != V4L2_PIX_FMT_YUV420)
49 {
50 struct pwc_raw_frame *raw_frame = image;
51 raw_frame->type = cpu_to_le16(pdev->type);
52 raw_frame->vbandlength = cpu_to_le16(pdev->vbandlength);
53 /* cmd_buf is always 4 bytes, but sometimes, only the
54 * first 3 bytes is filled (Nala case). We can
55 * determine this using the type of the webcam */
56 memcpy(raw_frame->cmd, pdev->cmd_buf, 4);
57 memcpy(raw_frame+1, yuv, pdev->frame_size);
58 vb2_set_plane_payload(&fbuf->vb, 0,
59 pdev->frame_size + sizeof(struct pwc_raw_frame));
60 return 0;
61 }
62
63 vb2_set_plane_payload(&fbuf->vb, 0, pdev->view.size);
64
65 if (pdev->vbandlength == 0) {
66 /* Uncompressed mode.
67 * We copy the data into the output buffer, using the viewport
68 * size (which may be larger than the image size).
69 * Unfortunately we have to do a bit of byte stuffing to get
70 * the desired output format/size.
71 *
72 * We do some byte shuffling here to go from the
73 * native format to YUV420P.
74 */
75 src = (u16 *)yuv;
76 n = pdev->view.x * pdev->view.y;
77
78 /* offset in Y plane */
79 stride = pdev->view.x * pdev->offset.y + pdev->offset.x;
80 dsty = (u16 *)(image + stride);
81
82 /* offsets in U/V planes */
83 stride = pdev->view.x * pdev->offset.y / 4 + pdev->offset.x / 2;
84 dstu = (u16 *)(image + n + stride);
85 dstv = (u16 *)(image + n + n / 4 + stride);
86
87 /* increment after each line */
88 stride = (pdev->view.x - pdev->image.x) / 2; /* u16 is 2 bytes */
89
90 for (line = 0; line < pdev->image.y; line++) {
91 for (col = 0; col < pdev->image.x; col += 4) {
92 *dsty++ = *src++;
93 *dsty++ = *src++;
94 if (line & 1)
95 *dstv++ = *src++;
96 else
97 *dstu++ = *src++;
98 }
99 dsty += stride;
100 if (line & 1)
101 dstv += (stride >> 1);
102 else
103 dstu += (stride >> 1);
104 }
105
106 return 0;
107 }
108
109 /*
110 * Compressed;
111 * the decompressor routines will write the data in planar format
112 * immediately.
113 */
114 if (pdev->vsize == PSZ_VGA && pdev->vframes == 5 && pdev->vsnapshot) {
115 PWC_ERROR("Mode Bayer is not supported for now\n");
116 /* flags |= PWCX_FLAG_BAYER; */
117 return -ENXIO; /* No such device or address: missing decompressor */
118 }
119
120 if (DEVICE_USE_CODEC1(pdev->type)) {
121
122 /* TODO & FIXME */
123 PWC_ERROR("This chipset is not supported for now\n");
124 return -ENXIO; /* No such device or address: missing decompressor */
125
126 } else {
127 pwc_dec23_decompress(pdev, yuv, image, PWCX_FLAG_PLANAR);
128 }
129 return 0;
130}
131
132
133/* vim: set cino= formatoptions=croql cindent shiftwidth=8 tabstop=8: */
diff --git a/drivers/media/video/pwc/pwc-v4l.c b/drivers/media/video/pwc/pwc-v4l.c
new file mode 100644
index 00000000000..8c70e64444e
--- /dev/null
+++ b/drivers/media/video/pwc/pwc-v4l.c
@@ -0,0 +1,1131 @@
1/* Linux driver for Philips webcam
2 USB and Video4Linux interface part.
3 (C) 1999-2004 Nemosoft Unv.
4 (C) 2004-2006 Luc Saillard (luc@saillard.org)
5 (C) 2011 Hans de Goede <hdegoede@redhat.com>
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
29#include <linux/errno.h>
30#include <linux/init.h>
31#include <linux/mm.h>
32#include <linux/module.h>
33#include <linux/poll.h>
34#include <linux/vmalloc.h>
35#include <linux/jiffies.h>
36#include <asm/io.h>
37
38#include "pwc.h"
39
40#define PWC_CID_CUSTOM(ctrl) ((V4L2_CID_USER_BASE | 0xf000) + custom_ ## ctrl)
41
42static int pwc_g_volatile_ctrl(struct v4l2_ctrl *ctrl);
43static int pwc_s_ctrl(struct v4l2_ctrl *ctrl);
44
45static const struct v4l2_ctrl_ops pwc_ctrl_ops = {
46 .g_volatile_ctrl = pwc_g_volatile_ctrl,
47 .s_ctrl = pwc_s_ctrl,
48};
49
50enum { awb_indoor, awb_outdoor, awb_fl, awb_manual, awb_auto };
51enum { custom_autocontour, custom_contour, custom_noise_reduction,
52 custom_save_user, custom_restore_user, custom_restore_factory };
53
54const char * const pwc_auto_whitebal_qmenu[] = {
55 "Indoor (Incandescant Lighting) Mode",
56 "Outdoor (Sunlight) Mode",
57 "Indoor (Fluorescent Lighting) Mode",
58 "Manual Mode",
59 "Auto Mode",
60 NULL
61};
62
63static const struct v4l2_ctrl_config pwc_auto_white_balance_cfg = {
64 .ops = &pwc_ctrl_ops,
65 .id = V4L2_CID_AUTO_WHITE_BALANCE,
66 .type = V4L2_CTRL_TYPE_MENU,
67 .max = awb_auto,
68 .qmenu = pwc_auto_whitebal_qmenu,
69};
70
71static const struct v4l2_ctrl_config pwc_autocontour_cfg = {
72 .ops = &pwc_ctrl_ops,
73 .id = PWC_CID_CUSTOM(autocontour),
74 .type = V4L2_CTRL_TYPE_BOOLEAN,
75 .name = "Auto contour",
76 .min = 0,
77 .max = 1,
78 .step = 1,
79};
80
81static const struct v4l2_ctrl_config pwc_contour_cfg = {
82 .ops = &pwc_ctrl_ops,
83 .id = PWC_CID_CUSTOM(contour),
84 .type = V4L2_CTRL_TYPE_INTEGER,
85 .name = "Contour",
86 .min = 0,
87 .max = 63,
88 .step = 1,
89};
90
91static const struct v4l2_ctrl_config pwc_backlight_cfg = {
92 .ops = &pwc_ctrl_ops,
93 .id = V4L2_CID_BACKLIGHT_COMPENSATION,
94 .type = V4L2_CTRL_TYPE_BOOLEAN,
95 .min = 0,
96 .max = 1,
97 .step = 1,
98};
99
100static const struct v4l2_ctrl_config pwc_flicker_cfg = {
101 .ops = &pwc_ctrl_ops,
102 .id = V4L2_CID_BAND_STOP_FILTER,
103 .type = V4L2_CTRL_TYPE_BOOLEAN,
104 .min = 0,
105 .max = 1,
106 .step = 1,
107};
108
109static const struct v4l2_ctrl_config pwc_noise_reduction_cfg = {
110 .ops = &pwc_ctrl_ops,
111 .id = PWC_CID_CUSTOM(noise_reduction),
112 .type = V4L2_CTRL_TYPE_INTEGER,
113 .name = "Dynamic Noise Reduction",
114 .min = 0,
115 .max = 3,
116 .step = 1,
117};
118
119static const struct v4l2_ctrl_config pwc_save_user_cfg = {
120 .ops = &pwc_ctrl_ops,
121 .id = PWC_CID_CUSTOM(save_user),
122 .type = V4L2_CTRL_TYPE_BUTTON,
123 .name = "Save User Settings",
124};
125
126static const struct v4l2_ctrl_config pwc_restore_user_cfg = {
127 .ops = &pwc_ctrl_ops,
128 .id = PWC_CID_CUSTOM(restore_user),
129 .type = V4L2_CTRL_TYPE_BUTTON,
130 .name = "Restore User Settings",
131};
132
133static const struct v4l2_ctrl_config pwc_restore_factory_cfg = {
134 .ops = &pwc_ctrl_ops,
135 .id = PWC_CID_CUSTOM(restore_factory),
136 .type = V4L2_CTRL_TYPE_BUTTON,
137 .name = "Restore Factory Settings",
138};
139
140int pwc_init_controls(struct pwc_device *pdev)
141{
142 struct v4l2_ctrl_handler *hdl;
143 struct v4l2_ctrl_config cfg;
144 int r, def;
145
146 hdl = &pdev->ctrl_handler;
147 r = v4l2_ctrl_handler_init(hdl, 20);
148 if (r)
149 return r;
150
151 /* Brightness, contrast, saturation, gamma */
152 r = pwc_get_u8_ctrl(pdev, GET_LUM_CTL, BRIGHTNESS_FORMATTER, &def);
153 if (r || def > 127)
154 def = 63;
155 pdev->brightness = v4l2_ctrl_new_std(hdl, &pwc_ctrl_ops,
156 V4L2_CID_BRIGHTNESS, 0, 127, 1, def);
157
158 r = pwc_get_u8_ctrl(pdev, GET_LUM_CTL, CONTRAST_FORMATTER, &def);
159 if (r || def > 63)
160 def = 31;
161 pdev->contrast = v4l2_ctrl_new_std(hdl, &pwc_ctrl_ops,
162 V4L2_CID_CONTRAST, 0, 63, 1, def);
163
164 if (pdev->type >= 675) {
165 if (pdev->type < 730)
166 pdev->saturation_fmt = SATURATION_MODE_FORMATTER2;
167 else
168 pdev->saturation_fmt = SATURATION_MODE_FORMATTER1;
169 r = pwc_get_s8_ctrl(pdev, GET_CHROM_CTL, pdev->saturation_fmt,
170 &def);
171 if (r || def < -100 || def > 100)
172 def = 0;
173 pdev->saturation = v4l2_ctrl_new_std(hdl, &pwc_ctrl_ops,
174 V4L2_CID_SATURATION, -100, 100, 1, def);
175 }
176
177 r = pwc_get_u8_ctrl(pdev, GET_LUM_CTL, GAMMA_FORMATTER, &def);
178 if (r || def > 31)
179 def = 15;
180 pdev->gamma = v4l2_ctrl_new_std(hdl, &pwc_ctrl_ops,
181 V4L2_CID_GAMMA, 0, 31, 1, def);
182
183 /* auto white balance, red gain, blue gain */
184 r = pwc_get_u8_ctrl(pdev, GET_CHROM_CTL, WB_MODE_FORMATTER, &def);
185 if (r || def > awb_auto)
186 def = awb_auto;
187 cfg = pwc_auto_white_balance_cfg;
188 cfg.name = v4l2_ctrl_get_name(cfg.id);
189 cfg.def = def;
190 pdev->auto_white_balance = v4l2_ctrl_new_custom(hdl, &cfg, NULL);
191 /* check auto controls to avoid NULL deref in v4l2_ctrl_auto_cluster */
192 if (!pdev->auto_white_balance)
193 return hdl->error;
194
195 r = pwc_get_u8_ctrl(pdev, GET_CHROM_CTL,
196 PRESET_MANUAL_RED_GAIN_FORMATTER, &def);
197 if (r)
198 def = 127;
199 pdev->red_balance = v4l2_ctrl_new_std(hdl, &pwc_ctrl_ops,
200 V4L2_CID_RED_BALANCE, 0, 255, 1, def);
201
202 r = pwc_get_u8_ctrl(pdev, GET_CHROM_CTL,
203 PRESET_MANUAL_BLUE_GAIN_FORMATTER, &def);
204 if (r)
205 def = 127;
206 pdev->blue_balance = v4l2_ctrl_new_std(hdl, &pwc_ctrl_ops,
207 V4L2_CID_BLUE_BALANCE, 0, 255, 1, def);
208
209 v4l2_ctrl_auto_cluster(3, &pdev->auto_white_balance, awb_manual,
210 pdev->auto_white_balance->cur.val == awb_auto);
211
212 /* autogain, gain */
213 r = pwc_get_u8_ctrl(pdev, GET_LUM_CTL, AGC_MODE_FORMATTER, &def);
214 if (r || (def != 0 && def != 0xff))
215 def = 0;
216 /* Note a register value if 0 means auto gain is on */
217 pdev->autogain = v4l2_ctrl_new_std(hdl, &pwc_ctrl_ops,
218 V4L2_CID_AUTOGAIN, 0, 1, 1, def == 0);
219 if (!pdev->autogain)
220 return hdl->error;
221
222 r = pwc_get_u8_ctrl(pdev, GET_LUM_CTL, PRESET_AGC_FORMATTER, &def);
223 if (r || def > 63)
224 def = 31;
225 pdev->gain = v4l2_ctrl_new_std(hdl, &pwc_ctrl_ops,
226 V4L2_CID_GAIN, 0, 63, 1, def);
227
228 /* auto exposure, exposure */
229 if (DEVICE_USE_CODEC2(pdev->type)) {
230 r = pwc_get_u8_ctrl(pdev, GET_LUM_CTL, SHUTTER_MODE_FORMATTER,
231 &def);
232 if (r || (def != 0 && def != 0xff))
233 def = 0;
234 /*
235 * def = 0 auto, def = ff manual
236 * menu idx 0 = auto, idx 1 = manual
237 */
238 pdev->exposure_auto = v4l2_ctrl_new_std_menu(hdl,
239 &pwc_ctrl_ops,
240 V4L2_CID_EXPOSURE_AUTO,
241 1, 0, def != 0);
242 if (!pdev->exposure_auto)
243 return hdl->error;
244
245 /* GET_LUM_CTL, PRESET_SHUTTER_FORMATTER is unreliable */
246 r = pwc_get_u16_ctrl(pdev, GET_STATUS_CTL,
247 READ_SHUTTER_FORMATTER, &def);
248 if (r || def > 655)
249 def = 655;
250 pdev->exposure = v4l2_ctrl_new_std(hdl, &pwc_ctrl_ops,
251 V4L2_CID_EXPOSURE, 0, 655, 1, def);
252 /* CODEC2: separate auto gain & auto exposure */
253 v4l2_ctrl_auto_cluster(2, &pdev->autogain, 0, true);
254 v4l2_ctrl_auto_cluster(2, &pdev->exposure_auto,
255 V4L2_EXPOSURE_MANUAL, true);
256 } else if (DEVICE_USE_CODEC3(pdev->type)) {
257 /* GET_LUM_CTL, PRESET_SHUTTER_FORMATTER is unreliable */
258 r = pwc_get_u16_ctrl(pdev, GET_STATUS_CTL,
259 READ_SHUTTER_FORMATTER, &def);
260 if (r || def > 255)
261 def = 255;
262 pdev->exposure = v4l2_ctrl_new_std(hdl, &pwc_ctrl_ops,
263 V4L2_CID_EXPOSURE, 0, 255, 1, def);
264 /* CODEC3: both gain and exposure controlled by autogain */
265 pdev->autogain_expo_cluster[0] = pdev->autogain;
266 pdev->autogain_expo_cluster[1] = pdev->gain;
267 pdev->autogain_expo_cluster[2] = pdev->exposure;
268 v4l2_ctrl_auto_cluster(3, pdev->autogain_expo_cluster,
269 0, true);
270 }
271
272 /* color / bw setting */
273 r = pwc_get_u8_ctrl(pdev, GET_CHROM_CTL, COLOUR_MODE_FORMATTER,
274 &def);
275 if (r || (def != 0 && def != 0xff))
276 def = 0xff;
277 /* def = 0 bw, def = ff color, menu idx 0 = color, idx 1 = bw */
278 pdev->colorfx = v4l2_ctrl_new_std_menu(hdl, &pwc_ctrl_ops,
279 V4L2_CID_COLORFX, 1, 0, def == 0);
280
281 /* autocontour, contour */
282 r = pwc_get_u8_ctrl(pdev, GET_LUM_CTL, AUTO_CONTOUR_FORMATTER, &def);
283 if (r || (def != 0 && def != 0xff))
284 def = 0;
285 cfg = pwc_autocontour_cfg;
286 cfg.def = def == 0;
287 pdev->autocontour = v4l2_ctrl_new_custom(hdl, &cfg, NULL);
288 if (!pdev->autocontour)
289 return hdl->error;
290
291 r = pwc_get_u8_ctrl(pdev, GET_LUM_CTL, PRESET_CONTOUR_FORMATTER, &def);
292 if (r || def > 63)
293 def = 31;
294 cfg = pwc_contour_cfg;
295 cfg.def = def;
296 pdev->contour = v4l2_ctrl_new_custom(hdl, &cfg, NULL);
297
298 v4l2_ctrl_auto_cluster(2, &pdev->autocontour, 0, false);
299
300 /* backlight */
301 r = pwc_get_u8_ctrl(pdev, GET_LUM_CTL,
302 BACK_LIGHT_COMPENSATION_FORMATTER, &def);
303 if (r || (def != 0 && def != 0xff))
304 def = 0;
305 cfg = pwc_backlight_cfg;
306 cfg.name = v4l2_ctrl_get_name(cfg.id);
307 cfg.def = def == 0;
308 pdev->backlight = v4l2_ctrl_new_custom(hdl, &cfg, NULL);
309
310 /* flikker rediction */
311 r = pwc_get_u8_ctrl(pdev, GET_LUM_CTL,
312 FLICKERLESS_MODE_FORMATTER, &def);
313 if (r || (def != 0 && def != 0xff))
314 def = 0;
315 cfg = pwc_flicker_cfg;
316 cfg.name = v4l2_ctrl_get_name(cfg.id);
317 cfg.def = def == 0;
318 pdev->flicker = v4l2_ctrl_new_custom(hdl, &cfg, NULL);
319
320 /* Dynamic noise reduction */
321 r = pwc_get_u8_ctrl(pdev, GET_LUM_CTL,
322 DYNAMIC_NOISE_CONTROL_FORMATTER, &def);
323 if (r || def > 3)
324 def = 2;
325 cfg = pwc_noise_reduction_cfg;
326 cfg.def = def;
327 pdev->noise_reduction = v4l2_ctrl_new_custom(hdl, &cfg, NULL);
328
329 /* Save / Restore User / Factory Settings */
330 pdev->save_user = v4l2_ctrl_new_custom(hdl, &pwc_save_user_cfg, NULL);
331 pdev->restore_user = v4l2_ctrl_new_custom(hdl, &pwc_restore_user_cfg,
332 NULL);
333 if (pdev->restore_user)
334 pdev->restore_user->flags = V4L2_CTRL_FLAG_UPDATE;
335 pdev->restore_factory = v4l2_ctrl_new_custom(hdl,
336 &pwc_restore_factory_cfg,
337 NULL);
338 if (pdev->restore_factory)
339 pdev->restore_factory->flags = V4L2_CTRL_FLAG_UPDATE;
340
341 if (!(pdev->features & FEATURE_MOTOR_PANTILT))
342 return hdl->error;
343
344 /* Motor pan / tilt / reset */
345 pdev->motor_pan = v4l2_ctrl_new_std(hdl, &pwc_ctrl_ops,
346 V4L2_CID_PAN_RELATIVE, -4480, 4480, 64, 0);
347 if (!pdev->motor_pan)
348 return hdl->error;
349 pdev->motor_tilt = v4l2_ctrl_new_std(hdl, &pwc_ctrl_ops,
350 V4L2_CID_TILT_RELATIVE, -1920, 1920, 64, 0);
351 pdev->motor_pan_reset = v4l2_ctrl_new_std(hdl, &pwc_ctrl_ops,
352 V4L2_CID_PAN_RESET, 0, 0, 0, 0);
353 pdev->motor_tilt_reset = v4l2_ctrl_new_std(hdl, &pwc_ctrl_ops,
354 V4L2_CID_TILT_RESET, 0, 0, 0, 0);
355 v4l2_ctrl_cluster(4, &pdev->motor_pan);
356
357 return hdl->error;
358}
359
360static void pwc_vidioc_fill_fmt(const struct pwc_device *pdev, struct v4l2_format *f)
361{
362 memset(&f->fmt.pix, 0, sizeof(struct v4l2_pix_format));
363 f->fmt.pix.width = pdev->view.x;
364 f->fmt.pix.height = pdev->view.y;
365 f->fmt.pix.field = V4L2_FIELD_NONE;
366 if (pdev->pixfmt == V4L2_PIX_FMT_YUV420) {
367 f->fmt.pix.pixelformat = V4L2_PIX_FMT_YUV420;
368 f->fmt.pix.bytesperline = (f->fmt.pix.width * 3)/2;
369 f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline;
370 } else {
371 /* vbandlength contains 4 lines ... */
372 f->fmt.pix.bytesperline = pdev->vbandlength/4;
373 f->fmt.pix.sizeimage = pdev->frame_size + sizeof(struct pwc_raw_frame);
374 if (DEVICE_USE_CODEC1(pdev->type))
375 f->fmt.pix.pixelformat = V4L2_PIX_FMT_PWC1;
376 else
377 f->fmt.pix.pixelformat = V4L2_PIX_FMT_PWC2;
378 }
379 PWC_DEBUG_IOCTL("pwc_vidioc_fill_fmt() "
380 "width=%d, height=%d, bytesperline=%d, sizeimage=%d, pixelformat=%c%c%c%c\n",
381 f->fmt.pix.width,
382 f->fmt.pix.height,
383 f->fmt.pix.bytesperline,
384 f->fmt.pix.sizeimage,
385 (f->fmt.pix.pixelformat)&255,
386 (f->fmt.pix.pixelformat>>8)&255,
387 (f->fmt.pix.pixelformat>>16)&255,
388 (f->fmt.pix.pixelformat>>24)&255);
389}
390
391/* ioctl(VIDIOC_TRY_FMT) */
392static int pwc_vidioc_try_fmt(struct pwc_device *pdev, struct v4l2_format *f)
393{
394 if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
395 PWC_DEBUG_IOCTL("Bad video type must be V4L2_BUF_TYPE_VIDEO_CAPTURE\n");
396 return -EINVAL;
397 }
398
399 switch (f->fmt.pix.pixelformat) {
400 case V4L2_PIX_FMT_YUV420:
401 break;
402 case V4L2_PIX_FMT_PWC1:
403 if (DEVICE_USE_CODEC23(pdev->type)) {
404 PWC_DEBUG_IOCTL("codec1 is only supported for old pwc webcam\n");
405 return -EINVAL;
406 }
407 break;
408 case V4L2_PIX_FMT_PWC2:
409 if (DEVICE_USE_CODEC1(pdev->type)) {
410 PWC_DEBUG_IOCTL("codec23 is only supported for new pwc webcam\n");
411 return -EINVAL;
412 }
413 break;
414 default:
415 PWC_DEBUG_IOCTL("Unsupported pixel format\n");
416 return -EINVAL;
417
418 }
419
420 if (f->fmt.pix.width > pdev->view_max.x)
421 f->fmt.pix.width = pdev->view_max.x;
422 else if (f->fmt.pix.width < pdev->view_min.x)
423 f->fmt.pix.width = pdev->view_min.x;
424
425 if (f->fmt.pix.height > pdev->view_max.y)
426 f->fmt.pix.height = pdev->view_max.y;
427 else if (f->fmt.pix.height < pdev->view_min.y)
428 f->fmt.pix.height = pdev->view_min.y;
429
430 return 0;
431}
432
433/* ioctl(VIDIOC_SET_FMT) */
434
435static int pwc_s_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f)
436{
437 struct pwc_device *pdev = video_drvdata(file);
438 int ret, fps, snapshot, compression, pixelformat;
439
440 if (!pdev->udev)
441 return -ENODEV;
442
443 if (pdev->capt_file != NULL &&
444 pdev->capt_file != file)
445 return -EBUSY;
446
447 pdev->capt_file = file;
448
449 ret = pwc_vidioc_try_fmt(pdev, f);
450 if (ret<0)
451 return ret;
452
453 pixelformat = f->fmt.pix.pixelformat;
454 compression = pdev->vcompression;
455 snapshot = 0;
456 fps = pdev->vframes;
457 if (f->fmt.pix.priv) {
458 compression = (f->fmt.pix.priv & PWC_QLT_MASK) >> PWC_QLT_SHIFT;
459 snapshot = !!(f->fmt.pix.priv & PWC_FPS_SNAPSHOT);
460 fps = (f->fmt.pix.priv & PWC_FPS_FRMASK) >> PWC_FPS_SHIFT;
461 if (fps == 0)
462 fps = pdev->vframes;
463 }
464
465 if (pixelformat != V4L2_PIX_FMT_YUV420 &&
466 pixelformat != V4L2_PIX_FMT_PWC1 &&
467 pixelformat != V4L2_PIX_FMT_PWC2)
468 return -EINVAL;
469
470 if (vb2_is_streaming(&pdev->vb_queue))
471 return -EBUSY;
472
473 PWC_DEBUG_IOCTL("Trying to set format to: width=%d height=%d fps=%d "
474 "compression=%d snapshot=%d format=%c%c%c%c\n",
475 f->fmt.pix.width, f->fmt.pix.height, fps,
476 compression, snapshot,
477 (pixelformat)&255,
478 (pixelformat>>8)&255,
479 (pixelformat>>16)&255,
480 (pixelformat>>24)&255);
481
482 ret = pwc_set_video_mode(pdev,
483 f->fmt.pix.width,
484 f->fmt.pix.height,
485 fps,
486 compression,
487 snapshot);
488
489 PWC_DEBUG_IOCTL("pwc_set_video_mode(), return=%d\n", ret);
490
491 if (ret)
492 return ret;
493
494 pdev->pixfmt = pixelformat;
495
496 pwc_vidioc_fill_fmt(pdev, f);
497
498 return 0;
499
500}
501
502static int pwc_querycap(struct file *file, void *fh, struct v4l2_capability *cap)
503{
504 struct pwc_device *pdev = video_drvdata(file);
505
506 if (!pdev->udev)
507 return -ENODEV;
508
509 strcpy(cap->driver, PWC_NAME);
510 strlcpy(cap->card, pdev->vdev.name, sizeof(cap->card));
511 usb_make_path(pdev->udev, cap->bus_info, sizeof(cap->bus_info));
512 cap->capabilities =
513 V4L2_CAP_VIDEO_CAPTURE |
514 V4L2_CAP_STREAMING |
515 V4L2_CAP_READWRITE;
516 return 0;
517}
518
519static int pwc_enum_input(struct file *file, void *fh, struct v4l2_input *i)
520{
521 if (i->index) /* Only one INPUT is supported */
522 return -EINVAL;
523
524 strcpy(i->name, "usb");
525 return 0;
526}
527
528static int pwc_g_input(struct file *file, void *fh, unsigned int *i)
529{
530 *i = 0;
531 return 0;
532}
533
534static int pwc_s_input(struct file *file, void *fh, unsigned int i)
535{
536 return i ? -EINVAL : 0;
537}
538
539static int pwc_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
540{
541 struct pwc_device *pdev =
542 container_of(ctrl->handler, struct pwc_device, ctrl_handler);
543 int ret = 0;
544
545 /*
546 * Sometimes it can take quite long for the pwc to complete usb control
547 * transfers, so release the modlock to give streaming by another
548 * process / thread the chance to continue with a dqbuf.
549 */
550 mutex_unlock(&pdev->modlock);
551
552 /*
553 * Take the udev-lock to protect against the disconnect handler
554 * completing and setting dev->udev to NULL underneath us. Other code
555 * does not need to do this since it is protected by the modlock.
556 */
557 mutex_lock(&pdev->udevlock);
558
559 if (!pdev->udev) {
560 ret = -ENODEV;
561 goto leave;
562 }
563
564 switch (ctrl->id) {
565 case V4L2_CID_AUTO_WHITE_BALANCE:
566 if (pdev->color_bal_valid && time_before(jiffies,
567 pdev->last_color_bal_update + HZ / 4)) {
568 pdev->red_balance->val = pdev->last_red_balance;
569 pdev->blue_balance->val = pdev->last_blue_balance;
570 break;
571 }
572 ret = pwc_get_u8_ctrl(pdev, GET_STATUS_CTL,
573 READ_RED_GAIN_FORMATTER,
574 &pdev->red_balance->val);
575 if (ret)
576 break;
577 ret = pwc_get_u8_ctrl(pdev, GET_STATUS_CTL,
578 READ_BLUE_GAIN_FORMATTER,
579 &pdev->blue_balance->val);
580 if (ret)
581 break;
582 pdev->last_red_balance = pdev->red_balance->val;
583 pdev->last_blue_balance = pdev->blue_balance->val;
584 pdev->last_color_bal_update = jiffies;
585 pdev->color_bal_valid = true;
586 break;
587 case V4L2_CID_AUTOGAIN:
588 if (pdev->gain_valid && time_before(jiffies,
589 pdev->last_gain_update + HZ / 4)) {
590 pdev->gain->val = pdev->last_gain;
591 break;
592 }
593 ret = pwc_get_u8_ctrl(pdev, GET_STATUS_CTL,
594 READ_AGC_FORMATTER, &pdev->gain->val);
595 if (ret)
596 break;
597 pdev->last_gain = pdev->gain->val;
598 pdev->last_gain_update = jiffies;
599 pdev->gain_valid = true;
600 if (!DEVICE_USE_CODEC3(pdev->type))
601 break;
602 /* Fall through for CODEC3 where autogain also controls expo */
603 case V4L2_CID_EXPOSURE_AUTO:
604 if (pdev->exposure_valid && time_before(jiffies,
605 pdev->last_exposure_update + HZ / 4)) {
606 pdev->exposure->val = pdev->last_exposure;
607 break;
608 }
609 ret = pwc_get_u16_ctrl(pdev, GET_STATUS_CTL,
610 READ_SHUTTER_FORMATTER,
611 &pdev->exposure->val);
612 if (ret)
613 break;
614 pdev->last_exposure = pdev->exposure->val;
615 pdev->last_exposure_update = jiffies;
616 pdev->exposure_valid = true;
617 break;
618 default:
619 ret = -EINVAL;
620 }
621
622 if (ret)
623 PWC_ERROR("g_ctrl %s error %d\n", ctrl->name, ret);
624
625leave:
626 mutex_unlock(&pdev->udevlock);
627 mutex_lock(&pdev->modlock);
628 return ret;
629}
630
631static int pwc_set_awb(struct pwc_device *pdev)
632{
633 int ret = 0;
634
635 if (pdev->auto_white_balance->is_new) {
636 ret = pwc_set_u8_ctrl(pdev, SET_CHROM_CTL,
637 WB_MODE_FORMATTER,
638 pdev->auto_white_balance->val);
639 if (ret)
640 return ret;
641
642 /* Update val when coming from auto or going to a preset */
643 if (pdev->red_balance->is_volatile ||
644 pdev->auto_white_balance->val == awb_indoor ||
645 pdev->auto_white_balance->val == awb_outdoor ||
646 pdev->auto_white_balance->val == awb_fl) {
647 if (!pdev->red_balance->is_new)
648 pwc_get_u8_ctrl(pdev, GET_STATUS_CTL,
649 READ_RED_GAIN_FORMATTER,
650 &pdev->red_balance->val);
651 if (!pdev->blue_balance->is_new)
652 pwc_get_u8_ctrl(pdev, GET_STATUS_CTL,
653 READ_BLUE_GAIN_FORMATTER,
654 &pdev->blue_balance->val);
655 }
656 if (pdev->auto_white_balance->val == awb_auto) {
657 pdev->red_balance->is_volatile = true;
658 pdev->blue_balance->is_volatile = true;
659 pdev->color_bal_valid = false; /* Force cache update */
660 } else {
661 pdev->red_balance->is_volatile = false;
662 pdev->blue_balance->is_volatile = false;
663 }
664 }
665
666 if (ret == 0 && pdev->red_balance->is_new) {
667 if (pdev->auto_white_balance->val != awb_manual)
668 return -EBUSY;
669 ret = pwc_set_u8_ctrl(pdev, SET_CHROM_CTL,
670 PRESET_MANUAL_RED_GAIN_FORMATTER,
671 pdev->red_balance->val);
672 }
673
674 if (ret == 0 && pdev->blue_balance->is_new) {
675 if (pdev->auto_white_balance->val != awb_manual)
676 return -EBUSY;
677 ret = pwc_set_u8_ctrl(pdev, SET_CHROM_CTL,
678 PRESET_MANUAL_BLUE_GAIN_FORMATTER,
679 pdev->blue_balance->val);
680 }
681 return ret;
682}
683
684/* For CODEC2 models which have separate autogain and auto exposure */
685static int pwc_set_autogain(struct pwc_device *pdev)
686{
687 int ret = 0;
688
689 if (pdev->autogain->is_new) {
690 ret = pwc_set_u8_ctrl(pdev, SET_LUM_CTL,
691 AGC_MODE_FORMATTER,
692 pdev->autogain->val ? 0 : 0xff);
693 if (ret)
694 return ret;
695 if (pdev->autogain->val)
696 pdev->gain_valid = false; /* Force cache update */
697 else if (!pdev->gain->is_new)
698 pwc_get_u8_ctrl(pdev, GET_STATUS_CTL,
699 READ_AGC_FORMATTER,
700 &pdev->gain->val);
701 }
702 if (ret == 0 && pdev->gain->is_new) {
703 if (pdev->autogain->val)
704 return -EBUSY;
705 ret = pwc_set_u8_ctrl(pdev, SET_LUM_CTL,
706 PRESET_AGC_FORMATTER,
707 pdev->gain->val);
708 }
709 return ret;
710}
711
712/* For CODEC2 models which have separate autogain and auto exposure */
713static int pwc_set_exposure_auto(struct pwc_device *pdev)
714{
715 int ret = 0;
716 int is_auto = pdev->exposure_auto->val == V4L2_EXPOSURE_AUTO;
717
718 if (pdev->exposure_auto->is_new) {
719 ret = pwc_set_u8_ctrl(pdev, SET_LUM_CTL,
720 SHUTTER_MODE_FORMATTER,
721 is_auto ? 0 : 0xff);
722 if (ret)
723 return ret;
724 if (is_auto)
725 pdev->exposure_valid = false; /* Force cache update */
726 else if (!pdev->exposure->is_new)
727 pwc_get_u16_ctrl(pdev, GET_STATUS_CTL,
728 READ_SHUTTER_FORMATTER,
729 &pdev->exposure->val);
730 }
731 if (ret == 0 && pdev->exposure->is_new) {
732 if (is_auto)
733 return -EBUSY;
734 ret = pwc_set_u16_ctrl(pdev, SET_LUM_CTL,
735 PRESET_SHUTTER_FORMATTER,
736 pdev->exposure->val);
737 }
738 return ret;
739}
740
741/* For CODEC3 models which have autogain controlling both gain and exposure */
742static int pwc_set_autogain_expo(struct pwc_device *pdev)
743{
744 int ret = 0;
745
746 if (pdev->autogain->is_new) {
747 ret = pwc_set_u8_ctrl(pdev, SET_LUM_CTL,
748 AGC_MODE_FORMATTER,
749 pdev->autogain->val ? 0 : 0xff);
750 if (ret)
751 return ret;
752 if (pdev->autogain->val) {
753 pdev->gain_valid = false; /* Force cache update */
754 pdev->exposure_valid = false; /* Force cache update */
755 } else {
756 if (!pdev->gain->is_new)
757 pwc_get_u8_ctrl(pdev, GET_STATUS_CTL,
758 READ_AGC_FORMATTER,
759 &pdev->gain->val);
760 if (!pdev->exposure->is_new)
761 pwc_get_u16_ctrl(pdev, GET_STATUS_CTL,
762 READ_SHUTTER_FORMATTER,
763 &pdev->exposure->val);
764 }
765 }
766 if (ret == 0 && pdev->gain->is_new) {
767 if (pdev->autogain->val)
768 return -EBUSY;
769 ret = pwc_set_u8_ctrl(pdev, SET_LUM_CTL,
770 PRESET_AGC_FORMATTER,
771 pdev->gain->val);
772 }
773 if (ret == 0 && pdev->exposure->is_new) {
774 if (pdev->autogain->val)
775 return -EBUSY;
776 ret = pwc_set_u16_ctrl(pdev, SET_LUM_CTL,
777 PRESET_SHUTTER_FORMATTER,
778 pdev->exposure->val);
779 }
780 return ret;
781}
782
783static int pwc_set_motor(struct pwc_device *pdev)
784{
785 int ret;
786 u8 buf[4];
787
788 buf[0] = 0;
789 if (pdev->motor_pan_reset->is_new)
790 buf[0] |= 0x01;
791 if (pdev->motor_tilt_reset->is_new)
792 buf[0] |= 0x02;
793 if (pdev->motor_pan_reset->is_new || pdev->motor_tilt_reset->is_new) {
794 ret = send_control_msg(pdev, SET_MPT_CTL,
795 PT_RESET_CONTROL_FORMATTER, buf, 1);
796 if (ret < 0)
797 return ret;
798 }
799
800 memset(buf, 0, sizeof(buf));
801 if (pdev->motor_pan->is_new) {
802 buf[0] = pdev->motor_pan->val & 0xFF;
803 buf[1] = (pdev->motor_pan->val >> 8);
804 }
805 if (pdev->motor_tilt->is_new) {
806 buf[2] = pdev->motor_tilt->val & 0xFF;
807 buf[3] = (pdev->motor_tilt->val >> 8);
808 }
809 if (pdev->motor_pan->is_new || pdev->motor_tilt->is_new) {
810 ret = send_control_msg(pdev, SET_MPT_CTL,
811 PT_RELATIVE_CONTROL_FORMATTER,
812 buf, sizeof(buf));
813 if (ret < 0)
814 return ret;
815 }
816
817 return 0;
818}
819
820static int pwc_s_ctrl(struct v4l2_ctrl *ctrl)
821{
822 struct pwc_device *pdev =
823 container_of(ctrl->handler, struct pwc_device, ctrl_handler);
824 int ret = 0;
825
826 /* See the comments on locking in pwc_g_volatile_ctrl */
827 mutex_unlock(&pdev->modlock);
828 mutex_lock(&pdev->udevlock);
829
830 if (!pdev->udev) {
831 ret = -ENODEV;
832 goto leave;
833 }
834
835 switch (ctrl->id) {
836 case V4L2_CID_BRIGHTNESS:
837 ret = pwc_set_u8_ctrl(pdev, SET_LUM_CTL,
838 BRIGHTNESS_FORMATTER, ctrl->val);
839 break;
840 case V4L2_CID_CONTRAST:
841 ret = pwc_set_u8_ctrl(pdev, SET_LUM_CTL,
842 CONTRAST_FORMATTER, ctrl->val);
843 break;
844 case V4L2_CID_SATURATION:
845 ret = pwc_set_s8_ctrl(pdev, SET_CHROM_CTL,
846 pdev->saturation_fmt, ctrl->val);
847 break;
848 case V4L2_CID_GAMMA:
849 ret = pwc_set_u8_ctrl(pdev, SET_LUM_CTL,
850 GAMMA_FORMATTER, ctrl->val);
851 break;
852 case V4L2_CID_AUTO_WHITE_BALANCE:
853 ret = pwc_set_awb(pdev);
854 break;
855 case V4L2_CID_AUTOGAIN:
856 if (DEVICE_USE_CODEC2(pdev->type))
857 ret = pwc_set_autogain(pdev);
858 else if (DEVICE_USE_CODEC3(pdev->type))
859 ret = pwc_set_autogain_expo(pdev);
860 else
861 ret = -EINVAL;
862 break;
863 case V4L2_CID_EXPOSURE_AUTO:
864 if (DEVICE_USE_CODEC2(pdev->type))
865 ret = pwc_set_exposure_auto(pdev);
866 else
867 ret = -EINVAL;
868 break;
869 case V4L2_CID_COLORFX:
870 ret = pwc_set_u8_ctrl(pdev, SET_CHROM_CTL,
871 COLOUR_MODE_FORMATTER,
872 ctrl->val ? 0 : 0xff);
873 break;
874 case PWC_CID_CUSTOM(autocontour):
875 if (pdev->autocontour->is_new) {
876 ret = pwc_set_u8_ctrl(pdev, SET_LUM_CTL,
877 AUTO_CONTOUR_FORMATTER,
878 pdev->autocontour->val ? 0 : 0xff);
879 }
880 if (ret == 0 && pdev->contour->is_new) {
881 if (pdev->autocontour->val) {
882 ret = -EBUSY;
883 break;
884 }
885 ret = pwc_set_u8_ctrl(pdev, SET_LUM_CTL,
886 PRESET_CONTOUR_FORMATTER,
887 pdev->contour->val);
888 }
889 break;
890 case V4L2_CID_BACKLIGHT_COMPENSATION:
891 ret = pwc_set_u8_ctrl(pdev, SET_LUM_CTL,
892 BACK_LIGHT_COMPENSATION_FORMATTER,
893 ctrl->val ? 0 : 0xff);
894 break;
895 case V4L2_CID_BAND_STOP_FILTER:
896 ret = pwc_set_u8_ctrl(pdev, SET_LUM_CTL,
897 FLICKERLESS_MODE_FORMATTER,
898 ctrl->val ? 0 : 0xff);
899 break;
900 case PWC_CID_CUSTOM(noise_reduction):
901 ret = pwc_set_u8_ctrl(pdev, SET_LUM_CTL,
902 DYNAMIC_NOISE_CONTROL_FORMATTER,
903 ctrl->val);
904 break;
905 case PWC_CID_CUSTOM(save_user):
906 ret = pwc_button_ctrl(pdev, SAVE_USER_DEFAULTS_FORMATTER);
907 break;
908 case PWC_CID_CUSTOM(restore_user):
909 ret = pwc_button_ctrl(pdev, RESTORE_USER_DEFAULTS_FORMATTER);
910 break;
911 case PWC_CID_CUSTOM(restore_factory):
912 ret = pwc_button_ctrl(pdev,
913 RESTORE_FACTORY_DEFAULTS_FORMATTER);
914 break;
915 case V4L2_CID_PAN_RELATIVE:
916 ret = pwc_set_motor(pdev);
917 break;
918 default:
919 ret = -EINVAL;
920 }
921
922 if (ret)
923 PWC_ERROR("s_ctrl %s error %d\n", ctrl->name, ret);
924
925leave:
926 mutex_unlock(&pdev->udevlock);
927 mutex_lock(&pdev->modlock);
928 return ret;
929}
930
931static int pwc_enum_fmt_vid_cap(struct file *file, void *fh, struct v4l2_fmtdesc *f)
932{
933 struct pwc_device *pdev = video_drvdata(file);
934
935 /* We only support two format: the raw format, and YUV */
936 switch (f->index) {
937 case 0:
938 /* RAW format */
939 f->pixelformat = pdev->type <= 646 ? V4L2_PIX_FMT_PWC1 : V4L2_PIX_FMT_PWC2;
940 f->flags = V4L2_FMT_FLAG_COMPRESSED;
941 strlcpy(f->description, "Raw Philips Webcam", sizeof(f->description));
942 break;
943 case 1:
944 f->pixelformat = V4L2_PIX_FMT_YUV420;
945 strlcpy(f->description, "4:2:0, planar, Y-Cb-Cr", sizeof(f->description));
946 break;
947 default:
948 return -EINVAL;
949 }
950 return 0;
951}
952
953static int pwc_g_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f)
954{
955 struct pwc_device *pdev = video_drvdata(file);
956
957 PWC_DEBUG_IOCTL("ioctl(VIDIOC_G_FMT) return size %dx%d\n",
958 pdev->image.x, pdev->image.y);
959 pwc_vidioc_fill_fmt(pdev, f);
960 return 0;
961}
962
963static int pwc_try_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f)
964{
965 struct pwc_device *pdev = video_drvdata(file);
966
967 return pwc_vidioc_try_fmt(pdev, f);
968}
969
970static int pwc_reqbufs(struct file *file, void *fh,
971 struct v4l2_requestbuffers *rb)
972{
973 struct pwc_device *pdev = video_drvdata(file);
974
975 if (pdev->capt_file != NULL &&
976 pdev->capt_file != file)
977 return -EBUSY;
978
979 pdev->capt_file = file;
980
981 return vb2_reqbufs(&pdev->vb_queue, rb);
982}
983
984static int pwc_querybuf(struct file *file, void *fh, struct v4l2_buffer *buf)
985{
986 struct pwc_device *pdev = video_drvdata(file);
987
988 return vb2_querybuf(&pdev->vb_queue, buf);
989}
990
991static int pwc_qbuf(struct file *file, void *fh, struct v4l2_buffer *buf)
992{
993 struct pwc_device *pdev = video_drvdata(file);
994
995 if (!pdev->udev)
996 return -ENODEV;
997
998 if (pdev->capt_file != file)
999 return -EBUSY;
1000
1001 return vb2_qbuf(&pdev->vb_queue, buf);
1002}
1003
1004static int pwc_dqbuf(struct file *file, void *fh, struct v4l2_buffer *buf)
1005{
1006 struct pwc_device *pdev = video_drvdata(file);
1007
1008 if (!pdev->udev)
1009 return -ENODEV;
1010
1011 if (pdev->capt_file != file)
1012 return -EBUSY;
1013
1014 return vb2_dqbuf(&pdev->vb_queue, buf, file->f_flags & O_NONBLOCK);
1015}
1016
1017static int pwc_streamon(struct file *file, void *fh, enum v4l2_buf_type i)
1018{
1019 struct pwc_device *pdev = video_drvdata(file);
1020
1021 if (!pdev->udev)
1022 return -ENODEV;
1023
1024 if (pdev->capt_file != file)
1025 return -EBUSY;
1026
1027 return vb2_streamon(&pdev->vb_queue, i);
1028}
1029
1030static int pwc_streamoff(struct file *file, void *fh, enum v4l2_buf_type i)
1031{
1032 struct pwc_device *pdev = video_drvdata(file);
1033
1034 if (!pdev->udev)
1035 return -ENODEV;
1036
1037 if (pdev->capt_file != file)
1038 return -EBUSY;
1039
1040 return vb2_streamoff(&pdev->vb_queue, i);
1041}
1042
1043static int pwc_enum_framesizes(struct file *file, void *fh,
1044 struct v4l2_frmsizeenum *fsize)
1045{
1046 struct pwc_device *pdev = video_drvdata(file);
1047 unsigned int i = 0, index = fsize->index;
1048
1049 if (fsize->pixel_format == V4L2_PIX_FMT_YUV420) {
1050 for (i = 0; i < PSZ_MAX; i++) {
1051 if (pdev->image_mask & (1UL << i)) {
1052 if (!index--) {
1053 fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
1054 fsize->discrete.width = pwc_image_sizes[i].x;
1055 fsize->discrete.height = pwc_image_sizes[i].y;
1056 return 0;
1057 }
1058 }
1059 }
1060 } else if (fsize->index == 0 &&
1061 ((fsize->pixel_format == V4L2_PIX_FMT_PWC1 && DEVICE_USE_CODEC1(pdev->type)) ||
1062 (fsize->pixel_format == V4L2_PIX_FMT_PWC2 && DEVICE_USE_CODEC23(pdev->type)))) {
1063
1064 fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
1065 fsize->discrete.width = pdev->abs_max.x;
1066 fsize->discrete.height = pdev->abs_max.y;
1067 return 0;
1068 }
1069 return -EINVAL;
1070}
1071
1072static int pwc_enum_frameintervals(struct file *file, void *fh,
1073 struct v4l2_frmivalenum *fival)
1074{
1075 struct pwc_device *pdev = video_drvdata(file);
1076 int size = -1;
1077 unsigned int i;
1078
1079 for (i = 0; i < PSZ_MAX; i++) {
1080 if (pwc_image_sizes[i].x == fival->width &&
1081 pwc_image_sizes[i].y == fival->height) {
1082 size = i;
1083 break;
1084 }
1085 }
1086
1087 /* TODO: Support raw format */
1088 if (size < 0 || fival->pixel_format != V4L2_PIX_FMT_YUV420)
1089 return -EINVAL;
1090
1091 i = pwc_get_fps(pdev, fival->index, size);
1092 if (!i)
1093 return -EINVAL;
1094
1095 fival->type = V4L2_FRMIVAL_TYPE_DISCRETE;
1096 fival->discrete.numerator = 1;
1097 fival->discrete.denominator = i;
1098
1099 return 0;
1100}
1101
1102static long pwc_default(struct file *file, void *fh, bool valid_prio,
1103 int cmd, void *arg)
1104{
1105 struct pwc_device *pdev = video_drvdata(file);
1106
1107 return pwc_ioctl(pdev, cmd, arg);
1108}
1109
1110const struct v4l2_ioctl_ops pwc_ioctl_ops = {
1111 .vidioc_querycap = pwc_querycap,
1112 .vidioc_enum_input = pwc_enum_input,
1113 .vidioc_g_input = pwc_g_input,
1114 .vidioc_s_input = pwc_s_input,
1115 .vidioc_enum_fmt_vid_cap = pwc_enum_fmt_vid_cap,
1116 .vidioc_g_fmt_vid_cap = pwc_g_fmt_vid_cap,
1117 .vidioc_s_fmt_vid_cap = pwc_s_fmt_vid_cap,
1118 .vidioc_try_fmt_vid_cap = pwc_try_fmt_vid_cap,
1119 .vidioc_reqbufs = pwc_reqbufs,
1120 .vidioc_querybuf = pwc_querybuf,
1121 .vidioc_qbuf = pwc_qbuf,
1122 .vidioc_dqbuf = pwc_dqbuf,
1123 .vidioc_streamon = pwc_streamon,
1124 .vidioc_streamoff = pwc_streamoff,
1125 .vidioc_enum_framesizes = pwc_enum_framesizes,
1126 .vidioc_enum_frameintervals = pwc_enum_frameintervals,
1127 .vidioc_default = pwc_default,
1128};
1129
1130
1131/* vim: set cino= formatoptions=croql cindent shiftwidth=8 tabstop=8: */
diff --git a/drivers/media/video/pwc/pwc.h b/drivers/media/video/pwc/pwc.h
new file mode 100644
index 00000000000..0e4e2d7b787
--- /dev/null
+++ b/drivers/media/video/pwc/pwc.h
@@ -0,0 +1,387 @@
1/* (C) 1999-2003 Nemosoft Unv.
2 (C) 2004-2006 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/module.h>
29#include <linux/usb.h>
30#include <linux/spinlock.h>
31#include <linux/wait.h>
32#include <linux/mutex.h>
33#include <linux/mm.h>
34#include <linux/slab.h>
35#include <asm/errno.h>
36#include <linux/videodev2.h>
37#include <media/v4l2-common.h>
38#include <media/v4l2-ioctl.h>
39#include <media/v4l2-ctrls.h>
40#include <media/videobuf2-vmalloc.h>
41#ifdef CONFIG_USB_PWC_INPUT_EVDEV
42#include <linux/input.h>
43#endif
44
45#include <media/pwc-ioctl.h>
46
47/* Version block */
48#define PWC_VERSION "10.0.15"
49#define PWC_NAME "pwc"
50#define PFX PWC_NAME ": "
51
52
53/* Trace certain actions in the driver */
54#define PWC_DEBUG_LEVEL_MODULE (1<<0)
55#define PWC_DEBUG_LEVEL_PROBE (1<<1)
56#define PWC_DEBUG_LEVEL_OPEN (1<<2)
57#define PWC_DEBUG_LEVEL_READ (1<<3)
58#define PWC_DEBUG_LEVEL_MEMORY (1<<4)
59#define PWC_DEBUG_LEVEL_FLOW (1<<5)
60#define PWC_DEBUG_LEVEL_SIZE (1<<6)
61#define PWC_DEBUG_LEVEL_IOCTL (1<<7)
62#define PWC_DEBUG_LEVEL_TRACE (1<<8)
63
64#define PWC_DEBUG_MODULE(fmt, args...) PWC_DEBUG(MODULE, fmt, ##args)
65#define PWC_DEBUG_PROBE(fmt, args...) PWC_DEBUG(PROBE, fmt, ##args)
66#define PWC_DEBUG_OPEN(fmt, args...) PWC_DEBUG(OPEN, fmt, ##args)
67#define PWC_DEBUG_READ(fmt, args...) PWC_DEBUG(READ, fmt, ##args)
68#define PWC_DEBUG_MEMORY(fmt, args...) PWC_DEBUG(MEMORY, fmt, ##args)
69#define PWC_DEBUG_FLOW(fmt, args...) PWC_DEBUG(FLOW, fmt, ##args)
70#define PWC_DEBUG_SIZE(fmt, args...) PWC_DEBUG(SIZE, fmt, ##args)
71#define PWC_DEBUG_IOCTL(fmt, args...) PWC_DEBUG(IOCTL, fmt, ##args)
72#define PWC_DEBUG_TRACE(fmt, args...) PWC_DEBUG(TRACE, fmt, ##args)
73
74
75#ifdef CONFIG_USB_PWC_DEBUG
76
77#define PWC_DEBUG_LEVEL (PWC_DEBUG_LEVEL_MODULE)
78
79#define PWC_DEBUG(level, fmt, args...) do {\
80 if ((PWC_DEBUG_LEVEL_ ##level) & pwc_trace) \
81 printk(KERN_DEBUG PFX fmt, ##args); \
82 } while (0)
83
84#define PWC_ERROR(fmt, args...) printk(KERN_ERR PFX fmt, ##args)
85#define PWC_WARNING(fmt, args...) printk(KERN_WARNING PFX fmt, ##args)
86#define PWC_INFO(fmt, args...) printk(KERN_INFO PFX fmt, ##args)
87#define PWC_TRACE(fmt, args...) PWC_DEBUG(TRACE, fmt, ##args)
88
89#else /* if ! CONFIG_USB_PWC_DEBUG */
90
91#define PWC_ERROR(fmt, args...) printk(KERN_ERR PFX fmt, ##args)
92#define PWC_WARNING(fmt, args...) printk(KERN_WARNING PFX fmt, ##args)
93#define PWC_INFO(fmt, args...) printk(KERN_INFO PFX fmt, ##args)
94#define PWC_TRACE(fmt, args...) do { } while(0)
95#define PWC_DEBUG(level, fmt, args...) do { } while(0)
96
97#define pwc_trace 0
98
99#endif
100
101/* Defines for ToUCam cameras */
102#define TOUCAM_HEADER_SIZE 8
103#define TOUCAM_TRAILER_SIZE 4
104
105#define FEATURE_MOTOR_PANTILT 0x0001
106#define FEATURE_CODEC1 0x0002
107#define FEATURE_CODEC2 0x0004
108
109/* Ignore errors in the first N frames, to allow for startup delays */
110#define FRAME_LOWMARK 5
111
112/* Size and number of buffers for the ISO pipe. */
113#define MAX_ISO_BUFS 3
114#define ISO_FRAMES_PER_DESC 10
115#define ISO_MAX_FRAME_SIZE 960
116#define ISO_BUFFER_SIZE (ISO_FRAMES_PER_DESC * ISO_MAX_FRAME_SIZE)
117
118/* Maximum size after decompression is 640x480 YUV data, 1.5 * 640 * 480 */
119#define PWC_FRAME_SIZE (460800 + TOUCAM_HEADER_SIZE + TOUCAM_TRAILER_SIZE)
120
121/* Absolute minimum and maximum number of buffers available for mmap() */
122#define MIN_FRAMES 2
123#define MAX_FRAMES 16
124
125/* Some macros to quickly find the type of a webcam */
126#define DEVICE_USE_CODEC1(x) ((x)<675)
127#define DEVICE_USE_CODEC2(x) ((x)>=675 && (x)<700)
128#define DEVICE_USE_CODEC3(x) ((x)>=700)
129#define DEVICE_USE_CODEC23(x) ((x)>=675)
130
131/* from pwc-dec.h */
132#define PWCX_FLAG_PLANAR 0x0001
133
134/* Request types: video */
135#define SET_LUM_CTL 0x01
136#define GET_LUM_CTL 0x02
137#define SET_CHROM_CTL 0x03
138#define GET_CHROM_CTL 0x04
139#define SET_STATUS_CTL 0x05
140#define GET_STATUS_CTL 0x06
141#define SET_EP_STREAM_CTL 0x07
142#define GET_EP_STREAM_CTL 0x08
143#define GET_XX_CTL 0x09
144#define SET_XX_CTL 0x0A
145#define GET_XY_CTL 0x0B
146#define SET_XY_CTL 0x0C
147#define SET_MPT_CTL 0x0D
148#define GET_MPT_CTL 0x0E
149
150/* Selectors for the Luminance controls [GS]ET_LUM_CTL */
151#define AGC_MODE_FORMATTER 0x2000
152#define PRESET_AGC_FORMATTER 0x2100
153#define SHUTTER_MODE_FORMATTER 0x2200
154#define PRESET_SHUTTER_FORMATTER 0x2300
155#define PRESET_CONTOUR_FORMATTER 0x2400
156#define AUTO_CONTOUR_FORMATTER 0x2500
157#define BACK_LIGHT_COMPENSATION_FORMATTER 0x2600
158#define CONTRAST_FORMATTER 0x2700
159#define DYNAMIC_NOISE_CONTROL_FORMATTER 0x2800
160#define FLICKERLESS_MODE_FORMATTER 0x2900
161#define AE_CONTROL_SPEED 0x2A00
162#define BRIGHTNESS_FORMATTER 0x2B00
163#define GAMMA_FORMATTER 0x2C00
164
165/* Selectors for the Chrominance controls [GS]ET_CHROM_CTL */
166#define WB_MODE_FORMATTER 0x1000
167#define AWB_CONTROL_SPEED_FORMATTER 0x1100
168#define AWB_CONTROL_DELAY_FORMATTER 0x1200
169#define PRESET_MANUAL_RED_GAIN_FORMATTER 0x1300
170#define PRESET_MANUAL_BLUE_GAIN_FORMATTER 0x1400
171#define COLOUR_MODE_FORMATTER 0x1500
172#define SATURATION_MODE_FORMATTER1 0x1600
173#define SATURATION_MODE_FORMATTER2 0x1700
174
175/* Selectors for the Status controls [GS]ET_STATUS_CTL */
176#define SAVE_USER_DEFAULTS_FORMATTER 0x0200
177#define RESTORE_USER_DEFAULTS_FORMATTER 0x0300
178#define RESTORE_FACTORY_DEFAULTS_FORMATTER 0x0400
179#define READ_AGC_FORMATTER 0x0500
180#define READ_SHUTTER_FORMATTER 0x0600
181#define READ_RED_GAIN_FORMATTER 0x0700
182#define READ_BLUE_GAIN_FORMATTER 0x0800
183
184/* Formatters for the motorized pan & tilt [GS]ET_MPT_CTL */
185#define PT_RELATIVE_CONTROL_FORMATTER 0x01
186#define PT_RESET_CONTROL_FORMATTER 0x02
187#define PT_STATUS_FORMATTER 0x03
188
189/* intermediate buffers with raw data from the USB cam */
190struct pwc_frame_buf
191{
192 struct vb2_buffer vb; /* common v4l buffer stuff -- must be first */
193 struct list_head list;
194 void *data;
195 int filled; /* number of bytes filled */
196};
197
198struct pwc_device
199{
200 struct video_device vdev;
201 struct mutex modlock;
202
203 /* Pointer to our usb_device, may be NULL after unplug */
204 struct usb_device *udev;
205 /* Protects the setting of udev to NULL by our disconnect handler */
206 struct mutex udevlock;
207
208 /* type of cam (645, 646, 675, 680, 690, 720, 730, 740, 750) */
209 int type;
210 int release; /* release number */
211 int features; /* feature bits */
212 char serial[30]; /* serial number (string) */
213
214 /*** Video data ***/
215 struct file *capt_file; /* file doing video capture */
216 int vendpoint; /* video isoc endpoint */
217 int vcinterface; /* video control interface */
218 int valternate; /* alternate interface needed */
219 int vframes, vsize; /* frames-per-second & size (see PSZ_*) */
220 int pixfmt; /* pixelformat: V4L2_PIX_FMT_YUV420 or _PWCX */
221 int vframe_count; /* received frames */
222 int vmax_packet_size; /* USB maxpacket size */
223 int vlast_packet_size; /* for frame synchronisation */
224 int visoc_errors; /* number of contiguous ISOC errors */
225 int vcompression; /* desired compression factor */
226 int vbandlength; /* compressed band length; 0 is uncompressed */
227 char vsnapshot; /* snapshot mode */
228 char vsync; /* used by isoc handler */
229 char vmirror; /* for ToUCaM series */
230 char power_save; /* Do powersaving for this cam */
231
232 int cmd_len;
233 unsigned char cmd_buf[13];
234
235 struct urb *urbs[MAX_ISO_BUFS];
236 char iso_init;
237
238 /* videobuf2 queue and queued buffers list */
239 struct vb2_queue vb_queue;
240 struct list_head queued_bufs;
241 spinlock_t queued_bufs_lock;
242
243 /*
244 * Frame currently being filled, this only gets touched by the
245 * isoc urb complete handler, and by stream start / stop since
246 * start / stop touch it before / after starting / killing the urbs
247 * no locking is needed around this
248 */
249 struct pwc_frame_buf *fill_buf;
250
251 int frame_header_size, frame_trailer_size;
252 int frame_size;
253 int frame_total_size; /* including header & trailer */
254 int drop_frames;
255
256 void *decompress_data; /* private data for decompression engine */
257
258 /*
259 * We have an 'image' and a 'view', where 'image' is the fixed-size img
260 * as delivered by the camera, and 'view' is the size requested by the
261 * program. The camera image is centered in this viewport, laced with
262 * a gray or black border. view_min <= image <= view <= view_max;
263 */
264 int image_mask; /* supported sizes */
265 struct pwc_coord view_min, view_max; /* minimum and maximum view */
266 struct pwc_coord abs_max; /* maximum supported size */
267 struct pwc_coord image, view; /* image and viewport size */
268 struct pwc_coord offset; /* offset of the viewport */
269
270 /*** motorized pan/tilt feature */
271 struct pwc_mpt_range angle_range;
272 int pan_angle; /* in degrees * 100 */
273 int tilt_angle; /* absolute angle; 0,0 is home */
274
275 /*
276 * Set to 1 when the user push the button, reset to 0
277 * when this value is read from sysfs.
278 */
279 int snapshot_button_status;
280#ifdef CONFIG_USB_PWC_INPUT_EVDEV
281 struct input_dev *button_dev; /* webcam snapshot button input */
282 char button_phys[64];
283#endif
284
285 /* controls */
286 struct v4l2_ctrl_handler ctrl_handler;
287 u16 saturation_fmt;
288 struct v4l2_ctrl *brightness;
289 struct v4l2_ctrl *contrast;
290 struct v4l2_ctrl *saturation;
291 struct v4l2_ctrl *gamma;
292 struct {
293 /* awb / red-blue balance cluster */
294 struct v4l2_ctrl *auto_white_balance;
295 struct v4l2_ctrl *red_balance;
296 struct v4l2_ctrl *blue_balance;
297 /* usb ctrl transfers are slow, so we cache things */
298 int color_bal_valid;
299 unsigned long last_color_bal_update; /* In jiffies */
300 s32 last_red_balance;
301 s32 last_blue_balance;
302 };
303 struct {
304 /* autogain / gain cluster */
305 struct v4l2_ctrl *autogain;
306 struct v4l2_ctrl *gain;
307 int gain_valid;
308 unsigned long last_gain_update; /* In jiffies */
309 s32 last_gain;
310 };
311 struct {
312 /* exposure_auto / exposure cluster */
313 struct v4l2_ctrl *exposure_auto;
314 struct v4l2_ctrl *exposure;
315 int exposure_valid;
316 unsigned long last_exposure_update; /* In jiffies */
317 s32 last_exposure;
318 };
319 struct v4l2_ctrl *colorfx;
320 struct {
321 /* autocontour/contour cluster */
322 struct v4l2_ctrl *autocontour;
323 struct v4l2_ctrl *contour;
324 };
325 struct v4l2_ctrl *backlight;
326 struct v4l2_ctrl *flicker;
327 struct v4l2_ctrl *noise_reduction;
328 struct v4l2_ctrl *save_user;
329 struct v4l2_ctrl *restore_user;
330 struct v4l2_ctrl *restore_factory;
331 struct {
332 /* motor control cluster */
333 struct v4l2_ctrl *motor_pan;
334 struct v4l2_ctrl *motor_tilt;
335 struct v4l2_ctrl *motor_pan_reset;
336 struct v4l2_ctrl *motor_tilt_reset;
337 };
338 /* CODEC3 models have both gain and exposure controlled by autogain */
339 struct v4l2_ctrl *autogain_expo_cluster[3];
340};
341
342/* Global variables */
343#ifdef CONFIG_USB_PWC_DEBUG
344extern int pwc_trace;
345#endif
346
347/** Functions in pwc-misc.c */
348/* sizes in pixels */
349extern const struct pwc_coord pwc_image_sizes[PSZ_MAX];
350
351int pwc_decode_size(struct pwc_device *pdev, int width, int height);
352void pwc_construct(struct pwc_device *pdev);
353
354/** Functions in pwc-ctrl.c */
355/* Request a certain video mode. Returns < 0 if not possible */
356extern int pwc_set_video_mode(struct pwc_device *pdev, int width, int height, int frames, int compression, int snapshot);
357extern unsigned int pwc_get_fps(struct pwc_device *pdev, unsigned int index, unsigned int size);
358extern int pwc_mpt_reset(struct pwc_device *pdev, int flags);
359extern int pwc_mpt_set_angle(struct pwc_device *pdev, int pan, int tilt);
360extern int pwc_set_leds(struct pwc_device *pdev, int on_value, int off_value);
361extern int pwc_get_cmos_sensor(struct pwc_device *pdev, int *sensor);
362extern int send_control_msg(struct pwc_device *pdev,
363 u8 request, u16 value, void *buf, int buflen);
364
365/* Control get / set helpers */
366int pwc_get_u8_ctrl(struct pwc_device *pdev, u8 request, u16 value, int *data);
367int pwc_set_u8_ctrl(struct pwc_device *pdev, u8 request, u16 value, u8 data);
368int pwc_get_s8_ctrl(struct pwc_device *pdev, u8 request, u16 value, int *data);
369#define pwc_set_s8_ctrl pwc_set_u8_ctrl
370int pwc_get_u16_ctrl(struct pwc_device *pdev, u8 request, u16 value, int *dat);
371int pwc_set_u16_ctrl(struct pwc_device *pdev, u8 request, u16 value, u16 data);
372int pwc_button_ctrl(struct pwc_device *pdev, u16 value);
373int pwc_init_controls(struct pwc_device *pdev);
374
375/* Power down or up the camera; not supported by all models */
376extern void pwc_camera_power(struct pwc_device *pdev, int power);
377
378/* Private ioctl()s; see pwc-ioctl.h */
379extern long pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg);
380
381extern const struct v4l2_ioctl_ops pwc_ioctl_ops;
382
383/** pwc-uncompress.c */
384/* Expand frame to image, possibly including decompression. Uses read_frame and fill_image */
385int pwc_decompress(struct pwc_device *pdev, struct pwc_frame_buf *fbuf);
386
387#endif