aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLuc Saillard <luc@saillard.org>2006-04-24 09:29:46 -0400
committerMauro Carvalho Chehab <mchehab@infradead.org>2006-06-25 00:58:20 -0400
commit2b455db6d456ef2d44808a8377fd3bc832e08317 (patch)
treeb7b7bcabd53f9bb58d7f69eb6d012735dacd31c7
parentd9e12f25cf538d103426946121d214dff332efbb (diff)
V4L/DVB (3835): [PATCH] update pwc driver
Add v4l2 compatibility Include the decompressor (legal problem has been resolv by Alan Cox) Faster decoder and easier to maintain, optimize, ... Can export to userland compressed stream Support more cameras, lot of bugs are fixed. Signed-off-by: Luc Saillard <luc@saillard.org> Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
-rw-r--r--drivers/media/video/pwc/Kconfig13
-rw-r--r--drivers/media/video/pwc/Makefile11
-rw-r--r--drivers/media/video/pwc/pwc-ctrl.c699
-rw-r--r--drivers/media/video/pwc/pwc-dec1.c50
-rw-r--r--drivers/media/video/pwc/pwc-dec1.h43
-rw-r--r--drivers/media/video/pwc/pwc-dec23.c941
-rw-r--r--drivers/media/video/pwc/pwc-dec23.h67
-rw-r--r--drivers/media/video/pwc/pwc-if.c1335
-rw-r--r--drivers/media/video/pwc/pwc-kiara.c575
-rw-r--r--drivers/media/video/pwc/pwc-kiara.h8
-rw-r--r--drivers/media/video/pwc/pwc-misc.c67
-rw-r--r--drivers/media/video/pwc/pwc-timon.c1132
-rw-r--r--drivers/media/video/pwc/pwc-timon.h8
-rw-r--r--drivers/media/video/pwc/pwc-uncompress.c154
-rw-r--r--drivers/media/video/pwc/pwc-uncompress.h4
-rw-r--r--drivers/media/video/pwc/pwc-v4l.c1208
-rw-r--r--drivers/media/video/pwc/pwc.h176
-rw-r--r--include/media/pwc-ioctl.h325
18 files changed, 5552 insertions, 1264 deletions
diff --git a/drivers/media/video/pwc/Kconfig b/drivers/media/video/pwc/Kconfig
index 53cbc950f95c..697145e0bf15 100644
--- a/drivers/media/video/pwc/Kconfig
+++ b/drivers/media/video/pwc/Kconfig
@@ -7,6 +7,7 @@ config USB_PWC
7 * Philips PCA645, PCA646 7 * Philips PCA645, PCA646
8 * Philips PCVC675, PCVC680, PCVC690 8 * Philips PCVC675, PCVC680, PCVC690
9 * Philips PCVC720/40, PCVC730, PCVC740, PCVC750 9 * Philips PCVC720/40, PCVC730, PCVC740, PCVC750
10 * Philips SPC900NC
10 * Askey VC010 11 * Askey VC010
11 * Logitech QuickCam Pro 3000, 4000, 'Zoom', 'Notebook Pro' 12 * Logitech QuickCam Pro 3000, 4000, 'Zoom', 'Notebook Pro'
12 and 'Orbit'/'Sphere' 13 and 'Orbit'/'Sphere'
@@ -19,10 +20,18 @@ config USB_PWC
19 and never will be, but the 665 and 720/20 are supported by other 20 and never will be, but the 665 and 720/20 are supported by other
20 drivers. 21 drivers.
21 22
22 See <file:Documentation/usb/philips.txt> for more information and 23 Some newer logitech webcams are not handled by this driver but by the
23 installation instructions. 24 Usb Video Class driver (linux-uvc).
24 25
25 The built-in microphone is enabled by selecting USB Audio support. 26 The built-in microphone is enabled by selecting USB Audio support.
26 27
27 To compile this driver as a module, choose M here: the 28 To compile this driver as a module, choose M here: the
28 module will be called pwc. 29 module will be called pwc.
30
31config USB_PWC_DEBUG
32 bool "USB Philips Cameras verbose debug"
33 depends USB_PWC
34 help
35 Say Y here in order to have the pwc driver generate verbose debugging
36 messages.
37 A special module options 'trace' is used to control the verbosity.
diff --git a/drivers/media/video/pwc/Makefile b/drivers/media/video/pwc/Makefile
index 33d60126c024..9db2260d10cc 100644
--- a/drivers/media/video/pwc/Makefile
+++ b/drivers/media/video/pwc/Makefile
@@ -1,3 +1,12 @@
1pwc-objs := pwc-if.o pwc-misc.o pwc-ctrl.o pwc-uncompress.o pwc-timon.o pwc-kiara.o 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
2 3
3obj-$(CONFIG_USB_PWC) += pwc.o 4obj-$(CONFIG_USB_PWC) += pwc.o
5
6ifeq ($(CONFIG_USB_PWC_DEBUG),y)
7EXTRA_CFLAGS += -DCONFIG_PWC_DEBUG=1
8else
9EXTRA_CFLAGS += -DCONFIG_PWC_DEBUG=0
10endif
11
12
diff --git a/drivers/media/video/pwc/pwc-ctrl.c b/drivers/media/video/pwc/pwc-ctrl.c
index 4ba549bfa0e0..93306c717279 100644
--- a/drivers/media/video/pwc/pwc-ctrl.c
+++ b/drivers/media/video/pwc/pwc-ctrl.c
@@ -2,7 +2,7 @@
2 Functions that send various control messages to the webcam, including 2 Functions that send various control messages to the webcam, including
3 video modes. 3 video modes.
4 (C) 1999-2003 Nemosoft Unv. 4 (C) 1999-2003 Nemosoft Unv.
5 (C) 2004 Luc Saillard (luc@saillard.org) 5 (C) 2004-2006 Luc Saillard (luc@saillard.org)
6 6
7 NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx 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. 8 driver and thus may have bugs that are not present in the original version.
@@ -41,12 +41,14 @@
41#include <asm/uaccess.h> 41#include <asm/uaccess.h>
42#endif 42#endif
43#include <asm/errno.h> 43#include <asm/errno.h>
44#include <linux/version.h>
44 45
45#include "pwc.h" 46#include "pwc.h"
46#include "pwc-ioctl.h"
47#include "pwc-uncompress.h" 47#include "pwc-uncompress.h"
48#include "pwc-kiara.h" 48#include "pwc-kiara.h"
49#include "pwc-timon.h" 49#include "pwc-timon.h"
50#include "pwc-dec1.h"
51#include "pwc-dec23.h"
50 52
51/* Request types: video */ 53/* Request types: video */
52#define SET_LUM_CTL 0x01 54#define SET_LUM_CTL 0x01
@@ -57,6 +59,10 @@
57#define GET_STATUS_CTL 0x06 59#define GET_STATUS_CTL 0x06
58#define SET_EP_STREAM_CTL 0x07 60#define SET_EP_STREAM_CTL 0x07
59#define GET_EP_STREAM_CTL 0x08 61#define GET_EP_STREAM_CTL 0x08
62#define GET_XX_CTL 0x09
63#define SET_XX_CTL 0x0A
64#define GET_XY_CTL 0x0B
65#define SET_XY_CTL 0x0C
60#define SET_MPT_CTL 0x0D 66#define SET_MPT_CTL 0x0D
61#define GET_MPT_CTL 0x0E 67#define GET_MPT_CTL 0x0E
62 68
@@ -93,12 +99,20 @@
93#define READ_SHUTTER_FORMATTER 0x0600 99#define READ_SHUTTER_FORMATTER 0x0600
94#define READ_RED_GAIN_FORMATTER 0x0700 100#define READ_RED_GAIN_FORMATTER 0x0700
95#define READ_BLUE_GAIN_FORMATTER 0x0800 101#define READ_BLUE_GAIN_FORMATTER 0x0800
102#define GET_STATUS_B00 0x0B00
96#define SENSOR_TYPE_FORMATTER1 0x0C00 103#define SENSOR_TYPE_FORMATTER1 0x0C00
104#define GET_STATUS_3000 0x3000
97#define READ_RAW_Y_MEAN_FORMATTER 0x3100 105#define READ_RAW_Y_MEAN_FORMATTER 0x3100
98#define SET_POWER_SAVE_MODE_FORMATTER 0x3200 106#define SET_POWER_SAVE_MODE_FORMATTER 0x3200
99#define MIRROR_IMAGE_FORMATTER 0x3300 107#define MIRROR_IMAGE_FORMATTER 0x3300
100#define LED_FORMATTER 0x3400 108#define LED_FORMATTER 0x3400
109#define LOWLIGHT 0x3500
110#define GET_STATUS_3600 0x3600
101#define SENSOR_TYPE_FORMATTER2 0x3700 111#define SENSOR_TYPE_FORMATTER2 0x3700
112#define GET_STATUS_3800 0x3800
113#define GET_STATUS_4000 0x4000
114#define GET_STATUS_4100 0x4100 /* Get */
115#define CTL_STATUS_4200 0x4200 /* [GS] 1 */
102 116
103/* Formatters for the Video Endpoint controls [GS]ET_EP_STREAM_CTL */ 117/* Formatters for the Video Endpoint controls [GS]ET_EP_STREAM_CTL */
104#define VIDEO_OUTPUT_CONTROL_FORMATTER 0x0100 118#define VIDEO_OUTPUT_CONTROL_FORMATTER 0x0100
@@ -138,6 +152,7 @@ static struct Nala_table_entry Nala_table[PSZ_MAX][8] =
138#include "pwc-nala.h" 152#include "pwc-nala.h"
139}; 153};
140 154
155static void pwc_set_image_buffer_size(struct pwc_device *pdev);
141 156
142/****************************************************************************/ 157/****************************************************************************/
143 158
@@ -159,31 +174,7 @@ static struct Nala_table_entry Nala_table[PSZ_MAX][8] =
159 &buf, buflen, 500) 174 &buf, buflen, 500)
160 175
161 176
162#if PWC_DEBUG 177static int send_video_command(struct usb_device *udev, int index, void *buf, int buflen)
163void pwc_hexdump(void *p, int len)
164{
165 int i;
166 unsigned char *s;
167 char buf[100], *d;
168
169 s = (unsigned char *)p;
170 d = buf;
171 *d = '\0';
172 Debug("Doing hexdump @ %p, %d bytes.\n", p, len);
173 for (i = 0; i < len; i++) {
174 d += sprintf(d, "%02X ", *s++);
175 if ((i & 0xF) == 0xF) {
176 Debug("%s\n", buf);
177 d = buf;
178 *d = '\0';
179 }
180 }
181 if ((i & 0xF) != 0)
182 Debug("%s\n", buf);
183}
184#endif
185
186static inline int send_video_command(struct usb_device *udev, int index, void *buf, int buflen)
187{ 178{
188 return usb_control_msg(udev, 179 return usb_control_msg(udev,
189 usb_sndctrlpipe(udev, 0), 180 usb_sndctrlpipe(udev, 0),
@@ -196,7 +187,7 @@ static inline int send_video_command(struct usb_device *udev, int index, void *b
196 187
197 188
198 189
199static inline int set_video_mode_Nala(struct pwc_device *pdev, int size, int frames) 190static int set_video_mode_Nala(struct pwc_device *pdev, int size, int frames)
200{ 191{
201 unsigned char buf[3]; 192 unsigned char buf[3];
202 int ret, fps; 193 int ret, fps;
@@ -229,34 +220,14 @@ static inline int set_video_mode_Nala(struct pwc_device *pdev, int size, int fra
229 if (pEntry->alternate == 0) 220 if (pEntry->alternate == 0)
230 return -EINVAL; 221 return -EINVAL;
231 222
232 if (pEntry->compressed)
233 return -ENOENT; /* Not supported. */
234
235 memcpy(buf, pEntry->mode, 3); 223 memcpy(buf, pEntry->mode, 3);
236 ret = send_video_command(pdev->udev, pdev->vendpoint, buf, 3); 224 ret = send_video_command(pdev->udev, pdev->vendpoint, buf, 3);
237 if (ret < 0) { 225 if (ret < 0) {
238 Debug("Failed to send video command... %d\n", ret); 226 PWC_DEBUG_MODULE("Failed to send video command... %d\n", ret);
239 return ret; 227 return ret;
240 } 228 }
241 if (pEntry->compressed && pdev->vpalette != VIDEO_PALETTE_RAW) 229 if (pEntry->compressed && pdev->vpalette != VIDEO_PALETTE_RAW)
242 { 230 pwc_dec1_init(pdev->type, pdev->release, buf, pdev->decompress_data);
243 switch(pdev->type) {
244 case 645:
245 case 646:
246/* pwc_dec1_init(pdev->type, pdev->release, buf, pdev->decompress_data); */
247 break;
248
249 case 675:
250 case 680:
251 case 690:
252 case 720:
253 case 730:
254 case 740:
255 case 750:
256/* pwc_dec23_init(pdev->type, pdev->release, buf, pdev->decompress_data); */
257 break;
258 }
259 }
260 231
261 pdev->cmd_len = 3; 232 pdev->cmd_len = 3;
262 memcpy(pdev->cmd_buf, buf, 3); 233 memcpy(pdev->cmd_buf, buf, 3);
@@ -283,7 +254,7 @@ static inline int set_video_mode_Nala(struct pwc_device *pdev, int size, int fra
283} 254}
284 255
285 256
286static inline int set_video_mode_Timon(struct pwc_device *pdev, int size, int frames, int compression, int snapshot) 257static int set_video_mode_Timon(struct pwc_device *pdev, int size, int frames, int compression, int snapshot)
287{ 258{
288 unsigned char buf[13]; 259 unsigned char buf[13];
289 const struct Timon_table_entry *pChoose; 260 const struct Timon_table_entry *pChoose;
@@ -315,8 +286,8 @@ static inline int set_video_mode_Timon(struct pwc_device *pdev, int size, int fr
315 if (ret < 0) 286 if (ret < 0)
316 return ret; 287 return ret;
317 288
318/* if (pChoose->bandlength > 0 && pdev->vpalette != VIDEO_PALETTE_RAW) 289 if (pChoose->bandlength > 0 && pdev->vpalette != VIDEO_PALETTE_RAW)
319 pwc_dec23_init(pdev->type, pdev->release, buf, pdev->decompress_data); */ 290 pwc_dec23_init(pdev, pdev->type, buf);
320 291
321 pdev->cmd_len = 13; 292 pdev->cmd_len = 13;
322 memcpy(pdev->cmd_buf, buf, 13); 293 memcpy(pdev->cmd_buf, buf, 13);
@@ -336,7 +307,7 @@ static inline int set_video_mode_Timon(struct pwc_device *pdev, int size, int fr
336} 307}
337 308
338 309
339static inline int set_video_mode_Kiara(struct pwc_device *pdev, int size, int frames, int compression, int snapshot) 310static int set_video_mode_Kiara(struct pwc_device *pdev, int size, int frames, int compression, int snapshot)
340{ 311{
341 const struct Kiara_table_entry *pChoose = NULL; 312 const struct Kiara_table_entry *pChoose = NULL;
342 int fps, ret; 313 int fps, ret;
@@ -350,21 +321,14 @@ static inline int set_video_mode_Kiara(struct pwc_device *pdev, int size, int fr
350 fps = (frames / 5) - 1; 321 fps = (frames / 5) - 1;
351 322
352 /* special case: VGA @ 5 fps and snapshot is raw bayer mode */ 323 /* special case: VGA @ 5 fps and snapshot is raw bayer mode */
353 if (size == PSZ_VGA && frames == 5 && snapshot) 324 if (size == PSZ_VGA && frames == 5 && snapshot && pdev->vpalette == VIDEO_PALETTE_RAW)
354 { 325 {
355 /* Only available in case the raw palette is selected or 326 /* Only available in case the raw palette is selected or
356 we have the decompressor available. This mode is 327 we have the decompressor available. This mode is
357 only available in compressed form 328 only available in compressed form
358 */ 329 */
359 if (pdev->vpalette == VIDEO_PALETTE_RAW) 330 PWC_DEBUG_SIZE("Choosing VGA/5 BAYER mode.\n");
360 { 331 pChoose = &RawEntry;
361 Info("Choosing VGA/5 BAYER mode (%d).\n", pdev->vpalette);
362 pChoose = &RawEntry;
363 }
364 else
365 {
366 Info("VGA/5 BAYER mode _must_ have a decompressor available, or use RAW palette.\n");
367 }
368 } 332 }
369 else 333 else
370 { 334 {
@@ -372,6 +336,7 @@ static inline int set_video_mode_Kiara(struct pwc_device *pdev, int size, int fr
372 if the preferred ratio is not available. 336 if the preferred ratio is not available.
373 Skip this step when using RAW modes. 337 Skip this step when using RAW modes.
374 */ 338 */
339 snapshot = 0;
375 while (compression <= 3) { 340 while (compression <= 3) {
376 pChoose = &Kiara_table[size][fps][compression]; 341 pChoose = &Kiara_table[size][fps][compression];
377 if (pChoose->alternate != 0) 342 if (pChoose->alternate != 0)
@@ -382,7 +347,7 @@ static inline int set_video_mode_Kiara(struct pwc_device *pdev, int size, int fr
382 if (pChoose == NULL || pChoose->alternate == 0) 347 if (pChoose == NULL || pChoose->alternate == 0)
383 return -ENOENT; /* Not supported. */ 348 return -ENOENT; /* Not supported. */
384 349
385 Debug("Using alternate setting %d.\n", pChoose->alternate); 350 PWC_TRACE("Using alternate setting %d.\n", pChoose->alternate);
386 351
387 /* usb_control_msg won't take staticly allocated arrays as argument?? */ 352 /* usb_control_msg won't take staticly allocated arrays as argument?? */
388 memcpy(buf, pChoose->mode, 12); 353 memcpy(buf, pChoose->mode, 12);
@@ -394,8 +359,8 @@ static inline int set_video_mode_Kiara(struct pwc_device *pdev, int size, int fr
394 if (ret < 0) 359 if (ret < 0)
395 return ret; 360 return ret;
396 361
397/* if (pChoose->bandlength > 0 && pdev->vpalette != VIDEO_PALETTE_RAW) 362 if (pChoose->bandlength > 0 && pdev->vpalette != VIDEO_PALETTE_RAW)
398 pwc_dec23_init(pdev->type, pdev->release, buf, pdev->decompress_data); */ 363 pwc_dec23_init(pdev, pdev->type, buf);
399 364
400 pdev->cmd_len = 12; 365 pdev->cmd_len = 12;
401 memcpy(pdev->cmd_buf, buf, 12); 366 memcpy(pdev->cmd_buf, buf, 12);
@@ -410,49 +375,13 @@ static inline int set_video_mode_Kiara(struct pwc_device *pdev, int size, int fr
410 pdev->frame_size = (pdev->vbandlength * pdev->image.y) / 4; 375 pdev->frame_size = (pdev->vbandlength * pdev->image.y) / 4;
411 else 376 else
412 pdev->frame_size = (pdev->image.x * pdev->image.y * 12) / 8; 377 pdev->frame_size = (pdev->image.x * pdev->image.y * 12) / 8;
378 PWC_TRACE("frame_size=%d, vframes=%d, vsize=%d, vsnapshot=%d, vbandlength=%d\n",
379 pdev->frame_size,pdev->vframes,pdev->vsize,pdev->vsnapshot,pdev->vbandlength);
413 return 0; 380 return 0;
414} 381}
415 382
416 383
417 384
418static void pwc_set_image_buffer_size(struct pwc_device *pdev)
419{
420 int i, factor = 0, filler = 0;
421
422 /* for PALETTE_YUV420P */
423 switch(pdev->vpalette)
424 {
425 case VIDEO_PALETTE_YUV420P:
426 factor = 6;
427 filler = 128;
428 break;
429 case VIDEO_PALETTE_RAW:
430 factor = 6; /* can be uncompressed YUV420P */
431 filler = 0;
432 break;
433 }
434
435 /* Set sizes in bytes */
436 pdev->image.size = pdev->image.x * pdev->image.y * factor / 4;
437 pdev->view.size = pdev->view.x * pdev->view.y * factor / 4;
438
439 /* Align offset, or you'll get some very weird results in
440 YUV420 mode... x must be multiple of 4 (to get the Y's in
441 place), and y even (or you'll mixup U & V). This is less of a
442 problem for YUV420P.
443 */
444 pdev->offset.x = ((pdev->view.x - pdev->image.x) / 2) & 0xFFFC;
445 pdev->offset.y = ((pdev->view.y - pdev->image.y) / 2) & 0xFFFE;
446
447 /* Fill buffers with gray or black */
448 for (i = 0; i < MAX_IMAGES; i++) {
449 if (pdev->image_ptr[i] != NULL)
450 memset(pdev->image_ptr[i], filler, pdev->view.size);
451 }
452}
453
454
455
456/** 385/**
457 @pdev: device structure 386 @pdev: device structure
458 @width: viewport width 387 @width: viewport width
@@ -465,50 +394,78 @@ int pwc_set_video_mode(struct pwc_device *pdev, int width, int height, int frame
465{ 394{
466 int ret, size; 395 int ret, size;
467 396
468 Trace(TRACE_FLOW, "set_video_mode(%dx%d @ %d, palette %d).\n", width, height, frames, pdev->vpalette); 397 PWC_DEBUG_FLOW("set_video_mode(%dx%d @ %d, palette %d).\n", width, height, frames, pdev->vpalette);
469 size = pwc_decode_size(pdev, width, height); 398 size = pwc_decode_size(pdev, width, height);
470 if (size < 0) { 399 if (size < 0) {
471 Debug("Could not find suitable size.\n"); 400 PWC_DEBUG_MODULE("Could not find suitable size.\n");
472 return -ERANGE; 401 return -ERANGE;
473 } 402 }
474 Debug("decode_size = %d.\n", size); 403 PWC_TRACE("decode_size = %d.\n", size);
475 404
476 ret = -EINVAL; 405 if (DEVICE_USE_CODEC1(pdev->type)) {
477 switch(pdev->type) {
478 case 645:
479 case 646:
480 ret = set_video_mode_Nala(pdev, size, frames); 406 ret = set_video_mode_Nala(pdev, size, frames);
481 break;
482
483 case 675:
484 case 680:
485 case 690:
486 ret = set_video_mode_Timon(pdev, size, frames, compression, snapshot);
487 break;
488 407
489 case 720: 408 } else if (DEVICE_USE_CODEC3(pdev->type)) {
490 case 730:
491 case 740:
492 case 750:
493 ret = set_video_mode_Kiara(pdev, size, frames, compression, snapshot); 409 ret = set_video_mode_Kiara(pdev, size, frames, compression, snapshot);
494 break; 410
411 } else {
412 ret = set_video_mode_Timon(pdev, size, frames, compression, snapshot);
495 } 413 }
496 if (ret < 0) { 414 if (ret < 0) {
497 if (ret == -ENOENT) 415 PWC_ERROR("Failed to set video mode %s@%d fps; return code = %d\n", size2name[size], frames, ret);
498 Info("Video mode %s@%d fps is only supported with the decompressor module (pwcx).\n", size2name[size], frames);
499 else {
500 Err("Failed to set video mode %s@%d fps; return code = %d\n", size2name[size], frames, ret);
501 }
502 return ret; 416 return ret;
503 } 417 }
504 pdev->view.x = width; 418 pdev->view.x = width;
505 pdev->view.y = height; 419 pdev->view.y = height;
506 pdev->frame_total_size = pdev->frame_size + pdev->frame_header_size + pdev->frame_trailer_size; 420 pdev->frame_total_size = pdev->frame_size + pdev->frame_header_size + pdev->frame_trailer_size;
507 pwc_set_image_buffer_size(pdev); 421 pwc_set_image_buffer_size(pdev);
508 Trace(TRACE_SIZE, "Set viewport to %dx%d, image size is %dx%d.\n", width, height, pwc_image_sizes[size].x, pwc_image_sizes[size].y); 422 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);
509 return 0; 423 return 0;
510} 424}
511 425
426#define BLACK_Y 0
427#define BLACK_U 128
428#define BLACK_V 128
429
430static void pwc_set_image_buffer_size(struct pwc_device *pdev)
431{
432 int i, factor = 0;
433
434 /* for PALETTE_YUV420P */
435 switch(pdev->vpalette)
436 {
437 case VIDEO_PALETTE_YUV420P:
438 factor = 6;
439 break;
440 case VIDEO_PALETTE_RAW:
441 factor = 6; /* can be uncompressed YUV420P */
442 break;
443 }
444
445 /* Set sizes in bytes */
446 pdev->image.size = pdev->image.x * pdev->image.y * factor / 4;
447 pdev->view.size = pdev->view.x * pdev->view.y * factor / 4;
448
449 /* Align offset, or you'll get some very weird results in
450 YUV420 mode... x must be multiple of 4 (to get the Y's in
451 place), and y even (or you'll mixup U & V). This is less of a
452 problem for YUV420P.
453 */
454 pdev->offset.x = ((pdev->view.x - pdev->image.x) / 2) & 0xFFFC;
455 pdev->offset.y = ((pdev->view.y - pdev->image.y) / 2) & 0xFFFE;
456
457 /* Fill buffers with black colors */
458 for (i = 0; i < pwc_mbufs; i++) {
459 unsigned char *p = pdev->image_data + pdev->images[i].offset;
460 memset(p, BLACK_Y, pdev->view.x * pdev->view.y);
461 p += pdev->view.x * pdev->view.y;
462 memset(p, BLACK_U, pdev->view.x * pdev->view.y/4);
463 p += pdev->view.x * pdev->view.y/4;
464 memset(p, BLACK_V, pdev->view.x * pdev->view.y/4);
465 }
466}
467
468
512 469
513/* BRIGHTNESS */ 470/* BRIGHTNESS */
514 471
@@ -520,7 +477,7 @@ int pwc_get_brightness(struct pwc_device *pdev)
520 ret = RecvControlMsg(GET_LUM_CTL, BRIGHTNESS_FORMATTER, 1); 477 ret = RecvControlMsg(GET_LUM_CTL, BRIGHTNESS_FORMATTER, 1);
521 if (ret < 0) 478 if (ret < 0)
522 return ret; 479 return ret;
523 return buf << 9; 480 return buf;
524} 481}
525 482
526int pwc_set_brightness(struct pwc_device *pdev, int value) 483int pwc_set_brightness(struct pwc_device *pdev, int value)
@@ -545,7 +502,7 @@ int pwc_get_contrast(struct pwc_device *pdev)
545 ret = RecvControlMsg(GET_LUM_CTL, CONTRAST_FORMATTER, 1); 502 ret = RecvControlMsg(GET_LUM_CTL, CONTRAST_FORMATTER, 1);
546 if (ret < 0) 503 if (ret < 0)
547 return ret; 504 return ret;
548 return buf << 10; 505 return buf;
549} 506}
550 507
551int pwc_set_contrast(struct pwc_device *pdev, int value) 508int pwc_set_contrast(struct pwc_device *pdev, int value)
@@ -570,7 +527,7 @@ int pwc_get_gamma(struct pwc_device *pdev)
570 ret = RecvControlMsg(GET_LUM_CTL, GAMMA_FORMATTER, 1); 527 ret = RecvControlMsg(GET_LUM_CTL, GAMMA_FORMATTER, 1);
571 if (ret < 0) 528 if (ret < 0)
572 return ret; 529 return ret;
573 return buf << 11; 530 return buf;
574} 531}
575 532
576int pwc_set_gamma(struct pwc_device *pdev, int value) 533int pwc_set_gamma(struct pwc_device *pdev, int value)
@@ -588,37 +545,47 @@ int pwc_set_gamma(struct pwc_device *pdev, int value)
588 545
589/* SATURATION */ 546/* SATURATION */
590 547
591int pwc_get_saturation(struct pwc_device *pdev) 548/* return a value between [-100 , 100] */
549int pwc_get_saturation(struct pwc_device *pdev, int *value)
592{ 550{
593 char buf; 551 char buf;
594 int ret; 552 int ret, saturation_register;
595 553
596 if (pdev->type < 675) 554 if (pdev->type < 675)
597 return -1; 555 return -EINVAL;
598 ret = RecvControlMsg(GET_CHROM_CTL, pdev->type < 730 ? SATURATION_MODE_FORMATTER2 : SATURATION_MODE_FORMATTER1, 1); 556 if (pdev->type < 730)
557 saturation_register = SATURATION_MODE_FORMATTER2;
558 else
559 saturation_register = SATURATION_MODE_FORMATTER1;
560 ret = RecvControlMsg(GET_CHROM_CTL, saturation_register, 1);
599 if (ret < 0) 561 if (ret < 0)
600 return ret; 562 return ret;
601 return 32768 + buf * 327; 563 *value = (signed)buf;
564 return 0;
602} 565}
603 566
567/* @param value saturation color between [-100 , 100] */
604int pwc_set_saturation(struct pwc_device *pdev, int value) 568int pwc_set_saturation(struct pwc_device *pdev, int value)
605{ 569{
606 char buf; 570 char buf;
571 int saturation_register;
607 572
608 if (pdev->type < 675) 573 if (pdev->type < 675)
609 return -EINVAL; 574 return -EINVAL;
610 if (value < 0) 575 if (value < -100)
611 value = 0; 576 value = -100;
612 if (value > 0xffff) 577 if (value > 100)
613 value = 0xffff; 578 value = 100;
614 /* saturation ranges from -100 to +100 */ 579 if (pdev->type < 730)
615 buf = (value - 32768) / 327; 580 saturation_register = SATURATION_MODE_FORMATTER2;
616 return SendControlMsg(SET_CHROM_CTL, pdev->type < 730 ? SATURATION_MODE_FORMATTER2 : SATURATION_MODE_FORMATTER1, 1); 581 else
582 saturation_register = SATURATION_MODE_FORMATTER1;
583 return SendControlMsg(SET_CHROM_CTL, saturation_register, 1);
617} 584}
618 585
619/* AGC */ 586/* AGC */
620 587
621static inline int pwc_set_agc(struct pwc_device *pdev, int mode, int value) 588int pwc_set_agc(struct pwc_device *pdev, int mode, int value)
622{ 589{
623 char buf; 590 char buf;
624 int ret; 591 int ret;
@@ -643,7 +610,7 @@ static inline int pwc_set_agc(struct pwc_device *pdev, int mode, int value)
643 return 0; 610 return 0;
644} 611}
645 612
646static inline int pwc_get_agc(struct pwc_device *pdev, int *value) 613int pwc_get_agc(struct pwc_device *pdev, int *value)
647{ 614{
648 unsigned char buf; 615 unsigned char buf;
649 int ret; 616 int ret;
@@ -673,7 +640,7 @@ static inline int pwc_get_agc(struct pwc_device *pdev, int *value)
673 return 0; 640 return 0;
674} 641}
675 642
676static inline int pwc_set_shutter_speed(struct pwc_device *pdev, int mode, int value) 643int pwc_set_shutter_speed(struct pwc_device *pdev, int mode, int value)
677{ 644{
678 char buf[2]; 645 char buf[2];
679 int speed, ret; 646 int speed, ret;
@@ -691,23 +658,16 @@ static inline int pwc_set_shutter_speed(struct pwc_device *pdev, int mode, int v
691 value = 0; 658 value = 0;
692 if (value > 0xffff) 659 if (value > 0xffff)
693 value = 0xffff; 660 value = 0xffff;
694 switch(pdev->type) { 661
695 case 675: 662 if (DEVICE_USE_CODEC2(pdev->type)) {
696 case 680:
697 case 690:
698 /* speed ranges from 0x0 to 0x290 (656) */ 663 /* speed ranges from 0x0 to 0x290 (656) */
699 speed = (value / 100); 664 speed = (value / 100);
700 buf[1] = speed >> 8; 665 buf[1] = speed >> 8;
701 buf[0] = speed & 0xff; 666 buf[0] = speed & 0xff;
702 break; 667 } else if (DEVICE_USE_CODEC3(pdev->type)) {
703 case 720:
704 case 730:
705 case 740:
706 case 750:
707 /* speed seems to range from 0x0 to 0xff */ 668 /* speed seems to range from 0x0 to 0xff */
708 buf[1] = 0; 669 buf[1] = 0;
709 buf[0] = value >> 8; 670 buf[0] = value >> 8;
710 break;
711 } 671 }
712 672
713 ret = SendControlMsg(SET_LUM_CTL, PRESET_SHUTTER_FORMATTER, 2); 673 ret = SendControlMsg(SET_LUM_CTL, PRESET_SHUTTER_FORMATTER, 2);
@@ -715,6 +675,25 @@ static inline int pwc_set_shutter_speed(struct pwc_device *pdev, int mode, int v
715 return ret; 675 return ret;
716} 676}
717 677
678/* This function is not exported to v4l1, so output values between 0 -> 256 */
679int pwc_get_shutter_speed(struct pwc_device *pdev, int *value)
680{
681 unsigned char buf[2];
682 int ret;
683
684 ret = RecvControlMsg(GET_STATUS_CTL, READ_SHUTTER_FORMATTER, 2);
685 if (ret < 0)
686 return ret;
687 *value = buf[0] + (buf[1] << 8);
688 if (DEVICE_USE_CODEC2(pdev->type)) {
689 /* speed ranges from 0x0 to 0x290 (656) */
690 *value *= 256/656;
691 } else if (DEVICE_USE_CODEC3(pdev->type)) {
692 /* speed seems to range from 0x0 to 0xff */
693 }
694 return 0;
695}
696
718 697
719/* POWER */ 698/* POWER */
720 699
@@ -736,19 +715,19 @@ int pwc_camera_power(struct pwc_device *pdev, int power)
736 715
737/* private calls */ 716/* private calls */
738 717
739static inline int pwc_restore_user(struct pwc_device *pdev) 718int pwc_restore_user(struct pwc_device *pdev)
740{ 719{
741 char buf; /* dummy */ 720 char buf; /* dummy */
742 return SendControlMsg(SET_STATUS_CTL, RESTORE_USER_DEFAULTS_FORMATTER, 0); 721 return SendControlMsg(SET_STATUS_CTL, RESTORE_USER_DEFAULTS_FORMATTER, 0);
743} 722}
744 723
745static inline int pwc_save_user(struct pwc_device *pdev) 724int pwc_save_user(struct pwc_device *pdev)
746{ 725{
747 char buf; /* dummy */ 726 char buf; /* dummy */
748 return SendControlMsg(SET_STATUS_CTL, SAVE_USER_DEFAULTS_FORMATTER, 0); 727 return SendControlMsg(SET_STATUS_CTL, SAVE_USER_DEFAULTS_FORMATTER, 0);
749} 728}
750 729
751static inline int pwc_restore_factory(struct pwc_device *pdev) 730int pwc_restore_factory(struct pwc_device *pdev)
752{ 731{
753 char buf; /* dummy */ 732 char buf; /* dummy */
754 return SendControlMsg(SET_STATUS_CTL, RESTORE_FACTORY_DEFAULTS_FORMATTER, 0); 733 return SendControlMsg(SET_STATUS_CTL, RESTORE_FACTORY_DEFAULTS_FORMATTER, 0);
@@ -766,7 +745,7 @@ static inline int pwc_restore_factory(struct pwc_device *pdev)
766 * 03: manual 745 * 03: manual
767 * 04: auto 746 * 04: auto
768 */ 747 */
769static inline int pwc_set_awb(struct pwc_device *pdev, int mode) 748int pwc_set_awb(struct pwc_device *pdev, int mode)
770{ 749{
771 char buf; 750 char buf;
772 int ret; 751 int ret;
@@ -786,7 +765,7 @@ static inline int pwc_set_awb(struct pwc_device *pdev, int mode)
786 return 0; 765 return 0;
787} 766}
788 767
789static inline int pwc_get_awb(struct pwc_device *pdev) 768int pwc_get_awb(struct pwc_device *pdev)
790{ 769{
791 unsigned char buf; 770 unsigned char buf;
792 int ret; 771 int ret;
@@ -798,7 +777,7 @@ static inline int pwc_get_awb(struct pwc_device *pdev)
798 return buf; 777 return buf;
799} 778}
800 779
801static inline int pwc_set_red_gain(struct pwc_device *pdev, int value) 780int pwc_set_red_gain(struct pwc_device *pdev, int value)
802{ 781{
803 unsigned char buf; 782 unsigned char buf;
804 783
@@ -811,7 +790,7 @@ static inline int pwc_set_red_gain(struct pwc_device *pdev, int value)
811 return SendControlMsg(SET_CHROM_CTL, PRESET_MANUAL_RED_GAIN_FORMATTER, 1); 790 return SendControlMsg(SET_CHROM_CTL, PRESET_MANUAL_RED_GAIN_FORMATTER, 1);
812} 791}
813 792
814static inline int pwc_get_red_gain(struct pwc_device *pdev, int *value) 793int pwc_get_red_gain(struct pwc_device *pdev, int *value)
815{ 794{
816 unsigned char buf; 795 unsigned char buf;
817 int ret; 796 int ret;
@@ -824,7 +803,7 @@ static inline int pwc_get_red_gain(struct pwc_device *pdev, int *value)
824} 803}
825 804
826 805
827static inline int pwc_set_blue_gain(struct pwc_device *pdev, int value) 806int pwc_set_blue_gain(struct pwc_device *pdev, int value)
828{ 807{
829 unsigned char buf; 808 unsigned char buf;
830 809
@@ -837,7 +816,7 @@ static inline int pwc_set_blue_gain(struct pwc_device *pdev, int value)
837 return SendControlMsg(SET_CHROM_CTL, PRESET_MANUAL_BLUE_GAIN_FORMATTER, 1); 816 return SendControlMsg(SET_CHROM_CTL, PRESET_MANUAL_BLUE_GAIN_FORMATTER, 1);
838} 817}
839 818
840static inline int pwc_get_blue_gain(struct pwc_device *pdev, int *value) 819int pwc_get_blue_gain(struct pwc_device *pdev, int *value)
841{ 820{
842 unsigned char buf; 821 unsigned char buf;
843 int ret; 822 int ret;
@@ -854,7 +833,7 @@ static inline int pwc_get_blue_gain(struct pwc_device *pdev, int *value)
854 internal red/blue gains, which may be different from the manual 833 internal red/blue gains, which may be different from the manual
855 gains set or read above. 834 gains set or read above.
856 */ 835 */
857static inline int pwc_read_red_gain(struct pwc_device *pdev, int *value) 836static int pwc_read_red_gain(struct pwc_device *pdev, int *value)
858{ 837{
859 unsigned char buf; 838 unsigned char buf;
860 int ret; 839 int ret;
@@ -866,7 +845,7 @@ static inline int pwc_read_red_gain(struct pwc_device *pdev, int *value)
866 return 0; 845 return 0;
867} 846}
868 847
869static inline int pwc_read_blue_gain(struct pwc_device *pdev, int *value) 848static int pwc_read_blue_gain(struct pwc_device *pdev, int *value)
870{ 849{
871 unsigned char buf; 850 unsigned char buf;
872 int ret; 851 int ret;
@@ -879,7 +858,7 @@ static inline int pwc_read_blue_gain(struct pwc_device *pdev, int *value)
879} 858}
880 859
881 860
882static inline int pwc_set_wb_speed(struct pwc_device *pdev, int speed) 861static int pwc_set_wb_speed(struct pwc_device *pdev, int speed)
883{ 862{
884 unsigned char buf; 863 unsigned char buf;
885 864
@@ -888,7 +867,7 @@ static inline int pwc_set_wb_speed(struct pwc_device *pdev, int speed)
888 return SendControlMsg(SET_CHROM_CTL, AWB_CONTROL_SPEED_FORMATTER, 1); 867 return SendControlMsg(SET_CHROM_CTL, AWB_CONTROL_SPEED_FORMATTER, 1);
889} 868}
890 869
891static inline int pwc_get_wb_speed(struct pwc_device *pdev, int *value) 870static int pwc_get_wb_speed(struct pwc_device *pdev, int *value)
892{ 871{
893 unsigned char buf; 872 unsigned char buf;
894 int ret; 873 int ret;
@@ -901,7 +880,7 @@ static inline int pwc_get_wb_speed(struct pwc_device *pdev, int *value)
901} 880}
902 881
903 882
904static inline int pwc_set_wb_delay(struct pwc_device *pdev, int delay) 883static int pwc_set_wb_delay(struct pwc_device *pdev, int delay)
905{ 884{
906 unsigned char buf; 885 unsigned char buf;
907 886
@@ -910,7 +889,7 @@ static inline int pwc_set_wb_delay(struct pwc_device *pdev, int delay)
910 return SendControlMsg(SET_CHROM_CTL, AWB_CONTROL_DELAY_FORMATTER, 1); 889 return SendControlMsg(SET_CHROM_CTL, AWB_CONTROL_DELAY_FORMATTER, 1);
911} 890}
912 891
913static inline int pwc_get_wb_delay(struct pwc_device *pdev, int *value) 892static int pwc_get_wb_delay(struct pwc_device *pdev, int *value)
914{ 893{
915 unsigned char buf; 894 unsigned char buf;
916 int ret; 895 int ret;
@@ -946,7 +925,7 @@ int pwc_set_leds(struct pwc_device *pdev, int on_value, int off_value)
946 return SendControlMsg(SET_STATUS_CTL, LED_FORMATTER, 2); 925 return SendControlMsg(SET_STATUS_CTL, LED_FORMATTER, 2);
947} 926}
948 927
949static int pwc_get_leds(struct pwc_device *pdev, int *on_value, int *off_value) 928int pwc_get_leds(struct pwc_device *pdev, int *on_value, int *off_value)
950{ 929{
951 unsigned char buf[2]; 930 unsigned char buf[2];
952 int ret; 931 int ret;
@@ -965,7 +944,7 @@ static int pwc_get_leds(struct pwc_device *pdev, int *on_value, int *off_value)
965 return 0; 944 return 0;
966} 945}
967 946
968static inline int pwc_set_contour(struct pwc_device *pdev, int contour) 947int pwc_set_contour(struct pwc_device *pdev, int contour)
969{ 948{
970 unsigned char buf; 949 unsigned char buf;
971 int ret; 950 int ret;
@@ -990,7 +969,7 @@ static inline int pwc_set_contour(struct pwc_device *pdev, int contour)
990 return 0; 969 return 0;
991} 970}
992 971
993static inline int pwc_get_contour(struct pwc_device *pdev, int *contour) 972int pwc_get_contour(struct pwc_device *pdev, int *contour)
994{ 973{
995 unsigned char buf; 974 unsigned char buf;
996 int ret; 975 int ret;
@@ -1012,7 +991,7 @@ static inline int pwc_get_contour(struct pwc_device *pdev, int *contour)
1012} 991}
1013 992
1014 993
1015static inline int pwc_set_backlight(struct pwc_device *pdev, int backlight) 994int pwc_set_backlight(struct pwc_device *pdev, int backlight)
1016{ 995{
1017 unsigned char buf; 996 unsigned char buf;
1018 997
@@ -1023,7 +1002,7 @@ static inline int pwc_set_backlight(struct pwc_device *pdev, int backlight)
1023 return SendControlMsg(SET_LUM_CTL, BACK_LIGHT_COMPENSATION_FORMATTER, 1); 1002 return SendControlMsg(SET_LUM_CTL, BACK_LIGHT_COMPENSATION_FORMATTER, 1);
1024} 1003}
1025 1004
1026static inline int pwc_get_backlight(struct pwc_device *pdev, int *backlight) 1005int pwc_get_backlight(struct pwc_device *pdev, int *backlight)
1027{ 1006{
1028 int ret; 1007 int ret;
1029 unsigned char buf; 1008 unsigned char buf;
@@ -1031,12 +1010,35 @@ static inline int pwc_get_backlight(struct pwc_device *pdev, int *backlight)
1031 ret = RecvControlMsg(GET_LUM_CTL, BACK_LIGHT_COMPENSATION_FORMATTER, 1); 1010 ret = RecvControlMsg(GET_LUM_CTL, BACK_LIGHT_COMPENSATION_FORMATTER, 1);
1032 if (ret < 0) 1011 if (ret < 0)
1033 return ret; 1012 return ret;
1034 *backlight = buf; 1013 *backlight = !!buf;
1014 return 0;
1015}
1016
1017int pwc_set_colour_mode(struct pwc_device *pdev, int colour)
1018{
1019 unsigned char buf;
1020
1021 if (colour)
1022 buf = 0xff;
1023 else
1024 buf = 0x0;
1025 return SendControlMsg(SET_CHROM_CTL, COLOUR_MODE_FORMATTER, 1);
1026}
1027
1028int pwc_get_colour_mode(struct pwc_device *pdev, int *colour)
1029{
1030 int ret;
1031 unsigned char buf;
1032
1033 ret = RecvControlMsg(GET_CHROM_CTL, COLOUR_MODE_FORMATTER, 1);
1034 if (ret < 0)
1035 return ret;
1036 *colour = !!buf;
1035 return 0; 1037 return 0;
1036} 1038}
1037 1039
1038 1040
1039static inline int pwc_set_flicker(struct pwc_device *pdev, int flicker) 1041int pwc_set_flicker(struct pwc_device *pdev, int flicker)
1040{ 1042{
1041 unsigned char buf; 1043 unsigned char buf;
1042 1044
@@ -1047,7 +1049,7 @@ static inline int pwc_set_flicker(struct pwc_device *pdev, int flicker)
1047 return SendControlMsg(SET_LUM_CTL, FLICKERLESS_MODE_FORMATTER, 1); 1049 return SendControlMsg(SET_LUM_CTL, FLICKERLESS_MODE_FORMATTER, 1);
1048} 1050}
1049 1051
1050static inline int pwc_get_flicker(struct pwc_device *pdev, int *flicker) 1052int pwc_get_flicker(struct pwc_device *pdev, int *flicker)
1051{ 1053{
1052 int ret; 1054 int ret;
1053 unsigned char buf; 1055 unsigned char buf;
@@ -1055,12 +1057,11 @@ static inline int pwc_get_flicker(struct pwc_device *pdev, int *flicker)
1055 ret = RecvControlMsg(GET_LUM_CTL, FLICKERLESS_MODE_FORMATTER, 1); 1057 ret = RecvControlMsg(GET_LUM_CTL, FLICKERLESS_MODE_FORMATTER, 1);
1056 if (ret < 0) 1058 if (ret < 0)
1057 return ret; 1059 return ret;
1058 *flicker = buf; 1060 *flicker = !!buf;
1059 return 0; 1061 return 0;
1060} 1062}
1061 1063
1062 1064int pwc_set_dynamic_noise(struct pwc_device *pdev, int noise)
1063static inline int pwc_set_dynamic_noise(struct pwc_device *pdev, int noise)
1064{ 1065{
1065 unsigned char buf; 1066 unsigned char buf;
1066 1067
@@ -1072,7 +1073,7 @@ static inline int pwc_set_dynamic_noise(struct pwc_device *pdev, int noise)
1072 return SendControlMsg(SET_LUM_CTL, DYNAMIC_NOISE_CONTROL_FORMATTER, 1); 1073 return SendControlMsg(SET_LUM_CTL, DYNAMIC_NOISE_CONTROL_FORMATTER, 1);
1073} 1074}
1074 1075
1075static inline int pwc_get_dynamic_noise(struct pwc_device *pdev, int *noise) 1076int pwc_get_dynamic_noise(struct pwc_device *pdev, int *noise)
1076{ 1077{
1077 int ret; 1078 int ret;
1078 unsigned char buf; 1079 unsigned char buf;
@@ -1084,7 +1085,7 @@ static inline int pwc_get_dynamic_noise(struct pwc_device *pdev, int *noise)
1084 return 0; 1085 return 0;
1085} 1086}
1086 1087
1087static int pwc_mpt_reset(struct pwc_device *pdev, int flags) 1088static int _pwc_mpt_reset(struct pwc_device *pdev, int flags)
1088{ 1089{
1089 unsigned char buf; 1090 unsigned char buf;
1090 1091
@@ -1092,7 +1093,18 @@ static int pwc_mpt_reset(struct pwc_device *pdev, int flags)
1092 return SendControlMsg(SET_MPT_CTL, PT_RESET_CONTROL_FORMATTER, 1); 1093 return SendControlMsg(SET_MPT_CTL, PT_RESET_CONTROL_FORMATTER, 1);
1093} 1094}
1094 1095
1095static inline int pwc_mpt_set_angle(struct pwc_device *pdev, int pan, int tilt) 1096int pwc_mpt_reset(struct pwc_device *pdev, int flags)
1097{
1098 int ret;
1099 ret = _pwc_mpt_reset(pdev, flags);
1100 if (ret >= 0) {
1101 pdev->pan_angle = 0;
1102 pdev->tilt_angle = 0;
1103 }
1104 return ret;
1105}
1106
1107static int _pwc_mpt_set_angle(struct pwc_device *pdev, int pan, int tilt)
1096{ 1108{
1097 unsigned char buf[4]; 1109 unsigned char buf[4];
1098 1110
@@ -1110,7 +1122,35 @@ static inline int pwc_mpt_set_angle(struct pwc_device *pdev, int pan, int tilt)
1110 return SendControlMsg(SET_MPT_CTL, PT_RELATIVE_CONTROL_FORMATTER, 4); 1122 return SendControlMsg(SET_MPT_CTL, PT_RELATIVE_CONTROL_FORMATTER, 4);
1111} 1123}
1112 1124
1113static inline int pwc_mpt_get_status(struct pwc_device *pdev, struct pwc_mpt_status *status) 1125int pwc_mpt_set_angle(struct pwc_device *pdev, int pan, int tilt)
1126{
1127 int ret;
1128
1129 /* check absolute ranges */
1130 if (pan < pdev->angle_range.pan_min ||
1131 pan > pdev->angle_range.pan_max ||
1132 tilt < pdev->angle_range.tilt_min ||
1133 tilt > pdev->angle_range.tilt_max)
1134 return -ERANGE;
1135
1136 /* go to relative range, check again */
1137 pan -= pdev->pan_angle;
1138 tilt -= pdev->tilt_angle;
1139 /* angles are specified in degrees * 100, thus the limit = 36000 */
1140 if (pan < -36000 || pan > 36000 || tilt < -36000 || tilt > 36000)
1141 return -ERANGE;
1142
1143 ret = _pwc_mpt_set_angle(pdev, pan, tilt);
1144 if (ret >= 0) {
1145 pdev->pan_angle += pan;
1146 pdev->tilt_angle += tilt;
1147 }
1148 if (ret == -EPIPE) /* stall -> out of range */
1149 ret = -ERANGE;
1150 return ret;
1151}
1152
1153static int pwc_mpt_get_status(struct pwc_device *pdev, struct pwc_mpt_status *status)
1114{ 1154{
1115 int ret; 1155 int ret;
1116 unsigned char buf[5]; 1156 unsigned char buf[5];
@@ -1151,6 +1191,26 @@ int pwc_get_cmos_sensor(struct pwc_device *pdev, int *sensor)
1151 /* End of Add-Ons */ 1191 /* End of Add-Ons */
1152 /* ************************************************* */ 1192 /* ************************************************* */
1153 1193
1194/* Linux 2.5.something and 2.6 pass direct pointers to arguments of
1195 ioctl() calls. With 2.4, you have to do tedious copy_from_user()
1196 and copy_to_user() calls. With these macros we circumvent this,
1197 and let me maintain only one source file. The functionality is
1198 exactly the same otherwise.
1199 */
1200
1201
1202/* define local variable for arg */
1203#define ARG_DEF(ARG_type, ARG_name)\
1204 ARG_type *ARG_name = arg;
1205/* copy arg to local variable */
1206#define ARG_IN(ARG_name) /* nothing */
1207/* argument itself (referenced) */
1208#define ARGR(ARG_name) (*ARG_name)
1209/* argument address */
1210#define ARGA(ARG_name) ARG_name
1211/* copy local variable to arg */
1212#define ARG_OUT(ARG_name) /* nothing */
1213
1154 1214
1155int pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg) 1215int pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg)
1156{ 1216{
@@ -1180,206 +1240,243 @@ int pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg)
1180 1240
1181 case VIDIOCPWCSCQUAL: 1241 case VIDIOCPWCSCQUAL:
1182 { 1242 {
1183 int *qual = arg; 1243 ARG_DEF(int, qual)
1184 1244
1185 if (*qual < 0 || *qual > 3) 1245 ARG_IN(qual)
1246 if (ARGR(qual) < 0 || ARGR(qual) > 3)
1186 ret = -EINVAL; 1247 ret = -EINVAL;
1187 else 1248 else
1188 ret = pwc_try_video_mode(pdev, pdev->view.x, pdev->view.y, pdev->vframes, *qual, pdev->vsnapshot); 1249 ret = pwc_try_video_mode(pdev, pdev->view.x, pdev->view.y, pdev->vframes, ARGR(qual), pdev->vsnapshot);
1189 if (ret >= 0) 1250 if (ret >= 0)
1190 pdev->vcompression = *qual; 1251 pdev->vcompression = ARGR(qual);
1191 break; 1252 break;
1192 } 1253 }
1193 1254
1194 case VIDIOCPWCGCQUAL: 1255 case VIDIOCPWCGCQUAL:
1195 { 1256 {
1196 int *qual = arg; 1257 ARG_DEF(int, qual)
1197 *qual = pdev->vcompression; 1258
1259 ARGR(qual) = pdev->vcompression;
1260 ARG_OUT(qual)
1198 break; 1261 break;
1199 } 1262 }
1200 1263
1201 case VIDIOCPWCPROBE: 1264 case VIDIOCPWCPROBE:
1202 { 1265 {
1203 struct pwc_probe *probe = arg; 1266 ARG_DEF(struct pwc_probe, probe)
1204 strcpy(probe->name, pdev->vdev->name); 1267
1205 probe->type = pdev->type; 1268 strcpy(ARGR(probe).name, pdev->vdev->name);
1269 ARGR(probe).type = pdev->type;
1270 ARG_OUT(probe)
1206 break; 1271 break;
1207 } 1272 }
1208 1273
1209 case VIDIOCPWCGSERIAL: 1274 case VIDIOCPWCGSERIAL:
1210 { 1275 {
1211 struct pwc_serial *serial = arg; 1276 ARG_DEF(struct pwc_serial, serial)
1212 strcpy(serial->serial, pdev->serial); 1277
1278 strcpy(ARGR(serial).serial, pdev->serial);
1279 ARG_OUT(serial)
1213 break; 1280 break;
1214 } 1281 }
1215 1282
1216 case VIDIOCPWCSAGC: 1283 case VIDIOCPWCSAGC:
1217 { 1284 {
1218 int *agc = arg; 1285 ARG_DEF(int, agc)
1219 if (pwc_set_agc(pdev, *agc < 0 ? 1 : 0, *agc)) 1286
1287 ARG_IN(agc)
1288 if (pwc_set_agc(pdev, ARGR(agc) < 0 ? 1 : 0, ARGR(agc)))
1220 ret = -EINVAL; 1289 ret = -EINVAL;
1221 break; 1290 break;
1222 } 1291 }
1223 1292
1224 case VIDIOCPWCGAGC: 1293 case VIDIOCPWCGAGC:
1225 { 1294 {
1226 int *agc = arg; 1295 ARG_DEF(int, agc)
1227 1296
1228 if (pwc_get_agc(pdev, agc)) 1297 if (pwc_get_agc(pdev, ARGA(agc)))
1229 ret = -EINVAL; 1298 ret = -EINVAL;
1299 ARG_OUT(agc)
1230 break; 1300 break;
1231 } 1301 }
1232 1302
1233 case VIDIOCPWCSSHUTTER: 1303 case VIDIOCPWCSSHUTTER:
1234 { 1304 {
1235 int *shutter_speed = arg; 1305 ARG_DEF(int, shutter_speed)
1236 ret = pwc_set_shutter_speed(pdev, *shutter_speed < 0 ? 1 : 0, *shutter_speed); 1306
1307 ARG_IN(shutter_speed)
1308 ret = pwc_set_shutter_speed(pdev, ARGR(shutter_speed) < 0 ? 1 : 0, ARGR(shutter_speed));
1237 break; 1309 break;
1238 } 1310 }
1239 1311
1240 case VIDIOCPWCSAWB: 1312 case VIDIOCPWCSAWB:
1241 { 1313 {
1242 struct pwc_whitebalance *wb = arg; 1314 ARG_DEF(struct pwc_whitebalance, wb)
1243 1315
1244 ret = pwc_set_awb(pdev, wb->mode); 1316 ARG_IN(wb)
1245 if (ret >= 0 && wb->mode == PWC_WB_MANUAL) { 1317 ret = pwc_set_awb(pdev, ARGR(wb).mode);
1246 pwc_set_red_gain(pdev, wb->manual_red); 1318 if (ret >= 0 && ARGR(wb).mode == PWC_WB_MANUAL) {
1247 pwc_set_blue_gain(pdev, wb->manual_blue); 1319 pwc_set_red_gain(pdev, ARGR(wb).manual_red);
1320 pwc_set_blue_gain(pdev, ARGR(wb).manual_blue);
1248 } 1321 }
1249 break; 1322 break;
1250 } 1323 }
1251 1324
1252 case VIDIOCPWCGAWB: 1325 case VIDIOCPWCGAWB:
1253 { 1326 {
1254 struct pwc_whitebalance *wb = arg; 1327 ARG_DEF(struct pwc_whitebalance, wb)
1255 1328
1256 memset(wb, 0, sizeof(struct pwc_whitebalance)); 1329 memset(ARGA(wb), 0, sizeof(struct pwc_whitebalance));
1257 wb->mode = pwc_get_awb(pdev); 1330 ARGR(wb).mode = pwc_get_awb(pdev);
1258 if (wb->mode < 0) 1331 if (ARGR(wb).mode < 0)
1259 ret = -EINVAL; 1332 ret = -EINVAL;
1260 else { 1333 else {
1261 if (wb->mode == PWC_WB_MANUAL) { 1334 if (ARGR(wb).mode == PWC_WB_MANUAL) {
1262 ret = pwc_get_red_gain(pdev, &wb->manual_red); 1335 ret = pwc_get_red_gain(pdev, &ARGR(wb).manual_red);
1263 if (ret < 0) 1336 if (ret < 0)
1264 break; 1337 break;
1265 ret = pwc_get_blue_gain(pdev, &wb->manual_blue); 1338 ret = pwc_get_blue_gain(pdev, &ARGR(wb).manual_blue);
1266 if (ret < 0) 1339 if (ret < 0)
1267 break; 1340 break;
1268 } 1341 }
1269 if (wb->mode == PWC_WB_AUTO) { 1342 if (ARGR(wb).mode == PWC_WB_AUTO) {
1270 ret = pwc_read_red_gain(pdev, &wb->read_red); 1343 ret = pwc_read_red_gain(pdev, &ARGR(wb).read_red);
1271 if (ret < 0) 1344 if (ret < 0)
1272 break; 1345 break;
1273 ret = pwc_read_blue_gain(pdev, &wb->read_blue); 1346 ret =pwc_read_blue_gain(pdev, &ARGR(wb).read_blue);
1274 if (ret < 0) 1347 if (ret < 0)
1275 break; 1348 break;
1276 } 1349 }
1277 } 1350 }
1351 ARG_OUT(wb)
1278 break; 1352 break;
1279 } 1353 }
1280 1354
1281 case VIDIOCPWCSAWBSPEED: 1355 case VIDIOCPWCSAWBSPEED:
1282 { 1356 {
1283 struct pwc_wb_speed *wbs = arg; 1357 ARG_DEF(struct pwc_wb_speed, wbs)
1284 1358
1285 if (wbs->control_speed > 0) { 1359 if (ARGR(wbs).control_speed > 0) {
1286 ret = pwc_set_wb_speed(pdev, wbs->control_speed); 1360 ret = pwc_set_wb_speed(pdev, ARGR(wbs).control_speed);
1287 } 1361 }
1288 if (wbs->control_delay > 0) { 1362 if (ARGR(wbs).control_delay > 0) {
1289 ret = pwc_set_wb_delay(pdev, wbs->control_delay); 1363 ret = pwc_set_wb_delay(pdev, ARGR(wbs).control_delay);
1290 } 1364 }
1291 break; 1365 break;
1292 } 1366 }
1293 1367
1294 case VIDIOCPWCGAWBSPEED: 1368 case VIDIOCPWCGAWBSPEED:
1295 { 1369 {
1296 struct pwc_wb_speed *wbs = arg; 1370 ARG_DEF(struct pwc_wb_speed, wbs)
1297 1371
1298 ret = pwc_get_wb_speed(pdev, &wbs->control_speed); 1372 ret = pwc_get_wb_speed(pdev, &ARGR(wbs).control_speed);
1299 if (ret < 0) 1373 if (ret < 0)
1300 break; 1374 break;
1301 ret = pwc_get_wb_delay(pdev, &wbs->control_delay); 1375 ret = pwc_get_wb_delay(pdev, &ARGR(wbs).control_delay);
1302 if (ret < 0) 1376 if (ret < 0)
1303 break; 1377 break;
1378 ARG_OUT(wbs)
1304 break; 1379 break;
1305 } 1380 }
1306 1381
1307 case VIDIOCPWCSLED: 1382 case VIDIOCPWCSLED:
1308 { 1383 {
1309 struct pwc_leds *leds = arg; 1384 ARG_DEF(struct pwc_leds, leds)
1310 ret = pwc_set_leds(pdev, leds->led_on, leds->led_off); 1385
1386 ARG_IN(leds)
1387 ret = pwc_set_leds(pdev, ARGR(leds).led_on, ARGR(leds).led_off);
1311 break; 1388 break;
1312 } 1389 }
1313 1390
1314 1391
1315 case VIDIOCPWCGLED: 1392 case VIDIOCPWCGLED:
1316 { 1393 {
1317 struct pwc_leds *leds = arg; 1394 ARG_DEF(struct pwc_leds, leds)
1318 ret = pwc_get_leds(pdev, &leds->led_on, &leds->led_off); 1395
1396 ret = pwc_get_leds(pdev, &ARGR(leds).led_on, &ARGR(leds).led_off);
1397 ARG_OUT(leds)
1319 break; 1398 break;
1320 } 1399 }
1321 1400
1322 case VIDIOCPWCSCONTOUR: 1401 case VIDIOCPWCSCONTOUR:
1323 { 1402 {
1324 int *contour = arg; 1403 ARG_DEF(int, contour)
1325 ret = pwc_set_contour(pdev, *contour); 1404
1405 ARG_IN(contour)
1406 ret = pwc_set_contour(pdev, ARGR(contour));
1326 break; 1407 break;
1327 } 1408 }
1328 1409
1329 case VIDIOCPWCGCONTOUR: 1410 case VIDIOCPWCGCONTOUR:
1330 { 1411 {
1331 int *contour = arg; 1412 ARG_DEF(int, contour)
1332 ret = pwc_get_contour(pdev, contour); 1413
1414 ret = pwc_get_contour(pdev, ARGA(contour));
1415 ARG_OUT(contour)
1333 break; 1416 break;
1334 } 1417 }
1335 1418
1336 case VIDIOCPWCSBACKLIGHT: 1419 case VIDIOCPWCSBACKLIGHT:
1337 { 1420 {
1338 int *backlight = arg; 1421 ARG_DEF(int, backlight)
1339 ret = pwc_set_backlight(pdev, *backlight); 1422
1423 ARG_IN(backlight)
1424 ret = pwc_set_backlight(pdev, ARGR(backlight));
1340 break; 1425 break;
1341 } 1426 }
1342 1427
1343 case VIDIOCPWCGBACKLIGHT: 1428 case VIDIOCPWCGBACKLIGHT:
1344 { 1429 {
1345 int *backlight = arg; 1430 ARG_DEF(int, backlight)
1346 ret = pwc_get_backlight(pdev, backlight); 1431
1432 ret = pwc_get_backlight(pdev, ARGA(backlight));
1433 ARG_OUT(backlight)
1347 break; 1434 break;
1348 } 1435 }
1349 1436
1350 case VIDIOCPWCSFLICKER: 1437 case VIDIOCPWCSFLICKER:
1351 { 1438 {
1352 int *flicker = arg; 1439 ARG_DEF(int, flicker)
1353 ret = pwc_set_flicker(pdev, *flicker); 1440
1441 ARG_IN(flicker)
1442 ret = pwc_set_flicker(pdev, ARGR(flicker));
1354 break; 1443 break;
1355 } 1444 }
1356 1445
1357 case VIDIOCPWCGFLICKER: 1446 case VIDIOCPWCGFLICKER:
1358 { 1447 {
1359 int *flicker = arg; 1448 ARG_DEF(int, flicker)
1360 ret = pwc_get_flicker(pdev, flicker); 1449
1450 ret = pwc_get_flicker(pdev, ARGA(flicker));
1451 ARG_OUT(flicker)
1361 break; 1452 break;
1362 } 1453 }
1363 1454
1364 case VIDIOCPWCSDYNNOISE: 1455 case VIDIOCPWCSDYNNOISE:
1365 { 1456 {
1366 int *dynnoise = arg; 1457 ARG_DEF(int, dynnoise)
1367 ret = pwc_set_dynamic_noise(pdev, *dynnoise); 1458
1459 ARG_IN(dynnoise)
1460 ret = pwc_set_dynamic_noise(pdev, ARGR(dynnoise));
1368 break; 1461 break;
1369 } 1462 }
1370 1463
1371 case VIDIOCPWCGDYNNOISE: 1464 case VIDIOCPWCGDYNNOISE:
1372 { 1465 {
1373 int *dynnoise = arg; 1466 ARG_DEF(int, dynnoise)
1374 ret = pwc_get_dynamic_noise(pdev, dynnoise); 1467
1468 ret = pwc_get_dynamic_noise(pdev, ARGA(dynnoise));
1469 ARG_OUT(dynnoise);
1375 break; 1470 break;
1376 } 1471 }
1377 1472
1378 case VIDIOCPWCGREALSIZE: 1473 case VIDIOCPWCGREALSIZE:
1379 { 1474 {
1380 struct pwc_imagesize *size = arg; 1475 ARG_DEF(struct pwc_imagesize, size)
1381 size->width = pdev->image.x; 1476
1382 size->height = pdev->image.y; 1477 ARGR(size).width = pdev->image.x;
1478 ARGR(size).height = pdev->image.y;
1479 ARG_OUT(size)
1383 break; 1480 break;
1384 } 1481 }
1385 1482
@@ -1387,14 +1484,10 @@ int pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg)
1387 { 1484 {
1388 if (pdev->features & FEATURE_MOTOR_PANTILT) 1485 if (pdev->features & FEATURE_MOTOR_PANTILT)
1389 { 1486 {
1390 int *flags = arg; 1487 ARG_DEF(int, flags)
1391 1488
1392 ret = pwc_mpt_reset(pdev, *flags); 1489 ARG_IN(flags)
1393 if (ret >= 0) 1490 ret = pwc_mpt_reset(pdev, ARGR(flags));
1394 {
1395 pdev->pan_angle = 0;
1396 pdev->tilt_angle = 0;
1397 }
1398 } 1491 }
1399 else 1492 else
1400 { 1493 {
@@ -1407,8 +1500,10 @@ int pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg)
1407 { 1500 {
1408 if (pdev->features & FEATURE_MOTOR_PANTILT) 1501 if (pdev->features & FEATURE_MOTOR_PANTILT)
1409 { 1502 {
1410 struct pwc_mpt_range *range = arg; 1503 ARG_DEF(struct pwc_mpt_range, range)
1411 *range = pdev->angle_range; 1504
1505 ARGR(range) = pdev->angle_range;
1506 ARG_OUT(range)
1412 } 1507 }
1413 else 1508 else
1414 { 1509 {
@@ -1423,48 +1518,23 @@ int pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg)
1423 1518
1424 if (pdev->features & FEATURE_MOTOR_PANTILT) 1519 if (pdev->features & FEATURE_MOTOR_PANTILT)
1425 { 1520 {
1426 struct pwc_mpt_angles *angles = arg; 1521 ARG_DEF(struct pwc_mpt_angles, angles)
1522
1523 ARG_IN(angles)
1427 /* The camera can only set relative angles, so 1524 /* The camera can only set relative angles, so
1428 do some calculations when getting an absolute angle . 1525 do some calculations when getting an absolute angle .
1429 */ 1526 */
1430 if (angles->absolute) 1527 if (ARGR(angles).absolute)
1431 { 1528 {
1432 new_pan = angles->pan; 1529 new_pan = ARGR(angles).pan;
1433 new_tilt = angles->tilt; 1530 new_tilt = ARGR(angles).tilt;
1434 } 1531 }
1435 else 1532 else
1436 { 1533 {
1437 new_pan = pdev->pan_angle + angles->pan; 1534 new_pan = pdev->pan_angle + ARGR(angles).pan;
1438 new_tilt = pdev->tilt_angle + angles->tilt; 1535 new_tilt = pdev->tilt_angle + ARGR(angles).tilt;
1439 }
1440 /* check absolute ranges */
1441 if (new_pan < pdev->angle_range.pan_min ||
1442 new_pan > pdev->angle_range.pan_max ||
1443 new_tilt < pdev->angle_range.tilt_min ||
1444 new_tilt > pdev->angle_range.tilt_max)
1445 {
1446 ret = -ERANGE;
1447 }
1448 else
1449 {
1450 /* go to relative range, check again */
1451 new_pan -= pdev->pan_angle;
1452 new_tilt -= pdev->tilt_angle;
1453 /* angles are specified in degrees * 100, thus the limit = 36000 */
1454 if (new_pan < -36000 || new_pan > 36000 || new_tilt < -36000 || new_tilt > 36000)
1455 ret = -ERANGE;
1456 }
1457 if (ret == 0) /* no errors so far */
1458 {
1459 ret = pwc_mpt_set_angle(pdev, new_pan, new_tilt);
1460 if (ret >= 0)
1461 {
1462 pdev->pan_angle += new_pan;
1463 pdev->tilt_angle += new_tilt;
1464 }
1465 if (ret == -EPIPE) /* stall -> out of range */
1466 ret = -ERANGE;
1467 } 1536 }
1537 ret = pwc_mpt_set_angle(pdev, new_pan, new_tilt);
1468 } 1538 }
1469 else 1539 else
1470 { 1540 {
@@ -1478,11 +1548,12 @@ int pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg)
1478 1548
1479 if (pdev->features & FEATURE_MOTOR_PANTILT) 1549 if (pdev->features & FEATURE_MOTOR_PANTILT)
1480 { 1550 {
1481 struct pwc_mpt_angles *angles = arg; 1551 ARG_DEF(struct pwc_mpt_angles, angles)
1482 1552
1483 angles->absolute = 1; 1553 ARGR(angles).absolute = 1;
1484 angles->pan = pdev->pan_angle; 1554 ARGR(angles).pan = pdev->pan_angle;
1485 angles->tilt = pdev->tilt_angle; 1555 ARGR(angles).tilt = pdev->tilt_angle;
1556 ARG_OUT(angles)
1486 } 1557 }
1487 else 1558 else
1488 { 1559 {
@@ -1495,8 +1566,10 @@ int pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg)
1495 { 1566 {
1496 if (pdev->features & FEATURE_MOTOR_PANTILT) 1567 if (pdev->features & FEATURE_MOTOR_PANTILT)
1497 { 1568 {
1498 struct pwc_mpt_status *status = arg; 1569 ARG_DEF(struct pwc_mpt_status, status)
1499 ret = pwc_mpt_get_status(pdev, status); 1570
1571 ret = pwc_mpt_get_status(pdev, ARGA(status));
1572 ARG_OUT(status)
1500 } 1573 }
1501 else 1574 else
1502 { 1575 {
@@ -1507,22 +1580,24 @@ int pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg)
1507 1580
1508 case VIDIOCPWCGVIDCMD: 1581 case VIDIOCPWCGVIDCMD:
1509 { 1582 {
1510 struct pwc_video_command *cmd = arg; 1583 ARG_DEF(struct pwc_video_command, cmd);
1511 1584
1512 cmd->type = pdev->type; 1585 ARGR(cmd).type = pdev->type;
1513 cmd->release = pdev->release; 1586 ARGR(cmd).release = pdev->release;
1514 cmd->command_len = pdev->cmd_len; 1587 ARGR(cmd).command_len = pdev->cmd_len;
1515 memcpy(&cmd->command_buf, pdev->cmd_buf, pdev->cmd_len); 1588 memcpy(&ARGR(cmd).command_buf, pdev->cmd_buf, pdev->cmd_len);
1516 cmd->bandlength = pdev->vbandlength; 1589 ARGR(cmd).bandlength = pdev->vbandlength;
1517 cmd->frame_size = pdev->frame_size; 1590 ARGR(cmd).frame_size = pdev->frame_size;
1591 ARG_OUT(cmd)
1518 break; 1592 break;
1519 } 1593 }
1520 /* 1594 /*
1521 case VIDIOCPWCGVIDTABLE: 1595 case VIDIOCPWCGVIDTABLE:
1522 { 1596 {
1523 struct pwc_table_init_buffer *table = arg; 1597 ARG_DEF(struct pwc_table_init_buffer, table);
1524 table->len = pdev->cmd_len; 1598 ARGR(table).len = pdev->cmd_len;
1525 memcpy(&table->buffer, pdev->decompress_data, pdev->decompressor->table_size); 1599 memcpy(&ARGR(table).buffer, pdev->decompress_data, pdev->decompressor->table_size);
1600 ARG_OUT(table)
1526 break; 1601 break;
1527 } 1602 }
1528 */ 1603 */
@@ -1538,4 +1613,4 @@ int pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg)
1538} 1613}
1539 1614
1540 1615
1541 1616/* 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 000000000000..c29593f589eb
--- /dev/null
+++ b/drivers/media/video/pwc/pwc-dec1.c
@@ -0,0 +1,50 @@
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
26
27
28#include "pwc-dec1.h"
29
30
31void pwc_dec1_init(int type, int release, void *buffer, void *table)
32{
33
34}
35
36void pwc_dec1_exit(void)
37{
38
39
40
41}
42
43int pwc_dec1_alloc(struct pwc_device *pwc)
44{
45 pwc->decompress_data = kmalloc(sizeof(struct pwc_dec1_private), GFP_KERNEL);
46 if (pwc->decompress_data == NULL)
47 return -ENOMEM;
48 return 0;
49}
50
diff --git a/drivers/media/video/pwc/pwc-dec1.h b/drivers/media/video/pwc/pwc-dec1.h
new file mode 100644
index 000000000000..8b62ddcc5c7e
--- /dev/null
+++ b/drivers/media/video/pwc/pwc-dec1.h
@@ -0,0 +1,43 @@
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#ifndef PWC_DEC1_H
28#define PWC_DEC1_H
29
30#include "pwc.h"
31
32struct pwc_dec1_private
33{
34 int version;
35
36};
37
38int pwc_dec1_alloc(struct pwc_device *pwc);
39void pwc_dec1_init(int type, int release, void *buffer, void *private_data);
40void pwc_dec1_exit(void);
41
42#endif
43
diff --git a/drivers/media/video/pwc/pwc-dec23.c b/drivers/media/video/pwc/pwc-dec23.c
new file mode 100644
index 000000000000..f9096c72cbb7
--- /dev/null
+++ b/drivers/media/video/pwc/pwc-dec23.c
@@ -0,0 +1,941 @@
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
34/*
35 * USE_LOOKUP_TABLE_TO_CLAMP
36 * 0: use a C version of this tests: { a<0?0:(a>255?255:a) }
37 * 1: use a faster lookup table for cpu with a big cache (intel)
38 */
39#define USE_LOOKUP_TABLE_TO_CLAMP 1
40/*
41 * UNROLL_LOOP_FOR_COPYING_BLOCK
42 * 0: use a loop for a smaller code (but little slower)
43 * 1: when unrolling the loop, gcc produces some faster code (perhaps only
44 * valid for intel processor class). Activating this option, automaticaly
45 * activate USE_LOOKUP_TABLE_TO_CLAMP
46 */
47#define UNROLL_LOOP_FOR_COPY 1
48#if UNROLL_LOOP_FOR_COPY
49# undef USE_LOOKUP_TABLE_TO_CLAMP
50# define USE_LOOKUP_TABLE_TO_CLAMP 1
51#endif
52
53/*
54 * ENABLE_BAYER_DECODER
55 * 0: bayer decoder is not build (save some space)
56 * 1: bayer decoder is build and can be used
57 */
58#define ENABLE_BAYER_DECODER 0
59
60static void build_subblock_pattern(struct pwc_dec23_private *pdec)
61{
62 static const unsigned int initial_values[12] = {
63 -0x526500, -0x221200, 0x221200, 0x526500,
64 -0x3de200, 0x3de200,
65 -0x6db480, -0x2d5d00, 0x2d5d00, 0x6db480,
66 -0x12c200, 0x12c200
67
68 };
69 static const unsigned int values_derivated[12] = {
70 0xa4ca, 0x4424, -0x4424, -0xa4ca,
71 0x7bc4, -0x7bc4,
72 0xdb69, 0x5aba, -0x5aba, -0xdb69,
73 0x2584, -0x2584
74 };
75 unsigned int temp_values[12];
76 int i, j;
77
78 memcpy(temp_values, initial_values, sizeof(initial_values));
79 for (i = 0; i < 256; i++) {
80 for (j = 0; j < 12; j++) {
81 pdec->table_subblock[i][j] = temp_values[j];
82 temp_values[j] += values_derivated[j];
83 }
84 }
85}
86
87static void build_bit_powermask_table(struct pwc_dec23_private *pdec)
88{
89 unsigned char *p;
90 unsigned int bit, byte, mask, val;
91 unsigned int bitpower = 1;
92
93 for (bit = 0; bit < 8; bit++) {
94 mask = bitpower - 1;
95 p = pdec->table_bitpowermask[bit];
96 for (byte = 0; byte < 256; byte++) {
97 val = (byte & mask);
98 if (byte & bitpower)
99 val = -val;
100 *p++ = val;
101 }
102 bitpower<<=1;
103 }
104}
105
106
107static void build_table_color(const unsigned int romtable[16][8],
108 unsigned char p0004[16][1024],
109 unsigned char p8004[16][256])
110{
111 int compression_mode, j, k, bit, pw;
112 unsigned char *p0, *p8;
113 const unsigned int *r;
114
115 /* We have 16 compressions tables */
116 for (compression_mode = 0; compression_mode < 16; compression_mode++) {
117 p0 = p0004[compression_mode];
118 p8 = p8004[compression_mode];
119 r = romtable[compression_mode];
120
121 for (j = 0; j < 8; j++, r++, p0 += 128) {
122
123 for (k = 0; k < 16; k++) {
124 if (k == 0)
125 bit = 1;
126 else if (k >= 1 && k < 3)
127 bit = (r[0] >> 15) & 7;
128 else if (k >= 3 && k < 6)
129 bit = (r[0] >> 12) & 7;
130 else if (k >= 6 && k < 10)
131 bit = (r[0] >> 9) & 7;
132 else if (k >= 10 && k < 13)
133 bit = (r[0] >> 6) & 7;
134 else if (k >= 13 && k < 15)
135 bit = (r[0] >> 3) & 7;
136 else
137 bit = (r[0]) & 7;
138 if (k == 0)
139 *p8++ = 8;
140 else
141 *p8++ = j - bit;
142 *p8++ = bit;
143
144 pw = 1 << bit;
145 p0[k + 0x00] = (1 * pw) + 0x80;
146 p0[k + 0x10] = (2 * pw) + 0x80;
147 p0[k + 0x20] = (3 * pw) + 0x80;
148 p0[k + 0x30] = (4 * pw) + 0x80;
149 p0[k + 0x40] = (-1 * pw) + 0x80;
150 p0[k + 0x50] = (-2 * pw) + 0x80;
151 p0[k + 0x60] = (-3 * pw) + 0x80;
152 p0[k + 0x70] = (-4 * pw) + 0x80;
153 } /* end of for (k=0; k<16; k++, p8++) */
154 } /* end of for (j=0; j<8; j++ , table++) */
155 } /* end of foreach compression_mode */
156}
157
158/*
159 *
160 */
161static void fill_table_dc00_d800(struct pwc_dec23_private *pdec)
162{
163#define SCALEBITS 15
164#define ONE_HALF (1UL << (SCALEBITS - 1))
165 int i;
166 unsigned int offset1 = ONE_HALF;
167 unsigned int offset2 = 0x0000;
168
169 for (i=0; i<256; i++) {
170 pdec->table_dc00[i] = offset1 & ~(ONE_HALF);
171 pdec->table_d800[i] = offset2;
172
173 offset1 += 0x7bc4;
174 offset2 += 0x7bc4;
175 }
176}
177
178/*
179 * To decode the stream:
180 * if look_bits(2) == 0: # op == 2 in the lookup table
181 * skip_bits(2)
182 * end of the stream
183 * elif look_bits(3) == 7: # op == 1 in the lookup table
184 * skip_bits(3)
185 * yyyy = get_bits(4)
186 * xxxx = get_bits(8)
187 * else: # op == 0 in the lookup table
188 * skip_bits(x)
189 *
190 * For speedup processing, we build a lookup table and we takes the first 6 bits.
191 *
192 * struct {
193 * unsigned char op; // operation to execute
194 * unsigned char bits; // bits use to perform operation
195 * unsigned char offset1; // offset to add to access in the table_0004 % 16
196 * unsigned char offset2; // offset to add to access in the table_0004
197 * }
198 *
199 * How to build this table ?
200 * op == 2 when (i%4)==0
201 * op == 1 when (i%8)==7
202 * op == 0 otherwise
203 *
204 */
205static const unsigned char hash_table_ops[64*4] = {
206 0x02, 0x00, 0x00, 0x00,
207 0x00, 0x03, 0x01, 0x00,
208 0x00, 0x04, 0x01, 0x10,
209 0x00, 0x06, 0x01, 0x30,
210 0x02, 0x00, 0x00, 0x00,
211 0x00, 0x03, 0x01, 0x40,
212 0x00, 0x05, 0x01, 0x20,
213 0x01, 0x00, 0x00, 0x00,
214 0x02, 0x00, 0x00, 0x00,
215 0x00, 0x03, 0x01, 0x00,
216 0x00, 0x04, 0x01, 0x50,
217 0x00, 0x05, 0x02, 0x00,
218 0x02, 0x00, 0x00, 0x00,
219 0x00, 0x03, 0x01, 0x40,
220 0x00, 0x05, 0x03, 0x00,
221 0x01, 0x00, 0x00, 0x00,
222 0x02, 0x00, 0x00, 0x00,
223 0x00, 0x03, 0x01, 0x00,
224 0x00, 0x04, 0x01, 0x10,
225 0x00, 0x06, 0x02, 0x10,
226 0x02, 0x00, 0x00, 0x00,
227 0x00, 0x03, 0x01, 0x40,
228 0x00, 0x05, 0x01, 0x60,
229 0x01, 0x00, 0x00, 0x00,
230 0x02, 0x00, 0x00, 0x00,
231 0x00, 0x03, 0x01, 0x00,
232 0x00, 0x04, 0x01, 0x50,
233 0x00, 0x05, 0x02, 0x40,
234 0x02, 0x00, 0x00, 0x00,
235 0x00, 0x03, 0x01, 0x40,
236 0x00, 0x05, 0x03, 0x40,
237 0x01, 0x00, 0x00, 0x00,
238 0x02, 0x00, 0x00, 0x00,
239 0x00, 0x03, 0x01, 0x00,
240 0x00, 0x04, 0x01, 0x10,
241 0x00, 0x06, 0x01, 0x70,
242 0x02, 0x00, 0x00, 0x00,
243 0x00, 0x03, 0x01, 0x40,
244 0x00, 0x05, 0x01, 0x20,
245 0x01, 0x00, 0x00, 0x00,
246 0x02, 0x00, 0x00, 0x00,
247 0x00, 0x03, 0x01, 0x00,
248 0x00, 0x04, 0x01, 0x50,
249 0x00, 0x05, 0x02, 0x00,
250 0x02, 0x00, 0x00, 0x00,
251 0x00, 0x03, 0x01, 0x40,
252 0x00, 0x05, 0x03, 0x00,
253 0x01, 0x00, 0x00, 0x00,
254 0x02, 0x00, 0x00, 0x00,
255 0x00, 0x03, 0x01, 0x00,
256 0x00, 0x04, 0x01, 0x10,
257 0x00, 0x06, 0x02, 0x50,
258 0x02, 0x00, 0x00, 0x00,
259 0x00, 0x03, 0x01, 0x40,
260 0x00, 0x05, 0x01, 0x60,
261 0x01, 0x00, 0x00, 0x00,
262 0x02, 0x00, 0x00, 0x00,
263 0x00, 0x03, 0x01, 0x00,
264 0x00, 0x04, 0x01, 0x50,
265 0x00, 0x05, 0x02, 0x40,
266 0x02, 0x00, 0x00, 0x00,
267 0x00, 0x03, 0x01, 0x40,
268 0x00, 0x05, 0x03, 0x40,
269 0x01, 0x00, 0x00, 0x00
270};
271
272/*
273 *
274 */
275static const unsigned int MulIdx[16][16] = {
276 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,},
277 {0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3,},
278 {0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3,},
279 {4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 4, 4, 4, 4,},
280 {6, 7, 8, 9, 7, 10, 11, 8, 8, 11, 10, 7, 9, 8, 7, 6,},
281 {4, 5, 5, 4, 4, 5, 5, 4, 4, 5, 5, 4, 4, 5, 5, 4,},
282 {1, 3, 0, 2, 1, 3, 0, 2, 1, 3, 0, 2, 1, 3, 0, 2,},
283 {0, 3, 3, 0, 1, 2, 2, 1, 2, 1, 1, 2, 3, 0, 0, 3,},
284 {0, 1, 2, 3, 3, 2, 1, 0, 3, 2, 1, 0, 0, 1, 2, 3,},
285 {1, 1, 1, 1, 3, 3, 3, 3, 0, 0, 0, 0, 2, 2, 2, 2,},
286 {7, 10, 11, 8, 9, 8, 7, 6, 6, 7, 8, 9, 8, 11, 10, 7,},
287 {4, 5, 5, 4, 5, 4, 4, 5, 5, 4, 4, 5, 4, 5, 5, 4,},
288 {7, 9, 6, 8, 10, 8, 7, 11, 11, 7, 8, 10, 8, 6, 9, 7,},
289 {1, 3, 0, 2, 2, 0, 3, 1, 2, 0, 3, 1, 1, 3, 0, 2,},
290 {1, 2, 2, 1, 3, 0, 0, 3, 0, 3, 3, 0, 2, 1, 1, 2,},
291 {10, 8, 7, 11, 8, 6, 9, 7, 7, 9, 6, 8, 11, 7, 8, 10}
292};
293
294#if USE_LOOKUP_TABLE_TO_CLAMP
295#define MAX_OUTER_CROP_VALUE (512)
296static unsigned char pwc_crop_table[256 + 2*MAX_OUTER_CROP_VALUE];
297#define CLAMP(x) (pwc_crop_table[MAX_OUTER_CROP_VALUE+(x)])
298#else
299#define CLAMP(x) ((x)>255?255:((x)<0?0:x))
300#endif
301
302
303/* If the type or the command change, we rebuild the lookup table */
304int pwc_dec23_init(struct pwc_device *pwc, int type, unsigned char *cmd)
305{
306 int flags, version, shift, i;
307 struct pwc_dec23_private *pdec;
308
309 if (pwc->decompress_data == NULL) {
310 pdec = kmalloc(sizeof(struct pwc_dec23_private), GFP_KERNEL);
311 if (pdec == NULL)
312 return -ENOMEM;
313 pwc->decompress_data = pdec;
314 }
315 pdec = pwc->decompress_data;
316
317 if (DEVICE_USE_CODEC3(type)) {
318 flags = cmd[2] & 0x18;
319 if (flags == 8)
320 pdec->nbits = 7; /* More bits, mean more bits to encode the stream, but better quality */
321 else if (flags == 0x10)
322 pdec->nbits = 8;
323 else
324 pdec->nbits = 6;
325
326 version = cmd[2] >> 5;
327 build_table_color(KiaraRomTable[version][0], pdec->table_0004_pass1, pdec->table_8004_pass1);
328 build_table_color(KiaraRomTable[version][1], pdec->table_0004_pass2, pdec->table_8004_pass2);
329
330 } else {
331
332 flags = cmd[2] & 6;
333 if (flags == 2)
334 pdec->nbits = 7;
335 else if (flags == 4)
336 pdec->nbits = 8;
337 else
338 pdec->nbits = 6;
339
340 version = cmd[2] >> 3;
341 build_table_color(TimonRomTable[version][0], pdec->table_0004_pass1, pdec->table_8004_pass1);
342 build_table_color(TimonRomTable[version][1], pdec->table_0004_pass2, pdec->table_8004_pass2);
343 }
344
345 /* Informations can be coded on a variable number of bits but never less than 8 */
346 shift = 8 - pdec->nbits;
347 pdec->scalebits = SCALEBITS - shift;
348 pdec->nbitsmask = 0xFF >> shift;
349
350 fill_table_dc00_d800(pdec);
351 build_subblock_pattern(pdec);
352 build_bit_powermask_table(pdec);
353
354#if USE_LOOKUP_TABLE_TO_CLAMP
355 /* Build the static table to clamp value [0-255] */
356 for (i=0;i<MAX_OUTER_CROP_VALUE;i++)
357 pwc_crop_table[i] = 0;
358 for (i=0; i<256; i++)
359 pwc_crop_table[MAX_OUTER_CROP_VALUE+i] = i;
360 for (i=0; i<MAX_OUTER_CROP_VALUE; i++)
361 pwc_crop_table[MAX_OUTER_CROP_VALUE+256+i] = 255;
362#endif
363
364 return 0;
365}
366
367/*
368 * Copy the 4x4 image block to Y plane buffer
369 */
370static void copy_image_block_Y(const int *src, unsigned char *dst, unsigned int bytes_per_line, unsigned int scalebits)
371{
372#if UNROLL_LOOP_FOR_COPY
373 const unsigned char *cm = pwc_crop_table+MAX_OUTER_CROP_VALUE;
374 const int *c = src;
375 unsigned char *d = dst;
376
377 *d++ = cm[c[0] >> scalebits];
378 *d++ = cm[c[1] >> scalebits];
379 *d++ = cm[c[2] >> scalebits];
380 *d++ = cm[c[3] >> scalebits];
381
382 d = dst + bytes_per_line;
383 *d++ = cm[c[4] >> scalebits];
384 *d++ = cm[c[5] >> scalebits];
385 *d++ = cm[c[6] >> scalebits];
386 *d++ = cm[c[7] >> scalebits];
387
388 d = dst + bytes_per_line*2;
389 *d++ = cm[c[8] >> scalebits];
390 *d++ = cm[c[9] >> scalebits];
391 *d++ = cm[c[10] >> scalebits];
392 *d++ = cm[c[11] >> scalebits];
393
394 d = dst + bytes_per_line*3;
395 *d++ = cm[c[12] >> scalebits];
396 *d++ = cm[c[13] >> scalebits];
397 *d++ = cm[c[14] >> scalebits];
398 *d++ = cm[c[15] >> scalebits];
399#else
400 int i;
401 const int *c = src;
402 unsigned char *d = dst;
403 for (i = 0; i < 4; i++, c++)
404 *d++ = CLAMP((*c) >> scalebits);
405
406 d = dst + bytes_per_line;
407 for (i = 0; i < 4; i++, c++)
408 *d++ = CLAMP((*c) >> scalebits);
409
410 d = dst + bytes_per_line*2;
411 for (i = 0; i < 4; i++, c++)
412 *d++ = CLAMP((*c) >> scalebits);
413
414 d = dst + bytes_per_line*3;
415 for (i = 0; i < 4; i++, c++)
416 *d++ = CLAMP((*c) >> scalebits);
417#endif
418}
419
420/*
421 * Copy the 4x4 image block to a CrCb plane buffer
422 *
423 */
424static void copy_image_block_CrCb(const int *src, unsigned char *dst, unsigned int bytes_per_line, unsigned int scalebits)
425{
426#if UNROLL_LOOP_FOR_COPY
427 /* Unroll all loops */
428 const unsigned char *cm = pwc_crop_table+MAX_OUTER_CROP_VALUE;
429 const int *c = src;
430 unsigned char *d = dst;
431
432 *d++ = cm[c[0] >> scalebits];
433 *d++ = cm[c[4] >> scalebits];
434 *d++ = cm[c[1] >> scalebits];
435 *d++ = cm[c[5] >> scalebits];
436 *d++ = cm[c[2] >> scalebits];
437 *d++ = cm[c[6] >> scalebits];
438 *d++ = cm[c[3] >> scalebits];
439 *d++ = cm[c[7] >> scalebits];
440
441 d = dst + bytes_per_line;
442 *d++ = cm[c[12] >> scalebits];
443 *d++ = cm[c[8] >> scalebits];
444 *d++ = cm[c[13] >> scalebits];
445 *d++ = cm[c[9] >> scalebits];
446 *d++ = cm[c[14] >> scalebits];
447 *d++ = cm[c[10] >> scalebits];
448 *d++ = cm[c[15] >> scalebits];
449 *d++ = cm[c[11] >> scalebits];
450#else
451 int i;
452 const int *c1 = src;
453 const int *c2 = src + 4;
454 unsigned char *d = dst;
455
456 for (i = 0; i < 4; i++, c1++, c2++) {
457 *d++ = CLAMP((*c1) >> scalebits);
458 *d++ = CLAMP((*c2) >> scalebits);
459 }
460 c1 = src + 12;
461 d = dst + bytes_per_line;
462 for (i = 0; i < 4; i++, c1++, c2++) {
463 *d++ = CLAMP((*c1) >> scalebits);
464 *d++ = CLAMP((*c2) >> scalebits);
465 }
466#endif
467}
468
469#if ENABLE_BAYER_DECODER
470/*
471 * Format: 8x2 pixels
472 * . G . G . G . G . G . G . G
473 * . . . . . . . . . . . . . .
474 * . G . G . G . G . G . G . G
475 * . . . . . . . . . . . . . .
476 * or
477 * . . . . . . . . . . . . . .
478 * G . G . G . G . G . G . G .
479 * . . . . . . . . . . . . . .
480 * G . G . G . G . G . G . G .
481*/
482static void copy_image_block_Green(const int *src, unsigned char *dst, unsigned int bytes_per_line, unsigned int scalebits)
483{
484#if UNROLL_LOOP_FOR_COPY
485 /* Unroll all loops */
486 const unsigned char *cm = pwc_crop_table+MAX_OUTER_CROP_VALUE;
487 unsigned char *d = dst;
488 const int *c = src;
489
490 d[0] = cm[c[0] >> scalebits];
491 d[2] = cm[c[1] >> scalebits];
492 d[4] = cm[c[2] >> scalebits];
493 d[6] = cm[c[3] >> scalebits];
494 d[8] = cm[c[4] >> scalebits];
495 d[10] = cm[c[5] >> scalebits];
496 d[12] = cm[c[6] >> scalebits];
497 d[14] = cm[c[7] >> scalebits];
498
499 d = dst + bytes_per_line;
500 d[0] = cm[c[8] >> scalebits];
501 d[2] = cm[c[9] >> scalebits];
502 d[4] = cm[c[10] >> scalebits];
503 d[6] = cm[c[11] >> scalebits];
504 d[8] = cm[c[12] >> scalebits];
505 d[10] = cm[c[13] >> scalebits];
506 d[12] = cm[c[14] >> scalebits];
507 d[14] = cm[c[15] >> scalebits];
508#else
509 int i;
510 unsigned char *d;
511 const int *c = src;
512
513 d = dst;
514 for (i = 0; i < 8; i++, c++)
515 d[i*2] = CLAMP((*c) >> scalebits);
516
517 d = dst + bytes_per_line;
518 for (i = 0; i < 8; i++, c++)
519 d[i*2] = CLAMP((*c) >> scalebits);
520#endif
521}
522#endif
523
524#if ENABLE_BAYER_DECODER
525/*
526 * Format: 4x4 pixels
527 * R . R . R . R
528 * . B . B . B .
529 * R . R . R . R
530 * . B . B . B .
531 */
532static void copy_image_block_RedBlue(const int *src, unsigned char *dst, unsigned int bytes_per_line, unsigned int scalebits)
533{
534#if UNROLL_LOOP_FOR_COPY
535 /* Unroll all loops */
536 const unsigned char *cm = pwc_crop_table+MAX_OUTER_CROP_VALUE;
537 unsigned char *d = dst;
538 const int *c = src;
539
540 d[0] = cm[c[0] >> scalebits];
541 d[2] = cm[c[1] >> scalebits];
542 d[4] = cm[c[2] >> scalebits];
543 d[6] = cm[c[3] >> scalebits];
544
545 d = dst + bytes_per_line;
546 d[1] = cm[c[4] >> scalebits];
547 d[3] = cm[c[5] >> scalebits];
548 d[5] = cm[c[6] >> scalebits];
549 d[7] = cm[c[7] >> scalebits];
550
551 d = dst + bytes_per_line*2;
552 d[0] = cm[c[8] >> scalebits];
553 d[2] = cm[c[9] >> scalebits];
554 d[4] = cm[c[10] >> scalebits];
555 d[6] = cm[c[11] >> scalebits];
556
557 d = dst + bytes_per_line*3;
558 d[1] = cm[c[12] >> scalebits];
559 d[3] = cm[c[13] >> scalebits];
560 d[5] = cm[c[14] >> scalebits];
561 d[7] = cm[c[15] >> scalebits];
562#else
563 int i;
564 unsigned char *d;
565 const int *c = src;
566
567 d = dst;
568 for (i = 0; i < 4; i++, c++)
569 d[i*2] = CLAMP((*c) >> scalebits);
570
571 d = dst + bytes_per_line;
572 for (i = 0; i < 4; i++, c++)
573 d[i*2+1] = CLAMP((*c) >> scalebits);
574
575 d = dst + bytes_per_line*2;
576 for (i = 0; i < 4; i++, c++)
577 d[i*2] = CLAMP((*c) >> scalebits);
578
579 d = dst + bytes_per_line*3;
580 for (i = 0; i < 4; i++, c++)
581 d[i*2+1] = CLAMP((*c) >> scalebits);
582#endif
583}
584#endif
585
586/*
587 * To manage the stream, we keep bits in a 32 bits register.
588 * fill_nbits(n): fill the reservoir with at least n bits
589 * skip_bits(n): discard n bits from the reservoir
590 * get_bits(n): fill the reservoir, returns the first n bits and discard the
591 * bits from the reservoir.
592 * __get_nbits(n): faster version of get_bits(n), but asumes that the reservoir
593 * contains at least n bits. bits returned is discarded.
594 */
595#define fill_nbits(pdec, nbits_wanted) do { \
596 while (pdec->nbits_in_reservoir<(nbits_wanted)) \
597 { \
598 pdec->reservoir |= (*(pdec->stream)++) << (pdec->nbits_in_reservoir); \
599 pdec->nbits_in_reservoir += 8; \
600 } \
601} while(0);
602
603#define skip_nbits(pdec, nbits_to_skip) do { \
604 pdec->reservoir >>= (nbits_to_skip); \
605 pdec->nbits_in_reservoir -= (nbits_to_skip); \
606} while(0);
607
608#define get_nbits(pdec, nbits_wanted, result) do { \
609 fill_nbits(pdec, nbits_wanted); \
610 result = (pdec->reservoir) & ((1U<<(nbits_wanted))-1); \
611 skip_nbits(pdec, nbits_wanted); \
612} while(0);
613
614#define __get_nbits(pdec, nbits_wanted, result) do { \
615 result = (pdec->reservoir) & ((1U<<(nbits_wanted))-1); \
616 skip_nbits(pdec, nbits_wanted); \
617} while(0);
618
619#define look_nbits(pdec, nbits_wanted) \
620 ((pdec->reservoir) & ((1U<<(nbits_wanted))-1))
621
622/*
623 * Decode a 4x4 pixel block
624 */
625static void decode_block(struct pwc_dec23_private *pdec,
626 const unsigned char *ptable0004,
627 const unsigned char *ptable8004)
628{
629 unsigned int primary_color;
630 unsigned int channel_v, offset1, op;
631 int i;
632
633 fill_nbits(pdec, 16);
634 __get_nbits(pdec, pdec->nbits, primary_color);
635
636 if (look_nbits(pdec,2) == 0) {
637 skip_nbits(pdec, 2);
638 /* Very simple, the color is the same for all pixels of the square */
639 for (i = 0; i < 16; i++)
640 pdec->temp_colors[i] = pdec->table_dc00[primary_color];
641
642 return;
643 }
644
645 /* This block is encoded with small pattern */
646 for (i = 0; i < 16; i++)
647 pdec->temp_colors[i] = pdec->table_d800[primary_color];
648
649 __get_nbits(pdec, 3, channel_v);
650 channel_v = ((channel_v & 1) << 2) | (channel_v & 2) | ((channel_v & 4) >> 2);
651
652 ptable0004 += (channel_v * 128);
653 ptable8004 += (channel_v * 32);
654
655 offset1 = 0;
656 do
657 {
658 unsigned int htable_idx, rows = 0;
659 const unsigned int *block;
660
661 /* [ zzzz y x x ]
662 * xx == 00 :=> end of the block def, remove the two bits from the stream
663 * yxx == 111
664 * yxx == any other value
665 *
666 */
667 fill_nbits(pdec, 16);
668 htable_idx = look_nbits(pdec, 6);
669 op = hash_table_ops[htable_idx * 4];
670
671 if (op == 2) {
672 skip_nbits(pdec, 2);
673
674 } else if (op == 1) {
675 /* 15bits [ xxxx xxxx yyyy 111 ]
676 * yyy => offset in the table8004
677 * xxx => offset in the tabled004 (tree)
678 */
679 unsigned int mask, shift;
680 unsigned int nbits, col1;
681 unsigned int yyyy;
682
683 skip_nbits(pdec, 3);
684 /* offset1 += yyyy */
685 __get_nbits(pdec, 4, yyyy);
686 offset1 += 1 + yyyy;
687 offset1 &= 0x0F;
688 nbits = ptable8004[offset1 * 2];
689
690 /* col1 = xxxx xxxx */
691 __get_nbits(pdec, nbits+1, col1);
692
693 /* Bit mask table */
694 mask = pdec->table_bitpowermask[nbits][col1];
695 shift = ptable8004[offset1 * 2 + 1];
696 rows = ((mask << shift) + 0x80) & 0xFF;
697
698 block = pdec->table_subblock[rows];
699 for (i = 0; i < 16; i++)
700 pdec->temp_colors[i] += block[MulIdx[offset1][i]];
701
702 } else {
703 /* op == 0
704 * offset1 is coded on 3 bits
705 */
706 unsigned int shift;
707
708 offset1 += hash_table_ops [htable_idx * 4 + 2];
709 offset1 &= 0x0F;
710
711 rows = ptable0004[offset1 + hash_table_ops [htable_idx * 4 + 3]];
712 block = pdec->table_subblock[rows];
713 for (i = 0; i < 16; i++)
714 pdec->temp_colors[i] += block[MulIdx[offset1][i]];
715
716 shift = hash_table_ops[htable_idx * 4 + 1];
717 skip_nbits(pdec, shift);
718 }
719
720 } while (op != 2);
721
722}
723
724static void DecompressBand23(struct pwc_dec23_private *pdec,
725 const unsigned char *rawyuv,
726 unsigned char *planar_y,
727 unsigned char *planar_u,
728 unsigned char *planar_v,
729 unsigned int compressed_image_width,
730 unsigned int real_image_width)
731{
732 int compression_index, nblocks;
733 const unsigned char *ptable0004;
734 const unsigned char *ptable8004;
735
736 pdec->reservoir = 0;
737 pdec->nbits_in_reservoir = 0;
738 pdec->stream = rawyuv + 1; /* The first byte of the stream is skipped */
739
740 get_nbits(pdec, 4, compression_index);
741
742 /* pass 1: uncompress Y component */
743 nblocks = compressed_image_width / 4;
744
745 ptable0004 = pdec->table_0004_pass1[compression_index];
746 ptable8004 = pdec->table_8004_pass1[compression_index];
747
748 /* Each block decode a square of 4x4 */
749 while (nblocks) {
750 decode_block(pdec, ptable0004, ptable8004);
751 copy_image_block_Y(pdec->temp_colors, planar_y, real_image_width, pdec->scalebits);
752 planar_y += 4;
753 nblocks--;
754 }
755
756 /* pass 2: uncompress UV component */
757 nblocks = compressed_image_width / 8;
758
759 ptable0004 = pdec->table_0004_pass2[compression_index];
760 ptable8004 = pdec->table_8004_pass2[compression_index];
761
762 /* Each block decode a square of 4x4 */
763 while (nblocks) {
764 decode_block(pdec, ptable0004, ptable8004);
765 copy_image_block_CrCb(pdec->temp_colors, planar_u, real_image_width/2, pdec->scalebits);
766
767 decode_block(pdec, ptable0004, ptable8004);
768 copy_image_block_CrCb(pdec->temp_colors, planar_v, real_image_width/2, pdec->scalebits);
769
770 planar_v += 8;
771 planar_u += 8;
772 nblocks -= 2;
773 }
774
775}
776
777#if ENABLE_BAYER_DECODER
778/*
779 * Size need to be a multiple of 8 in width
780 *
781 * Return a block of four line encoded like this:
782 *
783 * G R G R G R G R G R G R G R G R
784 * B G B G B G B G B G B G B G B G
785 * G R G R G R G R G R G R G R G R
786 * B G B G B G B G B G B G B G B G
787 *
788 */
789static void DecompressBandBayer(struct pwc_dec23_private *pdec,
790 const unsigned char *rawyuv,
791 unsigned char *rgbbayer,
792 unsigned int compressed_image_width,
793 unsigned int real_image_width)
794{
795 int compression_index, nblocks;
796 const unsigned char *ptable0004;
797 const unsigned char *ptable8004;
798 unsigned char *dest;
799
800 pdec->reservoir = 0;
801 pdec->nbits_in_reservoir = 0;
802 pdec->stream = rawyuv + 1; /* The first byte of the stream is skipped */
803
804 get_nbits(pdec, 4, compression_index);
805
806 /* pass 1: uncompress RB component */
807 nblocks = compressed_image_width / 4;
808
809 ptable0004 = pdec->table_0004_pass1[compression_index];
810 ptable8004 = pdec->table_8004_pass1[compression_index];
811 dest = rgbbayer;
812
813 /* Each block decode a square of 4x4 */
814 while (nblocks) {
815 decode_block(pdec, ptable0004, ptable8004);
816 copy_image_block_RedBlue(pdec->temp_colors, rgbbayer, real_image_width, pdec->scalebits);
817 dest += 8;
818 nblocks--;
819 }
820
821 /* pass 2: uncompress G component */
822 nblocks = compressed_image_width / 8;
823
824 ptable0004 = pdec->table_0004_pass2[compression_index];
825 ptable8004 = pdec->table_8004_pass2[compression_index];
826
827 /* Each block decode a square of 4x4 */
828 while (nblocks) {
829 decode_block(pdec, ptable0004, ptable8004);
830 copy_image_block_Green(pdec->temp_colors, rgbbayer+1, real_image_width, pdec->scalebits);
831
832 decode_block(pdec, ptable0004, ptable8004);
833 copy_image_block_Green(pdec->temp_colors, rgbbayer+real_image_width, real_image_width, pdec->scalebits);
834
835 rgbbayer += 16;
836 nblocks -= 2;
837 }
838}
839#endif
840
841
842/**
843 *
844 * Uncompress a pwc23 buffer.
845 *
846 * pwc.view: size of the image wanted
847 * pwc.image: size of the image returned by the camera
848 * pwc.offset: (x,y) to displayer image in the view
849 *
850 * src: raw data
851 * dst: image output
852 * flags: PWCX_FLAG_PLANAR or PWCX_FLAG_BAYER
853 */
854void pwc_dec23_decompress(const struct pwc_device *pwc,
855 const void *src,
856 void *dst,
857 int flags)
858{
859 int bandlines_left, stride, bytes_per_block;
860
861 bandlines_left = pwc->image.y / 4;
862 bytes_per_block = pwc->view.x * 4;
863
864 if (flags & PWCX_FLAG_BAYER) {
865#if ENABLE_BAYER_DECODER
866 /* RGB Bayer format */
867 unsigned char *rgbout;
868
869 stride = pwc->view.x * pwc->offset.y;
870 rgbout = dst + stride + pwc->offset.x;
871
872
873 while (bandlines_left--) {
874
875 DecompressBandBayer(pwc->decompress_data,
876 src,
877 rgbout,
878 pwc->image.x, pwc->view.x);
879
880 src += pwc->vbandlength;
881 rgbout += bytes_per_block;
882
883 }
884#else
885 memcpy(dst, 0, pwc->view.x * pwc->view.y);
886#endif
887
888 } else {
889 /* YUV420P image format */
890 unsigned char *pout_planar_y;
891 unsigned char *pout_planar_u;
892 unsigned char *pout_planar_v;
893 unsigned int plane_size;
894
895 plane_size = pwc->view.x * pwc->view.y;
896
897 /* offset in Y plane */
898 stride = pwc->view.x * pwc->offset.y;
899 pout_planar_y = dst + stride + pwc->offset.x;
900
901 /* offsets in U/V planes */
902 stride = (pwc->view.x * pwc->offset.y) / 4 + pwc->offset.x / 2;
903 pout_planar_u = dst + plane_size + stride;
904 pout_planar_v = dst + plane_size + plane_size / 4 + stride;
905
906 while (bandlines_left--) {
907
908 DecompressBand23(pwc->decompress_data,
909 src,
910 pout_planar_y, pout_planar_u, pout_planar_v,
911 pwc->image.x, pwc->view.x);
912 src += pwc->vbandlength;
913 pout_planar_y += bytes_per_block;
914 pout_planar_u += pwc->view.x;
915 pout_planar_v += pwc->view.x;
916
917 }
918
919 }
920
921}
922
923void pwc_dec23_exit(void)
924{
925 /* Do nothing */
926
927}
928
929/**
930 * Allocate a private structure used by lookup table.
931 * You must call kfree() to free the memory allocated.
932 */
933int pwc_dec23_alloc(struct pwc_device *pwc)
934{
935 pwc->decompress_data = kmalloc(sizeof(struct pwc_dec23_private), GFP_KERNEL);
936 if (pwc->decompress_data == NULL)
937 return -ENOMEM;
938 return 0;
939}
940
941/* vim: set cino= formatoptions=croql cindent shiftwidth=8 tabstop=8: */
diff --git a/drivers/media/video/pwc/pwc-dec23.h b/drivers/media/video/pwc/pwc-dec23.h
new file mode 100644
index 000000000000..1c55298ad153
--- /dev/null
+++ b/drivers/media/video/pwc/pwc-dec23.h
@@ -0,0 +1,67 @@
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
52
53int pwc_dec23_alloc(struct pwc_device *pwc);
54int pwc_dec23_init(struct pwc_device *pwc, int type, unsigned char *cmd);
55void pwc_dec23_exit(void);
56void pwc_dec23_decompress(const struct pwc_device *pwc,
57 const void *src,
58 void *dst,
59 int flags);
60
61
62
63#endif
64
65
66/* vim: set cino= formatoptions=croql cindent shiftwidth=8 tabstop=8: */
67
diff --git a/drivers/media/video/pwc/pwc-if.c b/drivers/media/video/pwc/pwc-if.c
index 41418294a32b..98059c8d6f69 100644
--- a/drivers/media/video/pwc/pwc-if.c
+++ b/drivers/media/video/pwc/pwc-if.c
@@ -1,7 +1,7 @@
1/* Linux driver for Philips webcam 1/* Linux driver for Philips webcam
2 USB and Video4Linux interface part. 2 USB and Video4Linux interface part.
3 (C) 1999-2004 Nemosoft Unv. 3 (C) 1999-2004 Nemosoft Unv.
4 (C) 2004 Luc Saillard (luc@saillard.org) 4 (C) 2004-2006 Luc Saillard (luc@saillard.org)
5 5
6 NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx 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. 7 driver and thus may have bugs that are not present in the original version.
@@ -62,18 +62,21 @@
62#include <linux/poll.h> 62#include <linux/poll.h>
63#include <linux/slab.h> 63#include <linux/slab.h>
64#include <linux/vmalloc.h> 64#include <linux/vmalloc.h>
65#include <linux/version.h>
65#include <asm/io.h> 66#include <asm/io.h>
67#include <linux/moduleparam.h>
66 68
67#include "pwc.h" 69#include "pwc.h"
68#include "pwc-ioctl.h"
69#include "pwc-kiara.h" 70#include "pwc-kiara.h"
70#include "pwc-timon.h" 71#include "pwc-timon.h"
72#include "pwc-dec23.h"
73#include "pwc-dec1.h"
71#include "pwc-uncompress.h" 74#include "pwc-uncompress.h"
72 75
73/* Function prototypes and driver templates */ 76/* Function prototypes and driver templates */
74 77
75/* hotplug device table support */ 78/* hotplug device table support */
76static struct usb_device_id pwc_device_table [] = { 79static const struct usb_device_id pwc_device_table [] = {
77 { USB_DEVICE(0x0471, 0x0302) }, /* Philips models */ 80 { USB_DEVICE(0x0471, 0x0302) }, /* Philips models */
78 { USB_DEVICE(0x0471, 0x0303) }, 81 { USB_DEVICE(0x0471, 0x0303) },
79 { USB_DEVICE(0x0471, 0x0304) }, 82 { USB_DEVICE(0x0471, 0x0304) },
@@ -81,9 +84,10 @@ static struct usb_device_id pwc_device_table [] = {
81 { USB_DEVICE(0x0471, 0x0308) }, 84 { USB_DEVICE(0x0471, 0x0308) },
82 { USB_DEVICE(0x0471, 0x030C) }, 85 { USB_DEVICE(0x0471, 0x030C) },
83 { USB_DEVICE(0x0471, 0x0310) }, 86 { USB_DEVICE(0x0471, 0x0310) },
84 { USB_DEVICE(0x0471, 0x0311) }, 87 { USB_DEVICE(0x0471, 0x0311) }, /* Philips ToUcam PRO II */
85 { USB_DEVICE(0x0471, 0x0312) }, 88 { USB_DEVICE(0x0471, 0x0312) },
86 { USB_DEVICE(0x0471, 0x0313) }, /* the 'new' 720K */ 89 { USB_DEVICE(0x0471, 0x0313) }, /* the 'new' 720K */
90 { USB_DEVICE(0x0471, 0x0329) }, /* Philips SPC 900NC PC Camera */
87 { USB_DEVICE(0x069A, 0x0001) }, /* Askey */ 91 { USB_DEVICE(0x069A, 0x0001) }, /* Askey */
88 { USB_DEVICE(0x046D, 0x08B0) }, /* Logitech QuickCam Pro 3000 */ 92 { USB_DEVICE(0x046D, 0x08B0) }, /* Logitech QuickCam Pro 3000 */
89 { USB_DEVICE(0x046D, 0x08B1) }, /* Logitech QuickCam Notebook Pro */ 93 { USB_DEVICE(0x046D, 0x08B1) }, /* Logitech QuickCam Notebook Pro */
@@ -94,8 +98,9 @@ static struct usb_device_id pwc_device_table [] = {
94 { USB_DEVICE(0x046D, 0x08B6) }, /* Logitech (reserved) */ 98 { USB_DEVICE(0x046D, 0x08B6) }, /* Logitech (reserved) */
95 { USB_DEVICE(0x046D, 0x08B7) }, /* Logitech (reserved) */ 99 { USB_DEVICE(0x046D, 0x08B7) }, /* Logitech (reserved) */
96 { USB_DEVICE(0x046D, 0x08B8) }, /* Logitech (reserved) */ 100 { USB_DEVICE(0x046D, 0x08B8) }, /* Logitech (reserved) */
97 { USB_DEVICE(0x055D, 0x9000) }, /* Samsung */ 101 { USB_DEVICE(0x055D, 0x9000) }, /* Samsung MPC-C10 */
98 { USB_DEVICE(0x055D, 0x9001) }, 102 { USB_DEVICE(0x055D, 0x9001) }, /* Samsung MPC-C30 */
103 { USB_DEVICE(0x055D, 0x9002) }, /* Samsung SNC-35E (Ver3.0) */
99 { USB_DEVICE(0x041E, 0x400C) }, /* Creative Webcam 5 */ 104 { USB_DEVICE(0x041E, 0x400C) }, /* Creative Webcam 5 */
100 { USB_DEVICE(0x041E, 0x4011) }, /* Creative Webcam Pro Ex */ 105 { USB_DEVICE(0x041E, 0x4011) }, /* Creative Webcam Pro Ex */
101 { USB_DEVICE(0x04CC, 0x8116) }, /* Afina Eye */ 106 { USB_DEVICE(0x04CC, 0x8116) }, /* Afina Eye */
@@ -122,11 +127,13 @@ static struct usb_driver pwc_driver = {
122static int default_size = PSZ_QCIF; 127static int default_size = PSZ_QCIF;
123static int default_fps = 10; 128static int default_fps = 10;
124static int default_fbufs = 3; /* Default number of frame buffers */ 129static int default_fbufs = 3; /* Default number of frame buffers */
125static int default_mbufs = 2; /* Default number of mmap() buffers */ 130 int pwc_mbufs = 2; /* Default number of mmap() buffers */
126 int pwc_trace = TRACE_MODULE | TRACE_FLOW | TRACE_PWCX; 131#if CONFIG_PWC_DEBUG
132 int pwc_trace = PWC_DEBUG_LEVEL;
133#endif
127static int power_save = 0; 134static int power_save = 0;
128static int led_on = 100, led_off = 0; /* defaults to LED that is on while in use */ 135static int led_on = 100, led_off = 0; /* defaults to LED that is on while in use */
129static int pwc_preferred_compression = 2; /* 0..3 = uncompressed..high */ 136 int pwc_preferred_compression = 1; /* 0..3 = uncompressed..high */
130static struct { 137static struct {
131 int type; 138 int type;
132 char serial_number[30]; 139 char serial_number[30];
@@ -138,7 +145,7 @@ static struct {
138 145
139static int pwc_video_open(struct inode *inode, struct file *file); 146static int pwc_video_open(struct inode *inode, struct file *file);
140static int pwc_video_close(struct inode *inode, struct file *file); 147static int pwc_video_close(struct inode *inode, struct file *file);
141static ssize_t pwc_video_read(struct file *file, char __user * buf, 148static ssize_t pwc_video_read(struct file *file, char __user *buf,
142 size_t count, loff_t *ppos); 149 size_t count, loff_t *ppos);
143static unsigned int pwc_video_poll(struct file *file, poll_table *wait); 150static unsigned int pwc_video_poll(struct file *file, poll_table *wait);
144static int pwc_video_ioctl(struct inode *inode, struct file *file, 151static int pwc_video_ioctl(struct inode *inode, struct file *file,
@@ -153,7 +160,6 @@ static struct file_operations pwc_fops = {
153 .poll = pwc_video_poll, 160 .poll = pwc_video_poll,
154 .mmap = pwc_video_mmap, 161 .mmap = pwc_video_mmap,
155 .ioctl = pwc_video_ioctl, 162 .ioctl = pwc_video_ioctl,
156 .compat_ioctl = v4l_compat_ioctl32,
157 .llseek = no_llseek, 163 .llseek = no_llseek,
158}; 164};
159static struct video_device pwc_template = { 165static struct video_device pwc_template = {
@@ -203,52 +209,44 @@ static struct video_device pwc_template = {
203/* Here we want the physical address of the memory. 209/* Here we want the physical address of the memory.
204 * This is used when initializing the contents of the area. 210 * This is used when initializing the contents of the area.
205 */ 211 */
206static inline unsigned long kvirt_to_pa(unsigned long adr)
207{
208 unsigned long kva, ret;
209 212
210 kva = (unsigned long) page_address(vmalloc_to_page((void *)adr));
211 kva |= adr & (PAGE_SIZE-1); /* restore the offset */
212 ret = __pa(kva);
213 return ret;
214}
215 213
216static void * rvmalloc(unsigned long size) 214
215static void *pwc_rvmalloc(unsigned long size)
217{ 216{
218 void * mem; 217 void * mem;
219 unsigned long adr; 218 unsigned long adr;
220 219
221 size=PAGE_ALIGN(size);
222 mem=vmalloc_32(size); 220 mem=vmalloc_32(size);
223 if (mem) 221 if (!mem)
224 { 222 return NULL;
225 memset(mem, 0, size); /* Clear the ram out, no junk to the user */ 223
226 adr=(unsigned long) mem; 224 memset(mem, 0, size); /* Clear the ram out, no junk to the user */
227 while (size > 0) 225 adr=(unsigned long) mem;
228 { 226 while (size > 0)
229 SetPageReserved(vmalloc_to_page((void *)adr)); 227 {
230 adr+=PAGE_SIZE; 228 SetPageReserved(vmalloc_to_page((void *)adr));
231 size-=PAGE_SIZE; 229 adr += PAGE_SIZE;
232 } 230 size -= PAGE_SIZE;
233 } 231 }
234 return mem; 232 return mem;
235} 233}
236 234
237static void rvfree(void * mem, unsigned long size) 235static void pwc_rvfree(void * mem, unsigned long size)
238{ 236{
239 unsigned long adr; 237 unsigned long adr;
240 238
241 if (mem) 239 if (!mem)
242 { 240 return;
243 adr=(unsigned long) mem; 241
244 while ((long) size > 0) 242 adr=(unsigned long) mem;
245 { 243 while ((long) size > 0)
246 ClearPageReserved(vmalloc_to_page((void *)adr)); 244 {
247 adr+=PAGE_SIZE; 245 ClearPageReserved(vmalloc_to_page((void *)adr));
248 size-=PAGE_SIZE; 246 adr += PAGE_SIZE;
249 } 247 size -= PAGE_SIZE;
250 vfree(mem); 248 }
251 } 249 vfree(mem);
252} 250}
253 251
254 252
@@ -256,100 +254,83 @@ static void rvfree(void * mem, unsigned long size)
256 254
257static int pwc_allocate_buffers(struct pwc_device *pdev) 255static int pwc_allocate_buffers(struct pwc_device *pdev)
258{ 256{
259 int i; 257 int i, err;
260 void *kbuf; 258 void *kbuf;
261 259
262 Trace(TRACE_MEMORY, ">> pwc_allocate_buffers(pdev = 0x%p)\n", pdev); 260 PWC_DEBUG_MEMORY(">> pwc_allocate_buffers(pdev = 0x%p)\n", pdev);
263 261
264 if (pdev == NULL) 262 if (pdev == NULL)
265 return -ENXIO; 263 return -ENXIO;
266 264
267#ifdef PWC_MAGIC 265 /* Allocate Isochronuous pipe buffers */
268 if (pdev->magic != PWC_MAGIC) {
269 Err("allocate_buffers(): magic failed.\n");
270 return -ENXIO;
271 }
272#endif
273 /* Allocate Isochronous pipe buffers */
274 for (i = 0; i < MAX_ISO_BUFS; i++) { 266 for (i = 0; i < MAX_ISO_BUFS; i++) {
275 if (pdev->sbuf[i].data == NULL) { 267 if (pdev->sbuf[i].data == NULL) {
276 kbuf = kmalloc(ISO_BUFFER_SIZE, GFP_KERNEL); 268 kbuf = kzalloc(ISO_BUFFER_SIZE, GFP_KERNEL);
277 if (kbuf == NULL) { 269 if (kbuf == NULL) {
278 Err("Failed to allocate iso buffer %d.\n", i); 270 PWC_ERROR("Failed to allocate iso buffer %d.\n", i);
279 return -ENOMEM; 271 return -ENOMEM;
280 } 272 }
281 Trace(TRACE_MEMORY, "Allocated iso buffer at %p.\n", kbuf); 273 PWC_DEBUG_MEMORY("Allocated iso buffer at %p.\n", kbuf);
282 pdev->sbuf[i].data = kbuf; 274 pdev->sbuf[i].data = kbuf;
283 memset(kbuf, 0, ISO_BUFFER_SIZE);
284 } 275 }
285 } 276 }
286 277
287 /* Allocate frame buffer structure */ 278 /* Allocate frame buffer structure */
288 if (pdev->fbuf == NULL) { 279 if (pdev->fbuf == NULL) {
289 kbuf = kmalloc(default_fbufs * sizeof(struct pwc_frame_buf), GFP_KERNEL); 280 kbuf = kzalloc(default_fbufs * sizeof(struct pwc_frame_buf), GFP_KERNEL);
290 if (kbuf == NULL) { 281 if (kbuf == NULL) {
291 Err("Failed to allocate frame buffer structure.\n"); 282 PWC_ERROR("Failed to allocate frame buffer structure.\n");
292 return -ENOMEM; 283 return -ENOMEM;
293 } 284 }
294 Trace(TRACE_MEMORY, "Allocated frame buffer structure at %p.\n", kbuf); 285 PWC_DEBUG_MEMORY("Allocated frame buffer structure at %p.\n", kbuf);
295 pdev->fbuf = kbuf; 286 pdev->fbuf = kbuf;
296 memset(kbuf, 0, default_fbufs * sizeof(struct pwc_frame_buf));
297 } 287 }
288
298 /* create frame buffers, and make circular ring */ 289 /* create frame buffers, and make circular ring */
299 for (i = 0; i < default_fbufs; i++) { 290 for (i = 0; i < default_fbufs; i++) {
300 if (pdev->fbuf[i].data == NULL) { 291 if (pdev->fbuf[i].data == NULL) {
301 kbuf = vmalloc(PWC_FRAME_SIZE); /* need vmalloc since frame buffer > 128K */ 292 kbuf = vmalloc(PWC_FRAME_SIZE); /* need vmalloc since frame buffer > 128K */
302 if (kbuf == NULL) { 293 if (kbuf == NULL) {
303 Err("Failed to allocate frame buffer %d.\n", i); 294 PWC_ERROR("Failed to allocate frame buffer %d.\n", i);
304 return -ENOMEM; 295 return -ENOMEM;
305 } 296 }
306 Trace(TRACE_MEMORY, "Allocated frame buffer %d at %p.\n", i, kbuf); 297 PWC_DEBUG_MEMORY("Allocated frame buffer %d at %p.\n", i, kbuf);
307 pdev->fbuf[i].data = kbuf; 298 pdev->fbuf[i].data = kbuf;
308 memset(kbuf, 128, PWC_FRAME_SIZE); 299 memset(kbuf, 0, PWC_FRAME_SIZE);
309 } 300 }
310 } 301 }
311 302
312 /* Allocate decompressor table space */ 303 /* Allocate decompressor table space */
313 kbuf = NULL; 304 if (DEVICE_USE_CODEC1(pdev->type))
314 switch (pdev->type) 305 err = pwc_dec1_alloc(pdev);
315 { 306 else
316 case 675: 307 err = pwc_dec23_alloc(pdev);
317 case 680: 308
318 case 690: 309 if (err) {
319 case 720: 310 PWC_ERROR("Failed to allocate decompress table.\n");
320 case 730: 311 return err;
321 case 740: 312 }
322 case 750:
323#if 0
324 Trace(TRACE_MEMORY,"private_data(%zu)\n",sizeof(struct pwc_dec23_private));
325 kbuf = kmalloc(sizeof(struct pwc_dec23_private), GFP_KERNEL); /* Timon & Kiara */
326 break;
327 case 645:
328 case 646:
329 /* TODO & FIXME */
330 kbuf = kmalloc(sizeof(struct pwc_dec23_private), GFP_KERNEL);
331 break;
332#endif
333 ;
334 }
335 pdev->decompress_data = kbuf;
336 313
337 /* Allocate image buffer; double buffer for mmap() */ 314 /* Allocate image buffer; double buffer for mmap() */
338 kbuf = rvmalloc(default_mbufs * pdev->len_per_image); 315 kbuf = pwc_rvmalloc(pwc_mbufs * pdev->len_per_image);
339 if (kbuf == NULL) { 316 if (kbuf == NULL) {
340 Err("Failed to allocate image buffer(s). needed (%d)\n",default_mbufs * pdev->len_per_image); 317 PWC_ERROR("Failed to allocate image buffer(s). needed (%d)\n",
318 pwc_mbufs * pdev->len_per_image);
341 return -ENOMEM; 319 return -ENOMEM;
342 } 320 }
343 Trace(TRACE_MEMORY, "Allocated image buffer at %p.\n", kbuf); 321 PWC_DEBUG_MEMORY("Allocated image buffer at %p.\n", kbuf);
344 pdev->image_data = kbuf; 322 pdev->image_data = kbuf;
345 for (i = 0; i < default_mbufs; i++) 323 for (i = 0; i < pwc_mbufs; i++) {
346 pdev->image_ptr[i] = kbuf + i * pdev->len_per_image; 324 pdev->images[i].offset = i * pdev->len_per_image;
347 for (; i < MAX_IMAGES; i++) 325 pdev->images[i].vma_use_count = 0;
348 pdev->image_ptr[i] = NULL; 326 }
327 for (; i < MAX_IMAGES; i++) {
328 pdev->images[i].offset = 0;
329 }
349 330
350 kbuf = NULL; 331 kbuf = NULL;
351 332
352 Trace(TRACE_MEMORY, "<< pwc_allocate_buffers()\n"); 333 PWC_DEBUG_MEMORY("<< pwc_allocate_buffers()\n");
353 return 0; 334 return 0;
354} 335}
355 336
@@ -357,21 +338,14 @@ static void pwc_free_buffers(struct pwc_device *pdev)
357{ 338{
358 int i; 339 int i;
359 340
360 Trace(TRACE_MEMORY, "Entering free_buffers(%p).\n", pdev); 341 PWC_DEBUG_MEMORY("Entering free_buffers(%p).\n", pdev);
361 342
362 if (pdev == NULL) 343 if (pdev == NULL)
363 return; 344 return;
364#ifdef PWC_MAGIC
365 if (pdev->magic != PWC_MAGIC) {
366 Err("free_buffers(): magic failed.\n");
367 return;
368 }
369#endif
370
371 /* Release Iso-pipe buffers */ 345 /* Release Iso-pipe buffers */
372 for (i = 0; i < MAX_ISO_BUFS; i++) 346 for (i = 0; i < MAX_ISO_BUFS; i++)
373 if (pdev->sbuf[i].data != NULL) { 347 if (pdev->sbuf[i].data != NULL) {
374 Trace(TRACE_MEMORY, "Freeing ISO buffer at %p.\n", pdev->sbuf[i].data); 348 PWC_DEBUG_MEMORY("Freeing ISO buffer at %p.\n", pdev->sbuf[i].data);
375 kfree(pdev->sbuf[i].data); 349 kfree(pdev->sbuf[i].data);
376 pdev->sbuf[i].data = NULL; 350 pdev->sbuf[i].data = NULL;
377 } 351 }
@@ -380,7 +354,7 @@ static void pwc_free_buffers(struct pwc_device *pdev)
380 if (pdev->fbuf != NULL) { 354 if (pdev->fbuf != NULL) {
381 for (i = 0; i < default_fbufs; i++) { 355 for (i = 0; i < default_fbufs; i++) {
382 if (pdev->fbuf[i].data != NULL) { 356 if (pdev->fbuf[i].data != NULL) {
383 Trace(TRACE_MEMORY, "Freeing frame buffer %d at %p.\n", i, pdev->fbuf[i].data); 357 PWC_DEBUG_MEMORY("Freeing frame buffer %d at %p.\n", i, pdev->fbuf[i].data);
384 vfree(pdev->fbuf[i].data); 358 vfree(pdev->fbuf[i].data);
385 pdev->fbuf[i].data = NULL; 359 pdev->fbuf[i].data = NULL;
386 } 360 }
@@ -391,20 +365,19 @@ static void pwc_free_buffers(struct pwc_device *pdev)
391 365
392 /* Intermediate decompression buffer & tables */ 366 /* Intermediate decompression buffer & tables */
393 if (pdev->decompress_data != NULL) { 367 if (pdev->decompress_data != NULL) {
394 Trace(TRACE_MEMORY, "Freeing decompression buffer at %p.\n", pdev->decompress_data); 368 PWC_DEBUG_MEMORY("Freeing decompression buffer at %p.\n", pdev->decompress_data);
395 kfree(pdev->decompress_data); 369 kfree(pdev->decompress_data);
396 pdev->decompress_data = NULL; 370 pdev->decompress_data = NULL;
397 } 371 }
398 pdev->decompressor = NULL;
399 372
400 /* Release image buffers */ 373 /* Release image buffers */
401 if (pdev->image_data != NULL) { 374 if (pdev->image_data != NULL) {
402 Trace(TRACE_MEMORY, "Freeing image buffer at %p.\n", pdev->image_data); 375 PWC_DEBUG_MEMORY("Freeing image buffer at %p.\n", pdev->image_data);
403 rvfree(pdev->image_data, default_mbufs * pdev->len_per_image); 376 pwc_rvfree(pdev->image_data, pwc_mbufs * pdev->len_per_image);
404 } 377 }
405 pdev->image_data = NULL; 378 pdev->image_data = NULL;
406 379
407 Trace(TRACE_MEMORY, "Leaving free_buffers().\n"); 380 PWC_DEBUG_MEMORY("Leaving free_buffers().\n");
408} 381}
409 382
410/* The frame & image buffer mess. 383/* The frame & image buffer mess.
@@ -464,7 +437,7 @@ static void pwc_free_buffers(struct pwc_device *pdev)
464/** 437/**
465 \brief Find next frame buffer to fill. Take from empty or full list, whichever comes first. 438 \brief Find next frame buffer to fill. Take from empty or full list, whichever comes first.
466 */ 439 */
467static inline int pwc_next_fill_frame(struct pwc_device *pdev) 440static int pwc_next_fill_frame(struct pwc_device *pdev)
468{ 441{
469 int ret; 442 int ret;
470 unsigned long flags; 443 unsigned long flags;
@@ -489,23 +462,17 @@ static inline int pwc_next_fill_frame(struct pwc_device *pdev)
489 } 462 }
490 else { 463 else {
491 /* Hmm. Take it from the full list */ 464 /* Hmm. Take it from the full list */
492#if PWC_DEBUG
493 /* sanity check */ 465 /* sanity check */
494 if (pdev->full_frames == NULL) { 466 if (pdev->full_frames == NULL) {
495 Err("Neither empty or full frames available!\n"); 467 PWC_ERROR("Neither empty or full frames available!\n");
496 spin_unlock_irqrestore(&pdev->ptrlock, flags); 468 spin_unlock_irqrestore(&pdev->ptrlock, flags);
497 return -EINVAL; 469 return -EINVAL;
498 } 470 }
499#endif
500 pdev->fill_frame = pdev->full_frames; 471 pdev->fill_frame = pdev->full_frames;
501 pdev->full_frames = pdev->full_frames->next; 472 pdev->full_frames = pdev->full_frames->next;
502 ret = 1; 473 ret = 1;
503 } 474 }
504 pdev->fill_frame->next = NULL; 475 pdev->fill_frame->next = NULL;
505#if PWC_DEBUG
506 Trace(TRACE_SEQUENCE, "Assigning sequence number %d.\n", pdev->sequence);
507 pdev->fill_frame->sequence = pdev->sequence++;
508#endif
509 spin_unlock_irqrestore(&pdev->ptrlock, flags); 476 spin_unlock_irqrestore(&pdev->ptrlock, flags);
510 return ret; 477 return ret;
511} 478}
@@ -521,6 +488,8 @@ static void pwc_reset_buffers(struct pwc_device *pdev)
521 int i; 488 int i;
522 unsigned long flags; 489 unsigned long flags;
523 490
491 PWC_DEBUG_MEMORY(">> %s __enter__\n", __FUNCTION__);
492
524 spin_lock_irqsave(&pdev->ptrlock, flags); 493 spin_lock_irqsave(&pdev->ptrlock, flags);
525 pdev->full_frames = NULL; 494 pdev->full_frames = NULL;
526 pdev->full_frames_tail = NULL; 495 pdev->full_frames_tail = NULL;
@@ -540,13 +509,15 @@ static void pwc_reset_buffers(struct pwc_device *pdev)
540 pdev->image_read_pos = 0; 509 pdev->image_read_pos = 0;
541 pdev->fill_image = 0; 510 pdev->fill_image = 0;
542 spin_unlock_irqrestore(&pdev->ptrlock, flags); 511 spin_unlock_irqrestore(&pdev->ptrlock, flags);
512
513 PWC_DEBUG_MEMORY("<< %s __leaving__\n", __FUNCTION__);
543} 514}
544 515
545 516
546/** 517/**
547 \brief Do all the handling for getting one frame: get pointer, decompress, advance pointers. 518 \brief Do all the handling for getting one frame: get pointer, decompress, advance pointers.
548 */ 519 */
549static int pwc_handle_frame(struct pwc_device *pdev) 520int pwc_handle_frame(struct pwc_device *pdev)
550{ 521{
551 int ret = 0; 522 int ret = 0;
552 unsigned long flags; 523 unsigned long flags;
@@ -556,41 +527,40 @@ static int pwc_handle_frame(struct pwc_device *pdev)
556 we can release the lock after this without problems */ 527 we can release the lock after this without problems */
557 if (pdev->read_frame != NULL) { 528 if (pdev->read_frame != NULL) {
558 /* This can't theoretically happen */ 529 /* This can't theoretically happen */
559 Err("Huh? Read frame still in use?\n"); 530 PWC_ERROR("Huh? Read frame still in use?\n");
531 spin_unlock_irqrestore(&pdev->ptrlock, flags);
532 return ret;
533 }
534
535
536 if (pdev->full_frames == NULL) {
537 PWC_ERROR("Woops. No frames ready.\n");
560 } 538 }
561 else { 539 else {
562 if (pdev->full_frames == NULL) { 540 pdev->read_frame = pdev->full_frames;
563 Err("Woops. No frames ready.\n"); 541 pdev->full_frames = pdev->full_frames->next;
542 pdev->read_frame->next = NULL;
543 }
544
545 if (pdev->read_frame != NULL) {
546 /* Decompression is a lenghty process, so it's outside of the lock.
547 This gives the isoc_handler the opportunity to fill more frames
548 in the mean time.
549 */
550 spin_unlock_irqrestore(&pdev->ptrlock, flags);
551 ret = pwc_decompress(pdev);
552 spin_lock_irqsave(&pdev->ptrlock, flags);
553
554 /* We're done with read_buffer, tack it to the end of the empty buffer list */
555 if (pdev->empty_frames == NULL) {
556 pdev->empty_frames = pdev->read_frame;
557 pdev->empty_frames_tail = pdev->empty_frames;
564 } 558 }
565 else { 559 else {
566 pdev->read_frame = pdev->full_frames; 560 pdev->empty_frames_tail->next = pdev->read_frame;
567 pdev->full_frames = pdev->full_frames->next; 561 pdev->empty_frames_tail = pdev->read_frame;
568 pdev->read_frame->next = NULL;
569 }
570
571 if (pdev->read_frame != NULL) {
572#if PWC_DEBUG
573 Trace(TRACE_SEQUENCE, "Decompressing frame %d\n", pdev->read_frame->sequence);
574#endif
575 /* Decompression is a lenghty process, so it's outside of the lock.
576 This gives the isoc_handler the opportunity to fill more frames
577 in the mean time.
578 */
579 spin_unlock_irqrestore(&pdev->ptrlock, flags);
580 ret = pwc_decompress(pdev);
581 spin_lock_irqsave(&pdev->ptrlock, flags);
582
583 /* We're done with read_buffer, tack it to the end of the empty buffer list */
584 if (pdev->empty_frames == NULL) {
585 pdev->empty_frames = pdev->read_frame;
586 pdev->empty_frames_tail = pdev->empty_frames;
587 }
588 else {
589 pdev->empty_frames_tail->next = pdev->read_frame;
590 pdev->empty_frames_tail = pdev->read_frame;
591 }
592 pdev->read_frame = NULL;
593 } 562 }
563 pdev->read_frame = NULL;
594 } 564 }
595 spin_unlock_irqrestore(&pdev->ptrlock, flags); 565 spin_unlock_irqrestore(&pdev->ptrlock, flags);
596 return ret; 566 return ret;
@@ -599,12 +569,114 @@ static int pwc_handle_frame(struct pwc_device *pdev)
599/** 569/**
600 \brief Advance pointers of image buffer (after each user request) 570 \brief Advance pointers of image buffer (after each user request)
601*/ 571*/
602static inline void pwc_next_image(struct pwc_device *pdev) 572void pwc_next_image(struct pwc_device *pdev)
603{ 573{
604 pdev->image_used[pdev->fill_image] = 0; 574 pdev->image_used[pdev->fill_image] = 0;
605 pdev->fill_image = (pdev->fill_image + 1) % default_mbufs; 575 pdev->fill_image = (pdev->fill_image + 1) % pwc_mbufs;
606} 576}
607 577
578/**
579 * Print debug information when a frame is discarded because all of our buffer
580 * is full
581 */
582static void pwc_frame_dumped(struct pwc_device *pdev)
583{
584 pdev->vframes_dumped++;
585 if (pdev->vframe_count < FRAME_LOWMARK)
586 return;
587
588 if (pdev->vframes_dumped < 20)
589 PWC_DEBUG_FLOW("Dumping frame %d\n", pdev->vframe_count);
590 else if (pdev->vframes_dumped == 20)
591 PWC_DEBUG_FLOW("Dumping frame %d (last message)\n",
592 pdev->vframe_count);
593}
594
595static int pwc_rcv_short_packet(struct pwc_device *pdev, const struct pwc_frame_buf *fbuf)
596{
597 int awake = 0;
598
599 /* The ToUCam Fun CMOS sensor causes the firmware to send 2 or 3 bogus
600 frames on the USB wire after an exposure change. This conditition is
601 however detected in the cam and a bit is set in the header.
602 */
603 if (pdev->type == 730) {
604 unsigned char *ptr = (unsigned char *)fbuf->data;
605
606 if (ptr[1] == 1 && ptr[0] & 0x10) {
607 PWC_TRACE("Hyundai CMOS sensor bug. Dropping frame.\n");
608 pdev->drop_frames += 2;
609 pdev->vframes_error++;
610 }
611 if ((ptr[0] ^ pdev->vmirror) & 0x01) {
612 if (ptr[0] & 0x01) {
613 pdev->snapshot_button_status = 1;
614 PWC_TRACE("Snapshot button pressed.\n");
615 }
616 else {
617 PWC_TRACE("Snapshot button released.\n");
618 }
619 }
620 if ((ptr[0] ^ pdev->vmirror) & 0x02) {
621 if (ptr[0] & 0x02)
622 PWC_TRACE("Image is mirrored.\n");
623 else
624 PWC_TRACE("Image is normal.\n");
625 }
626 pdev->vmirror = ptr[0] & 0x03;
627 /* Sometimes the trailer of the 730 is still sent as a 4 byte packet
628 after a short frame; this condition is filtered out specifically. A 4 byte
629 frame doesn't make sense anyway.
630 So we get either this sequence:
631 drop_bit set -> 4 byte frame -> short frame -> good frame
632 Or this one:
633 drop_bit set -> short frame -> good frame
634 So we drop either 3 or 2 frames in all!
635 */
636 if (fbuf->filled == 4)
637 pdev->drop_frames++;
638 }
639 else if (pdev->type == 740 || pdev->type == 720) {
640 unsigned char *ptr = (unsigned char *)fbuf->data;
641 if ((ptr[0] ^ pdev->vmirror) & 0x01) {
642 if (ptr[0] & 0x01) {
643 pdev->snapshot_button_status = 1;
644 PWC_TRACE("Snapshot button pressed.\n");
645 }
646 else
647 PWC_TRACE("Snapshot button released.\n");
648 }
649 pdev->vmirror = ptr[0] & 0x03;
650 }
651
652 /* In case we were instructed to drop the frame, do so silently.
653 The buffer pointers are not updated either (but the counters are reset below).
654 */
655 if (pdev->drop_frames > 0)
656 pdev->drop_frames--;
657 else {
658 /* Check for underflow first */
659 if (fbuf->filled < pdev->frame_total_size) {
660 PWC_DEBUG_FLOW("Frame buffer underflow (%d bytes);"
661 " discarded.\n", fbuf->filled);
662 pdev->vframes_error++;
663 }
664 else {
665 /* Send only once per EOF */
666 awake = 1; /* delay wake_ups */
667
668 /* Find our next frame to fill. This will always succeed, since we
669 * nick a frame from either empty or full list, but if we had to
670 * take it from the full list, it means a frame got dropped.
671 */
672 if (pwc_next_fill_frame(pdev))
673 pwc_frame_dumped(pdev);
674
675 }
676 } /* !drop_frames */
677 pdev->vframe_count++;
678 return awake;
679}
608 680
609/* This gets called for the Isochronous pipe (video). This is done in 681/* This gets called for the Isochronous pipe (video). This is done in
610 * interrupt time, so it has to be fast, not crash, and not stall. Neat. 682 * interrupt time, so it has to be fast, not crash, and not stall. Neat.
@@ -620,17 +692,12 @@ static void pwc_isoc_handler(struct urb *urb, struct pt_regs *regs)
620 awake = 0; 692 awake = 0;
621 pdev = (struct pwc_device *)urb->context; 693 pdev = (struct pwc_device *)urb->context;
622 if (pdev == NULL) { 694 if (pdev == NULL) {
623 Err("isoc_handler() called with NULL device?!\n"); 695 PWC_ERROR("isoc_handler() called with NULL device?!\n");
624 return; 696 return;
625 } 697 }
626#ifdef PWC_MAGIC 698
627 if (pdev->magic != PWC_MAGIC) {
628 Err("isoc_handler() called with bad magic!\n");
629 return;
630 }
631#endif
632 if (urb->status == -ENOENT || urb->status == -ECONNRESET) { 699 if (urb->status == -ENOENT || urb->status == -ECONNRESET) {
633 Trace(TRACE_OPEN, "pwc_isoc_handler(): URB (%p) unlinked %ssynchronuously.\n", urb, urb->status == -ENOENT ? "" : "a"); 700 PWC_DEBUG_OPEN("URB (%p) unlinked %ssynchronuously.\n", urb, urb->status == -ENOENT ? "" : "a");
634 return; 701 return;
635 } 702 }
636 if (urb->status != -EINPROGRESS && urb->status != 0) { 703 if (urb->status != -EINPROGRESS && urb->status != 0) {
@@ -645,13 +712,13 @@ static void pwc_isoc_handler(struct urb *urb, struct pt_regs *regs)
645 case -EILSEQ: errmsg = "CRC/Timeout (could be anything)"; break; 712 case -EILSEQ: errmsg = "CRC/Timeout (could be anything)"; break;
646 case -ETIMEDOUT: errmsg = "NAK (device does not respond)"; break; 713 case -ETIMEDOUT: errmsg = "NAK (device does not respond)"; break;
647 } 714 }
648 Trace(TRACE_FLOW, "pwc_isoc_handler() called with status %d [%s].\n", urb->status, errmsg); 715 PWC_DEBUG_FLOW("pwc_isoc_handler() called with status %d [%s].\n", urb->status, errmsg);
649 /* Give up after a number of contiguous errors on the USB bus. 716 /* Give up after a number of contiguous errors on the USB bus.
650 Appearantly something is wrong so we simulate an unplug event. 717 Appearantly something is wrong so we simulate an unplug event.
651 */ 718 */
652 if (++pdev->visoc_errors > MAX_ISOC_ERRORS) 719 if (++pdev->visoc_errors > MAX_ISOC_ERRORS)
653 { 720 {
654 Info("Too many ISOC errors, bailing out.\n"); 721 PWC_INFO("Too many ISOC errors, bailing out.\n");
655 pdev->error_status = EIO; 722 pdev->error_status = EIO;
656 awake = 1; 723 awake = 1;
657 wake_up_interruptible(&pdev->frameq); 724 wake_up_interruptible(&pdev->frameq);
@@ -661,7 +728,7 @@ static void pwc_isoc_handler(struct urb *urb, struct pt_regs *regs)
661 728
662 fbuf = pdev->fill_frame; 729 fbuf = pdev->fill_frame;
663 if (fbuf == NULL) { 730 if (fbuf == NULL) {
664 Err("pwc_isoc_handler without valid fill frame.\n"); 731 PWC_ERROR("pwc_isoc_handler without valid fill frame.\n");
665 awake = 1; 732 awake = 1;
666 goto handler_end; 733 goto handler_end;
667 } 734 }
@@ -688,7 +755,7 @@ static void pwc_isoc_handler(struct urb *urb, struct pt_regs *regs)
688 755
689 /* ...copy data to frame buffer, if possible */ 756 /* ...copy data to frame buffer, if possible */
690 if (flen + fbuf->filled > pdev->frame_total_size) { 757 if (flen + fbuf->filled > pdev->frame_total_size) {
691 Trace(TRACE_FLOW, "Frame buffer overflow (flen = %d, frame_total_size = %d).\n", flen, pdev->frame_total_size); 758 PWC_DEBUG_FLOW("Frame buffer overflow (flen = %d, frame_total_size = %d).\n", flen, pdev->frame_total_size);
692 pdev->vsync = 0; /* Hmm, let's wait for an EOF (end-of-frame) */ 759 pdev->vsync = 0; /* Hmm, let's wait for an EOF (end-of-frame) */
693 pdev->vframes_error++; 760 pdev->vframes_error++;
694 } 761 }
@@ -704,96 +771,28 @@ static void pwc_isoc_handler(struct urb *urb, struct pt_regs *regs)
704 /* Shorter packet... We probably have the end of an image-frame; 771 /* Shorter packet... We probably have the end of an image-frame;
705 wake up read() process and let select()/poll() do something. 772 wake up read() process and let select()/poll() do something.
706 Decompression is done in user time over there. 773 Decompression is done in user time over there.
707 */ 774 */
708 if (pdev->vsync == 2) { 775 if (pdev->vsync == 2) {
709 /* The ToUCam Fun CMOS sensor causes the firmware to send 2 or 3 bogus 776 if (pwc_rcv_short_packet(pdev, fbuf)) {
710 frames on the USB wire after an exposure change. This conditition is 777 awake = 1;
711 however detected in the cam and a bit is set in the header. 778 fbuf = pdev->fill_frame;
712 */
713 if (pdev->type == 730) {
714 unsigned char *ptr = (unsigned char *)fbuf->data;
715
716 if (ptr[1] == 1 && ptr[0] & 0x10) {
717#if PWC_DEBUG
718 Debug("Hyundai CMOS sensor bug. Dropping frame %d.\n", fbuf->sequence);
719#endif
720 pdev->drop_frames += 2;
721 pdev->vframes_error++;
722 }
723 if ((ptr[0] ^ pdev->vmirror) & 0x01) {
724 if (ptr[0] & 0x01)
725 Info("Snapshot button pressed.\n");
726 else
727 Info("Snapshot button released.\n");
728 }
729 if ((ptr[0] ^ pdev->vmirror) & 0x02) {
730 if (ptr[0] & 0x02)
731 Info("Image is mirrored.\n");
732 else
733 Info("Image is normal.\n");
734 }
735 pdev->vmirror = ptr[0] & 0x03;
736 /* Sometimes the trailer of the 730 is still sent as a 4 byte packet
737 after a short frame; this condition is filtered out specifically. A 4 byte
738 frame doesn't make sense anyway.
739 So we get either this sequence:
740 drop_bit set -> 4 byte frame -> short frame -> good frame
741 Or this one:
742 drop_bit set -> short frame -> good frame
743 So we drop either 3 or 2 frames in all!
744 */
745 if (fbuf->filled == 4)
746 pdev->drop_frames++;
747 } 779 }
748
749 /* In case we were instructed to drop the frame, do so silently.
750 The buffer pointers are not updated either (but the counters are reset below).
751 */
752 if (pdev->drop_frames > 0)
753 pdev->drop_frames--;
754 else {
755 /* Check for underflow first */
756 if (fbuf->filled < pdev->frame_total_size) {
757 Trace(TRACE_FLOW, "Frame buffer underflow (%d bytes); discarded.\n", fbuf->filled);
758 pdev->vframes_error++;
759 }
760 else {
761 /* Send only once per EOF */
762 awake = 1; /* delay wake_ups */
763
764 /* Find our next frame to fill. This will always succeed, since we
765 * nick a frame from either empty or full list, but if we had to
766 * take it from the full list, it means a frame got dropped.
767 */
768 if (pwc_next_fill_frame(pdev)) {
769 pdev->vframes_dumped++;
770 if ((pdev->vframe_count > FRAME_LOWMARK) && (pwc_trace & TRACE_FLOW)) {
771 if (pdev->vframes_dumped < 20)
772 Trace(TRACE_FLOW, "Dumping frame %d.\n", pdev->vframe_count);
773 if (pdev->vframes_dumped == 20)
774 Trace(TRACE_FLOW, "Dumping frame %d (last message).\n", pdev->vframe_count);
775 }
776 }
777 fbuf = pdev->fill_frame;
778 }
779 } /* !drop_frames */
780 pdev->vframe_count++;
781 } 780 }
782 fbuf->filled = 0; 781 fbuf->filled = 0;
783 fillptr = fbuf->data; 782 fillptr = fbuf->data;
784 pdev->vsync = 1; 783 pdev->vsync = 1;
785 } /* .. flen < last_packet_size */ 784 }
785
786 pdev->vlast_packet_size = flen; 786 pdev->vlast_packet_size = flen;
787 } /* ..status == 0 */ 787 } /* ..status == 0 */
788#if PWC_DEBUG
789 /* This is normally not interesting to the user, unless you are really debugging something */
790 else { 788 else {
789 /* This is normally not interesting to the user, unless
790 * you are really debugging something */
791 static int iso_error = 0; 791 static int iso_error = 0;
792 iso_error++; 792 iso_error++;
793 if (iso_error < 20) 793 if (iso_error < 20)
794 Trace(TRACE_FLOW, "Iso frame %d of USB has error %d\n", i, fst); 794 PWC_DEBUG_FLOW("Iso frame %d of USB has error %d\n", i, fst);
795 } 795 }
796#endif
797 } 796 }
798 797
799handler_end: 798handler_end:
@@ -803,11 +802,11 @@ handler_end:
803 urb->dev = pdev->udev; 802 urb->dev = pdev->udev;
804 i = usb_submit_urb(urb, GFP_ATOMIC); 803 i = usb_submit_urb(urb, GFP_ATOMIC);
805 if (i != 0) 804 if (i != 0)
806 Err("Error (%d) re-submitting urb in pwc_isoc_handler.\n", i); 805 PWC_ERROR("Error (%d) re-submitting urb in pwc_isoc_handler.\n", i);
807} 806}
808 807
809 808
810static int pwc_isoc_init(struct pwc_device *pdev) 809int pwc_isoc_init(struct pwc_device *pdev)
811{ 810{
812 struct usb_device *udev; 811 struct usb_device *udev;
813 struct urb *urb; 812 struct urb *urb;
@@ -826,7 +825,6 @@ static int pwc_isoc_init(struct pwc_device *pdev)
826 /* Get the current alternate interface, adjust packet size */ 825 /* Get the current alternate interface, adjust packet size */
827 if (!udev->actconfig) 826 if (!udev->actconfig)
828 return -EFAULT; 827 return -EFAULT;
829
830 intf = usb_ifnum_to_if(udev, 0); 828 intf = usb_ifnum_to_if(udev, 0);
831 if (intf) 829 if (intf)
832 idesc = usb_altnum_to_altsetting(intf, pdev->valternate); 830 idesc = usb_altnum_to_altsetting(intf, pdev->valternate);
@@ -836,20 +834,21 @@ static int pwc_isoc_init(struct pwc_device *pdev)
836 834
837 /* Search video endpoint */ 835 /* Search video endpoint */
838 pdev->vmax_packet_size = -1; 836 pdev->vmax_packet_size = -1;
839 for (i = 0; i < idesc->desc.bNumEndpoints; i++) 837 for (i = 0; i < idesc->desc.bNumEndpoints; i++) {
840 if ((idesc->endpoint[i].desc.bEndpointAddress & 0xF) == pdev->vendpoint) { 838 if ((idesc->endpoint[i].desc.bEndpointAddress & 0xF) == pdev->vendpoint) {
841 pdev->vmax_packet_size = le16_to_cpu(idesc->endpoint[i].desc.wMaxPacketSize); 839 pdev->vmax_packet_size = le16_to_cpu(idesc->endpoint[i].desc.wMaxPacketSize);
842 break; 840 break;
843 } 841 }
842 }
844 843
845 if (pdev->vmax_packet_size < 0 || pdev->vmax_packet_size > ISO_MAX_FRAME_SIZE) { 844 if (pdev->vmax_packet_size < 0 || pdev->vmax_packet_size > ISO_MAX_FRAME_SIZE) {
846 Err("Failed to find packet size for video endpoint in current alternate setting.\n"); 845 PWC_ERROR("Failed to find packet size for video endpoint in current alternate setting.\n");
847 return -ENFILE; /* Odd error, that should be noticeable */ 846 return -ENFILE; /* Odd error, that should be noticeable */
848 } 847 }
849 848
850 /* Set alternate interface */ 849 /* Set alternate interface */
851 ret = 0; 850 ret = 0;
852 Trace(TRACE_OPEN, "Setting alternate interface %d\n", pdev->valternate); 851 PWC_DEBUG_OPEN("Setting alternate interface %d\n", pdev->valternate);
853 ret = usb_set_interface(pdev->udev, 0, pdev->valternate); 852 ret = usb_set_interface(pdev->udev, 0, pdev->valternate);
854 if (ret < 0) 853 if (ret < 0)
855 return ret; 854 return ret;
@@ -857,12 +856,12 @@ static int pwc_isoc_init(struct pwc_device *pdev)
857 for (i = 0; i < MAX_ISO_BUFS; i++) { 856 for (i = 0; i < MAX_ISO_BUFS; i++) {
858 urb = usb_alloc_urb(ISO_FRAMES_PER_DESC, GFP_KERNEL); 857 urb = usb_alloc_urb(ISO_FRAMES_PER_DESC, GFP_KERNEL);
859 if (urb == NULL) { 858 if (urb == NULL) {
860 Err("Failed to allocate urb %d\n", i); 859 PWC_ERROR("Failed to allocate urb %d\n", i);
861 ret = -ENOMEM; 860 ret = -ENOMEM;
862 break; 861 break;
863 } 862 }
864 pdev->sbuf[i].urb = urb; 863 pdev->sbuf[i].urb = urb;
865 Trace(TRACE_MEMORY, "Allocated URB at 0x%p\n", urb); 864 PWC_DEBUG_MEMORY("Allocated URB at 0x%p\n", urb);
866 } 865 }
867 if (ret) { 866 if (ret) {
868 /* De-allocate in reverse order */ 867 /* De-allocate in reverse order */
@@ -899,24 +898,26 @@ static int pwc_isoc_init(struct pwc_device *pdev)
899 for (i = 0; i < MAX_ISO_BUFS; i++) { 898 for (i = 0; i < MAX_ISO_BUFS; i++) {
900 ret = usb_submit_urb(pdev->sbuf[i].urb, GFP_KERNEL); 899 ret = usb_submit_urb(pdev->sbuf[i].urb, GFP_KERNEL);
901 if (ret) 900 if (ret)
902 Err("isoc_init() submit_urb %d failed with error %d\n", i, ret); 901 PWC_ERROR("isoc_init() submit_urb %d failed with error %d\n", i, ret);
903 else 902 else
904 Trace(TRACE_MEMORY, "URB 0x%p submitted.\n", pdev->sbuf[i].urb); 903 PWC_DEBUG_MEMORY("URB 0x%p submitted.\n", pdev->sbuf[i].urb);
905 } 904 }
906 905
907 /* All is done... */ 906 /* All is done... */
908 pdev->iso_init = 1; 907 pdev->iso_init = 1;
909 Trace(TRACE_OPEN, "<< pwc_isoc_init()\n"); 908 PWC_DEBUG_OPEN("<< pwc_isoc_init()\n");
910 return 0; 909 return 0;
911} 910}
912 911
913static void pwc_isoc_cleanup(struct pwc_device *pdev) 912void pwc_isoc_cleanup(struct pwc_device *pdev)
914{ 913{
915 int i; 914 int i;
916 915
917 Trace(TRACE_OPEN, ">> pwc_isoc_cleanup()\n"); 916 PWC_DEBUG_OPEN(">> pwc_isoc_cleanup()\n");
918 if (pdev == NULL) 917 if (pdev == NULL)
919 return; 918 return;
919 if (pdev->iso_init == 0)
920 return;
920 921
921 /* Unlinking ISOC buffers one by one */ 922 /* Unlinking ISOC buffers one by one */
922 for (i = 0; i < MAX_ISO_BUFS; i++) { 923 for (i = 0; i < MAX_ISO_BUFS; i++) {
@@ -925,10 +926,10 @@ static void pwc_isoc_cleanup(struct pwc_device *pdev)
925 urb = pdev->sbuf[i].urb; 926 urb = pdev->sbuf[i].urb;
926 if (urb != 0) { 927 if (urb != 0) {
927 if (pdev->iso_init) { 928 if (pdev->iso_init) {
928 Trace(TRACE_MEMORY, "Unlinking URB %p\n", urb); 929 PWC_DEBUG_MEMORY("Unlinking URB %p\n", urb);
929 usb_kill_urb(urb); 930 usb_kill_urb(urb);
930 } 931 }
931 Trace(TRACE_MEMORY, "Freeing URB\n"); 932 PWC_DEBUG_MEMORY("Freeing URB\n");
932 usb_free_urb(urb); 933 usb_free_urb(urb);
933 pdev->sbuf[i].urb = NULL; 934 pdev->sbuf[i].urb = NULL;
934 } 935 }
@@ -938,12 +939,12 @@ static void pwc_isoc_cleanup(struct pwc_device *pdev)
938 is signalled by EPIPE) 939 is signalled by EPIPE)
939 */ 940 */
940 if (pdev->error_status && pdev->error_status != EPIPE) { 941 if (pdev->error_status && pdev->error_status != EPIPE) {
941 Trace(TRACE_OPEN, "Setting alternate interface 0.\n"); 942 PWC_DEBUG_OPEN("Setting alternate interface 0.\n");
942 usb_set_interface(pdev->udev, 0, 0); 943 usb_set_interface(pdev->udev, 0, 0);
943 } 944 }
944 945
945 pdev->iso_init = 0; 946 pdev->iso_init = 0;
946 Trace(TRACE_OPEN, "<< pwc_isoc_cleanup()\n"); 947 PWC_DEBUG_OPEN("<< pwc_isoc_cleanup()\n");
947} 948}
948 949
949int pwc_try_video_mode(struct pwc_device *pdev, int width, int height, int new_fps, int new_compression, int new_snapshot) 950int pwc_try_video_mode(struct pwc_device *pdev, int width, int height, int new_fps, int new_compression, int new_snapshot)
@@ -957,18 +958,18 @@ int pwc_try_video_mode(struct pwc_device *pdev, int width, int height, int new_f
957 /* Try to set video mode... */ 958 /* Try to set video mode... */
958 start = ret = pwc_set_video_mode(pdev, width, height, new_fps, new_compression, new_snapshot); 959 start = ret = pwc_set_video_mode(pdev, width, height, new_fps, new_compression, new_snapshot);
959 if (ret) { 960 if (ret) {
960 Trace(TRACE_FLOW, "pwc_set_video_mode attempt 1 failed.\n"); 961 PWC_DEBUG_FLOW("pwc_set_video_mode attempt 1 failed.\n");
961 /* That failed... restore old mode (we know that worked) */ 962 /* That failed... restore old mode (we know that worked) */
962 start = pwc_set_video_mode(pdev, pdev->view.x, pdev->view.y, pdev->vframes, pdev->vcompression, pdev->vsnapshot); 963 start = pwc_set_video_mode(pdev, pdev->view.x, pdev->view.y, pdev->vframes, pdev->vcompression, pdev->vsnapshot);
963 if (start) { 964 if (start) {
964 Trace(TRACE_FLOW, "pwc_set_video_mode attempt 2 failed.\n"); 965 PWC_DEBUG_FLOW("pwc_set_video_mode attempt 2 failed.\n");
965 } 966 }
966 } 967 }
967 if (start == 0) 968 if (start == 0)
968 { 969 {
969 if (pwc_isoc_init(pdev) < 0) 970 if (pwc_isoc_init(pdev) < 0)
970 { 971 {
971 Info("Failed to restart ISOC transfers in pwc_try_video_mode.\n"); 972 PWC_WARNING("Failed to restart ISOC transfers in pwc_try_video_mode.\n");
972 ret = -EAGAIN; /* let's try again, who knows if it works a second time */ 973 ret = -EAGAIN; /* let's try again, who knows if it works a second time */
973 } 974 }
974 } 975 }
@@ -976,54 +977,129 @@ int pwc_try_video_mode(struct pwc_device *pdev, int width, int height, int new_f
976 return ret; /* Return original error code */ 977 return ret; /* Return original error code */
977} 978}
978 979
980/*********
981 * sysfs
982 *********/
983static struct pwc_device *cd_to_pwc(struct class_device *cd)
984{
985 struct video_device *vdev = to_video_device(cd);
986 return video_get_drvdata(vdev);
987}
988
989static ssize_t show_pan_tilt(struct class_device *class_dev, char *buf)
990{
991 struct pwc_device *pdev = cd_to_pwc(class_dev);
992 return sprintf(buf, "%d %d\n", pdev->pan_angle, pdev->tilt_angle);
993}
994
995static ssize_t store_pan_tilt(struct class_device *class_dev, const char *buf,
996 size_t count)
997{
998 struct pwc_device *pdev = cd_to_pwc(class_dev);
999 int pan, tilt;
1000 int ret = -EINVAL;
1001
1002 if (strncmp(buf, "reset", 5) == 0)
1003 ret = pwc_mpt_reset(pdev, 0x3);
1004
1005 else if (sscanf(buf, "%d %d", &pan, &tilt) > 0)
1006 ret = pwc_mpt_set_angle(pdev, pan, tilt);
1007
1008 if (ret < 0)
1009 return ret;
1010 return strlen(buf);
1011}
1012static CLASS_DEVICE_ATTR(pan_tilt, S_IRUGO | S_IWUSR, show_pan_tilt,
1013 store_pan_tilt);
1014
1015static ssize_t show_snapshot_button_status(struct class_device *class_dev, char *buf)
1016{
1017 struct pwc_device *pdev = cd_to_pwc(class_dev);
1018 int status = pdev->snapshot_button_status;
1019 pdev->snapshot_button_status = 0;
1020 return sprintf(buf, "%d\n", status);
1021}
1022
1023static CLASS_DEVICE_ATTR(button, S_IRUGO | S_IWUSR, show_snapshot_button_status,
1024 NULL);
1025
1026static void pwc_create_sysfs_files(struct video_device *vdev)
1027{
1028 struct pwc_device *pdev = video_get_drvdata(vdev);
1029 if (pdev->features & FEATURE_MOTOR_PANTILT)
1030 video_device_create_file(vdev, &class_device_attr_pan_tilt);
1031 video_device_create_file(vdev, &class_device_attr_button);
1032}
1033
1034static void pwc_remove_sysfs_files(struct video_device *vdev)
1035{
1036 struct pwc_device *pdev = video_get_drvdata(vdev);
1037 if (pdev->features & FEATURE_MOTOR_PANTILT)
1038 video_device_remove_file(vdev, &class_device_attr_pan_tilt);
1039 video_device_remove_file(vdev, &class_device_attr_button);
1040}
1041
1042#if CONFIG_PWC_DEBUG
1043static const char *pwc_sensor_type_to_string(unsigned int sensor_type)
1044{
1045 switch(sensor_type) {
1046 case 0x00:
1047 return "Hyundai CMOS sensor";
1048 case 0x20:
1049 return "Sony CCD sensor + TDA8787";
1050 case 0x2E:
1051 return "Sony CCD sensor + Exas 98L59";
1052 case 0x2F:
1053 return "Sony CCD sensor + ADI 9804";
1054 case 0x30:
1055 return "Sharp CCD sensor + TDA8787";
1056 case 0x3E:
1057 return "Sharp CCD sensor + Exas 98L59";
1058 case 0x3F:
1059 return "Sharp CCD sensor + ADI 9804";
1060 case 0x40:
1061 return "UPA 1021 sensor";
1062 case 0x100:
1063 return "VGA sensor";
1064 case 0x101:
1065 return "PAL MR sensor";
1066 default:
1067 return "unknown type of sensor";
1068 }
1069}
1070#endif
979 1071
980/***************************************************************************/ 1072/***************************************************************************/
981/* Video4Linux functions */ 1073/* Video4Linux functions */
982 1074
983static int pwc_video_open(struct inode *inode, struct file *file) 1075static int pwc_video_open(struct inode *inode, struct file *file)
984{ 1076{
985 int i; 1077 int i, ret;
986 struct video_device *vdev = video_devdata(file); 1078 struct video_device *vdev = video_devdata(file);
987 struct pwc_device *pdev; 1079 struct pwc_device *pdev;
988 1080
989 Trace(TRACE_OPEN, ">> video_open called(vdev = 0x%p).\n", vdev); 1081 PWC_DEBUG_OPEN(">> video_open called(vdev = 0x%p).\n", vdev);
990 1082
991 pdev = (struct pwc_device *)vdev->priv; 1083 pdev = (struct pwc_device *)vdev->priv;
992 if (pdev == NULL) 1084 if (pdev == NULL)
993 BUG(); 1085 BUG();
994 if (pdev->vopen) 1086 if (pdev->vopen) {
1087 PWC_DEBUG_OPEN("I'm busy, someone is using the device.\n");
995 return -EBUSY; 1088 return -EBUSY;
1089 }
996 1090
997 down(&pdev->modlock); 1091 down(&pdev->modlock);
998 if (!pdev->usb_init) { 1092 if (!pdev->usb_init) {
999 Trace(TRACE_OPEN, "Doing first time initialization.\n"); 1093 PWC_DEBUG_OPEN("Doing first time initialization.\n");
1000 pdev->usb_init = 1; 1094 pdev->usb_init = 1;
1001 1095
1002 if (pwc_trace & TRACE_OPEN) 1096 /* Query sensor type */
1097 ret = pwc_get_cmos_sensor(pdev, &i);
1098 if (ret >= 0)
1003 { 1099 {
1004 /* Query sensor type */ 1100 PWC_DEBUG_OPEN("This %s camera is equipped with a %s (%d).\n",
1005 const char *sensor_type = NULL; 1101 pdev->vdev->name,
1006 int ret; 1102 pwc_sensor_type_to_string(i), i);
1007
1008 ret = pwc_get_cmos_sensor(pdev, &i);
1009 if (ret >= 0)
1010 {
1011 switch(i) {
1012 case 0x00: sensor_type = "Hyundai CMOS sensor"; break;
1013 case 0x20: sensor_type = "Sony CCD sensor + TDA8787"; break;
1014 case 0x2E: sensor_type = "Sony CCD sensor + Exas 98L59"; break;
1015 case 0x2F: sensor_type = "Sony CCD sensor + ADI 9804"; break;
1016 case 0x30: sensor_type = "Sharp CCD sensor + TDA8787"; break;
1017 case 0x3E: sensor_type = "Sharp CCD sensor + Exas 98L59"; break;
1018 case 0x3F: sensor_type = "Sharp CCD sensor + ADI 9804"; break;
1019 case 0x40: sensor_type = "UPA 1021 sensor"; break;
1020 case 0x100: sensor_type = "VGA sensor"; break;
1021 case 0x101: sensor_type = "PAL MR sensor"; break;
1022 default: sensor_type = "unknown type of sensor"; break;
1023 }
1024 }
1025 if (sensor_type != NULL)
1026 Info("This %s camera is equipped with a %s (%d).\n", pdev->vdev->name, sensor_type, i);
1027 } 1103 }
1028 } 1104 }
1029 1105
@@ -1031,34 +1107,32 @@ static int pwc_video_open(struct inode *inode, struct file *file)
1031 if (power_save) { 1107 if (power_save) {
1032 i = pwc_camera_power(pdev, 1); 1108 i = pwc_camera_power(pdev, 1);
1033 if (i < 0) 1109 if (i < 0)
1034 Info("Failed to restore power to the camera! (%d)\n", i); 1110 PWC_DEBUG_OPEN("Failed to restore power to the camera! (%d)\n", i);
1035 } 1111 }
1036 /* Set LED on/off time */ 1112 /* Set LED on/off time */
1037 if (pwc_set_leds(pdev, led_on, led_off) < 0) 1113 if (pwc_set_leds(pdev, led_on, led_off) < 0)
1038 Info("Failed to set LED on/off time.\n"); 1114 PWC_DEBUG_OPEN("Failed to set LED on/off time.\n");
1039 1115
1040 pwc_construct(pdev); /* set min/max sizes correct */ 1116 pwc_construct(pdev); /* set min/max sizes correct */
1041 1117
1042 /* So far, so good. Allocate memory. */ 1118 /* So far, so good. Allocate memory. */
1043 i = pwc_allocate_buffers(pdev); 1119 i = pwc_allocate_buffers(pdev);
1044 if (i < 0) { 1120 if (i < 0) {
1045 Trace(TRACE_OPEN, "Failed to allocate buffer memory.\n"); 1121 PWC_DEBUG_OPEN("Failed to allocate buffers memory.\n");
1122 pwc_free_buffers(pdev);
1046 up(&pdev->modlock); 1123 up(&pdev->modlock);
1047 return i; 1124 return i;
1048 } 1125 }
1049 1126
1050 /* Reset buffers & parameters */ 1127 /* Reset buffers & parameters */
1051 pwc_reset_buffers(pdev); 1128 pwc_reset_buffers(pdev);
1052 for (i = 0; i < default_mbufs; i++) 1129 for (i = 0; i < pwc_mbufs; i++)
1053 pdev->image_used[i] = 0; 1130 pdev->image_used[i] = 0;
1054 pdev->vframe_count = 0; 1131 pdev->vframe_count = 0;
1055 pdev->vframes_dumped = 0; 1132 pdev->vframes_dumped = 0;
1056 pdev->vframes_error = 0; 1133 pdev->vframes_error = 0;
1057 pdev->visoc_errors = 0; 1134 pdev->visoc_errors = 0;
1058 pdev->error_status = 0; 1135 pdev->error_status = 0;
1059#if PWC_DEBUG
1060 pdev->sequence = 0;
1061#endif
1062 pwc_construct(pdev); /* set min/max sizes correct */ 1136 pwc_construct(pdev); /* set min/max sizes correct */
1063 1137
1064 /* Set some defaults */ 1138 /* Set some defaults */
@@ -1070,29 +1144,44 @@ static int pwc_video_open(struct inode *inode, struct file *file)
1070 */ 1144 */
1071 i = pwc_set_video_mode(pdev, pwc_image_sizes[pdev->vsize].x, pwc_image_sizes[pdev->vsize].y, pdev->vframes, pdev->vcompression, 0); 1145 i = pwc_set_video_mode(pdev, pwc_image_sizes[pdev->vsize].x, pwc_image_sizes[pdev->vsize].y, pdev->vframes, pdev->vcompression, 0);
1072 if (i) { 1146 if (i) {
1073 Trace(TRACE_OPEN, "First attempt at set_video_mode failed.\n"); 1147 unsigned int default_resolution;
1074 if (pdev->type == 730 || pdev->type == 740 || pdev->type == 750) 1148 PWC_DEBUG_OPEN("First attempt at set_video_mode failed.\n");
1075 i = pwc_set_video_mode(pdev, pwc_image_sizes[PSZ_QSIF].x, pwc_image_sizes[PSZ_QSIF].y, 10, pdev->vcompression, 0); 1149 if (pdev->type>= 730)
1150 default_resolution = PSZ_QSIF;
1076 else 1151 else
1077 i = pwc_set_video_mode(pdev, pwc_image_sizes[PSZ_QCIF].x, pwc_image_sizes[PSZ_QCIF].y, 10, pdev->vcompression, 0); 1152 default_resolution = PSZ_QCIF;
1153
1154 i = pwc_set_video_mode(pdev,
1155 pwc_image_sizes[default_resolution].x,
1156 pwc_image_sizes[default_resolution].y,
1157 10,
1158 pdev->vcompression,
1159 0);
1078 } 1160 }
1079 if (i) { 1161 if (i) {
1080 Trace(TRACE_OPEN, "Second attempt at set_video_mode failed.\n"); 1162 PWC_DEBUG_OPEN("Second attempt at set_video_mode failed.\n");
1163 pwc_free_buffers(pdev);
1081 up(&pdev->modlock); 1164 up(&pdev->modlock);
1082 return i; 1165 return i;
1083 } 1166 }
1084 1167
1085 i = pwc_isoc_init(pdev); 1168 i = pwc_isoc_init(pdev);
1086 if (i) { 1169 if (i) {
1087 Trace(TRACE_OPEN, "Failed to init ISOC stuff = %d.\n", i); 1170 PWC_DEBUG_OPEN("Failed to init ISOC stuff = %d.\n", i);
1171 pwc_isoc_cleanup(pdev);
1172 pwc_free_buffers(pdev);
1088 up(&pdev->modlock); 1173 up(&pdev->modlock);
1089 return i; 1174 return i;
1090 } 1175 }
1091 1176
1177 /* Initialize the webcam to sane value */
1178 pwc_set_brightness(pdev, 0x7fff);
1179 pwc_set_agc(pdev, 1, 0);
1180
1092 pdev->vopen++; 1181 pdev->vopen++;
1093 file->private_data = vdev; 1182 file->private_data = vdev;
1094 up(&pdev->modlock); 1183 up(&pdev->modlock);
1095 Trace(TRACE_OPEN, "<< video_open() returns 0.\n"); 1184 PWC_DEBUG_OPEN("<< video_open() returns 0.\n");
1096 return 0; 1185 return 0;
1097} 1186}
1098 1187
@@ -1103,35 +1192,23 @@ static int pwc_video_close(struct inode *inode, struct file *file)
1103 struct pwc_device *pdev; 1192 struct pwc_device *pdev;
1104 int i; 1193 int i;
1105 1194
1106 Trace(TRACE_OPEN, ">> video_close called(vdev = 0x%p).\n", vdev); 1195 PWC_DEBUG_OPEN(">> video_close called(vdev = 0x%p).\n", vdev);
1107 1196
1108 pdev = (struct pwc_device *)vdev->priv; 1197 pdev = (struct pwc_device *)vdev->priv;
1109 if (pdev->vopen == 0) 1198 if (pdev->vopen == 0)
1110 Info("video_close() called on closed device?\n"); 1199 PWC_DEBUG_MODULE("video_close() called on closed device?\n");
1111 1200
1112 /* Dump statistics, but only if a reasonable amount of frames were 1201 /* Dump statistics, but only if a reasonable amount of frames were
1113 processed (to prevent endless log-entries in case of snap-shot 1202 processed (to prevent endless log-entries in case of snap-shot
1114 programs) 1203 programs)
1115 */ 1204 */
1116 if (pdev->vframe_count > 20) 1205 if (pdev->vframe_count > 20)
1117 Info("Closing video device: %d frames received, dumped %d frames, %d frames with errors.\n", pdev->vframe_count, pdev->vframes_dumped, pdev->vframes_error); 1206 PWC_DEBUG_MODULE("Closing video device: %d frames received, dumped %d frames, %d frames with errors.\n", pdev->vframe_count, pdev->vframes_dumped, pdev->vframes_error);
1118 1207
1119 switch (pdev->type) 1208 if (DEVICE_USE_CODEC1(pdev->type))
1120 { 1209 pwc_dec1_exit();
1121 case 675: 1210 else
1122 case 680: 1211 pwc_dec23_exit();
1123 case 690:
1124 case 720:
1125 case 730:
1126 case 740:
1127 case 750:
1128/* pwc_dec23_exit(); *//* Timon & Kiara */
1129 break;
1130 case 645:
1131 case 646:
1132/* pwc_dec1_exit(); */
1133 break;
1134 }
1135 1212
1136 pwc_isoc_cleanup(pdev); 1213 pwc_isoc_cleanup(pdev);
1137 pwc_free_buffers(pdev); 1214 pwc_free_buffers(pdev);
@@ -1140,15 +1217,15 @@ static int pwc_video_close(struct inode *inode, struct file *file)
1140 if (pdev->error_status != EPIPE) { 1217 if (pdev->error_status != EPIPE) {
1141 /* Turn LEDs off */ 1218 /* Turn LEDs off */
1142 if (pwc_set_leds(pdev, 0, 0) < 0) 1219 if (pwc_set_leds(pdev, 0, 0) < 0)
1143 Info("Failed to set LED on/off time.\n"); 1220 PWC_DEBUG_MODULE("Failed to set LED on/off time.\n");
1144 if (power_save) { 1221 if (power_save) {
1145 i = pwc_camera_power(pdev, 0); 1222 i = pwc_camera_power(pdev, 0);
1146 if (i < 0) 1223 if (i < 0)
1147 Err("Failed to power down camera (%d)\n", i); 1224 PWC_ERROR("Failed to power down camera (%d)\n", i);
1148 } 1225 }
1149 } 1226 }
1150 pdev->vopen = 0; 1227 pdev->vopen--;
1151 Trace(TRACE_OPEN, "<< video_close()\n"); 1228 PWC_DEBUG_OPEN("<< video_close() vopen=%d\n", pdev->vopen);
1152 return 0; 1229 return 0;
1153} 1230}
1154 1231
@@ -1164,7 +1241,7 @@ static int pwc_video_close(struct inode *inode, struct file *file)
1164 device is tricky anyhow. 1241 device is tricky anyhow.
1165 */ 1242 */
1166 1243
1167static ssize_t pwc_video_read(struct file *file, char __user * buf, 1244static ssize_t pwc_video_read(struct file *file, char __user *buf,
1168 size_t count, loff_t *ppos) 1245 size_t count, loff_t *ppos)
1169{ 1246{
1170 struct video_device *vdev = file->private_data; 1247 struct video_device *vdev = file->private_data;
@@ -1172,8 +1249,10 @@ static ssize_t pwc_video_read(struct file *file, char __user * buf,
1172 int noblock = file->f_flags & O_NONBLOCK; 1249 int noblock = file->f_flags & O_NONBLOCK;
1173 DECLARE_WAITQUEUE(wait, current); 1250 DECLARE_WAITQUEUE(wait, current);
1174 int bytes_to_read; 1251 int bytes_to_read;
1252 void *image_buffer_addr;
1175 1253
1176 Trace(TRACE_READ, "video_read(0x%p, %p, %zu) called.\n", vdev, buf, count); 1254 PWC_DEBUG_READ("pwc_video_read(vdev=0x%p, buf=%p, count=%zd) called.\n",
1255 vdev, buf, count);
1177 if (vdev == NULL) 1256 if (vdev == NULL)
1178 return -EFAULT; 1257 return -EFAULT;
1179 pdev = vdev->priv; 1258 pdev = vdev->priv;
@@ -1214,16 +1293,19 @@ static ssize_t pwc_video_read(struct file *file, char __user * buf,
1214 return -EFAULT; 1293 return -EFAULT;
1215 } 1294 }
1216 1295
1217 Trace(TRACE_READ, "Copying data to user space.\n"); 1296 PWC_DEBUG_READ("Copying data to user space.\n");
1218 if (pdev->vpalette == VIDEO_PALETTE_RAW) 1297 if (pdev->vpalette == VIDEO_PALETTE_RAW)
1219 bytes_to_read = pdev->frame_size; 1298 bytes_to_read = pdev->frame_size + sizeof(struct pwc_raw_frame);
1220 else 1299 else
1221 bytes_to_read = pdev->view.size; 1300 bytes_to_read = pdev->view.size;
1222 1301
1223 /* copy bytes to user space; we allow for partial reads */ 1302 /* copy bytes to user space; we allow for partial reads */
1224 if (count + pdev->image_read_pos > bytes_to_read) 1303 if (count + pdev->image_read_pos > bytes_to_read)
1225 count = bytes_to_read - pdev->image_read_pos; 1304 count = bytes_to_read - pdev->image_read_pos;
1226 if (copy_to_user(buf, pdev->image_ptr[pdev->fill_image] + pdev->image_read_pos, count)) 1305 image_buffer_addr = pdev->image_data;
1306 image_buffer_addr += pdev->images[pdev->fill_image].offset;
1307 image_buffer_addr += pdev->image_read_pos;
1308 if (copy_to_user(buf, image_buffer_addr, count))
1227 return -EFAULT; 1309 return -EFAULT;
1228 pdev->image_read_pos += count; 1310 pdev->image_read_pos += count;
1229 if (pdev->image_read_pos >= bytes_to_read) { /* All data has been read */ 1311 if (pdev->image_read_pos >= bytes_to_read) { /* All data has been read */
@@ -1253,370 +1335,56 @@ static unsigned int pwc_video_poll(struct file *file, poll_table *wait)
1253 return 0; 1335 return 0;
1254} 1336}
1255 1337
1256static int pwc_video_do_ioctl(struct inode *inode, struct file *file,
1257 unsigned int cmd, void *arg)
1258{
1259 struct video_device *vdev = file->private_data;
1260 struct pwc_device *pdev;
1261 DECLARE_WAITQUEUE(wait, current);
1262
1263 if (vdev == NULL)
1264 return -EFAULT;
1265 pdev = vdev->priv;
1266 if (pdev == NULL)
1267 return -EFAULT;
1268
1269 switch (cmd) {
1270 /* Query cabapilities */
1271 case VIDIOCGCAP:
1272 {
1273 struct video_capability *caps = arg;
1274
1275 strcpy(caps->name, vdev->name);
1276 caps->type = VID_TYPE_CAPTURE;
1277 caps->channels = 1;
1278 caps->audios = 1;
1279 caps->minwidth = pdev->view_min.x;
1280 caps->minheight = pdev->view_min.y;
1281 caps->maxwidth = pdev->view_max.x;
1282 caps->maxheight = pdev->view_max.y;
1283 break;
1284 }
1285
1286 /* Channel functions (simulate 1 channel) */
1287 case VIDIOCGCHAN:
1288 {
1289 struct video_channel *v = arg;
1290
1291 if (v->channel != 0)
1292 return -EINVAL;
1293 v->flags = 0;
1294 v->tuners = 0;
1295 v->type = VIDEO_TYPE_CAMERA;
1296 strcpy(v->name, "Webcam");
1297 return 0;
1298 }
1299
1300 case VIDIOCSCHAN:
1301 {
1302 /* The spec says the argument is an integer, but
1303 the bttv driver uses a video_channel arg, which
1304 makes sense becasue it also has the norm flag.
1305 */
1306 struct video_channel *v = arg;
1307 if (v->channel != 0)
1308 return -EINVAL;
1309 return 0;
1310 }
1311
1312
1313 /* Picture functions; contrast etc. */
1314 case VIDIOCGPICT:
1315 {
1316 struct video_picture *p = arg;
1317 int val;
1318
1319 val = pwc_get_brightness(pdev);
1320 if (val >= 0)
1321 p->brightness = val;
1322 else
1323 p->brightness = 0xffff;
1324 val = pwc_get_contrast(pdev);
1325 if (val >= 0)
1326 p->contrast = val;
1327 else
1328 p->contrast = 0xffff;
1329 /* Gamma, Whiteness, what's the difference? :) */
1330 val = pwc_get_gamma(pdev);
1331 if (val >= 0)
1332 p->whiteness = val;
1333 else
1334 p->whiteness = 0xffff;
1335 val = pwc_get_saturation(pdev);
1336 if (val >= 0)
1337 p->colour = val;
1338 else
1339 p->colour = 0xffff;
1340 p->depth = 24;
1341 p->palette = pdev->vpalette;
1342 p->hue = 0xFFFF; /* N/A */
1343 break;
1344 }
1345
1346 case VIDIOCSPICT:
1347 {
1348 struct video_picture *p = arg;
1349 /*
1350 * FIXME: Suppose we are mid read
1351 ANSWER: No problem: the firmware of the camera
1352 can handle brightness/contrast/etc
1353 changes at _any_ time, and the palette
1354 is used exactly once in the uncompress
1355 routine.
1356 */
1357 pwc_set_brightness(pdev, p->brightness);
1358 pwc_set_contrast(pdev, p->contrast);
1359 pwc_set_gamma(pdev, p->whiteness);
1360 pwc_set_saturation(pdev, p->colour);
1361 if (p->palette && p->palette != pdev->vpalette) {
1362 switch (p->palette) {
1363 case VIDEO_PALETTE_YUV420P:
1364 case VIDEO_PALETTE_RAW:
1365 pdev->vpalette = p->palette;
1366 return pwc_try_video_mode(pdev, pdev->image.x, pdev->image.y, pdev->vframes, pdev->vcompression, pdev->vsnapshot);
1367 break;
1368 default:
1369 return -EINVAL;
1370 break;
1371 }
1372 }
1373 break;
1374 }
1375
1376 /* Window/size parameters */
1377 case VIDIOCGWIN:
1378 {
1379 struct video_window *vw = arg;
1380
1381 vw->x = 0;
1382 vw->y = 0;
1383 vw->width = pdev->view.x;
1384 vw->height = pdev->view.y;
1385 vw->chromakey = 0;
1386 vw->flags = (pdev->vframes << PWC_FPS_SHIFT) |
1387 (pdev->vsnapshot ? PWC_FPS_SNAPSHOT : 0);
1388 break;
1389 }
1390
1391 case VIDIOCSWIN:
1392 {
1393 struct video_window *vw = arg;
1394 int fps, snapshot, ret;
1395
1396 fps = (vw->flags & PWC_FPS_FRMASK) >> PWC_FPS_SHIFT;
1397 snapshot = vw->flags & PWC_FPS_SNAPSHOT;
1398 if (fps == 0)
1399 fps = pdev->vframes;
1400 if (pdev->view.x == vw->width && pdev->view.y && fps == pdev->vframes && snapshot == pdev->vsnapshot)
1401 return 0;
1402 ret = pwc_try_video_mode(pdev, vw->width, vw->height, fps, pdev->vcompression, snapshot);
1403 if (ret)
1404 return ret;
1405 break;
1406 }
1407
1408 /* We don't have overlay support (yet) */
1409 case VIDIOCGFBUF:
1410 {
1411 struct video_buffer *vb = arg;
1412
1413 memset(vb,0,sizeof(*vb));
1414 break;
1415 }
1416
1417 /* mmap() functions */
1418 case VIDIOCGMBUF:
1419 {
1420 /* Tell the user program how much memory is needed for a mmap() */
1421 struct video_mbuf *vm = arg;
1422 int i;
1423
1424 memset(vm, 0, sizeof(*vm));
1425 vm->size = default_mbufs * pdev->len_per_image;
1426 vm->frames = default_mbufs; /* double buffering should be enough for most applications */
1427 for (i = 0; i < default_mbufs; i++)
1428 vm->offsets[i] = i * pdev->len_per_image;
1429 break;
1430 }
1431
1432 case VIDIOCMCAPTURE:
1433 {
1434 /* Start capture into a given image buffer (called 'frame' in video_mmap structure) */
1435 struct video_mmap *vm = arg;
1436
1437 Trace(TRACE_READ, "VIDIOCMCAPTURE: %dx%d, frame %d, format %d\n", vm->width, vm->height, vm->frame, vm->format);
1438 if (vm->frame < 0 || vm->frame >= default_mbufs)
1439 return -EINVAL;
1440
1441 /* xawtv is nasty. It probes the available palettes
1442 by setting a very small image size and trying
1443 various palettes... The driver doesn't support
1444 such small images, so I'm working around it.
1445 */
1446 if (vm->format)
1447 {
1448 switch (vm->format)
1449 {
1450 case VIDEO_PALETTE_YUV420P:
1451 case VIDEO_PALETTE_RAW:
1452 break;
1453 default:
1454 return -EINVAL;
1455 break;
1456 }
1457 }
1458
1459 if ((vm->width != pdev->view.x || vm->height != pdev->view.y) &&
1460 (vm->width >= pdev->view_min.x && vm->height >= pdev->view_min.y)) {
1461 int ret;
1462
1463 Trace(TRACE_OPEN, "VIDIOCMCAPTURE: changing size to please xawtv :-(.\n");
1464 ret = pwc_try_video_mode(pdev, vm->width, vm->height, pdev->vframes, pdev->vcompression, pdev->vsnapshot);
1465 if (ret)
1466 return ret;
1467 } /* ... size mismatch */
1468
1469 /* FIXME: should we lock here? */
1470 if (pdev->image_used[vm->frame])
1471 return -EBUSY; /* buffer wasn't available. Bummer */
1472 pdev->image_used[vm->frame] = 1;
1473
1474 /* Okay, we're done here. In the SYNC call we wait until a
1475 frame comes available, then expand image into the given
1476 buffer.
1477 In contrast to the CPiA cam the Philips cams deliver a
1478 constant stream, almost like a grabber card. Also,
1479 we have separate buffers for the rawdata and the image,
1480 meaning we can nearly always expand into the requested buffer.
1481 */
1482 Trace(TRACE_READ, "VIDIOCMCAPTURE done.\n");
1483 break;
1484 }
1485
1486 case VIDIOCSYNC:
1487 {
1488 /* The doc says: "Whenever a buffer is used it should
1489 call VIDIOCSYNC to free this frame up and continue."
1490
1491 The only odd thing about this whole procedure is
1492 that MCAPTURE flags the buffer as "in use", and
1493 SYNC immediately unmarks it, while it isn't
1494 after SYNC that you know that the buffer actually
1495 got filled! So you better not start a CAPTURE in
1496 the same frame immediately (use double buffering).
1497 This is not a problem for this cam, since it has
1498 extra intermediate buffers, but a hardware
1499 grabber card will then overwrite the buffer
1500 you're working on.
1501 */
1502 int *mbuf = arg;
1503 int ret;
1504
1505 Trace(TRACE_READ, "VIDIOCSYNC called (%d).\n", *mbuf);
1506
1507 /* bounds check */
1508 if (*mbuf < 0 || *mbuf >= default_mbufs)
1509 return -EINVAL;
1510 /* check if this buffer was requested anyway */
1511 if (pdev->image_used[*mbuf] == 0)
1512 return -EINVAL;
1513
1514 /* Add ourselves to the frame wait-queue.
1515
1516 FIXME: needs auditing for safety.
1517 QUESTION: In what respect? I think that using the
1518 frameq is safe now.
1519 */
1520 add_wait_queue(&pdev->frameq, &wait);
1521 while (pdev->full_frames == NULL) {
1522 if (pdev->error_status) {
1523 remove_wait_queue(&pdev->frameq, &wait);
1524 set_current_state(TASK_RUNNING);
1525 return -pdev->error_status;
1526 }
1527
1528 if (signal_pending(current)) {
1529 remove_wait_queue(&pdev->frameq, &wait);
1530 set_current_state(TASK_RUNNING);
1531 return -ERESTARTSYS;
1532 }
1533 schedule();
1534 set_current_state(TASK_INTERRUPTIBLE);
1535 }
1536 remove_wait_queue(&pdev->frameq, &wait);
1537 set_current_state(TASK_RUNNING);
1538
1539 /* The frame is ready. Expand in the image buffer
1540 requested by the user. I don't care if you
1541 mmap() 5 buffers and request data in this order:
1542 buffer 4 2 3 0 1 2 3 0 4 3 1 . . .
1543 Grabber hardware may not be so forgiving.
1544 */
1545 Trace(TRACE_READ, "VIDIOCSYNC: frame ready.\n");
1546 pdev->fill_image = *mbuf; /* tell in which buffer we want the image to be expanded */
1547 /* Decompress, etc */
1548 ret = pwc_handle_frame(pdev);
1549 pdev->image_used[*mbuf] = 0;
1550 if (ret)
1551 return -EFAULT;
1552 break;
1553 }
1554
1555 case VIDIOCGAUDIO:
1556 {
1557 struct video_audio *v = arg;
1558
1559 strcpy(v->name, "Microphone");
1560 v->audio = -1; /* unknown audio minor */
1561 v->flags = 0;
1562 v->mode = VIDEO_SOUND_MONO;
1563 v->volume = 0;
1564 v->bass = 0;
1565 v->treble = 0;
1566 v->balance = 0x8000;
1567 v->step = 1;
1568 break;
1569 }
1570
1571 case VIDIOCSAUDIO:
1572 {
1573 /* Dummy: nothing can be set */
1574 break;
1575 }
1576
1577 case VIDIOCGUNIT:
1578 {
1579 struct video_unit *vu = arg;
1580
1581 vu->video = pdev->vdev->minor & 0x3F;
1582 vu->audio = -1; /* not known yet */
1583 vu->vbi = -1;
1584 vu->radio = -1;
1585 vu->teletext = -1;
1586 break;
1587 }
1588 default:
1589 return pwc_ioctl(pdev, cmd, arg);
1590 } /* ..switch */
1591 return 0;
1592}
1593
1594static int pwc_video_ioctl(struct inode *inode, struct file *file, 1338static int pwc_video_ioctl(struct inode *inode, struct file *file,
1595 unsigned int cmd, unsigned long arg) 1339 unsigned int cmd, unsigned long arg)
1596{ 1340{
1597 return video_usercopy(inode, file, cmd, arg, pwc_video_do_ioctl); 1341 return video_usercopy(inode, file, cmd, arg, pwc_video_do_ioctl);
1598} 1342}
1599 1343
1600
1601static int pwc_video_mmap(struct file *file, struct vm_area_struct *vma) 1344static int pwc_video_mmap(struct file *file, struct vm_area_struct *vma)
1602{ 1345{
1603 struct video_device *vdev = file->private_data; 1346 struct video_device *vdev = file->private_data;
1604 struct pwc_device *pdev; 1347 struct pwc_device *pdev;
1605 unsigned long start = vma->vm_start; 1348 unsigned long start;
1606 unsigned long size = vma->vm_end-vma->vm_start; 1349 unsigned long size;
1607 unsigned long page, pos; 1350 unsigned long page, pos = 0;
1351 int index;
1608 1352
1609 Trace(TRACE_MEMORY, "mmap(0x%p, 0x%lx, %lu) called.\n", vdev, start, size); 1353 PWC_DEBUG_MEMORY(">> %s\n", __FUNCTION__);
1610 pdev = vdev->priv; 1354 pdev = vdev->priv;
1355 size = vma->vm_end - vma->vm_start;
1356 start = vma->vm_start;
1611 1357
1612 vma->vm_flags |= VM_IO; 1358 /* Find the idx buffer for this mapping */
1359 for (index = 0; index < pwc_mbufs; index++) {
1360 pos = pdev->images[index].offset;
1361 if ((pos>>PAGE_SHIFT) == vma->vm_pgoff)
1362 break;
1363 }
1364 if (index == MAX_IMAGES)
1365 return -EINVAL;
1366 if (index == 0) {
1367 /*
1368 * Special case for v4l1. In v4l1, we map only one big buffer,
1369 * but in v4l2 each buffer is mapped
1370 */
1371 unsigned long total_size;
1372 total_size = pwc_mbufs * pdev->len_per_image;
1373 if (size != pdev->len_per_image && size != total_size) {
1374 PWC_ERROR("Wrong size (%lu) needed to be len_per_image=%d or total_size=%lu\n",
1375 size, pdev->len_per_image, total_size);
1376 return -EINVAL;
1377 }
1378 } else if (size > pdev->len_per_image)
1379 return -EINVAL;
1380
1381 vma->vm_flags |= VM_IO; /* from 2.6.9-acX */
1613 1382
1614 pos = (unsigned long)pdev->image_data; 1383 pos += (unsigned long)pdev->image_data;
1615 while (size > 0) { 1384 while (size > 0) {
1616 page = vmalloc_to_pfn((void *)pos); 1385 page = vmalloc_to_pfn((void *)pos);
1617 if (remap_pfn_range(vma, start, page, PAGE_SIZE, PAGE_SHARED)) 1386 if (remap_pfn_range(vma, start, page, PAGE_SIZE, PAGE_SHARED))
1618 return -EAGAIN; 1387 return -EAGAIN;
1619
1620 start += PAGE_SIZE; 1388 start += PAGE_SIZE;
1621 pos += PAGE_SIZE; 1389 pos += PAGE_SIZE;
1622 if (size > PAGE_SIZE) 1390 if (size > PAGE_SIZE)
@@ -1624,7 +1392,6 @@ static int pwc_video_mmap(struct file *file, struct vm_area_struct *vma)
1624 else 1392 else
1625 size = 0; 1393 size = 0;
1626 } 1394 }
1627
1628 return 0; 1395 return 0;
1629} 1396}
1630 1397
@@ -1645,10 +1412,12 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id
1645 int video_nr = -1; /* default: use next available device */ 1412 int video_nr = -1; /* default: use next available device */
1646 char serial_number[30], *name; 1413 char serial_number[30], *name;
1647 1414
1415 vendor_id = le16_to_cpu(udev->descriptor.idVendor);
1416 product_id = le16_to_cpu(udev->descriptor.idProduct);
1417
1648 /* Check if we can handle this device */ 1418 /* Check if we can handle this device */
1649 Trace(TRACE_PROBE, "probe() called [%04X %04X], if %d\n", 1419 PWC_DEBUG_PROBE("probe() called [%04X %04X], if %d\n",
1650 le16_to_cpu(udev->descriptor.idVendor), 1420 vendor_id, product_id,
1651 le16_to_cpu(udev->descriptor.idProduct),
1652 intf->altsetting->desc.bInterfaceNumber); 1421 intf->altsetting->desc.bInterfaceNumber);
1653 1422
1654 /* the interfaces are probed one by one. We are only interested in the 1423 /* the interfaces are probed one by one. We are only interested in the
@@ -1658,61 +1427,63 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id
1658 if (intf->altsetting->desc.bInterfaceNumber > 0) 1427 if (intf->altsetting->desc.bInterfaceNumber > 0)
1659 return -ENODEV; 1428 return -ENODEV;
1660 1429
1661 vendor_id = le16_to_cpu(udev->descriptor.idVendor);
1662 product_id = le16_to_cpu(udev->descriptor.idProduct);
1663
1664 if (vendor_id == 0x0471) { 1430 if (vendor_id == 0x0471) {
1665 switch (product_id) { 1431 switch (product_id) {
1666 case 0x0302: 1432 case 0x0302:
1667 Info("Philips PCA645VC USB webcam detected.\n"); 1433 PWC_INFO("Philips PCA645VC USB webcam detected.\n");
1668 name = "Philips 645 webcam"; 1434 name = "Philips 645 webcam";
1669 type_id = 645; 1435 type_id = 645;
1670 break; 1436 break;
1671 case 0x0303: 1437 case 0x0303:
1672 Info("Philips PCA646VC USB webcam detected.\n"); 1438 PWC_INFO("Philips PCA646VC USB webcam detected.\n");
1673 name = "Philips 646 webcam"; 1439 name = "Philips 646 webcam";
1674 type_id = 646; 1440 type_id = 646;
1675 break; 1441 break;
1676 case 0x0304: 1442 case 0x0304:
1677 Info("Askey VC010 type 2 USB webcam detected.\n"); 1443 PWC_INFO("Askey VC010 type 2 USB webcam detected.\n");
1678 name = "Askey VC010 webcam"; 1444 name = "Askey VC010 webcam";
1679 type_id = 646; 1445 type_id = 646;
1680 break; 1446 break;
1681 case 0x0307: 1447 case 0x0307:
1682 Info("Philips PCVC675K (Vesta) USB webcam detected.\n"); 1448 PWC_INFO("Philips PCVC675K (Vesta) USB webcam detected.\n");
1683 name = "Philips 675 webcam"; 1449 name = "Philips 675 webcam";
1684 type_id = 675; 1450 type_id = 675;
1685 break; 1451 break;
1686 case 0x0308: 1452 case 0x0308:
1687 Info("Philips PCVC680K (Vesta Pro) USB webcam detected.\n"); 1453 PWC_INFO("Philips PCVC680K (Vesta Pro) USB webcam detected.\n");
1688 name = "Philips 680 webcam"; 1454 name = "Philips 680 webcam";
1689 type_id = 680; 1455 type_id = 680;
1690 break; 1456 break;
1691 case 0x030C: 1457 case 0x030C:
1692 Info("Philips PCVC690K (Vesta Pro Scan) USB webcam detected.\n"); 1458 PWC_INFO("Philips PCVC690K (Vesta Pro Scan) USB webcam detected.\n");
1693 name = "Philips 690 webcam"; 1459 name = "Philips 690 webcam";
1694 type_id = 690; 1460 type_id = 690;
1695 break; 1461 break;
1696 case 0x0310: 1462 case 0x0310:
1697 Info("Philips PCVC730K (ToUCam Fun)/PCVC830 (ToUCam II) USB webcam detected.\n"); 1463 PWC_INFO("Philips PCVC730K (ToUCam Fun)/PCVC830 (ToUCam II) USB webcam detected.\n");
1698 name = "Philips 730 webcam"; 1464 name = "Philips 730 webcam";
1699 type_id = 730; 1465 type_id = 730;
1700 break; 1466 break;
1701 case 0x0311: 1467 case 0x0311:
1702 Info("Philips PCVC740K (ToUCam Pro)/PCVC840 (ToUCam II) USB webcam detected.\n"); 1468 PWC_INFO("Philips PCVC740K (ToUCam Pro)/PCVC840 (ToUCam II) USB webcam detected.\n");
1703 name = "Philips 740 webcam"; 1469 name = "Philips 740 webcam";
1704 type_id = 740; 1470 type_id = 740;
1705 break; 1471 break;
1706 case 0x0312: 1472 case 0x0312:
1707 Info("Philips PCVC750K (ToUCam Pro Scan) USB webcam detected.\n"); 1473 PWC_INFO("Philips PCVC750K (ToUCam Pro Scan) USB webcam detected.\n");
1708 name = "Philips 750 webcam"; 1474 name = "Philips 750 webcam";
1709 type_id = 750; 1475 type_id = 750;
1710 break; 1476 break;
1711 case 0x0313: 1477 case 0x0313:
1712 Info("Philips PCVC720K/40 (ToUCam XS) USB webcam detected.\n"); 1478 PWC_INFO("Philips PCVC720K/40 (ToUCam XS) USB webcam detected.\n");
1713 name = "Philips 720K/40 webcam"; 1479 name = "Philips 720K/40 webcam";
1714 type_id = 720; 1480 type_id = 720;
1715 break; 1481 break;
1482 case 0x0329:
1483 PWC_INFO("Philips SPC 900NC USB webcam detected.\n");
1484 name = "Philips SPC 900NC webcam";
1485 type_id = 720;
1486 break;
1716 default: 1487 default:
1717 return -ENODEV; 1488 return -ENODEV;
1718 break; 1489 break;
@@ -1721,7 +1492,7 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id
1721 else if (vendor_id == 0x069A) { 1492 else if (vendor_id == 0x069A) {
1722 switch(product_id) { 1493 switch(product_id) {
1723 case 0x0001: 1494 case 0x0001:
1724 Info("Askey VC010 type 1 USB webcam detected.\n"); 1495 PWC_INFO("Askey VC010 type 1 USB webcam detected.\n");
1725 name = "Askey VC010 webcam"; 1496 name = "Askey VC010 webcam";
1726 type_id = 645; 1497 type_id = 645;
1727 break; 1498 break;
@@ -1733,32 +1504,33 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id
1733 else if (vendor_id == 0x046d) { 1504 else if (vendor_id == 0x046d) {
1734 switch(product_id) { 1505 switch(product_id) {
1735 case 0x08b0: 1506 case 0x08b0:
1736 Info("Logitech QuickCam Pro 3000 USB webcam detected.\n"); 1507 PWC_INFO("Logitech QuickCam Pro 3000 USB webcam detected.\n");
1737 name = "Logitech QuickCam Pro 3000"; 1508 name = "Logitech QuickCam Pro 3000";
1738 type_id = 740; /* CCD sensor */ 1509 type_id = 740; /* CCD sensor */
1739 break; 1510 break;
1740 case 0x08b1: 1511 case 0x08b1:
1741 Info("Logitech QuickCam Notebook Pro USB webcam detected.\n"); 1512 PWC_INFO("Logitech QuickCam Notebook Pro USB webcam detected.\n");
1742 name = "Logitech QuickCam Notebook Pro"; 1513 name = "Logitech QuickCam Notebook Pro";
1743 type_id = 740; /* CCD sensor */ 1514 type_id = 740; /* CCD sensor */
1744 break; 1515 break;
1745 case 0x08b2: 1516 case 0x08b2:
1746 Info("Logitech QuickCam 4000 Pro USB webcam detected.\n"); 1517 PWC_INFO("Logitech QuickCam 4000 Pro USB webcam detected.\n");
1747 name = "Logitech QuickCam Pro 4000"; 1518 name = "Logitech QuickCam Pro 4000";
1748 type_id = 740; /* CCD sensor */ 1519 type_id = 740; /* CCD sensor */
1749 break; 1520 break;
1750 case 0x08b3: 1521 case 0x08b3:
1751 Info("Logitech QuickCam Zoom USB webcam detected.\n"); 1522 PWC_INFO("Logitech QuickCam Zoom USB webcam detected.\n");
1752 name = "Logitech QuickCam Zoom"; 1523 name = "Logitech QuickCam Zoom";
1753 type_id = 740; /* CCD sensor */ 1524 type_id = 740; /* CCD sensor */
1754 break; 1525 break;
1755 case 0x08B4: 1526 case 0x08B4:
1756 Info("Logitech QuickCam Zoom (new model) USB webcam detected.\n"); 1527 PWC_INFO("Logitech QuickCam Zoom (new model) USB webcam detected.\n");
1757 name = "Logitech QuickCam Zoom"; 1528 name = "Logitech QuickCam Zoom";
1758 type_id = 740; /* CCD sensor */ 1529 type_id = 740; /* CCD sensor */
1530 power_save = 1;
1759 break; 1531 break;
1760 case 0x08b5: 1532 case 0x08b5:
1761 Info("Logitech QuickCam Orbit/Sphere USB webcam detected.\n"); 1533 PWC_INFO("Logitech QuickCam Orbit/Sphere USB webcam detected.\n");
1762 name = "Logitech QuickCam Orbit"; 1534 name = "Logitech QuickCam Orbit";
1763 type_id = 740; /* CCD sensor */ 1535 type_id = 740; /* CCD sensor */
1764 features |= FEATURE_MOTOR_PANTILT; 1536 features |= FEATURE_MOTOR_PANTILT;
@@ -1766,7 +1538,7 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id
1766 case 0x08b6: 1538 case 0x08b6:
1767 case 0x08b7: 1539 case 0x08b7:
1768 case 0x08b8: 1540 case 0x08b8:
1769 Info("Logitech QuickCam detected (reserved ID).\n"); 1541 PWC_INFO("Logitech QuickCam detected (reserved ID).\n");
1770 name = "Logitech QuickCam (res.)"; 1542 name = "Logitech QuickCam (res.)";
1771 type_id = 730; /* Assuming CMOS */ 1543 type_id = 730; /* Assuming CMOS */
1772 break; 1544 break;
@@ -1782,15 +1554,20 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id
1782 */ 1554 */
1783 switch(product_id) { 1555 switch(product_id) {
1784 case 0x9000: 1556 case 0x9000:
1785 Info("Samsung MPC-C10 USB webcam detected.\n"); 1557 PWC_INFO("Samsung MPC-C10 USB webcam detected.\n");
1786 name = "Samsung MPC-C10"; 1558 name = "Samsung MPC-C10";
1787 type_id = 675; 1559 type_id = 675;
1788 break; 1560 break;
1789 case 0x9001: 1561 case 0x9001:
1790 Info("Samsung MPC-C30 USB webcam detected.\n"); 1562 PWC_INFO("Samsung MPC-C30 USB webcam detected.\n");
1791 name = "Samsung MPC-C30"; 1563 name = "Samsung MPC-C30";
1792 type_id = 675; 1564 type_id = 675;
1793 break; 1565 break;
1566 case 0x9002:
1567 PWC_INFO("Samsung SNC-35E (v3.0) USB webcam detected.\n");
1568 name = "Samsung MPC-C30";
1569 type_id = 740;
1570 break;
1794 default: 1571 default:
1795 return -ENODEV; 1572 return -ENODEV;
1796 break; 1573 break;
@@ -1799,12 +1576,12 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id
1799 else if (vendor_id == 0x041e) { 1576 else if (vendor_id == 0x041e) {
1800 switch(product_id) { 1577 switch(product_id) {
1801 case 0x400c: 1578 case 0x400c:
1802 Info("Creative Labs Webcam 5 detected.\n"); 1579 PWC_INFO("Creative Labs Webcam 5 detected.\n");
1803 name = "Creative Labs Webcam 5"; 1580 name = "Creative Labs Webcam 5";
1804 type_id = 730; 1581 type_id = 730;
1805 break; 1582 break;
1806 case 0x4011: 1583 case 0x4011:
1807 Info("Creative Labs Webcam Pro Ex detected.\n"); 1584 PWC_INFO("Creative Labs Webcam Pro Ex detected.\n");
1808 name = "Creative Labs Webcam Pro Ex"; 1585 name = "Creative Labs Webcam Pro Ex";
1809 type_id = 740; 1586 type_id = 740;
1810 break; 1587 break;
@@ -1816,7 +1593,7 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id
1816 else if (vendor_id == 0x04cc) { 1593 else if (vendor_id == 0x04cc) {
1817 switch(product_id) { 1594 switch(product_id) {
1818 case 0x8116: 1595 case 0x8116:
1819 Info("Sotec Afina Eye USB webcam detected.\n"); 1596 PWC_INFO("Sotec Afina Eye USB webcam detected.\n");
1820 name = "Sotec Afina Eye"; 1597 name = "Sotec Afina Eye";
1821 type_id = 730; 1598 type_id = 730;
1822 break; 1599 break;
@@ -1829,7 +1606,7 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id
1829 switch(product_id) { 1606 switch(product_id) {
1830 case 0x8116: 1607 case 0x8116:
1831 /* This is essentially the same cam as the Sotec Afina Eye */ 1608 /* This is essentially the same cam as the Sotec Afina Eye */
1832 Info("AME Co. Afina Eye USB webcam detected.\n"); 1609 PWC_INFO("AME Co. Afina Eye USB webcam detected.\n");
1833 name = "AME Co. Afina Eye"; 1610 name = "AME Co. Afina Eye";
1834 type_id = 750; 1611 type_id = 750;
1835 break; 1612 break;
@@ -1842,12 +1619,12 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id
1842 else if (vendor_id == 0x0d81) { 1619 else if (vendor_id == 0x0d81) {
1843 switch(product_id) { 1620 switch(product_id) {
1844 case 0x1900: 1621 case 0x1900:
1845 Info("Visionite VCS-UC300 USB webcam detected.\n"); 1622 PWC_INFO("Visionite VCS-UC300 USB webcam detected.\n");
1846 name = "Visionite VCS-UC300"; 1623 name = "Visionite VCS-UC300";
1847 type_id = 740; /* CCD sensor */ 1624 type_id = 740; /* CCD sensor */
1848 break; 1625 break;
1849 case 0x1910: 1626 case 0x1910:
1850 Info("Visionite VCS-UM100 USB webcam detected.\n"); 1627 PWC_INFO("Visionite VCS-UM100 USB webcam detected.\n");
1851 name = "Visionite VCS-UM100"; 1628 name = "Visionite VCS-UM100";
1852 type_id = 730; /* CMOS sensor */ 1629 type_id = 730; /* CMOS sensor */
1853 break; 1630 break;
@@ -1861,15 +1638,15 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id
1861 1638
1862 memset(serial_number, 0, 30); 1639 memset(serial_number, 0, 30);
1863 usb_string(udev, udev->descriptor.iSerialNumber, serial_number, 29); 1640 usb_string(udev, udev->descriptor.iSerialNumber, serial_number, 29);
1864 Trace(TRACE_PROBE, "Device serial number is %s\n", serial_number); 1641 PWC_DEBUG_PROBE("Device serial number is %s\n", serial_number);
1865 1642
1866 if (udev->descriptor.bNumConfigurations > 1) 1643 if (udev->descriptor.bNumConfigurations > 1)
1867 Info("Warning: more than 1 configuration available.\n"); 1644 PWC_WARNING("Warning: more than 1 configuration available.\n");
1868 1645
1869 /* Allocate structure, initialize pointers, mutexes, etc. and link it to the usb_device */ 1646 /* Allocate structure, initialize pointers, mutexes, etc. and link it to the usb_device */
1870 pdev = kzalloc(sizeof(struct pwc_device), GFP_KERNEL); 1647 pdev = kzalloc(sizeof(struct pwc_device), GFP_KERNEL);
1871 if (pdev == NULL) { 1648 if (pdev == NULL) {
1872 Err("Oops, could not allocate memory for pwc_device.\n"); 1649 PWC_ERROR("Oops, could not allocate memory for pwc_device.\n");
1873 return -ENOMEM; 1650 return -ENOMEM;
1874 } 1651 }
1875 pdev->type = type_id; 1652 pdev->type = type_id;
@@ -1900,17 +1677,18 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id
1900 pdev->vdev = video_device_alloc(); 1677 pdev->vdev = video_device_alloc();
1901 if (pdev->vdev == 0) 1678 if (pdev->vdev == 0)
1902 { 1679 {
1903 Err("Err, cannot allocate video_device struture. Failing probe."); 1680 PWC_ERROR("Err, cannot allocate video_device struture. Failing probe.");
1904 kfree(pdev); 1681 kfree(pdev);
1905 return -ENOMEM; 1682 return -ENOMEM;
1906 } 1683 }
1907 memcpy(pdev->vdev, &pwc_template, sizeof(pwc_template)); 1684 memcpy(pdev->vdev, &pwc_template, sizeof(pwc_template));
1685 pdev->vdev->dev = &(udev->dev);
1908 strcpy(pdev->vdev->name, name); 1686 strcpy(pdev->vdev->name, name);
1909 pdev->vdev->owner = THIS_MODULE; 1687 pdev->vdev->owner = THIS_MODULE;
1910 video_set_drvdata(pdev->vdev, pdev); 1688 video_set_drvdata(pdev->vdev, pdev);
1911 1689
1912 pdev->release = le16_to_cpu(udev->descriptor.bcdDevice); 1690 pdev->release = le16_to_cpu(udev->descriptor.bcdDevice);
1913 Trace(TRACE_PROBE, "Release: %04x\n", pdev->release); 1691 PWC_DEBUG_PROBE("Release: %04x\n", pdev->release);
1914 1692
1915 /* Now search device_hint[] table for a match, so we can hint a node number. */ 1693 /* Now search device_hint[] table for a match, so we can hint a node number. */
1916 for (hint = 0; hint < MAX_DEV_HINTS; hint++) { 1694 for (hint = 0; hint < MAX_DEV_HINTS; hint++) {
@@ -1920,7 +1698,7 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id
1920 if ((device_hint[hint].serial_number[0] == '*') || !strcmp(device_hint[hint].serial_number, serial_number)) { 1698 if ((device_hint[hint].serial_number[0] == '*') || !strcmp(device_hint[hint].serial_number, serial_number)) {
1921 /* match! */ 1699 /* match! */
1922 video_nr = device_hint[hint].device_node; 1700 video_nr = device_hint[hint].device_node;
1923 Trace(TRACE_PROBE, "Found hint, will try to register as /dev/video%d\n", video_nr); 1701 PWC_DEBUG_PROBE("Found hint, will try to register as /dev/video%d\n", video_nr);
1924 break; 1702 break;
1925 } 1703 }
1926 } 1704 }
@@ -1929,21 +1707,27 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id
1929 pdev->vdev->release = video_device_release; 1707 pdev->vdev->release = video_device_release;
1930 i = video_register_device(pdev->vdev, VFL_TYPE_GRABBER, video_nr); 1708 i = video_register_device(pdev->vdev, VFL_TYPE_GRABBER, video_nr);
1931 if (i < 0) { 1709 if (i < 0) {
1932 Err("Failed to register as video device (%d).\n", i); 1710 PWC_ERROR("Failed to register as video device (%d).\n", i);
1933 video_device_release(pdev->vdev); /* Drip... drip... drip... */ 1711 video_device_release(pdev->vdev); /* Drip... drip... drip... */
1934 kfree(pdev); /* Oops, no memory leaks please */ 1712 kfree(pdev); /* Oops, no memory leaks please */
1935 return -EIO; 1713 return -EIO;
1936 } 1714 }
1937 else { 1715 else {
1938 Info("Registered as /dev/video%d.\n", pdev->vdev->minor & 0x3F); 1716 PWC_INFO("Registered as /dev/video%d.\n", pdev->vdev->minor & 0x3F);
1939 } 1717 }
1940 1718
1941 /* occupy slot */ 1719 /* occupy slot */
1942 if (hint < MAX_DEV_HINTS) 1720 if (hint < MAX_DEV_HINTS)
1943 device_hint[hint].pdev = pdev; 1721 device_hint[hint].pdev = pdev;
1944 1722
1945 Trace(TRACE_PROBE, "probe() function returning struct at 0x%p.\n", pdev); 1723 PWC_DEBUG_PROBE("probe() function returning struct at 0x%p.\n", pdev);
1946 usb_set_intfdata (intf, pdev); 1724 usb_set_intfdata (intf, pdev);
1725 pwc_create_sysfs_files(pdev->vdev);
1726
1727 /* Set the leds off */
1728 pwc_set_leds(pdev, 0, 0);
1729 pwc_camera_power(pdev, 0);
1730
1947 return 0; 1731 return 0;
1948} 1732}
1949 1733
@@ -1957,27 +1741,21 @@ static void usb_pwc_disconnect(struct usb_interface *intf)
1957 pdev = usb_get_intfdata (intf); 1741 pdev = usb_get_intfdata (intf);
1958 usb_set_intfdata (intf, NULL); 1742 usb_set_intfdata (intf, NULL);
1959 if (pdev == NULL) { 1743 if (pdev == NULL) {
1960 Err("pwc_disconnect() Called without private pointer.\n"); 1744 PWC_ERROR("pwc_disconnect() Called without private pointer.\n");
1961 goto disconnect_out; 1745 goto disconnect_out;
1962 } 1746 }
1963 if (pdev->udev == NULL) { 1747 if (pdev->udev == NULL) {
1964 Err("pwc_disconnect() already called for %p\n", pdev); 1748 PWC_ERROR("pwc_disconnect() already called for %p\n", pdev);
1965 goto disconnect_out; 1749 goto disconnect_out;
1966 } 1750 }
1967 if (pdev->udev != interface_to_usbdev(intf)) { 1751 if (pdev->udev != interface_to_usbdev(intf)) {
1968 Err("pwc_disconnect() Woops: pointer mismatch udev/pdev.\n"); 1752 PWC_ERROR("pwc_disconnect() Woops: pointer mismatch udev/pdev.\n");
1969 goto disconnect_out;
1970 }
1971#ifdef PWC_MAGIC
1972 if (pdev->magic != PWC_MAGIC) {
1973 Err("pwc_disconnect() Magic number failed. Consult your scrolls and try again.\n");
1974 goto disconnect_out; 1753 goto disconnect_out;
1975 } 1754 }
1976#endif
1977 1755
1978 /* We got unplugged; this is signalled by an EPIPE error code */ 1756 /* We got unplugged; this is signalled by an EPIPE error code */
1979 if (pdev->vopen) { 1757 if (pdev->vopen) {
1980 Info("Disconnected while webcam is in use!\n"); 1758 PWC_INFO("Disconnected while webcam is in use!\n");
1981 pdev->error_status = EPIPE; 1759 pdev->error_status = EPIPE;
1982 } 1760 }
1983 1761
@@ -1987,7 +1765,8 @@ static void usb_pwc_disconnect(struct usb_interface *intf)
1987 while (pdev->vopen) 1765 while (pdev->vopen)
1988 schedule(); 1766 schedule();
1989 /* Device is now closed, so we can safely unregister it */ 1767 /* Device is now closed, so we can safely unregister it */
1990 Trace(TRACE_PROBE, "Unregistering video device in disconnect().\n"); 1768 PWC_DEBUG_PROBE("Unregistering video device in disconnect().\n");
1769 pwc_remove_sysfs_files(pdev->vdev);
1991 video_unregister_device(pdev->vdev); 1770 video_unregister_device(pdev->vdev);
1992 1771
1993 /* Free memory (don't set pdev to 0 just yet) */ 1772 /* Free memory (don't set pdev to 0 just yet) */
@@ -2021,58 +1800,64 @@ static int pwc_atoi(const char *s)
2021 * Initialization code & module stuff 1800 * Initialization code & module stuff
2022 */ 1801 */
2023 1802
2024static char size[10]; 1803static char *size;
2025static int fps = 0; 1804static int fps;
2026static int fbufs = 0; 1805static int fbufs;
2027static int mbufs = 0; 1806static int mbufs;
2028static int trace = -1;
2029static int compression = -1; 1807static int compression = -1;
2030static int leds[2] = { -1, -1 }; 1808static int leds[2] = { -1, -1 };
2031static char *dev_hint[MAX_DEV_HINTS] = { }; 1809static int leds_nargs;
1810static char *dev_hint[MAX_DEV_HINTS];
1811static int dev_hint_nargs;
1812
1813module_param(size, charp, 0444);
1814module_param(fps, int, 0444);
1815module_param(fbufs, int, 0444);
1816module_param(mbufs, int, 0444);
1817#if CONFIG_PWC_DEBUG
1818module_param_named(trace, pwc_trace, int, 0644);
1819#endif
1820module_param(power_save, int, 0444);
1821module_param(compression, int, 0444);
1822module_param_array(leds, int, &leds_nargs, 0444);
1823module_param_array(dev_hint, charp, &dev_hint_nargs, 0444);
2032 1824
2033module_param_string(size, size, sizeof(size), 0);
2034MODULE_PARM_DESC(size, "Initial image size. One of sqcif, qsif, qcif, sif, cif, vga"); 1825MODULE_PARM_DESC(size, "Initial image size. One of sqcif, qsif, qcif, sif, cif, vga");
2035module_param(fps, int, 0000);
2036MODULE_PARM_DESC(fps, "Initial frames per second. Varies with model, useful range 5-30"); 1826MODULE_PARM_DESC(fps, "Initial frames per second. Varies with model, useful range 5-30");
2037module_param(fbufs, int, 0000);
2038MODULE_PARM_DESC(fbufs, "Number of internal frame buffers to reserve"); 1827MODULE_PARM_DESC(fbufs, "Number of internal frame buffers to reserve");
2039module_param(mbufs, int, 0000);
2040MODULE_PARM_DESC(mbufs, "Number of external (mmap()ed) image buffers"); 1828MODULE_PARM_DESC(mbufs, "Number of external (mmap()ed) image buffers");
2041module_param(trace, int, 0000);
2042MODULE_PARM_DESC(trace, "For debugging purposes"); 1829MODULE_PARM_DESC(trace, "For debugging purposes");
2043module_param(power_save, bool, 0000);
2044MODULE_PARM_DESC(power_save, "Turn power save feature in camera on or off"); 1830MODULE_PARM_DESC(power_save, "Turn power save feature in camera on or off");
2045module_param(compression, int, 0000);
2046MODULE_PARM_DESC(compression, "Preferred compression quality. Range 0 (uncompressed) to 3 (high compression)"); 1831MODULE_PARM_DESC(compression, "Preferred compression quality. Range 0 (uncompressed) to 3 (high compression)");
2047module_param_array(leds, int, NULL, 0000);
2048MODULE_PARM_DESC(leds, "LED on,off time in milliseconds"); 1832MODULE_PARM_DESC(leds, "LED on,off time in milliseconds");
2049module_param_array(dev_hint, charp, NULL, 0000);
2050MODULE_PARM_DESC(dev_hint, "Device node hints"); 1833MODULE_PARM_DESC(dev_hint, "Device node hints");
2051 1834
2052MODULE_DESCRIPTION("Philips & OEM USB webcam driver"); 1835MODULE_DESCRIPTION("Philips & OEM USB webcam driver");
2053MODULE_AUTHOR("Luc Saillard <luc@saillard.org>"); 1836MODULE_AUTHOR("Luc Saillard <luc@saillard.org>");
2054MODULE_LICENSE("GPL"); 1837MODULE_LICENSE("GPL");
1838MODULE_ALIAS("pwcx");
1839MODULE_VERSION( PWC_VERSION );
2055 1840
2056static int __init usb_pwc_init(void) 1841static int __init usb_pwc_init(void)
2057{ 1842{
2058 int i, sz; 1843 int i, sz;
2059 char *sizenames[PSZ_MAX] = { "sqcif", "qsif", "qcif", "sif", "cif", "vga" }; 1844 char *sizenames[PSZ_MAX] = { "sqcif", "qsif", "qcif", "sif", "cif", "vga" };
2060 1845
2061 Info("Philips webcam module version " PWC_VERSION " loaded.\n"); 1846 PWC_INFO("Philips webcam module version " PWC_VERSION " loaded.\n");
2062 Info("Supports Philips PCA645/646, PCVC675/680/690, PCVC720[40]/730/740/750 & PCVC830/840.\n"); 1847 PWC_INFO("Supports Philips PCA645/646, PCVC675/680/690, PCVC720[40]/730/740/750 & PCVC830/840.\n");
2063 Info("Also supports the Askey VC010, various Logitech Quickcams, Samsung MPC-C10 and MPC-C30,\n"); 1848 PWC_INFO("Also supports the Askey VC010, various Logitech Quickcams, Samsung MPC-C10 and MPC-C30,\n");
2064 Info("the Creative WebCam 5 & Pro Ex, SOTEC Afina Eye and Visionite VCS-UC300 and VCS-UM100.\n"); 1849 PWC_INFO("the Creative WebCam 5 & Pro Ex, SOTEC Afina Eye and Visionite VCS-UC300 and VCS-UM100.\n");
2065 1850
2066 if (fps) { 1851 if (fps) {
2067 if (fps < 4 || fps > 30) { 1852 if (fps < 4 || fps > 30) {
2068 Err("Framerate out of bounds (4-30).\n"); 1853 PWC_ERROR("Framerate out of bounds (4-30).\n");
2069 return -EINVAL; 1854 return -EINVAL;
2070 } 1855 }
2071 default_fps = fps; 1856 default_fps = fps;
2072 Info("Default framerate set to %d.\n", default_fps); 1857 PWC_DEBUG_MODULE("Default framerate set to %d.\n", default_fps);
2073 } 1858 }
2074 1859
2075 if (size[0]) { 1860 if (size) {
2076 /* string; try matching with array */ 1861 /* string; try matching with array */
2077 for (sz = 0; sz < PSZ_MAX; sz++) { 1862 for (sz = 0; sz < PSZ_MAX; sz++) {
2078 if (!strcmp(sizenames[sz], size)) { /* Found! */ 1863 if (!strcmp(sizenames[sz], size)) { /* Found! */
@@ -2081,41 +1866,42 @@ static int __init usb_pwc_init(void)
2081 } 1866 }
2082 } 1867 }
2083 if (sz == PSZ_MAX) { 1868 if (sz == PSZ_MAX) {
2084 Err("Size not recognized; try size=[sqcif | qsif | qcif | sif | cif | vga].\n"); 1869 PWC_ERROR("Size not recognized; try size=[sqcif | qsif | qcif | sif | cif | vga].\n");
2085 return -EINVAL; 1870 return -EINVAL;
2086 } 1871 }
2087 Info("Default image size set to %s [%dx%d].\n", sizenames[default_size], pwc_image_sizes[default_size].x, pwc_image_sizes[default_size].y); 1872 PWC_DEBUG_MODULE("Default image size set to %s [%dx%d].\n", sizenames[default_size], pwc_image_sizes[default_size].x, pwc_image_sizes[default_size].y);
2088 } 1873 }
2089 if (mbufs) { 1874 if (mbufs) {
2090 if (mbufs < 1 || mbufs > MAX_IMAGES) { 1875 if (mbufs < 1 || mbufs > MAX_IMAGES) {
2091 Err("Illegal number of mmap() buffers; use a number between 1 and %d.\n", MAX_IMAGES); 1876 PWC_ERROR("Illegal number of mmap() buffers; use a number between 1 and %d.\n", MAX_IMAGES);
2092 return -EINVAL; 1877 return -EINVAL;
2093 } 1878 }
2094 default_mbufs = mbufs; 1879 pwc_mbufs = mbufs;
2095 Info("Number of image buffers set to %d.\n", default_mbufs); 1880 PWC_DEBUG_MODULE("Number of image buffers set to %d.\n", pwc_mbufs);
2096 } 1881 }
2097 if (fbufs) { 1882 if (fbufs) {
2098 if (fbufs < 2 || fbufs > MAX_FRAMES) { 1883 if (fbufs < 2 || fbufs > MAX_FRAMES) {
2099 Err("Illegal number of frame buffers; use a number between 2 and %d.\n", MAX_FRAMES); 1884 PWC_ERROR("Illegal number of frame buffers; use a number between 2 and %d.\n", MAX_FRAMES);
2100 return -EINVAL; 1885 return -EINVAL;
2101 } 1886 }
2102 default_fbufs = fbufs; 1887 default_fbufs = fbufs;
2103 Info("Number of frame buffers set to %d.\n", default_fbufs); 1888 PWC_DEBUG_MODULE("Number of frame buffers set to %d.\n", default_fbufs);
2104 } 1889 }
2105 if (trace >= 0) { 1890#if CONFIG_PWC_DEBUG
2106 Info("Trace options: 0x%04x\n", trace); 1891 if (pwc_trace >= 0) {
2107 pwc_trace = trace; 1892 PWC_DEBUG_MODULE("Trace options: 0x%04x\n", pwc_trace);
2108 } 1893 }
1894#endif
2109 if (compression >= 0) { 1895 if (compression >= 0) {
2110 if (compression > 3) { 1896 if (compression > 3) {
2111 Err("Invalid compression setting; use a number between 0 (uncompressed) and 3 (high).\n"); 1897 PWC_ERROR("Invalid compression setting; use a number between 0 (uncompressed) and 3 (high).\n");
2112 return -EINVAL; 1898 return -EINVAL;
2113 } 1899 }
2114 pwc_preferred_compression = compression; 1900 pwc_preferred_compression = compression;
2115 Info("Preferred compression set to %d.\n", pwc_preferred_compression); 1901 PWC_DEBUG_MODULE("Preferred compression set to %d.\n", pwc_preferred_compression);
2116 } 1902 }
2117 if (power_save) 1903 if (power_save)
2118 Info("Enabling power save on open/close.\n"); 1904 PWC_DEBUG_MODULE("Enabling power save on open/close.\n");
2119 if (leds[0] >= 0) 1905 if (leds[0] >= 0)
2120 led_on = leds[0]; 1906 led_on = leds[0];
2121 if (leds[1] >= 0) 1907 if (leds[1] >= 0)
@@ -2146,14 +1932,14 @@ static int __init usb_pwc_init(void)
2146 dot++; 1932 dot++;
2147 /* Few sanity checks */ 1933 /* Few sanity checks */
2148 if (*dot != '\0' && dot > colon) { 1934 if (*dot != '\0' && dot > colon) {
2149 Err("Malformed camera hint: the colon must be after the dot.\n"); 1935 PWC_ERROR("Malformed camera hint: the colon must be after the dot.\n");
2150 return -EINVAL; 1936 return -EINVAL;
2151 } 1937 }
2152 1938
2153 if (*colon == '\0') { 1939 if (*colon == '\0') {
2154 /* No colon */ 1940 /* No colon */
2155 if (*dot != '\0') { 1941 if (*dot != '\0') {
2156 Err("Malformed camera hint: no colon + device node given.\n"); 1942 PWC_ERROR("Malformed camera hint: no colon + device node given.\n");
2157 return -EINVAL; 1943 return -EINVAL;
2158 } 1944 }
2159 else { 1945 else {
@@ -2178,28 +1964,27 @@ static int __init usb_pwc_init(void)
2178 device_hint[i].serial_number[k] = '\0'; 1964 device_hint[i].serial_number[k] = '\0';
2179 } 1965 }
2180 } 1966 }
2181#if PWC_DEBUG 1967 PWC_TRACE("device_hint[%d]:\n", i);
2182 Debug("device_hint[%d]:\n", i); 1968 PWC_TRACE(" type : %d\n", device_hint[i].type);
2183 Debug(" type : %d\n", device_hint[i].type); 1969 PWC_TRACE(" serial# : %s\n", device_hint[i].serial_number);
2184 Debug(" serial# : %s\n", device_hint[i].serial_number); 1970 PWC_TRACE(" node : %d\n", device_hint[i].device_node);
2185 Debug(" node : %d\n", device_hint[i].device_node);
2186#endif
2187 } 1971 }
2188 else 1972 else
2189 device_hint[i].type = 0; /* not filled */ 1973 device_hint[i].type = 0; /* not filled */
2190 } /* ..for MAX_DEV_HINTS */ 1974 } /* ..for MAX_DEV_HINTS */
2191 1975
2192 Trace(TRACE_PROBE, "Registering driver at address 0x%p.\n", &pwc_driver); 1976 PWC_DEBUG_PROBE("Registering driver at address 0x%p.\n", &pwc_driver);
2193 return usb_register(&pwc_driver); 1977 return usb_register(&pwc_driver);
2194} 1978}
2195 1979
2196static void __exit usb_pwc_exit(void) 1980static void __exit usb_pwc_exit(void)
2197{ 1981{
2198 Trace(TRACE_MODULE, "Deregistering driver.\n"); 1982 PWC_DEBUG_MODULE("Deregistering driver.\n");
2199 usb_deregister(&pwc_driver); 1983 usb_deregister(&pwc_driver);
2200 Info("Philips webcam module removed.\n"); 1984 PWC_INFO("Philips webcam module removed.\n");
2201} 1985}
2202 1986
2203module_init(usb_pwc_init); 1987module_init(usb_pwc_init);
2204module_exit(usb_pwc_exit); 1988module_exit(usb_pwc_exit);
2205 1989
1990/* 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
index 4c96037f7be5..fec39cc5a9f1 100644
--- a/drivers/media/video/pwc/pwc-kiara.c
+++ b/drivers/media/video/pwc/pwc-kiara.c
@@ -1,5 +1,5 @@
1/* Linux driver for Philips webcam 1/* Linux driver for Philips webcam
2 (C) 2004 Luc Saillard (luc@saillard.org) 2 (C) 2004-2006 Luc Saillard (luc@saillard.org)
3 3
4 NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx 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. 5 driver and thus may have bugs that are not present in the original version.
@@ -316,3 +316,576 @@ const struct Kiara_table_entry Kiara_table[PSZ_MAX][6][4] =
316 }, 316 },
317}; 317};
318 318
319
320/*
321 * Rom table for kiara chips
322 *
323 * 32 roms tables (one for each resolution ?)
324 * 2 tables per roms (one for each passes) (Y, and U&V)
325 * 128 bytes per passes
326 */
327
328const unsigned int KiaraRomTable [8][2][16][8] =
329{
330 { /* version 0 */
331 { /* version 0, passes 0 */
332 {0x00000000,0x00000000,0x00000000,0x00000000,
333 0x00000000,0x00000000,0x00000001,0x00000001},
334 {0x00000000,0x00000000,0x00000009,0x00000009,
335 0x00000009,0x00000009,0x00000009,0x00000009},
336 {0x00000000,0x00000000,0x00000009,0x00000049,
337 0x00000049,0x00000049,0x00000049,0x00000049},
338 {0x00000000,0x00000000,0x00000049,0x00000049,
339 0x00000049,0x00000249,0x0000024a,0x00000049},
340 {0x00000000,0x00000000,0x00000049,0x00000049,
341 0x00000249,0x00000249,0x0000024a,0x0000024a},
342 {0x00000000,0x00000000,0x00000049,0x00000249,
343 0x00000249,0x0000124a,0x0000024a,0x0000024a},
344 {0x00000000,0x00000000,0x00000049,0x00000249,
345 0x0000124a,0x00009252,0x00001252,0x00001252},
346 {0x00000000,0x00000000,0x00000249,0x00000249,
347 0x00009252,0x00009292,0x00009292,0x00009292},
348 {0x00000000,0x00000000,0x00000249,0x00001249,
349 0x00009292,0x00009292,0x00009493,0x000124db},
350 {0x00000000,0x00000000,0x00000249,0x0000924a,
351 0x00009492,0x0000a49b,0x0000a49b,0x000124db},
352 {0x00000000,0x00000000,0x00001249,0x00009252,
353 0x0000a493,0x000124db,0x000124db,0x000126dc},
354 {0x00000000,0x00000000,0x00001249,0x00009493,
355 0x000124db,0x000126dc,0x000136e4,0x000126dc},
356 {0x00000000,0x00000000,0x00009292,0x0000a49b,
357 0x000124db,0x000136e4,0x000136e4,0x000136e4},
358 {0x00000000,0x00000000,0x00009292,0x0000a49b,
359 0x000126dc,0x0001b724,0x0001b92d,0x0001b925},
360 {0x00000000,0x00000000,0x00009492,0x000124db,
361 0x000136e4,0x0001b925,0x0001c96e,0x0001c92d},
362 {0x00000000,0x00000000,0x00000000,0x00000000,
363 0x00000000,0x00000000,0x00000000,0x00000000}
364 },
365 { /* version 0, passes 1 */
366 {0x00000000,0x00000000,0x00000000,0x00000000,
367 0x00000000,0x00000000,0x00000000,0x00000000},
368 {0x00000000,0x00000000,0x00000000,0x00000000,
369 0x00000000,0x00000000,0x00000000,0x00000000},
370 {0x00000000,0x00000000,0x00000001,0x00000009,
371 0x00000009,0x00000009,0x00000009,0x00000001},
372 {0x00000000,0x00000000,0x00000009,0x00000009,
373 0x00000049,0x00000049,0x00000049,0x00000049},
374 {0x00000000,0x00000000,0x00000049,0x00000049,
375 0x00000049,0x00000049,0x0000024a,0x0000024a},
376 {0x00000000,0x00000000,0x00000049,0x00000049,
377 0x00000249,0x00000249,0x0000024a,0x0000024a},
378 {0x00000000,0x00000000,0x00000049,0x00000249,
379 0x00000249,0x00000249,0x0000024a,0x00001252},
380 {0x00000000,0x00000000,0x00000049,0x00001249,
381 0x0000124a,0x0000124a,0x00001252,0x00009292},
382 {0x00000000,0x00000000,0x00000249,0x00001249,
383 0x00009252,0x00009252,0x00009292,0x00009493},
384 {0x00000000,0x00000000,0x00000249,0x0000924a,
385 0x00009292,0x00009292,0x00009292,0x00009493},
386 {0x00000000,0x00000000,0x00000249,0x00009292,
387 0x00009492,0x00009493,0x0000a49b,0x00009493},
388 {0x00000000,0x00000000,0x00001249,0x00009292,
389 0x0000a493,0x000124db,0x000126dc,0x000126dc},
390 {0x00000000,0x00000000,0x0000924a,0x00009493,
391 0x0000a493,0x000126dc,0x000136e4,0x000136e4},
392 {0x00000000,0x00000000,0x00009252,0x00009493,
393 0x000126dc,0x000126dc,0x000136e4,0x000136e4},
394 {0x00000000,0x00000000,0x00009292,0x0000a49b,
395 0x000136e4,0x000136e4,0x0001b725,0x0001b724},
396 {0x00000000,0x00000000,0x00000000,0x00000000,
397 0x00000000,0x00000000,0x00000000,0x00000000}
398 }
399 },
400 { /* version 1 */
401 { /* version 1, passes 0 */
402 {0x00000000,0x00000000,0x00000000,0x00000000,
403 0x00000000,0x00000000,0x00000000,0x00000001},
404 {0x00000000,0x00000000,0x00000009,0x00000009,
405 0x00000009,0x00000009,0x00000009,0x00000009},
406 {0x00000000,0x00000000,0x00000049,0x00000049,
407 0x00000049,0x00000049,0x00000049,0x00000049},
408 {0x00000000,0x00000000,0x00000049,0x00000049,
409 0x00000049,0x00000249,0x0000024a,0x0000024a},
410 {0x00000000,0x00000000,0x00000049,0x00000249,
411 0x00000249,0x00000249,0x0000024a,0x00001252},
412 {0x00000000,0x00000000,0x00000249,0x00000249,
413 0x00000249,0x0000124a,0x00001252,0x00001252},
414 {0x00000000,0x00000000,0x00000249,0x00000249,
415 0x0000124a,0x0000124a,0x00009292,0x00009292},
416 {0x00000000,0x00000000,0x00000249,0x00001249,
417 0x0000124a,0x00009252,0x00009292,0x00009292},
418 {0x00000000,0x00000000,0x00000249,0x00001249,
419 0x00009252,0x00009292,0x00009292,0x00009292},
420 {0x00000000,0x00000000,0x00000249,0x00001249,
421 0x00009252,0x00009292,0x00009493,0x00009493},
422 {0x00000000,0x00000000,0x00000249,0x0000924a,
423 0x00009252,0x00009493,0x00009493,0x00009493},
424 {0x00000000,0x00000000,0x00000249,0x0000924a,
425 0x00009292,0x00009493,0x00009493,0x00009493},
426 {0x00000000,0x00000000,0x00000249,0x00009252,
427 0x00009492,0x00009493,0x0000a49b,0x0000a49b},
428 {0x00000000,0x00000000,0x00001249,0x00009292,
429 0x00009492,0x000124db,0x000124db,0x000124db},
430 {0x00000000,0x00000000,0x0000924a,0x00009493,
431 0x0000a493,0x000126dc,0x000126dc,0x000126dc},
432 {0x00000000,0x00000000,0x00000000,0x00000000,
433 0x00000000,0x00000000,0x00000000,0x00000000}
434 },
435 { /* version 1, passes 1 */
436 {0x00000000,0x00000000,0x00000000,0x00000000,
437 0x00000000,0x00000000,0x00000000,0x00000000},
438 {0x00000000,0x00000000,0x00000049,0x00000009,
439 0x00000049,0x00000009,0x00000001,0x00000000},
440 {0x00000000,0x00000000,0x00000049,0x00000049,
441 0x00000049,0x00000049,0x00000049,0x00000000},
442 {0x00000000,0x00000000,0x00000249,0x00000049,
443 0x00000249,0x00000049,0x0000024a,0x00000001},
444 {0x00000000,0x00000000,0x00000249,0x00000249,
445 0x00000249,0x00000249,0x0000024a,0x00000001},
446 {0x00000000,0x00000000,0x00000249,0x00000249,
447 0x00000249,0x00000249,0x0000024a,0x00000001},
448 {0x00000000,0x00000000,0x00000249,0x00000249,
449 0x00000249,0x00000249,0x0000024a,0x00000009},
450 {0x00000000,0x00000000,0x00000249,0x00000249,
451 0x0000124a,0x0000124a,0x0000024a,0x00000009},
452 {0x00000000,0x00000000,0x00000249,0x00000249,
453 0x0000124a,0x0000124a,0x0000024a,0x00000009},
454 {0x00000000,0x00000000,0x00001249,0x00001249,
455 0x0000124a,0x00009252,0x00001252,0x00000049},
456 {0x00000000,0x00000000,0x00001249,0x00001249,
457 0x0000124a,0x00009292,0x00001252,0x00000049},
458 {0x00000000,0x00000000,0x00001249,0x00001249,
459 0x0000124a,0x00009292,0x00001252,0x00000049},
460 {0x00000000,0x00000000,0x00001249,0x00001249,
461 0x00009252,0x00009292,0x00001252,0x0000024a},
462 {0x00000000,0x00000000,0x00001249,0x00001249,
463 0x00009292,0x00009292,0x00001252,0x0000024a},
464 {0x00000000,0x00000000,0x0000924a,0x0000924a,
465 0x00009492,0x00009493,0x00009292,0x00001252},
466 {0x00000000,0x00000000,0x00000000,0x00000000,
467 0x00000000,0x00000000,0x00000000,0x00000000}
468 }
469 },
470 { /* version 2 */
471 { /* version 2, passes 0 */
472 {0x00000000,0x00000000,0x00000049,0x00000049,
473 0x00000049,0x00000049,0x0000024a,0x0000024a},
474 {0x00000000,0x00000000,0x00000249,0x00000249,
475 0x00000249,0x0000124a,0x00001252,0x00009292},
476 {0x00000000,0x00000000,0x00000249,0x00000249,
477 0x0000124a,0x00009252,0x00009292,0x00009292},
478 {0x00000000,0x00000000,0x00000249,0x00001249,
479 0x0000124a,0x00009292,0x00009493,0x00009493},
480 {0x00000000,0x00000000,0x00000249,0x00001249,
481 0x00009252,0x00009493,0x00009493,0x0000a49b},
482 {0x00000000,0x00000000,0x00000249,0x0000924a,
483 0x00009292,0x00009493,0x0000a49b,0x0000a49b},
484 {0x00000000,0x00000000,0x00001249,0x0000924a,
485 0x00009292,0x00009493,0x0000a49b,0x000124db},
486 {0x00000000,0x00000000,0x00001249,0x00009252,
487 0x00009492,0x0000a49b,0x0000a49b,0x000124db},
488 {0x00000000,0x00000000,0x00001249,0x00009292,
489 0x00009492,0x000124db,0x000124db,0x000126dc},
490 {0x00000000,0x00000000,0x00001249,0x00009292,
491 0x0000a493,0x000124db,0x000126dc,0x000126dc},
492 {0x00000000,0x00000000,0x00001249,0x00009493,
493 0x0000a493,0x000124db,0x000126dc,0x000136e4},
494 {0x00000000,0x00000000,0x00001249,0x00009493,
495 0x0000a493,0x000126dc,0x000136e4,0x000136e4},
496 {0x00000000,0x00000000,0x0000924a,0x00009493,
497 0x0001249b,0x000126dc,0x000136e4,0x000136e4},
498 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
499 0x000124db,0x000136e4,0x000136e4,0x0001b724},
500 {0x00000000,0x00000000,0x00009252,0x000124db,
501 0x000126dc,0x0001b724,0x0001b725,0x0001b925},
502 {0x00000000,0x00000000,0x00000000,0x00000000,
503 0x00000000,0x00000000,0x00000000,0x00000000}
504 },
505 { /* version 2, passes 1 */
506 {0x00000000,0x00000000,0x00000049,0x00000049,
507 0x00000049,0x00000049,0x00000049,0x00000049},
508 {0x00000000,0x00000000,0x00000249,0x00000249,
509 0x00000249,0x00000249,0x0000024a,0x00000049},
510 {0x00000000,0x00000000,0x00001249,0x00000249,
511 0x0000124a,0x0000124a,0x00001252,0x00000049},
512 {0x00000000,0x00000000,0x00001249,0x00001249,
513 0x0000124a,0x0000124a,0x00009292,0x0000024a},
514 {0x00000000,0x00000000,0x00001249,0x00001249,
515 0x00009252,0x00009292,0x00009292,0x0000024a},
516 {0x00000000,0x00000000,0x00001249,0x00001249,
517 0x00009252,0x00009292,0x0000a49b,0x0000024a},
518 {0x00000000,0x00000000,0x00001249,0x00001249,
519 0x00009292,0x00009493,0x0000a49b,0x00001252},
520 {0x00000000,0x00000000,0x00001249,0x00001249,
521 0x00009292,0x00009493,0x0000a49b,0x00001252},
522 {0x00000000,0x00000000,0x00001249,0x0000924a,
523 0x00009492,0x0000a49b,0x0000a49b,0x00001252},
524 {0x00000000,0x00000000,0x00001249,0x00009252,
525 0x00009492,0x0000a49b,0x0000a49b,0x00009292},
526 {0x00000000,0x00000000,0x00001249,0x00009292,
527 0x00009492,0x0000a49b,0x0000a49b,0x00009292},
528 {0x00000000,0x00000000,0x00001249,0x00009493,
529 0x0000a493,0x0000a49b,0x0000a49b,0x00009292},
530 {0x00000000,0x00000000,0x00001249,0x00009493,
531 0x0000a493,0x0000a49b,0x0000a49b,0x00009493},
532 {0x00000000,0x00000000,0x0000924a,0x00009493,
533 0x0000a493,0x000124db,0x0000a49b,0x00009493},
534 {0x00000000,0x00000000,0x00009252,0x0000a49b,
535 0x0001249b,0x000126dc,0x000124db,0x0000a49b},
536 {0x00000000,0x00000000,0x00000000,0x00000000,
537 0x00000000,0x00000000,0x00000000,0x00000000}
538 }
539 },
540 { /* version 3 */
541 { /* version 3, passes 0 */
542 {0x00000000,0x00000000,0x00000249,0x00000249,
543 0x0000124a,0x0000124a,0x00009292,0x00009292},
544 {0x00000000,0x00000000,0x00001249,0x00001249,
545 0x00009292,0x00009493,0x0000a49b,0x0000a49b},
546 {0x00000000,0x00000000,0x00001249,0x0000924a,
547 0x00009492,0x0000a49b,0x0000a49b,0x000124db},
548 {0x00000000,0x00000000,0x00001249,0x00009292,
549 0x00009492,0x000124db,0x000126dc,0x000126dc},
550 {0x00000000,0x00000000,0x00001249,0x00009493,
551 0x0000a493,0x000124db,0x000126dc,0x000126dc},
552 {0x00000000,0x00000000,0x00001249,0x00009493,
553 0x0000a493,0x000126dc,0x000136e4,0x000136e4},
554 {0x00000000,0x00000000,0x00001249,0x00009493,
555 0x0000a493,0x000126dc,0x000136e4,0x0001b724},
556 {0x00000000,0x00000000,0x00001249,0x00009493,
557 0x0001249b,0x000126dc,0x000136e4,0x0001b724},
558 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
559 0x0001249b,0x000126dc,0x000136e4,0x0001b724},
560 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
561 0x0001249b,0x000136e4,0x0001b725,0x0001b724},
562 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
563 0x000124db,0x000136e4,0x0001b725,0x0001b925},
564 {0x00000000,0x00000000,0x00009292,0x0000a49b,
565 0x000126dc,0x000136e4,0x0001b92d,0x0001b925},
566 {0x00000000,0x00000000,0x00009292,0x0000a49b,
567 0x000126dc,0x0001b724,0x0001b92d,0x0001c92d},
568 {0x00000000,0x00000000,0x00009492,0x000124db,
569 0x000126dc,0x0001b724,0x0001c96e,0x0001c92d},
570 {0x00000000,0x00000000,0x0000a492,0x000126db,
571 0x000136e4,0x0001b925,0x00025bb6,0x00024b77},
572 {0x00000000,0x00000000,0x00000000,0x00000000,
573 0x00000000,0x00000000,0x00000000,0x00000000}
574 },
575 { /* version 3, passes 1 */
576 {0x00000000,0x00000000,0x00001249,0x00000249,
577 0x0000124a,0x0000124a,0x00001252,0x00001252},
578 {0x00000000,0x00000000,0x00001249,0x00001249,
579 0x00009252,0x00009292,0x00009292,0x00001252},
580 {0x00000000,0x00000000,0x00001249,0x0000924a,
581 0x00009492,0x00009493,0x0000a49b,0x00001252},
582 {0x00000000,0x00000000,0x00001249,0x00009252,
583 0x00009492,0x0000a49b,0x0000a49b,0x00009292},
584 {0x00000000,0x00000000,0x00001249,0x00009292,
585 0x00009492,0x0000a49b,0x0000a49b,0x00009292},
586 {0x00000000,0x00000000,0x00001249,0x00009493,
587 0x0000a493,0x0000a49b,0x000126dc,0x00009292},
588 {0x00000000,0x00000000,0x0000924a,0x00009493,
589 0x0000a493,0x0000a49b,0x000126dc,0x00009493},
590 {0x00000000,0x00000000,0x0000924a,0x00009493,
591 0x0000a493,0x0000a49b,0x000126dc,0x00009493},
592 {0x00000000,0x00000000,0x0000924a,0x00009493,
593 0x0000a493,0x000124db,0x000126dc,0x00009493},
594 {0x00000000,0x00000000,0x0000924a,0x00009493,
595 0x0000a493,0x000124db,0x000126dc,0x0000a49b},
596 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
597 0x0000a493,0x000124db,0x000126dc,0x0000a49b},
598 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
599 0x0001249b,0x000126dc,0x000126dc,0x0000a49b},
600 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
601 0x000124db,0x000136e4,0x000126dc,0x000124db},
602 {0x00000000,0x00000000,0x00009492,0x0000a49b,
603 0x000136e4,0x000136e4,0x000126dc,0x000124db},
604 {0x00000000,0x00000000,0x0000a492,0x000124db,
605 0x0001b724,0x0001b724,0x000136e4,0x000126dc},
606 {0x00000000,0x00000000,0x00000000,0x00000000,
607 0x00000000,0x00000000,0x00000000,0x00000000}
608 }
609 },
610 { /* version 4 */
611 { /* version 4, passes 0 */
612 {0x00000000,0x00000000,0x00000049,0x00000049,
613 0x00000049,0x00000049,0x00000049,0x00000049},
614 {0x00000000,0x00000000,0x00000249,0x00000049,
615 0x00000249,0x00000249,0x0000024a,0x00000049},
616 {0x00000000,0x00000000,0x00000249,0x00000249,
617 0x0000124a,0x00009252,0x00001252,0x0000024a},
618 {0x00000000,0x00000000,0x00001249,0x00001249,
619 0x00009252,0x00009292,0x00009493,0x00001252},
620 {0x00000000,0x00000000,0x00001249,0x0000924a,
621 0x00009292,0x00009493,0x00009493,0x00001252},
622 {0x00000000,0x00000000,0x00001249,0x00009292,
623 0x00009492,0x0000a49b,0x0000a49b,0x00009292},
624 {0x00000000,0x00000000,0x00001249,0x00009493,
625 0x0000a493,0x000124db,0x000124db,0x00009493},
626 {0x00000000,0x00000000,0x0000924a,0x00009493,
627 0x0000a493,0x000124db,0x000126dc,0x0000a49b},
628 {0x00000000,0x00000000,0x0000924a,0x00009493,
629 0x0000a493,0x000124db,0x000126dc,0x0000a49b},
630 {0x00000000,0x00000000,0x0000924a,0x00009493,
631 0x0001249b,0x000126dc,0x000126dc,0x000124db},
632 {0x00000000,0x00000000,0x00009252,0x00009493,
633 0x000124db,0x000136e4,0x000136e4,0x000126dc},
634 {0x00000000,0x00000000,0x00009252,0x0000a49b,
635 0x000124db,0x000136e4,0x000136e4,0x000126dc},
636 {0x00000000,0x00000000,0x00009292,0x0000a49b,
637 0x000126dc,0x000136e4,0x000136e4,0x000136e4},
638 {0x00000000,0x00000000,0x00009492,0x0000a49b,
639 0x000126dc,0x0001b724,0x0001b725,0x0001b724},
640 {0x00000000,0x00000000,0x0000a492,0x000124db,
641 0x000136e4,0x0001b925,0x0001b92d,0x0001b925},
642 {0x00000000,0x00000000,0x00000000,0x00000000,
643 0x00000000,0x00000000,0x00000000,0x00000000}
644 },
645 { /* version 4, passes 1 */
646 {0x00000000,0x00000000,0x00000249,0x00000049,
647 0x00000009,0x00000009,0x00000009,0x00000009},
648 {0x00000000,0x00000000,0x00000249,0x00000249,
649 0x00000049,0x00000049,0x00000009,0x00000009},
650 {0x00000000,0x00000000,0x00001249,0x00001249,
651 0x0000124a,0x00000249,0x00000049,0x00000049},
652 {0x00000000,0x00000000,0x00001249,0x00001249,
653 0x0000124a,0x0000124a,0x00000049,0x00000049},
654 {0x00000000,0x00000000,0x00001249,0x00001249,
655 0x00009252,0x0000124a,0x0000024a,0x0000024a},
656 {0x00000000,0x00000000,0x00001249,0x0000924a,
657 0x00009252,0x0000124a,0x0000024a,0x0000024a},
658 {0x00000000,0x00000000,0x00001249,0x00009292,
659 0x00009492,0x00009252,0x00001252,0x00001252},
660 {0x00000000,0x00000000,0x00001249,0x00009493,
661 0x0000a493,0x00009292,0x00009292,0x00001252},
662 {0x00000000,0x00000000,0x0000924a,0x00009493,
663 0x0000a493,0x00009292,0x00009292,0x00009292},
664 {0x00000000,0x00000000,0x0000924a,0x00009493,
665 0x0000a493,0x00009493,0x00009493,0x00009292},
666 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
667 0x0000a493,0x0000a49b,0x00009493,0x00009493},
668 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
669 0x0000a493,0x0000a49b,0x0000a49b,0x00009493},
670 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
671 0x0001249b,0x000124db,0x0000a49b,0x0000a49b},
672 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
673 0x000136e4,0x000126dc,0x000124db,0x0000a49b},
674 {0x00000000,0x00000000,0x00009252,0x000124db,
675 0x0001b724,0x000136e4,0x000126dc,0x000124db},
676 {0x00000000,0x00000000,0x00000000,0x00000000,
677 0x00000000,0x00000000,0x00000000,0x00000000}
678 }
679 },
680 { /* version 5 */
681 { /* version 5, passes 0 */
682 {0x00000000,0x00000000,0x00000249,0x00000249,
683 0x00000249,0x00000249,0x00001252,0x00001252},
684 {0x00000000,0x00000000,0x00001249,0x00001249,
685 0x00009252,0x00009292,0x00009292,0x00001252},
686 {0x00000000,0x00000000,0x00001249,0x0000924a,
687 0x00009492,0x0000a49b,0x0000a49b,0x00009292},
688 {0x00000000,0x00000000,0x00001249,0x00009493,
689 0x0000a493,0x0000a49b,0x000124db,0x00009493},
690 {0x00000000,0x00000000,0x00001249,0x00009493,
691 0x0000a493,0x000124db,0x000126dc,0x00009493},
692 {0x00000000,0x00000000,0x0000924a,0x00009493,
693 0x0000a493,0x000126dc,0x000126dc,0x0000a49b},
694 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
695 0x0001249b,0x000126dc,0x000136e4,0x000124db},
696 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
697 0x000126dc,0x000136e4,0x000136e4,0x000126dc},
698 {0x00000000,0x00000000,0x00009292,0x0000a49b,
699 0x000126dc,0x000136e4,0x000136e4,0x000126dc},
700 {0x00000000,0x00000000,0x00009292,0x0000a49b,
701 0x000126dc,0x0001b724,0x0001b725,0x000136e4},
702 {0x00000000,0x00000000,0x00009292,0x0000a49b,
703 0x000136e4,0x0001b724,0x0001b92d,0x0001b724},
704 {0x00000000,0x00000000,0x00009492,0x0000a49b,
705 0x000136e4,0x0001b724,0x0001b92d,0x0001b724},
706 {0x00000000,0x00000000,0x00009492,0x000124db,
707 0x000136e4,0x0001b925,0x0001c96e,0x0001b925},
708 {0x00000000,0x00000000,0x00009492,0x000124db,
709 0x0001b724,0x0001b925,0x0001c96e,0x0001c92d},
710 {0x00000000,0x00000000,0x0000a492,0x000126db,
711 0x0001c924,0x0002496d,0x00025bb6,0x00024b77},
712 {0x00000000,0x00000000,0x00000000,0x00000000,
713 0x00000000,0x00000000,0x00000000,0x00000000}
714 },
715 { /* version 5, passes 1 */
716 {0x00000000,0x00000000,0x00001249,0x00000249,
717 0x00000249,0x00000249,0x0000024a,0x0000024a},
718 {0x00000000,0x00000000,0x00001249,0x00001249,
719 0x0000124a,0x0000124a,0x0000024a,0x0000024a},
720 {0x00000000,0x00000000,0x00001249,0x0000924a,
721 0x00009252,0x00009252,0x0000024a,0x0000024a},
722 {0x00000000,0x00000000,0x00001249,0x00009292,
723 0x00009492,0x0000a49b,0x00001252,0x00001252},
724 {0x00000000,0x00000000,0x0000924a,0x00009493,
725 0x0000a493,0x0000a49b,0x00001252,0x00001252},
726 {0x00000000,0x00000000,0x0000924a,0x00009493,
727 0x0000a493,0x0000a49b,0x00009292,0x00001252},
728 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
729 0x0000a493,0x0000a49b,0x00009292,0x00009292},
730 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
731 0x0000a493,0x0000a49b,0x00009493,0x00009292},
732 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
733 0x0001249b,0x000124db,0x00009493,0x00009292},
734 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
735 0x0001249b,0x000124db,0x00009493,0x00009493},
736 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
737 0x000124db,0x000124db,0x0000a49b,0x00009493},
738 {0x00000000,0x00000000,0x0000924a,0x000124db,
739 0x000126dc,0x000126dc,0x0000a49b,0x00009493},
740 {0x00000000,0x00000000,0x0000924a,0x000124db,
741 0x000136e4,0x000126dc,0x000124db,0x0000a49b},
742 {0x00000000,0x00000000,0x00009292,0x000124db,
743 0x000136e4,0x000126dc,0x000124db,0x0000a49b},
744 {0x00000000,0x00000000,0x00009492,0x000126db,
745 0x0001b724,0x000136e4,0x000126dc,0x000124db},
746 {0x00000000,0x00000000,0x00000000,0x00000000,
747 0x00000000,0x00000000,0x00000000,0x00000000}
748 }
749 },
750 { /* version 6 */
751 { /* version 6, passes 0 */
752 {0x00000000,0x00000000,0x00001249,0x00001249,
753 0x00009252,0x00009292,0x00009493,0x00009493},
754 {0x00000000,0x00000000,0x00001249,0x00009292,
755 0x0000a493,0x0000a49b,0x0000a49b,0x00009493},
756 {0x00000000,0x00000000,0x00001249,0x00009493,
757 0x0000a493,0x000124db,0x000124db,0x0000a49b},
758 {0x00000000,0x00000000,0x0000924a,0x00009493,
759 0x0000a493,0x000126dc,0x000126dc,0x0000a49b},
760 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
761 0x0001249b,0x000126dc,0x000136e4,0x000124db},
762 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
763 0x000126dc,0x000136e4,0x000136e4,0x000126dc},
764 {0x00000000,0x00000000,0x00009292,0x0000a49b,
765 0x000126dc,0x0001b724,0x0001b725,0x000126dc},
766 {0x00000000,0x00000000,0x00009292,0x0000a49b,
767 0x000136e4,0x0001b724,0x0001b92d,0x000136e4},
768 {0x00000000,0x00000000,0x00009492,0x0000a49b,
769 0x000136e4,0x0001b724,0x0001b92d,0x0001b724},
770 {0x00000000,0x00000000,0x00009492,0x000124db,
771 0x000136e4,0x0001b724,0x0001b92d,0x0001b724},
772 {0x00000000,0x00000000,0x00009492,0x000124db,
773 0x000136e4,0x0001b925,0x0001b92d,0x0001b925},
774 {0x00000000,0x00000000,0x00009492,0x000124db,
775 0x0001b724,0x0001b925,0x0001c96e,0x0001c92d},
776 {0x00000000,0x00000000,0x0000a492,0x000124db,
777 0x0001b724,0x0001c92d,0x0001c96e,0x0001c92d},
778 {0x00000000,0x00000000,0x0000a492,0x000124db,
779 0x0001b724,0x0001c92d,0x00024b76,0x0002496e},
780 {0x00000000,0x00000000,0x00012492,0x000126db,
781 0x0001c924,0x00024b6d,0x0002ddb6,0x00025bbf},
782 {0x00000000,0x00000000,0x00000000,0x00000000,
783 0x00000000,0x00000000,0x00000000,0x00000000}
784 },
785 { /* version 6, passes 1 */
786 {0x00000000,0x00000000,0x00001249,0x00001249,
787 0x0000124a,0x0000124a,0x00001252,0x00001252},
788 {0x00000000,0x00000000,0x00001249,0x00009292,
789 0x00009492,0x00009252,0x00001252,0x00001252},
790 {0x00000000,0x00000000,0x0000924a,0x00009493,
791 0x0000a493,0x00009292,0x00001252,0x00001252},
792 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
793 0x0000a493,0x0000a49b,0x00009292,0x00009292},
794 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
795 0x0000a493,0x0000a49b,0x00009292,0x00009292},
796 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
797 0x0001249b,0x0000a49b,0x00009493,0x00009292},
798 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
799 0x000124db,0x000124db,0x00009493,0x00009493},
800 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
801 0x000124db,0x000124db,0x0000a49b,0x00009493},
802 {0x00000000,0x00000000,0x0000924a,0x000124db,
803 0x000126dc,0x000124db,0x0000a49b,0x00009493},
804 {0x00000000,0x00000000,0x0000924a,0x000124db,
805 0x000126dc,0x000126dc,0x0000a49b,0x0000a49b},
806 {0x00000000,0x00000000,0x0000924a,0x000124db,
807 0x000136e4,0x000126dc,0x000124db,0x0000a49b},
808 {0x00000000,0x00000000,0x00009492,0x000126db,
809 0x000136e4,0x000126dc,0x000124db,0x0000a49b},
810 {0x00000000,0x00000000,0x00009492,0x000126db,
811 0x0001b724,0x000136e4,0x000126dc,0x000124db},
812 {0x00000000,0x00000000,0x00009492,0x000126db,
813 0x0001b724,0x000136e4,0x000126dc,0x000124db},
814 {0x00000000,0x00000000,0x0000a492,0x000136db,
815 0x0001c924,0x0001b724,0x000136e4,0x000126dc},
816 {0x00000000,0x00000000,0x00000000,0x00000000,
817 0x00000000,0x00000000,0x00000000,0x00000000}
818 }
819 },
820 { /* version 7 */
821 { /* version 7, passes 0 */
822 {0x00000000,0x00000000,0x00001249,0x00001249,
823 0x00009252,0x00009292,0x00009493,0x00009493},
824 {0x00000000,0x00000000,0x00001249,0x00009493,
825 0x0000a493,0x000124db,0x000126dc,0x00009493},
826 {0x00000000,0x00000000,0x00001249,0x0000a49b,
827 0x0001249b,0x000126dc,0x000126dc,0x0000a49b},
828 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
829 0x0001249b,0x000126dc,0x000136e4,0x0000a49b},
830 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
831 0x000126dc,0x000136e4,0x0001b725,0x000124db},
832 {0x00000000,0x00000000,0x00009292,0x0000a49b,
833 0x000136e4,0x0001b724,0x0001b725,0x000126dc},
834 {0x00000000,0x00000000,0x00009292,0x000124db,
835 0x000136e4,0x0001b724,0x0001b725,0x000126dc},
836 {0x00000000,0x00000000,0x00009492,0x000124db,
837 0x000136e4,0x0001b724,0x0001c96e,0x000136e4},
838 {0x00000000,0x00000000,0x00009492,0x000124db,
839 0x000136e4,0x0001c92d,0x0001c96e,0x0001b724},
840 {0x00000000,0x00000000,0x0000a492,0x000124db,
841 0x000136e4,0x0001c92d,0x0001c96e,0x0001b724},
842 {0x00000000,0x00000000,0x0000a492,0x000124db,
843 0x0001b724,0x0001c92d,0x0001c96e,0x0001b925},
844 {0x00000000,0x00000000,0x0000a492,0x000126db,
845 0x0001b724,0x0001c92d,0x00024b76,0x0001c92d},
846 {0x00000000,0x00000000,0x0000a492,0x000126db,
847 0x0001b924,0x0001c92d,0x00024b76,0x0001c92d},
848 {0x00000000,0x00000000,0x0000a492,0x000126db,
849 0x0001b924,0x0001c92d,0x00024b76,0x0002496e},
850 {0x00000000,0x00000000,0x00012492,0x000136db,
851 0x00024924,0x00024b6d,0x0002ddb6,0x00025bbf},
852 {0x00000000,0x00000000,0x00000000,0x00000000,
853 0x00000000,0x00000000,0x00000000,0x00000000}
854 },
855 { /* version 7, passes 1 */
856 {0x00000000,0x00000000,0x00001249,0x00001249,
857 0x0000124a,0x0000124a,0x00001252,0x00001252},
858 {0x00000000,0x00000000,0x0000924a,0x00009493,
859 0x00009492,0x00009292,0x00001252,0x00001252},
860 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
861 0x0000a493,0x0000a49b,0x00001252,0x00001252},
862 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
863 0x0000a493,0x0000a49b,0x00009292,0x00009292},
864 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
865 0x0000a493,0x0000a49b,0x00009292,0x00009292},
866 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
867 0x000126dc,0x0000a49b,0x00009493,0x00009292},
868 {0x00000000,0x00000000,0x0000924a,0x000124db,
869 0x000126dc,0x000124db,0x00009493,0x00009493},
870 {0x00000000,0x00000000,0x0000924a,0x000124db,
871 0x000136e4,0x000124db,0x0000a49b,0x00009493},
872 {0x00000000,0x00000000,0x0000924a,0x000136db,
873 0x0001b724,0x000124db,0x0000a49b,0x00009493},
874 {0x00000000,0x00000000,0x0000924a,0x000136db,
875 0x0001b724,0x000126dc,0x0000a49b,0x0000a49b},
876 {0x00000000,0x00000000,0x00009292,0x000136db,
877 0x0001b724,0x000126dc,0x000124db,0x0000a49b},
878 {0x00000000,0x00000000,0x00009492,0x000136db,
879 0x0001b724,0x000126dc,0x000124db,0x0000a49b},
880 {0x00000000,0x00000000,0x0000a492,0x000136db,
881 0x0001b724,0x000136e4,0x000126dc,0x000124db},
882 {0x00000000,0x00000000,0x0000a492,0x000136db,
883 0x0001b724,0x000136e4,0x000126dc,0x000124db},
884 {0x00000000,0x00000000,0x00012492,0x0001b6db,
885 0x0001c924,0x0001b724,0x000136e4,0x000126dc},
886 {0x00000000,0x00000000,0x00000000,0x00000000,
887 0x00000000,0x00000000,0x00000000,0x00000000}
888 }
889 }
890};
891
diff --git a/drivers/media/video/pwc/pwc-kiara.h b/drivers/media/video/pwc/pwc-kiara.h
index 12929abbb1f0..0bdb22547d86 100644
--- a/drivers/media/video/pwc/pwc-kiara.h
+++ b/drivers/media/video/pwc/pwc-kiara.h
@@ -1,5 +1,5 @@
1/* Linux driver for Philips webcam 1/* Linux driver for Philips webcam
2 (C) 2004 Luc Saillard (luc@saillard.org) 2 (C) 2004-2006 Luc Saillard (luc@saillard.org)
3 3
4 NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx 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. 5 driver and thus may have bugs that are not present in the original version.
@@ -27,7 +27,7 @@
27#ifndef PWC_KIARA_H 27#ifndef PWC_KIARA_H
28#define PWC_KIARA_H 28#define PWC_KIARA_H
29 29
30#include "pwc-ioctl.h" 30#include <media/pwc-ioctl.h>
31 31
32struct Kiara_table_entry 32struct Kiara_table_entry
33{ 33{
@@ -37,8 +37,8 @@ struct Kiara_table_entry
37 unsigned char mode[12]; /* precomputed mode settings for cam */ 37 unsigned char mode[12]; /* precomputed mode settings for cam */
38}; 38};
39 39
40const extern struct Kiara_table_entry Kiara_table[PSZ_MAX][6][4]; 40extern const struct Kiara_table_entry Kiara_table[PSZ_MAX][6][4];
41const extern unsigned int KiaraRomTable[8][2][16][8]; 41extern const unsigned int KiaraRomTable[8][2][16][8];
42 42
43#endif 43#endif
44 44
diff --git a/drivers/media/video/pwc/pwc-misc.c b/drivers/media/video/pwc/pwc-misc.c
index 58fe79747992..589c687439da 100644
--- a/drivers/media/video/pwc/pwc-misc.c
+++ b/drivers/media/video/pwc/pwc-misc.c
@@ -1,7 +1,7 @@
1/* Linux driver for Philips webcam 1/* Linux driver for Philips webcam
2 Various miscellaneous functions and tables. 2 Various miscellaneous functions and tables.
3 (C) 1999-2003 Nemosoft Unv. 3 (C) 1999-2003 Nemosoft Unv.
4 (C) 2004 Luc Saillard (luc@saillard.org) 4 (C) 2004-2006 Luc Saillard (luc@saillard.org)
5 5
6 NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx 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. 7 driver and thus may have bugs that are not present in the original version.
@@ -24,18 +24,17 @@
24 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 24 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25*/ 25*/
26 26
27#include <linux/slab.h>
28 27
29#include "pwc.h" 28#include "pwc.h"
30 29
31struct pwc_coord pwc_image_sizes[PSZ_MAX] = 30const struct pwc_coord pwc_image_sizes[PSZ_MAX] =
32{ 31{
33 { 128, 96, 0 }, 32 { 128, 96, 0 }, /* sqcif */
34 { 160, 120, 0 }, 33 { 160, 120, 0 }, /* qsif */
35 { 176, 144, 0 }, 34 { 176, 144, 0 }, /* qcif */
36 { 320, 240, 0 }, 35 { 320, 240, 0 }, /* sif */
37 { 352, 288, 0 }, 36 { 352, 288, 0 }, /* cif */
38 { 640, 480, 0 }, 37 { 640, 480, 0 }, /* vga */
39}; 38};
40 39
41/* x,y -> PSZ_ */ 40/* x,y -> PSZ_ */
@@ -52,7 +51,7 @@ int pwc_decode_size(struct pwc_device *pdev, int width, int height)
52 { 51 {
53 if (width > pdev->abs_max.x || height > pdev->abs_max.y) 52 if (width > pdev->abs_max.x || height > pdev->abs_max.y)
54 { 53 {
55 Debug("VIDEO_PALETTE_RAW: going beyond abs_max.\n"); 54 PWC_DEBUG_SIZE("VIDEO_PALETTE_RAW: going beyond abs_max.\n");
56 return -1; 55 return -1;
57 } 56 }
58 } 57 }
@@ -60,7 +59,7 @@ int pwc_decode_size(struct pwc_device *pdev, int width, int height)
60 { 59 {
61 if (width > pdev->view_max.x || height > pdev->view_max.y) 60 if (width > pdev->view_max.x || height > pdev->view_max.y)
62 { 61 {
63 Debug("VIDEO_PALETTE_ not RAW: going beyond view_max.\n"); 62 PWC_DEBUG_SIZE("VIDEO_PALETTE_not RAW: going beyond view_max.\n");
64 return -1; 63 return -1;
65 } 64 }
66 } 65 }
@@ -81,9 +80,8 @@ int pwc_decode_size(struct pwc_device *pdev, int width, int height)
81/* initialize variables depending on type and decompressor*/ 80/* initialize variables depending on type and decompressor*/
82void pwc_construct(struct pwc_device *pdev) 81void pwc_construct(struct pwc_device *pdev)
83{ 82{
84 switch(pdev->type) { 83 if (DEVICE_USE_CODEC1(pdev->type)) {
85 case 645: 84
86 case 646:
87 pdev->view_min.x = 128; 85 pdev->view_min.x = 128;
88 pdev->view_min.y = 96; 86 pdev->view_min.y = 96;
89 pdev->view_max.x = 352; 87 pdev->view_max.x = 352;
@@ -95,10 +93,23 @@ void pwc_construct(struct pwc_device *pdev)
95 pdev->vendpoint = 4; 93 pdev->vendpoint = 4;
96 pdev->frame_header_size = 0; 94 pdev->frame_header_size = 0;
97 pdev->frame_trailer_size = 0; 95 pdev->frame_trailer_size = 0;
98 break; 96
99 case 675: 97 } else if (DEVICE_USE_CODEC3(pdev->type)) {
100 case 680: 98
101 case 690: 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
102 pdev->view_min.x = 128; 113 pdev->view_min.x = 128;
103 pdev->view_min.y = 96; 114 pdev->view_min.y = 96;
104 /* Anthill bug #38: PWC always reports max size, even without PWCX */ 115 /* Anthill bug #38: PWC always reports max size, even without PWCX */
@@ -111,30 +122,12 @@ void pwc_construct(struct pwc_device *pdev)
111 pdev->vendpoint = 4; 122 pdev->vendpoint = 4;
112 pdev->frame_header_size = 0; 123 pdev->frame_header_size = 0;
113 pdev->frame_trailer_size = 0; 124 pdev->frame_trailer_size = 0;
114 break;
115 case 720:
116 case 730:
117 case 740:
118 case 750:
119 pdev->view_min.x = 160;
120 pdev->view_min.y = 120;
121 pdev->view_max.x = 640;
122 pdev->view_max.y = 480;
123 pdev->image_mask = 1 << PSZ_QSIF | 1 << PSZ_SIF | 1 << PSZ_VGA;
124 pdev->abs_max.x = 640;
125 pdev->abs_max.y = 480;
126 pdev->vcinterface = 3;
127 pdev->vendpoint = 5;
128 pdev->frame_header_size = TOUCAM_HEADER_SIZE;
129 pdev->frame_trailer_size = TOUCAM_TRAILER_SIZE;
130 break;
131 } 125 }
132 Debug("type = %d\n",pdev->type);
133 pdev->vpalette = VIDEO_PALETTE_YUV420P; /* default */ 126 pdev->vpalette = VIDEO_PALETTE_YUV420P; /* default */
134 pdev->view_min.size = pdev->view_min.x * pdev->view_min.y; 127 pdev->view_min.size = pdev->view_min.x * pdev->view_min.y;
135 pdev->view_max.size = pdev->view_max.x * pdev->view_max.y; 128 pdev->view_max.size = pdev->view_max.x * pdev->view_max.y;
136 /* length of image, in YUV format; always allocate enough memory. */ 129 /* length of image, in YUV format; always allocate enough memory. */
137 pdev->len_per_image = (pdev->abs_max.x * pdev->abs_max.y * 3) / 2; 130 pdev->len_per_image = PAGE_ALIGN((pdev->abs_max.x * pdev->abs_max.y * 3) / 2);
138} 131}
139 132
140 133
diff --git a/drivers/media/video/pwc/pwc-timon.c b/drivers/media/video/pwc/pwc-timon.c
index 175250d089cf..be65bdcd195b 100644
--- a/drivers/media/video/pwc/pwc-timon.c
+++ b/drivers/media/video/pwc/pwc-timon.c
@@ -1,5 +1,5 @@
1/* Linux driver for Philips webcam 1/* Linux driver for Philips webcam
2 (C) 2004 Luc Saillard (luc@saillard.org) 2 (C) 2004-2006 Luc Saillard (luc@saillard.org)
3 3
4 NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx 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. 5 driver and thus may have bugs that are not present in the original version.
@@ -314,3 +314,1133 @@ const struct Timon_table_entry Timon_table[PSZ_MAX][6][4] =
314 }, 314 },
315}; 315};
316 316
317/*
318 * 16 versions:
319 * 2 tables (one for Y, and one for U&V)
320 * 16 levels of details per tables
321 * 8 blocs
322 */
323
324const unsigned int TimonRomTable [16][2][16][8] =
325{
326 { /* version 0 */
327 { /* version 0, passes 0 */
328 {0x00000000,0x00000000,0x00000000,0x00000000,
329 0x00000000,0x00000000,0x00000000,0x00000001},
330 {0x00000000,0x00000000,0x00000001,0x00000001,
331 0x00000001,0x00000001,0x00000001,0x00000001},
332 {0x00000000,0x00000000,0x00000001,0x00000001,
333 0x00000001,0x00000009,0x00000009,0x00000009},
334 {0x00000000,0x00000000,0x00000009,0x00000001,
335 0x00000009,0x00000009,0x00000009,0x00000009},
336 {0x00000000,0x00000000,0x00000009,0x00000009,
337 0x00000009,0x00000009,0x00000049,0x00000009},
338 {0x00000000,0x00000000,0x00000009,0x00000009,
339 0x00000009,0x00000049,0x00000049,0x00000049},
340 {0x00000000,0x00000000,0x00000009,0x00000009,
341 0x00000049,0x00000049,0x00000049,0x00000049},
342 {0x00000000,0x00000000,0x00000009,0x00000049,
343 0x00000049,0x00000049,0x00000049,0x00000049},
344 {0x00000000,0x00000000,0x00000049,0x00000049,
345 0x00000049,0x00000049,0x0000024a,0x0000024a},
346 {0x00000000,0x00000000,0x00000049,0x00000049,
347 0x00000049,0x00000249,0x0000024a,0x0000024a},
348 {0x00000000,0x00000000,0x00000049,0x00000049,
349 0x00000249,0x00000249,0x0000024a,0x0000024a},
350 {0x00000000,0x00000000,0x00000049,0x00000049,
351 0x00000249,0x00000249,0x00001252,0x0000024a},
352 {0x00000000,0x00000000,0x00000049,0x00000049,
353 0x00000249,0x0000124a,0x00001252,0x0000024a},
354 {0x00000000,0x00000000,0x00000049,0x00000249,
355 0x00000249,0x0000124a,0x00001252,0x0000024a},
356 {0x00000000,0x00000000,0x00000249,0x00001249,
357 0x0000124a,0x00009252,0x00009292,0x00001252},
358 {0x00000000,0x00000000,0x00000000,0x00000000,
359 0x00000000,0x00000000,0x00000000,0x00000000}
360 },
361 { /* version 0, passes 1 */
362 {0x00000000,0x00000000,0x00000000,0x00000000,
363 0x00000000,0x00000000,0x00000000,0x00000000},
364 {0x00000000,0x00000000,0x00000001,0x00000001,
365 0x00000001,0x00000001,0x00000000,0x00000000},
366 {0x00000000,0x00000000,0x00000009,0x00000001,
367 0x00000001,0x00000009,0x00000000,0x00000000},
368 {0x00000000,0x00000000,0x00000009,0x00000009,
369 0x00000009,0x00000009,0x00000000,0x00000000},
370 {0x00000000,0x00000000,0x00000009,0x00000009,
371 0x00000009,0x00000009,0x00000001,0x00000000},
372 {0x00000000,0x00000000,0x00000049,0x00000009,
373 0x00000009,0x00000049,0x00000001,0x00000001},
374 {0x00000000,0x00000000,0x00000049,0x00000009,
375 0x00000009,0x00000049,0x00000001,0x00000001},
376 {0x00000000,0x00000000,0x00000049,0x00000049,
377 0x00000049,0x00000049,0x00000009,0x00000001},
378 {0x00000000,0x00000000,0x00000049,0x00000049,
379 0x00000049,0x00000049,0x00000009,0x00000001},
380 {0x00000000,0x00000000,0x00000049,0x00000049,
381 0x00000049,0x00000049,0x00000009,0x00000001},
382 {0x00000000,0x00000000,0x00000049,0x00000049,
383 0x00000049,0x00000049,0x00000009,0x00000009},
384 {0x00000000,0x00000000,0x00000049,0x00000049,
385 0x00000049,0x00000249,0x00000049,0x00000009},
386 {0x00000000,0x00000000,0x00000049,0x00000049,
387 0x00000049,0x00000249,0x00000049,0x00000009},
388 {0x00000000,0x00000000,0x00000249,0x00000049,
389 0x00000249,0x00000249,0x00000049,0x00000009},
390 {0x00000000,0x00000000,0x00001249,0x00000249,
391 0x0000124a,0x0000124a,0x0000024a,0x00000049},
392 {0x00000000,0x00000000,0x00000000,0x00000000,
393 0x00000000,0x00000000,0x00000000,0x00000000}
394 }
395 },
396 { /* version 1 */
397 { /* version 1, passes 0 */
398 {0x00000000,0x00000000,0x00000000,0x00000000,
399 0x00000000,0x00000000,0x00000000,0x00000001},
400 {0x00000000,0x00000000,0x00000001,0x00000001,
401 0x00000001,0x00000009,0x00000009,0x00000009},
402 {0x00000000,0x00000000,0x00000009,0x00000009,
403 0x00000009,0x00000009,0x00000009,0x00000009},
404 {0x00000000,0x00000000,0x00000009,0x00000009,
405 0x00000009,0x00000049,0x00000049,0x00000049},
406 {0x00000000,0x00000000,0x00000009,0x00000049,
407 0x00000049,0x00000049,0x00000049,0x00000049},
408 {0x00000000,0x00000000,0x00000049,0x00000049,
409 0x00000049,0x00000249,0x0000024a,0x0000024a},
410 {0x00000000,0x00000000,0x00000049,0x00000049,
411 0x00000249,0x00000249,0x0000024a,0x0000024a},
412 {0x00000000,0x00000000,0x00000049,0x00000249,
413 0x00000249,0x00000249,0x0000024a,0x00001252},
414 {0x00000000,0x00000000,0x00000049,0x00000249,
415 0x00000249,0x0000124a,0x00001252,0x00001252},
416 {0x00000000,0x00000000,0x00000049,0x00000249,
417 0x0000124a,0x0000124a,0x00001252,0x00001252},
418 {0x00000000,0x00000000,0x00000249,0x00000249,
419 0x0000124a,0x0000124a,0x00009292,0x00009292},
420 {0x00000000,0x00000000,0x00000249,0x00001249,
421 0x0000124a,0x00009252,0x00009292,0x00009292},
422 {0x00000000,0x00000000,0x00000249,0x00001249,
423 0x00009252,0x00009252,0x00009292,0x00009292},
424 {0x00000000,0x00000000,0x00000249,0x0000924a,
425 0x00009292,0x00009493,0x00009493,0x00009493},
426 {0x00000000,0x00000000,0x00001249,0x00009252,
427 0x00009492,0x0000a49b,0x0000a49b,0x0000a49b},
428 {0x00000000,0x00000000,0x00000000,0x00000000,
429 0x00000000,0x00000000,0x00000000,0x00000000}
430 },
431 { /* version 1, passes 1 */
432 {0x00000000,0x00000000,0x00000000,0x00000000,
433 0x00000000,0x00000000,0x00000000,0x00000000},
434 {0x00000000,0x00000000,0x00000009,0x00000009,
435 0x00000009,0x00000001,0x00000001,0x00000000},
436 {0x00000000,0x00000000,0x00000009,0x00000009,
437 0x00000009,0x00000009,0x00000001,0x00000000},
438 {0x00000000,0x00000000,0x00000049,0x00000049,
439 0x00000049,0x00000009,0x00000001,0x00000000},
440 {0x00000000,0x00000000,0x00000049,0x00000049,
441 0x00000049,0x00000049,0x00000001,0x00000001},
442 {0x00000000,0x00000000,0x00000049,0x00000049,
443 0x00000049,0x00000049,0x00000009,0x00000001},
444 {0x00000000,0x00000000,0x00000249,0x00000049,
445 0x00000049,0x00000249,0x00000009,0x00000001},
446 {0x00000000,0x00000000,0x00000249,0x00000049,
447 0x00000249,0x00000249,0x00000009,0x00000009},
448 {0x00000000,0x00000000,0x00000249,0x00000249,
449 0x00000249,0x00000249,0x00000049,0x00000009},
450 {0x00000000,0x00000000,0x00000249,0x00000249,
451 0x00000249,0x0000124a,0x00000049,0x00000009},
452 {0x00000000,0x00000000,0x00000249,0x00000249,
453 0x00000249,0x0000124a,0x00000049,0x00000009},
454 {0x00000000,0x00000000,0x00000249,0x00000249,
455 0x00000249,0x0000124a,0x0000024a,0x00000049},
456 {0x00000000,0x00000000,0x00000249,0x00000249,
457 0x0000124a,0x0000124a,0x0000024a,0x00000049},
458 {0x00000000,0x00000000,0x00000249,0x00000249,
459 0x0000124a,0x0000124a,0x0000024a,0x00000049},
460 {0x00000000,0x00000000,0x00001249,0x00001249,
461 0x00009252,0x00009252,0x00001252,0x0000024a},
462 {0x00000000,0x00000000,0x00000000,0x00000000,
463 0x00000000,0x00000000,0x00000000,0x00000000}
464 }
465 },
466 { /* version 2 */
467 { /* version 2, passes 0 */
468 {0x00000000,0x00000000,0x00000000,0x00000000,
469 0x00000000,0x00000000,0x00000000,0x00000001},
470 {0x00000000,0x00000000,0x00000009,0x00000009,
471 0x00000009,0x00000009,0x00000009,0x00000009},
472 {0x00000000,0x00000000,0x00000049,0x00000049,
473 0x00000049,0x00000049,0x00000049,0x00000049},
474 {0x00000000,0x00000000,0x00000049,0x00000049,
475 0x00000049,0x00000249,0x0000024a,0x0000024a},
476 {0x00000000,0x00000000,0x00000049,0x00000249,
477 0x00000249,0x00000249,0x0000024a,0x00001252},
478 {0x00000000,0x00000000,0x00000249,0x00000249,
479 0x00000249,0x0000124a,0x00001252,0x00001252},
480 {0x00000000,0x00000000,0x00000249,0x00000249,
481 0x0000124a,0x0000124a,0x00009292,0x00009292},
482 {0x00000000,0x00000000,0x00000249,0x00001249,
483 0x0000124a,0x00009252,0x00009292,0x00009292},
484 {0x00000000,0x00000000,0x00000249,0x00001249,
485 0x00009252,0x00009292,0x00009292,0x00009292},
486 {0x00000000,0x00000000,0x00000249,0x00001249,
487 0x00009252,0x00009292,0x00009493,0x00009493},
488 {0x00000000,0x00000000,0x00000249,0x0000924a,
489 0x00009252,0x00009493,0x00009493,0x00009493},
490 {0x00000000,0x00000000,0x00000249,0x0000924a,
491 0x00009292,0x00009493,0x00009493,0x00009493},
492 {0x00000000,0x00000000,0x00000249,0x00009252,
493 0x00009492,0x00009493,0x0000a49b,0x0000a49b},
494 {0x00000000,0x00000000,0x00001249,0x00009292,
495 0x00009492,0x000124db,0x000124db,0x000124db},
496 {0x00000000,0x00000000,0x0000924a,0x00009493,
497 0x0000a493,0x000126dc,0x000126dc,0x000126dc},
498 {0x00000000,0x00000000,0x00000000,0x00000000,
499 0x00000000,0x00000000,0x00000000,0x00000000}
500 },
501 { /* version 2, passes 1 */
502 {0x00000000,0x00000000,0x00000000,0x00000000,
503 0x00000000,0x00000000,0x00000000,0x00000000},
504 {0x00000000,0x00000000,0x00000049,0x00000009,
505 0x00000049,0x00000009,0x00000001,0x00000000},
506 {0x00000000,0x00000000,0x00000049,0x00000049,
507 0x00000049,0x00000049,0x00000049,0x00000000},
508 {0x00000000,0x00000000,0x00000249,0x00000049,
509 0x00000249,0x00000049,0x0000024a,0x00000001},
510 {0x00000000,0x00000000,0x00000249,0x00000249,
511 0x00000249,0x00000249,0x0000024a,0x00000001},
512 {0x00000000,0x00000000,0x00000249,0x00000249,
513 0x00000249,0x00000249,0x0000024a,0x00000001},
514 {0x00000000,0x00000000,0x00000249,0x00000249,
515 0x00000249,0x00000249,0x0000024a,0x00000009},
516 {0x00000000,0x00000000,0x00000249,0x00000249,
517 0x0000124a,0x0000124a,0x0000024a,0x00000009},
518 {0x00000000,0x00000000,0x00000249,0x00000249,
519 0x0000124a,0x0000124a,0x0000024a,0x00000009},
520 {0x00000000,0x00000000,0x00001249,0x00001249,
521 0x0000124a,0x00009252,0x00001252,0x00000049},
522 {0x00000000,0x00000000,0x00001249,0x00001249,
523 0x0000124a,0x00009292,0x00001252,0x00000049},
524 {0x00000000,0x00000000,0x00001249,0x00001249,
525 0x0000124a,0x00009292,0x00001252,0x00000049},
526 {0x00000000,0x00000000,0x00001249,0x00001249,
527 0x00009252,0x00009292,0x00001252,0x0000024a},
528 {0x00000000,0x00000000,0x00001249,0x00001249,
529 0x00009292,0x00009292,0x00001252,0x0000024a},
530 {0x00000000,0x00000000,0x0000924a,0x0000924a,
531 0x00009492,0x00009493,0x00009292,0x00001252},
532 {0x00000000,0x00000000,0x00000000,0x00000000,
533 0x00000000,0x00000000,0x00000000,0x00000000}
534 }
535 },
536 { /* version 3 */
537 { /* version 3, passes 0 */
538 {0x00000000,0x00000000,0x00000000,0x00000000,
539 0x00000000,0x00000000,0x00000000,0x00000001},
540 {0x00000000,0x00000000,0x00000049,0x00000049,
541 0x00000049,0x00000049,0x00000049,0x00000049},
542 {0x00000000,0x00000000,0x00000049,0x00000249,
543 0x00000249,0x00000249,0x00001252,0x0000024a},
544 {0x00000000,0x00000000,0x00000249,0x00000249,
545 0x00000249,0x0000124a,0x00001252,0x00001252},
546 {0x00000000,0x00000000,0x00000249,0x00000249,
547 0x0000124a,0x00009252,0x00009292,0x00009292},
548 {0x00000000,0x00000000,0x00000249,0x00001249,
549 0x0000124a,0x00009292,0x00009292,0x00009493},
550 {0x00000000,0x00000000,0x00000249,0x00001249,
551 0x00009252,0x00009292,0x00009493,0x00009493},
552 {0x00000000,0x00000000,0x00000249,0x00001249,
553 0x00009292,0x00009493,0x00009493,0x00009493},
554 {0x00000000,0x00000000,0x00000249,0x00009252,
555 0x00009292,0x00009493,0x0000a49b,0x0000a49b},
556 {0x00000000,0x00000000,0x00001249,0x00009252,
557 0x00009292,0x0000a49b,0x0000a49b,0x0000a49b},
558 {0x00000000,0x00000000,0x00001249,0x00009252,
559 0x00009492,0x0000a49b,0x0000a49b,0x0000a49b},
560 {0x00000000,0x00000000,0x00001249,0x00009292,
561 0x00009492,0x0000a49b,0x000124db,0x000124db},
562 {0x00000000,0x00000000,0x00001249,0x00009292,
563 0x0000a493,0x0000a49b,0x000124db,0x000124db},
564 {0x00000000,0x00000000,0x00001249,0x00009493,
565 0x0001249b,0x000126dc,0x000136e4,0x000126dc},
566 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
567 0x000124db,0x000136e4,0x0001b725,0x000136e4},
568 {0x00000000,0x00000000,0x00000000,0x00000000,
569 0x00000000,0x00000000,0x00000000,0x00000000}
570 },
571 { /* version 3, passes 1 */
572 {0x00000000,0x00000000,0x00000000,0x00000000,
573 0x00000000,0x00000000,0x00000000,0x00000000},
574 {0x00000000,0x00000000,0x00000049,0x00000049,
575 0x00000049,0x00000049,0x00000001,0x00000000},
576 {0x00000000,0x00000000,0x00000249,0x00000249,
577 0x00000249,0x00000249,0x00000049,0x00000001},
578 {0x00000000,0x00000000,0x00000249,0x00000249,
579 0x00000249,0x0000124a,0x00001252,0x00000001},
580 {0x00000000,0x00000000,0x00000249,0x00000249,
581 0x0000124a,0x0000124a,0x00001252,0x00000009},
582 {0x00000000,0x00000000,0x00000249,0x00001249,
583 0x0000124a,0x00009252,0x00009292,0x00000009},
584 {0x00000000,0x00000000,0x00001249,0x00001249,
585 0x0000124a,0x00009252,0x00009292,0x00000049},
586 {0x00000000,0x00000000,0x00001249,0x00001249,
587 0x00009252,0x00009252,0x00009292,0x00000049},
588 {0x00000000,0x00000000,0x00001249,0x00001249,
589 0x00009252,0x00009493,0x00009292,0x0000024a},
590 {0x00000000,0x00000000,0x00001249,0x00001249,
591 0x00009252,0x00009493,0x00009292,0x0000024a},
592 {0x00000000,0x00000000,0x00001249,0x00001249,
593 0x00009252,0x00009493,0x00009493,0x00001252},
594 {0x00000000,0x00000000,0x00001249,0x0000924a,
595 0x00009292,0x00009493,0x00009493,0x00001252},
596 {0x00000000,0x00000000,0x00001249,0x0000924a,
597 0x00009492,0x00009493,0x00009493,0x00009292},
598 {0x00000000,0x00000000,0x00001249,0x00009252,
599 0x00009492,0x0000a49b,0x00009493,0x00009292},
600 {0x00000000,0x00000000,0x0000924a,0x00009292,
601 0x0000a493,0x000124db,0x0000a49b,0x00009493},
602 {0x00000000,0x00000000,0x00000000,0x00000000,
603 0x00000000,0x00000000,0x00000000,0x00000000}
604 }
605 },
606 { /* version 4 */
607 { /* version 4, passes 0 */
608 {0x00000000,0x00000000,0x00000049,0x00000049,
609 0x00000049,0x00000049,0x0000024a,0x0000024a},
610 {0x00000000,0x00000000,0x00000249,0x00000249,
611 0x00000249,0x0000124a,0x00001252,0x00009292},
612 {0x00000000,0x00000000,0x00000249,0x00000249,
613 0x0000124a,0x00009252,0x00009292,0x00009292},
614 {0x00000000,0x00000000,0x00000249,0x00001249,
615 0x0000124a,0x00009292,0x00009493,0x00009493},
616 {0x00000000,0x00000000,0x00000249,0x00001249,
617 0x00009252,0x00009493,0x00009493,0x0000a49b},
618 {0x00000000,0x00000000,0x00000249,0x0000924a,
619 0x00009292,0x00009493,0x0000a49b,0x0000a49b},
620 {0x00000000,0x00000000,0x00001249,0x0000924a,
621 0x00009292,0x00009493,0x0000a49b,0x000124db},
622 {0x00000000,0x00000000,0x00001249,0x00009252,
623 0x00009492,0x0000a49b,0x0000a49b,0x000124db},
624 {0x00000000,0x00000000,0x00001249,0x00009292,
625 0x00009492,0x000124db,0x000124db,0x000126dc},
626 {0x00000000,0x00000000,0x00001249,0x00009292,
627 0x0000a493,0x000124db,0x000126dc,0x000126dc},
628 {0x00000000,0x00000000,0x00001249,0x00009493,
629 0x0000a493,0x000124db,0x000126dc,0x000136e4},
630 {0x00000000,0x00000000,0x00001249,0x00009493,
631 0x0000a493,0x000126dc,0x000136e4,0x000136e4},
632 {0x00000000,0x00000000,0x0000924a,0x00009493,
633 0x0001249b,0x000126dc,0x000136e4,0x000136e4},
634 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
635 0x000124db,0x000136e4,0x000136e4,0x0001b724},
636 {0x00000000,0x00000000,0x00009252,0x000124db,
637 0x000126dc,0x0001b724,0x0001b725,0x0001b925},
638 {0x00000000,0x00000000,0x00000000,0x00000000,
639 0x00000000,0x00000000,0x00000000,0x00000000}
640 },
641 { /* version 4, passes 1 */
642 {0x00000000,0x00000000,0x00000049,0x00000049,
643 0x00000049,0x00000049,0x00000049,0x00000049},
644 {0x00000000,0x00000000,0x00000249,0x00000249,
645 0x00000249,0x00000249,0x0000024a,0x00000049},
646 {0x00000000,0x00000000,0x00001249,0x00000249,
647 0x0000124a,0x0000124a,0x00001252,0x00000049},
648 {0x00000000,0x00000000,0x00001249,0x00001249,
649 0x0000124a,0x0000124a,0x00009292,0x0000024a},
650 {0x00000000,0x00000000,0x00001249,0x00001249,
651 0x00009252,0x00009292,0x00009292,0x0000024a},
652 {0x00000000,0x00000000,0x00001249,0x00001249,
653 0x00009252,0x00009292,0x0000a49b,0x0000024a},
654 {0x00000000,0x00000000,0x00001249,0x00001249,
655 0x00009292,0x00009493,0x0000a49b,0x00001252},
656 {0x00000000,0x00000000,0x00001249,0x00001249,
657 0x00009292,0x00009493,0x0000a49b,0x00001252},
658 {0x00000000,0x00000000,0x00001249,0x0000924a,
659 0x00009492,0x0000a49b,0x0000a49b,0x00001252},
660 {0x00000000,0x00000000,0x00001249,0x00009252,
661 0x00009492,0x0000a49b,0x0000a49b,0x00009292},
662 {0x00000000,0x00000000,0x00001249,0x00009292,
663 0x00009492,0x0000a49b,0x0000a49b,0x00009292},
664 {0x00000000,0x00000000,0x00001249,0x00009493,
665 0x0000a493,0x0000a49b,0x0000a49b,0x00009292},
666 {0x00000000,0x00000000,0x00001249,0x00009493,
667 0x0000a493,0x0000a49b,0x0000a49b,0x00009493},
668 {0x00000000,0x00000000,0x0000924a,0x00009493,
669 0x0000a493,0x000124db,0x0000a49b,0x00009493},
670 {0x00000000,0x00000000,0x00009252,0x0000a49b,
671 0x0001249b,0x000126dc,0x000124db,0x0000a49b},
672 {0x00000000,0x00000000,0x00000000,0x00000000,
673 0x00000000,0x00000000,0x00000000,0x00000000}
674 }
675 },
676 { /* version 5 */
677 { /* version 5, passes 0 */
678 {0x00000000,0x00000000,0x00000249,0x00000249,
679 0x00000249,0x0000124a,0x00001252,0x00009292},
680 {0x00000000,0x00000000,0x00000249,0x00001249,
681 0x0000124a,0x00009292,0x00009292,0x00009493},
682 {0x00000000,0x00000000,0x00000249,0x0000924a,
683 0x00009292,0x00009493,0x0000a49b,0x0000a49b},
684 {0x00000000,0x00000000,0x00001249,0x0000924a,
685 0x00009292,0x00009493,0x0000a49b,0x0000a49b},
686 {0x00000000,0x00000000,0x00001249,0x0000924a,
687 0x00009492,0x0000a49b,0x0000a49b,0x000124db},
688 {0x00000000,0x00000000,0x00001249,0x00009292,
689 0x00009492,0x0000a49b,0x000124db,0x000124db},
690 {0x00000000,0x00000000,0x00001249,0x00009292,
691 0x0000a493,0x000124db,0x000124db,0x000126dc},
692 {0x00000000,0x00000000,0x00001249,0x00009493,
693 0x0000a493,0x000124db,0x000126dc,0x000126dc},
694 {0x00000000,0x00000000,0x00001249,0x00009493,
695 0x0000a493,0x000126dc,0x000136e4,0x000136e4},
696 {0x00000000,0x00000000,0x00001249,0x00009493,
697 0x0001249b,0x000126dc,0x000136e4,0x000136e4},
698 {0x00000000,0x00000000,0x00001249,0x00009493,
699 0x0001249b,0x000126dc,0x000136e4,0x000136e4},
700 {0x00000000,0x00000000,0x0000924a,0x00009493,
701 0x0001249b,0x000126dc,0x0001b725,0x0001b724},
702 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
703 0x000124db,0x000126dc,0x0001b725,0x0001b724},
704 {0x00000000,0x00000000,0x00009292,0x0000a49b,
705 0x000126dc,0x000136e4,0x0001b92d,0x0001b925},
706 {0x00000000,0x00000000,0x00009492,0x000124db,
707 0x000136e4,0x0001b724,0x0001c96e,0x0001c92d},
708 {0x00000000,0x00000000,0x00000000,0x00000000,
709 0x00000000,0x00000000,0x00000000,0x00000000}
710 },
711 { /* version 5, passes 1 */
712 {0x00000000,0x00000000,0x00000249,0x00000249,
713 0x0000124a,0x00000249,0x0000024a,0x0000024a},
714 {0x00000000,0x00000000,0x00001249,0x00001249,
715 0x0000124a,0x0000124a,0x00001252,0x0000024a},
716 {0x00000000,0x00000000,0x00001249,0x00001249,
717 0x00009292,0x00009493,0x00009493,0x0000024a},
718 {0x00000000,0x00000000,0x00001249,0x00001249,
719 0x00009292,0x00009493,0x00009493,0x00001252},
720 {0x00000000,0x00000000,0x00001249,0x00001249,
721 0x00009292,0x00009493,0x0000a49b,0x00001252},
722 {0x00000000,0x00000000,0x00001249,0x0000924a,
723 0x00009492,0x00009493,0x000124db,0x00001252},
724 {0x00000000,0x00000000,0x00001249,0x00009292,
725 0x00009492,0x00009493,0x000124db,0x00009292},
726 {0x00000000,0x00000000,0x00001249,0x00009292,
727 0x00009492,0x0000a49b,0x000124db,0x00009292},
728 {0x00000000,0x00000000,0x00001249,0x00009493,
729 0x0000a493,0x0000a49b,0x000124db,0x00009292},
730 {0x00000000,0x00000000,0x00001249,0x00009493,
731 0x0000a493,0x000124db,0x000124db,0x00009493},
732 {0x00000000,0x00000000,0x0000924a,0x00009493,
733 0x0000a493,0x000124db,0x000124db,0x00009493},
734 {0x00000000,0x00000000,0x0000924a,0x00009493,
735 0x0000a493,0x000124db,0x000124db,0x00009493},
736 {0x00000000,0x00000000,0x0000924a,0x00009493,
737 0x0000a493,0x000124db,0x000124db,0x0000a49b},
738 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
739 0x000124db,0x000126dc,0x000124db,0x0000a49b},
740 {0x00000000,0x00000000,0x00009252,0x000124db,
741 0x000126dc,0x000136e4,0x000126dc,0x000124db},
742 {0x00000000,0x00000000,0x00000000,0x00000000,
743 0x00000000,0x00000000,0x00000000,0x00000000}
744 }
745 },
746 { /* version 6 */
747 { /* version 6, passes 0 */
748 {0x00000000,0x00000000,0x00000249,0x00000249,
749 0x0000124a,0x0000124a,0x00009292,0x00009292},
750 {0x00000000,0x00000000,0x00001249,0x00001249,
751 0x00009292,0x00009493,0x0000a49b,0x0000a49b},
752 {0x00000000,0x00000000,0x00001249,0x0000924a,
753 0x00009492,0x0000a49b,0x0000a49b,0x000124db},
754 {0x00000000,0x00000000,0x00001249,0x00009292,
755 0x00009492,0x000124db,0x000126dc,0x000126dc},
756 {0x00000000,0x00000000,0x00001249,0x00009493,
757 0x0000a493,0x000124db,0x000126dc,0x000126dc},
758 {0x00000000,0x00000000,0x00001249,0x00009493,
759 0x0000a493,0x000126dc,0x000136e4,0x000136e4},
760 {0x00000000,0x00000000,0x00001249,0x00009493,
761 0x0000a493,0x000126dc,0x000136e4,0x0001b724},
762 {0x00000000,0x00000000,0x00001249,0x00009493,
763 0x0001249b,0x000126dc,0x000136e4,0x0001b724},
764 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
765 0x0001249b,0x000126dc,0x000136e4,0x0001b724},
766 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
767 0x0001249b,0x000136e4,0x0001b725,0x0001b724},
768 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
769 0x000124db,0x000136e4,0x0001b725,0x0001b925},
770 {0x00000000,0x00000000,0x00009292,0x0000a49b,
771 0x000126dc,0x000136e4,0x0001b92d,0x0001b925},
772 {0x00000000,0x00000000,0x00009292,0x0000a49b,
773 0x000126dc,0x0001b724,0x0001b92d,0x0001c92d},
774 {0x00000000,0x00000000,0x00009492,0x000124db,
775 0x000126dc,0x0001b724,0x0001c96e,0x0001c92d},
776 {0x00000000,0x00000000,0x0000a492,0x000126db,
777 0x000136e4,0x0001b925,0x00025bb6,0x00024b77},
778 {0x00000000,0x00000000,0x00000000,0x00000000,
779 0x00000000,0x00000000,0x00000000,0x00000000}
780 },
781 { /* version 6, passes 1 */
782 {0x00000000,0x00000000,0x00001249,0x00000249,
783 0x0000124a,0x0000124a,0x00001252,0x00001252},
784 {0x00000000,0x00000000,0x00001249,0x00001249,
785 0x00009252,0x00009292,0x00009292,0x00001252},
786 {0x00000000,0x00000000,0x00001249,0x0000924a,
787 0x00009492,0x00009493,0x0000a49b,0x00001252},
788 {0x00000000,0x00000000,0x00001249,0x00009252,
789 0x00009492,0x0000a49b,0x0000a49b,0x00009292},
790 {0x00000000,0x00000000,0x00001249,0x00009292,
791 0x00009492,0x0000a49b,0x0000a49b,0x00009292},
792 {0x00000000,0x00000000,0x00001249,0x00009493,
793 0x0000a493,0x0000a49b,0x000126dc,0x00009292},
794 {0x00000000,0x00000000,0x0000924a,0x00009493,
795 0x0000a493,0x0000a49b,0x000126dc,0x00009493},
796 {0x00000000,0x00000000,0x0000924a,0x00009493,
797 0x0000a493,0x0000a49b,0x000126dc,0x00009493},
798 {0x00000000,0x00000000,0x0000924a,0x00009493,
799 0x0000a493,0x000124db,0x000126dc,0x00009493},
800 {0x00000000,0x00000000,0x0000924a,0x00009493,
801 0x0000a493,0x000124db,0x000126dc,0x0000a49b},
802 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
803 0x0000a493,0x000124db,0x000126dc,0x0000a49b},
804 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
805 0x0001249b,0x000126dc,0x000126dc,0x0000a49b},
806 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
807 0x000124db,0x000136e4,0x000126dc,0x000124db},
808 {0x00000000,0x00000000,0x00009492,0x0000a49b,
809 0x000136e4,0x000136e4,0x000126dc,0x000124db},
810 {0x00000000,0x00000000,0x0000a492,0x000124db,
811 0x0001b724,0x0001b724,0x000136e4,0x000126dc},
812 {0x00000000,0x00000000,0x00000000,0x00000000,
813 0x00000000,0x00000000,0x00000000,0x00000000}
814 }
815 },
816 { /* version 7 */
817 { /* version 7, passes 0 */
818 {0x00000000,0x00000000,0x00001249,0x00001249,
819 0x00009292,0x00009493,0x0000a49b,0x000124db},
820 {0x00000000,0x00000000,0x00001249,0x00009292,
821 0x0000a493,0x0000a49b,0x000124db,0x000126dc},
822 {0x00000000,0x00000000,0x00001249,0x00009493,
823 0x0000a493,0x000124db,0x000126dc,0x000136e4},
824 {0x00000000,0x00000000,0x00001249,0x00009493,
825 0x0000a493,0x000124db,0x000136e4,0x000136e4},
826 {0x00000000,0x00000000,0x00001249,0x00009493,
827 0x0001249b,0x000126dc,0x000136e4,0x000136e4},
828 {0x00000000,0x00000000,0x00001249,0x0000a49b,
829 0x0001249b,0x000126dc,0x000136e4,0x0001b724},
830 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
831 0x0001249b,0x000126dc,0x000136e4,0x0001b724},
832 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
833 0x000124db,0x000136e4,0x0001b725,0x0001b724},
834 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
835 0x000126dc,0x000136e4,0x0001b725,0x0001b925},
836 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
837 0x000126dc,0x0001b724,0x0001b92d,0x0001b925},
838 {0x00000000,0x00000000,0x00009292,0x0000a49b,
839 0x000126dc,0x0001b724,0x0001c96e,0x0001c92d},
840 {0x00000000,0x00000000,0x00009292,0x000124db,
841 0x000126dc,0x0001b724,0x0001c96e,0x0001c92d},
842 {0x00000000,0x00000000,0x00009492,0x000124db,
843 0x000136e4,0x0001b724,0x0001c96e,0x0002496e},
844 {0x00000000,0x00000000,0x00009492,0x000126db,
845 0x000136e4,0x0001b925,0x0001c96e,0x0002496e},
846 {0x00000000,0x00000000,0x0000a492,0x000136db,
847 0x0001b724,0x0002496d,0x00025bb6,0x00025bbf},
848 {0x00000000,0x00000000,0x00000000,0x00000000,
849 0x00000000,0x00000000,0x00000000,0x00000000}
850 },
851 { /* version 7, passes 1 */
852 {0x00000000,0x00000000,0x00001249,0x00001249,
853 0x00009252,0x00009292,0x00009292,0x00009292},
854 {0x00000000,0x00000000,0x00001249,0x0000924a,
855 0x00009492,0x00009493,0x00009493,0x00009292},
856 {0x00000000,0x00000000,0x00001249,0x00009493,
857 0x0000a493,0x0000a49b,0x0000a49b,0x00009292},
858 {0x00000000,0x00000000,0x0000924a,0x00009493,
859 0x0000a493,0x0000a49b,0x000124db,0x00009493},
860 {0x00000000,0x00000000,0x0000924a,0x00009493,
861 0x0000a493,0x000124db,0x000124db,0x00009493},
862 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
863 0x0000a493,0x000124db,0x000136e4,0x00009493},
864 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
865 0x0000a493,0x000124db,0x000136e4,0x0000a49b},
866 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
867 0x0001249b,0x000124db,0x000136e4,0x0000a49b},
868 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
869 0x0001249b,0x000126dc,0x000136e4,0x0000a49b},
870 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
871 0x0001249b,0x000126dc,0x000136e4,0x000124db},
872 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
873 0x000126dc,0x000136e4,0x000136e4,0x000124db},
874 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
875 0x000126dc,0x000136e4,0x000136e4,0x000124db},
876 {0x00000000,0x00000000,0x0000924a,0x000124db,
877 0x000136e4,0x000136e4,0x000136e4,0x000126dc},
878 {0x00000000,0x00000000,0x0000a492,0x000124db,
879 0x000136e4,0x0001b724,0x000136e4,0x000126dc},
880 {0x00000000,0x00000000,0x00012492,0x000126db,
881 0x0001b724,0x0001b925,0x0001b725,0x000136e4},
882 {0x00000000,0x00000000,0x00000000,0x00000000,
883 0x00000000,0x00000000,0x00000000,0x00000000}
884 }
885 },
886 { /* version 8 */
887 { /* version 8, passes 0 */
888 {0x00000000,0x00000000,0x00001249,0x00001249,
889 0x00009292,0x00009493,0x0000a49b,0x000124db},
890 {0x00000000,0x00000000,0x00001249,0x00009292,
891 0x0000a493,0x000124db,0x000126dc,0x000126dc},
892 {0x00000000,0x00000000,0x00001249,0x00009493,
893 0x0000a493,0x000124db,0x000126dc,0x000136e4},
894 {0x00000000,0x00000000,0x00001249,0x0000a49b,
895 0x0001249b,0x000126dc,0x000136e4,0x0001b724},
896 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
897 0x0001249b,0x000126dc,0x000136e4,0x0001b724},
898 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
899 0x000124db,0x000136e4,0x0001b725,0x0001b724},
900 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
901 0x000126dc,0x000136e4,0x0001b725,0x0001b925},
902 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
903 0x000126dc,0x0001b724,0x0001b92d,0x0001c92d},
904 {0x00000000,0x00000000,0x00009252,0x000124db,
905 0x000126dc,0x0001b724,0x0001b92d,0x0001c92d},
906 {0x00000000,0x00000000,0x00009292,0x000124db,
907 0x000126dc,0x0001b925,0x0001c96e,0x0001c92d},
908 {0x00000000,0x00000000,0x00009492,0x000124db,
909 0x000136e4,0x0001b925,0x0001c96e,0x0001c92d},
910 {0x00000000,0x00000000,0x00009492,0x000124db,
911 0x000136e4,0x0001b925,0x00024b76,0x00024b77},
912 {0x00000000,0x00000000,0x00009492,0x000126db,
913 0x000136e4,0x0001b925,0x00024b76,0x00025bbf},
914 {0x00000000,0x00000000,0x0000a492,0x000126db,
915 0x000136e4,0x0001c92d,0x00024b76,0x00025bbf},
916 {0x00000000,0x00000000,0x00012492,0x000136db,
917 0x0001b724,0x00024b6d,0x0002ddb6,0x0002efff},
918 {0x00000000,0x00000000,0x00000000,0x00000000,
919 0x00000000,0x00000000,0x00000000,0x00000000}
920 },
921 { /* version 8, passes 1 */
922 {0x00000000,0x00000000,0x00001249,0x00001249,
923 0x00009252,0x00009493,0x00009493,0x00009493},
924 {0x00000000,0x00000000,0x00001249,0x00009292,
925 0x0000a493,0x0000a49b,0x0000a49b,0x00009493},
926 {0x00000000,0x00000000,0x0000924a,0x00009493,
927 0x0000a493,0x0000a49b,0x000124db,0x00009493},
928 {0x00000000,0x00000000,0x0000924a,0x00009493,
929 0x0000a493,0x000124db,0x000126dc,0x0000a49b},
930 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
931 0x0000a493,0x000124db,0x000126dc,0x0000a49b},
932 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
933 0x0000a493,0x000124db,0x000136e4,0x000124db},
934 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
935 0x0001249b,0x000126dc,0x000136e4,0x000124db},
936 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
937 0x000126dc,0x000126dc,0x000136e4,0x000126dc},
938 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
939 0x000126dc,0x000136e4,0x000136e4,0x000126dc},
940 {0x00000000,0x00000000,0x0000924a,0x000124db,
941 0x000126dc,0x000136e4,0x000136e4,0x000126dc},
942 {0x00000000,0x00000000,0x0000924a,0x000124db,
943 0x000126dc,0x000136e4,0x000136e4,0x000136e4},
944 {0x00000000,0x00000000,0x00009292,0x000124db,
945 0x000136e4,0x0001b724,0x0001b725,0x000136e4},
946 {0x00000000,0x00000000,0x00009492,0x000126db,
947 0x000136e4,0x0001b925,0x0001b725,0x0001b724},
948 {0x00000000,0x00000000,0x00009492,0x000126db,
949 0x000136e4,0x0001b925,0x0001b725,0x0001b724},
950 {0x00000000,0x00000000,0x0000a492,0x000136db,
951 0x0001b724,0x0002496d,0x0001b92d,0x0001b925},
952 {0x00000000,0x00000000,0x00000000,0x00000000,
953 0x00000000,0x00000000,0x00000000,0x00000000}
954 }
955 },
956 { /* version 9 */
957 { /* version 9, passes 0 */
958 {0x00000000,0x00000000,0x00000049,0x00000049,
959 0x00000049,0x00000049,0x00000049,0x00000049},
960 {0x00000000,0x00000000,0x00000249,0x00000049,
961 0x00000249,0x00000249,0x0000024a,0x00000049},
962 {0x00000000,0x00000000,0x00000249,0x00000249,
963 0x0000124a,0x00009252,0x00001252,0x0000024a},
964 {0x00000000,0x00000000,0x00001249,0x00001249,
965 0x00009252,0x00009292,0x00009493,0x00001252},
966 {0x00000000,0x00000000,0x00001249,0x0000924a,
967 0x00009292,0x00009493,0x00009493,0x00001252},
968 {0x00000000,0x00000000,0x00001249,0x00009292,
969 0x00009492,0x0000a49b,0x0000a49b,0x00009292},
970 {0x00000000,0x00000000,0x00001249,0x00009493,
971 0x0000a493,0x000124db,0x000124db,0x00009493},
972 {0x00000000,0x00000000,0x0000924a,0x00009493,
973 0x0000a493,0x000124db,0x000126dc,0x0000a49b},
974 {0x00000000,0x00000000,0x0000924a,0x00009493,
975 0x0000a493,0x000124db,0x000126dc,0x0000a49b},
976 {0x00000000,0x00000000,0x0000924a,0x00009493,
977 0x0001249b,0x000126dc,0x000126dc,0x000124db},
978 {0x00000000,0x00000000,0x00009252,0x00009493,
979 0x000124db,0x000136e4,0x000136e4,0x000126dc},
980 {0x00000000,0x00000000,0x00009252,0x0000a49b,
981 0x000124db,0x000136e4,0x000136e4,0x000126dc},
982 {0x00000000,0x00000000,0x00009292,0x0000a49b,
983 0x000126dc,0x000136e4,0x000136e4,0x000136e4},
984 {0x00000000,0x00000000,0x00009492,0x0000a49b,
985 0x000126dc,0x0001b724,0x0001b725,0x0001b724},
986 {0x00000000,0x00000000,0x0000a492,0x000124db,
987 0x000136e4,0x0001b925,0x0001b92d,0x0001b925},
988 {0x00000000,0x00000000,0x00000000,0x00000000,
989 0x00000000,0x00000000,0x00000000,0x00000000}
990 },
991 { /* version 9, passes 1 */
992 {0x00000000,0x00000000,0x00000249,0x00000049,
993 0x00000009,0x00000009,0x00000009,0x00000009},
994 {0x00000000,0x00000000,0x00000249,0x00000249,
995 0x00000049,0x00000049,0x00000009,0x00000009},
996 {0x00000000,0x00000000,0x00001249,0x00001249,
997 0x0000124a,0x00000249,0x00000049,0x00000049},
998 {0x00000000,0x00000000,0x00001249,0x00001249,
999 0x0000124a,0x0000124a,0x00000049,0x00000049},
1000 {0x00000000,0x00000000,0x00001249,0x00001249,
1001 0x00009252,0x0000124a,0x0000024a,0x0000024a},
1002 {0x00000000,0x00000000,0x00001249,0x0000924a,
1003 0x00009252,0x0000124a,0x0000024a,0x0000024a},
1004 {0x00000000,0x00000000,0x00001249,0x00009292,
1005 0x00009492,0x00009252,0x00001252,0x00001252},
1006 {0x00000000,0x00000000,0x00001249,0x00009493,
1007 0x0000a493,0x00009292,0x00009292,0x00001252},
1008 {0x00000000,0x00000000,0x0000924a,0x00009493,
1009 0x0000a493,0x00009292,0x00009292,0x00009292},
1010 {0x00000000,0x00000000,0x0000924a,0x00009493,
1011 0x0000a493,0x00009493,0x00009493,0x00009292},
1012 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1013 0x0000a493,0x0000a49b,0x00009493,0x00009493},
1014 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1015 0x0000a493,0x0000a49b,0x0000a49b,0x00009493},
1016 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1017 0x0001249b,0x000124db,0x0000a49b,0x0000a49b},
1018 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1019 0x000136e4,0x000126dc,0x000124db,0x0000a49b},
1020 {0x00000000,0x00000000,0x00009252,0x000124db,
1021 0x0001b724,0x000136e4,0x000126dc,0x000124db},
1022 {0x00000000,0x00000000,0x00000000,0x00000000,
1023 0x00000000,0x00000000,0x00000000,0x00000000}
1024 }
1025 },
1026 { /* version 10 */
1027 { /* version 10, passes 0 */
1028 {0x00000000,0x00000000,0x00000249,0x00000249,
1029 0x00000249,0x00000249,0x0000024a,0x0000024a},
1030 {0x00000000,0x00000000,0x00000249,0x00001249,
1031 0x00009252,0x00009292,0x00009292,0x0000024a},
1032 {0x00000000,0x00000000,0x00001249,0x00001249,
1033 0x00009252,0x00009292,0x00009292,0x00001252},
1034 {0x00000000,0x00000000,0x00001249,0x0000924a,
1035 0x00009492,0x00009493,0x0000a49b,0x00009292},
1036 {0x00000000,0x00000000,0x00001249,0x00009292,
1037 0x00009492,0x000124db,0x000124db,0x00009292},
1038 {0x00000000,0x00000000,0x00001249,0x00009493,
1039 0x0000a493,0x000124db,0x000124db,0x00009493},
1040 {0x00000000,0x00000000,0x00001249,0x00009493,
1041 0x0000a493,0x000124db,0x000126dc,0x0000a49b},
1042 {0x00000000,0x00000000,0x0000924a,0x00009493,
1043 0x0000a493,0x000124db,0x000126dc,0x000124db},
1044 {0x00000000,0x00000000,0x0000924a,0x00009493,
1045 0x0001249b,0x000126dc,0x000126dc,0x000124db},
1046 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1047 0x000124db,0x000126dc,0x000136e4,0x000126dc},
1048 {0x00000000,0x00000000,0x00009252,0x0000a49b,
1049 0x000124db,0x000136e4,0x000136e4,0x000136e4},
1050 {0x00000000,0x00000000,0x00009292,0x0000a49b,
1051 0x000126dc,0x000136e4,0x000136e4,0x000136e4},
1052 {0x00000000,0x00000000,0x00009492,0x0000a49b,
1053 0x000126dc,0x0001b724,0x0001b92d,0x0001b724},
1054 {0x00000000,0x00000000,0x00009492,0x000124db,
1055 0x000126dc,0x0001b925,0x0001b92d,0x0001b925},
1056 {0x00000000,0x00000000,0x0000a492,0x000126db,
1057 0x000136e4,0x0002496d,0x0001c96e,0x0001c92d},
1058 {0x00000000,0x00000000,0x00000000,0x00000000,
1059 0x00000000,0x00000000,0x00000000,0x00000000}
1060 },
1061 { /* version 10, passes 1 */
1062 {0x00000000,0x00000000,0x00000249,0x00000249,
1063 0x00000049,0x00000049,0x00000049,0x00000049},
1064 {0x00000000,0x00000000,0x00001249,0x00001249,
1065 0x0000124a,0x00000249,0x00000049,0x00000049},
1066 {0x00000000,0x00000000,0x00001249,0x00001249,
1067 0x0000124a,0x00009252,0x0000024a,0x00000049},
1068 {0x00000000,0x00000000,0x00001249,0x00001249,
1069 0x00009252,0x00009493,0x0000024a,0x0000024a},
1070 {0x00000000,0x00000000,0x00001249,0x00009252,
1071 0x00009492,0x00009493,0x00001252,0x0000024a},
1072 {0x00000000,0x00000000,0x00001249,0x00009292,
1073 0x00009492,0x00009493,0x00001252,0x00001252},
1074 {0x00000000,0x00000000,0x0000924a,0x00009493,
1075 0x00009492,0x00009493,0x00009292,0x00001252},
1076 {0x00000000,0x00000000,0x0000924a,0x00009493,
1077 0x0000a493,0x00009493,0x00009292,0x00009292},
1078 {0x00000000,0x00000000,0x0000924a,0x00009493,
1079 0x0000a493,0x0000a49b,0x00009493,0x00009292},
1080 {0x00000000,0x00000000,0x0000924a,0x00009493,
1081 0x0000a493,0x0000a49b,0x00009493,0x00009292},
1082 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1083 0x0000a493,0x000124db,0x0000a49b,0x00009493},
1084 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1085 0x0000a493,0x000124db,0x0000a49b,0x00009493},
1086 {0x00000000,0x00000000,0x0000924a,0x000124db,
1087 0x000136e4,0x000126dc,0x000124db,0x0000a49b},
1088 {0x00000000,0x00000000,0x0000924a,0x000124db,
1089 0x000136e4,0x000126dc,0x000124db,0x0000a49b},
1090 {0x00000000,0x00000000,0x00009252,0x000126db,
1091 0x0001b724,0x000136e4,0x000126dc,0x000124db},
1092 {0x00000000,0x00000000,0x00000000,0x00000000,
1093 0x00000000,0x00000000,0x00000000,0x00000000}
1094 }
1095 },
1096 { /* version 11 */
1097 { /* version 11, passes 0 */
1098 {0x00000000,0x00000000,0x00000249,0x00000249,
1099 0x00000249,0x00000249,0x00001252,0x00001252},
1100 {0x00000000,0x00000000,0x00001249,0x00001249,
1101 0x00009252,0x00009292,0x00009292,0x00001252},
1102 {0x00000000,0x00000000,0x00001249,0x0000924a,
1103 0x00009492,0x0000a49b,0x0000a49b,0x00009292},
1104 {0x00000000,0x00000000,0x00001249,0x00009493,
1105 0x0000a493,0x0000a49b,0x000124db,0x00009493},
1106 {0x00000000,0x00000000,0x00001249,0x00009493,
1107 0x0000a493,0x000124db,0x000126dc,0x00009493},
1108 {0x00000000,0x00000000,0x0000924a,0x00009493,
1109 0x0000a493,0x000126dc,0x000126dc,0x0000a49b},
1110 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1111 0x0001249b,0x000126dc,0x000136e4,0x000124db},
1112 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1113 0x000126dc,0x000136e4,0x000136e4,0x000126dc},
1114 {0x00000000,0x00000000,0x00009292,0x0000a49b,
1115 0x000126dc,0x000136e4,0x000136e4,0x000126dc},
1116 {0x00000000,0x00000000,0x00009292,0x0000a49b,
1117 0x000126dc,0x0001b724,0x0001b725,0x000136e4},
1118 {0x00000000,0x00000000,0x00009292,0x0000a49b,
1119 0x000136e4,0x0001b724,0x0001b92d,0x0001b724},
1120 {0x00000000,0x00000000,0x00009492,0x0000a49b,
1121 0x000136e4,0x0001b724,0x0001b92d,0x0001b724},
1122 {0x00000000,0x00000000,0x00009492,0x000124db,
1123 0x000136e4,0x0001b925,0x0001c96e,0x0001b925},
1124 {0x00000000,0x00000000,0x00009492,0x000124db,
1125 0x0001b724,0x0001b925,0x0001c96e,0x0001c92d},
1126 {0x00000000,0x00000000,0x0000a492,0x000126db,
1127 0x0001c924,0x0002496d,0x00025bb6,0x00024b77},
1128 {0x00000000,0x00000000,0x00000000,0x00000000,
1129 0x00000000,0x00000000,0x00000000,0x00000000}
1130 },
1131 { /* version 11, passes 1 */
1132 {0x00000000,0x00000000,0x00001249,0x00000249,
1133 0x00000249,0x00000249,0x0000024a,0x0000024a},
1134 {0x00000000,0x00000000,0x00001249,0x00001249,
1135 0x0000124a,0x0000124a,0x0000024a,0x0000024a},
1136 {0x00000000,0x00000000,0x00001249,0x0000924a,
1137 0x00009252,0x00009252,0x0000024a,0x0000024a},
1138 {0x00000000,0x00000000,0x00001249,0x00009292,
1139 0x00009492,0x0000a49b,0x00001252,0x00001252},
1140 {0x00000000,0x00000000,0x0000924a,0x00009493,
1141 0x0000a493,0x0000a49b,0x00001252,0x00001252},
1142 {0x00000000,0x00000000,0x0000924a,0x00009493,
1143 0x0000a493,0x0000a49b,0x00009292,0x00001252},
1144 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1145 0x0000a493,0x0000a49b,0x00009292,0x00009292},
1146 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1147 0x0000a493,0x0000a49b,0x00009493,0x00009292},
1148 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1149 0x0001249b,0x000124db,0x00009493,0x00009292},
1150 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1151 0x0001249b,0x000124db,0x00009493,0x00009493},
1152 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1153 0x000124db,0x000124db,0x0000a49b,0x00009493},
1154 {0x00000000,0x00000000,0x0000924a,0x000124db,
1155 0x000126dc,0x000126dc,0x0000a49b,0x00009493},
1156 {0x00000000,0x00000000,0x0000924a,0x000124db,
1157 0x000136e4,0x000126dc,0x000124db,0x0000a49b},
1158 {0x00000000,0x00000000,0x00009292,0x000124db,
1159 0x000136e4,0x000126dc,0x000124db,0x0000a49b},
1160 {0x00000000,0x00000000,0x00009492,0x000126db,
1161 0x0001b724,0x000136e4,0x000126dc,0x000124db},
1162 {0x00000000,0x00000000,0x00000000,0x00000000,
1163 0x00000000,0x00000000,0x00000000,0x00000000}
1164 }
1165 },
1166 { /* version 12 */
1167 { /* version 12, passes 0 */
1168 {0x00000000,0x00000000,0x00001249,0x00001249,
1169 0x00009252,0x00009292,0x00009493,0x00009493},
1170 {0x00000000,0x00000000,0x00001249,0x00009292,
1171 0x0000a493,0x0000a49b,0x0000a49b,0x00009493},
1172 {0x00000000,0x00000000,0x00001249,0x00009493,
1173 0x0000a493,0x000124db,0x000124db,0x0000a49b},
1174 {0x00000000,0x00000000,0x0000924a,0x00009493,
1175 0x0000a493,0x000126dc,0x000126dc,0x0000a49b},
1176 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1177 0x0001249b,0x000126dc,0x000136e4,0x000124db},
1178 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1179 0x000126dc,0x000136e4,0x000136e4,0x000126dc},
1180 {0x00000000,0x00000000,0x00009292,0x0000a49b,
1181 0x000126dc,0x0001b724,0x0001b725,0x000126dc},
1182 {0x00000000,0x00000000,0x00009292,0x0000a49b,
1183 0x000136e4,0x0001b724,0x0001b92d,0x000136e4},
1184 {0x00000000,0x00000000,0x00009492,0x0000a49b,
1185 0x000136e4,0x0001b724,0x0001b92d,0x0001b724},
1186 {0x00000000,0x00000000,0x00009492,0x000124db,
1187 0x000136e4,0x0001b724,0x0001b92d,0x0001b724},
1188 {0x00000000,0x00000000,0x00009492,0x000124db,
1189 0x000136e4,0x0001b925,0x0001b92d,0x0001b925},
1190 {0x00000000,0x00000000,0x00009492,0x000124db,
1191 0x0001b724,0x0001b925,0x0001c96e,0x0001c92d},
1192 {0x00000000,0x00000000,0x0000a492,0x000124db,
1193 0x0001b724,0x0001c92d,0x0001c96e,0x0001c92d},
1194 {0x00000000,0x00000000,0x0000a492,0x000124db,
1195 0x0001b724,0x0001c92d,0x00024b76,0x0002496e},
1196 {0x00000000,0x00000000,0x00012492,0x000126db,
1197 0x0001c924,0x00024b6d,0x0002ddb6,0x00025bbf},
1198 {0x00000000,0x00000000,0x00000000,0x00000000,
1199 0x00000000,0x00000000,0x00000000,0x00000000}
1200 },
1201 { /* version 12, passes 1 */
1202 {0x00000000,0x00000000,0x00001249,0x00001249,
1203 0x0000124a,0x0000124a,0x00001252,0x00001252},
1204 {0x00000000,0x00000000,0x00001249,0x00009292,
1205 0x00009492,0x00009252,0x00001252,0x00001252},
1206 {0x00000000,0x00000000,0x0000924a,0x00009493,
1207 0x0000a493,0x00009292,0x00001252,0x00001252},
1208 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1209 0x0000a493,0x0000a49b,0x00009292,0x00009292},
1210 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1211 0x0000a493,0x0000a49b,0x00009292,0x00009292},
1212 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1213 0x0001249b,0x0000a49b,0x00009493,0x00009292},
1214 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1215 0x000124db,0x000124db,0x00009493,0x00009493},
1216 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1217 0x000124db,0x000124db,0x0000a49b,0x00009493},
1218 {0x00000000,0x00000000,0x0000924a,0x000124db,
1219 0x000126dc,0x000124db,0x0000a49b,0x00009493},
1220 {0x00000000,0x00000000,0x0000924a,0x000124db,
1221 0x000126dc,0x000126dc,0x0000a49b,0x0000a49b},
1222 {0x00000000,0x00000000,0x0000924a,0x000124db,
1223 0x000136e4,0x000126dc,0x000124db,0x0000a49b},
1224 {0x00000000,0x00000000,0x00009492,0x000126db,
1225 0x000136e4,0x000126dc,0x000124db,0x0000a49b},
1226 {0x00000000,0x00000000,0x00009492,0x000126db,
1227 0x0001b724,0x000136e4,0x000126dc,0x000124db},
1228 {0x00000000,0x00000000,0x00009492,0x000126db,
1229 0x0001b724,0x000136e4,0x000126dc,0x000124db},
1230 {0x00000000,0x00000000,0x0000a492,0x000136db,
1231 0x0001c924,0x0001b724,0x000136e4,0x000126dc},
1232 {0x00000000,0x00000000,0x00000000,0x00000000,
1233 0x00000000,0x00000000,0x00000000,0x00000000}
1234 }
1235 },
1236 { /* version 13 */
1237 { /* version 13, passes 0 */
1238 {0x00000000,0x00000000,0x00001249,0x00001249,
1239 0x00009252,0x00009292,0x00009493,0x00009493},
1240 {0x00000000,0x00000000,0x00001249,0x00009493,
1241 0x0000a493,0x000124db,0x000126dc,0x00009493},
1242 {0x00000000,0x00000000,0x00001249,0x0000a49b,
1243 0x0001249b,0x000126dc,0x000126dc,0x0000a49b},
1244 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1245 0x0001249b,0x000126dc,0x000136e4,0x0000a49b},
1246 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1247 0x000126dc,0x000136e4,0x0001b725,0x000124db},
1248 {0x00000000,0x00000000,0x00009292,0x0000a49b,
1249 0x000136e4,0x0001b724,0x0001b725,0x000126dc},
1250 {0x00000000,0x00000000,0x00009292,0x000124db,
1251 0x000136e4,0x0001b724,0x0001b725,0x000126dc},
1252 {0x00000000,0x00000000,0x00009492,0x000124db,
1253 0x000136e4,0x0001b724,0x0001c96e,0x000136e4},
1254 {0x00000000,0x00000000,0x00009492,0x000124db,
1255 0x000136e4,0x0001c92d,0x0001c96e,0x0001b724},
1256 {0x00000000,0x00000000,0x0000a492,0x000124db,
1257 0x000136e4,0x0001c92d,0x0001c96e,0x0001b724},
1258 {0x00000000,0x00000000,0x0000a492,0x000124db,
1259 0x0001b724,0x0001c92d,0x0001c96e,0x0001b925},
1260 {0x00000000,0x00000000,0x0000a492,0x000126db,
1261 0x0001b724,0x0001c92d,0x00024b76,0x0001c92d},
1262 {0x00000000,0x00000000,0x0000a492,0x000126db,
1263 0x0001b924,0x0001c92d,0x00024b76,0x0001c92d},
1264 {0x00000000,0x00000000,0x0000a492,0x000126db,
1265 0x0001b924,0x0001c92d,0x00024b76,0x0002496e},
1266 {0x00000000,0x00000000,0x00012492,0x000136db,
1267 0x00024924,0x00024b6d,0x0002ddb6,0x00025bbf},
1268 {0x00000000,0x00000000,0x00000000,0x00000000,
1269 0x00000000,0x00000000,0x00000000,0x00000000}
1270 },
1271 { /* version 13, passes 1 */
1272 {0x00000000,0x00000000,0x00001249,0x00001249,
1273 0x0000124a,0x0000124a,0x00001252,0x00001252},
1274 {0x00000000,0x00000000,0x0000924a,0x00009493,
1275 0x00009492,0x00009292,0x00001252,0x00001252},
1276 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1277 0x0000a493,0x0000a49b,0x00001252,0x00001252},
1278 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1279 0x0000a493,0x0000a49b,0x00009292,0x00009292},
1280 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1281 0x0000a493,0x0000a49b,0x00009292,0x00009292},
1282 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1283 0x000126dc,0x0000a49b,0x00009493,0x00009292},
1284 {0x00000000,0x00000000,0x0000924a,0x000124db,
1285 0x000126dc,0x000124db,0x00009493,0x00009493},
1286 {0x00000000,0x00000000,0x0000924a,0x000124db,
1287 0x000136e4,0x000124db,0x0000a49b,0x00009493},
1288 {0x00000000,0x00000000,0x0000924a,0x000136db,
1289 0x0001b724,0x000124db,0x0000a49b,0x00009493},
1290 {0x00000000,0x00000000,0x0000924a,0x000136db,
1291 0x0001b724,0x000126dc,0x0000a49b,0x0000a49b},
1292 {0x00000000,0x00000000,0x00009292,0x000136db,
1293 0x0001b724,0x000126dc,0x000124db,0x0000a49b},
1294 {0x00000000,0x00000000,0x00009492,0x000136db,
1295 0x0001b724,0x000126dc,0x000124db,0x0000a49b},
1296 {0x00000000,0x00000000,0x0000a492,0x000136db,
1297 0x0001b724,0x000136e4,0x000126dc,0x000124db},
1298 {0x00000000,0x00000000,0x0000a492,0x000136db,
1299 0x0001b724,0x000136e4,0x000126dc,0x000124db},
1300 {0x00000000,0x00000000,0x00012492,0x0001b6db,
1301 0x0001c924,0x0001b724,0x000136e4,0x000126dc},
1302 {0x00000000,0x00000000,0x00000000,0x00000000,
1303 0x00000000,0x00000000,0x00000000,0x00000000}
1304 }
1305 },
1306 { /* version 14 */
1307 { /* version 14, passes 0 */
1308 {0x00000000,0x00000000,0x00001249,0x0000924a,
1309 0x00009292,0x00009493,0x00009493,0x00009493},
1310 {0x00000000,0x00000000,0x00001249,0x0000a49b,
1311 0x0000a493,0x000124db,0x000126dc,0x00009493},
1312 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1313 0x0001249b,0x000126dc,0x000136e4,0x0000a49b},
1314 {0x00000000,0x00000000,0x0000924a,0x000124db,
1315 0x000126dc,0x000136e4,0x0001b725,0x000124db},
1316 {0x00000000,0x00000000,0x00009292,0x000124db,
1317 0x000126dc,0x0001b724,0x0001b92d,0x000126dc},
1318 {0x00000000,0x00000000,0x00009492,0x000124db,
1319 0x000136e4,0x0001b724,0x0001b92d,0x000126dc},
1320 {0x00000000,0x00000000,0x00009492,0x000124db,
1321 0x000136e4,0x0001c92d,0x0001c96e,0x000136e4},
1322 {0x00000000,0x00000000,0x00009492,0x000124db,
1323 0x0001b724,0x0001c92d,0x0001c96e,0x0001b724},
1324 {0x00000000,0x00000000,0x0000a492,0x000124db,
1325 0x0001b724,0x0001c92d,0x00024b76,0x0001b925},
1326 {0x00000000,0x00000000,0x0000a492,0x000126db,
1327 0x0001b724,0x0001c92d,0x00024b76,0x0001c92d},
1328 {0x00000000,0x00000000,0x0000a492,0x000126db,
1329 0x0001b724,0x0001c92d,0x00024b76,0x0001c92d},
1330 {0x00000000,0x00000000,0x0000a492,0x000136db,
1331 0x0001b724,0x0001c92d,0x00024b76,0x0002496e},
1332 {0x00000000,0x00000000,0x0000a492,0x000136db,
1333 0x0001b924,0x0002496d,0x00024b76,0x00024b77},
1334 {0x00000000,0x00000000,0x0000a492,0x000136db,
1335 0x0001b924,0x00024b6d,0x0002ddb6,0x00025bbf},
1336 {0x00000000,0x00000000,0x00012492,0x0001b6db,
1337 0x00024924,0x0002db6d,0x00036db6,0x0002efff},
1338 {0x00000000,0x00000000,0x00000000,0x00000000,
1339 0x00000000,0x00000000,0x00000000,0x00000000}
1340 },
1341 { /* version 14, passes 1 */
1342 {0x00000000,0x00000000,0x00001249,0x00001249,
1343 0x0000124a,0x0000124a,0x00001252,0x00001252},
1344 {0x00000000,0x00000000,0x0000924a,0x00009493,
1345 0x0000a493,0x00009292,0x00001252,0x00001252},
1346 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1347 0x0000a493,0x0000a49b,0x00001252,0x00001252},
1348 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1349 0x0001249b,0x000136e4,0x00009292,0x00009292},
1350 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1351 0x0001249b,0x000136e4,0x00009292,0x00009292},
1352 {0x00000000,0x00000000,0x0000924a,0x000124db,
1353 0x000136e4,0x000136e4,0x00009493,0x00009292},
1354 {0x00000000,0x00000000,0x00009492,0x000136db,
1355 0x0001b724,0x000136e4,0x00009493,0x00009493},
1356 {0x00000000,0x00000000,0x00009492,0x000136db,
1357 0x0001b724,0x000136e4,0x0000a49b,0x00009493},
1358 {0x00000000,0x00000000,0x00009492,0x000136db,
1359 0x0001b724,0x000136e4,0x0000a49b,0x00009493},
1360 {0x00000000,0x00000000,0x00009492,0x000136db,
1361 0x0001b724,0x000136e4,0x0000a49b,0x0000a49b},
1362 {0x00000000,0x00000000,0x0000a492,0x000136db,
1363 0x0001b724,0x000136e4,0x000124db,0x0000a49b},
1364 {0x00000000,0x00000000,0x0000a492,0x000136db,
1365 0x0001b724,0x000136e4,0x000124db,0x0000a49b},
1366 {0x00000000,0x00000000,0x0000a492,0x000136db,
1367 0x0001b724,0x000136e4,0x000126dc,0x000124db},
1368 {0x00000000,0x00000000,0x0000a492,0x000136db,
1369 0x0001b724,0x000136e4,0x000126dc,0x000124db},
1370 {0x00000000,0x00000000,0x00012492,0x0001b6db,
1371 0x0001c924,0x0001b724,0x000136e4,0x000126dc},
1372 {0x00000000,0x00000000,0x00000000,0x00000000,
1373 0x00000000,0x00000000,0x00000000,0x00000000}
1374 }
1375 },
1376 { /* version 15 */
1377 { /* version 15, passes 0 */
1378 {0x00000000,0x00000000,0x00001249,0x00009493,
1379 0x0000a493,0x0000a49b,0x000124db,0x000124db},
1380 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1381 0x0001249b,0x000126dc,0x000136e4,0x000124db},
1382 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1383 0x000126dc,0x0001b724,0x0001b725,0x000126dc},
1384 {0x00000000,0x00000000,0x0000924a,0x000124db,
1385 0x000136e4,0x0001b724,0x0001b92d,0x000126dc},
1386 {0x00000000,0x00000000,0x00009492,0x000124db,
1387 0x000136e4,0x0001b925,0x0001c96e,0x000136e4},
1388 {0x00000000,0x00000000,0x00009492,0x000124db,
1389 0x0001b724,0x0001c92d,0x0001c96e,0x0001b724},
1390 {0x00000000,0x00000000,0x0000a492,0x000124db,
1391 0x0001b724,0x0001c92d,0x0001c96e,0x0001b724},
1392 {0x00000000,0x00000000,0x0000a492,0x000126db,
1393 0x0001b724,0x0001c92d,0x0001c96e,0x0001b925},
1394 {0x00000000,0x00000000,0x0000a492,0x000126db,
1395 0x0001b924,0x0001c92d,0x00024b76,0x0001c92d},
1396 {0x00000000,0x00000000,0x0000a492,0x000136db,
1397 0x0001b924,0x0001c92d,0x00024b76,0x0001c92d},
1398 {0x00000000,0x00000000,0x0000a492,0x000136db,
1399 0x0001b924,0x0002496d,0x00024b76,0x0002496e},
1400 {0x00000000,0x00000000,0x0000a492,0x000136db,
1401 0x0001c924,0x0002496d,0x00025bb6,0x00024b77},
1402 {0x00000000,0x00000000,0x0000a492,0x000136db,
1403 0x0001c924,0x00024b6d,0x00025bb6,0x00024b77},
1404 {0x00000000,0x00000000,0x00012492,0x000136db,
1405 0x0001c924,0x00024b6d,0x0002ddb6,0x00025bbf},
1406 {0x00000000,0x00000000,0x00012492,0x0001b6db,
1407 0x00024924,0x0002db6d,0x00036db6,0x0002efff},
1408 {0x00000000,0x00000000,0x00000000,0x00000000,
1409 0x00000000,0x00000000,0x00000000,0x00000000}
1410 },
1411 { /* version 15, passes 1 */
1412 {0x00000000,0x00000000,0x0000924a,0x0000924a,
1413 0x00009292,0x00009292,0x00009292,0x00009292},
1414 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1415 0x0000a493,0x000124db,0x00009292,0x00009292},
1416 {0x00000000,0x00000000,0x0000924a,0x000124db,
1417 0x000124db,0x0001b724,0x00009493,0x00009493},
1418 {0x00000000,0x00000000,0x0000924a,0x000124db,
1419 0x000126dc,0x0001b724,0x00009493,0x00009493},
1420 {0x00000000,0x00000000,0x0000924a,0x000124db,
1421 0x000136e4,0x0001b724,0x0000a49b,0x0000a49b},
1422 {0x00000000,0x00000000,0x00009292,0x000136db,
1423 0x0001b724,0x0001b724,0x0000a49b,0x0000a49b},
1424 {0x00000000,0x00000000,0x00009492,0x000136db,
1425 0x0001c924,0x0001b724,0x000124db,0x000124db},
1426 {0x00000000,0x00000000,0x00009492,0x000136db,
1427 0x0001c924,0x0001b724,0x000124db,0x000124db},
1428 {0x00000000,0x00000000,0x0000a492,0x000136db,
1429 0x0001c924,0x0001b724,0x000126dc,0x000126dc},
1430 {0x00000000,0x00000000,0x0000a492,0x000136db,
1431 0x0001c924,0x0001b925,0x000126dc,0x000126dc},
1432 {0x00000000,0x00000000,0x0000a492,0x000136db,
1433 0x0001c924,0x0001b925,0x000136e4,0x000136e4},
1434 {0x00000000,0x00000000,0x0000a492,0x000136db,
1435 0x0001c924,0x0001b925,0x000136e4,0x000136e4},
1436 {0x00000000,0x00000000,0x0000a492,0x000136db,
1437 0x0001c924,0x0001b925,0x0001b725,0x0001b724},
1438 {0x00000000,0x00000000,0x00012492,0x000136db,
1439 0x0001c924,0x0001b925,0x0001b725,0x0001b724},
1440 {0x00000000,0x00000000,0x00012492,0x0001b6db,
1441 0x00024924,0x0002496d,0x0001b92d,0x0001b925},
1442 {0x00000000,0x00000000,0x00000000,0x00000000,
1443 0x00000000,0x00000000,0x00000000,0x00000000}
1444 }
1445 }
1446};
diff --git a/drivers/media/video/pwc/pwc-timon.h b/drivers/media/video/pwc/pwc-timon.h
index a86b3782a081..eef9e2cd4320 100644
--- a/drivers/media/video/pwc/pwc-timon.h
+++ b/drivers/media/video/pwc/pwc-timon.h
@@ -1,5 +1,5 @@
1/* Linux driver for Philips webcam 1/* Linux driver for Philips webcam
2 (C) 2004 Luc Saillard (luc@saillard.org) 2 (C) 2004-2006 Luc Saillard (luc@saillard.org)
3 3
4 NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx 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. 5 driver and thus may have bugs that are not present in the original version.
@@ -42,7 +42,7 @@
42#ifndef PWC_TIMON_H 42#ifndef PWC_TIMON_H
43#define PWC_TIMON_H 43#define PWC_TIMON_H
44 44
45#include "pwc-ioctl.h" 45#include <media/pwc-ioctl.h>
46 46
47struct Timon_table_entry 47struct Timon_table_entry
48{ 48{
@@ -52,8 +52,8 @@ struct Timon_table_entry
52 unsigned char mode[13]; /* precomputed mode settings for cam */ 52 unsigned char mode[13]; /* precomputed mode settings for cam */
53}; 53};
54 54
55const extern struct Timon_table_entry Timon_table[PSZ_MAX][6][4]; 55extern const struct Timon_table_entry Timon_table[PSZ_MAX][6][4];
56const extern unsigned int TimonRomTable [16][2][16][8]; 56extern const unsigned int TimonRomTable [16][2][16][8];
57 57
58 58
59#endif 59#endif
diff --git a/drivers/media/video/pwc/pwc-uncompress.c b/drivers/media/video/pwc/pwc-uncompress.c
index b37a89a163f9..5d82028ef942 100644
--- a/drivers/media/video/pwc/pwc-uncompress.c
+++ b/drivers/media/video/pwc/pwc-uncompress.c
@@ -1,7 +1,7 @@
1/* Linux driver for Philips webcam 1/* Linux driver for Philips webcam
2 Decompression frontend. 2 Decompression frontend.
3 (C) 1999-2003 Nemosoft Unv. 3 (C) 1999-2003 Nemosoft Unv.
4 (C) 2004 Luc Saillard (luc@saillard.org) 4 (C) 2004-2006 Luc Saillard (luc@saillard.org)
5 5
6 NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx 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. 7 driver and thus may have bugs that are not present in the original version.
@@ -22,6 +22,8 @@
22 You should have received a copy of the GNU General Public License 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 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 24 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25
26 vim: set ts=8:
25*/ 27*/
26 28
27#include <asm/current.h> 29#include <asm/current.h>
@@ -29,6 +31,8 @@
29 31
30#include "pwc.h" 32#include "pwc.h"
31#include "pwc-uncompress.h" 33#include "pwc-uncompress.h"
34#include "pwc-dec1.h"
35#include "pwc-dec23.h"
32 36
33int pwc_decompress(struct pwc_device *pdev) 37int pwc_decompress(struct pwc_device *pdev)
34{ 38{
@@ -40,107 +44,95 @@ int pwc_decompress(struct pwc_device *pdev)
40 44
41 if (pdev == NULL) 45 if (pdev == NULL)
42 return -EFAULT; 46 return -EFAULT;
43#if defined(__KERNEL__) && defined(PWC_MAGIC)
44 if (pdev->magic != PWC_MAGIC) {
45 Err("pwc_decompress(): magic failed.\n");
46 return -EFAULT;
47 }
48#endif
49 47
50 fbuf = pdev->read_frame; 48 fbuf = pdev->read_frame;
51 if (fbuf == NULL) 49 if (fbuf == NULL)
52 return -EFAULT; 50 return -EFAULT;
53 image = pdev->image_ptr[pdev->fill_image]; 51 image = pdev->image_data;
54 if (!image) 52 image += pdev->images[pdev->fill_image].offset;
55 return -EFAULT;
56 53
57 yuv = fbuf->data + pdev->frame_header_size; /* Skip header */ 54 yuv = fbuf->data + pdev->frame_header_size; /* Skip header */
58 55
59 /* Raw format; that's easy... */ 56 /* Raw format; that's easy... */
60 if (pdev->vpalette == VIDEO_PALETTE_RAW) 57 if (pdev->vpalette == VIDEO_PALETTE_RAW)
61 { 58 {
62 memcpy(image, yuv, pdev->frame_size); 59 struct pwc_raw_frame *raw_frame = image;
60 raw_frame->type = cpu_to_le16(pdev->type);
61 raw_frame->vbandlength = cpu_to_le16(pdev->vbandlength);
62 /* cmd_buf is always 4 bytes, but sometimes, only the
63 * first 3 bytes is filled (Nala case). We can
64 * determine this using the type of the webcam */
65 memcpy(raw_frame->cmd, pdev->cmd_buf, 4);
66 memcpy(raw_frame+1, yuv, pdev->frame_size);
63 return 0; 67 return 0;
64 } 68 }
65 69
66 if (pdev->vbandlength == 0) { 70 if (pdev->vbandlength == 0) {
67 /* Uncompressed mode. We copy the data into the output buffer, 71 /* Uncompressed mode.
68 using the viewport size (which may be larger than the image 72 * We copy the data into the output buffer, using the viewport
69 size). Unfortunately we have to do a bit of byte stuffing 73 * size (which may be larger than the image size).
70 to get the desired output format/size. 74 * Unfortunately we have to do a bit of byte stuffing to get
75 * the desired output format/size.
76 *
77 * We do some byte shuffling here to go from the
78 * native format to YUV420P.
71 */ 79 */
72 /* 80 src = (u16 *)yuv;
73 * We do some byte shuffling here to go from the 81 n = pdev->view.x * pdev->view.y;
74 * native format to YUV420P. 82
75 */ 83 /* offset in Y plane */
76 src = (u16 *)yuv; 84 stride = pdev->view.x * pdev->offset.y + pdev->offset.x;
77 n = pdev->view.x * pdev->view.y; 85 dsty = (u16 *)(image + stride);
78 86
79 /* offset in Y plane */ 87 /* offsets in U/V planes */
80 stride = pdev->view.x * pdev->offset.y + pdev->offset.x; 88 stride = pdev->view.x * pdev->offset.y / 4 + pdev->offset.x / 2;
81 dsty = (u16 *)(image + stride); 89 dstu = (u16 *)(image + n + stride);
82 90 dstv = (u16 *)(image + n + n / 4 + stride);
83 /* offsets in U/V planes */ 91
84 stride = pdev->view.x * pdev->offset.y / 4 + pdev->offset.x / 2; 92 /* increment after each line */
85 dstu = (u16 *)(image + n + stride); 93 stride = (pdev->view.x - pdev->image.x) / 2; /* u16 is 2 bytes */
86 dstv = (u16 *)(image + n + n / 4 + stride); 94
87 95 for (line = 0; line < pdev->image.y; line++) {
88 /* increment after each line */ 96 for (col = 0; col < pdev->image.x; col += 4) {
89 stride = (pdev->view.x - pdev->image.x) / 2; /* u16 is 2 bytes */ 97 *dsty++ = *src++;
90 98 *dsty++ = *src++;
91 for (line = 0; line < pdev->image.y; line++) {
92 for (col = 0; col < pdev->image.x; col += 4) {
93 *dsty++ = *src++;
94 *dsty++ = *src++;
95 if (line & 1)
96 *dstv++ = *src++;
97 else
98 *dstu++ = *src++;
99 }
100 dsty += stride;
101 if (line & 1) 99 if (line & 1)
102 dstv += (stride >> 1); 100 *dstv++ = *src++;
103 else 101 else
104 dstu += (stride >> 1); 102 *dstu++ = *src++;
105 } 103 }
104 dsty += stride;
105 if (line & 1)
106 dstv += (stride >> 1);
107 else
108 dstu += (stride >> 1);
109 }
110
111 return 0;
106 } 112 }
107 else { 113
108 /* Compressed; the decompressor routines will write the data 114 /*
109 in planar format immediately. 115 * Compressed;
110 */ 116 * the decompressor routines will write the data in planar format
111 int flags; 117 * immediately.
112 118 */
113 flags = PWCX_FLAG_PLANAR; 119 if (pdev->vsize == PSZ_VGA && pdev->vframes == 5 && pdev->vsnapshot) {
114 if (pdev->vsize == PSZ_VGA && pdev->vframes == 5 && pdev->vsnapshot) 120 PWC_ERROR("Mode Bayer is not supported for now\n");
115 { 121 /* flags |= PWCX_FLAG_BAYER; */
116 printk(KERN_ERR "pwc: Mode Bayer is not supported for now\n"); 122 return -ENXIO; /* No such device or address: missing decompressor */
117 flags |= PWCX_FLAG_BAYER; 123 }
118 return -ENXIO; /* No such device or address: missing decompressor */ 124
119 } 125 if (DEVICE_USE_CODEC1(pdev->type)) {
120 126
121#if 0 127 /* TODO & FIXME */
122 switch (pdev->type) 128 PWC_ERROR("This chipset is not supported for now\n");
123 { 129 return -ENXIO; /* No such device or address: missing decompressor */
124 case 675: 130
125 case 680: 131 } else {
126 case 690: 132 pwc_dec23_decompress(pdev, yuv, image, PWCX_FLAG_PLANAR);
127 case 720:
128 case 730:
129 case 740:
130 case 750:
131 pwc_dec23_decompress(&pdev->image, &pdev->view,
132 &pdev->offset, yuv, image, flags,
133 pdev->decompress_data, pdev->vbandlength);
134 break;
135 case 645:
136 case 646:
137 /* TODO & FIXME */
138 return -ENXIO; /* Missing decompressor */
139 break;
140 }
141#endif
142 } 133 }
143 return 0; 134 return 0;
144} 135}
145 136
146 137
138/* vim: set cino= formatoptions=croql cindent shiftwidth=8 tabstop=8: */
diff --git a/drivers/media/video/pwc/pwc-uncompress.h b/drivers/media/video/pwc/pwc-uncompress.h
index f75e1b6cbe19..041227f65246 100644
--- a/drivers/media/video/pwc/pwc-uncompress.h
+++ b/drivers/media/video/pwc/pwc-uncompress.h
@@ -1,5 +1,5 @@
1/* (C) 1999-2003 Nemosoft Unv. 1/* (C) 1999-2003 Nemosoft Unv.
2 (C) 2004 Luc Saillard (luc@saillard.org) 2 (C) 2004-2006 Luc Saillard (luc@saillard.org)
3 3
4 NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx 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. 5 driver and thus may have bugs that are not present in the original version.
@@ -32,7 +32,7 @@
32 32
33#include <linux/config.h> 33#include <linux/config.h>
34 34
35#include "pwc-ioctl.h" 35#include <media/pwc-ioctl.h>
36 36
37/* from pwc-dec.h */ 37/* from pwc-dec.h */
38#define PWCX_FLAG_PLANAR 0x0001 38#define PWCX_FLAG_PLANAR 0x0001
diff --git a/drivers/media/video/pwc/pwc-v4l.c b/drivers/media/video/pwc/pwc-v4l.c
new file mode 100644
index 000000000000..68e7573c8ef2
--- /dev/null
+++ b/drivers/media/video/pwc/pwc-v4l.c
@@ -0,0 +1,1208 @@
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
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 <linux/errno.h>
29#include <linux/init.h>
30#include <linux/mm.h>
31#include <linux/module.h>
32#include <linux/poll.h>
33#include <linux/slab.h>
34#include <linux/vmalloc.h>
35#include <asm/io.h>
36
37#include "pwc.h"
38
39static struct v4l2_queryctrl pwc_controls[] = {
40 {
41 .id = V4L2_CID_BRIGHTNESS,
42 .type = V4L2_CTRL_TYPE_INTEGER,
43 .name = "Brightness",
44 .minimum = 0,
45 .maximum = 128,
46 .step = 1,
47 .default_value = 64,
48 },
49 {
50 .id = V4L2_CID_CONTRAST,
51 .type = V4L2_CTRL_TYPE_INTEGER,
52 .name = "Contrast",
53 .minimum = 0,
54 .maximum = 64,
55 .step = 1,
56 .default_value = 0,
57 },
58 {
59 .id = V4L2_CID_SATURATION,
60 .type = V4L2_CTRL_TYPE_INTEGER,
61 .name = "Saturation",
62 .minimum = -100,
63 .maximum = 100,
64 .step = 1,
65 .default_value = 0,
66 },
67 {
68 .id = V4L2_CID_GAMMA,
69 .type = V4L2_CTRL_TYPE_INTEGER,
70 .name = "Gamma",
71 .minimum = 0,
72 .maximum = 32,
73 .step = 1,
74 .default_value = 0,
75 },
76 {
77 .id = V4L2_CID_RED_BALANCE,
78 .type = V4L2_CTRL_TYPE_INTEGER,
79 .name = "Red Gain",
80 .minimum = 0,
81 .maximum = 256,
82 .step = 1,
83 .default_value = 0,
84 },
85 {
86 .id = V4L2_CID_BLUE_BALANCE,
87 .type = V4L2_CTRL_TYPE_INTEGER,
88 .name = "Blue Gain",
89 .minimum = 0,
90 .maximum = 256,
91 .step = 1,
92 .default_value = 0,
93 },
94 {
95 .id = V4L2_CID_AUTO_WHITE_BALANCE,
96 .type = V4L2_CTRL_TYPE_BOOLEAN,
97 .name = "Auto White Balance",
98 .minimum = 0,
99 .maximum = 1,
100 .step = 1,
101 .default_value = 0,
102 },
103 {
104 .id = V4L2_CID_EXPOSURE,
105 .type = V4L2_CTRL_TYPE_INTEGER,
106 .name = "Shutter Speed (Exposure)",
107 .minimum = 0,
108 .maximum = 256,
109 .step = 1,
110 .default_value = 200,
111 },
112 {
113 .id = V4L2_CID_AUTOGAIN,
114 .type = V4L2_CTRL_TYPE_BOOLEAN,
115 .name = "Auto Gain Enabled",
116 .minimum = 0,
117 .maximum = 1,
118 .step = 1,
119 .default_value = 1,
120 },
121 {
122 .id = V4L2_CID_GAIN,
123 .type = V4L2_CTRL_TYPE_INTEGER,
124 .name = "Gain Level",
125 .minimum = 0,
126 .maximum = 256,
127 .step = 1,
128 .default_value = 0,
129 },
130#if XAWTV_HAS_BEEN_FIXED
131 {
132 .id = V4L2_CID_PRIVATE_SAVE_USER,
133 .type = V4L2_CTRL_TYPE_BUTTON,
134 .name = "Save User Settings",
135 .minimum = 0,
136 .maximum = 0,
137 .step = 0,
138 .default_value = 0,
139 },
140 {
141 .id = V4L2_CID_PRIVATE_RESTORE_USER,
142 .type = V4L2_CTRL_TYPE_BUTTON,
143 .name = "Restore User Settings",
144 .minimum = 0,
145 .maximum = 0,
146 .step = 0,
147 .default_value = 0,
148 },
149 {
150 .id = V4L2_CID_PRIVATE_RESTORE_FACTORY,
151 .type = V4L2_CTRL_TYPE_BUTTON,
152 .name = "Restore Factory Settings",
153 .minimum = 0,
154 .maximum = 0,
155 .step = 0,
156 .default_value = 0,
157 },
158 {
159 .id = V4L2_CID_PRIVATE_COLOUR_MODE,
160 .type = V4L2_CTRL_TYPE_BOOLEAN,
161 .name = "Colour mode",
162 .minimum = 0,
163 .maximum = 1,
164 .step = 1,
165 .default_value = 0,
166 },
167 {
168 .id = V4L2_CID_PRIVATE_AUTOCONTOUR,
169 .type = V4L2_CTRL_TYPE_BOOLEAN,
170 .name = "Auto contour",
171 .minimum = 0,
172 .maximum = 1,
173 .step = 1,
174 .default_value = 0,
175 },
176 {
177 .id = V4L2_CID_PRIVATE_CONTOUR,
178 .type = V4L2_CTRL_TYPE_INTEGER,
179 .name = "Contour",
180 .minimum = 0,
181 .maximum = 63,
182 .step = 1,
183 .default_value = 0,
184 },
185 {
186 .id = V4L2_CID_PRIVATE_BACKLIGHT,
187 .type = V4L2_CTRL_TYPE_BOOLEAN,
188 .name = "Backlight compensation",
189 .minimum = 0,
190 .maximum = 1,
191 .step = 1,
192 .default_value = 0,
193 },
194 {
195 .id = V4L2_CID_PRIVATE_FLICKERLESS,
196 .type = V4L2_CTRL_TYPE_BOOLEAN,
197 .name = "Flickerless",
198 .minimum = 0,
199 .maximum = 1,
200 .step = 1,
201 .default_value = 0,
202 },
203 {
204 .id = V4L2_CID_PRIVATE_NOISE_REDUCTION,
205 .type = V4L2_CTRL_TYPE_INTEGER,
206 .name = "Noise reduction",
207 .minimum = 0,
208 .maximum = 3,
209 .step = 1,
210 .default_value = 0,
211 },
212#endif
213};
214
215#if CONFIG_PWC_DEBUG
216/* In 2.6.16-rc1 v4l_printk_ioctl is not defined but exported */
217extern void v4l_printk_ioctl(unsigned int cmd);
218#endif
219
220static void pwc_vidioc_fill_fmt(const struct pwc_device *pdev, struct v4l2_format *f)
221{
222 memset(&f->fmt.pix, 0, sizeof(struct v4l2_pix_format));
223 f->fmt.pix.width = pdev->view.x;
224 f->fmt.pix.height = pdev->view.y;
225 f->fmt.pix.field = V4L2_FIELD_NONE;
226 if (pdev->vpalette == VIDEO_PALETTE_YUV420P) {
227 f->fmt.pix.pixelformat = V4L2_PIX_FMT_YUV420;
228 f->fmt.pix.bytesperline = (f->fmt.pix.width * 3)/2;
229 f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline;
230 } else {
231 /* vbandlength contains 4 lines ... */
232 f->fmt.pix.bytesperline = pdev->vbandlength/4;
233 f->fmt.pix.sizeimage = pdev->frame_size + sizeof(struct pwc_raw_frame);
234 if (DEVICE_USE_CODEC1(pdev->type))
235 f->fmt.pix.pixelformat = V4L2_PIX_FMT_PWC1;
236 else
237 f->fmt.pix.pixelformat = V4L2_PIX_FMT_PWC2;
238 }
239 PWC_DEBUG_IOCTL("pwc_vidioc_fill_fmt() "
240 "width=%d, height=%d, bytesperline=%d, sizeimage=%d, pixelformat=%c%c%c%c\n",
241 f->fmt.pix.width,
242 f->fmt.pix.height,
243 f->fmt.pix.bytesperline,
244 f->fmt.pix.sizeimage,
245 (f->fmt.pix.pixelformat)&255,
246 (f->fmt.pix.pixelformat>>8)&255,
247 (f->fmt.pix.pixelformat>>16)&255,
248 (f->fmt.pix.pixelformat>>24)&255);
249}
250
251/* ioctl(VIDIOC_TRY_FMT) */
252static int pwc_vidioc_try_fmt(struct pwc_device *pdev, struct v4l2_format *f)
253{
254 if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
255 PWC_DEBUG_IOCTL("Bad video type must be V4L2_BUF_TYPE_VIDEO_CAPTURE\n");
256 return -EINVAL;
257 }
258
259 switch (f->fmt.pix.pixelformat) {
260 case V4L2_PIX_FMT_YUV420:
261 break;
262 case V4L2_PIX_FMT_PWC1:
263 if (DEVICE_USE_CODEC23(pdev->type)) {
264 PWC_DEBUG_IOCTL("codec1 is only supported for old pwc webcam\n");
265 return -EINVAL;
266 }
267 break;
268 case V4L2_PIX_FMT_PWC2:
269 if (DEVICE_USE_CODEC1(pdev->type)) {
270 PWC_DEBUG_IOCTL("codec23 is only supported for new pwc webcam\n");
271 return -EINVAL;
272 }
273 break;
274 default:
275 PWC_DEBUG_IOCTL("Unsupported pixel format\n");
276 return -EINVAL;
277
278 }
279
280 if (f->fmt.pix.width > pdev->view_max.x)
281 f->fmt.pix.width = pdev->view_max.x;
282 else if (f->fmt.pix.width < pdev->view_min.x)
283 f->fmt.pix.width = pdev->view_min.x;
284
285 if (f->fmt.pix.height > pdev->view_max.y)
286 f->fmt.pix.height = pdev->view_max.y;
287 else if (f->fmt.pix.height < pdev->view_min.y)
288 f->fmt.pix.height = pdev->view_min.y;
289
290 return 0;
291}
292
293/* ioctl(VIDIOC_SET_FMT) */
294static int pwc_vidioc_set_fmt(struct pwc_device *pdev, struct v4l2_format *f)
295{
296 int ret, fps, snapshot, compression, pixelformat;
297
298 ret = pwc_vidioc_try_fmt(pdev, f);
299 if (ret<0)
300 return ret;
301
302 pixelformat = f->fmt.pix.pixelformat;
303 compression = pdev->vcompression;
304 snapshot = 0;
305 fps = pdev->vframes;
306 if (f->fmt.pix.priv) {
307 compression = (f->fmt.pix.priv & PWC_QLT_MASK) >> PWC_QLT_SHIFT;
308 snapshot = !!(f->fmt.pix.priv & PWC_FPS_SNAPSHOT);
309 fps = (f->fmt.pix.priv & PWC_FPS_FRMASK) >> PWC_FPS_SHIFT;
310 if (fps == 0)
311 fps = pdev->vframes;
312 }
313
314 if (pixelformat == V4L2_PIX_FMT_YUV420)
315 pdev->vpalette = VIDEO_PALETTE_YUV420P;
316 else
317 pdev->vpalette = VIDEO_PALETTE_RAW;
318
319 PWC_DEBUG_IOCTL("Try to change format to: width=%d height=%d fps=%d "
320 "compression=%d snapshot=%d format=%c%c%c%c\n",
321 f->fmt.pix.width, f->fmt.pix.height, fps,
322 compression, snapshot,
323 (pixelformat)&255,
324 (pixelformat>>8)&255,
325 (pixelformat>>16)&255,
326 (pixelformat>>24)&255);
327
328 ret = pwc_try_video_mode(pdev,
329 f->fmt.pix.width,
330 f->fmt.pix.height,
331 fps,
332 compression,
333 snapshot);
334
335 PWC_DEBUG_IOCTL("pwc_try_video_mode(), return=%d\n", ret);
336
337 if (ret)
338 return ret;
339
340 pwc_vidioc_fill_fmt(pdev, f);
341
342 return 0;
343
344}
345
346int pwc_video_do_ioctl(struct inode *inode, struct file *file,
347 unsigned int cmd, void *arg)
348{
349 struct video_device *vdev = video_devdata(file);
350 struct pwc_device *pdev;
351 DECLARE_WAITQUEUE(wait, current);
352
353 if (vdev == NULL)
354 return -EFAULT;
355 pdev = vdev->priv;
356 if (pdev == NULL)
357 return -EFAULT;
358
359#if CONFIG_PWC_DEBUG
360 if (PWC_DEBUG_LEVEL_IOCTL & pwc_trace)
361 v4l_printk_ioctl(cmd);
362#endif
363
364
365 switch (cmd) {
366 /* Query cabapilities */
367 case VIDIOCGCAP:
368 {
369 struct video_capability *caps = arg;
370
371 strcpy(caps->name, vdev->name);
372 caps->type = VID_TYPE_CAPTURE;
373 caps->channels = 1;
374 caps->audios = 1;
375 caps->minwidth = pdev->view_min.x;
376 caps->minheight = pdev->view_min.y;
377 caps->maxwidth = pdev->view_max.x;
378 caps->maxheight = pdev->view_max.y;
379 break;
380 }
381
382 /* Channel functions (simulate 1 channel) */
383 case VIDIOCGCHAN:
384 {
385 struct video_channel *v = arg;
386
387 if (v->channel != 0)
388 return -EINVAL;
389 v->flags = 0;
390 v->tuners = 0;
391 v->type = VIDEO_TYPE_CAMERA;
392 strcpy(v->name, "Webcam");
393 return 0;
394 }
395
396 case VIDIOCSCHAN:
397 {
398 /* The spec says the argument is an integer, but
399 the bttv driver uses a video_channel arg, which
400 makes sense becasue it also has the norm flag.
401 */
402 struct video_channel *v = arg;
403 if (v->channel != 0)
404 return -EINVAL;
405 return 0;
406 }
407
408
409 /* Picture functions; contrast etc. */
410 case VIDIOCGPICT:
411 {
412 struct video_picture *p = arg;
413 int val;
414
415 val = pwc_get_brightness(pdev);
416 if (val >= 0)
417 p->brightness = (val<<9);
418 else
419 p->brightness = 0xffff;
420 val = pwc_get_contrast(pdev);
421 if (val >= 0)
422 p->contrast = (val<<10);
423 else
424 p->contrast = 0xffff;
425 /* Gamma, Whiteness, what's the difference? :) */
426 val = pwc_get_gamma(pdev);
427 if (val >= 0)
428 p->whiteness = (val<<11);
429 else
430 p->whiteness = 0xffff;
431 if (pwc_get_saturation(pdev, &val)<0)
432 p->colour = 0xffff;
433 else
434 p->colour = 32768 + val * 327;
435 p->depth = 24;
436 p->palette = pdev->vpalette;
437 p->hue = 0xFFFF; /* N/A */
438 break;
439 }
440
441 case VIDIOCSPICT:
442 {
443 struct video_picture *p = arg;
444 /*
445 * FIXME: Suppose we are mid read
446 ANSWER: No problem: the firmware of the camera
447 can handle brightness/contrast/etc
448 changes at _any_ time, and the palette
449 is used exactly once in the uncompress
450 routine.
451 */
452 pwc_set_brightness(pdev, p->brightness);
453 pwc_set_contrast(pdev, p->contrast);
454 pwc_set_gamma(pdev, p->whiteness);
455 pwc_set_saturation(pdev, (p->colour-32768)/327);
456 if (p->palette && p->palette != pdev->vpalette) {
457 switch (p->palette) {
458 case VIDEO_PALETTE_YUV420P:
459 case VIDEO_PALETTE_RAW:
460 pdev->vpalette = p->palette;
461 return pwc_try_video_mode(pdev, pdev->image.x, pdev->image.y, pdev->vframes, pdev->vcompression, pdev->vsnapshot);
462 break;
463 default:
464 return -EINVAL;
465 break;
466 }
467 }
468 break;
469 }
470
471 /* Window/size parameters */
472 case VIDIOCGWIN:
473 {
474 struct video_window *vw = arg;
475
476 vw->x = 0;
477 vw->y = 0;
478 vw->width = pdev->view.x;
479 vw->height = pdev->view.y;
480 vw->chromakey = 0;
481 vw->flags = (pdev->vframes << PWC_FPS_SHIFT) |
482 (pdev->vsnapshot ? PWC_FPS_SNAPSHOT : 0);
483 break;
484 }
485
486 case VIDIOCSWIN:
487 {
488 struct video_window *vw = arg;
489 int fps, snapshot, ret;
490
491 fps = (vw->flags & PWC_FPS_FRMASK) >> PWC_FPS_SHIFT;
492 snapshot = vw->flags & PWC_FPS_SNAPSHOT;
493 if (fps == 0)
494 fps = pdev->vframes;
495 if (pdev->view.x == vw->width && pdev->view.y && fps == pdev->vframes && snapshot == pdev->vsnapshot)
496 return 0;
497 ret = pwc_try_video_mode(pdev, vw->width, vw->height, fps, pdev->vcompression, snapshot);
498 if (ret)
499 return ret;
500 break;
501 }
502
503 /* We don't have overlay support (yet) */
504 case VIDIOCGFBUF:
505 {
506 struct video_buffer *vb = arg;
507
508 memset(vb,0,sizeof(*vb));
509 break;
510 }
511
512 /* mmap() functions */
513 case VIDIOCGMBUF:
514 {
515 /* Tell the user program how much memory is needed for a mmap() */
516 struct video_mbuf *vm = arg;
517 int i;
518
519 memset(vm, 0, sizeof(*vm));
520 vm->size = pwc_mbufs * pdev->len_per_image;
521 vm->frames = pwc_mbufs; /* double buffering should be enough for most applications */
522 for (i = 0; i < pwc_mbufs; i++)
523 vm->offsets[i] = i * pdev->len_per_image;
524 break;
525 }
526
527 case VIDIOCMCAPTURE:
528 {
529 /* Start capture into a given image buffer (called 'frame' in video_mmap structure) */
530 struct video_mmap *vm = arg;
531
532 PWC_DEBUG_READ("VIDIOCMCAPTURE: %dx%d, frame %d, format %d\n", vm->width, vm->height, vm->frame, vm->format);
533 if (vm->frame < 0 || vm->frame >= pwc_mbufs)
534 return -EINVAL;
535
536 /* xawtv is nasty. It probes the available palettes
537 by setting a very small image size and trying
538 various palettes... The driver doesn't support
539 such small images, so I'm working around it.
540 */
541 if (vm->format)
542 {
543 switch (vm->format)
544 {
545 case VIDEO_PALETTE_YUV420P:
546 case VIDEO_PALETTE_RAW:
547 break;
548 default:
549 return -EINVAL;
550 break;
551 }
552 }
553
554 if ((vm->width != pdev->view.x || vm->height != pdev->view.y) &&
555 (vm->width >= pdev->view_min.x && vm->height >= pdev->view_min.y)) {
556 int ret;
557
558 PWC_DEBUG_OPEN("VIDIOCMCAPTURE: changing size to please xawtv :-(.\n");
559 ret = pwc_try_video_mode(pdev, vm->width, vm->height, pdev->vframes, pdev->vcompression, pdev->vsnapshot);
560 if (ret)
561 return ret;
562 } /* ... size mismatch */
563
564 /* FIXME: should we lock here? */
565 if (pdev->image_used[vm->frame])
566 return -EBUSY; /* buffer wasn't available. Bummer */
567 pdev->image_used[vm->frame] = 1;
568
569 /* Okay, we're done here. In the SYNC call we wait until a
570 frame comes available, then expand image into the given
571 buffer.
572 In contrast to the CPiA cam the Philips cams deliver a
573 constant stream, almost like a grabber card. Also,
574 we have separate buffers for the rawdata and the image,
575 meaning we can nearly always expand into the requested buffer.
576 */
577 PWC_DEBUG_READ("VIDIOCMCAPTURE done.\n");
578 break;
579 }
580
581 case VIDIOCSYNC:
582 {
583 /* The doc says: "Whenever a buffer is used it should
584 call VIDIOCSYNC to free this frame up and continue."
585
586 The only odd thing about this whole procedure is
587 that MCAPTURE flags the buffer as "in use", and
588 SYNC immediately unmarks it, while it isn't
589 after SYNC that you know that the buffer actually
590 got filled! So you better not start a CAPTURE in
591 the same frame immediately (use double buffering).
592 This is not a problem for this cam, since it has
593 extra intermediate buffers, but a hardware
594 grabber card will then overwrite the buffer
595 you're working on.
596 */
597 int *mbuf = arg;
598 int ret;
599
600 PWC_DEBUG_READ("VIDIOCSYNC called (%d).\n", *mbuf);
601
602 /* bounds check */
603 if (*mbuf < 0 || *mbuf >= pwc_mbufs)
604 return -EINVAL;
605 /* check if this buffer was requested anyway */
606 if (pdev->image_used[*mbuf] == 0)
607 return -EINVAL;
608
609 /* Add ourselves to the frame wait-queue.
610
611 FIXME: needs auditing for safety.
612 QUESTION: In what respect? I think that using the
613 frameq is safe now.
614 */
615 add_wait_queue(&pdev->frameq, &wait);
616 while (pdev->full_frames == NULL) {
617 /* Check for unplugged/etc. here */
618 if (pdev->error_status) {
619 remove_wait_queue(&pdev->frameq, &wait);
620 set_current_state(TASK_RUNNING);
621 return -pdev->error_status;
622 }
623
624 if (signal_pending(current)) {
625 remove_wait_queue(&pdev->frameq, &wait);
626 set_current_state(TASK_RUNNING);
627 return -ERESTARTSYS;
628 }
629 schedule();
630 set_current_state(TASK_INTERRUPTIBLE);
631 }
632 remove_wait_queue(&pdev->frameq, &wait);
633 set_current_state(TASK_RUNNING);
634
635 /* The frame is ready. Expand in the image buffer
636 requested by the user. I don't care if you
637 mmap() 5 buffers and request data in this order:
638 buffer 4 2 3 0 1 2 3 0 4 3 1 . . .
639 Grabber hardware may not be so forgiving.
640 */
641 PWC_DEBUG_READ("VIDIOCSYNC: frame ready.\n");
642 pdev->fill_image = *mbuf; /* tell in which buffer we want the image to be expanded */
643 /* Decompress, etc */
644 ret = pwc_handle_frame(pdev);
645 pdev->image_used[*mbuf] = 0;
646 if (ret)
647 return -EFAULT;
648 break;
649 }
650
651 case VIDIOCGAUDIO:
652 {
653 struct video_audio *v = arg;
654
655 strcpy(v->name, "Microphone");
656 v->audio = -1; /* unknown audio minor */
657 v->flags = 0;
658 v->mode = VIDEO_SOUND_MONO;
659 v->volume = 0;
660 v->bass = 0;
661 v->treble = 0;
662 v->balance = 0x8000;
663 v->step = 1;
664 break;
665 }
666
667 case VIDIOCSAUDIO:
668 {
669 /* Dummy: nothing can be set */
670 break;
671 }
672
673 case VIDIOCGUNIT:
674 {
675 struct video_unit *vu = arg;
676
677 vu->video = pdev->vdev->minor & 0x3F;
678 vu->audio = -1; /* not known yet */
679 vu->vbi = -1;
680 vu->radio = -1;
681 vu->teletext = -1;
682 break;
683 }
684
685 /* V4L2 Layer */
686 case VIDIOC_QUERYCAP:
687 {
688 struct v4l2_capability *cap = arg;
689
690 PWC_DEBUG_IOCTL("ioctl(VIDIOC_QUERYCAP) This application "\
691 "try to use the v4l2 layer\n");
692 strcpy(cap->driver,PWC_NAME);
693 strlcpy(cap->card, vdev->name, sizeof(cap->card));
694 usb_make_path(pdev->udev,cap->bus_info,sizeof(cap->bus_info));
695 cap->version = PWC_VERSION_CODE;
696 cap->capabilities =
697 V4L2_CAP_VIDEO_CAPTURE |
698 V4L2_CAP_STREAMING |
699 V4L2_CAP_READWRITE;
700 return 0;
701 }
702
703 case VIDIOC_ENUMINPUT:
704 {
705 struct v4l2_input *i = arg;
706
707 if ( i->index ) /* Only one INPUT is supported */
708 return -EINVAL;
709
710 memset(i, 0, sizeof(struct v4l2_input));
711 strcpy(i->name, "usb");
712 return 0;
713 }
714
715 case VIDIOC_G_INPUT:
716 {
717 int *i = arg;
718 *i = 0; /* Only one INPUT is supported */
719 return 0;
720 }
721 case VIDIOC_S_INPUT:
722 {
723 int *i = arg;
724
725 if ( *i ) { /* Only one INPUT is supported */
726 PWC_DEBUG_IOCTL("Only one input source is"\
727 " supported with this webcam.\n");
728 return -EINVAL;
729 }
730 return 0;
731 }
732
733 /* TODO: */
734 case VIDIOC_QUERYCTRL:
735 {
736 struct v4l2_queryctrl *c = arg;
737 int i;
738
739 PWC_DEBUG_IOCTL("ioctl(VIDIOC_QUERYCTRL) query id=%d\n", c->id);
740 for (i=0; i<sizeof(pwc_controls)/sizeof(struct v4l2_queryctrl); i++) {
741 if (pwc_controls[i].id == c->id) {
742 PWC_DEBUG_IOCTL("ioctl(VIDIOC_QUERYCTRL) found\n");
743 memcpy(c,&pwc_controls[i],sizeof(struct v4l2_queryctrl));
744 return 0;
745 }
746 }
747 PWC_DEBUG_IOCTL("ioctl(VIDIOC_QUERYCTRL) not found\n");
748
749 return -EINVAL;
750 }
751 case VIDIOC_G_CTRL:
752 {
753 struct v4l2_control *c = arg;
754 int ret;
755
756 switch (c->id)
757 {
758 case V4L2_CID_BRIGHTNESS:
759 c->value = pwc_get_brightness(pdev);
760 if (c->value<0)
761 return -EINVAL;
762 return 0;
763 case V4L2_CID_CONTRAST:
764 c->value = pwc_get_contrast(pdev);
765 if (c->value<0)
766 return -EINVAL;
767 return 0;
768 case V4L2_CID_SATURATION:
769 ret = pwc_get_saturation(pdev, &c->value);
770 if (ret<0)
771 return -EINVAL;
772 return 0;
773 case V4L2_CID_GAMMA:
774 c->value = pwc_get_gamma(pdev);
775 if (c->value<0)
776 return -EINVAL;
777 return 0;
778 case V4L2_CID_RED_BALANCE:
779 ret = pwc_get_red_gain(pdev, &c->value);
780 if (ret<0)
781 return -EINVAL;
782 c->value >>= 8;
783 return 0;
784 case V4L2_CID_BLUE_BALANCE:
785 ret = pwc_get_blue_gain(pdev, &c->value);
786 if (ret<0)
787 return -EINVAL;
788 c->value >>= 8;
789 return 0;
790 case V4L2_CID_AUTO_WHITE_BALANCE:
791 ret = pwc_get_awb(pdev);
792 if (ret<0)
793 return -EINVAL;
794 c->value = (ret == PWC_WB_MANUAL)?0:1;
795 return 0;
796 case V4L2_CID_GAIN:
797 ret = pwc_get_agc(pdev, &c->value);
798 if (ret<0)
799 return -EINVAL;
800 c->value >>= 8;
801 return 0;
802 case V4L2_CID_AUTOGAIN:
803 ret = pwc_get_agc(pdev, &c->value);
804 if (ret<0)
805 return -EINVAL;
806 c->value = (c->value < 0)?1:0;
807 return 0;
808 case V4L2_CID_EXPOSURE:
809 ret = pwc_get_shutter_speed(pdev, &c->value);
810 if (ret<0)
811 return -EINVAL;
812 return 0;
813 case V4L2_CID_PRIVATE_COLOUR_MODE:
814 ret = pwc_get_colour_mode(pdev, &c->value);
815 if (ret < 0)
816 return -EINVAL;
817 return 0;
818 case V4L2_CID_PRIVATE_AUTOCONTOUR:
819 ret = pwc_get_contour(pdev, &c->value);
820 if (ret < 0)
821 return -EINVAL;
822 c->value=(c->value == -1?1:0);
823 return 0;
824 case V4L2_CID_PRIVATE_CONTOUR:
825 ret = pwc_get_contour(pdev, &c->value);
826 if (ret < 0)
827 return -EINVAL;
828 c->value >>= 10;
829 return 0;
830 case V4L2_CID_PRIVATE_BACKLIGHT:
831 ret = pwc_get_backlight(pdev, &c->value);
832 if (ret < 0)
833 return -EINVAL;
834 return 0;
835 case V4L2_CID_PRIVATE_FLICKERLESS:
836 ret = pwc_get_flicker(pdev, &c->value);
837 if (ret < 0)
838 return -EINVAL;
839 c->value=(c->value?1:0);
840 return 0;
841 case V4L2_CID_PRIVATE_NOISE_REDUCTION:
842 ret = pwc_get_dynamic_noise(pdev, &c->value);
843 if (ret < 0)
844 return -EINVAL;
845 return 0;
846
847 case V4L2_CID_PRIVATE_SAVE_USER:
848 case V4L2_CID_PRIVATE_RESTORE_USER:
849 case V4L2_CID_PRIVATE_RESTORE_FACTORY:
850 return -EINVAL;
851 }
852 return -EINVAL;
853 }
854 case VIDIOC_S_CTRL:
855 {
856 struct v4l2_control *c = arg;
857 int ret;
858
859 switch (c->id)
860 {
861 case V4L2_CID_BRIGHTNESS:
862 c->value <<= 9;
863 ret = pwc_set_brightness(pdev, c->value);
864 if (ret<0)
865 return -EINVAL;
866 return 0;
867 case V4L2_CID_CONTRAST:
868 c->value <<= 10;
869 ret = pwc_set_contrast(pdev, c->value);
870 if (ret<0)
871 return -EINVAL;
872 return 0;
873 case V4L2_CID_SATURATION:
874 ret = pwc_set_saturation(pdev, c->value);
875 if (ret<0)
876 return -EINVAL;
877 return 0;
878 case V4L2_CID_GAMMA:
879 c->value <<= 11;
880 ret = pwc_set_gamma(pdev, c->value);
881 if (ret<0)
882 return -EINVAL;
883 return 0;
884 case V4L2_CID_RED_BALANCE:
885 c->value <<= 8;
886 ret = pwc_set_red_gain(pdev, c->value);
887 if (ret<0)
888 return -EINVAL;
889 return 0;
890 case V4L2_CID_BLUE_BALANCE:
891 c->value <<= 8;
892 ret = pwc_set_blue_gain(pdev, c->value);
893 if (ret<0)
894 return -EINVAL;
895 return 0;
896 case V4L2_CID_AUTO_WHITE_BALANCE:
897 c->value = (c->value == 0)?PWC_WB_MANUAL:PWC_WB_AUTO;
898 ret = pwc_set_awb(pdev, c->value);
899 if (ret<0)
900 return -EINVAL;
901 return 0;
902 case V4L2_CID_EXPOSURE:
903 c->value <<= 8;
904 ret = pwc_set_shutter_speed(pdev, c->value?0:1, c->value);
905 if (ret<0)
906 return -EINVAL;
907 return 0;
908 case V4L2_CID_AUTOGAIN:
909 /* autogain off means nothing without a gain */
910 if (c->value == 0)
911 return 0;
912 ret = pwc_set_agc(pdev, c->value, 0);
913 if (ret<0)
914 return -EINVAL;
915 return 0;
916 case V4L2_CID_GAIN:
917 c->value <<= 8;
918 ret = pwc_set_agc(pdev, 0, c->value);
919 if (ret<0)
920 return -EINVAL;
921 return 0;
922 case V4L2_CID_PRIVATE_SAVE_USER:
923 if (pwc_save_user(pdev))
924 return -EINVAL;
925 return 0;
926 case V4L2_CID_PRIVATE_RESTORE_USER:
927 if (pwc_restore_user(pdev))
928 return -EINVAL;
929 return 0;
930 case V4L2_CID_PRIVATE_RESTORE_FACTORY:
931 if (pwc_restore_factory(pdev))
932 return -EINVAL;
933 return 0;
934 case V4L2_CID_PRIVATE_COLOUR_MODE:
935 ret = pwc_set_colour_mode(pdev, c->value);
936 if (ret < 0)
937 return -EINVAL;
938 return 0;
939 case V4L2_CID_PRIVATE_AUTOCONTOUR:
940 c->value=(c->value == 1)?-1:0;
941 ret = pwc_set_contour(pdev, c->value);
942 if (ret < 0)
943 return -EINVAL;
944 return 0;
945 case V4L2_CID_PRIVATE_CONTOUR:
946 c->value <<= 10;
947 ret = pwc_set_contour(pdev, c->value);
948 if (ret < 0)
949 return -EINVAL;
950 return 0;
951 case V4L2_CID_PRIVATE_BACKLIGHT:
952 ret = pwc_set_backlight(pdev, c->value);
953 if (ret < 0)
954 return -EINVAL;
955 return 0;
956 case V4L2_CID_PRIVATE_FLICKERLESS:
957 ret = pwc_set_flicker(pdev, c->value);
958 if (ret < 0)
959 return -EINVAL;
960 case V4L2_CID_PRIVATE_NOISE_REDUCTION:
961 ret = pwc_set_dynamic_noise(pdev, c->value);
962 if (ret < 0)
963 return -EINVAL;
964 return 0;
965
966 }
967 return -EINVAL;
968 }
969
970 case VIDIOC_ENUM_FMT:
971 {
972 struct v4l2_fmtdesc *f = arg;
973 int index;
974
975 if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
976 return -EINVAL;
977
978 /* We only support two format: the raw format, and YUV */
979 index = f->index;
980 memset(f,0,sizeof(struct v4l2_fmtdesc));
981 f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
982 f->index = index;
983 switch(index)
984 {
985 case 0:
986 /* RAW format */
987 f->pixelformat = pdev->type<=646?V4L2_PIX_FMT_PWC1:V4L2_PIX_FMT_PWC2;
988 f->flags = V4L2_FMT_FLAG_COMPRESSED;
989 strlcpy(f->description,"Raw Philips Webcam",sizeof(f->description));
990 break;
991 case 1:
992 f->pixelformat = V4L2_PIX_FMT_YUV420;
993 strlcpy(f->description,"4:2:0, planar, Y-Cb-Cr",sizeof(f->description));
994 break;
995 default:
996 return -EINVAL;
997 }
998 return 0;
999 }
1000
1001 case VIDIOC_G_FMT:
1002 {
1003 struct v4l2_format *f = arg;
1004
1005 PWC_DEBUG_IOCTL("ioctl(VIDIOC_G_FMT) return size %dx%d\n",pdev->image.x,pdev->image.y);
1006 if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1007 return -EINVAL;
1008
1009 pwc_vidioc_fill_fmt(pdev, f);
1010
1011 return 0;
1012 }
1013
1014 case VIDIOC_TRY_FMT:
1015 return pwc_vidioc_try_fmt(pdev, arg);
1016
1017 case VIDIOC_S_FMT:
1018 return pwc_vidioc_set_fmt(pdev, arg);
1019
1020 case VIDIOC_G_STD:
1021 {
1022 v4l2_std_id *std = arg;
1023 *std = V4L2_STD_UNKNOWN;
1024 return 0;
1025 }
1026
1027 case VIDIOC_S_STD:
1028 {
1029 v4l2_std_id *std = arg;
1030 if (*std != V4L2_STD_UNKNOWN)
1031 return -EINVAL;
1032 return 0;
1033 }
1034
1035 case VIDIOC_ENUMSTD:
1036 {
1037 struct v4l2_standard *std = arg;
1038 if (std->index != 0)
1039 return -EINVAL;
1040 std->id = V4L2_STD_UNKNOWN;
1041 strncpy(std->name, "webcam", sizeof(std->name));
1042 return 0;
1043 }
1044
1045 case VIDIOC_REQBUFS:
1046 {
1047 struct v4l2_requestbuffers *rb = arg;
1048 int nbuffers;
1049
1050 PWC_DEBUG_IOCTL("ioctl(VIDIOC_REQBUFS) count=%d\n",rb->count);
1051 if (rb->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1052 return -EINVAL;
1053 if (rb->memory != V4L2_MEMORY_MMAP)
1054 return -EINVAL;
1055
1056 nbuffers = rb->count;
1057 if (nbuffers < 2)
1058 nbuffers = 2;
1059 else if (nbuffers > pwc_mbufs)
1060 nbuffers = pwc_mbufs;
1061 /* Force to use our # of buffers */
1062 rb->count = pwc_mbufs;
1063 return 0;
1064 }
1065
1066 case VIDIOC_QUERYBUF:
1067 {
1068 struct v4l2_buffer *buf = arg;
1069 int index;
1070
1071 PWC_DEBUG_IOCTL("ioctl(VIDIOC_QUERYBUF) index=%d\n",buf->index);
1072 if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
1073 PWC_DEBUG_IOCTL("ioctl(VIDIOC_QUERYBUF) Bad type\n");
1074 return -EINVAL;
1075 }
1076 if (buf->memory != V4L2_MEMORY_MMAP) {
1077 PWC_DEBUG_IOCTL("ioctl(VIDIOC_QUERYBUF) Bad memory type\n");
1078 return -EINVAL;
1079 }
1080 index = buf->index;
1081 if (index < 0 || index >= pwc_mbufs) {
1082 PWC_DEBUG_IOCTL("ioctl(VIDIOC_QUERYBUF) Bad index %d\n", buf->index);
1083 return -EINVAL;
1084 }
1085
1086 memset(buf, 0, sizeof(struct v4l2_buffer));
1087 buf->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1088 buf->index = index;
1089 buf->m.offset = index * pdev->len_per_image;
1090 if (pdev->vpalette == VIDEO_PALETTE_RAW)
1091 buf->bytesused = pdev->frame_size + sizeof(struct pwc_raw_frame);
1092 else
1093 buf->bytesused = pdev->view.size;
1094 buf->field = V4L2_FIELD_NONE;
1095 buf->memory = V4L2_MEMORY_MMAP;
1096 //buf->flags = V4L2_BUF_FLAG_MAPPED;
1097 buf->length = pdev->len_per_image;
1098
1099 PWC_DEBUG_READ("VIDIOC_QUERYBUF: index=%d\n",buf->index);
1100 PWC_DEBUG_READ("VIDIOC_QUERYBUF: m.offset=%d\n",buf->m.offset);
1101 PWC_DEBUG_READ("VIDIOC_QUERYBUF: bytesused=%d\n",buf->bytesused);
1102
1103 return 0;
1104 }
1105
1106 case VIDIOC_QBUF:
1107 {
1108 struct v4l2_buffer *buf = arg;
1109
1110 PWC_DEBUG_IOCTL("ioctl(VIDIOC_QBUF) index=%d\n",buf->index);
1111 if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1112 return -EINVAL;
1113 if (buf->memory != V4L2_MEMORY_MMAP)
1114 return -EINVAL;
1115 if (buf->index < 0 || buf->index >= pwc_mbufs)
1116 return -EINVAL;
1117
1118 buf->flags |= V4L2_BUF_FLAG_QUEUED;
1119 buf->flags &= ~V4L2_BUF_FLAG_DONE;
1120
1121 return 0;
1122 }
1123
1124 case VIDIOC_DQBUF:
1125 {
1126 struct v4l2_buffer *buf = arg;
1127 int ret;
1128
1129 PWC_DEBUG_IOCTL("ioctl(VIDIOC_DQBUF)\n");
1130
1131 if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1132 return -EINVAL;
1133
1134 /* Add ourselves to the frame wait-queue.
1135
1136 FIXME: needs auditing for safety.
1137 QUESTION: In what respect? I think that using the
1138 frameq is safe now.
1139 */
1140 add_wait_queue(&pdev->frameq, &wait);
1141 while (pdev->full_frames == NULL) {
1142 if (pdev->error_status) {
1143 remove_wait_queue(&pdev->frameq, &wait);
1144 set_current_state(TASK_RUNNING);
1145 return -pdev->error_status;
1146 }
1147
1148 if (signal_pending(current)) {
1149 remove_wait_queue(&pdev->frameq, &wait);
1150 set_current_state(TASK_RUNNING);
1151 return -ERESTARTSYS;
1152 }
1153 schedule();
1154 set_current_state(TASK_INTERRUPTIBLE);
1155 }
1156 remove_wait_queue(&pdev->frameq, &wait);
1157 set_current_state(TASK_RUNNING);
1158
1159 PWC_DEBUG_IOCTL("VIDIOC_DQBUF: frame ready.\n");
1160 /* Decompress data in pdev->images[pdev->fill_image] */
1161 ret = pwc_handle_frame(pdev);
1162 if (ret)
1163 return -EFAULT;
1164 PWC_DEBUG_IOCTL("VIDIOC_DQBUF: after pwc_handle_frame\n");
1165
1166 buf->index = pdev->fill_image;
1167 if (pdev->vpalette == VIDEO_PALETTE_RAW)
1168 buf->bytesused = pdev->frame_size + sizeof(struct pwc_raw_frame);
1169 else
1170 buf->bytesused = pdev->view.size;
1171 buf->flags = V4L2_BUF_FLAG_MAPPED;
1172 buf->field = V4L2_FIELD_NONE;
1173 do_gettimeofday(&buf->timestamp);
1174 buf->sequence = 0;
1175 buf->memory = V4L2_MEMORY_MMAP;
1176 buf->m.offset = pdev->fill_image * pdev->len_per_image;
1177 buf->length = buf->bytesused;
1178 pwc_next_image(pdev);
1179
1180 PWC_DEBUG_IOCTL("VIDIOC_DQBUF: buf->index=%d\n",buf->index);
1181 PWC_DEBUG_IOCTL("VIDIOC_DQBUF: buf->length=%d\n",buf->length);
1182 PWC_DEBUG_IOCTL("VIDIOC_DQBUF: m.offset=%d\n",buf->m.offset);
1183 PWC_DEBUG_IOCTL("VIDIOC_DQBUF: bytesused=%d\n",buf->bytesused);
1184 PWC_DEBUG_IOCTL("VIDIOC_DQBUF: leaving\n");
1185 return 0;
1186
1187 }
1188
1189 case VIDIOC_STREAMON:
1190 {
1191 /* WARNING: pwc_try_video_mode() called pwc_isoc_init */
1192 pwc_isoc_init(pdev);
1193 return 0;
1194 }
1195
1196 case VIDIOC_STREAMOFF:
1197 {
1198 pwc_isoc_cleanup(pdev);
1199 return 0;
1200 }
1201
1202 default:
1203 return pwc_ioctl(pdev, cmd, arg);
1204 } /* ..switch */
1205 return 0;
1206}
1207
1208/* 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
index 1b0ee0ced0ed..1fd8c34d1181 100644
--- a/drivers/media/video/pwc/pwc.h
+++ b/drivers/media/video/pwc/pwc.h
@@ -1,5 +1,5 @@
1/* (C) 1999-2003 Nemosoft Unv. 1/* (C) 1999-2003 Nemosoft Unv.
2 (C) 2004 Luc Saillard (luc@saillard.org) 2 (C) 2004-2006 Luc Saillard (luc@saillard.org)
3 3
4 NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx 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. 5 driver and thus may have bugs that are not present in the original version.
@@ -29,51 +29,87 @@
29#include <linux/module.h> 29#include <linux/module.h>
30#include <linux/usb.h> 30#include <linux/usb.h>
31#include <linux/spinlock.h> 31#include <linux/spinlock.h>
32#include <linux/videodev.h>
33#include <linux/wait.h> 32#include <linux/wait.h>
34#include <linux/smp_lock.h> 33#include <linux/smp_lock.h>
34#include <linux/version.h>
35#include <asm/semaphore.h> 35#include <asm/semaphore.h>
36#include <asm/errno.h> 36#include <asm/errno.h>
37#include <linux/videodev.h>
38#include <linux/videodev2.h>
37 39
38#include "pwc-uncompress.h" 40#include "pwc-uncompress.h"
39#include "pwc-ioctl.h" 41#include <media/pwc-ioctl.h>
40
41/* Defines and structures for the Philips webcam */
42/* Used for checking memory corruption/pointer validation */
43#define PWC_MAGIC 0x89DC10ABUL
44#undef PWC_MAGIC
45 42
46/* Turn some debugging options on/off */ 43/* Turn some debugging options on/off */
47#define PWC_DEBUG 0 44#ifndef CONFIG_PWC_DEBUG
45#define CONFIG_PWC_DEBUG 1
46#endif
47
48/* Version block */
49#define PWC_MAJOR 10
50#define PWC_MINOR 0
51#define PWC_EXTRAMINOR 12
52#define PWC_VERSION_CODE KERNEL_VERSION(PWC_MAJOR,PWC_MINOR,PWC_EXTRAMINOR)
53#define PWC_VERSION "10.0.12"
54#define PWC_NAME "pwc"
55#define PFX PWC_NAME ": "
56
48 57
49/* Trace certain actions in the driver */ 58/* Trace certain actions in the driver */
50#define TRACE_MODULE 0x0001 59#define PWC_DEBUG_LEVEL_MODULE (1<<0)
51#define TRACE_PROBE 0x0002 60#define PWC_DEBUG_LEVEL_PROBE (1<<1)
52#define TRACE_OPEN 0x0004 61#define PWC_DEBUG_LEVEL_OPEN (1<<2)
53#define TRACE_READ 0x0008 62#define PWC_DEBUG_LEVEL_READ (1<<3)
54#define TRACE_MEMORY 0x0010 63#define PWC_DEBUG_LEVEL_MEMORY (1<<4)
55#define TRACE_FLOW 0x0020 64#define PWC_DEBUG_LEVEL_FLOW (1<<5)
56#define TRACE_SIZE 0x0040 65#define PWC_DEBUG_LEVEL_SIZE (1<<6)
57#define TRACE_PWCX 0x0080 66#define PWC_DEBUG_LEVEL_IOCTL (1<<7)
58#define TRACE_SEQUENCE 0x1000 67#define PWC_DEBUG_LEVEL_TRACE (1<<8)
59 68
60#define Trace(R, A...) if (pwc_trace & R) printk(KERN_DEBUG PWC_NAME " " A) 69#define PWC_DEBUG_MODULE(fmt, args...) PWC_DEBUG(MODULE, fmt, ##args)
61#define Debug(A...) printk(KERN_DEBUG PWC_NAME " " A) 70#define PWC_DEBUG_PROBE(fmt, args...) PWC_DEBUG(PROBE, fmt, ##args)
62#define Info(A...) printk(KERN_INFO PWC_NAME " " A) 71#define PWC_DEBUG_OPEN(fmt, args...) PWC_DEBUG(OPEN, fmt, ##args)
63#define Err(A...) printk(KERN_ERR PWC_NAME " " A) 72#define PWC_DEBUG_READ(fmt, args...) PWC_DEBUG(READ, fmt, ##args)
73#define PWC_DEBUG_MEMORY(fmt, args...) PWC_DEBUG(MEMORY, fmt, ##args)
74#define PWC_DEBUG_FLOW(fmt, args...) PWC_DEBUG(FLOW, fmt, ##args)
75#define PWC_DEBUG_SIZE(fmt, args...) PWC_DEBUG(SIZE, fmt, ##args)
76#define PWC_DEBUG_IOCTL(fmt, args...) PWC_DEBUG(IOCTL, fmt, ##args)
77#define PWC_DEBUG_TRACE(fmt, args...) PWC_DEBUG(TRACE, fmt, ##args)
78
79
80#if CONFIG_PWC_DEBUG
81
82#define PWC_DEBUG_LEVEL (PWC_DEBUG_LEVEL_MODULE)
83
84#define PWC_DEBUG(level, fmt, args...) do {\
85 if ((PWC_DEBUG_LEVEL_ ##level) & pwc_trace) \
86 printk(KERN_DEBUG PFX fmt, ##args); \
87 } while(0)
88
89#define PWC_ERROR(fmt, args...) printk(KERN_ERR PFX fmt, ##args)
90#define PWC_WARNING(fmt, args...) printk(KERN_WARNING PFX fmt, ##args)
91#define PWC_INFO(fmt, args...) printk(KERN_INFO PFX fmt, ##args)
92#define PWC_TRACE(fmt, args...) PWC_DEBUG(TRACE, fmt, ##args)
93
94#else /* if ! CONFIG_PWC_DEBUG */
95
96#define PWC_ERROR(fmt, args...) printk(KERN_ERR PFX fmt, ##args)
97#define PWC_WARNING(fmt, args...) printk(KERN_WARNING PFX fmt, ##args)
98#define PWC_INFO(fmt, args...) printk(KERN_INFO PFX fmt, ##args)
99#define PWC_TRACE(fmt, args...) do { } while(0)
100#define PWC_DEBUG(level, fmt, args...) do { } while(0)
101
102#define pwc_trace 0
64 103
104#endif
65 105
66/* Defines for ToUCam cameras */ 106/* Defines for ToUCam cameras */
67#define TOUCAM_HEADER_SIZE 8 107#define TOUCAM_HEADER_SIZE 8
68#define TOUCAM_TRAILER_SIZE 4 108#define TOUCAM_TRAILER_SIZE 4
69 109
70#define FEATURE_MOTOR_PANTILT 0x0001 110#define FEATURE_MOTOR_PANTILT 0x0001
71 111#define FEATURE_CODEC1 0x0002
72/* Version block */ 112#define FEATURE_CODEC2 0x0004
73#define PWC_MAJOR 9
74#define PWC_MINOR 0
75#define PWC_VERSION "9.0.2-unofficial"
76#define PWC_NAME "pwc"
77 113
78/* Turn certain features on/off */ 114/* Turn certain features on/off */
79#define PWC_INT_PIPE 0 115#define PWC_INT_PIPE 0
@@ -95,6 +131,18 @@
95/* Absolute maximum number of buffers available for mmap() */ 131/* Absolute maximum number of buffers available for mmap() */
96#define MAX_IMAGES 10 132#define MAX_IMAGES 10
97 133
134/* Some macros to quickly find the type of a webcam */
135#define DEVICE_USE_CODEC1(x) ((x)<675)
136#define DEVICE_USE_CODEC2(x) ((x)>=675 && (x)<700)
137#define DEVICE_USE_CODEC3(x) ((x)>=700)
138#define DEVICE_USE_CODEC23(x) ((x)>=675)
139
140
141#ifndef V4L2_PIX_FMT_PWC1
142#define V4L2_PIX_FMT_PWC1 v4l2_fourcc('P','W','C','1')
143#define V4L2_PIX_FMT_PWC2 v4l2_fourcc('P','W','C','2')
144#endif
145
98/* The following structures were based on cpia.h. Why reinvent the wheel? :-) */ 146/* The following structures were based on cpia.h. Why reinvent the wheel? :-) */
99struct pwc_iso_buf 147struct pwc_iso_buf
100{ 148{
@@ -110,17 +158,19 @@ struct pwc_frame_buf
110 void *data; 158 void *data;
111 volatile int filled; /* number of bytes filled */ 159 volatile int filled; /* number of bytes filled */
112 struct pwc_frame_buf *next; /* list */ 160 struct pwc_frame_buf *next; /* list */
113#if PWC_DEBUG 161};
114 int sequence; /* Sequence number */ 162
115#endif 163/* additionnal informations used when dealing image between kernel and userland */
164struct pwc_imgbuf
165{
166 unsigned long offset; /* offset of this buffer in the big array of image_data */
167 int vma_use_count; /* count the number of time this memory is mapped */
116}; 168};
117 169
118struct pwc_device 170struct pwc_device
119{ 171{
120 struct video_device *vdev; 172 struct video_device *vdev;
121#ifdef PWC_MAGIC 173
122 int magic;
123#endif
124 /* Pointer to our usb_device */ 174 /* Pointer to our usb_device */
125 struct usb_device *udev; 175 struct usb_device *udev;
126 176
@@ -177,12 +227,8 @@ struct pwc_device
177 int frame_size; 227 int frame_size;
178 int frame_total_size; /* including header & trailer */ 228 int frame_total_size; /* including header & trailer */
179 int drop_frames; 229 int drop_frames;
180#if PWC_DEBUG
181 int sequence; /* Debugging aid */
182#endif
183 230
184 /* 3: decompression */ 231 /* 3: decompression */
185 struct pwc_decompressor *decompressor; /* function block with decompression routines */
186 void *decompress_data; /* private data for decompression engine */ 232 void *decompress_data; /* private data for decompression engine */
187 233
188 /* 4: image */ 234 /* 4: image */
@@ -198,7 +244,7 @@ struct pwc_device
198 struct pwc_coord offset; /* offset within the viewport */ 244 struct pwc_coord offset; /* offset within the viewport */
199 245
200 void *image_data; /* total buffer, which is subdivided into ... */ 246 void *image_data; /* total buffer, which is subdivided into ... */
201 void *image_ptr[MAX_IMAGES]; /* ...several images... */ 247 struct pwc_imgbuf images[MAX_IMAGES];/* ...several images... */
202 int fill_image; /* ...which are rotated. */ 248 int fill_image; /* ...which are rotated. */
203 int len_per_image; /* length per image */ 249 int len_per_image; /* length per image */
204 int image_read_pos; /* In case we read data in pieces, keep track of were we are in the imagebuffer */ 250 int image_read_pos; /* In case we read data in pieces, keep track of were we are in the imagebuffer */
@@ -211,6 +257,7 @@ struct pwc_device
211 struct pwc_mpt_range angle_range; 257 struct pwc_mpt_range angle_range;
212 int pan_angle; /* in degrees * 100 */ 258 int pan_angle; /* in degrees * 100 */
213 int tilt_angle; /* absolute angle; 0,0 is home position */ 259 int tilt_angle; /* absolute angle; 0,0 is home position */
260 int snapshot_button_status; /* set to 1 when the user push the button, reset to 0 when this value is read */
214 261
215 /*** Misc. data ***/ 262 /*** Misc. data ***/
216 wait_queue_head_t frameq; /* When waiting for a frame to finish... */ 263 wait_queue_head_t frameq; /* When waiting for a frame to finish... */
@@ -219,20 +266,27 @@ struct pwc_device
219#endif 266#endif
220}; 267};
221 268
222
223#ifdef __cplusplus 269#ifdef __cplusplus
224extern "C" { 270extern "C" {
225#endif 271#endif
226 272
227/* Global variable */ 273/* Global variables */
274#if CONFIG_PWC_DEBUG
228extern int pwc_trace; 275extern int pwc_trace;
276#endif
277extern int pwc_preferred_compression;
278extern int pwc_mbufs;
229 279
230/** functions in pwc-if.c */ 280/** functions in pwc-if.c */
231int pwc_try_video_mode(struct pwc_device *pdev, int width, int height, int new_fps, int new_compression, int new_snapshot); 281int pwc_try_video_mode(struct pwc_device *pdev, int width, int height, int new_fps, int new_compression, int new_snapshot);
282int pwc_handle_frame(struct pwc_device *pdev);
283void pwc_next_image(struct pwc_device *pdev);
284int pwc_isoc_init(struct pwc_device *pdev);
285void pwc_isoc_cleanup(struct pwc_device *pdev);
232 286
233/** Functions in pwc-misc.c */ 287/** Functions in pwc-misc.c */
234/* sizes in pixels */ 288/* sizes in pixels */
235extern struct pwc_coord pwc_image_sizes[PSZ_MAX]; 289extern const struct pwc_coord pwc_image_sizes[PSZ_MAX];
236 290
237int pwc_decode_size(struct pwc_device *pdev, int width, int height); 291int pwc_decode_size(struct pwc_device *pdev, int width, int height);
238void pwc_construct(struct pwc_device *pdev); 292void pwc_construct(struct pwc_device *pdev);
@@ -240,6 +294,9 @@ void pwc_construct(struct pwc_device *pdev);
240/** Functions in pwc-ctrl.c */ 294/** Functions in pwc-ctrl.c */
241/* Request a certain video mode. Returns < 0 if not possible */ 295/* Request a certain video mode. Returns < 0 if not possible */
242extern int pwc_set_video_mode(struct pwc_device *pdev, int width, int height, int frames, int compression, int snapshot); 296extern int pwc_set_video_mode(struct pwc_device *pdev, int width, int height, int frames, int compression, int snapshot);
297/* Calculate the number of bytes per image (not frame) */
298extern int pwc_mpt_reset(struct pwc_device *pdev, int flags);
299extern int pwc_mpt_set_angle(struct pwc_device *pdev, int pan, int tilt);
243 300
244/* Various controls; should be obvious. Value 0..65535, or < 0 on error */ 301/* Various controls; should be obvious. Value 0..65535, or < 0 on error */
245extern int pwc_get_brightness(struct pwc_device *pdev); 302extern int pwc_get_brightness(struct pwc_device *pdev);
@@ -248,10 +305,37 @@ extern int pwc_get_contrast(struct pwc_device *pdev);
248extern int pwc_set_contrast(struct pwc_device *pdev, int value); 305extern int pwc_set_contrast(struct pwc_device *pdev, int value);
249extern int pwc_get_gamma(struct pwc_device *pdev); 306extern int pwc_get_gamma(struct pwc_device *pdev);
250extern int pwc_set_gamma(struct pwc_device *pdev, int value); 307extern int pwc_set_gamma(struct pwc_device *pdev, int value);
251extern int pwc_get_saturation(struct pwc_device *pdev); 308extern int pwc_get_saturation(struct pwc_device *pdev, int *value);
252extern int pwc_set_saturation(struct pwc_device *pdev, int value); 309extern int pwc_set_saturation(struct pwc_device *pdev, int value);
253extern int pwc_set_leds(struct pwc_device *pdev, int on_value, int off_value); 310extern int pwc_set_leds(struct pwc_device *pdev, int on_value, int off_value);
311extern int pwc_get_leds(struct pwc_device *pdev, int *on_value, int *off_value);
254extern int pwc_get_cmos_sensor(struct pwc_device *pdev, int *sensor); 312extern int pwc_get_cmos_sensor(struct pwc_device *pdev, int *sensor);
313extern int pwc_restore_user(struct pwc_device *pdev);
314extern int pwc_save_user(struct pwc_device *pdev);
315extern int pwc_restore_factory(struct pwc_device *pdev);
316
317/* exported for use by v4l2 controls */
318extern int pwc_get_red_gain(struct pwc_device *pdev, int *value);
319extern int pwc_set_red_gain(struct pwc_device *pdev, int value);
320extern int pwc_get_blue_gain(struct pwc_device *pdev, int *value);
321extern int pwc_set_blue_gain(struct pwc_device *pdev, int value);
322extern int pwc_get_awb(struct pwc_device *pdev);
323extern int pwc_set_awb(struct pwc_device *pdev, int mode);
324extern int pwc_set_agc(struct pwc_device *pdev, int mode, int value);
325extern int pwc_get_agc(struct pwc_device *pdev, int *value);
326extern int pwc_set_shutter_speed(struct pwc_device *pdev, int mode, int value);
327extern int pwc_get_shutter_speed(struct pwc_device *pdev, int *value);
328
329extern int pwc_set_colour_mode(struct pwc_device *pdev, int colour);
330extern int pwc_get_colour_mode(struct pwc_device *pdev, int *colour);
331extern int pwc_set_contour(struct pwc_device *pdev, int contour);
332extern int pwc_get_contour(struct pwc_device *pdev, int *contour);
333extern int pwc_set_backlight(struct pwc_device *pdev, int backlight);
334extern int pwc_get_backlight(struct pwc_device *pdev, int *backlight);
335extern int pwc_set_flicker(struct pwc_device *pdev, int flicker);
336extern int pwc_get_flicker(struct pwc_device *pdev, int *flicker);
337extern int pwc_set_dynamic_noise(struct pwc_device *pdev, int noise);
338extern int pwc_get_dynamic_noise(struct pwc_device *pdev, int *noise);
255 339
256/* Power down or up the camera; not supported by all models */ 340/* Power down or up the camera; not supported by all models */
257extern int pwc_camera_power(struct pwc_device *pdev, int power); 341extern int pwc_camera_power(struct pwc_device *pdev, int power);
@@ -259,6 +343,9 @@ extern int pwc_camera_power(struct pwc_device *pdev, int power);
259/* Private ioctl()s; see pwc-ioctl.h */ 343/* Private ioctl()s; see pwc-ioctl.h */
260extern int pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg); 344extern int pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg);
261 345
346/** Functions in pwc-v4l.c */
347extern int pwc_video_do_ioctl(struct inode *inode, struct file *file,
348 unsigned int cmd, void *arg);
262 349
263/** pwc-uncompress.c */ 350/** pwc-uncompress.c */
264/* Expand frame to image, possibly including decompression. Uses read_frame and fill_image */ 351/* Expand frame to image, possibly including decompression. Uses read_frame and fill_image */
@@ -270,3 +357,4 @@ extern int pwc_decompress(struct pwc_device *pdev);
270 357
271 358
272#endif 359#endif
360/* vim: set cino= formatoptions=croql cindent shiftwidth=8 tabstop=8: */
diff --git a/include/media/pwc-ioctl.h b/include/media/pwc-ioctl.h
new file mode 100644
index 000000000000..adc1254e887e
--- /dev/null
+++ b/include/media/pwc-ioctl.h
@@ -0,0 +1,325 @@
1#ifndef PWC_IOCTL_H
2#define PWC_IOCTL_H
3
4/* (C) 2001-2004 Nemosoft Unv.
5 (C) 2004-2006 Luc Saillard (luc@saillard.org)
6
7 NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx
8 driver and thus may have bugs that are not present in the original version.
9 Please send bug reports and support requests to <luc@saillard.org>.
10 The decompression routines have been implemented by reverse-engineering the
11 Nemosoft binary pwcx module. Caveat emptor.
12
13 This program is free software; you can redistribute it and/or modify
14 it under the terms of the GNU General Public License as published by
15 the Free Software Foundation; either version 2 of the License, or
16 (at your option) any later version.
17
18 This program is distributed in the hope that it will be useful,
19 but WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 GNU General Public License for more details.
22
23 You should have received a copy of the GNU General Public License
24 along with this program; if not, write to the Free Software
25 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26*/
27
28/* This is pwc-ioctl.h belonging to PWC 10.0.10
29 It contains structures and defines to communicate from user space
30 directly to the driver.
31 */
32
33/*
34 Changes
35 2001/08/03 Alvarado Added ioctl constants to access methods for
36 changing white balance and red/blue gains
37 2002/12/15 G. H. Fernandez-Toribio VIDIOCGREALSIZE
38 2003/12/13 Nemosft Unv. Some modifications to make interfacing to
39 PWCX easier
40 2006/01/01 Luc Saillard Add raw format definition
41 */
42
43/* These are private ioctl() commands, specific for the Philips webcams.
44 They contain functions not found in other webcams, and settings not
45 specified in the Video4Linux API.
46
47 The #define names are built up like follows:
48 VIDIOC VIDeo IOCtl prefix
49 PWC Philps WebCam
50 G optional: Get
51 S optional: Set
52 ... the function
53 */
54
55#include <linux/types.h>
56#include <linux/version.h>
57
58
59 /* Enumeration of image sizes */
60#define PSZ_SQCIF 0x00
61#define PSZ_QSIF 0x01
62#define PSZ_QCIF 0x02
63#define PSZ_SIF 0x03
64#define PSZ_CIF 0x04
65#define PSZ_VGA 0x05
66#define PSZ_MAX 6
67
68
69/* The frame rate is encoded in the video_window.flags parameter using
70 the upper 16 bits, since some flags are defined nowadays. The following
71 defines provide a mask and shift to filter out this value.
72 This value can also be passing using the private flag when using v4l2 and
73 VIDIOC_S_FMT ioctl.
74
75 In 'Snapshot' mode the camera freezes its automatic exposure and colour
76 balance controls.
77 */
78#define PWC_FPS_SHIFT 16
79#define PWC_FPS_MASK 0x00FF0000
80#define PWC_FPS_FRMASK 0x003F0000
81#define PWC_FPS_SNAPSHOT 0x00400000
82#define PWC_QLT_MASK 0x03000000
83#define PWC_QLT_SHIFT 24
84
85
86/* structure for transferring x & y coordinates */
87struct pwc_coord
88{
89 int x, y; /* guess what */
90 int size; /* size, or offset */
91};
92
93
94/* Used with VIDIOCPWCPROBE */
95struct pwc_probe
96{
97 char name[32];
98 int type;
99};
100
101struct pwc_serial
102{
103 char serial[30]; /* String with serial number. Contains terminating 0 */
104};
105
106/* pwc_whitebalance.mode values */
107#define PWC_WB_INDOOR 0
108#define PWC_WB_OUTDOOR 1
109#define PWC_WB_FL 2
110#define PWC_WB_MANUAL 3
111#define PWC_WB_AUTO 4
112
113/* Used with VIDIOCPWC[SG]AWB (Auto White Balance).
114 Set mode to one of the PWC_WB_* values above.
115 *red and *blue are the respective gains of these colour components inside
116 the camera; range 0..65535
117 When 'mode' == PWC_WB_MANUAL, 'manual_red' and 'manual_blue' are set or read;
118 otherwise undefined.
119 'read_red' and 'read_blue' are read-only.
120*/
121struct pwc_whitebalance
122{
123 int mode;
124 int manual_red, manual_blue; /* R/W */
125 int read_red, read_blue; /* R/O */
126};
127
128/*
129 'control_speed' and 'control_delay' are used in automatic whitebalance mode,
130 and tell the camera how fast it should react to changes in lighting, and
131 with how much delay. Valid values are 0..65535.
132*/
133struct pwc_wb_speed
134{
135 int control_speed;
136 int control_delay;
137
138};
139
140/* Used with VIDIOCPWC[SG]LED */
141struct pwc_leds
142{
143 int led_on; /* Led on-time; range = 0..25000 */
144 int led_off; /* Led off-time; range = 0..25000 */
145};
146
147/* Image size (used with GREALSIZE) */
148struct pwc_imagesize
149{
150 int width;
151 int height;
152};
153
154/* Defines and structures for Motorized Pan & Tilt */
155#define PWC_MPT_PAN 0x01
156#define PWC_MPT_TILT 0x02
157#define PWC_MPT_TIMEOUT 0x04 /* for status */
158
159/* Set angles; when absolute != 0, the angle is absolute and the
160 driver calculates the relative offset for you. This can only
161 be used with VIDIOCPWCSANGLE; VIDIOCPWCGANGLE always returns
162 absolute angles.
163 */
164struct pwc_mpt_angles
165{
166 int absolute; /* write-only */
167 int pan; /* degrees * 100 */
168 int tilt; /* degress * 100 */
169};
170
171/* Range of angles of the camera, both horizontally and vertically.
172 */
173struct pwc_mpt_range
174{
175 int pan_min, pan_max; /* degrees * 100 */
176 int tilt_min, tilt_max;
177};
178
179struct pwc_mpt_status
180{
181 int status;
182 int time_pan;
183 int time_tilt;
184};
185
186
187/* This is used for out-of-kernel decompression. With it, you can get
188 all the necessary information to initialize and use the decompressor
189 routines in standalone applications.
190 */
191struct pwc_video_command
192{
193 int type; /* camera type (645, 675, 730, etc.) */
194 int release; /* release number */
195
196 int size; /* one of PSZ_* */
197 int alternate;
198 int command_len; /* length of USB video command */
199 unsigned char command_buf[13]; /* Actual USB video command */
200 int bandlength; /* >0 = compressed */
201 int frame_size; /* Size of one (un)compressed frame */
202};
203
204/* Flags for PWCX subroutines. Not all modules honour all flags. */
205#define PWCX_FLAG_PLANAR 0x0001
206#define PWCX_FLAG_BAYER 0x0008
207
208
209/* IOCTL definitions */
210
211 /* Restore user settings */
212#define VIDIOCPWCRUSER _IO('v', 192)
213 /* Save user settings */
214#define VIDIOCPWCSUSER _IO('v', 193)
215 /* Restore factory settings */
216#define VIDIOCPWCFACTORY _IO('v', 194)
217
218 /* You can manipulate the compression factor. A compression preference of 0
219 means use uncompressed modes when available; 1 is low compression, 2 is
220 medium and 3 is high compression preferred. Of course, the higher the
221 compression, the lower the bandwidth used but more chance of artefacts
222 in the image. The driver automatically chooses a higher compression when
223 the preferred mode is not available.
224 */
225 /* Set preferred compression quality (0 = uncompressed, 3 = highest compression) */
226#define VIDIOCPWCSCQUAL _IOW('v', 195, int)
227 /* Get preferred compression quality */
228#define VIDIOCPWCGCQUAL _IOR('v', 195, int)
229
230
231/* Retrieve serial number of camera */
232#define VIDIOCPWCGSERIAL _IOR('v', 198, struct pwc_serial)
233
234 /* This is a probe function; since so many devices are supported, it
235 becomes difficult to include all the names in programs that want to
236 check for the enhanced Philips stuff. So in stead, try this PROBE;
237 it returns a structure with the original name, and the corresponding
238 Philips type.
239 To use, fill the structure with zeroes, call PROBE and if that succeeds,
240 compare the name with that returned from VIDIOCGCAP; they should be the
241 same. If so, you can be assured it is a Philips (OEM) cam and the type
242 is valid.
243 */
244#define VIDIOCPWCPROBE _IOR('v', 199, struct pwc_probe)
245
246 /* Set AGC (Automatic Gain Control); int < 0 = auto, 0..65535 = fixed */
247#define VIDIOCPWCSAGC _IOW('v', 200, int)
248 /* Get AGC; int < 0 = auto; >= 0 = fixed, range 0..65535 */
249#define VIDIOCPWCGAGC _IOR('v', 200, int)
250 /* Set shutter speed; int < 0 = auto; >= 0 = fixed, range 0..65535 */
251#define VIDIOCPWCSSHUTTER _IOW('v', 201, int)
252
253 /* Color compensation (Auto White Balance) */
254#define VIDIOCPWCSAWB _IOW('v', 202, struct pwc_whitebalance)
255#define VIDIOCPWCGAWB _IOR('v', 202, struct pwc_whitebalance)
256
257 /* Auto WB speed */
258#define VIDIOCPWCSAWBSPEED _IOW('v', 203, struct pwc_wb_speed)
259#define VIDIOCPWCGAWBSPEED _IOR('v', 203, struct pwc_wb_speed)
260
261 /* LEDs on/off/blink; int range 0..65535 */
262#define VIDIOCPWCSLED _IOW('v', 205, struct pwc_leds)
263#define VIDIOCPWCGLED _IOR('v', 205, struct pwc_leds)
264
265 /* Contour (sharpness); int < 0 = auto, 0..65536 = fixed */
266#define VIDIOCPWCSCONTOUR _IOW('v', 206, int)
267#define VIDIOCPWCGCONTOUR _IOR('v', 206, int)
268
269 /* Backlight compensation; 0 = off, otherwise on */
270#define VIDIOCPWCSBACKLIGHT _IOW('v', 207, int)
271#define VIDIOCPWCGBACKLIGHT _IOR('v', 207, int)
272
273 /* Flickerless mode; = 0 off, otherwise on */
274#define VIDIOCPWCSFLICKER _IOW('v', 208, int)
275#define VIDIOCPWCGFLICKER _IOR('v', 208, int)
276
277 /* Dynamic noise reduction; 0 off, 3 = high noise reduction */
278#define VIDIOCPWCSDYNNOISE _IOW('v', 209, int)
279#define VIDIOCPWCGDYNNOISE _IOR('v', 209, int)
280
281 /* Real image size as used by the camera; tells you whether or not there's a gray border around the image */
282#define VIDIOCPWCGREALSIZE _IOR('v', 210, struct pwc_imagesize)
283
284 /* Motorized pan & tilt functions */
285#define VIDIOCPWCMPTRESET _IOW('v', 211, int)
286#define VIDIOCPWCMPTGRANGE _IOR('v', 211, struct pwc_mpt_range)
287#define VIDIOCPWCMPTSANGLE _IOW('v', 212, struct pwc_mpt_angles)
288#define VIDIOCPWCMPTGANGLE _IOR('v', 212, struct pwc_mpt_angles)
289#define VIDIOCPWCMPTSTATUS _IOR('v', 213, struct pwc_mpt_status)
290
291 /* Get the USB set-video command; needed for initializing libpwcx */
292#define VIDIOCPWCGVIDCMD _IOR('v', 215, struct pwc_video_command)
293struct pwc_table_init_buffer {
294 int len;
295 char *buffer;
296
297};
298#define VIDIOCPWCGVIDTABLE _IOR('v', 216, struct pwc_table_init_buffer)
299
300/*
301 * This is private command used when communicating with v4l2.
302 * In the future all private ioctl will be remove/replace to
303 * use interface offer by v4l2.
304 */
305
306#define V4L2_CID_PRIVATE_SAVE_USER (V4L2_CID_PRIVATE_BASE + 0)
307#define V4L2_CID_PRIVATE_RESTORE_USER (V4L2_CID_PRIVATE_BASE + 1)
308#define V4L2_CID_PRIVATE_RESTORE_FACTORY (V4L2_CID_PRIVATE_BASE + 2)
309#define V4L2_CID_PRIVATE_COLOUR_MODE (V4L2_CID_PRIVATE_BASE + 3)
310#define V4L2_CID_PRIVATE_AUTOCONTOUR (V4L2_CID_PRIVATE_BASE + 4)
311#define V4L2_CID_PRIVATE_CONTOUR (V4L2_CID_PRIVATE_BASE + 5)
312#define V4L2_CID_PRIVATE_BACKLIGHT (V4L2_CID_PRIVATE_BASE + 6)
313#define V4L2_CID_PRIVATE_FLICKERLESS (V4L2_CID_PRIVATE_BASE + 7)
314#define V4L2_CID_PRIVATE_NOISE_REDUCTION (V4L2_CID_PRIVATE_BASE + 8)
315
316struct pwc_raw_frame {
317 __le16 type; /* type of the webcam */
318 __le16 vbandlength; /* Size of 4lines compressed (used by the decompressor) */
319 __u8 cmd[4]; /* the four byte of the command (in case of nala,
320 only the first 3 bytes is filled) */
321 __u8 rawframe[0]; /* frame_size = H/4*vbandlength */
322} __attribute__ ((packed));
323
324
325#endif