Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Luc Saillard and committed by
Mauro Carvalho Chehab
2b455db6 d9e12f25

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