aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video')
-rw-r--r--drivers/media/video/Kconfig232
-rw-r--r--drivers/media/video/Makefile19
-rw-r--r--drivers/media/video/dabfirmware.h1408
-rw-r--r--drivers/media/video/dabusb.c874
-rw-r--r--drivers/media/video/dabusb.h85
-rw-r--r--drivers/media/video/dsbr100.c429
-rw-r--r--drivers/media/video/et61x251/Makefile4
-rw-r--r--drivers/media/video/et61x251/et61x251.h234
-rw-r--r--drivers/media/video/et61x251/et61x251_core.c2630
-rw-r--r--drivers/media/video/et61x251/et61x251_sensor.h116
-rw-r--r--drivers/media/video/et61x251/et61x251_tas5130d1b.c141
-rw-r--r--drivers/media/video/ov511.c5932
-rw-r--r--drivers/media/video/ov511.h568
-rw-r--r--drivers/media/video/pwc/Makefile20
-rw-r--r--drivers/media/video/pwc/philips.txt236
-rw-r--r--drivers/media/video/pwc/pwc-ctrl.c1541
-rw-r--r--drivers/media/video/pwc/pwc-if.c2205
-rw-r--r--drivers/media/video/pwc/pwc-ioctl.h292
-rw-r--r--drivers/media/video/pwc/pwc-kiara.c318
-rw-r--r--drivers/media/video/pwc/pwc-kiara.h45
-rw-r--r--drivers/media/video/pwc/pwc-misc.c140
-rw-r--r--drivers/media/video/pwc/pwc-nala.h66
-rw-r--r--drivers/media/video/pwc/pwc-timon.c316
-rw-r--r--drivers/media/video/pwc/pwc-timon.h61
-rw-r--r--drivers/media/video/pwc/pwc-uncompress.c146
-rw-r--r--drivers/media/video/pwc/pwc-uncompress.h41
-rw-r--r--drivers/media/video/pwc/pwc.h272
-rw-r--r--drivers/media/video/se401.c1435
-rw-r--r--drivers/media/video/se401.h234
-rw-r--r--drivers/media/video/sn9c102/Makefile7
-rw-r--r--drivers/media/video/sn9c102/sn9c102.h218
-rw-r--r--drivers/media/video/sn9c102/sn9c102_core.c2919
-rw-r--r--drivers/media/video/sn9c102/sn9c102_hv7131d.c271
-rw-r--r--drivers/media/video/sn9c102/sn9c102_mi0343.c363
-rw-r--r--drivers/media/video/sn9c102/sn9c102_ov7630.c401
-rw-r--r--drivers/media/video/sn9c102/sn9c102_pas106b.c307
-rw-r--r--drivers/media/video/sn9c102/sn9c102_pas202bca.c238
-rw-r--r--drivers/media/video/sn9c102/sn9c102_pas202bcb.c293
-rw-r--r--drivers/media/video/sn9c102/sn9c102_sensor.h389
-rw-r--r--drivers/media/video/sn9c102/sn9c102_tas5110c1b.c159
-rw-r--r--drivers/media/video/sn9c102/sn9c102_tas5130d1b.c169
-rw-r--r--drivers/media/video/stv680.c1508
-rw-r--r--drivers/media/video/stv680.h227
-rw-r--r--drivers/media/video/usbvideo/Makefile4
-rw-r--r--drivers/media/video/usbvideo/ibmcam.c3932
-rw-r--r--drivers/media/video/usbvideo/konicawc.c978
-rw-r--r--drivers/media/video/usbvideo/ultracam.c679
-rw-r--r--drivers/media/video/usbvideo/usbvideo.c2190
-rw-r--r--drivers/media/video/usbvideo/usbvideo.h394
-rw-r--r--drivers/media/video/usbvideo/vicam.c1411
-rw-r--r--drivers/media/video/w9968cf.c3691
-rw-r--r--drivers/media/video/w9968cf.h330
-rw-r--r--drivers/media/video/w9968cf_decoder.h86
-rw-r--r--drivers/media/video/w9968cf_vpp.h40
-rw-r--r--drivers/media/video/zc0301/Makefile3
-rw-r--r--drivers/media/video/zc0301/zc0301.h192
-rw-r--r--drivers/media/video/zc0301/zc0301_core.c2055
-rw-r--r--drivers/media/video/zc0301/zc0301_pas202bcb.c361
-rw-r--r--drivers/media/video/zc0301/zc0301_sensor.h103
59 files changed, 43956 insertions, 2 deletions
diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig
index b3d3b22d3f78..1f8a46b5916e 100644
--- a/drivers/media/video/Kconfig
+++ b/drivers/media/video/Kconfig
@@ -291,8 +291,6 @@ config VIDEO_HEXIUM_GEMINI
291 291
292source "drivers/media/video/cx88/Kconfig" 292source "drivers/media/video/cx88/Kconfig"
293 293
294source "drivers/media/video/em28xx/Kconfig"
295
296config VIDEO_OVCAMCHIP 294config VIDEO_OVCAMCHIP
297 tristate "OmniVision Camera Chip support" 295 tristate "OmniVision Camera Chip support"
298 depends on VIDEO_DEV && I2C 296 depends on VIDEO_DEV && I2C
@@ -367,4 +365,234 @@ config VIDEO_SAA7127
367 To compile this driver as a module, choose M here: the 365 To compile this driver as a module, choose M here: the
368 module will be called saa7127 366 module will be called saa7127
369 367
368#
369# USB Multimedia device configuration
370#
371
372menu "V4L USB devices"
373 depends on USB && VIDEO_DEV
374
375source "drivers/media/video/em28xx/Kconfig"
376
377config USB_VICAM
378 tristate "USB 3com HomeConnect (aka vicam) support (EXPERIMENTAL)"
379 depends on USB && VIDEO_DEV && EXPERIMENTAL
380 ---help---
381 Say Y here if you have 3com homeconnect camera (vicam).
382
383 This driver uses the Video For Linux API. You must say Y or M to
384 "Video For Linux" (under Multimedia Devices) to use this driver.
385 Information on this API and pointers to "v4l" programs may be found
386 at <file:Documentation/video4linux/API.html>.
387
388 To compile this driver as a module, choose M here: the
389 module will be called vicam.
390
391config USB_DSBR
392 tristate "D-Link USB FM radio support (EXPERIMENTAL)"
393 depends on USB && VIDEO_DEV && EXPERIMENTAL
394 ---help---
395 Say Y here if you want to connect this type of radio to your
396 computer's USB port. Note that the audio is not digital, and
397 you must connect the line out connector to a sound card or a
398 set of speakers.
399
400 This driver uses the Video For Linux API. You must enable
401 (Y or M in config) Video For Linux (under Character Devices)
402 to use this driver. Information on this API and pointers to
403 "v4l" programs may be found at
404 <file:Documentation/video4linux/API.html>.
405
406 To compile this driver as a module, choose M here: the
407 module will be called dsbr100.
408
409config USB_ET61X251
410 tristate "USB ET61X[12]51 PC Camera Controller support"
411 depends on USB && VIDEO_DEV
412 ---help---
413 Say Y here if you want support for cameras based on Etoms ET61X151
414 or ET61X251 PC Camera Controllers.
415
416 See <file:Documentation/usb/et61x251.txt> for more informations.
417
418 This driver uses the Video For Linux API. You must say Y or M to
419 "Video For Linux" to use this driver.
420
421 To compile this driver as a module, choose M here: the
422 module will be called et61x251.
423
424config USB_IBMCAM
425 tristate "USB IBM (Xirlink) C-it Camera support"
426 depends on USB && VIDEO_DEV
427 ---help---
428 Say Y here if you want to connect a IBM "C-It" camera, also known as
429 "Xirlink PC Camera" to your computer's USB port. For more
430 information, read <file:Documentation/usb/ibmcam.txt>.
431
432 This driver uses the Video For Linux API. You must enable
433 (Y or M in config) Video For Linux (under Character Devices)
434 to use this driver. Information on this API and pointers to
435 "v4l" programs may be found at
436 <file:Documentation/video4linux/API.html>.
437
438 To compile this driver as a module, choose M here: the
439 module will be called ibmcam.
440
441 This camera has several configuration options which
442 can be specified when you load the module. Read
443 <file:Documentation/usb/ibmcam.txt> to learn more.
444
445config USB_KONICAWC
446 tristate "USB Konica Webcam support"
447 depends on USB && VIDEO_DEV
448 ---help---
449 Say Y here if you want support for webcams based on a Konica
450 chipset. This is known to work with the Intel YC76 webcam.
451
452 This driver uses the Video For Linux API. You must enable
453 (Y or M in config) Video For Linux (under Character Devices)
454 to use this driver. Information on this API and pointers to
455 "v4l" programs may be found at
456 <file:Documentation/video4linux/API.html>.
457
458 To compile this driver as a module, choose M here: the
459 module will be called konicawc.
460
461config USB_OV511
462 tristate "USB OV511 Camera support"
463 depends on USB && VIDEO_DEV
464 ---help---
465 Say Y here if you want to connect this type of camera to your
466 computer's USB port. See <file:Documentation/usb/ov511.txt> for more
467 information and for a list of supported cameras.
468
469 This driver uses the Video For Linux API. You must say Y or M to
470 "Video For Linux" (under Character Devices) to use this driver.
471 Information on this API and pointers to "v4l" programs may be found
472 at <file:Documentation/video4linux/API.html>.
473
474 To compile this driver as a module, choose M here: the
475 module will be called ov511.
476
477config USB_SE401
478 tristate "USB SE401 Camera support"
479 depends on USB && VIDEO_DEV
480 ---help---
481 Say Y here if you want to connect this type of camera to your
482 computer's USB port. See <file:Documentation/usb/se401.txt> for more
483 information and for a list of supported cameras.
484
485 This driver uses the Video For Linux API. You must say Y or M to
486 "Video For Linux" (under Multimedia Devices) to use this driver.
487 Information on this API and pointers to "v4l" programs may be found
488 at <file:Documentation/video4linux/API.html>.
489
490 To compile this driver as a module, choose M here: the
491 module will be called se401.
492
493config USB_SN9C102
494 tristate "USB SN9C10x PC Camera Controller support"
495 depends on USB && VIDEO_DEV
496 ---help---
497 Say Y here if you want support for cameras based on SONiX SN9C101,
498 SN9C102 or SN9C103 PC Camera Controllers.
499
500 See <file:Documentation/usb/sn9c102.txt> for more informations.
501
502 This driver uses the Video For Linux API. You must say Y or M to
503 "Video For Linux" to use this driver.
504
505 To compile this driver as a module, choose M here: the
506 module will be called sn9c102.
507
508config USB_STV680
509 tristate "USB STV680 (Pencam) Camera support"
510 depends on USB && VIDEO_DEV
511 ---help---
512 Say Y here if you want to connect this type of camera to your
513 computer's USB port. This includes the Pencam line of cameras.
514 See <file:Documentation/usb/stv680.txt> for more information and for
515 a list of supported cameras.
516
517 This driver uses the Video For Linux API. You must say Y or M to
518 "Video For Linux" (under Multimedia Devices) to use this driver.
519 Information on this API and pointers to "v4l" programs may be found
520 at <file:Documentation/video4linux/API.html>.
521
522 To compile this driver as a module, choose M here: the
523 module will be called stv680.
524
525config USB_W9968CF
526 tristate "USB W996[87]CF JPEG Dual Mode Camera support"
527 depends on USB && VIDEO_DEV && I2C && VIDEO_OVCAMCHIP
528 ---help---
529 Say Y here if you want support for cameras based on OV681 or
530 Winbond W9967CF/W9968CF JPEG USB Dual Mode Camera Chips.
531
532 This driver has an optional plugin, which is distributed as a
533 separate module only (released under GPL). It allows to use higher
534 resolutions and framerates, but cannot be included in the official
535 Linux kernel for performance purposes.
536
537 See <file:Documentation/usb/w9968cf.txt> for more informations.
538
539 This driver uses the Video For Linux and the I2C APIs. It needs the
540 OmniVision Camera Chip support as well. You must say Y or M to
541 "Video For Linux", "I2C Support" and "OmniVision Camera Chip
542 support" to use this driver.
543
544 To compile this driver as a module, choose M here: the
545 module will be called w9968cf.
546
547config USB_ZC0301
548 tristate "USB ZC0301 Image Processor and Control Chip support"
549 depends on USB && VIDEO_DEV
550 ---help---
551 Say Y here if you want support for cameras based on the ZC0301
552 Image Processor and Control Chip.
553
554 See <file:Documentation/usb/zc0301.txt> for more informations.
555
556 This driver uses the Video For Linux API. You must say Y or M to
557 "Video For Linux" to use this driver.
558
559 To compile this driver as a module, choose M here: the
560 module will be called zc0301.
561
562config USB_PWC
563 tristate "USB Philips Cameras"
564 depends on USB && VIDEO_DEV
565 ---help---
566 Say Y or M here if you want to use one of these Philips & OEM
567 webcams:
568 * Philips PCA645, PCA646
569 * Philips PCVC675, PCVC680, PCVC690
570 * Philips PCVC720/40, PCVC730, PCVC740, PCVC750
571 * Askey VC010
572 * Logitech QuickCam Pro 3000, 4000, 'Zoom', 'Notebook Pro'
573 and 'Orbit'/'Sphere'
574 * Samsung MPC-C10, MPC-C30
575 * Creative Webcam 5, Pro Ex
576 * SOTEC Afina Eye
577 * Visionite VCS-UC300, VCS-UM100
578
579 The PCA635, PCVC665 and PCVC720/20 are not supported by this driver
580 and never will be, but the 665 and 720/20 are supported by other
581 drivers.
582
583 See <file:Documentation/usb/philips.txt> for more information and
584 installation instructions.
585
586 The built-in microphone is enabled by selecting USB Audio support.
587
588 This driver uses the Video For Linux API. You must say Y or M to
589 "Video For Linux" (under Character Devices) to use this driver.
590 Information on this API and pointers to "v4l" programs may be found
591 at <file:Documentation/video4linux/API.html>.
592
593 To compile this driver as a module, choose M here: the
594 module will be called pwc.
595
596endmenu # V4L USB devices
597
370endmenu 598endmenu
diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile
index 1a56a2d9e294..1c0e72e5a593 100644
--- a/drivers/media/video/Makefile
+++ b/drivers/media/video/Makefile
@@ -65,4 +65,23 @@ obj-$(CONFIG_VIDEO_CX25840) += cx25840/
65obj-$(CONFIG_VIDEO_SAA711X) += saa7115.o 65obj-$(CONFIG_VIDEO_SAA711X) += saa7115.o
66obj-$(CONFIG_VIDEO_SAA7127) += saa7127.o 66obj-$(CONFIG_VIDEO_SAA7127) += saa7127.o
67 67
68et61x251-objs := et61x251_core.o et61x251_tas5130d1b.o
69zc0301-objs := zc0301_core.o zc0301_pas202bcb.o
70
71obj-$(CONFIG_USB_DABUSB) += dabusb.o
72obj-$(CONFIG_USB_DSBR) += dsbr100.o
73obj-$(CONFIG_USB_OV511) += ov511.o
74obj-$(CONFIG_USB_SE401) += se401.o
75obj-$(CONFIG_USB_STV680) += stv680.o
76obj-$(CONFIG_USB_W9968CF) += w9968cf.o
77
78obj-$(CONFIG_USB_SN9C102) += sn9c102/
79obj-$(CONFIG_USB_ET61X251) += et61x251/
80obj-$(CONFIG_USB_PWC) += pwc/
81obj-$(CONFIG_USB_ZC0301) += zc0301/
82
83obj-$(CONFIG_USB_IBMCAM) += usbvideo/
84obj-$(CONFIG_USB_KONICAWC) += usbvideo/
85obj-$(CONFIG_USB_VICAM) += usbvideo/
86
68EXTRA_CFLAGS += -I$(srctree)/drivers/media/dvb/dvb-core 87EXTRA_CFLAGS += -I$(srctree)/drivers/media/dvb/dvb-core
diff --git a/drivers/media/video/dabfirmware.h b/drivers/media/video/dabfirmware.h
new file mode 100644
index 000000000000..d14d803566a3
--- /dev/null
+++ b/drivers/media/video/dabfirmware.h
@@ -0,0 +1,1408 @@
1/*
2 * dabdata.h - dab usb firmware and bitstream data
3 */
4
5static INTEL_HEX_RECORD firmware[] = {
6
7{ 2, 0x0000, 0, {0x21,0x57} },
8{ 3, 0x0003, 0, {0x02,0x01,0x66} },
9{ 3, 0x000b, 0, {0x02,0x01,0x66} },
10{ 3, 0x0013, 0, {0x02,0x01,0x66} },
11{ 3, 0x001b, 0, {0x02,0x01,0x66} },
12{ 3, 0x0023, 0, {0x02,0x01,0x66} },
13{ 3, 0x002b, 0, {0x02,0x01,0x66} },
14{ 3, 0x0033, 0, {0x02,0x03,0x0f} },
15{ 3, 0x003b, 0, {0x02,0x01,0x66} },
16{ 3, 0x0043, 0, {0x02,0x01,0x00} },
17{ 3, 0x004b, 0, {0x02,0x01,0x66} },
18{ 3, 0x0053, 0, {0x02,0x01,0x66} },
19{ 3, 0x005b, 0, {0x02,0x04,0xbd} },
20{ 3, 0x0063, 0, {0x02,0x01,0x67} },
21{ 3, 0x0100, 0, {0x02,0x0c,0x5a} },
22{ 3, 0x0104, 0, {0x02,0x01,0xed} },
23{ 3, 0x0108, 0, {0x02,0x02,0x51} },
24{ 3, 0x010c, 0, {0x02,0x02,0x7c} },
25{ 3, 0x0110, 0, {0x02,0x02,0xe4} },
26{ 1, 0x0114, 0, {0x32} },
27{ 1, 0x0118, 0, {0x32} },
28{ 3, 0x011c, 0, {0x02,0x05,0xfd} },
29{ 3, 0x0120, 0, {0x02,0x00,0x00} },
30{ 3, 0x0124, 0, {0x02,0x00,0x00} },
31{ 3, 0x0128, 0, {0x02,0x04,0x3c} },
32{ 3, 0x012c, 0, {0x02,0x04,0x6a} },
33{ 3, 0x0130, 0, {0x02,0x00,0x00} },
34{ 3, 0x0134, 0, {0x02,0x00,0x00} },
35{ 3, 0x0138, 0, {0x02,0x00,0x00} },
36{ 3, 0x013c, 0, {0x02,0x00,0x00} },
37{ 3, 0x0140, 0, {0x02,0x00,0x00} },
38{ 3, 0x0144, 0, {0x02,0x00,0x00} },
39{ 3, 0x0148, 0, {0x02,0x00,0x00} },
40{ 3, 0x014c, 0, {0x02,0x00,0x00} },
41{ 3, 0x0150, 0, {0x02,0x00,0x00} },
42{ 3, 0x0154, 0, {0x02,0x00,0x00} },
43{ 10, 0x0157, 0, {0x75,0x81,0x7f,0xe5,0x82,0x60,0x03,0x02,0x01,0x61} },
44{ 5, 0x0161, 0, {0x12,0x07,0x6f,0x21,0x64} },
45{ 1, 0x0166, 0, {0x32} },
46{ 14, 0x0167, 0, {0xc0,0xd0,0xc0,0x86,0xc0,0x82,0xc0,0x83,0xc0,0xe0,0x90,0x7f,0x97,0xe0} },
47{ 14, 0x0175, 0, {0x44,0x80,0xf0,0x90,0x7f,0x69,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0} },
48{ 14, 0x0183, 0, {0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0} },
49{ 14, 0x0191, 0, {0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0x90,0x7f,0x97,0xe0} },
50{ 3, 0x019f, 0, {0x55,0x7f,0xf0} },
51{ 14, 0x01a2, 0, {0x90,0x7f,0x9a,0xe0,0x30,0xe4,0x23,0x90,0x7f,0x68,0xf0,0xf0,0xf0,0xf0} },
52{ 14, 0x01b0, 0, {0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0} },
53{ 14, 0x01be, 0, {0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0} },
54{ 14, 0x01cc, 0, {0xe5,0xd8,0xc2,0xe3,0xf5,0xd8,0xd0,0xe0,0xd0,0x83,0xd0,0x82,0xd0,0x86} },
55{ 3, 0x01da, 0, {0xd0,0xd0,0x32} },
56{ 8, 0x01dd, 0, {0x75,0x86,0x00,0x90,0xff,0xc3,0x7c,0x05} },
57{ 7, 0x01e5, 0, {0xa3,0xe5,0x82,0x45,0x83,0x70,0xf9} },
58{ 1, 0x01ec, 0, {0x22} },
59{ 14, 0x01ed, 0, {0xc0,0xe0,0xc0,0xf0,0xc0,0x82,0xc0,0x83,0xc0,0x02,0xc0,0x03,0xc0,0xd0} },
60{ 14, 0x01fb, 0, {0x75,0xd0,0x00,0xc0,0x86,0x75,0x86,0x00,0xe5,0x91,0xc2,0xe4,0xf5,0x91} },
61{ 13, 0x0209, 0, {0x90,0x88,0x00,0xe0,0xf5,0x41,0x90,0x7f,0xab,0x74,0x02,0xf0,0x90} },
62{ 9, 0x0216, 0, {0x7f,0xab,0x74,0x02,0xf0,0xe5,0x32,0x60,0x21} },
63{ 4, 0x021f, 0, {0x7a,0x00,0x7b,0x00} },
64{ 11, 0x0223, 0, {0xc3,0xea,0x94,0x18,0xeb,0x64,0x80,0x94,0x80,0x50,0x12} },
65{ 14, 0x022e, 0, {0x90,0x7f,0x69,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0x0a,0xba,0x00} },
66{ 2, 0x023c, 0, {0x01,0x0b} },
67{ 2, 0x023e, 0, {0x80,0xe3} },
68{ 2, 0x0240, 0, {0xd0,0x86} },
69{ 14, 0x0242, 0, {0xd0,0xd0,0xd0,0x03,0xd0,0x02,0xd0,0x83,0xd0,0x82,0xd0,0xf0,0xd0,0xe0} },
70{ 1, 0x0250, 0, {0x32} },
71{ 14, 0x0251, 0, {0xc0,0xe0,0xc0,0xf0,0xc0,0x82,0xc0,0x83,0xc0,0xd0,0x75,0xd0,0x00,0xc0} },
72{ 14, 0x025f, 0, {0x86,0x75,0x86,0x00,0xe5,0x91,0xc2,0xe4,0xf5,0x91,0x90,0x7f,0xab,0x74} },
73{ 4, 0x026d, 0, {0x04,0xf0,0xd0,0x86} },
74{ 11, 0x0271, 0, {0xd0,0xd0,0xd0,0x83,0xd0,0x82,0xd0,0xf0,0xd0,0xe0,0x32} },
75{ 14, 0x027c, 0, {0xc0,0xe0,0xc0,0xf0,0xc0,0x82,0xc0,0x83,0xc0,0x02,0xc0,0x03,0xc0,0x04} },
76{ 14, 0x028a, 0, {0xc0,0x05,0xc0,0x06,0xc0,0x07,0xc0,0x00,0xc0,0x01,0xc0,0xd0,0x75,0xd0} },
77{ 13, 0x0298, 0, {0x00,0xc0,0x86,0x75,0x86,0x00,0xe5,0x91,0xc2,0xe4,0xf5,0x91,0x90} },
78{ 12, 0x02a5, 0, {0x7f,0xab,0x74,0x08,0xf0,0x75,0x6e,0x00,0x75,0x6f,0x02,0x12} },
79{ 6, 0x02b1, 0, {0x11,0x44,0x75,0x70,0x39,0x75} },
80{ 6, 0x02b7, 0, {0x71,0x0c,0x75,0x72,0x02,0x12} },
81{ 12, 0x02bd, 0, {0x11,0x75,0x90,0x7f,0xd6,0xe4,0xf0,0x75,0xd8,0x20,0xd0,0x86} },
82{ 14, 0x02c9, 0, {0xd0,0xd0,0xd0,0x01,0xd0,0x00,0xd0,0x07,0xd0,0x06,0xd0,0x05,0xd0,0x04} },
83{ 13, 0x02d7, 0, {0xd0,0x03,0xd0,0x02,0xd0,0x83,0xd0,0x82,0xd0,0xf0,0xd0,0xe0,0x32} },
84{ 14, 0x02e4, 0, {0xc0,0xe0,0xc0,0xf0,0xc0,0x82,0xc0,0x83,0xc0,0xd0,0x75,0xd0,0x00,0xc0} },
85{ 14, 0x02f2, 0, {0x86,0x75,0x86,0x00,0xe5,0x91,0xc2,0xe4,0xf5,0x91,0x90,0x7f,0xab,0x74} },
86{ 4, 0x0300, 0, {0x10,0xf0,0xd0,0x86} },
87{ 11, 0x0304, 0, {0xd0,0xd0,0xd0,0x83,0xd0,0x82,0xd0,0xf0,0xd0,0xe0,0x32} },
88{ 14, 0x030f, 0, {0xc0,0xe0,0xc0,0xf0,0xc0,0x82,0xc0,0x83,0xc0,0x02,0xc0,0x03,0xc0,0x04} },
89{ 14, 0x031d, 0, {0xc0,0x05,0xc0,0x06,0xc0,0x07,0xc0,0x00,0xc0,0x01,0xc0,0xd0,0x75,0xd0} },
90{ 12, 0x032b, 0, {0x00,0xc0,0x86,0x75,0x86,0x00,0x75,0x6e,0x00,0x75,0x6f,0x02} },
91{ 7, 0x0337, 0, {0x12,0x11,0x44,0x75,0x70,0x40,0x75} },
92{ 6, 0x033e, 0, {0x71,0x0c,0x75,0x72,0x02,0x12} },
93{ 14, 0x0344, 0, {0x11,0x75,0x90,0x7f,0xd6,0x74,0x02,0xf0,0x90,0x7f,0xd6,0x74,0x06,0xf0} },
94{ 5, 0x0352, 0, {0x75,0xd8,0x10,0xd0,0x86} },
95{ 14, 0x0357, 0, {0xd0,0xd0,0xd0,0x01,0xd0,0x00,0xd0,0x07,0xd0,0x06,0xd0,0x05,0xd0,0x04} },
96{ 13, 0x0365, 0, {0xd0,0x03,0xd0,0x02,0xd0,0x83,0xd0,0x82,0xd0,0xf0,0xd0,0xe0,0x32} },
97{ 13, 0x0372, 0, {0x90,0x7f,0xa5,0x74,0x80,0xf0,0x90,0x7f,0xa6,0x74,0x9a,0xf0,0x12} },
98{ 12, 0x037f, 0, {0x10,0x1b,0x90,0x7f,0xa6,0xe5,0x42,0xf0,0x12,0x10,0x1b,0x90} },
99{ 13, 0x038b, 0, {0x7f,0xa6,0xe5,0x43,0xf0,0x12,0x10,0x1b,0x90,0x7f,0xa5,0x74,0x40} },
100{ 1, 0x0398, 0, {0xf0} },
101{ 1, 0x0399, 0, {0x22} },
102{ 13, 0x039a, 0, {0x90,0x7f,0xa5,0x74,0x80,0xf0,0x90,0x7f,0xa6,0x74,0x9a,0xf0,0x12} },
103{ 12, 0x03a7, 0, {0x10,0x1b,0x90,0x7f,0xa6,0xe5,0x44,0xf0,0x12,0x10,0x1b,0x90} },
104{ 12, 0x03b3, 0, {0x7f,0xa6,0xe5,0x45,0xf0,0x12,0x10,0x1b,0x90,0x7f,0xa6,0xe5} },
105{ 11, 0x03bf, 0, {0x46,0xf0,0x12,0x10,0x1b,0x90,0x7f,0xa5,0x74,0x40,0xf0} },
106{ 1, 0x03ca, 0, {0x22} },
107{ 10, 0x03cb, 0, {0x75,0x44,0x02,0x75,0x45,0x00,0x75,0x46,0x00,0x12} },
108{ 9, 0x03d5, 0, {0x03,0x9a,0x75,0x42,0x03,0x75,0x43,0x00,0x12} },
109{ 2, 0x03de, 0, {0x03,0x72} },
110{ 1, 0x03e0, 0, {0x22} },
111{ 12, 0x03e1, 0, {0x90,0x88,0x00,0xe5,0x36,0xf0,0x90,0x88,0x00,0x74,0x10,0x25} },
112{ 9, 0x03ed, 0, {0x36,0xf0,0x12,0x01,0xdd,0x75,0x42,0x01,0x75} },
113{ 9, 0x03f6, 0, {0x43,0x18,0x12,0x03,0x72,0x75,0x44,0x02,0x75} },
114{ 9, 0x03ff, 0,{0x45,0x00,0x75,0x46,0x00,0x12,0x03,0x9a,0x75} },
115{ 8, 0x0408, 0,{0x42,0x03,0x75,0x43,0x44,0x12,0x03,0x72} },
116{ 1, 0x0410, 0,{0x22} },
117{ 14, 0x0411, 0, {0xc0,0xe0,0xc0,0xf0,0xc0,0x82,0xc0,0x83,0xc0,0xd0,0x75,0xd0,0x00,0xc0} },
118{ 14, 0x041f, 0, {0x86,0x75,0x86,0x00,0xe5,0x91,0xc2,0xe4,0xf5,0x91,0x90,0x7f,0xaa,0x74} },
119{ 4, 0x042d, 0, {0x02,0xf0,0xd0,0x86} },
120{ 11, 0x0431, 0, {0xd0,0xd0,0xd0,0x83,0xd0,0x82,0xd0,0xf0,0xd0,0xe0,0x32} },
121{ 14, 0x043c, 0, {0xc0,0xe0,0xc0,0xf0,0xc0,0x82,0xc0,0x83,0xc0,0xd0,0x75,0xd0,0x00,0xc0} },
122{ 14, 0x044a, 0, {0x86,0x75,0x86,0x00,0xe5,0x91,0xc2,0xe4,0xf5,0x91,0x90,0x7f,0xa9,0x74} },
123{ 7, 0x0458, 0, {0x04,0xf0,0x75,0x30,0x01,0xd0,0x86} },
124{ 11, 0x045f, 0, {0xd0,0xd0,0xd0,0x83,0xd0,0x82,0xd0,0xf0,0xd0,0xe0,0x32} },
125{ 14, 0x046a, 0, {0xc0,0xe0,0xc0,0xf0,0xc0,0x82,0xc0,0x83,0xc0,0xd0,0x75,0xd0,0x00,0xc0} },
126{ 14, 0x0478, 0, {0x86,0x75,0x86,0x00,0xe5,0x91,0xc2,0xe4,0xf5,0x91,0x90,0x7f,0xaa,0x74} },
127{ 7, 0x0486, 0, {0x04,0xf0,0x75,0x31,0x01,0xd0,0x86} },
128{ 11, 0x048d, 0, {0xd0,0xd0,0xd0,0x83,0xd0,0x82,0xd0,0xf0,0xd0,0xe0,0x32} },
129{ 14, 0x0498, 0, {0xc0,0xe0,0xc0,0xf0,0xc0,0x82,0xc0,0x83,0xc0,0xd0,0x75,0xd0,0x00,0xc0} },
130{ 12, 0x04a6, 0, {0x86,0x75,0x86,0x00,0xe5,0x91,0xc2,0xe5,0xf5,0x91,0xd0,0x86} },
131{ 11, 0x04b2, 0, {0xd0,0xd0,0xd0,0x83,0xd0,0x82,0xd0,0xf0,0xd0,0xe0,0x32} },
132{ 14, 0x04bd, 0, {0xc0,0xe0,0xc0,0xf0,0xc0,0x82,0xc0,0x83,0xc0,0xd0,0x75,0xd0,0x00,0xc0} },
133{ 12, 0x04cb, 0, {0x86,0x75,0x86,0x00,0xe5,0x91,0xc2,0xe7,0xf5,0x91,0xd0,0x86} },
134{ 11, 0x04d7, 0, {0xd0,0xd0,0xd0,0x83,0xd0,0x82,0xd0,0xf0,0xd0,0xe0,0x32} },
135{ 12, 0x04e2, 0, {0x90,0x7f,0xea,0xe0,0xfa,0x8a,0x20,0x90,0x7f,0x96,0xe4,0xf0} },
136{ 1, 0x04ee, 0, {0x22} },
137{ 7, 0x04ef, 0, {0x90,0x7f,0xea,0xe0,0xfa,0x8a,0x21} },
138{ 1, 0x04f6, 0, {0x22} },
139{ 14, 0x04f7, 0, {0x90,0x17,0x13,0xe0,0xfa,0x90,0x17,0x15,0xe0,0xfb,0x74,0x80,0x2a,0xfa} },
140{ 14, 0x0505, 0, {0x74,0x80,0x2b,0xfb,0xea,0x03,0x03,0x54,0x3f,0xfc,0xea,0xc4,0x23,0x54} },
141{ 14, 0x0513, 0, {0x1f,0xfa,0x2c,0xfa,0xeb,0x03,0x03,0x54,0x3f,0xfc,0xeb,0xc4,0x23,0x54} },
142{ 11, 0x0521, 0, {0x1f,0xfb,0x2c,0xfb,0x90,0x17,0x0a,0xe0,0xfc,0x60,0x02} },
143{ 2, 0x052c, 0, {0x7a,0x00} },
144{ 7, 0x052e, 0, {0x90,0x17,0x0c,0xe0,0xfc,0x60,0x02} },
145{ 2, 0x0535, 0, {0x7b,0x00} },
146{ 11, 0x0537, 0, {0xea,0x2b,0xfc,0xc3,0x13,0xf5,0x3a,0x75,0x44,0x02,0x8b} },
147{ 7, 0x0542, 0, {0x45,0x8a,0x46,0x12,0x03,0x9a,0x75} },
148{ 9, 0x0549, 0, {0x6e,0x08,0x75,0x6f,0x00,0x12,0x11,0x44,0x75} },
149{ 4, 0x0552, 0, {0x70,0x47,0x75,0x71} },
150{ 8, 0x0556, 0, {0x0c,0x75,0x72,0x02,0x12,0x11,0x75,0x85} },
151{ 5, 0x055e, 0, {0x3a,0x73,0x12,0x11,0xa0} },
152{ 1, 0x0563, 0, {0x22} },
153{ 14, 0x0564, 0, {0x90,0x7f,0x96,0xe0,0xfa,0x90,0x7f,0x96,0x74,0x80,0x65,0x02,0xf0,0x90} },
154{ 14, 0x0572, 0, {0x7f,0xeb,0xe0,0xfa,0x90,0x7f,0xea,0xe0,0xfb,0x90,0x7f,0xef,0xe0,0xfc} },
155{ 14, 0x0580, 0, {0x33,0x95,0xe0,0xfd,0x8c,0x05,0x7c,0x00,0x90,0x7f,0xee,0xe0,0xfe,0x33} },
156{ 14, 0x058e, 0, {0x95,0xe0,0xff,0xec,0x2e,0xfc,0xed,0x3f,0xfd,0x90,0x7f,0xe9,0xe0,0xfe} },
157{ 5, 0x059c, 0, {0xbe,0x01,0x02,0x80,0x03} },
158{ 3, 0x05a1, 0, {0x02,0x05,0xf9} },
159{ 6, 0x05a4, 0, {0xbc,0x01,0x21,0xbd,0x00,0x1e} },
160{ 14, 0x05aa, 0, {0xea,0xc4,0x03,0x54,0xf8,0xfc,0xeb,0x25,0xe0,0xfd,0x2c,0x24,0x00,0xfc} },
161{ 14, 0x05b8, 0, {0xe4,0x34,0x17,0xfd,0x90,0x7e,0xc0,0xe0,0xfe,0x8c,0x82,0x8d,0x83,0xf0} },
162{ 2, 0x05c6, 0, {0x80,0x31} },
163{ 14, 0x05c8, 0, {0xea,0xc4,0x03,0x54,0xf8,0xfa,0xeb,0x25,0xe0,0xfb,0x2a,0xfa,0x24,0x00} },
164{ 14, 0x05d6, 0, {0xfb,0xe4,0x34,0x17,0xfc,0x90,0x7e,0xc0,0xe0,0xfd,0x8b,0x82,0x8c,0x83} },
165{ 14, 0x05e4, 0, {0xf0,0x74,0x01,0x2a,0x24,0x00,0xfa,0xe4,0x34,0x17,0xfb,0x90,0x7e,0xc1} },
166{ 7, 0x05f2, 0, {0xe0,0xfc,0x8a,0x82,0x8b,0x83,0xf0} },
167{ 3, 0x05f9, 0, {0x75,0x38,0x01} },
168{ 1, 0x05fc, 0, {0x22} },
169{ 14, 0x05fd, 0, {0xc0,0xe0,0xc0,0xf0,0xc0,0x82,0xc0,0x83,0xc0,0x02,0xc0,0x03,0xc0,0x04} },
170{ 14, 0x060b, 0, {0xc0,0x05,0xc0,0x06,0xc0,0x07,0xc0,0x00,0xc0,0x01,0xc0,0xd0,0x75,0xd0} },
171{ 13, 0x0619, 0, {0x00,0xc0,0x86,0x75,0x86,0x00,0xe5,0x91,0xc2,0xe4,0xf5,0x91,0x90} },
172{ 13, 0x0626, 0, {0x7f,0xaa,0x74,0x01,0xf0,0x12,0x05,0x64,0x75,0x37,0x00,0xd0,0x86} },
173{ 14, 0x0633, 0, {0xd0,0xd0,0xd0,0x01,0xd0,0x00,0xd0,0x07,0xd0,0x06,0xd0,0x05,0xd0,0x04} },
174{ 13, 0x0641, 0, {0xd0,0x03,0xd0,0x02,0xd0,0x83,0xd0,0x82,0xd0,0xf0,0xd0,0xe0,0x32} },
175{ 14, 0x064e, 0, {0x90,0x7f,0xeb,0xe0,0xfa,0x90,0x7f,0xea,0xe0,0xfb,0x90,0x7f,0xee,0xe0} },
176{ 14, 0x065c, 0, {0xfc,0x33,0x95,0xe0,0xfd,0x90,0x7f,0x96,0xe0,0xfe,0x90,0x7f,0x96,0x74} },
177{ 14, 0x066a, 0, {0x80,0x65,0x06,0xf0,0x90,0x7f,0x00,0x74,0x01,0xf0,0xea,0xc4,0x03,0x54} },
178{ 14, 0x0678, 0, {0xf8,0xfe,0xeb,0x25,0xe0,0xfb,0x2e,0xfe,0x24,0x00,0xfb,0xe4,0x34,0x17} },
179{ 14, 0x0686, 0, {0xff,0x8b,0x82,0x8f,0x83,0xe0,0xfb,0x74,0x01,0x2e,0x24,0x00,0xfe,0xe4} },
180{ 14, 0x0694, 0, {0x34,0x17,0xff,0x8e,0x82,0x8f,0x83,0xe0,0xfe,0x90,0x7f,0xe9,0xe0,0xff} },
181{ 3, 0x06a2, 0, {0xbf,0x81,0x0a} },
182{ 10, 0x06a5, 0, {0x90,0x7f,0x00,0xeb,0xf0,0x90,0x7f,0x01,0xee,0xf0} },
183{ 8, 0x06af, 0, {0x90,0x7f,0xe9,0xe0,0xfb,0xbb,0x82,0x1a} },
184{ 3, 0x06b7, 0, {0xba,0x01,0x0c} },
185{ 12, 0x06ba, 0, {0x90,0x7f,0x00,0xe4,0xf0,0x90,0x7f,0x01,0xe4,0xf0,0x80,0x0b} },
186{ 11, 0x06c6, 0, {0x90,0x7f,0x00,0xe4,0xf0,0x90,0x7f,0x01,0x74,0xb5,0xf0} },
187{ 8, 0x06d1, 0, {0x90,0x7f,0xe9,0xe0,0xfb,0xbb,0x83,0x1b} },
188{ 3, 0x06d9, 0, {0xba,0x01,0x0d} },
189{ 13, 0x06dc, 0, {0x90,0x7f,0x00,0x74,0x01,0xf0,0x90,0x7f,0x01,0xe4,0xf0,0x80,0x0b} },
190{ 11, 0x06e9, 0, {0x90,0x7f,0x00,0xe4,0xf0,0x90,0x7f,0x01,0x74,0x12,0xf0} },
191{ 8, 0x06f4, 0, {0x90,0x7f,0xe9,0xe0,0xfb,0xbb,0x84,0x1c} },
192{ 3, 0x06fc, 0, {0xba,0x01,0x0d} },
193{ 13, 0x06ff, 0, {0x90,0x7f,0x00,0x74,0x01,0xf0,0x90,0x7f,0x01,0xe4,0xf0,0x80,0x0c} },
194{ 12, 0x070c, 0, {0x90,0x7f,0x00,0x74,0x80,0xf0,0x90,0x7f,0x01,0x74,0x01,0xf0} },
195{ 5, 0x0718, 0, {0x90,0x7f,0xb5,0xec,0xf0} },
196{ 1, 0x071d, 0, {0x22} },
197{ 12, 0x071e, 0, {0x75,0x36,0x0d,0x90,0x88,0x00,0x74,0x1d,0xf0,0x75,0x6b,0x80} },
198{ 10, 0x072a, 0, {0x75,0x6c,0x3c,0x12,0x10,0xe2,0x75,0x6b,0x80,0x75} },
199{ 9, 0x0734, 0, {0x6c,0x0f,0x12,0x10,0xe2,0x75,0x6b,0x80,0x75} },
200{ 9, 0x073d, 0, {0x6c,0x06,0x12,0x10,0xe2,0x75,0x6b,0x80,0x75} },
201{ 7, 0x0746, 0, {0x6c,0x01,0x12,0x10,0xe2,0x7a,0x00} },
202{ 3, 0x074d, 0, {0xba,0xff,0x00} },
203{ 2, 0x0750, 0, {0x50,0x0a} },
204{ 10, 0x0752, 0, {0xc0,0x02,0x12,0x01,0xdd,0xd0,0x02,0x0a,0x80,0xf1} },
205{ 10, 0x075c, 0, {0x75,0x6b,0x80,0x75,0x6c,0x3c,0x12,0x10,0xe2,0x75} },
206{ 8, 0x0766, 0, {0x6b,0x80,0x75,0x6c,0x0f,0x12,0x10,0xe2} },
207{ 1, 0x076e, 0, {0x22} },
208{ 14, 0x076f, 0, {0x90,0x7f,0xa1,0xe4,0xf0,0x90,0x7f,0xaf,0x74,0x01,0xf0,0x90,0x7f,0x92} },
209{ 14, 0x077d, 0, {0x74,0x02,0xf0,0x75,0x8e,0x31,0x75,0x89,0x21,0x75,0x88,0x00,0x75,0xc8} },
210{ 14, 0x078b, 0, {0x00,0x75,0x8d,0x40,0x75,0x98,0x40,0x75,0xc0,0x40,0x75,0x87,0x00,0x75} },
211{ 9, 0x0799, 0, {0x20,0x00,0x75,0x21,0x00,0x75,0x22,0x00,0x75} },
212{ 5, 0x07a2, 0, {0x23,0x00,0x75,0x47,0x00} },
213{ 7, 0x07a7, 0, {0xc3,0xe5,0x47,0x94,0x20,0x50,0x11} },
214{ 13, 0x07ae, 0, {0xe5,0x47,0x24,0x00,0xf5,0x82,0xe4,0x34,0x17,0xf5,0x83,0xe4,0xf0} },
215{ 4, 0x07bb, 0, {0x05,0x47,0x80,0xe8} },
216{ 9, 0x07bf, 0, {0xe4,0xf5,0x40,0xf5,0x3f,0xe4,0xf5,0x3c,0xf5} },
217{ 7, 0x07c8, 0, {0x3b,0xe4,0xf5,0x3e,0xf5,0x3d,0x75} },
218{ 11, 0x07cf, 0, {0x32,0x00,0x75,0x37,0x00,0x75,0x39,0x00,0x90,0x7f,0x93} },
219{ 14, 0x07da, 0, {0x74,0x3c,0xf0,0x90,0x7f,0x9c,0x74,0xff,0xf0,0x90,0x7f,0x96,0x74,0x80} },
220{ 14, 0x07e8, 0, {0xf0,0x90,0x7f,0x94,0x74,0x70,0xf0,0x90,0x7f,0x9d,0x74,0x8f,0xf0,0x90} },
221{ 14, 0x07f6, 0, {0x7f,0x97,0xe4,0xf0,0x90,0x7f,0x95,0x74,0xc2,0xf0,0x90,0x7f,0x98,0x74} },
222{ 14, 0x0804, 0, {0x28,0xf0,0x90,0x7f,0x9e,0x74,0x28,0xf0,0x90,0x7f,0xf0,0xe4,0xf0,0x90} },
223{ 14, 0x0812, 0, {0x7f,0xf1,0xe4,0xf0,0x90,0x7f,0xf2,0xe4,0xf0,0x90,0x7f,0xf3,0xe4,0xf0} },
224{ 14, 0x0820, 0, {0x90,0x7f,0xf4,0xe4,0xf0,0x90,0x7f,0xf5,0xe4,0xf0,0x90,0x7f,0xf6,0xe4} },
225{ 14, 0x082e, 0, {0xf0,0x90,0x7f,0xf7,0xe4,0xf0,0x90,0x7f,0xf8,0xe4,0xf0,0x90,0x7f,0xf9} },
226{ 14, 0x083c, 0, {0x74,0x38,0xf0,0x90,0x7f,0xfa,0x74,0xa0,0xf0,0x90,0x7f,0xfb,0x74,0xa0} },
227{ 14, 0x084a, 0, {0xf0,0x90,0x7f,0xfc,0x74,0xa0,0xf0,0x90,0x7f,0xfd,0x74,0xa0,0xf0,0x90} },
228{ 14, 0x0858, 0, {0x7f,0xfe,0x74,0xa0,0xf0,0x90,0x7f,0xff,0x74,0xa0,0xf0,0x90,0x7f,0xe0} },
229{ 14, 0x0866, 0, {0x74,0x03,0xf0,0x90,0x7f,0xe1,0x74,0x01,0xf0,0x90,0x7f,0xdd,0x74,0x80} },
230{ 11, 0x0874, 0, {0xf0,0x12,0x12,0x43,0x12,0x07,0x1e,0x7a,0x00,0x7b,0x00} },
231{ 9, 0x087f, 0, {0xc3,0xea,0x94,0x1e,0xeb,0x94,0x00,0x50,0x17} },
232{ 12, 0x0888, 0, {0x90,0x88,0x00,0xe0,0xf5,0x47,0x90,0x88,0x0b,0xe0,0xf5,0x47} },
233{ 9, 0x0894, 0, {0x90,0x7f,0x68,0xf0,0x0a,0xba,0x00,0x01,0x0b} },
234{ 2, 0x089d, 0, {0x80,0xe0} },
235{ 12, 0x089f, 0, {0x12,0x03,0xe1,0x90,0x7f,0xd6,0xe4,0xf0,0x7a,0x00,0x7b,0x00} },
236{ 13, 0x08ab, 0, {0x8a,0x04,0x8b,0x05,0xc3,0xea,0x94,0xe0,0xeb,0x94,0x2e,0x50,0x1a} },
237{ 14, 0x08b8, 0, {0xc0,0x02,0xc0,0x03,0xc0,0x04,0xc0,0x05,0x12,0x01,0xdd,0xd0,0x05,0xd0} },
238{ 10, 0x08c6, 0, {0x04,0xd0,0x03,0xd0,0x02,0x0a,0xba,0x00,0x01,0x0b} },
239{ 2, 0x08d0, 0, {0x80,0xd9} },
240{ 13, 0x08d2, 0, {0x90,0x7f,0xd6,0x74,0x02,0xf0,0x90,0x7f,0xd6,0x74,0x06,0xf0,0x90} },
241{ 14, 0x08df, 0, {0x7f,0xde,0x74,0x05,0xf0,0x90,0x7f,0xdf,0x74,0x05,0xf0,0x90,0x7f,0xac} },
242{ 14, 0x08ed, 0, {0xe4,0xf0,0x90,0x7f,0xad,0x74,0x05,0xf0,0x75,0xa8,0x80,0x75,0xf8,0x10} },
243{ 13, 0x08fb, 0, {0x90,0x7f,0xae,0x74,0x0b,0xf0,0x90,0x7f,0xe2,0x74,0x88,0xf0,0x90} },
244{ 12, 0x0908, 0, {0x7f,0xab,0x74,0x08,0xf0,0x75,0xe8,0x11,0x75,0x32,0x01,0x75} },
245{ 12, 0x0914, 0, {0x31,0x00,0x75,0x30,0x00,0xc0,0x04,0xc0,0x05,0x12,0x04,0xf7} },
246{ 10, 0x0920, 0, {0xd0,0x05,0xd0,0x04,0x75,0x34,0x00,0x75,0x35,0x01} },
247{ 13, 0x092a, 0, {0x90,0x7f,0xae,0x74,0x03,0xf0,0x8c,0x02,0xba,0x00,0x02,0x80,0x03} },
248{ 3, 0x0937, 0, {0x02,0x0a,0x3f} },
249{ 12, 0x093a, 0, {0x85,0x33,0x34,0x90,0x7f,0x9d,0x74,0x8f,0xf0,0x90,0x7f,0x97} },
250{ 14, 0x0946, 0, {0x74,0x08,0xf0,0x90,0x7f,0x9d,0x74,0x88,0xf0,0x90,0x7f,0x9a,0xe0,0xfa} },
251{ 12, 0x0954, 0, {0x74,0x05,0x5a,0xf5,0x33,0x90,0x7f,0x9d,0x74,0x8f,0xf0,0x90} },
252{ 13, 0x0960, 0, {0x7f,0x97,0x74,0x02,0xf0,0x90,0x7f,0x9d,0x74,0x82,0xf0,0xe5,0x33} },
253{ 13, 0x096d, 0, {0x25,0xe0,0xfa,0x90,0x7f,0x9a,0xe0,0x54,0x05,0xfb,0x4a,0xf5,0x33} },
254{ 2, 0x097a, 0, {0x60,0x0c} },
255{ 12, 0x097c, 0, {0x90,0x7f,0x96,0xe0,0xfa,0x90,0x7f,0x96,0x74,0x80,0x4a,0xf0} },
256{ 11, 0x0988, 0, {0x75,0x6e,0x00,0x75,0x6f,0x00,0xc0,0x04,0xc0,0x05,0x12} },
257{ 14, 0x0993, 0, {0x11,0x44,0xd0,0x05,0xd0,0x04,0x90,0x17,0x13,0xe0,0xfa,0x74,0x80,0x2a} },
258{ 6, 0x09a1, 0, {0xfa,0xe5,0x33,0xb4,0x04,0x29} },
259{ 3, 0x09a7, 0, {0xba,0xa0,0x00} },
260{ 2, 0x09aa, 0, {0x50,0x24} },
261{ 13, 0x09ac, 0, {0x90,0x17,0x13,0xe0,0x04,0xfb,0x0b,0x90,0x17,0x13,0xeb,0xf0,0x90} },
262{ 14, 0x09b9, 0, {0x17,0x13,0xe0,0xfb,0x90,0x17,0x15,0xf0,0xc0,0x02,0xc0,0x04,0xc0,0x05} },
263{ 9, 0x09c7, 0, {0x12,0x04,0xf7,0xd0,0x05,0xd0,0x04,0xd0,0x02} },
264{ 5, 0x09d0, 0, {0xe5,0x33,0xb4,0x02,0x26} },
265{ 6, 0x09d5, 0, {0xc3,0x74,0x04,0x9a,0x50,0x20} },
266{ 13, 0x09db, 0, {0x90,0x17,0x13,0xe0,0xfa,0x1a,0x1a,0x90,0x17,0x13,0xea,0xf0,0x90} },
267{ 13, 0x09e8, 0, {0x17,0x13,0xe0,0xfa,0x90,0x17,0x15,0xf0,0xc0,0x04,0xc0,0x05,0x12} },
268{ 6, 0x09f5, 0, {0x04,0xf7,0xd0,0x05,0xd0,0x04} },
269{ 5, 0x09fb, 0, {0xe5,0x33,0xb4,0x08,0x1d} },
270{ 4, 0x0a00, 0, {0xe5,0x34,0x70,0x19} },
271{ 10, 0x0a04, 0, {0x74,0x01,0x25,0x35,0x54,0x0f,0xf5,0x35,0x85,0x35} },
272{ 12, 0x0a0e, 0, {0x75,0x75,0x76,0x00,0xc0,0x04,0xc0,0x05,0x12,0x13,0xfe,0xd0} },
273{ 3, 0x0a1a, 0, {0x05,0xd0,0x04} },
274{ 5, 0x0a1d, 0, {0xe5,0x33,0xb4,0x01,0x1d} },
275{ 4, 0x0a22, 0, {0xe5,0x34,0x70,0x19} },
276{ 10, 0x0a26, 0, {0xe5,0x35,0x24,0xff,0x54,0x0f,0xf5,0x35,0x85,0x35} },
277{ 12, 0x0a30, 0, {0x75,0x75,0x76,0x00,0xc0,0x04,0xc0,0x05,0x12,0x13,0xfe,0xd0} },
278{ 3, 0x0a3c, 0, {0x05,0xd0,0x04} },
279{ 14, 0x0a3f, 0, {0xc0,0x04,0xc0,0x05,0x12,0x01,0xdd,0xd0,0x05,0xd0,0x04,0x90,0x7f,0x96} },
280{ 14, 0x0a4d, 0, {0xe0,0xfa,0x90,0x7f,0x96,0x74,0x7f,0x5a,0xf0,0x90,0x7f,0x97,0x74,0x08} },
281{ 10, 0x0a5b, 0, {0xf0,0xc3,0xec,0x94,0x00,0xed,0x94,0x02,0x40,0x08} },
282{ 8, 0x0a65, 0, {0x90,0x7f,0x96,0xe0,0xfa,0x20,0xe6,0x08} },
283{ 8, 0x0a6d, 0, {0xc3,0xe4,0x9c,0x74,0x08,0x9d,0x50,0x13} },
284{ 14, 0x0a75, 0, {0x90,0x7f,0x96,0xe0,0xfa,0x90,0x7f,0x96,0x74,0x40,0x65,0x02,0xf0,0x7c} },
285{ 5, 0x0a83, 0, {0x00,0x7d,0x00,0x80,0x05} },
286{ 5, 0x0a88, 0, {0x0c,0xbc,0x00,0x01,0x0d} },
287{ 5, 0x0a8d, 0, {0xe5,0x38,0xb4,0x01,0x0e} },
288{ 13, 0x0a92, 0, {0xc0,0x04,0xc0,0x05,0x12,0x04,0xf7,0xd0,0x05,0xd0,0x04,0x75,0x38} },
289{ 1, 0x0a9f, 0, {0x00} },
290{ 7, 0x0aa0, 0, {0xe5,0x31,0x70,0x03,0x02,0x09,0x2a} },
291{ 10, 0x0aa7, 0, {0x90,0x7f,0xc9,0xe0,0xfa,0x70,0x03,0x02,0x0c,0x2d} },
292{ 14, 0x0ab1, 0, {0x90,0x7f,0x96,0xe0,0xfa,0x90,0x7f,0x96,0x74,0x80,0x65,0x02,0xf0,0x90} },
293{ 9, 0x0abf, 0, {0x7d,0xc0,0xe0,0xfa,0xba,0x2c,0x02,0x80,0x03} },
294{ 3, 0x0ac8, 0, {0x02,0x0b,0x36} },
295{ 5, 0x0acb, 0, {0x75,0x32,0x00,0x7b,0x00} },
296{ 3, 0x0ad0, 0, {0xbb,0x64,0x00} },
297{ 2, 0x0ad3, 0, {0x50,0x1c} },
298{ 14, 0x0ad5, 0, {0xc0,0x02,0xc0,0x03,0xc0,0x04,0xc0,0x05,0x12,0x01,0xdd,0xd0,0x05,0xd0} },
299{ 13, 0x0ae3, 0, {0x04,0xd0,0x03,0xd0,0x02,0x90,0x88,0x0f,0xe0,0xf5,0x47,0x0b,0x80} },
300{ 1, 0x0af0, 0, {0xdf} },
301{ 13, 0x0af1, 0, {0xc0,0x02,0xc0,0x04,0xc0,0x05,0x12,0x07,0x1e,0x12,0x03,0xe1,0x12} },
302{ 12, 0x0afe, 0, {0x04,0xf7,0xd0,0x05,0xd0,0x04,0xd0,0x02,0x75,0x6e,0x00,0x75} },
303{ 13, 0x0b0a, 0, {0x6f,0x01,0xc0,0x02,0xc0,0x04,0xc0,0x05,0x12,0x11,0x44,0xd0,0x05} },
304{ 9, 0x0b17, 0, {0xd0,0x04,0xd0,0x02,0x75,0x70,0x4d,0x75,0x71} },
305{ 11, 0x0b20, 0, {0x0c,0x75,0x72,0x02,0xc0,0x02,0xc0,0x04,0xc0,0x05,0x12} },
306{ 11, 0x0b2b, 0, {0x11,0x75,0xd0,0x05,0xd0,0x04,0xd0,0x02,0x02,0x0c,0x2d} },
307{ 3, 0x0b36, 0, {0xba,0x2a,0x3b} },
308{ 13, 0x0b39, 0, {0x90,0x7f,0x98,0x74,0x20,0xf0,0xc0,0x02,0xc0,0x04,0xc0,0x05,0x12} },
309{ 14, 0x0b46, 0, {0x01,0xdd,0xd0,0x05,0xd0,0x04,0xd0,0x02,0x90,0x7f,0x98,0x74,0x28,0xf0} },
310{ 2, 0x0b54, 0, {0x7b,0x00} },
311{ 3, 0x0b56, 0, {0xbb,0x0a,0x00} },
312{ 5, 0x0b59, 0, {0x40,0x03,0x02,0x0c,0x2d} },
313{ 14, 0x0b5e, 0, {0xc0,0x02,0xc0,0x03,0xc0,0x04,0xc0,0x05,0x12,0x01,0xdd,0xd0,0x05,0xd0} },
314{ 8, 0x0b6c, 0, {0x04,0xd0,0x03,0xd0,0x02,0x0b,0x80,0xe2} },
315{ 3, 0x0b74, 0, {0xba,0x2b,0x1a} },
316{ 8, 0x0b77, 0, {0x90,0x7f,0xc9,0xe0,0xfb,0xbb,0x40,0x12} },
317{ 14, 0x0b7f, 0, {0xc0,0x02,0xc0,0x04,0xc0,0x05,0x12,0x12,0x05,0xd0,0x05,0xd0,0x04,0xd0} },
318{ 4, 0x0b8d, 0, {0x02,0x02,0x0c,0x2d} },
319{ 3, 0x0b91, 0, {0xba,0x10,0x1f} },
320{ 14, 0x0b94, 0, {0x90,0x7f,0x96,0xe0,0xfb,0x90,0x7f,0x96,0x74,0x80,0x65,0x03,0xf0,0xc0} },
321{ 14, 0x0ba2, 0, {0x02,0xc0,0x04,0xc0,0x05,0x12,0x10,0x3d,0xd0,0x05,0xd0,0x04,0xd0,0x02} },
322{ 3, 0x0bb0, 0, {0x02,0x0c,0x2d} },
323{ 3, 0x0bb3, 0, {0xba,0x11,0x12} },
324{ 14, 0x0bb6, 0, {0xc0,0x02,0xc0,0x04,0xc0,0x05,0x12,0x10,0x6a,0xd0,0x05,0xd0,0x04,0xd0} },
325{ 4, 0x0bc4, 0, {0x02,0x02,0x0c,0x2d} },
326{ 3, 0x0bc8, 0, {0xba,0x12,0x12} },
327{ 14, 0x0bcb, 0, {0xc0,0x02,0xc0,0x04,0xc0,0x05,0x12,0x10,0x8f,0xd0,0x05,0xd0,0x04,0xd0} },
328{ 4, 0x0bd9, 0, {0x02,0x02,0x0c,0x2d} },
329{ 3, 0x0bdd, 0, {0xba,0x13,0x0b} },
330{ 11, 0x0be0, 0, {0x90,0x7d,0xc1,0xe0,0xfb,0x90,0x88,0x00,0xf0,0x80,0x42} },
331{ 3, 0x0beb, 0, {0xba,0x14,0x11} },
332{ 14, 0x0bee, 0, {0xc0,0x02,0xc0,0x04,0xc0,0x05,0x12,0x11,0xdd,0xd0,0x05,0xd0,0x04,0xd0} },
333{ 3, 0x0bfc, 0, {0x02,0x80,0x2e} },
334{ 3, 0x0bff, 0, {0xba,0x15,0x1d} },
335{ 12, 0x0c02, 0, {0x90,0x7d,0xc1,0xe0,0xf5,0x75,0x90,0x7d,0xc2,0xe0,0xf5,0x76} },
336{ 14, 0x0c0e, 0, {0xc0,0x02,0xc0,0x04,0xc0,0x05,0x12,0x13,0xfe,0xd0,0x05,0xd0,0x04,0xd0} },
337{ 3, 0x0c1c, 0, {0x02,0x80,0x0e} },
338{ 3, 0x0c1f, 0, {0xba,0x16,0x0b} },
339{ 11, 0x0c22, 0, {0xc0,0x04,0xc0,0x05,0x12,0x13,0xa3,0xd0,0x05,0xd0,0x04} },
340{ 11, 0x0c2d, 0, {0x90,0x7f,0xc9,0xe4,0xf0,0x75,0x31,0x00,0x02,0x09,0x2a} },
341{ 1, 0x0c38, 0, {0x22} },
342{ 7, 0x0c39, 0, {0x53,0x55,0x50,0x45,0x4e,0x44,0x00} },
343{ 7, 0x0c40, 0, {0x52,0x45,0x53,0x55,0x4d,0x45,0x00} },
344{ 6, 0x0c47, 0, {0x20,0x56,0x6f,0x6c,0x20,0x00} },
345{ 13, 0x0c4d, 0, {0x44,0x41,0x42,0x55,0x53,0x42,0x20,0x76,0x31,0x2e,0x30,0x30,0x00} },
346{ 14, 0x0c5a, 0, {0xc0,0xe0,0xc0,0xf0,0xc0,0x82,0xc0,0x83,0xc0,0x02,0xc0,0x03,0xc0,0x04} },
347{ 14, 0x0c68, 0, {0xc0,0x05,0xc0,0x06,0xc0,0x07,0xc0,0x00,0xc0,0x01,0xc0,0xd0,0x75,0xd0} },
348{ 13, 0x0c76, 0, {0x00,0xc0,0x86,0x75,0x86,0x00,0xe5,0x91,0xc2,0xe4,0xf5,0x91,0x90} },
349{ 14, 0x0c83, 0, {0x7f,0xab,0x74,0x01,0xf0,0x90,0x7f,0xe8,0xe0,0xfa,0x90,0x7f,0xe9,0xe0} },
350{ 6, 0x0c91, 0, {0xfb,0xbb,0x00,0x02,0x80,0x03} },
351{ 3, 0x0c97, 0, {0x02,0x0d,0x38} },
352{ 3, 0x0c9a, 0, {0xba,0x80,0x14} },
353{ 14, 0x0c9d, 0, {0x90,0x7f,0x00,0x74,0x01,0xf0,0x90,0x7f,0x01,0xe4,0xf0,0x90,0x7f,0xb5} },
354{ 6, 0x0cab, 0, {0x74,0x02,0xf0,0x02,0x0e,0xcd} },
355{ 5, 0x0cb1, 0, {0xba,0x82,0x02,0x80,0x03} },
356{ 3, 0x0cb6, 0, {0x02,0x0d,0x1d} },
357{ 8, 0x0cb9, 0, {0x90,0x7f,0xec,0xe0,0xfc,0xbc,0x01,0x00} },
358{ 2, 0x0cc1, 0, {0x40,0x21} },
359{ 6, 0x0cc3, 0, {0xc3,0x74,0x07,0x9c,0x40,0x1b} },
360{ 14, 0x0cc9, 0, {0xec,0x24,0xff,0x25,0xe0,0xfd,0x24,0xc6,0xf5,0x82,0xe4,0x34,0x7f,0xf5} },
361{ 13, 0x0cd7, 0, {0x83,0xe0,0xfd,0x53,0x05,0x01,0x90,0x7f,0x00,0xed,0xf0,0x80,0x2b} },
362{ 3, 0x0ce4, 0, {0xbc,0x81,0x00} },
363{ 2, 0x0ce7, 0, {0x40,0x21} },
364{ 6, 0x0ce9, 0, {0xc3,0x74,0x87,0x9c,0x40,0x1b} },
365{ 14, 0x0cef, 0, {0xec,0x24,0x7f,0x25,0xe0,0xfc,0x24,0xb6,0xf5,0x82,0xe4,0x34,0x7f,0xf5} },
366{ 13, 0x0cfd, 0, {0x83,0xe0,0xfc,0x53,0x04,0x01,0x90,0x7f,0x00,0xec,0xf0,0x80,0x05} },
367{ 5, 0x0d0a, 0, {0x90,0x7f,0x00,0xe4,0xf0} },
368{ 14, 0x0d0f, 0, {0x90,0x7f,0x01,0xe4,0xf0,0x90,0x7f,0xb5,0x74,0x02,0xf0,0x02,0x0e,0xcd} },
369{ 5, 0x0d1d, 0, {0xba,0x81,0x02,0x80,0x03} },
370{ 3, 0x0d22, 0, {0x02,0x0e,0xc5} },
371{ 14, 0x0d25, 0, {0x90,0x7f,0x00,0xe4,0xf0,0x90,0x7f,0x01,0xe4,0xf0,0x90,0x7f,0xb5,0x74} },
372{ 5, 0x0d33, 0, {0x02,0xf0,0x02,0x0e,0xcd} },
373{ 3, 0x0d38, 0, {0xbb,0x01,0x2d} },
374{ 6, 0x0d3b, 0, {0xba,0x00,0x03,0x02,0x0e,0xcd} },
375{ 3, 0x0d41, 0, {0xba,0x02,0x11} },
376{ 13, 0x0d44, 0, {0x75,0x59,0x00,0xc0,0x02,0xc0,0x03,0x12,0x0e,0xf0,0xd0,0x03,0xd0} },
377{ 4, 0x0d51, 0, {0x02,0x02,0x0e,0xcd} },
378{ 5, 0x0d55, 0, {0xba,0x21,0x02,0x80,0x03} },
379{ 3, 0x0d5a, 0, {0x02,0x0e,0xcd} },
380{ 11, 0x0d5d, 0, {0x75,0x37,0x01,0x90,0x7f,0xc5,0xe4,0xf0,0x02,0x0e,0xcd} },
381{ 3, 0x0d68, 0, {0xbb,0x03,0x1f} },
382{ 6, 0x0d6b, 0, {0xba,0x00,0x03,0x02,0x0e,0xcd} },
383{ 5, 0x0d71, 0, {0xba,0x02,0x02,0x80,0x03} },
384{ 3, 0x0d76, 0, {0x02,0x0e,0xcd} },
385{ 13, 0x0d79, 0, {0x75,0x59,0x01,0xc0,0x02,0xc0,0x03,0x12,0x0e,0xf0,0xd0,0x03,0xd0} },
386{ 4, 0x0d86, 0, {0x02,0x02,0x0e,0xcd} },
387{ 3, 0x0d8a, 0, {0xbb,0x06,0x54} },
388{ 5, 0x0d8d, 0, {0xba,0x80,0x02,0x80,0x03} },
389{ 3, 0x0d92, 0, {0x02,0x0e,0xc5} },
390{ 8, 0x0d95, 0, {0x90,0x7f,0xeb,0xe0,0xfc,0xbc,0x01,0x15} },
391{ 12, 0x0d9d, 0, {0x7c,0xfb,0x7d,0x0f,0x8d,0x06,0x7f,0x00,0x90,0x7f,0xd4,0xee} },
392{ 9, 0x0da9, 0, {0xf0,0x90,0x7f,0xd5,0xec,0xf0,0x02,0x0e,0xcd} },
393{ 10, 0x0db2, 0, {0x90,0x7f,0xeb,0xe0,0xfc,0xbc,0x02,0x02,0x80,0x03} },
394{ 3, 0x0dbc, 0, {0x02,0x0e,0xc5} },
395{ 10, 0x0dbf, 0, {0x90,0x7f,0xea,0xe0,0xfc,0xbc,0x00,0x02,0x80,0x03} },
396{ 3, 0x0dc9, 0, {0x02,0x0e,0xc5} },
397{ 12, 0x0dcc, 0, {0x7c,0x3b,0x7d,0x0f,0x8d,0x06,0x7f,0x00,0x90,0x7f,0xd4,0xee} },
398{ 9, 0x0dd8, 0, {0xf0,0x90,0x7f,0xd5,0xec,0xf0,0x02,0x0e,0xcd} },
399{ 6, 0x0de1, 0, {0xbb,0x07,0x03,0x02,0x0e,0xc5} },
400{ 3, 0x0de7, 0, {0xbb,0x08,0x10} },
401{ 13, 0x0dea, 0, {0xac,0x48,0x90,0x7f,0x00,0xec,0xf0,0x90,0x7f,0xb5,0x74,0x01,0xf0} },
402{ 3, 0x0df7, 0, {0x02,0x0e,0xcd} },
403{ 3, 0x0dfa, 0, {0xbb,0x09,0x31} },
404{ 5, 0x0dfd, 0, {0xba,0x00,0x02,0x80,0x03} },
405{ 3, 0x0e02, 0, {0x02,0x0e,0xc5} },
406{ 14, 0x0e05, 0, {0x90,0x7f,0xea,0xe0,0xfc,0xc3,0x74,0x01,0x9c,0x50,0x03,0x02,0x0e,0xc5} },
407{ 8, 0x0e13, 0, {0x90,0x7f,0xea,0xe0,0xfc,0xbc,0x00,0x0a} },
408{ 10, 0x0e1b, 0, {0x90,0x17,0x21,0xe4,0xf0,0x90,0x17,0x22,0xe4,0xf0} },
409{ 9, 0x0e25, 0, {0x90,0x7f,0xea,0xe0,0xf5,0x48,0x02,0x0e,0xcd} },
410{ 3, 0x0e2e, 0, {0xbb,0x0a,0x27} },
411{ 5, 0x0e31, 0, {0xba,0x81,0x02,0x80,0x03} },
412{ 3, 0x0e36, 0, {0x02,0x0e,0xc5} },
413{ 14, 0x0e39, 0, {0x90,0x7f,0xec,0xe0,0xfa,0x24,0x20,0xfa,0xe4,0x34,0x17,0xfc,0x8a,0x82} },
414{ 14, 0x0e47, 0, {0x8c,0x83,0xe0,0xfa,0x90,0x7f,0x00,0xf0,0x90,0x7f,0xb5,0x74,0x01,0xf0} },
415{ 3, 0x0e55, 0, {0x02,0x0e,0xcd} },
416{ 5, 0x0e58, 0, {0xbb,0x0b,0x02,0x80,0x03} },
417{ 3, 0x0e5d, 0, {0x02,0x0e,0xa9} },
418{ 13, 0x0e60, 0, {0x90,0x17,0x20,0xe4,0xf0,0x90,0x7f,0xec,0xe0,0xfa,0xba,0x01,0x1a} },
419{ 8, 0x0e6d, 0, {0x90,0x7f,0xed,0xe0,0xfa,0xba,0x00,0x12} },
420{ 14, 0x0e75, 0, {0x90,0x7f,0xea,0xe0,0xfa,0x90,0x17,0x21,0xf0,0xc0,0x03,0x12,0x04,0xe2} },
421{ 4, 0x0e83, 0, {0xd0,0x03,0x80,0x46} },
422{ 8, 0x0e87, 0, {0x90,0x7f,0xec,0xe0,0xfa,0xba,0x02,0x3e} },
423{ 8, 0x0e8f, 0, {0x90,0x7f,0xed,0xe0,0xfa,0xba,0x00,0x36} },
424{ 13, 0x0e97, 0, {0xc0,0x03,0x12,0x04,0xef,0xd0,0x03,0x90,0x7f,0xea,0xe0,0xfa,0x90} },
425{ 5, 0x0ea4, 0, {0x17,0x22,0xf0,0x80,0x24} },
426{ 5, 0x0ea9, 0, {0xbb,0x12,0x02,0x80,0x17} },
427{ 5, 0x0eae, 0, {0xbb,0x81,0x02,0x80,0x0d} },
428{ 5, 0x0eb3, 0, {0xbb,0x83,0x02,0x80,0x08} },
429{ 5, 0x0eb8, 0, {0xbb,0x82,0x02,0x80,0x03} },
430{ 3, 0x0ebd, 0, {0xbb,0x84,0x05} },
431{ 5, 0x0ec0, 0, {0x12,0x06,0x4e,0x80,0x08} },
432{ 8, 0x0ec5, 0, {0x90,0x7f,0xb4,0x74,0x03,0xf0,0x80,0x06} },
433{ 6, 0x0ecd, 0, {0x90,0x7f,0xb4,0x74,0x02,0xf0} },
434{ 2, 0x0ed3, 0, {0xd0,0x86} },
435{ 14, 0x0ed5, 0, {0xd0,0xd0,0xd0,0x01,0xd0,0x00,0xd0,0x07,0xd0,0x06,0xd0,0x05,0xd0,0x04} },
436{ 13, 0x0ee3, 0, {0xd0,0x03,0xd0,0x02,0xd0,0x83,0xd0,0x82,0xd0,0xf0,0xd0,0xe0,0x32} },
437{ 11, 0x0ef0, 0, {0x90,0x7f,0xec,0xe0,0xf5,0x5a,0xc3,0x94,0x01,0x40,0x1d} },
438{ 7, 0x0efb, 0, {0xc3,0x74,0x07,0x95,0x5a,0x40,0x16} },
439{ 13, 0x0f02, 0, {0xe5,0x5a,0x24,0xff,0x25,0xe0,0xfa,0x24,0xc6,0xf5,0x82,0xe4,0x34} },
440{ 9, 0x0f0f, 0, {0x7f,0xf5,0x83,0xaa,0x59,0xea,0xf0,0x80,0x22} },
441{ 7, 0x0f18, 0, {0xc3,0xe5,0x5a,0x94,0x81,0x40,0x1b} },
442{ 7, 0x0f1f, 0, {0xc3,0x74,0x87,0x95,0x5a,0x40,0x14} },
443{ 13, 0x0f26, 0, {0xe5,0x5a,0x24,0xff,0x25,0xe0,0xfa,0x24,0xb6,0xf5,0x82,0xe4,0x34} },
444{ 7, 0x0f33, 0, {0x7f,0xf5,0x83,0xaa,0x59,0xea,0xf0} },
445{ 1, 0x0f3a, 0, {0x22} },
446{ 14, 0x0f3b, 0, {0x09,0x02,0xba,0x00,0x03,0x01,0x00,0x40,0x00,0x09,0x04,0x00,0x00,0x00} },
447{ 14, 0x0f49, 0, {0x01,0x01,0x00,0x00,0x09,0x24,0x01,0x00,0x01,0x3d,0x00,0x01,0x01,0x0c} },
448{ 14, 0x0f57, 0, {0x24,0x02,0x01,0x10,0x07,0x00,0x02,0x03,0x00,0x00,0x00,0x0d,0x24,0x06} },
449{ 14, 0x0f65, 0, {0x03,0x01,0x02,0x15,0x00,0x03,0x00,0x03,0x00,0x00,0x09,0x24,0x03,0x02} },
450{ 14, 0x0f73, 0, {0x01,0x01,0x00,0x01,0x00,0x09,0x24,0x03,0x04,0x02,0x03,0x00,0x03,0x00} },
451{ 14, 0x0f81, 0, {0x09,0x24,0x03,0x05,0x03,0x06,0x00,0x01,0x00,0x09,0x04,0x01,0x00,0x00} },
452{ 14, 0x0f8f, 0, {0x01,0x02,0x00,0x00,0x09,0x04,0x01,0x01,0x01,0x01,0x02,0x00,0x00,0x07} },
453{ 14, 0x0f9d, 0, {0x24,0x01,0x02,0x01,0x01,0x00,0x0b,0x24,0x02,0x01,0x02,0x02,0x10,0x01} },
454{ 14, 0x0fab, 0, {0x80,0xbb,0x00,0x09,0x05,0x88,0x05,0x00,0x01,0x01,0x00,0x00,0x07,0x25} },
455{ 14, 0x0fb9, 0, {0x01,0x00,0x00,0x00,0x00,0x09,0x04,0x02,0x00,0x02,0x00,0x00,0x00,0x00} },
456{ 14, 0x0fc7, 0, {0x07,0x05,0x82,0x02,0x40,0x00,0x00,0x07,0x05,0x02,0x02,0x40,0x00,0x00} },
457{ 14, 0x0fd5, 0, {0x09,0x04,0x02,0x01,0x03,0x00,0x00,0x00,0x00,0x07,0x05,0x82,0x02,0x40} },
458{ 14, 0x0fe3, 0, {0x00,0x00,0x07,0x05,0x02,0x02,0x40,0x00,0x00,0x09,0x05,0x89,0x05,0xa0} },
459{ 10, 0x0ff1, 0, {0x01,0x01,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0x00} },
460{ 14, 0x0ffb, 0, {0x12,0x01,0x00,0x01,0x00,0x00,0x00,0x40,0x47,0x05,0x99,0x99,0x00,0x01} },
461{ 14, 0x1009, 0, {0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x09,0x02,0xba} },
462{ 4, 0x1017, 0, {0x00,0x03,0x01,0x00} },
463{ 2, 0x101b, 0, {0x7a,0x00} },
464{ 3, 0x101d, 0, {0xba,0x05,0x00} },
465{ 2, 0x1020, 0, {0x50,0x17} },
466{ 8, 0x1022, 0, {0x90,0x7f,0xa5,0xe0,0xfb,0x30,0xe0,0x05} },
467{ 5, 0x102a, 0, {0x90,0x00,0x01,0x80,0x0d} },
468{ 10, 0x102f, 0, {0xc0,0x02,0x12,0x01,0xdd,0xd0,0x02,0x0a,0x80,0xe4} },
469{ 3, 0x1039, 0, {0x90,0x00,0x01} },
470{ 1, 0x103c, 0, {0x22} },
471{ 14, 0x103d, 0, {0x90,0x7d,0xc1,0xe0,0xf9,0xa3,0xe0,0xfa,0xa3,0xe0,0xfb,0x7c,0x00,0x7d} },
472{ 4, 0x104b, 0, {0x7e,0xeb,0x60,0x12} },
473{ 14, 0x104f, 0, {0x89,0x82,0x8a,0x83,0xe0,0xa3,0xa9,0x82,0xaa,0x83,0x8c,0x82,0x8d,0x83} },
474{ 4, 0x105d, 0, {0xf0,0x0c,0xdb,0xee} },
475{ 8, 0x1061, 0, {0x90,0x7d,0xc3,0xe0,0x90,0x7f,0xb9,0xf0} },
476{ 1, 0x1069, 0, {0x22} },
477{ 14, 0x106a, 0, {0x90,0x7d,0xc1,0xe0,0xf9,0xa3,0xe0,0xfa,0xa3,0xe0,0xfb,0x7c,0xc4,0x7d} },
478{ 4, 0x1078, 0, {0x7d,0xeb,0x60,0xe5} },
479{ 14, 0x107c, 0, {0x8c,0x82,0x8d,0x83,0xe0,0x0c,0x89,0x82,0x8a,0x83,0xf0,0xa3,0xa9,0x82} },
480{ 4, 0x108a, 0, {0xaa,0x83,0xdb,0xee} },
481{ 1, 0x108e, 0, {0x22} },
482{ 14, 0x108f, 0, {0x90,0x7f,0xa5,0x74,0x80,0xf0,0x05,0x86,0x90,0x7d,0xc1,0xe0,0x05,0x86} },
483{ 14, 0x109d, 0, {0xa3,0xf0,0x12,0x10,0x1b,0x90,0x7f,0xa6,0x05,0x86,0xa3,0xa3,0xe0,0xf9} },
484{ 5, 0x10ab, 0, {0x60,0x16,0xa3,0x05,0x86} },
485{ 13, 0x10b0, 0, {0x90,0x7f,0xa6,0x05,0x86,0xe0,0xa3,0x05,0x86,0xf0,0xc0,0x01,0x12} },
486{ 6, 0x10bd, 0, {0x10,0x1b,0xd0,0x01,0xd9,0xed} },
487{ 6, 0x10c3, 0, {0x90,0x7f,0xa5,0x74,0x40,0xf0} },
488{ 1, 0x10c9, 0, {0x22} },
489{ 8, 0x10ca, 0, {0x90,0x88,0x02,0x74,0x01,0xf0,0x7a,0x00} },
490{ 3, 0x10d2, 0, {0xba,0xff,0x00} },
491{ 2, 0x10d5, 0, {0x50,0x0a} },
492{ 10, 0x10d7, 0, {0xc0,0x02,0x12,0x01,0xdd,0xd0,0x02,0x0a,0x80,0xf1} },
493{ 1, 0x10e1, 0, {0x22} },
494{ 5, 0x10e2, 0, {0xe5,0x6b,0xb4,0xc0,0x08} },
495{ 8, 0x10e7, 0, {0x90,0x88,0x03,0xe5,0x6c,0xf0,0x80,0x06} },
496{ 6, 0x10ef, 0, {0x90,0x88,0x02,0xe5,0x6c,0xf0} },
497{ 4, 0x10f5, 0, {0x7a,0x00,0x7b,0x00} },
498{ 11, 0x10f9, 0, {0xc3,0xea,0x94,0x32,0xeb,0x64,0x80,0x94,0x80,0x50,0x07} },
499{ 5, 0x1104, 0, {0x0a,0xba,0x00,0x01,0x0b} },
500{ 2, 0x1109, 0, {0x80,0xee} },
501{ 1, 0x110b, 0, {0x22} },
502{ 10, 0x110c, 0, {0x90,0x88,0x03,0xe5,0x6d,0xf0,0x05,0x39,0x7a,0x00} },
503{ 3, 0x1116, 0, {0xba,0x28,0x00} },
504{ 2, 0x1119, 0, {0x50,0x03} },
505{ 3, 0x111b, 0, {0x0a,0x80,0xf8} },
506{ 5, 0x111e, 0, {0xe5,0x39,0xb4,0x10,0x08} },
507{ 8, 0x1123, 0, {0x90,0x88,0x02,0x74,0xc0,0xf0,0x80,0x0e} },
508{ 5, 0x112b, 0, {0xe5,0x39,0xb4,0x20,0x09} },
509{ 9, 0x1130, 0, {0x90,0x88,0x02,0x74,0x80,0xf0,0x75,0x39,0x00} },
510{ 2, 0x1139, 0, {0x7a,0x00} },
511{ 3, 0x113b, 0, {0xba,0x28,0x00} },
512{ 2, 0x113e, 0, {0x50,0x03} },
513{ 3, 0x1140, 0, {0x0a,0x80,0xf8} },
514{ 1, 0x1143, 0, {0x22} },
515{ 4, 0x1144, 0, {0xe5,0x6f,0x60,0x02} },
516{ 2, 0x1148, 0, {0x80,0x07} },
517{ 7, 0x114a, 0, {0x7a,0x00,0x75,0x39,0x00,0x80,0x05} },
518{ 5, 0x1151, 0, {0x7a,0x40,0x75,0x39,0x10} },
519{ 9, 0x1156, 0, {0xe5,0x6e,0x2a,0xfa,0xe5,0x6e,0x25,0x39,0xf5} },
520{ 10, 0x115f, 0, {0x39,0x90,0x88,0x02,0x74,0x80,0x2a,0xf0,0x7a,0x00} },
521{ 8, 0x1169, 0, {0xc3,0xea,0x64,0x80,0x94,0xa8,0x50,0x03} },
522{ 3, 0x1171, 0, {0x0a,0x80,0xf5} },
523{ 1, 0x1174, 0, {0x22} },
524{ 6, 0x1175, 0, {0xaa,0x70,0xab,0x71,0xac,0x72} },
525{ 12, 0x117b, 0, {0x8a,0x82,0x8b,0x83,0x8c,0xf0,0x12,0x14,0xee,0xfd,0x60,0x18} },
526{ 13, 0x1187, 0, {0x8d,0x6d,0xc0,0x02,0xc0,0x03,0xc0,0x04,0x12,0x11,0x0c,0xd0,0x04} },
527{ 9, 0x1194, 0, {0xd0,0x03,0xd0,0x02,0x0a,0xba,0x00,0x01,0x0b} },
528{ 2, 0x119d, 0, {0x80,0xdc} },
529{ 1, 0x119f, 0, {0x22} },
530{ 13, 0x11a0, 0, {0xe5,0x73,0xc4,0x54,0x0f,0xfa,0x53,0x02,0x0f,0xc3,0x74,0x09,0x9a} },
531{ 2, 0x11ad, 0, {0x50,0x06} },
532{ 6, 0x11af, 0, {0x74,0x37,0x2a,0xfb,0x80,0x04} },
533{ 4, 0x11b5, 0, {0x74,0x30,0x2a,0xfb} },
534{ 12, 0x11b9, 0, {0x8b,0x6d,0xc0,0x03,0x12,0x11,0x0c,0xd0,0x03,0xaa,0x73,0x53} },
535{ 8, 0x11c5, 0, {0x02,0x0f,0xc3,0x74,0x09,0x9a,0x50,0x06} },
536{ 6, 0x11cd, 0, {0x74,0x37,0x2a,0xfb,0x80,0x04} },
537{ 4, 0x11d3, 0, {0x74,0x30,0x2a,0xfb} },
538{ 5, 0x11d7, 0, {0x8b,0x6d,0x12,0x11,0x0c} },
539{ 1, 0x11dc, 0, {0x22} },
540{ 7, 0x11dd, 0, {0x90,0x7d,0xc3,0xe0,0xfa,0x60,0x0f} },
541{ 12, 0x11e4, 0, {0x90,0x7d,0xc1,0xe0,0xf5,0x6e,0x90,0x7d,0xc2,0xe0,0xf5,0x6f} },
542{ 3, 0x11f0, 0, {0x12,0x11,0x44} },
543{ 12, 0x11f3, 0, {0x90,0x7d,0xff,0xe4,0xf0,0x75,0x70,0xc4,0x75,0x71,0x7d,0x75} },
544{ 5, 0x11ff, 0, {0x72,0x01,0x12,0x11,0x75} },
545{ 1, 0x1204, 0, {0x22} },
546{ 2, 0x1205, 0, {0x7a,0x04} },
547{ 3, 0x1207, 0, {0xba,0x40,0x00} },
548{ 2, 0x120a, 0, {0x50,0x36} },
549{ 14, 0x120c, 0, {0xea,0x24,0xc0,0xf5,0x82,0xe4,0x34,0x7d,0xf5,0x83,0xe0,0xfb,0x7c,0x00} },
550{ 3, 0x121a, 0, {0xbc,0x08,0x00} },
551{ 2, 0x121d, 0, {0x50,0x20} },
552{ 6, 0x121f, 0, {0x8b,0x05,0xed,0x30,0xe7,0x0b} },
553{ 11, 0x1225, 0, {0x90,0x7f,0x96,0x74,0x42,0xf0,0x74,0xc3,0xf0,0x80,0x08} },
554{ 8, 0x1230, 0, {0x90,0x7f,0x96,0xe4,0xf0,0x74,0x81,0xf0} },
555{ 7, 0x1238, 0, {0xeb,0x25,0xe0,0xfb,0x0c,0x80,0xdb} },
556{ 3, 0x123f, 0, {0x0a,0x80,0xc5} },
557{ 1, 0x1242, 0, {0x22} },
558{ 4, 0x1243, 0, {0x7a,0x00,0x7b,0xef} },
559{ 3, 0x1247, 0, {0xba,0x10,0x00} },
560{ 2, 0x124a, 0, {0x50,0x20} },
561{ 14, 0x124c, 0, {0x74,0x11,0x2b,0xfb,0x24,0x00,0xfc,0xe4,0x34,0x18,0xfd,0x8c,0x82,0x8d} },
562{ 14, 0x125a, 0, {0x83,0xe4,0xf0,0xea,0x24,0x00,0xf5,0x82,0xe4,0x34,0x19,0xf5,0x83,0xe4} },
563{ 4, 0x1268, 0, {0xf0,0x0a,0x80,0xdb} },
564{ 1, 0x126c, 0, {0x22} },
565{ 14, 0x126d, 0, {0x74,0xf8,0x24,0x00,0xf5,0x82,0x74,0x03,0x34,0x84,0xf5,0x83,0xe4,0xf0} },
566{ 14, 0x127b, 0, {0x74,0xf9,0x24,0x00,0xf5,0x82,0x74,0x03,0x34,0x84,0xf5,0x83,0xe4,0xf0} },
567{ 14, 0x1289, 0, {0x74,0xfa,0x24,0x00,0xf5,0x82,0x74,0x03,0x34,0x84,0xf5,0x83,0xe4,0xf0} },
568{ 14, 0x1297, 0, {0x74,0xfb,0x24,0x00,0xf5,0x82,0x74,0x03,0x34,0x84,0xf5,0x83,0xe4,0xf0} },
569{ 14, 0x12a5, 0, {0x74,0xff,0x24,0x00,0xf5,0x82,0x74,0x03,0x34,0x84,0xf5,0x83,0xe4,0xf0} },
570{ 1, 0x12b3, 0, {0x22} },
571{ 14, 0x12b4, 0, {0x12,0x03,0xcb,0x12,0x12,0x6d,0x7a,0xc0,0x7b,0x87,0x7c,0x01,0x74,0x01} },
572{ 14, 0x12c2, 0, {0x2a,0xfd,0xe4,0x3b,0xfe,0x8c,0x07,0x8a,0x82,0x8b,0x83,0x8c,0xf0,0x74} },
573{ 14, 0x12d0, 0, {0x01,0x12,0x14,0xbf,0x2d,0xfa,0xe4,0x3e,0xfb,0x8f,0x04,0x8d,0x82,0x8e} },
574{ 14, 0x12de, 0, {0x83,0x8f,0xf0,0x74,0x06,0x12,0x14,0xbf,0x74,0x01,0x2a,0xfd,0xe4,0x3b} },
575{ 14, 0x12ec, 0, {0xfe,0x8c,0x07,0x8a,0x82,0x8b,0x83,0x8c,0xf0,0xe4,0x12,0x14,0xbf,0x74} },
576{ 14, 0x12fa, 0, {0x01,0x2d,0xfa,0xe4,0x3e,0xfb,0x8f,0x04,0x8d,0x82,0x8e,0x83,0x8f,0xf0} },
577{ 14, 0x1308, 0, {0x74,0x0b,0x12,0x14,0xbf,0x74,0x01,0x2a,0xfd,0xe4,0x3b,0xfe,0x8c,0x07} },
578{ 14, 0x1316, 0, {0x8a,0x82,0x8b,0x83,0x8c,0xf0,0x74,0x08,0x12,0x14,0xbf,0x74,0x01,0x2d} },
579{ 14, 0x1324, 0, {0xfa,0xe4,0x3e,0xfb,0x8f,0x04,0x8d,0x82,0x8e,0x83,0x8f,0xf0,0x74,0x01} },
580{ 14, 0x1332, 0, {0x12,0x14,0xbf,0x2a,0xfd,0xe4,0x3b,0xfe,0x8c,0x07,0x8a,0x82,0x8b,0x83} },
581{ 14, 0x1340, 0, {0x8c,0xf0,0xe4,0x12,0x14,0xbf,0x74,0x01,0x2d,0xfa,0xe4,0x3e,0xfb,0x8f} },
582{ 14, 0x134e, 0, {0x04,0x8d,0x82,0x8e,0x83,0x8f,0xf0,0x74,0x03,0x12,0x14,0xbf,0x7d,0x00} },
583{ 3, 0x135c, 0, {0xbd,0x06,0x00} },
584{ 2, 0x135f, 0, {0x50,0x12} },
585{ 11, 0x1361, 0, {0x8a,0x82,0x8b,0x83,0x8c,0xf0,0x0a,0xba,0x00,0x01,0x0b} },
586{ 7, 0x136c, 0, {0xe4,0x12,0x14,0xbf,0x0d,0x80,0xe9} },
587{ 13, 0x1373, 0, {0x8a,0x82,0x8b,0x83,0x8c,0xf0,0xe5,0x74,0x12,0x14,0xbf,0x74,0xf9} },
588{ 14, 0x1380, 0, {0x24,0x00,0xf5,0x82,0x74,0x03,0x34,0x84,0xf5,0x83,0x74,0x0f,0xf0,0x74} },
589{ 14, 0x138e, 0, {0xfe,0x24,0x00,0xf5,0x82,0x74,0x03,0x34,0x84,0xf5,0x83,0x74,0x01,0xf0} },
590{ 6, 0x139c, 0, {0x12,0x03,0xe1,0x12,0x04,0xf7} },
591{ 1, 0x13a2, 0, {0x22} },
592{ 13, 0x13a3, 0, {0x90,0x7d,0xc1,0xe0,0xfa,0x24,0x00,0xfb,0xe4,0x34,0x19,0xfc,0x90} },
593{ 14, 0x13b0, 0, {0x7d,0xc2,0xe0,0xfd,0x8b,0x82,0x8c,0x83,0xf0,0x75,0xf0,0x11,0xea,0xa4} },
594{ 3, 0x13be, 0, {0xfa,0x7b,0x00} },
595{ 3, 0x13c1, 0, {0xbb,0x10,0x00} },
596{ 2, 0x13c4, 0, {0x50,0x24} },
597{ 14, 0x13c6, 0, {0xea,0x24,0x00,0xfc,0xe4,0x34,0x18,0xfd,0xeb,0x2c,0xfc,0xe4,0x3d,0xfd} },
598{ 14, 0x13d4, 0, {0x74,0x04,0x2b,0x24,0xc0,0xf5,0x82,0xe4,0x34,0x7d,0xf5,0x83,0xe0,0xfe} },
599{ 8, 0x13e2, 0, {0x8c,0x82,0x8d,0x83,0xf0,0x0b,0x80,0xd7} },
600{ 14, 0x13ea, 0, {0xea,0x24,0x00,0xfa,0xe4,0x34,0x18,0xfb,0x74,0x10,0x2a,0xf5,0x82,0xe4} },
601{ 5, 0x13f8, 0, {0x3b,0xf5,0x83,0xe4,0xf0} },
602{ 1, 0x13fd, 0, {0x22} },
603{ 4, 0x13fe, 0, {0xe5,0x76,0x60,0x02} },
604{ 2, 0x1402, 0, {0x80,0x16} },
605{ 12, 0x1404, 0, {0x74,0x0f,0x55,0x75,0xfa,0x8a,0x75,0x24,0x00,0xf5,0x82,0xe4} },
606{ 10, 0x1410, 0, {0x34,0x19,0xf5,0x83,0xe0,0xf5,0x74,0x12,0x12,0xb4} },
607{ 10, 0x141a, 0, {0x12,0x10,0xca,0x75,0x6e,0x00,0x75,0x6f,0x00,0x12} },
608{ 6, 0x1424, 0, {0x11,0x44,0x75,0x70,0xb9,0x75} },
609{ 6, 0x142a, 0, {0x71,0x14,0x75,0x72,0x02,0x12} },
610{ 11, 0x1430, 0, {0x11,0x75,0xe5,0x76,0xb4,0x02,0x04,0x74,0x01,0x80,0x01} },
611{ 1, 0x143b, 0, {0xe4} },
612{ 3, 0x143c, 0, {0xfa,0x70,0x0f} },
613{ 12, 0x143f, 0, {0x74,0x01,0x25,0x75,0xf5,0x73,0xc0,0x02,0x12,0x11,0xa0,0xd0} },
614{ 3, 0x144b, 0, {0x02,0x80,0x0a} },
615{ 10, 0x144e, 0, {0x85,0x75,0x73,0xc0,0x02,0x12,0x11,0xa0,0xd0,0x02} },
616{ 12, 0x1458, 0, {0x75,0x6e,0x00,0x75,0x6f,0x01,0xc0,0x02,0x12,0x11,0x44,0xd0} },
617{ 4, 0x1464, 0, {0x02,0xea,0x70,0x1a} },
618{ 13, 0x1468, 0, {0x75,0xf0,0x11,0xe5,0x75,0xa4,0xfa,0x24,0x00,0xfa,0xe4,0x34,0x18} },
619{ 9, 0x1475, 0, {0xfb,0x8a,0x70,0x8b,0x71,0x75,0x72,0x01,0x12} },
620{ 4, 0x147e, 0, {0x11,0x75,0x80,0x36} },
621{ 2, 0x1482, 0, {0x7a,0x00} },
622{ 3, 0x1484, 0, {0xba,0x10,0x00} },
623{ 2, 0x1487, 0, {0x50,0x2f} },
624{ 13, 0x1489, 0, {0xea,0x24,0x00,0xf5,0x82,0xe4,0x34,0x19,0xf5,0x83,0xe0,0xfb,0xe5} },
625{ 4, 0x1496, 0, {0x75,0xb5,0x03,0x1b} },
626{ 14, 0x149a, 0, {0x75,0xf0,0x11,0xea,0xa4,0xfb,0x24,0x00,0xfb,0xe4,0x34,0x18,0xfc,0x8b} },
627{ 9, 0x14a8, 0, {0x70,0x8c,0x71,0x75,0x72,0x01,0xc0,0x02,0x12} },
628{ 4, 0x14b1, 0, {0x11,0x75,0xd0,0x02} },
629{ 3, 0x14b5, 0, {0x0a,0x80,0xcc} },
630{ 1, 0x14b8, 0, {0x22} },
631{ 6, 0x14b9, 0, {0x50,0x72,0x6f,0x67,0x20,0x00} },
632{ 14, 0x14bf, 0, {0xc8,0xc0,0xe0,0xc8,0xc0,0xe0,0xe5,0xf0,0x60,0x0b,0x14,0x60,0x0f,0x14} },
633{ 7, 0x14cd, 0, {0x60,0x11,0x14,0x60,0x12,0x80,0x15} },
634{ 7, 0x14d4, 0, {0xd0,0xe0,0xa8,0x82,0xf6,0x80,0x0e} },
635{ 5, 0x14db, 0, {0xd0,0xe0,0xf0,0x80,0x09} },
636{ 4, 0x14e0, 0, {0xd0,0xe0,0x80,0x05} },
637{ 5, 0x14e4, 0, {0xd0,0xe0,0xa8,0x82,0xf2} },
638{ 4, 0x14e9, 0, {0xc8,0xd0,0xe0,0xc8} },
639{ 1, 0x14ed, 0, {0x22} },
640{ 14, 0x14ee, 0, {0xc8,0xc0,0xe0,0xe5,0xf0,0x60,0x0d,0x14,0x60,0x0f,0x14,0x60,0x0f,0x14} },
641{ 6, 0x14fc, 0, {0x60,0x10,0x74,0xff,0x80,0x0f} },
642{ 5, 0x1502, 0, {0xa8,0x82,0xe6,0x80,0x0a} },
643{ 3, 0x1507, 0, {0xe0,0x80,0x07} },
644{ 4, 0x150a, 0, {0xe4,0x93,0x80,0x03} },
645{ 3, 0x150e, 0, {0xa8,0x82,0xe2} },
646{ 4, 0x1511, 0, {0xf8,0xd0,0xe0,0xc8} },
647{ 1, 0x1515, 0, {0x22} },
648{ 0, 0x0000, 1, {0} }
649
650};
651
652static unsigned char bitstream[] = {
653
6540x00,0x09,0x0F,0xF0,0x0F,0xF0,0x0F,0xF0, 0x0F,0xF0,0x00,0x00,0x01,0x61,0x00,0x0D,
6550x64,0x61,0x62,0x75,0x73,0x62,0x74,0x72, 0x2E,0x6E,0x63,0x64,0x00,0x62,0x00,0x0B,
6560x73,0x31,0x30,0x78,0x6C,0x76,0x71,0x31, 0x30,0x30,0x00,0x63,0x00,0x0B,0x31,0x39,
6570x39,0x39,0x2F,0x30,0x39,0x2F,0x32,0x34, 0x00,0x64,0x00,0x09,0x31,0x30,0x3A,0x34,
6580x32,0x3A,0x34,0x36,0x00,0x65,0x00,0x00, 0x2E,0xC0,0xFF,0x20,0x17,0x5F,0x9F,0x5B,
6590xFE,0xFB,0xBB,0xB7,0xBB,0xBB,0xFB,0xBF, 0xAF,0xEF,0xFB,0xDF,0xB7,0xFB,0xFB,0x7F,
6600xBF,0xB7,0xEF,0xF2,0xFF,0xFB,0xFE,0xFF, 0xFF,0xEF,0xFF,0xFE,0xFF,0xBF,0xFF,0xFF,
6610xFF,0xFF,0xAF,0xFF,0xFA,0xFF,0xFF,0xFF, 0xC9,0xFF,0xFF,0xFF,0xDF,0xFF,0xFF,0xFF,
6620xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFB,0xFF,0xA3,0xFF,0xFB,
6630xFE,0xFF,0xBF,0xEF,0xE3,0xFE,0xFF,0xBF, 0xE3,0xFE,0xFF,0xBF,0x6F,0xFB,0xF6,0xFF,
6640xBF,0xFF,0x47,0xFF,0xFF,0x9F,0xEE,0xF9, 0xFE,0xCF,0x9F,0xEF,0xFB,0xCF,0x9B,0xEE,
6650xF8,0xFE,0xEF,0x8F,0xEE,0xFB,0xFE,0x0B, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
6660xFF,0xFF,0xBF,0xFF,0xFF,0xFB,0xFF,0xFF, 0xBF,0xFF,0xFF,0xFC,0x17,0xFF,0xFF,0xFF,
6670xFF,0xFF,0xFF,0x7F,0xFF,0xFF,0xFF,0x7F, 0xFF,0xFF,0xFB,0xFF,0xFF,0x7F,0xFF,0xFF,
6680xFC,0x3F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFB,0xFF,0xFF,0xFF,0xFF,
6690xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0x5F,0xFF, 0xFF,0xFD,0xFF,0xFF,0xDB,0xFF,0xFD,0xFF,
6700x77,0xFF,0xFD,0xFF,0xFF,0xDF,0xFE,0xFD, 0xFF,0xFF,0xF2,0xFF,0xFF,0xFF,0xFF,0xFF,
6710xFF,0xFD,0xFF,0xFF,0xFF,0xFD,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xE1,
6720x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0x3F,0xFF,0xFF,
6730xFF,0xFF,0xFF,0xFF,0xE3,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xBF,
6740xFF,0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0x67,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
6750x7F,0xFF,0xFF,0xFF,0x7F,0xFF,0xFF,0xFF, 0xFF,0xFF,0xDF,0xFF,0xFF,0xFF,0x2F,0xFF,
6760xF3,0xFD,0xFF,0x7F,0xDE,0xF7,0xFD,0xFF, 0x7F,0xF7,0x7D,0xFF,0x7F,0xDF,0xF7,0xBD,
6770xFF,0x7F,0xFF,0x1F,0xFF,0xEF,0xFB,0xFE, 0xFF,0xBF,0xEF,0xFB,0xFE,0xFF,0xEF,0xFB,
6780xFE,0xFF,0xBF,0xEF,0xFB,0xFE,0xFF,0xFF, 0x3F,0xFE,0x7F,0x9F,0xE7,0xF9,0xFE,0x7F,
6790x9F,0xE7,0xFA,0x7F,0x9F,0xE7,0xF9,0xFE, 0x7F,0x9F,0xE7,0xFF,0xFC,0x7F,0xBF,0xBF,
6800xEF,0xFB,0xFE,0xFF,0xBF,0xEF,0xFB,0xB7, 0xBF,0xEF,0xFB,0xFE,0xFF,0xBF,0xEF,0xFB,
6810xFF,0xE0,0xFD,0xF9,0xFE,0x7F,0x9F,0xE7, 0xF9,0xFE,0x7F,0x9D,0xF9,0xFE,0x7D,0x9D,
6820xE7,0xF9,0xFE,0x7F,0x9F,0xED,0xED,0xFF, 0xFD,0xFF,0x7F,0xDF,0xF7,0xFD,0xFF,0x7F,
6830xDF,0xFD,0xFF,0x7F,0xDF,0xF7,0xFD,0xFF, 0x7F,0xDF,0xFF,0x9B,0xFF,0xEF,0xFB,0xFE,
6840xFB,0xBF,0xEF,0xBB,0xFE,0xFF,0xAF,0xBB, 0xBE,0xFF,0xBF,0xEF,0xFB,0xFE,0xFF,0xFF,
6850xB7,0xBF,0xDB,0xF6,0xBD,0xBF,0x6B,0xDB, 0xF6,0xF9,0xBF,0x5B,0xD6,0xF9,0xBF,0x6F,
6860xDB,0xF6,0xFD,0xBF,0xFF,0x0E,0xFF,0xFF, 0xFF,0xFF,0x5F,0xFF,0xF7,0xFF,0xFF,0x7F,
6870xF7,0xBD,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xDF,0x9F,0xFF,0xFF,0xFF,0xFE,0xFF,
6880xFF,0xEF,0xFE,0xFE,0xFF,0xFF,0x77,0xFF, 0xFB,0xFB,0xFF,0xFF,0xFF,0xFF,0xF8,0x3F,
6890xFF,0xFD,0xFF,0xFF,0xFF,0xFD,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
6900xFF,0xFF,0xFF,0xF4,0x7F,0xFF,0xFE,0xFD, 0xBE,0xFF,0xDF,0xFE,0xFF,0xFF,0xEF,0x7F,
6910xFF,0xCF,0xFF,0xCF,0xFF,0xFF,0xFF,0xDF, 0xE6,0xFF,0xFF,0x7F,0xDF,0xF7,0xDD,0x7F,
6920x7F,0xDF,0xF7,0xFF,0x7F,0xDF,0xD7,0xFD, 0xFF,0x7F,0xDF,0xF7,0xFF,0xCD,0xFF,0xF2,
6930xFF,0xFF,0x4F,0x7F,0xF4,0xFF,0xFF,0xFF, 0xE7,0xEF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
6940xFF,0xFF,0xBB,0xFF,0xEF,0xFF,0xFE,0xFF, 0xFF,0xFF,0xEF,0xFF,0xFF,0xEF,0xFF,0xFB,
6950xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x65, 0xEF,0xFF,0xFF,0x7F,0xFF,0xFD,0xEF,0xFF,
6960xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFE,0xCF,0xDF,0xFE,0xFF,
6970xFF,0xFB,0xFF,0xFF,0xFF,0xFF,0xF3,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
6980xFE,0xDF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
6990xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xBF,0xFF, 0xFF,0xFF,0xE3,0x7F,0xFF,0xFF,0xFF,0xFF,
7000xFF,0xFF,0xEF,0xEB,0xFF,0xFE,0xBF,0xFF, 0xEB,0xFF,0xFC,0x7F,0xFF,0xFF,0xFF,0xEE,
7010xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xDD,0xFF, 0xD6,0xFF,0xFD,0xBF,0xFF,0xFB,0xFF,0xFE,
7020xFD,0xFF,0xFF,0xFD,0xEF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xDE,0xFF,0xFF,0xFF,0xFF,
7030xFF,0xFF,0xBF,0xFF,0xFD,0xFF,0x7F,0xBF, 0xFF,0x5F,0xDF,0xFF,0xFF,0xBF,0x77,0xFF,
7040xFF,0xFF,0x7F,0xD7,0xFF,0xFF,0xFF,0xFF, 0xFF,0xC3,0xFF,0xFF,0xFF,0xFF,0xDF,0xEF,
7050xFF,0xFF,0xFE,0xFB,0xFF,0xFF,0xDF,0xBF, 0xFF,0xFF,0xFF,0xFF,0xED,0xFF,0xB7,0xFF,
7060xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
7070xFF,0xFF,0xFF,0xAF,0x7F,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
7080xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xDF,0xBF,0xDF,0xF3,0xFD,0xFB,0xFF,0x5B,
7090xFD,0xFF,0xBF,0xEF,0xF7,0xFF,0xFF,0x7D, 0xFF,0xFF,0xFF,0xFF,0xF8,0x3B,0xFF,0xBF,
7100x6F,0xFF,0xFE,0xFF,0xBF,0xFF,0xEB,0x7D, 0xFF,0xEF,0xFB,0xFE,0xFF,0xFF,0xFF,0xFF,
7110xFF,0xF2,0x7F,0xFC,0xFF,0x3F,0xDF,0xED, 0xFE,0xFF,0xFF,0xFF,0xFF,0xEF,0x5F,0xF7,
7120xB5,0xFF,0xEF,0xFF,0xFF,0xFF,0xE0,0x3F, 0x9F,0x9E,0xFF,0xFF,0xEF,0xFF,0xDF,0xFF,
7130xBF,0x5F,0xBF,0xCF,0xF3,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0x69,0xAF,0x33,0xFD,0xFF,
7140xFB,0xFF,0xFF,0xFF,0xFF,0xFC,0xFF,0x7F, 0xD9,0xFF,0xDF,0xFF,0xFF,0xFF,0xFF,0xF5,
7150xA3,0xDF,0x6E,0xDE,0xFF,0xFF,0xBD,0xFF, 0xFF,0xFE,0xFF,0xFF,0xFF,0xFE,0xE7,0xFD,
7160xFF,0xFF,0xFF,0xF9,0xEF,0xC6,0xFE,0xB7, 0xAD,0xE5,0xF9,0xFF,0xFF,0xFF,0xCF,0xFF,
7170xFF,0xFF,0xCD,0xFB,0x7F,0xFF,0xFF,0xFF, 0xF9,0xF6,0x0F,0xDF,0xEC,0xCF,0x7F,0xFF,
7180xFB,0x7F,0xFF,0xFF,0xFF,0xFD,0xFF,0xFE, 0xF9,0xFD,0x7F,0xFF,0x7F,0xFF,0xF9,0x5B,
7190xFF,0x73,0xDC,0xFD,0x7B,0xDF,0xFF,0xFF, 0xFF,0x7B,0xFF,0xFF,0xF7,0x53,0xD6,0xFF,
7200xFF,0xFF,0xFF,0xD8,0x9F,0xFE,0xFF,0xEF, 0x7F,0xEE,0xFF,0xFF,0xFF,0xFB,0xED,0xED,
7210xFD,0xFF,0xFE,0xFF,0xFF,0xFB,0x7F,0xFF, 0xE2,0x7F,0xFF,0x6F,0xD8,0x57,0xF7,0xFF,
7220xFF,0xFF,0xDF,0xFF,0xE8,0xFF,0xFF,0xFD, 0xFF,0xFF,0xFC,0x7F,0xFF,0xE4,0xFF,0xFB,
7230xEF,0xFB,0xFE,0xDF,0xB7,0xED,0xFF,0xFE, 0xDF,0x7F,0xFF,0xFE,0x7F,0xB7,0xFF,0xFF,
7240xFF,0xFF,0x89,0xFF,0xFF,0xCF,0xF3,0xFE, 0x7F,0xFF,0xEF,0xFF,0xFE,0x7E,0x7F,0xFB,
7250xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xF1, 0xFF,0xEB,0x7A,0xD5,0xBF,0x6F,0xDB,0xBE,
7260xFD,0xB7,0xD8,0xF6,0xE5,0xBF,0x6F,0xFB, 0xFE,0xF5,0xBD,0x7E,0x06,0xFF,0xDF,0xF7,
7270xFB,0xF6,0xFF,0x3F,0xFF,0xDB,0xFF,0xFF, 0x6F,0xFB,0xF7,0xFF,0xFF,0xFF,0xFB,0xFE,
7280xF7,0xAF,0xFF,0xB7,0xED,0xEF,0xF7,0xFE, 0xFF,0xFF,0xDF,0xFF,0xFE,0xFF,0xEF,0xFF,
7290xFF,0xFF,0xFF,0xBF,0xF7,0xFC,0x1F,0xEE, 0xFB,0xFE,0xBD,0xFF,0x7F,0x5F,0xD7,0xFD,
7300xFB,0x43,0xFF,0xFF,0xFD,0xFF,0x5F,0xFF, 0xF7,0xFF,0xF9,0x3F,0xFF,0xCF,0xF3,0xFD,
7310xF7,0x7E,0xEF,0xA7,0xF9,0xFE,0x8F,0xA7, 0xE9,0xF3,0x7E,0x9F,0xFB,0xF8,0xFF,0xFF,
7320x3F,0xFD,0x7F,0x5F,0xDF,0xFD,0xFF,0xFF, 0x5F,0xFF,0xFD,0x5F,0xFF,0xFF,0x7F,0xFD,
7330x7F,0xFD,0x9F,0xFF,0xE0,0xFF,0xFA,0xF8, 0xBE,0x6F,0x9F,0xE6,0xF8,0xBE,0x3F,0x9A,
7340xF9,0xBE,0x6F,0x9F,0xE2,0xF9,0xFE,0x6F, 0x9F,0xF9,0xFF,0xF5,0xFD,0x7F,0xCF,0xDF,
7350xFD,0xFD,0x7F,0xFF,0xF5,0xFF,0xFF,0xFF, 0xF7,0xF5,0xFD,0x0F,0xDB,0xFF,0xD3,0xFF,
7360xEB,0xFA,0xFF,0xFF,0xBF,0xFF,0xFA,0xFF, 0xFF,0xCB,0xFB,0xFE,0xFF,0xFF,0xEB,0xFA,
7370xFE,0xFF,0xFF,0xB7,0xFF,0xFF,0xFF,0xFF, 0xBF,0xFF,0xDF,0xF5,0xFF,0xFF,0xD7,0xFF,
7380xFF,0xFF,0xDF,0xD7,0xF5,0xFF,0x7F,0xFE, 0x4F,0xFF,0xFD,0xFF,0x7F,0x7F,0xFF,0xAD,
7390xEB,0xFB,0xFF,0xAD,0xFF,0xFF,0xFF,0xFF, 0xAF,0xEB,0xFB,0xFF,0xFC,0x0D,0xFF,0xFF,
7400xDF,0xD2,0xFD,0xFF,0xFF,0xFD,0xF6,0xFF, 0xFF,0x7F,0xFF,0xFF,0x1F,0xFF,0xFF,0xFF,
7410xFF,0xFB,0x3F,0x7D,0xEB,0x32,0xFE,0xBF, 0x2F,0xEB,0xFA,0xAE,0xBD,0xE0,0xFA,0x7E,
7420xBF,0xAD,0xEB,0xFA,0xFE,0xBF,0xF5,0x7F, 0xFF,0xDE,0xFE,0xE3,0xFB,0xFF,0xFF,0xFF,
7430xDF,0xEF,0x4F,0xDF,0xFF,0x7F,0xDF,0xFF, 0xF7,0xFF,0xFF,0xF8,0x7F,0xFF,0xFF,0xEF,
7440xFB,0xFF,0xFF,0xFF,0xEF,0xFF,0xFF,0xDF, 0xED,0xFB,0xDF,0xFF,0xBF,0xFF,0xFF,0xFF,
7450x81,0xFF,0xFF,0xFF,0xFF,0x3F,0xFF,0xFF, 0xFF,0xFF,0xFE,0xDD,0xFE,0xEF,0xFD,0xFF,
7460xFF,0xFB,0xFE,0xF7,0xFF,0x93,0xFD,0xFB, 0x7E,0xFF,0xFE,0x87,0xE9,0xFF,0x7F,0xB3,
7470x9F,0xFE,0xFE,0xFF,0xAF,0xFD,0xFE,0x7E, 0x3F,0xFE,0x67,0xFF,0xFF,0xF7,0xFF,0xFF,
7480xFC,0xF7,0xDF,0xFD,0xFF,0x7F,0xFF,0xFF, 0x7F,0x6D,0xFF,0xFF,0xFE,0xFF,0xFF,0x2F,
7490xFF,0xBF,0xFF,0xFF,0xEE,0xFF,0xBE,0xFF, 0xFF,0xFE,0xFF,0xEF,0xFF,0xFF,0xFE,0xFF,
7500xEF,0xFF,0xFF,0xFA,0x5F,0xFF,0xFF,0xFB, 0xFF,0xFF,0xEF,0xFF,0xFB,0xFE,0xFD,0xFF,
7510xFE,0xFF,0xFB,0xFF,0xFF,0xFF,0x7F,0xFF, 0xFE,0xBF,0xDF,0xFF,0xFB,0xFF,0xFF,0xF7,
7520xFC,0xFD,0xFF,0xFF,0xFF,0xFF,0xFF,0x7F, 0xFF,0xFF,0xFF,0xFF,0xFF,0xF2,0x7F,0xFF,
7530xFF,0xFF,0xFF,0x7F,0xFF,0xFF,0xFF,0xFF, 0xF3,0xFF,0xFF,0xFF,0xEF,0xFB,0xFF,0xFF,
7540xFF,0xDF,0xE2,0xFF,0xFF,0xFB,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFB,0xE7,0xFF,0xFD,
7550xFF,0xFF,0xFF,0xBF,0xFF,0xFF,0xFF,0xED, 0xEF,0xFD,0xFF,0xFF,0xDF,0xD7,0xF5,0xFD,
7560x7F,0x5D,0xFD,0xFF,0x7F,0xDF,0x97,0xF4, 0xFD,0x7B,0x5F,0xFF,0xC9,0xFF,0xFB,0xFE,
7570xFF,0xBF,0xFF,0x5F,0xFF,0xFF,0xF7,0xFF, 0xEF,0xFD,0xFF,0xEF,0xFF,0xFF,0xFF,0xFF,
7580xFF,0xF7,0xFF,0xD7,0xFD,0x7D,0x7F,0xFF, 0xFF,0xFF,0xFF,0xEF,0xDF,0xF7,0xFD,0xFF,
7590xBB,0xFF,0xFF,0x7F,0xFF,0xFE,0xE3,0xFF, 0xF9,0xFE,0x7F,0xBF,0xEF,0xFB,0xFE,0xFF,
7600xBF,0xF9,0xFE,0xFF,0x9F,0xEF,0xF9,0xFE, 0xFF,0xBF,0xF3,0xDA,0xFF,0x37,0xCD,0xF3,
7610x7C,0xDF,0x37,0xCD,0xF3,0x7F,0x37,0xCD, 0xF3,0x7C,0xDF,0x37,0xCC,0xF3,0x7F,0x5A,
7620xBD,0xF6,0xFD,0xBF,0x6F,0xDB,0xF6,0xFD, 0xBF,0x6F,0xDE,0xFD,0xBF,0x6F,0xDB,0xF6,
7630xFD,0xBF,0x6F,0xFE,0xF1,0x6F,0xEB,0x7A, 0xDE,0xB7,0xAD,0xEB,0x7A,0xDE,0xB7,0xAF,
7640x7A,0xDE,0xB7,0xAD,0xEB,0x7A,0xDE,0xB7, 0xFF,0x7E,0xFF,0xFE,0xCD,0xB3,0x6C,0xDB,
7650x36,0xCD,0xB3,0x6C,0xDE,0xCD,0xB3,0x6C, 0xDB,0x36,0xCD,0xB3,0x6C,0xDF,0xC9,0xBF,
7660xF7,0xBD,0xEF,0x7A,0x9E,0xA7,0xA9,0xEA, 0x7A,0xB7,0xBD,0xEA,0x7B,0xDE,0xA7,0xBD,
7670xCA,0x72,0x8D,0x91,0xFF,0xEF,0xFB,0xFE, 0xFF,0xBF,0xEF,0xFB,0xFE,0xF7,0xEF,0xFB,
7680xFE,0xFF,0xBF,0xEF,0xFB,0xFE,0xFF,0xFE, 0x87,0xFF,0xF6,0xFD,0xBF,0x6F,0xDB,0xF6,
7690xFD,0xBF,0x6F,0xF6,0xFD,0xBF,0x6F,0xDB, 0xF6,0xFD,0xBF,0x6F,0xFE,0x4F,0xFF,0xBF,
7700xEF,0xBB,0xEE,0xFB,0xBE,0xEF,0xBB,0xEF, 0xBE,0xEF,0xBB,0xEE,0xFB,0xBE,0xEF,0xBB,
7710xEF,0xFC,0x5F,0xFF,0xFF,0xFF,0x3F,0xCF, 0xF3,0xFC,0xFF,0x3F,0xCF,0xFC,0xFF,0x3F,
7720xCF,0xF3,0xFC,0xFF,0x3F,0xCF,0xFD,0x9F, 0xFE,0xBF,0xAF,0xEB,0xFA,0xFE,0xBF,0xAF,
7730xEB,0xFE,0xBF,0xAF,0xEB,0xFA,0xFE,0xBF, 0xAF,0xEB,0xFF,0xE1,0x6F,0xFD,0xFF,0x7F,
7740xDF,0xF7,0xFD,0xFF,0x7F,0xDF,0xFD,0xFF, 0x7F,0xDF,0xF7,0xFD,0xFF,0x7F,0xDF,0xFF,
7750x7A,0xBF,0xFB,0xFE,0xDF,0xB7,0xED,0xFB, 0x7E,0xDF,0xB7,0xFB,0x7E,0xDF,0xB7,0xED,
7760xFB,0x7E,0xDF,0xB7,0xFF,0xC9,0xFF,0xFF, 0xBF,0xEF,0xFB,0xFE,0xFF,0xBF,0xEF,0xFB,
7770xFF,0xBF,0xEF,0xFB,0xFE,0xFF,0xBF,0xEE, 0xFB,0xFE,0xBB,0xFF,0xFE,0xFF,0xBF,0xEF,
7780xFB,0xFE,0xFF,0xBF,0xEF,0xFE,0xFF,0xBF, 0xEF,0xFB,0xFE,0xFF,0x3F,0xCF,0xFF,0xE7,
7790xFE,0xFF,0xF5,0xFD,0x77,0x5D,0xD7,0x35, 0xDD,0x77,0xD7,0xF5,0xCD,0x7B,0x5D,0xD7,
7800xF5,0xDD,0x77,0xFE,0x27,0xFF,0xFF,0x8B, 0xE2,0xF8,0xBE,0x2F,0x8B,0xE2,0xF9,0xAF,
7810x8B,0xE2,0xF8,0xBE,0x2F,0x8B,0xE2,0xF9, 0xFE,0x1F,0xFF,0x5F,0xD7,0xF5,0xFD,0x7F,
7820x5F,0xD7,0xF5,0xFF,0x5F,0xD7,0xF5,0xFD, 0x7F,0x5F,0xD7,0xF5,0xFF,0xFA,0x3F,0xFE,
7830xBF,0xAF,0xEB,0xFA,0xFE,0xBF,0xAF,0xEB, 0xEC,0xBF,0xAF,0xEB,0xFA,0xFE,0xBF,0xAF,
7840xEB,0xFF,0xFE,0x7F,0xFD,0x7F,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
7850xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xE6, 0xFF,0xFA,0xDF,0xF7,0xFD,0xFF,0x7F,0xDF,
7860xF7,0xFC,0xFF,0xDF,0xF7,0xFD,0xFF,0x7F, 0xDF,0xF7,0xFD,0xFF,0xF5,0xFF,0xFF,0xFF,
7870xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFB,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
7880xFF,0x02,0xFF,0xFE,0xBF,0xAB,0xEB,0xFA, 0xBE,0xBF,0x23,0xEB,0xDE,0x1F,0xAF,0xEA,
7890xFA,0xFE,0xAF,0xAF,0xEB,0xFD,0x97,0xFF, 0xF3,0xFC,0x7B,0x1F,0xCF,0xF1,0xFC,0x7F,
7900x1F,0xF1,0xFC,0x77,0x1F,0xCD,0xF1,0xFC, 0xFF,0x1F,0xFE,0x87,0xFF,0xAF,0xEF,0xFA,
7910xFE,0xFF,0xAF,0xEF,0xFA,0xFD,0xBF,0x2B, 0xFB,0x7E,0xBF,0xBF,0xEB,0xFB,0xFB,0xFB,
7920xDF,0xFF,0xFB,0xF7,0xFF,0xFF,0x7F,0xF7, 0xF7,0xFF,0xFD,0xDF,0xFE,0xFC,0xDF,0xFF,
7930xDF,0xFF,0xFD,0xFF,0xDA,0xBF,0xFF,0xBB, 0xEF,0xFB,0xF9,0xFF,0xBE,0xEF,0xFB,0xFB,
7940xBF,0xEF,0xFB,0xFE,0xFF,0xBF,0xEF,0xFB, 0xFF,0xF7,0x7F,0xFD,0xD7,0xFF,0xFF,0x7F,
7950xFF,0xFF,0xFF,0xFE,0xF7,0xFF,0xFE,0xFF, 0xF7,0xFF,0xFF,0x7F,0xFF,0xFF,0xEC,0xFF,
7960xFF,0xFE,0xDF,0xBF,0xFF,0xFB,0xFE,0xFF, 0xBB,0x68,0xAE,0x1F,0xAE,0xFB,0xFB,0xFF,
7970xFF,0xBF,0xFF,0xD5,0xFF,0x7F,0xFF,0xFF, 0xF7,0xFE,0xFE,0xFF,0xBF,0xEF,0x9F,0xFD,
7980x7F,0xFF,0xCB,0xFF,0xFF,0xDF,0xFF,0xFF, 0xBB,0xF7,0xBF,0xFF,0xFF,0xFF,0xFF,0xDF,
7990xFF,0xBF,0xFB,0xFF,0xFF,0xFF,0xDE,0x3F, 0xFF,0xFF,0xFF,0xFF,0xFF,0xA7,0xFF,0xFF,
8000xFF,0xFF,0xEF,0xFF,0x7F,0xFB,0xFD,0xFB, 0x7F,0xFF,0xFF,0xFF,0xFF,0xCF,0xF3,0x7C,
8010xFF,0x7F,0x8D,0x7F,0xFF,0xFF,0xFF,0xFF, 0xFB,0xFF,0xF7,0xFB,0xFE,0xFD,0xFF,0xFF,
8020xFF,0xFF,0xF7,0xFD,0xFF,0x7F,0xFD,0x1F, 0xFD,0xFF,0xFF,0xFF,0xFF,0xBF,0xDF,0xFF,
8030xFF,0xFE,0x5C,0xFF,0x6D,0xFF,0x7F,0xAB, 0xE7,0xF1,0xFF,0xFD,0x9F,0xFF,0xFF,0xAD,
8040xEB,0x7A,0x3F,0x1F,0xFF,0xFF,0xFE,0xBF, 0xAF,0xF3,0xDE,0xF5,0xFF,0x8F,0xFB,0xDF,
8050xE6,0x7F,0xFF,0xDF,0xF3,0xFD,0xFF,0x7E, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFD,0xF7,0xF3,
8060x7F,0xDF,0xF7,0xEF,0xFF,0xF6,0x3F,0x9F, 0xDF,0xFF,0xFF,0xEE,0xFF,0xFF,0xEF,0xFB,
8070xFF,0xFF,0xF9,0xFB,0xFE,0x4F,0xBF,0xEF, 0xBB,0xFF,0x69,0xAF,0xAF,0xFC,0xFF,0x3F,
8080xDD,0xFF,0xFC,0xBF,0x8F,0xFF,0xFD,0xF3, 0xBF,0xED,0x9E,0xFC,0xBF,0x6F,0xF5,0xD3,
8090xDF,0xFF,0xDB,0xD6,0xF5,0xEF,0xFD,0xFE, 0xFF,0xB9,0xFF,0x1F,0xD2,0xA9,0xAF,0xFF,
8100xDB,0xF7,0xBF,0xEF,0x46,0xFF,0xFF,0xAD, 0xEB,0x7A,0xDF,0xEF,0xF7,0xFF,0x7F,0xF7,
8110x9F,0xED,0xFF,0x7F,0xFF,0xAD,0xEB,0x7F, 0xF5,0x6F,0xFF,0xFD,0xFB,0xD6,0xF4,0xF7,
8120xFB,0xF9,0x7E,0x7F,0xFF,0x5F,0xC2,0xFE, 0xBF,0xFD,0xFB,0x33,0xDF,0xF9,0x5B,0xFF,
8130xFF,0xDD,0x67,0x7D,0xCF,0xEF,0xDB,0xEC, 0xFF,0x77,0xDD,0xF7,0xFD,0xFF,0xFF,0xDE,
8140xA7,0xBF,0xD4,0x9F,0xFF,0xFF,0xBF,0xEF, 0xFE,0xFF,0xDF,0xEF,0xBB,0xFF,0xFF,0xEF,
8150xEB,0xFA,0xFF,0xEF,0xBD,0xFB,0xFF,0xE2, 0x7F,0xFF,0xDF,0xDF,0xF7,0xFD,0xBF,0xBB,
8160x73,0xF7,0xFD,0x7F,0xDF,0xDE,0xF7,0xBF, 0xEA,0xDB,0xF6,0xFF,0xD6,0xFF,0xFF,0x66,
8170xFF,0xBE,0xFF,0xBF,0x6B,0xD9,0xF6,0xDF, 0xFF,0xFB,0x7E,0x7F,0xB7,0x7E,0xFF,0xFE,
8180xFF,0xCD,0xFF,0xFE,0x7F,0xFF,0xFC,0xFD, 0x3F,0xFB,0xFB,0xF7,0xFF,0xFF,0xFB,0xF6,
8190x7D,0xFE,0x7F,0xFF,0xFC,0xFF,0xB9,0xFF, 0xF9,0xFA,0xFE,0xBF,0xAF,0x5B,0xD6,0xED,
8200xAD,0x7B,0xF6,0xF9,0xBF,0xEF,0xF8,0xFA, 0xFE,0xBF,0xFE,0xE6,0xFF,0xFF,0xF7,0xFD,
8210xFF,0x7F,0xBF,0xEF,0xF3,0xFF,0xFF,0x6F, 0xF7,0xFE,0xFF,0xFF,0xF7,0xFD,0xFE,0xF7,
8220xEF,0xFF,0xFB,0xEF,0xFB,0x7E,0xDE,0xFE, 0xFF,0xBF,0xFF,0xFE,0xFF,0xFF,0xFB,0xFF,
8230xFF,0xEF,0xFB,0x6F,0xFC,0x1F,0xFE,0xE7, 0xFF,0xFF,0xFF,0xEF,0xFF,0xD3,0xB4,0xBB,
8240xFF,0xFF,0xFD,0xBF,0x6F,0xE3,0xFE,0xFF, 0xBF,0xFC,0xBF,0xF7,0xCF,0xF7,0xFD,0xFF,
8250x2F,0xDF,0xAB,0xEA,0xFF,0xDF,0xE7,0xEA, 0x9A,0xAF,0xEF,0xFB,0xFE,0xFF,0xF5,0x3F,
8260xFD,0x7E,0xFF,0xD7,0xF5,0xFB,0xFF,0xFD, 0xF7,0xFF,0x7F,0xFE,0xF7,0xFD,0xFF,0xD7,
8270xFF,0xD7,0x7F,0xEE,0x7F,0xFA,0x79,0xFE, 0x2F,0x8B,0xE6,0xF9,0xFE,0x3F,0x9E,0xF9,
8280xBE,0x2F,0x0B,0xE7,0xF9,0xFE,0x2F,0x9F, 0xFD,0xFF,0xFE,0x7D,0x7F,0x5F,0xD7,0xFF,
8290xFF,0x7F,0xFF,0xFD,0xFF,0x7F,0x5F,0x97, 0xFF,0xFD,0x7F,0x5F,0xFF,0xE3,0xFF,0xFF,
8300xFA,0xFE,0xBF,0xAF,0xFB,0xFB,0xFF,0xFF, 0xCF,0xEB,0xFE,0xBF,0xAF,0xFF,0xFA,0xFE,
8310xBF,0xFF,0x87,0xFF,0xFF,0xF5,0xFF,0xFF, 0xFF,0xFF,0xFD,0xFF,0x7F,0xFF,0xFF,0xFF,
8320xFB,0xFF,0xFF,0xF5,0xFF,0xFF,0xFE,0x0F, 0xFF,0xFD,0xEB,0xFF,0xFF,0xF7,0xFF,0xEF,
8330x7B,0xDF,0xFE,0xFF,0xFF,0xDF,0xF7,0xFD, 0xEB,0x7F,0xDF,0xFF,0x5F,0xFF,0xFF,0xFF,
8340xFF,0xFD,0xBF,0xFF,0x7E,0xFA,0xBF,0xC7, 0xDB,0xF7,0xBD,0x3F,0xFB,0xFF,0xF6,0xFF,
8350xFA,0xAF,0xFF,0xEB,0xFA,0xFE,0x3F,0x2F, 0xEA,0xFA,0x3E,0xAD,0xC9,0xBA,0xF6,0xAD,
8360xAF,0xEB,0xFA,0xF6,0xBF,0xFE,0x7F,0xFF, 0xFF,0xFD,0xFF,0xF1,0x7F,0x3F,0xCF,0xF1,
8370xEF,0xFF,0x7F,0xFF,0xBC,0xDF,0xDF,0xF7, 0xDD,0xFF,0xE0,0x7F,0xFF,0xFF,0xFE,0xFF,
8380xFA,0xEC,0xBB,0x7F,0x5F,0xFF,0xFB,0xEC, 0xFF,0xEF,0xB7,0xFF,0xF7,0xFF,0xFF,0xB5,
8390xFF,0xFF,0x7F,0xFF,0xFF,0xFF,0xEE,0xDF, 0x5F,0xDF,0xDE,0xFF,0xAE,0xE7,0x77,0xFF,
8400xFF,0xDF,0xF7,0xFF,0xE3,0xFF,0xFA,0xBB, 0xFE,0xFF,0xAF,0xFD,0xFB,0xFE,0xBF,0xAB,
8410xF9,0xFE,0xFF,0xBF,0x7F,0xBF,0xFE,0xBD, 0xFE,0xD7,0xFF,0x9F,0xFD,0xFF,0xBE,0xEF,
8420xFF,0xEE,0xFD,0xBB,0x5B,0xEF,0xFF,0x7F, 0xEF,0xFF,0xEF,0xFF,0x7F,0xFF,0x4F,0xFF,
8430xEF,0xFB,0xBC,0xFC,0xFF,0xFF,0xFF,0xFE, 0xFE,0xFD,0xFA,0xFE,0xFB,0xFF,0xFD,0xF3,
8440xFB,0xFF,0xF8,0x5F,0xFF,0xFF,0xD7,0xF5, 0xFD,0xDF,0xEF,0xFF,0xF3,0xDC,0x5F,0xCE,
8450xF5,0xBD,0xFF,0xFF,0xD7,0xFF,0xFF,0xF9, 0x3F,0xFF,0xDF,0xF7,0xFF,0xFE,0xFF,0xFD,
8460xFF,0xFB,0xFF,0xF7,0xB9,0x7D,0xFE,0xDF, 0xFF,0xFF,0xFF,0xFF,0xF9,0x7F,0xFF,0xFE,
8470xFF,0xFF,0x7F,0xFF,0xFE,0xFF,0xFF,0xF7, 0xF6,0xFF,0xBF,0xF1,0xF8,0xFF,0xFF,0xFF,
8480xFF,0xE0,0xFF,0xFF,0xFF,0xFF,0xF9,0xFF, 0xFF,0xFF,0xFF,0xFF,0xEF,0xEF,0xFF,0xFF,
8490x9B,0xFB,0x7F,0xFF,0xFF,0xFF,0xC1,0xFF, 0xDF,0xFF,0x3F,0x5F,0xD7,0xBF,0xEF,0xBB,
8500xDE,0xEE,0xFF,0x7F,0xDF,0xFF,0xFE,0xF5, 0x7F,0xDF,0xFF,0x99,0xFF,0xFF,0xFA,0xFF,
8510xBF,0xFD,0xEB,0x7A,0xFF,0xB7,0xFE,0xFE, 0xFF,0xFF,0xEF,0xFF,0xFF,0xFD,0xBF,0xFF,
8520x97,0xFF,0xFD,0xF7,0xFF,0x7F,0xF7,0xFF, 0xFF,0xFD,0x5F,0xFE,0xF3,0xF9,0xDF,0xDF,
8530xFF,0xFF,0xFC,0xFF,0xFF,0x83,0xFF,0xFF, 0xFE,0xFF,0x9E,0xEC,0xFB,0xEE,0xFF,0x9F,
8540xBF,0xEF,0xFF,0xFE,0xED,0x7B,0xFF,0xFF, 0xFF,0xF1,0x5A,0xFF,0xFF,0xFD,0xFF,0x7C,
8550x69,0x3B,0xDF,0xFF,0x7F,0x1F,0xDF,0xFF, 0xFD,0xBA,0xFF,0xFF,0xFB,0xFF,0x5B,0xBD,
8560xFF,0xFF,0xFF,0xFF,0xD7,0xB6,0xED,0xE9, 0xFF,0xD6,0xBD,0x6F,0x5F,0xFB,0xFF,0xEF,
8570xFF,0x5F,0xFE,0xF6,0x6F,0xFF,0xFF,0xFF, 0xFF,0xF7,0xEB,0x7A,0xDF,0xFF,0x9F,0x7F,
8580x7F,0xFF,0xB7,0xFF,0xFF,0xFE,0xDF,0xFF, 0x6C,0xFF,0xFB,0xFF,0xBB,0x6F,0xEB,0xFE,
8590xCC,0xF7,0xA5,0xFA,0x5C,0xF5,0x75,0xBB, 0xB7,0xDF,0xFE,0x6F,0x5F,0xC5,0xBF,0xFD,
8600x7B,0xFE,0xFF,0x95,0xE7,0x29,0xCF,0x4F, 0xF5,0x91,0xEE,0x6B,0xDF,0xEF,0xFD,0x54,
8610xF5,0xBD,0xB1,0xFF,0xEF,0xEE,0xFB,0xBE, 0xBF,0xAF,0xFE,0xDE,0xBD,0x6F,0xDA,0xF2,
8620xFF,0xAF,0xBE,0xFF,0xFF,0xFD,0x7E,0xA7, 0xFF,0xF7,0xFF,0xBF,0xEF,0x7B,0xF6,0xFD,
8630xBD,0x4A,0xF2,0x85,0x85,0xBF,0x5B,0xFE, 0xB5,0xFD,0xFA,0xFF,0x4F,0xFF,0xFE,0xDF,
8640xFF,0xED,0xFF,0xBF,0xFF,0xBF,0x7F,0xFE, 0xFF,0xB7,0x6D,0xFF,0xF7,0xBF,0xBF,0xEF,
8650xFD,0x1F,0xFF,0xFE,0x7D,0xFF,0x67,0xFF, 0xFF,0xFF,0x3F,0x7F,0xFE,0xBF,0xFF,0xE7,
8660xDF,0xE7,0xFF,0xEF,0x6B,0xFC,0x1F,0xFF, 0xBF,0xEF,0xFB,0xFE,0xDE,0xBF,0xAF,0xFA,
8670xFF,0xB6,0xEF,0xF9,0xFE,0xFF,0x8F,0xEF, 0xDB,0xEF,0xAB,0x6F,0xFB,0xFE,0xFF,0xFF,
8680xEF,0xFD,0xFF,0x7F,0xFF,0xFF,0xDE,0xFF, 0xFF,0xEF,0xFF,0xFF,0xFF,0x3F,0xFF,0x6C,
8690xFF,0xBF,0xFB,0xFF,0xFE,0xFF,0xFB,0xFE, 0xDF,0xFF,0xFF,0xEF,0xFF,0xFF,0xBF,0xFF,
8700xFF,0xFE,0xFB,0xFF,0xD5,0x7F,0xFF,0xFF, 0xEF,0xFB,0xFF,0xFF,0xBF,0xEF,0x43,0xB5,
8710xFD,0x6F,0xCF,0xD6,0xBE,0x3F,0x7F,0xDB, 0xFE,0xC3,0xFF,0xFD,0xFF,0xAF,0xEB,0xFB,
8720xFC,0xFF,0x3E,0xEF,0xE8,0xFA,0xBD,0xCD, 0xAA,0xFE,0xFE,0x7D,0xCF,0xFF,0xB7,0xFF,
8730xF7,0xFF,0xFF,0xFF,0xFD,0xFF,0x75,0xCD, 0x52,0xD7,0xFD,0xFB,0xF7,0xDD,0xFB,0xEF,
8740xEB,0xFF,0xFF,0x4F,0xFF,0xBF,0x9F,0xE7, 0xF9,0xFC,0x7F,0x8B,0xC3,0xF9,0xAF,0x8F,
8750xE7,0xE9,0xBE,0x7F,0x9F,0xE6,0xF9,0xFC, 0x5F,0xFF,0xFF,0xF7,0xFD,0xFF,0x7A,0x5F,
8760xD7,0xED,0xFF,0xFF,0xD7,0xFF,0xDD,0x7F, 0xE7,0xFF,0xFC,0xFF,0xFC,0x3F,0xFF,0xFF,
8770xFF,0xFB,0xFF,0xFE,0xBF,0xAF,0xFF,0xFD, 0xFF,0xEF,0xFF,0xEB,0xFF,0xFF,0xFF,0xFF,
8780xFF,0xF7,0x7F,0xFF,0x7F,0xDF,0xFF,0xFD, 0xFD,0x7F,0xFE,0xF7,0xFD,0x7F,0xDF,0xFF,
8790xFD,0xFF,0xFF,0xDF,0xFB,0xFF,0xEE,0xFF, 0xFB,0xFF,0xF7,0xFD,0xFF,0x7A,0xDF,0xF5,
8800xFD,0xFA,0xDF,0xF7,0xFC,0xFF,0x7F,0xDF, 0xBF,0xED,0xFF,0xC9,0xFF,0xDF,0xFF,0xBF,
8810x2F,0xFB,0xFF,0xBC,0xAD,0xFF,0xF7,0xFF, 0xFF,0xEF,0xD3,0xFF,0x7D,0xBF,0x6F,0xFF,
8820xFA,0xFF,0xFE,0xBF,0xAE,0xEA,0xFA,0xBE, 0xAD,0xA5,0xEB,0xCE,0xBF,0xA7,0xEB,0x5A,
8830xDE,0xBD,0xAF,0x6B,0xFD,0x57,0xFF,0xFF, 0xF4,0x7F,0x1F,0x7F,0xFD,0xFF,0x7F,0x36,
8840xF0,0xDF,0x79,0xFF,0xFF,0xFF,0xF7,0xFD, 0xBF,0xFF,0x87,0xFF,0xFB,0xF3,0xFC,0xFF,
8850xFF,0xFF,0xFF,0x7E,0xFF,0xBF,0xDF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFD,0xBF,0xF8,0x9F,
8860xFF,0xFF,0xFF,0xFF,0xBF,0xFF,0xFF,0xFD, 0xF7,0xFC,0xBD,0xFF,0xFE,0xFF,0xFF,0xFF,
8870xFF,0xFF,0xFB,0xF9,0xBF,0xFF,0xFF,0xEB, 0xE2,0xFE,0xFF,0xBF,0xEF,0xA9,0xBA,0x2F,
8880xEB,0xF9,0xFE,0x77,0xDF,0xF7,0xFF,0xFF, 0xF9,0x7F,0xFF,0xFF,0x7F,0xEF,0xD7,0xFF,
8890xFD,0xFF,0xFB,0xF5,0xFF,0xBF,0x6F,0xDF, 0xFF,0xFF,0xFD,0xFF,0xFF,0xF0,0xFF,0xFF,
8900xFF,0x3F,0xCF,0xFF,0xBA,0xEE,0x9B,0xBF, 0xEE,0xD7,0xFE,0xCD,0xEF,0xFF,0xDF,0xBF,
8910xFF,0xFF,0xC5,0xFF,0xFF,0xFD,0x7F,0x4F, 0xFD,0xF6,0xD9,0xFF,0x4F,0xD6,0xFD,0xBF,
8920x6E,0xFF,0xFF,0xF4,0x7F,0xFF,0x7F,0x8B, 0xFF,0xFF,0xFF,0xFF,0xF7,0xFF,0xF9,0xFE,
8930x37,0xFF,0xD9,0xFB,0xF5,0xAF,0xFD,0xFF, 0xFF,0xFB,0xFF,0xFF,0x07,0xFF,0xFF,0xFF,
8940xFB,0xF7,0xFF,0xFD,0xFF,0x7C,0xFA,0x7E, 0x4F,0xFC,0xDF,0x1D,0xC7,0xFF,0xFF,0xFF,
8950xFF,0xAE,0xFF,0xFF,0xFF,0xFF,0xFD,0xFB, 0xFF,0xFF,0xFE,0xFE,0xFC,0xFF,0x7F,0x7F,
8960xBF,0xEF,0xFE,0xFF,0xFF,0xFF,0x5F,0xFD, 0xFF,0xFF,0xFF,0xFD,0x6F,0x5A,0xD7,0x7B,
8970xBE,0x5F,0xFE,0x39,0xFF,0xF7,0xFF,0xF7, 0xFD,0xFE,0xAA,0x1F,0xFF,0xFF,0xFF,0xFF,
8980xFE,0xFE,0xAB,0xAF,0xFD,0xFE,0xBF,0xFF, 0xF7,0xFF,0x7F,0xFE,0x8F,0xE3,0xFB,0xEE,
8990x7F,0xFF,0xFF,0xFF,0xFF,0xEB,0xFB,0xFF, 0xFD,0xBF,0xEF,0xDF,0xFF,0xFF,0xFF,0xFF,
9000xFF,0xFF,0xFF,0xFB,0xE4,0x3F,0xFF,0xDF, 0xFF,0xFF,0xFF,0xFF,0xF3,0xEF,0xBB,0xFB,
9010xBF,0xEF,0xBB,0xFF,0xD7,0xBF,0xFF,0xFF, 0xFF,0x29,0xAF,0xF7,0xFF,0xFF,0xFB,0xFF,
9020xFB,0xE6,0xFF,0x0F,0xFB,0x3F,0xDF,0x0F, 0xFF,0xAF,0xFF,0xFF,0xFF,0xF5,0xC3,0xDF,
9030x5F,0xFF,0xFF,0xFF,0xFE,0x6B,0xCA,0xBE, 0xBC,0xFF,0x9F,0xF2,0xBF,0xFF,0xFE,0xFA,
9040xFF,0xFF,0xEF,0x16,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFC,0xDF,0x97,0xFD,0x79,0xFF,0x37,
9050xE7,0x7F,0xFF,0xFF,0xB5,0xFF,0xFF,0xF6, 0x2F,0xFF,0xFD,0xFB,0xFE,0xFF,0xFF,0xFD,
9060x5F,0x57,0x5F,0xFF,0xDB,0x52,0xDF,0xFF, 0xFD,0xBF,0xFF,0xFF,0xFC,0xDB,0xFF,0x7B,
9070xB5,0xFD,0x7F,0xFF,0x71,0x9C,0x6E,0xFF, 0xF6,0x35,0xA5,0x9B,0xFF,0xFF,0xFD,0xFF,
9080xFF,0xDB,0x9E,0x7F,0xFE,0xEF,0xFB,0xFF, 0xFF,0xBD,0xEF,0xFF,0xDE,0xB7,0xF9,0x4B,
9090xFF,0xF5,0xEF,0xFF,0xFF,0xFF,0xE8,0x7E, 0xFF,0xEA,0xDF,0xF7,0xFF,0xFD,0x69,0x5B,
9100xFC,0x9F,0xEF,0x78,0xD6,0xFF,0xEB,0xEF, 0xFF,0xFF,0xFF,0xE8,0xFF,0xFF,0xED,0xFF,
9110xFF,0xFF,0xFF,0xE3,0xF9,0xF6,0xBF,0xFF, 0xFF,0xFE,0xDF,0xFF,0x7F,0xFF,0xFF,0xFF,
9120xD1,0xFF,0xFF,0xE7,0xFF,0xFF,0xFF,0xFF, 0xE7,0xF9,0xFF,0xBF,0x7F,0xD9,0xFF,0xFD,
9130xFE,0x7F,0xFF,0xFE,0xFF,0xF9,0xFF,0xFB, 0xD6,0xDF,0xBF,0xEF,0x5B,0xD6,0xFF,0xBF,
9140xFB,0xF6,0xFF,0xBF,0xEF,0xF8,0xF6,0xDD, 0xBE,0xFE,0x16,0xFF,0xBF,0xEF,0xFF,0xFE,
9150xFF,0xBF,0xEF,0xFF,0xFF,0xFF,0x6F,0xFB, 0xFF,0xFF,0xFF,0x6F,0xF3,0xFF,0xF7,0xEF,
9160xFB,0xFF,0xBF,0xFF,0xEF,0xFE,0xFF,0xBF, 0xFF,0xFF,0xFF,0xBE,0xBF,0xFF,0xEF,0xFF,
9170x7F,0xEF,0xFF,0xFD,0x17,0xFB,0x7B,0xFF, 0xFF,0xFD,0x7F,0xDB,0xF6,0xF4,0x7F,0xFA,
9180xFE,0xF5,0xBF,0xEB,0xE3,0xF7,0xFF,0xFF, 0xE9,0xBF,0xFF,0xAF,0xF7,0xFD,0xF3,0x7E,
9190x8F,0xA3,0xEA,0xFF,0xCB,0xF3,0xEE,0xFF, 0xBF,0xEF,0xF7,0xF9,0xFF,0xFE,0x7F,0xFF,
9200xFF,0xFF,0xFF,0xF5,0xFB,0xF6,0xFF,0xF5, 0x2F,0xFE,0xFB,0xD7,0xBF,0xFF,0xBE,0xDF,
9210x9F,0xFF,0xF0,0xFF,0xFF,0xF9,0xFE,0x7F, 0x8F,0xA3,0xF8,0xFE,0x6F,0x9F,0xF9,0xF6,
9220x2F,0x9F,0xE7,0xF9,0xFE,0x2F,0x9F,0xE1, 0xFF,0xFF,0xFF,0x7F,0xDF,0xF7,0xF5,0xFD,
9230x7F,0x7F,0xF5,0xFF,0x9F,0x5F,0xFB,0xFE, 0xFF,0x7F,0xFF,0xFF,0xCB,0xFF,0xFF,0xFB,
9240xFE,0xFF,0xBF,0xAF,0xFB,0xFE,0xFF,0xDF, 0xFE,0xFE,0xBF,0xF7,0xFF,0xFF,0xFF,0xFF,
9250xFF,0xC7,0xFF,0xFF,0xFD,0xFF,0x7F,0xDD, 0xF7,0xFD,0xFF,0xFF,0xD7,0xFF,0xFD,0x7F,
9260xFF,0xFB,0xFD,0xFF,0xFF,0xFE,0xEF,0x7F, 0xFD,0xEF,0xFB,0xFE,0xFB,0xFD,0xFF,0x7F,
9270xDF,0xFD,0xFF,0x7A,0xDF,0xF7,0xFD,0xFF, 0xFF,0xFF,0xFF,0x1F,0xFF,0xFF,0xD3,0xF7,
9280xFF,0xFF,0x6F,0xDB,0xFF,0xFF,0xEF,0xCB, 0xF4,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,
9290x29,0xFF,0xE8,0xDA,0x76,0x9F,0xAF,0x6A, 0xDA,0xFE,0x35,0xEB,0xDA,0xD6,0xBF,0xAB,
9300xEB,0x7A,0xDE,0xBF,0xD7,0x7F,0xFF,0xFE, 0xFF,0xBF,0xEF,0xFD,0xDF,0x77,0xBF,0xFD,
9310x37,0xEF,0xFF,0xEF,0xFF,0x3F,0xFF,0xFF, 0xFF,0xFE,0x7F,0xFF,0xFF,0xFF,0xF7,0x7E,
9320xDF,0xFF,0xFF,0xFF,0xFA,0xB7,0x7F,0xFF, 0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,0x89,0xFF,
9330xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0x9F,0xFB,0xFF,0xFF,0xFF,0xE7,0xFF,
9340xFF,0xFF,0xFF,0xAA,0xFF,0xAB,0xFB,0xFA, 0xEF,0xBF,0xFF,0xDF,0xFA,0x7B,0xB9,0xFE,
9350xFE,0xFF,0xFD,0xFF,0xF7,0xFE,0x3F,0xFF, 0xB7,0xFF,0xF7,0xEE,0xFF,0x7F,0xEF,0xFF,
9360xFF,0x7F,0xFF,0x1F,0xFB,0xFF,0xBF,0xFB, 0xFE,0xFF,0xBD,0xFF,0xFF,0x2F,0xFF,0xBF,
9370xFF,0x7F,0xDF,0xFA,0xFF,0xFF,0xFC,0xEE, 0xF5,0xF3,0xBE,0xFB,0x0F,0xEF,0xF3,0xBE,
9380xEF,0xFC,0x5F,0xFF,0x5A,0xFF,0xF7,0xDF, 0xFF,0xFF,0xFE,0xD5,0xFC,0x5F,0xFB,0xF2,
9390xFF,0xFF,0x2F,0xBB,0xF3,0xFF,0xFF,0xBF, 0xFF,0xEF,0xFF,0xEF,0xFF,0xFF,0xFF,0xFF,
9400xBF,0xFF,0xFF,0xFD,0x7B,0xFF,0xDF,0xB9, 0xFF,0xFB,0xFF,0xD8,0x7F,0xFF,0xFF,0xFF,
9410xFB,0xFF,0xFC,0x7F,0x1F,0xBF,0xE0,0xDF, 0xF7,0xEF,0xFF,0xFD,0x7F,0xFE,0xDF,0xFF,
9420xE0,0xFF,0xFF,0xFD,0xEF,0xFB,0xFF,0xFE, 0xF7,0xDF,0xFF,0xEB,0x5F,0xFF,0xF7,0xFF,
9430xFF,0xFF,0xFF,0xBF,0xFF,0xFD,0xFF,0xFD, 0xFF,0xFF,0xFF,0xF7,0xFD,0xFF,0x3B,0xDC,
9440xFD,0x6D,0x7B,0x5F,0x57,0xF5,0xFD,0x7F, 0x5F,0xFF,0xB1,0xFF,0xEB,0xFF,0xFF,0xFF,
9450xFB,0xFB,0xFE,0xFF,0xBF,0xFB,0xBE,0xFF, 0xBF,0xEF,0xFB,0xFE,0xFF,0xAF,0xFE,0xF7,
9460xDF,0xDF,0xFF,0xFF,0xFF,0x7F,0xCF,0xF3, 0xF8,0xFF,0xD7,0xFB,0xFF,0x5F,0xBF,0xF7,
9470xFB,0xFF,0x7F,0xFE,0x23,0xFF,0xFF,0xFE, 0x7F,0xF3,0xFF,0xFB,0xFE,0xFF,0xFF,0xF3,
9480xFF,0xFF,0xF5,0xF9,0xFF,0x3F,0xFF,0xFF, 0xF0,0x9A,0xFF,0xBE,0x7F,0xFF,0xFC,0xF9,
9490xFF,0xFD,0xAF,0xEB,0xFE,0xBF,0xFF,0xCF, 0xF3,0xFE,0x7F,0xFF,0xFF,0x5B,0xBD,0xFF,
9500xBC,0xEB,0xFF,0xD7,0xD4,0xAF,0xAF,0xFD, 0xFF,0xCF,0xF7,0xFD,0xFF,0x7F,0xDF,0xF7,
9510xFD,0xFE,0xFF,0x6F,0xFF,0xFB,0xFF,0xFF, 0xFF,0xFD,0x7F,0x5E,0xFD,0xBF,0xDB,0xF6,
9520xFD,0xBF,0x6F,0xFB,0xEE,0xFD,0xFF,0x7A, 0xFF,0xFA,0xFB,0xFF,0x3F,0xFB,0xB7,0x5F,
9530xD6,0xF7,0x1F,0x71,0xDC,0x77,0x1D,0xC7, 0x31,0xDC,0x77,0xDF,0xF9,0xBF,0xF5,0x5B,
9540xF4,0xD7,0x9D,0xAE,0xFF,0xBF,0xFD,0xBF, 0xDB,0xF6,0xFD,0xBF,0x6F,0xDB,0xF6,0xFE,
9550x3D,0x81,0xFF,0xEB,0xFE,0xFE,0xFE,0xFF, 0xEB,0x7A,0xDF,0x7D,0x77,0x7D,0xF5,0x79,
9560xDF,0x57,0xDD,0xF5,0x7D,0x7E,0xE6,0xFF, 0xD6,0x3F,0xBF,0x7F,0xFF,0xD4,0xF5,0x3F,
9570xBF,0xFB,0xBE,0xEF,0xB3,0xEE,0xFB,0x9E, 0xEF,0xBB,0xFE,0x8B,0xFF,0xFE,0xDF,0xB7,
9580xED,0xFF,0xF7,0xFD,0xFE,0xFF,0xEF,0xBB, 0xEE,0xFF,0xBE,0xEF,0xBB,0xEE,0xEB,0xFC,
9590x1F,0xFF,0xFF,0xFD,0xFF,0xE7,0xFF,0xF7, 0xFD,0xFF,0xEF,0xFE,0xFF,0xBF,0xEF,0xFB,
9600xFE,0xFF,0xBF,0xEB,0xFA,0x1F,0xFF,0xB7, 0xEF,0x5B,0xFE,0xFF,0xAF,0xEB,0xDD,0xE7,
9610xDE,0x77,0x9D,0xE7,0x79,0xDE,0x77,0x9D, 0xBF,0xE6,0x6F,0xFF,0xFE,0xFF,0xBF,0xEF,
9620xFB,0xFE,0xFD,0xBF,0x6F,0xF6,0xFD,0xBF, 0x6F,0xDB,0xF6,0xFD,0xBF,0xFF,0x7E,0xFF,
9630xFF,0xFB,0xFE,0xFE,0xFF,0xEF,0xFB,0xFD, 0xEF,0x7E,0xF7,0xBD,0xEF,0x7B,0xDE,0xF7,
9640xBD,0xEF,0xFF,0xD5,0xFF,0xBF,0xFF,0xEF, 0xFE,0xFF,0xFC,0x3F,0x0F,0xE7,0xFE,0x7F,
9650x9F,0xE7,0xF9,0xFE,0x7F,0x9F,0xE7,0xFE, 0xF3,0xFF,0xFE,0xDF,0xAD,0xDF,0x67,0xEE,
9660xFB,0xBF,0xEF,0xFE,0xFF,0xBF,0xEF,0xFB, 0xFE,0xFF,0xBF,0xEF,0xFF,0x23,0xFF,0xFF,
9670xFF,0xFF,0x7F,0xFF,0xF3,0xBC,0xDB,0xFE, 0xFB,0xFF,0xFB,0xBE,0xF7,0xFB,0xFF,0x7F,
9680xDF,0xFF,0xCF,0xFB,0xFF,0x9F,0xE3,0xF9, 0xBE,0x3F,0x8F,0xE7,0x79,0xFF,0x9D,0xE7,
9690xF9,0xFE,0x7F,0x9F,0xE7,0xF9,0xFE,0x5F, 0xFF,0xCF,0xF7,0xFF,0xFF,0xFF,0xDF,0xF7,
9700xFE,0x7F,0xE7,0xF9,0xFE,0x7F,0xFF,0xFF, 0xFB,0xFE,0xFF,0xFF,0xBF,0xFF,0xBF,0xBF,
9710xFF,0xFE,0xFF,0xBF,0xEF,0xFF,0xFD,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xF7,0xFD,0xFF,
9720xFF,0x3F,0xFF,0xBF,0xFF,0xF7,0xFF,0xFF, 0x7F,0xDF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
9730xFF,0xFF,0xFF,0xFF,0xFF,0xE8,0xEF,0xFF, 0x5F,0xF7,0xBF,0xF9,0xFE,0xDF,0xB7,0xFD,
9740xFF,0xDF,0xF7,0xFD,0xFF,0x7F,0xDF,0xF7, 0xFD,0xFF,0xDD,0xFF,0xF2,0xFF,0xBF,0xFF,
9750xFF,0xBF,0xFF,0xFF,0x2F,0xF2,0xFF,0xBF, 0x2F,0x7B,0xD2,0xF7,0xBF,0x2F,0xFF,0xBB,
9760xFF,0xEE,0x8F,0xAF,0xEB,0xFA,0xFE,0x3F, 0xA7,0x69,0xCE,0x8F,0xA4,0xEA,0xFA,0xEE,
9770xB7,0xAE,0xEB,0xFD,0xC7,0xFF,0xF7,0xF7, 0xFF,0xFF,0xFF,0xFF,0xFF,0x7F,0x3E,0xF3,
9780x74,0xFF,0x3F,0x4F,0xFF,0xE7,0xFF,0x3F, 0xFE,0xA7,0xFF,0xFF,0xDF,0xF7,0xB7,0xFF,
9790xF7,0xFF,0xBA,0xEF,0x37,0xEB,0xFB,0xFE, 0xBF,0xFB,0xFE,0xF3,0xFF,0xF9,0xDF,0xFF,
9800xBF,0xFF,0xFF,0xFF,0xBF,0xFF,0xFF,0xFF, 0xFD,0xDF,0xFF,0xFD,0xFF,0xFF,0xFB,0xFE,
9810xFD,0xFF,0xFB,0xBF,0xFE,0x3F,0xED,0xFF, 0xDF,0xBE,0x3D,0xA7,0xFB,0xFA,0x3F,0xE6,
9820xE1,0xFE,0xFE,0x3F,0xEF,0xE3,0xDF,0xF5, 0x7F,0xFE,0xFF,0x7E,0xFF,0xFF,0xFF,0xFF,
9830xEF,0x6F,0xF6,0xFF,0x7D,0xEF,0xD7,0xDE, 0xFF,0x7D,0xEF,0xFF,0xF2,0xFF,0xFF,0xFF,
9840xFF,0xFF,0xFF,0x7B,0xDE,0xFB,0xE6,0xEE, 0xEF,0x37,0x6E,0xF3,0x7E,0xEB,0x37,0xEF,
9850xFF,0xC1,0xFF,0xFE,0xFF,0xF7,0xEF,0xFF, 0xFF,0xFF,0xBF,0x3F,0xD2,0xDF,0xBF,0x2F,
9860x7B,0xE2,0xFF,0xFE,0x3B,0xBD,0xDB,0xFF, 0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xEF,0xFE,
9870xFF,0xFB,0xFF,0xFF,0xBF,0xFF,0xFB,0xDF, 0xFF,0xBF,0xFF,0xB7,0xFF,0xFF,0xBF,0xEF,
9880xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x0F,0xFF, 0x7F,0xFF,0x1F,0xEF,0xF1,0xFD,0xFF,0xF6,
9890xAF,0xFF,0xFF,0xFF,0xFF,0xFF,0xEF,0xFF, 0xFF,0xFF,0xFE,0x9F,0xFF,0xFF,0xFF,0x77,
9900xEF,0xF7,0xFB,0xFF,0xFE,0x5F,0xFF,0xFF, 0xBF,0xCF,0xFB,0xF7,0xDD,0xF7,0xF5,0xFF,
9910x5F,0xD5,0xF5,0xFD,0x7F,0x5F,0xD7,0xF5, 0xFF,0xFB,0x0F,0xFF,0xFF,0xA9,0xEA,0x7A,
9920xFF,0xAF,0x8F,0xFE,0xDF,0xAF,0xEF,0xFB, 0xFE,0xFF,0xBF,0xEF,0xFB,0xDF,0xE5,0x5F,
9930xFF,0xFF,0xFF,0xFF,0xFF,0xBD,0x57,0xFF, 0xFF,0x6F,0x77,0xBF,0xF7,0xFB,0xFF,0x7F,
9940xBF,0xF7,0xFF,0xFC,0xBF,0xFF,0x9F,0xFF, 0xFF,0xEF,0xFF,0xFE,0xFF,0xFF,0xFF,0x1F,
9950xCF,0xFF,0xFC,0xFF,0xFF,0xFF,0xFF,0xFB, 0x65,0xAF,0xF3,0x7C,0xFF,0x3F,0xDF,0xFF,
9960xFD,0xE9,0xFE,0x7F,0xE7,0xFF,0xFE,0x7F, 0xFF,0xFF,0xFF,0xFF,0xFD,0xE3,0xDF,0xFB,
9970xDB,0xF6,0xFD,0xEF,0x5B,0xFB,0xFF,0xDF, 0xFC,0xFF,0x3F,0xDF,0xF3,0xFD,0xFF,0x7F,
9980xDF,0xEF,0x66,0xFF,0xDF,0xAD,0xEB,0x7A, 0xDE,0xF7,0xF7,0xE7,0xD9,0xFD,0x9F,0x67,
9990xD9,0xF6,0x7D,0x9F,0xE7,0xDF,0xF5,0x47, 0xFD,0x65,0x5B,0xD6,0xF4,0xFE,0xFF,0xEF,
10000xFF,0x6D,0xF6,0xDD,0xB7,0x6D,0xDB,0x76, 0xDC,0xB7,0x7D,0xFA,0x9B,0xF6,0x6D,0x9D,
10010x67,0x59,0xDF,0xF7,0xDD,0xFF,0xEB,0xFE, 0xBF,0xAF,0xEB,0xFA,0xFE,0xBF,0xAF,0xE3,
10020xD1,0x9F,0xFF,0xBD,0xBF,0xEF,0xFE,0xF7, 0xBF,0xBF,0xF7,0xD7,0x7F,0xDD,0xF7,0x9D,
10030xDF,0x7F,0xDF,0xF7,0xFF,0xE0,0x7F,0xFD, 0xC1,0xDF,0xF7,0xFD,0xC7,0x7F,0x7F,0xFB,
10040xFF,0xBB,0xEC,0xFB,0x3E,0xFF,0xBF,0xEC, 0xFB,0xFF,0xD8,0x7F,0xBF,0x6C,0xFF,0xBE,
10050xFF,0xBF,0xED,0xFF,0xEF,0xFE,0xFB,0xBF, 0xEF,0xFB,0xFE,0xFF,0xBF,0xEE,0xFF,0xC5,
10060xFF,0xAF,0x6F,0xFF,0xFC,0xFD,0x3F,0xE7, 0xFF,0xFE,0xFF,0xEF,0xFB,0xFE,0xFF,0xBF,
10070xEF,0xFB,0xFE,0xBF,0x89,0xFE,0xFA,0xBA, 0xFE,0xBF,0xAF,0xFB,0xF6,0xF5,0xD9,0x7D,
10080x97,0x65,0xD9,0x74,0x5D,0x97,0x65,0xD3, 0xFE,0xD6,0xFF,0xBF,0xF7,0xFD,0xFF,0x7F,
10090xBF,0xCF,0xFB,0xFE,0xFF,0xEF,0xFB,0xFE, 0xFF,0xBF,0xEF,0xFB,0xFF,0xF6,0x8F,0xFB,
10100xFF,0xEF,0xFB,0x7E,0xDB,0xFE,0xFF,0xBE, 0xEF,0xEE,0xFB,0xBE,0xEF,0xBB,0xEE,0xFB,
10110xBE,0xFF,0xFF,0xDF,0xFF,0x43,0xFF,0xFF, 0xFB,0xEF,0x5F,0xB7,0xFE,0x7F,0xE7,0xF9,
10120xFE,0x7F,0x9F,0xE7,0xF9,0xFE,0x7F,0xF9, 0xBF,0xFE,0xAF,0x77,0xFD,0xFF,0x2F,0xAF,
10130xA7,0xFE,0xFF,0xEF,0xFB,0xFE,0xFF,0xBF, 0xEF,0xFB,0xFE,0xFF,0xF1,0x7F,0xEF,0xDF,
10140xFF,0x97,0xF5,0xEF,0xFF,0xDF,0xFF,0xFF, 0xBF,0xFF,0xBF,0xFF,0xFF,0xFE,0xFF,0xFF,
10150xFF,0xE0,0xFF,0xFF,0xF9,0xFE,0x2F,0x8B, 0xE3,0xF8,0xBE,0x77,0x9F,0xF9,0xDA,0x77,
10160x9D,0xE7,0x79,0xDE,0x77,0x9F,0xDD,0xFF, 0xFD,0xFD,0x7F,0x5F,0xD7,0xFD,0xFF,0x7F,
10170xE7,0xFE,0x7F,0x97,0xE7,0xFB,0xFE,0xFF, 0xBF,0xEF,0xFF,0xAB,0xFF,0xEF,0xFA,0xFE,
10180xBF,0xAF,0xFF,0xFA,0xFF,0xFF,0xDF,0xFF, 0xFB,0xFF,0xF7,0xFD,0xFF,0x7F,0xDF,0xFF,
10190x67,0xFF,0xF7,0xF5,0xFF,0xFF,0xFF,0xDF, 0xFD,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
10200xFF,0xFF,0xFF,0xFF,0xFF,0xEF,0xFF,0xBD, 0xEB,0xFF,0xFF,0xF7,0xAD,0xEB,0xFF,0xDF,
10210xFD,0xFF,0x3F,0xDF,0xF7,0xFD,0xFF,0x7F, 0xDF,0xFF,0x5F,0xFF,0xF7,0xFF,0xFF,0xFD,
10220xBF,0xFF,0xCB,0xF4,0xFF,0x7F,0xD3,0xF7, 0xFD,0x3F,0x7F,0xD3,0xF7,0xFF,0xFC,0x3F,
10230xFF,0xEA,0xFA,0xBE,0xAF,0xAB,0xEB,0xBA, 0xF4,0x95,0x6B,0x52,0xD4,0xAD,0x2F,0x4A,
10240xD2,0xF6,0xBF,0xD2,0x7F,0xF7,0x3F,0xFF, 0xFF,0xF3,0x7F,0xFF,0xFF,0xF7,0xFF,0xBA,
10250xDF,0xFB,0xFD,0xFF,0xBF,0xFF,0xFB,0xFF, 0xF8,0x7F,0xEA,0xFF,0xFE,0xFE,0xDF,0xFF,
10260xF7,0xFF,0x7F,0xBB,0xFF,0xFF,0xBF,0xDF, 0xFB,0xFF,0xFF,0xBF,0xFF,0xB1,0x7F,0xFF,
10270xFB,0xEF,0xFF,0xFF,0xFF,0xFF,0xFF,0xBF, 0xCF,0xFE,0xFF,0xFF,0xEF,0xFF,0xF7,0xFF,
10280xFF,0xFF,0xF1,0xFF,0x69,0xBE,0xFA,0xBF, 0xAF,0xE2,0xFF,0xFE,0xFD,0xAF,0xF3,0xFE,
10290xFF,0xBF,0xEF,0xFB,0xFC,0xFF,0xFF,0x07, 0xFD,0x95,0xDB,0xDF,0x7F,0xDF,0xAF,0xFF,
10300xF7,0xAF,0x36,0xFE,0xBF,0x65,0xEB,0xF6, 0xFE,0x9F,0x6F,0xFE,0x07,0xFF,0xCF,0xFF,
10310xF8,0xFE,0xFF,0xCF,0xFF,0xF6,0xFA,0xE7, 0xFB,0xFE,0xFF,0xBB,0xED,0xF9,0xFF,0xFF,
10320xFF,0x5F,0xFF,0xFF,0xFF,0x75,0xFF,0xEF, 0x7E,0xFD,0xE0,0xE8,0x5E,0xD3,0xE5,0xF9,
10330x3E,0x5F,0xD7,0xF7,0xFF,0xFA,0x2F,0xFB, 0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0x7F,
10340x7F,0xD7,0xF5,0x7D,0x5F,0x57,0xD5,0xF5, 0xEF,0xFF,0xF3,0x7F,0xFC,0x7F,0xFF,0xC7,
10350xF1,0xFF,0xFF,0x1F,0xCF,0xB0,0xFF,0x3F, 0xCF,0xF3,0xFC,0xFF,0x3F,0xCE,0xFF,0xE4,
10360xFF,0xDF,0x7F,0xFE,0xF7,0xBB,0xFF,0xFF, 0xDF,0xEF,0xEE,0xFF,0xBF,0xEF,0xFB,0xFE,
10370xBF,0xBF,0xEF,0xFF,0xD1,0xFF,0xFF,0xFF, 0xFD,0xFB,0xFF,0xFD,0xFF,0xFB,0x9F,0xE9,
10380xFE,0x7F,0x9F,0xE7,0xF9,0xFE,0x7F,0xBF, 0xFF,0xB3,0xFF,0xFF,0xF7,0xFF,0xFF,0xAF,
10390xF7,0xFF,0xB6,0x3F,0xEB,0xFA,0xFE,0xBF, 0xAF,0xEB,0xFA,0xFE,0xBF,0xFE,0xA7,0xFF,
10400xFF,0xFF,0xFF,0xFF,0xF7,0xFF,0xFF,0xFF, 0xFE,0x9F,0xF7,0xF9,0xFF,0x7F,0x9F,0xE7,
10410xFF,0xFF,0xFE,0xAF,0x6F,0xFF,0xFF,0xFF, 0x9F,0xFF,0xDF,0xFF,0x7D,0x5F,0xDD,0xFF,
10420xFB,0xBF,0xE7,0xBB,0xFF,0xFB,0xDF,0x6D, 0x5F,0x7E,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
10430xEB,0xF7,0xFF,0xE7,0xEF,0xF7,0xFF,0xFF, 0x7F,0xFF,0xF7,0xFF,0xFC,0x8F,0xFF,0xEF,
10440xFD,0xFE,0xFF,0xBE,0xF4,0xF2,0x7D,0xD7, 0xCF,0xFF,0x3F,0xFF,0xFF,0xFF,0xFF,0xFF,
10450xFF,0xCF,0x6B,0xFF,0xBF,0x3F,0xFB,0xF2, 0xFC,0x7F,0xEB,0xFF,0x9F,0xFA,0xFF,0xFF,
10460x3F,0xFF,0xF3,0xFF,0xFF,0xFD,0x70,0xF7, 0xFF,0xFF,0xBF,0xFF,0xFB,0xD7,0xFE,0xF5,
10470x77,0xFF,0x15,0xDD,0x77,0xFD,0xFF,0x7F, 0xDF,0xF7,0xFB,0xCD,0xBF,0xFF,0xFD,0xFF,
10480xFF,0xDF,0x37,0xCD,0xF9,0xEC,0xFE,0xEF, 0xBB,0xF4,0xFB,0x3F,0x4F,0xB3,0xFF,0xFD,
10490xCB,0xFF,0xE9,0x7E,0x54,0x9F,0xE5,0x4B, 0xB7,0xFF,0xDD,0x7D,0xC7,0x71,0xDD,0x77,
10500x5D,0xD7,0x75,0xCD,0x7F,0xD6,0xFF,0xD3, 0xF6,0xF9,0x3F,0x6D,0x95,0xAF,0x7F,0xFE,
10510xFF,0xEF,0xFB,0xFE,0xFF,0xBF,0xEF,0xFB, 0xFE,0xF6,0xC7,0xFF,0xAD,0x7B,0xCA,0xFF,
10520xBF,0xBF,0xEF,0xFD,0xE3,0xDF,0xB7,0xED, 0xFB,0x7E,0xDF,0x37,0xED,0xE3,0xFB,0xDF,
10530xFF,0x52,0x5C,0x15,0xFD,0xCF,0x7F,0xDF, 0xFE,0xEF,0xEF,0xFB,0xFE,0xFF,0xBF,0xEC,
10540x7B,0xFE,0xFF,0xFE,0x3E,0x7F,0xDA,0xF7, 0xFD,0xFF,0x7F,0xFF,0xFF,0xFB,0xEF,0xBB,
10550x6F,0xFB,0xFE,0xFF,0xBF,0xEF,0xFB,0xFF, 0xF7,0x7D,0xFF,0xD8,0xFF,0xFD,0xBF,0x7F,
10560xFB,0xFF,0xFF,0x9F,0xFB,0xFE,0x7F,0x9F, 0xE7,0xF9,0xFE,0x7F,0x9F,0xEA,0x7F,0xF6,
10570xBF,0xBD,0x6A,0x5A,0xF6,0xE5,0xBF,0x77, 0x5F,0x6D,0xDD,0x77,0x5D,0xD7,0x75,0xDD,
10580x77,0xFF,0xA5,0xBF,0xCF,0xFB,0xFF,0xFF, 0xBF,0xCF,0xFB,0xFD,0xFF,0xBF,0xF3,0xFE,
10590xFF,0xBF,0xEF,0xFB,0xFE,0xFF,0xFD,0xAB, 0xFF,0xBF,0xBF,0xFF,0xFB,0xFF,0x7F,0xEF,
10600xFF,0xBE,0xFB,0xEE,0xFB,0xBE,0xEF,0xBB, 0xEE,0xFB,0xBF,0xFF,0xB5,0xFF,0xD0,0xBC,
10610xFD,0x2F,0x4B,0xF7,0xFF,0xFF,0x9F,0xF9, 0xFE,0x7F,0x9F,0xE7,0xF9,0xFE,0x7F,0x9F,
10620xFA,0x8F,0xFD,0xAB,0xFA,0xDA,0xBF,0xAF, 0xB3,0xFD,0xFF,0xBF,0xFB,0xFE,0xFF,0xBF,
10630xEF,0xFB,0xFE,0xF7,0xBF,0xFF,0x9F,0xFF, 0x77,0xF7,0xBD,0xFD,0x77,0xDF,0xFF,0x7E,
10640xDF,0xED,0xBB,0xFE,0xFF,0xBE,0xEF,0xFB, 0xFE,0xFF,0xFA,0x3F,0xFF,0xBE,0x6F,0x8F,
10650xE6,0xF9,0xFE,0x7F,0x9F,0xC7,0xFE,0x7F, 0x9F,0xE7,0xF9,0xFE,0x7F,0x9F,0xE7,0xFB,
10660x7F,0xFF,0x7F,0xCF,0xFF,0xFD,0xFF,0xFF, 0xDF,0xFB,0xAF,0xBF,0xEF,0xFF,0xFE,0xFF,
10670x9F,0xEF,0xFB,0xFF,0xFC,0xFF,0xFB,0xFE, 0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xF7,
10680xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xF5,0xFF,0xFF,0xFF,0x3F,0xDF,0xF7,
10690xFF,0xFF,0x7F,0xEF,0xFE,0xFF,0xBF,0xFF, 0xFB,0xFF,0xFF,0xBF,0xEF,0xFF,0xB3,0x7F,
10700xFF,0x7B,0x5E,0xF7,0xFD,0xFF,0x7B,0x7F, 0xF7,0xFF,0x7F,0xDF,0xF7,0xFD,0xFF,0x7F,
10710xDF,0xF7,0xFF,0x17,0xFF,0xFF,0xFF,0x7F, 0xFF,0xFF,0xDD,0xF6,0xFC,0xBF,0xCB,0xF2,
10720xBC,0xBF,0x2F,0xCB,0xF2,0xFC,0xBF,0xFE, 0x8F,0xFF,0xFA,0x7E,0xBF,0xA7,0xEB,0xDA,
10730xFC,0xBF,0xAF,0x7A,0xFE,0xBF,0xAF,0xEA, 0xFA,0xFE,0xBF,0xAF,0xF4,0xDF,0xFE,0xFF,
10740xF3,0x3C,0x7F,0x3E,0xFF,0xCF,0xF8,0xBF, 0x8F,0xE3,0xF8,0xFE,0x3F,0x8F,0xE7,0xE8,
10750xFF,0xFC,0x9F,0xFF,0xFF,0xCF,0xEB,0xB3, 0xE7,0xFB,0x7B,0xF3,0xFE,0xFF,0xCF,0xDB,
10760xFB,0xFB,0xBF,0x6F,0x6F,0xDF,0xEC,0x7F, 0xFF,0xFF,0xF7,0xFD,0xFD,0xFF,0xFF,0xFF,
10770xFF,0xB2,0xBF,0xFF,0xDE,0xFD,0xBD,0xEF, 0xFB,0xF6,0xDF,0xEA,0xE7,0xDB,0xFE,0xBB,
10780xFF,0xEB,0xFB,0xBF,0x9F,0x8F,0xE8,0xFE, 0x3F,0x8F,0xA3,0xF8,0xFE,0x3F,0x8F,0xFF,
10790xF8,0x7E,0xFD,0xFD,0x7F,0xFF,0xFB,0xCD, 0xFF,0xFD,0xFF,0x5F,0xEF,0xFD,0xFF,0xFF,
10800xDF,0xF7,0xFD,0xFF,0xBE,0x90,0xFF,0xFF, 0xEE,0xFF,0x3F,0xBF,0xF3,0xBB,0xFE,0xB7,
10810xAB,0xFA,0xFE,0xAF,0xAD,0xEA,0xFA,0xDE, 0xAB,0xFF,0x63,0xFF,0xFE,0xF2,0xFF,0xB3,
10820xFF,0xDF,0xEE,0x7D,0xFF,0x03,0xF1,0xF4, 0x3F,0x1F,0xC3,0xF1,0xEC,0x7F,0xFE,0x6F,
10830xFF,0xFB,0xFB,0xFF,0x9F,0xFF,0xBF,0xFF, 0x7B,0x5F,0xFD,0xFF,0xDF,0xF7,0xFD,0xFD,
10840x7F,0x7F,0xDF,0xFE,0xCF,0xFB,0xFF,0xFF, 0xAF,0xFB,0xFF,0x1F,0xEF,0xA5,0xFD,0xBF,
10850xDF,0xFB,0x7D,0xFF,0xBF,0xDF,0xFB,0xFF, 0xFD,0x3B,0xFF,0xFF,0xFF,0xFF,0xFF,0xFD,
10860xAF,0xF3,0xFF,0xFB,0x7F,0xBF,0xD7,0xFB, 0xBF,0x7F,0xBB,0xF7,0xFF,0xF8,0x7F,0xFF,
10870xFA,0x5F,0xD7,0xFF,0xDF,0x7F,0xEF,0xFF, 0xFF,0x7F,0xDB,0xF7,0xFD,0xFF,0x7F,0xDF,
10880xB7,0xFB,0xEC,0xFF,0xFF,0xF7,0xBF,0xEF, 0xFD,0xFC,0xFB,0xFF,0xEF,0xF0,0xFE,0x3F,
10890x8F,0xE3,0xF8,0xFE,0x3F,0x8F,0xEF,0x8D, 0xFF,0xFF,0xEF,0x7F,0xBF,0xFF,0xFB,0xFF,
10900xDB,0xBF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xEF,0xD8,0xFF,0x2E,0x7F,
10910xBE,0xEF,0xFE,0x6E,0xFF,0xBF,0xF9,0xFF, 0xFF,0xF3,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
10920xFC,0x66,0xBE,0x47,0xF3,0x7F,0xDF,0xFE, 0x87,0x9F,0xFF,0xFF,0xFF,0xFF,0xE7,0xFF,
10930xFF,0xFF,0xFF,0xFF,0xFF,0xD6,0x6F,0x7C, 0xFB,0x4F,0xD2,0xFF,0xFD,0x2B,0xFE,0xFF,
10940xFF,0xFD,0x5F,0xD7,0xD5,0xF5,0x7D,0xFF, 0xFF,0xFF,0xBF,0x9B,0xFF,0xFF,0xDF,0xB7,
10950xFF,0xFF,0xDF,0xFF,0x3F,0xCF,0xFE,0x7F, 0xBF,0xEF,0xFB,0xFC,0xFF,0x3F,0xFF,0xD9,
10960xBF,0xFE,0x97,0xEC,0x8F,0xB7,0xFE,0x9B, 0x7D,0xFD,0xB7,0xDD,0x77,0x1D,0xC7,0x71,
10970xDD,0x77,0x5D,0xD7,0xF3,0x6F,0xFD,0x3F, 0x73,0xDD,0xAF,0xFD,0x7A,0xFF,0xFF,0xAF,
10980xFE,0xFD,0xBF,0xEF,0xFB,0xFE,0xFF,0xBF, 0xEF,0x66,0x7F,0xFF,0xFF,0xBF,0xBF,0xFF,
10990xFB,0xFF,0xF7,0xDF,0xFD,0xFB,0x7D,0xDF, 0xB7,0xCD,0xF3,0x7C,0x5F,0x3F,0x91,0x3F,
11000xFF,0x3D,0xEF,0x7B,0xFF,0xFC,0xFF,0xCA, 0xEF,0xFE,0xFF,0xBD,0xEF,0xFB,0x1E,0xE7,
11010xBB,0xEC,0x7F,0xB3,0xFF,0xFD,0x9F,0xFF, 0xFF,0xFE,0xFF,0xFF,0x7F,0xBF,0xFB,0xFE,
11020xFF,0xBF,0xEF,0xFB,0xEE,0xFB,0xBF,0xDF, 0x67,0xFF,0xFF,0xBF,0xEF,0xDB,0xFF,0xBC,
11030xFE,0x7F,0xFB,0xFF,0x9F,0xEF,0xF9,0xFE, 0x7F,0x9F,0xE7,0xF9,0xFE,0x87,0xFF,0xEE,
11040xFB,0xBE,0xE5,0xBF,0xEF,0xF9,0xD7,0x65, 0xF7,0xDD,0xE7,0x7D,0xDF,0x77,0x5D,0xD7,
11050x7F,0xF8,0x9B,0xFE,0xFF,0xBF,0xEF,0xFB, 0xFF,0xFF,0xBF,0xEF,0xFB,0xFF,0x7F,0xCF,
11060xF3,0xFC,0xFF,0xBF,0xEF,0xFF,0xDB,0x3F, 0xEF,0xFB,0xFE,0xFF,0xDF,0xFF,0xFE,0xFB,
11070xBB,0xEF,0xBF,0xEF,0xBB,0xEE,0xFB,0xBE, 0xEF,0xBB,0xFF,0xFC,0x7F,0xFD,0x3B,0x5B,
11080xD6,0xE5,0xFD,0x4F,0xC3,0xFB,0xFF,0xBF, 0xEF,0xFB,0xFE,0xFF,0xBF,0xEF,0xFB,0xFF,
11090xB4,0xFF,0xFA,0xBC,0x8F,0xB2,0xE9,0xD2, 0x2E,0xCF,0xFB,0xFF,0xBF,0xEF,0xFB,0xFE,
11100xFF,0xBF,0xEF,0xFB,0xFF,0xEC,0xFF,0xFD, 0xFD,0x7F,0xDF,0xF7,0xE4,0xDF,0x5F,0xFF,
11110xFF,0xFB,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xC3,0xFF,0xEF,0xE6,0xF8,0xFE,
11120x3F,0x8B,0x83,0xF9,0xFE,0x7F,0xE7,0xF9, 0xFE,0x7F,0x9F,0xE7,0xF9,0xFE,0x7F,0x17,
11130xFD,0xFF,0xFF,0xFF,0x7F,0x5F,0xF7,0x2C, 0xFF,0xFF,0xFF,0xFE,0x7F,0xFF,0xE7,0xF9,
11140xFE,0x7F,0x9F,0xFE,0x2F,0xFF,0xFF,0xEF, 0xFF,0xFE,0xBF,0xEF,0xAD,0xFF,0xFF,0x7F,
11150xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFE,0xDF,0xFF,0xDF,0xFF,0xFD,0xFD,0x7F,
11160xDF,0xF7,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFA,0x3F,0xFE,
11170xF7,0xFD,0xEF,0x7A,0xFF,0xB1,0xBD,0xFF, 0x7F,0xF7,0xFD,0xFF,0x7F,0xDF,0xF7,0xFD,
11180xFF,0x7F,0xF3,0x27,0xFF,0xDF,0xFF,0xDD, 0xFF,0xFC,0x9B,0xFF,0xCB,0xFC,0xBF,0x2F,
11190xCB,0xF2,0xFC,0xBF,0x2F,0xC9,0xFF,0xDE, 0xFF,0xDF,0xAF,0xEB,0xDA,0xFE,0xBB,0xAF,
11200xEB,0xF8,0xF7,0xAF,0xE8,0xFA,0xFE,0xBF, 0xAF,0xEB,0xF2,0xFF,0xFD,0xFF,0xFF,0xEF,
11210xBD,0xD7,0xBF,0xFF,0xFF,0xDE,0x8F,0xB8, 0xDE,0x37,0x8D,0xA3,0x78,0xDA,0x3F,0x8F,
11220xFF,0xA1,0xFF,0xFF,0xFB,0xFB,0xFF,0xFF, 0xFF,0xFF,0xA7,0xBD,0xFB,0x76,0xFD,0xBF,
11230xEF,0xDB,0xFE,0xBB,0xBF,0xFE,0x27,0x7F, 0xFF,0xFE,0xFE,0xFD,0xF5,0xFF,0xEF,0xF5,
11240xDF,0x1F,0xE7,0xFD,0xFF,0x7F,0xDF,0xF7, 0xFD,0xFF,0xFF,0xCD,0xFD,0xAE,0xFF,0xFA,
11250x3E,0x3F,0xAB,0xFD,0xF8,0x7E,0x8F,0xE3, 0xF8,0xFE,0x3E,0x8F,0xE3,0xF8,0xFF,0xFE,
11260x1F,0xEF,0xDF,0xBF,0xFE,0xDE,0xDF,0xD9, 0xFF,0xDF,0xBC,0xFF,0xFF,0x7F,0xFF,0xEF,
11270xFD,0x7F,0xDF,0xF7,0xF9,0x3F,0xFE,0xFF, 0xFF,0x6F,0xFE,0xDE,0xBF,0xF7,0xED,0xEA,
11280xFD,0x8F,0x83,0xF8,0xEA,0x3F,0x8F,0xEF, 0xFF,0xF4,0x7F,0xFF,0xEF,0xEF,0x7B,0xF3,
11290xF1,0x5F,0xFF,0xFF,0xF1,0x3B,0x7F,0xDF, 0xF7,0xFD,0xFF,0xFF,0xFF,0xFF,0xE0,0xFF,
11300xFF,0xFF,0xF7,0xFF,0x6F,0xFF,0x7F,0xFF, 0xFF,0xF7,0xDE,0xF7,0xBF,0xEF,0xFB,0xF7,
11310xFD,0xFF,0xFF,0xF5,0xFA,0xFF,0xFF,0xFB, 0xE7,0xFF,0xF3,0xF8,0x7F,0xF3,0xDF,0xFF,
11320xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x1F,0xEF, 0xBB,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFD,
11330xFF,0x7F,0xFF,0x9F,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xCF,0xFF,0x37,0xFF,0xFF,
11340x7F,0xDF,0x77,0x5D,0xE7,0xFC,0xFF,0xBF, 0xF7,0xF5,0xFB,0xFF,0xFF,0xD7,0xF5,0xFB,
11350xFF,0xFF,0x45,0xFD,0x7F,0xEA,0xFD,0xBE, 0xBF,0xDF,0xF7,0xFF,0xFF,0xDB,0xFB,0xFE,
11360xFF,0xBF,0xEF,0xFF,0xFF,0xFF,0xFB,0x5F, 0x7F,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,
11370xFF,0xFE,0xFF,0xEF,0xFD,0xFF,0x7F,0xDF, 0xFF,0xEF,0xFB,0xF8,0x0F,0xF3,0xFF,0xF9,
11380x2E,0xFB,0xFE,0xFC,0xF3,0xEF,0xFF,0xFF, 0xBF,0xFF,0xFB,0xE7,0xFF,0xFE,0x7E,0xFF,
11390xC0,0x6B,0xCF,0xFF,0x34,0xDF,0xF1,0xFD, 0xFF,0xEF,0xFF,0xFF,0xFF,0xDF,0xF7,0xFD,
11400xCF,0x7F,0x9C,0xFD,0xFD,0x6C,0xF7,0xFF, 0xF6,0xFD,0xEB,0x2B,0x9F,0xFF,0xFC,0xFE,
11410x7E,0xFF,0xFF,0xFF,0xFF,0xD7,0xF3,0xF7, 0xFF,0xFB,0xE1,0xBF,0xFF,0xEB,0x7A,0xDE,
11420xD7,0xFB,0xFF,0xF9,0xFE,0xFF,0xFF,0xF3, 0xDE,0x7F,0xFD,0xE7,0x7F,0xFF,0xFD,0xBB,
11430xFF,0xFF,0x7E,0xCC,0xF6,0xAF,0x5F,0x7F, 0xFE,0xF4,0x7D,0xF7,0xFD,0xBB,0x6E,0xDB,
11440xB7,0xFF,0xF7,0xDF,0x66,0xFF,0xFF,0xF7, 0x3D,0xCF,0xDE,0xBD,0xFF,0xFF,0xDE,0xDB,
11450x8D,0xF7,0x7E,0xDF,0xB7,0xEF,0x7F,0xFF, 0xF6,0x87,0xFF,0xFF,0xEF,0xFE,0xDE,0xBF,
11460xFF,0xFF,0xFF,0xBB,0xEF,0xFD,0xFF,0x7B, 0xDE,0xF7,0x3F,0xFF,0xBF,0xFB,0xDB,0xFF,
11470xF2,0xB6,0xFD,0xBD,0x7F,0xE7,0xFF,0xFF, 0xFF,0x6F,0xF7,0xFF,0xFF,0xFF,0xFE,0x77,
11480xFF,0xBF,0xF8,0xAF,0xFF,0xDF,0xBF,0xFF, 0xBF,0x7F,0xFB,0xFF,0xFF,0xFF,0xDB,0xFE,
11490xFF,0xBF,0xFF,0xFA,0xFF,0xFD,0xFF,0xF6, 0x7F,0xFF,0x9F,0xFF,0xFF,0x3F,0xEF,0xF8,
11500xEE,0x7E,0x9F,0xBA,0xFE,0xBF,0x8F,0xEF, 0xFE,0xFE,0xF9,0xFF,0xFA,0x7F,0xFE,0x7E,
11510xBF,0xAF,0xFB,0x96,0xFD,0x9F,0xEF,0x5E, 0x65,0xBE,0xEF,0x5B,0xB6,0xFF,0xBE,0xE3,
11520xFF,0xB5,0xBF,0xFF,0xFD,0xFF,0x7F,0xFF, 0xEF,0xDF,0xFE,0xFF,0xBF,0xFB,0xFE,0xFF,
11530xBF,0xCF,0xFF,0xFF,0xFF,0xFD,0x9B,0xFF, 0xFE,0xFB,0xFE,0xDF,0xFF,0x7F,0xFF,0xF7,
11540xFE,0xFF,0xDF,0xFB,0xFB,0xFE,0xFF,0xFF, 0xFF,0xFF,0xFF,0xB7,0xFE,0xFA,0xFF,0xAB,
11550xEF,0xFF,0xFD,0xB5,0x7B,0x7F,0xFB,0xF7, 0xFD,0xFF,0xFF,0xDD,0xFF,0xEF,0x8F,0xFF,
11560x2F,0xFF,0xFB,0x7C,0xFF,0x3F,0xDF,0x73, 0xEB,0xFE,0x3F,0xFF,0xEF,0xFB,0xFE,0xFF,
11570xEF,0xFD,0xFF,0xBF,0xFD,0x0F,0xFF,0xFF, 0xFF,0xF5,0xF9,0xFF,0x7F,0xD7,0xFD,0xFF,
11580xDF,0xFF,0xF7,0xFB,0xFF,0x7F,0xBF,0xFF, 0xFF,0xF0,0x9F,0xFF,0xFE,0x7F,0x8B,0xE3,
11590xF9,0xDE,0x27,0x9B,0xE6,0xBE,0x7F,0x9B, 0xC3,0xF8,0xDE,0x7F,0x9D,0xE7,0xFE,0x7F,
11600xFF,0xFF,0x5F,0xD7,0xFF,0xFF,0xFF,0x4F, 0xFB,0xFF,0xFF,0x7F,0xFF,0xAF,0xFF,0x9F,
11610x7F,0xFB,0xFF,0xE8,0xFF,0xFF,0xFE,0xBF, 0xAF,0xFF,0xFF,0xFE,0xBF,0xEF,0xF7,0xFF,
11620xBF,0xFF,0xFF,0xFF,0xFF,0xFF,0xF7,0xFF, 0xFC,0xFF,0xFF,0xFD,0x7F,0xFF,0xFF,0xFF,
11630xFD,0x3F,0xCF,0xFF,0xFF,0xFF,0xFF,0xF7, 0xFF,0xFD,0x7F,0xFF,0xFF,0x93,0xFF,0xFF,
11640x7A,0xDF,0xF7,0xFF,0xFF,0x7B,0x7F,0xB7, 0xEF,0xFF,0xFF,0xFD,0xBF,0xFD,0xFB,0xFF,
11650xF7,0xFF,0xD7,0xFF,0xFF,0xFF,0xFC,0x9F, 0x6F,0xCB,0xFF,0xF4,0xBB,0xDF,0xD6,0xFD,
11660xBF,0x2F,0xD3,0xF7,0xFF,0xDF,0xFF,0xCF, 0xFF,0xFA,0xBE,0xBD,0xAF,0x6A,0xDA,0xBE,
11670xBB,0xAB,0x3A,0xBE,0x2D,0xAE,0xEB,0xDA, 0xF6,0x3F,0xAD,0xF5,0xDD,0xFF,0xCF,0xF1,
11680xFF,0xF9,0x7F,0xFF,0x73,0xFE,0xFF,0xCF, 0xC3,0xF4,0xF7,0x2F,0xF3,0xFF,0xFC,0xFF,
11690x7C,0x1F,0xFF,0x3F,0x4F,0xFF,0x7E,0xFF, 0xEF,0xBD,0xF6,0xFE,0xFF,0x2B,0xEF,0xDC,
11700xFB,0xFD,0xFF,0xFB,0xFF,0xEA,0x7B,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFB,0xF7,0xDF,0xFF,
11710xE3,0x7D,0xFF,0xB7,0xFF,0xBF,0xFF,0xFF, 0xDF,0xFF,0xF8,0xFF,0xBF,0xFF,0xBF,0xEB,
11720xE7,0xFA,0xFE,0x3D,0xBF,0xE9,0xFC,0xBF, 0xFF,0xFA,0xFB,0xFE,0xFF,0xFF,0xFF,0xD9,
11730xFF,0xFF,0xFF,0xF6,0x7F,0xFF,0xF6,0x7D, 0xFF,0xDF,0xCF,0xFD,0xBF,0xFB,0xEF,0x7E,
11740xFF,0x7F,0xFF,0xFF,0xD3,0xFF,0xFD,0xFB, 0xFF,0xFB,0xFF,0xFF,0xFF,0xEF,0xFF,0xBF,
11750xFE,0xFF,0xF7,0xEF,0xFF,0xFF,0xFF,0xFB, 0xFF,0x87,0xFF,0xFD,0xFF,0xFF,0xFF,0xFF,
11760x7B,0xFE,0xFF,0xFE,0x3B,0xF7,0xF7,0xFF, 0x3F,0xFF,0xFF,0xFF,0xFF,0xFF,0x0F,0xFF,
11770xFF,0xFF,0xFF,0xFB,0xFF,0xFF,0xFF,0xF7, 0xFF,0xFF,0xAD,0xFF,0xFE,0xF7,0xFF,0xFF,
11780x5F,0xFF,0xFF,0xDF,0xFF,0xFD,0xFF,0xF5, 0xFF,0xDF,0xFF,0xBD,0xFF,0xE9,0xFF,0xC7,
11790xF3,0xFF,0xFF,0xF7,0xFF,0xF3,0xFF,0xF8, 0x3B,0xFF,0xFF,0x7B,0xDF,0xBF,0xFB,0xEF,
11800xFB,0xFF,0xFB,0xF7,0xF7,0xBB,0xFF,0xFF, 0xFF,0xFF,0xFB,0xFF,0xFE,0x7F,0xF3,0x7F,
11810x5E,0xB7,0xBF,0xFD,0x7F,0xFF,0xF9,0x7F, 0xFB,0xFF,0xEB,0xFD,0x7F,0x7F,0xFF,0xEF,
11820xFB,0xE0,0x3F,0xFE,0xBF,0xBF,0xDF,0xFF, 0x7E,0xFF,0xF7,0xFF,0xFF,0xFE,0xBF,0xFF,
11830xDB,0x78,0xFF,0xFF,0xFF,0xEE,0xA1,0xBF, 0xF5,0xDE,0xFB,0xF7,0xFF,0xFB,0xFF,0xFF,
11840xFF,0xFF,0xFB,0xFF,0xFF,0xD7,0xFF,0xFF, 0xFF,0xFF,0xEF,0xF0,0xFF,0xFF,0xFF,0xF3,
11850xF7,0xFF,0xEF,0xFF,0xE7,0xCF,0xFF,0xFB, 0xFF,0xEF,0xFF,0xFF,0x9F,0x9F,0xEF,0xFC,
11860x16,0xBF,0xFE,0xF3,0xE4,0xFF,0xFF,0xC6, 0xFF,0xE7,0xFF,0xFF,0xFD,0xFF,0xBF,0xFF,
11870xFF,0x3F,0xFF,0xBF,0xD6,0xAF,0x7F,0xFE, 0x6B,0x7E,0x7F,0xFF,0xAF,0xFF,0xFF,0xBF,
11880xFF,0x5F,0xFF,0xFE,0xFF,0xFF,0xFE,0xFF, 0xFF,0xBD,0xDB,0xFF,0xFE,0x5F,0xF2,0xFF,
11890xFF,0x5F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xEF,0x7F,0xFF,0xFF,0xFF,0xFF,0xDE,0xBF,
11900xFF,0xFF,0xEF,0xFB,0x77,0xFE,0xBD,0x7F, 0x5F,0xFF,0xFF,0xFF,0xDF,0x6F,0xED,0xFF,
11910xFD,0xFF,0x7F,0xFD,0x6F,0xFF,0xFF,0x77, 0xDA,0xCF,0xFD,0x5F,0xFF,0xBF,0xFF,0xFF,
11920xDF,0x7F,0xFF,0xFB,0xFF,0xFF,0xFF,0xFF, 0x66,0x7F,0xFF,0xFE,0xBF,0xE7,0xBF,0xFA,
11930xFF,0xFE,0xFF,0xFF,0xFF,0xDF,0xFF,0x59, 0xEF,0xFF,0xEF,0xFB,0x7F,0x89,0xFF,0xFF,
11940xE9,0xFF,0x6F,0xFF,0xF5,0xFF,0xFF,0xFF, 0xFF,0xFF,0x7F,0xF2,0xF7,0xFF,0xFF,0xEF,
11950xF8,0x7F,0xFB,0xFF,0xFD,0xFF,0xFF,0xD9, 0xFF,0xEF,0xBB,0xFF,0xFF,0xFF,0xBF,0xEF,
11960xDE,0xFF,0xFF,0x9F,0x7F,0xDF,0xFF,0xF7, 0xFF,0xFF,0xFF,0xFF,0xDF,0xFF,0xFF,0xAF,
11970xFF,0xFF,0xF7,0x3F,0xEB,0x9F,0xFE,0x7F, 0x9E,0x7F,0x9F,0xFE,0x87,0xFF,0xED,0xDB,
11980x56,0xFF,0xBF,0xAF,0x0B,0xD2,0xFF,0xEF, 0xDB,0x6E,0x7D,0xBD,0x6F,0xF8,0xFE,0x3F,
11990xFA,0x5B,0xFF,0xFD,0xBF,0xEF,0xFF,0xBF, 0x6F,0xDB,0xE6,0xFF,0xFF,0x3F,0xFF,0xDF,
12000xFE,0xFF,0xFF,0xFF,0xFF,0xDA,0x3F,0xFF, 0xFB,0xFE,0xFE,0xFF,0xFF,0xDF,0xF7,0xBD,
12010xFF,0xFD,0xFF,0xFE,0xFF,0xFB,0xFF,0xFF, 0xFF,0xFF,0xF1,0x5F,0xFD,0x9F,0xDF,0xFD,
12020xFF,0xFD,0x7F,0xFF,0xFF,0xFF,0xFF,0x76, 0xFA,0xFF,0xFF,0x7F,0xE3,0xF8,0xFF,0xAE,
12030xFF,0xFB,0x7E,0x9D,0x73,0xFF,0xFA,0x7F, 0xDF,0xFF,0xFF,0x7F,0xFF,0xFB,0xCD,0xFF,
12040x7F,0xEF,0xFB,0xFF,0xFD,0xFF,0xF7,0x7F, 0x7F,0xEF,0xFF,0xED,0xFF,0xFF,0xFF,0xB5,
12050xFF,0xBF,0xFF,0xBF,0xFD,0xEF,0xDB,0xF7, 0xFF,0x93,0xFF,0xEF,0xE2,0xF9,0xBE,0x7F,
12060x8B,0xE7,0xF9,0xFE,0x6B,0xE7,0xF9,0xFE, 0x7F,0x9F,0xE7,0xF9,0xFE,0x7F,0x47,0xFF,
12070xFF,0xFD,0xFF,0x9F,0xFF,0xD7,0xFF,0xFF, 0xFF,0xFF,0xF5,0xFF,0x9F,0xFF,0xF7,0xFE,
12080xFF,0xBF,0xFE,0x6F,0xFF,0xFF,0xFB,0xFF, 0xFF,0xFF,0xAF,0xFF,0xFF,0xFF,0x7F,0xFB,
12090xFF,0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFD, 0xDF,0xFF,0xFF,0xF7,0xFF,0xFF,0xFF,0xDF,
12100xFF,0xFF,0xFF,0x5F,0xFF,0xFF,0xFF,0xFF, 0x5F,0xFB,0xFE,0xFF,0xF8,0x37,0xFF,0xFF,
12110xEF,0xFF,0x7F,0xFE,0xBF,0xFF,0xFF,0xFE, 0xBF,0xFF,0xFF,0x7F,0xFF,0xBF,0xFD,0xFF,
12120x7F,0xFA,0x7F,0xFF,0xFF,0x6F,0xFF,0xFF, 0x7D,0xFF,0xCF,0xFF,0xFF,0xFF,0x4F,0xFF,
12130xF2,0xFF,0xFF,0xFF,0xFF,0xFF,0xFA,0xBF, 0xFF,0xAE,0xEB,0xFA,0xFE,0xBB,0xAD,0xEB,
12140xFA,0xF7,0xAF,0x6B,0xFA,0xF6,0xBF,0x25, 0xE9,0xF2,0x7F,0x45,0xFF,0xFF,0xFD,0xF7,
12150xF7,0xBF,0xFF,0xDF,0xFF,0xFF,0xBF,0xFB, 0xFF,0xDF,0xF3,0xFF,0xF7,0x3F,0xCF,0xFF,
12160xA1,0xFF,0xFF,0xBF,0xE7,0xFF,0xFF,0x7F, 0xFF,0x3D,0xFF,0xFF,0xFF,0xF7,0xFF,0x2F,
12170xFF,0xFB,0xF5,0x7F,0xFE,0x57,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xF7,
12180x3F,0xFF,0xFE,0xFF,0xFF,0xFF,0xFD,0xFE, 0xF7,0xEE,0xAF,0xFE,0xEE,0xE7,0xFA,0xFF,
12190xFE,0x9D,0xF9,0x5E,0xFE,0xFF,0xEB,0xFF, 0xFF,0xDF,0xA7,0xFF,0xFF,0xFF,0xFC,0xDB,
12200xFF,0xFF,0xFF,0x7E,0xFB,0xFF,0xFF,0xEF, 0xFB,0xFD,0xFF,0xDB,0xFF,0xFF,0xFF,0xEF,
12210xFF,0xFF,0xFF,0xFD,0xBF,0xFE,0xBF,0xFF, 0x6F,0x7F,0xFF,0xF7,0xFF,0xFF,0xF9,0xFF,
12220xF7,0xFF,0xBF,0xDE,0xF7,0xFF,0xFF,0xFF, 0xFA,0x7F,0xFD,0xBF,0x5F,0xFF,0xFF,0xBF,
12230xFF,0xED,0xFF,0xF7,0xBF,0xFF,0xFF,0xEF, 0xFF,0xDF,0xFF,0xFF,0xFF,0xE6,0xFF,0xFB,
12240x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xF7,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xEB,0xFF,
12250xFD,0xFF,0xF5,0xFF,0xF6,0x7F,0xDF,0xBD, 0xCF,0xFF,0xFF,0xFF,0xFF,0xDF,0xFF,0xFF,
12260xFF,0xF9,0xFF,0xFF,0xFF,0xFF,0xFF,0xE3, 0xFF,0xEE,0xBF,0xFF,0x7D,0xEF,0xFE,0xFF,
12270xFF,0xFF,0xBF,0xFF,0xFF,0xFF,0xFF,0xFE, 0xFF,0xFF,0xFF,0xFF,0xE7,0xFF,0xB5,0xAE,
12280xFF,0xFF,0xB6,0xFE,0xBF,0xFF,0xFF,0xBF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
12290xFF,0x27,0xFF,0xEF,0xFE,0x7F,0xDF,0xFF, 0x7E,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
12300xFF,0xFF,0xFD,0xFF,0xF7,0xF9,0x9F,0xFF, 0x5F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x7F,
12310xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0x0F,0xFF,0xE7,0xBF,0xFE,
12320xFF,0xBF,0xFF,0xFF,0xFF,0xFF,0xFC,0xBF, 0xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,0xC4,
12330x6B,0xFF,0x29,0x1F,0xFB,0xAF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xEF,0x1B,0xFE,0xFF,0xFC,
12340x6F,0xFF,0xFF,0xFD,0x6A,0xF7,0xD7,0xF5, 0xBF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,
12350xFE,0xBF,0xFF,0xFF,0xFA,0xFF,0xFF,0xF7, 0xFB,0xDD,0xBF,0xFF,0xE7,0xFF,0xFF,0xFF,
12360xFF,0xFF,0xFF,0xFF,0xFF,0xFD,0x7F,0xFF, 0xFF,0xF5,0xFF,0xFF,0xF7,0xFD,0xB3,0xEF,
12370xFD,0x7E,0x5D,0xFF,0xFD,0xFF,0xFF,0xFF, 0xFD,0x7F,0xD2,0xF5,0xFB,0x7E,0xCB,0xB7,
12380xFF,0xFF,0xFF,0xC6,0xFF,0xFD,0xEE,0x63, 0xFF,0xFF,0xFF,0xFF,0xFF,0xF6,0xFD,0x65,
12390x5B,0xDF,0xFF,0xD5,0xFF,0xFF,0xFF,0xF6, 0xE7,0xBF,0xF7,0xA9,0xFF,0xFF,0xED,0xFF,
12400xFF,0xFF,0xFF,0xFF,0xEB,0xFF,0xFF,0xFF, 0xAF,0xFF,0xFF,0xFF,0xF8,0x1B,0xFF,0xE3,
12410xD0,0xBF,0xFF,0xE1,0xFF,0xFF,0xFF,0xFF, 0xFF,0xD7,0xFF,0xFF,0xFF,0x5F,0xFF,0xFF,
12420xFF,0xFF,0xAF,0xFF,0xDB,0x76,0xBF,0xFF, 0x7F,0xFF,0xBF,0xEF,0xFE,0xFF,0xBF,0xEF,
12430xFB,0xFE,0xFF,0xFF,0xFF,0xBF,0xF2,0x7F, 0xFF,0x9F,0xFE,0xBD,0xFE,0x7F,0xFF,0xFF,
12440xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xF7,0x3F,0xEC,0x7F,0xF6,0x95,0xBB,
12450xEF,0xF8,0xFE,0xFC,0xBF,0x2F,0xDA,0xFC, 0xBF,0x2F,0xCB,0xF2,0xFC,0xBF,0xEF,0xFF,
12460xA9,0xBF,0xCF,0xFB,0xFF,0xFF,0xFF,0xFE, 0xDD,0xB7,0x6D,0xF6,0xD9,0xB6,0x6D,0x9B,
12470x76,0xD9,0xBF,0xFB,0xFD,0xA3,0xFF,0xBF, 0xEF,0xFF,0xEF,0xFF,0xFF,0xFF,0x7F,0xDF,
12480xFD,0xEF,0x7B,0xDE,0xF7,0xFD,0xEF,0x7F, 0xFF,0xFF,0x05,0xFF,0xFA,0xFE,0x7F,0xEF,
12490xE3,0xFF,0xFF,0xFD,0x7F,0xFF,0xFF,0xFF, 0xFF,0x5F,0xFF,0xFF,0xFD,0x7F,0xFB,0xAF,
12500xFF,0x63,0xC8,0xFF,0xBF,0xEF,0xFF,0xFF, 0xFA,0x7F,0xFF,0xFF,0xFF,0xFE,0x9F,0xF7,
12510xFF,0xFA,0xBF,0xFE,0x9F,0xFB,0x7F,0xFF, 0xFF,0xEF,0xD7,0xFF,0xFF,0xF5,0xFF,0xFF,
12520xFF,0xFF,0xFD,0x7F,0xFF,0xFF,0xBF,0xFF, 0xF9,0xBF,0xFF,0xBE,0x27,0x9F,0xE7,0xF9,
12530xFE,0x7F,0x8B,0xE7,0xFE,0x7F,0x9F,0xE2, 0xF9,0xFE,0x7F,0x9F,0xE7,0xF1,0x7F,0xFF,
12540xFF,0xFF,0xFB,0xFE,0xFF,0xFF,0xFF,0xD7, 0xFF,0xFF,0xFF,0xFF,0xF5,0xFF,0xFF,0xFF,
12550xD7,0xFF,0xFA,0xFF,0xFE,0xFF,0xFF,0xFF, 0xFD,0xFF,0xFF,0xFF,0xAF,0xF7,0xFF,0xFF,
12560xFF,0xEB,0xFF,0xFF,0xFF,0xAF,0xFF,0xC4, 0xFF,0xF7,0xFF,0xFF,0xEF,0xFF,0xFF,0xFF,
12570xFF,0x5F,0xFF,0xFF,0xFF,0xFF,0xD7,0xFF, 0xFF,0xFF,0xFF,0xFF,0xEB,0xFF,0xFB,0x7A,
12580xDF,0xF7,0xFD,0xFF,0xFF,0xFE,0xBF,0xFF, 0xFF,0x7F,0xFF,0xAF,0xFF,0xFF,0xFF,0xF7,
12590xEF,0xE3,0xFF,0xDD,0xD2,0xFF,0xDF,0xFF, 0xFF,0xF2,0xFC,0xBF,0xCB,0xF6,0xFD,0xBF,
12600x2F,0xCB,0xFF,0x7F,0xDF,0xDE,0xAF,0xFF, 0xDA,0xEE,0xBF,0xAF,0xE9,0xFA,0xF4,0xBD,
12610xAF,0x5A,0xAE,0xBB,0xAB,0x6B,0xDA,0xDE, 0xBF,0xAD,0xD7,0x5E,0xFF,0xFF,0xBF,0xFC,
12620xFF,0xDF,0xFD,0xFF,0xFF,0xFF,0xFF,0xDF, 0xF7,0xFF,0xFF,0xFF,0xFF,0xFD,0xFF,0xFA,
12630x1F,0xFF,0xFE,0xFB,0xEF,0xBF,0xFD,0xFF, 0xFD,0xBD,0x77,0xFF,0xFF,0xFF,0xFF,0x9D,
12640xEF,0xFF,0xFF,0xFF,0xEF,0x7D,0xFF,0xFB, 0xFE,0xEF,0xFF,0xFF,0xFF,0xFF,0xFF,0xF7,
12650xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xEE, 0xBF,0xE4,0xFB,0xFF,0xFE,0x3F,0xFE,0xFF,
12660xFF,0xFF,0xFF,0xAF,0xEA,0xFE,0xBF,0xAF, 0xEB,0xFA,0xFE,0xFF,0xFF,0xFF,0x55,0xF6,
12670xFF,0xFE,0xF7,0xFF,0x7F,0xFF,0xEB,0xF7, 0x5F,0xC5,0xFD,0x7F,0x5F,0xD7,0xF5,0xFF,
12680x6F,0xFB,0xFF,0x8A,0xFF,0xFF,0xFF,0xFF, 0xEB,0xFF,0xFF,0xFF,0xFF,0xFB,0xBF,0xBF,
12690xEF,0xFB,0xFF,0xFF,0xFF,0xFF,0xFB,0xFF, 0x77,0xDF,0xFB,0xFF,0xFD,0x7F,0xEF,0xFF,
12700xFF,0xFF,0xBF,0x7F,0xFF,0xDF,0xBF,0xFF, 0xFB,0xFF,0xFF,0xFF,0xFE,0xEF,0xDF,0xFF,
12710xFE,0xFF,0x9F,0xEF,0x7D,0xFF,0xF7,0xFF, 0x7F,0xFF,0xFF,0xDF,0xF7,0xFD,0xFF,0xEF,
12720xDF,0xFF,0xDF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFD,0xFF,0xFF,0xFB,
12730xFD,0xFF,0xBF,0xDF,0xD1,0xFF,0xF8,0x3B, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
12740x7E,0xDB,0xFD,0xFF,0x77,0xDB,0xB7,0x7D, 0xBF,0xFB,0xFF,0xF8,0x7F,0xED,0x7B,0x5E,
12750xFF,0xFE,0xFF,0xFF,0x4F,0xD7,0xFD,0x7F, 0xDF,0xD7,0xF5,0xFF,0x7F,0xFF,0xFF,0xFF,
12760xF2,0x3F,0xFE,0xFF,0xBF,0xFF,0xFF,0xFF, 0xFF,0xBF,0xEF,0xFE,0xFF,0x3B,0xEE,0xFF,
12770xFC,0xEF,0xFF,0xFF,0xFF,0x85,0xFF,0xFD, 0xFE,0xFF,0xF5,0xFF,0xFF,0xFE,0xFF,0xDF,
12780xFB,0xFF,0x5F,0xBF,0xFF,0xFD,0xFF,0xFF, 0xFF,0xFF,0xA8,0xFF,0xFF,0x9F,0x9E,0xFF,
12790xFF,0xFF,0x7F,0xF3,0xFF,0xFF,0xCF,0xFF, 0xF7,0xFD,0xFF,0x7F,0xFF,0xFF,0xFC,0x16,
12800xBF,0xCF,0xA3,0xE5,0xEF,0x7F,0xFF,0xF3, 0xE4,0xFF,0xCF,0x93,0xFC,0xFF,0x3F,0xCF,
12810xFF,0xFF,0xFF,0xD6,0x0F,0x7D,0xBF,0x6E, 0xFB,0xF4,0xFC,0xAF,0x6D,0xDB,0x77,0xB7,
12820x6D,0xDB,0xF6,0xFD,0xBF,0xFF,0xFF,0xFF, 0xBF,0x9B,0xFA,0xDE,0xB7,0xB7,0xED,0xF9,
12830x7E,0xB7,0xAC,0xEB,0xD6,0xB3,0xAD,0xEB, 0x7A,0xDF,0xFF,0xFF,0xFF,0xD8,0xBF,0xFF,
12840xB7,0xED,0x9F,0x6F,0xDD,0xF7,0x68,0xDB, 0x37,0xB3,0x6C,0xDB,0x36,0xCD,0xB3,0x7F,
12850xFF,0x7F,0xF5,0x6F,0xFD,0xEF,0x79,0x3D, 0xF7,0x93,0xE4,0x7A,0x9E,0xAD,0xEA,0x7A,
12860x9E,0xF7,0xBD,0xEF,0xFF,0xFF,0xFF,0x76, 0x7F,0xFB,0xC6,0xFF,0xBB,0xEF,0xDA,0xFE,
12870xFD,0xBF,0xFB,0xFE,0xFF,0xBF,0xEF,0xFB, 0xFF,0xFF,0xFB,0xFF,0xA5,0xFF,0xFD,0xAB,
12880x6F,0x78,0xDE,0x17,0x8F,0x79,0xDF,0xFD, 0xFF,0x7F,0xDF,0xF7,0xFD,0xFF,0xFF,0xFB,
12890xFF,0xFB,0xFF,0xEF,0xFB,0xEF,0xFB,0xFE, 0xFF,0xBB,0xDA,0xF3,0xEF,0x3B,0xCE,0xF3,
12900xBC,0xEF,0x3F,0xCF,0xDF,0xFF,0xB7,0xFF, 0xFF,0xFF,0xCF,0x73,0xFF,0xBF,0xEF,0xFF,
12910xF3,0xFF,0x3F,0xCF,0xF3,0xFC,0xFF,0x3D, 0xCF,0x9F,0xFE,0x07,0xFF,0xAF,0xEB,0xFE,
12920xFD,0xBF,0xEF,0xEB,0xFA,0xFF,0xAF,0xEB, 0xFA,0xFE,0xBF,0xAF,0xFB,0xFE,0x3F,0xFB,
12930x9B,0xFF,0x7F,0xDF,0xFF,0xF3,0xFE,0xFF, 0xDE,0xF7,0xBF,0x7B,0xDE,0xF7,0xBD,0xEF,
12940x7B,0xFE,0xFF,0xFF,0xDF,0x3F,0xFE,0xFF, 0xB7,0xFF,0xEF,0xF7,0xFF,0xBF,0xED,0xFE,
12950xDF,0xB7,0xED,0xFB,0x7E,0xDF,0xFF,0xFF, 0xFF,0xFD,0x5F,0xEF,0xEB,0xFA,0xFE,0xF5,
12960xBF,0x6F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFE,0xF8,0xFF,0xA8,0xFF,
12970xFF,0xBF,0xEF,0xFB,0x6A,0xFB,0xB7,0xEF, 0xFB,0xFF,0xBF,0xEF,0xFB,0xFE,0xFF,0xBF,
12980xEF,0xFB,0xFF,0xE0,0xFF,0xFF,0xFD,0x7F, 0x5C,0xD7,0x7D,0xDF,0xF3,0x5C,0xF5,0xCD,
12990x73,0x5E,0xD7,0xB5,0xFD,0x7F,0xEF,0xFF, 0xDB,0xFF,0xFF,0xE2,0xF8,0xBE,0x2F,0x8F,
13000xE7,0xF8,0xBE,0x6B,0xE2,0xF8,0xBE,0x2F, 0x8B,0xE2,0xF9,0xFE,0x7F,0xE7,0xFF,0xD7,
13010xF5,0xFD,0x7F,0xFF,0xF7,0xF5,0xFD,0x7F, 0xD7,0xF5,0xFD,0x7F,0x5F,0xD7,0xF5,0xFF,
13020xFF,0xFF,0x8F,0xFF,0xAF,0xEB,0xFA,0xFF, 0xFF,0xBF,0xEB,0xFA,0xFF,0x2F,0xEB,0xFA,
13030xFE,0xBF,0xAF,0xEB,0xFF,0xFF,0xFE,0x5F, 0xFF,0x5F,0xFF,0xFF,0xFD,0xFF,0xFF,0xD7,
13040xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xBF,0xFE,0xB7,0xFD,
13050xFF,0x7E,0xDF,0xF7,0xAD,0xFF,0x7F,0xF7, 0xFD,0xFF,0x7F,0xDF,0xF7,0xFD,0xFF,0x7F,
13060xF6,0x7F,0xFF,0xFF,0xFF,0xDB,0xF6,0xFC, 0xAF,0xFF,0xFF,0xFF,0xFF,0xF7,0xFF,0xFF,
13070xFF,0xFF,0xFF,0xFF,0xFF,0xEC,0xBF,0xFF, 0xAF,0xEB,0xFA,0xF6,0xAB,0x8F,0xEB,0xFA,
13080xF7,0xA5,0xEB,0xFA,0xBE,0xBF,0xAF,0xEB, 0xFA,0xFF,0x6D,0xFF,0xFF,0x7F,0xDF,0x33,
13090xDD,0xFF,0x7F,0xFE,0xF7,0xFC,0x7F,0xFB, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xA9,
13100xFF,0xFD,0xFF,0xFF,0xFE,0xFF,0xFF,0xDF, 0xFF,0xFF,0xEF,0xEF,0xFD,0xFF,0x7F,0xFF,
13110xFF,0xFF,0xFF,0xFE,0xA7,0xFF,0xFF,0xFF, 0x77,0xDF,0xF7,0xFD,0x9F,0x7F,0xFE,0x77,
13120xEF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xAF,0xBF,0xAF,0xFF,0xF9,0xBE,0xBF,
13130x8F,0xFB,0xFE,0xFE,0xEF,0xFB,0xFE,0xFF, 0xBF,0xEF,0xFB,0xFF,0xFF,0xFD,0xDF,0x6F,
13140xEF,0xFF,0x7F,0xFF,0xBF,0xBF,0xDF,0xFF, 0xFC,0xFF,0xDF,0xF7,0xFD,0xEF,0x7F,0xDF,
13150xFF,0xFF,0xFF,0x3F,0xF6,0xFF,0xCF,0xFF, 0xDB,0xFB,0xF7,0xFF,0xEB,0x7A,0xFF,0xFF,
13160xFF,0xBF,0xEF,0xFB,0xFF,0xFF,0xFF,0xFE, 0x6D,0xFD,0xFF,0x5F,0xFB,0xFF,0xFF,0xF7,
13170xFF,0x5F,0xF5,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xF8,0xFF,0xFB,0xFF,
13180xFF,0xFD,0xFF,0xFF,0xFF,0xFF,0xE7,0xF6, 0xBF,0xFF,0xFF,0xFF,0xFF,0xFB,0xFF,0xFF,
13190xFF,0xC9,0xFF,0xFF,0xFF,0xBD,0xFF,0xBF, 0xAF,0xEF,0xEF,0x3F,0xD1,0xFC,0x7F,0xFB,
13200xC7,0xFF,0xFF,0xFF,0xFF,0xFF,0xE3,0xFF, 0xFF,0xFF,0xFF,0xFD,0xFF,0xFF,0x77,0xFF,
13210xDF,0xB7,0xFD,0xF7,0xFD,0xF7,0xFF,0xFF, 0xFF,0xFF,0xFF,0x57,0xFF,0xF7,0xA5,0xFD,
13220x3F,0xDF,0xBF,0xBF,0xFE,0x7F,0xFF,0xFF, 0xFF,0xDF,0xFA,0xFD,0xFF,0xFF,0xFF,0xFE,
13230x87,0xFF,0xE9,0xFF,0xFE,0xEF,0xBF,0xEF, 0xFE,0xFE,0xFF,0xEF,0xFF,0xFF,0xFF,0xFF,
13240xFF,0xFF,0xFF,0xFF,0xFA,0x9F,0xFF,0x3F, 0xFF,0xFD,0xFD,0x57,0xDF,0xFD,0xF3,0xFF,
13250xDF,0xFD,0xFF,0x5F,0xDF,0xF5,0xFD,0xFF, 0xFF,0xF9,0x8F,0xFF,0xFF,0xFF,0xEE,0x7F,
13260xFF,0xFF,0xBF,0x5E,0xFE,0xEC,0xFB,0x3F, 0x7F,0x9F,0xEF,0xF9,0xFF,0xFF,0xCD,0x6B,
13270xFF,0xFF,0xFF,0xC5,0xF3,0xFC,0xFA,0x38, 0xFF,0xAF,0x3F,0xEE,0x7F,0x9F,0xFF,0xD9,
13280xFF,0xFF,0xFD,0x7A,0xF7,0xFF,0xF3,0xFF, 0xAF,0x6F,0xDB,0xF2,0xB9,0xE9,0xFB,0xFF,
13290xFF,0xFF,0xFE,0xFF,0xFF,0xEF,0xFF,0xFB, 0xC5,0xBF,0xFF,0xEF,0xFF,0x5E,0xB7,0xAD,
13300xCD,0x79,0x7C,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFD,0x93,0xFF,0xEF,
13310xEA,0xFE,0xBF,0xEF,0x5B,0xD2,0xCD,0xF5, 0x6D,0x77,0xDF,0xF7,0xFD,0xFF,0x7F,0xDF,
13320xFF,0xFF,0x66,0xFF,0xD5,0x65,0x7D,0x5F, 0x75,0x9D,0x65,0x7F,0xD6,0xFB,0x4F,0xFF,
13330xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xF6,0xC7, 0xFF,0xBF,0xEF,0xFA,0xFE,0xFF,0xBF,0xEB,
13340xFF,0xDF,0xFF,0x7E,0xFF,0xFF,0xEF,0xFD, 0x7E,0xD7,0xFF,0x78,0xDF,0xFF,0x5F,0xDF,
13350xF5,0xBF,0x7F,0xDF,0xC5,0xFF,0x3F,0xF6, 0x7E,0xFF,0x0F,0xEF,0xF2,0x3E,0xBF,0xFF,
13360xFB,0x3F,0xFF,0xFB,0x7F,0xFF,0xB3,0xFE, 0xFB,0xF6,0xFD,0xFF,0xDA,0xF7,0xFD,0xFF,
13370x7F,0xDF,0xF7,0xBF,0xFF,0xFA,0x7F,0xFF, 0xFF,0xFF,0xFF,0x9F,0xFF,0xF3,0xDC,0xF9,
13380xBF,0xCE,0xE7,0xF9,0xFE,0x7F,0x9F,0xE7, 0xFF,0xFF,0xE2,0x7F,0xFE,0xFF,0xBF,0xEF,
13390xEB,0xFA,0xFF,0x9F,0x67,0x1E,0xFF,0x8F, 0xE7,0xF8,0xFE,0x7F,0x8F,0xEF,0xFF,0xBD,
13400xBF,0xFF,0xFB,0xFF,0xFF,0xDF,0xF7,0xFF, 0xFC,0xFF,0xBF,0xFF,0xFF,0xFF,0xFF,0xFF,
13410xFF,0xFF,0xFF,0xFD,0xB3,0xFF,0xFF,0xEF, 0xFF,0xFF,0xBF,0xED,0xFF,0xFB,0xEE,0xFE,
13420xFF,0xFF,0xEF,0xFF,0xFE,0xFF,0xFF,0xFF, 0xFF,0xB5,0xFF,0xB7,0xFD,0xFD,0x6E,0xFF,
13430xFF,0xFE,0xFD,0x2F,0xD8,0xFE,0xBF,0x8F, 0xEB,0xF9,0xFE,0x3F,0xFF,0xFA,0xCF,0xFF,
13440xE7,0xD9,0xFA,0xBF,0xDF,0x77,0xFC,0xFB, 0x3F,0xAB,0xFE,0xFF,0xBF,0xEF,0xFB,0xFE,
13450xFF,0xFF,0xEE,0x1F,0xFF,0xDF,0xF7,0xFF, 0xFF,0xFF,0x5F,0x97,0x35,0xBF,0x5E,0xFE,
13460xBF,0xEF,0xFF,0xF7,0xFD,0xFF,0xFF,0xFA, 0xBF,0xFF,0xBE,0x6F,0x9F,0xE7,0xF8,0xBE,
13470x2F,0x8B,0x66,0x94,0x7D,0x9D,0xE7,0xF9, 0xFE,0x7F,0x9F,0xE7,0xF1,0x7F,0xFF,0xFF,
13480xFF,0xF7,0xF5,0xFD,0x7F,0x5F,0xFB,0xFD, 0x9E,0xFF,0xFB,0xFE,0xFF,0xFF,0xEF,0xFF,
13490xFF,0xA0,0xFF,0xFF,0xFF,0xBF,0xEF,0xEB, 0xFA,0xFE,0xBF,0xB7,0xF7,0xF7,0xFF,0xFF,
13500xFD,0xFF,0xFF,0xFF,0xFF,0xFF,0xDD,0xFF, 0xFD,0xFF,0xFF,0xFF,0xD7,0xFF,0xFF,0xFF,
13510x7F,0xF5,0xFF,0xFF,0xEF,0xFF,0xFF,0xFF, 0xBF,0xFF,0xFF,0xAB,0xFE,0xFB,0xFE,0xFF,
13520xF7,0xAF,0xFF,0xFF,0xDE,0xF7,0xEB,0x5F, 0xDF,0xF7,0xFD,0xFF,0x7F,0xDF,0xFF,0xFF,
13530xB3,0xFF,0xC9,0xFE,0xFF,0xFF,0xFF,0xFF, 0xD6,0xFF,0xFF,0xCB,0xFF,0xFF,0xDF,0xFF,
13540xFF,0xFF,0xFF,0xFF,0xFC,0x8F,0xFF,0xBA, 0xBE,0xBF,0xAF,0xEB,0x78,0xFE,0xB7,0xAD,
13550x3A,0xFE,0xB7,0xAF,0xEB,0x7A,0xFE,0xBF, 0xAF,0xFF,0x9F,0xFF,0xFF,0xDF,0xFC,0xFF,
13560xFF,0xFE,0xC3,0xFE,0xFF,0xFF,0x33,0xFC, 0xFF,0xBF,0xDF,0xF3,0xFF,0xFF,0xBB,0x9F,
13570xFF,0xFF,0xFF,0xEB,0xDF,0xFF,0xFF,0xAF, 0xF7,0x6F,0xF9,0xBF,0xEF,0xFD,0xFF,0xFF,
13580xFF,0xFF,0xFF,0xE3,0x7F,0xFF,0xFF,0xFF, 0xFB,0xFF,0xFF,0xBF,0xFD,0xFB,0xF7,0xFF,
13590xDF,0xF7,0xFF,0xFE,0xEF,0x5F,0xBD,0xFF, 0xFA,0xFF,0xF8,0xFF,0xBF,0xAF,0xFB,0xFE,
13600xFE,0x3F,0xEF,0xE8,0xFF,0xDF,0xF3,0xFD, 0xFF,0xFF,0xFF,0xFF,0xFF,0xED,0xFF,0xFB,
13610xFD,0xFF,0xAF,0xFF,0xFF,0xFE,0xFE,0xBF, 0xDB,0xFF,0xFF,0xFF,0xBF,0xFF,0xDF,0xFF,
13620xFD,0xFF,0xCB,0xFF,0xFF,0xFF,0xFF,0xFF, 0xBF,0x6F,0xFF,0x7F,0xB7,0xB3,0xFF,0xFF,
13630xDF,0xFF,0xFB,0xEF,0xFF,0xFF,0xFF,0x07, 0xFF,0xFB,0xFF,0xFF,0xFF,0xED,0xFF,0xF5,
13640x7C,0xFF,0x7F,0xFE,0xFF,0xFF,0xEF,0xCF, 0xFF,0xFB,0xFF,0xFF,0x2F,0xFF,0xFF,0xFF,
13650xFF,0xF3,0xFF,0xFB,0xFF,0xFE,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xBF,0xFF,0xFF,0xFF,
13660xFD,0x1B,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFE,0x7C,0xFF,0xFF,0xFF,0xFF,
13670xEF,0xFF,0xFF,0xFF,0xFF,0xFB,0xBF,0x7F, 0xFD,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
13680xDB,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFD, 0xFF,0xFF,0xF0,0x7F,0xFF,0xFF,0xFF,0xFF,
13690xFF,0xFF,0xFF,0xFF,0xFF,0xFB,0xFF,0xDF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFD,0xBF,0xFE,
13700x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xEF,0xFE,0xFF,0xBF,0xFF,0xFF,0xFF,
13710xFF,0xFF,0xEF,0xFA,0xB5,0xFF,0xFF,0xFF, 0xF7,0xF7,0xFF,0xFF,0xFF,0xFF,0xDF,0xFB,
13720xFC,0xFF,0xFF,0xFE,0xFF,0x7F,0xDF,0xBF, 0xFF,0xCB,0xBF,0xF9,0xFE,0x7F,0x9F,0xE7,
13730xF9,0xFE,0x7F,0x97,0xE1,0xFE,0x79,0x9F, 0xE7,0xFD,0xFE,0x7F,0xDF,0xFE,0x37,0xFF,
13740xFB,0xDE,0xDE,0xBD,0xEF,0xF3,0xFE,0xFB, 0xAF,0xEB,0xFE,0xFF,0xFF,0xCF,0xFF,0xFE,
13750xFF,0xBF,0xFF,0x8F,0xFF,0xEF,0xFB,0xFE, 0xFF,0xBF,0xE7,0xF9,0x5E,0x7F,0xEF,0xFB,
13760xDA,0xFF,0xBF,0xEF,0xFB,0xFE,0xFF,0xFD, 0x1F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xDF,
13770xFF,0xFF,0x7F,0xFF,0xFF,0xF7,0xFB,0x7F, 0xFF,0xFF,0xFF,0xFF,0xFC,0x3F,0xFF,0xBF,
13780xEF,0xFB,0xFE,0xFF,0xBF,0xEF,0x7B,0x7F, 0xBF,0xEF,0xFB,0xFE,0xFF,0xB5,0xEF,0xFB,
13790xBF,0xFA,0x7F,0xFC,0xFF,0x3F,0xCF,0xF3, 0xFC,0xFF,0x3F,0xCF,0xBC,0xFF,0x3F,0xEF,
13800xF3,0xFC,0xFE,0x3F,0xCF,0xFF,0xEE,0xEF, 0xFB,0xFE,0xFF,0xBF,0xEF,0xFB,0x6A,0xD7,
13810xB7,0xFB,0xF8,0xFF,0xB7,0xEF,0xBA,0xFE, 0xFF,0xBF,0x7F,0xE9,0xFF,0xF9,0x7E,0x5F,
13820x97,0xE5,0xF9,0xFE,0x7F,0xBF,0xF9,0x7E, 0x5F,0x9F,0xE5,0xFB,0xFE,0x5F,0xB7,0xFF,
13830xA3,0xFF,0xF7,0xFD,0xFF,0x7F,0xDF,0xF7, 0xFD,0xFF,0x5E,0xF7,0x7D,0xFF,0x77,0xDF,
13840xF7,0xFD,0xFF,0x7F,0xFF,0xD7,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFD,0xDF,0xFB,0x7F,
13850xFF,0xFF,0xEF,0xFF,0xFE,0xFB,0xFF,0xFF, 0xBF,0xFE,0x8F,0xFF,0xDF,0xF7,0xFD,0xFD,
13860x7F,0xDF,0xF7,0xFD,0x3E,0xDF,0xF5,0xBD, 0xFF,0x7F,0xDF,0xF7,0xFD,0xF7,0xFF,0x9F,
13870xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFD,0xFF,0xBE,0xFF,0xFF,0xFF,0xFF,
13880xFF,0xFF,0xFF,0xFD,0x3F,0xFF,0xDF,0xF7, 0xFD,0xFF,0x7F,0xDF,0xF7,0xFD,0xFF,0xCF,
13890x77,0xFC,0xFF,0x5F,0xDF,0xF7,0xFD,0xFF, 0xF4,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
13900xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFD,0xFF,0xFF,0xFF,0xEE,0xFF,0xFF,
13910xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xED,0xFB,0xFF,0xFF,0xBF,0xFF,0xFF,0xFF,
13920xFF,0xFF,0xE9,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFB,0xFF,0xFF,0xFF,0xD3,0xFF,0xFF,
13930xBF,0x3F,0xFB,0xFF,0xFF,0xFF,0xFB,0xF3, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
13940xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xF7, 0xFF,0xFF,0xFF,0xFF,0x17,0xFF,0xFF,0xFF,
13950xDF,0xFF,0xFD,0xFF,0xFF,0xFF,0xFF,0xFF, 0xDF,0xDF,0xFF,0xFD,0xFF,0xFF,0xDF,0xF7,
13960xFF,0x4F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFD,
13970xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0x9F,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
13980xFD,0xFF,0xFF,0xFF,0xFF,0xFF,0x7F,0xFF, 0xFF,0xFF,0x7A,0x3F,0xFF,0xFF,0xFF,0xFF,
13990xFF,0xFF,0xFF,0x7F,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xF2,
14000x7F,0xFF,0xFB,0xFE,0xFF,0xBF,0xEF,0xF8, 0xFE,0xFF,0xBF,0xFB,0xFE,0xFF,0x8F,0xEC,
14010xFB,0xFE,0xFF,0xBF,0xF8,0xF7,0xFE,0xFF, 0xBF,0xEF,0xFB,0xFE,0xFD,0xBF,0xCF,0xEC,
14020xFF,0x3F,0xEF,0xDB,0xF8,0xFF,0xBF,0xCF, 0xFF,0xF9,0xFF,0xFF,0xBF,0xFF,0xFB,0xFF,
14030xFF,0xFF,0xEF,0xFB,0xDF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xBF,0xFF,0xFF,0xFF,0xBB,0xFF,
14040xEF,0xFB,0xFE,0xEF,0xBF,0xEE,0xEB,0xFB, 0xFE,0xFF,0xEF,0xFE,0xEE,0xBF,0xFE,0xEB,
14050xFF,0xEF,0xFF,0x17,0xFF,0x7E,0xEB,0xBB, 0xFE,0xBF,0xBE,0xFB,0xEF,0x5B,0xF7,0xBD,
14060xFB,0xCF,0xBF,0xBF,0xBB,0xFB,0x7E,0xCC, 0xEF,0xFF
1407
1408};
diff --git a/drivers/media/video/dabusb.c b/drivers/media/video/dabusb.c
new file mode 100644
index 000000000000..1774ab7a40d2
--- /dev/null
+++ b/drivers/media/video/dabusb.c
@@ -0,0 +1,874 @@
1/*****************************************************************************/
2
3/*
4 * dabusb.c -- dab usb driver.
5 *
6 * Copyright (C) 1999 Deti Fliegl (deti@fliegl.de)
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 *
22 *
23 *
24 * $Id: dabusb.c,v 1.54 2000/07/24 21:39:39 deti Exp $
25 *
26 */
27
28/*****************************************************************************/
29
30#include <linux/module.h>
31#include <linux/socket.h>
32#include <linux/list.h>
33#include <linux/vmalloc.h>
34#include <linux/slab.h>
35#include <linux/init.h>
36#include <asm/uaccess.h>
37#include <asm/atomic.h>
38#include <linux/delay.h>
39#include <linux/usb.h>
40#include <linux/smp_lock.h>
41#include <linux/mutex.h>
42
43#include "dabusb.h"
44#include "dabfirmware.h"
45
46/*
47 * Version Information
48 */
49#define DRIVER_VERSION "v1.54"
50#define DRIVER_AUTHOR "Deti Fliegl, deti@fliegl.de"
51#define DRIVER_DESC "DAB-USB Interface Driver for Linux (c)1999"
52
53/* --------------------------------------------------------------------- */
54
55#ifdef CONFIG_USB_DYNAMIC_MINORS
56#define NRDABUSB 256
57#else
58#define NRDABUSB 4
59#endif
60
61/*-------------------------------------------------------------------*/
62
63static dabusb_t dabusb[NRDABUSB];
64static int buffers = 256;
65static struct usb_driver dabusb_driver;
66
67/*-------------------------------------------------------------------*/
68
69static int dabusb_add_buf_tail (pdabusb_t s, struct list_head *dst, struct list_head *src)
70{
71 unsigned long flags;
72 struct list_head *tmp;
73 int ret = 0;
74
75 spin_lock_irqsave (&s->lock, flags);
76
77 if (list_empty (src)) {
78 // no elements in source buffer
79 ret = -1;
80 goto err;
81 }
82 tmp = src->next;
83 list_move_tail (tmp, dst);
84
85 err: spin_unlock_irqrestore (&s->lock, flags);
86 return ret;
87}
88/*-------------------------------------------------------------------*/
89#ifdef DEBUG
90static void dump_urb (struct urb *urb)
91{
92 dbg("urb :%p", urb);
93 dbg("dev :%p", urb->dev);
94 dbg("pipe :%08X", urb->pipe);
95 dbg("status :%d", urb->status);
96 dbg("transfer_flags :%08X", urb->transfer_flags);
97 dbg("transfer_buffer :%p", urb->transfer_buffer);
98 dbg("transfer_buffer_length:%d", urb->transfer_buffer_length);
99 dbg("actual_length :%d", urb->actual_length);
100 dbg("setup_packet :%p", urb->setup_packet);
101 dbg("start_frame :%d", urb->start_frame);
102 dbg("number_of_packets :%d", urb->number_of_packets);
103 dbg("interval :%d", urb->interval);
104 dbg("error_count :%d", urb->error_count);
105 dbg("context :%p", urb->context);
106 dbg("complete :%p", urb->complete);
107}
108#endif
109/*-------------------------------------------------------------------*/
110static int dabusb_cancel_queue (pdabusb_t s, struct list_head *q)
111{
112 unsigned long flags;
113 pbuff_t b;
114
115 dbg("dabusb_cancel_queue");
116
117 spin_lock_irqsave (&s->lock, flags);
118
119 list_for_each_entry(b, q, buff_list) {
120#ifdef DEBUG
121 dump_urb(b->purb);
122#endif
123 usb_unlink_urb (b->purb);
124 }
125 spin_unlock_irqrestore (&s->lock, flags);
126 return 0;
127}
128/*-------------------------------------------------------------------*/
129static int dabusb_free_queue (struct list_head *q)
130{
131 struct list_head *tmp;
132 struct list_head *p;
133 pbuff_t b;
134
135 dbg("dabusb_free_queue");
136 for (p = q->next; p != q;) {
137 b = list_entry (p, buff_t, buff_list);
138
139#ifdef DEBUG
140 dump_urb(b->purb);
141#endif
142 kfree(b->purb->transfer_buffer);
143 usb_free_urb(b->purb);
144 tmp = p->next;
145 list_del (p);
146 kfree (b);
147 p = tmp;
148 }
149
150 return 0;
151}
152/*-------------------------------------------------------------------*/
153static int dabusb_free_buffers (pdabusb_t s)
154{
155 unsigned long flags;
156 dbg("dabusb_free_buffers");
157
158 spin_lock_irqsave(&s->lock, flags);
159
160 dabusb_free_queue (&s->free_buff_list);
161 dabusb_free_queue (&s->rec_buff_list);
162
163 spin_unlock_irqrestore(&s->lock, flags);
164
165 s->got_mem = 0;
166 return 0;
167}
168/*-------------------------------------------------------------------*/
169static void dabusb_iso_complete (struct urb *purb, struct pt_regs *regs)
170{
171 pbuff_t b = purb->context;
172 pdabusb_t s = b->s;
173 int i;
174 int len;
175 int dst = 0;
176 void *buf = purb->transfer_buffer;
177
178 dbg("dabusb_iso_complete");
179
180 // process if URB was not killed
181 if (purb->status != -ENOENT) {
182 unsigned int pipe = usb_rcvisocpipe (purb->dev, _DABUSB_ISOPIPE);
183 int pipesize = usb_maxpacket (purb->dev, pipe, usb_pipeout (pipe));
184 for (i = 0; i < purb->number_of_packets; i++)
185 if (!purb->iso_frame_desc[i].status) {
186 len = purb->iso_frame_desc[i].actual_length;
187 if (len <= pipesize) {
188 memcpy (buf + dst, buf + purb->iso_frame_desc[i].offset, len);
189 dst += len;
190 }
191 else
192 err("dabusb_iso_complete: invalid len %d", len);
193 }
194 else
195 warn("dabusb_iso_complete: corrupted packet status: %d", purb->iso_frame_desc[i].status);
196 if (dst != purb->actual_length)
197 err("dst!=purb->actual_length:%d!=%d", dst, purb->actual_length);
198 }
199
200 if (atomic_dec_and_test (&s->pending_io) && !s->remove_pending && s->state != _stopped) {
201 s->overruns++;
202 err("overrun (%d)", s->overruns);
203 }
204 wake_up (&s->wait);
205}
206/*-------------------------------------------------------------------*/
207static int dabusb_alloc_buffers (pdabusb_t s)
208{
209 int buffers = 0;
210 pbuff_t b;
211 unsigned int pipe = usb_rcvisocpipe (s->usbdev, _DABUSB_ISOPIPE);
212 int pipesize = usb_maxpacket (s->usbdev, pipe, usb_pipeout (pipe));
213 int packets = _ISOPIPESIZE / pipesize;
214 int transfer_buffer_length = packets * pipesize;
215 int i;
216
217 dbg("dabusb_alloc_buffers pipesize:%d packets:%d transfer_buffer_len:%d",
218 pipesize, packets, transfer_buffer_length);
219
220 while (buffers < (s->total_buffer_size << 10)) {
221 b = (pbuff_t) kzalloc (sizeof (buff_t), GFP_KERNEL);
222 if (!b) {
223 err("kzalloc(sizeof(buff_t))==NULL");
224 goto err;
225 }
226 b->s = s;
227 b->purb = usb_alloc_urb(packets, GFP_KERNEL);
228 if (!b->purb) {
229 err("usb_alloc_urb == NULL");
230 kfree (b);
231 goto err;
232 }
233
234 b->purb->transfer_buffer = kmalloc (transfer_buffer_length, GFP_KERNEL);
235 if (!b->purb->transfer_buffer) {
236 kfree (b->purb);
237 kfree (b);
238 err("kmalloc(%d)==NULL", transfer_buffer_length);
239 goto err;
240 }
241
242 b->purb->transfer_buffer_length = transfer_buffer_length;
243 b->purb->number_of_packets = packets;
244 b->purb->complete = dabusb_iso_complete;
245 b->purb->context = b;
246 b->purb->dev = s->usbdev;
247 b->purb->pipe = pipe;
248 b->purb->transfer_flags = URB_ISO_ASAP;
249
250 for (i = 0; i < packets; i++) {
251 b->purb->iso_frame_desc[i].offset = i * pipesize;
252 b->purb->iso_frame_desc[i].length = pipesize;
253 }
254
255 buffers += transfer_buffer_length;
256 list_add_tail (&b->buff_list, &s->free_buff_list);
257 }
258 s->got_mem = buffers;
259
260 return 0;
261
262 err:
263 dabusb_free_buffers (s);
264 return -ENOMEM;
265}
266/*-------------------------------------------------------------------*/
267static int dabusb_bulk (pdabusb_t s, pbulk_transfer_t pb)
268{
269 int ret;
270 unsigned int pipe;
271 int actual_length;
272
273 dbg("dabusb_bulk");
274
275 if (!pb->pipe)
276 pipe = usb_rcvbulkpipe (s->usbdev, 2);
277 else
278 pipe = usb_sndbulkpipe (s->usbdev, 2);
279
280 ret=usb_bulk_msg(s->usbdev, pipe, pb->data, pb->size, &actual_length, 100);
281 if(ret<0) {
282 err("dabusb: usb_bulk_msg failed(%d)",ret);
283
284 if (usb_set_interface (s->usbdev, _DABUSB_IF, 1) < 0) {
285 err("set_interface failed");
286 return -EINVAL;
287 }
288
289 }
290
291 if( ret == -EPIPE ) {
292 warn("CLEAR_FEATURE request to remove STALL condition.");
293 if(usb_clear_halt(s->usbdev, usb_pipeendpoint(pipe)))
294 err("request failed");
295 }
296
297 pb->size = actual_length;
298 return ret;
299}
300/* --------------------------------------------------------------------- */
301static int dabusb_writemem (pdabusb_t s, int pos, unsigned char *data, int len)
302{
303 int ret;
304 unsigned char *transfer_buffer = kmalloc (len, GFP_KERNEL);
305
306 if (!transfer_buffer) {
307 err("dabusb_writemem: kmalloc(%d) failed.", len);
308 return -ENOMEM;
309 }
310
311 memcpy (transfer_buffer, data, len);
312
313 ret=usb_control_msg(s->usbdev, usb_sndctrlpipe( s->usbdev, 0 ), 0xa0, 0x40, pos, 0, transfer_buffer, len, 300);
314
315 kfree (transfer_buffer);
316 return ret;
317}
318/* --------------------------------------------------------------------- */
319static int dabusb_8051_reset (pdabusb_t s, unsigned char reset_bit)
320{
321 dbg("dabusb_8051_reset: %d",reset_bit);
322 return dabusb_writemem (s, CPUCS_REG, &reset_bit, 1);
323}
324/* --------------------------------------------------------------------- */
325static int dabusb_loadmem (pdabusb_t s, const char *fname)
326{
327 int ret;
328 PINTEL_HEX_RECORD ptr = firmware;
329
330 dbg("Enter dabusb_loadmem (internal)");
331
332 ret = dabusb_8051_reset (s, 1);
333 while (ptr->Type == 0) {
334
335 dbg("dabusb_writemem: %04X %p %d)", ptr->Address, ptr->Data, ptr->Length);
336
337 ret = dabusb_writemem (s, ptr->Address, ptr->Data, ptr->Length);
338 if (ret < 0) {
339 err("dabusb_writemem failed (%d %04X %p %d)", ret, ptr->Address, ptr->Data, ptr->Length);
340 break;
341 }
342 ptr++;
343 }
344 ret = dabusb_8051_reset (s, 0);
345
346 dbg("dabusb_loadmem: exit");
347
348 return ret;
349}
350/* --------------------------------------------------------------------- */
351static int dabusb_fpga_clear (pdabusb_t s, pbulk_transfer_t b)
352{
353 b->size = 4;
354 b->data[0] = 0x2a;
355 b->data[1] = 0;
356 b->data[2] = 0;
357 b->data[3] = 0;
358
359 dbg("dabusb_fpga_clear");
360
361 return dabusb_bulk (s, b);
362}
363/* --------------------------------------------------------------------- */
364static int dabusb_fpga_init (pdabusb_t s, pbulk_transfer_t b)
365{
366 b->size = 4;
367 b->data[0] = 0x2c;
368 b->data[1] = 0;
369 b->data[2] = 0;
370 b->data[3] = 0;
371
372 dbg("dabusb_fpga_init");
373
374 return dabusb_bulk (s, b);
375}
376/* --------------------------------------------------------------------- */
377static int dabusb_fpga_download (pdabusb_t s, const char *fname)
378{
379 pbulk_transfer_t b = kmalloc (sizeof (bulk_transfer_t), GFP_KERNEL);
380 unsigned int blen, n;
381 int ret;
382 unsigned char *buf = bitstream;
383
384 dbg("Enter dabusb_fpga_download (internal)");
385
386 if (!b) {
387 err("kmalloc(sizeof(bulk_transfer_t))==NULL");
388 return -ENOMEM;
389 }
390
391 b->pipe = 1;
392 ret = dabusb_fpga_clear (s, b);
393 mdelay (10);
394 blen = buf[73] + (buf[72] << 8);
395
396 dbg("Bitstream len: %i", blen);
397
398 b->data[0] = 0x2b;
399 b->data[1] = 0;
400 b->data[2] = 0;
401 b->data[3] = 60;
402
403 for (n = 0; n <= blen + 60; n += 60) {
404 // some cclks for startup
405 b->size = 64;
406 memcpy (b->data + 4, buf + 74 + n, 60);
407 ret = dabusb_bulk (s, b);
408 if (ret < 0) {
409 err("dabusb_bulk failed.");
410 break;
411 }
412 mdelay (1);
413 }
414
415 ret = dabusb_fpga_init (s, b);
416 kfree (b);
417
418 dbg("exit dabusb_fpga_download");
419
420 return ret;
421}
422
423static int dabusb_stop (pdabusb_t s)
424{
425 dbg("dabusb_stop");
426
427 s->state = _stopped;
428 dabusb_cancel_queue (s, &s->rec_buff_list);
429
430 dbg("pending_io: %d", s->pending_io.counter);
431
432 s->pending_io.counter = 0;
433 return 0;
434}
435
436static int dabusb_startrek (pdabusb_t s)
437{
438 if (!s->got_mem && s->state != _started) {
439
440 dbg("dabusb_startrek");
441
442 if (dabusb_alloc_buffers (s) < 0)
443 return -ENOMEM;
444 dabusb_stop (s);
445 s->state = _started;
446 s->readptr = 0;
447 }
448
449 if (!list_empty (&s->free_buff_list)) {
450 pbuff_t end;
451 int ret;
452
453 while (!dabusb_add_buf_tail (s, &s->rec_buff_list, &s->free_buff_list)) {
454
455 dbg("submitting: end:%p s->rec_buff_list:%p", s->rec_buff_list.prev, &s->rec_buff_list);
456
457 end = list_entry (s->rec_buff_list.prev, buff_t, buff_list);
458
459 ret = usb_submit_urb (end->purb, GFP_KERNEL);
460 if (ret) {
461 err("usb_submit_urb returned:%d", ret);
462 if (dabusb_add_buf_tail (s, &s->free_buff_list, &s->rec_buff_list))
463 err("startrek: dabusb_add_buf_tail failed");
464 break;
465 }
466 else
467 atomic_inc (&s->pending_io);
468 }
469 dbg("pending_io: %d",s->pending_io.counter);
470 }
471
472 return 0;
473}
474
475static ssize_t dabusb_read (struct file *file, char __user *buf, size_t count, loff_t * ppos)
476{
477 pdabusb_t s = (pdabusb_t) file->private_data;
478 unsigned long flags;
479 unsigned ret = 0;
480 int rem;
481 int cnt;
482 pbuff_t b;
483 struct urb *purb = NULL;
484
485 dbg("dabusb_read");
486
487 if (*ppos)
488 return -ESPIPE;
489
490 if (s->remove_pending)
491 return -EIO;
492
493
494 if (!s->usbdev)
495 return -EIO;
496
497 while (count > 0) {
498 dabusb_startrek (s);
499
500 spin_lock_irqsave (&s->lock, flags);
501
502 if (list_empty (&s->rec_buff_list)) {
503
504 spin_unlock_irqrestore(&s->lock, flags);
505
506 err("error: rec_buf_list is empty");
507 goto err;
508 }
509
510 b = list_entry (s->rec_buff_list.next, buff_t, buff_list);
511 purb = b->purb;
512
513 spin_unlock_irqrestore(&s->lock, flags);
514
515 if (purb->status == -EINPROGRESS) {
516 if (file->f_flags & O_NONBLOCK) // return nonblocking
517 {
518 if (!ret)
519 ret = -EAGAIN;
520 goto err;
521 }
522
523 interruptible_sleep_on (&s->wait);
524
525 if (signal_pending (current)) {
526 if (!ret)
527 ret = -ERESTARTSYS;
528 goto err;
529 }
530
531 spin_lock_irqsave (&s->lock, flags);
532
533 if (list_empty (&s->rec_buff_list)) {
534 spin_unlock_irqrestore(&s->lock, flags);
535 err("error: still no buffer available.");
536 goto err;
537 }
538 spin_unlock_irqrestore(&s->lock, flags);
539 s->readptr = 0;
540 }
541 if (s->remove_pending) {
542 ret = -EIO;
543 goto err;
544 }
545
546 rem = purb->actual_length - s->readptr; // set remaining bytes to copy
547
548 if (count >= rem)
549 cnt = rem;
550 else
551 cnt = count;
552
553 dbg("copy_to_user:%p %p %d",buf, purb->transfer_buffer + s->readptr, cnt);
554
555 if (copy_to_user (buf, purb->transfer_buffer + s->readptr, cnt)) {
556 err("read: copy_to_user failed");
557 if (!ret)
558 ret = -EFAULT;
559 goto err;
560 }
561
562 s->readptr += cnt;
563 count -= cnt;
564 buf += cnt;
565 ret += cnt;
566
567 if (s->readptr == purb->actual_length) {
568 // finished, take next buffer
569 if (dabusb_add_buf_tail (s, &s->free_buff_list, &s->rec_buff_list))
570 err("read: dabusb_add_buf_tail failed");
571 s->readptr = 0;
572 }
573 }
574 err: //mutex_unlock(&s->mutex);
575 return ret;
576}
577
578static int dabusb_open (struct inode *inode, struct file *file)
579{
580 int devnum = iminor(inode);
581 pdabusb_t s;
582
583 if (devnum < DABUSB_MINOR || devnum >= (DABUSB_MINOR + NRDABUSB))
584 return -EIO;
585
586 s = &dabusb[devnum - DABUSB_MINOR];
587
588 dbg("dabusb_open");
589 mutex_lock(&s->mutex);
590
591 while (!s->usbdev || s->opened) {
592 mutex_unlock(&s->mutex);
593
594 if (file->f_flags & O_NONBLOCK) {
595 return -EBUSY;
596 }
597 msleep_interruptible(500);
598
599 if (signal_pending (current)) {
600 return -EAGAIN;
601 }
602 mutex_lock(&s->mutex);
603 }
604 if (usb_set_interface (s->usbdev, _DABUSB_IF, 1) < 0) {
605 mutex_unlock(&s->mutex);
606 err("set_interface failed");
607 return -EINVAL;
608 }
609 s->opened = 1;
610 mutex_unlock(&s->mutex);
611
612 file->f_pos = 0;
613 file->private_data = s;
614
615 return nonseekable_open(inode, file);
616}
617
618static int dabusb_release (struct inode *inode, struct file *file)
619{
620 pdabusb_t s = (pdabusb_t) file->private_data;
621
622 dbg("dabusb_release");
623
624 mutex_lock(&s->mutex);
625 dabusb_stop (s);
626 dabusb_free_buffers (s);
627 mutex_unlock(&s->mutex);
628
629 if (!s->remove_pending) {
630 if (usb_set_interface (s->usbdev, _DABUSB_IF, 0) < 0)
631 err("set_interface failed");
632 }
633 else
634 wake_up (&s->remove_ok);
635
636 s->opened = 0;
637 return 0;
638}
639
640static int dabusb_ioctl (struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
641{
642 pdabusb_t s = (pdabusb_t) file->private_data;
643 pbulk_transfer_t pbulk;
644 int ret = 0;
645 int version = DABUSB_VERSION;
646
647 dbg("dabusb_ioctl");
648
649 if (s->remove_pending)
650 return -EIO;
651
652 mutex_lock(&s->mutex);
653
654 if (!s->usbdev) {
655 mutex_unlock(&s->mutex);
656 return -EIO;
657 }
658
659 switch (cmd) {
660
661 case IOCTL_DAB_BULK:
662 pbulk = (pbulk_transfer_t) kmalloc (sizeof (bulk_transfer_t), GFP_KERNEL);
663
664 if (!pbulk) {
665 ret = -ENOMEM;
666 break;
667 }
668
669 if (copy_from_user (pbulk, (void __user *) arg, sizeof (bulk_transfer_t))) {
670 ret = -EFAULT;
671 kfree (pbulk);
672 break;
673 }
674
675 ret=dabusb_bulk (s, pbulk);
676 if(ret==0)
677 if (copy_to_user((void __user *)arg, pbulk,
678 sizeof(bulk_transfer_t)))
679 ret = -EFAULT;
680 kfree (pbulk);
681 break;
682
683 case IOCTL_DAB_OVERRUNS:
684 ret = put_user (s->overruns, (unsigned int __user *) arg);
685 break;
686
687 case IOCTL_DAB_VERSION:
688 ret = put_user (version, (unsigned int __user *) arg);
689 break;
690
691 default:
692 ret = -ENOIOCTLCMD;
693 break;
694 }
695 mutex_unlock(&s->mutex);
696 return ret;
697}
698
699static struct file_operations dabusb_fops =
700{
701 .owner = THIS_MODULE,
702 .llseek = no_llseek,
703 .read = dabusb_read,
704 .ioctl = dabusb_ioctl,
705 .open = dabusb_open,
706 .release = dabusb_release,
707};
708
709static struct usb_class_driver dabusb_class = {
710 .name = "dabusb%d",
711 .fops = &dabusb_fops,
712 .minor_base = DABUSB_MINOR,
713};
714
715
716/* --------------------------------------------------------------------- */
717static int dabusb_probe (struct usb_interface *intf,
718 const struct usb_device_id *id)
719{
720 struct usb_device *usbdev = interface_to_usbdev(intf);
721 int retval;
722 pdabusb_t s;
723
724 dbg("dabusb: probe: vendor id 0x%x, device id 0x%x ifnum:%d",
725 le16_to_cpu(usbdev->descriptor.idVendor),
726 le16_to_cpu(usbdev->descriptor.idProduct),
727 intf->altsetting->desc.bInterfaceNumber);
728
729 /* We don't handle multiple configurations */
730 if (usbdev->descriptor.bNumConfigurations != 1)
731 return -ENODEV;
732
733 if (intf->altsetting->desc.bInterfaceNumber != _DABUSB_IF &&
734 le16_to_cpu(usbdev->descriptor.idProduct) == 0x9999)
735 return -ENODEV;
736
737
738
739 s = &dabusb[intf->minor];
740
741 mutex_lock(&s->mutex);
742 s->remove_pending = 0;
743 s->usbdev = usbdev;
744 s->devnum = intf->minor;
745
746 if (usb_reset_configuration (usbdev) < 0) {
747 err("reset_configuration failed");
748 goto reject;
749 }
750 if (le16_to_cpu(usbdev->descriptor.idProduct) == 0x2131) {
751 dabusb_loadmem (s, NULL);
752 goto reject;
753 }
754 else {
755 dabusb_fpga_download (s, NULL);
756
757 if (usb_set_interface (s->usbdev, _DABUSB_IF, 0) < 0) {
758 err("set_interface failed");
759 goto reject;
760 }
761 }
762 dbg("bound to interface: %d", intf->altsetting->desc.bInterfaceNumber);
763 usb_set_intfdata (intf, s);
764 mutex_unlock(&s->mutex);
765
766 retval = usb_register_dev(intf, &dabusb_class);
767 if (retval) {
768 usb_set_intfdata (intf, NULL);
769 return -ENOMEM;
770 }
771
772 return 0;
773
774 reject:
775 mutex_unlock(&s->mutex);
776 s->usbdev = NULL;
777 return -ENODEV;
778}
779
780static void dabusb_disconnect (struct usb_interface *intf)
781{
782 wait_queue_t __wait;
783 pdabusb_t s = usb_get_intfdata (intf);
784
785 dbg("dabusb_disconnect");
786
787 init_waitqueue_entry(&__wait, current);
788
789 usb_set_intfdata (intf, NULL);
790 if (s) {
791 usb_deregister_dev (intf, &dabusb_class);
792 s->remove_pending = 1;
793 wake_up (&s->wait);
794 add_wait_queue(&s->remove_ok, &__wait);
795 set_current_state(TASK_UNINTERRUPTIBLE);
796 if (s->state == _started)
797 schedule();
798 current->state = TASK_RUNNING;
799 remove_wait_queue(&s->remove_ok, &__wait);
800
801 s->usbdev = NULL;
802 s->overruns = 0;
803 }
804}
805
806static struct usb_device_id dabusb_ids [] = {
807 // { USB_DEVICE(0x0547, 0x2131) }, /* An2131 chip, no boot ROM */
808 { USB_DEVICE(0x0547, 0x9999) },
809 { } /* Terminating entry */
810};
811
812MODULE_DEVICE_TABLE (usb, dabusb_ids);
813
814static struct usb_driver dabusb_driver = {
815 .name = "dabusb",
816 .probe = dabusb_probe,
817 .disconnect = dabusb_disconnect,
818 .id_table = dabusb_ids,
819};
820
821/* --------------------------------------------------------------------- */
822
823static int __init dabusb_init (void)
824{
825 int retval;
826 unsigned u;
827
828 /* initialize struct */
829 for (u = 0; u < NRDABUSB; u++) {
830 pdabusb_t s = &dabusb[u];
831 memset (s, 0, sizeof (dabusb_t));
832 mutex_init (&s->mutex);
833 s->usbdev = NULL;
834 s->total_buffer_size = buffers;
835 init_waitqueue_head (&s->wait);
836 init_waitqueue_head (&s->remove_ok);
837 spin_lock_init (&s->lock);
838 INIT_LIST_HEAD (&s->free_buff_list);
839 INIT_LIST_HEAD (&s->rec_buff_list);
840 }
841
842 /* register misc device */
843 retval = usb_register(&dabusb_driver);
844 if (retval)
845 goto out;
846
847 dbg("dabusb_init: driver registered");
848
849 info(DRIVER_VERSION ":" DRIVER_DESC);
850
851out:
852 return retval;
853}
854
855static void __exit dabusb_cleanup (void)
856{
857 dbg("dabusb_cleanup");
858
859 usb_deregister (&dabusb_driver);
860}
861
862/* --------------------------------------------------------------------- */
863
864MODULE_AUTHOR( DRIVER_AUTHOR );
865MODULE_DESCRIPTION( DRIVER_DESC );
866MODULE_LICENSE("GPL");
867
868module_param(buffers, int, 0);
869MODULE_PARM_DESC (buffers, "Number of buffers (default=256)");
870
871module_init (dabusb_init);
872module_exit (dabusb_cleanup);
873
874/* --------------------------------------------------------------------- */
diff --git a/drivers/media/video/dabusb.h b/drivers/media/video/dabusb.h
new file mode 100644
index 000000000000..96b03e4af8b9
--- /dev/null
+++ b/drivers/media/video/dabusb.h
@@ -0,0 +1,85 @@
1#define _BULK_DATA_LEN 64
2typedef struct
3{
4 unsigned char data[_BULK_DATA_LEN];
5 unsigned int size;
6 unsigned int pipe;
7}bulk_transfer_t,*pbulk_transfer_t;
8
9#define DABUSB_MINOR 240 /* some unassigned USB minor */
10#define DABUSB_VERSION 0x1000
11#define IOCTL_DAB_BULK _IOWR('d', 0x30, bulk_transfer_t)
12#define IOCTL_DAB_OVERRUNS _IOR('d', 0x15, int)
13#define IOCTL_DAB_VERSION _IOR('d', 0x3f, int)
14
15#ifdef __KERNEL__
16
17typedef enum { _stopped=0, _started } driver_state_t;
18
19typedef struct
20{
21 struct mutex mutex;
22 struct usb_device *usbdev;
23 wait_queue_head_t wait;
24 wait_queue_head_t remove_ok;
25 spinlock_t lock;
26 atomic_t pending_io;
27 driver_state_t state;
28 int remove_pending;
29 int got_mem;
30 int total_buffer_size;
31 unsigned int overruns;
32 int readptr;
33 int opened;
34 int devnum;
35 struct list_head free_buff_list;
36 struct list_head rec_buff_list;
37} dabusb_t,*pdabusb_t;
38
39typedef struct
40{
41 pdabusb_t s;
42 struct urb *purb;
43 struct list_head buff_list;
44} buff_t,*pbuff_t;
45
46typedef struct
47{
48 wait_queue_head_t wait;
49} bulk_completion_context_t, *pbulk_completion_context_t;
50
51
52#define _DABUSB_IF 2
53#define _DABUSB_ISOPIPE 0x09
54#define _ISOPIPESIZE 16384
55
56#define _BULK_DATA_LEN 64
57// Vendor specific request code for Anchor Upload/Download
58// This one is implemented in the core
59#define ANCHOR_LOAD_INTERNAL 0xA0
60
61// EZ-USB Control and Status Register. Bit 0 controls 8051 reset
62#define CPUCS_REG 0x7F92
63#define _TOTAL_BUFFERS 384
64
65#define MAX_INTEL_HEX_RECORD_LENGTH 16
66
67#ifndef _BYTE_DEFINED
68#define _BYTE_DEFINED
69typedef unsigned char BYTE;
70#endif // !_BYTE_DEFINED
71
72#ifndef _WORD_DEFINED
73#define _WORD_DEFINED
74typedef unsigned short WORD;
75#endif // !_WORD_DEFINED
76
77typedef struct _INTEL_HEX_RECORD
78{
79 BYTE Length;
80 WORD Address;
81 BYTE Type;
82 BYTE Data[MAX_INTEL_HEX_RECORD_LENGTH];
83} INTEL_HEX_RECORD, *PINTEL_HEX_RECORD;
84
85#endif
diff --git a/drivers/media/video/dsbr100.c b/drivers/media/video/dsbr100.c
new file mode 100644
index 000000000000..25646804d5be
--- /dev/null
+++ b/drivers/media/video/dsbr100.c
@@ -0,0 +1,429 @@
1/* A driver for the D-Link DSB-R100 USB radio. The R100 plugs
2 into both the USB and an analog audio input, so this thing
3 only deals with initialisation and frequency setting, the
4 audio data has to be handled by a sound driver.
5
6 Major issue: I can't find out where the device reports the signal
7 strength, and indeed the windows software appearantly just looks
8 at the stereo indicator as well. So, scanning will only find
9 stereo stations. Sad, but I can't help it.
10
11 Also, the windows program sends oodles of messages over to the
12 device, and I couldn't figure out their meaning. My suspicion
13 is that they don't have any:-)
14
15 You might find some interesting stuff about this module at
16 http://unimut.fsk.uni-heidelberg.de/unimut/demi/dsbr
17
18 Copyright (c) 2000 Markus Demleitner <msdemlei@cl.uni-heidelberg.de>
19
20 This program is free software; you can redistribute it and/or modify
21 it under the terms of the GNU General Public License as published by
22 the Free Software Foundation; either version 2 of the License, or
23 (at your option) any later version.
24
25 This program is distributed in the hope that it will be useful,
26 but WITHOUT ANY WARRANTY; without even the implied warranty of
27 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28 GNU General Public License for more details.
29
30 You should have received a copy of the GNU General Public License
31 along with this program; if not, write to the Free Software
32 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
33
34 History:
35
36 Version 0.40:
37 Markus: Updates for 2.6.x kernels, code layout changes, name sanitizing
38
39 Version 0.30:
40 Markus: Updates for 2.5.x kernel and more ISO compliant source
41
42 Version 0.25:
43 PSL and Markus: Cleanup, radio now doesn't stop on device close
44
45 Version 0.24:
46 Markus: Hope I got these silly VIDEO_TUNER_LOW issues finally
47 right. Some minor cleanup, improved standalone compilation
48
49 Version 0.23:
50 Markus: Sign extension bug fixed by declaring transfer_buffer unsigned
51
52 Version 0.22:
53 Markus: Some (brown bag) cleanup in what VIDIOCSTUNER returns,
54 thanks to Mike Cox for pointing the problem out.
55
56 Version 0.21:
57 Markus: Minor cleanup, warnings if something goes wrong, lame attempt
58 to adhere to Documentation/CodingStyle
59
60 Version 0.2:
61 Brad Hards <bradh@dynamite.com.au>: Fixes to make it work as non-module
62 Markus: Copyright clarification
63
64 Version 0.01: Markus: initial release
65
66*/
67
68
69#include <linux/kernel.h>
70#include <linux/module.h>
71#include <linux/init.h>
72#include <linux/slab.h>
73#include <linux/input.h>
74#include <linux/videodev.h>
75#include <linux/usb.h>
76#include <linux/smp_lock.h>
77
78/*
79 * Version Information
80 */
81#define DRIVER_VERSION "v0.40"
82#define DRIVER_AUTHOR "Markus Demleitner <msdemlei@tucana.harvard.edu>"
83#define DRIVER_DESC "D-Link DSB-R100 USB FM radio driver"
84
85#define DSB100_VENDOR 0x04b4
86#define DSB100_PRODUCT 0x1002
87
88/* Commands the device appears to understand */
89#define DSB100_TUNE 1
90#define DSB100_ONOFF 2
91
92#define TB_LEN 16
93
94/* Frequency limits in MHz -- these are European values. For Japanese
95devices, that would be 76 and 91. */
96#define FREQ_MIN 87.5
97#define FREQ_MAX 108.0
98#define FREQ_MUL 16000
99
100
101static int usb_dsbr100_probe(struct usb_interface *intf,
102 const struct usb_device_id *id);
103static void usb_dsbr100_disconnect(struct usb_interface *intf);
104static int usb_dsbr100_ioctl(struct inode *inode, struct file *file,
105 unsigned int cmd, unsigned long arg);
106static int usb_dsbr100_open(struct inode *inode, struct file *file);
107static int usb_dsbr100_close(struct inode *inode, struct file *file);
108
109static int radio_nr = -1;
110module_param(radio_nr, int, 0);
111
112/* Data for one (physical) device */
113typedef struct {
114 struct usb_device *usbdev;
115 struct video_device *videodev;
116 unsigned char transfer_buffer[TB_LEN];
117 int curfreq;
118 int stereo;
119 int users;
120 int removed;
121} dsbr100_device;
122
123
124/* File system interface */
125static struct file_operations usb_dsbr100_fops = {
126 .owner = THIS_MODULE,
127 .open = usb_dsbr100_open,
128 .release = usb_dsbr100_close,
129 .ioctl = usb_dsbr100_ioctl,
130 .compat_ioctl = v4l_compat_ioctl32,
131 .llseek = no_llseek,
132};
133
134/* V4L interface */
135static struct video_device dsbr100_videodev_template=
136{
137 .owner = THIS_MODULE,
138 .name = "D-Link DSB-R 100",
139 .type = VID_TYPE_TUNER,
140 .hardware = VID_HARDWARE_AZTECH,
141 .fops = &usb_dsbr100_fops,
142 .release = video_device_release,
143};
144
145static struct usb_device_id usb_dsbr100_device_table [] = {
146 { USB_DEVICE(DSB100_VENDOR, DSB100_PRODUCT) },
147 { } /* Terminating entry */
148};
149
150MODULE_DEVICE_TABLE (usb, usb_dsbr100_device_table);
151
152/* USB subsystem interface */
153static struct usb_driver usb_dsbr100_driver = {
154 .name = "dsbr100",
155 .probe = usb_dsbr100_probe,
156 .disconnect = usb_dsbr100_disconnect,
157 .id_table = usb_dsbr100_device_table,
158};
159
160/* Low-level device interface begins here */
161
162/* switch on radio */
163static int dsbr100_start(dsbr100_device *radio)
164{
165 if (usb_control_msg(radio->usbdev, usb_rcvctrlpipe(radio->usbdev, 0),
166 USB_REQ_GET_STATUS,
167 USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
168 0x00, 0xC7, radio->transfer_buffer, 8, 300)<0 ||
169 usb_control_msg(radio->usbdev, usb_rcvctrlpipe(radio->usbdev, 0),
170 DSB100_ONOFF,
171 USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
172 0x01, 0x00, radio->transfer_buffer, 8, 300)<0)
173 return -1;
174 return (radio->transfer_buffer)[0];
175}
176
177
178/* switch off radio */
179static int dsbr100_stop(dsbr100_device *radio)
180{
181 if (usb_control_msg(radio->usbdev, usb_rcvctrlpipe(radio->usbdev, 0),
182 USB_REQ_GET_STATUS,
183 USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
184 0x16, 0x1C, radio->transfer_buffer, 8, 300)<0 ||
185 usb_control_msg(radio->usbdev, usb_rcvctrlpipe(radio->usbdev, 0),
186 DSB100_ONOFF,
187 USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
188 0x00, 0x00, radio->transfer_buffer, 8, 300)<0)
189 return -1;
190 return (radio->transfer_buffer)[0];
191}
192
193/* set a frequency, freq is defined by v4l's TUNER_LOW, i.e. 1/16th kHz */
194static int dsbr100_setfreq(dsbr100_device *radio, int freq)
195{
196 freq = (freq/16*80)/1000+856;
197 if (usb_control_msg(radio->usbdev, usb_rcvctrlpipe(radio->usbdev, 0),
198 DSB100_TUNE,
199 USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
200 (freq>>8)&0x00ff, freq&0xff,
201 radio->transfer_buffer, 8, 300)<0 ||
202 usb_control_msg(radio->usbdev, usb_rcvctrlpipe(radio->usbdev, 0),
203 USB_REQ_GET_STATUS,
204 USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
205 0x96, 0xB7, radio->transfer_buffer, 8, 300)<0 ||
206 usb_control_msg(radio->usbdev, usb_rcvctrlpipe(radio->usbdev, 0),
207 USB_REQ_GET_STATUS,
208 USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
209 0x00, 0x24, radio->transfer_buffer, 8, 300)<0) {
210 radio->stereo = -1;
211 return -1;
212 }
213 radio->stereo = ! ((radio->transfer_buffer)[0]&0x01);
214 return (radio->transfer_buffer)[0];
215}
216
217/* return the device status. This is, in effect, just whether it
218sees a stereo signal or not. Pity. */
219static void dsbr100_getstat(dsbr100_device *radio)
220{
221 if (usb_control_msg(radio->usbdev, usb_rcvctrlpipe(radio->usbdev, 0),
222 USB_REQ_GET_STATUS,
223 USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
224 0x00 , 0x24, radio->transfer_buffer, 8, 300)<0)
225 radio->stereo = -1;
226 else
227 radio->stereo = ! (radio->transfer_buffer[0]&0x01);
228}
229
230
231/* USB subsystem interface begins here */
232
233/* check if the device is present and register with v4l and
234usb if it is */
235static int usb_dsbr100_probe(struct usb_interface *intf,
236 const struct usb_device_id *id)
237{
238 dsbr100_device *radio;
239
240 if (!(radio = kmalloc(sizeof(dsbr100_device), GFP_KERNEL)))
241 return -ENOMEM;
242 if (!(radio->videodev = video_device_alloc())) {
243 kfree(radio);
244 return -ENOMEM;
245 }
246 memcpy(radio->videodev, &dsbr100_videodev_template,
247 sizeof(dsbr100_videodev_template));
248 radio->removed = 0;
249 radio->users = 0;
250 radio->usbdev = interface_to_usbdev(intf);
251 radio->curfreq = FREQ_MIN*FREQ_MUL;
252 video_set_drvdata(radio->videodev, radio);
253 if (video_register_device(radio->videodev, VFL_TYPE_RADIO,
254 radio_nr)) {
255 warn("Could not register video device");
256 video_device_release(radio->videodev);
257 kfree(radio);
258 return -EIO;
259 }
260 usb_set_intfdata(intf, radio);
261 return 0;
262}
263
264/* handle unplugging of the device, release data structures
265if nothing keeps us from doing it. If something is still
266keeping us busy, the release callback of v4l will take care
267of releasing it. stv680.c does not relase its private
268data, so I don't do this here either. Checking out the
269code I'd expect I better did that, but if there's a memory
270leak here it's tiny (~50 bytes per disconnect) */
271static void usb_dsbr100_disconnect(struct usb_interface *intf)
272{
273 dsbr100_device *radio = usb_get_intfdata(intf);
274
275 usb_set_intfdata (intf, NULL);
276 if (radio) {
277 video_unregister_device(radio->videodev);
278 radio->videodev = NULL;
279 if (radio->users) {
280 kfree(radio);
281 } else {
282 radio->removed = 1;
283 }
284 }
285}
286
287
288/* Video for Linux interface */
289
290static int usb_dsbr100_do_ioctl(struct inode *inode, struct file *file,
291 unsigned int cmd, void *arg)
292{
293 dsbr100_device *radio=video_get_drvdata(video_devdata(file));
294
295 if (!radio)
296 return -EIO;
297
298 switch(cmd) {
299 case VIDIOCGCAP: {
300 struct video_capability *v = arg;
301
302 memset(v, 0, sizeof(*v));
303 v->type = VID_TYPE_TUNER;
304 v->channels = 1;
305 v->audios = 1;
306 strcpy(v->name, "D-Link R-100 USB FM Radio");
307 return 0;
308 }
309 case VIDIOCGTUNER: {
310 struct video_tuner *v = arg;
311
312 dsbr100_getstat(radio);
313 if(v->tuner) /* Only 1 tuner */
314 return -EINVAL;
315 v->rangelow = FREQ_MIN*FREQ_MUL;
316 v->rangehigh = FREQ_MAX*FREQ_MUL;
317 v->flags = VIDEO_TUNER_LOW;
318 v->mode = VIDEO_MODE_AUTO;
319 v->signal = radio->stereo*0x7000;
320 /* Don't know how to get signal strength */
321 v->flags |= VIDEO_TUNER_STEREO_ON*radio->stereo;
322 strcpy(v->name, "DSB R-100");
323 return 0;
324 }
325 case VIDIOCSTUNER: {
326 struct video_tuner *v = arg;
327
328 if(v->tuner!=0)
329 return -EINVAL;
330 /* Only 1 tuner so no setting needed ! */
331 return 0;
332 }
333 case VIDIOCGFREQ: {
334 int *freq = arg;
335
336 if (radio->curfreq==-1)
337 return -EINVAL;
338 *freq = radio->curfreq;
339 return 0;
340 }
341 case VIDIOCSFREQ: {
342 int *freq = arg;
343
344 radio->curfreq = *freq;
345 if (dsbr100_setfreq(radio, radio->curfreq)==-1)
346 warn("Set frequency failed");
347 return 0;
348 }
349 case VIDIOCGAUDIO: {
350 struct video_audio *v = arg;
351
352 memset(v, 0, sizeof(*v));
353 v->flags |= VIDEO_AUDIO_MUTABLE;
354 v->mode = VIDEO_SOUND_STEREO;
355 v->volume = 1;
356 v->step = 1;
357 strcpy(v->name, "Radio");
358 return 0;
359 }
360 case VIDIOCSAUDIO: {
361 struct video_audio *v = arg;
362
363 if (v->audio)
364 return -EINVAL;
365 if (v->flags&VIDEO_AUDIO_MUTE) {
366 if (dsbr100_stop(radio)==-1)
367 warn("Radio did not respond properly");
368 }
369 else
370 if (dsbr100_start(radio)==-1)
371 warn("Radio did not respond properly");
372 return 0;
373 }
374 default:
375 return -ENOIOCTLCMD;
376 }
377}
378
379static int usb_dsbr100_ioctl(struct inode *inode, struct file *file,
380 unsigned int cmd, unsigned long arg)
381{
382 return video_usercopy(inode, file, cmd, arg, usb_dsbr100_do_ioctl);
383}
384
385static int usb_dsbr100_open(struct inode *inode, struct file *file)
386{
387 dsbr100_device *radio=video_get_drvdata(video_devdata(file));
388
389 radio->users = 1;
390 if (dsbr100_start(radio)<0) {
391 warn("Radio did not start up properly");
392 radio->users = 0;
393 return -EIO;
394 }
395 dsbr100_setfreq(radio, radio->curfreq);
396 return 0;
397}
398
399static int usb_dsbr100_close(struct inode *inode, struct file *file)
400{
401 dsbr100_device *radio=video_get_drvdata(video_devdata(file));
402
403 if (!radio)
404 return -ENODEV;
405 radio->users = 0;
406 if (radio->removed) {
407 kfree(radio);
408 }
409 return 0;
410}
411
412static int __init dsbr100_init(void)
413{
414 int retval = usb_register(&usb_dsbr100_driver);
415 info(DRIVER_VERSION ":" DRIVER_DESC);
416 return retval;
417}
418
419static void __exit dsbr100_exit(void)
420{
421 usb_deregister(&usb_dsbr100_driver);
422}
423
424module_init (dsbr100_init);
425module_exit (dsbr100_exit);
426
427MODULE_AUTHOR( DRIVER_AUTHOR );
428MODULE_DESCRIPTION( DRIVER_DESC );
429MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/et61x251/Makefile b/drivers/media/video/et61x251/Makefile
new file mode 100644
index 000000000000..2ff4db9ec882
--- /dev/null
+++ b/drivers/media/video/et61x251/Makefile
@@ -0,0 +1,4 @@
1et61x251-objs := et61x251_core.o et61x251_tas5130d1b.o
2
3obj-$(CONFIG_USB_ET61X251) += et61x251.o
4
diff --git a/drivers/media/video/et61x251/et61x251.h b/drivers/media/video/et61x251/et61x251.h
new file mode 100644
index 000000000000..eee8afc9be72
--- /dev/null
+++ b/drivers/media/video/et61x251/et61x251.h
@@ -0,0 +1,234 @@
1/***************************************************************************
2 * V4L2 driver for ET61X[12]51 PC Camera Controllers *
3 * *
4 * Copyright (C) 2006 by Luca Risolia <luca.risolia@studio.unibo.it> *
5 * *
6 * This program is free software; you can redistribute it and/or modify *
7 * it under the terms of the GNU General Public License as published by *
8 * the Free Software Foundation; either version 2 of the License, or *
9 * (at your option) any later version. *
10 * *
11 * This program is distributed in the hope that it will be useful, *
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14 * GNU General Public License for more details. *
15 * *
16 * You should have received a copy of the GNU General Public License *
17 * along with this program; if not, write to the Free Software *
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
19 ***************************************************************************/
20
21#ifndef _ET61X251_H_
22#define _ET61X251_H_
23
24#include <linux/version.h>
25#include <linux/usb.h>
26#include <linux/videodev2.h>
27#include <media/v4l2-common.h>
28#include <linux/device.h>
29#include <linux/list.h>
30#include <linux/spinlock.h>
31#include <linux/time.h>
32#include <linux/wait.h>
33#include <linux/types.h>
34#include <linux/param.h>
35#include <linux/rwsem.h>
36#include <linux/mutex.h>
37#include <linux/stddef.h>
38#include <linux/string.h>
39
40#include "et61x251_sensor.h"
41
42/*****************************************************************************/
43
44#define ET61X251_DEBUG
45#define ET61X251_DEBUG_LEVEL 2
46#define ET61X251_MAX_DEVICES 64
47#define ET61X251_PRESERVE_IMGSCALE 0
48#define ET61X251_FORCE_MUNMAP 0
49#define ET61X251_MAX_FRAMES 32
50#define ET61X251_COMPRESSION_QUALITY 0
51#define ET61X251_URBS 2
52#define ET61X251_ISO_PACKETS 7
53#define ET61X251_ALTERNATE_SETTING 13
54#define ET61X251_URB_TIMEOUT msecs_to_jiffies(2 * ET61X251_ISO_PACKETS)
55#define ET61X251_CTRL_TIMEOUT 100
56#define ET61X251_FRAME_TIMEOUT 2
57
58/*****************************************************************************/
59
60static const struct usb_device_id et61x251_id_table[] = {
61 { USB_DEVICE(0x102c, 0x6151), },
62 { USB_DEVICE(0x102c, 0x6251), },
63 { USB_DEVICE(0x102c, 0x6253), },
64 { USB_DEVICE(0x102c, 0x6254), },
65 { USB_DEVICE(0x102c, 0x6255), },
66 { USB_DEVICE(0x102c, 0x6256), },
67 { USB_DEVICE(0x102c, 0x6257), },
68 { USB_DEVICE(0x102c, 0x6258), },
69 { USB_DEVICE(0x102c, 0x6259), },
70 { USB_DEVICE(0x102c, 0x625a), },
71 { USB_DEVICE(0x102c, 0x625b), },
72 { USB_DEVICE(0x102c, 0x625c), },
73 { USB_DEVICE(0x102c, 0x625d), },
74 { USB_DEVICE(0x102c, 0x625e), },
75 { USB_DEVICE(0x102c, 0x625f), },
76 { USB_DEVICE(0x102c, 0x6260), },
77 { USB_DEVICE(0x102c, 0x6261), },
78 { USB_DEVICE(0x102c, 0x6262), },
79 { USB_DEVICE(0x102c, 0x6263), },
80 { USB_DEVICE(0x102c, 0x6264), },
81 { USB_DEVICE(0x102c, 0x6265), },
82 { USB_DEVICE(0x102c, 0x6266), },
83 { USB_DEVICE(0x102c, 0x6267), },
84 { USB_DEVICE(0x102c, 0x6268), },
85 { USB_DEVICE(0x102c, 0x6269), },
86 { }
87};
88
89ET61X251_SENSOR_TABLE
90
91/*****************************************************************************/
92
93enum et61x251_frame_state {
94 F_UNUSED,
95 F_QUEUED,
96 F_GRABBING,
97 F_DONE,
98 F_ERROR,
99};
100
101struct et61x251_frame_t {
102 void* bufmem;
103 struct v4l2_buffer buf;
104 enum et61x251_frame_state state;
105 struct list_head frame;
106 unsigned long vma_use_count;
107};
108
109enum et61x251_dev_state {
110 DEV_INITIALIZED = 0x01,
111 DEV_DISCONNECTED = 0x02,
112 DEV_MISCONFIGURED = 0x04,
113};
114
115enum et61x251_io_method {
116 IO_NONE,
117 IO_READ,
118 IO_MMAP,
119};
120
121enum et61x251_stream_state {
122 STREAM_OFF,
123 STREAM_INTERRUPT,
124 STREAM_ON,
125};
126
127struct et61x251_sysfs_attr {
128 u8 reg, i2c_reg;
129};
130
131struct et61x251_module_param {
132 u8 force_munmap;
133 u16 frame_timeout;
134};
135
136static DEFINE_MUTEX(et61x251_sysfs_lock);
137static DECLARE_RWSEM(et61x251_disconnect);
138
139struct et61x251_device {
140 struct video_device* v4ldev;
141
142 struct et61x251_sensor sensor;
143
144 struct usb_device* usbdev;
145 struct urb* urb[ET61X251_URBS];
146 void* transfer_buffer[ET61X251_URBS];
147 u8* control_buffer;
148
149 struct et61x251_frame_t *frame_current, frame[ET61X251_MAX_FRAMES];
150 struct list_head inqueue, outqueue;
151 u32 frame_count, nbuffers, nreadbuffers;
152
153 enum et61x251_io_method io;
154 enum et61x251_stream_state stream;
155
156 struct v4l2_jpegcompression compression;
157
158 struct et61x251_sysfs_attr sysfs;
159 struct et61x251_module_param module_param;
160
161 enum et61x251_dev_state state;
162 u8 users;
163
164 struct mutex dev_mutex, fileop_mutex;
165 spinlock_t queue_lock;
166 wait_queue_head_t open, wait_frame, wait_stream;
167};
168
169/*****************************************************************************/
170
171struct et61x251_device*
172et61x251_match_id(struct et61x251_device* cam, const struct usb_device_id *id)
173{
174 if (usb_match_id(usb_ifnum_to_if(cam->usbdev, 0), id))
175 return cam;
176
177 return NULL;
178}
179
180
181void
182et61x251_attach_sensor(struct et61x251_device* cam,
183 struct et61x251_sensor* sensor)
184{
185 memcpy(&cam->sensor, sensor, sizeof(struct et61x251_sensor));
186}
187
188/*****************************************************************************/
189
190#undef DBG
191#undef KDBG
192#ifdef ET61X251_DEBUG
193# define DBG(level, fmt, args...) \
194do { \
195 if (debug >= (level)) { \
196 if ((level) == 1) \
197 dev_err(&cam->usbdev->dev, fmt "\n", ## args); \
198 else if ((level) == 2) \
199 dev_info(&cam->usbdev->dev, fmt "\n", ## args); \
200 else if ((level) >= 3) \
201 dev_info(&cam->usbdev->dev, "[%s:%d] " fmt "\n", \
202 __FUNCTION__, __LINE__ , ## args); \
203 } \
204} while (0)
205# define KDBG(level, fmt, args...) \
206do { \
207 if (debug >= (level)) { \
208 if ((level) == 1 || (level) == 2) \
209 pr_info("et61x251: " fmt "\n", ## args); \
210 else if ((level) == 3) \
211 pr_debug("et61x251: [%s:%d] " fmt "\n", __FUNCTION__, \
212 __LINE__ , ## args); \
213 } \
214} while (0)
215# define V4LDBG(level, name, cmd) \
216do { \
217 if (debug >= (level)) \
218 v4l_print_ioctl(name, cmd); \
219} while (0)
220#else
221# define DBG(level, fmt, args...) do {;} while(0)
222# define KDBG(level, fmt, args...) do {;} while(0)
223# define V4LDBG(level, name, cmd) do {;} while(0)
224#endif
225
226#undef PDBG
227#define PDBG(fmt, args...) \
228dev_info(&cam->usbdev->dev, "[%s:%d] " fmt "\n", \
229 __FUNCTION__, __LINE__ , ## args)
230
231#undef PDBGG
232#define PDBGG(fmt, args...) do {;} while(0) /* placeholder */
233
234#endif /* _ET61X251_H_ */
diff --git a/drivers/media/video/et61x251/et61x251_core.c b/drivers/media/video/et61x251/et61x251_core.c
new file mode 100644
index 000000000000..7cc01b828b3d
--- /dev/null
+++ b/drivers/media/video/et61x251/et61x251_core.c
@@ -0,0 +1,2630 @@
1/***************************************************************************
2 * V4L2 driver for ET61X[12]51 PC Camera Controllers *
3 * *
4 * Copyright (C) 2006 by Luca Risolia <luca.risolia@studio.unibo.it> *
5 * *
6 * This program is free software; you can redistribute it and/or modify *
7 * it under the terms of the GNU General Public License as published by *
8 * the Free Software Foundation; either version 2 of the License, or *
9 * (at your option) any later version. *
10 * *
11 * This program is distributed in the hope that it will be useful, *
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14 * GNU General Public License for more details. *
15 * *
16 * You should have received a copy of the GNU General Public License *
17 * along with this program; if not, write to the Free Software *
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
19 ***************************************************************************/
20
21#include <linux/module.h>
22#include <linux/init.h>
23#include <linux/kernel.h>
24#include <linux/param.h>
25#include <linux/moduleparam.h>
26#include <linux/errno.h>
27#include <linux/slab.h>
28#include <linux/device.h>
29#include <linux/fs.h>
30#include <linux/delay.h>
31#include <linux/compiler.h>
32#include <linux/ioctl.h>
33#include <linux/poll.h>
34#include <linux/stat.h>
35#include <linux/mm.h>
36#include <linux/vmalloc.h>
37#include <linux/page-flags.h>
38#include <linux/byteorder/generic.h>
39#include <asm/page.h>
40#include <asm/uaccess.h>
41
42#include "et61x251.h"
43
44/*****************************************************************************/
45
46#define ET61X251_MODULE_NAME "V4L2 driver for ET61X[12]51 " \
47 "PC Camera Controllers"
48#define ET61X251_MODULE_AUTHOR "(C) 2006 Luca Risolia"
49#define ET61X251_AUTHOR_EMAIL "<luca.risolia@studio.unibo.it>"
50#define ET61X251_MODULE_LICENSE "GPL"
51#define ET61X251_MODULE_VERSION "1:1.02"
52#define ET61X251_MODULE_VERSION_CODE KERNEL_VERSION(1, 0, 2)
53
54/*****************************************************************************/
55
56MODULE_DEVICE_TABLE(usb, et61x251_id_table);
57
58MODULE_AUTHOR(ET61X251_MODULE_AUTHOR " " ET61X251_AUTHOR_EMAIL);
59MODULE_DESCRIPTION(ET61X251_MODULE_NAME);
60MODULE_VERSION(ET61X251_MODULE_VERSION);
61MODULE_LICENSE(ET61X251_MODULE_LICENSE);
62
63static short video_nr[] = {[0 ... ET61X251_MAX_DEVICES-1] = -1};
64module_param_array(video_nr, short, NULL, 0444);
65MODULE_PARM_DESC(video_nr,
66 "\n<-1|n[,...]> Specify V4L2 minor mode number."
67 "\n -1 = use next available (default)"
68 "\n n = use minor number n (integer >= 0)"
69 "\nYou can specify up to "
70 __MODULE_STRING(ET61X251_MAX_DEVICES) " cameras this way."
71 "\nFor example:"
72 "\nvideo_nr=-1,2,-1 would assign minor number 2 to"
73 "\nthe second registered camera and use auto for the first"
74 "\none and for every other camera."
75 "\n");
76
77static short force_munmap[] = {[0 ... ET61X251_MAX_DEVICES-1] =
78 ET61X251_FORCE_MUNMAP};
79module_param_array(force_munmap, bool, NULL, 0444);
80MODULE_PARM_DESC(force_munmap,
81 "\n<0|1[,...]> Force the application to unmap previously"
82 "\nmapped buffer memory before calling any VIDIOC_S_CROP or"
83 "\nVIDIOC_S_FMT ioctl's. Not all the applications support"
84 "\nthis feature. This parameter is specific for each"
85 "\ndetected camera."
86 "\n 0 = do not force memory unmapping"
87 "\n 1 = force memory unmapping (save memory)"
88 "\nDefault value is "__MODULE_STRING(SN9C102_FORCE_MUNMAP)"."
89 "\n");
90
91static unsigned int frame_timeout[] = {[0 ... ET61X251_MAX_DEVICES-1] =
92 ET61X251_FRAME_TIMEOUT};
93module_param_array(frame_timeout, uint, NULL, 0644);
94MODULE_PARM_DESC(frame_timeout,
95 "\n<n[,...]> Timeout for a video frame in seconds."
96 "\nThis parameter is specific for each detected camera."
97 "\nDefault value is "
98 __MODULE_STRING(ET61X251_FRAME_TIMEOUT)"."
99 "\n");
100
101#ifdef ET61X251_DEBUG
102static unsigned short debug = ET61X251_DEBUG_LEVEL;
103module_param(debug, ushort, 0644);
104MODULE_PARM_DESC(debug,
105 "\n<n> Debugging information level, from 0 to 3:"
106 "\n0 = none (use carefully)"
107 "\n1 = critical errors"
108 "\n2 = significant informations"
109 "\n3 = more verbose messages"
110 "\nLevel 3 is useful for testing only, when only "
111 "one device is used."
112 "\nDefault value is "__MODULE_STRING(ET61X251_DEBUG_LEVEL)"."
113 "\n");
114#endif
115
116/*****************************************************************************/
117
118static u32
119et61x251_request_buffers(struct et61x251_device* cam, u32 count,
120 enum et61x251_io_method io)
121{
122 struct v4l2_pix_format* p = &(cam->sensor.pix_format);
123 struct v4l2_rect* r = &(cam->sensor.cropcap.bounds);
124 const size_t imagesize = cam->module_param.force_munmap ||
125 io == IO_READ ?
126 (p->width * p->height * p->priv) / 8 :
127 (r->width * r->height * p->priv) / 8;
128 void* buff = NULL;
129 u32 i;
130
131 if (count > ET61X251_MAX_FRAMES)
132 count = ET61X251_MAX_FRAMES;
133
134 cam->nbuffers = count;
135 while (cam->nbuffers > 0) {
136 if ((buff = vmalloc_32(cam->nbuffers * PAGE_ALIGN(imagesize))))
137 break;
138 cam->nbuffers--;
139 }
140
141 for (i = 0; i < cam->nbuffers; i++) {
142 cam->frame[i].bufmem = buff + i*PAGE_ALIGN(imagesize);
143 cam->frame[i].buf.index = i;
144 cam->frame[i].buf.m.offset = i*PAGE_ALIGN(imagesize);
145 cam->frame[i].buf.length = imagesize;
146 cam->frame[i].buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
147 cam->frame[i].buf.sequence = 0;
148 cam->frame[i].buf.field = V4L2_FIELD_NONE;
149 cam->frame[i].buf.memory = V4L2_MEMORY_MMAP;
150 cam->frame[i].buf.flags = 0;
151 }
152
153 return cam->nbuffers;
154}
155
156
157static void et61x251_release_buffers(struct et61x251_device* cam)
158{
159 if (cam->nbuffers) {
160 vfree(cam->frame[0].bufmem);
161 cam->nbuffers = 0;
162 }
163 cam->frame_current = NULL;
164}
165
166
167static void et61x251_empty_framequeues(struct et61x251_device* cam)
168{
169 u32 i;
170
171 INIT_LIST_HEAD(&cam->inqueue);
172 INIT_LIST_HEAD(&cam->outqueue);
173
174 for (i = 0; i < ET61X251_MAX_FRAMES; i++) {
175 cam->frame[i].state = F_UNUSED;
176 cam->frame[i].buf.bytesused = 0;
177 }
178}
179
180
181static void et61x251_requeue_outqueue(struct et61x251_device* cam)
182{
183 struct et61x251_frame_t *i;
184
185 list_for_each_entry(i, &cam->outqueue, frame) {
186 i->state = F_QUEUED;
187 list_add(&i->frame, &cam->inqueue);
188 }
189
190 INIT_LIST_HEAD(&cam->outqueue);
191}
192
193
194static void et61x251_queue_unusedframes(struct et61x251_device* cam)
195{
196 unsigned long lock_flags;
197 u32 i;
198
199 for (i = 0; i < cam->nbuffers; i++)
200 if (cam->frame[i].state == F_UNUSED) {
201 cam->frame[i].state = F_QUEUED;
202 spin_lock_irqsave(&cam->queue_lock, lock_flags);
203 list_add_tail(&cam->frame[i].frame, &cam->inqueue);
204 spin_unlock_irqrestore(&cam->queue_lock, lock_flags);
205 }
206}
207
208/*****************************************************************************/
209
210int et61x251_write_reg(struct et61x251_device* cam, u8 value, u16 index)
211{
212 struct usb_device* udev = cam->usbdev;
213 u8* buff = cam->control_buffer;
214 int res;
215
216 *buff = value;
217
218 res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x00, 0x41,
219 0, index, buff, 1, ET61X251_CTRL_TIMEOUT);
220 if (res < 0) {
221 DBG(3, "Failed to write a register (value 0x%02X, index "
222 "0x%02X, error %d)", value, index, res);
223 return -1;
224 }
225
226 return 0;
227}
228
229
230int et61x251_read_reg(struct et61x251_device* cam, u16 index)
231{
232 struct usb_device* udev = cam->usbdev;
233 u8* buff = cam->control_buffer;
234 int res;
235
236 res = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), 0x00, 0xc1,
237 0, index, buff, 1, ET61X251_CTRL_TIMEOUT);
238 if (res < 0)
239 DBG(3, "Failed to read a register (index 0x%02X, error %d)",
240 index, res);
241
242 return (res >= 0) ? (int)(*buff) : -1;
243}
244
245
246static int
247et61x251_i2c_wait(struct et61x251_device* cam, struct et61x251_sensor* sensor)
248{
249 int i, r;
250
251 for (i = 1; i <= 8; i++) {
252 if (sensor->interface == ET61X251_I2C_3WIRES) {
253 r = et61x251_read_reg(cam, 0x8e);
254 if (!(r & 0x02) && (r >= 0))
255 return 0;
256 } else {
257 r = et61x251_read_reg(cam, 0x8b);
258 if (!(r & 0x01) && (r >= 0))
259 return 0;
260 }
261 if (r < 0)
262 return -EIO;
263 udelay(8*8); /* minimum for sensors at 400kHz */
264 }
265
266 return -EBUSY;
267}
268
269
270int
271et61x251_i2c_try_read(struct et61x251_device* cam,
272 struct et61x251_sensor* sensor, u8 address)
273{
274 struct usb_device* udev = cam->usbdev;
275 u8* data = cam->control_buffer;
276 int err = 0, res;
277
278 data[0] = address;
279 data[1] = cam->sensor.i2c_slave_id;
280 data[2] = cam->sensor.rsta | 0x10;
281 data[3] = !(et61x251_read_reg(cam, 0x8b) & 0x02);
282 res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x00, 0x41,
283 0, 0x88, data, 4, ET61X251_CTRL_TIMEOUT);
284 if (res < 0)
285 err += res;
286
287 err += et61x251_i2c_wait(cam, sensor);
288
289 res = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), 0x00, 0xc1,
290 0, 0x80, data, 8, ET61X251_CTRL_TIMEOUT);
291 if (res < 0)
292 err += res;
293
294 if (err)
295 DBG(3, "I2C read failed for %s image sensor", sensor->name);
296
297 PDBGG("I2C read: address 0x%02X, value: 0x%02X", address, data[0]);
298
299 return err ? -1 : (int)data[0];
300}
301
302
303int
304et61x251_i2c_try_write(struct et61x251_device* cam,
305 struct et61x251_sensor* sensor, u8 address, u8 value)
306{
307 struct usb_device* udev = cam->usbdev;
308 u8* data = cam->control_buffer;
309 int err = 0, res;
310
311 data[0] = address;
312 data[1] = cam->sensor.i2c_slave_id;
313 data[2] = cam->sensor.rsta | 0x12;
314 res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x00, 0x41,
315 0, 0x88, data, 3, ET61X251_CTRL_TIMEOUT);
316 if (res < 0)
317 err += res;
318
319 data[0] = value;
320 res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x00, 0x41,
321 0, 0x80, data, 1, ET61X251_CTRL_TIMEOUT);
322 if (res < 0)
323 err += res;
324
325 err += et61x251_i2c_wait(cam, sensor);
326
327 if (err)
328 DBG(3, "I2C write failed for %s image sensor", sensor->name);
329
330 PDBGG("I2C write: address 0x%02X, value: 0x%02X", address, value);
331
332 return err ? -1 : 0;
333}
334
335
336int
337et61x251_i2c_raw_write(struct et61x251_device* cam, u8 n, u8 data1, u8 data2,
338 u8 data3, u8 data4, u8 data5, u8 data6, u8 data7,
339 u8 data8, u8 address)
340{
341 struct usb_device* udev = cam->usbdev;
342 u8* data = cam->control_buffer;
343 int err = 0, res;
344
345 data[0] = data2;
346 data[1] = data3;
347 data[2] = data4;
348 data[3] = data5;
349 data[4] = data6;
350 data[5] = data7;
351 data[6] = data8;
352 res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x00, 0x41,
353 0, 0x81, data, n-1, ET61X251_CTRL_TIMEOUT);
354 if (res < 0)
355 err += res;
356
357 data[0] = address;
358 data[1] = cam->sensor.i2c_slave_id;
359 data[2] = cam->sensor.rsta | 0x02 | (n << 4);
360 res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x00, 0x41,
361 0, 0x88, data, 3, ET61X251_CTRL_TIMEOUT);
362 if (res < 0)
363 err += res;
364
365 /* Start writing through the serial interface */
366 data[0] = data1;
367 res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x00, 0x41,
368 0, 0x80, data, 1, ET61X251_CTRL_TIMEOUT);
369 if (res < 0)
370 err += res;
371
372 err += et61x251_i2c_wait(cam, &cam->sensor);
373
374 if (err)
375 DBG(3, "I2C raw write failed for %s image sensor",
376 cam->sensor.name);
377
378 PDBGG("I2C raw write: %u bytes, address = 0x%02X, data1 = 0x%02X, "
379 "data2 = 0x%02X, data3 = 0x%02X, data4 = 0x%02X, data5 = 0x%02X,"
380 " data6 = 0x%02X, data7 = 0x%02X, data8 = 0x%02X", n, address,
381 data1, data2, data3, data4, data5, data6, data7, data8);
382
383 return err ? -1 : 0;
384
385}
386
387
388int et61x251_i2c_read(struct et61x251_device* cam, u8 address)
389{
390 return et61x251_i2c_try_read(cam, &cam->sensor, address);
391}
392
393
394int et61x251_i2c_write(struct et61x251_device* cam, u8 address, u8 value)
395{
396 return et61x251_i2c_try_write(cam, &cam->sensor, address, value);
397}
398
399/*****************************************************************************/
400
401static void et61x251_urb_complete(struct urb *urb, struct pt_regs* regs)
402{
403 struct et61x251_device* cam = urb->context;
404 struct et61x251_frame_t** f;
405 size_t imagesize;
406 u8 i;
407 int err = 0;
408
409 if (urb->status == -ENOENT)
410 return;
411
412 f = &cam->frame_current;
413
414 if (cam->stream == STREAM_INTERRUPT) {
415 cam->stream = STREAM_OFF;
416 if ((*f))
417 (*f)->state = F_QUEUED;
418 DBG(3, "Stream interrupted");
419 wake_up(&cam->wait_stream);
420 }
421
422 if (cam->state & DEV_DISCONNECTED)
423 return;
424
425 if (cam->state & DEV_MISCONFIGURED) {
426 wake_up_interruptible(&cam->wait_frame);
427 return;
428 }
429
430 if (cam->stream == STREAM_OFF || list_empty(&cam->inqueue))
431 goto resubmit_urb;
432
433 if (!(*f))
434 (*f) = list_entry(cam->inqueue.next, struct et61x251_frame_t,
435 frame);
436
437 imagesize = (cam->sensor.pix_format.width *
438 cam->sensor.pix_format.height *
439 cam->sensor.pix_format.priv) / 8;
440
441 for (i = 0; i < urb->number_of_packets; i++) {
442 unsigned int len, status;
443 void *pos;
444 u8* b1, * b2, sof;
445 const u8 VOID_BYTES = 6;
446 size_t imglen;
447
448 len = urb->iso_frame_desc[i].actual_length;
449 status = urb->iso_frame_desc[i].status;
450 pos = urb->iso_frame_desc[i].offset + urb->transfer_buffer;
451
452 if (status) {
453 DBG(3, "Error in isochronous frame");
454 (*f)->state = F_ERROR;
455 continue;
456 }
457
458 b1 = pos++;
459 b2 = pos++;
460 sof = ((*b1 & 0x3f) == 63);
461 imglen = ((*b1 & 0xc0) << 2) | *b2;
462
463 PDBGG("Isochrnous frame: length %u, #%u i, image length %zu",
464 len, i, imglen);
465
466 if ((*f)->state == F_QUEUED || (*f)->state == F_ERROR)
467start_of_frame:
468 if (sof) {
469 (*f)->state = F_GRABBING;
470 (*f)->buf.bytesused = 0;
471 do_gettimeofday(&(*f)->buf.timestamp);
472 pos += 22;
473 DBG(3, "SOF detected: new video frame");
474 }
475
476 if ((*f)->state == F_GRABBING) {
477 if (sof && (*f)->buf.bytesused) {
478 if (cam->sensor.pix_format.pixelformat ==
479 V4L2_PIX_FMT_ET61X251)
480 goto end_of_frame;
481 else {
482 DBG(3, "Not expected SOF detected "
483 "after %lu bytes",
484 (unsigned long)(*f)->buf.bytesused);
485 (*f)->state = F_ERROR;
486 continue;
487 }
488 }
489
490 if ((*f)->buf.bytesused + imglen > imagesize) {
491 DBG(3, "Video frame size exceeded");
492 (*f)->state = F_ERROR;
493 continue;
494 }
495
496 pos += VOID_BYTES;
497
498 memcpy((*f)->bufmem+(*f)->buf.bytesused, pos, imglen);
499 (*f)->buf.bytesused += imglen;
500
501 if ((*f)->buf.bytesused == imagesize) {
502 u32 b;
503end_of_frame:
504 b = (*f)->buf.bytesused;
505 (*f)->state = F_DONE;
506 (*f)->buf.sequence= ++cam->frame_count;
507 spin_lock(&cam->queue_lock);
508 list_move_tail(&(*f)->frame, &cam->outqueue);
509 if (!list_empty(&cam->inqueue))
510 (*f) = list_entry(cam->inqueue.next,
511 struct et61x251_frame_t,
512 frame);
513 else
514 (*f) = NULL;
515 spin_unlock(&cam->queue_lock);
516 DBG(3, "Video frame captured: : %lu bytes",
517 (unsigned long)(b));
518
519 if (!(*f))
520 goto resubmit_urb;
521
522 if (sof &&
523 cam->sensor.pix_format.pixelformat ==
524 V4L2_PIX_FMT_ET61X251)
525 goto start_of_frame;
526 }
527 }
528 }
529
530resubmit_urb:
531 urb->dev = cam->usbdev;
532 err = usb_submit_urb(urb, GFP_ATOMIC);
533 if (err < 0 && err != -EPERM) {
534 cam->state |= DEV_MISCONFIGURED;
535 DBG(1, "usb_submit_urb() failed");
536 }
537
538 wake_up_interruptible(&cam->wait_frame);
539}
540
541
542static int et61x251_start_transfer(struct et61x251_device* cam)
543{
544 struct usb_device *udev = cam->usbdev;
545 struct urb* urb;
546 const unsigned int wMaxPacketSize[] = {0, 256, 384, 512, 640, 768, 832,
547 864, 896, 920, 956, 980, 1000,
548 1022};
549 const unsigned int psz = wMaxPacketSize[ET61X251_ALTERNATE_SETTING];
550 s8 i, j;
551 int err = 0;
552
553 for (i = 0; i < ET61X251_URBS; i++) {
554 cam->transfer_buffer[i] = kzalloc(ET61X251_ISO_PACKETS * psz,
555 GFP_KERNEL);
556 if (!cam->transfer_buffer[i]) {
557 err = -ENOMEM;
558 DBG(1, "Not enough memory");
559 goto free_buffers;
560 }
561 }
562
563 for (i = 0; i < ET61X251_URBS; i++) {
564 urb = usb_alloc_urb(ET61X251_ISO_PACKETS, GFP_KERNEL);
565 cam->urb[i] = urb;
566 if (!urb) {
567 err = -ENOMEM;
568 DBG(1, "usb_alloc_urb() failed");
569 goto free_urbs;
570 }
571 urb->dev = udev;
572 urb->context = cam;
573 urb->pipe = usb_rcvisocpipe(udev, 1);
574 urb->transfer_flags = URB_ISO_ASAP;
575 urb->number_of_packets = ET61X251_ISO_PACKETS;
576 urb->complete = et61x251_urb_complete;
577 urb->transfer_buffer = cam->transfer_buffer[i];
578 urb->transfer_buffer_length = psz * ET61X251_ISO_PACKETS;
579 urb->interval = 1;
580 for (j = 0; j < ET61X251_ISO_PACKETS; j++) {
581 urb->iso_frame_desc[j].offset = psz * j;
582 urb->iso_frame_desc[j].length = psz;
583 }
584 }
585
586 err = et61x251_write_reg(cam, 0x01, 0x03);
587 err = et61x251_write_reg(cam, 0x00, 0x03);
588 err = et61x251_write_reg(cam, 0x08, 0x03);
589 if (err) {
590 err = -EIO;
591 DBG(1, "I/O hardware error");
592 goto free_urbs;
593 }
594
595 err = usb_set_interface(udev, 0, ET61X251_ALTERNATE_SETTING);
596 if (err) {
597 DBG(1, "usb_set_interface() failed");
598 goto free_urbs;
599 }
600
601 cam->frame_current = NULL;
602
603 for (i = 0; i < ET61X251_URBS; i++) {
604 err = usb_submit_urb(cam->urb[i], GFP_KERNEL);
605 if (err) {
606 for (j = i-1; j >= 0; j--)
607 usb_kill_urb(cam->urb[j]);
608 DBG(1, "usb_submit_urb() failed, error %d", err);
609 goto free_urbs;
610 }
611 }
612
613 return 0;
614
615free_urbs:
616 for (i = 0; (i < ET61X251_URBS) && cam->urb[i]; i++)
617 usb_free_urb(cam->urb[i]);
618
619free_buffers:
620 for (i = 0; (i < ET61X251_URBS) && cam->transfer_buffer[i]; i++)
621 kfree(cam->transfer_buffer[i]);
622
623 return err;
624}
625
626
627static int et61x251_stop_transfer(struct et61x251_device* cam)
628{
629 struct usb_device *udev = cam->usbdev;
630 s8 i;
631 int err = 0;
632
633 if (cam->state & DEV_DISCONNECTED)
634 return 0;
635
636 for (i = ET61X251_URBS-1; i >= 0; i--) {
637 usb_kill_urb(cam->urb[i]);
638 usb_free_urb(cam->urb[i]);
639 kfree(cam->transfer_buffer[i]);
640 }
641
642 err = usb_set_interface(udev, 0, 0); /* 0 Mb/s */
643 if (err)
644 DBG(3, "usb_set_interface() failed");
645
646 return err;
647}
648
649
650static int et61x251_stream_interrupt(struct et61x251_device* cam)
651{
652 long timeout;
653
654 cam->stream = STREAM_INTERRUPT;
655 timeout = wait_event_timeout(cam->wait_stream,
656 (cam->stream == STREAM_OFF) ||
657 (cam->state & DEV_DISCONNECTED),
658 ET61X251_URB_TIMEOUT);
659 if (cam->state & DEV_DISCONNECTED)
660 return -ENODEV;
661 else if (cam->stream != STREAM_OFF) {
662 cam->state |= DEV_MISCONFIGURED;
663 DBG(1, "URB timeout reached. The camera is misconfigured. To "
664 "use it, close and open /dev/video%d again.",
665 cam->v4ldev->minor);
666 return -EIO;
667 }
668
669 return 0;
670}
671
672/*****************************************************************************/
673
674#ifdef CONFIG_VIDEO_ADV_DEBUG
675static u8 et61x251_strtou8(const char* buff, size_t len, ssize_t* count)
676{
677 char str[5];
678 char* endp;
679 unsigned long val;
680
681 if (len < 4) {
682 strncpy(str, buff, len);
683 str[len+1] = '\0';
684 } else {
685 strncpy(str, buff, 4);
686 str[4] = '\0';
687 }
688
689 val = simple_strtoul(str, &endp, 0);
690
691 *count = 0;
692 if (val <= 0xff)
693 *count = (ssize_t)(endp - str);
694 if ((*count) && (len == *count+1) && (buff[*count] == '\n'))
695 *count += 1;
696
697 return (u8)val;
698}
699
700/*
701 NOTE 1: being inside one of the following methods implies that the v4l
702 device exists for sure (see kobjects and reference counters)
703 NOTE 2: buffers are PAGE_SIZE long
704*/
705
706static ssize_t et61x251_show_reg(struct class_device* cd, char* buf)
707{
708 struct et61x251_device* cam;
709 ssize_t count;
710
711 if (mutex_lock_interruptible(&et61x251_sysfs_lock))
712 return -ERESTARTSYS;
713
714 cam = video_get_drvdata(to_video_device(cd));
715 if (!cam) {
716 mutex_unlock(&et61x251_sysfs_lock);
717 return -ENODEV;
718 }
719
720 count = sprintf(buf, "%u\n", cam->sysfs.reg);
721
722 mutex_unlock(&et61x251_sysfs_lock);
723
724 return count;
725}
726
727
728static ssize_t
729et61x251_store_reg(struct class_device* cd, const char* buf, size_t len)
730{
731 struct et61x251_device* cam;
732 u8 index;
733 ssize_t count;
734
735 if (mutex_lock_interruptible(&et61x251_sysfs_lock))
736 return -ERESTARTSYS;
737
738 cam = video_get_drvdata(to_video_device(cd));
739 if (!cam) {
740 mutex_unlock(&et61x251_sysfs_lock);
741 return -ENODEV;
742 }
743
744 index = et61x251_strtou8(buf, len, &count);
745 if (index > 0x8e || !count) {
746 mutex_unlock(&et61x251_sysfs_lock);
747 return -EINVAL;
748 }
749
750 cam->sysfs.reg = index;
751
752 DBG(2, "Moved ET61X[12]51 register index to 0x%02X", cam->sysfs.reg);
753 DBG(3, "Written bytes: %zd", count);
754
755 mutex_unlock(&et61x251_sysfs_lock);
756
757 return count;
758}
759
760
761static ssize_t et61x251_show_val(struct class_device* cd, char* buf)
762{
763 struct et61x251_device* cam;
764 ssize_t count;
765 int val;
766
767 if (mutex_lock_interruptible(&et61x251_sysfs_lock))
768 return -ERESTARTSYS;
769
770 cam = video_get_drvdata(to_video_device(cd));
771 if (!cam) {
772 mutex_unlock(&et61x251_sysfs_lock);
773 return -ENODEV;
774 }
775
776 if ((val = et61x251_read_reg(cam, cam->sysfs.reg)) < 0) {
777 mutex_unlock(&et61x251_sysfs_lock);
778 return -EIO;
779 }
780
781 count = sprintf(buf, "%d\n", val);
782
783 DBG(3, "Read bytes: %zd", count);
784
785 mutex_unlock(&et61x251_sysfs_lock);
786
787 return count;
788}
789
790
791static ssize_t
792et61x251_store_val(struct class_device* cd, const char* buf, size_t len)
793{
794 struct et61x251_device* cam;
795 u8 value;
796 ssize_t count;
797 int err;
798
799 if (mutex_lock_interruptible(&et61x251_sysfs_lock))
800 return -ERESTARTSYS;
801
802 cam = video_get_drvdata(to_video_device(cd));
803 if (!cam) {
804 mutex_unlock(&et61x251_sysfs_lock);
805 return -ENODEV;
806 }
807
808 value = et61x251_strtou8(buf, len, &count);
809 if (!count) {
810 mutex_unlock(&et61x251_sysfs_lock);
811 return -EINVAL;
812 }
813
814 err = et61x251_write_reg(cam, value, cam->sysfs.reg);
815 if (err) {
816 mutex_unlock(&et61x251_sysfs_lock);
817 return -EIO;
818 }
819
820 DBG(2, "Written ET61X[12]51 reg. 0x%02X, val. 0x%02X",
821 cam->sysfs.reg, value);
822 DBG(3, "Written bytes: %zd", count);
823
824 mutex_unlock(&et61x251_sysfs_lock);
825
826 return count;
827}
828
829
830static ssize_t et61x251_show_i2c_reg(struct class_device* cd, char* buf)
831{
832 struct et61x251_device* cam;
833 ssize_t count;
834
835 if (mutex_lock_interruptible(&et61x251_sysfs_lock))
836 return -ERESTARTSYS;
837
838 cam = video_get_drvdata(to_video_device(cd));
839 if (!cam) {
840 mutex_unlock(&et61x251_sysfs_lock);
841 return -ENODEV;
842 }
843
844 count = sprintf(buf, "%u\n", cam->sysfs.i2c_reg);
845
846 DBG(3, "Read bytes: %zd", count);
847
848 mutex_unlock(&et61x251_sysfs_lock);
849
850 return count;
851}
852
853
854static ssize_t
855et61x251_store_i2c_reg(struct class_device* cd, const char* buf, size_t len)
856{
857 struct et61x251_device* cam;
858 u8 index;
859 ssize_t count;
860
861 if (mutex_lock_interruptible(&et61x251_sysfs_lock))
862 return -ERESTARTSYS;
863
864 cam = video_get_drvdata(to_video_device(cd));
865 if (!cam) {
866 mutex_unlock(&et61x251_sysfs_lock);
867 return -ENODEV;
868 }
869
870 index = et61x251_strtou8(buf, len, &count);
871 if (!count) {
872 mutex_unlock(&et61x251_sysfs_lock);
873 return -EINVAL;
874 }
875
876 cam->sysfs.i2c_reg = index;
877
878 DBG(2, "Moved sensor register index to 0x%02X", cam->sysfs.i2c_reg);
879 DBG(3, "Written bytes: %zd", count);
880
881 mutex_unlock(&et61x251_sysfs_lock);
882
883 return count;
884}
885
886
887static ssize_t et61x251_show_i2c_val(struct class_device* cd, char* buf)
888{
889 struct et61x251_device* cam;
890 ssize_t count;
891 int val;
892
893 if (mutex_lock_interruptible(&et61x251_sysfs_lock))
894 return -ERESTARTSYS;
895
896 cam = video_get_drvdata(to_video_device(cd));
897 if (!cam) {
898 mutex_unlock(&et61x251_sysfs_lock);
899 return -ENODEV;
900 }
901
902 if (!(cam->sensor.sysfs_ops & ET61X251_I2C_READ)) {
903 mutex_unlock(&et61x251_sysfs_lock);
904 return -ENOSYS;
905 }
906
907 if ((val = et61x251_i2c_read(cam, cam->sysfs.i2c_reg)) < 0) {
908 mutex_unlock(&et61x251_sysfs_lock);
909 return -EIO;
910 }
911
912 count = sprintf(buf, "%d\n", val);
913
914 DBG(3, "Read bytes: %zd", count);
915
916 mutex_unlock(&et61x251_sysfs_lock);
917
918 return count;
919}
920
921
922static ssize_t
923et61x251_store_i2c_val(struct class_device* cd, const char* buf, size_t len)
924{
925 struct et61x251_device* cam;
926 u8 value;
927 ssize_t count;
928 int err;
929
930 if (mutex_lock_interruptible(&et61x251_sysfs_lock))
931 return -ERESTARTSYS;
932
933 cam = video_get_drvdata(to_video_device(cd));
934 if (!cam) {
935 mutex_unlock(&et61x251_sysfs_lock);
936 return -ENODEV;
937 }
938
939 if (!(cam->sensor.sysfs_ops & ET61X251_I2C_READ)) {
940 mutex_unlock(&et61x251_sysfs_lock);
941 return -ENOSYS;
942 }
943
944 value = et61x251_strtou8(buf, len, &count);
945 if (!count) {
946 mutex_unlock(&et61x251_sysfs_lock);
947 return -EINVAL;
948 }
949
950 err = et61x251_i2c_write(cam, cam->sysfs.i2c_reg, value);
951 if (err) {
952 mutex_unlock(&et61x251_sysfs_lock);
953 return -EIO;
954 }
955
956 DBG(2, "Written sensor reg. 0x%02X, val. 0x%02X",
957 cam->sysfs.i2c_reg, value);
958 DBG(3, "Written bytes: %zd", count);
959
960 mutex_unlock(&et61x251_sysfs_lock);
961
962 return count;
963}
964
965
966static CLASS_DEVICE_ATTR(reg, S_IRUGO | S_IWUSR,
967 et61x251_show_reg, et61x251_store_reg);
968static CLASS_DEVICE_ATTR(val, S_IRUGO | S_IWUSR,
969 et61x251_show_val, et61x251_store_val);
970static CLASS_DEVICE_ATTR(i2c_reg, S_IRUGO | S_IWUSR,
971 et61x251_show_i2c_reg, et61x251_store_i2c_reg);
972static CLASS_DEVICE_ATTR(i2c_val, S_IRUGO | S_IWUSR,
973 et61x251_show_i2c_val, et61x251_store_i2c_val);
974
975
976static void et61x251_create_sysfs(struct et61x251_device* cam)
977{
978 struct video_device *v4ldev = cam->v4ldev;
979
980 video_device_create_file(v4ldev, &class_device_attr_reg);
981 video_device_create_file(v4ldev, &class_device_attr_val);
982 if (cam->sensor.sysfs_ops) {
983 video_device_create_file(v4ldev, &class_device_attr_i2c_reg);
984 video_device_create_file(v4ldev, &class_device_attr_i2c_val);
985 }
986}
987#endif /* CONFIG_VIDEO_ADV_DEBUG */
988
989/*****************************************************************************/
990
991static int
992et61x251_set_pix_format(struct et61x251_device* cam,
993 struct v4l2_pix_format* pix)
994{
995 int r, err = 0;
996
997 if ((r = et61x251_read_reg(cam, 0x12)) < 0)
998 err += r;
999 if (pix->pixelformat == V4L2_PIX_FMT_ET61X251)
1000 err += et61x251_write_reg(cam, r & 0xfd, 0x12);
1001 else
1002 err += et61x251_write_reg(cam, r | 0x02, 0x12);
1003
1004 return err ? -EIO : 0;
1005}
1006
1007
1008static int
1009et61x251_set_compression(struct et61x251_device* cam,
1010 struct v4l2_jpegcompression* compression)
1011{
1012 int r, err = 0;
1013
1014 if ((r = et61x251_read_reg(cam, 0x12)) < 0)
1015 err += r;
1016 if (compression->quality == 0)
1017 err += et61x251_write_reg(cam, r & 0xfb, 0x12);
1018 else
1019 err += et61x251_write_reg(cam, r | 0x04, 0x12);
1020
1021 return err ? -EIO : 0;
1022}
1023
1024
1025static int et61x251_set_scale(struct et61x251_device* cam, u8 scale)
1026{
1027 int r = 0, err = 0;
1028
1029 r = et61x251_read_reg(cam, 0x12);
1030 if (r < 0)
1031 err += r;
1032
1033 if (scale == 1)
1034 err += et61x251_write_reg(cam, r & ~0x01, 0x12);
1035 else if (scale == 2)
1036 err += et61x251_write_reg(cam, r | 0x01, 0x12);
1037
1038 if (err)
1039 return -EIO;
1040
1041 PDBGG("Scaling factor: %u", scale);
1042
1043 return 0;
1044}
1045
1046
1047static int
1048et61x251_set_crop(struct et61x251_device* cam, struct v4l2_rect* rect)
1049{
1050 struct et61x251_sensor* s = &cam->sensor;
1051 u16 fmw_sx = (u16)(rect->left - s->cropcap.bounds.left +
1052 s->active_pixel.left),
1053 fmw_sy = (u16)(rect->top - s->cropcap.bounds.top +
1054 s->active_pixel.top),
1055 fmw_length = (u16)(rect->width),
1056 fmw_height = (u16)(rect->height);
1057 int err = 0;
1058
1059 err += et61x251_write_reg(cam, fmw_sx & 0xff, 0x69);
1060 err += et61x251_write_reg(cam, fmw_sy & 0xff, 0x6a);
1061 err += et61x251_write_reg(cam, fmw_length & 0xff, 0x6b);
1062 err += et61x251_write_reg(cam, fmw_height & 0xff, 0x6c);
1063 err += et61x251_write_reg(cam, (fmw_sx >> 8) | ((fmw_sy & 0x300) >> 6)
1064 | ((fmw_length & 0x300) >> 4)
1065 | ((fmw_height & 0x300) >> 2), 0x6d);
1066 if (err)
1067 return -EIO;
1068
1069 PDBGG("fmw_sx, fmw_sy, fmw_length, fmw_height: %u %u %u %u",
1070 fmw_sx, fmw_sy, fmw_length, fmw_height);
1071
1072 return 0;
1073}
1074
1075
1076static int et61x251_init(struct et61x251_device* cam)
1077{
1078 struct et61x251_sensor* s = &cam->sensor;
1079 struct v4l2_control ctrl;
1080 struct v4l2_queryctrl *qctrl;
1081 struct v4l2_rect* rect;
1082 u8 i = 0;
1083 int err = 0;
1084
1085 if (!(cam->state & DEV_INITIALIZED)) {
1086 init_waitqueue_head(&cam->open);
1087 qctrl = s->qctrl;
1088 rect = &(s->cropcap.defrect);
1089 cam->compression.quality = ET61X251_COMPRESSION_QUALITY;
1090 } else { /* use current values */
1091 qctrl = s->_qctrl;
1092 rect = &(s->_rect);
1093 }
1094
1095 err += et61x251_set_scale(cam, rect->width / s->pix_format.width);
1096 err += et61x251_set_crop(cam, rect);
1097 if (err)
1098 return err;
1099
1100 if (s->init) {
1101 err = s->init(cam);
1102 if (err) {
1103 DBG(3, "Sensor initialization failed");
1104 return err;
1105 }
1106 }
1107
1108 err += et61x251_set_compression(cam, &cam->compression);
1109 err += et61x251_set_pix_format(cam, &s->pix_format);
1110 if (s->set_pix_format)
1111 err += s->set_pix_format(cam, &s->pix_format);
1112 if (err)
1113 return err;
1114
1115 if (s->pix_format.pixelformat == V4L2_PIX_FMT_ET61X251)
1116 DBG(3, "Compressed video format is active, quality %d",
1117 cam->compression.quality);
1118 else
1119 DBG(3, "Uncompressed video format is active");
1120
1121 if (s->set_crop)
1122 if ((err = s->set_crop(cam, rect))) {
1123 DBG(3, "set_crop() failed");
1124 return err;
1125 }
1126
1127 if (s->set_ctrl) {
1128 for (i = 0; i < ARRAY_SIZE(s->qctrl); i++)
1129 if (s->qctrl[i].id != 0 &&
1130 !(s->qctrl[i].flags & V4L2_CTRL_FLAG_DISABLED)) {
1131 ctrl.id = s->qctrl[i].id;
1132 ctrl.value = qctrl[i].default_value;
1133 err = s->set_ctrl(cam, &ctrl);
1134 if (err) {
1135 DBG(3, "Set %s control failed",
1136 s->qctrl[i].name);
1137 return err;
1138 }
1139 DBG(3, "Image sensor supports '%s' control",
1140 s->qctrl[i].name);
1141 }
1142 }
1143
1144 if (!(cam->state & DEV_INITIALIZED)) {
1145 mutex_init(&cam->fileop_mutex);
1146 spin_lock_init(&cam->queue_lock);
1147 init_waitqueue_head(&cam->wait_frame);
1148 init_waitqueue_head(&cam->wait_stream);
1149 cam->nreadbuffers = 2;
1150 memcpy(s->_qctrl, s->qctrl, sizeof(s->qctrl));
1151 memcpy(&(s->_rect), &(s->cropcap.defrect),
1152 sizeof(struct v4l2_rect));
1153 cam->state |= DEV_INITIALIZED;
1154 }
1155
1156 DBG(2, "Initialization succeeded");
1157 return 0;
1158}
1159
1160
1161static void et61x251_release_resources(struct et61x251_device* cam)
1162{
1163 mutex_lock(&et61x251_sysfs_lock);
1164
1165 DBG(2, "V4L2 device /dev/video%d deregistered", cam->v4ldev->minor);
1166 video_set_drvdata(cam->v4ldev, NULL);
1167 video_unregister_device(cam->v4ldev);
1168
1169 usb_put_dev(cam->usbdev);
1170
1171 mutex_unlock(&et61x251_sysfs_lock);
1172
1173 kfree(cam->control_buffer);
1174}
1175
1176/*****************************************************************************/
1177
1178static int et61x251_open(struct inode* inode, struct file* filp)
1179{
1180 struct et61x251_device* cam;
1181 int err = 0;
1182
1183 /*
1184 This is the only safe way to prevent race conditions with
1185 disconnect
1186 */
1187 if (!down_read_trylock(&et61x251_disconnect))
1188 return -ERESTARTSYS;
1189
1190 cam = video_get_drvdata(video_devdata(filp));
1191
1192 if (mutex_lock_interruptible(&cam->dev_mutex)) {
1193 up_read(&et61x251_disconnect);
1194 return -ERESTARTSYS;
1195 }
1196
1197 if (cam->users) {
1198 DBG(2, "Device /dev/video%d is busy...", cam->v4ldev->minor);
1199 if ((filp->f_flags & O_NONBLOCK) ||
1200 (filp->f_flags & O_NDELAY)) {
1201 err = -EWOULDBLOCK;
1202 goto out;
1203 }
1204 mutex_unlock(&cam->dev_mutex);
1205 err = wait_event_interruptible_exclusive(cam->open,
1206 cam->state & DEV_DISCONNECTED
1207 || !cam->users);
1208 if (err) {
1209 up_read(&et61x251_disconnect);
1210 return err;
1211 }
1212 if (cam->state & DEV_DISCONNECTED) {
1213 up_read(&et61x251_disconnect);
1214 return -ENODEV;
1215 }
1216 mutex_lock(&cam->dev_mutex);
1217 }
1218
1219
1220 if (cam->state & DEV_MISCONFIGURED) {
1221 err = et61x251_init(cam);
1222 if (err) {
1223 DBG(1, "Initialization failed again. "
1224 "I will retry on next open().");
1225 goto out;
1226 }
1227 cam->state &= ~DEV_MISCONFIGURED;
1228 }
1229
1230 if ((err = et61x251_start_transfer(cam)))
1231 goto out;
1232
1233 filp->private_data = cam;
1234 cam->users++;
1235 cam->io = IO_NONE;
1236 cam->stream = STREAM_OFF;
1237 cam->nbuffers = 0;
1238 cam->frame_count = 0;
1239 et61x251_empty_framequeues(cam);
1240
1241 DBG(3, "Video device /dev/video%d is open", cam->v4ldev->minor);
1242
1243out:
1244 mutex_unlock(&cam->dev_mutex);
1245 up_read(&et61x251_disconnect);
1246 return err;
1247}
1248
1249
1250static int et61x251_release(struct inode* inode, struct file* filp)
1251{
1252 struct et61x251_device* cam = video_get_drvdata(video_devdata(filp));
1253
1254 mutex_lock(&cam->dev_mutex); /* prevent disconnect() to be called */
1255
1256 et61x251_stop_transfer(cam);
1257
1258 et61x251_release_buffers(cam);
1259
1260 if (cam->state & DEV_DISCONNECTED) {
1261 et61x251_release_resources(cam);
1262 mutex_unlock(&cam->dev_mutex);
1263 kfree(cam);
1264 return 0;
1265 }
1266
1267 cam->users--;
1268 wake_up_interruptible_nr(&cam->open, 1);
1269
1270 DBG(3, "Video device /dev/video%d closed", cam->v4ldev->minor);
1271
1272 mutex_unlock(&cam->dev_mutex);
1273
1274 return 0;
1275}
1276
1277
1278static ssize_t
1279et61x251_read(struct file* filp, char __user * buf,
1280 size_t count, loff_t* f_pos)
1281{
1282 struct et61x251_device* cam = video_get_drvdata(video_devdata(filp));
1283 struct et61x251_frame_t* f, * i;
1284 unsigned long lock_flags;
1285 long timeout;
1286 int err = 0;
1287
1288 if (mutex_lock_interruptible(&cam->fileop_mutex))
1289 return -ERESTARTSYS;
1290
1291 if (cam->state & DEV_DISCONNECTED) {
1292 DBG(1, "Device not present");
1293 mutex_unlock(&cam->fileop_mutex);
1294 return -ENODEV;
1295 }
1296
1297 if (cam->state & DEV_MISCONFIGURED) {
1298 DBG(1, "The camera is misconfigured. Close and open it "
1299 "again.");
1300 mutex_unlock(&cam->fileop_mutex);
1301 return -EIO;
1302 }
1303
1304 if (cam->io == IO_MMAP) {
1305 DBG(3, "Close and open the device again to choose the read "
1306 "method");
1307 mutex_unlock(&cam->fileop_mutex);
1308 return -EINVAL;
1309 }
1310
1311 if (cam->io == IO_NONE) {
1312 if (!et61x251_request_buffers(cam, cam->nreadbuffers,
1313 IO_READ)) {
1314 DBG(1, "read() failed, not enough memory");
1315 mutex_unlock(&cam->fileop_mutex);
1316 return -ENOMEM;
1317 }
1318 cam->io = IO_READ;
1319 cam->stream = STREAM_ON;
1320 }
1321
1322 if (list_empty(&cam->inqueue)) {
1323 if (!list_empty(&cam->outqueue))
1324 et61x251_empty_framequeues(cam);
1325 et61x251_queue_unusedframes(cam);
1326 }
1327
1328 if (!count) {
1329 mutex_unlock(&cam->fileop_mutex);
1330 return 0;
1331 }
1332
1333 if (list_empty(&cam->outqueue)) {
1334 if (filp->f_flags & O_NONBLOCK) {
1335 mutex_unlock(&cam->fileop_mutex);
1336 return -EAGAIN;
1337 }
1338 timeout = wait_event_interruptible_timeout
1339 ( cam->wait_frame,
1340 (!list_empty(&cam->outqueue)) ||
1341 (cam->state & DEV_DISCONNECTED) ||
1342 (cam->state & DEV_MISCONFIGURED),
1343 cam->module_param.frame_timeout *
1344 1000 * msecs_to_jiffies(1) );
1345 if (timeout < 0) {
1346 mutex_unlock(&cam->fileop_mutex);
1347 return timeout;
1348 }
1349 if (cam->state & DEV_DISCONNECTED) {
1350 mutex_unlock(&cam->fileop_mutex);
1351 return -ENODEV;
1352 }
1353 if (!timeout || (cam->state & DEV_MISCONFIGURED)) {
1354 mutex_unlock(&cam->fileop_mutex);
1355 return -EIO;
1356 }
1357 }
1358
1359 f = list_entry(cam->outqueue.prev, struct et61x251_frame_t, frame);
1360
1361 if (count > f->buf.bytesused)
1362 count = f->buf.bytesused;
1363
1364 if (copy_to_user(buf, f->bufmem, count)) {
1365 err = -EFAULT;
1366 goto exit;
1367 }
1368 *f_pos += count;
1369
1370exit:
1371 spin_lock_irqsave(&cam->queue_lock, lock_flags);
1372 list_for_each_entry(i, &cam->outqueue, frame)
1373 i->state = F_UNUSED;
1374 INIT_LIST_HEAD(&cam->outqueue);
1375 spin_unlock_irqrestore(&cam->queue_lock, lock_flags);
1376
1377 et61x251_queue_unusedframes(cam);
1378
1379 PDBGG("Frame #%lu, bytes read: %zu",
1380 (unsigned long)f->buf.index, count);
1381
1382 mutex_unlock(&cam->fileop_mutex);
1383
1384 return err ? err : count;
1385}
1386
1387
1388static unsigned int et61x251_poll(struct file *filp, poll_table *wait)
1389{
1390 struct et61x251_device* cam = video_get_drvdata(video_devdata(filp));
1391 struct et61x251_frame_t* f;
1392 unsigned long lock_flags;
1393 unsigned int mask = 0;
1394
1395 if (mutex_lock_interruptible(&cam->fileop_mutex))
1396 return POLLERR;
1397
1398 if (cam->state & DEV_DISCONNECTED) {
1399 DBG(1, "Device not present");
1400 goto error;
1401 }
1402
1403 if (cam->state & DEV_MISCONFIGURED) {
1404 DBG(1, "The camera is misconfigured. Close and open it "
1405 "again.");
1406 goto error;
1407 }
1408
1409 if (cam->io == IO_NONE) {
1410 if (!et61x251_request_buffers(cam, cam->nreadbuffers,
1411 IO_READ)) {
1412 DBG(1, "poll() failed, not enough memory");
1413 goto error;
1414 }
1415 cam->io = IO_READ;
1416 cam->stream = STREAM_ON;
1417 }
1418
1419 if (cam->io == IO_READ) {
1420 spin_lock_irqsave(&cam->queue_lock, lock_flags);
1421 list_for_each_entry(f, &cam->outqueue, frame)
1422 f->state = F_UNUSED;
1423 INIT_LIST_HEAD(&cam->outqueue);
1424 spin_unlock_irqrestore(&cam->queue_lock, lock_flags);
1425 et61x251_queue_unusedframes(cam);
1426 }
1427
1428 poll_wait(filp, &cam->wait_frame, wait);
1429
1430 if (!list_empty(&cam->outqueue))
1431 mask |= POLLIN | POLLRDNORM;
1432
1433 mutex_unlock(&cam->fileop_mutex);
1434
1435 return mask;
1436
1437error:
1438 mutex_unlock(&cam->fileop_mutex);
1439 return POLLERR;
1440}
1441
1442
1443static void et61x251_vm_open(struct vm_area_struct* vma)
1444{
1445 struct et61x251_frame_t* f = vma->vm_private_data;
1446 f->vma_use_count++;
1447}
1448
1449
1450static void et61x251_vm_close(struct vm_area_struct* vma)
1451{
1452 /* NOTE: buffers are not freed here */
1453 struct et61x251_frame_t* f = vma->vm_private_data;
1454 f->vma_use_count--;
1455}
1456
1457
1458static struct vm_operations_struct et61x251_vm_ops = {
1459 .open = et61x251_vm_open,
1460 .close = et61x251_vm_close,
1461};
1462
1463
1464static int et61x251_mmap(struct file* filp, struct vm_area_struct *vma)
1465{
1466 struct et61x251_device* cam = video_get_drvdata(video_devdata(filp));
1467 unsigned long size = vma->vm_end - vma->vm_start,
1468 start = vma->vm_start;
1469 void *pos;
1470 u32 i;
1471
1472 if (mutex_lock_interruptible(&cam->fileop_mutex))
1473 return -ERESTARTSYS;
1474
1475 if (cam->state & DEV_DISCONNECTED) {
1476 DBG(1, "Device not present");
1477 mutex_unlock(&cam->fileop_mutex);
1478 return -ENODEV;
1479 }
1480
1481 if (cam->state & DEV_MISCONFIGURED) {
1482 DBG(1, "The camera is misconfigured. Close and open it "
1483 "again.");
1484 mutex_unlock(&cam->fileop_mutex);
1485 return -EIO;
1486 }
1487
1488 if (cam->io != IO_MMAP || !(vma->vm_flags & VM_WRITE) ||
1489 size != PAGE_ALIGN(cam->frame[0].buf.length)) {
1490 mutex_unlock(&cam->fileop_mutex);
1491 return -EINVAL;
1492 }
1493
1494 for (i = 0; i < cam->nbuffers; i++) {
1495 if ((cam->frame[i].buf.m.offset>>PAGE_SHIFT) == vma->vm_pgoff)
1496 break;
1497 }
1498 if (i == cam->nbuffers) {
1499 mutex_unlock(&cam->fileop_mutex);
1500 return -EINVAL;
1501 }
1502
1503 vma->vm_flags |= VM_IO;
1504 vma->vm_flags |= VM_RESERVED;
1505
1506 pos = cam->frame[i].bufmem;
1507 while (size > 0) { /* size is page-aligned */
1508 if (vm_insert_page(vma, start, vmalloc_to_page(pos))) {
1509 mutex_unlock(&cam->fileop_mutex);
1510 return -EAGAIN;
1511 }
1512 start += PAGE_SIZE;
1513 pos += PAGE_SIZE;
1514 size -= PAGE_SIZE;
1515 }
1516
1517 vma->vm_ops = &et61x251_vm_ops;
1518 vma->vm_private_data = &cam->frame[i];
1519
1520 et61x251_vm_open(vma);
1521
1522 mutex_unlock(&cam->fileop_mutex);
1523
1524 return 0;
1525}
1526
1527/*****************************************************************************/
1528
1529static int
1530et61x251_vidioc_querycap(struct et61x251_device* cam, void __user * arg)
1531{
1532 struct v4l2_capability cap = {
1533 .driver = "et61x251",
1534 .version = ET61X251_MODULE_VERSION_CODE,
1535 .capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE |
1536 V4L2_CAP_STREAMING,
1537 };
1538
1539 strlcpy(cap.card, cam->v4ldev->name, sizeof(cap.card));
1540 if (usb_make_path(cam->usbdev, cap.bus_info, sizeof(cap.bus_info)) < 0)
1541 strlcpy(cap.bus_info, cam->usbdev->dev.bus_id,
1542 sizeof(cap.bus_info));
1543
1544 if (copy_to_user(arg, &cap, sizeof(cap)))
1545 return -EFAULT;
1546
1547 return 0;
1548}
1549
1550
1551static int
1552et61x251_vidioc_enuminput(struct et61x251_device* cam, void __user * arg)
1553{
1554 struct v4l2_input i;
1555
1556 if (copy_from_user(&i, arg, sizeof(i)))
1557 return -EFAULT;
1558
1559 if (i.index)
1560 return -EINVAL;
1561
1562 memset(&i, 0, sizeof(i));
1563 strcpy(i.name, "Camera");
1564 i.type = V4L2_INPUT_TYPE_CAMERA;
1565
1566 if (copy_to_user(arg, &i, sizeof(i)))
1567 return -EFAULT;
1568
1569 return 0;
1570}
1571
1572
1573static int
1574et61x251_vidioc_g_input(struct et61x251_device* cam, void __user * arg)
1575{
1576 int index = 0;
1577
1578 if (copy_to_user(arg, &index, sizeof(index)))
1579 return -EFAULT;
1580
1581 return 0;
1582}
1583
1584
1585static int
1586et61x251_vidioc_s_input(struct et61x251_device* cam, void __user * arg)
1587{
1588 int index;
1589
1590 if (copy_from_user(&index, arg, sizeof(index)))
1591 return -EFAULT;
1592
1593 if (index != 0)
1594 return -EINVAL;
1595
1596 return 0;
1597}
1598
1599
1600static int
1601et61x251_vidioc_query_ctrl(struct et61x251_device* cam, void __user * arg)
1602{
1603 struct et61x251_sensor* s = &cam->sensor;
1604 struct v4l2_queryctrl qc;
1605 u8 i;
1606
1607 if (copy_from_user(&qc, arg, sizeof(qc)))
1608 return -EFAULT;
1609
1610 for (i = 0; i < ARRAY_SIZE(s->qctrl); i++)
1611 if (qc.id && qc.id == s->qctrl[i].id) {
1612 memcpy(&qc, &(s->qctrl[i]), sizeof(qc));
1613 if (copy_to_user(arg, &qc, sizeof(qc)))
1614 return -EFAULT;
1615 return 0;
1616 }
1617
1618 return -EINVAL;
1619}
1620
1621
1622static int
1623et61x251_vidioc_g_ctrl(struct et61x251_device* cam, void __user * arg)
1624{
1625 struct et61x251_sensor* s = &cam->sensor;
1626 struct v4l2_control ctrl;
1627 int err = 0;
1628 u8 i;
1629
1630 if (!s->get_ctrl && !s->set_ctrl)
1631 return -EINVAL;
1632
1633 if (copy_from_user(&ctrl, arg, sizeof(ctrl)))
1634 return -EFAULT;
1635
1636 if (!s->get_ctrl) {
1637 for (i = 0; i < ARRAY_SIZE(s->qctrl); i++)
1638 if (ctrl.id == s->qctrl[i].id) {
1639 ctrl.value = s->_qctrl[i].default_value;
1640 goto exit;
1641 }
1642 return -EINVAL;
1643 } else
1644 err = s->get_ctrl(cam, &ctrl);
1645
1646exit:
1647 if (copy_to_user(arg, &ctrl, sizeof(ctrl)))
1648 return -EFAULT;
1649
1650 return err;
1651}
1652
1653
1654static int
1655et61x251_vidioc_s_ctrl(struct et61x251_device* cam, void __user * arg)
1656{
1657 struct et61x251_sensor* s = &cam->sensor;
1658 struct v4l2_control ctrl;
1659 u8 i;
1660 int err = 0;
1661
1662 if (!s->set_ctrl)
1663 return -EINVAL;
1664
1665 if (copy_from_user(&ctrl, arg, sizeof(ctrl)))
1666 return -EFAULT;
1667
1668 for (i = 0; i < ARRAY_SIZE(s->qctrl); i++)
1669 if (ctrl.id == s->qctrl[i].id) {
1670 if (s->qctrl[i].flags & V4L2_CTRL_FLAG_DISABLED)
1671 return -EINVAL;
1672 if (ctrl.value < s->qctrl[i].minimum ||
1673 ctrl.value > s->qctrl[i].maximum)
1674 return -ERANGE;
1675 ctrl.value -= ctrl.value % s->qctrl[i].step;
1676 break;
1677 }
1678
1679 if ((err = s->set_ctrl(cam, &ctrl)))
1680 return err;
1681
1682 s->_qctrl[i].default_value = ctrl.value;
1683
1684 return 0;
1685}
1686
1687
1688static int
1689et61x251_vidioc_cropcap(struct et61x251_device* cam, void __user * arg)
1690{
1691 struct v4l2_cropcap* cc = &(cam->sensor.cropcap);
1692
1693 cc->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1694 cc->pixelaspect.numerator = 1;
1695 cc->pixelaspect.denominator = 1;
1696
1697 if (copy_to_user(arg, cc, sizeof(*cc)))
1698 return -EFAULT;
1699
1700 return 0;
1701}
1702
1703
1704static int
1705et61x251_vidioc_g_crop(struct et61x251_device* cam, void __user * arg)
1706{
1707 struct et61x251_sensor* s = &cam->sensor;
1708 struct v4l2_crop crop = {
1709 .type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
1710 };
1711
1712 memcpy(&(crop.c), &(s->_rect), sizeof(struct v4l2_rect));
1713
1714 if (copy_to_user(arg, &crop, sizeof(crop)))
1715 return -EFAULT;
1716
1717 return 0;
1718}
1719
1720
1721static int
1722et61x251_vidioc_s_crop(struct et61x251_device* cam, void __user * arg)
1723{
1724 struct et61x251_sensor* s = &cam->sensor;
1725 struct v4l2_crop crop;
1726 struct v4l2_rect* rect;
1727 struct v4l2_rect* bounds = &(s->cropcap.bounds);
1728 struct v4l2_pix_format* pix_format = &(s->pix_format);
1729 u8 scale;
1730 const enum et61x251_stream_state stream = cam->stream;
1731 const u32 nbuffers = cam->nbuffers;
1732 u32 i;
1733 int err = 0;
1734
1735 if (copy_from_user(&crop, arg, sizeof(crop)))
1736 return -EFAULT;
1737
1738 rect = &(crop.c);
1739
1740 if (crop.type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1741 return -EINVAL;
1742
1743 if (cam->module_param.force_munmap)
1744 for (i = 0; i < cam->nbuffers; i++)
1745 if (cam->frame[i].vma_use_count) {
1746 DBG(3, "VIDIOC_S_CROP failed. "
1747 "Unmap the buffers first.");
1748 return -EINVAL;
1749 }
1750
1751 /* Preserve R,G or B origin */
1752 rect->left = (s->_rect.left & 1L) ? rect->left | 1L : rect->left & ~1L;
1753 rect->top = (s->_rect.top & 1L) ? rect->top | 1L : rect->top & ~1L;
1754
1755 if (rect->width < 4)
1756 rect->width = 4;
1757 if (rect->height < 4)
1758 rect->height = 4;
1759 if (rect->width > bounds->width)
1760 rect->width = bounds->width;
1761 if (rect->height > bounds->height)
1762 rect->height = bounds->height;
1763 if (rect->left < bounds->left)
1764 rect->left = bounds->left;
1765 if (rect->top < bounds->top)
1766 rect->top = bounds->top;
1767 if (rect->left + rect->width > bounds->left + bounds->width)
1768 rect->left = bounds->left+bounds->width - rect->width;
1769 if (rect->top + rect->height > bounds->top + bounds->height)
1770 rect->top = bounds->top+bounds->height - rect->height;
1771
1772 rect->width &= ~3L;
1773 rect->height &= ~3L;
1774
1775 if (ET61X251_PRESERVE_IMGSCALE) {
1776 /* Calculate the actual scaling factor */
1777 u32 a, b;
1778 a = rect->width * rect->height;
1779 b = pix_format->width * pix_format->height;
1780 scale = b ? (u8)((a / b) < 4 ? 1 : 2) : 1;
1781 } else
1782 scale = 1;
1783
1784 if (cam->stream == STREAM_ON)
1785 if ((err = et61x251_stream_interrupt(cam)))
1786 return err;
1787
1788 if (copy_to_user(arg, &crop, sizeof(crop))) {
1789 cam->stream = stream;
1790 return -EFAULT;
1791 }
1792
1793 if (cam->module_param.force_munmap || cam->io == IO_READ)
1794 et61x251_release_buffers(cam);
1795
1796 err = et61x251_set_crop(cam, rect);
1797 if (s->set_crop)
1798 err += s->set_crop(cam, rect);
1799 err += et61x251_set_scale(cam, scale);
1800
1801 if (err) { /* atomic, no rollback in ioctl() */
1802 cam->state |= DEV_MISCONFIGURED;
1803 DBG(1, "VIDIOC_S_CROP failed because of hardware problems. To "
1804 "use the camera, close and open /dev/video%d again.",
1805 cam->v4ldev->minor);
1806 return -EIO;
1807 }
1808
1809 s->pix_format.width = rect->width/scale;
1810 s->pix_format.height = rect->height/scale;
1811 memcpy(&(s->_rect), rect, sizeof(*rect));
1812
1813 if ((cam->module_param.force_munmap || cam->io == IO_READ) &&
1814 nbuffers != et61x251_request_buffers(cam, nbuffers, cam->io)) {
1815 cam->state |= DEV_MISCONFIGURED;
1816 DBG(1, "VIDIOC_S_CROP failed because of not enough memory. To "
1817 "use the camera, close and open /dev/video%d again.",
1818 cam->v4ldev->minor);
1819 return -ENOMEM;
1820 }
1821
1822 if (cam->io == IO_READ)
1823 et61x251_empty_framequeues(cam);
1824 else if (cam->module_param.force_munmap)
1825 et61x251_requeue_outqueue(cam);
1826
1827 cam->stream = stream;
1828
1829 return 0;
1830}
1831
1832
1833static int
1834et61x251_vidioc_enum_fmt(struct et61x251_device* cam, void __user * arg)
1835{
1836 struct v4l2_fmtdesc fmtd;
1837
1838 if (copy_from_user(&fmtd, arg, sizeof(fmtd)))
1839 return -EFAULT;
1840
1841 if (fmtd.index == 0) {
1842 strcpy(fmtd.description, "bayer rgb");
1843 fmtd.pixelformat = V4L2_PIX_FMT_SBGGR8;
1844 } else if (fmtd.index == 1) {
1845 strcpy(fmtd.description, "compressed");
1846 fmtd.pixelformat = V4L2_PIX_FMT_ET61X251;
1847 fmtd.flags = V4L2_FMT_FLAG_COMPRESSED;
1848 } else
1849 return -EINVAL;
1850
1851 fmtd.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1852 memset(&fmtd.reserved, 0, sizeof(fmtd.reserved));
1853
1854 if (copy_to_user(arg, &fmtd, sizeof(fmtd)))
1855 return -EFAULT;
1856
1857 return 0;
1858}
1859
1860
1861static int
1862et61x251_vidioc_g_fmt(struct et61x251_device* cam, void __user * arg)
1863{
1864 struct v4l2_format format;
1865 struct v4l2_pix_format* pfmt = &(cam->sensor.pix_format);
1866
1867 if (copy_from_user(&format, arg, sizeof(format)))
1868 return -EFAULT;
1869
1870 if (format.type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1871 return -EINVAL;
1872
1873 pfmt->bytesperline = (pfmt->pixelformat==V4L2_PIX_FMT_ET61X251)
1874 ? 0 : (pfmt->width * pfmt->priv) / 8;
1875 pfmt->sizeimage = pfmt->height * ((pfmt->width*pfmt->priv)/8);
1876 pfmt->field = V4L2_FIELD_NONE;
1877 memcpy(&(format.fmt.pix), pfmt, sizeof(*pfmt));
1878
1879 if (copy_to_user(arg, &format, sizeof(format)))
1880 return -EFAULT;
1881
1882 return 0;
1883}
1884
1885
1886static int
1887et61x251_vidioc_try_s_fmt(struct et61x251_device* cam, unsigned int cmd,
1888 void __user * arg)
1889{
1890 struct et61x251_sensor* s = &cam->sensor;
1891 struct v4l2_format format;
1892 struct v4l2_pix_format* pix;
1893 struct v4l2_pix_format* pfmt = &(s->pix_format);
1894 struct v4l2_rect* bounds = &(s->cropcap.bounds);
1895 struct v4l2_rect rect;
1896 u8 scale;
1897 const enum et61x251_stream_state stream = cam->stream;
1898 const u32 nbuffers = cam->nbuffers;
1899 u32 i;
1900 int err = 0;
1901
1902 if (copy_from_user(&format, arg, sizeof(format)))
1903 return -EFAULT;
1904
1905 pix = &(format.fmt.pix);
1906
1907 if (format.type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1908 return -EINVAL;
1909
1910 memcpy(&rect, &(s->_rect), sizeof(rect));
1911
1912 { /* calculate the actual scaling factor */
1913 u32 a, b;
1914 a = rect.width * rect.height;
1915 b = pix->width * pix->height;
1916 scale = b ? (u8)((a / b) < 4 ? 1 : 2) : 1;
1917 }
1918
1919 rect.width = scale * pix->width;
1920 rect.height = scale * pix->height;
1921
1922 if (rect.width < 4)
1923 rect.width = 4;
1924 if (rect.height < 4)
1925 rect.height = 4;
1926 if (rect.width > bounds->left + bounds->width - rect.left)
1927 rect.width = bounds->left + bounds->width - rect.left;
1928 if (rect.height > bounds->top + bounds->height - rect.top)
1929 rect.height = bounds->top + bounds->height - rect.top;
1930
1931 rect.width &= ~3L;
1932 rect.height &= ~3L;
1933
1934 { /* adjust the scaling factor */
1935 u32 a, b;
1936 a = rect.width * rect.height;
1937 b = pix->width * pix->height;
1938 scale = b ? (u8)((a / b) < 4 ? 1 : 2) : 1;
1939 }
1940
1941 pix->width = rect.width / scale;
1942 pix->height = rect.height / scale;
1943
1944 if (pix->pixelformat != V4L2_PIX_FMT_ET61X251 &&
1945 pix->pixelformat != V4L2_PIX_FMT_SBGGR8)
1946 pix->pixelformat = pfmt->pixelformat;
1947 pix->priv = pfmt->priv; /* bpp */
1948 pix->colorspace = pfmt->colorspace;
1949 pix->bytesperline = (pix->pixelformat == V4L2_PIX_FMT_ET61X251)
1950 ? 0 : (pix->width * pix->priv) / 8;
1951 pix->sizeimage = pix->height * ((pix->width * pix->priv) / 8);
1952 pix->field = V4L2_FIELD_NONE;
1953
1954 if (cmd == VIDIOC_TRY_FMT) {
1955 if (copy_to_user(arg, &format, sizeof(format)))
1956 return -EFAULT;
1957 return 0;
1958 }
1959
1960 if (cam->module_param.force_munmap)
1961 for (i = 0; i < cam->nbuffers; i++)
1962 if (cam->frame[i].vma_use_count) {
1963 DBG(3, "VIDIOC_S_FMT failed. "
1964 "Unmap the buffers first.");
1965 return -EINVAL;
1966 }
1967
1968 if (cam->stream == STREAM_ON)
1969 if ((err = et61x251_stream_interrupt(cam)))
1970 return err;
1971
1972 if (copy_to_user(arg, &format, sizeof(format))) {
1973 cam->stream = stream;
1974 return -EFAULT;
1975 }
1976
1977 if (cam->module_param.force_munmap || cam->io == IO_READ)
1978 et61x251_release_buffers(cam);
1979
1980 err += et61x251_set_pix_format(cam, pix);
1981 err += et61x251_set_crop(cam, &rect);
1982 if (s->set_pix_format)
1983 err += s->set_pix_format(cam, pix);
1984 if (s->set_crop)
1985 err += s->set_crop(cam, &rect);
1986 err += et61x251_set_scale(cam, scale);
1987
1988 if (err) { /* atomic, no rollback in ioctl() */
1989 cam->state |= DEV_MISCONFIGURED;
1990 DBG(1, "VIDIOC_S_FMT failed because of hardware problems. To "
1991 "use the camera, close and open /dev/video%d again.",
1992 cam->v4ldev->minor);
1993 return -EIO;
1994 }
1995
1996 memcpy(pfmt, pix, sizeof(*pix));
1997 memcpy(&(s->_rect), &rect, sizeof(rect));
1998
1999 if ((cam->module_param.force_munmap || cam->io == IO_READ) &&
2000 nbuffers != et61x251_request_buffers(cam, nbuffers, cam->io)) {
2001 cam->state |= DEV_MISCONFIGURED;
2002 DBG(1, "VIDIOC_S_FMT failed because of not enough memory. To "
2003 "use the camera, close and open /dev/video%d again.",
2004 cam->v4ldev->minor);
2005 return -ENOMEM;
2006 }
2007
2008 if (cam->io == IO_READ)
2009 et61x251_empty_framequeues(cam);
2010 else if (cam->module_param.force_munmap)
2011 et61x251_requeue_outqueue(cam);
2012
2013 cam->stream = stream;
2014
2015 return 0;
2016}
2017
2018
2019static int
2020et61x251_vidioc_g_jpegcomp(struct et61x251_device* cam, void __user * arg)
2021{
2022 if (copy_to_user(arg, &cam->compression,
2023 sizeof(cam->compression)))
2024 return -EFAULT;
2025
2026 return 0;
2027}
2028
2029
2030static int
2031et61x251_vidioc_s_jpegcomp(struct et61x251_device* cam, void __user * arg)
2032{
2033 struct v4l2_jpegcompression jc;
2034 const enum et61x251_stream_state stream = cam->stream;
2035 int err = 0;
2036
2037 if (copy_from_user(&jc, arg, sizeof(jc)))
2038 return -EFAULT;
2039
2040 if (jc.quality != 0 && jc.quality != 1)
2041 return -EINVAL;
2042
2043 if (cam->stream == STREAM_ON)
2044 if ((err = et61x251_stream_interrupt(cam)))
2045 return err;
2046
2047 err += et61x251_set_compression(cam, &jc);
2048 if (err) { /* atomic, no rollback in ioctl() */
2049 cam->state |= DEV_MISCONFIGURED;
2050 DBG(1, "VIDIOC_S_JPEGCOMP failed because of hardware "
2051 "problems. To use the camera, close and open "
2052 "/dev/video%d again.", cam->v4ldev->minor);
2053 return -EIO;
2054 }
2055
2056 cam->compression.quality = jc.quality;
2057
2058 cam->stream = stream;
2059
2060 return 0;
2061}
2062
2063
2064static int
2065et61x251_vidioc_reqbufs(struct et61x251_device* cam, void __user * arg)
2066{
2067 struct v4l2_requestbuffers rb;
2068 u32 i;
2069 int err;
2070
2071 if (copy_from_user(&rb, arg, sizeof(rb)))
2072 return -EFAULT;
2073
2074 if (rb.type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
2075 rb.memory != V4L2_MEMORY_MMAP)
2076 return -EINVAL;
2077
2078 if (cam->io == IO_READ) {
2079 DBG(3, "Close and open the device again to choose the mmap "
2080 "I/O method");
2081 return -EINVAL;
2082 }
2083
2084 for (i = 0; i < cam->nbuffers; i++)
2085 if (cam->frame[i].vma_use_count) {
2086 DBG(3, "VIDIOC_REQBUFS failed. "
2087 "Previous buffers are still mapped.");
2088 return -EINVAL;
2089 }
2090
2091 if (cam->stream == STREAM_ON)
2092 if ((err = et61x251_stream_interrupt(cam)))
2093 return err;
2094
2095 et61x251_empty_framequeues(cam);
2096
2097 et61x251_release_buffers(cam);
2098 if (rb.count)
2099 rb.count = et61x251_request_buffers(cam, rb.count, IO_MMAP);
2100
2101 if (copy_to_user(arg, &rb, sizeof(rb))) {
2102 et61x251_release_buffers(cam);
2103 cam->io = IO_NONE;
2104 return -EFAULT;
2105 }
2106
2107 cam->io = rb.count ? IO_MMAP : IO_NONE;
2108
2109 return 0;
2110}
2111
2112
2113static int
2114et61x251_vidioc_querybuf(struct et61x251_device* cam, void __user * arg)
2115{
2116 struct v4l2_buffer b;
2117
2118 if (copy_from_user(&b, arg, sizeof(b)))
2119 return -EFAULT;
2120
2121 if (b.type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
2122 b.index >= cam->nbuffers || cam->io != IO_MMAP)
2123 return -EINVAL;
2124
2125 memcpy(&b, &cam->frame[b.index].buf, sizeof(b));
2126
2127 if (cam->frame[b.index].vma_use_count)
2128 b.flags |= V4L2_BUF_FLAG_MAPPED;
2129
2130 if (cam->frame[b.index].state == F_DONE)
2131 b.flags |= V4L2_BUF_FLAG_DONE;
2132 else if (cam->frame[b.index].state != F_UNUSED)
2133 b.flags |= V4L2_BUF_FLAG_QUEUED;
2134
2135 if (copy_to_user(arg, &b, sizeof(b)))
2136 return -EFAULT;
2137
2138 return 0;
2139}
2140
2141
2142static int
2143et61x251_vidioc_qbuf(struct et61x251_device* cam, void __user * arg)
2144{
2145 struct v4l2_buffer b;
2146 unsigned long lock_flags;
2147
2148 if (copy_from_user(&b, arg, sizeof(b)))
2149 return -EFAULT;
2150
2151 if (b.type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
2152 b.index >= cam->nbuffers || cam->io != IO_MMAP)
2153 return -EINVAL;
2154
2155 if (cam->frame[b.index].state != F_UNUSED)
2156 return -EINVAL;
2157
2158 cam->frame[b.index].state = F_QUEUED;
2159
2160 spin_lock_irqsave(&cam->queue_lock, lock_flags);
2161 list_add_tail(&cam->frame[b.index].frame, &cam->inqueue);
2162 spin_unlock_irqrestore(&cam->queue_lock, lock_flags);
2163
2164 PDBGG("Frame #%lu queued", (unsigned long)b.index);
2165
2166 return 0;
2167}
2168
2169
2170static int
2171et61x251_vidioc_dqbuf(struct et61x251_device* cam, struct file* filp,
2172 void __user * arg)
2173{
2174 struct v4l2_buffer b;
2175 struct et61x251_frame_t *f;
2176 unsigned long lock_flags;
2177 long timeout;
2178
2179 if (copy_from_user(&b, arg, sizeof(b)))
2180 return -EFAULT;
2181
2182 if (b.type != V4L2_BUF_TYPE_VIDEO_CAPTURE || cam->io!= IO_MMAP)
2183 return -EINVAL;
2184
2185 if (list_empty(&cam->outqueue)) {
2186 if (cam->stream == STREAM_OFF)
2187 return -EINVAL;
2188 if (filp->f_flags & O_NONBLOCK)
2189 return -EAGAIN;
2190 timeout = wait_event_interruptible_timeout
2191 ( cam->wait_frame,
2192 (!list_empty(&cam->outqueue)) ||
2193 (cam->state & DEV_DISCONNECTED) ||
2194 (cam->state & DEV_MISCONFIGURED),
2195 cam->module_param.frame_timeout *
2196 1000 * msecs_to_jiffies(1) );
2197 if (timeout < 0)
2198 return timeout;
2199 if (cam->state & DEV_DISCONNECTED)
2200 return -ENODEV;
2201 if (!timeout || (cam->state & DEV_MISCONFIGURED))
2202 return -EIO;
2203 }
2204
2205 spin_lock_irqsave(&cam->queue_lock, lock_flags);
2206 f = list_entry(cam->outqueue.next, struct et61x251_frame_t, frame);
2207 list_del(cam->outqueue.next);
2208 spin_unlock_irqrestore(&cam->queue_lock, lock_flags);
2209
2210 f->state = F_UNUSED;
2211
2212 memcpy(&b, &f->buf, sizeof(b));
2213 if (f->vma_use_count)
2214 b.flags |= V4L2_BUF_FLAG_MAPPED;
2215
2216 if (copy_to_user(arg, &b, sizeof(b)))
2217 return -EFAULT;
2218
2219 PDBGG("Frame #%lu dequeued", (unsigned long)f->buf.index);
2220
2221 return 0;
2222}
2223
2224
2225static int
2226et61x251_vidioc_streamon(struct et61x251_device* cam, void __user * arg)
2227{
2228 int type;
2229
2230 if (copy_from_user(&type, arg, sizeof(type)))
2231 return -EFAULT;
2232
2233 if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE || cam->io != IO_MMAP)
2234 return -EINVAL;
2235
2236 if (list_empty(&cam->inqueue))
2237 return -EINVAL;
2238
2239 cam->stream = STREAM_ON;
2240
2241 DBG(3, "Stream on");
2242
2243 return 0;
2244}
2245
2246
2247static int
2248et61x251_vidioc_streamoff(struct et61x251_device* cam, void __user * arg)
2249{
2250 int type, err;
2251
2252 if (copy_from_user(&type, arg, sizeof(type)))
2253 return -EFAULT;
2254
2255 if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE || cam->io != IO_MMAP)
2256 return -EINVAL;
2257
2258 if (cam->stream == STREAM_ON)
2259 if ((err = et61x251_stream_interrupt(cam)))
2260 return err;
2261
2262 et61x251_empty_framequeues(cam);
2263
2264 DBG(3, "Stream off");
2265
2266 return 0;
2267}
2268
2269
2270static int
2271et61x251_vidioc_g_parm(struct et61x251_device* cam, void __user * arg)
2272{
2273 struct v4l2_streamparm sp;
2274
2275 if (copy_from_user(&sp, arg, sizeof(sp)))
2276 return -EFAULT;
2277
2278 if (sp.type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
2279 return -EINVAL;
2280
2281 sp.parm.capture.extendedmode = 0;
2282 sp.parm.capture.readbuffers = cam->nreadbuffers;
2283
2284 if (copy_to_user(arg, &sp, sizeof(sp)))
2285 return -EFAULT;
2286
2287 return 0;
2288}
2289
2290
2291static int
2292et61x251_vidioc_s_parm(struct et61x251_device* cam, void __user * arg)
2293{
2294 struct v4l2_streamparm sp;
2295
2296 if (copy_from_user(&sp, arg, sizeof(sp)))
2297 return -EFAULT;
2298
2299 if (sp.type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
2300 return -EINVAL;
2301
2302 sp.parm.capture.extendedmode = 0;
2303
2304 if (sp.parm.capture.readbuffers == 0)
2305 sp.parm.capture.readbuffers = cam->nreadbuffers;
2306
2307 if (sp.parm.capture.readbuffers > ET61X251_MAX_FRAMES)
2308 sp.parm.capture.readbuffers = ET61X251_MAX_FRAMES;
2309
2310 if (copy_to_user(arg, &sp, sizeof(sp)))
2311 return -EFAULT;
2312
2313 cam->nreadbuffers = sp.parm.capture.readbuffers;
2314
2315 return 0;
2316}
2317
2318
2319static int et61x251_ioctl_v4l2(struct inode* inode, struct file* filp,
2320 unsigned int cmd, void __user * arg)
2321{
2322 struct et61x251_device* cam = video_get_drvdata(video_devdata(filp));
2323
2324 switch (cmd) {
2325
2326 case VIDIOC_QUERYCAP:
2327 return et61x251_vidioc_querycap(cam, arg);
2328
2329 case VIDIOC_ENUMINPUT:
2330 return et61x251_vidioc_enuminput(cam, arg);
2331
2332 case VIDIOC_G_INPUT:
2333 return et61x251_vidioc_g_input(cam, arg);
2334
2335 case VIDIOC_S_INPUT:
2336 return et61x251_vidioc_s_input(cam, arg);
2337
2338 case VIDIOC_QUERYCTRL:
2339 return et61x251_vidioc_query_ctrl(cam, arg);
2340
2341 case VIDIOC_G_CTRL:
2342 return et61x251_vidioc_g_ctrl(cam, arg);
2343
2344 case VIDIOC_S_CTRL_OLD:
2345 case VIDIOC_S_CTRL:
2346 return et61x251_vidioc_s_ctrl(cam, arg);
2347
2348 case VIDIOC_CROPCAP_OLD:
2349 case VIDIOC_CROPCAP:
2350 return et61x251_vidioc_cropcap(cam, arg);
2351
2352 case VIDIOC_G_CROP:
2353 return et61x251_vidioc_g_crop(cam, arg);
2354
2355 case VIDIOC_S_CROP:
2356 return et61x251_vidioc_s_crop(cam, arg);
2357
2358 case VIDIOC_ENUM_FMT:
2359 return et61x251_vidioc_enum_fmt(cam, arg);
2360
2361 case VIDIOC_G_FMT:
2362 return et61x251_vidioc_g_fmt(cam, arg);
2363
2364 case VIDIOC_TRY_FMT:
2365 case VIDIOC_S_FMT:
2366 return et61x251_vidioc_try_s_fmt(cam, cmd, arg);
2367
2368 case VIDIOC_G_JPEGCOMP:
2369 return et61x251_vidioc_g_jpegcomp(cam, arg);
2370
2371 case VIDIOC_S_JPEGCOMP:
2372 return et61x251_vidioc_s_jpegcomp(cam, arg);
2373
2374 case VIDIOC_REQBUFS:
2375 return et61x251_vidioc_reqbufs(cam, arg);
2376
2377 case VIDIOC_QUERYBUF:
2378 return et61x251_vidioc_querybuf(cam, arg);
2379
2380 case VIDIOC_QBUF:
2381 return et61x251_vidioc_qbuf(cam, arg);
2382
2383 case VIDIOC_DQBUF:
2384 return et61x251_vidioc_dqbuf(cam, filp, arg);
2385
2386 case VIDIOC_STREAMON:
2387 return et61x251_vidioc_streamon(cam, arg);
2388
2389 case VIDIOC_STREAMOFF:
2390 return et61x251_vidioc_streamoff(cam, arg);
2391
2392 case VIDIOC_G_PARM:
2393 return et61x251_vidioc_g_parm(cam, arg);
2394
2395 case VIDIOC_S_PARM_OLD:
2396 case VIDIOC_S_PARM:
2397 return et61x251_vidioc_s_parm(cam, arg);
2398
2399 case VIDIOC_G_STD:
2400 case VIDIOC_S_STD:
2401 case VIDIOC_QUERYSTD:
2402 case VIDIOC_ENUMSTD:
2403 case VIDIOC_QUERYMENU:
2404 return -EINVAL;
2405
2406 default:
2407 return -EINVAL;
2408
2409 }
2410}
2411
2412
2413static int et61x251_ioctl(struct inode* inode, struct file* filp,
2414 unsigned int cmd, unsigned long arg)
2415{
2416 struct et61x251_device* cam = video_get_drvdata(video_devdata(filp));
2417 int err = 0;
2418
2419 if (mutex_lock_interruptible(&cam->fileop_mutex))
2420 return -ERESTARTSYS;
2421
2422 if (cam->state & DEV_DISCONNECTED) {
2423 DBG(1, "Device not present");
2424 mutex_unlock(&cam->fileop_mutex);
2425 return -ENODEV;
2426 }
2427
2428 if (cam->state & DEV_MISCONFIGURED) {
2429 DBG(1, "The camera is misconfigured. Close and open it "
2430 "again.");
2431 mutex_unlock(&cam->fileop_mutex);
2432 return -EIO;
2433 }
2434
2435 V4LDBG(3, "et61x251", cmd);
2436
2437 err = et61x251_ioctl_v4l2(inode, filp, cmd, (void __user *)arg);
2438
2439 mutex_unlock(&cam->fileop_mutex);
2440
2441 return err;
2442}
2443
2444
2445static struct file_operations et61x251_fops = {
2446 .owner = THIS_MODULE,
2447 .open = et61x251_open,
2448 .release = et61x251_release,
2449 .ioctl = et61x251_ioctl,
2450 .read = et61x251_read,
2451 .poll = et61x251_poll,
2452 .mmap = et61x251_mmap,
2453 .llseek = no_llseek,
2454};
2455
2456/*****************************************************************************/
2457
2458/* It exists a single interface only. We do not need to validate anything. */
2459static int
2460et61x251_usb_probe(struct usb_interface* intf, const struct usb_device_id* id)
2461{
2462 struct usb_device *udev = interface_to_usbdev(intf);
2463 struct et61x251_device* cam;
2464 static unsigned int dev_nr = 0;
2465 unsigned int i;
2466 int err = 0;
2467
2468 if (!(cam = kzalloc(sizeof(struct et61x251_device), GFP_KERNEL)))
2469 return -ENOMEM;
2470
2471 cam->usbdev = udev;
2472
2473 if (!(cam->control_buffer = kzalloc(8, GFP_KERNEL))) {
2474 DBG(1, "kmalloc() failed");
2475 err = -ENOMEM;
2476 goto fail;
2477 }
2478
2479 if (!(cam->v4ldev = video_device_alloc())) {
2480 DBG(1, "video_device_alloc() failed");
2481 err = -ENOMEM;
2482 goto fail;
2483 }
2484
2485 mutex_init(&cam->dev_mutex);
2486
2487 DBG(2, "ET61X[12]51 PC Camera Controller detected "
2488 "(vid/pid 0x%04X/0x%04X)",id->idVendor, id->idProduct);
2489
2490 for (i = 0; et61x251_sensor_table[i]; i++) {
2491 err = et61x251_sensor_table[i](cam);
2492 if (!err)
2493 break;
2494 }
2495
2496 if (!err)
2497 DBG(2, "%s image sensor detected", cam->sensor.name);
2498 else {
2499 DBG(1, "No supported image sensor detected");
2500 err = -ENODEV;
2501 goto fail;
2502 }
2503
2504 if (et61x251_init(cam)) {
2505 DBG(1, "Initialization failed. I will retry on open().");
2506 cam->state |= DEV_MISCONFIGURED;
2507 }
2508
2509 strcpy(cam->v4ldev->name, "ET61X[12]51 PC Camera");
2510 cam->v4ldev->owner = THIS_MODULE;
2511 cam->v4ldev->type = VID_TYPE_CAPTURE | VID_TYPE_SCALES;
2512 cam->v4ldev->hardware = 0;
2513 cam->v4ldev->fops = &et61x251_fops;
2514 cam->v4ldev->minor = video_nr[dev_nr];
2515 cam->v4ldev->release = video_device_release;
2516 video_set_drvdata(cam->v4ldev, cam);
2517
2518 mutex_lock(&cam->dev_mutex);
2519
2520 err = video_register_device(cam->v4ldev, VFL_TYPE_GRABBER,
2521 video_nr[dev_nr]);
2522 if (err) {
2523 DBG(1, "V4L2 device registration failed");
2524 if (err == -ENFILE && video_nr[dev_nr] == -1)
2525 DBG(1, "Free /dev/videoX node not found");
2526 video_nr[dev_nr] = -1;
2527 dev_nr = (dev_nr < ET61X251_MAX_DEVICES-1) ? dev_nr+1 : 0;
2528 mutex_unlock(&cam->dev_mutex);
2529 goto fail;
2530 }
2531
2532 DBG(2, "V4L2 device registered as /dev/video%d", cam->v4ldev->minor);
2533
2534 cam->module_param.force_munmap = force_munmap[dev_nr];
2535 cam->module_param.frame_timeout = frame_timeout[dev_nr];
2536
2537 dev_nr = (dev_nr < ET61X251_MAX_DEVICES-1) ? dev_nr+1 : 0;
2538
2539#ifdef CONFIG_VIDEO_ADV_DEBUG
2540 et61x251_create_sysfs(cam);
2541 DBG(2, "Optional device control through 'sysfs' interface ready");
2542#endif
2543
2544 usb_set_intfdata(intf, cam);
2545
2546 mutex_unlock(&cam->dev_mutex);
2547
2548 return 0;
2549
2550fail:
2551 if (cam) {
2552 kfree(cam->control_buffer);
2553 if (cam->v4ldev)
2554 video_device_release(cam->v4ldev);
2555 kfree(cam);
2556 }
2557 return err;
2558}
2559
2560
2561static void et61x251_usb_disconnect(struct usb_interface* intf)
2562{
2563 struct et61x251_device* cam = usb_get_intfdata(intf);
2564
2565 if (!cam)
2566 return;
2567
2568 down_write(&et61x251_disconnect);
2569
2570 mutex_lock(&cam->dev_mutex);
2571
2572 DBG(2, "Disconnecting %s...", cam->v4ldev->name);
2573
2574 wake_up_interruptible_all(&cam->open);
2575
2576 if (cam->users) {
2577 DBG(2, "Device /dev/video%d is open! Deregistration and "
2578 "memory deallocation are deferred on close.",
2579 cam->v4ldev->minor);
2580 cam->state |= DEV_MISCONFIGURED;
2581 et61x251_stop_transfer(cam);
2582 cam->state |= DEV_DISCONNECTED;
2583 wake_up_interruptible(&cam->wait_frame);
2584 wake_up(&cam->wait_stream);
2585 usb_get_dev(cam->usbdev);
2586 } else {
2587 cam->state |= DEV_DISCONNECTED;
2588 et61x251_release_resources(cam);
2589 }
2590
2591 mutex_unlock(&cam->dev_mutex);
2592
2593 if (!cam->users)
2594 kfree(cam);
2595
2596 up_write(&et61x251_disconnect);
2597}
2598
2599
2600static struct usb_driver et61x251_usb_driver = {
2601 .name = "et61x251",
2602 .id_table = et61x251_id_table,
2603 .probe = et61x251_usb_probe,
2604 .disconnect = et61x251_usb_disconnect,
2605};
2606
2607/*****************************************************************************/
2608
2609static int __init et61x251_module_init(void)
2610{
2611 int err = 0;
2612
2613 KDBG(2, ET61X251_MODULE_NAME " v" ET61X251_MODULE_VERSION);
2614 KDBG(3, ET61X251_MODULE_AUTHOR);
2615
2616 if ((err = usb_register(&et61x251_usb_driver)))
2617 KDBG(1, "usb_register() failed");
2618
2619 return err;
2620}
2621
2622
2623static void __exit et61x251_module_exit(void)
2624{
2625 usb_deregister(&et61x251_usb_driver);
2626}
2627
2628
2629module_init(et61x251_module_init);
2630module_exit(et61x251_module_exit);
diff --git a/drivers/media/video/et61x251/et61x251_sensor.h b/drivers/media/video/et61x251/et61x251_sensor.h
new file mode 100644
index 000000000000..56841ae8a207
--- /dev/null
+++ b/drivers/media/video/et61x251/et61x251_sensor.h
@@ -0,0 +1,116 @@
1/***************************************************************************
2 * API for image sensors connected to ET61X[12]51 PC Camera Controllers *
3 * *
4 * Copyright (C) 2006 by Luca Risolia <luca.risolia@studio.unibo.it> *
5 * *
6 * This program is free software; you can redistribute it and/or modify *
7 * it under the terms of the GNU General Public License as published by *
8 * the Free Software Foundation; either version 2 of the License, or *
9 * (at your option) any later version. *
10 * *
11 * This program is distributed in the hope that it will be useful, *
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14 * GNU General Public License for more details. *
15 * *
16 * You should have received a copy of the GNU General Public License *
17 * along with this program; if not, write to the Free Software *
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
19 ***************************************************************************/
20
21#ifndef _ET61X251_SENSOR_H_
22#define _ET61X251_SENSOR_H_
23
24#include <linux/usb.h>
25#include <linux/videodev.h>
26#include <linux/device.h>
27#include <linux/stddef.h>
28#include <linux/errno.h>
29#include <asm/types.h>
30
31struct et61x251_device;
32struct et61x251_sensor;
33
34/*****************************************************************************/
35
36extern int et61x251_probe_tas5130d1b(struct et61x251_device* cam);
37
38#define ET61X251_SENSOR_TABLE \
39/* Weak detections must go at the end of the list */ \
40static int (*et61x251_sensor_table[])(struct et61x251_device*) = { \
41 &et61x251_probe_tas5130d1b, \
42 NULL, \
43};
44
45extern struct et61x251_device*
46et61x251_match_id(struct et61x251_device* cam, const struct usb_device_id *id);
47
48extern void
49et61x251_attach_sensor(struct et61x251_device* cam,
50 struct et61x251_sensor* sensor);
51
52/*****************************************************************************/
53
54extern int et61x251_write_reg(struct et61x251_device*, u8 value, u16 index);
55extern int et61x251_read_reg(struct et61x251_device*, u16 index);
56extern int et61x251_i2c_write(struct et61x251_device*, u8 address, u8 value);
57extern int et61x251_i2c_read(struct et61x251_device*, u8 address);
58extern int et61x251_i2c_try_write(struct et61x251_device*,
59 struct et61x251_sensor*, u8 address,
60 u8 value);
61extern int et61x251_i2c_try_read(struct et61x251_device*,
62 struct et61x251_sensor*, u8 address);
63extern int et61x251_i2c_raw_write(struct et61x251_device*, u8 n, u8 data1,
64 u8 data2, u8 data3, u8 data4, u8 data5,
65 u8 data6, u8 data7, u8 data8, u8 address);
66
67/*****************************************************************************/
68
69enum et61x251_i2c_sysfs_ops {
70 ET61X251_I2C_READ = 0x01,
71 ET61X251_I2C_WRITE = 0x02,
72};
73
74enum et61x251_i2c_interface {
75 ET61X251_I2C_2WIRES,
76 ET61X251_I2C_3WIRES,
77};
78
79/* Repeat start condition when RSTA is high */
80enum et61x251_i2c_rsta {
81 ET61X251_I2C_RSTA_STOP = 0x00, /* stop then start */
82 ET61X251_I2C_RSTA_REPEAT = 0x01, /* repeat start */
83};
84
85#define ET61X251_MAX_CTRLS V4L2_CID_LASTP1-V4L2_CID_BASE+10
86
87struct et61x251_sensor {
88 char name[32];
89
90 enum et61x251_i2c_sysfs_ops sysfs_ops;
91
92 enum et61x251_i2c_interface interface;
93 u8 i2c_slave_id;
94 enum et61x251_i2c_rsta rsta;
95 struct v4l2_rect active_pixel; /* left and top define FVSX and FVSY */
96
97 struct v4l2_queryctrl qctrl[ET61X251_MAX_CTRLS];
98 struct v4l2_cropcap cropcap;
99 struct v4l2_pix_format pix_format;
100
101 int (*init)(struct et61x251_device* cam);
102 int (*get_ctrl)(struct et61x251_device* cam,
103 struct v4l2_control* ctrl);
104 int (*set_ctrl)(struct et61x251_device* cam,
105 const struct v4l2_control* ctrl);
106 int (*set_crop)(struct et61x251_device* cam,
107 const struct v4l2_rect* rect);
108 int (*set_pix_format)(struct et61x251_device* cam,
109 const struct v4l2_pix_format* pix);
110
111 /* Private */
112 struct v4l2_queryctrl _qctrl[ET61X251_MAX_CTRLS];
113 struct v4l2_rect _rect;
114};
115
116#endif /* _ET61X251_SENSOR_H_ */
diff --git a/drivers/media/video/et61x251/et61x251_tas5130d1b.c b/drivers/media/video/et61x251/et61x251_tas5130d1b.c
new file mode 100644
index 000000000000..3998d76a307a
--- /dev/null
+++ b/drivers/media/video/et61x251/et61x251_tas5130d1b.c
@@ -0,0 +1,141 @@
1/***************************************************************************
2 * Plug-in for TAS5130D1B image sensor connected to the ET61X[12]51 *
3 * PC Camera Controllers *
4 * *
5 * Copyright (C) 2006 by Luca Risolia <luca.risolia@studio.unibo.it> *
6 * *
7 * This program is free software; you can redistribute it and/or modify *
8 * it under the terms of the GNU General Public License as published by *
9 * the Free Software Foundation; either version 2 of the License, or *
10 * (at your option) any later version. *
11 * *
12 * This program is distributed in the hope that it will be useful, *
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15 * GNU General Public License for more details. *
16 * *
17 * You should have received a copy of the GNU General Public License *
18 * along with this program; if not, write to the Free Software *
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
20 ***************************************************************************/
21
22#include "et61x251_sensor.h"
23
24
25static int tas5130d1b_init(struct et61x251_device* cam)
26{
27 int err = 0;
28
29 err += et61x251_write_reg(cam, 0x14, 0x01);
30 err += et61x251_write_reg(cam, 0x1b, 0x02);
31 err += et61x251_write_reg(cam, 0x02, 0x12);
32 err += et61x251_write_reg(cam, 0x0e, 0x60);
33 err += et61x251_write_reg(cam, 0x80, 0x61);
34 err += et61x251_write_reg(cam, 0xf0, 0x62);
35 err += et61x251_write_reg(cam, 0x03, 0x63);
36 err += et61x251_write_reg(cam, 0x14, 0x64);
37 err += et61x251_write_reg(cam, 0xf4, 0x65);
38 err += et61x251_write_reg(cam, 0x01, 0x66);
39 err += et61x251_write_reg(cam, 0x05, 0x67);
40 err += et61x251_write_reg(cam, 0x8f, 0x68);
41 err += et61x251_write_reg(cam, 0x0f, 0x8d);
42 err += et61x251_write_reg(cam, 0x08, 0x8e);
43
44 return err;
45}
46
47
48static int tas5130d1b_set_ctrl(struct et61x251_device* cam,
49 const struct v4l2_control* ctrl)
50{
51 int err = 0;
52
53 switch (ctrl->id) {
54 case V4L2_CID_GAIN:
55 err += et61x251_i2c_raw_write(cam, 2, 0x20,
56 0xf6-ctrl->value, 0, 0, 0,
57 0, 0, 0, 0);
58 break;
59 case V4L2_CID_EXPOSURE:
60 err += et61x251_i2c_raw_write(cam, 2, 0x40,
61 0x47-ctrl->value, 0, 0, 0,
62 0, 0, 0, 0);
63 break;
64 default:
65 return -EINVAL;
66 }
67
68 return err ? -EIO : 0;
69}
70
71
72static struct et61x251_sensor tas5130d1b = {
73 .name = "TAS5130D1B",
74 .interface = ET61X251_I2C_3WIRES,
75 .rsta = ET61X251_I2C_RSTA_STOP,
76 .active_pixel = {
77 .left = 106,
78 .top = 13,
79 },
80 .init = &tas5130d1b_init,
81 .qctrl = {
82 {
83 .id = V4L2_CID_GAIN,
84 .type = V4L2_CTRL_TYPE_INTEGER,
85 .name = "global gain",
86 .minimum = 0x00,
87 .maximum = 0xf6,
88 .step = 0x02,
89 .default_value = 0x0d,
90 .flags = 0,
91 },
92 {
93 .id = V4L2_CID_EXPOSURE,
94 .type = V4L2_CTRL_TYPE_INTEGER,
95 .name = "exposure",
96 .minimum = 0x00,
97 .maximum = 0x47,
98 .step = 0x01,
99 .default_value = 0x23,
100 .flags = 0,
101 },
102 },
103 .set_ctrl = &tas5130d1b_set_ctrl,
104 .cropcap = {
105 .bounds = {
106 .left = 0,
107 .top = 0,
108 .width = 640,
109 .height = 480,
110 },
111 .defrect = {
112 .left = 0,
113 .top = 0,
114 .width = 640,
115 .height = 480,
116 },
117 },
118 .pix_format = {
119 .width = 640,
120 .height = 480,
121 .pixelformat = V4L2_PIX_FMT_SBGGR8,
122 .priv = 8,
123 },
124};
125
126
127int et61x251_probe_tas5130d1b(struct et61x251_device* cam)
128{
129 const struct usb_device_id tas5130d1b_id_table[] = {
130 { USB_DEVICE(0x102c, 0x6251), },
131 { }
132 };
133
134 /* Sensor detection is based on USB pid/vid */
135 if (!et61x251_match_id(cam, tas5130d1b_id_table))
136 return -ENODEV;
137
138 et61x251_attach_sensor(cam, &tas5130d1b);
139
140 return 0;
141}
diff --git a/drivers/media/video/ov511.c b/drivers/media/video/ov511.c
new file mode 100644
index 000000000000..da44579d6f29
--- /dev/null
+++ b/drivers/media/video/ov511.c
@@ -0,0 +1,5932 @@
1/*
2 * OmniVision OV511 Camera-to-USB Bridge Driver
3 *
4 * Copyright (c) 1999-2003 Mark W. McClelland
5 * Original decompression code Copyright 1998-2000 OmniVision Technologies
6 * Many improvements by Bret Wallach <bwallac1@san.rr.com>
7 * Color fixes by by Orion Sky Lawlor <olawlor@acm.org> (2/26/2000)
8 * Snapshot code by Kevin Moore
9 * OV7620 fixes by Charl P. Botha <cpbotha@ieee.org>
10 * Changes by Claudio Matsuoka <claudio@conectiva.com>
11 * Original SAA7111A code by Dave Perks <dperks@ibm.net>
12 * URB error messages from pwc driver by Nemosoft
13 * generic_ioctl() code from videodev.c by Gerd Knorr and Alan Cox
14 * Memory management (rvmalloc) code from bttv driver, by Gerd Knorr and others
15 *
16 * Based on the Linux CPiA driver written by Peter Pregler,
17 * Scott J. Bertin and Johannes Erdfelt.
18 *
19 * Please see the file: Documentation/usb/ov511.txt
20 * and the website at: http://alpha.dyndns.org/ov511
21 * for more info.
22 *
23 * This program is free software; you can redistribute it and/or modify it
24 * under the terms of the GNU General Public License as published by the
25 * Free Software Foundation; either version 2 of the License, or (at your
26 * option) any later version.
27 *
28 * This program is distributed in the hope that it will be useful, but
29 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
30 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
31 * for more details.
32 *
33 * You should have received a copy of the GNU General Public License
34 * along with this program; if not, write to the Free Software Foundation,
35 * Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
36 */
37
38#include <linux/config.h>
39#include <linux/module.h>
40#include <linux/init.h>
41#include <linux/vmalloc.h>
42#include <linux/slab.h>
43#include <linux/ctype.h>
44#include <linux/pagemap.h>
45#include <asm/semaphore.h>
46#include <asm/processor.h>
47#include <linux/mm.h>
48#include <linux/device.h>
49
50#if defined (__i386__)
51 #include <asm/cpufeature.h>
52#endif
53
54#include "ov511.h"
55
56/*
57 * Version Information
58 */
59#define DRIVER_VERSION "v1.64 for Linux 2.5"
60#define EMAIL "mark@alpha.dyndns.org"
61#define DRIVER_AUTHOR "Mark McClelland <mark@alpha.dyndns.org> & Bret Wallach \
62 & Orion Sky Lawlor <olawlor@acm.org> & Kevin Moore & Charl P. Botha \
63 <cpbotha@ieee.org> & Claudio Matsuoka <claudio@conectiva.com>"
64#define DRIVER_DESC "ov511 USB Camera Driver"
65
66#define OV511_I2C_RETRIES 3
67#define ENABLE_Y_QUANTABLE 1
68#define ENABLE_UV_QUANTABLE 1
69
70#define OV511_MAX_UNIT_VIDEO 16
71
72/* Pixel count * bytes per YUV420 pixel (1.5) */
73#define MAX_FRAME_SIZE(w, h) ((w) * (h) * 3 / 2)
74
75#define MAX_DATA_SIZE(w, h) (MAX_FRAME_SIZE(w, h) + sizeof(struct timeval))
76
77/* Max size * bytes per YUV420 pixel (1.5) + one extra isoc frame for safety */
78#define MAX_RAW_DATA_SIZE(w, h) ((w) * (h) * 3 / 2 + 1024)
79
80#define FATAL_ERROR(rc) ((rc) < 0 && (rc) != -EPERM)
81
82/**********************************************************************
83 * Module Parameters
84 * (See ov511.txt for detailed descriptions of these)
85 **********************************************************************/
86
87/* These variables (and all static globals) default to zero */
88static int autobright = 1;
89static int autogain = 1;
90static int autoexp = 1;
91static int debug;
92static int snapshot;
93static int cams = 1;
94static int compress;
95static int testpat;
96static int dumppix;
97static int led = 1;
98static int dump_bridge;
99static int dump_sensor;
100static int printph;
101static int phy = 0x1f;
102static int phuv = 0x05;
103static int pvy = 0x06;
104static int pvuv = 0x06;
105static int qhy = 0x14;
106static int qhuv = 0x03;
107static int qvy = 0x04;
108static int qvuv = 0x04;
109static int lightfreq;
110static int bandingfilter;
111static int clockdiv = -1;
112static int packetsize = -1;
113static int framedrop = -1;
114static int fastset;
115static int force_palette;
116static int backlight;
117static int unit_video[OV511_MAX_UNIT_VIDEO];
118static int remove_zeros;
119static int mirror;
120static int ov518_color;
121
122module_param(autobright, int, 0);
123MODULE_PARM_DESC(autobright, "Sensor automatically changes brightness");
124module_param(autogain, int, 0);
125MODULE_PARM_DESC(autogain, "Sensor automatically changes gain");
126module_param(autoexp, int, 0);
127MODULE_PARM_DESC(autoexp, "Sensor automatically changes exposure");
128module_param(debug, int, 0);
129MODULE_PARM_DESC(debug,
130 "Debug level: 0=none, 1=inits, 2=warning, 3=config, 4=functions, 5=max");
131module_param(snapshot, int, 0);
132MODULE_PARM_DESC(snapshot, "Enable snapshot mode");
133module_param(cams, int, 0);
134MODULE_PARM_DESC(cams, "Number of simultaneous cameras");
135module_param(compress, int, 0);
136MODULE_PARM_DESC(compress, "Turn on compression");
137module_param(testpat, int, 0);
138MODULE_PARM_DESC(testpat,
139 "Replace image with vertical bar testpattern (only partially working)");
140module_param(dumppix, int, 0);
141MODULE_PARM_DESC(dumppix, "Dump raw pixel data");
142module_param(led, int, 0);
143MODULE_PARM_DESC(led,
144 "LED policy (OV511+ or later). 0=off, 1=on (default), 2=auto (on when open)");
145module_param(dump_bridge, int, 0);
146MODULE_PARM_DESC(dump_bridge, "Dump the bridge registers");
147module_param(dump_sensor, int, 0);
148MODULE_PARM_DESC(dump_sensor, "Dump the sensor registers");
149module_param(printph, int, 0);
150MODULE_PARM_DESC(printph, "Print frame start/end headers");
151module_param(phy, int, 0);
152MODULE_PARM_DESC(phy, "Prediction range (horiz. Y)");
153module_param(phuv, int, 0);
154MODULE_PARM_DESC(phuv, "Prediction range (horiz. UV)");
155module_param(pvy, int, 0);
156MODULE_PARM_DESC(pvy, "Prediction range (vert. Y)");
157module_param(pvuv, int, 0);
158MODULE_PARM_DESC(pvuv, "Prediction range (vert. UV)");
159module_param(qhy, int, 0);
160MODULE_PARM_DESC(qhy, "Quantization threshold (horiz. Y)");
161module_param(qhuv, int, 0);
162MODULE_PARM_DESC(qhuv, "Quantization threshold (horiz. UV)");
163module_param(qvy, int, 0);
164MODULE_PARM_DESC(qvy, "Quantization threshold (vert. Y)");
165module_param(qvuv, int, 0);
166MODULE_PARM_DESC(qvuv, "Quantization threshold (vert. UV)");
167module_param(lightfreq, int, 0);
168MODULE_PARM_DESC(lightfreq,
169 "Light frequency. Set to 50 or 60 Hz, or zero for default settings");
170module_param(bandingfilter, int, 0);
171MODULE_PARM_DESC(bandingfilter,
172 "Enable banding filter (to reduce effects of fluorescent lighting)");
173module_param(clockdiv, int, 0);
174MODULE_PARM_DESC(clockdiv, "Force pixel clock divisor to a specific value");
175module_param(packetsize, int, 0);
176MODULE_PARM_DESC(packetsize, "Force a specific isoc packet size");
177module_param(framedrop, int, 0);
178MODULE_PARM_DESC(framedrop, "Force a specific frame drop register setting");
179module_param(fastset, int, 0);
180MODULE_PARM_DESC(fastset, "Allows picture settings to take effect immediately");
181module_param(force_palette, int, 0);
182MODULE_PARM_DESC(force_palette, "Force the palette to a specific value");
183module_param(backlight, int, 0);
184MODULE_PARM_DESC(backlight, "For objects that are lit from behind");
185static int num_uv;
186module_param_array(unit_video, int, &num_uv, 0);
187MODULE_PARM_DESC(unit_video,
188 "Force use of specific minor number(s). 0 is not allowed.");
189module_param(remove_zeros, int, 0);
190MODULE_PARM_DESC(remove_zeros,
191 "Remove zero-padding from uncompressed incoming data");
192module_param(mirror, int, 0);
193MODULE_PARM_DESC(mirror, "Reverse image horizontally");
194module_param(ov518_color, int, 0);
195MODULE_PARM_DESC(ov518_color, "Enable OV518 color (experimental)");
196
197MODULE_AUTHOR(DRIVER_AUTHOR);
198MODULE_DESCRIPTION(DRIVER_DESC);
199MODULE_LICENSE("GPL");
200
201/**********************************************************************
202 * Miscellaneous Globals
203 **********************************************************************/
204
205static struct usb_driver ov511_driver;
206
207/* Number of times to retry a failed I2C transaction. Increase this if you
208 * are getting "Failed to read sensor ID..." */
209static const int i2c_detect_tries = 5;
210
211static struct usb_device_id device_table [] = {
212 { USB_DEVICE(VEND_OMNIVISION, PROD_OV511) },
213 { USB_DEVICE(VEND_OMNIVISION, PROD_OV511PLUS) },
214 { USB_DEVICE(VEND_OMNIVISION, PROD_OV518) },
215 { USB_DEVICE(VEND_OMNIVISION, PROD_OV518PLUS) },
216 { USB_DEVICE(VEND_MATTEL, PROD_ME2CAM) },
217 { } /* Terminating entry */
218};
219
220MODULE_DEVICE_TABLE (usb, device_table);
221
222static unsigned char yQuanTable511[] = OV511_YQUANTABLE;
223static unsigned char uvQuanTable511[] = OV511_UVQUANTABLE;
224static unsigned char yQuanTable518[] = OV518_YQUANTABLE;
225static unsigned char uvQuanTable518[] = OV518_UVQUANTABLE;
226
227/**********************************************************************
228 * Symbolic Names
229 **********************************************************************/
230
231/* Known OV511-based cameras */
232static struct symbolic_list camlist[] = {
233 { 0, "Generic Camera (no ID)" },
234 { 1, "Mustek WCam 3X" },
235 { 3, "D-Link DSB-C300" },
236 { 4, "Generic OV511/OV7610" },
237 { 5, "Puretek PT-6007" },
238 { 6, "Lifeview USB Life TV (NTSC)" },
239 { 21, "Creative Labs WebCam 3" },
240 { 22, "Lifeview USB Life TV (PAL D/K+B/G)" },
241 { 36, "Koala-Cam" },
242 { 38, "Lifeview USB Life TV (PAL)" },
243 { 41, "Samsung Anycam MPC-M10" },
244 { 43, "Mtekvision Zeca MV402" },
245 { 46, "Suma eON" },
246 { 70, "Lifeview USB Life TV (PAL/SECAM)" },
247 { 100, "Lifeview RoboCam" },
248 { 102, "AverMedia InterCam Elite" },
249 { 112, "MediaForte MV300" }, /* or OV7110 evaluation kit */
250 { 134, "Ezonics EZCam II" },
251 { 192, "Webeye 2000B" },
252 { 253, "Alpha Vision Tech. AlphaCam SE" },
253 { -1, NULL }
254};
255
256/* Video4Linux1 Palettes */
257static struct symbolic_list v4l1_plist[] = {
258 { VIDEO_PALETTE_GREY, "GREY" },
259 { VIDEO_PALETTE_HI240, "HI240" },
260 { VIDEO_PALETTE_RGB565, "RGB565" },
261 { VIDEO_PALETTE_RGB24, "RGB24" },
262 { VIDEO_PALETTE_RGB32, "RGB32" },
263 { VIDEO_PALETTE_RGB555, "RGB555" },
264 { VIDEO_PALETTE_YUV422, "YUV422" },
265 { VIDEO_PALETTE_YUYV, "YUYV" },
266 { VIDEO_PALETTE_UYVY, "UYVY" },
267 { VIDEO_PALETTE_YUV420, "YUV420" },
268 { VIDEO_PALETTE_YUV411, "YUV411" },
269 { VIDEO_PALETTE_RAW, "RAW" },
270 { VIDEO_PALETTE_YUV422P,"YUV422P" },
271 { VIDEO_PALETTE_YUV411P,"YUV411P" },
272 { VIDEO_PALETTE_YUV420P,"YUV420P" },
273 { VIDEO_PALETTE_YUV410P,"YUV410P" },
274 { -1, NULL }
275};
276
277static struct symbolic_list brglist[] = {
278 { BRG_OV511, "OV511" },
279 { BRG_OV511PLUS, "OV511+" },
280 { BRG_OV518, "OV518" },
281 { BRG_OV518PLUS, "OV518+" },
282 { -1, NULL }
283};
284
285static struct symbolic_list senlist[] = {
286 { SEN_OV76BE, "OV76BE" },
287 { SEN_OV7610, "OV7610" },
288 { SEN_OV7620, "OV7620" },
289 { SEN_OV7620AE, "OV7620AE" },
290 { SEN_OV6620, "OV6620" },
291 { SEN_OV6630, "OV6630" },
292 { SEN_OV6630AE, "OV6630AE" },
293 { SEN_OV6630AF, "OV6630AF" },
294 { SEN_OV8600, "OV8600" },
295 { SEN_KS0127, "KS0127" },
296 { SEN_KS0127B, "KS0127B" },
297 { SEN_SAA7111A, "SAA7111A" },
298 { -1, NULL }
299};
300
301/* URB error codes: */
302static struct symbolic_list urb_errlist[] = {
303 { -ENOSR, "Buffer error (overrun)" },
304 { -EPIPE, "Stalled (device not responding)" },
305 { -EOVERFLOW, "Babble (bad cable?)" },
306 { -EPROTO, "Bit-stuff error (bad cable?)" },
307 { -EILSEQ, "CRC/Timeout" },
308 { -ETIMEDOUT, "NAK (device does not respond)" },
309 { -1, NULL }
310};
311
312/**********************************************************************
313 * Memory management
314 **********************************************************************/
315static void *
316rvmalloc(unsigned long size)
317{
318 void *mem;
319 unsigned long adr;
320
321 size = PAGE_ALIGN(size);
322 mem = vmalloc_32(size);
323 if (!mem)
324 return NULL;
325
326 memset(mem, 0, size); /* Clear the ram out, no junk to the user */
327 adr = (unsigned long) mem;
328 while (size > 0) {
329 SetPageReserved(vmalloc_to_page((void *)adr));
330 adr += PAGE_SIZE;
331 size -= PAGE_SIZE;
332 }
333
334 return mem;
335}
336
337static void
338rvfree(void *mem, unsigned long size)
339{
340 unsigned long adr;
341
342 if (!mem)
343 return;
344
345 adr = (unsigned long) mem;
346 while ((long) size > 0) {
347 ClearPageReserved(vmalloc_to_page((void *)adr));
348 adr += PAGE_SIZE;
349 size -= PAGE_SIZE;
350 }
351 vfree(mem);
352}
353
354/**********************************************************************
355 *
356 * Register I/O
357 *
358 **********************************************************************/
359
360/* Write an OV51x register */
361static int
362reg_w(struct usb_ov511 *ov, unsigned char reg, unsigned char value)
363{
364 int rc;
365
366 PDEBUG(5, "0x%02X:0x%02X", reg, value);
367
368 mutex_lock(&ov->cbuf_lock);
369 ov->cbuf[0] = value;
370 rc = usb_control_msg(ov->dev,
371 usb_sndctrlpipe(ov->dev, 0),
372 (ov->bclass == BCL_OV518)?1:2 /* REG_IO */,
373 USB_TYPE_VENDOR | USB_RECIP_DEVICE,
374 0, (__u16)reg, &ov->cbuf[0], 1, 1000);
375 mutex_unlock(&ov->cbuf_lock);
376
377 if (rc < 0)
378 err("reg write: error %d: %s", rc, symbolic(urb_errlist, rc));
379
380 return rc;
381}
382
383/* Read from an OV51x register */
384/* returns: negative is error, pos or zero is data */
385static int
386reg_r(struct usb_ov511 *ov, unsigned char reg)
387{
388 int rc;
389
390 mutex_lock(&ov->cbuf_lock);
391 rc = usb_control_msg(ov->dev,
392 usb_rcvctrlpipe(ov->dev, 0),
393 (ov->bclass == BCL_OV518)?1:3 /* REG_IO */,
394 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
395 0, (__u16)reg, &ov->cbuf[0], 1, 1000);
396
397 if (rc < 0) {
398 err("reg read: error %d: %s", rc, symbolic(urb_errlist, rc));
399 } else {
400 rc = ov->cbuf[0];
401 PDEBUG(5, "0x%02X:0x%02X", reg, ov->cbuf[0]);
402 }
403
404 mutex_unlock(&ov->cbuf_lock);
405
406 return rc;
407}
408
409/*
410 * Writes bits at positions specified by mask to an OV51x reg. Bits that are in
411 * the same position as 1's in "mask" are cleared and set to "value". Bits
412 * that are in the same position as 0's in "mask" are preserved, regardless
413 * of their respective state in "value".
414 */
415static int
416reg_w_mask(struct usb_ov511 *ov,
417 unsigned char reg,
418 unsigned char value,
419 unsigned char mask)
420{
421 int ret;
422 unsigned char oldval, newval;
423
424 ret = reg_r(ov, reg);
425 if (ret < 0)
426 return ret;
427
428 oldval = (unsigned char) ret;
429 oldval &= (~mask); /* Clear the masked bits */
430 value &= mask; /* Enforce mask on value */
431 newval = oldval | value; /* Set the desired bits */
432
433 return (reg_w(ov, reg, newval));
434}
435
436/*
437 * Writes multiple (n) byte value to a single register. Only valid with certain
438 * registers (0x30 and 0xc4 - 0xce).
439 */
440static int
441ov518_reg_w32(struct usb_ov511 *ov, unsigned char reg, u32 val, int n)
442{
443 int rc;
444
445 PDEBUG(5, "0x%02X:%7d, n=%d", reg, val, n);
446
447 mutex_lock(&ov->cbuf_lock);
448
449 *((__le32 *)ov->cbuf) = __cpu_to_le32(val);
450
451 rc = usb_control_msg(ov->dev,
452 usb_sndctrlpipe(ov->dev, 0),
453 1 /* REG_IO */,
454 USB_TYPE_VENDOR | USB_RECIP_DEVICE,
455 0, (__u16)reg, ov->cbuf, n, 1000);
456 mutex_unlock(&ov->cbuf_lock);
457
458 if (rc < 0)
459 err("reg write multiple: error %d: %s", rc,
460 symbolic(urb_errlist, rc));
461
462 return rc;
463}
464
465static int
466ov511_upload_quan_tables(struct usb_ov511 *ov)
467{
468 unsigned char *pYTable = yQuanTable511;
469 unsigned char *pUVTable = uvQuanTable511;
470 unsigned char val0, val1;
471 int i, rc, reg = R511_COMP_LUT_BEGIN;
472
473 PDEBUG(4, "Uploading quantization tables");
474
475 for (i = 0; i < OV511_QUANTABLESIZE / 2; i++) {
476 if (ENABLE_Y_QUANTABLE) {
477 val0 = *pYTable++;
478 val1 = *pYTable++;
479 val0 &= 0x0f;
480 val1 &= 0x0f;
481 val0 |= val1 << 4;
482 rc = reg_w(ov, reg, val0);
483 if (rc < 0)
484 return rc;
485 }
486
487 if (ENABLE_UV_QUANTABLE) {
488 val0 = *pUVTable++;
489 val1 = *pUVTable++;
490 val0 &= 0x0f;
491 val1 &= 0x0f;
492 val0 |= val1 << 4;
493 rc = reg_w(ov, reg + OV511_QUANTABLESIZE/2, val0);
494 if (rc < 0)
495 return rc;
496 }
497
498 reg++;
499 }
500
501 return 0;
502}
503
504/* OV518 quantization tables are 8x4 (instead of 8x8) */
505static int
506ov518_upload_quan_tables(struct usb_ov511 *ov)
507{
508 unsigned char *pYTable = yQuanTable518;
509 unsigned char *pUVTable = uvQuanTable518;
510 unsigned char val0, val1;
511 int i, rc, reg = R511_COMP_LUT_BEGIN;
512
513 PDEBUG(4, "Uploading quantization tables");
514
515 for (i = 0; i < OV518_QUANTABLESIZE / 2; i++) {
516 if (ENABLE_Y_QUANTABLE) {
517 val0 = *pYTable++;
518 val1 = *pYTable++;
519 val0 &= 0x0f;
520 val1 &= 0x0f;
521 val0 |= val1 << 4;
522 rc = reg_w(ov, reg, val0);
523 if (rc < 0)
524 return rc;
525 }
526
527 if (ENABLE_UV_QUANTABLE) {
528 val0 = *pUVTable++;
529 val1 = *pUVTable++;
530 val0 &= 0x0f;
531 val1 &= 0x0f;
532 val0 |= val1 << 4;
533 rc = reg_w(ov, reg + OV518_QUANTABLESIZE/2, val0);
534 if (rc < 0)
535 return rc;
536 }
537
538 reg++;
539 }
540
541 return 0;
542}
543
544static int
545ov51x_reset(struct usb_ov511 *ov, unsigned char reset_type)
546{
547 int rc;
548
549 /* Setting bit 0 not allowed on 518/518Plus */
550 if (ov->bclass == BCL_OV518)
551 reset_type &= 0xfe;
552
553 PDEBUG(4, "Reset: type=0x%02X", reset_type);
554
555 rc = reg_w(ov, R51x_SYS_RESET, reset_type);
556 rc = reg_w(ov, R51x_SYS_RESET, 0);
557
558 if (rc < 0)
559 err("reset: command failed");
560
561 return rc;
562}
563
564/**********************************************************************
565 *
566 * Low-level I2C I/O functions
567 *
568 **********************************************************************/
569
570/* NOTE: Do not call this function directly!
571 * The OV518 I2C I/O procedure is different, hence, this function.
572 * This is normally only called from i2c_w(). Note that this function
573 * always succeeds regardless of whether the sensor is present and working.
574 */
575static int
576ov518_i2c_write_internal(struct usb_ov511 *ov,
577 unsigned char reg,
578 unsigned char value)
579{
580 int rc;
581
582 PDEBUG(5, "0x%02X:0x%02X", reg, value);
583
584 /* Select camera register */
585 rc = reg_w(ov, R51x_I2C_SADDR_3, reg);
586 if (rc < 0)
587 return rc;
588
589 /* Write "value" to I2C data port of OV511 */
590 rc = reg_w(ov, R51x_I2C_DATA, value);
591 if (rc < 0)
592 return rc;
593
594 /* Initiate 3-byte write cycle */
595 rc = reg_w(ov, R518_I2C_CTL, 0x01);
596 if (rc < 0)
597 return rc;
598
599 return 0;
600}
601
602/* NOTE: Do not call this function directly! */
603static int
604ov511_i2c_write_internal(struct usb_ov511 *ov,
605 unsigned char reg,
606 unsigned char value)
607{
608 int rc, retries;
609
610 PDEBUG(5, "0x%02X:0x%02X", reg, value);
611
612 /* Three byte write cycle */
613 for (retries = OV511_I2C_RETRIES; ; ) {
614 /* Select camera register */
615 rc = reg_w(ov, R51x_I2C_SADDR_3, reg);
616 if (rc < 0)
617 break;
618
619 /* Write "value" to I2C data port of OV511 */
620 rc = reg_w(ov, R51x_I2C_DATA, value);
621 if (rc < 0)
622 break;
623
624 /* Initiate 3-byte write cycle */
625 rc = reg_w(ov, R511_I2C_CTL, 0x01);
626 if (rc < 0)
627 break;
628
629 /* Retry until idle */
630 do
631 rc = reg_r(ov, R511_I2C_CTL);
632 while (rc > 0 && ((rc&1) == 0));
633 if (rc < 0)
634 break;
635
636 /* Ack? */
637 if ((rc&2) == 0) {
638 rc = 0;
639 break;
640 }
641#if 0
642 /* I2C abort */
643 reg_w(ov, R511_I2C_CTL, 0x10);
644#endif
645 if (--retries < 0) {
646 err("i2c write retries exhausted");
647 rc = -1;
648 break;
649 }
650 }
651
652 return rc;
653}
654
655/* NOTE: Do not call this function directly!
656 * The OV518 I2C I/O procedure is different, hence, this function.
657 * This is normally only called from i2c_r(). Note that this function
658 * always succeeds regardless of whether the sensor is present and working.
659 */
660static int
661ov518_i2c_read_internal(struct usb_ov511 *ov, unsigned char reg)
662{
663 int rc, value;
664
665 /* Select camera register */
666 rc = reg_w(ov, R51x_I2C_SADDR_2, reg);
667 if (rc < 0)
668 return rc;
669
670 /* Initiate 2-byte write cycle */
671 rc = reg_w(ov, R518_I2C_CTL, 0x03);
672 if (rc < 0)
673 return rc;
674
675 /* Initiate 2-byte read cycle */
676 rc = reg_w(ov, R518_I2C_CTL, 0x05);
677 if (rc < 0)
678 return rc;
679
680 value = reg_r(ov, R51x_I2C_DATA);
681
682 PDEBUG(5, "0x%02X:0x%02X", reg, value);
683
684 return value;
685}
686
687/* NOTE: Do not call this function directly!
688 * returns: negative is error, pos or zero is data */
689static int
690ov511_i2c_read_internal(struct usb_ov511 *ov, unsigned char reg)
691{
692 int rc, value, retries;
693
694 /* Two byte write cycle */
695 for (retries = OV511_I2C_RETRIES; ; ) {
696 /* Select camera register */
697 rc = reg_w(ov, R51x_I2C_SADDR_2, reg);
698 if (rc < 0)
699 return rc;
700
701 /* Initiate 2-byte write cycle */
702 rc = reg_w(ov, R511_I2C_CTL, 0x03);
703 if (rc < 0)
704 return rc;
705
706 /* Retry until idle */
707 do
708 rc = reg_r(ov, R511_I2C_CTL);
709 while (rc > 0 && ((rc&1) == 0));
710 if (rc < 0)
711 return rc;
712
713 if ((rc&2) == 0) /* Ack? */
714 break;
715
716 /* I2C abort */
717 reg_w(ov, R511_I2C_CTL, 0x10);
718
719 if (--retries < 0) {
720 err("i2c write retries exhausted");
721 return -1;
722 }
723 }
724
725 /* Two byte read cycle */
726 for (retries = OV511_I2C_RETRIES; ; ) {
727 /* Initiate 2-byte read cycle */
728 rc = reg_w(ov, R511_I2C_CTL, 0x05);
729 if (rc < 0)
730 return rc;
731
732 /* Retry until idle */
733 do
734 rc = reg_r(ov, R511_I2C_CTL);
735 while (rc > 0 && ((rc&1) == 0));
736 if (rc < 0)
737 return rc;
738
739 if ((rc&2) == 0) /* Ack? */
740 break;
741
742 /* I2C abort */
743 rc = reg_w(ov, R511_I2C_CTL, 0x10);
744 if (rc < 0)
745 return rc;
746
747 if (--retries < 0) {
748 err("i2c read retries exhausted");
749 return -1;
750 }
751 }
752
753 value = reg_r(ov, R51x_I2C_DATA);
754
755 PDEBUG(5, "0x%02X:0x%02X", reg, value);
756
757 /* This is needed to make i2c_w() work */
758 rc = reg_w(ov, R511_I2C_CTL, 0x05);
759 if (rc < 0)
760 return rc;
761
762 return value;
763}
764
765/* returns: negative is error, pos or zero is data */
766static int
767i2c_r(struct usb_ov511 *ov, unsigned char reg)
768{
769 int rc;
770
771 mutex_lock(&ov->i2c_lock);
772
773 if (ov->bclass == BCL_OV518)
774 rc = ov518_i2c_read_internal(ov, reg);
775 else
776 rc = ov511_i2c_read_internal(ov, reg);
777
778 mutex_unlock(&ov->i2c_lock);
779
780 return rc;
781}
782
783static int
784i2c_w(struct usb_ov511 *ov, unsigned char reg, unsigned char value)
785{
786 int rc;
787
788 mutex_lock(&ov->i2c_lock);
789
790 if (ov->bclass == BCL_OV518)
791 rc = ov518_i2c_write_internal(ov, reg, value);
792 else
793 rc = ov511_i2c_write_internal(ov, reg, value);
794
795 mutex_unlock(&ov->i2c_lock);
796
797 return rc;
798}
799
800/* Do not call this function directly! */
801static int
802ov51x_i2c_write_mask_internal(struct usb_ov511 *ov,
803 unsigned char reg,
804 unsigned char value,
805 unsigned char mask)
806{
807 int rc;
808 unsigned char oldval, newval;
809
810 if (mask == 0xff) {
811 newval = value;
812 } else {
813 if (ov->bclass == BCL_OV518)
814 rc = ov518_i2c_read_internal(ov, reg);
815 else
816 rc = ov511_i2c_read_internal(ov, reg);
817 if (rc < 0)
818 return rc;
819
820 oldval = (unsigned char) rc;
821 oldval &= (~mask); /* Clear the masked bits */
822 value &= mask; /* Enforce mask on value */
823 newval = oldval | value; /* Set the desired bits */
824 }
825
826 if (ov->bclass == BCL_OV518)
827 return (ov518_i2c_write_internal(ov, reg, newval));
828 else
829 return (ov511_i2c_write_internal(ov, reg, newval));
830}
831
832/* Writes bits at positions specified by mask to an I2C reg. Bits that are in
833 * the same position as 1's in "mask" are cleared and set to "value". Bits
834 * that are in the same position as 0's in "mask" are preserved, regardless
835 * of their respective state in "value".
836 */
837static int
838i2c_w_mask(struct usb_ov511 *ov,
839 unsigned char reg,
840 unsigned char value,
841 unsigned char mask)
842{
843 int rc;
844
845 mutex_lock(&ov->i2c_lock);
846 rc = ov51x_i2c_write_mask_internal(ov, reg, value, mask);
847 mutex_unlock(&ov->i2c_lock);
848
849 return rc;
850}
851
852/* Set the read and write slave IDs. The "slave" argument is the write slave,
853 * and the read slave will be set to (slave + 1). ov->i2c_lock should be held
854 * when calling this. This should not be called from outside the i2c I/O
855 * functions.
856 */
857static int
858i2c_set_slave_internal(struct usb_ov511 *ov, unsigned char slave)
859{
860 int rc;
861
862 rc = reg_w(ov, R51x_I2C_W_SID, slave);
863 if (rc < 0)
864 return rc;
865
866 rc = reg_w(ov, R51x_I2C_R_SID, slave + 1);
867 if (rc < 0)
868 return rc;
869
870 return 0;
871}
872
873/* Write to a specific I2C slave ID and register, using the specified mask */
874static int
875i2c_w_slave(struct usb_ov511 *ov,
876 unsigned char slave,
877 unsigned char reg,
878 unsigned char value,
879 unsigned char mask)
880{
881 int rc = 0;
882
883 mutex_lock(&ov->i2c_lock);
884
885 /* Set new slave IDs */
886 rc = i2c_set_slave_internal(ov, slave);
887 if (rc < 0)
888 goto out;
889
890 rc = ov51x_i2c_write_mask_internal(ov, reg, value, mask);
891
892out:
893 /* Restore primary IDs */
894 if (i2c_set_slave_internal(ov, ov->primary_i2c_slave) < 0)
895 err("Couldn't restore primary I2C slave");
896
897 mutex_unlock(&ov->i2c_lock);
898 return rc;
899}
900
901/* Read from a specific I2C slave ID and register */
902static int
903i2c_r_slave(struct usb_ov511 *ov,
904 unsigned char slave,
905 unsigned char reg)
906{
907 int rc;
908
909 mutex_lock(&ov->i2c_lock);
910
911 /* Set new slave IDs */
912 rc = i2c_set_slave_internal(ov, slave);
913 if (rc < 0)
914 goto out;
915
916 if (ov->bclass == BCL_OV518)
917 rc = ov518_i2c_read_internal(ov, reg);
918 else
919 rc = ov511_i2c_read_internal(ov, reg);
920
921out:
922 /* Restore primary IDs */
923 if (i2c_set_slave_internal(ov, ov->primary_i2c_slave) < 0)
924 err("Couldn't restore primary I2C slave");
925
926 mutex_unlock(&ov->i2c_lock);
927 return rc;
928}
929
930/* Sets I2C read and write slave IDs. Returns <0 for error */
931static int
932ov51x_set_slave_ids(struct usb_ov511 *ov, unsigned char sid)
933{
934 int rc;
935
936 mutex_lock(&ov->i2c_lock);
937
938 rc = i2c_set_slave_internal(ov, sid);
939 if (rc < 0)
940 goto out;
941
942 // FIXME: Is this actually necessary?
943 rc = ov51x_reset(ov, OV511_RESET_NOREGS);
944out:
945 mutex_unlock(&ov->i2c_lock);
946 return rc;
947}
948
949static int
950write_regvals(struct usb_ov511 *ov, struct ov511_regvals * pRegvals)
951{
952 int rc;
953
954 while (pRegvals->bus != OV511_DONE_BUS) {
955 if (pRegvals->bus == OV511_REG_BUS) {
956 if ((rc = reg_w(ov, pRegvals->reg, pRegvals->val)) < 0)
957 return rc;
958 } else if (pRegvals->bus == OV511_I2C_BUS) {
959 if ((rc = i2c_w(ov, pRegvals->reg, pRegvals->val)) < 0)
960 return rc;
961 } else {
962 err("Bad regval array");
963 return -1;
964 }
965 pRegvals++;
966 }
967 return 0;
968}
969
970#ifdef OV511_DEBUG
971static void
972dump_i2c_range(struct usb_ov511 *ov, int reg1, int regn)
973{
974 int i, rc;
975
976 for (i = reg1; i <= regn; i++) {
977 rc = i2c_r(ov, i);
978 info("Sensor[0x%02X] = 0x%02X", i, rc);
979 }
980}
981
982static void
983dump_i2c_regs(struct usb_ov511 *ov)
984{
985 info("I2C REGS");
986 dump_i2c_range(ov, 0x00, 0x7C);
987}
988
989static void
990dump_reg_range(struct usb_ov511 *ov, int reg1, int regn)
991{
992 int i, rc;
993
994 for (i = reg1; i <= regn; i++) {
995 rc = reg_r(ov, i);
996 info("OV511[0x%02X] = 0x%02X", i, rc);
997 }
998}
999
1000static void
1001ov511_dump_regs(struct usb_ov511 *ov)
1002{
1003 info("CAMERA INTERFACE REGS");
1004 dump_reg_range(ov, 0x10, 0x1f);
1005 info("DRAM INTERFACE REGS");
1006 dump_reg_range(ov, 0x20, 0x23);
1007 info("ISO FIFO REGS");
1008 dump_reg_range(ov, 0x30, 0x31);
1009 info("PIO REGS");
1010 dump_reg_range(ov, 0x38, 0x39);
1011 dump_reg_range(ov, 0x3e, 0x3e);
1012 info("I2C REGS");
1013 dump_reg_range(ov, 0x40, 0x49);
1014 info("SYSTEM CONTROL REGS");
1015 dump_reg_range(ov, 0x50, 0x55);
1016 dump_reg_range(ov, 0x5e, 0x5f);
1017 info("OmniCE REGS");
1018 dump_reg_range(ov, 0x70, 0x79);
1019 /* NOTE: Quantization tables are not readable. You will get the value
1020 * in reg. 0x79 for every table register */
1021 dump_reg_range(ov, 0x80, 0x9f);
1022 dump_reg_range(ov, 0xa0, 0xbf);
1023
1024}
1025
1026static void
1027ov518_dump_regs(struct usb_ov511 *ov)
1028{
1029 info("VIDEO MODE REGS");
1030 dump_reg_range(ov, 0x20, 0x2f);
1031 info("DATA PUMP AND SNAPSHOT REGS");
1032 dump_reg_range(ov, 0x30, 0x3f);
1033 info("I2C REGS");
1034 dump_reg_range(ov, 0x40, 0x4f);
1035 info("SYSTEM CONTROL AND VENDOR REGS");
1036 dump_reg_range(ov, 0x50, 0x5f);
1037 info("60 - 6F");
1038 dump_reg_range(ov, 0x60, 0x6f);
1039 info("70 - 7F");
1040 dump_reg_range(ov, 0x70, 0x7f);
1041 info("Y QUANTIZATION TABLE");
1042 dump_reg_range(ov, 0x80, 0x8f);
1043 info("UV QUANTIZATION TABLE");
1044 dump_reg_range(ov, 0x90, 0x9f);
1045 info("A0 - BF");
1046 dump_reg_range(ov, 0xa0, 0xbf);
1047 info("CBR");
1048 dump_reg_range(ov, 0xc0, 0xcf);
1049}
1050#endif
1051
1052/*****************************************************************************/
1053
1054/* Temporarily stops OV511 from functioning. Must do this before changing
1055 * registers while the camera is streaming */
1056static inline int
1057ov51x_stop(struct usb_ov511 *ov)
1058{
1059 PDEBUG(4, "stopping");
1060 ov->stopped = 1;
1061 if (ov->bclass == BCL_OV518)
1062 return (reg_w_mask(ov, R51x_SYS_RESET, 0x3a, 0x3a));
1063 else
1064 return (reg_w(ov, R51x_SYS_RESET, 0x3d));
1065}
1066
1067/* Restarts OV511 after ov511_stop() is called. Has no effect if it is not
1068 * actually stopped (for performance). */
1069static inline int
1070ov51x_restart(struct usb_ov511 *ov)
1071{
1072 if (ov->stopped) {
1073 PDEBUG(4, "restarting");
1074 ov->stopped = 0;
1075
1076 /* Reinitialize the stream */
1077 if (ov->bclass == BCL_OV518)
1078 reg_w(ov, 0x2f, 0x80);
1079
1080 return (reg_w(ov, R51x_SYS_RESET, 0x00));
1081 }
1082
1083 return 0;
1084}
1085
1086/* Sleeps until no frames are active. Returns !0 if got signal */
1087static int
1088ov51x_wait_frames_inactive(struct usb_ov511 *ov)
1089{
1090 return wait_event_interruptible(ov->wq, ov->curframe < 0);
1091}
1092
1093/* Resets the hardware snapshot button */
1094static void
1095ov51x_clear_snapshot(struct usb_ov511 *ov)
1096{
1097 if (ov->bclass == BCL_OV511) {
1098 reg_w(ov, R51x_SYS_SNAP, 0x00);
1099 reg_w(ov, R51x_SYS_SNAP, 0x02);
1100 reg_w(ov, R51x_SYS_SNAP, 0x00);
1101 } else if (ov->bclass == BCL_OV518) {
1102 warn("snapshot reset not supported yet on OV518(+)");
1103 } else {
1104 err("clear snap: invalid bridge type");
1105 }
1106}
1107
1108#if 0
1109/* Checks the status of the snapshot button. Returns 1 if it was pressed since
1110 * it was last cleared, and zero in all other cases (including errors) */
1111static int
1112ov51x_check_snapshot(struct usb_ov511 *ov)
1113{
1114 int ret, status = 0;
1115
1116 if (ov->bclass == BCL_OV511) {
1117 ret = reg_r(ov, R51x_SYS_SNAP);
1118 if (ret < 0) {
1119 err("Error checking snspshot status (%d)", ret);
1120 } else if (ret & 0x08) {
1121 status = 1;
1122 }
1123 } else if (ov->bclass == BCL_OV518) {
1124 warn("snapshot check not supported yet on OV518(+)");
1125 } else {
1126 err("check snap: invalid bridge type");
1127 }
1128
1129 return status;
1130}
1131#endif
1132
1133/* This does an initial reset of an OmniVision sensor and ensures that I2C
1134 * is synchronized. Returns <0 for failure.
1135 */
1136static int
1137init_ov_sensor(struct usb_ov511 *ov)
1138{
1139 int i, success;
1140
1141 /* Reset the sensor */
1142 if (i2c_w(ov, 0x12, 0x80) < 0)
1143 return -EIO;
1144
1145 /* Wait for it to initialize */
1146 msleep(150);
1147
1148 for (i = 0, success = 0; i < i2c_detect_tries && !success; i++) {
1149 if ((i2c_r(ov, OV7610_REG_ID_HIGH) == 0x7F) &&
1150 (i2c_r(ov, OV7610_REG_ID_LOW) == 0xA2)) {
1151 success = 1;
1152 continue;
1153 }
1154
1155 /* Reset the sensor */
1156 if (i2c_w(ov, 0x12, 0x80) < 0)
1157 return -EIO;
1158 /* Wait for it to initialize */
1159 msleep(150);
1160 /* Dummy read to sync I2C */
1161 if (i2c_r(ov, 0x00) < 0)
1162 return -EIO;
1163 }
1164
1165 if (!success)
1166 return -EIO;
1167
1168 PDEBUG(1, "I2C synced in %d attempt(s)", i);
1169
1170 return 0;
1171}
1172
1173static int
1174ov511_set_packet_size(struct usb_ov511 *ov, int size)
1175{
1176 int alt, mult;
1177
1178 if (ov51x_stop(ov) < 0)
1179 return -EIO;
1180
1181 mult = size >> 5;
1182
1183 if (ov->bridge == BRG_OV511) {
1184 if (size == 0)
1185 alt = OV511_ALT_SIZE_0;
1186 else if (size == 257)
1187 alt = OV511_ALT_SIZE_257;
1188 else if (size == 513)
1189 alt = OV511_ALT_SIZE_513;
1190 else if (size == 769)
1191 alt = OV511_ALT_SIZE_769;
1192 else if (size == 993)
1193 alt = OV511_ALT_SIZE_993;
1194 else {
1195 err("Set packet size: invalid size (%d)", size);
1196 return -EINVAL;
1197 }
1198 } else if (ov->bridge == BRG_OV511PLUS) {
1199 if (size == 0)
1200 alt = OV511PLUS_ALT_SIZE_0;
1201 else if (size == 33)
1202 alt = OV511PLUS_ALT_SIZE_33;
1203 else if (size == 129)
1204 alt = OV511PLUS_ALT_SIZE_129;
1205 else if (size == 257)
1206 alt = OV511PLUS_ALT_SIZE_257;
1207 else if (size == 385)
1208 alt = OV511PLUS_ALT_SIZE_385;
1209 else if (size == 513)
1210 alt = OV511PLUS_ALT_SIZE_513;
1211 else if (size == 769)
1212 alt = OV511PLUS_ALT_SIZE_769;
1213 else if (size == 961)
1214 alt = OV511PLUS_ALT_SIZE_961;
1215 else {
1216 err("Set packet size: invalid size (%d)", size);
1217 return -EINVAL;
1218 }
1219 } else {
1220 err("Set packet size: Invalid bridge type");
1221 return -EINVAL;
1222 }
1223
1224 PDEBUG(3, "%d, mult=%d, alt=%d", size, mult, alt);
1225
1226 if (reg_w(ov, R51x_FIFO_PSIZE, mult) < 0)
1227 return -EIO;
1228
1229 if (usb_set_interface(ov->dev, ov->iface, alt) < 0) {
1230 err("Set packet size: set interface error");
1231 return -EBUSY;
1232 }
1233
1234 if (ov51x_reset(ov, OV511_RESET_NOREGS) < 0)
1235 return -EIO;
1236
1237 ov->packet_size = size;
1238
1239 if (ov51x_restart(ov) < 0)
1240 return -EIO;
1241
1242 return 0;
1243}
1244
1245/* Note: Unlike the OV511/OV511+, the size argument does NOT include the
1246 * optional packet number byte. The actual size *is* stored in ov->packet_size,
1247 * though. */
1248static int
1249ov518_set_packet_size(struct usb_ov511 *ov, int size)
1250{
1251 int alt;
1252
1253 if (ov51x_stop(ov) < 0)
1254 return -EIO;
1255
1256 if (ov->bclass == BCL_OV518) {
1257 if (size == 0)
1258 alt = OV518_ALT_SIZE_0;
1259 else if (size == 128)
1260 alt = OV518_ALT_SIZE_128;
1261 else if (size == 256)
1262 alt = OV518_ALT_SIZE_256;
1263 else if (size == 384)
1264 alt = OV518_ALT_SIZE_384;
1265 else if (size == 512)
1266 alt = OV518_ALT_SIZE_512;
1267 else if (size == 640)
1268 alt = OV518_ALT_SIZE_640;
1269 else if (size == 768)
1270 alt = OV518_ALT_SIZE_768;
1271 else if (size == 896)
1272 alt = OV518_ALT_SIZE_896;
1273 else {
1274 err("Set packet size: invalid size (%d)", size);
1275 return -EINVAL;
1276 }
1277 } else {
1278 err("Set packet size: Invalid bridge type");
1279 return -EINVAL;
1280 }
1281
1282 PDEBUG(3, "%d, alt=%d", size, alt);
1283
1284 ov->packet_size = size;
1285 if (size > 0) {
1286 /* Program ISO FIFO size reg (packet number isn't included) */
1287 ov518_reg_w32(ov, 0x30, size, 2);
1288
1289 if (ov->packet_numbering)
1290 ++ov->packet_size;
1291 }
1292
1293 if (usb_set_interface(ov->dev, ov->iface, alt) < 0) {
1294 err("Set packet size: set interface error");
1295 return -EBUSY;
1296 }
1297
1298 /* Initialize the stream */
1299 if (reg_w(ov, 0x2f, 0x80) < 0)
1300 return -EIO;
1301
1302 if (ov51x_restart(ov) < 0)
1303 return -EIO;
1304
1305 if (ov51x_reset(ov, OV511_RESET_NOREGS) < 0)
1306 return -EIO;
1307
1308 return 0;
1309}
1310
1311/* Upload compression params and quantization tables. Returns 0 for success. */
1312static int
1313ov511_init_compression(struct usb_ov511 *ov)
1314{
1315 int rc = 0;
1316
1317 if (!ov->compress_inited) {
1318 reg_w(ov, 0x70, phy);
1319 reg_w(ov, 0x71, phuv);
1320 reg_w(ov, 0x72, pvy);
1321 reg_w(ov, 0x73, pvuv);
1322 reg_w(ov, 0x74, qhy);
1323 reg_w(ov, 0x75, qhuv);
1324 reg_w(ov, 0x76, qvy);
1325 reg_w(ov, 0x77, qvuv);
1326
1327 if (ov511_upload_quan_tables(ov) < 0) {
1328 err("Error uploading quantization tables");
1329 rc = -EIO;
1330 goto out;
1331 }
1332 }
1333
1334 ov->compress_inited = 1;
1335out:
1336 return rc;
1337}
1338
1339/* Upload compression params and quantization tables. Returns 0 for success. */
1340static int
1341ov518_init_compression(struct usb_ov511 *ov)
1342{
1343 int rc = 0;
1344
1345 if (!ov->compress_inited) {
1346 if (ov518_upload_quan_tables(ov) < 0) {
1347 err("Error uploading quantization tables");
1348 rc = -EIO;
1349 goto out;
1350 }
1351 }
1352
1353 ov->compress_inited = 1;
1354out:
1355 return rc;
1356}
1357
1358/* -------------------------------------------------------------------------- */
1359
1360/* Sets sensor's contrast setting to "val" */
1361static int
1362sensor_set_contrast(struct usb_ov511 *ov, unsigned short val)
1363{
1364 int rc;
1365
1366 PDEBUG(3, "%d", val);
1367
1368 if (ov->stop_during_set)
1369 if (ov51x_stop(ov) < 0)
1370 return -EIO;
1371
1372 switch (ov->sensor) {
1373 case SEN_OV7610:
1374 case SEN_OV6620:
1375 {
1376 rc = i2c_w(ov, OV7610_REG_CNT, val >> 8);
1377 if (rc < 0)
1378 goto out;
1379 break;
1380 }
1381 case SEN_OV6630:
1382 {
1383 rc = i2c_w_mask(ov, OV7610_REG_CNT, val >> 12, 0x0f);
1384 if (rc < 0)
1385 goto out;
1386 break;
1387 }
1388 case SEN_OV7620:
1389 {
1390 unsigned char ctab[] = {
1391 0x01, 0x05, 0x09, 0x11, 0x15, 0x35, 0x37, 0x57,
1392 0x5b, 0xa5, 0xa7, 0xc7, 0xc9, 0xcf, 0xef, 0xff
1393 };
1394
1395 /* Use Y gamma control instead. Bit 0 enables it. */
1396 rc = i2c_w(ov, 0x64, ctab[val>>12]);
1397 if (rc < 0)
1398 goto out;
1399 break;
1400 }
1401 case SEN_SAA7111A:
1402 {
1403 rc = i2c_w(ov, 0x0b, val >> 9);
1404 if (rc < 0)
1405 goto out;
1406 break;
1407 }
1408 default:
1409 {
1410 PDEBUG(3, "Unsupported with this sensor");
1411 rc = -EPERM;
1412 goto out;
1413 }
1414 }
1415
1416 rc = 0; /* Success */
1417 ov->contrast = val;
1418out:
1419 if (ov51x_restart(ov) < 0)
1420 return -EIO;
1421
1422 return rc;
1423}
1424
1425/* Gets sensor's contrast setting */
1426static int
1427sensor_get_contrast(struct usb_ov511 *ov, unsigned short *val)
1428{
1429 int rc;
1430
1431 switch (ov->sensor) {
1432 case SEN_OV7610:
1433 case SEN_OV6620:
1434 rc = i2c_r(ov, OV7610_REG_CNT);
1435 if (rc < 0)
1436 return rc;
1437 else
1438 *val = rc << 8;
1439 break;
1440 case SEN_OV6630:
1441 rc = i2c_r(ov, OV7610_REG_CNT);
1442 if (rc < 0)
1443 return rc;
1444 else
1445 *val = rc << 12;
1446 break;
1447 case SEN_OV7620:
1448 /* Use Y gamma reg instead. Bit 0 is the enable bit. */
1449 rc = i2c_r(ov, 0x64);
1450 if (rc < 0)
1451 return rc;
1452 else
1453 *val = (rc & 0xfe) << 8;
1454 break;
1455 case SEN_SAA7111A:
1456 *val = ov->contrast;
1457 break;
1458 default:
1459 PDEBUG(3, "Unsupported with this sensor");
1460 return -EPERM;
1461 }
1462
1463 PDEBUG(3, "%d", *val);
1464 ov->contrast = *val;
1465
1466 return 0;
1467}
1468
1469/* -------------------------------------------------------------------------- */
1470
1471/* Sets sensor's brightness setting to "val" */
1472static int
1473sensor_set_brightness(struct usb_ov511 *ov, unsigned short val)
1474{
1475 int rc;
1476
1477 PDEBUG(4, "%d", val);
1478
1479 if (ov->stop_during_set)
1480 if (ov51x_stop(ov) < 0)
1481 return -EIO;
1482
1483 switch (ov->sensor) {
1484 case SEN_OV7610:
1485 case SEN_OV76BE:
1486 case SEN_OV6620:
1487 case SEN_OV6630:
1488 rc = i2c_w(ov, OV7610_REG_BRT, val >> 8);
1489 if (rc < 0)
1490 goto out;
1491 break;
1492 case SEN_OV7620:
1493 /* 7620 doesn't like manual changes when in auto mode */
1494 if (!ov->auto_brt) {
1495 rc = i2c_w(ov, OV7610_REG_BRT, val >> 8);
1496 if (rc < 0)
1497 goto out;
1498 }
1499 break;
1500 case SEN_SAA7111A:
1501 rc = i2c_w(ov, 0x0a, val >> 8);
1502 if (rc < 0)
1503 goto out;
1504 break;
1505 default:
1506 PDEBUG(3, "Unsupported with this sensor");
1507 rc = -EPERM;
1508 goto out;
1509 }
1510
1511 rc = 0; /* Success */
1512 ov->brightness = val;
1513out:
1514 if (ov51x_restart(ov) < 0)
1515 return -EIO;
1516
1517 return rc;
1518}
1519
1520/* Gets sensor's brightness setting */
1521static int
1522sensor_get_brightness(struct usb_ov511 *ov, unsigned short *val)
1523{
1524 int rc;
1525
1526 switch (ov->sensor) {
1527 case SEN_OV7610:
1528 case SEN_OV76BE:
1529 case SEN_OV7620:
1530 case SEN_OV6620:
1531 case SEN_OV6630:
1532 rc = i2c_r(ov, OV7610_REG_BRT);
1533 if (rc < 0)
1534 return rc;
1535 else
1536 *val = rc << 8;
1537 break;
1538 case SEN_SAA7111A:
1539 *val = ov->brightness;
1540 break;
1541 default:
1542 PDEBUG(3, "Unsupported with this sensor");
1543 return -EPERM;
1544 }
1545
1546 PDEBUG(3, "%d", *val);
1547 ov->brightness = *val;
1548
1549 return 0;
1550}
1551
1552/* -------------------------------------------------------------------------- */
1553
1554/* Sets sensor's saturation (color intensity) setting to "val" */
1555static int
1556sensor_set_saturation(struct usb_ov511 *ov, unsigned short val)
1557{
1558 int rc;
1559
1560 PDEBUG(3, "%d", val);
1561
1562 if (ov->stop_during_set)
1563 if (ov51x_stop(ov) < 0)
1564 return -EIO;
1565
1566 switch (ov->sensor) {
1567 case SEN_OV7610:
1568 case SEN_OV76BE:
1569 case SEN_OV6620:
1570 case SEN_OV6630:
1571 rc = i2c_w(ov, OV7610_REG_SAT, val >> 8);
1572 if (rc < 0)
1573 goto out;
1574 break;
1575 case SEN_OV7620:
1576// /* Use UV gamma control instead. Bits 0 & 7 are reserved. */
1577// rc = ov_i2c_write(ov->dev, 0x62, (val >> 9) & 0x7e);
1578// if (rc < 0)
1579// goto out;
1580 rc = i2c_w(ov, OV7610_REG_SAT, val >> 8);
1581 if (rc < 0)
1582 goto out;
1583 break;
1584 case SEN_SAA7111A:
1585 rc = i2c_w(ov, 0x0c, val >> 9);
1586 if (rc < 0)
1587 goto out;
1588 break;
1589 default:
1590 PDEBUG(3, "Unsupported with this sensor");
1591 rc = -EPERM;
1592 goto out;
1593 }
1594
1595 rc = 0; /* Success */
1596 ov->colour = val;
1597out:
1598 if (ov51x_restart(ov) < 0)
1599 return -EIO;
1600
1601 return rc;
1602}
1603
1604/* Gets sensor's saturation (color intensity) setting */
1605static int
1606sensor_get_saturation(struct usb_ov511 *ov, unsigned short *val)
1607{
1608 int rc;
1609
1610 switch (ov->sensor) {
1611 case SEN_OV7610:
1612 case SEN_OV76BE:
1613 case SEN_OV6620:
1614 case SEN_OV6630:
1615 rc = i2c_r(ov, OV7610_REG_SAT);
1616 if (rc < 0)
1617 return rc;
1618 else
1619 *val = rc << 8;
1620 break;
1621 case SEN_OV7620:
1622// /* Use UV gamma reg instead. Bits 0 & 7 are reserved. */
1623// rc = i2c_r(ov, 0x62);
1624// if (rc < 0)
1625// return rc;
1626// else
1627// *val = (rc & 0x7e) << 9;
1628 rc = i2c_r(ov, OV7610_REG_SAT);
1629 if (rc < 0)
1630 return rc;
1631 else
1632 *val = rc << 8;
1633 break;
1634 case SEN_SAA7111A:
1635 *val = ov->colour;
1636 break;
1637 default:
1638 PDEBUG(3, "Unsupported with this sensor");
1639 return -EPERM;
1640 }
1641
1642 PDEBUG(3, "%d", *val);
1643 ov->colour = *val;
1644
1645 return 0;
1646}
1647
1648/* -------------------------------------------------------------------------- */
1649
1650/* Sets sensor's hue (red/blue balance) setting to "val" */
1651static int
1652sensor_set_hue(struct usb_ov511 *ov, unsigned short val)
1653{
1654 int rc;
1655
1656 PDEBUG(3, "%d", val);
1657
1658 if (ov->stop_during_set)
1659 if (ov51x_stop(ov) < 0)
1660 return -EIO;
1661
1662 switch (ov->sensor) {
1663 case SEN_OV7610:
1664 case SEN_OV6620:
1665 case SEN_OV6630:
1666 rc = i2c_w(ov, OV7610_REG_RED, 0xFF - (val >> 8));
1667 if (rc < 0)
1668 goto out;
1669
1670 rc = i2c_w(ov, OV7610_REG_BLUE, val >> 8);
1671 if (rc < 0)
1672 goto out;
1673 break;
1674 case SEN_OV7620:
1675// Hue control is causing problems. I will enable it once it's fixed.
1676#if 0
1677 rc = i2c_w(ov, 0x7a, (unsigned char)(val >> 8) + 0xb);
1678 if (rc < 0)
1679 goto out;
1680
1681 rc = i2c_w(ov, 0x79, (unsigned char)(val >> 8) + 0xb);
1682 if (rc < 0)
1683 goto out;
1684#endif
1685 break;
1686 case SEN_SAA7111A:
1687 rc = i2c_w(ov, 0x0d, (val + 32768) >> 8);
1688 if (rc < 0)
1689 goto out;
1690 break;
1691 default:
1692 PDEBUG(3, "Unsupported with this sensor");
1693 rc = -EPERM;
1694 goto out;
1695 }
1696
1697 rc = 0; /* Success */
1698 ov->hue = val;
1699out:
1700 if (ov51x_restart(ov) < 0)
1701 return -EIO;
1702
1703 return rc;
1704}
1705
1706/* Gets sensor's hue (red/blue balance) setting */
1707static int
1708sensor_get_hue(struct usb_ov511 *ov, unsigned short *val)
1709{
1710 int rc;
1711
1712 switch (ov->sensor) {
1713 case SEN_OV7610:
1714 case SEN_OV6620:
1715 case SEN_OV6630:
1716 rc = i2c_r(ov, OV7610_REG_BLUE);
1717 if (rc < 0)
1718 return rc;
1719 else
1720 *val = rc << 8;
1721 break;
1722 case SEN_OV7620:
1723 rc = i2c_r(ov, 0x7a);
1724 if (rc < 0)
1725 return rc;
1726 else
1727 *val = rc << 8;
1728 break;
1729 case SEN_SAA7111A:
1730 *val = ov->hue;
1731 break;
1732 default:
1733 PDEBUG(3, "Unsupported with this sensor");
1734 return -EPERM;
1735 }
1736
1737 PDEBUG(3, "%d", *val);
1738 ov->hue = *val;
1739
1740 return 0;
1741}
1742
1743/* -------------------------------------------------------------------------- */
1744
1745static int
1746sensor_set_picture(struct usb_ov511 *ov, struct video_picture *p)
1747{
1748 int rc;
1749
1750 PDEBUG(4, "sensor_set_picture");
1751
1752 ov->whiteness = p->whiteness;
1753
1754 /* Don't return error if a setting is unsupported, or rest of settings
1755 * will not be performed */
1756
1757 rc = sensor_set_contrast(ov, p->contrast);
1758 if (FATAL_ERROR(rc))
1759 return rc;
1760
1761 rc = sensor_set_brightness(ov, p->brightness);
1762 if (FATAL_ERROR(rc))
1763 return rc;
1764
1765 rc = sensor_set_saturation(ov, p->colour);
1766 if (FATAL_ERROR(rc))
1767 return rc;
1768
1769 rc = sensor_set_hue(ov, p->hue);
1770 if (FATAL_ERROR(rc))
1771 return rc;
1772
1773 return 0;
1774}
1775
1776static int
1777sensor_get_picture(struct usb_ov511 *ov, struct video_picture *p)
1778{
1779 int rc;
1780
1781 PDEBUG(4, "sensor_get_picture");
1782
1783 /* Don't return error if a setting is unsupported, or rest of settings
1784 * will not be performed */
1785
1786 rc = sensor_get_contrast(ov, &(p->contrast));
1787 if (FATAL_ERROR(rc))
1788 return rc;
1789
1790 rc = sensor_get_brightness(ov, &(p->brightness));
1791 if (FATAL_ERROR(rc))
1792 return rc;
1793
1794 rc = sensor_get_saturation(ov, &(p->colour));
1795 if (FATAL_ERROR(rc))
1796 return rc;
1797
1798 rc = sensor_get_hue(ov, &(p->hue));
1799 if (FATAL_ERROR(rc))
1800 return rc;
1801
1802 p->whiteness = 105 << 8;
1803
1804 return 0;
1805}
1806
1807#if 0
1808// FIXME: Exposure range is only 0x00-0x7f in interlace mode
1809/* Sets current exposure for sensor. This only has an effect if auto-exposure
1810 * is off */
1811static inline int
1812sensor_set_exposure(struct usb_ov511 *ov, unsigned char val)
1813{
1814 int rc;
1815
1816 PDEBUG(3, "%d", val);
1817
1818 if (ov->stop_during_set)
1819 if (ov51x_stop(ov) < 0)
1820 return -EIO;
1821
1822 switch (ov->sensor) {
1823 case SEN_OV6620:
1824 case SEN_OV6630:
1825 case SEN_OV7610:
1826 case SEN_OV7620:
1827 case SEN_OV76BE:
1828 case SEN_OV8600:
1829 rc = i2c_w(ov, 0x10, val);
1830 if (rc < 0)
1831 goto out;
1832
1833 break;
1834 case SEN_KS0127:
1835 case SEN_KS0127B:
1836 case SEN_SAA7111A:
1837 PDEBUG(3, "Unsupported with this sensor");
1838 return -EPERM;
1839 default:
1840 err("Sensor not supported for set_exposure");
1841 return -EINVAL;
1842 }
1843
1844 rc = 0; /* Success */
1845 ov->exposure = val;
1846out:
1847 if (ov51x_restart(ov) < 0)
1848 return -EIO;
1849
1850 return rc;
1851}
1852#endif
1853
1854/* Gets current exposure level from sensor, regardless of whether it is under
1855 * manual control. */
1856static int
1857sensor_get_exposure(struct usb_ov511 *ov, unsigned char *val)
1858{
1859 int rc;
1860
1861 switch (ov->sensor) {
1862 case SEN_OV7610:
1863 case SEN_OV6620:
1864 case SEN_OV6630:
1865 case SEN_OV7620:
1866 case SEN_OV76BE:
1867 case SEN_OV8600:
1868 rc = i2c_r(ov, 0x10);
1869 if (rc < 0)
1870 return rc;
1871 else
1872 *val = rc;
1873 break;
1874 case SEN_KS0127:
1875 case SEN_KS0127B:
1876 case SEN_SAA7111A:
1877 val = NULL;
1878 PDEBUG(3, "Unsupported with this sensor");
1879 return -EPERM;
1880 default:
1881 err("Sensor not supported for get_exposure");
1882 return -EINVAL;
1883 }
1884
1885 PDEBUG(3, "%d", *val);
1886 ov->exposure = *val;
1887
1888 return 0;
1889}
1890
1891/* Turns on or off the LED. Only has an effect with OV511+/OV518(+) */
1892static void
1893ov51x_led_control(struct usb_ov511 *ov, int enable)
1894{
1895 PDEBUG(4, " (%s)", enable ? "turn on" : "turn off");
1896
1897 if (ov->bridge == BRG_OV511PLUS)
1898 reg_w(ov, R511_SYS_LED_CTL, enable ? 1 : 0);
1899 else if (ov->bclass == BCL_OV518)
1900 reg_w_mask(ov, R518_GPIO_OUT, enable ? 0x02 : 0x00, 0x02);
1901
1902 return;
1903}
1904
1905/* Matches the sensor's internal frame rate to the lighting frequency.
1906 * Valid frequencies are:
1907 * 50 - 50Hz, for European and Asian lighting
1908 * 60 - 60Hz, for American lighting
1909 *
1910 * Tested with: OV7610, OV7620, OV76BE, OV6620
1911 * Unsupported: KS0127, KS0127B, SAA7111A
1912 * Returns: 0 for success
1913 */
1914static int
1915sensor_set_light_freq(struct usb_ov511 *ov, int freq)
1916{
1917 int sixty;
1918
1919 PDEBUG(4, "%d Hz", freq);
1920
1921 if (freq == 60)
1922 sixty = 1;
1923 else if (freq == 50)
1924 sixty = 0;
1925 else {
1926 err("Invalid light freq (%d Hz)", freq);
1927 return -EINVAL;
1928 }
1929
1930 switch (ov->sensor) {
1931 case SEN_OV7610:
1932 i2c_w_mask(ov, 0x2a, sixty?0x00:0x80, 0x80);
1933 i2c_w(ov, 0x2b, sixty?0x00:0xac);
1934 i2c_w_mask(ov, 0x13, 0x10, 0x10);
1935 i2c_w_mask(ov, 0x13, 0x00, 0x10);
1936 break;
1937 case SEN_OV7620:
1938 case SEN_OV76BE:
1939 case SEN_OV8600:
1940 i2c_w_mask(ov, 0x2a, sixty?0x00:0x80, 0x80);
1941 i2c_w(ov, 0x2b, sixty?0x00:0xac);
1942 i2c_w_mask(ov, 0x76, 0x01, 0x01);
1943 break;
1944 case SEN_OV6620:
1945 case SEN_OV6630:
1946 i2c_w(ov, 0x2b, sixty?0xa8:0x28);
1947 i2c_w(ov, 0x2a, sixty?0x84:0xa4);
1948 break;
1949 case SEN_KS0127:
1950 case SEN_KS0127B:
1951 case SEN_SAA7111A:
1952 PDEBUG(5, "Unsupported with this sensor");
1953 return -EPERM;
1954 default:
1955 err("Sensor not supported for set_light_freq");
1956 return -EINVAL;
1957 }
1958
1959 ov->lightfreq = freq;
1960
1961 return 0;
1962}
1963
1964/* If enable is true, turn on the sensor's banding filter, otherwise turn it
1965 * off. This filter tries to reduce the pattern of horizontal light/dark bands
1966 * caused by some (usually fluorescent) lighting. The light frequency must be
1967 * set either before or after enabling it with ov51x_set_light_freq().
1968 *
1969 * Tested with: OV7610, OV7620, OV76BE, OV6620.
1970 * Unsupported: KS0127, KS0127B, SAA7111A
1971 * Returns: 0 for success
1972 */
1973static int
1974sensor_set_banding_filter(struct usb_ov511 *ov, int enable)
1975{
1976 int rc;
1977
1978 PDEBUG(4, " (%s)", enable ? "turn on" : "turn off");
1979
1980 if (ov->sensor == SEN_KS0127 || ov->sensor == SEN_KS0127B
1981 || ov->sensor == SEN_SAA7111A) {
1982 PDEBUG(5, "Unsupported with this sensor");
1983 return -EPERM;
1984 }
1985
1986 rc = i2c_w_mask(ov, 0x2d, enable?0x04:0x00, 0x04);
1987 if (rc < 0)
1988 return rc;
1989
1990 ov->bandfilt = enable;
1991
1992 return 0;
1993}
1994
1995/* If enable is true, turn on the sensor's auto brightness control, otherwise
1996 * turn it off.
1997 *
1998 * Unsupported: KS0127, KS0127B, SAA7111A
1999 * Returns: 0 for success
2000 */
2001static int
2002sensor_set_auto_brightness(struct usb_ov511 *ov, int enable)
2003{
2004 int rc;
2005
2006 PDEBUG(4, " (%s)", enable ? "turn on" : "turn off");
2007
2008 if (ov->sensor == SEN_KS0127 || ov->sensor == SEN_KS0127B
2009 || ov->sensor == SEN_SAA7111A) {
2010 PDEBUG(5, "Unsupported with this sensor");
2011 return -EPERM;
2012 }
2013
2014 rc = i2c_w_mask(ov, 0x2d, enable?0x10:0x00, 0x10);
2015 if (rc < 0)
2016 return rc;
2017
2018 ov->auto_brt = enable;
2019
2020 return 0;
2021}
2022
2023/* If enable is true, turn on the sensor's auto exposure control, otherwise
2024 * turn it off.
2025 *
2026 * Unsupported: KS0127, KS0127B, SAA7111A
2027 * Returns: 0 for success
2028 */
2029static int
2030sensor_set_auto_exposure(struct usb_ov511 *ov, int enable)
2031{
2032 PDEBUG(4, " (%s)", enable ? "turn on" : "turn off");
2033
2034 switch (ov->sensor) {
2035 case SEN_OV7610:
2036 i2c_w_mask(ov, 0x29, enable?0x00:0x80, 0x80);
2037 break;
2038 case SEN_OV6620:
2039 case SEN_OV7620:
2040 case SEN_OV76BE:
2041 case SEN_OV8600:
2042 i2c_w_mask(ov, 0x13, enable?0x01:0x00, 0x01);
2043 break;
2044 case SEN_OV6630:
2045 i2c_w_mask(ov, 0x28, enable?0x00:0x10, 0x10);
2046 break;
2047 case SEN_KS0127:
2048 case SEN_KS0127B:
2049 case SEN_SAA7111A:
2050 PDEBUG(5, "Unsupported with this sensor");
2051 return -EPERM;
2052 default:
2053 err("Sensor not supported for set_auto_exposure");
2054 return -EINVAL;
2055 }
2056
2057 ov->auto_exp = enable;
2058
2059 return 0;
2060}
2061
2062/* Modifies the sensor's exposure algorithm to allow proper exposure of objects
2063 * that are illuminated from behind.
2064 *
2065 * Tested with: OV6620, OV7620
2066 * Unsupported: OV7610, OV76BE, KS0127, KS0127B, SAA7111A
2067 * Returns: 0 for success
2068 */
2069static int
2070sensor_set_backlight(struct usb_ov511 *ov, int enable)
2071{
2072 PDEBUG(4, " (%s)", enable ? "turn on" : "turn off");
2073
2074 switch (ov->sensor) {
2075 case SEN_OV7620:
2076 case SEN_OV8600:
2077 i2c_w_mask(ov, 0x68, enable?0xe0:0xc0, 0xe0);
2078 i2c_w_mask(ov, 0x29, enable?0x08:0x00, 0x08);
2079 i2c_w_mask(ov, 0x28, enable?0x02:0x00, 0x02);
2080 break;
2081 case SEN_OV6620:
2082 i2c_w_mask(ov, 0x4e, enable?0xe0:0xc0, 0xe0);
2083 i2c_w_mask(ov, 0x29, enable?0x08:0x00, 0x08);
2084 i2c_w_mask(ov, 0x0e, enable?0x80:0x00, 0x80);
2085 break;
2086 case SEN_OV6630:
2087 i2c_w_mask(ov, 0x4e, enable?0x80:0x60, 0xe0);
2088 i2c_w_mask(ov, 0x29, enable?0x08:0x00, 0x08);
2089 i2c_w_mask(ov, 0x28, enable?0x02:0x00, 0x02);
2090 break;
2091 case SEN_OV7610:
2092 case SEN_OV76BE:
2093 case SEN_KS0127:
2094 case SEN_KS0127B:
2095 case SEN_SAA7111A:
2096 PDEBUG(5, "Unsupported with this sensor");
2097 return -EPERM;
2098 default:
2099 err("Sensor not supported for set_backlight");
2100 return -EINVAL;
2101 }
2102
2103 ov->backlight = enable;
2104
2105 return 0;
2106}
2107
2108static int
2109sensor_set_mirror(struct usb_ov511 *ov, int enable)
2110{
2111 PDEBUG(4, " (%s)", enable ? "turn on" : "turn off");
2112
2113 switch (ov->sensor) {
2114 case SEN_OV6620:
2115 case SEN_OV6630:
2116 case SEN_OV7610:
2117 case SEN_OV7620:
2118 case SEN_OV76BE:
2119 case SEN_OV8600:
2120 i2c_w_mask(ov, 0x12, enable?0x40:0x00, 0x40);
2121 break;
2122 case SEN_KS0127:
2123 case SEN_KS0127B:
2124 case SEN_SAA7111A:
2125 PDEBUG(5, "Unsupported with this sensor");
2126 return -EPERM;
2127 default:
2128 err("Sensor not supported for set_mirror");
2129 return -EINVAL;
2130 }
2131
2132 ov->mirror = enable;
2133
2134 return 0;
2135}
2136
2137/* Returns number of bits per pixel (regardless of where they are located;
2138 * planar or not), or zero for unsupported format.
2139 */
2140static inline int
2141get_depth(int palette)
2142{
2143 switch (palette) {
2144 case VIDEO_PALETTE_GREY: return 8;
2145 case VIDEO_PALETTE_YUV420: return 12;
2146 case VIDEO_PALETTE_YUV420P: return 12; /* Planar */
2147 default: return 0; /* Invalid format */
2148 }
2149}
2150
2151/* Bytes per frame. Used by read(). Return of 0 indicates error */
2152static inline long int
2153get_frame_length(struct ov511_frame *frame)
2154{
2155 if (!frame)
2156 return 0;
2157 else
2158 return ((frame->width * frame->height
2159 * get_depth(frame->format)) >> 3);
2160}
2161
2162static int
2163mode_init_ov_sensor_regs(struct usb_ov511 *ov, int width, int height,
2164 int mode, int sub_flag, int qvga)
2165{
2166 int clock;
2167
2168 /******** Mode (VGA/QVGA) and sensor specific regs ********/
2169
2170 switch (ov->sensor) {
2171 case SEN_OV7610:
2172 i2c_w(ov, 0x14, qvga?0x24:0x04);
2173// FIXME: Does this improve the image quality or frame rate?
2174#if 0
2175 i2c_w_mask(ov, 0x28, qvga?0x00:0x20, 0x20);
2176 i2c_w(ov, 0x24, 0x10);
2177 i2c_w(ov, 0x25, qvga?0x40:0x8a);
2178 i2c_w(ov, 0x2f, qvga?0x30:0xb0);
2179 i2c_w(ov, 0x35, qvga?0x1c:0x9c);
2180#endif
2181 break;
2182 case SEN_OV7620:
2183// i2c_w(ov, 0x2b, 0x00);
2184 i2c_w(ov, 0x14, qvga?0xa4:0x84);
2185 i2c_w_mask(ov, 0x28, qvga?0x00:0x20, 0x20);
2186 i2c_w(ov, 0x24, qvga?0x20:0x3a);
2187 i2c_w(ov, 0x25, qvga?0x30:0x60);
2188 i2c_w_mask(ov, 0x2d, qvga?0x40:0x00, 0x40);
2189 i2c_w_mask(ov, 0x67, qvga?0xf0:0x90, 0xf0);
2190 i2c_w_mask(ov, 0x74, qvga?0x20:0x00, 0x20);
2191 break;
2192 case SEN_OV76BE:
2193// i2c_w(ov, 0x2b, 0x00);
2194 i2c_w(ov, 0x14, qvga?0xa4:0x84);
2195// FIXME: Enable this once 7620AE uses 7620 initial settings
2196#if 0
2197 i2c_w_mask(ov, 0x28, qvga?0x00:0x20, 0x20);
2198 i2c_w(ov, 0x24, qvga?0x20:0x3a);
2199 i2c_w(ov, 0x25, qvga?0x30:0x60);
2200 i2c_w_mask(ov, 0x2d, qvga?0x40:0x00, 0x40);
2201 i2c_w_mask(ov, 0x67, qvga?0xb0:0x90, 0xf0);
2202 i2c_w_mask(ov, 0x74, qvga?0x20:0x00, 0x20);
2203#endif
2204 break;
2205 case SEN_OV6620:
2206 i2c_w(ov, 0x14, qvga?0x24:0x04);
2207 break;
2208 case SEN_OV6630:
2209 i2c_w(ov, 0x14, qvga?0xa0:0x80);
2210 break;
2211 default:
2212 err("Invalid sensor");
2213 return -EINVAL;
2214 }
2215
2216 /******** Palette-specific regs ********/
2217
2218 if (mode == VIDEO_PALETTE_GREY) {
2219 if (ov->sensor == SEN_OV7610 || ov->sensor == SEN_OV76BE) {
2220 /* these aren't valid on the OV6620/OV7620/6630? */
2221 i2c_w_mask(ov, 0x0e, 0x40, 0x40);
2222 }
2223
2224 if (ov->sensor == SEN_OV6630 && ov->bridge == BRG_OV518
2225 && ov518_color) {
2226 i2c_w_mask(ov, 0x12, 0x00, 0x10);
2227 i2c_w_mask(ov, 0x13, 0x00, 0x20);
2228 } else {
2229 i2c_w_mask(ov, 0x13, 0x20, 0x20);
2230 }
2231 } else {
2232 if (ov->sensor == SEN_OV7610 || ov->sensor == SEN_OV76BE) {
2233 /* not valid on the OV6620/OV7620/6630? */
2234 i2c_w_mask(ov, 0x0e, 0x00, 0x40);
2235 }
2236
2237 /* The OV518 needs special treatment. Although both the OV518
2238 * and the OV6630 support a 16-bit video bus, only the 8 bit Y
2239 * bus is actually used. The UV bus is tied to ground.
2240 * Therefore, the OV6630 needs to be in 8-bit multiplexed
2241 * output mode */
2242
2243 if (ov->sensor == SEN_OV6630 && ov->bridge == BRG_OV518
2244 && ov518_color) {
2245 i2c_w_mask(ov, 0x12, 0x10, 0x10);
2246 i2c_w_mask(ov, 0x13, 0x20, 0x20);
2247 } else {
2248 i2c_w_mask(ov, 0x13, 0x00, 0x20);
2249 }
2250 }
2251
2252 /******** Clock programming ********/
2253
2254 /* The OV6620 needs special handling. This prevents the
2255 * severe banding that normally occurs */
2256 if (ov->sensor == SEN_OV6620 || ov->sensor == SEN_OV6630)
2257 {
2258 /* Clock down */
2259
2260 i2c_w(ov, 0x2a, 0x04);
2261
2262 if (ov->compress) {
2263// clock = 0; /* This ensures the highest frame rate */
2264 clock = 3;
2265 } else if (clockdiv == -1) { /* If user didn't override it */
2266 clock = 3; /* Gives better exposure time */
2267 } else {
2268 clock = clockdiv;
2269 }
2270
2271 PDEBUG(4, "Setting clock divisor to %d", clock);
2272
2273 i2c_w(ov, 0x11, clock);
2274
2275 i2c_w(ov, 0x2a, 0x84);
2276 /* This next setting is critical. It seems to improve
2277 * the gain or the contrast. The "reserved" bits seem
2278 * to have some effect in this case. */
2279 i2c_w(ov, 0x2d, 0x85);
2280 }
2281 else
2282 {
2283 if (ov->compress) {
2284 clock = 1; /* This ensures the highest frame rate */
2285 } else if (clockdiv == -1) { /* If user didn't override it */
2286 /* Calculate and set the clock divisor */
2287 clock = ((sub_flag ? ov->subw * ov->subh
2288 : width * height)
2289 * (mode == VIDEO_PALETTE_GREY ? 2 : 3) / 2)
2290 / 66000;
2291 } else {
2292 clock = clockdiv;
2293 }
2294
2295 PDEBUG(4, "Setting clock divisor to %d", clock);
2296
2297 i2c_w(ov, 0x11, clock);
2298 }
2299
2300 /******** Special Features ********/
2301
2302 if (framedrop >= 0)
2303 i2c_w(ov, 0x16, framedrop);
2304
2305 /* Test Pattern */
2306 i2c_w_mask(ov, 0x12, (testpat?0x02:0x00), 0x02);
2307
2308 /* Enable auto white balance */
2309 i2c_w_mask(ov, 0x12, 0x04, 0x04);
2310
2311 // This will go away as soon as ov51x_mode_init_sensor_regs()
2312 // is fully tested.
2313 /* 7620/6620/6630? don't have register 0x35, so play it safe */
2314 if (ov->sensor == SEN_OV7610 || ov->sensor == SEN_OV76BE) {
2315 if (width == 640 && height == 480)
2316 i2c_w(ov, 0x35, 0x9e);
2317 else
2318 i2c_w(ov, 0x35, 0x1e);
2319 }
2320
2321 return 0;
2322}
2323
2324static int
2325set_ov_sensor_window(struct usb_ov511 *ov, int width, int height, int mode,
2326 int sub_flag)
2327{
2328 int ret;
2329 int hwsbase, hwebase, vwsbase, vwebase, hwsize, vwsize;
2330 int hoffset, voffset, hwscale = 0, vwscale = 0;
2331
2332 /* The different sensor ICs handle setting up of window differently.
2333 * IF YOU SET IT WRONG, YOU WILL GET ALL ZERO ISOC DATA FROM OV51x!!! */
2334 switch (ov->sensor) {
2335 case SEN_OV7610:
2336 case SEN_OV76BE:
2337 hwsbase = 0x38;
2338 hwebase = 0x3a;
2339 vwsbase = vwebase = 0x05;
2340 break;
2341 case SEN_OV6620:
2342 case SEN_OV6630:
2343 hwsbase = 0x38;
2344 hwebase = 0x3a;
2345 vwsbase = 0x05;
2346 vwebase = 0x06;
2347 break;
2348 case SEN_OV7620:
2349 hwsbase = 0x2f; /* From 7620.SET (spec is wrong) */
2350 hwebase = 0x2f;
2351 vwsbase = vwebase = 0x05;
2352 break;
2353 default:
2354 err("Invalid sensor");
2355 return -EINVAL;
2356 }
2357
2358 if (ov->sensor == SEN_OV6620 || ov->sensor == SEN_OV6630) {
2359 /* Note: OV518(+) does downsample on its own) */
2360 if ((width > 176 && height > 144)
2361 || ov->bclass == BCL_OV518) { /* CIF */
2362 ret = mode_init_ov_sensor_regs(ov, width, height,
2363 mode, sub_flag, 0);
2364 if (ret < 0)
2365 return ret;
2366 hwscale = 1;
2367 vwscale = 1; /* The datasheet says 0; it's wrong */
2368 hwsize = 352;
2369 vwsize = 288;
2370 } else if (width > 176 || height > 144) {
2371 err("Illegal dimensions");
2372 return -EINVAL;
2373 } else { /* QCIF */
2374 ret = mode_init_ov_sensor_regs(ov, width, height,
2375 mode, sub_flag, 1);
2376 if (ret < 0)
2377 return ret;
2378 hwsize = 176;
2379 vwsize = 144;
2380 }
2381 } else {
2382 if (width > 320 && height > 240) { /* VGA */
2383 ret = mode_init_ov_sensor_regs(ov, width, height,
2384 mode, sub_flag, 0);
2385 if (ret < 0)
2386 return ret;
2387 hwscale = 2;
2388 vwscale = 1;
2389 hwsize = 640;
2390 vwsize = 480;
2391 } else if (width > 320 || height > 240) {
2392 err("Illegal dimensions");
2393 return -EINVAL;
2394 } else { /* QVGA */
2395 ret = mode_init_ov_sensor_regs(ov, width, height,
2396 mode, sub_flag, 1);
2397 if (ret < 0)
2398 return ret;
2399 hwscale = 1;
2400 hwsize = 320;
2401 vwsize = 240;
2402 }
2403 }
2404
2405 /* Center the window */
2406 hoffset = ((hwsize - width) / 2) >> hwscale;
2407 voffset = ((vwsize - height) / 2) >> vwscale;
2408
2409 /* FIXME! - This needs to be changed to support 160x120 and 6620!!! */
2410 if (sub_flag) {
2411 i2c_w(ov, 0x17, hwsbase+(ov->subx>>hwscale));
2412 i2c_w(ov, 0x18, hwebase+((ov->subx+ov->subw)>>hwscale));
2413 i2c_w(ov, 0x19, vwsbase+(ov->suby>>vwscale));
2414 i2c_w(ov, 0x1a, vwebase+((ov->suby+ov->subh)>>vwscale));
2415 } else {
2416 i2c_w(ov, 0x17, hwsbase + hoffset);
2417 i2c_w(ov, 0x18, hwebase + hoffset + (hwsize>>hwscale));
2418 i2c_w(ov, 0x19, vwsbase + voffset);
2419 i2c_w(ov, 0x1a, vwebase + voffset + (vwsize>>vwscale));
2420 }
2421
2422#ifdef OV511_DEBUG
2423 if (dump_sensor)
2424 dump_i2c_regs(ov);
2425#endif
2426
2427 return 0;
2428}
2429
2430/* Set up the OV511/OV511+ with the given image parameters.
2431 *
2432 * Do not put any sensor-specific code in here (including I2C I/O functions)
2433 */
2434static int
2435ov511_mode_init_regs(struct usb_ov511 *ov,
2436 int width, int height, int mode, int sub_flag)
2437{
2438 int hsegs, vsegs;
2439
2440 if (sub_flag) {
2441 width = ov->subw;
2442 height = ov->subh;
2443 }
2444
2445 PDEBUG(3, "width:%d, height:%d, mode:%d, sub:%d",
2446 width, height, mode, sub_flag);
2447
2448 // FIXME: This should be moved to a 7111a-specific function once
2449 // subcapture is dealt with properly
2450 if (ov->sensor == SEN_SAA7111A) {
2451 if (width == 320 && height == 240) {
2452 /* No need to do anything special */
2453 } else if (width == 640 && height == 480) {
2454 /* Set the OV511 up as 320x480, but keep the
2455 * V4L resolution as 640x480 */
2456 width = 320;
2457 } else {
2458 err("SAA7111A only allows 320x240 or 640x480");
2459 return -EINVAL;
2460 }
2461 }
2462
2463 /* Make sure width and height are a multiple of 8 */
2464 if (width % 8 || height % 8) {
2465 err("Invalid size (%d, %d) (mode = %d)", width, height, mode);
2466 return -EINVAL;
2467 }
2468
2469 if (width < ov->minwidth || height < ov->minheight) {
2470 err("Requested dimensions are too small");
2471 return -EINVAL;
2472 }
2473
2474 if (ov51x_stop(ov) < 0)
2475 return -EIO;
2476
2477 if (mode == VIDEO_PALETTE_GREY) {
2478 reg_w(ov, R511_CAM_UV_EN, 0x00);
2479 reg_w(ov, R511_SNAP_UV_EN, 0x00);
2480 reg_w(ov, R511_SNAP_OPTS, 0x01);
2481 } else {
2482 reg_w(ov, R511_CAM_UV_EN, 0x01);
2483 reg_w(ov, R511_SNAP_UV_EN, 0x01);
2484 reg_w(ov, R511_SNAP_OPTS, 0x03);
2485 }
2486
2487 /* Here I'm assuming that snapshot size == image size.
2488 * I hope that's always true. --claudio
2489 */
2490 hsegs = (width >> 3) - 1;
2491 vsegs = (height >> 3) - 1;
2492
2493 reg_w(ov, R511_CAM_PXCNT, hsegs);
2494 reg_w(ov, R511_CAM_LNCNT, vsegs);
2495 reg_w(ov, R511_CAM_PXDIV, 0x00);
2496 reg_w(ov, R511_CAM_LNDIV, 0x00);
2497
2498 /* YUV420, low pass filter on */
2499 reg_w(ov, R511_CAM_OPTS, 0x03);
2500
2501 /* Snapshot additions */
2502 reg_w(ov, R511_SNAP_PXCNT, hsegs);
2503 reg_w(ov, R511_SNAP_LNCNT, vsegs);
2504 reg_w(ov, R511_SNAP_PXDIV, 0x00);
2505 reg_w(ov, R511_SNAP_LNDIV, 0x00);
2506
2507 if (ov->compress) {
2508 /* Enable Y and UV quantization and compression */
2509 reg_w(ov, R511_COMP_EN, 0x07);
2510 reg_w(ov, R511_COMP_LUT_EN, 0x03);
2511 ov51x_reset(ov, OV511_RESET_OMNICE);
2512 }
2513
2514 if (ov51x_restart(ov) < 0)
2515 return -EIO;
2516
2517 return 0;
2518}
2519
2520/* Sets up the OV518/OV518+ with the given image parameters
2521 *
2522 * OV518 needs a completely different approach, until we can figure out what
2523 * the individual registers do. Also, only 15 FPS is supported now.
2524 *
2525 * Do not put any sensor-specific code in here (including I2C I/O functions)
2526 */
2527static int
2528ov518_mode_init_regs(struct usb_ov511 *ov,
2529 int width, int height, int mode, int sub_flag)
2530{
2531 int hsegs, vsegs, hi_res;
2532
2533 if (sub_flag) {
2534 width = ov->subw;
2535 height = ov->subh;
2536 }
2537
2538 PDEBUG(3, "width:%d, height:%d, mode:%d, sub:%d",
2539 width, height, mode, sub_flag);
2540
2541 if (width % 16 || height % 8) {
2542 err("Invalid size (%d, %d)", width, height);
2543 return -EINVAL;
2544 }
2545
2546 if (width < ov->minwidth || height < ov->minheight) {
2547 err("Requested dimensions are too small");
2548 return -EINVAL;
2549 }
2550
2551 if (width >= 320 && height >= 240) {
2552 hi_res = 1;
2553 } else if (width >= 320 || height >= 240) {
2554 err("Invalid width/height combination (%d, %d)", width, height);
2555 return -EINVAL;
2556 } else {
2557 hi_res = 0;
2558 }
2559
2560 if (ov51x_stop(ov) < 0)
2561 return -EIO;
2562
2563 /******** Set the mode ********/
2564
2565 reg_w(ov, 0x2b, 0);
2566 reg_w(ov, 0x2c, 0);
2567 reg_w(ov, 0x2d, 0);
2568 reg_w(ov, 0x2e, 0);
2569 reg_w(ov, 0x3b, 0);
2570 reg_w(ov, 0x3c, 0);
2571 reg_w(ov, 0x3d, 0);
2572 reg_w(ov, 0x3e, 0);
2573
2574 if (ov->bridge == BRG_OV518 && ov518_color) {
2575 /* OV518 needs U and V swapped */
2576 i2c_w_mask(ov, 0x15, 0x00, 0x01);
2577
2578 if (mode == VIDEO_PALETTE_GREY) {
2579 /* Set 16-bit input format (UV data are ignored) */
2580 reg_w_mask(ov, 0x20, 0x00, 0x08);
2581
2582 /* Set 8-bit (4:0:0) output format */
2583 reg_w_mask(ov, 0x28, 0x00, 0xf0);
2584 reg_w_mask(ov, 0x38, 0x00, 0xf0);
2585 } else {
2586 /* Set 8-bit (YVYU) input format */
2587 reg_w_mask(ov, 0x20, 0x08, 0x08);
2588
2589 /* Set 12-bit (4:2:0) output format */
2590 reg_w_mask(ov, 0x28, 0x80, 0xf0);
2591 reg_w_mask(ov, 0x38, 0x80, 0xf0);
2592 }
2593 } else {
2594 reg_w(ov, 0x28, (mode == VIDEO_PALETTE_GREY) ? 0x00:0x80);
2595 reg_w(ov, 0x38, (mode == VIDEO_PALETTE_GREY) ? 0x00:0x80);
2596 }
2597
2598 hsegs = width / 16;
2599 vsegs = height / 4;
2600
2601 reg_w(ov, 0x29, hsegs);
2602 reg_w(ov, 0x2a, vsegs);
2603
2604 reg_w(ov, 0x39, hsegs);
2605 reg_w(ov, 0x3a, vsegs);
2606
2607 /* Windows driver does this here; who knows why */
2608 reg_w(ov, 0x2f, 0x80);
2609
2610 /******** Set the framerate (to 15 FPS) ********/
2611
2612 /* Mode independent, but framerate dependent, regs */
2613 reg_w(ov, 0x51, 0x02); /* Clock divider; lower==faster */
2614 reg_w(ov, 0x22, 0x18);
2615 reg_w(ov, 0x23, 0xff);
2616
2617 if (ov->bridge == BRG_OV518PLUS)
2618 reg_w(ov, 0x21, 0x19);
2619 else
2620 reg_w(ov, 0x71, 0x19); /* Compression-related? */
2621
2622 // FIXME: Sensor-specific
2623 /* Bit 5 is what matters here. Of course, it is "reserved" */
2624 i2c_w(ov, 0x54, 0x23);
2625
2626 reg_w(ov, 0x2f, 0x80);
2627
2628 if (ov->bridge == BRG_OV518PLUS) {
2629 reg_w(ov, 0x24, 0x94);
2630 reg_w(ov, 0x25, 0x90);
2631 ov518_reg_w32(ov, 0xc4, 400, 2); /* 190h */
2632 ov518_reg_w32(ov, 0xc6, 540, 2); /* 21ch */
2633 ov518_reg_w32(ov, 0xc7, 540, 2); /* 21ch */
2634 ov518_reg_w32(ov, 0xc8, 108, 2); /* 6ch */
2635 ov518_reg_w32(ov, 0xca, 131098, 3); /* 2001ah */
2636 ov518_reg_w32(ov, 0xcb, 532, 2); /* 214h */
2637 ov518_reg_w32(ov, 0xcc, 2400, 2); /* 960h */
2638 ov518_reg_w32(ov, 0xcd, 32, 2); /* 20h */
2639 ov518_reg_w32(ov, 0xce, 608, 2); /* 260h */
2640 } else {
2641 reg_w(ov, 0x24, 0x9f);
2642 reg_w(ov, 0x25, 0x90);
2643 ov518_reg_w32(ov, 0xc4, 400, 2); /* 190h */
2644 ov518_reg_w32(ov, 0xc6, 500, 2); /* 1f4h */
2645 ov518_reg_w32(ov, 0xc7, 500, 2); /* 1f4h */
2646 ov518_reg_w32(ov, 0xc8, 142, 2); /* 8eh */
2647 ov518_reg_w32(ov, 0xca, 131098, 3); /* 2001ah */
2648 ov518_reg_w32(ov, 0xcb, 532, 2); /* 214h */
2649 ov518_reg_w32(ov, 0xcc, 2000, 2); /* 7d0h */
2650 ov518_reg_w32(ov, 0xcd, 32, 2); /* 20h */
2651 ov518_reg_w32(ov, 0xce, 608, 2); /* 260h */
2652 }
2653
2654 reg_w(ov, 0x2f, 0x80);
2655
2656 if (ov51x_restart(ov) < 0)
2657 return -EIO;
2658
2659 /* Reset it just for good measure */
2660 if (ov51x_reset(ov, OV511_RESET_NOREGS) < 0)
2661 return -EIO;
2662
2663 return 0;
2664}
2665
2666/* This is a wrapper around the OV511, OV518, and sensor specific functions */
2667static int
2668mode_init_regs(struct usb_ov511 *ov,
2669 int width, int height, int mode, int sub_flag)
2670{
2671 int rc = 0;
2672
2673 if (!ov || !ov->dev)
2674 return -EFAULT;
2675
2676 if (ov->bclass == BCL_OV518) {
2677 rc = ov518_mode_init_regs(ov, width, height, mode, sub_flag);
2678 } else {
2679 rc = ov511_mode_init_regs(ov, width, height, mode, sub_flag);
2680 }
2681
2682 if (FATAL_ERROR(rc))
2683 return rc;
2684
2685 switch (ov->sensor) {
2686 case SEN_OV7610:
2687 case SEN_OV7620:
2688 case SEN_OV76BE:
2689 case SEN_OV8600:
2690 case SEN_OV6620:
2691 case SEN_OV6630:
2692 rc = set_ov_sensor_window(ov, width, height, mode, sub_flag);
2693 break;
2694 case SEN_KS0127:
2695 case SEN_KS0127B:
2696 err("KS0127-series decoders not supported yet");
2697 rc = -EINVAL;
2698 break;
2699 case SEN_SAA7111A:
2700// rc = mode_init_saa_sensor_regs(ov, width, height, mode,
2701// sub_flag);
2702
2703 PDEBUG(1, "SAA status = 0x%02X", i2c_r(ov, 0x1f));
2704 break;
2705 default:
2706 err("Unknown sensor");
2707 rc = -EINVAL;
2708 }
2709
2710 if (FATAL_ERROR(rc))
2711 return rc;
2712
2713 /* Sensor-independent settings */
2714 rc = sensor_set_auto_brightness(ov, ov->auto_brt);
2715 if (FATAL_ERROR(rc))
2716 return rc;
2717
2718 rc = sensor_set_auto_exposure(ov, ov->auto_exp);
2719 if (FATAL_ERROR(rc))
2720 return rc;
2721
2722 rc = sensor_set_banding_filter(ov, bandingfilter);
2723 if (FATAL_ERROR(rc))
2724 return rc;
2725
2726 if (ov->lightfreq) {
2727 rc = sensor_set_light_freq(ov, lightfreq);
2728 if (FATAL_ERROR(rc))
2729 return rc;
2730 }
2731
2732 rc = sensor_set_backlight(ov, ov->backlight);
2733 if (FATAL_ERROR(rc))
2734 return rc;
2735
2736 rc = sensor_set_mirror(ov, ov->mirror);
2737 if (FATAL_ERROR(rc))
2738 return rc;
2739
2740 return 0;
2741}
2742
2743/* This sets the default image parameters. This is useful for apps that use
2744 * read() and do not set these.
2745 */
2746static int
2747ov51x_set_default_params(struct usb_ov511 *ov)
2748{
2749 int i;
2750
2751 /* Set default sizes in case IOCTL (VIDIOCMCAPTURE) is not used
2752 * (using read() instead). */
2753 for (i = 0; i < OV511_NUMFRAMES; i++) {
2754 ov->frame[i].width = ov->maxwidth;
2755 ov->frame[i].height = ov->maxheight;
2756 ov->frame[i].bytes_read = 0;
2757 if (force_palette)
2758 ov->frame[i].format = force_palette;
2759 else
2760 ov->frame[i].format = VIDEO_PALETTE_YUV420;
2761
2762 ov->frame[i].depth = get_depth(ov->frame[i].format);
2763 }
2764
2765 PDEBUG(3, "%dx%d, %s", ov->maxwidth, ov->maxheight,
2766 symbolic(v4l1_plist, ov->frame[0].format));
2767
2768 /* Initialize to max width/height, YUV420 or RGB24 (if supported) */
2769 if (mode_init_regs(ov, ov->maxwidth, ov->maxheight,
2770 ov->frame[0].format, 0) < 0)
2771 return -EINVAL;
2772
2773 return 0;
2774}
2775
2776/**********************************************************************
2777 *
2778 * Video decoder stuff
2779 *
2780 **********************************************************************/
2781
2782/* Set analog input port of decoder */
2783static int
2784decoder_set_input(struct usb_ov511 *ov, int input)
2785{
2786 PDEBUG(4, "port %d", input);
2787
2788 switch (ov->sensor) {
2789 case SEN_SAA7111A:
2790 {
2791 /* Select mode */
2792 i2c_w_mask(ov, 0x02, input, 0x07);
2793 /* Bypass chrominance trap for modes 4..7 */
2794 i2c_w_mask(ov, 0x09, (input > 3) ? 0x80:0x00, 0x80);
2795 break;
2796 }
2797 default:
2798 return -EINVAL;
2799 }
2800
2801 return 0;
2802}
2803
2804/* Get ASCII name of video input */
2805static int
2806decoder_get_input_name(struct usb_ov511 *ov, int input, char *name)
2807{
2808 switch (ov->sensor) {
2809 case SEN_SAA7111A:
2810 {
2811 if (input < 0 || input > 7)
2812 return -EINVAL;
2813 else if (input < 4)
2814 sprintf(name, "CVBS-%d", input);
2815 else // if (input < 8)
2816 sprintf(name, "S-Video-%d", input - 4);
2817 break;
2818 }
2819 default:
2820 sprintf(name, "%s", "Camera");
2821 }
2822
2823 return 0;
2824}
2825
2826/* Set norm (NTSC, PAL, SECAM, AUTO) */
2827static int
2828decoder_set_norm(struct usb_ov511 *ov, int norm)
2829{
2830 PDEBUG(4, "%d", norm);
2831
2832 switch (ov->sensor) {
2833 case SEN_SAA7111A:
2834 {
2835 int reg_8, reg_e;
2836
2837 if (norm == VIDEO_MODE_NTSC) {
2838 reg_8 = 0x40; /* 60 Hz */
2839 reg_e = 0x00; /* NTSC M / PAL BGHI */
2840 } else if (norm == VIDEO_MODE_PAL) {
2841 reg_8 = 0x00; /* 50 Hz */
2842 reg_e = 0x00; /* NTSC M / PAL BGHI */
2843 } else if (norm == VIDEO_MODE_AUTO) {
2844 reg_8 = 0x80; /* Auto field detect */
2845 reg_e = 0x00; /* NTSC M / PAL BGHI */
2846 } else if (norm == VIDEO_MODE_SECAM) {
2847 reg_8 = 0x00; /* 50 Hz */
2848 reg_e = 0x50; /* SECAM / PAL 4.43 */
2849 } else {
2850 return -EINVAL;
2851 }
2852
2853 i2c_w_mask(ov, 0x08, reg_8, 0xc0);
2854 i2c_w_mask(ov, 0x0e, reg_e, 0x70);
2855 break;
2856 }
2857 default:
2858 return -EINVAL;
2859 }
2860
2861 return 0;
2862}
2863
2864/**********************************************************************
2865 *
2866 * Raw data parsing
2867 *
2868 **********************************************************************/
2869
2870/* Copies a 64-byte segment at pIn to an 8x8 block at pOut. The width of the
2871 * image at pOut is specified by w.
2872 */
2873static inline void
2874make_8x8(unsigned char *pIn, unsigned char *pOut, int w)
2875{
2876 unsigned char *pOut1 = pOut;
2877 int x, y;
2878
2879 for (y = 0; y < 8; y++) {
2880 pOut1 = pOut;
2881 for (x = 0; x < 8; x++) {
2882 *pOut1++ = *pIn++;
2883 }
2884 pOut += w;
2885 }
2886}
2887
2888/*
2889 * For RAW BW (YUV 4:0:0) images, data show up in 256 byte segments.
2890 * The segments represent 4 squares of 8x8 pixels as follows:
2891 *
2892 * 0 1 ... 7 64 65 ... 71 ... 192 193 ... 199
2893 * 8 9 ... 15 72 73 ... 79 200 201 ... 207
2894 * ... ... ...
2895 * 56 57 ... 63 120 121 ... 127 248 249 ... 255
2896 *
2897 */
2898static void
2899yuv400raw_to_yuv400p(struct ov511_frame *frame,
2900 unsigned char *pIn0, unsigned char *pOut0)
2901{
2902 int x, y;
2903 unsigned char *pIn, *pOut, *pOutLine;
2904
2905 /* Copy Y */
2906 pIn = pIn0;
2907 pOutLine = pOut0;
2908 for (y = 0; y < frame->rawheight - 1; y += 8) {
2909 pOut = pOutLine;
2910 for (x = 0; x < frame->rawwidth - 1; x += 8) {
2911 make_8x8(pIn, pOut, frame->rawwidth);
2912 pIn += 64;
2913 pOut += 8;
2914 }
2915 pOutLine += 8 * frame->rawwidth;
2916 }
2917}
2918
2919/*
2920 * For YUV 4:2:0 images, the data show up in 384 byte segments.
2921 * The first 64 bytes of each segment are U, the next 64 are V. The U and
2922 * V are arranged as follows:
2923 *
2924 * 0 1 ... 7
2925 * 8 9 ... 15
2926 * ...
2927 * 56 57 ... 63
2928 *
2929 * U and V are shipped at half resolution (1 U,V sample -> one 2x2 block).
2930 *
2931 * The next 256 bytes are full resolution Y data and represent 4 squares
2932 * of 8x8 pixels as follows:
2933 *
2934 * 0 1 ... 7 64 65 ... 71 ... 192 193 ... 199
2935 * 8 9 ... 15 72 73 ... 79 200 201 ... 207
2936 * ... ... ...
2937 * 56 57 ... 63 120 121 ... 127 ... 248 249 ... 255
2938 *
2939 * Note that the U and V data in one segment represent a 16 x 16 pixel
2940 * area, but the Y data represent a 32 x 8 pixel area. If the width is not an
2941 * even multiple of 32, the extra 8x8 blocks within a 32x8 block belong to the
2942 * next horizontal stripe.
2943 *
2944 * If dumppix module param is set, _parse_data just dumps the incoming segments,
2945 * verbatim, in order, into the frame. When used with vidcat -f ppm -s 640x480
2946 * this puts the data on the standard output and can be analyzed with the
2947 * parseppm.c utility I wrote. That's a much faster way for figuring out how
2948 * these data are scrambled.
2949 */
2950
2951/* Converts from raw, uncompressed segments at pIn0 to a YUV420P frame at pOut0.
2952 *
2953 * FIXME: Currently only handles width and height that are multiples of 16
2954 */
2955static void
2956yuv420raw_to_yuv420p(struct ov511_frame *frame,
2957 unsigned char *pIn0, unsigned char *pOut0)
2958{
2959 int k, x, y;
2960 unsigned char *pIn, *pOut, *pOutLine;
2961 const unsigned int a = frame->rawwidth * frame->rawheight;
2962 const unsigned int w = frame->rawwidth / 2;
2963
2964 /* Copy U and V */
2965 pIn = pIn0;
2966 pOutLine = pOut0 + a;
2967 for (y = 0; y < frame->rawheight - 1; y += 16) {
2968 pOut = pOutLine;
2969 for (x = 0; x < frame->rawwidth - 1; x += 16) {
2970 make_8x8(pIn, pOut, w);
2971 make_8x8(pIn + 64, pOut + a/4, w);
2972 pIn += 384;
2973 pOut += 8;
2974 }
2975 pOutLine += 8 * w;
2976 }
2977
2978 /* Copy Y */
2979 pIn = pIn0 + 128;
2980 pOutLine = pOut0;
2981 k = 0;
2982 for (y = 0; y < frame->rawheight - 1; y += 8) {
2983 pOut = pOutLine;
2984 for (x = 0; x < frame->rawwidth - 1; x += 8) {
2985 make_8x8(pIn, pOut, frame->rawwidth);
2986 pIn += 64;
2987 pOut += 8;
2988 if ((++k) > 3) {
2989 k = 0;
2990 pIn += 128;
2991 }
2992 }
2993 pOutLine += 8 * frame->rawwidth;
2994 }
2995}
2996
2997/**********************************************************************
2998 *
2999 * Decompression
3000 *
3001 **********************************************************************/
3002
3003static int
3004request_decompressor(struct usb_ov511 *ov)
3005{
3006 if (ov->bclass == BCL_OV511 || ov->bclass == BCL_OV518) {
3007 err("No decompressor available");
3008 } else {
3009 err("Unknown bridge");
3010 }
3011
3012 return -ENOSYS;
3013}
3014
3015static void
3016decompress(struct usb_ov511 *ov, struct ov511_frame *frame,
3017 unsigned char *pIn0, unsigned char *pOut0)
3018{
3019 if (!ov->decomp_ops)
3020 if (request_decompressor(ov))
3021 return;
3022
3023}
3024
3025/**********************************************************************
3026 *
3027 * Format conversion
3028 *
3029 **********************************************************************/
3030
3031/* Fuses even and odd fields together, and doubles width.
3032 * INPUT: an odd field followed by an even field at pIn0, in YUV planar format
3033 * OUTPUT: a normal YUV planar image, with correct aspect ratio
3034 */
3035static void
3036deinterlace(struct ov511_frame *frame, int rawformat,
3037 unsigned char *pIn0, unsigned char *pOut0)
3038{
3039 const int fieldheight = frame->rawheight / 2;
3040 const int fieldpix = fieldheight * frame->rawwidth;
3041 const int w = frame->width;
3042 int x, y;
3043 unsigned char *pInEven, *pInOdd, *pOut;
3044
3045 PDEBUG(5, "fieldheight=%d", fieldheight);
3046
3047 if (frame->rawheight != frame->height) {
3048 err("invalid height");
3049 return;
3050 }
3051
3052 if ((frame->rawwidth * 2) != frame->width) {
3053 err("invalid width");
3054 return;
3055 }
3056
3057 /* Y */
3058 pInOdd = pIn0;
3059 pInEven = pInOdd + fieldpix;
3060 pOut = pOut0;
3061 for (y = 0; y < fieldheight; y++) {
3062 for (x = 0; x < frame->rawwidth; x++) {
3063 *pOut = *pInEven;
3064 *(pOut+1) = *pInEven++;
3065 *(pOut+w) = *pInOdd;
3066 *(pOut+w+1) = *pInOdd++;
3067 pOut += 2;
3068 }
3069 pOut += w;
3070 }
3071
3072 if (rawformat == RAWFMT_YUV420) {
3073 /* U */
3074 pInOdd = pIn0 + fieldpix * 2;
3075 pInEven = pInOdd + fieldpix / 4;
3076 for (y = 0; y < fieldheight / 2; y++) {
3077 for (x = 0; x < frame->rawwidth / 2; x++) {
3078 *pOut = *pInEven;
3079 *(pOut+1) = *pInEven++;
3080 *(pOut+w/2) = *pInOdd;
3081 *(pOut+w/2+1) = *pInOdd++;
3082 pOut += 2;
3083 }
3084 pOut += w/2;
3085 }
3086 /* V */
3087 pInOdd = pIn0 + fieldpix * 2 + fieldpix / 2;
3088 pInEven = pInOdd + fieldpix / 4;
3089 for (y = 0; y < fieldheight / 2; y++) {
3090 for (x = 0; x < frame->rawwidth / 2; x++) {
3091 *pOut = *pInEven;
3092 *(pOut+1) = *pInEven++;
3093 *(pOut+w/2) = *pInOdd;
3094 *(pOut+w/2+1) = *pInOdd++;
3095 pOut += 2;
3096 }
3097 pOut += w/2;
3098 }
3099 }
3100}
3101
3102static void
3103ov51x_postprocess_grey(struct usb_ov511 *ov, struct ov511_frame *frame)
3104{
3105 /* Deinterlace frame, if necessary */
3106 if (ov->sensor == SEN_SAA7111A && frame->rawheight >= 480) {
3107 if (frame->compressed)
3108 decompress(ov, frame, frame->rawdata,
3109 frame->tempdata);
3110 else
3111 yuv400raw_to_yuv400p(frame, frame->rawdata,
3112 frame->tempdata);
3113
3114 deinterlace(frame, RAWFMT_YUV400, frame->tempdata,
3115 frame->data);
3116 } else {
3117 if (frame->compressed)
3118 decompress(ov, frame, frame->rawdata,
3119 frame->data);
3120 else
3121 yuv400raw_to_yuv400p(frame, frame->rawdata,
3122 frame->data);
3123 }
3124}
3125
3126/* Process raw YUV420 data into standard YUV420P */
3127static void
3128ov51x_postprocess_yuv420(struct usb_ov511 *ov, struct ov511_frame *frame)
3129{
3130 /* Deinterlace frame, if necessary */
3131 if (ov->sensor == SEN_SAA7111A && frame->rawheight >= 480) {
3132 if (frame->compressed)
3133 decompress(ov, frame, frame->rawdata, frame->tempdata);
3134 else
3135 yuv420raw_to_yuv420p(frame, frame->rawdata,
3136 frame->tempdata);
3137
3138 deinterlace(frame, RAWFMT_YUV420, frame->tempdata,
3139 frame->data);
3140 } else {
3141 if (frame->compressed)
3142 decompress(ov, frame, frame->rawdata, frame->data);
3143 else
3144 yuv420raw_to_yuv420p(frame, frame->rawdata,
3145 frame->data);
3146 }
3147}
3148
3149/* Post-processes the specified frame. This consists of:
3150 * 1. Decompress frame, if necessary
3151 * 2. Deinterlace frame and scale to proper size, if necessary
3152 * 3. Convert from YUV planar to destination format, if necessary
3153 * 4. Fix the RGB offset, if necessary
3154 */
3155static void
3156ov51x_postprocess(struct usb_ov511 *ov, struct ov511_frame *frame)
3157{
3158 if (dumppix) {
3159 memset(frame->data, 0,
3160 MAX_DATA_SIZE(ov->maxwidth, ov->maxheight));
3161 PDEBUG(4, "Dumping %d bytes", frame->bytes_recvd);
3162 memcpy(frame->data, frame->rawdata, frame->bytes_recvd);
3163 } else {
3164 switch (frame->format) {
3165 case VIDEO_PALETTE_GREY:
3166 ov51x_postprocess_grey(ov, frame);
3167 break;
3168 case VIDEO_PALETTE_YUV420:
3169 case VIDEO_PALETTE_YUV420P:
3170 ov51x_postprocess_yuv420(ov, frame);
3171 break;
3172 default:
3173 err("Cannot convert data to %s",
3174 symbolic(v4l1_plist, frame->format));
3175 }
3176 }
3177}
3178
3179/**********************************************************************
3180 *
3181 * OV51x data transfer, IRQ handler
3182 *
3183 **********************************************************************/
3184
3185static inline void
3186ov511_move_data(struct usb_ov511 *ov, unsigned char *in, int n)
3187{
3188 int num, offset;
3189 int pnum = in[ov->packet_size - 1]; /* Get packet number */
3190 int max_raw = MAX_RAW_DATA_SIZE(ov->maxwidth, ov->maxheight);
3191 struct ov511_frame *frame = &ov->frame[ov->curframe];
3192 struct timeval *ts;
3193
3194 /* SOF/EOF packets have 1st to 8th bytes zeroed and the 9th
3195 * byte non-zero. The EOF packet has image width/height in the
3196 * 10th and 11th bytes. The 9th byte is given as follows:
3197 *
3198 * bit 7: EOF
3199 * 6: compression enabled
3200 * 5: 422/420/400 modes
3201 * 4: 422/420/400 modes
3202 * 3: 1
3203 * 2: snapshot button on
3204 * 1: snapshot frame
3205 * 0: even/odd field
3206 */
3207
3208 if (printph) {
3209 info("ph(%3d): %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x",
3210 pnum, in[0], in[1], in[2], in[3], in[4], in[5], in[6],
3211 in[7], in[8], in[9], in[10], in[11]);
3212 }
3213
3214 /* Check for SOF/EOF packet */
3215 if ((in[0] | in[1] | in[2] | in[3] | in[4] | in[5] | in[6] | in[7]) ||
3216 (~in[8] & 0x08))
3217 goto check_middle;
3218
3219 /* Frame end */
3220 if (in[8] & 0x80) {
3221 ts = (struct timeval *)(frame->data
3222 + MAX_FRAME_SIZE(ov->maxwidth, ov->maxheight));
3223 do_gettimeofday(ts);
3224
3225 /* Get the actual frame size from the EOF header */
3226 frame->rawwidth = ((int)(in[9]) + 1) * 8;
3227 frame->rawheight = ((int)(in[10]) + 1) * 8;
3228
3229 PDEBUG(4, "Frame end, frame=%d, pnum=%d, w=%d, h=%d, recvd=%d",
3230 ov->curframe, pnum, frame->rawwidth, frame->rawheight,
3231 frame->bytes_recvd);
3232
3233 /* Validate the header data */
3234 RESTRICT_TO_RANGE(frame->rawwidth, ov->minwidth, ov->maxwidth);
3235 RESTRICT_TO_RANGE(frame->rawheight, ov->minheight,
3236 ov->maxheight);
3237
3238 /* Don't allow byte count to exceed buffer size */
3239 RESTRICT_TO_RANGE(frame->bytes_recvd, 8, max_raw);
3240
3241 if (frame->scanstate == STATE_LINES) {
3242 int nextf;
3243
3244 frame->grabstate = FRAME_DONE;
3245 wake_up_interruptible(&frame->wq);
3246
3247 /* If next frame is ready or grabbing,
3248 * point to it */
3249 nextf = (ov->curframe + 1) % OV511_NUMFRAMES;
3250 if (ov->frame[nextf].grabstate == FRAME_READY
3251 || ov->frame[nextf].grabstate == FRAME_GRABBING) {
3252 ov->curframe = nextf;
3253 ov->frame[nextf].scanstate = STATE_SCANNING;
3254 } else {
3255 if (frame->grabstate == FRAME_DONE) {
3256 PDEBUG(4, "** Frame done **");
3257 } else {
3258 PDEBUG(4, "Frame not ready? state = %d",
3259 ov->frame[nextf].grabstate);
3260 }
3261
3262 ov->curframe = -1;
3263 }
3264 } else {
3265 PDEBUG(5, "Frame done, but not scanning");
3266 }
3267 /* Image corruption caused by misplaced frame->segment = 0
3268 * fixed by carlosf@conectiva.com.br
3269 */
3270 } else {
3271 /* Frame start */
3272 PDEBUG(4, "Frame start, framenum = %d", ov->curframe);
3273
3274 /* Check to see if it's a snapshot frame */
3275 /* FIXME?? Should the snapshot reset go here? Performance? */
3276 if (in[8] & 0x02) {
3277 frame->snapshot = 1;
3278 PDEBUG(3, "snapshot detected");
3279 }
3280
3281 frame->scanstate = STATE_LINES;
3282 frame->bytes_recvd = 0;
3283 frame->compressed = in[8] & 0x40;
3284 }
3285
3286check_middle:
3287 /* Are we in a frame? */
3288 if (frame->scanstate != STATE_LINES) {
3289 PDEBUG(5, "Not in a frame; packet skipped");
3290 return;
3291 }
3292
3293 /* If frame start, skip header */
3294 if (frame->bytes_recvd == 0)
3295 offset = 9;
3296 else
3297 offset = 0;
3298
3299 num = n - offset - 1;
3300
3301 /* Dump all data exactly as received */
3302 if (dumppix == 2) {
3303 frame->bytes_recvd += n - 1;
3304 if (frame->bytes_recvd <= max_raw)
3305 memcpy(frame->rawdata + frame->bytes_recvd - (n - 1),
3306 in, n - 1);
3307 else
3308 PDEBUG(3, "Raw data buffer overrun!! (%d)",
3309 frame->bytes_recvd - max_raw);
3310 } else if (!frame->compressed && !remove_zeros) {
3311 frame->bytes_recvd += num;
3312 if (frame->bytes_recvd <= max_raw)
3313 memcpy(frame->rawdata + frame->bytes_recvd - num,
3314 in + offset, num);
3315 else
3316 PDEBUG(3, "Raw data buffer overrun!! (%d)",
3317 frame->bytes_recvd - max_raw);
3318 } else { /* Remove all-zero FIFO lines (aligned 32-byte blocks) */
3319 int b, read = 0, allzero, copied = 0;
3320 if (offset) {
3321 frame->bytes_recvd += 32 - offset; // Bytes out
3322 memcpy(frame->rawdata, in + offset, 32 - offset);
3323 read += 32;
3324 }
3325
3326 while (read < n - 1) {
3327 allzero = 1;
3328 for (b = 0; b < 32; b++) {
3329 if (in[read + b]) {
3330 allzero = 0;
3331 break;
3332 }
3333 }
3334
3335 if (allzero) {
3336 /* Don't copy it */
3337 } else {
3338 if (frame->bytes_recvd + copied + 32 <= max_raw)
3339 {
3340 memcpy(frame->rawdata
3341 + frame->bytes_recvd + copied,
3342 in + read, 32);
3343 copied += 32;
3344 } else {
3345 PDEBUG(3, "Raw data buffer overrun!!");
3346 }
3347 }
3348 read += 32;
3349 }
3350
3351 frame->bytes_recvd += copied;
3352 }
3353}
3354
3355static inline void
3356ov518_move_data(struct usb_ov511 *ov, unsigned char *in, int n)
3357{
3358 int max_raw = MAX_RAW_DATA_SIZE(ov->maxwidth, ov->maxheight);
3359 struct ov511_frame *frame = &ov->frame[ov->curframe];
3360 struct timeval *ts;
3361
3362 /* Don't copy the packet number byte */
3363 if (ov->packet_numbering)
3364 --n;
3365
3366 /* A false positive here is likely, until OVT gives me
3367 * the definitive SOF/EOF format */
3368 if ((!(in[0] | in[1] | in[2] | in[3] | in[5])) && in[6]) {
3369 if (printph) {
3370 info("ph: %2x %2x %2x %2x %2x %2x %2x %2x", in[0],
3371 in[1], in[2], in[3], in[4], in[5], in[6], in[7]);
3372 }
3373
3374 if (frame->scanstate == STATE_LINES) {
3375 PDEBUG(4, "Detected frame end/start");
3376 goto eof;
3377 } else { //scanstate == STATE_SCANNING
3378 /* Frame start */
3379 PDEBUG(4, "Frame start, framenum = %d", ov->curframe);
3380 goto sof;
3381 }
3382 } else {
3383 goto check_middle;
3384 }
3385
3386eof:
3387 ts = (struct timeval *)(frame->data
3388 + MAX_FRAME_SIZE(ov->maxwidth, ov->maxheight));
3389 do_gettimeofday(ts);
3390
3391 PDEBUG(4, "Frame end, curframe = %d, hw=%d, vw=%d, recvd=%d",
3392 ov->curframe,
3393 (int)(in[9]), (int)(in[10]), frame->bytes_recvd);
3394
3395 // FIXME: Since we don't know the header formats yet,
3396 // there is no way to know what the actual image size is
3397 frame->rawwidth = frame->width;
3398 frame->rawheight = frame->height;
3399
3400 /* Validate the header data */
3401 RESTRICT_TO_RANGE(frame->rawwidth, ov->minwidth, ov->maxwidth);
3402 RESTRICT_TO_RANGE(frame->rawheight, ov->minheight, ov->maxheight);
3403
3404 /* Don't allow byte count to exceed buffer size */
3405 RESTRICT_TO_RANGE(frame->bytes_recvd, 8, max_raw);
3406
3407 if (frame->scanstate == STATE_LINES) {
3408 int nextf;
3409
3410 frame->grabstate = FRAME_DONE;
3411 wake_up_interruptible(&frame->wq);
3412
3413 /* If next frame is ready or grabbing,
3414 * point to it */
3415 nextf = (ov->curframe + 1) % OV511_NUMFRAMES;
3416 if (ov->frame[nextf].grabstate == FRAME_READY
3417 || ov->frame[nextf].grabstate == FRAME_GRABBING) {
3418 ov->curframe = nextf;
3419 ov->frame[nextf].scanstate = STATE_SCANNING;
3420 frame = &ov->frame[nextf];
3421 } else {
3422 if (frame->grabstate == FRAME_DONE) {
3423 PDEBUG(4, "** Frame done **");
3424 } else {
3425 PDEBUG(4, "Frame not ready? state = %d",
3426 ov->frame[nextf].grabstate);
3427 }
3428
3429 ov->curframe = -1;
3430 PDEBUG(4, "SOF dropped (no active frame)");
3431 return; /* Nowhere to store this frame */
3432 }
3433 }
3434sof:
3435 PDEBUG(4, "Starting capture on frame %d", frame->framenum);
3436
3437// Snapshot not reverse-engineered yet.
3438#if 0
3439 /* Check to see if it's a snapshot frame */
3440 /* FIXME?? Should the snapshot reset go here? Performance? */
3441 if (in[8] & 0x02) {
3442 frame->snapshot = 1;
3443 PDEBUG(3, "snapshot detected");
3444 }
3445#endif
3446 frame->scanstate = STATE_LINES;
3447 frame->bytes_recvd = 0;
3448 frame->compressed = 1;
3449
3450check_middle:
3451 /* Are we in a frame? */
3452 if (frame->scanstate != STATE_LINES) {
3453 PDEBUG(4, "scanstate: no SOF yet");
3454 return;
3455 }
3456
3457 /* Dump all data exactly as received */
3458 if (dumppix == 2) {
3459 frame->bytes_recvd += n;
3460 if (frame->bytes_recvd <= max_raw)
3461 memcpy(frame->rawdata + frame->bytes_recvd - n, in, n);
3462 else
3463 PDEBUG(3, "Raw data buffer overrun!! (%d)",
3464 frame->bytes_recvd - max_raw);
3465 } else {
3466 /* All incoming data are divided into 8-byte segments. If the
3467 * segment contains all zero bytes, it must be skipped. These
3468 * zero-segments allow the OV518 to mainain a constant data rate
3469 * regardless of the effectiveness of the compression. Segments
3470 * are aligned relative to the beginning of each isochronous
3471 * packet. The first segment in each image is a header (the
3472 * decompressor skips it later).
3473 */
3474
3475 int b, read = 0, allzero, copied = 0;
3476
3477 while (read < n) {
3478 allzero = 1;
3479 for (b = 0; b < 8; b++) {
3480 if (in[read + b]) {
3481 allzero = 0;
3482 break;
3483 }
3484 }
3485
3486 if (allzero) {
3487 /* Don't copy it */
3488 } else {
3489 if (frame->bytes_recvd + copied + 8 <= max_raw)
3490 {
3491 memcpy(frame->rawdata
3492 + frame->bytes_recvd + copied,
3493 in + read, 8);
3494 copied += 8;
3495 } else {
3496 PDEBUG(3, "Raw data buffer overrun!!");
3497 }
3498 }
3499 read += 8;
3500 }
3501 frame->bytes_recvd += copied;
3502 }
3503}
3504
3505static void
3506ov51x_isoc_irq(struct urb *urb, struct pt_regs *regs)
3507{
3508 int i;
3509 struct usb_ov511 *ov;
3510 struct ov511_sbuf *sbuf;
3511
3512 if (!urb->context) {
3513 PDEBUG(4, "no context");
3514 return;
3515 }
3516
3517 sbuf = urb->context;
3518 ov = sbuf->ov;
3519
3520 if (!ov || !ov->dev || !ov->user) {
3521 PDEBUG(4, "no device, or not open");
3522 return;
3523 }
3524
3525 if (!ov->streaming) {
3526 PDEBUG(4, "hmmm... not streaming, but got interrupt");
3527 return;
3528 }
3529
3530 if (urb->status == -ENOENT || urb->status == -ECONNRESET) {
3531 PDEBUG(4, "URB unlinked");
3532 return;
3533 }
3534
3535 if (urb->status != -EINPROGRESS && urb->status != 0) {
3536 err("ERROR: urb->status=%d: %s", urb->status,
3537 symbolic(urb_errlist, urb->status));
3538 }
3539
3540 /* Copy the data received into our frame buffer */
3541 PDEBUG(5, "sbuf[%d]: Moving %d packets", sbuf->n,
3542 urb->number_of_packets);
3543 for (i = 0; i < urb->number_of_packets; i++) {
3544 /* Warning: Don't call *_move_data() if no frame active! */
3545 if (ov->curframe >= 0) {
3546 int n = urb->iso_frame_desc[i].actual_length;
3547 int st = urb->iso_frame_desc[i].status;
3548 unsigned char *cdata;
3549
3550 urb->iso_frame_desc[i].actual_length = 0;
3551 urb->iso_frame_desc[i].status = 0;
3552
3553 cdata = urb->transfer_buffer
3554 + urb->iso_frame_desc[i].offset;
3555
3556 if (!n) {
3557 PDEBUG(4, "Zero-length packet");
3558 continue;
3559 }
3560
3561 if (st)
3562 PDEBUG(2, "data error: [%d] len=%d, status=%d",
3563 i, n, st);
3564
3565 if (ov->bclass == BCL_OV511)
3566 ov511_move_data(ov, cdata, n);
3567 else if (ov->bclass == BCL_OV518)
3568 ov518_move_data(ov, cdata, n);
3569 else
3570 err("Unknown bridge device (%d)", ov->bridge);
3571
3572 } else if (waitqueue_active(&ov->wq)) {
3573 wake_up_interruptible(&ov->wq);
3574 }
3575 }
3576
3577 /* Resubmit this URB */
3578 urb->dev = ov->dev;
3579 if ((i = usb_submit_urb(urb, GFP_ATOMIC)) != 0)
3580 err("usb_submit_urb() ret %d", i);
3581
3582 return;
3583}
3584
3585/****************************************************************************
3586 *
3587 * Stream initialization and termination
3588 *
3589 ***************************************************************************/
3590
3591static int
3592ov51x_init_isoc(struct usb_ov511 *ov)
3593{
3594 struct urb *urb;
3595 int fx, err, n, size;
3596
3597 PDEBUG(3, "*** Initializing capture ***");
3598
3599 ov->curframe = -1;
3600
3601 if (ov->bridge == BRG_OV511) {
3602 if (cams == 1)
3603 size = 993;
3604 else if (cams == 2)
3605 size = 513;
3606 else if (cams == 3 || cams == 4)
3607 size = 257;
3608 else {
3609 err("\"cams\" parameter too high!");
3610 return -1;
3611 }
3612 } else if (ov->bridge == BRG_OV511PLUS) {
3613 if (cams == 1)
3614 size = 961;
3615 else if (cams == 2)
3616 size = 513;
3617 else if (cams == 3 || cams == 4)
3618 size = 257;
3619 else if (cams >= 5 && cams <= 8)
3620 size = 129;
3621 else if (cams >= 9 && cams <= 31)
3622 size = 33;
3623 else {
3624 err("\"cams\" parameter too high!");
3625 return -1;
3626 }
3627 } else if (ov->bclass == BCL_OV518) {
3628 if (cams == 1)
3629 size = 896;
3630 else if (cams == 2)
3631 size = 512;
3632 else if (cams == 3 || cams == 4)
3633 size = 256;
3634 else if (cams >= 5 && cams <= 8)
3635 size = 128;
3636 else {
3637 err("\"cams\" parameter too high!");
3638 return -1;
3639 }
3640 } else {
3641 err("invalid bridge type");
3642 return -1;
3643 }
3644
3645 // FIXME: OV518 is hardcoded to 15 FPS (alternate 5) for now
3646 if (ov->bclass == BCL_OV518) {
3647 if (packetsize == -1) {
3648 ov518_set_packet_size(ov, 640);
3649 } else {
3650 info("Forcing packet size to %d", packetsize);
3651 ov518_set_packet_size(ov, packetsize);
3652 }
3653 } else {
3654 if (packetsize == -1) {
3655 ov511_set_packet_size(ov, size);
3656 } else {
3657 info("Forcing packet size to %d", packetsize);
3658 ov511_set_packet_size(ov, packetsize);
3659 }
3660 }
3661
3662 for (n = 0; n < OV511_NUMSBUF; n++) {
3663 urb = usb_alloc_urb(FRAMES_PER_DESC, GFP_KERNEL);
3664 if (!urb) {
3665 err("init isoc: usb_alloc_urb ret. NULL");
3666 return -ENOMEM;
3667 }
3668 ov->sbuf[n].urb = urb;
3669 urb->dev = ov->dev;
3670 urb->context = &ov->sbuf[n];
3671 urb->pipe = usb_rcvisocpipe(ov->dev, OV511_ENDPOINT_ADDRESS);
3672 urb->transfer_flags = URB_ISO_ASAP;
3673 urb->transfer_buffer = ov->sbuf[n].data;
3674 urb->complete = ov51x_isoc_irq;
3675 urb->number_of_packets = FRAMES_PER_DESC;
3676 urb->transfer_buffer_length = ov->packet_size * FRAMES_PER_DESC;
3677 urb->interval = 1;
3678 for (fx = 0; fx < FRAMES_PER_DESC; fx++) {
3679 urb->iso_frame_desc[fx].offset = ov->packet_size * fx;
3680 urb->iso_frame_desc[fx].length = ov->packet_size;
3681 }
3682 }
3683
3684 ov->streaming = 1;
3685
3686 for (n = 0; n < OV511_NUMSBUF; n++) {
3687 ov->sbuf[n].urb->dev = ov->dev;
3688 err = usb_submit_urb(ov->sbuf[n].urb, GFP_KERNEL);
3689 if (err) {
3690 err("init isoc: usb_submit_urb(%d) ret %d", n, err);
3691 return err;
3692 }
3693 }
3694
3695 return 0;
3696}
3697
3698static void
3699ov51x_unlink_isoc(struct usb_ov511 *ov)
3700{
3701 int n;
3702
3703 /* Unschedule all of the iso td's */
3704 for (n = OV511_NUMSBUF - 1; n >= 0; n--) {
3705 if (ov->sbuf[n].urb) {
3706 usb_kill_urb(ov->sbuf[n].urb);
3707 usb_free_urb(ov->sbuf[n].urb);
3708 ov->sbuf[n].urb = NULL;
3709 }
3710 }
3711}
3712
3713static void
3714ov51x_stop_isoc(struct usb_ov511 *ov)
3715{
3716 if (!ov->streaming || !ov->dev)
3717 return;
3718
3719 PDEBUG(3, "*** Stopping capture ***");
3720
3721 if (ov->bclass == BCL_OV518)
3722 ov518_set_packet_size(ov, 0);
3723 else
3724 ov511_set_packet_size(ov, 0);
3725
3726 ov->streaming = 0;
3727
3728 ov51x_unlink_isoc(ov);
3729}
3730
3731static int
3732ov51x_new_frame(struct usb_ov511 *ov, int framenum)
3733{
3734 struct ov511_frame *frame;
3735 int newnum;
3736
3737 PDEBUG(4, "ov->curframe = %d, framenum = %d", ov->curframe, framenum);
3738
3739 if (!ov->dev)
3740 return -1;
3741
3742 /* If we're not grabbing a frame right now and the other frame is */
3743 /* ready to be grabbed into, then use it instead */
3744 if (ov->curframe == -1) {
3745 newnum = (framenum - 1 + OV511_NUMFRAMES) % OV511_NUMFRAMES;
3746 if (ov->frame[newnum].grabstate == FRAME_READY)
3747 framenum = newnum;
3748 } else
3749 return 0;
3750
3751 frame = &ov->frame[framenum];
3752
3753 PDEBUG(4, "framenum = %d, width = %d, height = %d", framenum,
3754 frame->width, frame->height);
3755
3756 frame->grabstate = FRAME_GRABBING;
3757 frame->scanstate = STATE_SCANNING;
3758 frame->snapshot = 0;
3759
3760 ov->curframe = framenum;
3761
3762 /* Make sure it's not too big */
3763 if (frame->width > ov->maxwidth)
3764 frame->width = ov->maxwidth;
3765
3766 frame->width &= ~7L; /* Multiple of 8 */
3767
3768 if (frame->height > ov->maxheight)
3769 frame->height = ov->maxheight;
3770
3771 frame->height &= ~3L; /* Multiple of 4 */
3772
3773 return 0;
3774}
3775
3776/****************************************************************************
3777 *
3778 * Buffer management
3779 *
3780 ***************************************************************************/
3781
3782/*
3783 * - You must acquire buf_lock before entering this function.
3784 * - Because this code will free any non-null pointer, you must be sure to null
3785 * them if you explicitly free them somewhere else!
3786 */
3787static void
3788ov51x_do_dealloc(struct usb_ov511 *ov)
3789{
3790 int i;
3791 PDEBUG(4, "entered");
3792
3793 if (ov->fbuf) {
3794 rvfree(ov->fbuf, OV511_NUMFRAMES
3795 * MAX_DATA_SIZE(ov->maxwidth, ov->maxheight));
3796 ov->fbuf = NULL;
3797 }
3798
3799 vfree(ov->rawfbuf);
3800 ov->rawfbuf = NULL;
3801
3802 vfree(ov->tempfbuf);
3803 ov->tempfbuf = NULL;
3804
3805 for (i = 0; i < OV511_NUMSBUF; i++) {
3806 kfree(ov->sbuf[i].data);
3807 ov->sbuf[i].data = NULL;
3808 }
3809
3810 for (i = 0; i < OV511_NUMFRAMES; i++) {
3811 ov->frame[i].data = NULL;
3812 ov->frame[i].rawdata = NULL;
3813 ov->frame[i].tempdata = NULL;
3814 if (ov->frame[i].compbuf) {
3815 free_page((unsigned long) ov->frame[i].compbuf);
3816 ov->frame[i].compbuf = NULL;
3817 }
3818 }
3819
3820 PDEBUG(4, "buffer memory deallocated");
3821 ov->buf_state = BUF_NOT_ALLOCATED;
3822 PDEBUG(4, "leaving");
3823}
3824
3825static int
3826ov51x_alloc(struct usb_ov511 *ov)
3827{
3828 int i;
3829 const int w = ov->maxwidth;
3830 const int h = ov->maxheight;
3831 const int data_bufsize = OV511_NUMFRAMES * MAX_DATA_SIZE(w, h);
3832 const int raw_bufsize = OV511_NUMFRAMES * MAX_RAW_DATA_SIZE(w, h);
3833
3834 PDEBUG(4, "entered");
3835 mutex_lock(&ov->buf_lock);
3836
3837 if (ov->buf_state == BUF_ALLOCATED)
3838 goto out;
3839
3840 ov->fbuf = rvmalloc(data_bufsize);
3841 if (!ov->fbuf)
3842 goto error;
3843
3844 ov->rawfbuf = vmalloc(raw_bufsize);
3845 if (!ov->rawfbuf)
3846 goto error;
3847
3848 memset(ov->rawfbuf, 0, raw_bufsize);
3849
3850 ov->tempfbuf = vmalloc(raw_bufsize);
3851 if (!ov->tempfbuf)
3852 goto error;
3853
3854 memset(ov->tempfbuf, 0, raw_bufsize);
3855
3856 for (i = 0; i < OV511_NUMSBUF; i++) {
3857 ov->sbuf[i].data = kmalloc(FRAMES_PER_DESC *
3858 MAX_FRAME_SIZE_PER_DESC, GFP_KERNEL);
3859 if (!ov->sbuf[i].data)
3860 goto error;
3861
3862 PDEBUG(4, "sbuf[%d] @ %p", i, ov->sbuf[i].data);
3863 }
3864
3865 for (i = 0; i < OV511_NUMFRAMES; i++) {
3866 ov->frame[i].data = ov->fbuf + i * MAX_DATA_SIZE(w, h);
3867 ov->frame[i].rawdata = ov->rawfbuf
3868 + i * MAX_RAW_DATA_SIZE(w, h);
3869 ov->frame[i].tempdata = ov->tempfbuf
3870 + i * MAX_RAW_DATA_SIZE(w, h);
3871
3872 ov->frame[i].compbuf =
3873 (unsigned char *) __get_free_page(GFP_KERNEL);
3874 if (!ov->frame[i].compbuf)
3875 goto error;
3876
3877 PDEBUG(4, "frame[%d] @ %p", i, ov->frame[i].data);
3878 }
3879
3880 ov->buf_state = BUF_ALLOCATED;
3881out:
3882 mutex_unlock(&ov->buf_lock);
3883 PDEBUG(4, "leaving");
3884 return 0;
3885error:
3886 ov51x_do_dealloc(ov);
3887 mutex_unlock(&ov->buf_lock);
3888 PDEBUG(4, "errored");
3889 return -ENOMEM;
3890}
3891
3892static void
3893ov51x_dealloc(struct usb_ov511 *ov)
3894{
3895 PDEBUG(4, "entered");
3896 mutex_lock(&ov->buf_lock);
3897 ov51x_do_dealloc(ov);
3898 mutex_unlock(&ov->buf_lock);
3899 PDEBUG(4, "leaving");
3900}
3901
3902/****************************************************************************
3903 *
3904 * V4L 1 API
3905 *
3906 ***************************************************************************/
3907
3908static int
3909ov51x_v4l1_open(struct inode *inode, struct file *file)
3910{
3911 struct video_device *vdev = video_devdata(file);
3912 struct usb_ov511 *ov = video_get_drvdata(vdev);
3913 int err, i;
3914
3915 PDEBUG(4, "opening");
3916
3917 mutex_lock(&ov->lock);
3918
3919 err = -EBUSY;
3920 if (ov->user)
3921 goto out;
3922
3923 ov->sub_flag = 0;
3924
3925 /* In case app doesn't set them... */
3926 err = ov51x_set_default_params(ov);
3927 if (err < 0)
3928 goto out;
3929
3930 /* Make sure frames are reset */
3931 for (i = 0; i < OV511_NUMFRAMES; i++) {
3932 ov->frame[i].grabstate = FRAME_UNUSED;
3933 ov->frame[i].bytes_read = 0;
3934 }
3935
3936 /* If compression is on, make sure now that a
3937 * decompressor can be loaded */
3938 if (ov->compress && !ov->decomp_ops) {
3939 err = request_decompressor(ov);
3940 if (err && !dumppix)
3941 goto out;
3942 }
3943
3944 err = ov51x_alloc(ov);
3945 if (err < 0)
3946 goto out;
3947
3948 err = ov51x_init_isoc(ov);
3949 if (err) {
3950 ov51x_dealloc(ov);
3951 goto out;
3952 }
3953
3954 ov->user++;
3955 file->private_data = vdev;
3956
3957 if (ov->led_policy == LED_AUTO)
3958 ov51x_led_control(ov, 1);
3959
3960out:
3961 mutex_unlock(&ov->lock);
3962 return err;
3963}
3964
3965static int
3966ov51x_v4l1_close(struct inode *inode, struct file *file)
3967{
3968 struct video_device *vdev = file->private_data;
3969 struct usb_ov511 *ov = video_get_drvdata(vdev);
3970
3971 PDEBUG(4, "ov511_close");
3972
3973 mutex_lock(&ov->lock);
3974
3975 ov->user--;
3976 ov51x_stop_isoc(ov);
3977
3978 if (ov->led_policy == LED_AUTO)
3979 ov51x_led_control(ov, 0);
3980
3981 if (ov->dev)
3982 ov51x_dealloc(ov);
3983
3984 mutex_unlock(&ov->lock);
3985
3986 /* Device unplugged while open. Only a minimum of unregistration is done
3987 * here; the disconnect callback already did the rest. */
3988 if (!ov->dev) {
3989 mutex_lock(&ov->cbuf_lock);
3990 kfree(ov->cbuf);
3991 ov->cbuf = NULL;
3992 mutex_unlock(&ov->cbuf_lock);
3993
3994 ov51x_dealloc(ov);
3995 kfree(ov);
3996 ov = NULL;
3997 }
3998
3999 file->private_data = NULL;
4000 return 0;
4001}
4002
4003/* Do not call this function directly! */
4004static int
4005ov51x_v4l1_ioctl_internal(struct inode *inode, struct file *file,
4006 unsigned int cmd, void *arg)
4007{
4008 struct video_device *vdev = file->private_data;
4009 struct usb_ov511 *ov = video_get_drvdata(vdev);
4010 PDEBUG(5, "IOCtl: 0x%X", cmd);
4011
4012 if (!ov->dev)
4013 return -EIO;
4014
4015 switch (cmd) {
4016 case VIDIOCGCAP:
4017 {
4018 struct video_capability *b = arg;
4019
4020 PDEBUG(4, "VIDIOCGCAP");
4021
4022 memset(b, 0, sizeof(struct video_capability));
4023 sprintf(b->name, "%s USB Camera",
4024 symbolic(brglist, ov->bridge));
4025 b->type = VID_TYPE_CAPTURE | VID_TYPE_SUBCAPTURE;
4026 b->channels = ov->num_inputs;
4027 b->audios = 0;
4028 b->maxwidth = ov->maxwidth;
4029 b->maxheight = ov->maxheight;
4030 b->minwidth = ov->minwidth;
4031 b->minheight = ov->minheight;
4032
4033 return 0;
4034 }
4035 case VIDIOCGCHAN:
4036 {
4037 struct video_channel *v = arg;
4038
4039 PDEBUG(4, "VIDIOCGCHAN");
4040
4041 if ((unsigned)(v->channel) >= ov->num_inputs) {
4042 err("Invalid channel (%d)", v->channel);
4043 return -EINVAL;
4044 }
4045
4046 v->norm = ov->norm;
4047 v->type = VIDEO_TYPE_CAMERA;
4048 v->flags = 0;
4049// v->flags |= (ov->has_decoder) ? VIDEO_VC_NORM : 0;
4050 v->tuners = 0;
4051 decoder_get_input_name(ov, v->channel, v->name);
4052
4053 return 0;
4054 }
4055 case VIDIOCSCHAN:
4056 {
4057 struct video_channel *v = arg;
4058 int err;
4059
4060 PDEBUG(4, "VIDIOCSCHAN");
4061
4062 /* Make sure it's not a camera */
4063 if (!ov->has_decoder) {
4064 if (v->channel == 0)
4065 return 0;
4066 else
4067 return -EINVAL;
4068 }
4069
4070 if (v->norm != VIDEO_MODE_PAL &&
4071 v->norm != VIDEO_MODE_NTSC &&
4072 v->norm != VIDEO_MODE_SECAM &&
4073 v->norm != VIDEO_MODE_AUTO) {
4074 err("Invalid norm (%d)", v->norm);
4075 return -EINVAL;
4076 }
4077
4078 if ((unsigned)(v->channel) >= ov->num_inputs) {
4079 err("Invalid channel (%d)", v->channel);
4080 return -EINVAL;
4081 }
4082
4083 err = decoder_set_input(ov, v->channel);
4084 if (err)
4085 return err;
4086
4087 err = decoder_set_norm(ov, v->norm);
4088 if (err)
4089 return err;
4090
4091 return 0;
4092 }
4093 case VIDIOCGPICT:
4094 {
4095 struct video_picture *p = arg;
4096
4097 PDEBUG(4, "VIDIOCGPICT");
4098
4099 memset(p, 0, sizeof(struct video_picture));
4100 if (sensor_get_picture(ov, p))
4101 return -EIO;
4102
4103 /* Can we get these from frame[0]? -claudio? */
4104 p->depth = ov->frame[0].depth;
4105 p->palette = ov->frame[0].format;
4106
4107 return 0;
4108 }
4109 case VIDIOCSPICT:
4110 {
4111 struct video_picture *p = arg;
4112 int i, rc;
4113
4114 PDEBUG(4, "VIDIOCSPICT");
4115
4116 if (!get_depth(p->palette))
4117 return -EINVAL;
4118
4119 if (sensor_set_picture(ov, p))
4120 return -EIO;
4121
4122 if (force_palette && p->palette != force_palette) {
4123 info("Palette rejected (%s)",
4124 symbolic(v4l1_plist, p->palette));
4125 return -EINVAL;
4126 }
4127
4128 // FIXME: Format should be independent of frames
4129 if (p->palette != ov->frame[0].format) {
4130 PDEBUG(4, "Detected format change");
4131
4132 rc = ov51x_wait_frames_inactive(ov);
4133 if (rc)
4134 return rc;
4135
4136 mode_init_regs(ov, ov->frame[0].width,
4137 ov->frame[0].height, p->palette, ov->sub_flag);
4138 }
4139
4140 PDEBUG(4, "Setting depth=%d, palette=%s",
4141 p->depth, symbolic(v4l1_plist, p->palette));
4142
4143 for (i = 0; i < OV511_NUMFRAMES; i++) {
4144 ov->frame[i].depth = p->depth;
4145 ov->frame[i].format = p->palette;
4146 }
4147
4148 return 0;
4149 }
4150 case VIDIOCGCAPTURE:
4151 {
4152 int *vf = arg;
4153
4154 PDEBUG(4, "VIDIOCGCAPTURE");
4155
4156 ov->sub_flag = *vf;
4157 return 0;
4158 }
4159 case VIDIOCSCAPTURE:
4160 {
4161 struct video_capture *vc = arg;
4162
4163 PDEBUG(4, "VIDIOCSCAPTURE");
4164
4165 if (vc->flags)
4166 return -EINVAL;
4167 if (vc->decimation)
4168 return -EINVAL;
4169
4170 vc->x &= ~3L;
4171 vc->y &= ~1L;
4172 vc->y &= ~31L;
4173
4174 if (vc->width == 0)
4175 vc->width = 32;
4176
4177 vc->height /= 16;
4178 vc->height *= 16;
4179 if (vc->height == 0)
4180 vc->height = 16;
4181
4182 ov->subx = vc->x;
4183 ov->suby = vc->y;
4184 ov->subw = vc->width;
4185 ov->subh = vc->height;
4186
4187 return 0;
4188 }
4189 case VIDIOCSWIN:
4190 {
4191 struct video_window *vw = arg;
4192 int i, rc;
4193
4194 PDEBUG(4, "VIDIOCSWIN: %dx%d", vw->width, vw->height);
4195
4196#if 0
4197 if (vw->flags)
4198 return -EINVAL;
4199 if (vw->clipcount)
4200 return -EINVAL;
4201 if (vw->height != ov->maxheight)
4202 return -EINVAL;
4203 if (vw->width != ov->maxwidth)
4204 return -EINVAL;
4205#endif
4206
4207 rc = ov51x_wait_frames_inactive(ov);
4208 if (rc)
4209 return rc;
4210
4211 rc = mode_init_regs(ov, vw->width, vw->height,
4212 ov->frame[0].format, ov->sub_flag);
4213 if (rc < 0)
4214 return rc;
4215
4216 for (i = 0; i < OV511_NUMFRAMES; i++) {
4217 ov->frame[i].width = vw->width;
4218 ov->frame[i].height = vw->height;
4219 }
4220
4221 return 0;
4222 }
4223 case VIDIOCGWIN:
4224 {
4225 struct video_window *vw = arg;
4226
4227 memset(vw, 0, sizeof(struct video_window));
4228 vw->x = 0; /* FIXME */
4229 vw->y = 0;
4230 vw->width = ov->frame[0].width;
4231 vw->height = ov->frame[0].height;
4232 vw->flags = 30;
4233
4234 PDEBUG(4, "VIDIOCGWIN: %dx%d", vw->width, vw->height);
4235
4236 return 0;
4237 }
4238 case VIDIOCGMBUF:
4239 {
4240 struct video_mbuf *vm = arg;
4241 int i;
4242
4243 PDEBUG(4, "VIDIOCGMBUF");
4244
4245 memset(vm, 0, sizeof(struct video_mbuf));
4246 vm->size = OV511_NUMFRAMES
4247 * MAX_DATA_SIZE(ov->maxwidth, ov->maxheight);
4248 vm->frames = OV511_NUMFRAMES;
4249
4250 vm->offsets[0] = 0;
4251 for (i = 1; i < OV511_NUMFRAMES; i++) {
4252 vm->offsets[i] = vm->offsets[i-1]
4253 + MAX_DATA_SIZE(ov->maxwidth, ov->maxheight);
4254 }
4255
4256 return 0;
4257 }
4258 case VIDIOCMCAPTURE:
4259 {
4260 struct video_mmap *vm = arg;
4261 int rc, depth;
4262 unsigned int f = vm->frame;
4263
4264 PDEBUG(4, "VIDIOCMCAPTURE: frame: %d, %dx%d, %s", f, vm->width,
4265 vm->height, symbolic(v4l1_plist, vm->format));
4266
4267 depth = get_depth(vm->format);
4268 if (!depth) {
4269 PDEBUG(2, "VIDIOCMCAPTURE: invalid format (%s)",
4270 symbolic(v4l1_plist, vm->format));
4271 return -EINVAL;
4272 }
4273
4274 if (f >= OV511_NUMFRAMES) {
4275 err("VIDIOCMCAPTURE: invalid frame (%d)", f);
4276 return -EINVAL;
4277 }
4278
4279 if (vm->width > ov->maxwidth
4280 || vm->height > ov->maxheight) {
4281 err("VIDIOCMCAPTURE: requested dimensions too big");
4282 return -EINVAL;
4283 }
4284
4285 if (ov->frame[f].grabstate == FRAME_GRABBING) {
4286 PDEBUG(4, "VIDIOCMCAPTURE: already grabbing");
4287 return -EBUSY;
4288 }
4289
4290 if (force_palette && (vm->format != force_palette)) {
4291 PDEBUG(2, "palette rejected (%s)",
4292 symbolic(v4l1_plist, vm->format));
4293 return -EINVAL;
4294 }
4295
4296 if ((ov->frame[f].width != vm->width) ||
4297 (ov->frame[f].height != vm->height) ||
4298 (ov->frame[f].format != vm->format) ||
4299 (ov->frame[f].sub_flag != ov->sub_flag) ||
4300 (ov->frame[f].depth != depth)) {
4301 PDEBUG(4, "VIDIOCMCAPTURE: change in image parameters");
4302
4303 rc = ov51x_wait_frames_inactive(ov);
4304 if (rc)
4305 return rc;
4306
4307 rc = mode_init_regs(ov, vm->width, vm->height,
4308 vm->format, ov->sub_flag);
4309#if 0
4310 if (rc < 0) {
4311 PDEBUG(1, "Got error while initializing regs ");
4312 return ret;
4313 }
4314#endif
4315 ov->frame[f].width = vm->width;
4316 ov->frame[f].height = vm->height;
4317 ov->frame[f].format = vm->format;
4318 ov->frame[f].sub_flag = ov->sub_flag;
4319 ov->frame[f].depth = depth;
4320 }
4321
4322 /* Mark it as ready */
4323 ov->frame[f].grabstate = FRAME_READY;
4324
4325 PDEBUG(4, "VIDIOCMCAPTURE: renewing frame %d", f);
4326
4327 return ov51x_new_frame(ov, f);
4328 }
4329 case VIDIOCSYNC:
4330 {
4331 unsigned int fnum = *((unsigned int *) arg);
4332 struct ov511_frame *frame;
4333 int rc;
4334
4335 if (fnum >= OV511_NUMFRAMES) {
4336 err("VIDIOCSYNC: invalid frame (%d)", fnum);
4337 return -EINVAL;
4338 }
4339
4340 frame = &ov->frame[fnum];
4341
4342 PDEBUG(4, "syncing to frame %d, grabstate = %d", fnum,
4343 frame->grabstate);
4344
4345 switch (frame->grabstate) {
4346 case FRAME_UNUSED:
4347 return -EINVAL;
4348 case FRAME_READY:
4349 case FRAME_GRABBING:
4350 case FRAME_ERROR:
4351redo:
4352 if (!ov->dev)
4353 return -EIO;
4354
4355 rc = wait_event_interruptible(frame->wq,
4356 (frame->grabstate == FRAME_DONE)
4357 || (frame->grabstate == FRAME_ERROR));
4358
4359 if (rc)
4360 return rc;
4361
4362 if (frame->grabstate == FRAME_ERROR) {
4363 if ((rc = ov51x_new_frame(ov, fnum)) < 0)
4364 return rc;
4365 goto redo;
4366 }
4367 /* Fall through */
4368 case FRAME_DONE:
4369 if (ov->snap_enabled && !frame->snapshot) {
4370 if ((rc = ov51x_new_frame(ov, fnum)) < 0)
4371 return rc;
4372 goto redo;
4373 }
4374
4375 frame->grabstate = FRAME_UNUSED;
4376
4377 /* Reset the hardware snapshot button */
4378 /* FIXME - Is this the best place for this? */
4379 if ((ov->snap_enabled) && (frame->snapshot)) {
4380 frame->snapshot = 0;
4381 ov51x_clear_snapshot(ov);
4382 }
4383
4384 /* Decompression, format conversion, etc... */
4385 ov51x_postprocess(ov, frame);
4386
4387 break;
4388 } /* end switch */
4389
4390 return 0;
4391 }
4392 case VIDIOCGFBUF:
4393 {
4394 struct video_buffer *vb = arg;
4395
4396 PDEBUG(4, "VIDIOCGFBUF");
4397
4398 memset(vb, 0, sizeof(struct video_buffer));
4399
4400 return 0;
4401 }
4402 case VIDIOCGUNIT:
4403 {
4404 struct video_unit *vu = arg;
4405
4406 PDEBUG(4, "VIDIOCGUNIT");
4407
4408 memset(vu, 0, sizeof(struct video_unit));
4409
4410 vu->video = ov->vdev->minor;
4411 vu->vbi = VIDEO_NO_UNIT;
4412 vu->radio = VIDEO_NO_UNIT;
4413 vu->audio = VIDEO_NO_UNIT;
4414 vu->teletext = VIDEO_NO_UNIT;
4415
4416 return 0;
4417 }
4418 case OV511IOC_WI2C:
4419 {
4420 struct ov511_i2c_struct *w = arg;
4421
4422 return i2c_w_slave(ov, w->slave, w->reg, w->value, w->mask);
4423 }
4424 case OV511IOC_RI2C:
4425 {
4426 struct ov511_i2c_struct *r = arg;
4427 int rc;
4428
4429 rc = i2c_r_slave(ov, r->slave, r->reg);
4430 if (rc < 0)
4431 return rc;
4432
4433 r->value = rc;
4434 return 0;
4435 }
4436 default:
4437 PDEBUG(3, "Unsupported IOCtl: 0x%X", cmd);
4438 return -ENOIOCTLCMD;
4439 } /* end switch */
4440
4441 return 0;
4442}
4443
4444static int
4445ov51x_v4l1_ioctl(struct inode *inode, struct file *file,
4446 unsigned int cmd, unsigned long arg)
4447{
4448 struct video_device *vdev = file->private_data;
4449 struct usb_ov511 *ov = video_get_drvdata(vdev);
4450 int rc;
4451
4452 if (mutex_lock_interruptible(&ov->lock))
4453 return -EINTR;
4454
4455 rc = video_usercopy(inode, file, cmd, arg, ov51x_v4l1_ioctl_internal);
4456
4457 mutex_unlock(&ov->lock);
4458 return rc;
4459}
4460
4461static ssize_t
4462ov51x_v4l1_read(struct file *file, char __user *buf, size_t cnt, loff_t *ppos)
4463{
4464 struct video_device *vdev = file->private_data;
4465 int noblock = file->f_flags&O_NONBLOCK;
4466 unsigned long count = cnt;
4467 struct usb_ov511 *ov = video_get_drvdata(vdev);
4468 int i, rc = 0, frmx = -1;
4469 struct ov511_frame *frame;
4470
4471 if (mutex_lock_interruptible(&ov->lock))
4472 return -EINTR;
4473
4474 PDEBUG(4, "%ld bytes, noblock=%d", count, noblock);
4475
4476 if (!vdev || !buf) {
4477 rc = -EFAULT;
4478 goto error;
4479 }
4480
4481 if (!ov->dev) {
4482 rc = -EIO;
4483 goto error;
4484 }
4485
4486// FIXME: Only supports two frames
4487 /* See if a frame is completed, then use it. */
4488 if (ov->frame[0].grabstate >= FRAME_DONE) /* _DONE or _ERROR */
4489 frmx = 0;
4490 else if (ov->frame[1].grabstate >= FRAME_DONE)/* _DONE or _ERROR */
4491 frmx = 1;
4492
4493 /* If nonblocking we return immediately */
4494 if (noblock && (frmx == -1)) {
4495 rc = -EAGAIN;
4496 goto error;
4497 }
4498
4499 /* If no FRAME_DONE, look for a FRAME_GRABBING state. */
4500 /* See if a frame is in process (grabbing), then use it. */
4501 if (frmx == -1) {
4502 if (ov->frame[0].grabstate == FRAME_GRABBING)
4503 frmx = 0;
4504 else if (ov->frame[1].grabstate == FRAME_GRABBING)
4505 frmx = 1;
4506 }
4507
4508 /* If no frame is active, start one. */
4509 if (frmx == -1) {
4510 if ((rc = ov51x_new_frame(ov, frmx = 0))) {
4511 err("read: ov51x_new_frame error");
4512 goto error;
4513 }
4514 }
4515
4516 frame = &ov->frame[frmx];
4517
4518restart:
4519 if (!ov->dev) {
4520 rc = -EIO;
4521 goto error;
4522 }
4523
4524 /* Wait while we're grabbing the image */
4525 PDEBUG(4, "Waiting image grabbing");
4526 rc = wait_event_interruptible(frame->wq,
4527 (frame->grabstate == FRAME_DONE)
4528 || (frame->grabstate == FRAME_ERROR));
4529
4530 if (rc)
4531 goto error;
4532
4533 PDEBUG(4, "Got image, frame->grabstate = %d", frame->grabstate);
4534 PDEBUG(4, "bytes_recvd = %d", frame->bytes_recvd);
4535
4536 if (frame->grabstate == FRAME_ERROR) {
4537 frame->bytes_read = 0;
4538 err("** ick! ** Errored frame %d", ov->curframe);
4539 if (ov51x_new_frame(ov, frmx)) {
4540 err("read: ov51x_new_frame error");
4541 goto error;
4542 }
4543 goto restart;
4544 }
4545
4546
4547 /* Repeat until we get a snapshot frame */
4548 if (ov->snap_enabled)
4549 PDEBUG(4, "Waiting snapshot frame");
4550 if (ov->snap_enabled && !frame->snapshot) {
4551 frame->bytes_read = 0;
4552 if ((rc = ov51x_new_frame(ov, frmx))) {
4553 err("read: ov51x_new_frame error");
4554 goto error;
4555 }
4556 goto restart;
4557 }
4558
4559 /* Clear the snapshot */
4560 if (ov->snap_enabled && frame->snapshot) {
4561 frame->snapshot = 0;
4562 ov51x_clear_snapshot(ov);
4563 }
4564
4565 /* Decompression, format conversion, etc... */
4566 ov51x_postprocess(ov, frame);
4567
4568 PDEBUG(4, "frmx=%d, bytes_read=%ld, length=%ld", frmx,
4569 frame->bytes_read,
4570 get_frame_length(frame));
4571
4572 /* copy bytes to user space; we allow for partials reads */
4573// if ((count + frame->bytes_read)
4574// > get_frame_length((struct ov511_frame *)frame))
4575// count = frame->scanlength - frame->bytes_read;
4576
4577 /* FIXME - count hardwired to be one frame... */
4578 count = get_frame_length(frame);
4579
4580 PDEBUG(4, "Copy to user space: %ld bytes", count);
4581 if ((i = copy_to_user(buf, frame->data + frame->bytes_read, count))) {
4582 PDEBUG(4, "Copy failed! %d bytes not copied", i);
4583 rc = -EFAULT;
4584 goto error;
4585 }
4586
4587 frame->bytes_read += count;
4588 PDEBUG(4, "{copy} count used=%ld, new bytes_read=%ld",
4589 count, frame->bytes_read);
4590
4591 /* If all data have been read... */
4592 if (frame->bytes_read
4593 >= get_frame_length(frame)) {
4594 frame->bytes_read = 0;
4595
4596// FIXME: Only supports two frames
4597 /* Mark it as available to be used again. */
4598 ov->frame[frmx].grabstate = FRAME_UNUSED;
4599 if ((rc = ov51x_new_frame(ov, !frmx))) {
4600 err("ov51x_new_frame returned error");
4601 goto error;
4602 }
4603 }
4604
4605 PDEBUG(4, "read finished, returning %ld (sweet)", count);
4606
4607 mutex_unlock(&ov->lock);
4608 return count;
4609
4610error:
4611 mutex_unlock(&ov->lock);
4612 return rc;
4613}
4614
4615static int
4616ov51x_v4l1_mmap(struct file *file, struct vm_area_struct *vma)
4617{
4618 struct video_device *vdev = file->private_data;
4619 unsigned long start = vma->vm_start;
4620 unsigned long size = vma->vm_end - vma->vm_start;
4621 struct usb_ov511 *ov = video_get_drvdata(vdev);
4622 unsigned long page, pos;
4623
4624 if (ov->dev == NULL)
4625 return -EIO;
4626
4627 PDEBUG(4, "mmap: %ld (%lX) bytes", size, size);
4628
4629 if (size > (((OV511_NUMFRAMES
4630 * MAX_DATA_SIZE(ov->maxwidth, ov->maxheight)
4631 + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1))))
4632 return -EINVAL;
4633
4634 if (mutex_lock_interruptible(&ov->lock))
4635 return -EINTR;
4636
4637 pos = (unsigned long)ov->fbuf;
4638 while (size > 0) {
4639 page = vmalloc_to_pfn((void *)pos);
4640 if (remap_pfn_range(vma, start, page, PAGE_SIZE, PAGE_SHARED)) {
4641 mutex_unlock(&ov->lock);
4642 return -EAGAIN;
4643 }
4644 start += PAGE_SIZE;
4645 pos += PAGE_SIZE;
4646 if (size > PAGE_SIZE)
4647 size -= PAGE_SIZE;
4648 else
4649 size = 0;
4650 }
4651
4652 mutex_unlock(&ov->lock);
4653 return 0;
4654}
4655
4656static struct file_operations ov511_fops = {
4657 .owner = THIS_MODULE,
4658 .open = ov51x_v4l1_open,
4659 .release = ov51x_v4l1_close,
4660 .read = ov51x_v4l1_read,
4661 .mmap = ov51x_v4l1_mmap,
4662 .ioctl = ov51x_v4l1_ioctl,
4663 .compat_ioctl = v4l_compat_ioctl32,
4664 .llseek = no_llseek,
4665};
4666
4667static struct video_device vdev_template = {
4668 .owner = THIS_MODULE,
4669 .name = "OV511 USB Camera",
4670 .type = VID_TYPE_CAPTURE,
4671 .hardware = VID_HARDWARE_OV511,
4672 .fops = &ov511_fops,
4673 .release = video_device_release,
4674 .minor = -1,
4675};
4676
4677/****************************************************************************
4678 *
4679 * OV511 and sensor configuration
4680 *
4681 ***************************************************************************/
4682
4683/* This initializes the OV7610, OV7620, or OV76BE sensor. The OV76BE uses
4684 * the same register settings as the OV7610, since they are very similar.
4685 */
4686static int
4687ov7xx0_configure(struct usb_ov511 *ov)
4688{
4689 int i, success;
4690 int rc;
4691
4692 /* Lawrence Glaister <lg@jfm.bc.ca> reports:
4693 *
4694 * Register 0x0f in the 7610 has the following effects:
4695 *
4696 * 0x85 (AEC method 1): Best overall, good contrast range
4697 * 0x45 (AEC method 2): Very overexposed
4698 * 0xa5 (spec sheet default): Ok, but the black level is
4699 * shifted resulting in loss of contrast
4700 * 0x05 (old driver setting): very overexposed, too much
4701 * contrast
4702 */
4703 static struct ov511_regvals aRegvalsNorm7610[] = {
4704 { OV511_I2C_BUS, 0x10, 0xff },
4705 { OV511_I2C_BUS, 0x16, 0x06 },
4706 { OV511_I2C_BUS, 0x28, 0x24 },
4707 { OV511_I2C_BUS, 0x2b, 0xac },
4708 { OV511_I2C_BUS, 0x12, 0x00 },
4709 { OV511_I2C_BUS, 0x38, 0x81 },
4710 { OV511_I2C_BUS, 0x28, 0x24 }, /* 0c */
4711 { OV511_I2C_BUS, 0x0f, 0x85 }, /* lg's setting */
4712 { OV511_I2C_BUS, 0x15, 0x01 },
4713 { OV511_I2C_BUS, 0x20, 0x1c },
4714 { OV511_I2C_BUS, 0x23, 0x2a },
4715 { OV511_I2C_BUS, 0x24, 0x10 },
4716 { OV511_I2C_BUS, 0x25, 0x8a },
4717 { OV511_I2C_BUS, 0x26, 0xa2 },
4718 { OV511_I2C_BUS, 0x27, 0xc2 },
4719 { OV511_I2C_BUS, 0x2a, 0x04 },
4720 { OV511_I2C_BUS, 0x2c, 0xfe },
4721 { OV511_I2C_BUS, 0x2d, 0x93 },
4722 { OV511_I2C_BUS, 0x30, 0x71 },
4723 { OV511_I2C_BUS, 0x31, 0x60 },
4724 { OV511_I2C_BUS, 0x32, 0x26 },
4725 { OV511_I2C_BUS, 0x33, 0x20 },
4726 { OV511_I2C_BUS, 0x34, 0x48 },
4727 { OV511_I2C_BUS, 0x12, 0x24 },
4728 { OV511_I2C_BUS, 0x11, 0x01 },
4729 { OV511_I2C_BUS, 0x0c, 0x24 },
4730 { OV511_I2C_BUS, 0x0d, 0x24 },
4731 { OV511_DONE_BUS, 0x0, 0x00 },
4732 };
4733
4734 static struct ov511_regvals aRegvalsNorm7620[] = {
4735 { OV511_I2C_BUS, 0x00, 0x00 },
4736 { OV511_I2C_BUS, 0x01, 0x80 },
4737 { OV511_I2C_BUS, 0x02, 0x80 },
4738 { OV511_I2C_BUS, 0x03, 0xc0 },
4739 { OV511_I2C_BUS, 0x06, 0x60 },
4740 { OV511_I2C_BUS, 0x07, 0x00 },
4741 { OV511_I2C_BUS, 0x0c, 0x24 },
4742 { OV511_I2C_BUS, 0x0c, 0x24 },
4743 { OV511_I2C_BUS, 0x0d, 0x24 },
4744 { OV511_I2C_BUS, 0x11, 0x01 },
4745 { OV511_I2C_BUS, 0x12, 0x24 },
4746 { OV511_I2C_BUS, 0x13, 0x01 },
4747 { OV511_I2C_BUS, 0x14, 0x84 },
4748 { OV511_I2C_BUS, 0x15, 0x01 },
4749 { OV511_I2C_BUS, 0x16, 0x03 },
4750 { OV511_I2C_BUS, 0x17, 0x2f },
4751 { OV511_I2C_BUS, 0x18, 0xcf },
4752 { OV511_I2C_BUS, 0x19, 0x06 },
4753 { OV511_I2C_BUS, 0x1a, 0xf5 },
4754 { OV511_I2C_BUS, 0x1b, 0x00 },
4755 { OV511_I2C_BUS, 0x20, 0x18 },
4756 { OV511_I2C_BUS, 0x21, 0x80 },
4757 { OV511_I2C_BUS, 0x22, 0x80 },
4758 { OV511_I2C_BUS, 0x23, 0x00 },
4759 { OV511_I2C_BUS, 0x26, 0xa2 },
4760 { OV511_I2C_BUS, 0x27, 0xea },
4761 { OV511_I2C_BUS, 0x28, 0x20 },
4762 { OV511_I2C_BUS, 0x29, 0x00 },
4763 { OV511_I2C_BUS, 0x2a, 0x10 },
4764 { OV511_I2C_BUS, 0x2b, 0x00 },
4765 { OV511_I2C_BUS, 0x2c, 0x88 },
4766 { OV511_I2C_BUS, 0x2d, 0x91 },
4767 { OV511_I2C_BUS, 0x2e, 0x80 },
4768 { OV511_I2C_BUS, 0x2f, 0x44 },
4769 { OV511_I2C_BUS, 0x60, 0x27 },
4770 { OV511_I2C_BUS, 0x61, 0x02 },
4771 { OV511_I2C_BUS, 0x62, 0x5f },
4772 { OV511_I2C_BUS, 0x63, 0xd5 },
4773 { OV511_I2C_BUS, 0x64, 0x57 },
4774 { OV511_I2C_BUS, 0x65, 0x83 },
4775 { OV511_I2C_BUS, 0x66, 0x55 },
4776 { OV511_I2C_BUS, 0x67, 0x92 },
4777 { OV511_I2C_BUS, 0x68, 0xcf },
4778 { OV511_I2C_BUS, 0x69, 0x76 },
4779 { OV511_I2C_BUS, 0x6a, 0x22 },
4780 { OV511_I2C_BUS, 0x6b, 0x00 },
4781 { OV511_I2C_BUS, 0x6c, 0x02 },
4782 { OV511_I2C_BUS, 0x6d, 0x44 },
4783 { OV511_I2C_BUS, 0x6e, 0x80 },
4784 { OV511_I2C_BUS, 0x6f, 0x1d },
4785 { OV511_I2C_BUS, 0x70, 0x8b },
4786 { OV511_I2C_BUS, 0x71, 0x00 },
4787 { OV511_I2C_BUS, 0x72, 0x14 },
4788 { OV511_I2C_BUS, 0x73, 0x54 },
4789 { OV511_I2C_BUS, 0x74, 0x00 },
4790 { OV511_I2C_BUS, 0x75, 0x8e },
4791 { OV511_I2C_BUS, 0x76, 0x00 },
4792 { OV511_I2C_BUS, 0x77, 0xff },
4793 { OV511_I2C_BUS, 0x78, 0x80 },
4794 { OV511_I2C_BUS, 0x79, 0x80 },
4795 { OV511_I2C_BUS, 0x7a, 0x80 },
4796 { OV511_I2C_BUS, 0x7b, 0xe2 },
4797 { OV511_I2C_BUS, 0x7c, 0x00 },
4798 { OV511_DONE_BUS, 0x0, 0x00 },
4799 };
4800
4801 PDEBUG(4, "starting configuration");
4802
4803 /* This looks redundant, but is necessary for WebCam 3 */
4804 ov->primary_i2c_slave = OV7xx0_SID;
4805 if (ov51x_set_slave_ids(ov, OV7xx0_SID) < 0)
4806 return -1;
4807
4808 if (init_ov_sensor(ov) >= 0) {
4809 PDEBUG(1, "OV7xx0 sensor initalized (method 1)");
4810 } else {
4811 /* Reset the 76xx */
4812 if (i2c_w(ov, 0x12, 0x80) < 0)
4813 return -1;
4814
4815 /* Wait for it to initialize */
4816 msleep(150);
4817
4818 i = 0;
4819 success = 0;
4820 while (i <= i2c_detect_tries) {
4821 if ((i2c_r(ov, OV7610_REG_ID_HIGH) == 0x7F) &&
4822 (i2c_r(ov, OV7610_REG_ID_LOW) == 0xA2)) {
4823 success = 1;
4824 break;
4825 } else {
4826 i++;
4827 }
4828 }
4829
4830// Was (i == i2c_detect_tries) previously. This obviously used to always report
4831// success. Whether anyone actually depended on that bug is unknown
4832 if ((i >= i2c_detect_tries) && (success == 0)) {
4833 err("Failed to read sensor ID. You might not have an");
4834 err("OV7610/20, or it may be not responding. Report");
4835 err("this to " EMAIL);
4836 err("This is only a warning. You can attempt to use");
4837 err("your camera anyway");
4838// Only issue a warning for now
4839// return -1;
4840 } else {
4841 PDEBUG(1, "OV7xx0 initialized (method 2, %dx)", i+1);
4842 }
4843 }
4844
4845 /* Detect sensor (sub)type */
4846 rc = i2c_r(ov, OV7610_REG_COM_I);
4847
4848 if (rc < 0) {
4849 err("Error detecting sensor type");
4850 return -1;
4851 } else if ((rc & 3) == 3) {
4852 info("Sensor is an OV7610");
4853 ov->sensor = SEN_OV7610;
4854 } else if ((rc & 3) == 1) {
4855 /* I don't know what's different about the 76BE yet. */
4856 if (i2c_r(ov, 0x15) & 1)
4857 info("Sensor is an OV7620AE");
4858 else
4859 info("Sensor is an OV76BE");
4860
4861 /* OV511+ will return all zero isoc data unless we
4862 * configure the sensor as a 7620. Someone needs to
4863 * find the exact reg. setting that causes this. */
4864 if (ov->bridge == BRG_OV511PLUS) {
4865 info("Enabling 511+/7620AE workaround");
4866 ov->sensor = SEN_OV7620;
4867 } else {
4868 ov->sensor = SEN_OV76BE;
4869 }
4870 } else if ((rc & 3) == 0) {
4871 info("Sensor is an OV7620");
4872 ov->sensor = SEN_OV7620;
4873 } else {
4874 err("Unknown image sensor version: %d", rc & 3);
4875 return -1;
4876 }
4877
4878 if (ov->sensor == SEN_OV7620) {
4879 PDEBUG(4, "Writing 7620 registers");
4880 if (write_regvals(ov, aRegvalsNorm7620))
4881 return -1;
4882 } else {
4883 PDEBUG(4, "Writing 7610 registers");
4884 if (write_regvals(ov, aRegvalsNorm7610))
4885 return -1;
4886 }
4887
4888 /* Set sensor-specific vars */
4889 ov->maxwidth = 640;
4890 ov->maxheight = 480;
4891 ov->minwidth = 64;
4892 ov->minheight = 48;
4893
4894 // FIXME: These do not match the actual settings yet
4895 ov->brightness = 0x80 << 8;
4896 ov->contrast = 0x80 << 8;
4897 ov->colour = 0x80 << 8;
4898 ov->hue = 0x80 << 8;
4899
4900 return 0;
4901}
4902
4903/* This initializes the OV6620, OV6630, OV6630AE, or OV6630AF sensor. */
4904static int
4905ov6xx0_configure(struct usb_ov511 *ov)
4906{
4907 int rc;
4908
4909 static struct ov511_regvals aRegvalsNorm6x20[] = {
4910 { OV511_I2C_BUS, 0x12, 0x80 }, /* reset */
4911 { OV511_I2C_BUS, 0x11, 0x01 },
4912 { OV511_I2C_BUS, 0x03, 0x60 },
4913 { OV511_I2C_BUS, 0x05, 0x7f }, /* For when autoadjust is off */
4914 { OV511_I2C_BUS, 0x07, 0xa8 },
4915 /* The ratio of 0x0c and 0x0d controls the white point */
4916 { OV511_I2C_BUS, 0x0c, 0x24 },
4917 { OV511_I2C_BUS, 0x0d, 0x24 },
4918 { OV511_I2C_BUS, 0x0f, 0x15 }, /* COMS */
4919 { OV511_I2C_BUS, 0x10, 0x75 }, /* AEC Exposure time */
4920 { OV511_I2C_BUS, 0x12, 0x24 }, /* Enable AGC */
4921 { OV511_I2C_BUS, 0x14, 0x04 },
4922 /* 0x16: 0x06 helps frame stability with moving objects */
4923 { OV511_I2C_BUS, 0x16, 0x06 },
4924// { OV511_I2C_BUS, 0x20, 0x30 }, /* Aperture correction enable */
4925 { OV511_I2C_BUS, 0x26, 0xb2 }, /* BLC enable */
4926 /* 0x28: 0x05 Selects RGB format if RGB on */
4927 { OV511_I2C_BUS, 0x28, 0x05 },
4928 { OV511_I2C_BUS, 0x2a, 0x04 }, /* Disable framerate adjust */
4929// { OV511_I2C_BUS, 0x2b, 0xac }, /* Framerate; Set 2a[7] first */
4930 { OV511_I2C_BUS, 0x2d, 0x99 },
4931 { OV511_I2C_BUS, 0x33, 0xa0 }, /* Color Processing Parameter */
4932 { OV511_I2C_BUS, 0x34, 0xd2 }, /* Max A/D range */
4933 { OV511_I2C_BUS, 0x38, 0x8b },
4934 { OV511_I2C_BUS, 0x39, 0x40 },
4935
4936 { OV511_I2C_BUS, 0x3c, 0x39 }, /* Enable AEC mode changing */
4937 { OV511_I2C_BUS, 0x3c, 0x3c }, /* Change AEC mode */
4938 { OV511_I2C_BUS, 0x3c, 0x24 }, /* Disable AEC mode changing */
4939
4940 { OV511_I2C_BUS, 0x3d, 0x80 },
4941 /* These next two registers (0x4a, 0x4b) are undocumented. They
4942 * control the color balance */
4943 { OV511_I2C_BUS, 0x4a, 0x80 },
4944 { OV511_I2C_BUS, 0x4b, 0x80 },
4945 { OV511_I2C_BUS, 0x4d, 0xd2 }, /* This reduces noise a bit */
4946 { OV511_I2C_BUS, 0x4e, 0xc1 },
4947 { OV511_I2C_BUS, 0x4f, 0x04 },
4948// Do 50-53 have any effect?
4949// Toggle 0x12[2] off and on here?
4950 { OV511_DONE_BUS, 0x0, 0x00 }, /* END MARKER */
4951 };
4952
4953 static struct ov511_regvals aRegvalsNorm6x30[] = {
4954 /*OK*/ { OV511_I2C_BUS, 0x12, 0x80 }, /* reset */
4955 { OV511_I2C_BUS, 0x11, 0x00 },
4956 /*OK*/ { OV511_I2C_BUS, 0x03, 0x60 },
4957 /*0A?*/ { OV511_I2C_BUS, 0x05, 0x7f }, /* For when autoadjust is off */
4958 { OV511_I2C_BUS, 0x07, 0xa8 },
4959 /* The ratio of 0x0c and 0x0d controls the white point */
4960 /*OK*/ { OV511_I2C_BUS, 0x0c, 0x24 },
4961 /*OK*/ { OV511_I2C_BUS, 0x0d, 0x24 },
4962 /*A*/ { OV511_I2C_BUS, 0x0e, 0x20 },
4963// /*04?*/ { OV511_I2C_BUS, 0x14, 0x80 },
4964 { OV511_I2C_BUS, 0x16, 0x03 },
4965// /*OK*/ { OV511_I2C_BUS, 0x20, 0x30 }, /* Aperture correction enable */
4966 // 21 & 22? The suggested values look wrong. Go with default
4967 /*A*/ { OV511_I2C_BUS, 0x23, 0xc0 },
4968 /*A*/ { OV511_I2C_BUS, 0x25, 0x9a }, // Check this against default
4969// /*OK*/ { OV511_I2C_BUS, 0x26, 0xb2 }, /* BLC enable */
4970
4971 /* 0x28: 0x05 Selects RGB format if RGB on */
4972// /*04?*/ { OV511_I2C_BUS, 0x28, 0x05 },
4973// /*04?*/ { OV511_I2C_BUS, 0x28, 0x45 }, // DEBUG: Tristate UV bus
4974
4975 /*OK*/ { OV511_I2C_BUS, 0x2a, 0x04 }, /* Disable framerate adjust */
4976// /*OK*/ { OV511_I2C_BUS, 0x2b, 0xac }, /* Framerate; Set 2a[7] first */
4977 { OV511_I2C_BUS, 0x2d, 0x99 },
4978// /*A*/ { OV511_I2C_BUS, 0x33, 0x26 }, // Reserved bits on 6620
4979// /*d2?*/ { OV511_I2C_BUS, 0x34, 0x03 }, /* Max A/D range */
4980// /*8b?*/ { OV511_I2C_BUS, 0x38, 0x83 },
4981// /*40?*/ { OV511_I2C_BUS, 0x39, 0xc0 }, // 6630 adds bit 7
4982// { OV511_I2C_BUS, 0x3c, 0x39 }, /* Enable AEC mode changing */
4983// { OV511_I2C_BUS, 0x3c, 0x3c }, /* Change AEC mode */
4984// { OV511_I2C_BUS, 0x3c, 0x24 }, /* Disable AEC mode changing */
4985 { OV511_I2C_BUS, 0x3d, 0x80 },
4986// /*A*/ { OV511_I2C_BUS, 0x3f, 0x0e },
4987
4988 /* These next two registers (0x4a, 0x4b) are undocumented. They
4989 * control the color balance */
4990// /*OK?*/ { OV511_I2C_BUS, 0x4a, 0x80 }, // Check these
4991// /*OK?*/ { OV511_I2C_BUS, 0x4b, 0x80 },
4992 { OV511_I2C_BUS, 0x4d, 0x10 }, /* U = 0.563u, V = 0.714v */
4993 /*c1?*/ { OV511_I2C_BUS, 0x4e, 0x40 },
4994
4995 /* UV average mode, color killer: strongest */
4996 { OV511_I2C_BUS, 0x4f, 0x07 },
4997
4998 { OV511_I2C_BUS, 0x54, 0x23 }, /* Max AGC gain: 18dB */
4999 { OV511_I2C_BUS, 0x57, 0x81 }, /* (default) */
5000 { OV511_I2C_BUS, 0x59, 0x01 }, /* AGC dark current comp: +1 */
5001 { OV511_I2C_BUS, 0x5a, 0x2c }, /* (undocumented) */
5002 { OV511_I2C_BUS, 0x5b, 0x0f }, /* AWB chrominance levels */
5003// { OV511_I2C_BUS, 0x5c, 0x10 },
5004 { OV511_DONE_BUS, 0x0, 0x00 }, /* END MARKER */
5005 };
5006
5007 PDEBUG(4, "starting sensor configuration");
5008
5009 if (init_ov_sensor(ov) < 0) {
5010 err("Failed to read sensor ID. You might not have an OV6xx0,");
5011 err("or it may be not responding. Report this to " EMAIL);
5012 return -1;
5013 } else {
5014 PDEBUG(1, "OV6xx0 sensor detected");
5015 }
5016
5017 /* Detect sensor (sub)type */
5018 rc = i2c_r(ov, OV7610_REG_COM_I);
5019
5020 if (rc < 0) {
5021 err("Error detecting sensor type");
5022 return -1;
5023 }
5024
5025 if ((rc & 3) == 0) {
5026 ov->sensor = SEN_OV6630;
5027 info("Sensor is an OV6630");
5028 } else if ((rc & 3) == 1) {
5029 ov->sensor = SEN_OV6620;
5030 info("Sensor is an OV6620");
5031 } else if ((rc & 3) == 2) {
5032 ov->sensor = SEN_OV6630;
5033 info("Sensor is an OV6630AE");
5034 } else if ((rc & 3) == 3) {
5035 ov->sensor = SEN_OV6630;
5036 info("Sensor is an OV6630AF");
5037 }
5038
5039 /* Set sensor-specific vars */
5040 ov->maxwidth = 352;
5041 ov->maxheight = 288;
5042 ov->minwidth = 64;
5043 ov->minheight = 48;
5044
5045 // FIXME: These do not match the actual settings yet
5046 ov->brightness = 0x80 << 8;
5047 ov->contrast = 0x80 << 8;
5048 ov->colour = 0x80 << 8;
5049 ov->hue = 0x80 << 8;
5050
5051 if (ov->sensor == SEN_OV6620) {
5052 PDEBUG(4, "Writing 6x20 registers");
5053 if (write_regvals(ov, aRegvalsNorm6x20))
5054 return -1;
5055 } else {
5056 PDEBUG(4, "Writing 6x30 registers");
5057 if (write_regvals(ov, aRegvalsNorm6x30))
5058 return -1;
5059 }
5060
5061 return 0;
5062}
5063
5064/* This initializes the KS0127 and KS0127B video decoders. */
5065static int
5066ks0127_configure(struct usb_ov511 *ov)
5067{
5068 int rc;
5069
5070// FIXME: I don't know how to sync or reset it yet
5071#if 0
5072 if (ov51x_init_ks_sensor(ov) < 0) {
5073 err("Failed to initialize the KS0127");
5074 return -1;
5075 } else {
5076 PDEBUG(1, "KS012x(B) sensor detected");
5077 }
5078#endif
5079
5080 /* Detect decoder subtype */
5081 rc = i2c_r(ov, 0x00);
5082 if (rc < 0) {
5083 err("Error detecting sensor type");
5084 return -1;
5085 } else if (rc & 0x08) {
5086 rc = i2c_r(ov, 0x3d);
5087 if (rc < 0) {
5088 err("Error detecting sensor type");
5089 return -1;
5090 } else if ((rc & 0x0f) == 0) {
5091 info("Sensor is a KS0127");
5092 ov->sensor = SEN_KS0127;
5093 } else if ((rc & 0x0f) == 9) {
5094 info("Sensor is a KS0127B Rev. A");
5095 ov->sensor = SEN_KS0127B;
5096 }
5097 } else {
5098 err("Error: Sensor is an unsupported KS0122");
5099 return -1;
5100 }
5101
5102 /* Set sensor-specific vars */
5103 ov->maxwidth = 640;
5104 ov->maxheight = 480;
5105 ov->minwidth = 64;
5106 ov->minheight = 48;
5107
5108 // FIXME: These do not match the actual settings yet
5109 ov->brightness = 0x80 << 8;
5110 ov->contrast = 0x80 << 8;
5111 ov->colour = 0x80 << 8;
5112 ov->hue = 0x80 << 8;
5113
5114 /* This device is not supported yet. Bail out now... */
5115 err("This sensor is not supported yet.");
5116 return -1;
5117
5118 return 0;
5119}
5120
5121/* This initializes the SAA7111A video decoder. */
5122static int
5123saa7111a_configure(struct usb_ov511 *ov)
5124{
5125 int rc;
5126
5127 /* Since there is no register reset command, all registers must be
5128 * written, otherwise gives erratic results */
5129 static struct ov511_regvals aRegvalsNormSAA7111A[] = {
5130 { OV511_I2C_BUS, 0x06, 0xce },
5131 { OV511_I2C_BUS, 0x07, 0x00 },
5132 { OV511_I2C_BUS, 0x10, 0x44 }, /* YUV422, 240/286 lines */
5133 { OV511_I2C_BUS, 0x0e, 0x01 }, /* NTSC M or PAL BGHI */
5134 { OV511_I2C_BUS, 0x00, 0x00 },
5135 { OV511_I2C_BUS, 0x01, 0x00 },
5136 { OV511_I2C_BUS, 0x03, 0x23 },
5137 { OV511_I2C_BUS, 0x04, 0x00 },
5138 { OV511_I2C_BUS, 0x05, 0x00 },
5139 { OV511_I2C_BUS, 0x08, 0xc8 }, /* Auto field freq */
5140 { OV511_I2C_BUS, 0x09, 0x01 }, /* Chrom. trap off, APER=0.25 */
5141 { OV511_I2C_BUS, 0x0a, 0x80 }, /* BRIG=128 */
5142 { OV511_I2C_BUS, 0x0b, 0x40 }, /* CONT=1.0 */
5143 { OV511_I2C_BUS, 0x0c, 0x40 }, /* SATN=1.0 */
5144 { OV511_I2C_BUS, 0x0d, 0x00 }, /* HUE=0 */
5145 { OV511_I2C_BUS, 0x0f, 0x00 },
5146 { OV511_I2C_BUS, 0x11, 0x0c },
5147 { OV511_I2C_BUS, 0x12, 0x00 },
5148 { OV511_I2C_BUS, 0x13, 0x00 },
5149 { OV511_I2C_BUS, 0x14, 0x00 },
5150 { OV511_I2C_BUS, 0x15, 0x00 },
5151 { OV511_I2C_BUS, 0x16, 0x00 },
5152 { OV511_I2C_BUS, 0x17, 0x00 },
5153 { OV511_I2C_BUS, 0x02, 0xc0 }, /* Composite input 0 */
5154 { OV511_DONE_BUS, 0x0, 0x00 },
5155 };
5156
5157// FIXME: I don't know how to sync or reset it yet
5158#if 0
5159 if (ov51x_init_saa_sensor(ov) < 0) {
5160 err("Failed to initialize the SAA7111A");
5161 return -1;
5162 } else {
5163 PDEBUG(1, "SAA7111A sensor detected");
5164 }
5165#endif
5166
5167 /* 640x480 not supported with PAL */
5168 if (ov->pal) {
5169 ov->maxwidth = 320;
5170 ov->maxheight = 240; /* Even field only */
5171 } else {
5172 ov->maxwidth = 640;
5173 ov->maxheight = 480; /* Even/Odd fields */
5174 }
5175
5176 ov->minwidth = 320;
5177 ov->minheight = 240; /* Even field only */
5178
5179 ov->has_decoder = 1;
5180 ov->num_inputs = 8;
5181 ov->norm = VIDEO_MODE_AUTO;
5182 ov->stop_during_set = 0; /* Decoder guarantees stable image */
5183
5184 /* Decoder doesn't change these values, so we use these instead of
5185 * acutally reading the registers (which doesn't work) */
5186 ov->brightness = 0x80 << 8;
5187 ov->contrast = 0x40 << 9;
5188 ov->colour = 0x40 << 9;
5189 ov->hue = 32768;
5190
5191 PDEBUG(4, "Writing SAA7111A registers");
5192 if (write_regvals(ov, aRegvalsNormSAA7111A))
5193 return -1;
5194
5195 /* Detect version of decoder. This must be done after writing the
5196 * initial regs or the decoder will lock up. */
5197 rc = i2c_r(ov, 0x00);
5198
5199 if (rc < 0) {
5200 err("Error detecting sensor version");
5201 return -1;
5202 } else {
5203 info("Sensor is an SAA7111A (version 0x%x)", rc);
5204 ov->sensor = SEN_SAA7111A;
5205 }
5206
5207 // FIXME: Fix this for OV518(+)
5208 /* Latch to negative edge of clock. Otherwise, we get incorrect
5209 * colors and jitter in the digital signal. */
5210 if (ov->bclass == BCL_OV511)
5211 reg_w(ov, 0x11, 0x00);
5212 else
5213 warn("SAA7111A not yet supported with OV518/OV518+");
5214
5215 return 0;
5216}
5217
5218/* This initializes the OV511/OV511+ and the sensor */
5219static int
5220ov511_configure(struct usb_ov511 *ov)
5221{
5222 static struct ov511_regvals aRegvalsInit511[] = {
5223 { OV511_REG_BUS, R51x_SYS_RESET, 0x7f },
5224 { OV511_REG_BUS, R51x_SYS_INIT, 0x01 },
5225 { OV511_REG_BUS, R51x_SYS_RESET, 0x7f },
5226 { OV511_REG_BUS, R51x_SYS_INIT, 0x01 },
5227 { OV511_REG_BUS, R51x_SYS_RESET, 0x3f },
5228 { OV511_REG_BUS, R51x_SYS_INIT, 0x01 },
5229 { OV511_REG_BUS, R51x_SYS_RESET, 0x3d },
5230 { OV511_DONE_BUS, 0x0, 0x00},
5231 };
5232
5233 static struct ov511_regvals aRegvalsNorm511[] = {
5234 { OV511_REG_BUS, R511_DRAM_FLOW_CTL, 0x01 },
5235 { OV511_REG_BUS, R51x_SYS_SNAP, 0x00 },
5236 { OV511_REG_BUS, R51x_SYS_SNAP, 0x02 },
5237 { OV511_REG_BUS, R51x_SYS_SNAP, 0x00 },
5238 { OV511_REG_BUS, R511_FIFO_OPTS, 0x1f },
5239 { OV511_REG_BUS, R511_COMP_EN, 0x00 },
5240 { OV511_REG_BUS, R511_COMP_LUT_EN, 0x03 },
5241 { OV511_DONE_BUS, 0x0, 0x00 },
5242 };
5243
5244 static struct ov511_regvals aRegvalsNorm511Plus[] = {
5245 { OV511_REG_BUS, R511_DRAM_FLOW_CTL, 0xff },
5246 { OV511_REG_BUS, R51x_SYS_SNAP, 0x00 },
5247 { OV511_REG_BUS, R51x_SYS_SNAP, 0x02 },
5248 { OV511_REG_BUS, R51x_SYS_SNAP, 0x00 },
5249 { OV511_REG_BUS, R511_FIFO_OPTS, 0xff },
5250 { OV511_REG_BUS, R511_COMP_EN, 0x00 },
5251 { OV511_REG_BUS, R511_COMP_LUT_EN, 0x03 },
5252 { OV511_DONE_BUS, 0x0, 0x00 },
5253 };
5254
5255 PDEBUG(4, "");
5256
5257 ov->customid = reg_r(ov, R511_SYS_CUST_ID);
5258 if (ov->customid < 0) {
5259 err("Unable to read camera bridge registers");
5260 goto error;
5261 }
5262
5263 PDEBUG (1, "CustomID = %d", ov->customid);
5264 ov->desc = symbolic(camlist, ov->customid);
5265 info("model: %s", ov->desc);
5266
5267 if (0 == strcmp(ov->desc, NOT_DEFINED_STR)) {
5268 err("Camera type (%d) not recognized", ov->customid);
5269 err("Please notify " EMAIL " of the name,");
5270 err("manufacturer, model, and this number of your camera.");
5271 err("Also include the output of the detection process.");
5272 }
5273
5274 if (ov->customid == 70) /* USB Life TV (PAL/SECAM) */
5275 ov->pal = 1;
5276
5277 if (write_regvals(ov, aRegvalsInit511))
5278 goto error;
5279
5280 if (ov->led_policy == LED_OFF || ov->led_policy == LED_AUTO)
5281 ov51x_led_control(ov, 0);
5282
5283 /* The OV511+ has undocumented bits in the flow control register.
5284 * Setting it to 0xff fixes the corruption with moving objects. */
5285 if (ov->bridge == BRG_OV511) {
5286 if (write_regvals(ov, aRegvalsNorm511))
5287 goto error;
5288 } else if (ov->bridge == BRG_OV511PLUS) {
5289 if (write_regvals(ov, aRegvalsNorm511Plus))
5290 goto error;
5291 } else {
5292 err("Invalid bridge");
5293 }
5294
5295 if (ov511_init_compression(ov))
5296 goto error;
5297
5298 ov->packet_numbering = 1;
5299 ov511_set_packet_size(ov, 0);
5300
5301 ov->snap_enabled = snapshot;
5302
5303 /* Test for 7xx0 */
5304 PDEBUG(3, "Testing for 0V7xx0");
5305 ov->primary_i2c_slave = OV7xx0_SID;
5306 if (ov51x_set_slave_ids(ov, OV7xx0_SID) < 0)
5307 goto error;
5308
5309 if (i2c_w(ov, 0x12, 0x80) < 0) {
5310 /* Test for 6xx0 */
5311 PDEBUG(3, "Testing for 0V6xx0");
5312 ov->primary_i2c_slave = OV6xx0_SID;
5313 if (ov51x_set_slave_ids(ov, OV6xx0_SID) < 0)
5314 goto error;
5315
5316 if (i2c_w(ov, 0x12, 0x80) < 0) {
5317 /* Test for 8xx0 */
5318 PDEBUG(3, "Testing for 0V8xx0");
5319 ov->primary_i2c_slave = OV8xx0_SID;
5320 if (ov51x_set_slave_ids(ov, OV8xx0_SID) < 0)
5321 goto error;
5322
5323 if (i2c_w(ov, 0x12, 0x80) < 0) {
5324 /* Test for SAA7111A */
5325 PDEBUG(3, "Testing for SAA7111A");
5326 ov->primary_i2c_slave = SAA7111A_SID;
5327 if (ov51x_set_slave_ids(ov, SAA7111A_SID) < 0)
5328 goto error;
5329
5330 if (i2c_w(ov, 0x0d, 0x00) < 0) {
5331 /* Test for KS0127 */
5332 PDEBUG(3, "Testing for KS0127");
5333 ov->primary_i2c_slave = KS0127_SID;
5334 if (ov51x_set_slave_ids(ov, KS0127_SID) < 0)
5335 goto error;
5336
5337 if (i2c_w(ov, 0x10, 0x00) < 0) {
5338 err("Can't determine sensor slave IDs");
5339 goto error;
5340 } else {
5341 if (ks0127_configure(ov) < 0) {
5342 err("Failed to configure KS0127");
5343 goto error;
5344 }
5345 }
5346 } else {
5347 if (saa7111a_configure(ov) < 0) {
5348 err("Failed to configure SAA7111A");
5349 goto error;
5350 }
5351 }
5352 } else {
5353 err("Detected unsupported OV8xx0 sensor");
5354 goto error;
5355 }
5356 } else {
5357 if (ov6xx0_configure(ov) < 0) {
5358 err("Failed to configure OV6xx0");
5359 goto error;
5360 }
5361 }
5362 } else {
5363 if (ov7xx0_configure(ov) < 0) {
5364 err("Failed to configure OV7xx0");
5365 goto error;
5366 }
5367 }
5368
5369 return 0;
5370
5371error:
5372 err("OV511 Config failed");
5373
5374 return -EBUSY;
5375}
5376
5377/* This initializes the OV518/OV518+ and the sensor */
5378static int
5379ov518_configure(struct usb_ov511 *ov)
5380{
5381 /* For 518 and 518+ */
5382 static struct ov511_regvals aRegvalsInit518[] = {
5383 { OV511_REG_BUS, R51x_SYS_RESET, 0x40 },
5384 { OV511_REG_BUS, R51x_SYS_INIT, 0xe1 },
5385 { OV511_REG_BUS, R51x_SYS_RESET, 0x3e },
5386 { OV511_REG_BUS, R51x_SYS_INIT, 0xe1 },
5387 { OV511_REG_BUS, R51x_SYS_RESET, 0x00 },
5388 { OV511_REG_BUS, R51x_SYS_INIT, 0xe1 },
5389 { OV511_REG_BUS, 0x46, 0x00 },
5390 { OV511_REG_BUS, 0x5d, 0x03 },
5391 { OV511_DONE_BUS, 0x0, 0x00},
5392 };
5393
5394 static struct ov511_regvals aRegvalsNorm518[] = {
5395 { OV511_REG_BUS, R51x_SYS_SNAP, 0x02 }, /* Reset */
5396 { OV511_REG_BUS, R51x_SYS_SNAP, 0x01 }, /* Enable */
5397 { OV511_REG_BUS, 0x31, 0x0f },
5398 { OV511_REG_BUS, 0x5d, 0x03 },
5399 { OV511_REG_BUS, 0x24, 0x9f },
5400 { OV511_REG_BUS, 0x25, 0x90 },
5401 { OV511_REG_BUS, 0x20, 0x00 },
5402 { OV511_REG_BUS, 0x51, 0x04 },
5403 { OV511_REG_BUS, 0x71, 0x19 },
5404 { OV511_DONE_BUS, 0x0, 0x00 },
5405 };
5406
5407 static struct ov511_regvals aRegvalsNorm518Plus[] = {
5408 { OV511_REG_BUS, R51x_SYS_SNAP, 0x02 }, /* Reset */
5409 { OV511_REG_BUS, R51x_SYS_SNAP, 0x01 }, /* Enable */
5410 { OV511_REG_BUS, 0x31, 0x0f },
5411 { OV511_REG_BUS, 0x5d, 0x03 },
5412 { OV511_REG_BUS, 0x24, 0x9f },
5413 { OV511_REG_BUS, 0x25, 0x90 },
5414 { OV511_REG_BUS, 0x20, 0x60 },
5415 { OV511_REG_BUS, 0x51, 0x02 },
5416 { OV511_REG_BUS, 0x71, 0x19 },
5417 { OV511_REG_BUS, 0x40, 0xff },
5418 { OV511_REG_BUS, 0x41, 0x42 },
5419 { OV511_REG_BUS, 0x46, 0x00 },
5420 { OV511_REG_BUS, 0x33, 0x04 },
5421 { OV511_REG_BUS, 0x21, 0x19 },
5422 { OV511_REG_BUS, 0x3f, 0x10 },
5423 { OV511_DONE_BUS, 0x0, 0x00 },
5424 };
5425
5426 PDEBUG(4, "");
5427
5428 /* First 5 bits of custom ID reg are a revision ID on OV518 */
5429 info("Device revision %d", 0x1F & reg_r(ov, R511_SYS_CUST_ID));
5430
5431 /* Give it the default description */
5432 ov->desc = symbolic(camlist, 0);
5433
5434 if (write_regvals(ov, aRegvalsInit518))
5435 goto error;
5436
5437 /* Set LED GPIO pin to output mode */
5438 if (reg_w_mask(ov, 0x57, 0x00, 0x02) < 0)
5439 goto error;
5440
5441 /* LED is off by default with OV518; have to explicitly turn it on */
5442 if (ov->led_policy == LED_OFF || ov->led_policy == LED_AUTO)
5443 ov51x_led_control(ov, 0);
5444 else
5445 ov51x_led_control(ov, 1);
5446
5447 /* Don't require compression if dumppix is enabled; otherwise it's
5448 * required. OV518 has no uncompressed mode, to save RAM. */
5449 if (!dumppix && !ov->compress) {
5450 ov->compress = 1;
5451 warn("Compression required with OV518...enabling");
5452 }
5453
5454 if (ov->bridge == BRG_OV518) {
5455 if (write_regvals(ov, aRegvalsNorm518))
5456 goto error;
5457 } else if (ov->bridge == BRG_OV518PLUS) {
5458 if (write_regvals(ov, aRegvalsNorm518Plus))
5459 goto error;
5460 } else {
5461 err("Invalid bridge");
5462 }
5463
5464 if (reg_w(ov, 0x2f, 0x80) < 0)
5465 goto error;
5466
5467 if (ov518_init_compression(ov))
5468 goto error;
5469
5470 if (ov->bridge == BRG_OV518)
5471 {
5472 struct usb_interface *ifp;
5473 struct usb_host_interface *alt;
5474 __u16 mxps = 0;
5475
5476 ifp = usb_ifnum_to_if(ov->dev, 0);
5477 if (ifp) {
5478 alt = usb_altnum_to_altsetting(ifp, 7);
5479 if (alt)
5480 mxps = le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize);
5481 }
5482
5483 /* Some OV518s have packet numbering by default, some don't */
5484 if (mxps == 897)
5485 ov->packet_numbering = 1;
5486 else
5487 ov->packet_numbering = 0;
5488 } else {
5489 /* OV518+ has packet numbering turned on by default */
5490 ov->packet_numbering = 1;
5491 }
5492
5493 ov518_set_packet_size(ov, 0);
5494
5495 ov->snap_enabled = snapshot;
5496
5497 /* Test for 76xx */
5498 ov->primary_i2c_slave = OV7xx0_SID;
5499 if (ov51x_set_slave_ids(ov, OV7xx0_SID) < 0)
5500 goto error;
5501
5502 /* The OV518 must be more aggressive about sensor detection since
5503 * I2C write will never fail if the sensor is not present. We have
5504 * to try to initialize the sensor to detect its presence */
5505
5506 if (init_ov_sensor(ov) < 0) {
5507 /* Test for 6xx0 */
5508 ov->primary_i2c_slave = OV6xx0_SID;
5509 if (ov51x_set_slave_ids(ov, OV6xx0_SID) < 0)
5510 goto error;
5511
5512 if (init_ov_sensor(ov) < 0) {
5513 /* Test for 8xx0 */
5514 ov->primary_i2c_slave = OV8xx0_SID;
5515 if (ov51x_set_slave_ids(ov, OV8xx0_SID) < 0)
5516 goto error;
5517
5518 if (init_ov_sensor(ov) < 0) {
5519 err("Can't determine sensor slave IDs");
5520 goto error;
5521 } else {
5522 err("Detected unsupported OV8xx0 sensor");
5523 goto error;
5524 }
5525 } else {
5526 if (ov6xx0_configure(ov) < 0) {
5527 err("Failed to configure OV6xx0");
5528 goto error;
5529 }
5530 }
5531 } else {
5532 if (ov7xx0_configure(ov) < 0) {
5533 err("Failed to configure OV7xx0");
5534 goto error;
5535 }
5536 }
5537
5538 ov->maxwidth = 352;
5539 ov->maxheight = 288;
5540
5541 // The OV518 cannot go as low as the sensor can
5542 ov->minwidth = 160;
5543 ov->minheight = 120;
5544
5545 return 0;
5546
5547error:
5548 err("OV518 Config failed");
5549
5550 return -EBUSY;
5551}
5552
5553/****************************************************************************
5554 * sysfs
5555 ***************************************************************************/
5556
5557static inline struct usb_ov511 *cd_to_ov(struct class_device *cd)
5558{
5559 struct video_device *vdev = to_video_device(cd);
5560 return video_get_drvdata(vdev);
5561}
5562
5563static ssize_t show_custom_id(struct class_device *cd, char *buf)
5564{
5565 struct usb_ov511 *ov = cd_to_ov(cd);
5566 return sprintf(buf, "%d\n", ov->customid);
5567}
5568static CLASS_DEVICE_ATTR(custom_id, S_IRUGO, show_custom_id, NULL);
5569
5570static ssize_t show_model(struct class_device *cd, char *buf)
5571{
5572 struct usb_ov511 *ov = cd_to_ov(cd);
5573 return sprintf(buf, "%s\n", ov->desc);
5574}
5575static CLASS_DEVICE_ATTR(model, S_IRUGO, show_model, NULL);
5576
5577static ssize_t show_bridge(struct class_device *cd, char *buf)
5578{
5579 struct usb_ov511 *ov = cd_to_ov(cd);
5580 return sprintf(buf, "%s\n", symbolic(brglist, ov->bridge));
5581}
5582static CLASS_DEVICE_ATTR(bridge, S_IRUGO, show_bridge, NULL);
5583
5584static ssize_t show_sensor(struct class_device *cd, char *buf)
5585{
5586 struct usb_ov511 *ov = cd_to_ov(cd);
5587 return sprintf(buf, "%s\n", symbolic(senlist, ov->sensor));
5588}
5589static CLASS_DEVICE_ATTR(sensor, S_IRUGO, show_sensor, NULL);
5590
5591static ssize_t show_brightness(struct class_device *cd, char *buf)
5592{
5593 struct usb_ov511 *ov = cd_to_ov(cd);
5594 unsigned short x;
5595
5596 if (!ov->dev)
5597 return -ENODEV;
5598 sensor_get_brightness(ov, &x);
5599 return sprintf(buf, "%d\n", x >> 8);
5600}
5601static CLASS_DEVICE_ATTR(brightness, S_IRUGO, show_brightness, NULL);
5602
5603static ssize_t show_saturation(struct class_device *cd, char *buf)
5604{
5605 struct usb_ov511 *ov = cd_to_ov(cd);
5606 unsigned short x;
5607
5608 if (!ov->dev)
5609 return -ENODEV;
5610 sensor_get_saturation(ov, &x);
5611 return sprintf(buf, "%d\n", x >> 8);
5612}
5613static CLASS_DEVICE_ATTR(saturation, S_IRUGO, show_saturation, NULL);
5614
5615static ssize_t show_contrast(struct class_device *cd, char *buf)
5616{
5617 struct usb_ov511 *ov = cd_to_ov(cd);
5618 unsigned short x;
5619
5620 if (!ov->dev)
5621 return -ENODEV;
5622 sensor_get_contrast(ov, &x);
5623 return sprintf(buf, "%d\n", x >> 8);
5624}
5625static CLASS_DEVICE_ATTR(contrast, S_IRUGO, show_contrast, NULL);
5626
5627static ssize_t show_hue(struct class_device *cd, char *buf)
5628{
5629 struct usb_ov511 *ov = cd_to_ov(cd);
5630 unsigned short x;
5631
5632 if (!ov->dev)
5633 return -ENODEV;
5634 sensor_get_hue(ov, &x);
5635 return sprintf(buf, "%d\n", x >> 8);
5636}
5637static CLASS_DEVICE_ATTR(hue, S_IRUGO, show_hue, NULL);
5638
5639static ssize_t show_exposure(struct class_device *cd, char *buf)
5640{
5641 struct usb_ov511 *ov = cd_to_ov(cd);
5642 unsigned char exp = 0;
5643
5644 if (!ov->dev)
5645 return -ENODEV;
5646 sensor_get_exposure(ov, &exp);
5647 return sprintf(buf, "%d\n", exp >> 8);
5648}
5649static CLASS_DEVICE_ATTR(exposure, S_IRUGO, show_exposure, NULL);
5650
5651static void ov_create_sysfs(struct video_device *vdev)
5652{
5653 video_device_create_file(vdev, &class_device_attr_custom_id);
5654 video_device_create_file(vdev, &class_device_attr_model);
5655 video_device_create_file(vdev, &class_device_attr_bridge);
5656 video_device_create_file(vdev, &class_device_attr_sensor);
5657 video_device_create_file(vdev, &class_device_attr_brightness);
5658 video_device_create_file(vdev, &class_device_attr_saturation);
5659 video_device_create_file(vdev, &class_device_attr_contrast);
5660 video_device_create_file(vdev, &class_device_attr_hue);
5661 video_device_create_file(vdev, &class_device_attr_exposure);
5662}
5663
5664/****************************************************************************
5665 * USB routines
5666 ***************************************************************************/
5667
5668static int
5669ov51x_probe(struct usb_interface *intf, const struct usb_device_id *id)
5670{
5671 struct usb_device *dev = interface_to_usbdev(intf);
5672 struct usb_interface_descriptor *idesc;
5673 struct usb_ov511 *ov;
5674 int i;
5675
5676 PDEBUG(1, "probing for device...");
5677
5678 /* We don't handle multi-config cameras */
5679 if (dev->descriptor.bNumConfigurations != 1)
5680 return -ENODEV;
5681
5682 idesc = &intf->cur_altsetting->desc;
5683
5684 if (idesc->bInterfaceClass != 0xFF)
5685 return -ENODEV;
5686 if (idesc->bInterfaceSubClass != 0x00)
5687 return -ENODEV;
5688
5689 if ((ov = kzalloc(sizeof(*ov), GFP_KERNEL)) == NULL) {
5690 err("couldn't kmalloc ov struct");
5691 goto error_out;
5692 }
5693
5694 ov->dev = dev;
5695 ov->iface = idesc->bInterfaceNumber;
5696 ov->led_policy = led;
5697 ov->compress = compress;
5698 ov->lightfreq = lightfreq;
5699 ov->num_inputs = 1; /* Video decoder init functs. change this */
5700 ov->stop_during_set = !fastset;
5701 ov->backlight = backlight;
5702 ov->mirror = mirror;
5703 ov->auto_brt = autobright;
5704 ov->auto_gain = autogain;
5705 ov->auto_exp = autoexp;
5706
5707 switch (le16_to_cpu(dev->descriptor.idProduct)) {
5708 case PROD_OV511:
5709 ov->bridge = BRG_OV511;
5710 ov->bclass = BCL_OV511;
5711 break;
5712 case PROD_OV511PLUS:
5713 ov->bridge = BRG_OV511PLUS;
5714 ov->bclass = BCL_OV511;
5715 break;
5716 case PROD_OV518:
5717 ov->bridge = BRG_OV518;
5718 ov->bclass = BCL_OV518;
5719 break;
5720 case PROD_OV518PLUS:
5721 ov->bridge = BRG_OV518PLUS;
5722 ov->bclass = BCL_OV518;
5723 break;
5724 case PROD_ME2CAM:
5725 if (le16_to_cpu(dev->descriptor.idVendor) != VEND_MATTEL)
5726 goto error;
5727 ov->bridge = BRG_OV511PLUS;
5728 ov->bclass = BCL_OV511;
5729 break;
5730 default:
5731 err("Unknown product ID 0x%04x", le16_to_cpu(dev->descriptor.idProduct));
5732 goto error;
5733 }
5734
5735 info("USB %s video device found", symbolic(brglist, ov->bridge));
5736
5737 init_waitqueue_head(&ov->wq);
5738
5739 mutex_init(&ov->lock); /* to 1 == available */
5740 mutex_init(&ov->buf_lock);
5741 mutex_init(&ov->i2c_lock);
5742 mutex_init(&ov->cbuf_lock);
5743
5744 ov->buf_state = BUF_NOT_ALLOCATED;
5745
5746 if (usb_make_path(dev, ov->usb_path, OV511_USB_PATH_LEN) < 0) {
5747 err("usb_make_path error");
5748 goto error;
5749 }
5750
5751 /* Allocate control transfer buffer. */
5752 /* Must be kmalloc()'ed, for DMA compatibility */
5753 ov->cbuf = kmalloc(OV511_CBUF_SIZE, GFP_KERNEL);
5754 if (!ov->cbuf)
5755 goto error;
5756
5757 if (ov->bclass == BCL_OV518) {
5758 if (ov518_configure(ov) < 0)
5759 goto error;
5760 } else {
5761 if (ov511_configure(ov) < 0)
5762 goto error;
5763 }
5764
5765 for (i = 0; i < OV511_NUMFRAMES; i++) {
5766 ov->frame[i].framenum = i;
5767 init_waitqueue_head(&ov->frame[i].wq);
5768 }
5769
5770 for (i = 0; i < OV511_NUMSBUF; i++) {
5771 ov->sbuf[i].ov = ov;
5772 spin_lock_init(&ov->sbuf[i].lock);
5773 ov->sbuf[i].n = i;
5774 }
5775
5776 /* Unnecessary? (This is done on open(). Need to make sure variables
5777 * are properly initialized without this before removing it, though). */
5778 if (ov51x_set_default_params(ov) < 0)
5779 goto error;
5780
5781#ifdef OV511_DEBUG
5782 if (dump_bridge) {
5783 if (ov->bclass == BCL_OV511)
5784 ov511_dump_regs(ov);
5785 else
5786 ov518_dump_regs(ov);
5787 }
5788#endif
5789
5790 ov->vdev = video_device_alloc();
5791 if (!ov->vdev)
5792 goto error;
5793
5794 memcpy(ov->vdev, &vdev_template, sizeof(*ov->vdev));
5795 ov->vdev->dev = &dev->dev;
5796 video_set_drvdata(ov->vdev, ov);
5797
5798 for (i = 0; i < OV511_MAX_UNIT_VIDEO; i++) {
5799 /* Minor 0 cannot be specified; assume user wants autodetect */
5800 if (unit_video[i] == 0)
5801 break;
5802
5803 if (video_register_device(ov->vdev, VFL_TYPE_GRABBER,
5804 unit_video[i]) >= 0) {
5805 break;
5806 }
5807 }
5808
5809 /* Use the next available one */
5810 if ((ov->vdev->minor == -1) &&
5811 video_register_device(ov->vdev, VFL_TYPE_GRABBER, -1) < 0) {
5812 err("video_register_device failed");
5813 goto error;
5814 }
5815
5816 info("Device at %s registered to minor %d", ov->usb_path,
5817 ov->vdev->minor);
5818
5819 usb_set_intfdata(intf, ov);
5820 ov_create_sysfs(ov->vdev);
5821 return 0;
5822
5823error:
5824 if (ov->vdev) {
5825 if (-1 == ov->vdev->minor)
5826 video_device_release(ov->vdev);
5827 else
5828 video_unregister_device(ov->vdev);
5829 ov->vdev = NULL;
5830 }
5831
5832 if (ov->cbuf) {
5833 mutex_lock(&ov->cbuf_lock);
5834 kfree(ov->cbuf);
5835 ov->cbuf = NULL;
5836 mutex_unlock(&ov->cbuf_lock);
5837 }
5838
5839 kfree(ov);
5840 ov = NULL;
5841
5842error_out:
5843 err("Camera initialization failed");
5844 return -EIO;
5845}
5846
5847static void
5848ov51x_disconnect(struct usb_interface *intf)
5849{
5850 struct usb_ov511 *ov = usb_get_intfdata(intf);
5851 int n;
5852
5853 PDEBUG(3, "");
5854
5855 usb_set_intfdata (intf, NULL);
5856
5857 if (!ov)
5858 return;
5859
5860 if (ov->vdev)
5861 video_unregister_device(ov->vdev);
5862
5863 for (n = 0; n < OV511_NUMFRAMES; n++)
5864 ov->frame[n].grabstate = FRAME_ERROR;
5865
5866 ov->curframe = -1;
5867
5868 /* This will cause the process to request another frame */
5869 for (n = 0; n < OV511_NUMFRAMES; n++)
5870 wake_up_interruptible(&ov->frame[n].wq);
5871
5872 wake_up_interruptible(&ov->wq);
5873
5874 ov->streaming = 0;
5875 ov51x_unlink_isoc(ov);
5876
5877 ov->dev = NULL;
5878
5879 /* Free the memory */
5880 if (ov && !ov->user) {
5881 mutex_lock(&ov->cbuf_lock);
5882 kfree(ov->cbuf);
5883 ov->cbuf = NULL;
5884 mutex_unlock(&ov->cbuf_lock);
5885
5886 ov51x_dealloc(ov);
5887 kfree(ov);
5888 ov = NULL;
5889 }
5890
5891 PDEBUG(3, "Disconnect complete");
5892}
5893
5894static struct usb_driver ov511_driver = {
5895 .name = "ov511",
5896 .id_table = device_table,
5897 .probe = ov51x_probe,
5898 .disconnect = ov51x_disconnect
5899};
5900
5901/****************************************************************************
5902 *
5903 * Module routines
5904 *
5905 ***************************************************************************/
5906
5907static int __init
5908usb_ov511_init(void)
5909{
5910 int retval;
5911
5912 retval = usb_register(&ov511_driver);
5913 if (retval)
5914 goto out;
5915
5916 info(DRIVER_VERSION " : " DRIVER_DESC);
5917
5918out:
5919 return retval;
5920}
5921
5922static void __exit
5923usb_ov511_exit(void)
5924{
5925 usb_deregister(&ov511_driver);
5926 info("driver deregistered");
5927
5928}
5929
5930module_init(usb_ov511_init);
5931module_exit(usb_ov511_exit);
5932
diff --git a/drivers/media/video/ov511.h b/drivers/media/video/ov511.h
new file mode 100644
index 000000000000..bce9b3633889
--- /dev/null
+++ b/drivers/media/video/ov511.h
@@ -0,0 +1,568 @@
1#ifndef __LINUX_OV511_H
2#define __LINUX_OV511_H
3
4#include <asm/uaccess.h>
5#include <linux/videodev.h>
6#include <linux/smp_lock.h>
7#include <linux/usb.h>
8#include <linux/mutex.h>
9
10#define OV511_DEBUG /* Turn on debug messages */
11
12#ifdef OV511_DEBUG
13 #define PDEBUG(level, fmt, args...) \
14 if (debug >= (level)) info("[%s:%d] " fmt, \
15 __FUNCTION__, __LINE__ , ## args)
16#else
17 #define PDEBUG(level, fmt, args...) do {} while(0)
18#endif
19
20/* This macro restricts an int variable to an inclusive range */
21#define RESTRICT_TO_RANGE(v,mi,ma) { \
22 if ((v) < (mi)) (v) = (mi); \
23 else if ((v) > (ma)) (v) = (ma); \
24}
25
26/* --------------------------------- */
27/* DEFINES FOR OV511 AND OTHER CHIPS */
28/* --------------------------------- */
29
30/* USB IDs */
31#define VEND_OMNIVISION 0x05A9
32#define PROD_OV511 0x0511
33#define PROD_OV511PLUS 0xA511
34#define PROD_OV518 0x0518
35#define PROD_OV518PLUS 0xA518
36
37#define VEND_MATTEL 0x0813
38#define PROD_ME2CAM 0x0002
39
40/* --------------------------------- */
41/* OV51x REGISTER MNEMONICS */
42/* --------------------------------- */
43
44/* Camera interface register numbers */
45#define R511_CAM_DELAY 0x10
46#define R511_CAM_EDGE 0x11
47#define R511_CAM_PXCNT 0x12
48#define R511_CAM_LNCNT 0x13
49#define R511_CAM_PXDIV 0x14
50#define R511_CAM_LNDIV 0x15
51#define R511_CAM_UV_EN 0x16
52#define R511_CAM_LINE_MODE 0x17
53#define R511_CAM_OPTS 0x18
54
55/* Snapshot mode camera interface register numbers */
56#define R511_SNAP_FRAME 0x19
57#define R511_SNAP_PXCNT 0x1A
58#define R511_SNAP_LNCNT 0x1B
59#define R511_SNAP_PXDIV 0x1C
60#define R511_SNAP_LNDIV 0x1D
61#define R511_SNAP_UV_EN 0x1E
62#define R511_SNAP_OPTS 0x1F
63
64/* DRAM register numbers */
65#define R511_DRAM_FLOW_CTL 0x20
66#define R511_DRAM_ARCP 0x21
67#define R511_DRAM_MRC 0x22
68#define R511_DRAM_RFC 0x23
69
70/* ISO FIFO register numbers */
71#define R51x_FIFO_PSIZE 0x30 /* 2 bytes wide w/ OV518(+) */
72#define R511_FIFO_OPTS 0x31
73
74/* Parallel IO register numbers */
75#define R511_PIO_OPTS 0x38
76#define R511_PIO_DATA 0x39
77#define R511_PIO_BIST 0x3E
78#define R518_GPIO_IN 0x55 /* OV518(+) only */
79#define R518_GPIO_OUT 0x56 /* OV518(+) only */
80#define R518_GPIO_CTL 0x57 /* OV518(+) only */
81#define R518_GPIO_PULSE_IN 0x58 /* OV518(+) only */
82#define R518_GPIO_PULSE_CLEAR 0x59 /* OV518(+) only */
83#define R518_GPIO_PULSE_POL 0x5a /* OV518(+) only */
84#define R518_GPIO_PULSE_EN 0x5b /* OV518(+) only */
85#define R518_GPIO_RESET 0x5c /* OV518(+) only */
86
87/* I2C registers */
88#define R511_I2C_CTL 0x40
89#define R518_I2C_CTL 0x47 /* OV518(+) only */
90#define R51x_I2C_W_SID 0x41
91#define R51x_I2C_SADDR_3 0x42
92#define R51x_I2C_SADDR_2 0x43
93#define R51x_I2C_R_SID 0x44
94#define R51x_I2C_DATA 0x45
95#define R51x_I2C_CLOCK 0x46
96#define R51x_I2C_TIMEOUT 0x47
97
98/* I2C snapshot registers */
99#define R511_SI2C_SADDR_3 0x48
100#define R511_SI2C_DATA 0x49
101
102/* System control registers */
103#define R51x_SYS_RESET 0x50
104 /* Reset type definitions */
105#define OV511_RESET_UDC 0x01
106#define OV511_RESET_I2C 0x02
107#define OV511_RESET_FIFO 0x04
108#define OV511_RESET_OMNICE 0x08
109#define OV511_RESET_DRAM 0x10
110#define OV511_RESET_CAM_INT 0x20
111#define OV511_RESET_OV511 0x40
112#define OV511_RESET_NOREGS 0x3F /* All but OV511 & regs */
113#define OV511_RESET_ALL 0x7F
114
115#define R511_SYS_CLOCK_DIV 0x51
116#define R51x_SYS_SNAP 0x52
117#define R51x_SYS_INIT 0x53
118#define R511_SYS_PWR_CLK 0x54 /* OV511+/OV518(+) only */
119#define R511_SYS_LED_CTL 0x55 /* OV511+ only */
120#define R511_SYS_USER 0x5E
121#define R511_SYS_CUST_ID 0x5F
122
123/* OmniCE (compression) registers */
124#define R511_COMP_PHY 0x70
125#define R511_COMP_PHUV 0x71
126#define R511_COMP_PVY 0x72
127#define R511_COMP_PVUV 0x73
128#define R511_COMP_QHY 0x74
129#define R511_COMP_QHUV 0x75
130#define R511_COMP_QVY 0x76
131#define R511_COMP_QVUV 0x77
132#define R511_COMP_EN 0x78
133#define R511_COMP_LUT_EN 0x79
134#define R511_COMP_LUT_BEGIN 0x80
135
136/* --------------------------------- */
137/* ALTERNATE NUMBERS */
138/* --------------------------------- */
139
140/* Alternate numbers for various max packet sizes (OV511 only) */
141#define OV511_ALT_SIZE_992 0
142#define OV511_ALT_SIZE_993 1
143#define OV511_ALT_SIZE_768 2
144#define OV511_ALT_SIZE_769 3
145#define OV511_ALT_SIZE_512 4
146#define OV511_ALT_SIZE_513 5
147#define OV511_ALT_SIZE_257 6
148#define OV511_ALT_SIZE_0 7
149
150/* Alternate numbers for various max packet sizes (OV511+ only) */
151#define OV511PLUS_ALT_SIZE_0 0
152#define OV511PLUS_ALT_SIZE_33 1
153#define OV511PLUS_ALT_SIZE_129 2
154#define OV511PLUS_ALT_SIZE_257 3
155#define OV511PLUS_ALT_SIZE_385 4
156#define OV511PLUS_ALT_SIZE_513 5
157#define OV511PLUS_ALT_SIZE_769 6
158#define OV511PLUS_ALT_SIZE_961 7
159
160/* Alternate numbers for various max packet sizes (OV518(+) only) */
161#define OV518_ALT_SIZE_0 0
162#define OV518_ALT_SIZE_128 1
163#define OV518_ALT_SIZE_256 2
164#define OV518_ALT_SIZE_384 3
165#define OV518_ALT_SIZE_512 4
166#define OV518_ALT_SIZE_640 5
167#define OV518_ALT_SIZE_768 6
168#define OV518_ALT_SIZE_896 7
169
170/* --------------------------------- */
171/* OV7610 REGISTER MNEMONICS */
172/* --------------------------------- */
173
174/* OV7610 registers */
175#define OV7610_REG_GAIN 0x00 /* gain setting (5:0) */
176#define OV7610_REG_BLUE 0x01 /* blue channel balance */
177#define OV7610_REG_RED 0x02 /* red channel balance */
178#define OV7610_REG_SAT 0x03 /* saturation */
179 /* 04 reserved */
180#define OV7610_REG_CNT 0x05 /* Y contrast */
181#define OV7610_REG_BRT 0x06 /* Y brightness */
182 /* 08-0b reserved */
183#define OV7610_REG_BLUE_BIAS 0x0C /* blue channel bias (5:0) */
184#define OV7610_REG_RED_BIAS 0x0D /* read channel bias (5:0) */
185#define OV7610_REG_GAMMA_COEFF 0x0E /* gamma settings */
186#define OV7610_REG_WB_RANGE 0x0F /* AEC/ALC/S-AWB settings */
187#define OV7610_REG_EXP 0x10 /* manual exposure setting */
188#define OV7610_REG_CLOCK 0x11 /* polarity/clock prescaler */
189#define OV7610_REG_COM_A 0x12 /* misc common regs */
190#define OV7610_REG_COM_B 0x13 /* misc common regs */
191#define OV7610_REG_COM_C 0x14 /* misc common regs */
192#define OV7610_REG_COM_D 0x15 /* misc common regs */
193#define OV7610_REG_FIELD_DIVIDE 0x16 /* field interval/mode settings */
194#define OV7610_REG_HWIN_START 0x17 /* horizontal window start */
195#define OV7610_REG_HWIN_END 0x18 /* horizontal window end */
196#define OV7610_REG_VWIN_START 0x19 /* vertical window start */
197#define OV7610_REG_VWIN_END 0x1A /* vertical window end */
198#define OV7610_REG_PIXEL_SHIFT 0x1B /* pixel shift */
199#define OV7610_REG_ID_HIGH 0x1C /* manufacturer ID MSB */
200#define OV7610_REG_ID_LOW 0x1D /* manufacturer ID LSB */
201 /* 0e-0f reserved */
202#define OV7610_REG_COM_E 0x20 /* misc common regs */
203#define OV7610_REG_YOFFSET 0x21 /* Y channel offset */
204#define OV7610_REG_UOFFSET 0x22 /* U channel offset */
205 /* 23 reserved */
206#define OV7610_REG_ECW 0x24 /* Exposure white level for AEC */
207#define OV7610_REG_ECB 0x25 /* Exposure black level for AEC */
208#define OV7610_REG_COM_F 0x26 /* misc settings */
209#define OV7610_REG_COM_G 0x27 /* misc settings */
210#define OV7610_REG_COM_H 0x28 /* misc settings */
211#define OV7610_REG_COM_I 0x29 /* misc settings */
212#define OV7610_REG_FRAMERATE_H 0x2A /* frame rate MSB + misc */
213#define OV7610_REG_FRAMERATE_L 0x2B /* frame rate LSB */
214#define OV7610_REG_ALC 0x2C /* Auto Level Control settings */
215#define OV7610_REG_COM_J 0x2D /* misc settings */
216#define OV7610_REG_VOFFSET 0x2E /* V channel offset adjustment */
217#define OV7610_REG_ARRAY_BIAS 0x2F /* Array bias -- don't change */
218 /* 30-32 reserved */
219#define OV7610_REG_YGAMMA 0x33 /* misc gamma settings (7:6) */
220#define OV7610_REG_BIAS_ADJUST 0x34 /* misc bias settings */
221#define OV7610_REG_COM_L 0x35 /* misc settings */
222 /* 36-37 reserved */
223#define OV7610_REG_COM_K 0x38 /* misc registers */
224
225/* --------------------------------- */
226/* I2C ADDRESSES */
227/* --------------------------------- */
228
229#define OV7xx0_SID 0x42
230#define OV6xx0_SID 0xC0
231#define OV8xx0_SID 0xA0
232#define KS0127_SID 0xD8
233#define SAA7111A_SID 0x48
234
235/* --------------------------------- */
236/* MISCELLANEOUS DEFINES */
237/* --------------------------------- */
238
239#define I2C_CLOCK_PRESCALER 0x03
240
241#define FRAMES_PER_DESC 10 /* FIXME - What should this be? */
242#define MAX_FRAME_SIZE_PER_DESC 993 /* For statically allocated stuff */
243#define PIXELS_PER_SEG 256 /* Pixels per segment */
244
245#define OV511_ENDPOINT_ADDRESS 1 /* Isoc endpoint number */
246
247#define OV511_NUMFRAMES 2
248#if OV511_NUMFRAMES > VIDEO_MAX_FRAME
249 #error "OV511_NUMFRAMES is too high"
250#endif
251
252#define OV511_NUMSBUF 2
253
254/* Control transfers use up to 4 bytes */
255#define OV511_CBUF_SIZE 4
256
257/* Size of usb_make_path() buffer */
258#define OV511_USB_PATH_LEN 64
259
260/* Bridge types */
261enum {
262 BRG_UNKNOWN,
263 BRG_OV511,
264 BRG_OV511PLUS,
265 BRG_OV518,
266 BRG_OV518PLUS,
267};
268
269/* Bridge classes */
270enum {
271 BCL_UNKNOWN,
272 BCL_OV511,
273 BCL_OV518,
274};
275
276/* Sensor types */
277enum {
278 SEN_UNKNOWN,
279 SEN_OV76BE,
280 SEN_OV7610,
281 SEN_OV7620,
282 SEN_OV7620AE,
283 SEN_OV6620,
284 SEN_OV6630,
285 SEN_OV6630AE,
286 SEN_OV6630AF,
287 SEN_OV8600,
288 SEN_KS0127,
289 SEN_KS0127B,
290 SEN_SAA7111A,
291};
292
293enum {
294 STATE_SCANNING, /* Scanning for start */
295 STATE_HEADER, /* Parsing header */
296 STATE_LINES, /* Parsing lines */
297};
298
299/* Buffer states */
300enum {
301 BUF_NOT_ALLOCATED,
302 BUF_ALLOCATED,
303};
304
305/* --------- Definition of ioctl interface --------- */
306
307#define OV511_INTERFACE_VER 101
308
309/* LED options */
310enum {
311 LED_OFF,
312 LED_ON,
313 LED_AUTO,
314};
315
316/* Raw frame formats */
317enum {
318 RAWFMT_INVALID,
319 RAWFMT_YUV400,
320 RAWFMT_YUV420,
321 RAWFMT_YUV422,
322 RAWFMT_GBR422,
323};
324
325struct ov511_i2c_struct {
326 unsigned char slave; /* Write slave ID (read ID - 1) */
327 unsigned char reg; /* Index of register */
328 unsigned char value; /* User sets this w/ write, driver does w/ read */
329 unsigned char mask; /* Bits to be changed. Not used with read ops */
330};
331
332/* ioctls */
333#define OV511IOC_WI2C _IOW('v', BASE_VIDIOCPRIVATE + 5, \
334 struct ov511_i2c_struct)
335#define OV511IOC_RI2C _IOWR('v', BASE_VIDIOCPRIVATE + 6, \
336 struct ov511_i2c_struct)
337/* ------------- End IOCTL interface -------------- */
338
339struct usb_ov511; /* Forward declaration */
340
341struct ov511_sbuf {
342 struct usb_ov511 *ov;
343 unsigned char *data;
344 struct urb *urb;
345 spinlock_t lock;
346 int n;
347};
348
349enum {
350 FRAME_UNUSED, /* Unused (no MCAPTURE) */
351 FRAME_READY, /* Ready to start grabbing */
352 FRAME_GRABBING, /* In the process of being grabbed into */
353 FRAME_DONE, /* Finished grabbing, but not been synced yet */
354 FRAME_ERROR, /* Something bad happened while processing */
355};
356
357struct ov511_regvals {
358 enum {
359 OV511_DONE_BUS,
360 OV511_REG_BUS,
361 OV511_I2C_BUS,
362 } bus;
363 unsigned char reg;
364 unsigned char val;
365};
366
367struct ov511_frame {
368 int framenum; /* Index of this frame */
369 unsigned char *data; /* Frame buffer */
370 unsigned char *tempdata; /* Temp buffer for multi-stage conversions */
371 unsigned char *rawdata; /* Raw camera data buffer */
372 unsigned char *compbuf; /* Temp buffer for decompressor */
373
374 int depth; /* Bytes per pixel */
375 int width; /* Width application is expecting */
376 int height; /* Height application is expecting */
377
378 int rawwidth; /* Actual width of frame sent from camera */
379 int rawheight; /* Actual height of frame sent from camera */
380
381 int sub_flag; /* Sub-capture mode for this frame? */
382 unsigned int format; /* Format for this frame */
383 int compressed; /* Is frame compressed? */
384
385 volatile int grabstate; /* State of grabbing */
386 int scanstate; /* State of scanning */
387
388 int bytes_recvd; /* Number of image bytes received from camera */
389
390 long bytes_read; /* Amount that has been read() */
391
392 wait_queue_head_t wq; /* Processes waiting */
393
394 int snapshot; /* True if frame was a snapshot */
395};
396
397#define DECOMP_INTERFACE_VER 4
398
399/* Compression module operations */
400struct ov51x_decomp_ops {
401 int (*decomp_400)(unsigned char *, unsigned char *, unsigned char *,
402 int, int, int);
403 int (*decomp_420)(unsigned char *, unsigned char *, unsigned char *,
404 int, int, int);
405 int (*decomp_422)(unsigned char *, unsigned char *, unsigned char *,
406 int, int, int);
407 struct module *owner;
408};
409
410struct usb_ov511 {
411 struct video_device *vdev;
412 struct usb_device *dev;
413
414 int customid;
415 char *desc;
416 unsigned char iface;
417 char usb_path[OV511_USB_PATH_LEN];
418
419 /* Determined by sensor type */
420 int maxwidth;
421 int maxheight;
422 int minwidth;
423 int minheight;
424
425 int brightness;
426 int colour;
427 int contrast;
428 int hue;
429 int whiteness;
430 int exposure;
431 int auto_brt; /* Auto brightness enabled flag */
432 int auto_gain; /* Auto gain control enabled flag */
433 int auto_exp; /* Auto exposure enabled flag */
434 int backlight; /* Backlight exposure algorithm flag */
435 int mirror; /* Image is reversed horizontally */
436
437 int led_policy; /* LED: off|on|auto; OV511+ only */
438
439 struct mutex lock; /* Serializes user-accessible operations */
440 int user; /* user count for exclusive use */
441
442 int streaming; /* Are we streaming Isochronous? */
443 int grabbing; /* Are we grabbing? */
444
445 int compress; /* Should the next frame be compressed? */
446 int compress_inited; /* Are compression params uploaded? */
447
448 int lightfreq; /* Power (lighting) frequency */
449 int bandfilt; /* Banding filter enabled flag */
450
451 unsigned char *fbuf; /* Videodev buffer area */
452 unsigned char *tempfbuf; /* Temporary (intermediate) buffer area */
453 unsigned char *rawfbuf; /* Raw camera data buffer area */
454
455 int sub_flag; /* Pix Array subcapture on flag */
456 int subx; /* Pix Array subcapture x offset */
457 int suby; /* Pix Array subcapture y offset */
458 int subw; /* Pix Array subcapture width */
459 int subh; /* Pix Array subcapture height */
460
461 int curframe; /* Current receiving sbuf */
462 struct ov511_frame frame[OV511_NUMFRAMES];
463
464 struct ov511_sbuf sbuf[OV511_NUMSBUF];
465
466 wait_queue_head_t wq; /* Processes waiting */
467
468 int snap_enabled; /* Snapshot mode enabled */
469
470 int bridge; /* Type of bridge (BRG_*) */
471 int bclass; /* Class of bridge (BCL_*) */
472 int sensor; /* Type of image sensor chip (SEN_*) */
473
474 int packet_size; /* Frame size per isoc desc */
475 int packet_numbering; /* Is ISO frame numbering enabled? */
476
477 /* Framebuffer/sbuf management */
478 int buf_state;
479 struct mutex buf_lock;
480
481 struct ov51x_decomp_ops *decomp_ops;
482
483 /* Stop streaming while changing picture settings */
484 int stop_during_set;
485
486 int stopped; /* Streaming is temporarily paused */
487
488 /* Video decoder stuff */
489 int input; /* Composite, S-VIDEO, etc... */
490 int num_inputs; /* Number of inputs */
491 int norm; /* NTSC / PAL / SECAM */
492 int has_decoder; /* Device has a video decoder */
493 int pal; /* Device is designed for PAL resolution */
494
495 /* I2C interface */
496 struct mutex i2c_lock; /* Protect I2C controller regs */
497 unsigned char primary_i2c_slave; /* I2C write id of sensor */
498
499 /* Control transaction stuff */
500 unsigned char *cbuf; /* Buffer for payload */
501 struct mutex cbuf_lock;
502};
503
504/* Used to represent a list of values and their respective symbolic names */
505struct symbolic_list {
506 int num;
507 char *name;
508};
509
510#define NOT_DEFINED_STR "Unknown"
511
512/* Returns the name of the matching element in the symbolic_list array. The
513 * end of the list must be marked with an element that has a NULL name.
514 */
515static inline char *
516symbolic(struct symbolic_list list[], int num)
517{
518 int i;
519
520 for (i = 0; list[i].name != NULL; i++)
521 if (list[i].num == num)
522 return (list[i].name);
523
524 return (NOT_DEFINED_STR);
525}
526
527/* Compression stuff */
528
529#define OV511_QUANTABLESIZE 64
530#define OV518_QUANTABLESIZE 32
531
532#define OV511_YQUANTABLE { \
533 0, 1, 1, 2, 2, 3, 3, 4, \
534 1, 1, 1, 2, 2, 3, 4, 4, \
535 1, 1, 2, 2, 3, 4, 4, 4, \
536 2, 2, 2, 3, 4, 4, 4, 4, \
537 2, 2, 3, 4, 4, 5, 5, 5, \
538 3, 3, 4, 4, 5, 5, 5, 5, \
539 3, 4, 4, 4, 5, 5, 5, 5, \
540 4, 4, 4, 4, 5, 5, 5, 5 \
541}
542
543#define OV511_UVQUANTABLE { \
544 0, 2, 2, 3, 4, 4, 4, 4, \
545 2, 2, 2, 4, 4, 4, 4, 4, \
546 2, 2, 3, 4, 4, 4, 4, 4, \
547 3, 4, 4, 4, 4, 4, 4, 4, \
548 4, 4, 4, 4, 4, 4, 4, 4, \
549 4, 4, 4, 4, 4, 4, 4, 4, \
550 4, 4, 4, 4, 4, 4, 4, 4, \
551 4, 4, 4, 4, 4, 4, 4, 4 \
552}
553
554#define OV518_YQUANTABLE { \
555 5, 4, 5, 6, 6, 7, 7, 7, \
556 5, 5, 5, 5, 6, 7, 7, 7, \
557 6, 6, 6, 6, 7, 7, 7, 8, \
558 7, 7, 6, 7, 7, 7, 8, 8 \
559}
560
561#define OV518_UVQUANTABLE { \
562 6, 6, 6, 7, 7, 7, 7, 7, \
563 6, 6, 6, 7, 7, 7, 7, 7, \
564 6, 6, 6, 7, 7, 7, 7, 8, \
565 7, 7, 7, 7, 7, 7, 8, 8 \
566}
567
568#endif
diff --git a/drivers/media/video/pwc/Makefile b/drivers/media/video/pwc/Makefile
new file mode 100644
index 000000000000..2d93a775011a
--- /dev/null
+++ b/drivers/media/video/pwc/Makefile
@@ -0,0 +1,20 @@
1ifneq ($(KERNELRELEASE),)
2
3pwc-objs := pwc-if.o pwc-misc.o pwc-ctrl.o pwc-uncompress.o pwc-timon.o pwc-kiara.o
4
5obj-$(CONFIG_USB_PWC) += pwc.o
6
7else
8
9KDIR := /lib/modules/$(shell uname -r)/build
10PWD := $(shell pwd)
11
12default:
13 $(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules
14
15endif
16
17clean:
18 rm -f *.[oas] .*.flags *.ko .*.cmd .*.d .*.tmp *.mod.c
19 rm -rf .tmp_versions
20
diff --git a/drivers/media/video/pwc/philips.txt b/drivers/media/video/pwc/philips.txt
new file mode 100644
index 000000000000..04a640d723ed
--- /dev/null
+++ b/drivers/media/video/pwc/philips.txt
@@ -0,0 +1,236 @@
1This file contains some additional information for the Philips and OEM webcams.
2E-mail: webcam@smcc.demon.nl Last updated: 2004-01-19
3Site: http://www.smcc.demon.nl/webcam/
4
5As of this moment, the following cameras are supported:
6 * Philips PCA645
7 * Philips PCA646
8 * Philips PCVC675
9 * Philips PCVC680
10 * Philips PCVC690
11 * Philips PCVC720/40
12 * Philips PCVC730
13 * Philips PCVC740
14 * Philips PCVC750
15 * Askey VC010
16 * Creative Labs Webcam 5
17 * Creative Labs Webcam Pro Ex
18 * Logitech QuickCam 3000 Pro
19 * Logitech QuickCam 4000 Pro
20 * Logitech QuickCam Notebook Pro
21 * Logitech QuickCam Zoom
22 * Logitech QuickCam Orbit
23 * Logitech QuickCam Sphere
24 * Samsung MPC-C10
25 * Samsung MPC-C30
26 * Sotec Afina Eye
27 * AME CU-001
28 * Visionite VCS-UM100
29 * Visionite VCS-UC300
30
31The main webpage for the Philips driver is at the address above. It contains
32a lot of extra information, a FAQ, and the binary plugin 'PWCX'. This plugin
33contains decompression routines that allow you to use higher image sizes and
34framerates; in addition the webcam uses less bandwidth on the USB bus (handy
35if you want to run more than 1 camera simultaneously). These routines fall
36under a NDA, and may therefor not be distributed as source; however, its use
37is completely optional.
38
39You can build this code either into your kernel, or as a module. I recommend
40the latter, since it makes troubleshooting a lot easier. The built-in
41microphone is supported through the USB Audio class.
42
43When you load the module you can set some default settings for the
44camera; some programs depend on a particular image-size or -format and
45don't know how to set it properly in the driver. The options are:
46
47size
48 Can be one of 'sqcif', 'qsif', 'qcif', 'sif', 'cif' or
49 'vga', for an image size of resp. 128x96, 160x120, 176x144,
50 320x240, 352x288 and 640x480 (of course, only for those cameras that
51 support these resolutions).
52
53fps
54 Specifies the desired framerate. Is an integer in the range of 4-30.
55
56fbufs
57 This paramter specifies the number of internal buffers to use for storing
58 frames from the cam. This will help if the process that reads images from
59 the cam is a bit slow or momentarely busy. However, on slow machines it
60 only introduces lag, so choose carefully. The default is 3, which is
61 reasonable. You can set it between 2 and 5.
62
63mbufs
64 This is an integer between 1 and 10. It will tell the module the number of
65 buffers to reserve for mmap(), VIDIOCCGMBUF, VIDIOCMCAPTURE and friends.
66 The default is 2, which is adequate for most applications (double
67 buffering).
68
69 Should you experience a lot of 'Dumping frame...' messages during
70 grabbing with a tool that uses mmap(), you might want to increase if.
71 However, it doesn't really buffer images, it just gives you a bit more
72 slack when your program is behind. But you need a multi-threaded or
73 forked program to really take advantage of these buffers.
74
75 The absolute maximum is 10, but don't set it too high! Every buffer takes
76 up 460 KB of RAM, so unless you have a lot of memory setting this to
77 something more than 4 is an absolute waste. This memory is only
78 allocated during open(), so nothing is wasted when the camera is not in
79 use.
80
81power_save
82 When power_save is enabled (set to 1), the module will try to shut down
83 the cam on close() and re-activate on open(). This will save power and
84 turn off the LED. Not all cameras support this though (the 645 and 646
85 don't have power saving at all), and some models don't work either (they
86 will shut down, but never wake up). Consider this experimental. By
87 default this option is disabled.
88
89compression (only useful with the plugin)
90 With this option you can control the compression factor that the camera
91 uses to squeeze the image through the USB bus. You can set the
92 parameter between 0 and 3:
93 0 = prefer uncompressed images; if the requested mode is not available
94 in an uncompressed format, the driver will silently switch to low
95 compression.
96 1 = low compression.
97 2 = medium compression.
98 3 = high compression.
99
100 High compression takes less bandwidth of course, but it could also
101 introduce some unwanted artefacts. The default is 2, medium compression.
102 See the FAQ on the website for an overview of which modes require
103 compression.
104
105 The compression parameter does not apply to the 645 and 646 cameras
106 and OEM models derived from those (only a few). Most cams honour this
107 parameter.
108
109leds
110 This settings takes 2 integers, that define the on/off time for the LED
111 (in milliseconds). One of the interesting things that you can do with
112 this is let the LED blink while the camera is in use. This:
113
114 leds=500,500
115
116 will blink the LED once every second. But with:
117
118 leds=0,0
119
120 the LED never goes on, making it suitable for silent surveillance.
121
122 By default the camera's LED is on solid while in use, and turned off
123 when the camera is not used anymore.
124
125 This parameter works only with the ToUCam range of cameras (720, 730, 740,
126 750) and OEMs. For other cameras this command is silently ignored, and
127 the LED cannot be controlled.
128
129 Finally: this parameters does not take effect UNTIL the first time you
130 open the camera device. Until then, the LED remains on.
131
132dev_hint
133 A long standing problem with USB devices is their dynamic nature: you
134 never know what device a camera gets assigned; it depends on module load
135 order, the hub configuration, the order in which devices are plugged in,
136 and the phase of the moon (i.e. it can be random). With this option you
137 can give the driver a hint as to what video device node (/dev/videoX) it
138 should use with a specific camera. This is also handy if you have two
139 cameras of the same model.
140
141 A camera is specified by its type (the number from the camera model,
142 like PCA645, PCVC750VC, etc) and optionally the serial number (visible
143 in /proc/bus/usb/devices). A hint consists of a string with the following
144 format:
145
146 [type[.serialnumber]:]node
147
148 The square brackets mean that both the type and the serialnumber are
149 optional, but a serialnumber cannot be specified without a type (which
150 would be rather pointless). The serialnumber is separated from the type
151 by a '.'; the node number by a ':'.
152
153 This somewhat cryptic syntax is best explained by a few examples:
154
155 dev_hint=3,5 The first detected cam gets assigned
156 /dev/video3, the second /dev/video5. Any
157 other cameras will get the first free
158 available slot (see below).
159
160 dev_hint=645:1,680:2 The PCA645 camera will get /dev/video1,
161 and a PCVC680 /dev/video2.
162
163 dev_hint=645.0123:3,645.4567:0 The PCA645 camera with serialnumber
164 0123 goes to /dev/video3, the same
165 camera model with the 4567 serial
166 gets /dev/video0.
167
168 dev_hint=750:1,4,5,6 The PCVC750 camera will get /dev/video1, the
169 next 3 Philips cams will use /dev/video4
170 through /dev/video6.
171
172 Some points worth knowing:
173 - Serialnumbers are case sensitive and must be written full, including
174 leading zeroes (it's treated as a string).
175 - If a device node is already occupied, registration will fail and
176 the webcam is not available.
177 - You can have up to 64 video devices; be sure to make enough device
178 nodes in /dev if you want to spread the numbers (this does not apply
179 to devfs). After /dev/video9 comes /dev/video10 (not /dev/videoA).
180 - If a camera does not match any dev_hint, it will simply get assigned
181 the first available device node, just as it used to be.
182
183trace
184 In order to better detect problems, it is now possible to turn on a
185 'trace' of some of the calls the module makes; it logs all items in your
186 kernel log at debug level.
187
188 The trace variable is a bitmask; each bit represents a certain feature.
189 If you want to trace something, look up the bit value(s) in the table
190 below, add the values together and supply that to the trace variable.
191
192 Value Value Description Default
193 (dec) (hex)
194 1 0x1 Module initialization; this will log messages On
195 while loading and unloading the module
196
197 2 0x2 probe() and disconnect() traces On
198
199 4 0x4 Trace open() and close() calls Off
200
201 8 0x8 read(), mmap() and associated ioctl() calls Off
202
203 16 0x10 Memory allocation of buffers, etc. Off
204
205 32 0x20 Showing underflow, overflow and Dumping frame On
206 messages
207
208 64 0x40 Show viewport and image sizes Off
209
210 128 0x80 PWCX debugging Off
211
212 For example, to trace the open() & read() fuctions, sum 8 + 4 = 12,
213 so you would supply trace=12 during insmod or modprobe. If
214 you want to turn the initialization and probing tracing off, set trace=0.
215 The default value for trace is 35 (0x23).
216
217
218
219Example:
220
221 # modprobe pwc size=cif fps=15 power_save=1
222
223The fbufs, mbufs and trace parameters are global and apply to all connected
224cameras. Each camera has its own set of buffers.
225
226size and fps only specify defaults when you open() the device; this is to
227accommodate some tools that don't set the size. You can change these
228settings after open() with the Video4Linux ioctl() calls. The default of
229defaults is QCIF size at 10 fps.
230
231The compression parameter is semiglobal; it sets the initial compression
232preference for all camera's, but this parameter can be set per camera with
233the VIDIOCPWCSCQUAL ioctl() call.
234
235All parameters are optional.
236
diff --git a/drivers/media/video/pwc/pwc-ctrl.c b/drivers/media/video/pwc/pwc-ctrl.c
new file mode 100644
index 000000000000..0398b812e0ce
--- /dev/null
+++ b/drivers/media/video/pwc/pwc-ctrl.c
@@ -0,0 +1,1541 @@
1/* Driver for Philips webcam
2 Functions that send various control messages to the webcam, including
3 video modes.
4 (C) 1999-2003 Nemosoft Unv.
5 (C) 2004 Luc Saillard (luc@saillard.org)
6
7 NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx
8 driver and thus may have bugs that are not present in the original version.
9 Please send bug reports and support requests to <luc@saillard.org>.
10
11 NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx
12 driver and thus may have bugs that are not present in the original version.
13 Please send bug reports and support requests to <luc@saillard.org>.
14 The decompression routines have been implemented by reverse-engineering the
15 Nemosoft binary pwcx module. Caveat emptor.
16
17 This program is free software; you can redistribute it and/or modify
18 it under the terms of the GNU General Public License as published by
19 the Free Software Foundation; either version 2 of the License, or
20 (at your option) any later version.
21
22 This program is distributed in the hope that it will be useful,
23 but WITHOUT ANY WARRANTY; without even the implied warranty of
24 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 GNU General Public License for more details.
26
27 You should have received a copy of the GNU General Public License
28 along with this program; if not, write to the Free Software
29 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
30*/
31
32/*
33 Changes
34 2001/08/03 Alvarado Added methods for changing white balance and
35 red/green gains
36 */
37
38/* Control functions for the cam; brightness, contrast, video mode, etc. */
39
40#ifdef __KERNEL__
41#include <asm/uaccess.h>
42#endif
43#include <asm/errno.h>
44
45#include "pwc.h"
46#include "pwc-ioctl.h"
47#include "pwc-uncompress.h"
48#include "pwc-kiara.h"
49#include "pwc-timon.h"
50
51/* Request types: video */
52#define SET_LUM_CTL 0x01
53#define GET_LUM_CTL 0x02
54#define SET_CHROM_CTL 0x03
55#define GET_CHROM_CTL 0x04
56#define SET_STATUS_CTL 0x05
57#define GET_STATUS_CTL 0x06
58#define SET_EP_STREAM_CTL 0x07
59#define GET_EP_STREAM_CTL 0x08
60#define SET_MPT_CTL 0x0D
61#define GET_MPT_CTL 0x0E
62
63/* Selectors for the Luminance controls [GS]ET_LUM_CTL */
64#define AGC_MODE_FORMATTER 0x2000
65#define PRESET_AGC_FORMATTER 0x2100
66#define SHUTTER_MODE_FORMATTER 0x2200
67#define PRESET_SHUTTER_FORMATTER 0x2300
68#define PRESET_CONTOUR_FORMATTER 0x2400
69#define AUTO_CONTOUR_FORMATTER 0x2500
70#define BACK_LIGHT_COMPENSATION_FORMATTER 0x2600
71#define CONTRAST_FORMATTER 0x2700
72#define DYNAMIC_NOISE_CONTROL_FORMATTER 0x2800
73#define FLICKERLESS_MODE_FORMATTER 0x2900
74#define AE_CONTROL_SPEED 0x2A00
75#define BRIGHTNESS_FORMATTER 0x2B00
76#define GAMMA_FORMATTER 0x2C00
77
78/* Selectors for the Chrominance controls [GS]ET_CHROM_CTL */
79#define WB_MODE_FORMATTER 0x1000
80#define AWB_CONTROL_SPEED_FORMATTER 0x1100
81#define AWB_CONTROL_DELAY_FORMATTER 0x1200
82#define PRESET_MANUAL_RED_GAIN_FORMATTER 0x1300
83#define PRESET_MANUAL_BLUE_GAIN_FORMATTER 0x1400
84#define COLOUR_MODE_FORMATTER 0x1500
85#define SATURATION_MODE_FORMATTER1 0x1600
86#define SATURATION_MODE_FORMATTER2 0x1700
87
88/* Selectors for the Status controls [GS]ET_STATUS_CTL */
89#define SAVE_USER_DEFAULTS_FORMATTER 0x0200
90#define RESTORE_USER_DEFAULTS_FORMATTER 0x0300
91#define RESTORE_FACTORY_DEFAULTS_FORMATTER 0x0400
92#define READ_AGC_FORMATTER 0x0500
93#define READ_SHUTTER_FORMATTER 0x0600
94#define READ_RED_GAIN_FORMATTER 0x0700
95#define READ_BLUE_GAIN_FORMATTER 0x0800
96#define SENSOR_TYPE_FORMATTER1 0x0C00
97#define READ_RAW_Y_MEAN_FORMATTER 0x3100
98#define SET_POWER_SAVE_MODE_FORMATTER 0x3200
99#define MIRROR_IMAGE_FORMATTER 0x3300
100#define LED_FORMATTER 0x3400
101#define SENSOR_TYPE_FORMATTER2 0x3700
102
103/* Formatters for the Video Endpoint controls [GS]ET_EP_STREAM_CTL */
104#define VIDEO_OUTPUT_CONTROL_FORMATTER 0x0100
105
106/* Formatters for the motorized pan & tilt [GS]ET_MPT_CTL */
107#define PT_RELATIVE_CONTROL_FORMATTER 0x01
108#define PT_RESET_CONTROL_FORMATTER 0x02
109#define PT_STATUS_FORMATTER 0x03
110
111static const char *size2name[PSZ_MAX] =
112{
113 "subQCIF",
114 "QSIF",
115 "QCIF",
116 "SIF",
117 "CIF",
118 "VGA",
119};
120
121/********/
122
123/* Entries for the Nala (645/646) camera; the Nala doesn't have compression
124 preferences, so you either get compressed or non-compressed streams.
125
126 An alternate value of 0 means this mode is not available at all.
127 */
128
129struct Nala_table_entry {
130 char alternate; /* USB alternate setting */
131 int compressed; /* Compressed yes/no */
132
133 unsigned char mode[3]; /* precomputed mode table */
134};
135
136static struct Nala_table_entry Nala_table[PSZ_MAX][8] =
137{
138#include "pwc-nala.h"
139};
140
141
142/****************************************************************************/
143
144
145#define SendControlMsg(request, value, buflen) \
146 usb_control_msg(pdev->udev, usb_sndctrlpipe(pdev->udev, 0), \
147 request, \
148 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, \
149 value, \
150 pdev->vcinterface, \
151 &buf, buflen, 500)
152
153#define RecvControlMsg(request, value, buflen) \
154 usb_control_msg(pdev->udev, usb_rcvctrlpipe(pdev->udev, 0), \
155 request, \
156 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, \
157 value, \
158 pdev->vcinterface, \
159 &buf, buflen, 500)
160
161
162#if PWC_DEBUG
163void pwc_hexdump(void *p, int len)
164{
165 int i;
166 unsigned char *s;
167 char buf[100], *d;
168
169 s = (unsigned char *)p;
170 d = buf;
171 *d = '\0';
172 Debug("Doing hexdump @ %p, %d bytes.\n", p, len);
173 for (i = 0; i < len; i++) {
174 d += sprintf(d, "%02X ", *s++);
175 if ((i & 0xF) == 0xF) {
176 Debug("%s\n", buf);
177 d = buf;
178 *d = '\0';
179 }
180 }
181 if ((i & 0xF) != 0)
182 Debug("%s\n", buf);
183}
184#endif
185
186static inline int send_video_command(struct usb_device *udev, int index, void *buf, int buflen)
187{
188 return usb_control_msg(udev,
189 usb_sndctrlpipe(udev, 0),
190 SET_EP_STREAM_CTL,
191 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
192 VIDEO_OUTPUT_CONTROL_FORMATTER,
193 index,
194 buf, buflen, 1000);
195}
196
197
198
199static inline int set_video_mode_Nala(struct pwc_device *pdev, int size, int frames)
200{
201 unsigned char buf[3];
202 int ret, fps;
203 struct Nala_table_entry *pEntry;
204 int frames2frames[31] =
205 { /* closest match of framerate */
206 0, 0, 0, 0, 4, /* 0-4 */
207 5, 5, 7, 7, 10, /* 5-9 */
208 10, 10, 12, 12, 15, /* 10-14 */
209 15, 15, 15, 20, 20, /* 15-19 */
210 20, 20, 20, 24, 24, /* 20-24 */
211 24, 24, 24, 24, 24, /* 25-29 */
212 24 /* 30 */
213 };
214 int frames2table[31] =
215 { 0, 0, 0, 0, 0, /* 0-4 */
216 1, 1, 1, 2, 2, /* 5-9 */
217 3, 3, 4, 4, 4, /* 10-14 */
218 5, 5, 5, 5, 5, /* 15-19 */
219 6, 6, 6, 6, 7, /* 20-24 */
220 7, 7, 7, 7, 7, /* 25-29 */
221 7 /* 30 */
222 };
223
224 if (size < 0 || size > PSZ_CIF || frames < 4 || frames > 25)
225 return -EINVAL;
226 frames = frames2frames[frames];
227 fps = frames2table[frames];
228 pEntry = &Nala_table[size][fps];
229 if (pEntry->alternate == 0)
230 return -EINVAL;
231
232 if (pEntry->compressed)
233 return -ENOENT; /* Not supported. */
234
235 memcpy(buf, pEntry->mode, 3);
236 ret = send_video_command(pdev->udev, pdev->vendpoint, buf, 3);
237 if (ret < 0) {
238 Debug("Failed to send video command... %d\n", ret);
239 return ret;
240 }
241 if (pEntry->compressed && pdev->vpalette != VIDEO_PALETTE_RAW)
242 {
243 switch(pdev->type) {
244 case 645:
245 case 646:
246/* pwc_dec1_init(pdev->type, pdev->release, buf, pdev->decompress_data); */
247 break;
248
249 case 675:
250 case 680:
251 case 690:
252 case 720:
253 case 730:
254 case 740:
255 case 750:
256/* pwc_dec23_init(pdev->type, pdev->release, buf, pdev->decompress_data); */
257 break;
258 }
259 }
260
261 pdev->cmd_len = 3;
262 memcpy(pdev->cmd_buf, buf, 3);
263
264 /* Set various parameters */
265 pdev->vframes = frames;
266 pdev->vsize = size;
267 pdev->valternate = pEntry->alternate;
268 pdev->image = pwc_image_sizes[size];
269 pdev->frame_size = (pdev->image.x * pdev->image.y * 3) / 2;
270 if (pEntry->compressed) {
271 if (pdev->release < 5) { /* 4 fold compression */
272 pdev->vbandlength = 528;
273 pdev->frame_size /= 4;
274 }
275 else {
276 pdev->vbandlength = 704;
277 pdev->frame_size /= 3;
278 }
279 }
280 else
281 pdev->vbandlength = 0;
282 return 0;
283}
284
285
286static inline int set_video_mode_Timon(struct pwc_device *pdev, int size, int frames, int compression, int snapshot)
287{
288 unsigned char buf[13];
289 const struct Timon_table_entry *pChoose;
290 int ret, fps;
291
292 if (size >= PSZ_MAX || frames < 5 || frames > 30 || compression < 0 || compression > 3)
293 return -EINVAL;
294 if (size == PSZ_VGA && frames > 15)
295 return -EINVAL;
296 fps = (frames / 5) - 1;
297
298 /* Find a supported framerate with progressively higher compression ratios
299 if the preferred ratio is not available.
300 */
301 pChoose = NULL;
302 while (compression <= 3) {
303 pChoose = &Timon_table[size][fps][compression];
304 if (pChoose->alternate != 0)
305 break;
306 compression++;
307 }
308 if (pChoose == NULL || pChoose->alternate == 0)
309 return -ENOENT; /* Not supported. */
310
311 memcpy(buf, pChoose->mode, 13);
312 if (snapshot)
313 buf[0] |= 0x80;
314 ret = send_video_command(pdev->udev, pdev->vendpoint, buf, 13);
315 if (ret < 0)
316 return ret;
317
318/* if (pChoose->bandlength > 0 && pdev->vpalette != VIDEO_PALETTE_RAW)
319 pwc_dec23_init(pdev->type, pdev->release, buf, pdev->decompress_data); */
320
321 pdev->cmd_len = 13;
322 memcpy(pdev->cmd_buf, buf, 13);
323
324 /* Set various parameters */
325 pdev->vframes = frames;
326 pdev->vsize = size;
327 pdev->vsnapshot = snapshot;
328 pdev->valternate = pChoose->alternate;
329 pdev->image = pwc_image_sizes[size];
330 pdev->vbandlength = pChoose->bandlength;
331 if (pChoose->bandlength > 0)
332 pdev->frame_size = (pChoose->bandlength * pdev->image.y) / 4;
333 else
334 pdev->frame_size = (pdev->image.x * pdev->image.y * 12) / 8;
335 return 0;
336}
337
338
339static inline int set_video_mode_Kiara(struct pwc_device *pdev, int size, int frames, int compression, int snapshot)
340{
341 const struct Kiara_table_entry *pChoose = NULL;
342 int fps, ret;
343 unsigned char buf[12];
344 struct Kiara_table_entry RawEntry = {6, 773, 1272, {0xAD, 0xF4, 0x10, 0x27, 0xB6, 0x24, 0x96, 0x02, 0x30, 0x05, 0x03, 0x80}};
345
346 if (size >= PSZ_MAX || frames < 5 || frames > 30 || compression < 0 || compression > 3)
347 return -EINVAL;
348 if (size == PSZ_VGA && frames > 15)
349 return -EINVAL;
350 fps = (frames / 5) - 1;
351
352 /* special case: VGA @ 5 fps and snapshot is raw bayer mode */
353 if (size == PSZ_VGA && frames == 5 && snapshot)
354 {
355 /* Only available in case the raw palette is selected or
356 we have the decompressor available. This mode is
357 only available in compressed form
358 */
359 if (pdev->vpalette == VIDEO_PALETTE_RAW)
360 {
361 Info("Choosing VGA/5 BAYER mode (%d).\n", pdev->vpalette);
362 pChoose = &RawEntry;
363 }
364 else
365 {
366 Info("VGA/5 BAYER mode _must_ have a decompressor available, or use RAW palette.\n");
367 }
368 }
369 else
370 {
371 /* Find a supported framerate with progressively higher compression ratios
372 if the preferred ratio is not available.
373 Skip this step when using RAW modes.
374 */
375 while (compression <= 3) {
376 pChoose = &Kiara_table[size][fps][compression];
377 if (pChoose->alternate != 0)
378 break;
379 compression++;
380 }
381 }
382 if (pChoose == NULL || pChoose->alternate == 0)
383 return -ENOENT; /* Not supported. */
384
385 Debug("Using alternate setting %d.\n", pChoose->alternate);
386
387 /* usb_control_msg won't take staticly allocated arrays as argument?? */
388 memcpy(buf, pChoose->mode, 12);
389 if (snapshot)
390 buf[0] |= 0x80;
391
392 /* Firmware bug: video endpoint is 5, but commands are sent to endpoint 4 */
393 ret = send_video_command(pdev->udev, 4 /* pdev->vendpoint */, buf, 12);
394 if (ret < 0)
395 return ret;
396
397/* if (pChoose->bandlength > 0 && pdev->vpalette != VIDEO_PALETTE_RAW)
398 pwc_dec23_init(pdev->type, pdev->release, buf, pdev->decompress_data); */
399
400 pdev->cmd_len = 12;
401 memcpy(pdev->cmd_buf, buf, 12);
402 /* All set and go */
403 pdev->vframes = frames;
404 pdev->vsize = size;
405 pdev->vsnapshot = snapshot;
406 pdev->valternate = pChoose->alternate;
407 pdev->image = pwc_image_sizes[size];
408 pdev->vbandlength = pChoose->bandlength;
409 if (pdev->vbandlength > 0)
410 pdev->frame_size = (pdev->vbandlength * pdev->image.y) / 4;
411 else
412 pdev->frame_size = (pdev->image.x * pdev->image.y * 12) / 8;
413 return 0;
414}
415
416
417
418static void pwc_set_image_buffer_size(struct pwc_device *pdev)
419{
420 int i, factor = 0, filler = 0;
421
422 /* for PALETTE_YUV420P */
423 switch(pdev->vpalette)
424 {
425 case VIDEO_PALETTE_YUV420P:
426 factor = 6;
427 filler = 128;
428 break;
429 case VIDEO_PALETTE_RAW:
430 factor = 6; /* can be uncompressed YUV420P */
431 filler = 0;
432 break;
433 }
434
435 /* Set sizes in bytes */
436 pdev->image.size = pdev->image.x * pdev->image.y * factor / 4;
437 pdev->view.size = pdev->view.x * pdev->view.y * factor / 4;
438
439 /* Align offset, or you'll get some very weird results in
440 YUV420 mode... x must be multiple of 4 (to get the Y's in
441 place), and y even (or you'll mixup U & V). This is less of a
442 problem for YUV420P.
443 */
444 pdev->offset.x = ((pdev->view.x - pdev->image.x) / 2) & 0xFFFC;
445 pdev->offset.y = ((pdev->view.y - pdev->image.y) / 2) & 0xFFFE;
446
447 /* Fill buffers with gray or black */
448 for (i = 0; i < MAX_IMAGES; i++) {
449 if (pdev->image_ptr[i] != NULL)
450 memset(pdev->image_ptr[i], filler, pdev->view.size);
451 }
452}
453
454
455
456/**
457 @pdev: device structure
458 @width: viewport width
459 @height: viewport height
460 @frame: framerate, in fps
461 @compression: preferred compression ratio
462 @snapshot: snapshot mode or streaming
463 */
464int pwc_set_video_mode(struct pwc_device *pdev, int width, int height, int frames, int compression, int snapshot)
465{
466 int ret, size;
467
468 Trace(TRACE_FLOW, "set_video_mode(%dx%d @ %d, palette %d).\n", width, height, frames, pdev->vpalette);
469 size = pwc_decode_size(pdev, width, height);
470 if (size < 0) {
471 Debug("Could not find suitable size.\n");
472 return -ERANGE;
473 }
474 Debug("decode_size = %d.\n", size);
475
476 ret = -EINVAL;
477 switch(pdev->type) {
478 case 645:
479 case 646:
480 ret = set_video_mode_Nala(pdev, size, frames);
481 break;
482
483 case 675:
484 case 680:
485 case 690:
486 ret = set_video_mode_Timon(pdev, size, frames, compression, snapshot);
487 break;
488
489 case 720:
490 case 730:
491 case 740:
492 case 750:
493 ret = set_video_mode_Kiara(pdev, size, frames, compression, snapshot);
494 break;
495 }
496 if (ret < 0) {
497 if (ret == -ENOENT)
498 Info("Video mode %s@%d fps is only supported with the decompressor module (pwcx).\n", size2name[size], frames);
499 else {
500 Err("Failed to set video mode %s@%d fps; return code = %d\n", size2name[size], frames, ret);
501 }
502 return ret;
503 }
504 pdev->view.x = width;
505 pdev->view.y = height;
506 pdev->frame_total_size = pdev->frame_size + pdev->frame_header_size + pdev->frame_trailer_size;
507 pwc_set_image_buffer_size(pdev);
508 Trace(TRACE_SIZE, "Set viewport to %dx%d, image size is %dx%d.\n", width, height, pwc_image_sizes[size].x, pwc_image_sizes[size].y);
509 return 0;
510}
511
512
513/* BRIGHTNESS */
514
515int pwc_get_brightness(struct pwc_device *pdev)
516{
517 char buf;
518 int ret;
519
520 ret = RecvControlMsg(GET_LUM_CTL, BRIGHTNESS_FORMATTER, 1);
521 if (ret < 0)
522 return ret;
523 return buf << 9;
524}
525
526int pwc_set_brightness(struct pwc_device *pdev, int value)
527{
528 char buf;
529
530 if (value < 0)
531 value = 0;
532 if (value > 0xffff)
533 value = 0xffff;
534 buf = (value >> 9) & 0x7f;
535 return SendControlMsg(SET_LUM_CTL, BRIGHTNESS_FORMATTER, 1);
536}
537
538/* CONTRAST */
539
540int pwc_get_contrast(struct pwc_device *pdev)
541{
542 char buf;
543 int ret;
544
545 ret = RecvControlMsg(GET_LUM_CTL, CONTRAST_FORMATTER, 1);
546 if (ret < 0)
547 return ret;
548 return buf << 10;
549}
550
551int pwc_set_contrast(struct pwc_device *pdev, int value)
552{
553 char buf;
554
555 if (value < 0)
556 value = 0;
557 if (value > 0xffff)
558 value = 0xffff;
559 buf = (value >> 10) & 0x3f;
560 return SendControlMsg(SET_LUM_CTL, CONTRAST_FORMATTER, 1);
561}
562
563/* GAMMA */
564
565int pwc_get_gamma(struct pwc_device *pdev)
566{
567 char buf;
568 int ret;
569
570 ret = RecvControlMsg(GET_LUM_CTL, GAMMA_FORMATTER, 1);
571 if (ret < 0)
572 return ret;
573 return buf << 11;
574}
575
576int pwc_set_gamma(struct pwc_device *pdev, int value)
577{
578 char buf;
579
580 if (value < 0)
581 value = 0;
582 if (value > 0xffff)
583 value = 0xffff;
584 buf = (value >> 11) & 0x1f;
585 return SendControlMsg(SET_LUM_CTL, GAMMA_FORMATTER, 1);
586}
587
588
589/* SATURATION */
590
591int pwc_get_saturation(struct pwc_device *pdev)
592{
593 char buf;
594 int ret;
595
596 if (pdev->type < 675)
597 return -1;
598 ret = RecvControlMsg(GET_CHROM_CTL, pdev->type < 730 ? SATURATION_MODE_FORMATTER2 : SATURATION_MODE_FORMATTER1, 1);
599 if (ret < 0)
600 return ret;
601 return 32768 + buf * 327;
602}
603
604int pwc_set_saturation(struct pwc_device *pdev, int value)
605{
606 char buf;
607
608 if (pdev->type < 675)
609 return -EINVAL;
610 if (value < 0)
611 value = 0;
612 if (value > 0xffff)
613 value = 0xffff;
614 /* saturation ranges from -100 to +100 */
615 buf = (value - 32768) / 327;
616 return SendControlMsg(SET_CHROM_CTL, pdev->type < 730 ? SATURATION_MODE_FORMATTER2 : SATURATION_MODE_FORMATTER1, 1);
617}
618
619/* AGC */
620
621static inline int pwc_set_agc(struct pwc_device *pdev, int mode, int value)
622{
623 char buf;
624 int ret;
625
626 if (mode)
627 buf = 0x0; /* auto */
628 else
629 buf = 0xff; /* fixed */
630
631 ret = SendControlMsg(SET_LUM_CTL, AGC_MODE_FORMATTER, 1);
632
633 if (!mode && ret >= 0) {
634 if (value < 0)
635 value = 0;
636 if (value > 0xffff)
637 value = 0xffff;
638 buf = (value >> 10) & 0x3F;
639 ret = SendControlMsg(SET_LUM_CTL, PRESET_AGC_FORMATTER, 1);
640 }
641 if (ret < 0)
642 return ret;
643 return 0;
644}
645
646static inline int pwc_get_agc(struct pwc_device *pdev, int *value)
647{
648 unsigned char buf;
649 int ret;
650
651 ret = RecvControlMsg(GET_LUM_CTL, AGC_MODE_FORMATTER, 1);
652 if (ret < 0)
653 return ret;
654
655 if (buf != 0) { /* fixed */
656 ret = RecvControlMsg(GET_LUM_CTL, PRESET_AGC_FORMATTER, 1);
657 if (ret < 0)
658 return ret;
659 if (buf > 0x3F)
660 buf = 0x3F;
661 *value = (buf << 10);
662 }
663 else { /* auto */
664 ret = RecvControlMsg(GET_STATUS_CTL, READ_AGC_FORMATTER, 1);
665 if (ret < 0)
666 return ret;
667 /* Gah... this value ranges from 0x00 ... 0x9F */
668 if (buf > 0x9F)
669 buf = 0x9F;
670 *value = -(48 + buf * 409);
671 }
672
673 return 0;
674}
675
676static inline int pwc_set_shutter_speed(struct pwc_device *pdev, int mode, int value)
677{
678 char buf[2];
679 int speed, ret;
680
681
682 if (mode)
683 buf[0] = 0x0; /* auto */
684 else
685 buf[0] = 0xff; /* fixed */
686
687 ret = SendControlMsg(SET_LUM_CTL, SHUTTER_MODE_FORMATTER, 1);
688
689 if (!mode && ret >= 0) {
690 if (value < 0)
691 value = 0;
692 if (value > 0xffff)
693 value = 0xffff;
694 switch(pdev->type) {
695 case 675:
696 case 680:
697 case 690:
698 /* speed ranges from 0x0 to 0x290 (656) */
699 speed = (value / 100);
700 buf[1] = speed >> 8;
701 buf[0] = speed & 0xff;
702 break;
703 case 720:
704 case 730:
705 case 740:
706 case 750:
707 /* speed seems to range from 0x0 to 0xff */
708 buf[1] = 0;
709 buf[0] = value >> 8;
710 break;
711 }
712
713 ret = SendControlMsg(SET_LUM_CTL, PRESET_SHUTTER_FORMATTER, 2);
714 }
715 return ret;
716}
717
718
719/* POWER */
720
721int pwc_camera_power(struct pwc_device *pdev, int power)
722{
723 char buf;
724
725 if (pdev->type < 675 || (pdev->type < 730 && pdev->release < 6))
726 return 0; /* Not supported by Nala or Timon < release 6 */
727
728 if (power)
729 buf = 0x00; /* active */
730 else
731 buf = 0xFF; /* power save */
732 return SendControlMsg(SET_STATUS_CTL, SET_POWER_SAVE_MODE_FORMATTER, 1);
733}
734
735
736
737/* private calls */
738
739static inline int pwc_restore_user(struct pwc_device *pdev)
740{
741 char buf; /* dummy */
742 return SendControlMsg(SET_STATUS_CTL, RESTORE_USER_DEFAULTS_FORMATTER, 0);
743}
744
745static inline int pwc_save_user(struct pwc_device *pdev)
746{
747 char buf; /* dummy */
748 return SendControlMsg(SET_STATUS_CTL, SAVE_USER_DEFAULTS_FORMATTER, 0);
749}
750
751static inline int pwc_restore_factory(struct pwc_device *pdev)
752{
753 char buf; /* dummy */
754 return SendControlMsg(SET_STATUS_CTL, RESTORE_FACTORY_DEFAULTS_FORMATTER, 0);
755}
756
757 /* ************************************************* */
758 /* Patch by Alvarado: (not in the original version */
759
760 /*
761 * the camera recognizes modes from 0 to 4:
762 *
763 * 00: indoor (incandescant lighting)
764 * 01: outdoor (sunlight)
765 * 02: fluorescent lighting
766 * 03: manual
767 * 04: auto
768 */
769static inline int pwc_set_awb(struct pwc_device *pdev, int mode)
770{
771 char buf;
772 int ret;
773
774 if (mode < 0)
775 mode = 0;
776
777 if (mode > 4)
778 mode = 4;
779
780 buf = mode & 0x07; /* just the lowest three bits */
781
782 ret = SendControlMsg(SET_CHROM_CTL, WB_MODE_FORMATTER, 1);
783
784 if (ret < 0)
785 return ret;
786 return 0;
787}
788
789static inline int pwc_get_awb(struct pwc_device *pdev)
790{
791 unsigned char buf;
792 int ret;
793
794 ret = RecvControlMsg(GET_CHROM_CTL, WB_MODE_FORMATTER, 1);
795
796 if (ret < 0)
797 return ret;
798 return buf;
799}
800
801static inline int pwc_set_red_gain(struct pwc_device *pdev, int value)
802{
803 unsigned char buf;
804
805 if (value < 0)
806 value = 0;
807 if (value > 0xffff)
808 value = 0xffff;
809 /* only the msb is considered */
810 buf = value >> 8;
811 return SendControlMsg(SET_CHROM_CTL, PRESET_MANUAL_RED_GAIN_FORMATTER, 1);
812}
813
814static inline int pwc_get_red_gain(struct pwc_device *pdev, int *value)
815{
816 unsigned char buf;
817 int ret;
818
819 ret = RecvControlMsg(GET_CHROM_CTL, PRESET_MANUAL_RED_GAIN_FORMATTER, 1);
820 if (ret < 0)
821 return ret;
822 *value = buf << 8;
823 return 0;
824}
825
826
827static inline int pwc_set_blue_gain(struct pwc_device *pdev, int value)
828{
829 unsigned char buf;
830
831 if (value < 0)
832 value = 0;
833 if (value > 0xffff)
834 value = 0xffff;
835 /* only the msb is considered */
836 buf = value >> 8;
837 return SendControlMsg(SET_CHROM_CTL, PRESET_MANUAL_BLUE_GAIN_FORMATTER, 1);
838}
839
840static inline int pwc_get_blue_gain(struct pwc_device *pdev, int *value)
841{
842 unsigned char buf;
843 int ret;
844
845 ret = RecvControlMsg(GET_CHROM_CTL, PRESET_MANUAL_BLUE_GAIN_FORMATTER, 1);
846 if (ret < 0)
847 return ret;
848 *value = buf << 8;
849 return 0;
850}
851
852
853/* The following two functions are different, since they only read the
854 internal red/blue gains, which may be different from the manual
855 gains set or read above.
856 */
857static inline int pwc_read_red_gain(struct pwc_device *pdev, int *value)
858{
859 unsigned char buf;
860 int ret;
861
862 ret = RecvControlMsg(GET_STATUS_CTL, READ_RED_GAIN_FORMATTER, 1);
863 if (ret < 0)
864 return ret;
865 *value = buf << 8;
866 return 0;
867}
868
869static inline int pwc_read_blue_gain(struct pwc_device *pdev, int *value)
870{
871 unsigned char buf;
872 int ret;
873
874 ret = RecvControlMsg(GET_STATUS_CTL, READ_BLUE_GAIN_FORMATTER, 1);
875 if (ret < 0)
876 return ret;
877 *value = buf << 8;
878 return 0;
879}
880
881
882static inline int pwc_set_wb_speed(struct pwc_device *pdev, int speed)
883{
884 unsigned char buf;
885
886 /* useful range is 0x01..0x20 */
887 buf = speed / 0x7f0;
888 return SendControlMsg(SET_CHROM_CTL, AWB_CONTROL_SPEED_FORMATTER, 1);
889}
890
891static inline int pwc_get_wb_speed(struct pwc_device *pdev, int *value)
892{
893 unsigned char buf;
894 int ret;
895
896 ret = RecvControlMsg(GET_CHROM_CTL, AWB_CONTROL_SPEED_FORMATTER, 1);
897 if (ret < 0)
898 return ret;
899 *value = buf * 0x7f0;
900 return 0;
901}
902
903
904static inline int pwc_set_wb_delay(struct pwc_device *pdev, int delay)
905{
906 unsigned char buf;
907
908 /* useful range is 0x01..0x3F */
909 buf = (delay >> 10);
910 return SendControlMsg(SET_CHROM_CTL, AWB_CONTROL_DELAY_FORMATTER, 1);
911}
912
913static inline int pwc_get_wb_delay(struct pwc_device *pdev, int *value)
914{
915 unsigned char buf;
916 int ret;
917
918 ret = RecvControlMsg(GET_CHROM_CTL, AWB_CONTROL_DELAY_FORMATTER, 1);
919 if (ret < 0)
920 return ret;
921 *value = buf << 10;
922 return 0;
923}
924
925
926int pwc_set_leds(struct pwc_device *pdev, int on_value, int off_value)
927{
928 unsigned char buf[2];
929
930 if (pdev->type < 730)
931 return 0;
932 on_value /= 100;
933 off_value /= 100;
934 if (on_value < 0)
935 on_value = 0;
936 if (on_value > 0xff)
937 on_value = 0xff;
938 if (off_value < 0)
939 off_value = 0;
940 if (off_value > 0xff)
941 off_value = 0xff;
942
943 buf[0] = on_value;
944 buf[1] = off_value;
945
946 return SendControlMsg(SET_STATUS_CTL, LED_FORMATTER, 2);
947}
948
949static int pwc_get_leds(struct pwc_device *pdev, int *on_value, int *off_value)
950{
951 unsigned char buf[2];
952 int ret;
953
954 if (pdev->type < 730) {
955 *on_value = -1;
956 *off_value = -1;
957 return 0;
958 }
959
960 ret = RecvControlMsg(GET_STATUS_CTL, LED_FORMATTER, 2);
961 if (ret < 0)
962 return ret;
963 *on_value = buf[0] * 100;
964 *off_value = buf[1] * 100;
965 return 0;
966}
967
968static inline int pwc_set_contour(struct pwc_device *pdev, int contour)
969{
970 unsigned char buf;
971 int ret;
972
973 if (contour < 0)
974 buf = 0xff; /* auto contour on */
975 else
976 buf = 0x0; /* auto contour off */
977 ret = SendControlMsg(SET_LUM_CTL, AUTO_CONTOUR_FORMATTER, 1);
978 if (ret < 0)
979 return ret;
980
981 if (contour < 0)
982 return 0;
983 if (contour > 0xffff)
984 contour = 0xffff;
985
986 buf = (contour >> 10); /* contour preset is [0..3f] */
987 ret = SendControlMsg(SET_LUM_CTL, PRESET_CONTOUR_FORMATTER, 1);
988 if (ret < 0)
989 return ret;
990 return 0;
991}
992
993static inline int pwc_get_contour(struct pwc_device *pdev, int *contour)
994{
995 unsigned char buf;
996 int ret;
997
998 ret = RecvControlMsg(GET_LUM_CTL, AUTO_CONTOUR_FORMATTER, 1);
999 if (ret < 0)
1000 return ret;
1001
1002 if (buf == 0) {
1003 /* auto mode off, query current preset value */
1004 ret = RecvControlMsg(GET_LUM_CTL, PRESET_CONTOUR_FORMATTER, 1);
1005 if (ret < 0)
1006 return ret;
1007 *contour = buf << 10;
1008 }
1009 else
1010 *contour = -1;
1011 return 0;
1012}
1013
1014
1015static inline int pwc_set_backlight(struct pwc_device *pdev, int backlight)
1016{
1017 unsigned char buf;
1018
1019 if (backlight)
1020 buf = 0xff;
1021 else
1022 buf = 0x0;
1023 return SendControlMsg(SET_LUM_CTL, BACK_LIGHT_COMPENSATION_FORMATTER, 1);
1024}
1025
1026static inline int pwc_get_backlight(struct pwc_device *pdev, int *backlight)
1027{
1028 int ret;
1029 unsigned char buf;
1030
1031 ret = RecvControlMsg(GET_LUM_CTL, BACK_LIGHT_COMPENSATION_FORMATTER, 1);
1032 if (ret < 0)
1033 return ret;
1034 *backlight = buf;
1035 return 0;
1036}
1037
1038
1039static inline int pwc_set_flicker(struct pwc_device *pdev, int flicker)
1040{
1041 unsigned char buf;
1042
1043 if (flicker)
1044 buf = 0xff;
1045 else
1046 buf = 0x0;
1047 return SendControlMsg(SET_LUM_CTL, FLICKERLESS_MODE_FORMATTER, 1);
1048}
1049
1050static inline int pwc_get_flicker(struct pwc_device *pdev, int *flicker)
1051{
1052 int ret;
1053 unsigned char buf;
1054
1055 ret = RecvControlMsg(GET_LUM_CTL, FLICKERLESS_MODE_FORMATTER, 1);
1056 if (ret < 0)
1057 return ret;
1058 *flicker = buf;
1059 return 0;
1060}
1061
1062
1063static inline int pwc_set_dynamic_noise(struct pwc_device *pdev, int noise)
1064{
1065 unsigned char buf;
1066
1067 if (noise < 0)
1068 noise = 0;
1069 if (noise > 3)
1070 noise = 3;
1071 buf = noise;
1072 return SendControlMsg(SET_LUM_CTL, DYNAMIC_NOISE_CONTROL_FORMATTER, 1);
1073}
1074
1075static inline int pwc_get_dynamic_noise(struct pwc_device *pdev, int *noise)
1076{
1077 int ret;
1078 unsigned char buf;
1079
1080 ret = RecvControlMsg(GET_LUM_CTL, DYNAMIC_NOISE_CONTROL_FORMATTER, 1);
1081 if (ret < 0)
1082 return ret;
1083 *noise = buf;
1084 return 0;
1085}
1086
1087static int pwc_mpt_reset(struct pwc_device *pdev, int flags)
1088{
1089 unsigned char buf;
1090
1091 buf = flags & 0x03; // only lower two bits are currently used
1092 return SendControlMsg(SET_MPT_CTL, PT_RESET_CONTROL_FORMATTER, 1);
1093}
1094
1095static inline int pwc_mpt_set_angle(struct pwc_device *pdev, int pan, int tilt)
1096{
1097 unsigned char buf[4];
1098
1099 /* set new relative angle; angles are expressed in degrees * 100,
1100 but cam as .5 degree resolution, hence divide by 200. Also
1101 the angle must be multiplied by 64 before it's send to
1102 the cam (??)
1103 */
1104 pan = 64 * pan / 100;
1105 tilt = -64 * tilt / 100; /* positive tilt is down, which is not what the user would expect */
1106 buf[0] = pan & 0xFF;
1107 buf[1] = (pan >> 8) & 0xFF;
1108 buf[2] = tilt & 0xFF;
1109 buf[3] = (tilt >> 8) & 0xFF;
1110 return SendControlMsg(SET_MPT_CTL, PT_RELATIVE_CONTROL_FORMATTER, 4);
1111}
1112
1113static inline int pwc_mpt_get_status(struct pwc_device *pdev, struct pwc_mpt_status *status)
1114{
1115 int ret;
1116 unsigned char buf[5];
1117
1118 ret = RecvControlMsg(GET_MPT_CTL, PT_STATUS_FORMATTER, 5);
1119 if (ret < 0)
1120 return ret;
1121 status->status = buf[0] & 0x7; // 3 bits are used for reporting
1122 status->time_pan = (buf[1] << 8) + buf[2];
1123 status->time_tilt = (buf[3] << 8) + buf[4];
1124 return 0;
1125}
1126
1127
1128int pwc_get_cmos_sensor(struct pwc_device *pdev, int *sensor)
1129{
1130 unsigned char buf;
1131 int ret = -1, request;
1132
1133 if (pdev->type < 675)
1134 request = SENSOR_TYPE_FORMATTER1;
1135 else if (pdev->type < 730)
1136 return -1; /* The Vesta series doesn't have this call */
1137 else
1138 request = SENSOR_TYPE_FORMATTER2;
1139
1140 ret = RecvControlMsg(GET_STATUS_CTL, request, 1);
1141 if (ret < 0)
1142 return ret;
1143 if (pdev->type < 675)
1144 *sensor = buf | 0x100;
1145 else
1146 *sensor = buf;
1147 return 0;
1148}
1149
1150
1151 /* End of Add-Ons */
1152 /* ************************************************* */
1153
1154
1155int pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg)
1156{
1157 int ret = 0;
1158
1159 switch(cmd) {
1160 case VIDIOCPWCRUSER:
1161 {
1162 if (pwc_restore_user(pdev))
1163 ret = -EINVAL;
1164 break;
1165 }
1166
1167 case VIDIOCPWCSUSER:
1168 {
1169 if (pwc_save_user(pdev))
1170 ret = -EINVAL;
1171 break;
1172 }
1173
1174 case VIDIOCPWCFACTORY:
1175 {
1176 if (pwc_restore_factory(pdev))
1177 ret = -EINVAL;
1178 break;
1179 }
1180
1181 case VIDIOCPWCSCQUAL:
1182 {
1183 int *qual = arg;
1184
1185 if (*qual < 0 || *qual > 3)
1186 ret = -EINVAL;
1187 else
1188 ret = pwc_try_video_mode(pdev, pdev->view.x, pdev->view.y, pdev->vframes, *qual, pdev->vsnapshot);
1189 if (ret >= 0)
1190 pdev->vcompression = *qual;
1191 break;
1192 }
1193
1194 case VIDIOCPWCGCQUAL:
1195 {
1196 int *qual = arg;
1197 *qual = pdev->vcompression;
1198 break;
1199 }
1200
1201 case VIDIOCPWCPROBE:
1202 {
1203 struct pwc_probe *probe = arg;
1204 strcpy(probe->name, pdev->vdev->name);
1205 probe->type = pdev->type;
1206 break;
1207 }
1208
1209 case VIDIOCPWCGSERIAL:
1210 {
1211 struct pwc_serial *serial = arg;
1212 strcpy(serial->serial, pdev->serial);
1213 break;
1214 }
1215
1216 case VIDIOCPWCSAGC:
1217 {
1218 int *agc = arg;
1219 if (pwc_set_agc(pdev, *agc < 0 ? 1 : 0, *agc))
1220 ret = -EINVAL;
1221 break;
1222 }
1223
1224 case VIDIOCPWCGAGC:
1225 {
1226 int *agc = arg;
1227
1228 if (pwc_get_agc(pdev, agc))
1229 ret = -EINVAL;
1230 break;
1231 }
1232
1233 case VIDIOCPWCSSHUTTER:
1234 {
1235 int *shutter_speed = arg;
1236 ret = pwc_set_shutter_speed(pdev, *shutter_speed < 0 ? 1 : 0, *shutter_speed);
1237 break;
1238 }
1239
1240 case VIDIOCPWCSAWB:
1241 {
1242 struct pwc_whitebalance *wb = arg;
1243
1244 ret = pwc_set_awb(pdev, wb->mode);
1245 if (ret >= 0 && wb->mode == PWC_WB_MANUAL) {
1246 pwc_set_red_gain(pdev, wb->manual_red);
1247 pwc_set_blue_gain(pdev, wb->manual_blue);
1248 }
1249 break;
1250 }
1251
1252 case VIDIOCPWCGAWB:
1253 {
1254 struct pwc_whitebalance *wb = arg;
1255
1256 memset(wb, 0, sizeof(struct pwc_whitebalance));
1257 wb->mode = pwc_get_awb(pdev);
1258 if (wb->mode < 0)
1259 ret = -EINVAL;
1260 else {
1261 if (wb->mode == PWC_WB_MANUAL) {
1262 ret = pwc_get_red_gain(pdev, &wb->manual_red);
1263 if (ret < 0)
1264 break;
1265 ret = pwc_get_blue_gain(pdev, &wb->manual_blue);
1266 if (ret < 0)
1267 break;
1268 }
1269 if (wb->mode == PWC_WB_AUTO) {
1270 ret = pwc_read_red_gain(pdev, &wb->read_red);
1271 if (ret < 0)
1272 break;
1273 ret = pwc_read_blue_gain(pdev, &wb->read_blue);
1274 if (ret < 0)
1275 break;
1276 }
1277 }
1278 break;
1279 }
1280
1281 case VIDIOCPWCSAWBSPEED:
1282 {
1283 struct pwc_wb_speed *wbs = arg;
1284
1285 if (wbs->control_speed > 0) {
1286 ret = pwc_set_wb_speed(pdev, wbs->control_speed);
1287 }
1288 if (wbs->control_delay > 0) {
1289 ret = pwc_set_wb_delay(pdev, wbs->control_delay);
1290 }
1291 break;
1292 }
1293
1294 case VIDIOCPWCGAWBSPEED:
1295 {
1296 struct pwc_wb_speed *wbs = arg;
1297
1298 ret = pwc_get_wb_speed(pdev, &wbs->control_speed);
1299 if (ret < 0)
1300 break;
1301 ret = pwc_get_wb_delay(pdev, &wbs->control_delay);
1302 if (ret < 0)
1303 break;
1304 break;
1305 }
1306
1307 case VIDIOCPWCSLED:
1308 {
1309 struct pwc_leds *leds = arg;
1310 ret = pwc_set_leds(pdev, leds->led_on, leds->led_off);
1311 break;
1312 }
1313
1314
1315 case VIDIOCPWCGLED:
1316 {
1317 struct pwc_leds *leds = arg;
1318 ret = pwc_get_leds(pdev, &leds->led_on, &leds->led_off);
1319 break;
1320 }
1321
1322 case VIDIOCPWCSCONTOUR:
1323 {
1324 int *contour = arg;
1325 ret = pwc_set_contour(pdev, *contour);
1326 break;
1327 }
1328
1329 case VIDIOCPWCGCONTOUR:
1330 {
1331 int *contour = arg;
1332 ret = pwc_get_contour(pdev, contour);
1333 break;
1334 }
1335
1336 case VIDIOCPWCSBACKLIGHT:
1337 {
1338 int *backlight = arg;
1339 ret = pwc_set_backlight(pdev, *backlight);
1340 break;
1341 }
1342
1343 case VIDIOCPWCGBACKLIGHT:
1344 {
1345 int *backlight = arg;
1346 ret = pwc_get_backlight(pdev, backlight);
1347 break;
1348 }
1349
1350 case VIDIOCPWCSFLICKER:
1351 {
1352 int *flicker = arg;
1353 ret = pwc_set_flicker(pdev, *flicker);
1354 break;
1355 }
1356
1357 case VIDIOCPWCGFLICKER:
1358 {
1359 int *flicker = arg;
1360 ret = pwc_get_flicker(pdev, flicker);
1361 break;
1362 }
1363
1364 case VIDIOCPWCSDYNNOISE:
1365 {
1366 int *dynnoise = arg;
1367 ret = pwc_set_dynamic_noise(pdev, *dynnoise);
1368 break;
1369 }
1370
1371 case VIDIOCPWCGDYNNOISE:
1372 {
1373 int *dynnoise = arg;
1374 ret = pwc_get_dynamic_noise(pdev, dynnoise);
1375 break;
1376 }
1377
1378 case VIDIOCPWCGREALSIZE:
1379 {
1380 struct pwc_imagesize *size = arg;
1381 size->width = pdev->image.x;
1382 size->height = pdev->image.y;
1383 break;
1384 }
1385
1386 case VIDIOCPWCMPTRESET:
1387 {
1388 if (pdev->features & FEATURE_MOTOR_PANTILT)
1389 {
1390 int *flags = arg;
1391
1392 ret = pwc_mpt_reset(pdev, *flags);
1393 if (ret >= 0)
1394 {
1395 pdev->pan_angle = 0;
1396 pdev->tilt_angle = 0;
1397 }
1398 }
1399 else
1400 {
1401 ret = -ENXIO;
1402 }
1403 break;
1404 }
1405
1406 case VIDIOCPWCMPTGRANGE:
1407 {
1408 if (pdev->features & FEATURE_MOTOR_PANTILT)
1409 {
1410 struct pwc_mpt_range *range = arg;
1411 *range = pdev->angle_range;
1412 }
1413 else
1414 {
1415 ret = -ENXIO;
1416 }
1417 break;
1418 }
1419
1420 case VIDIOCPWCMPTSANGLE:
1421 {
1422 int new_pan, new_tilt;
1423
1424 if (pdev->features & FEATURE_MOTOR_PANTILT)
1425 {
1426 struct pwc_mpt_angles *angles = arg;
1427 /* The camera can only set relative angles, so
1428 do some calculations when getting an absolute angle .
1429 */
1430 if (angles->absolute)
1431 {
1432 new_pan = angles->pan;
1433 new_tilt = angles->tilt;
1434 }
1435 else
1436 {
1437 new_pan = pdev->pan_angle + angles->pan;
1438 new_tilt = pdev->tilt_angle + angles->tilt;
1439 }
1440 /* check absolute ranges */
1441 if (new_pan < pdev->angle_range.pan_min ||
1442 new_pan > pdev->angle_range.pan_max ||
1443 new_tilt < pdev->angle_range.tilt_min ||
1444 new_tilt > pdev->angle_range.tilt_max)
1445 {
1446 ret = -ERANGE;
1447 }
1448 else
1449 {
1450 /* go to relative range, check again */
1451 new_pan -= pdev->pan_angle;
1452 new_tilt -= pdev->tilt_angle;
1453 /* angles are specified in degrees * 100, thus the limit = 36000 */
1454 if (new_pan < -36000 || new_pan > 36000 || new_tilt < -36000 || new_tilt > 36000)
1455 ret = -ERANGE;
1456 }
1457 if (ret == 0) /* no errors so far */
1458 {
1459 ret = pwc_mpt_set_angle(pdev, new_pan, new_tilt);
1460 if (ret >= 0)
1461 {
1462 pdev->pan_angle += new_pan;
1463 pdev->tilt_angle += new_tilt;
1464 }
1465 if (ret == -EPIPE) /* stall -> out of range */
1466 ret = -ERANGE;
1467 }
1468 }
1469 else
1470 {
1471 ret = -ENXIO;
1472 }
1473 break;
1474 }
1475
1476 case VIDIOCPWCMPTGANGLE:
1477 {
1478
1479 if (pdev->features & FEATURE_MOTOR_PANTILT)
1480 {
1481 struct pwc_mpt_angles *angles = arg;
1482
1483 angles->absolute = 1;
1484 angles->pan = pdev->pan_angle;
1485 angles->tilt = pdev->tilt_angle;
1486 }
1487 else
1488 {
1489 ret = -ENXIO;
1490 }
1491 break;
1492 }
1493
1494 case VIDIOCPWCMPTSTATUS:
1495 {
1496 if (pdev->features & FEATURE_MOTOR_PANTILT)
1497 {
1498 struct pwc_mpt_status *status = arg;
1499 ret = pwc_mpt_get_status(pdev, status);
1500 }
1501 else
1502 {
1503 ret = -ENXIO;
1504 }
1505 break;
1506 }
1507
1508 case VIDIOCPWCGVIDCMD:
1509 {
1510 struct pwc_video_command *cmd = arg;
1511
1512 cmd->type = pdev->type;
1513 cmd->release = pdev->release;
1514 cmd->command_len = pdev->cmd_len;
1515 memcpy(&cmd->command_buf, pdev->cmd_buf, pdev->cmd_len);
1516 cmd->bandlength = pdev->vbandlength;
1517 cmd->frame_size = pdev->frame_size;
1518 break;
1519 }
1520 /*
1521 case VIDIOCPWCGVIDTABLE:
1522 {
1523 struct pwc_table_init_buffer *table = arg;
1524 table->len = pdev->cmd_len;
1525 memcpy(&table->buffer, pdev->decompress_data, pdev->decompressor->table_size);
1526 break;
1527 }
1528 */
1529
1530 default:
1531 ret = -ENOIOCTLCMD;
1532 break;
1533 }
1534
1535 if (ret > 0)
1536 return 0;
1537 return ret;
1538}
1539
1540
1541
diff --git a/drivers/media/video/pwc/pwc-if.c b/drivers/media/video/pwc/pwc-if.c
new file mode 100644
index 000000000000..90eb26042817
--- /dev/null
+++ b/drivers/media/video/pwc/pwc-if.c
@@ -0,0 +1,2205 @@
1/* Linux driver for Philips webcam
2 USB and Video4Linux interface part.
3 (C) 1999-2004 Nemosoft Unv.
4 (C) 2004 Luc Saillard (luc@saillard.org)
5
6 NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx
7 driver and thus may have bugs that are not present in the original version.
8 Please send bug reports and support requests to <luc@saillard.org>.
9 The decompression routines have been implemented by reverse-engineering the
10 Nemosoft binary pwcx module. Caveat emptor.
11
12 This program is free software; you can redistribute it and/or modify
13 it under the terms of the GNU General Public License as published by
14 the Free Software Foundation; either version 2 of the License, or
15 (at your option) any later version.
16
17 This program is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 GNU General Public License for more details.
21
22 You should have received a copy of the GNU General Public License
23 along with this program; if not, write to the Free Software
24 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25
26*/
27
28/*
29 This code forms the interface between the USB layers and the Philips
30 specific stuff. Some adanved stuff of the driver falls under an
31 NDA, signed between me and Philips B.V., Eindhoven, the Netherlands, and
32 is thus not distributed in source form. The binary pwcx.o module
33 contains the code that falls under the NDA.
34
35 In case you're wondering: 'pwc' stands for "Philips WebCam", but
36 I really didn't want to type 'philips_web_cam' every time (I'm lazy as
37 any Linux kernel hacker, but I don't like uncomprehensible abbreviations
38 without explanation).
39
40 Oh yes, convention: to disctinguish between all the various pointers to
41 device-structures, I use these names for the pointer variables:
42 udev: struct usb_device *
43 vdev: struct video_device *
44 pdev: struct pwc_devive *
45*/
46
47/* Contributors:
48 - Alvarado: adding whitebalance code
49 - Alistar Moire: QuickCam 3000 Pro device/product ID
50 - Tony Hoyle: Creative Labs Webcam 5 device/product ID
51 - Mark Burazin: solving hang in VIDIOCSYNC when camera gets unplugged
52 - Jk Fang: Sotec Afina Eye ID
53 - Xavier Roche: QuickCam Pro 4000 ID
54 - Jens Knudsen: QuickCam Zoom ID
55 - J. Debert: QuickCam for Notebooks ID
56*/
57
58#include <linux/errno.h>
59#include <linux/init.h>
60#include <linux/mm.h>
61#include <linux/module.h>
62#include <linux/poll.h>
63#include <linux/slab.h>
64#include <linux/vmalloc.h>
65#include <asm/io.h>
66
67#include "pwc.h"
68#include "pwc-ioctl.h"
69#include "pwc-kiara.h"
70#include "pwc-timon.h"
71#include "pwc-uncompress.h"
72
73/* Function prototypes and driver templates */
74
75/* hotplug device table support */
76static struct usb_device_id pwc_device_table [] = {
77 { USB_DEVICE(0x0471, 0x0302) }, /* Philips models */
78 { USB_DEVICE(0x0471, 0x0303) },
79 { USB_DEVICE(0x0471, 0x0304) },
80 { USB_DEVICE(0x0471, 0x0307) },
81 { USB_DEVICE(0x0471, 0x0308) },
82 { USB_DEVICE(0x0471, 0x030C) },
83 { USB_DEVICE(0x0471, 0x0310) },
84 { USB_DEVICE(0x0471, 0x0311) },
85 { USB_DEVICE(0x0471, 0x0312) },
86 { USB_DEVICE(0x0471, 0x0313) }, /* the 'new' 720K */
87 { USB_DEVICE(0x069A, 0x0001) }, /* Askey */
88 { USB_DEVICE(0x046D, 0x08B0) }, /* Logitech QuickCam Pro 3000 */
89 { USB_DEVICE(0x046D, 0x08B1) }, /* Logitech QuickCam Notebook Pro */
90 { USB_DEVICE(0x046D, 0x08B2) }, /* Logitech QuickCam Pro 4000 */
91 { USB_DEVICE(0x046D, 0x08B3) }, /* Logitech QuickCam Zoom (old model) */
92 { USB_DEVICE(0x046D, 0x08B4) }, /* Logitech QuickCam Zoom (new model) */
93 { USB_DEVICE(0x046D, 0x08B5) }, /* Logitech QuickCam Orbit/Sphere */
94 { USB_DEVICE(0x046D, 0x08B6) }, /* Logitech (reserved) */
95 { USB_DEVICE(0x046D, 0x08B7) }, /* Logitech (reserved) */
96 { USB_DEVICE(0x046D, 0x08B8) }, /* Logitech (reserved) */
97 { USB_DEVICE(0x055D, 0x9000) }, /* Samsung */
98 { USB_DEVICE(0x055D, 0x9001) },
99 { USB_DEVICE(0x041E, 0x400C) }, /* Creative Webcam 5 */
100 { USB_DEVICE(0x041E, 0x4011) }, /* Creative Webcam Pro Ex */
101 { USB_DEVICE(0x04CC, 0x8116) }, /* Afina Eye */
102 { USB_DEVICE(0x06BE, 0x8116) }, /* new Afina Eye */
103 { USB_DEVICE(0x0d81, 0x1910) }, /* Visionite */
104 { USB_DEVICE(0x0d81, 0x1900) },
105 { }
106};
107MODULE_DEVICE_TABLE(usb, pwc_device_table);
108
109static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id *id);
110static void usb_pwc_disconnect(struct usb_interface *intf);
111
112static struct usb_driver pwc_driver = {
113 .name = "Philips webcam", /* name */
114 .id_table = pwc_device_table,
115 .probe = usb_pwc_probe, /* probe() */
116 .disconnect = usb_pwc_disconnect, /* disconnect() */
117};
118
119#define MAX_DEV_HINTS 20
120#define MAX_ISOC_ERRORS 20
121
122static int default_size = PSZ_QCIF;
123static int default_fps = 10;
124static int default_fbufs = 3; /* Default number of frame buffers */
125static int default_mbufs = 2; /* Default number of mmap() buffers */
126 int pwc_trace = TRACE_MODULE | TRACE_FLOW | TRACE_PWCX;
127static int power_save = 0;
128static int led_on = 100, led_off = 0; /* defaults to LED that is on while in use */
129static int pwc_preferred_compression = 2; /* 0..3 = uncompressed..high */
130static struct {
131 int type;
132 char serial_number[30];
133 int device_node;
134 struct pwc_device *pdev;
135} device_hint[MAX_DEV_HINTS];
136
137/***/
138
139static int pwc_video_open(struct inode *inode, struct file *file);
140static int pwc_video_close(struct inode *inode, struct file *file);
141static ssize_t pwc_video_read(struct file *file, char __user * buf,
142 size_t count, loff_t *ppos);
143static unsigned int pwc_video_poll(struct file *file, poll_table *wait);
144static int pwc_video_ioctl(struct inode *inode, struct file *file,
145 unsigned int ioctlnr, unsigned long arg);
146static int pwc_video_mmap(struct file *file, struct vm_area_struct *vma);
147
148static struct file_operations pwc_fops = {
149 .owner = THIS_MODULE,
150 .open = pwc_video_open,
151 .release = pwc_video_close,
152 .read = pwc_video_read,
153 .poll = pwc_video_poll,
154 .mmap = pwc_video_mmap,
155 .ioctl = pwc_video_ioctl,
156 .compat_ioctl = v4l_compat_ioctl32,
157 .llseek = no_llseek,
158};
159static struct video_device pwc_template = {
160 .owner = THIS_MODULE,
161 .name = "Philips Webcam", /* Filled in later */
162 .type = VID_TYPE_CAPTURE,
163 .hardware = VID_HARDWARE_PWC,
164 .release = video_device_release,
165 .fops = &pwc_fops,
166 .minor = -1,
167};
168
169/***************************************************************************/
170
171/* Okay, this is some magic that I worked out and the reasoning behind it...
172
173 The biggest problem with any USB device is of course: "what to do
174 when the user unplugs the device while it is in use by an application?"
175 We have several options:
176 1) Curse them with the 7 plagues when they do (requires divine intervention)
177 2) Tell them not to (won't work: they'll do it anyway)
178 3) Oops the kernel (this will have a negative effect on a user's uptime)
179 4) Do something sensible.
180
181 Of course, we go for option 4.
182
183 It happens that this device will be linked to two times, once from
184 usb_device and once from the video_device in their respective 'private'
185 pointers. This is done when the device is probed() and all initialization
186 succeeded. The pwc_device struct links back to both structures.
187
188 When a device is unplugged while in use it will be removed from the
189 list of known USB devices; I also de-register it as a V4L device, but
190 unfortunately I can't free the memory since the struct is still in use
191 by the file descriptor. This free-ing is then deferend until the first
192 opportunity. Crude, but it works.
193
194 A small 'advantage' is that if a user unplugs the cam and plugs it back
195 in, it should get assigned the same video device minor, but unfortunately
196 it's non-trivial to re-link the cam back to the video device... (that
197 would surely be magic! :))
198*/
199
200/***************************************************************************/
201/* Private functions */
202
203/* Here we want the physical address of the memory.
204 * This is used when initializing the contents of the area.
205 */
206static inline unsigned long kvirt_to_pa(unsigned long adr)
207{
208 unsigned long kva, ret;
209
210 kva = (unsigned long) page_address(vmalloc_to_page((void *)adr));
211 kva |= adr & (PAGE_SIZE-1); /* restore the offset */
212 ret = __pa(kva);
213 return ret;
214}
215
216static void * rvmalloc(unsigned long size)
217{
218 void * mem;
219 unsigned long adr;
220
221 size=PAGE_ALIGN(size);
222 mem=vmalloc_32(size);
223 if (mem)
224 {
225 memset(mem, 0, size); /* Clear the ram out, no junk to the user */
226 adr=(unsigned long) mem;
227 while (size > 0)
228 {
229 SetPageReserved(vmalloc_to_page((void *)adr));
230 adr+=PAGE_SIZE;
231 size-=PAGE_SIZE;
232 }
233 }
234 return mem;
235}
236
237static void rvfree(void * mem, unsigned long size)
238{
239 unsigned long adr;
240
241 if (mem)
242 {
243 adr=(unsigned long) mem;
244 while ((long) size > 0)
245 {
246 ClearPageReserved(vmalloc_to_page((void *)adr));
247 adr+=PAGE_SIZE;
248 size-=PAGE_SIZE;
249 }
250 vfree(mem);
251 }
252}
253
254
255
256
257static int pwc_allocate_buffers(struct pwc_device *pdev)
258{
259 int i;
260 void *kbuf;
261
262 Trace(TRACE_MEMORY, ">> pwc_allocate_buffers(pdev = 0x%p)\n", pdev);
263
264 if (pdev == NULL)
265 return -ENXIO;
266
267#ifdef PWC_MAGIC
268 if (pdev->magic != PWC_MAGIC) {
269 Err("allocate_buffers(): magic failed.\n");
270 return -ENXIO;
271 }
272#endif
273 /* Allocate Isochronous pipe buffers */
274 for (i = 0; i < MAX_ISO_BUFS; i++) {
275 if (pdev->sbuf[i].data == NULL) {
276 kbuf = kmalloc(ISO_BUFFER_SIZE, GFP_KERNEL);
277 if (kbuf == NULL) {
278 Err("Failed to allocate iso buffer %d.\n", i);
279 return -ENOMEM;
280 }
281 Trace(TRACE_MEMORY, "Allocated iso buffer at %p.\n", kbuf);
282 pdev->sbuf[i].data = kbuf;
283 memset(kbuf, 0, ISO_BUFFER_SIZE);
284 }
285 }
286
287 /* Allocate frame buffer structure */
288 if (pdev->fbuf == NULL) {
289 kbuf = kmalloc(default_fbufs * sizeof(struct pwc_frame_buf), GFP_KERNEL);
290 if (kbuf == NULL) {
291 Err("Failed to allocate frame buffer structure.\n");
292 return -ENOMEM;
293 }
294 Trace(TRACE_MEMORY, "Allocated frame buffer structure at %p.\n", kbuf);
295 pdev->fbuf = kbuf;
296 memset(kbuf, 0, default_fbufs * sizeof(struct pwc_frame_buf));
297 }
298 /* create frame buffers, and make circular ring */
299 for (i = 0; i < default_fbufs; i++) {
300 if (pdev->fbuf[i].data == NULL) {
301 kbuf = vmalloc(PWC_FRAME_SIZE); /* need vmalloc since frame buffer > 128K */
302 if (kbuf == NULL) {
303 Err("Failed to allocate frame buffer %d.\n", i);
304 return -ENOMEM;
305 }
306 Trace(TRACE_MEMORY, "Allocated frame buffer %d at %p.\n", i, kbuf);
307 pdev->fbuf[i].data = kbuf;
308 memset(kbuf, 128, PWC_FRAME_SIZE);
309 }
310 }
311
312 /* Allocate decompressor table space */
313 kbuf = NULL;
314 switch (pdev->type)
315 {
316 case 675:
317 case 680:
318 case 690:
319 case 720:
320 case 730:
321 case 740:
322 case 750:
323#if 0
324 Trace(TRACE_MEMORY,"private_data(%zu)\n",sizeof(struct pwc_dec23_private));
325 kbuf = kmalloc(sizeof(struct pwc_dec23_private), GFP_KERNEL); /* Timon & Kiara */
326 break;
327 case 645:
328 case 646:
329 /* TODO & FIXME */
330 kbuf = kmalloc(sizeof(struct pwc_dec23_private), GFP_KERNEL);
331 break;
332#endif
333 ;
334 }
335 pdev->decompress_data = kbuf;
336
337 /* Allocate image buffer; double buffer for mmap() */
338 kbuf = rvmalloc(default_mbufs * pdev->len_per_image);
339 if (kbuf == NULL) {
340 Err("Failed to allocate image buffer(s). needed (%d)\n",default_mbufs * pdev->len_per_image);
341 return -ENOMEM;
342 }
343 Trace(TRACE_MEMORY, "Allocated image buffer at %p.\n", kbuf);
344 pdev->image_data = kbuf;
345 for (i = 0; i < default_mbufs; i++)
346 pdev->image_ptr[i] = kbuf + i * pdev->len_per_image;
347 for (; i < MAX_IMAGES; i++)
348 pdev->image_ptr[i] = NULL;
349
350 kbuf = NULL;
351
352 Trace(TRACE_MEMORY, "<< pwc_allocate_buffers()\n");
353 return 0;
354}
355
356static void pwc_free_buffers(struct pwc_device *pdev)
357{
358 int i;
359
360 Trace(TRACE_MEMORY, "Entering free_buffers(%p).\n", pdev);
361
362 if (pdev == NULL)
363 return;
364#ifdef PWC_MAGIC
365 if (pdev->magic != PWC_MAGIC) {
366 Err("free_buffers(): magic failed.\n");
367 return;
368 }
369#endif
370
371 /* Release Iso-pipe buffers */
372 for (i = 0; i < MAX_ISO_BUFS; i++)
373 if (pdev->sbuf[i].data != NULL) {
374 Trace(TRACE_MEMORY, "Freeing ISO buffer at %p.\n", pdev->sbuf[i].data);
375 kfree(pdev->sbuf[i].data);
376 pdev->sbuf[i].data = NULL;
377 }
378
379 /* The same for frame buffers */
380 if (pdev->fbuf != NULL) {
381 for (i = 0; i < default_fbufs; i++) {
382 if (pdev->fbuf[i].data != NULL) {
383 Trace(TRACE_MEMORY, "Freeing frame buffer %d at %p.\n", i, pdev->fbuf[i].data);
384 vfree(pdev->fbuf[i].data);
385 pdev->fbuf[i].data = NULL;
386 }
387 }
388 kfree(pdev->fbuf);
389 pdev->fbuf = NULL;
390 }
391
392 /* Intermediate decompression buffer & tables */
393 if (pdev->decompress_data != NULL) {
394 Trace(TRACE_MEMORY, "Freeing decompression buffer at %p.\n", pdev->decompress_data);
395 kfree(pdev->decompress_data);
396 pdev->decompress_data = NULL;
397 }
398 pdev->decompressor = NULL;
399
400 /* Release image buffers */
401 if (pdev->image_data != NULL) {
402 Trace(TRACE_MEMORY, "Freeing image buffer at %p.\n", pdev->image_data);
403 rvfree(pdev->image_data, default_mbufs * pdev->len_per_image);
404 }
405 pdev->image_data = NULL;
406
407 Trace(TRACE_MEMORY, "Leaving free_buffers().\n");
408}
409
410/* The frame & image buffer mess.
411
412 Yes, this is a mess. Well, it used to be simple, but alas... In this
413 module, 3 buffers schemes are used to get the data from the USB bus to
414 the user program. The first scheme involves the ISO buffers (called thus
415 since they transport ISO data from the USB controller), and not really
416 interesting. Suffices to say the data from this buffer is quickly
417 gathered in an interrupt handler (pwc_isoc_handler) and placed into the
418 frame buffer.
419
420 The frame buffer is the second scheme, and is the central element here.
421 It collects the data from a single frame from the camera (hence, the
422 name). Frames are delimited by the USB camera with a short USB packet,
423 so that's easy to detect. The frame buffers form a list that is filled
424 by the camera+USB controller and drained by the user process through
425 either read() or mmap().
426
427 The image buffer is the third scheme, in which frames are decompressed
428 and converted into planar format. For mmap() there is more than
429 one image buffer available.
430
431 The frame buffers provide the image buffering. In case the user process
432 is a bit slow, this introduces lag and some undesired side-effects.
433 The problem arises when the frame buffer is full. I used to drop the last
434 frame, which makes the data in the queue stale very quickly. But dropping
435 the frame at the head of the queue proved to be a litte bit more difficult.
436 I tried a circular linked scheme, but this introduced more problems than
437 it solved.
438
439 Because filling and draining are completely asynchronous processes, this
440 requires some fiddling with pointers and mutexes.
441
442 Eventually, I came up with a system with 2 lists: an 'empty' frame list
443 and a 'full' frame list:
444 * Initially, all frame buffers but one are on the 'empty' list; the one
445 remaining buffer is our initial fill frame.
446 * If a frame is needed for filling, we try to take it from the 'empty'
447 list, unless that list is empty, in which case we take the buffer at
448 the head of the 'full' list.
449 * When our fill buffer has been filled, it is appended to the 'full'
450 list.
451 * If a frame is needed by read() or mmap(), it is taken from the head of
452 the 'full' list, handled, and then appended to the 'empty' list. If no
453 buffer is present on the 'full' list, we wait.
454 The advantage is that the buffer that is currently being decompressed/
455 converted, is on neither list, and thus not in our way (any other scheme
456 I tried had the problem of old data lingering in the queue).
457
458 Whatever strategy you choose, it always remains a tradeoff: with more
459 frame buffers the chances of a missed frame are reduced. On the other
460 hand, on slower machines it introduces lag because the queue will
461 always be full.
462 */
463
464/**
465 \brief Find next frame buffer to fill. Take from empty or full list, whichever comes first.
466 */
467static inline int pwc_next_fill_frame(struct pwc_device *pdev)
468{
469 int ret;
470 unsigned long flags;
471
472 ret = 0;
473 spin_lock_irqsave(&pdev->ptrlock, flags);
474 if (pdev->fill_frame != NULL) {
475 /* append to 'full' list */
476 if (pdev->full_frames == NULL) {
477 pdev->full_frames = pdev->fill_frame;
478 pdev->full_frames_tail = pdev->full_frames;
479 }
480 else {
481 pdev->full_frames_tail->next = pdev->fill_frame;
482 pdev->full_frames_tail = pdev->fill_frame;
483 }
484 }
485 if (pdev->empty_frames != NULL) {
486 /* We have empty frames available. That's easy */
487 pdev->fill_frame = pdev->empty_frames;
488 pdev->empty_frames = pdev->empty_frames->next;
489 }
490 else {
491 /* Hmm. Take it from the full list */
492#if PWC_DEBUG
493 /* sanity check */
494 if (pdev->full_frames == NULL) {
495 Err("Neither empty or full frames available!\n");
496 spin_unlock_irqrestore(&pdev->ptrlock, flags);
497 return -EINVAL;
498 }
499#endif
500 pdev->fill_frame = pdev->full_frames;
501 pdev->full_frames = pdev->full_frames->next;
502 ret = 1;
503 }
504 pdev->fill_frame->next = NULL;
505#if PWC_DEBUG
506 Trace(TRACE_SEQUENCE, "Assigning sequence number %d.\n", pdev->sequence);
507 pdev->fill_frame->sequence = pdev->sequence++;
508#endif
509 spin_unlock_irqrestore(&pdev->ptrlock, flags);
510 return ret;
511}
512
513
514/**
515 \brief Reset all buffers, pointers and lists, except for the image_used[] buffer.
516
517 If the image_used[] buffer is cleared too, mmap()/VIDIOCSYNC will run into trouble.
518 */
519static void pwc_reset_buffers(struct pwc_device *pdev)
520{
521 int i;
522 unsigned long flags;
523
524 spin_lock_irqsave(&pdev->ptrlock, flags);
525 pdev->full_frames = NULL;
526 pdev->full_frames_tail = NULL;
527 for (i = 0; i < default_fbufs; i++) {
528 pdev->fbuf[i].filled = 0;
529 if (i > 0)
530 pdev->fbuf[i].next = &pdev->fbuf[i - 1];
531 else
532 pdev->fbuf->next = NULL;
533 }
534 pdev->empty_frames = &pdev->fbuf[default_fbufs - 1];
535 pdev->empty_frames_tail = pdev->fbuf;
536 pdev->read_frame = NULL;
537 pdev->fill_frame = pdev->empty_frames;
538 pdev->empty_frames = pdev->empty_frames->next;
539
540 pdev->image_read_pos = 0;
541 pdev->fill_image = 0;
542 spin_unlock_irqrestore(&pdev->ptrlock, flags);
543}
544
545
546/**
547 \brief Do all the handling for getting one frame: get pointer, decompress, advance pointers.
548 */
549static int pwc_handle_frame(struct pwc_device *pdev)
550{
551 int ret = 0;
552 unsigned long flags;
553
554 spin_lock_irqsave(&pdev->ptrlock, flags);
555 /* First grab our read_frame; this is removed from all lists, so
556 we can release the lock after this without problems */
557 if (pdev->read_frame != NULL) {
558 /* This can't theoretically happen */
559 Err("Huh? Read frame still in use?\n");
560 }
561 else {
562 if (pdev->full_frames == NULL) {
563 Err("Woops. No frames ready.\n");
564 }
565 else {
566 pdev->read_frame = pdev->full_frames;
567 pdev->full_frames = pdev->full_frames->next;
568 pdev->read_frame->next = NULL;
569 }
570
571 if (pdev->read_frame != NULL) {
572#if PWC_DEBUG
573 Trace(TRACE_SEQUENCE, "Decompressing frame %d\n", pdev->read_frame->sequence);
574#endif
575 /* Decompression is a lenghty process, so it's outside of the lock.
576 This gives the isoc_handler the opportunity to fill more frames
577 in the mean time.
578 */
579 spin_unlock_irqrestore(&pdev->ptrlock, flags);
580 ret = pwc_decompress(pdev);
581 spin_lock_irqsave(&pdev->ptrlock, flags);
582
583 /* We're done with read_buffer, tack it to the end of the empty buffer list */
584 if (pdev->empty_frames == NULL) {
585 pdev->empty_frames = pdev->read_frame;
586 pdev->empty_frames_tail = pdev->empty_frames;
587 }
588 else {
589 pdev->empty_frames_tail->next = pdev->read_frame;
590 pdev->empty_frames_tail = pdev->read_frame;
591 }
592 pdev->read_frame = NULL;
593 }
594 }
595 spin_unlock_irqrestore(&pdev->ptrlock, flags);
596 return ret;
597}
598
599/**
600 \brief Advance pointers of image buffer (after each user request)
601*/
602static inline void pwc_next_image(struct pwc_device *pdev)
603{
604 pdev->image_used[pdev->fill_image] = 0;
605 pdev->fill_image = (pdev->fill_image + 1) % default_mbufs;
606}
607
608
609/* This gets called for the Isochronous pipe (video). This is done in
610 * interrupt time, so it has to be fast, not crash, and not stall. Neat.
611 */
612static void pwc_isoc_handler(struct urb *urb, struct pt_regs *regs)
613{
614 struct pwc_device *pdev;
615 int i, fst, flen;
616 int awake;
617 struct pwc_frame_buf *fbuf;
618 unsigned char *fillptr = NULL, *iso_buf = NULL;
619
620 awake = 0;
621 pdev = (struct pwc_device *)urb->context;
622 if (pdev == NULL) {
623 Err("isoc_handler() called with NULL device?!\n");
624 return;
625 }
626#ifdef PWC_MAGIC
627 if (pdev->magic != PWC_MAGIC) {
628 Err("isoc_handler() called with bad magic!\n");
629 return;
630 }
631#endif
632 if (urb->status == -ENOENT || urb->status == -ECONNRESET) {
633 Trace(TRACE_OPEN, "pwc_isoc_handler(): URB (%p) unlinked %ssynchronuously.\n", urb, urb->status == -ENOENT ? "" : "a");
634 return;
635 }
636 if (urb->status != -EINPROGRESS && urb->status != 0) {
637 const char *errmsg;
638
639 errmsg = "Unknown";
640 switch(urb->status) {
641 case -ENOSR: errmsg = "Buffer error (overrun)"; break;
642 case -EPIPE: errmsg = "Stalled (device not responding)"; break;
643 case -EOVERFLOW: errmsg = "Babble (bad cable?)"; break;
644 case -EPROTO: errmsg = "Bit-stuff error (bad cable?)"; break;
645 case -EILSEQ: errmsg = "CRC/Timeout (could be anything)"; break;
646 case -ETIMEDOUT: errmsg = "NAK (device does not respond)"; break;
647 }
648 Trace(TRACE_FLOW, "pwc_isoc_handler() called with status %d [%s].\n", urb->status, errmsg);
649 /* Give up after a number of contiguous errors on the USB bus.
650 Appearantly something is wrong so we simulate an unplug event.
651 */
652 if (++pdev->visoc_errors > MAX_ISOC_ERRORS)
653 {
654 Info("Too many ISOC errors, bailing out.\n");
655 pdev->error_status = EIO;
656 awake = 1;
657 wake_up_interruptible(&pdev->frameq);
658 }
659 goto handler_end; // ugly, but practical
660 }
661
662 fbuf = pdev->fill_frame;
663 if (fbuf == NULL) {
664 Err("pwc_isoc_handler without valid fill frame.\n");
665 awake = 1;
666 goto handler_end;
667 }
668 else {
669 fillptr = fbuf->data + fbuf->filled;
670 }
671
672 /* Reset ISOC error counter. We did get here, after all. */
673 pdev->visoc_errors = 0;
674
675 /* vsync: 0 = don't copy data
676 1 = sync-hunt
677 2 = synched
678 */
679 /* Compact data */
680 for (i = 0; i < urb->number_of_packets; i++) {
681 fst = urb->iso_frame_desc[i].status;
682 flen = urb->iso_frame_desc[i].actual_length;
683 iso_buf = urb->transfer_buffer + urb->iso_frame_desc[i].offset;
684 if (fst == 0) {
685 if (flen > 0) { /* if valid data... */
686 if (pdev->vsync > 0) { /* ...and we are not sync-hunting... */
687 pdev->vsync = 2;
688
689 /* ...copy data to frame buffer, if possible */
690 if (flen + fbuf->filled > pdev->frame_total_size) {
691 Trace(TRACE_FLOW, "Frame buffer overflow (flen = %d, frame_total_size = %d).\n", flen, pdev->frame_total_size);
692 pdev->vsync = 0; /* Hmm, let's wait for an EOF (end-of-frame) */
693 pdev->vframes_error++;
694 }
695 else {
696 memmove(fillptr, iso_buf, flen);
697 fillptr += flen;
698 }
699 }
700 fbuf->filled += flen;
701 } /* ..flen > 0 */
702
703 if (flen < pdev->vlast_packet_size) {
704 /* Shorter packet... We probably have the end of an image-frame;
705 wake up read() process and let select()/poll() do something.
706 Decompression is done in user time over there.
707 */
708 if (pdev->vsync == 2) {
709 /* The ToUCam Fun CMOS sensor causes the firmware to send 2 or 3 bogus
710 frames on the USB wire after an exposure change. This conditition is
711 however detected in the cam and a bit is set in the header.
712 */
713 if (pdev->type == 730) {
714 unsigned char *ptr = (unsigned char *)fbuf->data;
715
716 if (ptr[1] == 1 && ptr[0] & 0x10) {
717#if PWC_DEBUG
718 Debug("Hyundai CMOS sensor bug. Dropping frame %d.\n", fbuf->sequence);
719#endif
720 pdev->drop_frames += 2;
721 pdev->vframes_error++;
722 }
723 if ((ptr[0] ^ pdev->vmirror) & 0x01) {
724 if (ptr[0] & 0x01)
725 Info("Snapshot button pressed.\n");
726 else
727 Info("Snapshot button released.\n");
728 }
729 if ((ptr[0] ^ pdev->vmirror) & 0x02) {
730 if (ptr[0] & 0x02)
731 Info("Image is mirrored.\n");
732 else
733 Info("Image is normal.\n");
734 }
735 pdev->vmirror = ptr[0] & 0x03;
736 /* Sometimes the trailer of the 730 is still sent as a 4 byte packet
737 after a short frame; this condition is filtered out specifically. A 4 byte
738 frame doesn't make sense anyway.
739 So we get either this sequence:
740 drop_bit set -> 4 byte frame -> short frame -> good frame
741 Or this one:
742 drop_bit set -> short frame -> good frame
743 So we drop either 3 or 2 frames in all!
744 */
745 if (fbuf->filled == 4)
746 pdev->drop_frames++;
747 }
748
749 /* In case we were instructed to drop the frame, do so silently.
750 The buffer pointers are not updated either (but the counters are reset below).
751 */
752 if (pdev->drop_frames > 0)
753 pdev->drop_frames--;
754 else {
755 /* Check for underflow first */
756 if (fbuf->filled < pdev->frame_total_size) {
757 Trace(TRACE_FLOW, "Frame buffer underflow (%d bytes); discarded.\n", fbuf->filled);
758 pdev->vframes_error++;
759 }
760 else {
761 /* Send only once per EOF */
762 awake = 1; /* delay wake_ups */
763
764 /* Find our next frame to fill. This will always succeed, since we
765 * nick a frame from either empty or full list, but if we had to
766 * take it from the full list, it means a frame got dropped.
767 */
768 if (pwc_next_fill_frame(pdev)) {
769 pdev->vframes_dumped++;
770 if ((pdev->vframe_count > FRAME_LOWMARK) && (pwc_trace & TRACE_FLOW)) {
771 if (pdev->vframes_dumped < 20)
772 Trace(TRACE_FLOW, "Dumping frame %d.\n", pdev->vframe_count);
773 if (pdev->vframes_dumped == 20)
774 Trace(TRACE_FLOW, "Dumping frame %d (last message).\n", pdev->vframe_count);
775 }
776 }
777 fbuf = pdev->fill_frame;
778 }
779 } /* !drop_frames */
780 pdev->vframe_count++;
781 }
782 fbuf->filled = 0;
783 fillptr = fbuf->data;
784 pdev->vsync = 1;
785 } /* .. flen < last_packet_size */
786 pdev->vlast_packet_size = flen;
787 } /* ..status == 0 */
788#if PWC_DEBUG
789 /* This is normally not interesting to the user, unless you are really debugging something */
790 else {
791 static int iso_error = 0;
792 iso_error++;
793 if (iso_error < 20)
794 Trace(TRACE_FLOW, "Iso frame %d of USB has error %d\n", i, fst);
795 }
796#endif
797 }
798
799handler_end:
800 if (awake)
801 wake_up_interruptible(&pdev->frameq);
802
803 urb->dev = pdev->udev;
804 i = usb_submit_urb(urb, GFP_ATOMIC);
805 if (i != 0)
806 Err("Error (%d) re-submitting urb in pwc_isoc_handler.\n", i);
807}
808
809
810static int pwc_isoc_init(struct pwc_device *pdev)
811{
812 struct usb_device *udev;
813 struct urb *urb;
814 int i, j, ret;
815
816 struct usb_interface *intf;
817 struct usb_host_interface *idesc = NULL;
818
819 if (pdev == NULL)
820 return -EFAULT;
821 if (pdev->iso_init)
822 return 0;
823 pdev->vsync = 0;
824 udev = pdev->udev;
825
826 /* Get the current alternate interface, adjust packet size */
827 if (!udev->actconfig)
828 return -EFAULT;
829
830 intf = usb_ifnum_to_if(udev, 0);
831 if (intf)
832 idesc = usb_altnum_to_altsetting(intf, pdev->valternate);
833
834 if (!idesc)
835 return -EFAULT;
836
837 /* Search video endpoint */
838 pdev->vmax_packet_size = -1;
839 for (i = 0; i < idesc->desc.bNumEndpoints; i++)
840 if ((idesc->endpoint[i].desc.bEndpointAddress & 0xF) == pdev->vendpoint) {
841 pdev->vmax_packet_size = le16_to_cpu(idesc->endpoint[i].desc.wMaxPacketSize);
842 break;
843 }
844
845 if (pdev->vmax_packet_size < 0 || pdev->vmax_packet_size > ISO_MAX_FRAME_SIZE) {
846 Err("Failed to find packet size for video endpoint in current alternate setting.\n");
847 return -ENFILE; /* Odd error, that should be noticeable */
848 }
849
850 /* Set alternate interface */
851 ret = 0;
852 Trace(TRACE_OPEN, "Setting alternate interface %d\n", pdev->valternate);
853 ret = usb_set_interface(pdev->udev, 0, pdev->valternate);
854 if (ret < 0)
855 return ret;
856
857 for (i = 0; i < MAX_ISO_BUFS; i++) {
858 urb = usb_alloc_urb(ISO_FRAMES_PER_DESC, GFP_KERNEL);
859 if (urb == NULL) {
860 Err("Failed to allocate urb %d\n", i);
861 ret = -ENOMEM;
862 break;
863 }
864 pdev->sbuf[i].urb = urb;
865 Trace(TRACE_MEMORY, "Allocated URB at 0x%p\n", urb);
866 }
867 if (ret) {
868 /* De-allocate in reverse order */
869 while (i >= 0) {
870 if (pdev->sbuf[i].urb != NULL)
871 usb_free_urb(pdev->sbuf[i].urb);
872 pdev->sbuf[i].urb = NULL;
873 i--;
874 }
875 return ret;
876 }
877
878 /* init URB structure */
879 for (i = 0; i < MAX_ISO_BUFS; i++) {
880 urb = pdev->sbuf[i].urb;
881
882 urb->interval = 1; // devik
883 urb->dev = udev;
884 urb->pipe = usb_rcvisocpipe(udev, pdev->vendpoint);
885 urb->transfer_flags = URB_ISO_ASAP;
886 urb->transfer_buffer = pdev->sbuf[i].data;
887 urb->transfer_buffer_length = ISO_BUFFER_SIZE;
888 urb->complete = pwc_isoc_handler;
889 urb->context = pdev;
890 urb->start_frame = 0;
891 urb->number_of_packets = ISO_FRAMES_PER_DESC;
892 for (j = 0; j < ISO_FRAMES_PER_DESC; j++) {
893 urb->iso_frame_desc[j].offset = j * ISO_MAX_FRAME_SIZE;
894 urb->iso_frame_desc[j].length = pdev->vmax_packet_size;
895 }
896 }
897
898 /* link */
899 for (i = 0; i < MAX_ISO_BUFS; i++) {
900 ret = usb_submit_urb(pdev->sbuf[i].urb, GFP_KERNEL);
901 if (ret)
902 Err("isoc_init() submit_urb %d failed with error %d\n", i, ret);
903 else
904 Trace(TRACE_MEMORY, "URB 0x%p submitted.\n", pdev->sbuf[i].urb);
905 }
906
907 /* All is done... */
908 pdev->iso_init = 1;
909 Trace(TRACE_OPEN, "<< pwc_isoc_init()\n");
910 return 0;
911}
912
913static void pwc_isoc_cleanup(struct pwc_device *pdev)
914{
915 int i;
916
917 Trace(TRACE_OPEN, ">> pwc_isoc_cleanup()\n");
918 if (pdev == NULL)
919 return;
920
921 /* Unlinking ISOC buffers one by one */
922 for (i = 0; i < MAX_ISO_BUFS; i++) {
923 struct urb *urb;
924
925 urb = pdev->sbuf[i].urb;
926 if (urb != 0) {
927 if (pdev->iso_init) {
928 Trace(TRACE_MEMORY, "Unlinking URB %p\n", urb);
929 usb_kill_urb(urb);
930 }
931 Trace(TRACE_MEMORY, "Freeing URB\n");
932 usb_free_urb(urb);
933 pdev->sbuf[i].urb = NULL;
934 }
935 }
936
937 /* Stop camera, but only if we are sure the camera is still there (unplug
938 is signalled by EPIPE)
939 */
940 if (pdev->error_status && pdev->error_status != EPIPE) {
941 Trace(TRACE_OPEN, "Setting alternate interface 0.\n");
942 usb_set_interface(pdev->udev, 0, 0);
943 }
944
945 pdev->iso_init = 0;
946 Trace(TRACE_OPEN, "<< pwc_isoc_cleanup()\n");
947}
948
949int pwc_try_video_mode(struct pwc_device *pdev, int width, int height, int new_fps, int new_compression, int new_snapshot)
950{
951 int ret, start;
952
953 /* Stop isoc stuff */
954 pwc_isoc_cleanup(pdev);
955 /* Reset parameters */
956 pwc_reset_buffers(pdev);
957 /* Try to set video mode... */
958 start = ret = pwc_set_video_mode(pdev, width, height, new_fps, new_compression, new_snapshot);
959 if (ret) {
960 Trace(TRACE_FLOW, "pwc_set_video_mode attempt 1 failed.\n");
961 /* That failed... restore old mode (we know that worked) */
962 start = pwc_set_video_mode(pdev, pdev->view.x, pdev->view.y, pdev->vframes, pdev->vcompression, pdev->vsnapshot);
963 if (start) {
964 Trace(TRACE_FLOW, "pwc_set_video_mode attempt 2 failed.\n");
965 }
966 }
967 if (start == 0)
968 {
969 if (pwc_isoc_init(pdev) < 0)
970 {
971 Info("Failed to restart ISOC transfers in pwc_try_video_mode.\n");
972 ret = -EAGAIN; /* let's try again, who knows if it works a second time */
973 }
974 }
975 pdev->drop_frames++; /* try to avoid garbage during switch */
976 return ret; /* Return original error code */
977}
978
979
980/***************************************************************************/
981/* Video4Linux functions */
982
983static int pwc_video_open(struct inode *inode, struct file *file)
984{
985 int i;
986 struct video_device *vdev = video_devdata(file);
987 struct pwc_device *pdev;
988
989 Trace(TRACE_OPEN, ">> video_open called(vdev = 0x%p).\n", vdev);
990
991 pdev = (struct pwc_device *)vdev->priv;
992 if (pdev == NULL)
993 BUG();
994 if (pdev->vopen)
995 return -EBUSY;
996
997 down(&pdev->modlock);
998 if (!pdev->usb_init) {
999 Trace(TRACE_OPEN, "Doing first time initialization.\n");
1000 pdev->usb_init = 1;
1001
1002 if (pwc_trace & TRACE_OPEN)
1003 {
1004 /* Query sensor type */
1005 const char *sensor_type = NULL;
1006 int ret;
1007
1008 ret = pwc_get_cmos_sensor(pdev, &i);
1009 if (ret >= 0)
1010 {
1011 switch(i) {
1012 case 0x00: sensor_type = "Hyundai CMOS sensor"; break;
1013 case 0x20: sensor_type = "Sony CCD sensor + TDA8787"; break;
1014 case 0x2E: sensor_type = "Sony CCD sensor + Exas 98L59"; break;
1015 case 0x2F: sensor_type = "Sony CCD sensor + ADI 9804"; break;
1016 case 0x30: sensor_type = "Sharp CCD sensor + TDA8787"; break;
1017 case 0x3E: sensor_type = "Sharp CCD sensor + Exas 98L59"; break;
1018 case 0x3F: sensor_type = "Sharp CCD sensor + ADI 9804"; break;
1019 case 0x40: sensor_type = "UPA 1021 sensor"; break;
1020 case 0x100: sensor_type = "VGA sensor"; break;
1021 case 0x101: sensor_type = "PAL MR sensor"; break;
1022 default: sensor_type = "unknown type of sensor"; break;
1023 }
1024 }
1025 if (sensor_type != NULL)
1026 Info("This %s camera is equipped with a %s (%d).\n", pdev->vdev->name, sensor_type, i);
1027 }
1028 }
1029
1030 /* Turn on camera */
1031 if (power_save) {
1032 i = pwc_camera_power(pdev, 1);
1033 if (i < 0)
1034 Info("Failed to restore power to the camera! (%d)\n", i);
1035 }
1036 /* Set LED on/off time */
1037 if (pwc_set_leds(pdev, led_on, led_off) < 0)
1038 Info("Failed to set LED on/off time.\n");
1039
1040 pwc_construct(pdev); /* set min/max sizes correct */
1041
1042 /* So far, so good. Allocate memory. */
1043 i = pwc_allocate_buffers(pdev);
1044 if (i < 0) {
1045 Trace(TRACE_OPEN, "Failed to allocate buffer memory.\n");
1046 up(&pdev->modlock);
1047 return i;
1048 }
1049
1050 /* Reset buffers & parameters */
1051 pwc_reset_buffers(pdev);
1052 for (i = 0; i < default_mbufs; i++)
1053 pdev->image_used[i] = 0;
1054 pdev->vframe_count = 0;
1055 pdev->vframes_dumped = 0;
1056 pdev->vframes_error = 0;
1057 pdev->visoc_errors = 0;
1058 pdev->error_status = 0;
1059#if PWC_DEBUG
1060 pdev->sequence = 0;
1061#endif
1062 pwc_construct(pdev); /* set min/max sizes correct */
1063
1064 /* Set some defaults */
1065 pdev->vsnapshot = 0;
1066
1067 /* Start iso pipe for video; first try the last used video size
1068 (or the default one); if that fails try QCIF/10 or QSIF/10;
1069 it that fails too, give up.
1070 */
1071 i = pwc_set_video_mode(pdev, pwc_image_sizes[pdev->vsize].x, pwc_image_sizes[pdev->vsize].y, pdev->vframes, pdev->vcompression, 0);
1072 if (i) {
1073 Trace(TRACE_OPEN, "First attempt at set_video_mode failed.\n");
1074 if (pdev->type == 730 || pdev->type == 740 || pdev->type == 750)
1075 i = pwc_set_video_mode(pdev, pwc_image_sizes[PSZ_QSIF].x, pwc_image_sizes[PSZ_QSIF].y, 10, pdev->vcompression, 0);
1076 else
1077 i = pwc_set_video_mode(pdev, pwc_image_sizes[PSZ_QCIF].x, pwc_image_sizes[PSZ_QCIF].y, 10, pdev->vcompression, 0);
1078 }
1079 if (i) {
1080 Trace(TRACE_OPEN, "Second attempt at set_video_mode failed.\n");
1081 up(&pdev->modlock);
1082 return i;
1083 }
1084
1085 i = pwc_isoc_init(pdev);
1086 if (i) {
1087 Trace(TRACE_OPEN, "Failed to init ISOC stuff = %d.\n", i);
1088 up(&pdev->modlock);
1089 return i;
1090 }
1091
1092 pdev->vopen++;
1093 file->private_data = vdev;
1094 up(&pdev->modlock);
1095 Trace(TRACE_OPEN, "<< video_open() returns 0.\n");
1096 return 0;
1097}
1098
1099/* Note that all cleanup is done in the reverse order as in _open */
1100static int pwc_video_close(struct inode *inode, struct file *file)
1101{
1102 struct video_device *vdev = file->private_data;
1103 struct pwc_device *pdev;
1104 int i;
1105
1106 Trace(TRACE_OPEN, ">> video_close called(vdev = 0x%p).\n", vdev);
1107
1108 pdev = (struct pwc_device *)vdev->priv;
1109 if (pdev->vopen == 0)
1110 Info("video_close() called on closed device?\n");
1111
1112 /* Dump statistics, but only if a reasonable amount of frames were
1113 processed (to prevent endless log-entries in case of snap-shot
1114 programs)
1115 */
1116 if (pdev->vframe_count > 20)
1117 Info("Closing video device: %d frames received, dumped %d frames, %d frames with errors.\n", pdev->vframe_count, pdev->vframes_dumped, pdev->vframes_error);
1118
1119 switch (pdev->type)
1120 {
1121 case 675:
1122 case 680:
1123 case 690:
1124 case 720:
1125 case 730:
1126 case 740:
1127 case 750:
1128/* pwc_dec23_exit(); *//* Timon & Kiara */
1129 break;
1130 case 645:
1131 case 646:
1132/* pwc_dec1_exit(); */
1133 break;
1134 }
1135
1136 pwc_isoc_cleanup(pdev);
1137 pwc_free_buffers(pdev);
1138
1139 /* Turn off LEDS and power down camera, but only when not unplugged */
1140 if (pdev->error_status != EPIPE) {
1141 /* Turn LEDs off */
1142 if (pwc_set_leds(pdev, 0, 0) < 0)
1143 Info("Failed to set LED on/off time.\n");
1144 if (power_save) {
1145 i = pwc_camera_power(pdev, 0);
1146 if (i < 0)
1147 Err("Failed to power down camera (%d)\n", i);
1148 }
1149 }
1150 pdev->vopen = 0;
1151 Trace(TRACE_OPEN, "<< video_close()\n");
1152 return 0;
1153}
1154
1155/*
1156 * FIXME: what about two parallel reads ????
1157 * ANSWER: Not supported. You can't open the device more than once,
1158 despite what the V4L1 interface says. First, I don't see
1159 the need, second there's no mechanism of alerting the
1160 2nd/3rd/... process of events like changing image size.
1161 And I don't see the point of blocking that for the
1162 2nd/3rd/... process.
1163 In multi-threaded environments reading parallel from any
1164 device is tricky anyhow.
1165 */
1166
1167static ssize_t pwc_video_read(struct file *file, char __user * buf,
1168 size_t count, loff_t *ppos)
1169{
1170 struct video_device *vdev = file->private_data;
1171 struct pwc_device *pdev;
1172 int noblock = file->f_flags & O_NONBLOCK;
1173 DECLARE_WAITQUEUE(wait, current);
1174 int bytes_to_read;
1175
1176 Trace(TRACE_READ, "video_read(0x%p, %p, %zu) called.\n", vdev, buf, count);
1177 if (vdev == NULL)
1178 return -EFAULT;
1179 pdev = vdev->priv;
1180 if (pdev == NULL)
1181 return -EFAULT;
1182 if (pdev->error_status)
1183 return -pdev->error_status; /* Something happened, report what. */
1184
1185 /* In case we're doing partial reads, we don't have to wait for a frame */
1186 if (pdev->image_read_pos == 0) {
1187 /* Do wait queueing according to the (doc)book */
1188 add_wait_queue(&pdev->frameq, &wait);
1189 while (pdev->full_frames == NULL) {
1190 /* Check for unplugged/etc. here */
1191 if (pdev->error_status) {
1192 remove_wait_queue(&pdev->frameq, &wait);
1193 set_current_state(TASK_RUNNING);
1194 return -pdev->error_status ;
1195 }
1196 if (noblock) {
1197 remove_wait_queue(&pdev->frameq, &wait);
1198 set_current_state(TASK_RUNNING);
1199 return -EWOULDBLOCK;
1200 }
1201 if (signal_pending(current)) {
1202 remove_wait_queue(&pdev->frameq, &wait);
1203 set_current_state(TASK_RUNNING);
1204 return -ERESTARTSYS;
1205 }
1206 schedule();
1207 set_current_state(TASK_INTERRUPTIBLE);
1208 }
1209 remove_wait_queue(&pdev->frameq, &wait);
1210 set_current_state(TASK_RUNNING);
1211
1212 /* Decompress and release frame */
1213 if (pwc_handle_frame(pdev))
1214 return -EFAULT;
1215 }
1216
1217 Trace(TRACE_READ, "Copying data to user space.\n");
1218 if (pdev->vpalette == VIDEO_PALETTE_RAW)
1219 bytes_to_read = pdev->frame_size;
1220 else
1221 bytes_to_read = pdev->view.size;
1222
1223 /* copy bytes to user space; we allow for partial reads */
1224 if (count + pdev->image_read_pos > bytes_to_read)
1225 count = bytes_to_read - pdev->image_read_pos;
1226 if (copy_to_user(buf, pdev->image_ptr[pdev->fill_image] + pdev->image_read_pos, count))
1227 return -EFAULT;
1228 pdev->image_read_pos += count;
1229 if (pdev->image_read_pos >= bytes_to_read) { /* All data has been read */
1230 pdev->image_read_pos = 0;
1231 pwc_next_image(pdev);
1232 }
1233 return count;
1234}
1235
1236static unsigned int pwc_video_poll(struct file *file, poll_table *wait)
1237{
1238 struct video_device *vdev = file->private_data;
1239 struct pwc_device *pdev;
1240
1241 if (vdev == NULL)
1242 return -EFAULT;
1243 pdev = vdev->priv;
1244 if (pdev == NULL)
1245 return -EFAULT;
1246
1247 poll_wait(file, &pdev->frameq, wait);
1248 if (pdev->error_status)
1249 return POLLERR;
1250 if (pdev->full_frames != NULL) /* we have frames waiting */
1251 return (POLLIN | POLLRDNORM);
1252
1253 return 0;
1254}
1255
1256static int pwc_video_do_ioctl(struct inode *inode, struct file *file,
1257 unsigned int cmd, void *arg)
1258{
1259 struct video_device *vdev = file->private_data;
1260 struct pwc_device *pdev;
1261 DECLARE_WAITQUEUE(wait, current);
1262
1263 if (vdev == NULL)
1264 return -EFAULT;
1265 pdev = vdev->priv;
1266 if (pdev == NULL)
1267 return -EFAULT;
1268
1269 switch (cmd) {
1270 /* Query cabapilities */
1271 case VIDIOCGCAP:
1272 {
1273 struct video_capability *caps = arg;
1274
1275 strcpy(caps->name, vdev->name);
1276 caps->type = VID_TYPE_CAPTURE;
1277 caps->channels = 1;
1278 caps->audios = 1;
1279 caps->minwidth = pdev->view_min.x;
1280 caps->minheight = pdev->view_min.y;
1281 caps->maxwidth = pdev->view_max.x;
1282 caps->maxheight = pdev->view_max.y;
1283 break;
1284 }
1285
1286 /* Channel functions (simulate 1 channel) */
1287 case VIDIOCGCHAN:
1288 {
1289 struct video_channel *v = arg;
1290
1291 if (v->channel != 0)
1292 return -EINVAL;
1293 v->flags = 0;
1294 v->tuners = 0;
1295 v->type = VIDEO_TYPE_CAMERA;
1296 strcpy(v->name, "Webcam");
1297 return 0;
1298 }
1299
1300 case VIDIOCSCHAN:
1301 {
1302 /* The spec says the argument is an integer, but
1303 the bttv driver uses a video_channel arg, which
1304 makes sense becasue it also has the norm flag.
1305 */
1306 struct video_channel *v = arg;
1307 if (v->channel != 0)
1308 return -EINVAL;
1309 return 0;
1310 }
1311
1312
1313 /* Picture functions; contrast etc. */
1314 case VIDIOCGPICT:
1315 {
1316 struct video_picture *p = arg;
1317 int val;
1318
1319 val = pwc_get_brightness(pdev);
1320 if (val >= 0)
1321 p->brightness = val;
1322 else
1323 p->brightness = 0xffff;
1324 val = pwc_get_contrast(pdev);
1325 if (val >= 0)
1326 p->contrast = val;
1327 else
1328 p->contrast = 0xffff;
1329 /* Gamma, Whiteness, what's the difference? :) */
1330 val = pwc_get_gamma(pdev);
1331 if (val >= 0)
1332 p->whiteness = val;
1333 else
1334 p->whiteness = 0xffff;
1335 val = pwc_get_saturation(pdev);
1336 if (val >= 0)
1337 p->colour = val;
1338 else
1339 p->colour = 0xffff;
1340 p->depth = 24;
1341 p->palette = pdev->vpalette;
1342 p->hue = 0xFFFF; /* N/A */
1343 break;
1344 }
1345
1346 case VIDIOCSPICT:
1347 {
1348 struct video_picture *p = arg;
1349 /*
1350 * FIXME: Suppose we are mid read
1351 ANSWER: No problem: the firmware of the camera
1352 can handle brightness/contrast/etc
1353 changes at _any_ time, and the palette
1354 is used exactly once in the uncompress
1355 routine.
1356 */
1357 pwc_set_brightness(pdev, p->brightness);
1358 pwc_set_contrast(pdev, p->contrast);
1359 pwc_set_gamma(pdev, p->whiteness);
1360 pwc_set_saturation(pdev, p->colour);
1361 if (p->palette && p->palette != pdev->vpalette) {
1362 switch (p->palette) {
1363 case VIDEO_PALETTE_YUV420P:
1364 case VIDEO_PALETTE_RAW:
1365 pdev->vpalette = p->palette;
1366 return pwc_try_video_mode(pdev, pdev->image.x, pdev->image.y, pdev->vframes, pdev->vcompression, pdev->vsnapshot);
1367 break;
1368 default:
1369 return -EINVAL;
1370 break;
1371 }
1372 }
1373 break;
1374 }
1375
1376 /* Window/size parameters */
1377 case VIDIOCGWIN:
1378 {
1379 struct video_window *vw = arg;
1380
1381 vw->x = 0;
1382 vw->y = 0;
1383 vw->width = pdev->view.x;
1384 vw->height = pdev->view.y;
1385 vw->chromakey = 0;
1386 vw->flags = (pdev->vframes << PWC_FPS_SHIFT) |
1387 (pdev->vsnapshot ? PWC_FPS_SNAPSHOT : 0);
1388 break;
1389 }
1390
1391 case VIDIOCSWIN:
1392 {
1393 struct video_window *vw = arg;
1394 int fps, snapshot, ret;
1395
1396 fps = (vw->flags & PWC_FPS_FRMASK) >> PWC_FPS_SHIFT;
1397 snapshot = vw->flags & PWC_FPS_SNAPSHOT;
1398 if (fps == 0)
1399 fps = pdev->vframes;
1400 if (pdev->view.x == vw->width && pdev->view.y && fps == pdev->vframes && snapshot == pdev->vsnapshot)
1401 return 0;
1402 ret = pwc_try_video_mode(pdev, vw->width, vw->height, fps, pdev->vcompression, snapshot);
1403 if (ret)
1404 return ret;
1405 break;
1406 }
1407
1408 /* We don't have overlay support (yet) */
1409 case VIDIOCGFBUF:
1410 {
1411 struct video_buffer *vb = arg;
1412
1413 memset(vb,0,sizeof(*vb));
1414 break;
1415 }
1416
1417 /* mmap() functions */
1418 case VIDIOCGMBUF:
1419 {
1420 /* Tell the user program how much memory is needed for a mmap() */
1421 struct video_mbuf *vm = arg;
1422 int i;
1423
1424 memset(vm, 0, sizeof(*vm));
1425 vm->size = default_mbufs * pdev->len_per_image;
1426 vm->frames = default_mbufs; /* double buffering should be enough for most applications */
1427 for (i = 0; i < default_mbufs; i++)
1428 vm->offsets[i] = i * pdev->len_per_image;
1429 break;
1430 }
1431
1432 case VIDIOCMCAPTURE:
1433 {
1434 /* Start capture into a given image buffer (called 'frame' in video_mmap structure) */
1435 struct video_mmap *vm = arg;
1436
1437 Trace(TRACE_READ, "VIDIOCMCAPTURE: %dx%d, frame %d, format %d\n", vm->width, vm->height, vm->frame, vm->format);
1438 if (vm->frame < 0 || vm->frame >= default_mbufs)
1439 return -EINVAL;
1440
1441 /* xawtv is nasty. It probes the available palettes
1442 by setting a very small image size and trying
1443 various palettes... The driver doesn't support
1444 such small images, so I'm working around it.
1445 */
1446 if (vm->format)
1447 {
1448 switch (vm->format)
1449 {
1450 case VIDEO_PALETTE_YUV420P:
1451 case VIDEO_PALETTE_RAW:
1452 break;
1453 default:
1454 return -EINVAL;
1455 break;
1456 }
1457 }
1458
1459 if ((vm->width != pdev->view.x || vm->height != pdev->view.y) &&
1460 (vm->width >= pdev->view_min.x && vm->height >= pdev->view_min.y)) {
1461 int ret;
1462
1463 Trace(TRACE_OPEN, "VIDIOCMCAPTURE: changing size to please xawtv :-(.\n");
1464 ret = pwc_try_video_mode(pdev, vm->width, vm->height, pdev->vframes, pdev->vcompression, pdev->vsnapshot);
1465 if (ret)
1466 return ret;
1467 } /* ... size mismatch */
1468
1469 /* FIXME: should we lock here? */
1470 if (pdev->image_used[vm->frame])
1471 return -EBUSY; /* buffer wasn't available. Bummer */
1472 pdev->image_used[vm->frame] = 1;
1473
1474 /* Okay, we're done here. In the SYNC call we wait until a
1475 frame comes available, then expand image into the given
1476 buffer.
1477 In contrast to the CPiA cam the Philips cams deliver a
1478 constant stream, almost like a grabber card. Also,
1479 we have separate buffers for the rawdata and the image,
1480 meaning we can nearly always expand into the requested buffer.
1481 */
1482 Trace(TRACE_READ, "VIDIOCMCAPTURE done.\n");
1483 break;
1484 }
1485
1486 case VIDIOCSYNC:
1487 {
1488 /* The doc says: "Whenever a buffer is used it should
1489 call VIDIOCSYNC to free this frame up and continue."
1490
1491 The only odd thing about this whole procedure is
1492 that MCAPTURE flags the buffer as "in use", and
1493 SYNC immediately unmarks it, while it isn't
1494 after SYNC that you know that the buffer actually
1495 got filled! So you better not start a CAPTURE in
1496 the same frame immediately (use double buffering).
1497 This is not a problem for this cam, since it has
1498 extra intermediate buffers, but a hardware
1499 grabber card will then overwrite the buffer
1500 you're working on.
1501 */
1502 int *mbuf = arg;
1503 int ret;
1504
1505 Trace(TRACE_READ, "VIDIOCSYNC called (%d).\n", *mbuf);
1506
1507 /* bounds check */
1508 if (*mbuf < 0 || *mbuf >= default_mbufs)
1509 return -EINVAL;
1510 /* check if this buffer was requested anyway */
1511 if (pdev->image_used[*mbuf] == 0)
1512 return -EINVAL;
1513
1514 /* Add ourselves to the frame wait-queue.
1515
1516 FIXME: needs auditing for safety.
1517 QUESTION: In what respect? I think that using the
1518 frameq is safe now.
1519 */
1520 add_wait_queue(&pdev->frameq, &wait);
1521 while (pdev->full_frames == NULL) {
1522 if (pdev->error_status) {
1523 remove_wait_queue(&pdev->frameq, &wait);
1524 set_current_state(TASK_RUNNING);
1525 return -pdev->error_status;
1526 }
1527
1528 if (signal_pending(current)) {
1529 remove_wait_queue(&pdev->frameq, &wait);
1530 set_current_state(TASK_RUNNING);
1531 return -ERESTARTSYS;
1532 }
1533 schedule();
1534 set_current_state(TASK_INTERRUPTIBLE);
1535 }
1536 remove_wait_queue(&pdev->frameq, &wait);
1537 set_current_state(TASK_RUNNING);
1538
1539 /* The frame is ready. Expand in the image buffer
1540 requested by the user. I don't care if you
1541 mmap() 5 buffers and request data in this order:
1542 buffer 4 2 3 0 1 2 3 0 4 3 1 . . .
1543 Grabber hardware may not be so forgiving.
1544 */
1545 Trace(TRACE_READ, "VIDIOCSYNC: frame ready.\n");
1546 pdev->fill_image = *mbuf; /* tell in which buffer we want the image to be expanded */
1547 /* Decompress, etc */
1548 ret = pwc_handle_frame(pdev);
1549 pdev->image_used[*mbuf] = 0;
1550 if (ret)
1551 return -EFAULT;
1552 break;
1553 }
1554
1555 case VIDIOCGAUDIO:
1556 {
1557 struct video_audio *v = arg;
1558
1559 strcpy(v->name, "Microphone");
1560 v->audio = -1; /* unknown audio minor */
1561 v->flags = 0;
1562 v->mode = VIDEO_SOUND_MONO;
1563 v->volume = 0;
1564 v->bass = 0;
1565 v->treble = 0;
1566 v->balance = 0x8000;
1567 v->step = 1;
1568 break;
1569 }
1570
1571 case VIDIOCSAUDIO:
1572 {
1573 /* Dummy: nothing can be set */
1574 break;
1575 }
1576
1577 case VIDIOCGUNIT:
1578 {
1579 struct video_unit *vu = arg;
1580
1581 vu->video = pdev->vdev->minor & 0x3F;
1582 vu->audio = -1; /* not known yet */
1583 vu->vbi = -1;
1584 vu->radio = -1;
1585 vu->teletext = -1;
1586 break;
1587 }
1588 default:
1589 return pwc_ioctl(pdev, cmd, arg);
1590 } /* ..switch */
1591 return 0;
1592}
1593
1594static int pwc_video_ioctl(struct inode *inode, struct file *file,
1595 unsigned int cmd, unsigned long arg)
1596{
1597 return video_usercopy(inode, file, cmd, arg, pwc_video_do_ioctl);
1598}
1599
1600
1601static int pwc_video_mmap(struct file *file, struct vm_area_struct *vma)
1602{
1603 struct video_device *vdev = file->private_data;
1604 struct pwc_device *pdev;
1605 unsigned long start = vma->vm_start;
1606 unsigned long size = vma->vm_end-vma->vm_start;
1607 unsigned long page, pos;
1608
1609 Trace(TRACE_MEMORY, "mmap(0x%p, 0x%lx, %lu) called.\n", vdev, start, size);
1610 pdev = vdev->priv;
1611
1612 vma->vm_flags |= VM_IO;
1613
1614 pos = (unsigned long)pdev->image_data;
1615 while (size > 0) {
1616 page = vmalloc_to_pfn((void *)pos);
1617 if (remap_pfn_range(vma, start, page, PAGE_SIZE, PAGE_SHARED))
1618 return -EAGAIN;
1619
1620 start += PAGE_SIZE;
1621 pos += PAGE_SIZE;
1622 if (size > PAGE_SIZE)
1623 size -= PAGE_SIZE;
1624 else
1625 size = 0;
1626 }
1627
1628 return 0;
1629}
1630
1631/***************************************************************************/
1632/* USB functions */
1633
1634/* This function gets called when a new device is plugged in or the usb core
1635 * is loaded.
1636 */
1637
1638static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id *id)
1639{
1640 struct usb_device *udev = interface_to_usbdev(intf);
1641 struct pwc_device *pdev = NULL;
1642 int vendor_id, product_id, type_id;
1643 int i, hint;
1644 int features = 0;
1645 int video_nr = -1; /* default: use next available device */
1646 char serial_number[30], *name;
1647
1648 /* Check if we can handle this device */
1649 Trace(TRACE_PROBE, "probe() called [%04X %04X], if %d\n",
1650 le16_to_cpu(udev->descriptor.idVendor),
1651 le16_to_cpu(udev->descriptor.idProduct),
1652 intf->altsetting->desc.bInterfaceNumber);
1653
1654 /* the interfaces are probed one by one. We are only interested in the
1655 video interface (0) now.
1656 Interface 1 is the Audio Control, and interface 2 Audio itself.
1657 */
1658 if (intf->altsetting->desc.bInterfaceNumber > 0)
1659 return -ENODEV;
1660
1661 vendor_id = le16_to_cpu(udev->descriptor.idVendor);
1662 product_id = le16_to_cpu(udev->descriptor.idProduct);
1663
1664 if (vendor_id == 0x0471) {
1665 switch (product_id) {
1666 case 0x0302:
1667 Info("Philips PCA645VC USB webcam detected.\n");
1668 name = "Philips 645 webcam";
1669 type_id = 645;
1670 break;
1671 case 0x0303:
1672 Info("Philips PCA646VC USB webcam detected.\n");
1673 name = "Philips 646 webcam";
1674 type_id = 646;
1675 break;
1676 case 0x0304:
1677 Info("Askey VC010 type 2 USB webcam detected.\n");
1678 name = "Askey VC010 webcam";
1679 type_id = 646;
1680 break;
1681 case 0x0307:
1682 Info("Philips PCVC675K (Vesta) USB webcam detected.\n");
1683 name = "Philips 675 webcam";
1684 type_id = 675;
1685 break;
1686 case 0x0308:
1687 Info("Philips PCVC680K (Vesta Pro) USB webcam detected.\n");
1688 name = "Philips 680 webcam";
1689 type_id = 680;
1690 break;
1691 case 0x030C:
1692 Info("Philips PCVC690K (Vesta Pro Scan) USB webcam detected.\n");
1693 name = "Philips 690 webcam";
1694 type_id = 690;
1695 break;
1696 case 0x0310:
1697 Info("Philips PCVC730K (ToUCam Fun)/PCVC830 (ToUCam II) USB webcam detected.\n");
1698 name = "Philips 730 webcam";
1699 type_id = 730;
1700 break;
1701 case 0x0311:
1702 Info("Philips PCVC740K (ToUCam Pro)/PCVC840 (ToUCam II) USB webcam detected.\n");
1703 name = "Philips 740 webcam";
1704 type_id = 740;
1705 break;
1706 case 0x0312:
1707 Info("Philips PCVC750K (ToUCam Pro Scan) USB webcam detected.\n");
1708 name = "Philips 750 webcam";
1709 type_id = 750;
1710 break;
1711 case 0x0313:
1712 Info("Philips PCVC720K/40 (ToUCam XS) USB webcam detected.\n");
1713 name = "Philips 720K/40 webcam";
1714 type_id = 720;
1715 break;
1716 default:
1717 return -ENODEV;
1718 break;
1719 }
1720 }
1721 else if (vendor_id == 0x069A) {
1722 switch(product_id) {
1723 case 0x0001:
1724 Info("Askey VC010 type 1 USB webcam detected.\n");
1725 name = "Askey VC010 webcam";
1726 type_id = 645;
1727 break;
1728 default:
1729 return -ENODEV;
1730 break;
1731 }
1732 }
1733 else if (vendor_id == 0x046d) {
1734 switch(product_id) {
1735 case 0x08b0:
1736 Info("Logitech QuickCam Pro 3000 USB webcam detected.\n");
1737 name = "Logitech QuickCam Pro 3000";
1738 type_id = 740; /* CCD sensor */
1739 break;
1740 case 0x08b1:
1741 Info("Logitech QuickCam Notebook Pro USB webcam detected.\n");
1742 name = "Logitech QuickCam Notebook Pro";
1743 type_id = 740; /* CCD sensor */
1744 break;
1745 case 0x08b2:
1746 Info("Logitech QuickCam 4000 Pro USB webcam detected.\n");
1747 name = "Logitech QuickCam Pro 4000";
1748 type_id = 740; /* CCD sensor */
1749 break;
1750 case 0x08b3:
1751 Info("Logitech QuickCam Zoom USB webcam detected.\n");
1752 name = "Logitech QuickCam Zoom";
1753 type_id = 740; /* CCD sensor */
1754 break;
1755 case 0x08B4:
1756 Info("Logitech QuickCam Zoom (new model) USB webcam detected.\n");
1757 name = "Logitech QuickCam Zoom";
1758 type_id = 740; /* CCD sensor */
1759 break;
1760 case 0x08b5:
1761 Info("Logitech QuickCam Orbit/Sphere USB webcam detected.\n");
1762 name = "Logitech QuickCam Orbit";
1763 type_id = 740; /* CCD sensor */
1764 features |= FEATURE_MOTOR_PANTILT;
1765 break;
1766 case 0x08b6:
1767 case 0x08b7:
1768 case 0x08b8:
1769 Info("Logitech QuickCam detected (reserved ID).\n");
1770 name = "Logitech QuickCam (res.)";
1771 type_id = 730; /* Assuming CMOS */
1772 break;
1773 default:
1774 return -ENODEV;
1775 break;
1776 }
1777 }
1778 else if (vendor_id == 0x055d) {
1779 /* I don't know the difference between the C10 and the C30;
1780 I suppose the difference is the sensor, but both cameras
1781 work equally well with a type_id of 675
1782 */
1783 switch(product_id) {
1784 case 0x9000:
1785 Info("Samsung MPC-C10 USB webcam detected.\n");
1786 name = "Samsung MPC-C10";
1787 type_id = 675;
1788 break;
1789 case 0x9001:
1790 Info("Samsung MPC-C30 USB webcam detected.\n");
1791 name = "Samsung MPC-C30";
1792 type_id = 675;
1793 break;
1794 default:
1795 return -ENODEV;
1796 break;
1797 }
1798 }
1799 else if (vendor_id == 0x041e) {
1800 switch(product_id) {
1801 case 0x400c:
1802 Info("Creative Labs Webcam 5 detected.\n");
1803 name = "Creative Labs Webcam 5";
1804 type_id = 730;
1805 break;
1806 case 0x4011:
1807 Info("Creative Labs Webcam Pro Ex detected.\n");
1808 name = "Creative Labs Webcam Pro Ex";
1809 type_id = 740;
1810 break;
1811 default:
1812 return -ENODEV;
1813 break;
1814 }
1815 }
1816 else if (vendor_id == 0x04cc) {
1817 switch(product_id) {
1818 case 0x8116:
1819 Info("Sotec Afina Eye USB webcam detected.\n");
1820 name = "Sotec Afina Eye";
1821 type_id = 730;
1822 break;
1823 default:
1824 return -ENODEV;
1825 break;
1826 }
1827 }
1828 else if (vendor_id == 0x06be) {
1829 switch(product_id) {
1830 case 0x8116:
1831 /* This is essentially the same cam as the Sotec Afina Eye */
1832 Info("AME Co. Afina Eye USB webcam detected.\n");
1833 name = "AME Co. Afina Eye";
1834 type_id = 750;
1835 break;
1836 default:
1837 return -ENODEV;
1838 break;
1839 }
1840
1841 }
1842 else if (vendor_id == 0x0d81) {
1843 switch(product_id) {
1844 case 0x1900:
1845 Info("Visionite VCS-UC300 USB webcam detected.\n");
1846 name = "Visionite VCS-UC300";
1847 type_id = 740; /* CCD sensor */
1848 break;
1849 case 0x1910:
1850 Info("Visionite VCS-UM100 USB webcam detected.\n");
1851 name = "Visionite VCS-UM100";
1852 type_id = 730; /* CMOS sensor */
1853 break;
1854 default:
1855 return -ENODEV;
1856 break;
1857 }
1858 }
1859 else
1860 return -ENODEV; /* Not any of the know types; but the list keeps growing. */
1861
1862 memset(serial_number, 0, 30);
1863 usb_string(udev, udev->descriptor.iSerialNumber, serial_number, 29);
1864 Trace(TRACE_PROBE, "Device serial number is %s\n", serial_number);
1865
1866 if (udev->descriptor.bNumConfigurations > 1)
1867 Info("Warning: more than 1 configuration available.\n");
1868
1869 /* Allocate structure, initialize pointers, mutexes, etc. and link it to the usb_device */
1870 pdev = kzalloc(sizeof(struct pwc_device), GFP_KERNEL);
1871 if (pdev == NULL) {
1872 Err("Oops, could not allocate memory for pwc_device.\n");
1873 return -ENOMEM;
1874 }
1875 pdev->type = type_id;
1876 pdev->vsize = default_size;
1877 pdev->vframes = default_fps;
1878 strcpy(pdev->serial, serial_number);
1879 pdev->features = features;
1880 if (vendor_id == 0x046D && product_id == 0x08B5)
1881 {
1882 /* Logitech QuickCam Orbit
1883 The ranges have been determined experimentally; they may differ from cam to cam.
1884 Also, the exact ranges left-right and up-down are different for my cam
1885 */
1886 pdev->angle_range.pan_min = -7000;
1887 pdev->angle_range.pan_max = 7000;
1888 pdev->angle_range.tilt_min = -3000;
1889 pdev->angle_range.tilt_max = 2500;
1890 }
1891
1892 init_MUTEX(&pdev->modlock);
1893 spin_lock_init(&pdev->ptrlock);
1894
1895 pdev->udev = udev;
1896 init_waitqueue_head(&pdev->frameq);
1897 pdev->vcompression = pwc_preferred_compression;
1898
1899 /* Allocate video_device structure */
1900 pdev->vdev = video_device_alloc();
1901 if (pdev->vdev == 0)
1902 {
1903 Err("Err, cannot allocate video_device struture. Failing probe.");
1904 kfree(pdev);
1905 return -ENOMEM;
1906 }
1907 memcpy(pdev->vdev, &pwc_template, sizeof(pwc_template));
1908 strcpy(pdev->vdev->name, name);
1909 pdev->vdev->owner = THIS_MODULE;
1910 video_set_drvdata(pdev->vdev, pdev);
1911
1912 pdev->release = le16_to_cpu(udev->descriptor.bcdDevice);
1913 Trace(TRACE_PROBE, "Release: %04x\n", pdev->release);
1914
1915 /* Now search device_hint[] table for a match, so we can hint a node number. */
1916 for (hint = 0; hint < MAX_DEV_HINTS; hint++) {
1917 if (((device_hint[hint].type == -1) || (device_hint[hint].type == pdev->type)) &&
1918 (device_hint[hint].pdev == NULL)) {
1919 /* so far, so good... try serial number */
1920 if ((device_hint[hint].serial_number[0] == '*') || !strcmp(device_hint[hint].serial_number, serial_number)) {
1921 /* match! */
1922 video_nr = device_hint[hint].device_node;
1923 Trace(TRACE_PROBE, "Found hint, will try to register as /dev/video%d\n", video_nr);
1924 break;
1925 }
1926 }
1927 }
1928
1929 pdev->vdev->release = video_device_release;
1930 i = video_register_device(pdev->vdev, VFL_TYPE_GRABBER, video_nr);
1931 if (i < 0) {
1932 Err("Failed to register as video device (%d).\n", i);
1933 video_device_release(pdev->vdev); /* Drip... drip... drip... */
1934 kfree(pdev); /* Oops, no memory leaks please */
1935 return -EIO;
1936 }
1937 else {
1938 Info("Registered as /dev/video%d.\n", pdev->vdev->minor & 0x3F);
1939 }
1940
1941 /* occupy slot */
1942 if (hint < MAX_DEV_HINTS)
1943 device_hint[hint].pdev = pdev;
1944
1945 Trace(TRACE_PROBE, "probe() function returning struct at 0x%p.\n", pdev);
1946 usb_set_intfdata (intf, pdev);
1947 return 0;
1948}
1949
1950/* The user janked out the cable... */
1951static void usb_pwc_disconnect(struct usb_interface *intf)
1952{
1953 struct pwc_device *pdev;
1954 int hint;
1955
1956 lock_kernel();
1957 pdev = usb_get_intfdata (intf);
1958 usb_set_intfdata (intf, NULL);
1959 if (pdev == NULL) {
1960 Err("pwc_disconnect() Called without private pointer.\n");
1961 goto disconnect_out;
1962 }
1963 if (pdev->udev == NULL) {
1964 Err("pwc_disconnect() already called for %p\n", pdev);
1965 goto disconnect_out;
1966 }
1967 if (pdev->udev != interface_to_usbdev(intf)) {
1968 Err("pwc_disconnect() Woops: pointer mismatch udev/pdev.\n");
1969 goto disconnect_out;
1970 }
1971#ifdef PWC_MAGIC
1972 if (pdev->magic != PWC_MAGIC) {
1973 Err("pwc_disconnect() Magic number failed. Consult your scrolls and try again.\n");
1974 goto disconnect_out;
1975 }
1976#endif
1977
1978 /* We got unplugged; this is signalled by an EPIPE error code */
1979 if (pdev->vopen) {
1980 Info("Disconnected while webcam is in use!\n");
1981 pdev->error_status = EPIPE;
1982 }
1983
1984 /* Alert waiting processes */
1985 wake_up_interruptible(&pdev->frameq);
1986 /* Wait until device is closed */
1987 while (pdev->vopen)
1988 schedule();
1989 /* Device is now closed, so we can safely unregister it */
1990 Trace(TRACE_PROBE, "Unregistering video device in disconnect().\n");
1991 video_unregister_device(pdev->vdev);
1992
1993 /* Free memory (don't set pdev to 0 just yet) */
1994 kfree(pdev);
1995
1996disconnect_out:
1997 /* search device_hint[] table if we occupy a slot, by any chance */
1998 for (hint = 0; hint < MAX_DEV_HINTS; hint++)
1999 if (device_hint[hint].pdev == pdev)
2000 device_hint[hint].pdev = NULL;
2001
2002 unlock_kernel();
2003}
2004
2005
2006/* *grunt* We have to do atoi ourselves :-( */
2007static int pwc_atoi(const char *s)
2008{
2009 int k = 0;
2010
2011 k = 0;
2012 while (*s != '\0' && *s >= '0' && *s <= '9') {
2013 k = 10 * k + (*s - '0');
2014 s++;
2015 }
2016 return k;
2017}
2018
2019
2020/*
2021 * Initialization code & module stuff
2022 */
2023
2024static char size[10];
2025static int fps = 0;
2026static int fbufs = 0;
2027static int mbufs = 0;
2028static int trace = -1;
2029static int compression = -1;
2030static int leds[2] = { -1, -1 };
2031static char *dev_hint[MAX_DEV_HINTS] = { };
2032
2033module_param_string(size, size, sizeof(size), 0);
2034MODULE_PARM_DESC(size, "Initial image size. One of sqcif, qsif, qcif, sif, cif, vga");
2035module_param(fps, int, 0000);
2036MODULE_PARM_DESC(fps, "Initial frames per second. Varies with model, useful range 5-30");
2037module_param(fbufs, int, 0000);
2038MODULE_PARM_DESC(fbufs, "Number of internal frame buffers to reserve");
2039module_param(mbufs, int, 0000);
2040MODULE_PARM_DESC(mbufs, "Number of external (mmap()ed) image buffers");
2041module_param(trace, int, 0000);
2042MODULE_PARM_DESC(trace, "For debugging purposes");
2043module_param(power_save, bool, 0000);
2044MODULE_PARM_DESC(power_save, "Turn power save feature in camera on or off");
2045module_param(compression, int, 0000);
2046MODULE_PARM_DESC(compression, "Preferred compression quality. Range 0 (uncompressed) to 3 (high compression)");
2047module_param_array(leds, int, NULL, 0000);
2048MODULE_PARM_DESC(leds, "LED on,off time in milliseconds");
2049module_param_array(dev_hint, charp, NULL, 0000);
2050MODULE_PARM_DESC(dev_hint, "Device node hints");
2051
2052MODULE_DESCRIPTION("Philips & OEM USB webcam driver");
2053MODULE_AUTHOR("Luc Saillard <luc@saillard.org>");
2054MODULE_LICENSE("GPL");
2055
2056static int __init usb_pwc_init(void)
2057{
2058 int i, sz;
2059 char *sizenames[PSZ_MAX] = { "sqcif", "qsif", "qcif", "sif", "cif", "vga" };
2060
2061 Info("Philips webcam module version " PWC_VERSION " loaded.\n");
2062 Info("Supports Philips PCA645/646, PCVC675/680/690, PCVC720[40]/730/740/750 & PCVC830/840.\n");
2063 Info("Also supports the Askey VC010, various Logitech Quickcams, Samsung MPC-C10 and MPC-C30,\n");
2064 Info("the Creative WebCam 5 & Pro Ex, SOTEC Afina Eye and Visionite VCS-UC300 and VCS-UM100.\n");
2065
2066 if (fps) {
2067 if (fps < 4 || fps > 30) {
2068 Err("Framerate out of bounds (4-30).\n");
2069 return -EINVAL;
2070 }
2071 default_fps = fps;
2072 Info("Default framerate set to %d.\n", default_fps);
2073 }
2074
2075 if (size[0]) {
2076 /* string; try matching with array */
2077 for (sz = 0; sz < PSZ_MAX; sz++) {
2078 if (!strcmp(sizenames[sz], size)) { /* Found! */
2079 default_size = sz;
2080 break;
2081 }
2082 }
2083 if (sz == PSZ_MAX) {
2084 Err("Size not recognized; try size=[sqcif | qsif | qcif | sif | cif | vga].\n");
2085 return -EINVAL;
2086 }
2087 Info("Default image size set to %s [%dx%d].\n", sizenames[default_size], pwc_image_sizes[default_size].x, pwc_image_sizes[default_size].y);
2088 }
2089 if (mbufs) {
2090 if (mbufs < 1 || mbufs > MAX_IMAGES) {
2091 Err("Illegal number of mmap() buffers; use a number between 1 and %d.\n", MAX_IMAGES);
2092 return -EINVAL;
2093 }
2094 default_mbufs = mbufs;
2095 Info("Number of image buffers set to %d.\n", default_mbufs);
2096 }
2097 if (fbufs) {
2098 if (fbufs < 2 || fbufs > MAX_FRAMES) {
2099 Err("Illegal number of frame buffers; use a number between 2 and %d.\n", MAX_FRAMES);
2100 return -EINVAL;
2101 }
2102 default_fbufs = fbufs;
2103 Info("Number of frame buffers set to %d.\n", default_fbufs);
2104 }
2105 if (trace >= 0) {
2106 Info("Trace options: 0x%04x\n", trace);
2107 pwc_trace = trace;
2108 }
2109 if (compression >= 0) {
2110 if (compression > 3) {
2111 Err("Invalid compression setting; use a number between 0 (uncompressed) and 3 (high).\n");
2112 return -EINVAL;
2113 }
2114 pwc_preferred_compression = compression;
2115 Info("Preferred compression set to %d.\n", pwc_preferred_compression);
2116 }
2117 if (power_save)
2118 Info("Enabling power save on open/close.\n");
2119 if (leds[0] >= 0)
2120 led_on = leds[0];
2121 if (leds[1] >= 0)
2122 led_off = leds[1];
2123
2124 /* Big device node whoopla. Basically, it allows you to assign a
2125 device node (/dev/videoX) to a camera, based on its type
2126 & serial number. The format is [type[.serialnumber]:]node.
2127
2128 Any camera that isn't matched by these rules gets the next
2129 available free device node.
2130 */
2131 for (i = 0; i < MAX_DEV_HINTS; i++) {
2132 char *s, *colon, *dot;
2133
2134 /* This loop also initializes the array */
2135 device_hint[i].pdev = NULL;
2136 s = dev_hint[i];
2137 if (s != NULL && *s != '\0') {
2138 device_hint[i].type = -1; /* wildcard */
2139 strcpy(device_hint[i].serial_number, "*");
2140
2141 /* parse string: chop at ':' & '/' */
2142 colon = dot = s;
2143 while (*colon != '\0' && *colon != ':')
2144 colon++;
2145 while (*dot != '\0' && *dot != '.')
2146 dot++;
2147 /* Few sanity checks */
2148 if (*dot != '\0' && dot > colon) {
2149 Err("Malformed camera hint: the colon must be after the dot.\n");
2150 return -EINVAL;
2151 }
2152
2153 if (*colon == '\0') {
2154 /* No colon */
2155 if (*dot != '\0') {
2156 Err("Malformed camera hint: no colon + device node given.\n");
2157 return -EINVAL;
2158 }
2159 else {
2160 /* No type or serial number specified, just a number. */
2161 device_hint[i].device_node = pwc_atoi(s);
2162 }
2163 }
2164 else {
2165 /* There's a colon, so we have at least a type and a device node */
2166 device_hint[i].type = pwc_atoi(s);
2167 device_hint[i].device_node = pwc_atoi(colon + 1);
2168 if (*dot != '\0') {
2169 /* There's a serial number as well */
2170 int k;
2171
2172 dot++;
2173 k = 0;
2174 while (*dot != ':' && k < 29) {
2175 device_hint[i].serial_number[k++] = *dot;
2176 dot++;
2177 }
2178 device_hint[i].serial_number[k] = '\0';
2179 }
2180 }
2181#if PWC_DEBUG
2182 Debug("device_hint[%d]:\n", i);
2183 Debug(" type : %d\n", device_hint[i].type);
2184 Debug(" serial# : %s\n", device_hint[i].serial_number);
2185 Debug(" node : %d\n", device_hint[i].device_node);
2186#endif
2187 }
2188 else
2189 device_hint[i].type = 0; /* not filled */
2190 } /* ..for MAX_DEV_HINTS */
2191
2192 Trace(TRACE_PROBE, "Registering driver at address 0x%p.\n", &pwc_driver);
2193 return usb_register(&pwc_driver);
2194}
2195
2196static void __exit usb_pwc_exit(void)
2197{
2198 Trace(TRACE_MODULE, "Deregistering driver.\n");
2199 usb_deregister(&pwc_driver);
2200 Info("Philips webcam module removed.\n");
2201}
2202
2203module_init(usb_pwc_init);
2204module_exit(usb_pwc_exit);
2205
diff --git a/drivers/media/video/pwc/pwc-ioctl.h b/drivers/media/video/pwc/pwc-ioctl.h
new file mode 100644
index 000000000000..5f9cb08bc02e
--- /dev/null
+++ b/drivers/media/video/pwc/pwc-ioctl.h
@@ -0,0 +1,292 @@
1#ifndef PWC_IOCTL_H
2#define PWC_IOCTL_H
3
4/* (C) 2001-2004 Nemosoft Unv.
5 (C) 2004 Luc Saillard (luc@saillard.org)
6
7 NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx
8 driver and thus may have bugs that are not present in the original version.
9 Please send bug reports and support requests to <luc@saillard.org>.
10 The decompression routines have been implemented by reverse-engineering the
11 Nemosoft binary pwcx module. Caveat emptor.
12
13 This program is free software; you can redistribute it and/or modify
14 it under the terms of the GNU General Public License as published by
15 the Free Software Foundation; either version 2 of the License, or
16 (at your option) any later version.
17
18 This program is distributed in the hope that it will be useful,
19 but WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 GNU General Public License for more details.
22
23 You should have received a copy of the GNU General Public License
24 along with this program; if not, write to the Free Software
25 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26*/
27
28/* This is pwc-ioctl.h belonging to PWC 8.12.1
29 It contains structures and defines to communicate from user space
30 directly to the driver.
31 */
32
33/*
34 Changes
35 2001/08/03 Alvarado Added ioctl constants to access methods for
36 changing white balance and red/blue gains
37 2002/12/15 G. H. Fernandez-Toribio VIDIOCGREALSIZE
38 2003/12/13 Nemosft Unv. Some modifications to make interfacing to
39 PWCX easier
40 */
41
42/* These are private ioctl() commands, specific for the Philips webcams.
43 They contain functions not found in other webcams, and settings not
44 specified in the Video4Linux API.
45
46 The #define names are built up like follows:
47 VIDIOC VIDeo IOCtl prefix
48 PWC Philps WebCam
49 G optional: Get
50 S optional: Set
51 ... the function
52 */
53
54
55 /* Enumeration of image sizes */
56#define PSZ_SQCIF 0x00
57#define PSZ_QSIF 0x01
58#define PSZ_QCIF 0x02
59#define PSZ_SIF 0x03
60#define PSZ_CIF 0x04
61#define PSZ_VGA 0x05
62#define PSZ_MAX 6
63
64
65/* The frame rate is encoded in the video_window.flags parameter using
66 the upper 16 bits, since some flags are defined nowadays. The following
67 defines provide a mask and shift to filter out this value.
68
69 In 'Snapshot' mode the camera freezes its automatic exposure and colour
70 balance controls.
71 */
72#define PWC_FPS_SHIFT 16
73#define PWC_FPS_MASK 0x00FF0000
74#define PWC_FPS_FRMASK 0x003F0000
75#define PWC_FPS_SNAPSHOT 0x00400000
76
77
78/* structure for transferring x & y coordinates */
79struct pwc_coord
80{
81 int x, y; /* guess what */
82 int size; /* size, or offset */
83};
84
85
86/* Used with VIDIOCPWCPROBE */
87struct pwc_probe
88{
89 char name[32];
90 int type;
91};
92
93struct pwc_serial
94{
95 char serial[30]; /* String with serial number. Contains terminating 0 */
96};
97
98/* pwc_whitebalance.mode values */
99#define PWC_WB_INDOOR 0
100#define PWC_WB_OUTDOOR 1
101#define PWC_WB_FL 2
102#define PWC_WB_MANUAL 3
103#define PWC_WB_AUTO 4
104
105/* Used with VIDIOCPWC[SG]AWB (Auto White Balance).
106 Set mode to one of the PWC_WB_* values above.
107 *red and *blue are the respective gains of these colour components inside
108 the camera; range 0..65535
109 When 'mode' == PWC_WB_MANUAL, 'manual_red' and 'manual_blue' are set or read;
110 otherwise undefined.
111 'read_red' and 'read_blue' are read-only.
112*/
113struct pwc_whitebalance
114{
115 int mode;
116 int manual_red, manual_blue; /* R/W */
117 int read_red, read_blue; /* R/O */
118};
119
120/*
121 'control_speed' and 'control_delay' are used in automatic whitebalance mode,
122 and tell the camera how fast it should react to changes in lighting, and
123 with how much delay. Valid values are 0..65535.
124*/
125struct pwc_wb_speed
126{
127 int control_speed;
128 int control_delay;
129
130};
131
132/* Used with VIDIOCPWC[SG]LED */
133struct pwc_leds
134{
135 int led_on; /* Led on-time; range = 0..25000 */
136 int led_off; /* Led off-time; range = 0..25000 */
137};
138
139/* Image size (used with GREALSIZE) */
140struct pwc_imagesize
141{
142 int width;
143 int height;
144};
145
146/* Defines and structures for Motorized Pan & Tilt */
147#define PWC_MPT_PAN 0x01
148#define PWC_MPT_TILT 0x02
149#define PWC_MPT_TIMEOUT 0x04 /* for status */
150
151/* Set angles; when absolute != 0, the angle is absolute and the
152 driver calculates the relative offset for you. This can only
153 be used with VIDIOCPWCSANGLE; VIDIOCPWCGANGLE always returns
154 absolute angles.
155 */
156struct pwc_mpt_angles
157{
158 int absolute; /* write-only */
159 int pan; /* degrees * 100 */
160 int tilt; /* degress * 100 */
161};
162
163/* Range of angles of the camera, both horizontally and vertically.
164 */
165struct pwc_mpt_range
166{
167 int pan_min, pan_max; /* degrees * 100 */
168 int tilt_min, tilt_max;
169};
170
171struct pwc_mpt_status
172{
173 int status;
174 int time_pan;
175 int time_tilt;
176};
177
178
179/* This is used for out-of-kernel decompression. With it, you can get
180 all the necessary information to initialize and use the decompressor
181 routines in standalone applications.
182 */
183struct pwc_video_command
184{
185 int type; /* camera type (645, 675, 730, etc.) */
186 int release; /* release number */
187
188 int size; /* one of PSZ_* */
189 int alternate;
190 int command_len; /* length of USB video command */
191 unsigned char command_buf[13]; /* Actual USB video command */
192 int bandlength; /* >0 = compressed */
193 int frame_size; /* Size of one (un)compressed frame */
194};
195
196/* Flags for PWCX subroutines. Not all modules honour all flags. */
197#define PWCX_FLAG_PLANAR 0x0001
198#define PWCX_FLAG_BAYER 0x0008
199
200
201/* IOCTL definitions */
202
203 /* Restore user settings */
204#define VIDIOCPWCRUSER _IO('v', 192)
205 /* Save user settings */
206#define VIDIOCPWCSUSER _IO('v', 193)
207 /* Restore factory settings */
208#define VIDIOCPWCFACTORY _IO('v', 194)
209
210 /* You can manipulate the compression factor. A compression preference of 0
211 means use uncompressed modes when available; 1 is low compression, 2 is
212 medium and 3 is high compression preferred. Of course, the higher the
213 compression, the lower the bandwidth used but more chance of artefacts
214 in the image. The driver automatically chooses a higher compression when
215 the preferred mode is not available.
216 */
217 /* Set preferred compression quality (0 = uncompressed, 3 = highest compression) */
218#define VIDIOCPWCSCQUAL _IOW('v', 195, int)
219 /* Get preferred compression quality */
220#define VIDIOCPWCGCQUAL _IOR('v', 195, int)
221
222
223/* Retrieve serial number of camera */
224#define VIDIOCPWCGSERIAL _IOR('v', 198, struct pwc_serial)
225
226 /* This is a probe function; since so many devices are supported, it
227 becomes difficult to include all the names in programs that want to
228 check for the enhanced Philips stuff. So in stead, try this PROBE;
229 it returns a structure with the original name, and the corresponding
230 Philips type.
231 To use, fill the structure with zeroes, call PROBE and if that succeeds,
232 compare the name with that returned from VIDIOCGCAP; they should be the
233 same. If so, you can be assured it is a Philips (OEM) cam and the type
234 is valid.
235 */
236#define VIDIOCPWCPROBE _IOR('v', 199, struct pwc_probe)
237
238 /* Set AGC (Automatic Gain Control); int < 0 = auto, 0..65535 = fixed */
239#define VIDIOCPWCSAGC _IOW('v', 200, int)
240 /* Get AGC; int < 0 = auto; >= 0 = fixed, range 0..65535 */
241#define VIDIOCPWCGAGC _IOR('v', 200, int)
242 /* Set shutter speed; int < 0 = auto; >= 0 = fixed, range 0..65535 */
243#define VIDIOCPWCSSHUTTER _IOW('v', 201, int)
244
245 /* Color compensation (Auto White Balance) */
246#define VIDIOCPWCSAWB _IOW('v', 202, struct pwc_whitebalance)
247#define VIDIOCPWCGAWB _IOR('v', 202, struct pwc_whitebalance)
248
249 /* Auto WB speed */
250#define VIDIOCPWCSAWBSPEED _IOW('v', 203, struct pwc_wb_speed)
251#define VIDIOCPWCGAWBSPEED _IOR('v', 203, struct pwc_wb_speed)
252
253 /* LEDs on/off/blink; int range 0..65535 */
254#define VIDIOCPWCSLED _IOW('v', 205, struct pwc_leds)
255#define VIDIOCPWCGLED _IOR('v', 205, struct pwc_leds)
256
257 /* Contour (sharpness); int < 0 = auto, 0..65536 = fixed */
258#define VIDIOCPWCSCONTOUR _IOW('v', 206, int)
259#define VIDIOCPWCGCONTOUR _IOR('v', 206, int)
260
261 /* Backlight compensation; 0 = off, otherwise on */
262#define VIDIOCPWCSBACKLIGHT _IOW('v', 207, int)
263#define VIDIOCPWCGBACKLIGHT _IOR('v', 207, int)
264
265 /* Flickerless mode; = 0 off, otherwise on */
266#define VIDIOCPWCSFLICKER _IOW('v', 208, int)
267#define VIDIOCPWCGFLICKER _IOR('v', 208, int)
268
269 /* Dynamic noise reduction; 0 off, 3 = high noise reduction */
270#define VIDIOCPWCSDYNNOISE _IOW('v', 209, int)
271#define VIDIOCPWCGDYNNOISE _IOR('v', 209, int)
272
273 /* Real image size as used by the camera; tells you whether or not there's a gray border around the image */
274#define VIDIOCPWCGREALSIZE _IOR('v', 210, struct pwc_imagesize)
275
276 /* Motorized pan & tilt functions */
277#define VIDIOCPWCMPTRESET _IOW('v', 211, int)
278#define VIDIOCPWCMPTGRANGE _IOR('v', 211, struct pwc_mpt_range)
279#define VIDIOCPWCMPTSANGLE _IOW('v', 212, struct pwc_mpt_angles)
280#define VIDIOCPWCMPTGANGLE _IOR('v', 212, struct pwc_mpt_angles)
281#define VIDIOCPWCMPTSTATUS _IOR('v', 213, struct pwc_mpt_status)
282
283 /* Get the USB set-video command; needed for initializing libpwcx */
284#define VIDIOCPWCGVIDCMD _IOR('v', 215, struct pwc_video_command)
285struct pwc_table_init_buffer {
286 int len;
287 char *buffer;
288
289};
290#define VIDIOCPWCGVIDTABLE _IOR('v', 216, struct pwc_table_init_buffer)
291
292#endif
diff --git a/drivers/media/video/pwc/pwc-kiara.c b/drivers/media/video/pwc/pwc-kiara.c
new file mode 100644
index 000000000000..c498c68bace1
--- /dev/null
+++ b/drivers/media/video/pwc/pwc-kiara.c
@@ -0,0 +1,318 @@
1/* Linux driver for Philips webcam
2 (C) 2004 Luc Saillard (luc@saillard.org)
3
4 NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx
5 driver and thus may have bugs that are not present in the original version.
6 Please send bug reports and support requests to <luc@saillard.org>.
7 The decompression routines have been implemented by reverse-engineering the
8 Nemosoft binary pwcx module. Caveat emptor.
9
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2 of the License, or
13 (at your option) any later version.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23*/
24
25
26/* This tables contains entries for the 730/740/750 (Kiara) camera, with
27 4 different qualities (no compression, low, medium, high).
28 It lists the bandwidth requirements for said mode by its alternate interface
29 number. An alternate of 0 means that the mode is unavailable.
30
31 There are 6 * 4 * 4 entries:
32 6 different resolutions subqcif, qsif, qcif, sif, cif, vga
33 6 framerates: 5, 10, 15, 20, 25, 30
34 4 compression modi: none, low, medium, high
35
36 When an uncompressed mode is not available, the next available compressed mode
37 will be chosen (unless the decompressor is absent). Sometimes there are only
38 1 or 2 compressed modes available; in that case entries are duplicated.
39*/
40
41
42#include "pwc-kiara.h"
43#include "pwc-uncompress.h"
44
45const struct Kiara_table_entry Kiara_table[PSZ_MAX][6][4] =
46{
47 /* SQCIF */
48 {
49 /* 5 fps */
50 {
51 {0, },
52 {0, },
53 {0, },
54 {0, },
55 },
56 /* 10 fps */
57 {
58 {0, },
59 {0, },
60 {0, },
61 {0, },
62 },
63 /* 15 fps */
64 {
65 {0, },
66 {0, },
67 {0, },
68 {0, },
69 },
70 /* 20 fps */
71 {
72 {0, },
73 {0, },
74 {0, },
75 {0, },
76 },
77 /* 25 fps */
78 {
79 {0, },
80 {0, },
81 {0, },
82 {0, },
83 },
84 /* 30 fps */
85 {
86 {0, },
87 {0, },
88 {0, },
89 {0, },
90 },
91 },
92 /* QSIF */
93 {
94 /* 5 fps */
95 {
96 {1, 146, 0, {0x1D, 0xF4, 0x30, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x92, 0x00, 0x80}},
97 {1, 146, 0, {0x1D, 0xF4, 0x30, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x92, 0x00, 0x80}},
98 {1, 146, 0, {0x1D, 0xF4, 0x30, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x92, 0x00, 0x80}},
99 {1, 146, 0, {0x1D, 0xF4, 0x30, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x92, 0x00, 0x80}},
100 },
101 /* 10 fps */
102 {
103 {2, 291, 0, {0x1C, 0xF4, 0x30, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x23, 0x01, 0x80}},
104 {1, 192, 630, {0x14, 0xF4, 0x30, 0x13, 0xA9, 0x12, 0xE1, 0x17, 0x08, 0xC0, 0x00, 0x80}},
105 {1, 192, 630, {0x14, 0xF4, 0x30, 0x13, 0xA9, 0x12, 0xE1, 0x17, 0x08, 0xC0, 0x00, 0x80}},
106 {1, 192, 630, {0x14, 0xF4, 0x30, 0x13, 0xA9, 0x12, 0xE1, 0x17, 0x08, 0xC0, 0x00, 0x80}},
107 },
108 /* 15 fps */
109 {
110 {3, 437, 0, {0x1B, 0xF4, 0x30, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0xB5, 0x01, 0x80}},
111 {2, 292, 640, {0x13, 0xF4, 0x30, 0x13, 0xF7, 0x13, 0x2F, 0x13, 0x20, 0x24, 0x01, 0x80}},
112 {2, 292, 640, {0x13, 0xF4, 0x30, 0x13, 0xF7, 0x13, 0x2F, 0x13, 0x20, 0x24, 0x01, 0x80}},
113 {1, 192, 420, {0x13, 0xF4, 0x30, 0x0D, 0x1B, 0x0C, 0x53, 0x1E, 0x18, 0xC0, 0x00, 0x80}},
114 },
115 /* 20 fps */
116 {
117 {4, 589, 0, {0x1A, 0xF4, 0x30, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x4D, 0x02, 0x80}},
118 {3, 448, 730, {0x12, 0xF4, 0x30, 0x16, 0xC9, 0x16, 0x01, 0x0E, 0x18, 0xC0, 0x01, 0x80}},
119 {2, 292, 476, {0x12, 0xF4, 0x30, 0x0E, 0xD8, 0x0E, 0x10, 0x19, 0x18, 0x24, 0x01, 0x80}},
120 {1, 192, 312, {0x12, 0xF4, 0x50, 0x09, 0xB3, 0x08, 0xEB, 0x1E, 0x18, 0xC0, 0x00, 0x80}},
121 },
122 /* 25 fps */
123 {
124 {5, 703, 0, {0x19, 0xF4, 0x30, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0xBF, 0x02, 0x80}},
125 {3, 447, 610, {0x11, 0xF4, 0x30, 0x13, 0x0B, 0x12, 0x43, 0x14, 0x28, 0xBF, 0x01, 0x80}},
126 {2, 292, 398, {0x11, 0xF4, 0x50, 0x0C, 0x6C, 0x0B, 0xA4, 0x1E, 0x28, 0x24, 0x01, 0x80}},
127 {1, 193, 262, {0x11, 0xF4, 0x50, 0x08, 0x23, 0x07, 0x5B, 0x1E, 0x28, 0xC1, 0x00, 0x80}},
128 },
129 /* 30 fps */
130 {
131 {8, 874, 0, {0x18, 0xF4, 0x30, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x6A, 0x03, 0x80}},
132 {5, 704, 730, {0x10, 0xF4, 0x30, 0x16, 0xC9, 0x16, 0x01, 0x0E, 0x28, 0xC0, 0x02, 0x80}},
133 {3, 448, 492, {0x10, 0xF4, 0x30, 0x0F, 0x5D, 0x0E, 0x95, 0x15, 0x28, 0xC0, 0x01, 0x80}},
134 {2, 292, 320, {0x10, 0xF4, 0x50, 0x09, 0xFB, 0x09, 0x33, 0x1E, 0x28, 0x24, 0x01, 0x80}},
135 },
136 },
137 /* QCIF */
138 {
139 /* 5 fps */
140 {
141 {0, },
142 {0, },
143 {0, },
144 {0, },
145 },
146 /* 10 fps */
147 {
148 {0, },
149 {0, },
150 {0, },
151 {0, },
152 },
153 /* 15 fps */
154 {
155 {0, },
156 {0, },
157 {0, },
158 {0, },
159 },
160 /* 20 fps */
161 {
162 {0, },
163 {0, },
164 {0, },
165 {0, },
166 },
167 /* 25 fps */
168 {
169 {0, },
170 {0, },
171 {0, },
172 {0, },
173 },
174 /* 30 fps */
175 {
176 {0, },
177 {0, },
178 {0, },
179 {0, },
180 },
181 },
182 /* SIF */
183 {
184 /* 5 fps */
185 {
186 {4, 582, 0, {0x0D, 0xF4, 0x30, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x46, 0x02, 0x80}},
187 {3, 387, 1276, {0x05, 0xF4, 0x30, 0x27, 0xD8, 0x26, 0x48, 0x03, 0x10, 0x83, 0x01, 0x80}},
188 {2, 291, 960, {0x05, 0xF4, 0x30, 0x1D, 0xF2, 0x1C, 0x62, 0x04, 0x10, 0x23, 0x01, 0x80}},
189 {1, 191, 630, {0x05, 0xF4, 0x50, 0x13, 0xA9, 0x12, 0x19, 0x05, 0x18, 0xBF, 0x00, 0x80}},
190 },
191 /* 10 fps */
192 {
193 {0, },
194 {6, 775, 1278, {0x04, 0xF4, 0x30, 0x27, 0xE8, 0x26, 0x58, 0x05, 0x30, 0x07, 0x03, 0x80}},
195 {3, 447, 736, {0x04, 0xF4, 0x30, 0x16, 0xFB, 0x15, 0x6B, 0x05, 0x28, 0xBF, 0x01, 0x80}},
196 {2, 292, 480, {0x04, 0xF4, 0x70, 0x0E, 0xF9, 0x0D, 0x69, 0x09, 0x28, 0x24, 0x01, 0x80}},
197 },
198 /* 15 fps */
199 {
200 {0, },
201 {9, 955, 1050, {0x03, 0xF4, 0x30, 0x20, 0xCF, 0x1F, 0x3F, 0x06, 0x48, 0xBB, 0x03, 0x80}},
202 {4, 592, 650, {0x03, 0xF4, 0x30, 0x14, 0x44, 0x12, 0xB4, 0x08, 0x30, 0x50, 0x02, 0x80}},
203 {3, 448, 492, {0x03, 0xF4, 0x50, 0x0F, 0x52, 0x0D, 0xC2, 0x09, 0x38, 0xC0, 0x01, 0x80}},
204 },
205 /* 20 fps */
206 {
207 {0, },
208 {9, 958, 782, {0x02, 0xF4, 0x30, 0x18, 0x6A, 0x16, 0xDA, 0x0B, 0x58, 0xBE, 0x03, 0x80}},
209 {5, 703, 574, {0x02, 0xF4, 0x50, 0x11, 0xE7, 0x10, 0x57, 0x0B, 0x40, 0xBF, 0x02, 0x80}},
210 {3, 446, 364, {0x02, 0xF4, 0x90, 0x0B, 0x5C, 0x09, 0xCC, 0x0E, 0x38, 0xBE, 0x01, 0x80}},
211 },
212 /* 25 fps */
213 {
214 {0, },
215 {9, 958, 654, {0x01, 0xF4, 0x30, 0x14, 0x66, 0x12, 0xD6, 0x0B, 0x50, 0xBE, 0x03, 0x80}},
216 {6, 776, 530, {0x01, 0xF4, 0x50, 0x10, 0x8C, 0x0E, 0xFC, 0x0C, 0x48, 0x08, 0x03, 0x80}},
217 {4, 592, 404, {0x01, 0xF4, 0x70, 0x0C, 0x96, 0x0B, 0x06, 0x0B, 0x48, 0x50, 0x02, 0x80}},
218 },
219 /* 30 fps */
220 {
221 {0, },
222 {9, 957, 526, {0x00, 0xF4, 0x50, 0x10, 0x68, 0x0E, 0xD8, 0x0D, 0x58, 0xBD, 0x03, 0x80}},
223 {6, 775, 426, {0x00, 0xF4, 0x70, 0x0D, 0x48, 0x0B, 0xB8, 0x0F, 0x50, 0x07, 0x03, 0x80}},
224 {4, 590, 324, {0x00, 0x7A, 0x88, 0x0A, 0x1C, 0x08, 0xB4, 0x0E, 0x50, 0x4E, 0x02, 0x80}},
225 },
226 },
227 /* CIF */
228 {
229 /* 5 fps */
230 {
231 {0, },
232 {0, },
233 {0, },
234 {0, },
235 },
236 /* 10 fps */
237 {
238 {0, },
239 {0, },
240 {0, },
241 {0, },
242 },
243 /* 15 fps */
244 {
245 {0, },
246 {0, },
247 {0, },
248 {0, },
249 },
250 /* 20 fps */
251 {
252 {0, },
253 {0, },
254 {0, },
255 {0, },
256 },
257 /* 25 fps */
258 {
259 {0, },
260 {0, },
261 {0, },
262 {0, },
263 },
264 /* 30 fps */
265 {
266 {0, },
267 {0, },
268 {0, },
269 {0, },
270 },
271 },
272 /* VGA */
273 {
274 /* 5 fps */
275 {
276 {0, },
277 {6, 773, 1272, {0x25, 0xF4, 0x30, 0x27, 0xB6, 0x24, 0x96, 0x02, 0x30, 0x05, 0x03, 0x80}},
278 {4, 592, 976, {0x25, 0xF4, 0x50, 0x1E, 0x78, 0x1B, 0x58, 0x03, 0x30, 0x50, 0x02, 0x80}},
279 {3, 448, 738, {0x25, 0xF4, 0x90, 0x17, 0x0C, 0x13, 0xEC, 0x04, 0x30, 0xC0, 0x01, 0x80}},
280 },
281 /* 10 fps */
282 {
283 {0, },
284 {9, 956, 788, {0x24, 0xF4, 0x70, 0x18, 0x9C, 0x15, 0x7C, 0x03, 0x48, 0xBC, 0x03, 0x80}},
285 {6, 776, 640, {0x24, 0xF4, 0xB0, 0x13, 0xFC, 0x11, 0x2C, 0x04, 0x48, 0x08, 0x03, 0x80}},
286 {4, 592, 488, {0x24, 0x7A, 0xE8, 0x0F, 0x3C, 0x0C, 0x6C, 0x06, 0x48, 0x50, 0x02, 0x80}},
287 },
288 /* 15 fps */
289 {
290 {0, },
291 {9, 957, 526, {0x23, 0x7A, 0xE8, 0x10, 0x68, 0x0D, 0x98, 0x06, 0x58, 0xBD, 0x03, 0x80}},
292 {9, 957, 526, {0x23, 0x7A, 0xE8, 0x10, 0x68, 0x0D, 0x98, 0x06, 0x58, 0xBD, 0x03, 0x80}},
293 {8, 895, 492, {0x23, 0x7A, 0xE8, 0x0F, 0x5D, 0x0C, 0x8D, 0x06, 0x58, 0x7F, 0x03, 0x80}},
294 },
295 /* 20 fps */
296 {
297 {0, },
298 {0, },
299 {0, },
300 {0, },
301 },
302 /* 25 fps */
303 {
304 {0, },
305 {0, },
306 {0, },
307 {0, },
308 },
309 /* 30 fps */
310 {
311 {0, },
312 {0, },
313 {0, },
314 {0, },
315 },
316 },
317};
318
diff --git a/drivers/media/video/pwc/pwc-kiara.h b/drivers/media/video/pwc/pwc-kiara.h
new file mode 100644
index 000000000000..12929abbb1f0
--- /dev/null
+++ b/drivers/media/video/pwc/pwc-kiara.h
@@ -0,0 +1,45 @@
1/* Linux driver for Philips webcam
2 (C) 2004 Luc Saillard (luc@saillard.org)
3
4 NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx
5 driver and thus may have bugs that are not present in the original version.
6 Please send bug reports and support requests to <luc@saillard.org>.
7 The decompression routines have been implemented by reverse-engineering the
8 Nemosoft binary pwcx module. Caveat emptor.
9
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2 of the License, or
13 (at your option) any later version.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23*/
24
25/* Entries for the Kiara (730/740/750) camera */
26
27#ifndef PWC_KIARA_H
28#define PWC_KIARA_H
29
30#include "pwc-ioctl.h"
31
32struct Kiara_table_entry
33{
34 char alternate; /* USB alternate interface */
35 unsigned short packetsize; /* Normal packet size */
36 unsigned short bandlength; /* Bandlength when decompressing */
37 unsigned char mode[12]; /* precomputed mode settings for cam */
38};
39
40const extern struct Kiara_table_entry Kiara_table[PSZ_MAX][6][4];
41const extern unsigned int KiaraRomTable[8][2][16][8];
42
43#endif
44
45
diff --git a/drivers/media/video/pwc/pwc-misc.c b/drivers/media/video/pwc/pwc-misc.c
new file mode 100644
index 000000000000..b7a4bd3524c7
--- /dev/null
+++ b/drivers/media/video/pwc/pwc-misc.c
@@ -0,0 +1,140 @@
1/* Linux driver for Philips webcam
2 Various miscellaneous functions and tables.
3 (C) 1999-2003 Nemosoft Unv.
4 (C) 2004 Luc Saillard (luc@saillard.org)
5
6 NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx
7 driver and thus may have bugs that are not present in the original version.
8 Please send bug reports and support requests to <luc@saillard.org>.
9 The decompression routines have been implemented by reverse-engineering the
10 Nemosoft binary pwcx module. Caveat emptor.
11
12 This program is free software; you can redistribute it and/or modify
13 it under the terms of the GNU General Public License as published by
14 the Free Software Foundation; either version 2 of the License, or
15 (at your option) any later version.
16
17 This program is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 GNU General Public License for more details.
21
22 You should have received a copy of the GNU General Public License
23 along with this program; if not, write to the Free Software
24 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25*/
26
27#include <linux/slab.h>
28
29#include "pwc.h"
30
31struct pwc_coord pwc_image_sizes[PSZ_MAX] =
32{
33 { 128, 96, 0 },
34 { 160, 120, 0 },
35 { 176, 144, 0 },
36 { 320, 240, 0 },
37 { 352, 288, 0 },
38 { 640, 480, 0 },
39};
40
41/* x,y -> PSZ_ */
42int pwc_decode_size(struct pwc_device *pdev, int width, int height)
43{
44 int i, find;
45
46 /* Make sure we don't go beyond our max size.
47 NB: we have different limits for RAW and normal modes. In case
48 you don't have the decompressor loaded or use RAW mode,
49 the maximum viewable size is smaller.
50 */
51 if (pdev->vpalette == VIDEO_PALETTE_RAW)
52 {
53 if (width > pdev->abs_max.x || height > pdev->abs_max.y)
54 {
55 Debug("VIDEO_PALETTE_RAW: going beyond abs_max.\n");
56 return -1;
57 }
58 }
59 else
60 {
61 if (width > pdev->view_max.x || height > pdev->view_max.y)
62 {
63 Debug("VIDEO_PALETTE_ not RAW: going beyond view_max.\n");
64 return -1;
65 }
66 }
67
68 /* Find the largest size supported by the camera that fits into the
69 requested size.
70 */
71 find = -1;
72 for (i = 0; i < PSZ_MAX; i++) {
73 if (pdev->image_mask & (1 << i)) {
74 if (pwc_image_sizes[i].x <= width && pwc_image_sizes[i].y <= height)
75 find = i;
76 }
77 }
78 return find;
79}
80
81/* initialize variables depending on type and decompressor*/
82void pwc_construct(struct pwc_device *pdev)
83{
84 switch(pdev->type) {
85 case 645:
86 case 646:
87 pdev->view_min.x = 128;
88 pdev->view_min.y = 96;
89 pdev->view_max.x = 352;
90 pdev->view_max.y = 288;
91 pdev->abs_max.x = 352;
92 pdev->abs_max.y = 288;
93 pdev->image_mask = 1 << PSZ_SQCIF | 1 << PSZ_QCIF | 1 << PSZ_CIF;
94 pdev->vcinterface = 2;
95 pdev->vendpoint = 4;
96 pdev->frame_header_size = 0;
97 pdev->frame_trailer_size = 0;
98 break;
99 case 675:
100 case 680:
101 case 690:
102 pdev->view_min.x = 128;
103 pdev->view_min.y = 96;
104 /* Anthill bug #38: PWC always reports max size, even without PWCX */
105 pdev->view_max.x = 640;
106 pdev->view_max.y = 480;
107 pdev->image_mask = 1 << PSZ_SQCIF | 1 << PSZ_QSIF | 1 << PSZ_QCIF | 1 << PSZ_SIF | 1 << PSZ_CIF | 1 << PSZ_VGA;
108 pdev->abs_max.x = 640;
109 pdev->abs_max.y = 480;
110 pdev->vcinterface = 3;
111 pdev->vendpoint = 4;
112 pdev->frame_header_size = 0;
113 pdev->frame_trailer_size = 0;
114 break;
115 case 720:
116 case 730:
117 case 740:
118 case 750:
119 pdev->view_min.x = 160;
120 pdev->view_min.y = 120;
121 pdev->view_max.x = 640;
122 pdev->view_max.y = 480;
123 pdev->image_mask = 1 << PSZ_QSIF | 1 << PSZ_SIF | 1 << PSZ_VGA;
124 pdev->abs_max.x = 640;
125 pdev->abs_max.y = 480;
126 pdev->vcinterface = 3;
127 pdev->vendpoint = 5;
128 pdev->frame_header_size = TOUCAM_HEADER_SIZE;
129 pdev->frame_trailer_size = TOUCAM_TRAILER_SIZE;
130 break;
131 }
132 Debug("type = %d\n",pdev->type);
133 pdev->vpalette = VIDEO_PALETTE_YUV420P; /* default */
134 pdev->view_min.size = pdev->view_min.x * pdev->view_min.y;
135 pdev->view_max.size = pdev->view_max.x * pdev->view_max.y;
136 /* length of image, in YUV format; always allocate enough memory. */
137 pdev->len_per_image = (pdev->abs_max.x * pdev->abs_max.y * 3) / 2;
138}
139
140
diff --git a/drivers/media/video/pwc/pwc-nala.h b/drivers/media/video/pwc/pwc-nala.h
new file mode 100644
index 000000000000..e6c5cb69d03b
--- /dev/null
+++ b/drivers/media/video/pwc/pwc-nala.h
@@ -0,0 +1,66 @@
1 /* SQCIF */
2 {
3 {0, 0, {0x04, 0x01, 0x03}},
4 {8, 0, {0x05, 0x01, 0x03}},
5 {7, 0, {0x08, 0x01, 0x03}},
6 {7, 0, {0x0A, 0x01, 0x03}},
7 {6, 0, {0x0C, 0x01, 0x03}},
8 {5, 0, {0x0F, 0x01, 0x03}},
9 {4, 0, {0x14, 0x01, 0x03}},
10 {3, 0, {0x18, 0x01, 0x03}},
11 },
12 /* QSIF */
13 {
14 {0},
15 {0},
16 {0},
17 {0},
18 {0},
19 {0},
20 {0},
21 {0},
22 },
23 /* QCIF */
24 {
25 {0, 0, {0x04, 0x01, 0x02}},
26 {8, 0, {0x05, 0x01, 0x02}},
27 {7, 0, {0x08, 0x01, 0x02}},
28 {6, 0, {0x0A, 0x01, 0x02}},
29 {5, 0, {0x0C, 0x01, 0x02}},
30 {4, 0, {0x0F, 0x01, 0x02}},
31 {1, 0, {0x14, 0x01, 0x02}},
32 {1, 0, {0x18, 0x01, 0x02}},
33 },
34 /* SIF */
35 {
36 {0},
37 {0},
38 {0},
39 {0},
40 {0},
41 {0},
42 {0},
43 {0},
44 },
45 /* CIF */
46 {
47 {4, 0, {0x04, 0x01, 0x01}},
48 {7, 1, {0x05, 0x03, 0x01}},
49 {6, 1, {0x08, 0x03, 0x01}},
50 {4, 1, {0x0A, 0x03, 0x01}},
51 {3, 1, {0x0C, 0x03, 0x01}},
52 {2, 1, {0x0F, 0x03, 0x01}},
53 {0},
54 {0},
55 },
56 /* VGA */
57 {
58 {0},
59 {0},
60 {0},
61 {0},
62 {0},
63 {0},
64 {0},
65 {0},
66 },
diff --git a/drivers/media/video/pwc/pwc-timon.c b/drivers/media/video/pwc/pwc-timon.c
new file mode 100644
index 000000000000..dee967173d6c
--- /dev/null
+++ b/drivers/media/video/pwc/pwc-timon.c
@@ -0,0 +1,316 @@
1/* Linux driver for Philips webcam
2 (C) 2004 Luc Saillard (luc@saillard.org)
3
4 NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx
5 driver and thus may have bugs that are not present in the original version.
6 Please send bug reports and support requests to <luc@saillard.org>.
7 The decompression routines have been implemented by reverse-engineering the
8 Nemosoft binary pwcx module. Caveat emptor.
9
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2 of the License, or
13 (at your option) any later version.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23*/
24
25
26/* This tables contains entries for the 675/680/690 (Timon) camera, with
27 4 different qualities (no compression, low, medium, high).
28 It lists the bandwidth requirements for said mode by its alternate interface
29 number. An alternate of 0 means that the mode is unavailable.
30
31 There are 6 * 4 * 4 entries:
32 6 different resolutions subqcif, qsif, qcif, sif, cif, vga
33 6 framerates: 5, 10, 15, 20, 25, 30
34 4 compression modi: none, low, medium, high
35
36 When an uncompressed mode is not available, the next available compressed mode
37 will be chosen (unless the decompressor is absent). Sometimes there are only
38 1 or 2 compressed modes available; in that case entries are duplicated.
39*/
40
41#include "pwc-timon.h"
42
43const struct Timon_table_entry Timon_table[PSZ_MAX][6][4] =
44{
45 /* SQCIF */
46 {
47 /* 5 fps */
48 {
49 {1, 140, 0, {0x05, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x8C, 0xFC, 0x80, 0x02}},
50 {1, 140, 0, {0x05, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x8C, 0xFC, 0x80, 0x02}},
51 {1, 140, 0, {0x05, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x8C, 0xFC, 0x80, 0x02}},
52 {1, 140, 0, {0x05, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x8C, 0xFC, 0x80, 0x02}},
53 },
54 /* 10 fps */
55 {
56 {2, 280, 0, {0x04, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x18, 0xA9, 0x80, 0x02}},
57 {2, 280, 0, {0x04, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x18, 0xA9, 0x80, 0x02}},
58 {2, 280, 0, {0x04, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x18, 0xA9, 0x80, 0x02}},
59 {2, 280, 0, {0x04, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x18, 0xA9, 0x80, 0x02}},
60 },
61 /* 15 fps */
62 {
63 {3, 410, 0, {0x03, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x9A, 0x71, 0x80, 0x02}},
64 {3, 410, 0, {0x03, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x9A, 0x71, 0x80, 0x02}},
65 {3, 410, 0, {0x03, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x9A, 0x71, 0x80, 0x02}},
66 {3, 410, 0, {0x03, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x9A, 0x71, 0x80, 0x02}},
67 },
68 /* 20 fps */
69 {
70 {4, 559, 0, {0x02, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x2F, 0x56, 0x80, 0x02}},
71 {4, 559, 0, {0x02, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x2F, 0x56, 0x80, 0x02}},
72 {4, 559, 0, {0x02, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x2F, 0x56, 0x80, 0x02}},
73 {4, 559, 0, {0x02, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x2F, 0x56, 0x80, 0x02}},
74 },
75 /* 25 fps */
76 {
77 {5, 659, 0, {0x01, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x93, 0x46, 0x80, 0x02}},
78 {5, 659, 0, {0x01, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x93, 0x46, 0x80, 0x02}},
79 {5, 659, 0, {0x01, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x93, 0x46, 0x80, 0x02}},
80 {5, 659, 0, {0x01, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x93, 0x46, 0x80, 0x02}},
81 },
82 /* 30 fps */
83 {
84 {7, 838, 0, {0x00, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x46, 0x3B, 0x80, 0x02}},
85 {7, 838, 0, {0x00, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x46, 0x3B, 0x80, 0x02}},
86 {7, 838, 0, {0x00, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x46, 0x3B, 0x80, 0x02}},
87 {7, 838, 0, {0x00, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x46, 0x3B, 0x80, 0x02}},
88 },
89 },
90 /* QSIF */
91 {
92 /* 5 fps */
93 {
94 {1, 146, 0, {0x2D, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x92, 0xFC, 0xC0, 0x02}},
95 {1, 146, 0, {0x2D, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x92, 0xFC, 0xC0, 0x02}},
96 {1, 146, 0, {0x2D, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x92, 0xFC, 0xC0, 0x02}},
97 {1, 146, 0, {0x2D, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x92, 0xFC, 0xC0, 0x02}},
98 },
99 /* 10 fps */
100 {
101 {2, 291, 0, {0x2C, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x23, 0xA1, 0xC0, 0x02}},
102 {1, 191, 630, {0x2C, 0xF4, 0x05, 0x13, 0xA9, 0x12, 0xE1, 0x17, 0x08, 0xBF, 0xF4, 0xC0, 0x02}},
103 {1, 191, 630, {0x2C, 0xF4, 0x05, 0x13, 0xA9, 0x12, 0xE1, 0x17, 0x08, 0xBF, 0xF4, 0xC0, 0x02}},
104 {1, 191, 630, {0x2C, 0xF4, 0x05, 0x13, 0xA9, 0x12, 0xE1, 0x17, 0x08, 0xBF, 0xF4, 0xC0, 0x02}},
105 },
106 /* 15 fps */
107 {
108 {3, 437, 0, {0x2B, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0xB5, 0x6D, 0xC0, 0x02}},
109 {2, 291, 640, {0x2B, 0xF4, 0x05, 0x13, 0xF7, 0x13, 0x2F, 0x13, 0x08, 0x23, 0xA1, 0xC0, 0x02}},
110 {2, 291, 640, {0x2B, 0xF4, 0x05, 0x13, 0xF7, 0x13, 0x2F, 0x13, 0x08, 0x23, 0xA1, 0xC0, 0x02}},
111 {1, 191, 420, {0x2B, 0xF4, 0x0D, 0x0D, 0x1B, 0x0C, 0x53, 0x1E, 0x08, 0xBF, 0xF4, 0xC0, 0x02}},
112 },
113 /* 20 fps */
114 {
115 {4, 588, 0, {0x2A, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x4C, 0x52, 0xC0, 0x02}},
116 {3, 447, 730, {0x2A, 0xF4, 0x05, 0x16, 0xC9, 0x16, 0x01, 0x0E, 0x18, 0xBF, 0x69, 0xC0, 0x02}},
117 {2, 292, 476, {0x2A, 0xF4, 0x0D, 0x0E, 0xD8, 0x0E, 0x10, 0x19, 0x18, 0x24, 0xA1, 0xC0, 0x02}},
118 {1, 192, 312, {0x2A, 0xF4, 0x1D, 0x09, 0xB3, 0x08, 0xEB, 0x1E, 0x18, 0xC0, 0xF4, 0xC0, 0x02}},
119 },
120 /* 25 fps */
121 {
122 {5, 703, 0, {0x29, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0xBF, 0x42, 0xC0, 0x02}},
123 {3, 447, 610, {0x29, 0xF4, 0x05, 0x13, 0x0B, 0x12, 0x43, 0x14, 0x18, 0xBF, 0x69, 0xC0, 0x02}},
124 {2, 292, 398, {0x29, 0xF4, 0x0D, 0x0C, 0x6C, 0x0B, 0xA4, 0x1E, 0x18, 0x24, 0xA1, 0xC0, 0x02}},
125 {1, 192, 262, {0x29, 0xF4, 0x25, 0x08, 0x23, 0x07, 0x5B, 0x1E, 0x18, 0xC0, 0xF4, 0xC0, 0x02}},
126 },
127 /* 30 fps */
128 {
129 {8, 873, 0, {0x28, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x69, 0x37, 0xC0, 0x02}},
130 {5, 704, 774, {0x28, 0xF4, 0x05, 0x18, 0x21, 0x17, 0x59, 0x0F, 0x18, 0xC0, 0x42, 0xC0, 0x02}},
131 {3, 448, 492, {0x28, 0xF4, 0x05, 0x0F, 0x5D, 0x0E, 0x95, 0x15, 0x18, 0xC0, 0x69, 0xC0, 0x02}},
132 {2, 291, 320, {0x28, 0xF4, 0x1D, 0x09, 0xFB, 0x09, 0x33, 0x1E, 0x18, 0x23, 0xA1, 0xC0, 0x02}},
133 },
134 },
135 /* QCIF */
136 {
137 /* 5 fps */
138 {
139 {1, 193, 0, {0x0D, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0xC1, 0xF4, 0xC0, 0x02}},
140 {1, 193, 0, {0x0D, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0xC1, 0xF4, 0xC0, 0x02}},
141 {1, 193, 0, {0x0D, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0xC1, 0xF4, 0xC0, 0x02}},
142 {1, 193, 0, {0x0D, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0xC1, 0xF4, 0xC0, 0x02}},
143 },
144 /* 10 fps */
145 {
146 {3, 385, 0, {0x0C, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x81, 0x79, 0xC0, 0x02}},
147 {2, 291, 800, {0x0C, 0xF4, 0x05, 0x18, 0xF4, 0x18, 0x18, 0x11, 0x08, 0x23, 0xA1, 0xC0, 0x02}},
148 {2, 291, 800, {0x0C, 0xF4, 0x05, 0x18, 0xF4, 0x18, 0x18, 0x11, 0x08, 0x23, 0xA1, 0xC0, 0x02}},
149 {1, 194, 532, {0x0C, 0xF4, 0x05, 0x10, 0x9A, 0x0F, 0xBE, 0x1B, 0x08, 0xC2, 0xF0, 0xC0, 0x02}},
150 },
151 /* 15 fps */
152 {
153 {4, 577, 0, {0x0B, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x41, 0x52, 0xC0, 0x02}},
154 {3, 447, 818, {0x0B, 0xF4, 0x05, 0x19, 0x89, 0x18, 0xAD, 0x0F, 0x10, 0xBF, 0x69, 0xC0, 0x02}},
155 {2, 292, 534, {0x0B, 0xF4, 0x05, 0x10, 0xA3, 0x0F, 0xC7, 0x19, 0x10, 0x24, 0xA1, 0xC0, 0x02}},
156 {1, 195, 356, {0x0B, 0xF4, 0x15, 0x0B, 0x11, 0x0A, 0x35, 0x1E, 0x10, 0xC3, 0xF0, 0xC0, 0x02}},
157 },
158 /* 20 fps */
159 {
160 {6, 776, 0, {0x0A, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x08, 0x3F, 0xC0, 0x02}},
161 {4, 591, 804, {0x0A, 0xF4, 0x05, 0x19, 0x1E, 0x18, 0x42, 0x0F, 0x18, 0x4F, 0x4E, 0xC0, 0x02}},
162 {3, 447, 608, {0x0A, 0xF4, 0x05, 0x12, 0xFD, 0x12, 0x21, 0x15, 0x18, 0xBF, 0x69, 0xC0, 0x02}},
163 {2, 291, 396, {0x0A, 0xF4, 0x15, 0x0C, 0x5E, 0x0B, 0x82, 0x1E, 0x18, 0x23, 0xA1, 0xC0, 0x02}},
164 },
165 /* 25 fps */
166 {
167 {9, 928, 0, {0x09, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0xA0, 0x33, 0xC0, 0x02}},
168 {5, 703, 800, {0x09, 0xF4, 0x05, 0x18, 0xF4, 0x18, 0x18, 0x10, 0x18, 0xBF, 0x42, 0xC0, 0x02}},
169 {3, 447, 508, {0x09, 0xF4, 0x0D, 0x0F, 0xD2, 0x0E, 0xF6, 0x1B, 0x18, 0xBF, 0x69, 0xC0, 0x02}},
170 {2, 292, 332, {0x09, 0xF4, 0x1D, 0x0A, 0x5A, 0x09, 0x7E, 0x1E, 0x18, 0x24, 0xA1, 0xC0, 0x02}},
171 },
172 /* 30 fps */
173 {
174 {0, },
175 {9, 956, 876, {0x08, 0xF4, 0x05, 0x1B, 0x58, 0x1A, 0x7C, 0x0E, 0x20, 0xBC, 0x33, 0x10, 0x02}},
176 {4, 592, 542, {0x08, 0xF4, 0x05, 0x10, 0xE4, 0x10, 0x08, 0x17, 0x20, 0x50, 0x4E, 0x10, 0x02}},
177 {2, 291, 266, {0x08, 0xF4, 0x25, 0x08, 0x48, 0x07, 0x6C, 0x1E, 0x20, 0x23, 0xA1, 0x10, 0x02}},
178 },
179 },
180 /* SIF */
181 {
182 /* 5 fps */
183 {
184 {4, 582, 0, {0x35, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x46, 0x52, 0x60, 0x02}},
185 {3, 387, 1276, {0x35, 0xF4, 0x05, 0x27, 0xD8, 0x26, 0x48, 0x03, 0x10, 0x83, 0x79, 0x60, 0x02}},
186 {2, 291, 960, {0x35, 0xF4, 0x0D, 0x1D, 0xF2, 0x1C, 0x62, 0x04, 0x10, 0x23, 0xA1, 0x60, 0x02}},
187 {1, 191, 630, {0x35, 0xF4, 0x1D, 0x13, 0xA9, 0x12, 0x19, 0x05, 0x08, 0xBF, 0xF4, 0x60, 0x02}},
188 },
189 /* 10 fps */
190 {
191 {0, },
192 {6, 775, 1278, {0x34, 0xF4, 0x05, 0x27, 0xE8, 0x26, 0x58, 0x05, 0x30, 0x07, 0x3F, 0x10, 0x02}},
193 {3, 447, 736, {0x34, 0xF4, 0x15, 0x16, 0xFB, 0x15, 0x6B, 0x05, 0x18, 0xBF, 0x69, 0x10, 0x02}},
194 {2, 291, 480, {0x34, 0xF4, 0x2D, 0x0E, 0xF9, 0x0D, 0x69, 0x09, 0x18, 0x23, 0xA1, 0x10, 0x02}},
195 },
196 /* 15 fps */
197 {
198 {0, },
199 {9, 955, 1050, {0x33, 0xF4, 0x05, 0x20, 0xCF, 0x1F, 0x3F, 0x06, 0x48, 0xBB, 0x33, 0x10, 0x02}},
200 {4, 591, 650, {0x33, 0xF4, 0x15, 0x14, 0x44, 0x12, 0xB4, 0x08, 0x30, 0x4F, 0x4E, 0x10, 0x02}},
201 {3, 448, 492, {0x33, 0xF4, 0x25, 0x0F, 0x52, 0x0D, 0xC2, 0x09, 0x28, 0xC0, 0x69, 0x10, 0x02}},
202 },
203 /* 20 fps */
204 {
205 {0, },
206 {9, 958, 782, {0x32, 0xF4, 0x0D, 0x18, 0x6A, 0x16, 0xDA, 0x0B, 0x58, 0xBE, 0x33, 0xD0, 0x02}},
207 {5, 703, 574, {0x32, 0xF4, 0x1D, 0x11, 0xE7, 0x10, 0x57, 0x0B, 0x40, 0xBF, 0x42, 0xD0, 0x02}},
208 {3, 446, 364, {0x32, 0xF4, 0x3D, 0x0B, 0x5C, 0x09, 0xCC, 0x0E, 0x30, 0xBE, 0x69, 0xD0, 0x02}},
209 },
210 /* 25 fps */
211 {
212 {0, },
213 {9, 958, 654, {0x31, 0xF4, 0x15, 0x14, 0x66, 0x12, 0xD6, 0x0B, 0x50, 0xBE, 0x33, 0x90, 0x02}},
214 {6, 776, 530, {0x31, 0xF4, 0x25, 0x10, 0x8C, 0x0E, 0xFC, 0x0C, 0x48, 0x08, 0x3F, 0x90, 0x02}},
215 {4, 592, 404, {0x31, 0xF4, 0x35, 0x0C, 0x96, 0x0B, 0x06, 0x0B, 0x38, 0x50, 0x4E, 0x90, 0x02}},
216 },
217 /* 30 fps */
218 {
219 {0, },
220 {9, 957, 526, {0x30, 0xF4, 0x25, 0x10, 0x68, 0x0E, 0xD8, 0x0D, 0x58, 0xBD, 0x33, 0x60, 0x02}},
221 {6, 775, 426, {0x30, 0xF4, 0x35, 0x0D, 0x48, 0x0B, 0xB8, 0x0F, 0x50, 0x07, 0x3F, 0x60, 0x02}},
222 {4, 590, 324, {0x30, 0x7A, 0x4B, 0x0A, 0x1C, 0x08, 0xB4, 0x0E, 0x40, 0x4E, 0x52, 0x60, 0x02}},
223 },
224 },
225 /* CIF */
226 {
227 /* 5 fps */
228 {
229 {6, 771, 0, {0x15, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x03, 0x3F, 0x80, 0x02}},
230 {4, 465, 1278, {0x15, 0xF4, 0x05, 0x27, 0xEE, 0x26, 0x36, 0x03, 0x18, 0xD1, 0x65, 0x80, 0x02}},
231 {2, 291, 800, {0x15, 0xF4, 0x15, 0x18, 0xF4, 0x17, 0x3C, 0x05, 0x18, 0x23, 0xA1, 0x80, 0x02}},
232 {1, 193, 528, {0x15, 0xF4, 0x2D, 0x10, 0x7E, 0x0E, 0xC6, 0x0A, 0x18, 0xC1, 0xF4, 0x80, 0x02}},
233 },
234 /* 10 fps */
235 {
236 {0, },
237 {9, 932, 1278, {0x14, 0xF4, 0x05, 0x27, 0xEE, 0x26, 0x36, 0x04, 0x30, 0xA4, 0x33, 0x10, 0x02}},
238 {4, 591, 812, {0x14, 0xF4, 0x15, 0x19, 0x56, 0x17, 0x9E, 0x06, 0x28, 0x4F, 0x4E, 0x10, 0x02}},
239 {2, 291, 400, {0x14, 0xF4, 0x3D, 0x0C, 0x7A, 0x0A, 0xC2, 0x0E, 0x28, 0x23, 0xA1, 0x10, 0x02}},
240 },
241 /* 15 fps */
242 {
243 {0, },
244 {9, 956, 876, {0x13, 0xF4, 0x0D, 0x1B, 0x58, 0x19, 0xA0, 0x05, 0x38, 0xBC, 0x33, 0x60, 0x02}},
245 {5, 703, 644, {0x13, 0xF4, 0x1D, 0x14, 0x1C, 0x12, 0x64, 0x08, 0x38, 0xBF, 0x42, 0x60, 0x02}},
246 {3, 448, 410, {0x13, 0xF4, 0x3D, 0x0C, 0xC4, 0x0B, 0x0C, 0x0E, 0x38, 0xC0, 0x69, 0x60, 0x02}},
247 },
248 /* 20 fps */
249 {
250 {0, },
251 {9, 956, 650, {0x12, 0xF4, 0x1D, 0x14, 0x4A, 0x12, 0x92, 0x09, 0x48, 0xBC, 0x33, 0x10, 0x03}},
252 {6, 776, 528, {0x12, 0xF4, 0x2D, 0x10, 0x7E, 0x0E, 0xC6, 0x0A, 0x40, 0x08, 0x3F, 0x10, 0x03}},
253 {4, 591, 402, {0x12, 0xF4, 0x3D, 0x0C, 0x8F, 0x0A, 0xD7, 0x0E, 0x40, 0x4F, 0x4E, 0x10, 0x03}},
254 },
255 /* 25 fps */
256 {
257 {0, },
258 {9, 956, 544, {0x11, 0xF4, 0x25, 0x10, 0xF4, 0x0F, 0x3C, 0x0A, 0x48, 0xBC, 0x33, 0xC0, 0x02}},
259 {7, 840, 478, {0x11, 0xF4, 0x2D, 0x0E, 0xEB, 0x0D, 0x33, 0x0B, 0x48, 0x48, 0x3B, 0xC0, 0x02}},
260 {5, 703, 400, {0x11, 0xF4, 0x3D, 0x0C, 0x7A, 0x0A, 0xC2, 0x0E, 0x48, 0xBF, 0x42, 0xC0, 0x02}},
261 },
262 /* 30 fps */
263 {
264 {0, },
265 {9, 956, 438, {0x10, 0xF4, 0x35, 0x0D, 0xAC, 0x0B, 0xF4, 0x0D, 0x50, 0xBC, 0x33, 0x10, 0x02}},
266 {7, 838, 384, {0x10, 0xF4, 0x45, 0x0B, 0xFD, 0x0A, 0x45, 0x0F, 0x50, 0x46, 0x3B, 0x10, 0x02}},
267 {6, 773, 354, {0x10, 0x7A, 0x4B, 0x0B, 0x0C, 0x09, 0x80, 0x10, 0x50, 0x05, 0x3F, 0x10, 0x02}},
268 },
269 },
270 /* VGA */
271 {
272 /* 5 fps */
273 {
274 {0, },
275 {6, 773, 1272, {0x1D, 0xF4, 0x15, 0x27, 0xB6, 0x24, 0x96, 0x02, 0x30, 0x05, 0x3F, 0x10, 0x02}},
276 {4, 592, 976, {0x1D, 0xF4, 0x25, 0x1E, 0x78, 0x1B, 0x58, 0x03, 0x30, 0x50, 0x4E, 0x10, 0x02}},
277 {3, 448, 738, {0x1D, 0xF4, 0x3D, 0x17, 0x0C, 0x13, 0xEC, 0x04, 0x30, 0xC0, 0x69, 0x10, 0x02}},
278 },
279 /* 10 fps */
280 {
281 {0, },
282 {9, 956, 788, {0x1C, 0xF4, 0x35, 0x18, 0x9C, 0x15, 0x7C, 0x03, 0x48, 0xBC, 0x33, 0x10, 0x02}},
283 {6, 776, 640, {0x1C, 0x7A, 0x53, 0x13, 0xFC, 0x11, 0x2C, 0x04, 0x48, 0x08, 0x3F, 0x10, 0x02}},
284 {4, 592, 488, {0x1C, 0x7A, 0x6B, 0x0F, 0x3C, 0x0C, 0x6C, 0x06, 0x48, 0x50, 0x4E, 0x10, 0x02}},
285 },
286 /* 15 fps */
287 {
288 {0, },
289 {9, 957, 526, {0x1B, 0x7A, 0x63, 0x10, 0x68, 0x0D, 0x98, 0x06, 0x58, 0xBD, 0x33, 0x80, 0x02}},
290 {9, 957, 526, {0x1B, 0x7A, 0x63, 0x10, 0x68, 0x0D, 0x98, 0x06, 0x58, 0xBD, 0x33, 0x80, 0x02}},
291 {8, 895, 492, {0x1B, 0x7A, 0x6B, 0x0F, 0x5D, 0x0C, 0x8D, 0x06, 0x58, 0x7F, 0x37, 0x80, 0x02}},
292 },
293 /* 20 fps */
294 {
295 {0, },
296 {0, },
297 {0, },
298 {0, },
299 },
300 /* 25 fps */
301 {
302 {0, },
303 {0, },
304 {0, },
305 {0, },
306 },
307 /* 30 fps */
308 {
309 {0, },
310 {0, },
311 {0, },
312 {0, },
313 },
314 },
315};
316
diff --git a/drivers/media/video/pwc/pwc-timon.h b/drivers/media/video/pwc/pwc-timon.h
new file mode 100644
index 000000000000..a86b3782a081
--- /dev/null
+++ b/drivers/media/video/pwc/pwc-timon.h
@@ -0,0 +1,61 @@
1/* Linux driver for Philips webcam
2 (C) 2004 Luc Saillard (luc@saillard.org)
3
4 NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx
5 driver and thus may have bugs that are not present in the original version.
6 Please send bug reports and support requests to <luc@saillard.org>.
7 The decompression routines have been implemented by reverse-engineering the
8 Nemosoft binary pwcx module. Caveat emptor.
9
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2 of the License, or
13 (at your option) any later version.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23*/
24
25
26
27/* This tables contains entries for the 675/680/690 (Timon) camera, with
28 4 different qualities (no compression, low, medium, high).
29 It lists the bandwidth requirements for said mode by its alternate interface
30 number. An alternate of 0 means that the mode is unavailable.
31
32 There are 6 * 4 * 4 entries:
33 6 different resolutions subqcif, qsif, qcif, sif, cif, vga
34 6 framerates: 5, 10, 15, 20, 25, 30
35 4 compression modi: none, low, medium, high
36
37 When an uncompressed mode is not available, the next available compressed mode
38 will be chosen (unless the decompressor is absent). Sometimes there are only
39 1 or 2 compressed modes available; in that case entries are duplicated.
40*/
41
42#ifndef PWC_TIMON_H
43#define PWC_TIMON_H
44
45#include "pwc-ioctl.h"
46
47struct Timon_table_entry
48{
49 char alternate; /* USB alternate interface */
50 unsigned short packetsize; /* Normal packet size */
51 unsigned short bandlength; /* Bandlength when decompressing */
52 unsigned char mode[13]; /* precomputed mode settings for cam */
53};
54
55const extern struct Timon_table_entry Timon_table[PSZ_MAX][6][4];
56const extern unsigned int TimonRomTable [16][2][16][8];
57
58
59#endif
60
61
diff --git a/drivers/media/video/pwc/pwc-uncompress.c b/drivers/media/video/pwc/pwc-uncompress.c
new file mode 100644
index 000000000000..ef4204eab6c4
--- /dev/null
+++ b/drivers/media/video/pwc/pwc-uncompress.c
@@ -0,0 +1,146 @@
1/* Linux driver for Philips webcam
2 Decompression frontend.
3 (C) 1999-2003 Nemosoft Unv.
4 (C) 2004 Luc Saillard (luc@saillard.org)
5
6 NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx
7 driver and thus may have bugs that are not present in the original version.
8 Please send bug reports and support requests to <luc@saillard.org>.
9 The decompression routines have been implemented by reverse-engineering the
10 Nemosoft binary pwcx module. Caveat emptor.
11
12 This program is free software; you can redistribute it and/or modify
13 it under the terms of the GNU General Public License as published by
14 the Free Software Foundation; either version 2 of the License, or
15 (at your option) any later version.
16
17 This program is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 GNU General Public License for more details.
21
22 You should have received a copy of the GNU General Public License
23 along with this program; if not, write to the Free Software
24 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25*/
26
27#include <asm/current.h>
28#include <asm/types.h>
29
30#include "pwc.h"
31#include "pwc-uncompress.h"
32
33int pwc_decompress(struct pwc_device *pdev)
34{
35 struct pwc_frame_buf *fbuf;
36 int n, line, col, stride;
37 void *yuv, *image;
38 u16 *src;
39 u16 *dsty, *dstu, *dstv;
40
41 if (pdev == NULL)
42 return -EFAULT;
43#if defined(__KERNEL__) && defined(PWC_MAGIC)
44 if (pdev->magic != PWC_MAGIC) {
45 Err("pwc_decompress(): magic failed.\n");
46 return -EFAULT;
47 }
48#endif
49
50 fbuf = pdev->read_frame;
51 if (fbuf == NULL)
52 return -EFAULT;
53 image = pdev->image_ptr[pdev->fill_image];
54 if (!image)
55 return -EFAULT;
56
57 yuv = fbuf->data + pdev->frame_header_size; /* Skip header */
58
59 /* Raw format; that's easy... */
60 if (pdev->vpalette == VIDEO_PALETTE_RAW)
61 {
62 memcpy(image, yuv, pdev->frame_size);
63 return 0;
64 }
65
66 if (pdev->vbandlength == 0) {
67 /* Uncompressed mode. We copy the data into the output buffer,
68 using the viewport size (which may be larger than the image
69 size). Unfortunately we have to do a bit of byte stuffing
70 to get the desired output format/size.
71 */
72 /*
73 * We do some byte shuffling here to go from the
74 * native format to YUV420P.
75 */
76 src = (u16 *)yuv;
77 n = pdev->view.x * pdev->view.y;
78
79 /* offset in Y plane */
80 stride = pdev->view.x * pdev->offset.y + pdev->offset.x;
81 dsty = (u16 *)(image + stride);
82
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);
87
88 /* increment after each line */
89 stride = (pdev->view.x - pdev->image.x) / 2; /* u16 is 2 bytes */
90
91 for (line = 0; line < pdev->image.y; line++) {
92 for (col = 0; col < pdev->image.x; col += 4) {
93 *dsty++ = *src++;
94 *dsty++ = *src++;
95 if (line & 1)
96 *dstv++ = *src++;
97 else
98 *dstu++ = *src++;
99 }
100 dsty += stride;
101 if (line & 1)
102 dstv += (stride >> 1);
103 else
104 dstu += (stride >> 1);
105 }
106 }
107 else {
108 /* Compressed; the decompressor routines will write the data
109 in planar format immediately.
110 */
111 int flags;
112
113 flags = PWCX_FLAG_PLANAR;
114 if (pdev->vsize == PSZ_VGA && pdev->vframes == 5 && pdev->vsnapshot)
115 {
116 printk(KERN_ERR "pwc: Mode Bayer is not supported for now\n");
117 flags |= PWCX_FLAG_BAYER;
118 return -ENXIO; /* No such device or address: missing decompressor */
119 }
120
121#if 0
122 switch (pdev->type)
123 {
124 case 675:
125 case 680:
126 case 690:
127 case 720:
128 case 730:
129 case 740:
130 case 750:
131 pwc_dec23_decompress(&pdev->image, &pdev->view,
132 &pdev->offset, yuv, image, flags,
133 pdev->decompress_data, pdev->vbandlength);
134 break;
135 case 645:
136 case 646:
137 /* TODO & FIXME */
138 return -ENXIO; /* Missing decompressor */
139 break;
140 }
141#endif
142 }
143 return 0;
144}
145
146
diff --git a/drivers/media/video/pwc/pwc-uncompress.h b/drivers/media/video/pwc/pwc-uncompress.h
new file mode 100644
index 000000000000..d3b9250e4ed3
--- /dev/null
+++ b/drivers/media/video/pwc/pwc-uncompress.h
@@ -0,0 +1,41 @@
1/* (C) 1999-2003 Nemosoft Unv.
2 (C) 2004 Luc Saillard (luc@saillard.org)
3
4 NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx
5 driver and thus may have bugs that are not present in the original version.
6 Please send bug reports and support requests to <luc@saillard.org>.
7 The decompression routines have been implemented by reverse-engineering the
8 Nemosoft binary pwcx module. Caveat emptor.
9
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2 of the License, or
13 (at your option) any later version.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23*/
24
25/* This file is the bridge between the kernel module and the plugin; it
26 describes the structures and datatypes used in both modules. Any
27 significant change should be reflected by increasing the
28 pwc_decompressor_version major number.
29 */
30#ifndef PWC_UNCOMPRESS_H
31#define PWC_UNCOMPRESS_H
32
33#include <linux/config.h>
34
35#include "pwc-ioctl.h"
36
37/* from pwc-dec.h */
38#define PWCX_FLAG_PLANAR 0x0001
39/* */
40
41#endif
diff --git a/drivers/media/video/pwc/pwc.h b/drivers/media/video/pwc/pwc.h
new file mode 100644
index 000000000000..6dd76bb3dff1
--- /dev/null
+++ b/drivers/media/video/pwc/pwc.h
@@ -0,0 +1,272 @@
1/* (C) 1999-2003 Nemosoft Unv.
2 (C) 2004 Luc Saillard (luc@saillard.org)
3
4 NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx
5 driver and thus may have bugs that are not present in the original version.
6 Please send bug reports and support requests to <luc@saillard.org>.
7 The decompression routines have been implemented by reverse-engineering the
8 Nemosoft binary pwcx module. Caveat emptor.
9
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2 of the License, or
13 (at your option) any later version.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23*/
24
25#ifndef PWC_H
26#define PWC_H
27
28#include <linux/config.h>
29#include <linux/module.h>
30#include <linux/usb.h>
31#include <linux/spinlock.h>
32#include <linux/videodev.h>
33#include <linux/wait.h>
34#include <linux/smp_lock.h>
35#include <asm/semaphore.h>
36#include <asm/errno.h>
37
38#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
45
46/* Turn some debugging options on/off */
47#define PWC_DEBUG 0
48
49/* 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
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)
64
65
66/* Defines for ToUCam cameras */
67#define TOUCAM_HEADER_SIZE 8
68#define TOUCAM_TRAILER_SIZE 4
69
70#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"
77
78/* Turn certain features on/off */
79#define PWC_INT_PIPE 0
80
81/* Ignore errors in the first N frames, to allow for startup delays */
82#define FRAME_LOWMARK 5
83
84/* Size and number of buffers for the ISO pipe. */
85#define MAX_ISO_BUFS 2
86#define ISO_FRAMES_PER_DESC 10
87#define ISO_MAX_FRAME_SIZE 960
88#define ISO_BUFFER_SIZE (ISO_FRAMES_PER_DESC * ISO_MAX_FRAME_SIZE)
89
90/* Frame buffers: contains compressed or uncompressed video data. */
91#define MAX_FRAMES 5
92/* Maximum size after decompression is 640x480 YUV data, 1.5 * 640 * 480 */
93#define PWC_FRAME_SIZE (460800 + TOUCAM_HEADER_SIZE + TOUCAM_TRAILER_SIZE)
94
95/* Absolute maximum number of buffers available for mmap() */
96#define MAX_IMAGES 10
97
98/* The following structures were based on cpia.h. Why reinvent the wheel? :-) */
99struct pwc_iso_buf
100{
101 void *data;
102 int length;
103 int read;
104 struct urb *urb;
105};
106
107/* intermediate buffers with raw data from the USB cam */
108struct pwc_frame_buf
109{
110 void *data;
111 volatile int filled; /* number of bytes filled */
112 struct pwc_frame_buf *next; /* list */
113#if PWC_DEBUG
114 int sequence; /* Sequence number */
115#endif
116};
117
118struct pwc_device
119{
120 struct video_device *vdev;
121#ifdef PWC_MAGIC
122 int magic;
123#endif
124 /* Pointer to our usb_device */
125 struct usb_device *udev;
126
127 int type; /* type of cam (645, 646, 675, 680, 690, 720, 730, 740, 750) */
128 int release; /* release number */
129 int features; /* feature bits */
130 char serial[30]; /* serial number (string) */
131 int error_status; /* set when something goes wrong with the cam (unplugged, USB errors) */
132 int usb_init; /* set when the cam has been initialized over USB */
133
134 /*** Video data ***/
135 int vopen; /* flag */
136 int vendpoint; /* video isoc endpoint */
137 int vcinterface; /* video control interface */
138 int valternate; /* alternate interface needed */
139 int vframes, vsize; /* frames-per-second & size (see PSZ_*) */
140 int vpalette; /* palette: 420P, RAW or RGBBAYER */
141 int vframe_count; /* received frames */
142 int vframes_dumped; /* counter for dumped frames */
143 int vframes_error; /* frames received in error */
144 int vmax_packet_size; /* USB maxpacket size */
145 int vlast_packet_size; /* for frame synchronisation */
146 int visoc_errors; /* number of contiguous ISOC errors */
147 int vcompression; /* desired compression factor */
148 int vbandlength; /* compressed band length; 0 is uncompressed */
149 char vsnapshot; /* snapshot mode */
150 char vsync; /* used by isoc handler */
151 char vmirror; /* for ToUCaM series */
152
153 int cmd_len;
154 unsigned char cmd_buf[13];
155
156 /* The image acquisition requires 3 to 4 steps:
157 1. data is gathered in short packets from the USB controller
158 2. data is synchronized and packed into a frame buffer
159 3a. in case data is compressed, decompress it directly into image buffer
160 3b. in case data is uncompressed, copy into image buffer with viewport
161 4. data is transferred to the user process
162
163 Note that MAX_ISO_BUFS != MAX_FRAMES != MAX_IMAGES....
164 We have in effect a back-to-back-double-buffer system.
165 */
166 /* 1: isoc */
167 struct pwc_iso_buf sbuf[MAX_ISO_BUFS];
168 char iso_init;
169
170 /* 2: frame */
171 struct pwc_frame_buf *fbuf; /* all frames */
172 struct pwc_frame_buf *empty_frames, *empty_frames_tail; /* all empty frames */
173 struct pwc_frame_buf *full_frames, *full_frames_tail; /* all filled frames */
174 struct pwc_frame_buf *fill_frame; /* frame currently being filled */
175 struct pwc_frame_buf *read_frame; /* frame currently read by user process */
176 int frame_header_size, frame_trailer_size;
177 int frame_size;
178 int frame_total_size; /* including header & trailer */
179 int drop_frames;
180#if PWC_DEBUG
181 int sequence; /* Debugging aid */
182#endif
183
184 /* 3: decompression */
185 struct pwc_decompressor *decompressor; /* function block with decompression routines */
186 void *decompress_data; /* private data for decompression engine */
187
188 /* 4: image */
189 /* We have an 'image' and a 'view', where 'image' is the fixed-size image
190 as delivered by the camera, and 'view' is the size requested by the
191 program. The camera image is centered in this viewport, laced with
192 a gray or black border. view_min <= image <= view <= view_max;
193 */
194 int image_mask; /* bitmask of supported sizes */
195 struct pwc_coord view_min, view_max; /* minimum and maximum viewable sizes */
196 struct pwc_coord abs_max; /* maximum supported size with compression */
197 struct pwc_coord image, view; /* image and viewport size */
198 struct pwc_coord offset; /* offset within the viewport */
199
200 void *image_data; /* total buffer, which is subdivided into ... */
201 void *image_ptr[MAX_IMAGES]; /* ...several images... */
202 int fill_image; /* ...which are rotated. */
203 int len_per_image; /* length per image */
204 int image_read_pos; /* In case we read data in pieces, keep track of were we are in the imagebuffer */
205 int image_used[MAX_IMAGES]; /* For MCAPTURE and SYNC */
206
207 struct semaphore modlock; /* to prevent races in video_open(), etc */
208 spinlock_t ptrlock; /* for manipulating the buffer pointers */
209
210 /*** motorized pan/tilt feature */
211 struct pwc_mpt_range angle_range;
212 int pan_angle; /* in degrees * 100 */
213 int tilt_angle; /* absolute angle; 0,0 is home position */
214
215 /*** Misc. data ***/
216 wait_queue_head_t frameq; /* When waiting for a frame to finish... */
217#if PWC_INT_PIPE
218 void *usb_int_handler; /* for the interrupt endpoint */
219#endif
220};
221
222
223#ifdef __cplusplus
224extern "C" {
225#endif
226
227/* Global variable */
228extern int pwc_trace;
229
230/** functions in pwc-if.c */
231int pwc_try_video_mode(struct pwc_device *pdev, int width, int height, int new_fps, int new_compression, int new_snapshot);
232
233/** Functions in pwc-misc.c */
234/* sizes in pixels */
235extern struct pwc_coord pwc_image_sizes[PSZ_MAX];
236
237int pwc_decode_size(struct pwc_device *pdev, int width, int height);
238void pwc_construct(struct pwc_device *pdev);
239
240/** Functions in pwc-ctrl.c */
241/* Request a certain video mode. Returns < 0 if not possible */
242extern int pwc_set_video_mode(struct pwc_device *pdev, int width, int height, int frames, int compression, int snapshot);
243
244/* Various controls; should be obvious. Value 0..65535, or < 0 on error */
245extern int pwc_get_brightness(struct pwc_device *pdev);
246extern int pwc_set_brightness(struct pwc_device *pdev, int value);
247extern int pwc_get_contrast(struct pwc_device *pdev);
248extern int pwc_set_contrast(struct pwc_device *pdev, int value);
249extern int pwc_get_gamma(struct pwc_device *pdev);
250extern int pwc_set_gamma(struct pwc_device *pdev, int value);
251extern int pwc_get_saturation(struct pwc_device *pdev);
252extern int pwc_set_saturation(struct pwc_device *pdev, int value);
253extern int pwc_set_leds(struct pwc_device *pdev, int on_value, int off_value);
254extern int pwc_get_cmos_sensor(struct pwc_device *pdev, int *sensor);
255
256/* Power down or up the camera; not supported by all models */
257extern int pwc_camera_power(struct pwc_device *pdev, int power);
258
259/* Private ioctl()s; see pwc-ioctl.h */
260extern int pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg);
261
262
263/** pwc-uncompress.c */
264/* Expand frame to image, possibly including decompression. Uses read_frame and fill_image */
265extern int pwc_decompress(struct pwc_device *pdev);
266
267#ifdef __cplusplus
268}
269#endif
270
271
272#endif
diff --git a/drivers/media/video/se401.c b/drivers/media/video/se401.c
new file mode 100644
index 000000000000..f03ea7f89596
--- /dev/null
+++ b/drivers/media/video/se401.c
@@ -0,0 +1,1435 @@
1/*
2 * Endpoints (formerly known as AOX) se401 USB Camera Driver
3 *
4 * Copyright (c) 2000 Jeroen B. Vreeken (pe1rxq@amsat.org)
5 *
6 * Still somewhat based on the Linux ov511 driver.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 * for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software Foundation,
20 * Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 *
22 *
23 * Thanks to Endpoints Inc. (www.endpoints.com) for making documentation on
24 * their chipset available and supporting me while writing this driver.
25 * - Jeroen Vreeken
26 */
27
28static const char version[] = "0.24";
29
30#include <linux/config.h>
31#include <linux/module.h>
32#include <linux/init.h>
33#include <linux/vmalloc.h>
34#include <linux/slab.h>
35#include <linux/pagemap.h>
36#include <linux/usb.h>
37#include "se401.h"
38
39static int flickerless=0;
40static int video_nr = -1;
41
42static struct usb_device_id device_table [] = {
43 { USB_DEVICE(0x03e8, 0x0004) },/* Endpoints/Aox SE401 */
44 { USB_DEVICE(0x0471, 0x030b) },/* Philips PCVC665K */
45 { USB_DEVICE(0x047d, 0x5001) },/* Kensington 67014 */
46 { USB_DEVICE(0x047d, 0x5002) },/* Kensington 6701(5/7) */
47 { USB_DEVICE(0x047d, 0x5003) },/* Kensington 67016 */
48 { }
49};
50
51MODULE_DEVICE_TABLE(usb, device_table);
52
53MODULE_AUTHOR("Jeroen Vreeken <pe1rxq@amsat.org>");
54MODULE_DESCRIPTION("SE401 USB Camera Driver");
55MODULE_LICENSE("GPL");
56module_param(flickerless, int, 0);
57MODULE_PARM_DESC(flickerless, "Net frequency to adjust exposure time to (0/50/60)");
58module_param(video_nr, int, 0);
59
60static struct usb_driver se401_driver;
61
62
63/**********************************************************************
64 *
65 * Memory management
66 *
67 **********************************************************************/
68static void *rvmalloc(unsigned long size)
69{
70 void *mem;
71 unsigned long adr;
72
73 size = PAGE_ALIGN(size);
74 mem = vmalloc_32(size);
75 if (!mem)
76 return NULL;
77
78 memset(mem, 0, size); /* Clear the ram out, no junk to the user */
79 adr = (unsigned long) mem;
80 while (size > 0) {
81 SetPageReserved(vmalloc_to_page((void *)adr));
82 adr += PAGE_SIZE;
83 size -= PAGE_SIZE;
84 }
85
86 return mem;
87}
88
89static void rvfree(void *mem, unsigned long size)
90{
91 unsigned long adr;
92
93 if (!mem)
94 return;
95
96 adr = (unsigned long) mem;
97 while ((long) size > 0) {
98 ClearPageReserved(vmalloc_to_page((void *)adr));
99 adr += PAGE_SIZE;
100 size -= PAGE_SIZE;
101 }
102 vfree(mem);
103}
104
105
106
107/****************************************************************************
108 *
109 * se401 register read/write functions
110 *
111 ***************************************************************************/
112
113static int se401_sndctrl(int set, struct usb_se401 *se401, unsigned short req,
114 unsigned short value, unsigned char *cp, int size)
115{
116 return usb_control_msg (
117 se401->dev,
118 set ? usb_sndctrlpipe(se401->dev, 0) : usb_rcvctrlpipe(se401->dev, 0),
119 req,
120 (set ? USB_DIR_OUT : USB_DIR_IN) | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
121 value,
122 0,
123 cp,
124 size,
125 1000
126 );
127}
128
129static int se401_set_feature(struct usb_se401 *se401, unsigned short selector,
130 unsigned short param)
131{
132 /* specs say that the selector (address) should go in the value field
133 and the param in index, but in the logs of the windows driver they do
134 this the other way around...
135 */
136 return usb_control_msg (
137 se401->dev,
138 usb_sndctrlpipe(se401->dev, 0),
139 SE401_REQ_SET_EXT_FEATURE,
140 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
141 param,
142 selector,
143 NULL,
144 0,
145 1000
146 );
147}
148
149static unsigned short se401_get_feature(struct usb_se401 *se401,
150 unsigned short selector)
151{
152 /* For 'set' the selecetor should be in index, not sure if the spec is
153 wrong here to....
154 */
155 unsigned char cp[2];
156 usb_control_msg (
157 se401->dev,
158 usb_rcvctrlpipe(se401->dev, 0),
159 SE401_REQ_GET_EXT_FEATURE,
160 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
161 0,
162 selector,
163 cp,
164 2,
165 1000
166 );
167 return cp[0]+cp[1]*256;
168}
169
170/****************************************************************************
171 *
172 * Camera control
173 *
174 ***************************************************************************/
175
176
177static int se401_send_pict(struct usb_se401 *se401)
178{
179 se401_set_feature(se401, HV7131_REG_TITL, se401->expose_l);/* integration time low */
180 se401_set_feature(se401, HV7131_REG_TITM, se401->expose_m);/* integration time mid */
181 se401_set_feature(se401, HV7131_REG_TITU, se401->expose_h);/* integration time mid */
182 se401_set_feature(se401, HV7131_REG_ARLV, se401->resetlevel);/* reset level value */
183 se401_set_feature(se401, HV7131_REG_ARCG, se401->rgain);/* red color gain */
184 se401_set_feature(se401, HV7131_REG_AGCG, se401->ggain);/* green color gain */
185 se401_set_feature(se401, HV7131_REG_ABCG, se401->bgain);/* blue color gain */
186
187 return 0;
188}
189
190static void se401_set_exposure(struct usb_se401 *se401, int brightness)
191{
192 int integration=brightness<<5;
193
194 if (flickerless==50) {
195 integration=integration-integration%106667;
196 }
197 if (flickerless==60) {
198 integration=integration-integration%88889;
199 }
200 se401->brightness=integration>>5;
201 se401->expose_h=(integration>>16)&0xff;
202 se401->expose_m=(integration>>8)&0xff;
203 se401->expose_l=integration&0xff;
204}
205
206static int se401_get_pict(struct usb_se401 *se401, struct video_picture *p)
207{
208 p->brightness=se401->brightness;
209 if (se401->enhance) {
210 p->whiteness=32768;
211 } else {
212 p->whiteness=0;
213 }
214 p->colour=65535;
215 p->contrast=65535;
216 p->hue=se401->rgain<<10;
217 p->palette=se401->palette;
218 p->depth=3; /* rgb24 */
219 return 0;
220}
221
222
223static int se401_set_pict(struct usb_se401 *se401, struct video_picture *p)
224{
225 if (p->palette != VIDEO_PALETTE_RGB24)
226 return 1;
227 se401->palette=p->palette;
228 if (p->hue!=se401->hue) {
229 se401->rgain= p->hue>>10;
230 se401->bgain= 0x40-(p->hue>>10);
231 se401->hue=p->hue;
232 }
233 if (p->brightness!=se401->brightness) {
234 se401_set_exposure(se401, p->brightness);
235 }
236 if (p->whiteness>=32768) {
237 se401->enhance=1;
238 } else {
239 se401->enhance=0;
240 }
241 se401_send_pict(se401);
242 se401_send_pict(se401);
243 return 0;
244}
245
246/*
247 Hyundai have some really nice docs about this and other sensor related
248 stuff on their homepage: www.hei.co.kr
249*/
250static void se401_auto_resetlevel(struct usb_se401 *se401)
251{
252 unsigned int ahrc, alrc;
253 int oldreset=se401->resetlevel;
254
255 /* For some reason this normally read-only register doesn't get reset
256 to zero after reading them just once...
257 */
258 se401_get_feature(se401, HV7131_REG_HIREFNOH);
259 se401_get_feature(se401, HV7131_REG_HIREFNOL);
260 se401_get_feature(se401, HV7131_REG_LOREFNOH);
261 se401_get_feature(se401, HV7131_REG_LOREFNOL);
262 ahrc=256*se401_get_feature(se401, HV7131_REG_HIREFNOH) +
263 se401_get_feature(se401, HV7131_REG_HIREFNOL);
264 alrc=256*se401_get_feature(se401, HV7131_REG_LOREFNOH) +
265 se401_get_feature(se401, HV7131_REG_LOREFNOL);
266
267 /* Not an exact science, but it seems to work pretty well... */
268 if (alrc > 10) {
269 while (alrc>=10 && se401->resetlevel < 63) {
270 se401->resetlevel++;
271 alrc /=2;
272 }
273 } else if (ahrc > 20) {
274 while (ahrc>=20 && se401->resetlevel > 0) {
275 se401->resetlevel--;
276 ahrc /=2;
277 }
278 }
279 if (se401->resetlevel!=oldreset)
280 se401_set_feature(se401, HV7131_REG_ARLV, se401->resetlevel);
281
282 return;
283}
284
285/* irq handler for snapshot button */
286static void se401_button_irq(struct urb *urb, struct pt_regs *regs)
287{
288 struct usb_se401 *se401 = urb->context;
289 int status;
290
291 if (!se401->dev) {
292 info("ohoh: device vapourished");
293 return;
294 }
295
296 switch (urb->status) {
297 case 0:
298 /* success */
299 break;
300 case -ECONNRESET:
301 case -ENOENT:
302 case -ESHUTDOWN:
303 /* this urb is terminated, clean up */
304 dbg("%s - urb shutting down with status: %d", __FUNCTION__, urb->status);
305 return;
306 default:
307 dbg("%s - nonzero urb status received: %d", __FUNCTION__, urb->status);
308 goto exit;
309 }
310
311 if (urb->actual_length >=2) {
312 if (se401->button)
313 se401->buttonpressed=1;
314 }
315exit:
316 status = usb_submit_urb (urb, GFP_ATOMIC);
317 if (status)
318 err ("%s - usb_submit_urb failed with result %d",
319 __FUNCTION__, status);
320}
321
322static void se401_video_irq(struct urb *urb, struct pt_regs *regs)
323{
324 struct usb_se401 *se401 = urb->context;
325 int length = urb->actual_length;
326
327 /* ohoh... */
328 if (!se401->streaming)
329 return;
330
331 if (!se401->dev) {
332 info ("ohoh: device vapourished");
333 return;
334 }
335
336 /* 0 sized packets happen if we are to fast, but sometimes the camera
337 keeps sending them forever...
338 */
339 if (length && !urb->status) {
340 se401->nullpackets=0;
341 switch(se401->scratch[se401->scratch_next].state) {
342 case BUFFER_READY:
343 case BUFFER_BUSY: {
344 se401->dropped++;
345 break;
346 }
347 case BUFFER_UNUSED: {
348 memcpy(se401->scratch[se401->scratch_next].data, (unsigned char *)urb->transfer_buffer, length);
349 se401->scratch[se401->scratch_next].state=BUFFER_READY;
350 se401->scratch[se401->scratch_next].offset=se401->bayeroffset;
351 se401->scratch[se401->scratch_next].length=length;
352 if (waitqueue_active(&se401->wq)) {
353 wake_up_interruptible(&se401->wq);
354 }
355 se401->scratch_overflow=0;
356 se401->scratch_next++;
357 if (se401->scratch_next>=SE401_NUMSCRATCH)
358 se401->scratch_next=0;
359 break;
360 }
361 }
362 se401->bayeroffset+=length;
363 if (se401->bayeroffset>=se401->cheight*se401->cwidth) {
364 se401->bayeroffset=0;
365 }
366 } else {
367 se401->nullpackets++;
368 if (se401->nullpackets > SE401_MAX_NULLPACKETS) {
369 if (waitqueue_active(&se401->wq)) {
370 wake_up_interruptible(&se401->wq);
371 }
372 }
373 }
374
375 /* Resubmit urb for new data */
376 urb->status=0;
377 urb->dev=se401->dev;
378 if(usb_submit_urb(urb, GFP_KERNEL))
379 info("urb burned down");
380 return;
381}
382
383static void se401_send_size(struct usb_se401 *se401, int width, int height)
384{
385 int i=0;
386 int mode=0x03; /* No compression */
387 int sendheight=height;
388 int sendwidth=width;
389
390 /* JangGu compression can only be used with the camera supported sizes,
391 but bayer seems to work with any size that fits on the sensor.
392 We check if we can use compression with the current size with either
393 4 or 16 times subcapturing, if not we use uncompressed bayer data
394 but this will result in cutouts of the maximum size....
395 */
396 while (i<se401->sizes && !(se401->width[i]==width && se401->height[i]==height))
397 i++;
398 while (i<se401->sizes) {
399 if (se401->width[i]==width*2 && se401->height[i]==height*2) {
400 sendheight=se401->height[i];
401 sendwidth=se401->width[i];
402 mode=0x40;
403 }
404 if (se401->width[i]==width*4 && se401->height[i]==height*4) {
405 sendheight=se401->height[i];
406 sendwidth=se401->width[i];
407 mode=0x42;
408 }
409 i++;
410 }
411
412 se401_sndctrl(1, se401, SE401_REQ_SET_WIDTH, sendwidth, NULL, 0);
413 se401_sndctrl(1, se401, SE401_REQ_SET_HEIGHT, sendheight, NULL, 0);
414 se401_set_feature(se401, SE401_OPERATINGMODE, mode);
415
416 if (mode==0x03) {
417 se401->format=FMT_BAYER;
418 } else {
419 se401->format=FMT_JANGGU;
420 }
421
422 return;
423}
424
425/*
426 In this function se401_send_pict is called several times,
427 for some reason (depending on the state of the sensor and the phase of
428 the moon :) doing this only in either place doesn't always work...
429*/
430static int se401_start_stream(struct usb_se401 *se401)
431{
432 struct urb *urb;
433 int err=0, i;
434 se401->streaming=1;
435
436 se401_sndctrl(1, se401, SE401_REQ_CAMERA_POWER, 1, NULL, 0);
437 se401_sndctrl(1, se401, SE401_REQ_LED_CONTROL, 1, NULL, 0);
438
439 /* Set picture settings */
440 se401_set_feature(se401, HV7131_REG_MODE_B, 0x05);/*windowed + pix intg */
441 se401_send_pict(se401);
442
443 se401_send_size(se401, se401->cwidth, se401->cheight);
444
445 se401_sndctrl(1, se401, SE401_REQ_START_CONTINUOUS_CAPTURE, 0, NULL, 0);
446
447 /* Do some memory allocation */
448 for (i=0; i<SE401_NUMFRAMES; i++) {
449 se401->frame[i].data=se401->fbuf + i * se401->maxframesize;
450 se401->frame[i].curpix=0;
451 }
452 for (i=0; i<SE401_NUMSBUF; i++) {
453 se401->sbuf[i].data=kmalloc(SE401_PACKETSIZE, GFP_KERNEL);
454 }
455
456 se401->bayeroffset=0;
457 se401->scratch_next=0;
458 se401->scratch_use=0;
459 se401->scratch_overflow=0;
460 for (i=0; i<SE401_NUMSCRATCH; i++) {
461 se401->scratch[i].data=kmalloc(SE401_PACKETSIZE, GFP_KERNEL);
462 se401->scratch[i].state=BUFFER_UNUSED;
463 }
464
465 for (i=0; i<SE401_NUMSBUF; i++) {
466 urb=usb_alloc_urb(0, GFP_KERNEL);
467 if(!urb)
468 return -ENOMEM;
469
470 usb_fill_bulk_urb(urb, se401->dev,
471 usb_rcvbulkpipe(se401->dev, SE401_VIDEO_ENDPOINT),
472 se401->sbuf[i].data, SE401_PACKETSIZE,
473 se401_video_irq,
474 se401);
475
476 se401->urb[i]=urb;
477
478 err=usb_submit_urb(se401->urb[i], GFP_KERNEL);
479 if(err)
480 err("urb burned down");
481 }
482
483 se401->framecount=0;
484
485 return 0;
486}
487
488static int se401_stop_stream(struct usb_se401 *se401)
489{
490 int i;
491
492 if (!se401->streaming || !se401->dev)
493 return 1;
494
495 se401->streaming=0;
496
497 se401_sndctrl(1, se401, SE401_REQ_STOP_CONTINUOUS_CAPTURE, 0, NULL, 0);
498
499 se401_sndctrl(1, se401, SE401_REQ_LED_CONTROL, 0, NULL, 0);
500 se401_sndctrl(1, se401, SE401_REQ_CAMERA_POWER, 0, NULL, 0);
501
502 for (i=0; i<SE401_NUMSBUF; i++) if (se401->urb[i]) {
503 usb_kill_urb(se401->urb[i]);
504 usb_free_urb(se401->urb[i]);
505 se401->urb[i]=NULL;
506 kfree(se401->sbuf[i].data);
507 }
508 for (i=0; i<SE401_NUMSCRATCH; i++) {
509 kfree(se401->scratch[i].data);
510 se401->scratch[i].data=NULL;
511 }
512
513 return 0;
514}
515
516static int se401_set_size(struct usb_se401 *se401, int width, int height)
517{
518 int wasstreaming=se401->streaming;
519 /* Check to see if we need to change */
520 if (se401->cwidth==width && se401->cheight==height)
521 return 0;
522
523 /* Check for a valid mode */
524 if (!width || !height)
525 return 1;
526 if ((width & 1) || (height & 1))
527 return 1;
528 if (width>se401->width[se401->sizes-1])
529 return 1;
530 if (height>se401->height[se401->sizes-1])
531 return 1;
532
533 /* Stop a current stream and start it again at the new size */
534 if (wasstreaming)
535 se401_stop_stream(se401);
536 se401->cwidth=width;
537 se401->cheight=height;
538 if (wasstreaming)
539 se401_start_stream(se401);
540 return 0;
541}
542
543
544/****************************************************************************
545 *
546 * Video Decoding
547 *
548 ***************************************************************************/
549
550/*
551 This shouldn't really be done in a v4l driver....
552 But it does make the image look a lot more usable.
553 Basically it lifts the dark pixels more than the light pixels.
554*/
555static inline void enhance_picture(unsigned char *frame, int len)
556{
557 while (len--) {
558 *frame=(((*frame^255)*(*frame^255))/255)^255;
559 frame++;
560 }
561}
562
563static inline void decode_JangGu_integrate(struct usb_se401 *se401, int data)
564{
565 struct se401_frame *frame=&se401->frame[se401->curframe];
566 int linelength=se401->cwidth*3;
567
568 if (frame->curlinepix >= linelength) {
569 frame->curlinepix=0;
570 frame->curline+=linelength;
571 }
572
573 /* First three are absolute, all others relative.
574 * Format is rgb from right to left (mirrorred image),
575 * we flip it to get bgr from left to right. */
576 if (frame->curlinepix < 3) {
577 *(frame->curline-frame->curlinepix)=1+data*4;
578 } else {
579 *(frame->curline-frame->curlinepix)=
580 *(frame->curline-frame->curlinepix+3)+data*4;
581 }
582 frame->curlinepix++;
583}
584
585static inline void decode_JangGu_vlc (struct usb_se401 *se401, unsigned char *data, int bit_exp, int packetlength)
586{
587 int pos=0;
588 int vlc_cod=0;
589 int vlc_size=0;
590 int vlc_data=0;
591 int bit_cur;
592 int bit;
593 data+=4;
594 while (pos < packetlength) {
595 bit_cur=8;
596 while (bit_cur && bit_exp) {
597 bit=((*data)>>(bit_cur-1))&1;
598 if (!vlc_cod) {
599 if (bit) {
600 vlc_size++;
601 } else {
602 if (!vlc_size) {
603 decode_JangGu_integrate(se401, 0);
604 } else {
605 vlc_cod=2;
606 vlc_data=0;
607 }
608 }
609 } else {
610 if (vlc_cod==2) {
611 if (!bit)
612 vlc_data = -(1<<vlc_size) + 1;
613 vlc_cod--;
614 }
615 vlc_size--;
616 vlc_data+=bit<<vlc_size;
617 if (!vlc_size) {
618 decode_JangGu_integrate(se401, vlc_data);
619 vlc_cod=0;
620 }
621 }
622 bit_cur--;
623 bit_exp--;
624 }
625 pos++;
626 data++;
627 }
628}
629
630static inline void decode_JangGu (struct usb_se401 *se401, struct se401_scratch *buffer)
631{
632 unsigned char *data=buffer->data;
633 int len=buffer->length;
634 int bit_exp=0, pix_exp=0, frameinfo=0, packetlength=0, size;
635 int datapos=0;
636
637 /* New image? */
638 if (!se401->frame[se401->curframe].curpix) {
639 se401->frame[se401->curframe].curlinepix=0;
640 se401->frame[se401->curframe].curline=
641 se401->frame[se401->curframe].data+
642 se401->cwidth*3-1;
643 if (se401->frame[se401->curframe].grabstate==FRAME_READY)
644 se401->frame[se401->curframe].grabstate=FRAME_GRABBING;
645 se401->vlcdatapos=0;
646 }
647 while (datapos < len) {
648 size=1024-se401->vlcdatapos;
649 if (size+datapos > len)
650 size=len-datapos;
651 memcpy(se401->vlcdata+se401->vlcdatapos, data+datapos, size);
652 se401->vlcdatapos+=size;
653 packetlength=0;
654 if (se401->vlcdatapos >= 4) {
655 bit_exp=se401->vlcdata[3]+(se401->vlcdata[2]<<8);
656 pix_exp=se401->vlcdata[1]+((se401->vlcdata[0]&0x3f)<<8);
657 frameinfo=se401->vlcdata[0]&0xc0;
658 packetlength=((bit_exp+47)>>4)<<1;
659 if (packetlength > 1024) {
660 se401->vlcdatapos=0;
661 datapos=len;
662 packetlength=0;
663 se401->error++;
664 se401->frame[se401->curframe].curpix=0;
665 }
666 }
667 if (packetlength && se401->vlcdatapos >= packetlength) {
668 decode_JangGu_vlc(se401, se401->vlcdata, bit_exp, packetlength);
669 se401->frame[se401->curframe].curpix+=pix_exp*3;
670 datapos+=size-(se401->vlcdatapos-packetlength);
671 se401->vlcdatapos=0;
672 if (se401->frame[se401->curframe].curpix>=se401->cwidth*se401->cheight*3) {
673 if (se401->frame[se401->curframe].curpix==se401->cwidth*se401->cheight*3) {
674 if (se401->frame[se401->curframe].grabstate==FRAME_GRABBING) {
675 se401->frame[se401->curframe].grabstate=FRAME_DONE;
676 se401->framecount++;
677 se401->readcount++;
678 }
679 if (se401->frame[(se401->curframe+1)&(SE401_NUMFRAMES-1)].grabstate==FRAME_READY) {
680 se401->curframe=(se401->curframe+1) & (SE401_NUMFRAMES-1);
681 }
682 } else {
683 se401->error++;
684 }
685 se401->frame[se401->curframe].curpix=0;
686 datapos=len;
687 }
688 } else {
689 datapos+=size;
690 }
691 }
692}
693
694static inline void decode_bayer (struct usb_se401 *se401, struct se401_scratch *buffer)
695{
696 unsigned char *data=buffer->data;
697 int len=buffer->length;
698 int offset=buffer->offset;
699 int datasize=se401->cwidth*se401->cheight;
700 struct se401_frame *frame=&se401->frame[se401->curframe];
701
702 unsigned char *framedata=frame->data, *curline, *nextline;
703 int width=se401->cwidth;
704 int blineoffset=0, bline;
705 int linelength=width*3, i;
706
707
708 if (frame->curpix==0) {
709 if (frame->grabstate==FRAME_READY) {
710 frame->grabstate=FRAME_GRABBING;
711 }
712 frame->curline=framedata+linelength;
713 frame->curlinepix=0;
714 }
715
716 if (offset!=frame->curpix) {
717 /* Regard frame as lost :( */
718 frame->curpix=0;
719 se401->error++;
720 return;
721 }
722
723 /* Check if we have to much data */
724 if (frame->curpix+len > datasize) {
725 len=datasize-frame->curpix;
726 }
727 if (se401->cheight%4)
728 blineoffset=1;
729 bline=frame->curpix/se401->cwidth+blineoffset;
730
731 curline=frame->curline;
732 nextline=curline+linelength;
733 if (nextline >= framedata+datasize*3)
734 nextline=curline;
735 while (len) {
736 if (frame->curlinepix>=width) {
737 frame->curlinepix-=width;
738 bline=frame->curpix/width+blineoffset;
739 curline+=linelength*2;
740 nextline+=linelength*2;
741 if (curline >= framedata+datasize*3) {
742 frame->curlinepix++;
743 curline-=3;
744 nextline-=3;
745 len--;
746 data++;
747 frame->curpix++;
748 }
749 if (nextline >= framedata+datasize*3)
750 nextline=curline;
751 }
752 if ((bline&1)) {
753 if ((frame->curlinepix&1)) {
754 *(curline+2)=*data;
755 *(curline-1)=*data;
756 *(nextline+2)=*data;
757 *(nextline-1)=*data;
758 } else {
759 *(curline+1)=
760 (*(curline+1)+*data)/2;
761 *(curline-2)=
762 (*(curline-2)+*data)/2;
763 *(nextline+1)=*data;
764 *(nextline-2)=*data;
765 }
766 } else {
767 if ((frame->curlinepix&1)) {
768 *(curline+1)=
769 (*(curline+1)+*data)/2;
770 *(curline-2)=
771 (*(curline-2)+*data)/2;
772 *(nextline+1)=*data;
773 *(nextline-2)=*data;
774 } else {
775 *curline=*data;
776 *(curline-3)=*data;
777 *nextline=*data;
778 *(nextline-3)=*data;
779 }
780 }
781 frame->curlinepix++;
782 curline-=3;
783 nextline-=3;
784 len--;
785 data++;
786 frame->curpix++;
787 }
788 frame->curline=curline;
789
790 if (frame->curpix>=datasize) {
791 /* Fix the top line */
792 framedata+=linelength;
793 for (i=0; i<linelength; i++) {
794 framedata--;
795 *framedata=*(framedata+linelength);
796 }
797 /* Fix the left side (green is already present) */
798 for (i=0; i<se401->cheight; i++) {
799 *framedata=*(framedata+3);
800 *(framedata+1)=*(framedata+4);
801 *(framedata+2)=*(framedata+5);
802 framedata+=linelength;
803 }
804 frame->curpix=0;
805 frame->grabstate=FRAME_DONE;
806 se401->framecount++;
807 se401->readcount++;
808 if (se401->frame[(se401->curframe+1)&(SE401_NUMFRAMES-1)].grabstate==FRAME_READY) {
809 se401->curframe=(se401->curframe+1) & (SE401_NUMFRAMES-1);
810 }
811 }
812}
813
814static int se401_newframe(struct usb_se401 *se401, int framenr)
815{
816 DECLARE_WAITQUEUE(wait, current);
817 int errors=0;
818
819 while (se401->streaming &&
820 (se401->frame[framenr].grabstate==FRAME_READY ||
821 se401->frame[framenr].grabstate==FRAME_GRABBING) ) {
822 if(!se401->frame[framenr].curpix) {
823 errors++;
824 }
825 wait_interruptible(
826 se401->scratch[se401->scratch_use].state!=BUFFER_READY,
827 &se401->wq,
828 &wait
829 );
830 if (se401->nullpackets > SE401_MAX_NULLPACKETS) {
831 se401->nullpackets=0;
832 info("to many null length packets, restarting capture");
833 se401_stop_stream(se401);
834 se401_start_stream(se401);
835 } else {
836 if (se401->scratch[se401->scratch_use].state!=BUFFER_READY) {
837 se401->frame[framenr].grabstate=FRAME_ERROR;
838 return -EIO;
839 }
840 se401->scratch[se401->scratch_use].state=BUFFER_BUSY;
841 if (se401->format==FMT_JANGGU) {
842 decode_JangGu(se401, &se401->scratch[se401->scratch_use]);
843 } else {
844 decode_bayer(se401, &se401->scratch[se401->scratch_use]);
845 }
846 se401->scratch[se401->scratch_use].state=BUFFER_UNUSED;
847 se401->scratch_use++;
848 if (se401->scratch_use>=SE401_NUMSCRATCH)
849 se401->scratch_use=0;
850 if (errors > SE401_MAX_ERRORS) {
851 errors=0;
852 info("to much errors, restarting capture");
853 se401_stop_stream(se401);
854 se401_start_stream(se401);
855 }
856 }
857 }
858
859 if (se401->frame[framenr].grabstate==FRAME_DONE)
860 if (se401->enhance)
861 enhance_picture(se401->frame[framenr].data, se401->cheight*se401->cwidth*3);
862 return 0;
863}
864
865static void usb_se401_remove_disconnected (struct usb_se401 *se401)
866{
867 int i;
868
869 se401->dev = NULL;
870
871 for (i=0; i<SE401_NUMSBUF; i++)
872 if (se401->urb[i]) {
873 usb_kill_urb(se401->urb[i]);
874 usb_free_urb(se401->urb[i]);
875 se401->urb[i] = NULL;
876 kfree(se401->sbuf[i].data);
877 }
878 for (i=0; i<SE401_NUMSCRATCH; i++) {
879 kfree(se401->scratch[i].data);
880 }
881 if (se401->inturb) {
882 usb_kill_urb(se401->inturb);
883 usb_free_urb(se401->inturb);
884 }
885 info("%s disconnected", se401->camera_name);
886
887 /* Free the memory */
888 kfree(se401->width);
889 kfree(se401->height);
890 kfree(se401);
891}
892
893
894
895/****************************************************************************
896 *
897 * Video4Linux
898 *
899 ***************************************************************************/
900
901
902static int se401_open(struct inode *inode, struct file *file)
903{
904 struct video_device *dev = video_devdata(file);
905 struct usb_se401 *se401 = (struct usb_se401 *)dev;
906 int err = 0;
907
908 if (se401->user)
909 return -EBUSY;
910 se401->fbuf = rvmalloc(se401->maxframesize * SE401_NUMFRAMES);
911 if (se401->fbuf)
912 file->private_data = dev;
913 else
914 err = -ENOMEM;
915 se401->user = !err;
916
917 return err;
918}
919
920static int se401_close(struct inode *inode, struct file *file)
921{
922 struct video_device *dev = file->private_data;
923 struct usb_se401 *se401 = (struct usb_se401 *)dev;
924 int i;
925
926 rvfree(se401->fbuf, se401->maxframesize * SE401_NUMFRAMES);
927 if (se401->removed) {
928 usb_se401_remove_disconnected(se401);
929 info("device unregistered");
930 } else {
931 for (i=0; i<SE401_NUMFRAMES; i++)
932 se401->frame[i].grabstate=FRAME_UNUSED;
933 if (se401->streaming)
934 se401_stop_stream(se401);
935 se401->user=0;
936 }
937 file->private_data = NULL;
938 return 0;
939}
940
941static int se401_do_ioctl(struct inode *inode, struct file *file,
942 unsigned int cmd, void *arg)
943{
944 struct video_device *vdev = file->private_data;
945 struct usb_se401 *se401 = (struct usb_se401 *)vdev;
946
947 if (!se401->dev)
948 return -EIO;
949
950 switch (cmd) {
951 case VIDIOCGCAP:
952 {
953 struct video_capability *b = arg;
954 strcpy(b->name, se401->camera_name);
955 b->type = VID_TYPE_CAPTURE;
956 b->channels = 1;
957 b->audios = 0;
958 b->maxwidth = se401->width[se401->sizes-1];
959 b->maxheight = se401->height[se401->sizes-1];
960 b->minwidth = se401->width[0];
961 b->minheight = se401->height[0];
962 return 0;
963 }
964 case VIDIOCGCHAN:
965 {
966 struct video_channel *v = arg;
967
968 if (v->channel != 0)
969 return -EINVAL;
970 v->flags = 0;
971 v->tuners = 0;
972 v->type = VIDEO_TYPE_CAMERA;
973 strcpy(v->name, "Camera");
974 return 0;
975 }
976 case VIDIOCSCHAN:
977 {
978 struct video_channel *v = arg;
979
980 if (v->channel != 0)
981 return -EINVAL;
982 return 0;
983 }
984 case VIDIOCGPICT:
985 {
986 struct video_picture *p = arg;
987
988 se401_get_pict(se401, p);
989 return 0;
990 }
991 case VIDIOCSPICT:
992 {
993 struct video_picture *p = arg;
994
995 if (se401_set_pict(se401, p))
996 return -EINVAL;
997 return 0;
998 }
999 case VIDIOCSWIN:
1000 {
1001 struct video_window *vw = arg;
1002
1003 if (vw->flags)
1004 return -EINVAL;
1005 if (vw->clipcount)
1006 return -EINVAL;
1007 if (se401_set_size(se401, vw->width, vw->height))
1008 return -EINVAL;
1009 return 0;
1010 }
1011 case VIDIOCGWIN:
1012 {
1013 struct video_window *vw = arg;
1014
1015 vw->x = 0; /* FIXME */
1016 vw->y = 0;
1017 vw->chromakey = 0;
1018 vw->flags = 0;
1019 vw->clipcount = 0;
1020 vw->width = se401->cwidth;
1021 vw->height = se401->cheight;
1022 return 0;
1023 }
1024 case VIDIOCGMBUF:
1025 {
1026 struct video_mbuf *vm = arg;
1027 int i;
1028
1029 memset(vm, 0, sizeof(*vm));
1030 vm->size = SE401_NUMFRAMES * se401->maxframesize;
1031 vm->frames = SE401_NUMFRAMES;
1032 for (i=0; i<SE401_NUMFRAMES; i++)
1033 vm->offsets[i] = se401->maxframesize * i;
1034 return 0;
1035 }
1036 case VIDIOCMCAPTURE:
1037 {
1038 struct video_mmap *vm = arg;
1039
1040 if (vm->format != VIDEO_PALETTE_RGB24)
1041 return -EINVAL;
1042 if (vm->frame >= SE401_NUMFRAMES)
1043 return -EINVAL;
1044 if (se401->frame[vm->frame].grabstate != FRAME_UNUSED)
1045 return -EBUSY;
1046
1047 /* Is this according to the v4l spec??? */
1048 if (se401_set_size(se401, vm->width, vm->height))
1049 return -EINVAL;
1050 se401->frame[vm->frame].grabstate=FRAME_READY;
1051
1052 if (!se401->streaming)
1053 se401_start_stream(se401);
1054
1055 /* Set the picture properties */
1056 if (se401->framecount==0)
1057 se401_send_pict(se401);
1058 /* Calibrate the reset level after a few frames. */
1059 if (se401->framecount%20==1)
1060 se401_auto_resetlevel(se401);
1061
1062 return 0;
1063 }
1064 case VIDIOCSYNC:
1065 {
1066 int *frame = arg;
1067 int ret=0;
1068
1069 if(*frame <0 || *frame >= SE401_NUMFRAMES)
1070 return -EINVAL;
1071
1072 ret=se401_newframe(se401, *frame);
1073 se401->frame[*frame].grabstate=FRAME_UNUSED;
1074 return ret;
1075 }
1076 case VIDIOCGFBUF:
1077 {
1078 struct video_buffer *vb = arg;
1079
1080 memset(vb, 0, sizeof(*vb));
1081 return 0;
1082 }
1083 case VIDIOCKEY:
1084 return 0;
1085 case VIDIOCCAPTURE:
1086 return -EINVAL;
1087 case VIDIOCSFBUF:
1088 return -EINVAL;
1089 case VIDIOCGTUNER:
1090 case VIDIOCSTUNER:
1091 return -EINVAL;
1092 case VIDIOCGFREQ:
1093 case VIDIOCSFREQ:
1094 return -EINVAL;
1095 case VIDIOCGAUDIO:
1096 case VIDIOCSAUDIO:
1097 return -EINVAL;
1098 default:
1099 return -ENOIOCTLCMD;
1100 } /* end switch */
1101
1102 return 0;
1103}
1104
1105static int se401_ioctl(struct inode *inode, struct file *file,
1106 unsigned int cmd, unsigned long arg)
1107{
1108 return video_usercopy(inode, file, cmd, arg, se401_do_ioctl);
1109}
1110
1111static ssize_t se401_read(struct file *file, char __user *buf,
1112 size_t count, loff_t *ppos)
1113{
1114 int realcount=count, ret=0;
1115 struct video_device *dev = file->private_data;
1116 struct usb_se401 *se401 = (struct usb_se401 *)dev;
1117
1118
1119 if (se401->dev == NULL)
1120 return -EIO;
1121 if (realcount > se401->cwidth*se401->cheight*3)
1122 realcount=se401->cwidth*se401->cheight*3;
1123
1124 /* Shouldn't happen: */
1125 if (se401->frame[0].grabstate==FRAME_GRABBING)
1126 return -EBUSY;
1127 se401->frame[0].grabstate=FRAME_READY;
1128 se401->frame[1].grabstate=FRAME_UNUSED;
1129 se401->curframe=0;
1130
1131 if (!se401->streaming)
1132 se401_start_stream(se401);
1133
1134 /* Set the picture properties */
1135 if (se401->framecount==0)
1136 se401_send_pict(se401);
1137 /* Calibrate the reset level after a few frames. */
1138 if (se401->framecount%20==1)
1139 se401_auto_resetlevel(se401);
1140
1141 ret=se401_newframe(se401, 0);
1142
1143 se401->frame[0].grabstate=FRAME_UNUSED;
1144 if (ret)
1145 return ret;
1146 if (copy_to_user(buf, se401->frame[0].data, realcount))
1147 return -EFAULT;
1148
1149 return realcount;
1150}
1151
1152static int se401_mmap(struct file *file, struct vm_area_struct *vma)
1153{
1154 struct video_device *dev = file->private_data;
1155 struct usb_se401 *se401 = (struct usb_se401 *)dev;
1156 unsigned long start = vma->vm_start;
1157 unsigned long size = vma->vm_end-vma->vm_start;
1158 unsigned long page, pos;
1159
1160 mutex_lock(&se401->lock);
1161
1162 if (se401->dev == NULL) {
1163 mutex_unlock(&se401->lock);
1164 return -EIO;
1165 }
1166 if (size > (((SE401_NUMFRAMES * se401->maxframesize) + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1))) {
1167 mutex_unlock(&se401->lock);
1168 return -EINVAL;
1169 }
1170 pos = (unsigned long)se401->fbuf;
1171 while (size > 0) {
1172 page = vmalloc_to_pfn((void *)pos);
1173 if (remap_pfn_range(vma, start, page, PAGE_SIZE, PAGE_SHARED)) {
1174 mutex_unlock(&se401->lock);
1175 return -EAGAIN;
1176 }
1177 start += PAGE_SIZE;
1178 pos += PAGE_SIZE;
1179 if (size > PAGE_SIZE)
1180 size -= PAGE_SIZE;
1181 else
1182 size = 0;
1183 }
1184 mutex_unlock(&se401->lock);
1185
1186 return 0;
1187}
1188
1189static struct file_operations se401_fops = {
1190 .owner = THIS_MODULE,
1191 .open = se401_open,
1192 .release = se401_close,
1193 .read = se401_read,
1194 .mmap = se401_mmap,
1195 .ioctl = se401_ioctl,
1196 .compat_ioctl = v4l_compat_ioctl32,
1197 .llseek = no_llseek,
1198};
1199static struct video_device se401_template = {
1200 .owner = THIS_MODULE,
1201 .name = "se401 USB camera",
1202 .type = VID_TYPE_CAPTURE,
1203 .hardware = VID_HARDWARE_SE401,
1204 .fops = &se401_fops,
1205};
1206
1207
1208
1209/***************************/
1210static int se401_init(struct usb_se401 *se401, int button)
1211{
1212 int i=0, rc;
1213 unsigned char cp[0x40];
1214 char temp[200];
1215
1216 /* led on */
1217 se401_sndctrl(1, se401, SE401_REQ_LED_CONTROL, 1, NULL, 0);
1218
1219 /* get camera descriptor */
1220 rc=se401_sndctrl(0, se401, SE401_REQ_GET_CAMERA_DESCRIPTOR, 0, cp, sizeof(cp));
1221 if (cp[1]!=0x41) {
1222 err("Wrong descriptor type");
1223 return 1;
1224 }
1225 sprintf (temp, "ExtraFeatures: %d", cp[3]);
1226
1227 se401->sizes=cp[4]+cp[5]*256;
1228 se401->width=kmalloc(se401->sizes*sizeof(int), GFP_KERNEL);
1229 if (!se401->width)
1230 return 1;
1231 se401->height=kmalloc(se401->sizes*sizeof(int), GFP_KERNEL);
1232 if (!se401->height) {
1233 kfree(se401->width);
1234 return 1;
1235 }
1236 for (i=0; i<se401->sizes; i++) {
1237 se401->width[i]=cp[6+i*4+0]+cp[6+i*4+1]*256;
1238 se401->height[i]=cp[6+i*4+2]+cp[6+i*4+3]*256;
1239 }
1240 sprintf (temp, "%s Sizes:", temp);
1241 for (i=0; i<se401->sizes; i++) {
1242 sprintf(temp, "%s %dx%d", temp, se401->width[i], se401->height[i]);
1243 }
1244 info("%s", temp);
1245 se401->maxframesize=se401->width[se401->sizes-1]*se401->height[se401->sizes-1]*3;
1246
1247 rc=se401_sndctrl(0, se401, SE401_REQ_GET_WIDTH, 0, cp, sizeof(cp));
1248 se401->cwidth=cp[0]+cp[1]*256;
1249 rc=se401_sndctrl(0, se401, SE401_REQ_GET_HEIGHT, 0, cp, sizeof(cp));
1250 se401->cheight=cp[0]+cp[1]*256;
1251
1252 if (!cp[2] && SE401_FORMAT_BAYER) {
1253 err("Bayer format not supported!");
1254 return 1;
1255 }
1256 /* set output mode (BAYER) */
1257 se401_sndctrl(1, se401, SE401_REQ_SET_OUTPUT_MODE, SE401_FORMAT_BAYER, NULL, 0);
1258
1259 rc=se401_sndctrl(0, se401, SE401_REQ_GET_BRT, 0, cp, sizeof(cp));
1260 se401->brightness=cp[0]+cp[1]*256;
1261 /* some default values */
1262 se401->resetlevel=0x2d;
1263 se401->rgain=0x20;
1264 se401->ggain=0x20;
1265 se401->bgain=0x20;
1266 se401_set_exposure(se401, 20000);
1267 se401->palette=VIDEO_PALETTE_RGB24;
1268 se401->enhance=1;
1269 se401->dropped=0;
1270 se401->error=0;
1271 se401->framecount=0;
1272 se401->readcount=0;
1273
1274 /* Start interrupt transfers for snapshot button */
1275 if (button) {
1276 se401->inturb=usb_alloc_urb(0, GFP_KERNEL);
1277 if (!se401->inturb) {
1278 info("Allocation of inturb failed");
1279 return 1;
1280 }
1281 usb_fill_int_urb(se401->inturb, se401->dev,
1282 usb_rcvintpipe(se401->dev, SE401_BUTTON_ENDPOINT),
1283 &se401->button, sizeof(se401->button),
1284 se401_button_irq,
1285 se401,
1286 8
1287 );
1288 if (usb_submit_urb(se401->inturb, GFP_KERNEL)) {
1289 info("int urb burned down");
1290 return 1;
1291 }
1292 } else
1293 se401->inturb=NULL;
1294
1295 /* Flash the led */
1296 se401_sndctrl(1, se401, SE401_REQ_CAMERA_POWER, 1, NULL, 0);
1297 se401_sndctrl(1, se401, SE401_REQ_LED_CONTROL, 1, NULL, 0);
1298 se401_sndctrl(1, se401, SE401_REQ_CAMERA_POWER, 0, NULL, 0);
1299 se401_sndctrl(1, se401, SE401_REQ_LED_CONTROL, 0, NULL, 0);
1300
1301 return 0;
1302}
1303
1304static int se401_probe(struct usb_interface *intf,
1305 const struct usb_device_id *id)
1306{
1307 struct usb_device *dev = interface_to_usbdev(intf);
1308 struct usb_interface_descriptor *interface;
1309 struct usb_se401 *se401;
1310 char *camera_name=NULL;
1311 int button=1;
1312
1313 /* We don't handle multi-config cameras */
1314 if (dev->descriptor.bNumConfigurations != 1)
1315 return -ENODEV;
1316
1317 interface = &intf->cur_altsetting->desc;
1318
1319 /* Is it an se401? */
1320 if (le16_to_cpu(dev->descriptor.idVendor) == 0x03e8 &&
1321 le16_to_cpu(dev->descriptor.idProduct) == 0x0004) {
1322 camera_name="Endpoints/Aox SE401";
1323 } else if (le16_to_cpu(dev->descriptor.idVendor) == 0x0471 &&
1324 le16_to_cpu(dev->descriptor.idProduct) == 0x030b) {
1325 camera_name="Philips PCVC665K";
1326 } else if (le16_to_cpu(dev->descriptor.idVendor) == 0x047d &&
1327 le16_to_cpu(dev->descriptor.idProduct) == 0x5001) {
1328 camera_name="Kensington VideoCAM 67014";
1329 } else if (le16_to_cpu(dev->descriptor.idVendor) == 0x047d &&
1330 le16_to_cpu(dev->descriptor.idProduct) == 0x5002) {
1331 camera_name="Kensington VideoCAM 6701(5/7)";
1332 } else if (le16_to_cpu(dev->descriptor.idVendor) == 0x047d &&
1333 le16_to_cpu(dev->descriptor.idProduct) == 0x5003) {
1334 camera_name="Kensington VideoCAM 67016";
1335 button=0;
1336 } else
1337 return -ENODEV;
1338
1339 /* Checking vendor/product should be enough, but what the hell */
1340 if (interface->bInterfaceClass != 0x00)
1341 return -ENODEV;
1342 if (interface->bInterfaceSubClass != 0x00)
1343 return -ENODEV;
1344
1345 /* We found one */
1346 info("SE401 camera found: %s", camera_name);
1347
1348 if ((se401 = kzalloc(sizeof(*se401), GFP_KERNEL)) == NULL) {
1349 err("couldn't kmalloc se401 struct");
1350 return -ENOMEM;
1351 }
1352
1353 se401->dev = dev;
1354 se401->iface = interface->bInterfaceNumber;
1355 se401->camera_name = camera_name;
1356
1357 info("firmware version: %02x", le16_to_cpu(dev->descriptor.bcdDevice) & 255);
1358
1359 if (se401_init(se401, button)) {
1360 kfree(se401);
1361 return -EIO;
1362 }
1363
1364 memcpy(&se401->vdev, &se401_template, sizeof(se401_template));
1365 memcpy(se401->vdev.name, se401->camera_name, strlen(se401->camera_name));
1366 init_waitqueue_head(&se401->wq);
1367 mutex_init(&se401->lock);
1368 wmb();
1369
1370 if (video_register_device(&se401->vdev, VFL_TYPE_GRABBER, video_nr) == -1) {
1371 kfree(se401);
1372 err("video_register_device failed");
1373 return -EIO;
1374 }
1375 info("registered new video device: video%d", se401->vdev.minor);
1376
1377 usb_set_intfdata (intf, se401);
1378 return 0;
1379}
1380
1381static void se401_disconnect(struct usb_interface *intf)
1382{
1383 struct usb_se401 *se401 = usb_get_intfdata (intf);
1384
1385 usb_set_intfdata (intf, NULL);
1386 if (se401) {
1387 video_unregister_device(&se401->vdev);
1388 if (!se401->user){
1389 usb_se401_remove_disconnected(se401);
1390 } else {
1391 se401->frame[0].grabstate = FRAME_ERROR;
1392 se401->frame[0].grabstate = FRAME_ERROR;
1393
1394 se401->streaming = 0;
1395
1396 wake_up_interruptible(&se401->wq);
1397 se401->removed = 1;
1398 }
1399 }
1400}
1401
1402static struct usb_driver se401_driver = {
1403 .name = "se401",
1404 .id_table = device_table,
1405 .probe = se401_probe,
1406 .disconnect = se401_disconnect,
1407};
1408
1409
1410
1411/****************************************************************************
1412 *
1413 * Module routines
1414 *
1415 ***************************************************************************/
1416
1417static int __init usb_se401_init(void)
1418{
1419 info("SE401 usb camera driver version %s registering", version);
1420 if (flickerless)
1421 if (flickerless!=50 && flickerless!=60) {
1422 info("Invallid flickerless value, use 0, 50 or 60.");
1423 return -1;
1424 }
1425 return usb_register(&se401_driver);
1426}
1427
1428static void __exit usb_se401_exit(void)
1429{
1430 usb_deregister(&se401_driver);
1431 info("SE401 driver deregistered");
1432}
1433
1434module_init(usb_se401_init);
1435module_exit(usb_se401_exit);
diff --git a/drivers/media/video/se401.h b/drivers/media/video/se401.h
new file mode 100644
index 000000000000..e88a40d4c86a
--- /dev/null
+++ b/drivers/media/video/se401.h
@@ -0,0 +1,234 @@
1
2#ifndef __LINUX_se401_H
3#define __LINUX_se401_H
4
5#include <asm/uaccess.h>
6#include <linux/videodev.h>
7#include <linux/smp_lock.h>
8#include <linux/mutex.h>
9
10#define se401_DEBUG /* Turn on debug messages */
11
12#ifdef se401_DEBUG
13# define PDEBUG(level, fmt, args...) \
14if (debug >= level) info("[" __PRETTY_FUNCTION__ ":%d] " fmt, __LINE__ , ## args)
15#else
16# define PDEBUG(level, fmt, args...) do {} while(0)
17#endif
18
19/* An almost drop-in replacement for sleep_on_interruptible */
20#define wait_interruptible(test, queue, wait) \
21{ \
22 add_wait_queue(queue, wait); \
23 set_current_state(TASK_INTERRUPTIBLE); \
24 if (test) \
25 schedule(); \
26 remove_wait_queue(queue, wait); \
27 set_current_state(TASK_RUNNING); \
28 if (signal_pending(current)) \
29 break; \
30}
31
32#define SE401_REQ_GET_CAMERA_DESCRIPTOR 0x06
33#define SE401_REQ_START_CONTINUOUS_CAPTURE 0x41
34#define SE401_REQ_STOP_CONTINUOUS_CAPTURE 0x42
35#define SE401_REQ_CAPTURE_FRAME 0x43
36#define SE401_REQ_GET_BRT 0x44
37#define SE401_REQ_SET_BRT 0x45
38#define SE401_REQ_GET_WIDTH 0x4c
39#define SE401_REQ_SET_WIDTH 0x4d
40#define SE401_REQ_GET_HEIGHT 0x4e
41#define SE401_REQ_SET_HEIGHT 0x4f
42#define SE401_REQ_GET_OUTPUT_MODE 0x50
43#define SE401_REQ_SET_OUTPUT_MODE 0x51
44#define SE401_REQ_GET_EXT_FEATURE 0x52
45#define SE401_REQ_SET_EXT_FEATURE 0x53
46#define SE401_REQ_CAMERA_POWER 0x56
47#define SE401_REQ_LED_CONTROL 0x57
48#define SE401_REQ_BIOS 0xff
49
50#define SE401_BIOS_READ 0x07
51
52#define SE401_FORMAT_BAYER 0x40
53
54/* Hyundai hv7131b registers
55 7121 and 7141 should be the same (haven't really checked...) */
56/* Mode registers: */
57#define HV7131_REG_MODE_A 0x00
58#define HV7131_REG_MODE_B 0x01
59#define HV7131_REG_MODE_C 0x02
60/* Frame registers: */
61#define HV7131_REG_FRSU 0x10
62#define HV7131_REG_FRSL 0x11
63#define HV7131_REG_FCSU 0x12
64#define HV7131_REG_FCSL 0x13
65#define HV7131_REG_FWHU 0x14
66#define HV7131_REG_FWHL 0x15
67#define HV7131_REG_FWWU 0x16
68#define HV7131_REG_FWWL 0x17
69/* Timing registers: */
70#define HV7131_REG_THBU 0x20
71#define HV7131_REG_THBL 0x21
72#define HV7131_REG_TVBU 0x22
73#define HV7131_REG_TVBL 0x23
74#define HV7131_REG_TITU 0x25
75#define HV7131_REG_TITM 0x26
76#define HV7131_REG_TITL 0x27
77#define HV7131_REG_TMCD 0x28
78/* Adjust Registers: */
79#define HV7131_REG_ARLV 0x30
80#define HV7131_REG_ARCG 0x31
81#define HV7131_REG_AGCG 0x32
82#define HV7131_REG_ABCG 0x33
83#define HV7131_REG_APBV 0x34
84#define HV7131_REG_ASLP 0x54
85/* Offset Registers: */
86#define HV7131_REG_OFSR 0x50
87#define HV7131_REG_OFSG 0x51
88#define HV7131_REG_OFSB 0x52
89/* REset level statistics registers: */
90#define HV7131_REG_LOREFNOH 0x57
91#define HV7131_REG_LOREFNOL 0x58
92#define HV7131_REG_HIREFNOH 0x59
93#define HV7131_REG_HIREFNOL 0x5a
94
95/* se401 registers */
96#define SE401_OPERATINGMODE 0x2000
97
98
99/* size of usb transfers */
100#define SE401_PACKETSIZE 4096
101/* number of queued bulk transfers to use, should be about 8 */
102#define SE401_NUMSBUF 1
103/* read the usb specs for this one :) */
104#define SE401_VIDEO_ENDPOINT 1
105#define SE401_BUTTON_ENDPOINT 2
106/* number of frames supported by the v4l part */
107#define SE401_NUMFRAMES 2
108/* scratch buffers for passing data to the decoders */
109#define SE401_NUMSCRATCH 32
110/* maximum amount of data in a JangGu packet */
111#define SE401_VLCDATALEN 1024
112/* number of nul sized packets to receive before kicking the camera */
113#define SE401_MAX_NULLPACKETS 4000
114/* number of decoding errors before kicking the camera */
115#define SE401_MAX_ERRORS 200
116
117struct usb_device;
118
119struct se401_sbuf {
120 unsigned char *data;
121};
122
123enum {
124 FRAME_UNUSED, /* Unused (no MCAPTURE) */
125 FRAME_READY, /* Ready to start grabbing */
126 FRAME_GRABBING, /* In the process of being grabbed into */
127 FRAME_DONE, /* Finished grabbing, but not been synced yet */
128 FRAME_ERROR, /* Something bad happened while processing */
129};
130
131enum {
132 FMT_BAYER,
133 FMT_JANGGU,
134};
135
136enum {
137 BUFFER_UNUSED,
138 BUFFER_READY,
139 BUFFER_BUSY,
140 BUFFER_DONE,
141};
142
143struct se401_scratch {
144 unsigned char *data;
145 volatile int state;
146 int offset;
147 int length;
148};
149
150struct se401_frame {
151 unsigned char *data; /* Frame buffer */
152
153 volatile int grabstate; /* State of grabbing */
154
155 unsigned char *curline;
156 int curlinepix;
157 int curpix;
158};
159
160struct usb_se401 {
161 struct video_device vdev;
162
163 /* Device structure */
164 struct usb_device *dev;
165
166 unsigned char iface;
167
168 char *camera_name;
169
170 int change;
171 int brightness;
172 int hue;
173 int rgain;
174 int ggain;
175 int bgain;
176 int expose_h;
177 int expose_m;
178 int expose_l;
179 int resetlevel;
180
181 int enhance;
182
183 int format;
184 int sizes;
185 int *width;
186 int *height;
187 int cwidth; /* current width */
188 int cheight; /* current height */
189 int palette;
190 int maxframesize;
191 int cframesize; /* current framesize */
192
193 struct mutex lock;
194 int user; /* user count for exclusive use */
195 int removed; /* device disconnected */
196
197 int streaming; /* Are we streaming video? */
198
199 char *fbuf; /* Videodev buffer area */
200
201 struct urb *urb[SE401_NUMSBUF];
202 struct urb *inturb;
203
204 int button;
205 int buttonpressed;
206
207 int curframe; /* Current receiving frame */
208 struct se401_frame frame[SE401_NUMFRAMES];
209 int readcount;
210 int framecount;
211 int error;
212 int dropped;
213
214 int scratch_next;
215 int scratch_use;
216 int scratch_overflow;
217 struct se401_scratch scratch[SE401_NUMSCRATCH];
218
219 /* Decoder specific data: */
220 unsigned char vlcdata[SE401_VLCDATALEN];
221 int vlcdatapos;
222 int bayeroffset;
223
224 struct se401_sbuf sbuf[SE401_NUMSBUF];
225
226 wait_queue_head_t wq; /* Processes waiting */
227
228 int nullpackets;
229};
230
231
232
233#endif
234
diff --git a/drivers/media/video/sn9c102/Makefile b/drivers/media/video/sn9c102/Makefile
new file mode 100644
index 000000000000..8bcb0f71d69f
--- /dev/null
+++ b/drivers/media/video/sn9c102/Makefile
@@ -0,0 +1,7 @@
1sn9c102-objs := sn9c102_core.o sn9c102_hv7131d.o sn9c102_mi0343.o \
2 sn9c102_ov7630.o sn9c102_pas106b.o sn9c102_pas202bca.o \
3 sn9c102_pas202bcb.o sn9c102_tas5110c1b.o \
4 sn9c102_tas5130d1b.o
5
6obj-$(CONFIG_USB_SN9C102) += sn9c102.o
7
diff --git a/drivers/media/video/sn9c102/sn9c102.h b/drivers/media/video/sn9c102/sn9c102.h
new file mode 100644
index 000000000000..1d70a62b9f23
--- /dev/null
+++ b/drivers/media/video/sn9c102/sn9c102.h
@@ -0,0 +1,218 @@
1/***************************************************************************
2 * V4L2 driver for SN9C10x PC Camera Controllers *
3 * *
4 * Copyright (C) 2004-2006 by Luca Risolia <luca.risolia@studio.unibo.it> *
5 * *
6 * This program is free software; you can redistribute it and/or modify *
7 * it under the terms of the GNU General Public License as published by *
8 * the Free Software Foundation; either version 2 of the License, or *
9 * (at your option) any later version. *
10 * *
11 * This program is distributed in the hope that it will be useful, *
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14 * GNU General Public License for more details. *
15 * *
16 * You should have received a copy of the GNU General Public License *
17 * along with this program; if not, write to the Free Software *
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
19 ***************************************************************************/
20
21#ifndef _SN9C102_H_
22#define _SN9C102_H_
23
24#include <linux/version.h>
25#include <linux/usb.h>
26#include <linux/videodev2.h>
27#include <media/v4l2-common.h>
28#include <linux/device.h>
29#include <linux/list.h>
30#include <linux/spinlock.h>
31#include <linux/time.h>
32#include <linux/wait.h>
33#include <linux/types.h>
34#include <linux/param.h>
35#include <linux/rwsem.h>
36#include <linux/mutex.h>
37#include <linux/string.h>
38#include <linux/stddef.h>
39
40#include "sn9c102_sensor.h"
41
42/*****************************************************************************/
43
44#define SN9C102_DEBUG
45#define SN9C102_DEBUG_LEVEL 2
46#define SN9C102_MAX_DEVICES 64
47#define SN9C102_PRESERVE_IMGSCALE 0
48#define SN9C102_FORCE_MUNMAP 0
49#define SN9C102_MAX_FRAMES 32
50#define SN9C102_URBS 2
51#define SN9C102_ISO_PACKETS 7
52#define SN9C102_ALTERNATE_SETTING 8
53#define SN9C102_URB_TIMEOUT msecs_to_jiffies(2 * SN9C102_ISO_PACKETS)
54#define SN9C102_CTRL_TIMEOUT 300
55#define SN9C102_FRAME_TIMEOUT 2
56
57/*****************************************************************************/
58
59enum sn9c102_bridge {
60 BRIDGE_SN9C101 = 0x01,
61 BRIDGE_SN9C102 = 0x02,
62 BRIDGE_SN9C103 = 0x04,
63};
64
65SN9C102_ID_TABLE
66SN9C102_SENSOR_TABLE
67
68enum sn9c102_frame_state {
69 F_UNUSED,
70 F_QUEUED,
71 F_GRABBING,
72 F_DONE,
73 F_ERROR,
74};
75
76struct sn9c102_frame_t {
77 void* bufmem;
78 struct v4l2_buffer buf;
79 enum sn9c102_frame_state state;
80 struct list_head frame;
81 unsigned long vma_use_count;
82};
83
84enum sn9c102_dev_state {
85 DEV_INITIALIZED = 0x01,
86 DEV_DISCONNECTED = 0x02,
87 DEV_MISCONFIGURED = 0x04,
88};
89
90enum sn9c102_io_method {
91 IO_NONE,
92 IO_READ,
93 IO_MMAP,
94};
95
96enum sn9c102_stream_state {
97 STREAM_OFF,
98 STREAM_INTERRUPT,
99 STREAM_ON,
100};
101
102typedef char sn9c103_sof_header_t[18];
103typedef char sn9c102_sof_header_t[12];
104typedef char sn9c102_eof_header_t[4];
105
106struct sn9c102_sysfs_attr {
107 u8 reg, i2c_reg;
108 sn9c103_sof_header_t frame_header;
109};
110
111struct sn9c102_module_param {
112 u8 force_munmap;
113 u16 frame_timeout;
114};
115
116static DEFINE_MUTEX(sn9c102_sysfs_lock);
117static DECLARE_RWSEM(sn9c102_disconnect);
118
119struct sn9c102_device {
120 struct video_device* v4ldev;
121
122 enum sn9c102_bridge bridge;
123 struct sn9c102_sensor sensor;
124
125 struct usb_device* usbdev;
126 struct urb* urb[SN9C102_URBS];
127 void* transfer_buffer[SN9C102_URBS];
128 u8* control_buffer;
129
130 struct sn9c102_frame_t *frame_current, frame[SN9C102_MAX_FRAMES];
131 struct list_head inqueue, outqueue;
132 u32 frame_count, nbuffers, nreadbuffers;
133
134 enum sn9c102_io_method io;
135 enum sn9c102_stream_state stream;
136
137 struct v4l2_jpegcompression compression;
138
139 struct sn9c102_sysfs_attr sysfs;
140 sn9c103_sof_header_t sof_header;
141 u16 reg[63];
142
143 struct sn9c102_module_param module_param;
144
145 enum sn9c102_dev_state state;
146 u8 users;
147
148 struct mutex dev_mutex, fileop_mutex;
149 spinlock_t queue_lock;
150 wait_queue_head_t open, wait_frame, wait_stream;
151};
152
153/*****************************************************************************/
154
155struct sn9c102_device*
156sn9c102_match_id(struct sn9c102_device* cam, const struct usb_device_id *id)
157{
158 if (usb_match_id(usb_ifnum_to_if(cam->usbdev, 0), id))
159 return cam;
160
161 return NULL;
162}
163
164
165void
166sn9c102_attach_sensor(struct sn9c102_device* cam,
167 struct sn9c102_sensor* sensor)
168{
169 memcpy(&cam->sensor, sensor, sizeof(struct sn9c102_sensor));
170}
171
172/*****************************************************************************/
173
174#undef DBG
175#undef KDBG
176#ifdef SN9C102_DEBUG
177# define DBG(level, fmt, args...) \
178do { \
179 if (debug >= (level)) { \
180 if ((level) == 1) \
181 dev_err(&cam->usbdev->dev, fmt "\n", ## args); \
182 else if ((level) == 2) \
183 dev_info(&cam->usbdev->dev, fmt "\n", ## args); \
184 else if ((level) >= 3) \
185 dev_info(&cam->usbdev->dev, "[%s:%d] " fmt "\n", \
186 __FUNCTION__, __LINE__ , ## args); \
187 } \
188} while (0)
189# define V4LDBG(level, name, cmd) \
190do { \
191 if (debug >= (level)) \
192 v4l_print_ioctl(name, cmd); \
193} while (0)
194# define KDBG(level, fmt, args...) \
195do { \
196 if (debug >= (level)) { \
197 if ((level) == 1 || (level) == 2) \
198 pr_info("sn9c102: " fmt "\n", ## args); \
199 else if ((level) == 3) \
200 pr_debug("sn9c102: [%s:%d] " fmt "\n", __FUNCTION__, \
201 __LINE__ , ## args); \
202 } \
203} while (0)
204#else
205# define DBG(level, fmt, args...) do {;} while(0)
206# define V4LDBG(level, name, cmd) do {;} while(0)
207# define KDBG(level, fmt, args...) do {;} while(0)
208#endif
209
210#undef PDBG
211#define PDBG(fmt, args...) \
212dev_info(&cam->usbdev->dev, "[%s:%d] " fmt "\n", \
213 __FUNCTION__, __LINE__ , ## args)
214
215#undef PDBGG
216#define PDBGG(fmt, args...) do {;} while(0) /* placeholder */
217
218#endif /* _SN9C102_H_ */
diff --git a/drivers/media/video/sn9c102/sn9c102_core.c b/drivers/media/video/sn9c102/sn9c102_core.c
new file mode 100644
index 000000000000..4c6cc6395723
--- /dev/null
+++ b/drivers/media/video/sn9c102/sn9c102_core.c
@@ -0,0 +1,2919 @@
1/***************************************************************************
2 * V4L2 driver for SN9C10x PC Camera Controllers *
3 * *
4 * Copyright (C) 2004-2006 by Luca Risolia <luca.risolia@studio.unibo.it> *
5 * *
6 * This program is free software; you can redistribute it and/or modify *
7 * it under the terms of the GNU General Public License as published by *
8 * the Free Software Foundation; either version 2 of the License, or *
9 * (at your option) any later version. *
10 * *
11 * This program is distributed in the hope that it will be useful, *
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14 * GNU General Public License for more details. *
15 * *
16 * You should have received a copy of the GNU General Public License *
17 * along with this program; if not, write to the Free Software *
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
19 ***************************************************************************/
20
21#include <linux/module.h>
22#include <linux/init.h>
23#include <linux/kernel.h>
24#include <linux/param.h>
25#include <linux/moduleparam.h>
26#include <linux/errno.h>
27#include <linux/slab.h>
28#include <linux/device.h>
29#include <linux/fs.h>
30#include <linux/delay.h>
31#include <linux/compiler.h>
32#include <linux/ioctl.h>
33#include <linux/poll.h>
34#include <linux/stat.h>
35#include <linux/mm.h>
36#include <linux/vmalloc.h>
37#include <linux/page-flags.h>
38#include <linux/byteorder/generic.h>
39#include <asm/page.h>
40#include <asm/uaccess.h>
41
42#include "sn9c102.h"
43
44/*****************************************************************************/
45
46#define SN9C102_MODULE_NAME "V4L2 driver for SN9C10x PC Camera Controllers"
47#define SN9C102_MODULE_AUTHOR "(C) 2004-2006 Luca Risolia"
48#define SN9C102_AUTHOR_EMAIL "<luca.risolia@studio.unibo.it>"
49#define SN9C102_MODULE_LICENSE "GPL"
50#define SN9C102_MODULE_VERSION "1:1.27"
51#define SN9C102_MODULE_VERSION_CODE KERNEL_VERSION(1, 0, 27)
52
53/*****************************************************************************/
54
55MODULE_DEVICE_TABLE(usb, sn9c102_id_table);
56
57MODULE_AUTHOR(SN9C102_MODULE_AUTHOR " " SN9C102_AUTHOR_EMAIL);
58MODULE_DESCRIPTION(SN9C102_MODULE_NAME);
59MODULE_VERSION(SN9C102_MODULE_VERSION);
60MODULE_LICENSE(SN9C102_MODULE_LICENSE);
61
62static short video_nr[] = {[0 ... SN9C102_MAX_DEVICES-1] = -1};
63module_param_array(video_nr, short, NULL, 0444);
64MODULE_PARM_DESC(video_nr,
65 "\n<-1|n[,...]> Specify V4L2 minor mode number."
66 "\n -1 = use next available (default)"
67 "\n n = use minor number n (integer >= 0)"
68 "\nYou can specify up to "__MODULE_STRING(SN9C102_MAX_DEVICES)
69 " cameras this way."
70 "\nFor example:"
71 "\nvideo_nr=-1,2,-1 would assign minor number 2 to"
72 "\nthe second camera and use auto for the first"
73 "\none and for every other camera."
74 "\n");
75
76static short force_munmap[] = {[0 ... SN9C102_MAX_DEVICES-1] =
77 SN9C102_FORCE_MUNMAP};
78module_param_array(force_munmap, bool, NULL, 0444);
79MODULE_PARM_DESC(force_munmap,
80 "\n<0|1[,...]> Force the application to unmap previously"
81 "\nmapped buffer memory before calling any VIDIOC_S_CROP or"
82 "\nVIDIOC_S_FMT ioctl's. Not all the applications support"
83 "\nthis feature. This parameter is specific for each"
84 "\ndetected camera."
85 "\n 0 = do not force memory unmapping"
86 "\n 1 = force memory unmapping (save memory)"
87 "\nDefault value is "__MODULE_STRING(SN9C102_FORCE_MUNMAP)"."
88 "\n");
89
90static unsigned int frame_timeout[] = {[0 ... SN9C102_MAX_DEVICES-1] =
91 SN9C102_FRAME_TIMEOUT};
92module_param_array(frame_timeout, uint, NULL, 0644);
93MODULE_PARM_DESC(frame_timeout,
94 "\n<n[,...]> Timeout for a video frame in seconds."
95 "\nThis parameter is specific for each detected camera."
96 "\nDefault value is "__MODULE_STRING(SN9C102_FRAME_TIMEOUT)"."
97 "\n");
98
99#ifdef SN9C102_DEBUG
100static unsigned short debug = SN9C102_DEBUG_LEVEL;
101module_param(debug, ushort, 0644);
102MODULE_PARM_DESC(debug,
103 "\n<n> Debugging information level, from 0 to 3:"
104 "\n0 = none (use carefully)"
105 "\n1 = critical errors"
106 "\n2 = significant informations"
107 "\n3 = more verbose messages"
108 "\nLevel 3 is useful for testing only, when only "
109 "one device is used."
110 "\nDefault value is "__MODULE_STRING(SN9C102_DEBUG_LEVEL)"."
111 "\n");
112#endif
113
114/*****************************************************************************/
115
116static sn9c102_sof_header_t sn9c102_sof_header[] = {
117 {0xff, 0xff, 0x00, 0xc4, 0xc4, 0x96, 0x00},
118 {0xff, 0xff, 0x00, 0xc4, 0xc4, 0x96, 0x01},
119};
120
121static sn9c103_sof_header_t sn9c103_sof_header[] = {
122 {0xff, 0xff, 0x00, 0xc4, 0xc4, 0x96, 0x20},
123};
124
125static sn9c102_eof_header_t sn9c102_eof_header[] = {
126 {0x00, 0x00, 0x00, 0x00},
127 {0x40, 0x00, 0x00, 0x00},
128 {0x80, 0x00, 0x00, 0x00},
129 {0xc0, 0x00, 0x00, 0x00},
130};
131
132/*****************************************************************************/
133
134static u32
135sn9c102_request_buffers(struct sn9c102_device* cam, u32 count,
136 enum sn9c102_io_method io)
137{
138 struct v4l2_pix_format* p = &(cam->sensor.pix_format);
139 struct v4l2_rect* r = &(cam->sensor.cropcap.bounds);
140 const size_t imagesize = cam->module_param.force_munmap ||
141 io == IO_READ ?
142 (p->width * p->height * p->priv) / 8 :
143 (r->width * r->height * p->priv) / 8;
144 void* buff = NULL;
145 u32 i;
146
147 if (count > SN9C102_MAX_FRAMES)
148 count = SN9C102_MAX_FRAMES;
149
150 cam->nbuffers = count;
151 while (cam->nbuffers > 0) {
152 if ((buff = vmalloc_32(cam->nbuffers * PAGE_ALIGN(imagesize))))
153 break;
154 cam->nbuffers--;
155 }
156
157 for (i = 0; i < cam->nbuffers; i++) {
158 cam->frame[i].bufmem = buff + i*PAGE_ALIGN(imagesize);
159 cam->frame[i].buf.index = i;
160 cam->frame[i].buf.m.offset = i*PAGE_ALIGN(imagesize);
161 cam->frame[i].buf.length = imagesize;
162 cam->frame[i].buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
163 cam->frame[i].buf.sequence = 0;
164 cam->frame[i].buf.field = V4L2_FIELD_NONE;
165 cam->frame[i].buf.memory = V4L2_MEMORY_MMAP;
166 cam->frame[i].buf.flags = 0;
167 }
168
169 return cam->nbuffers;
170}
171
172
173static void sn9c102_release_buffers(struct sn9c102_device* cam)
174{
175 if (cam->nbuffers) {
176 vfree(cam->frame[0].bufmem);
177 cam->nbuffers = 0;
178 }
179 cam->frame_current = NULL;
180}
181
182
183static void sn9c102_empty_framequeues(struct sn9c102_device* cam)
184{
185 u32 i;
186
187 INIT_LIST_HEAD(&cam->inqueue);
188 INIT_LIST_HEAD(&cam->outqueue);
189
190 for (i = 0; i < SN9C102_MAX_FRAMES; i++) {
191 cam->frame[i].state = F_UNUSED;
192 cam->frame[i].buf.bytesused = 0;
193 }
194}
195
196
197static void sn9c102_requeue_outqueue(struct sn9c102_device* cam)
198{
199 struct sn9c102_frame_t *i;
200
201 list_for_each_entry(i, &cam->outqueue, frame) {
202 i->state = F_QUEUED;
203 list_add(&i->frame, &cam->inqueue);
204 }
205
206 INIT_LIST_HEAD(&cam->outqueue);
207}
208
209
210static void sn9c102_queue_unusedframes(struct sn9c102_device* cam)
211{
212 unsigned long lock_flags;
213 u32 i;
214
215 for (i = 0; i < cam->nbuffers; i++)
216 if (cam->frame[i].state == F_UNUSED) {
217 cam->frame[i].state = F_QUEUED;
218 spin_lock_irqsave(&cam->queue_lock, lock_flags);
219 list_add_tail(&cam->frame[i].frame, &cam->inqueue);
220 spin_unlock_irqrestore(&cam->queue_lock, lock_flags);
221 }
222}
223
224/*****************************************************************************/
225
226int sn9c102_write_regs(struct sn9c102_device* cam, u8* buff, u16 index)
227{
228 struct usb_device* udev = cam->usbdev;
229 int i, res;
230
231 if (index + sizeof(buff) >= ARRAY_SIZE(cam->reg))
232 return -1;
233
234 res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x08, 0x41,
235 index, 0, buff, sizeof(buff),
236 SN9C102_CTRL_TIMEOUT*sizeof(buff));
237 if (res < 0) {
238 DBG(3, "Failed to write registers (index 0x%02X, error %d)",
239 index, res);
240 return -1;
241 }
242
243 for (i = 0; i < sizeof(buff); i++)
244 cam->reg[index+i] = buff[i];
245
246 return 0;
247}
248
249
250int sn9c102_write_reg(struct sn9c102_device* cam, u8 value, u16 index)
251{
252 struct usb_device* udev = cam->usbdev;
253 u8* buff = cam->control_buffer;
254 int res;
255
256 if (index >= ARRAY_SIZE(cam->reg))
257 return -1;
258
259 *buff = value;
260
261 res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x08, 0x41,
262 index, 0, buff, 1, SN9C102_CTRL_TIMEOUT);
263 if (res < 0) {
264 DBG(3, "Failed to write a register (value 0x%02X, index "
265 "0x%02X, error %d)", value, index, res);
266 return -1;
267 }
268
269 cam->reg[index] = value;
270
271 return 0;
272}
273
274
275/* NOTE: reading some registers always returns 0 */
276static int sn9c102_read_reg(struct sn9c102_device* cam, u16 index)
277{
278 struct usb_device* udev = cam->usbdev;
279 u8* buff = cam->control_buffer;
280 int res;
281
282 res = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), 0x00, 0xc1,
283 index, 0, buff, 1, SN9C102_CTRL_TIMEOUT);
284 if (res < 0)
285 DBG(3, "Failed to read a register (index 0x%02X, error %d)",
286 index, res);
287
288 return (res >= 0) ? (int)(*buff) : -1;
289}
290
291
292int sn9c102_pread_reg(struct sn9c102_device* cam, u16 index)
293{
294 if (index >= ARRAY_SIZE(cam->reg))
295 return -1;
296
297 return cam->reg[index];
298}
299
300
301static int
302sn9c102_i2c_wait(struct sn9c102_device* cam, struct sn9c102_sensor* sensor)
303{
304 int i, r;
305
306 for (i = 1; i <= 5; i++) {
307 r = sn9c102_read_reg(cam, 0x08);
308 if (r < 0)
309 return -EIO;
310 if (r & 0x04)
311 return 0;
312 if (sensor->frequency & SN9C102_I2C_400KHZ)
313 udelay(5*16);
314 else
315 udelay(16*16);
316 }
317 return -EBUSY;
318}
319
320
321static int
322sn9c102_i2c_detect_read_error(struct sn9c102_device* cam,
323 struct sn9c102_sensor* sensor)
324{
325 int r;
326 r = sn9c102_read_reg(cam, 0x08);
327 return (r < 0 || (r >= 0 && !(r & 0x08))) ? -EIO : 0;
328}
329
330
331static int
332sn9c102_i2c_detect_write_error(struct sn9c102_device* cam,
333 struct sn9c102_sensor* sensor)
334{
335 int r;
336 r = sn9c102_read_reg(cam, 0x08);
337 return (r < 0 || (r >= 0 && (r & 0x08))) ? -EIO : 0;
338}
339
340
341int
342sn9c102_i2c_try_raw_read(struct sn9c102_device* cam,
343 struct sn9c102_sensor* sensor, u8 data0, u8 data1,
344 u8 n, u8 buffer[])
345{
346 struct usb_device* udev = cam->usbdev;
347 u8* data = cam->control_buffer;
348 int err = 0, res;
349
350 /* Write cycle */
351 data[0] = ((sensor->interface == SN9C102_I2C_2WIRES) ? 0x80 : 0) |
352 ((sensor->frequency & SN9C102_I2C_400KHZ) ? 0x01 : 0) | 0x10;
353 data[1] = data0; /* I2C slave id */
354 data[2] = data1; /* address */
355 data[7] = 0x10;
356 res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x08, 0x41,
357 0x08, 0, data, 8, SN9C102_CTRL_TIMEOUT);
358 if (res < 0)
359 err += res;
360
361 err += sn9c102_i2c_wait(cam, sensor);
362
363 /* Read cycle - n bytes */
364 data[0] = ((sensor->interface == SN9C102_I2C_2WIRES) ? 0x80 : 0) |
365 ((sensor->frequency & SN9C102_I2C_400KHZ) ? 0x01 : 0) |
366 (n << 4) | 0x02;
367 data[1] = data0;
368 data[7] = 0x10;
369 res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x08, 0x41,
370 0x08, 0, data, 8, SN9C102_CTRL_TIMEOUT);
371 if (res < 0)
372 err += res;
373
374 err += sn9c102_i2c_wait(cam, sensor);
375
376 /* The first read byte will be placed in data[4] */
377 res = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), 0x00, 0xc1,
378 0x0a, 0, data, 5, SN9C102_CTRL_TIMEOUT);
379 if (res < 0)
380 err += res;
381
382 err += sn9c102_i2c_detect_read_error(cam, sensor);
383
384 PDBGG("I2C read: address 0x%02X, first read byte: 0x%02X", data1,
385 data[4]);
386
387 if (err) {
388 DBG(3, "I2C read failed for %s image sensor", sensor->name);
389 return -1;
390 }
391
392 if (buffer)
393 memcpy(buffer, data, sizeof(buffer));
394
395 return (int)data[4];
396}
397
398
399int
400sn9c102_i2c_try_raw_write(struct sn9c102_device* cam,
401 struct sn9c102_sensor* sensor, u8 n, u8 data0,
402 u8 data1, u8 data2, u8 data3, u8 data4, u8 data5)
403{
404 struct usb_device* udev = cam->usbdev;
405 u8* data = cam->control_buffer;
406 int err = 0, res;
407
408 /* Write cycle. It usually is address + value */
409 data[0] = ((sensor->interface == SN9C102_I2C_2WIRES) ? 0x80 : 0) |
410 ((sensor->frequency & SN9C102_I2C_400KHZ) ? 0x01 : 0)
411 | ((n - 1) << 4);
412 data[1] = data0;
413 data[2] = data1;
414 data[3] = data2;
415 data[4] = data3;
416 data[5] = data4;
417 data[6] = data5;
418 data[7] = 0x14;
419 res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x08, 0x41,
420 0x08, 0, data, 8, SN9C102_CTRL_TIMEOUT);
421 if (res < 0)
422 err += res;
423
424 err += sn9c102_i2c_wait(cam, sensor);
425 err += sn9c102_i2c_detect_write_error(cam, sensor);
426
427 if (err)
428 DBG(3, "I2C write failed for %s image sensor", sensor->name);
429
430 PDBGG("I2C raw write: %u bytes, data0 = 0x%02X, data1 = 0x%02X, "
431 "data2 = 0x%02X, data3 = 0x%02X, data4 = 0x%02X, data5 = 0x%02X",
432 n, data0, data1, data2, data3, data4, data5);
433
434 return err ? -1 : 0;
435}
436
437
438int
439sn9c102_i2c_try_read(struct sn9c102_device* cam,
440 struct sn9c102_sensor* sensor, u8 address)
441{
442 return sn9c102_i2c_try_raw_read(cam, sensor, sensor->i2c_slave_id,
443 address, 1, NULL);
444}
445
446
447int
448sn9c102_i2c_try_write(struct sn9c102_device* cam,
449 struct sn9c102_sensor* sensor, u8 address, u8 value)
450{
451 return sn9c102_i2c_try_raw_write(cam, sensor, 3,
452 sensor->i2c_slave_id, address,
453 value, 0, 0, 0);
454}
455
456
457int sn9c102_i2c_read(struct sn9c102_device* cam, u8 address)
458{
459 return sn9c102_i2c_try_read(cam, &cam->sensor, address);
460}
461
462
463int sn9c102_i2c_write(struct sn9c102_device* cam, u8 address, u8 value)
464{
465 return sn9c102_i2c_try_write(cam, &cam->sensor, address, value);
466}
467
468/*****************************************************************************/
469
470static void*
471sn9c102_find_sof_header(struct sn9c102_device* cam, void* mem, size_t len)
472{
473 size_t soflen = 0, i;
474 u8 j, n = 0;
475
476 switch (cam->bridge) {
477 case BRIDGE_SN9C101:
478 case BRIDGE_SN9C102:
479 soflen = sizeof(sn9c102_sof_header_t);
480 n = sizeof(sn9c102_sof_header) / soflen;
481 break;
482 case BRIDGE_SN9C103:
483 soflen = sizeof(sn9c103_sof_header_t);
484 n = sizeof(sn9c103_sof_header) / soflen;
485 }
486
487 for (i = 0; (len >= soflen) && (i <= len - soflen); i++)
488 for (j = 0; j < n; j++)
489 /* The invariable part of the header is 6 bytes long */
490 if ((cam->bridge != BRIDGE_SN9C103 &&
491 !memcmp(mem + i, sn9c102_sof_header[j], 6)) ||
492 (cam->bridge == BRIDGE_SN9C103 &&
493 !memcmp(mem + i, sn9c103_sof_header[j], 6))) {
494 memcpy(cam->sof_header, mem + i, soflen);
495 /* Skip the header */
496 return mem + i + soflen;
497 }
498
499 return NULL;
500}
501
502
503static void*
504sn9c102_find_eof_header(struct sn9c102_device* cam, void* mem, size_t len)
505{
506 size_t eoflen = sizeof(sn9c102_eof_header_t), i;
507 unsigned j, n = sizeof(sn9c102_eof_header) / eoflen;
508
509 if (cam->sensor.pix_format.pixelformat == V4L2_PIX_FMT_SN9C10X)
510 return NULL; /* EOF header does not exist in compressed data */
511
512 for (i = 0; (len >= eoflen) && (i <= len - eoflen); i++)
513 for (j = 0; j < n; j++)
514 if (!memcmp(mem + i, sn9c102_eof_header[j], eoflen))
515 return mem + i;
516
517 return NULL;
518}
519
520
521static void sn9c102_urb_complete(struct urb *urb, struct pt_regs* regs)
522{
523 struct sn9c102_device* cam = urb->context;
524 struct sn9c102_frame_t** f;
525 size_t imagesize, soflen;
526 u8 i;
527 int err = 0;
528
529 if (urb->status == -ENOENT)
530 return;
531
532 f = &cam->frame_current;
533
534 if (cam->stream == STREAM_INTERRUPT) {
535 cam->stream = STREAM_OFF;
536 if ((*f))
537 (*f)->state = F_QUEUED;
538 DBG(3, "Stream interrupted");
539 wake_up(&cam->wait_stream);
540 }
541
542 if (cam->state & DEV_DISCONNECTED)
543 return;
544
545 if (cam->state & DEV_MISCONFIGURED) {
546 wake_up_interruptible(&cam->wait_frame);
547 return;
548 }
549
550 if (cam->stream == STREAM_OFF || list_empty(&cam->inqueue))
551 goto resubmit_urb;
552
553 if (!(*f))
554 (*f) = list_entry(cam->inqueue.next, struct sn9c102_frame_t,
555 frame);
556
557 imagesize = (cam->sensor.pix_format.width *
558 cam->sensor.pix_format.height *
559 cam->sensor.pix_format.priv) / 8;
560
561 soflen = (cam->bridge) == BRIDGE_SN9C103 ?
562 sizeof(sn9c103_sof_header_t) :
563 sizeof(sn9c102_sof_header_t);
564
565 for (i = 0; i < urb->number_of_packets; i++) {
566 unsigned int img, len, status;
567 void *pos, *sof, *eof;
568
569 len = urb->iso_frame_desc[i].actual_length;
570 status = urb->iso_frame_desc[i].status;
571 pos = urb->iso_frame_desc[i].offset + urb->transfer_buffer;
572
573 if (status) {
574 DBG(3, "Error in isochronous frame");
575 (*f)->state = F_ERROR;
576 continue;
577 }
578
579 PDBGG("Isochrnous frame: length %u, #%u i", len, i);
580
581redo:
582 sof = sn9c102_find_sof_header(cam, pos, len);
583 if (likely(!sof)) {
584 eof = sn9c102_find_eof_header(cam, pos, len);
585 if ((*f)->state == F_GRABBING) {
586end_of_frame:
587 img = len;
588
589 if (eof)
590 img = (eof > pos) ? eof - pos - 1 : 0;
591
592 if ((*f)->buf.bytesused+img > imagesize) {
593 u32 b;
594 b = (*f)->buf.bytesused + img -
595 imagesize;
596 img = imagesize - (*f)->buf.bytesused;
597 DBG(3, "Expected EOF not found: "
598 "video frame cut");
599 if (eof)
600 DBG(3, "Exceeded limit: +%u "
601 "bytes", (unsigned)(b));
602 }
603
604 memcpy((*f)->bufmem + (*f)->buf.bytesused, pos,
605 img);
606
607 if ((*f)->buf.bytesused == 0)
608 do_gettimeofday(&(*f)->buf.timestamp);
609
610 (*f)->buf.bytesused += img;
611
612 if ((*f)->buf.bytesused == imagesize ||
613 (cam->sensor.pix_format.pixelformat ==
614 V4L2_PIX_FMT_SN9C10X && eof)) {
615 u32 b;
616 b = (*f)->buf.bytesused;
617 (*f)->state = F_DONE;
618 (*f)->buf.sequence= ++cam->frame_count;
619 spin_lock(&cam->queue_lock);
620 list_move_tail(&(*f)->frame,
621 &cam->outqueue);
622 if (!list_empty(&cam->inqueue))
623 (*f) = list_entry(
624 cam->inqueue.next,
625 struct sn9c102_frame_t,
626 frame );
627 else
628 (*f) = NULL;
629 spin_unlock(&cam->queue_lock);
630 memcpy(cam->sysfs.frame_header,
631 cam->sof_header, soflen);
632 DBG(3, "Video frame captured: %lu "
633 "bytes", (unsigned long)(b));
634
635 if (!(*f))
636 goto resubmit_urb;
637
638 } else if (eof) {
639 (*f)->state = F_ERROR;
640 DBG(3, "Not expected EOF after %lu "
641 "bytes of image data",
642 (unsigned long)
643 ((*f)->buf.bytesused));
644 }
645
646 if (sof) /* (1) */
647 goto start_of_frame;
648
649 } else if (eof) {
650 DBG(3, "EOF without SOF");
651 continue;
652
653 } else {
654 PDBGG("Ignoring pointless isochronous frame");
655 continue;
656 }
657
658 } else if ((*f)->state == F_QUEUED || (*f)->state == F_ERROR) {
659start_of_frame:
660 (*f)->state = F_GRABBING;
661 (*f)->buf.bytesused = 0;
662 len -= (sof - pos);
663 pos = sof;
664 DBG(3, "SOF detected: new video frame");
665 if (len)
666 goto redo;
667
668 } else if ((*f)->state == F_GRABBING) {
669 eof = sn9c102_find_eof_header(cam, pos, len);
670 if (eof && eof < sof)
671 goto end_of_frame; /* (1) */
672 else {
673 if (cam->sensor.pix_format.pixelformat ==
674 V4L2_PIX_FMT_SN9C10X) {
675 eof = sof - soflen;
676 goto end_of_frame;
677 } else {
678 DBG(3, "SOF before expected EOF after "
679 "%lu bytes of image data",
680 (unsigned long)
681 ((*f)->buf.bytesused));
682 goto start_of_frame;
683 }
684 }
685 }
686 }
687
688resubmit_urb:
689 urb->dev = cam->usbdev;
690 err = usb_submit_urb(urb, GFP_ATOMIC);
691 if (err < 0 && err != -EPERM) {
692 cam->state |= DEV_MISCONFIGURED;
693 DBG(1, "usb_submit_urb() failed");
694 }
695
696 wake_up_interruptible(&cam->wait_frame);
697}
698
699
700static int sn9c102_start_transfer(struct sn9c102_device* cam)
701{
702 struct usb_device *udev = cam->usbdev;
703 struct urb* urb;
704 const unsigned int sn9c102_wMaxPacketSize[] = {0, 128, 256, 384, 512,
705 680, 800, 900, 1023};
706 const unsigned int sn9c103_wMaxPacketSize[] = {0, 128, 256, 384, 512,
707 680, 800, 900, 1003};
708 const unsigned int psz = (cam->bridge == BRIDGE_SN9C103) ?
709 sn9c103_wMaxPacketSize[SN9C102_ALTERNATE_SETTING] :
710 sn9c102_wMaxPacketSize[SN9C102_ALTERNATE_SETTING];
711 s8 i, j;
712 int err = 0;
713
714 for (i = 0; i < SN9C102_URBS; i++) {
715 cam->transfer_buffer[i] = kzalloc(SN9C102_ISO_PACKETS * psz,
716 GFP_KERNEL);
717 if (!cam->transfer_buffer[i]) {
718 err = -ENOMEM;
719 DBG(1, "Not enough memory");
720 goto free_buffers;
721 }
722 }
723
724 for (i = 0; i < SN9C102_URBS; i++) {
725 urb = usb_alloc_urb(SN9C102_ISO_PACKETS, GFP_KERNEL);
726 cam->urb[i] = urb;
727 if (!urb) {
728 err = -ENOMEM;
729 DBG(1, "usb_alloc_urb() failed");
730 goto free_urbs;
731 }
732 urb->dev = udev;
733 urb->context = cam;
734 urb->pipe = usb_rcvisocpipe(udev, 1);
735 urb->transfer_flags = URB_ISO_ASAP;
736 urb->number_of_packets = SN9C102_ISO_PACKETS;
737 urb->complete = sn9c102_urb_complete;
738 urb->transfer_buffer = cam->transfer_buffer[i];
739 urb->transfer_buffer_length = psz * SN9C102_ISO_PACKETS;
740 urb->interval = 1;
741 for (j = 0; j < SN9C102_ISO_PACKETS; j++) {
742 urb->iso_frame_desc[j].offset = psz * j;
743 urb->iso_frame_desc[j].length = psz;
744 }
745 }
746
747 /* Enable video */
748 if (!(cam->reg[0x01] & 0x04)) {
749 err = sn9c102_write_reg(cam, cam->reg[0x01] | 0x04, 0x01);
750 if (err) {
751 err = -EIO;
752 DBG(1, "I/O hardware error");
753 goto free_urbs;
754 }
755 }
756
757 err = usb_set_interface(udev, 0, SN9C102_ALTERNATE_SETTING);
758 if (err) {
759 DBG(1, "usb_set_interface() failed");
760 goto free_urbs;
761 }
762
763 cam->frame_current = NULL;
764
765 for (i = 0; i < SN9C102_URBS; i++) {
766 err = usb_submit_urb(cam->urb[i], GFP_KERNEL);
767 if (err) {
768 for (j = i-1; j >= 0; j--)
769 usb_kill_urb(cam->urb[j]);
770 DBG(1, "usb_submit_urb() failed, error %d", err);
771 goto free_urbs;
772 }
773 }
774
775 return 0;
776
777free_urbs:
778 for (i = 0; (i < SN9C102_URBS) && cam->urb[i]; i++)
779 usb_free_urb(cam->urb[i]);
780
781free_buffers:
782 for (i = 0; (i < SN9C102_URBS) && cam->transfer_buffer[i]; i++)
783 kfree(cam->transfer_buffer[i]);
784
785 return err;
786}
787
788
789static int sn9c102_stop_transfer(struct sn9c102_device* cam)
790{
791 struct usb_device *udev = cam->usbdev;
792 s8 i;
793 int err = 0;
794
795 if (cam->state & DEV_DISCONNECTED)
796 return 0;
797
798 for (i = SN9C102_URBS-1; i >= 0; i--) {
799 usb_kill_urb(cam->urb[i]);
800 usb_free_urb(cam->urb[i]);
801 kfree(cam->transfer_buffer[i]);
802 }
803
804 err = usb_set_interface(udev, 0, 0); /* 0 Mb/s */
805 if (err)
806 DBG(3, "usb_set_interface() failed");
807
808 return err;
809}
810
811
812static int sn9c102_stream_interrupt(struct sn9c102_device* cam)
813{
814 long timeout;
815
816 cam->stream = STREAM_INTERRUPT;
817 timeout = wait_event_timeout(cam->wait_stream,
818 (cam->stream == STREAM_OFF) ||
819 (cam->state & DEV_DISCONNECTED),
820 SN9C102_URB_TIMEOUT);
821 if (cam->state & DEV_DISCONNECTED)
822 return -ENODEV;
823 else if (cam->stream != STREAM_OFF) {
824 cam->state |= DEV_MISCONFIGURED;
825 DBG(1, "URB timeout reached. The camera is misconfigured. "
826 "To use it, close and open /dev/video%d again.",
827 cam->v4ldev->minor);
828 return -EIO;
829 }
830
831 return 0;
832}
833
834/*****************************************************************************/
835
836#ifdef CONFIG_VIDEO_ADV_DEBUG
837static u8 sn9c102_strtou8(const char* buff, size_t len, ssize_t* count)
838{
839 char str[5];
840 char* endp;
841 unsigned long val;
842
843 if (len < 4) {
844 strncpy(str, buff, len);
845 str[len+1] = '\0';
846 } else {
847 strncpy(str, buff, 4);
848 str[4] = '\0';
849 }
850
851 val = simple_strtoul(str, &endp, 0);
852
853 *count = 0;
854 if (val <= 0xff)
855 *count = (ssize_t)(endp - str);
856 if ((*count) && (len == *count+1) && (buff[*count] == '\n'))
857 *count += 1;
858
859 return (u8)val;
860}
861
862/*
863 NOTE 1: being inside one of the following methods implies that the v4l
864 device exists for sure (see kobjects and reference counters)
865 NOTE 2: buffers are PAGE_SIZE long
866*/
867
868static ssize_t sn9c102_show_reg(struct class_device* cd, char* buf)
869{
870 struct sn9c102_device* cam;
871 ssize_t count;
872
873 if (mutex_lock_interruptible(&sn9c102_sysfs_lock))
874 return -ERESTARTSYS;
875
876 cam = video_get_drvdata(to_video_device(cd));
877 if (!cam) {
878 mutex_unlock(&sn9c102_sysfs_lock);
879 return -ENODEV;
880 }
881
882 count = sprintf(buf, "%u\n", cam->sysfs.reg);
883
884 mutex_unlock(&sn9c102_sysfs_lock);
885
886 return count;
887}
888
889
890static ssize_t
891sn9c102_store_reg(struct class_device* cd, const char* buf, size_t len)
892{
893 struct sn9c102_device* cam;
894 u8 index;
895 ssize_t count;
896
897 if (mutex_lock_interruptible(&sn9c102_sysfs_lock))
898 return -ERESTARTSYS;
899
900 cam = video_get_drvdata(to_video_device(cd));
901 if (!cam) {
902 mutex_unlock(&sn9c102_sysfs_lock);
903 return -ENODEV;
904 }
905
906 index = sn9c102_strtou8(buf, len, &count);
907 if (index > 0x1f || !count) {
908 mutex_unlock(&sn9c102_sysfs_lock);
909 return -EINVAL;
910 }
911
912 cam->sysfs.reg = index;
913
914 DBG(2, "Moved SN9C10X register index to 0x%02X", cam->sysfs.reg);
915 DBG(3, "Written bytes: %zd", count);
916
917 mutex_unlock(&sn9c102_sysfs_lock);
918
919 return count;
920}
921
922
923static ssize_t sn9c102_show_val(struct class_device* cd, char* buf)
924{
925 struct sn9c102_device* cam;
926 ssize_t count;
927 int val;
928
929 if (mutex_lock_interruptible(&sn9c102_sysfs_lock))
930 return -ERESTARTSYS;
931
932 cam = video_get_drvdata(to_video_device(cd));
933 if (!cam) {
934 mutex_unlock(&sn9c102_sysfs_lock);
935 return -ENODEV;
936 }
937
938 if ((val = sn9c102_read_reg(cam, cam->sysfs.reg)) < 0) {
939 mutex_unlock(&sn9c102_sysfs_lock);
940 return -EIO;
941 }
942
943 count = sprintf(buf, "%d\n", val);
944
945 DBG(3, "Read bytes: %zd", count);
946
947 mutex_unlock(&sn9c102_sysfs_lock);
948
949 return count;
950}
951
952
953static ssize_t
954sn9c102_store_val(struct class_device* cd, const char* buf, size_t len)
955{
956 struct sn9c102_device* cam;
957 u8 value;
958 ssize_t count;
959 int err;
960
961 if (mutex_lock_interruptible(&sn9c102_sysfs_lock))
962 return -ERESTARTSYS;
963
964 cam = video_get_drvdata(to_video_device(cd));
965 if (!cam) {
966 mutex_unlock(&sn9c102_sysfs_lock);
967 return -ENODEV;
968 }
969
970 value = sn9c102_strtou8(buf, len, &count);
971 if (!count) {
972 mutex_unlock(&sn9c102_sysfs_lock);
973 return -EINVAL;
974 }
975
976 err = sn9c102_write_reg(cam, value, cam->sysfs.reg);
977 if (err) {
978 mutex_unlock(&sn9c102_sysfs_lock);
979 return -EIO;
980 }
981
982 DBG(2, "Written SN9C10X reg. 0x%02X, val. 0x%02X",
983 cam->sysfs.reg, value);
984 DBG(3, "Written bytes: %zd", count);
985
986 mutex_unlock(&sn9c102_sysfs_lock);
987
988 return count;
989}
990
991
992static ssize_t sn9c102_show_i2c_reg(struct class_device* cd, char* buf)
993{
994 struct sn9c102_device* cam;
995 ssize_t count;
996
997 if (mutex_lock_interruptible(&sn9c102_sysfs_lock))
998 return -ERESTARTSYS;
999
1000 cam = video_get_drvdata(to_video_device(cd));
1001 if (!cam) {
1002 mutex_unlock(&sn9c102_sysfs_lock);
1003 return -ENODEV;
1004 }
1005
1006 count = sprintf(buf, "%u\n", cam->sysfs.i2c_reg);
1007
1008 DBG(3, "Read bytes: %zd", count);
1009
1010 mutex_unlock(&sn9c102_sysfs_lock);
1011
1012 return count;
1013}
1014
1015
1016static ssize_t
1017sn9c102_store_i2c_reg(struct class_device* cd, const char* buf, size_t len)
1018{
1019 struct sn9c102_device* cam;
1020 u8 index;
1021 ssize_t count;
1022
1023 if (mutex_lock_interruptible(&sn9c102_sysfs_lock))
1024 return -ERESTARTSYS;
1025
1026 cam = video_get_drvdata(to_video_device(cd));
1027 if (!cam) {
1028 mutex_unlock(&sn9c102_sysfs_lock);
1029 return -ENODEV;
1030 }
1031
1032 index = sn9c102_strtou8(buf, len, &count);
1033 if (!count) {
1034 mutex_unlock(&sn9c102_sysfs_lock);
1035 return -EINVAL;
1036 }
1037
1038 cam->sysfs.i2c_reg = index;
1039
1040 DBG(2, "Moved sensor register index to 0x%02X", cam->sysfs.i2c_reg);
1041 DBG(3, "Written bytes: %zd", count);
1042
1043 mutex_unlock(&sn9c102_sysfs_lock);
1044
1045 return count;
1046}
1047
1048
1049static ssize_t sn9c102_show_i2c_val(struct class_device* cd, char* buf)
1050{
1051 struct sn9c102_device* cam;
1052 ssize_t count;
1053 int val;
1054
1055 if (mutex_lock_interruptible(&sn9c102_sysfs_lock))
1056 return -ERESTARTSYS;
1057
1058 cam = video_get_drvdata(to_video_device(cd));
1059 if (!cam) {
1060 mutex_unlock(&sn9c102_sysfs_lock);
1061 return -ENODEV;
1062 }
1063
1064 if (!(cam->sensor.sysfs_ops & SN9C102_I2C_READ)) {
1065 mutex_unlock(&sn9c102_sysfs_lock);
1066 return -ENOSYS;
1067 }
1068
1069 if ((val = sn9c102_i2c_read(cam, cam->sysfs.i2c_reg)) < 0) {
1070 mutex_unlock(&sn9c102_sysfs_lock);
1071 return -EIO;
1072 }
1073
1074 count = sprintf(buf, "%d\n", val);
1075
1076 DBG(3, "Read bytes: %zd", count);
1077
1078 mutex_unlock(&sn9c102_sysfs_lock);
1079
1080 return count;
1081}
1082
1083
1084static ssize_t
1085sn9c102_store_i2c_val(struct class_device* cd, const char* buf, size_t len)
1086{
1087 struct sn9c102_device* cam;
1088 u8 value;
1089 ssize_t count;
1090 int err;
1091
1092 if (mutex_lock_interruptible(&sn9c102_sysfs_lock))
1093 return -ERESTARTSYS;
1094
1095 cam = video_get_drvdata(to_video_device(cd));
1096 if (!cam) {
1097 mutex_unlock(&sn9c102_sysfs_lock);
1098 return -ENODEV;
1099 }
1100
1101 if (!(cam->sensor.sysfs_ops & SN9C102_I2C_WRITE)) {
1102 mutex_unlock(&sn9c102_sysfs_lock);
1103 return -ENOSYS;
1104 }
1105
1106 value = sn9c102_strtou8(buf, len, &count);
1107 if (!count) {
1108 mutex_unlock(&sn9c102_sysfs_lock);
1109 return -EINVAL;
1110 }
1111
1112 err = sn9c102_i2c_write(cam, cam->sysfs.i2c_reg, value);
1113 if (err) {
1114 mutex_unlock(&sn9c102_sysfs_lock);
1115 return -EIO;
1116 }
1117
1118 DBG(2, "Written sensor reg. 0x%02X, val. 0x%02X",
1119 cam->sysfs.i2c_reg, value);
1120 DBG(3, "Written bytes: %zd", count);
1121
1122 mutex_unlock(&sn9c102_sysfs_lock);
1123
1124 return count;
1125}
1126
1127
1128static ssize_t
1129sn9c102_store_green(struct class_device* cd, const char* buf, size_t len)
1130{
1131 struct sn9c102_device* cam;
1132 enum sn9c102_bridge bridge;
1133 ssize_t res = 0;
1134 u8 value;
1135 ssize_t count;
1136
1137 if (mutex_lock_interruptible(&sn9c102_sysfs_lock))
1138 return -ERESTARTSYS;
1139
1140 cam = video_get_drvdata(to_video_device(cd));
1141 if (!cam) {
1142 mutex_unlock(&sn9c102_sysfs_lock);
1143 return -ENODEV;
1144 }
1145
1146 bridge = cam->bridge;
1147
1148 mutex_unlock(&sn9c102_sysfs_lock);
1149
1150 value = sn9c102_strtou8(buf, len, &count);
1151 if (!count)
1152 return -EINVAL;
1153
1154 switch (bridge) {
1155 case BRIDGE_SN9C101:
1156 case BRIDGE_SN9C102:
1157 if (value > 0x0f)
1158 return -EINVAL;
1159 if ((res = sn9c102_store_reg(cd, "0x11", 4)) >= 0)
1160 res = sn9c102_store_val(cd, buf, len);
1161 break;
1162 case BRIDGE_SN9C103:
1163 if (value > 0x7f)
1164 return -EINVAL;
1165 if ((res = sn9c102_store_reg(cd, "0x04", 4)) >= 0)
1166 res = sn9c102_store_val(cd, buf, len);
1167 break;
1168 }
1169
1170 return res;
1171}
1172
1173
1174static ssize_t
1175sn9c102_store_blue(struct class_device* cd, const char* buf, size_t len)
1176{
1177 ssize_t res = 0;
1178 u8 value;
1179 ssize_t count;
1180
1181 value = sn9c102_strtou8(buf, len, &count);
1182 if (!count || value > 0x7f)
1183 return -EINVAL;
1184
1185 if ((res = sn9c102_store_reg(cd, "0x06", 4)) >= 0)
1186 res = sn9c102_store_val(cd, buf, len);
1187
1188 return res;
1189}
1190
1191
1192static ssize_t
1193sn9c102_store_red(struct class_device* cd, const char* buf, size_t len)
1194{
1195 ssize_t res = 0;
1196 u8 value;
1197 ssize_t count;
1198
1199 value = sn9c102_strtou8(buf, len, &count);
1200 if (!count || value > 0x7f)
1201 return -EINVAL;
1202
1203 if ((res = sn9c102_store_reg(cd, "0x05", 4)) >= 0)
1204 res = sn9c102_store_val(cd, buf, len);
1205
1206 return res;
1207}
1208
1209
1210static ssize_t sn9c102_show_frame_header(struct class_device* cd, char* buf)
1211{
1212 struct sn9c102_device* cam;
1213 ssize_t count;
1214
1215 cam = video_get_drvdata(to_video_device(cd));
1216 if (!cam)
1217 return -ENODEV;
1218
1219 count = sizeof(cam->sysfs.frame_header);
1220 memcpy(buf, cam->sysfs.frame_header, count);
1221
1222 DBG(3, "Frame header, read bytes: %zd", count);
1223
1224 return count;
1225}
1226
1227
1228static CLASS_DEVICE_ATTR(reg, S_IRUGO | S_IWUSR,
1229 sn9c102_show_reg, sn9c102_store_reg);
1230static CLASS_DEVICE_ATTR(val, S_IRUGO | S_IWUSR,
1231 sn9c102_show_val, sn9c102_store_val);
1232static CLASS_DEVICE_ATTR(i2c_reg, S_IRUGO | S_IWUSR,
1233 sn9c102_show_i2c_reg, sn9c102_store_i2c_reg);
1234static CLASS_DEVICE_ATTR(i2c_val, S_IRUGO | S_IWUSR,
1235 sn9c102_show_i2c_val, sn9c102_store_i2c_val);
1236static CLASS_DEVICE_ATTR(green, S_IWUGO, NULL, sn9c102_store_green);
1237static CLASS_DEVICE_ATTR(blue, S_IWUGO, NULL, sn9c102_store_blue);
1238static CLASS_DEVICE_ATTR(red, S_IWUGO, NULL, sn9c102_store_red);
1239static CLASS_DEVICE_ATTR(frame_header, S_IRUGO,
1240 sn9c102_show_frame_header, NULL);
1241
1242
1243static void sn9c102_create_sysfs(struct sn9c102_device* cam)
1244{
1245 struct video_device *v4ldev = cam->v4ldev;
1246
1247 video_device_create_file(v4ldev, &class_device_attr_reg);
1248 video_device_create_file(v4ldev, &class_device_attr_val);
1249 video_device_create_file(v4ldev, &class_device_attr_frame_header);
1250 if (cam->bridge == BRIDGE_SN9C101 || cam->bridge == BRIDGE_SN9C102)
1251 video_device_create_file(v4ldev, &class_device_attr_green);
1252 else if (cam->bridge == BRIDGE_SN9C103) {
1253 video_device_create_file(v4ldev, &class_device_attr_blue);
1254 video_device_create_file(v4ldev, &class_device_attr_red);
1255 }
1256 if (cam->sensor.sysfs_ops) {
1257 video_device_create_file(v4ldev, &class_device_attr_i2c_reg);
1258 video_device_create_file(v4ldev, &class_device_attr_i2c_val);
1259 }
1260}
1261#endif /* CONFIG_VIDEO_ADV_DEBUG */
1262
1263/*****************************************************************************/
1264
1265static int
1266sn9c102_set_pix_format(struct sn9c102_device* cam, struct v4l2_pix_format* pix)
1267{
1268 int err = 0;
1269
1270 if (pix->pixelformat == V4L2_PIX_FMT_SN9C10X)
1271 err += sn9c102_write_reg(cam, cam->reg[0x18] | 0x80, 0x18);
1272 else
1273 err += sn9c102_write_reg(cam, cam->reg[0x18] & 0x7f, 0x18);
1274
1275 return err ? -EIO : 0;
1276}
1277
1278
1279static int
1280sn9c102_set_compression(struct sn9c102_device* cam,
1281 struct v4l2_jpegcompression* compression)
1282{
1283 int err = 0;
1284
1285 if (compression->quality == 0)
1286 err += sn9c102_write_reg(cam, cam->reg[0x17] | 0x01, 0x17);
1287 else if (compression->quality == 1)
1288 err += sn9c102_write_reg(cam, cam->reg[0x17] & 0xfe, 0x17);
1289
1290 return err ? -EIO : 0;
1291}
1292
1293
1294static int sn9c102_set_scale(struct sn9c102_device* cam, u8 scale)
1295{
1296 u8 r = 0;
1297 int err = 0;
1298
1299 if (scale == 1)
1300 r = cam->reg[0x18] & 0xcf;
1301 else if (scale == 2) {
1302 r = cam->reg[0x18] & 0xcf;
1303 r |= 0x10;
1304 } else if (scale == 4)
1305 r = cam->reg[0x18] | 0x20;
1306
1307 err += sn9c102_write_reg(cam, r, 0x18);
1308 if (err)
1309 return -EIO;
1310
1311 PDBGG("Scaling factor: %u", scale);
1312
1313 return 0;
1314}
1315
1316
1317static int sn9c102_set_crop(struct sn9c102_device* cam, struct v4l2_rect* rect)
1318{
1319 struct sn9c102_sensor* s = &cam->sensor;
1320 u8 h_start = (u8)(rect->left - s->cropcap.bounds.left),
1321 v_start = (u8)(rect->top - s->cropcap.bounds.top),
1322 h_size = (u8)(rect->width / 16),
1323 v_size = (u8)(rect->height / 16);
1324 int err = 0;
1325
1326 err += sn9c102_write_reg(cam, h_start, 0x12);
1327 err += sn9c102_write_reg(cam, v_start, 0x13);
1328 err += sn9c102_write_reg(cam, h_size, 0x15);
1329 err += sn9c102_write_reg(cam, v_size, 0x16);
1330 if (err)
1331 return -EIO;
1332
1333 PDBGG("h_start, v_start, h_size, v_size, ho_size, vo_size "
1334 "%u %u %u %u", h_start, v_start, h_size, v_size);
1335
1336 return 0;
1337}
1338
1339
1340static int sn9c102_init(struct sn9c102_device* cam)
1341{
1342 struct sn9c102_sensor* s = &cam->sensor;
1343 struct v4l2_control ctrl;
1344 struct v4l2_queryctrl *qctrl;
1345 struct v4l2_rect* rect;
1346 u8 i = 0;
1347 int err = 0;
1348
1349 if (!(cam->state & DEV_INITIALIZED)) {
1350 init_waitqueue_head(&cam->open);
1351 qctrl = s->qctrl;
1352 rect = &(s->cropcap.defrect);
1353 } else { /* use current values */
1354 qctrl = s->_qctrl;
1355 rect = &(s->_rect);
1356 }
1357
1358 err += sn9c102_set_scale(cam, rect->width / s->pix_format.width);
1359 err += sn9c102_set_crop(cam, rect);
1360 if (err)
1361 return err;
1362
1363 if (s->init) {
1364 err = s->init(cam);
1365 if (err) {
1366 DBG(3, "Sensor initialization failed");
1367 return err;
1368 }
1369 }
1370
1371 if (!(cam->state & DEV_INITIALIZED))
1372 cam->compression.quality = cam->reg[0x17] & 0x01 ? 0 : 1;
1373 else
1374 err += sn9c102_set_compression(cam, &cam->compression);
1375 err += sn9c102_set_pix_format(cam, &s->pix_format);
1376 if (s->set_pix_format)
1377 err += s->set_pix_format(cam, &s->pix_format);
1378 if (err)
1379 return err;
1380
1381 if (s->pix_format.pixelformat == V4L2_PIX_FMT_SN9C10X)
1382 DBG(3, "Compressed video format is active, quality %d",
1383 cam->compression.quality);
1384 else
1385 DBG(3, "Uncompressed video format is active");
1386
1387 if (s->set_crop)
1388 if ((err = s->set_crop(cam, rect))) {
1389 DBG(3, "set_crop() failed");
1390 return err;
1391 }
1392
1393 if (s->set_ctrl) {
1394 for (i = 0; i < ARRAY_SIZE(s->qctrl); i++)
1395 if (s->qctrl[i].id != 0 &&
1396 !(s->qctrl[i].flags & V4L2_CTRL_FLAG_DISABLED)) {
1397 ctrl.id = s->qctrl[i].id;
1398 ctrl.value = qctrl[i].default_value;
1399 err = s->set_ctrl(cam, &ctrl);
1400 if (err) {
1401 DBG(3, "Set %s control failed",
1402 s->qctrl[i].name);
1403 return err;
1404 }
1405 DBG(3, "Image sensor supports '%s' control",
1406 s->qctrl[i].name);
1407 }
1408 }
1409
1410 if (!(cam->state & DEV_INITIALIZED)) {
1411 mutex_init(&cam->fileop_mutex);
1412 spin_lock_init(&cam->queue_lock);
1413 init_waitqueue_head(&cam->wait_frame);
1414 init_waitqueue_head(&cam->wait_stream);
1415 cam->nreadbuffers = 2;
1416 memcpy(s->_qctrl, s->qctrl, sizeof(s->qctrl));
1417 memcpy(&(s->_rect), &(s->cropcap.defrect),
1418 sizeof(struct v4l2_rect));
1419 cam->state |= DEV_INITIALIZED;
1420 }
1421
1422 DBG(2, "Initialization succeeded");
1423 return 0;
1424}
1425
1426
1427static void sn9c102_release_resources(struct sn9c102_device* cam)
1428{
1429 mutex_lock(&sn9c102_sysfs_lock);
1430
1431 DBG(2, "V4L2 device /dev/video%d deregistered", cam->v4ldev->minor);
1432 video_set_drvdata(cam->v4ldev, NULL);
1433 video_unregister_device(cam->v4ldev);
1434
1435 usb_put_dev(cam->usbdev);
1436
1437 mutex_unlock(&sn9c102_sysfs_lock);
1438
1439 kfree(cam->control_buffer);
1440}
1441
1442/*****************************************************************************/
1443
1444static int sn9c102_open(struct inode* inode, struct file* filp)
1445{
1446 struct sn9c102_device* cam;
1447 int err = 0;
1448
1449 /*
1450 This is the only safe way to prevent race conditions with
1451 disconnect
1452 */
1453 if (!down_read_trylock(&sn9c102_disconnect))
1454 return -ERESTARTSYS;
1455
1456 cam = video_get_drvdata(video_devdata(filp));
1457
1458 if (mutex_lock_interruptible(&cam->dev_mutex)) {
1459 up_read(&sn9c102_disconnect);
1460 return -ERESTARTSYS;
1461 }
1462
1463 if (cam->users) {
1464 DBG(2, "Device /dev/video%d is busy...", cam->v4ldev->minor);
1465 if ((filp->f_flags & O_NONBLOCK) ||
1466 (filp->f_flags & O_NDELAY)) {
1467 err = -EWOULDBLOCK;
1468 goto out;
1469 }
1470 mutex_unlock(&cam->dev_mutex);
1471 err = wait_event_interruptible_exclusive(cam->open,
1472 cam->state & DEV_DISCONNECTED
1473 || !cam->users);
1474 if (err) {
1475 up_read(&sn9c102_disconnect);
1476 return err;
1477 }
1478 if (cam->state & DEV_DISCONNECTED) {
1479 up_read(&sn9c102_disconnect);
1480 return -ENODEV;
1481 }
1482 mutex_lock(&cam->dev_mutex);
1483 }
1484
1485
1486 if (cam->state & DEV_MISCONFIGURED) {
1487 err = sn9c102_init(cam);
1488 if (err) {
1489 DBG(1, "Initialization failed again. "
1490 "I will retry on next open().");
1491 goto out;
1492 }
1493 cam->state &= ~DEV_MISCONFIGURED;
1494 }
1495
1496 if ((err = sn9c102_start_transfer(cam)))
1497 goto out;
1498
1499 filp->private_data = cam;
1500 cam->users++;
1501 cam->io = IO_NONE;
1502 cam->stream = STREAM_OFF;
1503 cam->nbuffers = 0;
1504 cam->frame_count = 0;
1505 sn9c102_empty_framequeues(cam);
1506
1507 DBG(3, "Video device /dev/video%d is open", cam->v4ldev->minor);
1508
1509out:
1510 mutex_unlock(&cam->dev_mutex);
1511 up_read(&sn9c102_disconnect);
1512 return err;
1513}
1514
1515
1516static int sn9c102_release(struct inode* inode, struct file* filp)
1517{
1518 struct sn9c102_device* cam = video_get_drvdata(video_devdata(filp));
1519
1520 mutex_lock(&cam->dev_mutex); /* prevent disconnect() to be called */
1521
1522 sn9c102_stop_transfer(cam);
1523
1524 sn9c102_release_buffers(cam);
1525
1526 if (cam->state & DEV_DISCONNECTED) {
1527 sn9c102_release_resources(cam);
1528 mutex_unlock(&cam->dev_mutex);
1529 kfree(cam);
1530 return 0;
1531 }
1532
1533 cam->users--;
1534 wake_up_interruptible_nr(&cam->open, 1);
1535
1536 DBG(3, "Video device /dev/video%d closed", cam->v4ldev->minor);
1537
1538 mutex_unlock(&cam->dev_mutex);
1539
1540 return 0;
1541}
1542
1543
1544static ssize_t
1545sn9c102_read(struct file* filp, char __user * buf, size_t count, loff_t* f_pos)
1546{
1547 struct sn9c102_device* cam = video_get_drvdata(video_devdata(filp));
1548 struct sn9c102_frame_t* f, * i;
1549 unsigned long lock_flags;
1550 long timeout;
1551 int err = 0;
1552
1553 if (mutex_lock_interruptible(&cam->fileop_mutex))
1554 return -ERESTARTSYS;
1555
1556 if (cam->state & DEV_DISCONNECTED) {
1557 DBG(1, "Device not present");
1558 mutex_unlock(&cam->fileop_mutex);
1559 return -ENODEV;
1560 }
1561
1562 if (cam->state & DEV_MISCONFIGURED) {
1563 DBG(1, "The camera is misconfigured. Close and open it "
1564 "again.");
1565 mutex_unlock(&cam->fileop_mutex);
1566 return -EIO;
1567 }
1568
1569 if (cam->io == IO_MMAP) {
1570 DBG(3, "Close and open the device again to choose "
1571 "the read method");
1572 mutex_unlock(&cam->fileop_mutex);
1573 return -EINVAL;
1574 }
1575
1576 if (cam->io == IO_NONE) {
1577 if (!sn9c102_request_buffers(cam,cam->nreadbuffers, IO_READ)) {
1578 DBG(1, "read() failed, not enough memory");
1579 mutex_unlock(&cam->fileop_mutex);
1580 return -ENOMEM;
1581 }
1582 cam->io = IO_READ;
1583 cam->stream = STREAM_ON;
1584 }
1585
1586 if (list_empty(&cam->inqueue)) {
1587 if (!list_empty(&cam->outqueue))
1588 sn9c102_empty_framequeues(cam);
1589 sn9c102_queue_unusedframes(cam);
1590 }
1591
1592 if (!count) {
1593 mutex_unlock(&cam->fileop_mutex);
1594 return 0;
1595 }
1596
1597 if (list_empty(&cam->outqueue)) {
1598 if (filp->f_flags & O_NONBLOCK) {
1599 mutex_unlock(&cam->fileop_mutex);
1600 return -EAGAIN;
1601 }
1602 timeout = wait_event_interruptible_timeout
1603 ( cam->wait_frame,
1604 (!list_empty(&cam->outqueue)) ||
1605 (cam->state & DEV_DISCONNECTED) ||
1606 (cam->state & DEV_MISCONFIGURED),
1607 cam->module_param.frame_timeout *
1608 1000 * msecs_to_jiffies(1) );
1609 if (timeout < 0) {
1610 mutex_unlock(&cam->fileop_mutex);
1611 return timeout;
1612 }
1613 if (cam->state & DEV_DISCONNECTED) {
1614 mutex_unlock(&cam->fileop_mutex);
1615 return -ENODEV;
1616 }
1617 if (!timeout || (cam->state & DEV_MISCONFIGURED)) {
1618 mutex_unlock(&cam->fileop_mutex);
1619 return -EIO;
1620 }
1621 }
1622
1623 f = list_entry(cam->outqueue.prev, struct sn9c102_frame_t, frame);
1624
1625 if (count > f->buf.bytesused)
1626 count = f->buf.bytesused;
1627
1628 if (copy_to_user(buf, f->bufmem, count)) {
1629 err = -EFAULT;
1630 goto exit;
1631 }
1632 *f_pos += count;
1633
1634exit:
1635 spin_lock_irqsave(&cam->queue_lock, lock_flags);
1636 list_for_each_entry(i, &cam->outqueue, frame)
1637 i->state = F_UNUSED;
1638 INIT_LIST_HEAD(&cam->outqueue);
1639 spin_unlock_irqrestore(&cam->queue_lock, lock_flags);
1640
1641 sn9c102_queue_unusedframes(cam);
1642
1643 PDBGG("Frame #%lu, bytes read: %zu",
1644 (unsigned long)f->buf.index, count);
1645
1646 mutex_unlock(&cam->fileop_mutex);
1647
1648 return count;
1649}
1650
1651
1652static unsigned int sn9c102_poll(struct file *filp, poll_table *wait)
1653{
1654 struct sn9c102_device* cam = video_get_drvdata(video_devdata(filp));
1655 struct sn9c102_frame_t* f;
1656 unsigned long lock_flags;
1657 unsigned int mask = 0;
1658
1659 if (mutex_lock_interruptible(&cam->fileop_mutex))
1660 return POLLERR;
1661
1662 if (cam->state & DEV_DISCONNECTED) {
1663 DBG(1, "Device not present");
1664 goto error;
1665 }
1666
1667 if (cam->state & DEV_MISCONFIGURED) {
1668 DBG(1, "The camera is misconfigured. Close and open it "
1669 "again.");
1670 goto error;
1671 }
1672
1673 if (cam->io == IO_NONE) {
1674 if (!sn9c102_request_buffers(cam, cam->nreadbuffers,
1675 IO_READ)) {
1676 DBG(1, "poll() failed, not enough memory");
1677 goto error;
1678 }
1679 cam->io = IO_READ;
1680 cam->stream = STREAM_ON;
1681 }
1682
1683 if (cam->io == IO_READ) {
1684 spin_lock_irqsave(&cam->queue_lock, lock_flags);
1685 list_for_each_entry(f, &cam->outqueue, frame)
1686 f->state = F_UNUSED;
1687 INIT_LIST_HEAD(&cam->outqueue);
1688 spin_unlock_irqrestore(&cam->queue_lock, lock_flags);
1689 sn9c102_queue_unusedframes(cam);
1690 }
1691
1692 poll_wait(filp, &cam->wait_frame, wait);
1693
1694 if (!list_empty(&cam->outqueue))
1695 mask |= POLLIN | POLLRDNORM;
1696
1697 mutex_unlock(&cam->fileop_mutex);
1698
1699 return mask;
1700
1701error:
1702 mutex_unlock(&cam->fileop_mutex);
1703 return POLLERR;
1704}
1705
1706
1707static void sn9c102_vm_open(struct vm_area_struct* vma)
1708{
1709 struct sn9c102_frame_t* f = vma->vm_private_data;
1710 f->vma_use_count++;
1711}
1712
1713
1714static void sn9c102_vm_close(struct vm_area_struct* vma)
1715{
1716 /* NOTE: buffers are not freed here */
1717 struct sn9c102_frame_t* f = vma->vm_private_data;
1718 f->vma_use_count--;
1719}
1720
1721
1722static struct vm_operations_struct sn9c102_vm_ops = {
1723 .open = sn9c102_vm_open,
1724 .close = sn9c102_vm_close,
1725};
1726
1727
1728static int sn9c102_mmap(struct file* filp, struct vm_area_struct *vma)
1729{
1730 struct sn9c102_device* cam = video_get_drvdata(video_devdata(filp));
1731 unsigned long size = vma->vm_end - vma->vm_start,
1732 start = vma->vm_start;
1733 void *pos;
1734 u32 i;
1735
1736 if (mutex_lock_interruptible(&cam->fileop_mutex))
1737 return -ERESTARTSYS;
1738
1739 if (cam->state & DEV_DISCONNECTED) {
1740 DBG(1, "Device not present");
1741 mutex_unlock(&cam->fileop_mutex);
1742 return -ENODEV;
1743 }
1744
1745 if (cam->state & DEV_MISCONFIGURED) {
1746 DBG(1, "The camera is misconfigured. Close and open it "
1747 "again.");
1748 mutex_unlock(&cam->fileop_mutex);
1749 return -EIO;
1750 }
1751
1752 if (cam->io != IO_MMAP || !(vma->vm_flags & VM_WRITE) ||
1753 size != PAGE_ALIGN(cam->frame[0].buf.length)) {
1754 mutex_unlock(&cam->fileop_mutex);
1755 return -EINVAL;
1756 }
1757
1758 for (i = 0; i < cam->nbuffers; i++) {
1759 if ((cam->frame[i].buf.m.offset>>PAGE_SHIFT) == vma->vm_pgoff)
1760 break;
1761 }
1762 if (i == cam->nbuffers) {
1763 mutex_unlock(&cam->fileop_mutex);
1764 return -EINVAL;
1765 }
1766
1767 vma->vm_flags |= VM_IO;
1768 vma->vm_flags |= VM_RESERVED;
1769
1770 pos = cam->frame[i].bufmem;
1771 while (size > 0) { /* size is page-aligned */
1772 if (vm_insert_page(vma, start, vmalloc_to_page(pos))) {
1773 mutex_unlock(&cam->fileop_mutex);
1774 return -EAGAIN;
1775 }
1776 start += PAGE_SIZE;
1777 pos += PAGE_SIZE;
1778 size -= PAGE_SIZE;
1779 }
1780
1781 vma->vm_ops = &sn9c102_vm_ops;
1782 vma->vm_private_data = &cam->frame[i];
1783
1784 sn9c102_vm_open(vma);
1785
1786 mutex_unlock(&cam->fileop_mutex);
1787
1788 return 0;
1789}
1790
1791/*****************************************************************************/
1792
1793static int
1794sn9c102_vidioc_querycap(struct sn9c102_device* cam, void __user * arg)
1795{
1796 struct v4l2_capability cap = {
1797 .driver = "sn9c102",
1798 .version = SN9C102_MODULE_VERSION_CODE,
1799 .capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE |
1800 V4L2_CAP_STREAMING,
1801 };
1802
1803 strlcpy(cap.card, cam->v4ldev->name, sizeof(cap.card));
1804 if (usb_make_path(cam->usbdev, cap.bus_info, sizeof(cap.bus_info)) < 0)
1805 strlcpy(cap.bus_info, cam->usbdev->dev.bus_id,
1806 sizeof(cap.bus_info));
1807
1808 if (copy_to_user(arg, &cap, sizeof(cap)))
1809 return -EFAULT;
1810
1811 return 0;
1812}
1813
1814
1815static int
1816sn9c102_vidioc_enuminput(struct sn9c102_device* cam, void __user * arg)
1817{
1818 struct v4l2_input i;
1819
1820 if (copy_from_user(&i, arg, sizeof(i)))
1821 return -EFAULT;
1822
1823 if (i.index)
1824 return -EINVAL;
1825
1826 memset(&i, 0, sizeof(i));
1827 strcpy(i.name, "Camera");
1828 i.type = V4L2_INPUT_TYPE_CAMERA;
1829
1830 if (copy_to_user(arg, &i, sizeof(i)))
1831 return -EFAULT;
1832
1833 return 0;
1834}
1835
1836
1837static int
1838sn9c102_vidioc_g_input(struct sn9c102_device* cam, void __user * arg)
1839{
1840 int index = 0;
1841
1842 if (copy_to_user(arg, &index, sizeof(index)))
1843 return -EFAULT;
1844
1845 return 0;
1846}
1847
1848
1849static int
1850sn9c102_vidioc_s_input(struct sn9c102_device* cam, void __user * arg)
1851{
1852 int index;
1853
1854 if (copy_from_user(&index, arg, sizeof(index)))
1855 return -EFAULT;
1856
1857 if (index != 0)
1858 return -EINVAL;
1859
1860 return 0;
1861}
1862
1863
1864static int
1865sn9c102_vidioc_query_ctrl(struct sn9c102_device* cam, void __user * arg)
1866{
1867 struct sn9c102_sensor* s = &cam->sensor;
1868 struct v4l2_queryctrl qc;
1869 u8 i;
1870
1871 if (copy_from_user(&qc, arg, sizeof(qc)))
1872 return -EFAULT;
1873
1874 for (i = 0; i < ARRAY_SIZE(s->qctrl); i++)
1875 if (qc.id && qc.id == s->qctrl[i].id) {
1876 memcpy(&qc, &(s->qctrl[i]), sizeof(qc));
1877 if (copy_to_user(arg, &qc, sizeof(qc)))
1878 return -EFAULT;
1879 return 0;
1880 }
1881
1882 return -EINVAL;
1883}
1884
1885
1886static int
1887sn9c102_vidioc_g_ctrl(struct sn9c102_device* cam, void __user * arg)
1888{
1889 struct sn9c102_sensor* s = &cam->sensor;
1890 struct v4l2_control ctrl;
1891 int err = 0;
1892 u8 i;
1893
1894 if (!s->get_ctrl && !s->set_ctrl)
1895 return -EINVAL;
1896
1897 if (copy_from_user(&ctrl, arg, sizeof(ctrl)))
1898 return -EFAULT;
1899
1900 if (!s->get_ctrl) {
1901 for (i = 0; i < ARRAY_SIZE(s->qctrl); i++)
1902 if (ctrl.id && ctrl.id == s->qctrl[i].id) {
1903 ctrl.value = s->_qctrl[i].default_value;
1904 goto exit;
1905 }
1906 return -EINVAL;
1907 } else
1908 err = s->get_ctrl(cam, &ctrl);
1909
1910exit:
1911 if (copy_to_user(arg, &ctrl, sizeof(ctrl)))
1912 return -EFAULT;
1913
1914 return err;
1915}
1916
1917
1918static int
1919sn9c102_vidioc_s_ctrl(struct sn9c102_device* cam, void __user * arg)
1920{
1921 struct sn9c102_sensor* s = &cam->sensor;
1922 struct v4l2_control ctrl;
1923 u8 i;
1924 int err = 0;
1925
1926 if (!s->set_ctrl)
1927 return -EINVAL;
1928
1929 if (copy_from_user(&ctrl, arg, sizeof(ctrl)))
1930 return -EFAULT;
1931
1932 for (i = 0; i < ARRAY_SIZE(s->qctrl); i++)
1933 if (ctrl.id == s->qctrl[i].id) {
1934 if (s->qctrl[i].flags & V4L2_CTRL_FLAG_DISABLED)
1935 return -EINVAL;
1936 if (ctrl.value < s->qctrl[i].minimum ||
1937 ctrl.value > s->qctrl[i].maximum)
1938 return -ERANGE;
1939 ctrl.value -= ctrl.value % s->qctrl[i].step;
1940 break;
1941 }
1942
1943 if ((err = s->set_ctrl(cam, &ctrl)))
1944 return err;
1945
1946 s->_qctrl[i].default_value = ctrl.value;
1947
1948 PDBGG("VIDIOC_S_CTRL: id %lu, value %lu",
1949 (unsigned long)ctrl.id, (unsigned long)ctrl.value);
1950
1951 return 0;
1952}
1953
1954
1955static int
1956sn9c102_vidioc_cropcap(struct sn9c102_device* cam, void __user * arg)
1957{
1958 struct v4l2_cropcap* cc = &(cam->sensor.cropcap);
1959
1960 cc->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1961 cc->pixelaspect.numerator = 1;
1962 cc->pixelaspect.denominator = 1;
1963
1964 if (copy_to_user(arg, cc, sizeof(*cc)))
1965 return -EFAULT;
1966
1967 return 0;
1968}
1969
1970
1971static int
1972sn9c102_vidioc_g_crop(struct sn9c102_device* cam, void __user * arg)
1973{
1974 struct sn9c102_sensor* s = &cam->sensor;
1975 struct v4l2_crop crop = {
1976 .type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
1977 };
1978
1979 memcpy(&(crop.c), &(s->_rect), sizeof(struct v4l2_rect));
1980
1981 if (copy_to_user(arg, &crop, sizeof(crop)))
1982 return -EFAULT;
1983
1984 return 0;
1985}
1986
1987
1988static int
1989sn9c102_vidioc_s_crop(struct sn9c102_device* cam, void __user * arg)
1990{
1991 struct sn9c102_sensor* s = &cam->sensor;
1992 struct v4l2_crop crop;
1993 struct v4l2_rect* rect;
1994 struct v4l2_rect* bounds = &(s->cropcap.bounds);
1995 struct v4l2_pix_format* pix_format = &(s->pix_format);
1996 u8 scale;
1997 const enum sn9c102_stream_state stream = cam->stream;
1998 const u32 nbuffers = cam->nbuffers;
1999 u32 i;
2000 int err = 0;
2001
2002 if (copy_from_user(&crop, arg, sizeof(crop)))
2003 return -EFAULT;
2004
2005 rect = &(crop.c);
2006
2007 if (crop.type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
2008 return -EINVAL;
2009
2010 if (cam->module_param.force_munmap)
2011 for (i = 0; i < cam->nbuffers; i++)
2012 if (cam->frame[i].vma_use_count) {
2013 DBG(3, "VIDIOC_S_CROP failed. "
2014 "Unmap the buffers first.");
2015 return -EINVAL;
2016 }
2017
2018 /* Preserve R,G or B origin */
2019 rect->left = (s->_rect.left & 1L) ? rect->left | 1L : rect->left & ~1L;
2020 rect->top = (s->_rect.top & 1L) ? rect->top | 1L : rect->top & ~1L;
2021
2022 if (rect->width < 16)
2023 rect->width = 16;
2024 if (rect->height < 16)
2025 rect->height = 16;
2026 if (rect->width > bounds->width)
2027 rect->width = bounds->width;
2028 if (rect->height > bounds->height)
2029 rect->height = bounds->height;
2030 if (rect->left < bounds->left)
2031 rect->left = bounds->left;
2032 if (rect->top < bounds->top)
2033 rect->top = bounds->top;
2034 if (rect->left + rect->width > bounds->left + bounds->width)
2035 rect->left = bounds->left+bounds->width - rect->width;
2036 if (rect->top + rect->height > bounds->top + bounds->height)
2037 rect->top = bounds->top+bounds->height - rect->height;
2038
2039 rect->width &= ~15L;
2040 rect->height &= ~15L;
2041
2042 if (SN9C102_PRESERVE_IMGSCALE) {
2043 /* Calculate the actual scaling factor */
2044 u32 a, b;
2045 a = rect->width * rect->height;
2046 b = pix_format->width * pix_format->height;
2047 scale = b ? (u8)((a / b) < 4 ? 1 : ((a / b) < 16 ? 2 : 4)) : 1;
2048 } else
2049 scale = 1;
2050
2051 if (cam->stream == STREAM_ON)
2052 if ((err = sn9c102_stream_interrupt(cam)))
2053 return err;
2054
2055 if (copy_to_user(arg, &crop, sizeof(crop))) {
2056 cam->stream = stream;
2057 return -EFAULT;
2058 }
2059
2060 if (cam->module_param.force_munmap || cam->io == IO_READ)
2061 sn9c102_release_buffers(cam);
2062
2063 err = sn9c102_set_crop(cam, rect);
2064 if (s->set_crop)
2065 err += s->set_crop(cam, rect);
2066 err += sn9c102_set_scale(cam, scale);
2067
2068 if (err) { /* atomic, no rollback in ioctl() */
2069 cam->state |= DEV_MISCONFIGURED;
2070 DBG(1, "VIDIOC_S_CROP failed because of hardware problems. To "
2071 "use the camera, close and open /dev/video%d again.",
2072 cam->v4ldev->minor);
2073 return -EIO;
2074 }
2075
2076 s->pix_format.width = rect->width/scale;
2077 s->pix_format.height = rect->height/scale;
2078 memcpy(&(s->_rect), rect, sizeof(*rect));
2079
2080 if ((cam->module_param.force_munmap || cam->io == IO_READ) &&
2081 nbuffers != sn9c102_request_buffers(cam, nbuffers, cam->io)) {
2082 cam->state |= DEV_MISCONFIGURED;
2083 DBG(1, "VIDIOC_S_CROP failed because of not enough memory. To "
2084 "use the camera, close and open /dev/video%d again.",
2085 cam->v4ldev->minor);
2086 return -ENOMEM;
2087 }
2088
2089 if (cam->io == IO_READ)
2090 sn9c102_empty_framequeues(cam);
2091 else if (cam->module_param.force_munmap)
2092 sn9c102_requeue_outqueue(cam);
2093
2094 cam->stream = stream;
2095
2096 return 0;
2097}
2098
2099
2100static int
2101sn9c102_vidioc_enum_fmt(struct sn9c102_device* cam, void __user * arg)
2102{
2103 struct v4l2_fmtdesc fmtd;
2104
2105 if (copy_from_user(&fmtd, arg, sizeof(fmtd)))
2106 return -EFAULT;
2107
2108 if (fmtd.index == 0) {
2109 strcpy(fmtd.description, "bayer rgb");
2110 fmtd.pixelformat = V4L2_PIX_FMT_SBGGR8;
2111 } else if (fmtd.index == 1) {
2112 strcpy(fmtd.description, "compressed");
2113 fmtd.pixelformat = V4L2_PIX_FMT_SN9C10X;
2114 fmtd.flags = V4L2_FMT_FLAG_COMPRESSED;
2115 } else
2116 return -EINVAL;
2117
2118 fmtd.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
2119 memset(&fmtd.reserved, 0, sizeof(fmtd.reserved));
2120
2121 if (copy_to_user(arg, &fmtd, sizeof(fmtd)))
2122 return -EFAULT;
2123
2124 return 0;
2125}
2126
2127
2128static int
2129sn9c102_vidioc_g_fmt(struct sn9c102_device* cam, void __user * arg)
2130{
2131 struct v4l2_format format;
2132 struct v4l2_pix_format* pfmt = &(cam->sensor.pix_format);
2133
2134 if (copy_from_user(&format, arg, sizeof(format)))
2135 return -EFAULT;
2136
2137 if (format.type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
2138 return -EINVAL;
2139
2140 pfmt->bytesperline = (pfmt->pixelformat==V4L2_PIX_FMT_SN9C10X)
2141 ? 0 : (pfmt->width * pfmt->priv) / 8;
2142 pfmt->sizeimage = pfmt->height * ((pfmt->width*pfmt->priv)/8);
2143 pfmt->field = V4L2_FIELD_NONE;
2144 memcpy(&(format.fmt.pix), pfmt, sizeof(*pfmt));
2145
2146 if (copy_to_user(arg, &format, sizeof(format)))
2147 return -EFAULT;
2148
2149 return 0;
2150}
2151
2152
2153static int
2154sn9c102_vidioc_try_s_fmt(struct sn9c102_device* cam, unsigned int cmd,
2155 void __user * arg)
2156{
2157 struct sn9c102_sensor* s = &cam->sensor;
2158 struct v4l2_format format;
2159 struct v4l2_pix_format* pix;
2160 struct v4l2_pix_format* pfmt = &(s->pix_format);
2161 struct v4l2_rect* bounds = &(s->cropcap.bounds);
2162 struct v4l2_rect rect;
2163 u8 scale;
2164 const enum sn9c102_stream_state stream = cam->stream;
2165 const u32 nbuffers = cam->nbuffers;
2166 u32 i;
2167 int err = 0;
2168
2169 if (copy_from_user(&format, arg, sizeof(format)))
2170 return -EFAULT;
2171
2172 pix = &(format.fmt.pix);
2173
2174 if (format.type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
2175 return -EINVAL;
2176
2177 memcpy(&rect, &(s->_rect), sizeof(rect));
2178
2179 { /* calculate the actual scaling factor */
2180 u32 a, b;
2181 a = rect.width * rect.height;
2182 b = pix->width * pix->height;
2183 scale = b ? (u8)((a / b) < 4 ? 1 : ((a / b) < 16 ? 2 : 4)) : 1;
2184 }
2185
2186 rect.width = scale * pix->width;
2187 rect.height = scale * pix->height;
2188
2189 if (rect.width < 16)
2190 rect.width = 16;
2191 if (rect.height < 16)
2192 rect.height = 16;
2193 if (rect.width > bounds->left + bounds->width - rect.left)
2194 rect.width = bounds->left + bounds->width - rect.left;
2195 if (rect.height > bounds->top + bounds->height - rect.top)
2196 rect.height = bounds->top + bounds->height - rect.top;
2197
2198 rect.width &= ~15L;
2199 rect.height &= ~15L;
2200
2201 { /* adjust the scaling factor */
2202 u32 a, b;
2203 a = rect.width * rect.height;
2204 b = pix->width * pix->height;
2205 scale = b ? (u8)((a / b) < 4 ? 1 : ((a / b) < 16 ? 2 : 4)) : 1;
2206 }
2207
2208 pix->width = rect.width / scale;
2209 pix->height = rect.height / scale;
2210
2211 if (pix->pixelformat != V4L2_PIX_FMT_SN9C10X &&
2212 pix->pixelformat != V4L2_PIX_FMT_SBGGR8)
2213 pix->pixelformat = pfmt->pixelformat;
2214 pix->priv = pfmt->priv; /* bpp */
2215 pix->colorspace = pfmt->colorspace;
2216 pix->bytesperline = (pix->pixelformat == V4L2_PIX_FMT_SN9C10X)
2217 ? 0 : (pix->width * pix->priv) / 8;
2218 pix->sizeimage = pix->height * ((pix->width * pix->priv) / 8);
2219 pix->field = V4L2_FIELD_NONE;
2220
2221 if (cmd == VIDIOC_TRY_FMT) {
2222 if (copy_to_user(arg, &format, sizeof(format)))
2223 return -EFAULT;
2224 return 0;
2225 }
2226
2227 if (cam->module_param.force_munmap)
2228 for (i = 0; i < cam->nbuffers; i++)
2229 if (cam->frame[i].vma_use_count) {
2230 DBG(3, "VIDIOC_S_FMT failed. Unmap the "
2231 "buffers first.");
2232 return -EINVAL;
2233 }
2234
2235 if (cam->stream == STREAM_ON)
2236 if ((err = sn9c102_stream_interrupt(cam)))
2237 return err;
2238
2239 if (copy_to_user(arg, &format, sizeof(format))) {
2240 cam->stream = stream;
2241 return -EFAULT;
2242 }
2243
2244 if (cam->module_param.force_munmap || cam->io == IO_READ)
2245 sn9c102_release_buffers(cam);
2246
2247 err += sn9c102_set_pix_format(cam, pix);
2248 err += sn9c102_set_crop(cam, &rect);
2249 if (s->set_pix_format)
2250 err += s->set_pix_format(cam, pix);
2251 if (s->set_crop)
2252 err += s->set_crop(cam, &rect);
2253 err += sn9c102_set_scale(cam, scale);
2254
2255 if (err) { /* atomic, no rollback in ioctl() */
2256 cam->state |= DEV_MISCONFIGURED;
2257 DBG(1, "VIDIOC_S_FMT failed because of hardware problems. To "
2258 "use the camera, close and open /dev/video%d again.",
2259 cam->v4ldev->minor);
2260 return -EIO;
2261 }
2262
2263 memcpy(pfmt, pix, sizeof(*pix));
2264 memcpy(&(s->_rect), &rect, sizeof(rect));
2265
2266 if ((cam->module_param.force_munmap || cam->io == IO_READ) &&
2267 nbuffers != sn9c102_request_buffers(cam, nbuffers, cam->io)) {
2268 cam->state |= DEV_MISCONFIGURED;
2269 DBG(1, "VIDIOC_S_FMT failed because of not enough memory. To "
2270 "use the camera, close and open /dev/video%d again.",
2271 cam->v4ldev->minor);
2272 return -ENOMEM;
2273 }
2274
2275 if (cam->io == IO_READ)
2276 sn9c102_empty_framequeues(cam);
2277 else if (cam->module_param.force_munmap)
2278 sn9c102_requeue_outqueue(cam);
2279
2280 cam->stream = stream;
2281
2282 return 0;
2283}
2284
2285
2286static int
2287sn9c102_vidioc_g_jpegcomp(struct sn9c102_device* cam, void __user * arg)
2288{
2289 if (copy_to_user(arg, &cam->compression,
2290 sizeof(cam->compression)))
2291 return -EFAULT;
2292
2293 return 0;
2294}
2295
2296
2297static int
2298sn9c102_vidioc_s_jpegcomp(struct sn9c102_device* cam, void __user * arg)
2299{
2300 struct v4l2_jpegcompression jc;
2301 const enum sn9c102_stream_state stream = cam->stream;
2302 int err = 0;
2303
2304 if (copy_from_user(&jc, arg, sizeof(jc)))
2305 return -EFAULT;
2306
2307 if (jc.quality != 0 && jc.quality != 1)
2308 return -EINVAL;
2309
2310 if (cam->stream == STREAM_ON)
2311 if ((err = sn9c102_stream_interrupt(cam)))
2312 return err;
2313
2314 err += sn9c102_set_compression(cam, &jc);
2315 if (err) { /* atomic, no rollback in ioctl() */
2316 cam->state |= DEV_MISCONFIGURED;
2317 DBG(1, "VIDIOC_S_JPEGCOMP failed because of hardware "
2318 "problems. To use the camera, close and open "
2319 "/dev/video%d again.", cam->v4ldev->minor);
2320 return -EIO;
2321 }
2322
2323 cam->compression.quality = jc.quality;
2324
2325 cam->stream = stream;
2326
2327 return 0;
2328}
2329
2330
2331static int
2332sn9c102_vidioc_reqbufs(struct sn9c102_device* cam, void __user * arg)
2333{
2334 struct v4l2_requestbuffers rb;
2335 u32 i;
2336 int err;
2337
2338 if (copy_from_user(&rb, arg, sizeof(rb)))
2339 return -EFAULT;
2340
2341 if (rb.type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
2342 rb.memory != V4L2_MEMORY_MMAP)
2343 return -EINVAL;
2344
2345 if (cam->io == IO_READ) {
2346 DBG(3, "Close and open the device again to choose the mmap "
2347 "I/O method");
2348 return -EINVAL;
2349 }
2350
2351 for (i = 0; i < cam->nbuffers; i++)
2352 if (cam->frame[i].vma_use_count) {
2353 DBG(3, "VIDIOC_REQBUFS failed. Previous buffers are "
2354 "still mapped.");
2355 return -EINVAL;
2356 }
2357
2358 if (cam->stream == STREAM_ON)
2359 if ((err = sn9c102_stream_interrupt(cam)))
2360 return err;
2361
2362 sn9c102_empty_framequeues(cam);
2363
2364 sn9c102_release_buffers(cam);
2365 if (rb.count)
2366 rb.count = sn9c102_request_buffers(cam, rb.count, IO_MMAP);
2367
2368 if (copy_to_user(arg, &rb, sizeof(rb))) {
2369 sn9c102_release_buffers(cam);
2370 cam->io = IO_NONE;
2371 return -EFAULT;
2372 }
2373
2374 cam->io = rb.count ? IO_MMAP : IO_NONE;
2375
2376 return 0;
2377}
2378
2379
2380static int
2381sn9c102_vidioc_querybuf(struct sn9c102_device* cam, void __user * arg)
2382{
2383 struct v4l2_buffer b;
2384
2385 if (copy_from_user(&b, arg, sizeof(b)))
2386 return -EFAULT;
2387
2388 if (b.type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
2389 b.index >= cam->nbuffers || cam->io != IO_MMAP)
2390 return -EINVAL;
2391
2392 memcpy(&b, &cam->frame[b.index].buf, sizeof(b));
2393
2394 if (cam->frame[b.index].vma_use_count)
2395 b.flags |= V4L2_BUF_FLAG_MAPPED;
2396
2397 if (cam->frame[b.index].state == F_DONE)
2398 b.flags |= V4L2_BUF_FLAG_DONE;
2399 else if (cam->frame[b.index].state != F_UNUSED)
2400 b.flags |= V4L2_BUF_FLAG_QUEUED;
2401
2402 if (copy_to_user(arg, &b, sizeof(b)))
2403 return -EFAULT;
2404
2405 return 0;
2406}
2407
2408
2409static int
2410sn9c102_vidioc_qbuf(struct sn9c102_device* cam, void __user * arg)
2411{
2412 struct v4l2_buffer b;
2413 unsigned long lock_flags;
2414
2415 if (copy_from_user(&b, arg, sizeof(b)))
2416 return -EFAULT;
2417
2418 if (b.type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
2419 b.index >= cam->nbuffers || cam->io != IO_MMAP)
2420 return -EINVAL;
2421
2422 if (cam->frame[b.index].state != F_UNUSED)
2423 return -EINVAL;
2424
2425 cam->frame[b.index].state = F_QUEUED;
2426
2427 spin_lock_irqsave(&cam->queue_lock, lock_flags);
2428 list_add_tail(&cam->frame[b.index].frame, &cam->inqueue);
2429 spin_unlock_irqrestore(&cam->queue_lock, lock_flags);
2430
2431 PDBGG("Frame #%lu queued", (unsigned long)b.index);
2432
2433 return 0;
2434}
2435
2436
2437static int
2438sn9c102_vidioc_dqbuf(struct sn9c102_device* cam, struct file* filp,
2439 void __user * arg)
2440{
2441 struct v4l2_buffer b;
2442 struct sn9c102_frame_t *f;
2443 unsigned long lock_flags;
2444 long timeout;
2445
2446 if (copy_from_user(&b, arg, sizeof(b)))
2447 return -EFAULT;
2448
2449 if (b.type != V4L2_BUF_TYPE_VIDEO_CAPTURE || cam->io != IO_MMAP)
2450 return -EINVAL;
2451
2452 if (list_empty(&cam->outqueue)) {
2453 if (cam->stream == STREAM_OFF)
2454 return -EINVAL;
2455 if (filp->f_flags & O_NONBLOCK)
2456 return -EAGAIN;
2457 timeout = wait_event_interruptible_timeout
2458 ( cam->wait_frame,
2459 (!list_empty(&cam->outqueue)) ||
2460 (cam->state & DEV_DISCONNECTED) ||
2461 (cam->state & DEV_MISCONFIGURED),
2462 cam->module_param.frame_timeout *
2463 1000 * msecs_to_jiffies(1) );
2464 if (timeout < 0)
2465 return timeout;
2466 if (cam->state & DEV_DISCONNECTED)
2467 return -ENODEV;
2468 if (!timeout || (cam->state & DEV_MISCONFIGURED))
2469 return -EIO;
2470 }
2471
2472 spin_lock_irqsave(&cam->queue_lock, lock_flags);
2473 f = list_entry(cam->outqueue.next, struct sn9c102_frame_t, frame);
2474 list_del(cam->outqueue.next);
2475 spin_unlock_irqrestore(&cam->queue_lock, lock_flags);
2476
2477 f->state = F_UNUSED;
2478
2479 memcpy(&b, &f->buf, sizeof(b));
2480 if (f->vma_use_count)
2481 b.flags |= V4L2_BUF_FLAG_MAPPED;
2482
2483 if (copy_to_user(arg, &b, sizeof(b)))
2484 return -EFAULT;
2485
2486 PDBGG("Frame #%lu dequeued", (unsigned long)f->buf.index);
2487
2488 return 0;
2489}
2490
2491
2492static int
2493sn9c102_vidioc_streamon(struct sn9c102_device* cam, void __user * arg)
2494{
2495 int type;
2496
2497 if (copy_from_user(&type, arg, sizeof(type)))
2498 return -EFAULT;
2499
2500 if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE || cam->io != IO_MMAP)
2501 return -EINVAL;
2502
2503 if (list_empty(&cam->inqueue))
2504 return -EINVAL;
2505
2506 cam->stream = STREAM_ON;
2507
2508 DBG(3, "Stream on");
2509
2510 return 0;
2511}
2512
2513
2514static int
2515sn9c102_vidioc_streamoff(struct sn9c102_device* cam, void __user * arg)
2516{
2517 int type, err;
2518
2519 if (copy_from_user(&type, arg, sizeof(type)))
2520 return -EFAULT;
2521
2522 if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE || cam->io != IO_MMAP)
2523 return -EINVAL;
2524
2525 if (cam->stream == STREAM_ON)
2526 if ((err = sn9c102_stream_interrupt(cam)))
2527 return err;
2528
2529 sn9c102_empty_framequeues(cam);
2530
2531 DBG(3, "Stream off");
2532
2533 return 0;
2534}
2535
2536
2537static int
2538sn9c102_vidioc_g_parm(struct sn9c102_device* cam, void __user * arg)
2539{
2540 struct v4l2_streamparm sp;
2541
2542 if (copy_from_user(&sp, arg, sizeof(sp)))
2543 return -EFAULT;
2544
2545 if (sp.type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
2546 return -EINVAL;
2547
2548 sp.parm.capture.extendedmode = 0;
2549 sp.parm.capture.readbuffers = cam->nreadbuffers;
2550
2551 if (copy_to_user(arg, &sp, sizeof(sp)))
2552 return -EFAULT;
2553
2554 return 0;
2555}
2556
2557
2558static int
2559sn9c102_vidioc_s_parm(struct sn9c102_device* cam, void __user * arg)
2560{
2561 struct v4l2_streamparm sp;
2562
2563 if (copy_from_user(&sp, arg, sizeof(sp)))
2564 return -EFAULT;
2565
2566 if (sp.type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
2567 return -EINVAL;
2568
2569 sp.parm.capture.extendedmode = 0;
2570
2571 if (sp.parm.capture.readbuffers == 0)
2572 sp.parm.capture.readbuffers = cam->nreadbuffers;
2573
2574 if (sp.parm.capture.readbuffers > SN9C102_MAX_FRAMES)
2575 sp.parm.capture.readbuffers = SN9C102_MAX_FRAMES;
2576
2577 if (copy_to_user(arg, &sp, sizeof(sp)))
2578 return -EFAULT;
2579
2580 cam->nreadbuffers = sp.parm.capture.readbuffers;
2581
2582 return 0;
2583}
2584
2585
2586static int sn9c102_ioctl_v4l2(struct inode* inode, struct file* filp,
2587 unsigned int cmd, void __user * arg)
2588{
2589 struct sn9c102_device* cam = video_get_drvdata(video_devdata(filp));
2590
2591 switch (cmd) {
2592
2593 case VIDIOC_QUERYCAP:
2594 return sn9c102_vidioc_querycap(cam, arg);
2595
2596 case VIDIOC_ENUMINPUT:
2597 return sn9c102_vidioc_enuminput(cam, arg);
2598
2599 case VIDIOC_G_INPUT:
2600 return sn9c102_vidioc_g_input(cam, arg);
2601
2602 case VIDIOC_S_INPUT:
2603 return sn9c102_vidioc_s_input(cam, arg);
2604
2605 case VIDIOC_QUERYCTRL:
2606 return sn9c102_vidioc_query_ctrl(cam, arg);
2607
2608 case VIDIOC_G_CTRL:
2609 return sn9c102_vidioc_g_ctrl(cam, arg);
2610
2611 case VIDIOC_S_CTRL_OLD:
2612 case VIDIOC_S_CTRL:
2613 return sn9c102_vidioc_s_ctrl(cam, arg);
2614
2615 case VIDIOC_CROPCAP_OLD:
2616 case VIDIOC_CROPCAP:
2617 return sn9c102_vidioc_cropcap(cam, arg);
2618
2619 case VIDIOC_G_CROP:
2620 return sn9c102_vidioc_g_crop(cam, arg);
2621
2622 case VIDIOC_S_CROP:
2623 return sn9c102_vidioc_s_crop(cam, arg);
2624
2625 case VIDIOC_ENUM_FMT:
2626 return sn9c102_vidioc_enum_fmt(cam, arg);
2627
2628 case VIDIOC_G_FMT:
2629 return sn9c102_vidioc_g_fmt(cam, arg);
2630
2631 case VIDIOC_TRY_FMT:
2632 case VIDIOC_S_FMT:
2633 return sn9c102_vidioc_try_s_fmt(cam, cmd, arg);
2634
2635 case VIDIOC_G_JPEGCOMP:
2636 return sn9c102_vidioc_g_jpegcomp(cam, arg);
2637
2638 case VIDIOC_S_JPEGCOMP:
2639 return sn9c102_vidioc_s_jpegcomp(cam, arg);
2640
2641 case VIDIOC_REQBUFS:
2642 return sn9c102_vidioc_reqbufs(cam, arg);
2643
2644 case VIDIOC_QUERYBUF:
2645 return sn9c102_vidioc_querybuf(cam, arg);
2646
2647 case VIDIOC_QBUF:
2648 return sn9c102_vidioc_qbuf(cam, arg);
2649
2650 case VIDIOC_DQBUF:
2651 return sn9c102_vidioc_dqbuf(cam, filp, arg);
2652
2653 case VIDIOC_STREAMON:
2654 return sn9c102_vidioc_streamon(cam, arg);
2655
2656 case VIDIOC_STREAMOFF:
2657 return sn9c102_vidioc_streamoff(cam, arg);
2658
2659 case VIDIOC_G_PARM:
2660 return sn9c102_vidioc_g_parm(cam, arg);
2661
2662 case VIDIOC_S_PARM_OLD:
2663 case VIDIOC_S_PARM:
2664 return sn9c102_vidioc_s_parm(cam, arg);
2665
2666 case VIDIOC_G_STD:
2667 case VIDIOC_S_STD:
2668 case VIDIOC_QUERYSTD:
2669 case VIDIOC_ENUMSTD:
2670 case VIDIOC_QUERYMENU:
2671 return -EINVAL;
2672
2673 default:
2674 return -EINVAL;
2675
2676 }
2677}
2678
2679
2680static int sn9c102_ioctl(struct inode* inode, struct file* filp,
2681 unsigned int cmd, unsigned long arg)
2682{
2683 struct sn9c102_device* cam = video_get_drvdata(video_devdata(filp));
2684 int err = 0;
2685
2686 if (mutex_lock_interruptible(&cam->fileop_mutex))
2687 return -ERESTARTSYS;
2688
2689 if (cam->state & DEV_DISCONNECTED) {
2690 DBG(1, "Device not present");
2691 mutex_unlock(&cam->fileop_mutex);
2692 return -ENODEV;
2693 }
2694
2695 if (cam->state & DEV_MISCONFIGURED) {
2696 DBG(1, "The camera is misconfigured. Close and open it "
2697 "again.");
2698 mutex_unlock(&cam->fileop_mutex);
2699 return -EIO;
2700 }
2701
2702 V4LDBG(3, "sn9c102", cmd);
2703
2704 err = sn9c102_ioctl_v4l2(inode, filp, cmd, (void __user *)arg);
2705
2706 mutex_unlock(&cam->fileop_mutex);
2707
2708 return err;
2709}
2710
2711/*****************************************************************************/
2712
2713static struct file_operations sn9c102_fops = {
2714 .owner = THIS_MODULE,
2715 .open = sn9c102_open,
2716 .release = sn9c102_release,
2717 .ioctl = sn9c102_ioctl,
2718 .read = sn9c102_read,
2719 .poll = sn9c102_poll,
2720 .mmap = sn9c102_mmap,
2721 .llseek = no_llseek,
2722};
2723
2724/*****************************************************************************/
2725
2726/* It exists a single interface only. We do not need to validate anything. */
2727static int
2728sn9c102_usb_probe(struct usb_interface* intf, const struct usb_device_id* id)
2729{
2730 struct usb_device *udev = interface_to_usbdev(intf);
2731 struct sn9c102_device* cam;
2732 static unsigned int dev_nr = 0;
2733 unsigned int i;
2734 int err = 0, r;
2735
2736 if (!(cam = kzalloc(sizeof(struct sn9c102_device), GFP_KERNEL)))
2737 return -ENOMEM;
2738
2739 cam->usbdev = udev;
2740
2741 if (!(cam->control_buffer = kzalloc(8, GFP_KERNEL))) {
2742 DBG(1, "kmalloc() failed");
2743 err = -ENOMEM;
2744 goto fail;
2745 }
2746
2747 if (!(cam->v4ldev = video_device_alloc())) {
2748 DBG(1, "video_device_alloc() failed");
2749 err = -ENOMEM;
2750 goto fail;
2751 }
2752
2753 mutex_init(&cam->dev_mutex);
2754
2755 r = sn9c102_read_reg(cam, 0x00);
2756 if (r < 0 || r != 0x10) {
2757 DBG(1, "Sorry, this is not a SN9C10x based camera "
2758 "(vid/pid 0x%04X/0x%04X)", id->idVendor, id->idProduct);
2759 err = -ENODEV;
2760 goto fail;
2761 }
2762
2763 cam->bridge = (id->idProduct & 0xffc0) == 0x6080 ?
2764 BRIDGE_SN9C103 : BRIDGE_SN9C102;
2765 switch (cam->bridge) {
2766 case BRIDGE_SN9C101:
2767 case BRIDGE_SN9C102:
2768 DBG(2, "SN9C10[12] PC Camera Controller detected "
2769 "(vid/pid 0x%04X/0x%04X)", id->idVendor, id->idProduct);
2770 break;
2771 case BRIDGE_SN9C103:
2772 DBG(2, "SN9C103 PC Camera Controller detected "
2773 "(vid/pid 0x%04X/0x%04X)", id->idVendor, id->idProduct);
2774 break;
2775 }
2776
2777 for (i = 0; sn9c102_sensor_table[i]; i++) {
2778 err = sn9c102_sensor_table[i](cam);
2779 if (!err)
2780 break;
2781 }
2782
2783 if (!err) {
2784 DBG(2, "%s image sensor detected", cam->sensor.name);
2785 DBG(3, "Support for %s maintained by %s",
2786 cam->sensor.name, cam->sensor.maintainer);
2787 } else {
2788 DBG(1, "No supported image sensor detected");
2789 err = -ENODEV;
2790 goto fail;
2791 }
2792
2793 if (sn9c102_init(cam)) {
2794 DBG(1, "Initialization failed. I will retry on open().");
2795 cam->state |= DEV_MISCONFIGURED;
2796 }
2797
2798 strcpy(cam->v4ldev->name, "SN9C10x PC Camera");
2799 cam->v4ldev->owner = THIS_MODULE;
2800 cam->v4ldev->type = VID_TYPE_CAPTURE | VID_TYPE_SCALES;
2801 cam->v4ldev->hardware = 0;
2802 cam->v4ldev->fops = &sn9c102_fops;
2803 cam->v4ldev->minor = video_nr[dev_nr];
2804 cam->v4ldev->release = video_device_release;
2805 video_set_drvdata(cam->v4ldev, cam);
2806
2807 mutex_lock(&cam->dev_mutex);
2808
2809 err = video_register_device(cam->v4ldev, VFL_TYPE_GRABBER,
2810 video_nr[dev_nr]);
2811 if (err) {
2812 DBG(1, "V4L2 device registration failed");
2813 if (err == -ENFILE && video_nr[dev_nr] == -1)
2814 DBG(1, "Free /dev/videoX node not found");
2815 video_nr[dev_nr] = -1;
2816 dev_nr = (dev_nr < SN9C102_MAX_DEVICES-1) ? dev_nr+1 : 0;
2817 mutex_unlock(&cam->dev_mutex);
2818 goto fail;
2819 }
2820
2821 DBG(2, "V4L2 device registered as /dev/video%d", cam->v4ldev->minor);
2822
2823 cam->module_param.force_munmap = force_munmap[dev_nr];
2824 cam->module_param.frame_timeout = frame_timeout[dev_nr];
2825
2826 dev_nr = (dev_nr < SN9C102_MAX_DEVICES-1) ? dev_nr+1 : 0;
2827
2828#ifdef CONFIG_VIDEO_ADV_DEBUG
2829 sn9c102_create_sysfs(cam);
2830 DBG(2, "Optional device control through 'sysfs' interface ready");
2831#endif
2832
2833 usb_set_intfdata(intf, cam);
2834
2835 mutex_unlock(&cam->dev_mutex);
2836
2837 return 0;
2838
2839fail:
2840 if (cam) {
2841 kfree(cam->control_buffer);
2842 if (cam->v4ldev)
2843 video_device_release(cam->v4ldev);
2844 kfree(cam);
2845 }
2846 return err;
2847}
2848
2849
2850static void sn9c102_usb_disconnect(struct usb_interface* intf)
2851{
2852 struct sn9c102_device* cam = usb_get_intfdata(intf);
2853
2854 if (!cam)
2855 return;
2856
2857 down_write(&sn9c102_disconnect);
2858
2859 mutex_lock(&cam->dev_mutex);
2860
2861 DBG(2, "Disconnecting %s...", cam->v4ldev->name);
2862
2863 wake_up_interruptible_all(&cam->open);
2864
2865 if (cam->users) {
2866 DBG(2, "Device /dev/video%d is open! Deregistration and "
2867 "memory deallocation are deferred on close.",
2868 cam->v4ldev->minor);
2869 cam->state |= DEV_MISCONFIGURED;
2870 sn9c102_stop_transfer(cam);
2871 cam->state |= DEV_DISCONNECTED;
2872 wake_up_interruptible(&cam->wait_frame);
2873 wake_up(&cam->wait_stream);
2874 usb_get_dev(cam->usbdev);
2875 } else {
2876 cam->state |= DEV_DISCONNECTED;
2877 sn9c102_release_resources(cam);
2878 }
2879
2880 mutex_unlock(&cam->dev_mutex);
2881
2882 if (!cam->users)
2883 kfree(cam);
2884
2885 up_write(&sn9c102_disconnect);
2886}
2887
2888
2889static struct usb_driver sn9c102_usb_driver = {
2890 .name = "sn9c102",
2891 .id_table = sn9c102_id_table,
2892 .probe = sn9c102_usb_probe,
2893 .disconnect = sn9c102_usb_disconnect,
2894};
2895
2896/*****************************************************************************/
2897
2898static int __init sn9c102_module_init(void)
2899{
2900 int err = 0;
2901
2902 KDBG(2, SN9C102_MODULE_NAME " v" SN9C102_MODULE_VERSION);
2903 KDBG(3, SN9C102_MODULE_AUTHOR);
2904
2905 if ((err = usb_register(&sn9c102_usb_driver)))
2906 KDBG(1, "usb_register() failed");
2907
2908 return err;
2909}
2910
2911
2912static void __exit sn9c102_module_exit(void)
2913{
2914 usb_deregister(&sn9c102_usb_driver);
2915}
2916
2917
2918module_init(sn9c102_module_init);
2919module_exit(sn9c102_module_exit);
diff --git a/drivers/media/video/sn9c102/sn9c102_hv7131d.c b/drivers/media/video/sn9c102/sn9c102_hv7131d.c
new file mode 100644
index 000000000000..46c12ec3ca62
--- /dev/null
+++ b/drivers/media/video/sn9c102/sn9c102_hv7131d.c
@@ -0,0 +1,271 @@
1/***************************************************************************
2 * Plug-in for HV7131D image sensor connected to the SN9C10x PC Camera *
3 * Controllers *
4 * *
5 * Copyright (C) 2004-2006 by Luca Risolia <luca.risolia@studio.unibo.it> *
6 * *
7 * This program is free software; you can redistribute it and/or modify *
8 * it under the terms of the GNU General Public License as published by *
9 * the Free Software Foundation; either version 2 of the License, or *
10 * (at your option) any later version. *
11 * *
12 * This program is distributed in the hope that it will be useful, *
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15 * GNU General Public License for more details. *
16 * *
17 * You should have received a copy of the GNU General Public License *
18 * along with this program; if not, write to the Free Software *
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
20 ***************************************************************************/
21
22#include "sn9c102_sensor.h"
23
24
25static struct sn9c102_sensor hv7131d;
26
27
28static int hv7131d_init(struct sn9c102_device* cam)
29{
30 int err = 0;
31
32 err += sn9c102_write_reg(cam, 0x00, 0x10);
33 err += sn9c102_write_reg(cam, 0x00, 0x11);
34 err += sn9c102_write_reg(cam, 0x00, 0x14);
35 err += sn9c102_write_reg(cam, 0x60, 0x17);
36 err += sn9c102_write_reg(cam, 0x0e, 0x18);
37 err += sn9c102_write_reg(cam, 0xf2, 0x19);
38
39 err += sn9c102_i2c_write(cam, 0x01, 0x04);
40 err += sn9c102_i2c_write(cam, 0x02, 0x00);
41 err += sn9c102_i2c_write(cam, 0x28, 0x00);
42
43 return err;
44}
45
46
47static int hv7131d_get_ctrl(struct sn9c102_device* cam,
48 struct v4l2_control* ctrl)
49{
50 switch (ctrl->id) {
51 case V4L2_CID_EXPOSURE:
52 {
53 int r1 = sn9c102_i2c_read(cam, 0x26),
54 r2 = sn9c102_i2c_read(cam, 0x27);
55 if (r1 < 0 || r2 < 0)
56 return -EIO;
57 ctrl->value = (r1 << 8) | (r2 & 0xff);
58 }
59 return 0;
60 case V4L2_CID_RED_BALANCE:
61 if ((ctrl->value = sn9c102_i2c_read(cam, 0x31)) < 0)
62 return -EIO;
63 ctrl->value = 0x3f - (ctrl->value & 0x3f);
64 return 0;
65 case V4L2_CID_BLUE_BALANCE:
66 if ((ctrl->value = sn9c102_i2c_read(cam, 0x33)) < 0)
67 return -EIO;
68 ctrl->value = 0x3f - (ctrl->value & 0x3f);
69 return 0;
70 case SN9C102_V4L2_CID_GREEN_BALANCE:
71 if ((ctrl->value = sn9c102_i2c_read(cam, 0x32)) < 0)
72 return -EIO;
73 ctrl->value = 0x3f - (ctrl->value & 0x3f);
74 return 0;
75 case SN9C102_V4L2_CID_RESET_LEVEL:
76 if ((ctrl->value = sn9c102_i2c_read(cam, 0x30)) < 0)
77 return -EIO;
78 ctrl->value &= 0x3f;
79 return 0;
80 case SN9C102_V4L2_CID_PIXEL_BIAS_VOLTAGE:
81 if ((ctrl->value = sn9c102_i2c_read(cam, 0x34)) < 0)
82 return -EIO;
83 ctrl->value &= 0x07;
84 return 0;
85 default:
86 return -EINVAL;
87 }
88}
89
90
91static int hv7131d_set_ctrl(struct sn9c102_device* cam,
92 const struct v4l2_control* ctrl)
93{
94 int err = 0;
95
96 switch (ctrl->id) {
97 case V4L2_CID_EXPOSURE:
98 err += sn9c102_i2c_write(cam, 0x26, ctrl->value >> 8);
99 err += sn9c102_i2c_write(cam, 0x27, ctrl->value & 0xff);
100 break;
101 case V4L2_CID_RED_BALANCE:
102 err += sn9c102_i2c_write(cam, 0x31, 0x3f - ctrl->value);
103 break;
104 case V4L2_CID_BLUE_BALANCE:
105 err += sn9c102_i2c_write(cam, 0x33, 0x3f - ctrl->value);
106 break;
107 case SN9C102_V4L2_CID_GREEN_BALANCE:
108 err += sn9c102_i2c_write(cam, 0x32, 0x3f - ctrl->value);
109 break;
110 case SN9C102_V4L2_CID_RESET_LEVEL:
111 err += sn9c102_i2c_write(cam, 0x30, ctrl->value);
112 break;
113 case SN9C102_V4L2_CID_PIXEL_BIAS_VOLTAGE:
114 err += sn9c102_i2c_write(cam, 0x34, ctrl->value);
115 break;
116 default:
117 return -EINVAL;
118 }
119
120 return err ? -EIO : 0;
121}
122
123
124static int hv7131d_set_crop(struct sn9c102_device* cam,
125 const struct v4l2_rect* rect)
126{
127 struct sn9c102_sensor* s = &hv7131d;
128 int err = 0;
129 u8 h_start = (u8)(rect->left - s->cropcap.bounds.left) + 2,
130 v_start = (u8)(rect->top - s->cropcap.bounds.top) + 2;
131
132 err += sn9c102_write_reg(cam, h_start, 0x12);
133 err += sn9c102_write_reg(cam, v_start, 0x13);
134
135 return err;
136}
137
138
139static int hv7131d_set_pix_format(struct sn9c102_device* cam,
140 const struct v4l2_pix_format* pix)
141{
142 int err = 0;
143
144 if (pix->pixelformat == V4L2_PIX_FMT_SN9C10X)
145 err += sn9c102_write_reg(cam, 0x42, 0x19);
146 else
147 err += sn9c102_write_reg(cam, 0xf2, 0x19);
148
149 return err;
150}
151
152
153static struct sn9c102_sensor hv7131d = {
154 .name = "HV7131D",
155 .maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>",
156 .sysfs_ops = SN9C102_I2C_READ | SN9C102_I2C_WRITE,
157 .frequency = SN9C102_I2C_100KHZ,
158 .interface = SN9C102_I2C_2WIRES,
159 .i2c_slave_id = 0x11,
160 .init = &hv7131d_init,
161 .qctrl = {
162 {
163 .id = V4L2_CID_EXPOSURE,
164 .type = V4L2_CTRL_TYPE_INTEGER,
165 .name = "exposure",
166 .minimum = 0x0250,
167 .maximum = 0xffff,
168 .step = 0x0001,
169 .default_value = 0x0250,
170 .flags = 0,
171 },
172 {
173 .id = V4L2_CID_RED_BALANCE,
174 .type = V4L2_CTRL_TYPE_INTEGER,
175 .name = "red balance",
176 .minimum = 0x00,
177 .maximum = 0x3f,
178 .step = 0x01,
179 .default_value = 0x00,
180 .flags = 0,
181 },
182 {
183 .id = V4L2_CID_BLUE_BALANCE,
184 .type = V4L2_CTRL_TYPE_INTEGER,
185 .name = "blue balance",
186 .minimum = 0x00,
187 .maximum = 0x3f,
188 .step = 0x01,
189 .default_value = 0x20,
190 .flags = 0,
191 },
192 {
193 .id = SN9C102_V4L2_CID_GREEN_BALANCE,
194 .type = V4L2_CTRL_TYPE_INTEGER,
195 .name = "green balance",
196 .minimum = 0x00,
197 .maximum = 0x3f,
198 .step = 0x01,
199 .default_value = 0x1e,
200 .flags = 0,
201 },
202 {
203 .id = SN9C102_V4L2_CID_RESET_LEVEL,
204 .type = V4L2_CTRL_TYPE_INTEGER,
205 .name = "reset level",
206 .minimum = 0x19,
207 .maximum = 0x3f,
208 .step = 0x01,
209 .default_value = 0x30,
210 .flags = 0,
211 },
212 {
213 .id = SN9C102_V4L2_CID_PIXEL_BIAS_VOLTAGE,
214 .type = V4L2_CTRL_TYPE_INTEGER,
215 .name = "pixel bias voltage",
216 .minimum = 0x00,
217 .maximum = 0x07,
218 .step = 0x01,
219 .default_value = 0x02,
220 .flags = 0,
221 },
222 },
223 .get_ctrl = &hv7131d_get_ctrl,
224 .set_ctrl = &hv7131d_set_ctrl,
225 .cropcap = {
226 .bounds = {
227 .left = 0,
228 .top = 0,
229 .width = 640,
230 .height = 480,
231 },
232 .defrect = {
233 .left = 0,
234 .top = 0,
235 .width = 640,
236 .height = 480,
237 },
238 },
239 .set_crop = &hv7131d_set_crop,
240 .pix_format = {
241 .width = 640,
242 .height = 480,
243 .pixelformat = V4L2_PIX_FMT_SBGGR8,
244 .priv = 8,
245 },
246 .set_pix_format = &hv7131d_set_pix_format
247};
248
249
250int sn9c102_probe_hv7131d(struct sn9c102_device* cam)
251{
252 int r0 = 0, r1 = 0, err = 0;
253
254 err += sn9c102_write_reg(cam, 0x01, 0x01);
255 err += sn9c102_write_reg(cam, 0x00, 0x01);
256 err += sn9c102_write_reg(cam, 0x28, 0x17);
257 if (err)
258 return -EIO;
259
260 r0 = sn9c102_i2c_try_read(cam, &hv7131d, 0x00);
261 r1 = sn9c102_i2c_try_read(cam, &hv7131d, 0x01);
262 if (r0 < 0 || r1 < 0)
263 return -EIO;
264
265 if (r0 != 0x00 && r1 != 0x04)
266 return -ENODEV;
267
268 sn9c102_attach_sensor(cam, &hv7131d);
269
270 return 0;
271}
diff --git a/drivers/media/video/sn9c102/sn9c102_mi0343.c b/drivers/media/video/sn9c102/sn9c102_mi0343.c
new file mode 100644
index 000000000000..d9aa7a61095d
--- /dev/null
+++ b/drivers/media/video/sn9c102/sn9c102_mi0343.c
@@ -0,0 +1,363 @@
1/***************************************************************************
2 * Plug-in for MI-0343 image sensor connected to the SN9C10x PC Camera *
3 * Controllers *
4 * *
5 * Copyright (C) 2004-2006 by Luca Risolia <luca.risolia@studio.unibo.it> *
6 * *
7 * This program is free software; you can redistribute it and/or modify *
8 * it under the terms of the GNU General Public License as published by *
9 * the Free Software Foundation; either version 2 of the License, or *
10 * (at your option) any later version. *
11 * *
12 * This program is distributed in the hope that it will be useful, *
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15 * GNU General Public License for more details. *
16 * *
17 * You should have received a copy of the GNU General Public License *
18 * along with this program; if not, write to the Free Software *
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
20 ***************************************************************************/
21
22#include "sn9c102_sensor.h"
23
24
25static struct sn9c102_sensor mi0343;
26static u8 mi0343_i2c_data[5+1];
27
28
29static int mi0343_init(struct sn9c102_device* cam)
30{
31 int err = 0;
32
33 err += sn9c102_write_reg(cam, 0x00, 0x10);
34 err += sn9c102_write_reg(cam, 0x00, 0x11);
35 err += sn9c102_write_reg(cam, 0x0a, 0x14);
36 err += sn9c102_write_reg(cam, 0x40, 0x01);
37 err += sn9c102_write_reg(cam, 0x20, 0x17);
38 err += sn9c102_write_reg(cam, 0x07, 0x18);
39 err += sn9c102_write_reg(cam, 0xa0, 0x19);
40
41 err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4, mi0343.i2c_slave_id,
42 0x0d, 0x00, 0x01, 0, 0);
43 err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4, mi0343.i2c_slave_id,
44 0x0d, 0x00, 0x00, 0, 0);
45 err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4, mi0343.i2c_slave_id,
46 0x03, 0x01, 0xe1, 0, 0);
47 err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4, mi0343.i2c_slave_id,
48 0x04, 0x02, 0x81, 0, 0);
49 err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4, mi0343.i2c_slave_id,
50 0x05, 0x00, 0x17, 0, 0);
51 err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4, mi0343.i2c_slave_id,
52 0x06, 0x00, 0x11, 0, 0);
53 err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4, mi0343.i2c_slave_id,
54 0x62, 0x04, 0x9a, 0, 0);
55
56 return err;
57}
58
59
60static int mi0343_get_ctrl(struct sn9c102_device* cam,
61 struct v4l2_control* ctrl)
62{
63 switch (ctrl->id) {
64 case V4L2_CID_EXPOSURE:
65 if (sn9c102_i2c_try_raw_read(cam, &mi0343, mi0343.i2c_slave_id,
66 0x09, 2+1, mi0343_i2c_data) < 0)
67 return -EIO;
68 ctrl->value = mi0343_i2c_data[2];
69 return 0;
70 case V4L2_CID_GAIN:
71 if (sn9c102_i2c_try_raw_read(cam, &mi0343, mi0343.i2c_slave_id,
72 0x35, 2+1, mi0343_i2c_data) < 0)
73 return -EIO;
74 break;
75 case V4L2_CID_HFLIP:
76 if (sn9c102_i2c_try_raw_read(cam, &mi0343, mi0343.i2c_slave_id,
77 0x20, 2+1, mi0343_i2c_data) < 0)
78 return -EIO;
79 ctrl->value = mi0343_i2c_data[3] & 0x20 ? 1 : 0;
80 return 0;
81 case V4L2_CID_VFLIP:
82 if (sn9c102_i2c_try_raw_read(cam, &mi0343, mi0343.i2c_slave_id,
83 0x20, 2+1, mi0343_i2c_data) < 0)
84 return -EIO;
85 ctrl->value = mi0343_i2c_data[3] & 0x80 ? 1 : 0;
86 return 0;
87 case V4L2_CID_RED_BALANCE:
88 if (sn9c102_i2c_try_raw_read(cam, &mi0343, mi0343.i2c_slave_id,
89 0x2d, 2+1, mi0343_i2c_data) < 0)
90 return -EIO;
91 break;
92 case V4L2_CID_BLUE_BALANCE:
93 if (sn9c102_i2c_try_raw_read(cam, &mi0343, mi0343.i2c_slave_id,
94 0x2c, 2+1, mi0343_i2c_data) < 0)
95 return -EIO;
96 break;
97 case SN9C102_V4L2_CID_GREEN_BALANCE:
98 if (sn9c102_i2c_try_raw_read(cam, &mi0343, mi0343.i2c_slave_id,
99 0x2e, 2+1, mi0343_i2c_data) < 0)
100 return -EIO;
101 break;
102 default:
103 return -EINVAL;
104 }
105
106 switch (ctrl->id) {
107 case V4L2_CID_GAIN:
108 case V4L2_CID_RED_BALANCE:
109 case V4L2_CID_BLUE_BALANCE:
110 case SN9C102_V4L2_CID_GREEN_BALANCE:
111 ctrl->value = mi0343_i2c_data[3] | (mi0343_i2c_data[2] << 8);
112 if (ctrl->value >= 0x10 && ctrl->value <= 0x3f)
113 ctrl->value -= 0x10;
114 else if (ctrl->value >= 0x60 && ctrl->value <= 0x7f)
115 ctrl->value -= 0x60;
116 else if (ctrl->value >= 0xe0 && ctrl->value <= 0xff)
117 ctrl->value -= 0xe0;
118 }
119
120 return 0;
121}
122
123
124static int mi0343_set_ctrl(struct sn9c102_device* cam,
125 const struct v4l2_control* ctrl)
126{
127 u16 reg = 0;
128 int err = 0;
129
130 switch (ctrl->id) {
131 case V4L2_CID_GAIN:
132 case V4L2_CID_RED_BALANCE:
133 case V4L2_CID_BLUE_BALANCE:
134 case SN9C102_V4L2_CID_GREEN_BALANCE:
135 if (ctrl->value <= (0x3f-0x10))
136 reg = 0x10 + ctrl->value;
137 else if (ctrl->value <= ((0x3f-0x10) + (0x7f-0x60)))
138 reg = 0x60 + (ctrl->value - (0x3f-0x10));
139 else
140 reg = 0xe0 + (ctrl->value - (0x3f-0x10) - (0x7f-0x60));
141 break;
142 }
143
144 switch (ctrl->id) {
145 case V4L2_CID_EXPOSURE:
146 err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4,
147 mi0343.i2c_slave_id,
148 0x09, ctrl->value, 0x00,
149 0, 0);
150 break;
151 case V4L2_CID_GAIN:
152 err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4,
153 mi0343.i2c_slave_id,
154 0x35, reg >> 8, reg & 0xff,
155 0, 0);
156 break;
157 case V4L2_CID_HFLIP:
158 err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4,
159 mi0343.i2c_slave_id,
160 0x20, ctrl->value ? 0x40:0x00,
161 ctrl->value ? 0x20:0x00,
162 0, 0);
163 break;
164 case V4L2_CID_VFLIP:
165 err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4,
166 mi0343.i2c_slave_id,
167 0x20, ctrl->value ? 0x80:0x00,
168 ctrl->value ? 0x80:0x00,
169 0, 0);
170 break;
171 case V4L2_CID_RED_BALANCE:
172 err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4,
173 mi0343.i2c_slave_id,
174 0x2d, reg >> 8, reg & 0xff,
175 0, 0);
176 break;
177 case V4L2_CID_BLUE_BALANCE:
178 err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4,
179 mi0343.i2c_slave_id,
180 0x2c, reg >> 8, reg & 0xff,
181 0, 0);
182 break;
183 case SN9C102_V4L2_CID_GREEN_BALANCE:
184 err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4,
185 mi0343.i2c_slave_id,
186 0x2b, reg >> 8, reg & 0xff,
187 0, 0);
188 err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4,
189 mi0343.i2c_slave_id,
190 0x2e, reg >> 8, reg & 0xff,
191 0, 0);
192 break;
193 default:
194 return -EINVAL;
195 }
196
197 return err ? -EIO : 0;
198}
199
200
201static int mi0343_set_crop(struct sn9c102_device* cam,
202 const struct v4l2_rect* rect)
203{
204 struct sn9c102_sensor* s = &mi0343;
205 int err = 0;
206 u8 h_start = (u8)(rect->left - s->cropcap.bounds.left) + 0,
207 v_start = (u8)(rect->top - s->cropcap.bounds.top) + 2;
208
209 err += sn9c102_write_reg(cam, h_start, 0x12);
210 err += sn9c102_write_reg(cam, v_start, 0x13);
211
212 return err;
213}
214
215
216static int mi0343_set_pix_format(struct sn9c102_device* cam,
217 const struct v4l2_pix_format* pix)
218{
219 int err = 0;
220
221 if (pix->pixelformat == V4L2_PIX_FMT_SN9C10X) {
222 err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4,
223 mi0343.i2c_slave_id,
224 0x0a, 0x00, 0x03, 0, 0);
225 err += sn9c102_write_reg(cam, 0x20, 0x19);
226 } else {
227 err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4,
228 mi0343.i2c_slave_id,
229 0x0a, 0x00, 0x05, 0, 0);
230 err += sn9c102_write_reg(cam, 0xa0, 0x19);
231 }
232
233 return err;
234}
235
236
237static struct sn9c102_sensor mi0343 = {
238 .name = "MI-0343",
239 .maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>",
240 .frequency = SN9C102_I2C_100KHZ,
241 .interface = SN9C102_I2C_2WIRES,
242 .i2c_slave_id = 0x5d,
243 .init = &mi0343_init,
244 .qctrl = {
245 {
246 .id = V4L2_CID_EXPOSURE,
247 .type = V4L2_CTRL_TYPE_INTEGER,
248 .name = "exposure",
249 .minimum = 0x00,
250 .maximum = 0x0f,
251 .step = 0x01,
252 .default_value = 0x06,
253 .flags = 0,
254 },
255 {
256 .id = V4L2_CID_GAIN,
257 .type = V4L2_CTRL_TYPE_INTEGER,
258 .name = "global gain",
259 .minimum = 0x00,
260 .maximum = (0x3f-0x10)+(0x7f-0x60)+(0xff-0xe0),/*0x6d*/
261 .step = 0x01,
262 .default_value = 0x00,
263 .flags = 0,
264 },
265 {
266 .id = V4L2_CID_HFLIP,
267 .type = V4L2_CTRL_TYPE_BOOLEAN,
268 .name = "horizontal mirror",
269 .minimum = 0,
270 .maximum = 1,
271 .step = 1,
272 .default_value = 0,
273 .flags = 0,
274 },
275 {
276 .id = V4L2_CID_VFLIP,
277 .type = V4L2_CTRL_TYPE_BOOLEAN,
278 .name = "vertical mirror",
279 .minimum = 0,
280 .maximum = 1,
281 .step = 1,
282 .default_value = 0,
283 .flags = 0,
284 },
285 {
286 .id = V4L2_CID_RED_BALANCE,
287 .type = V4L2_CTRL_TYPE_INTEGER,
288 .name = "red balance",
289 .minimum = 0x00,
290 .maximum = (0x3f-0x10)+(0x7f-0x60)+(0xff-0xe0),
291 .step = 0x01,
292 .default_value = 0x00,
293 .flags = 0,
294 },
295 {
296 .id = V4L2_CID_BLUE_BALANCE,
297 .type = V4L2_CTRL_TYPE_INTEGER,
298 .name = "blue balance",
299 .minimum = 0x00,
300 .maximum = (0x3f-0x10)+(0x7f-0x60)+(0xff-0xe0),
301 .step = 0x01,
302 .default_value = 0x00,
303 .flags = 0,
304 },
305 {
306 .id = SN9C102_V4L2_CID_GREEN_BALANCE,
307 .type = V4L2_CTRL_TYPE_INTEGER,
308 .name = "green balance",
309 .minimum = 0x00,
310 .maximum = ((0x3f-0x10)+(0x7f-0x60)+(0xff-0xe0)),
311 .step = 0x01,
312 .default_value = 0x00,
313 .flags = 0,
314 },
315 },
316 .get_ctrl = &mi0343_get_ctrl,
317 .set_ctrl = &mi0343_set_ctrl,
318 .cropcap = {
319 .bounds = {
320 .left = 0,
321 .top = 0,
322 .width = 640,
323 .height = 480,
324 },
325 .defrect = {
326 .left = 0,
327 .top = 0,
328 .width = 640,
329 .height = 480,
330 },
331 },
332 .set_crop = &mi0343_set_crop,
333 .pix_format = {
334 .width = 640,
335 .height = 480,
336 .pixelformat = V4L2_PIX_FMT_SBGGR8,
337 .priv = 8,
338 },
339 .set_pix_format = &mi0343_set_pix_format
340};
341
342
343int sn9c102_probe_mi0343(struct sn9c102_device* cam)
344{
345 int err = 0;
346
347 err += sn9c102_write_reg(cam, 0x01, 0x01);
348 err += sn9c102_write_reg(cam, 0x00, 0x01);
349 err += sn9c102_write_reg(cam, 0x28, 0x17);
350 if (err)
351 return -EIO;
352
353 if (sn9c102_i2c_try_raw_read(cam, &mi0343, mi0343.i2c_slave_id, 0x00,
354 2, mi0343_i2c_data) < 0)
355 return -EIO;
356
357 if (mi0343_i2c_data[4] != 0x32 && mi0343_i2c_data[3] != 0xe3)
358 return -ENODEV;
359
360 sn9c102_attach_sensor(cam, &mi0343);
361
362 return 0;
363}
diff --git a/drivers/media/video/sn9c102/sn9c102_ov7630.c b/drivers/media/video/sn9c102/sn9c102_ov7630.c
new file mode 100644
index 000000000000..42852b7cb042
--- /dev/null
+++ b/drivers/media/video/sn9c102/sn9c102_ov7630.c
@@ -0,0 +1,401 @@
1/***************************************************************************
2 * Plug-in for OV7630 image sensor connected to the SN9C10x PC Camera *
3 * Controllers *
4 * *
5 * Copyright (C) 2005-2006 by Luca Risolia <luca.risolia@studio.unibo.it> *
6 * *
7 * This program is free software; you can redistribute it and/or modify *
8 * it under the terms of the GNU General Public License as published by *
9 * the Free Software Foundation; either version 2 of the License, or *
10 * (at your option) any later version. *
11 * *
12 * This program is distributed in the hope that it will be useful, *
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15 * GNU General Public License for more details. *
16 * *
17 * You should have received a copy of the GNU General Public License *
18 * along with this program; if not, write to the Free Software *
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
20 ***************************************************************************/
21
22#include "sn9c102_sensor.h"
23
24
25static struct sn9c102_sensor ov7630;
26
27
28static int ov7630_init(struct sn9c102_device* cam)
29{
30 int err = 0;
31
32 err += sn9c102_write_reg(cam, 0x00, 0x14);
33 err += sn9c102_write_reg(cam, 0x60, 0x17);
34 err += sn9c102_write_reg(cam, 0x0f, 0x18);
35 err += sn9c102_write_reg(cam, 0x50, 0x19);
36
37 err += sn9c102_i2c_write(cam, 0x12, 0x80);
38 err += sn9c102_i2c_write(cam, 0x11, 0x01);
39 err += sn9c102_i2c_write(cam, 0x15, 0x34);
40 err += sn9c102_i2c_write(cam, 0x16, 0x03);
41 err += sn9c102_i2c_write(cam, 0x17, 0x1c);
42 err += sn9c102_i2c_write(cam, 0x18, 0xbd);
43 err += sn9c102_i2c_write(cam, 0x19, 0x06);
44 err += sn9c102_i2c_write(cam, 0x1a, 0xf6);
45 err += sn9c102_i2c_write(cam, 0x1b, 0x04);
46 err += sn9c102_i2c_write(cam, 0x20, 0xf6);
47 err += sn9c102_i2c_write(cam, 0x23, 0xee);
48 err += sn9c102_i2c_write(cam, 0x26, 0xa0);
49 err += sn9c102_i2c_write(cam, 0x27, 0x9a);
50 err += sn9c102_i2c_write(cam, 0x28, 0xa0);
51 err += sn9c102_i2c_write(cam, 0x29, 0x30);
52 err += sn9c102_i2c_write(cam, 0x2a, 0xa0);
53 err += sn9c102_i2c_write(cam, 0x2b, 0x1f);
54 err += sn9c102_i2c_write(cam, 0x2f, 0x3d);
55 err += sn9c102_i2c_write(cam, 0x30, 0x24);
56 err += sn9c102_i2c_write(cam, 0x32, 0x86);
57 err += sn9c102_i2c_write(cam, 0x60, 0xa9);
58 err += sn9c102_i2c_write(cam, 0x61, 0x42);
59 err += sn9c102_i2c_write(cam, 0x65, 0x00);
60 err += sn9c102_i2c_write(cam, 0x69, 0x38);
61 err += sn9c102_i2c_write(cam, 0x6f, 0x88);
62 err += sn9c102_i2c_write(cam, 0x70, 0x0b);
63 err += sn9c102_i2c_write(cam, 0x71, 0x00);
64 err += sn9c102_i2c_write(cam, 0x74, 0x21);
65 err += sn9c102_i2c_write(cam, 0x7d, 0xf7);
66
67 return err;
68}
69
70
71static int ov7630_set_ctrl(struct sn9c102_device* cam,
72 const struct v4l2_control* ctrl)
73{
74 int err = 0;
75
76 switch (ctrl->id) {
77 case V4L2_CID_EXPOSURE:
78 err += sn9c102_i2c_write(cam, 0x10, ctrl->value >> 2);
79 err += sn9c102_i2c_write(cam, 0x76, ctrl->value & 0x03);
80 break;
81 case V4L2_CID_RED_BALANCE:
82 err += sn9c102_i2c_write(cam, 0x02, ctrl->value);
83 break;
84 case V4L2_CID_BLUE_BALANCE:
85 err += sn9c102_i2c_write(cam, 0x01, ctrl->value);
86 break;
87 case V4L2_CID_GAIN:
88 err += sn9c102_i2c_write(cam, 0x00, ctrl->value);
89 break;
90 case V4L2_CID_CONTRAST:
91 err += ctrl->value ? sn9c102_i2c_write(cam, 0x05,
92 (ctrl->value-1) | 0x20)
93 : sn9c102_i2c_write(cam, 0x05, 0x00);
94 break;
95 case V4L2_CID_BRIGHTNESS:
96 err += sn9c102_i2c_write(cam, 0x06, ctrl->value);
97 break;
98 case V4L2_CID_SATURATION:
99 err += sn9c102_i2c_write(cam, 0x03, ctrl->value << 4);
100 break;
101 case V4L2_CID_HUE:
102 err += ctrl->value ? sn9c102_i2c_write(cam, 0x04,
103 (ctrl->value-1) | 0x20)
104 : sn9c102_i2c_write(cam, 0x04, 0x00);
105 break;
106 case V4L2_CID_DO_WHITE_BALANCE:
107 err += sn9c102_i2c_write(cam, 0x0c, ctrl->value);
108 break;
109 case V4L2_CID_WHITENESS:
110 err += sn9c102_i2c_write(cam, 0x0d, ctrl->value);
111 break;
112 case V4L2_CID_AUTO_WHITE_BALANCE:
113 err += sn9c102_i2c_write(cam, 0x12, (ctrl->value << 2) | 0x78);
114 break;
115 case V4L2_CID_AUTOGAIN:
116 err += sn9c102_i2c_write(cam, 0x13, ctrl->value);
117 break;
118 case V4L2_CID_VFLIP:
119 err += sn9c102_i2c_write(cam, 0x75, 0x0e | (ctrl->value << 7));
120 break;
121 case V4L2_CID_BLACK_LEVEL:
122 err += sn9c102_i2c_write(cam, 0x25, ctrl->value);
123 break;
124 case SN9C102_V4L2_CID_BRIGHT_LEVEL:
125 err += sn9c102_i2c_write(cam, 0x24, ctrl->value);
126 break;
127 case SN9C102_V4L2_CID_GAMMA:
128 err += sn9c102_i2c_write(cam, 0x14, (ctrl->value << 2) | 0x80);
129 break;
130 case SN9C102_V4L2_CID_BAND_FILTER:
131 err += sn9c102_i2c_write(cam, 0x2d, ctrl->value << 2);
132 break;
133 default:
134 return -EINVAL;
135 }
136
137 return err ? -EIO : 0;
138}
139
140
141static int ov7630_set_crop(struct sn9c102_device* cam,
142 const struct v4l2_rect* rect)
143{
144 struct sn9c102_sensor* s = &ov7630;
145 int err = 0;
146 u8 v_start = (u8)(rect->top - s->cropcap.bounds.top) + 1;
147
148 err += sn9c102_write_reg(cam, v_start, 0x13);
149
150 return err;
151}
152
153
154static int ov7630_set_pix_format(struct sn9c102_device* cam,
155 const struct v4l2_pix_format* pix)
156{
157 int err = 0;
158
159 if (pix->pixelformat == V4L2_PIX_FMT_SN9C10X)
160 err += sn9c102_write_reg(cam, 0x20, 0x19);
161 else
162 err += sn9c102_write_reg(cam, 0x50, 0x19);
163
164 return err;
165}
166
167
168static struct sn9c102_sensor ov7630 = {
169 .name = "OV7630",
170 .maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>",
171 .sysfs_ops = SN9C102_I2C_WRITE,
172 .frequency = SN9C102_I2C_100KHZ,
173 .interface = SN9C102_I2C_2WIRES,
174 .i2c_slave_id = 0x21,
175 .init = &ov7630_init,
176 .qctrl = {
177 {
178 .id = V4L2_CID_GAIN,
179 .type = V4L2_CTRL_TYPE_INTEGER,
180 .name = "global gain",
181 .minimum = 0x00,
182 .maximum = 0x3f,
183 .step = 0x01,
184 .default_value = 0x14,
185 .flags = 0,
186 },
187 {
188 .id = V4L2_CID_HUE,
189 .type = V4L2_CTRL_TYPE_INTEGER,
190 .name = "hue",
191 .minimum = 0x00,
192 .maximum = 0x1f+1,
193 .step = 0x01,
194 .default_value = 0x00,
195 .flags = 0,
196 },
197 {
198 .id = V4L2_CID_SATURATION,
199 .type = V4L2_CTRL_TYPE_INTEGER,
200 .name = "saturation",
201 .minimum = 0x00,
202 .maximum = 0x0f,
203 .step = 0x01,
204 .default_value = 0x08,
205 .flags = 0,
206 },
207 {
208 .id = V4L2_CID_CONTRAST,
209 .type = V4L2_CTRL_TYPE_INTEGER,
210 .name = "contrast",
211 .minimum = 0x00,
212 .maximum = 0x1f+1,
213 .step = 0x01,
214 .default_value = 0x00,
215 .flags = 0,
216 },
217 {
218 .id = V4L2_CID_EXPOSURE,
219 .type = V4L2_CTRL_TYPE_INTEGER,
220 .name = "exposure",
221 .minimum = 0x000,
222 .maximum = 0x3ff,
223 .step = 0x001,
224 .default_value = 0x83<<2,
225 .flags = 0,
226 },
227 {
228 .id = V4L2_CID_RED_BALANCE,
229 .type = V4L2_CTRL_TYPE_INTEGER,
230 .name = "red balance",
231 .minimum = 0x00,
232 .maximum = 0xff,
233 .step = 0x01,
234 .default_value = 0x3a,
235 .flags = 0,
236 },
237 {
238 .id = V4L2_CID_BLUE_BALANCE,
239 .type = V4L2_CTRL_TYPE_INTEGER,
240 .name = "blue balance",
241 .minimum = 0x00,
242 .maximum = 0xff,
243 .step = 0x01,
244 .default_value = 0x77,
245 .flags = 0,
246 },
247 {
248 .id = V4L2_CID_BRIGHTNESS,
249 .type = V4L2_CTRL_TYPE_INTEGER,
250 .name = "brightness",
251 .minimum = 0x00,
252 .maximum = 0xff,
253 .step = 0x01,
254 .default_value = 0xa0,
255 .flags = 0,
256 },
257 {
258 .id = V4L2_CID_DO_WHITE_BALANCE,
259 .type = V4L2_CTRL_TYPE_INTEGER,
260 .name = "white balance background: blue",
261 .minimum = 0x00,
262 .maximum = 0x3f,
263 .step = 0x01,
264 .default_value = 0x20,
265 .flags = 0,
266 },
267 {
268 .id = V4L2_CID_WHITENESS,
269 .type = V4L2_CTRL_TYPE_INTEGER,
270 .name = "white balance background: red",
271 .minimum = 0x00,
272 .maximum = 0x3f,
273 .step = 0x01,
274 .default_value = 0x20,
275 .flags = 0,
276 },
277 {
278 .id = V4L2_CID_AUTO_WHITE_BALANCE,
279 .type = V4L2_CTRL_TYPE_BOOLEAN,
280 .name = "auto white balance",
281 .minimum = 0x00,
282 .maximum = 0x01,
283 .step = 0x01,
284 .default_value = 0x01,
285 .flags = 0,
286 },
287 {
288 .id = V4L2_CID_AUTOGAIN,
289 .type = V4L2_CTRL_TYPE_INTEGER,
290 .name = "gain & exposure mode",
291 .minimum = 0x00,
292 .maximum = 0x03,
293 .step = 0x01,
294 .default_value = 0x00,
295 .flags = 0,
296 },
297 {
298 .id = V4L2_CID_VFLIP,
299 .type = V4L2_CTRL_TYPE_BOOLEAN,
300 .name = "vertical flip",
301 .minimum = 0x00,
302 .maximum = 0x01,
303 .step = 0x01,
304 .default_value = 0x01,
305 .flags = 0,
306 },
307 {
308 .id = V4L2_CID_BLACK_LEVEL,
309 .type = V4L2_CTRL_TYPE_INTEGER,
310 .name = "black pixel ratio",
311 .minimum = 0x01,
312 .maximum = 0x9a,
313 .step = 0x01,
314 .default_value = 0x8a,
315 .flags = 0,
316 },
317 {
318 .id = SN9C102_V4L2_CID_BRIGHT_LEVEL,
319 .type = V4L2_CTRL_TYPE_INTEGER,
320 .name = "bright pixel ratio",
321 .minimum = 0x01,
322 .maximum = 0x9a,
323 .step = 0x01,
324 .default_value = 0x10,
325 .flags = 0,
326 },
327 {
328 .id = SN9C102_V4L2_CID_BAND_FILTER,
329 .type = V4L2_CTRL_TYPE_BOOLEAN,
330 .name = "band filter",
331 .minimum = 0x00,
332 .maximum = 0x01,
333 .step = 0x01,
334 .default_value = 0x00,
335 .flags = 0,
336 },
337 {
338 .id = SN9C102_V4L2_CID_GAMMA,
339 .type = V4L2_CTRL_TYPE_BOOLEAN,
340 .name = "rgb gamma",
341 .minimum = 0x00,
342 .maximum = 0x01,
343 .step = 0x01,
344 .default_value = 0x00,
345 .flags = 0,
346 },
347 },
348 .set_ctrl = &ov7630_set_ctrl,
349 .cropcap = {
350 .bounds = {
351 .left = 0,
352 .top = 0,
353 .width = 640,
354 .height = 480,
355 },
356 .defrect = {
357 .left = 0,
358 .top = 0,
359 .width = 640,
360 .height = 480,
361 },
362 },
363 .set_crop = &ov7630_set_crop,
364 .pix_format = {
365 .width = 640,
366 .height = 480,
367 .pixelformat = V4L2_PIX_FMT_SBGGR8,
368 .priv = 8,
369 },
370 .set_pix_format = &ov7630_set_pix_format
371};
372
373
374int sn9c102_probe_ov7630(struct sn9c102_device* cam)
375{
376 const struct usb_device_id ov7630_id_table[] = {
377 { USB_DEVICE(0x0c45, 0x602c), },
378 { USB_DEVICE(0x0c45, 0x602d), },
379 { USB_DEVICE(0x0c45, 0x608f), },
380 { USB_DEVICE(0x0c45, 0x60b0), },
381 { }
382 };
383 int err = 0;
384
385 if (!sn9c102_match_id(cam, ov7630_id_table))
386 return -ENODEV;
387
388 err += sn9c102_write_reg(cam, 0x01, 0x01);
389 err += sn9c102_write_reg(cam, 0x00, 0x01);
390 err += sn9c102_write_reg(cam, 0x28, 0x17);
391 if (err)
392 return -EIO;
393
394 err += sn9c102_i2c_try_write(cam, &ov7630, 0x0b, 0);
395 if (err)
396 return -ENODEV;
397
398 sn9c102_attach_sensor(cam, &ov7630);
399
400 return 0;
401}
diff --git a/drivers/media/video/sn9c102/sn9c102_pas106b.c b/drivers/media/video/sn9c102/sn9c102_pas106b.c
new file mode 100644
index 000000000000..b1dee78abe04
--- /dev/null
+++ b/drivers/media/video/sn9c102/sn9c102_pas106b.c
@@ -0,0 +1,307 @@
1/***************************************************************************
2 * Plug-in for PAS106B image sensor connected to the SN9C10x PC Camera *
3 * Controllers *
4 * *
5 * Copyright (C) 2004-2006 by Luca Risolia <luca.risolia@studio.unibo.it> *
6 * *
7 * This program is free software; you can redistribute it and/or modify *
8 * it under the terms of the GNU General Public License as published by *
9 * the Free Software Foundation; either version 2 of the License, or *
10 * (at your option) any later version. *
11 * *
12 * This program is distributed in the hope that it will be useful, *
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15 * GNU General Public License for more details. *
16 * *
17 * You should have received a copy of the GNU General Public License *
18 * along with this program; if not, write to the Free Software *
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
20 ***************************************************************************/
21
22#include <linux/delay.h>
23#include "sn9c102_sensor.h"
24
25
26static struct sn9c102_sensor pas106b;
27
28
29static int pas106b_init(struct sn9c102_device* cam)
30{
31 int err = 0;
32
33 err += sn9c102_write_reg(cam, 0x00, 0x10);
34 err += sn9c102_write_reg(cam, 0x00, 0x11);
35 err += sn9c102_write_reg(cam, 0x00, 0x14);
36 err += sn9c102_write_reg(cam, 0x20, 0x17);
37 err += sn9c102_write_reg(cam, 0x20, 0x19);
38 err += sn9c102_write_reg(cam, 0x09, 0x18);
39
40 err += sn9c102_i2c_write(cam, 0x02, 0x0c);
41 err += sn9c102_i2c_write(cam, 0x05, 0x5a);
42 err += sn9c102_i2c_write(cam, 0x06, 0x88);
43 err += sn9c102_i2c_write(cam, 0x07, 0x80);
44 err += sn9c102_i2c_write(cam, 0x10, 0x06);
45 err += sn9c102_i2c_write(cam, 0x11, 0x06);
46 err += sn9c102_i2c_write(cam, 0x12, 0x00);
47 err += sn9c102_i2c_write(cam, 0x14, 0x02);
48 err += sn9c102_i2c_write(cam, 0x13, 0x01);
49
50 msleep(400);
51
52 return err;
53}
54
55
56static int pas106b_get_ctrl(struct sn9c102_device* cam,
57 struct v4l2_control* ctrl)
58{
59 switch (ctrl->id) {
60 case V4L2_CID_EXPOSURE:
61 {
62 int r1 = sn9c102_i2c_read(cam, 0x03),
63 r2 = sn9c102_i2c_read(cam, 0x04);
64 if (r1 < 0 || r2 < 0)
65 return -EIO;
66 ctrl->value = (r1 << 4) | (r2 & 0x0f);
67 }
68 return 0;
69 case V4L2_CID_RED_BALANCE:
70 if ((ctrl->value = sn9c102_i2c_read(cam, 0x0c)) < 0)
71 return -EIO;
72 ctrl->value &= 0x1f;
73 return 0;
74 case V4L2_CID_BLUE_BALANCE:
75 if ((ctrl->value = sn9c102_i2c_read(cam, 0x09)) < 0)
76 return -EIO;
77 ctrl->value &= 0x1f;
78 return 0;
79 case V4L2_CID_GAIN:
80 if ((ctrl->value = sn9c102_i2c_read(cam, 0x0e)) < 0)
81 return -EIO;
82 ctrl->value &= 0x1f;
83 return 0;
84 case V4L2_CID_CONTRAST:
85 if ((ctrl->value = sn9c102_i2c_read(cam, 0x0f)) < 0)
86 return -EIO;
87 ctrl->value &= 0x07;
88 return 0;
89 case SN9C102_V4L2_CID_GREEN_BALANCE:
90 if ((ctrl->value = sn9c102_i2c_read(cam, 0x0a)) < 0)
91 return -EIO;
92 ctrl->value = (ctrl->value & 0x1f) << 1;
93 return 0;
94 case SN9C102_V4L2_CID_DAC_MAGNITUDE:
95 if ((ctrl->value = sn9c102_i2c_read(cam, 0x08)) < 0)
96 return -EIO;
97 ctrl->value &= 0xf8;
98 return 0;
99 default:
100 return -EINVAL;
101 }
102}
103
104
105static int pas106b_set_ctrl(struct sn9c102_device* cam,
106 const struct v4l2_control* ctrl)
107{
108 int err = 0;
109
110 switch (ctrl->id) {
111 case V4L2_CID_EXPOSURE:
112 err += sn9c102_i2c_write(cam, 0x03, ctrl->value >> 4);
113 err += sn9c102_i2c_write(cam, 0x04, ctrl->value & 0x0f);
114 break;
115 case V4L2_CID_RED_BALANCE:
116 err += sn9c102_i2c_write(cam, 0x0c, ctrl->value);
117 break;
118 case V4L2_CID_BLUE_BALANCE:
119 err += sn9c102_i2c_write(cam, 0x09, ctrl->value);
120 break;
121 case V4L2_CID_GAIN:
122 err += sn9c102_i2c_write(cam, 0x0e, ctrl->value);
123 break;
124 case V4L2_CID_CONTRAST:
125 err += sn9c102_i2c_write(cam, 0x0f, ctrl->value);
126 break;
127 case SN9C102_V4L2_CID_GREEN_BALANCE:
128 err += sn9c102_i2c_write(cam, 0x0a, ctrl->value >> 1);
129 err += sn9c102_i2c_write(cam, 0x0b, ctrl->value >> 1);
130 break;
131 case SN9C102_V4L2_CID_DAC_MAGNITUDE:
132 err += sn9c102_i2c_write(cam, 0x08, ctrl->value << 3);
133 break;
134 default:
135 return -EINVAL;
136 }
137 err += sn9c102_i2c_write(cam, 0x13, 0x01);
138
139 return err ? -EIO : 0;
140}
141
142
143static int pas106b_set_crop(struct sn9c102_device* cam,
144 const struct v4l2_rect* rect)
145{
146 struct sn9c102_sensor* s = &pas106b;
147 int err = 0;
148 u8 h_start = (u8)(rect->left - s->cropcap.bounds.left) + 4,
149 v_start = (u8)(rect->top - s->cropcap.bounds.top) + 3;
150
151 err += sn9c102_write_reg(cam, h_start, 0x12);
152 err += sn9c102_write_reg(cam, v_start, 0x13);
153
154 return err;
155}
156
157
158static int pas106b_set_pix_format(struct sn9c102_device* cam,
159 const struct v4l2_pix_format* pix)
160{
161 int err = 0;
162
163 if (pix->pixelformat == V4L2_PIX_FMT_SN9C10X)
164 err += sn9c102_write_reg(cam, 0x2c, 0x17);
165 else
166 err += sn9c102_write_reg(cam, 0x20, 0x17);
167
168 return err;
169}
170
171
172static struct sn9c102_sensor pas106b = {
173 .name = "PAS106B",
174 .maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>",
175 .sysfs_ops = SN9C102_I2C_READ | SN9C102_I2C_WRITE,
176 .frequency = SN9C102_I2C_400KHZ | SN9C102_I2C_100KHZ,
177 .interface = SN9C102_I2C_2WIRES,
178 .i2c_slave_id = 0x40,
179 .init = &pas106b_init,
180 .qctrl = {
181 {
182 .id = V4L2_CID_EXPOSURE,
183 .type = V4L2_CTRL_TYPE_INTEGER,
184 .name = "exposure",
185 .minimum = 0x125,
186 .maximum = 0xfff,
187 .step = 0x001,
188 .default_value = 0x140,
189 .flags = 0,
190 },
191 {
192 .id = V4L2_CID_GAIN,
193 .type = V4L2_CTRL_TYPE_INTEGER,
194 .name = "global gain",
195 .minimum = 0x00,
196 .maximum = 0x1f,
197 .step = 0x01,
198 .default_value = 0x0d,
199 .flags = 0,
200 },
201 {
202 .id = V4L2_CID_CONTRAST,
203 .type = V4L2_CTRL_TYPE_INTEGER,
204 .name = "contrast",
205 .minimum = 0x00,
206 .maximum = 0x07,
207 .step = 0x01,
208 .default_value = 0x00, /* 0x00~0x03 have same effect */
209 .flags = 0,
210 },
211 {
212 .id = V4L2_CID_RED_BALANCE,
213 .type = V4L2_CTRL_TYPE_INTEGER,
214 .name = "red balance",
215 .minimum = 0x00,
216 .maximum = 0x1f,
217 .step = 0x01,
218 .default_value = 0x04,
219 .flags = 0,
220 },
221 {
222 .id = V4L2_CID_BLUE_BALANCE,
223 .type = V4L2_CTRL_TYPE_INTEGER,
224 .name = "blue balance",
225 .minimum = 0x00,
226 .maximum = 0x1f,
227 .step = 0x01,
228 .default_value = 0x06,
229 .flags = 0,
230 },
231 {
232 .id = SN9C102_V4L2_CID_GREEN_BALANCE,
233 .type = V4L2_CTRL_TYPE_INTEGER,
234 .name = "green balance",
235 .minimum = 0x00,
236 .maximum = 0x3e,
237 .step = 0x02,
238 .default_value = 0x02,
239 .flags = 0,
240 },
241 {
242 .id = SN9C102_V4L2_CID_DAC_MAGNITUDE,
243 .type = V4L2_CTRL_TYPE_INTEGER,
244 .name = "DAC magnitude",
245 .minimum = 0x00,
246 .maximum = 0x1f,
247 .step = 0x01,
248 .default_value = 0x01,
249 .flags = 0,
250 },
251 },
252 .get_ctrl = &pas106b_get_ctrl,
253 .set_ctrl = &pas106b_set_ctrl,
254 .cropcap = {
255 .bounds = {
256 .left = 0,
257 .top = 0,
258 .width = 352,
259 .height = 288,
260 },
261 .defrect = {
262 .left = 0,
263 .top = 0,
264 .width = 352,
265 .height = 288,
266 },
267 },
268 .set_crop = &pas106b_set_crop,
269 .pix_format = {
270 .width = 352,
271 .height = 288,
272 .pixelformat = V4L2_PIX_FMT_SBGGR8,
273 .priv = 8, /* we use this field as 'bits per pixel' */
274 },
275 .set_pix_format = &pas106b_set_pix_format
276};
277
278
279int sn9c102_probe_pas106b(struct sn9c102_device* cam)
280{
281 int r0 = 0, r1 = 0, err = 0;
282 unsigned int pid = 0;
283
284 /*
285 Minimal initialization to enable the I2C communication
286 NOTE: do NOT change the values!
287 */
288 err += sn9c102_write_reg(cam, 0x01, 0x01); /* sensor power down */
289 err += sn9c102_write_reg(cam, 0x00, 0x01); /* sensor power on */
290 err += sn9c102_write_reg(cam, 0x28, 0x17); /* sensor clock at 24 MHz */
291 if (err)
292 return -EIO;
293
294 r0 = sn9c102_i2c_try_read(cam, &pas106b, 0x00);
295 r1 = sn9c102_i2c_try_read(cam, &pas106b, 0x01);
296
297 if (r0 < 0 || r1 < 0)
298 return -EIO;
299
300 pid = (r0 << 11) | ((r1 & 0xf0) >> 4);
301 if (pid != 0x007)
302 return -ENODEV;
303
304 sn9c102_attach_sensor(cam, &pas106b);
305
306 return 0;
307}
diff --git a/drivers/media/video/sn9c102/sn9c102_pas202bca.c b/drivers/media/video/sn9c102/sn9c102_pas202bca.c
new file mode 100644
index 000000000000..3453237055bb
--- /dev/null
+++ b/drivers/media/video/sn9c102/sn9c102_pas202bca.c
@@ -0,0 +1,238 @@
1/***************************************************************************
2 * Plug-in for PAS202BCA image sensor connected to the SN9C10x PC Camera *
3 * Controllers *
4 * *
5 * Copyright (C) 2006 by Luca Risolia <luca.risolia@studio.unibo.it> *
6 * *
7 * This program is free software; you can redistribute it and/or modify *
8 * it under the terms of the GNU General Public License as published by *
9 * the Free Software Foundation; either version 2 of the License, or *
10 * (at your option) any later version. *
11 * *
12 * This program is distributed in the hope that it will be useful, *
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15 * GNU General Public License for more details. *
16 * *
17 * You should have received a copy of the GNU General Public License *
18 * along with this program; if not, write to the Free Software *
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
20 ***************************************************************************/
21
22#include <linux/delay.h>
23#include "sn9c102_sensor.h"
24
25
26static struct sn9c102_sensor pas202bca;
27
28
29static int pas202bca_init(struct sn9c102_device* cam)
30{
31 int err = 0;
32
33 err += sn9c102_write_reg(cam, 0x00, 0x10);
34 err += sn9c102_write_reg(cam, 0x00, 0x11);
35 err += sn9c102_write_reg(cam, 0x00, 0x14);
36 err += sn9c102_write_reg(cam, 0x20, 0x17);
37 err += sn9c102_write_reg(cam, 0x30, 0x19);
38 err += sn9c102_write_reg(cam, 0x09, 0x18);
39
40 err += sn9c102_i2c_write(cam, 0x02, 0x14);
41 err += sn9c102_i2c_write(cam, 0x03, 0x40);
42 err += sn9c102_i2c_write(cam, 0x0d, 0x2c);
43 err += sn9c102_i2c_write(cam, 0x0e, 0x01);
44 err += sn9c102_i2c_write(cam, 0x0f, 0xa9);
45 err += sn9c102_i2c_write(cam, 0x10, 0x08);
46 err += sn9c102_i2c_write(cam, 0x13, 0x63);
47 err += sn9c102_i2c_write(cam, 0x15, 0x70);
48 err += sn9c102_i2c_write(cam, 0x11, 0x01);
49
50 msleep(400);
51
52 return err;
53}
54
55
56static int pas202bca_set_pix_format(struct sn9c102_device* cam,
57 const struct v4l2_pix_format* pix)
58{
59 int err = 0;
60
61 if (pix->pixelformat == V4L2_PIX_FMT_SN9C10X)
62 err += sn9c102_write_reg(cam, 0x24, 0x17);
63 else
64 err += sn9c102_write_reg(cam, 0x20, 0x17);
65
66 return err;
67}
68
69
70static int pas202bca_set_ctrl(struct sn9c102_device* cam,
71 const struct v4l2_control* ctrl)
72{
73 int err = 0;
74
75 switch (ctrl->id) {
76 case V4L2_CID_EXPOSURE:
77 err += sn9c102_i2c_write(cam, 0x04, ctrl->value >> 6);
78 err += sn9c102_i2c_write(cam, 0x05, ctrl->value & 0x3f);
79 break;
80 case V4L2_CID_RED_BALANCE:
81 err += sn9c102_i2c_write(cam, 0x09, ctrl->value);
82 break;
83 case V4L2_CID_BLUE_BALANCE:
84 err += sn9c102_i2c_write(cam, 0x07, ctrl->value);
85 break;
86 case V4L2_CID_GAIN:
87 err += sn9c102_i2c_write(cam, 0x10, ctrl->value);
88 break;
89 case SN9C102_V4L2_CID_GREEN_BALANCE:
90 err += sn9c102_i2c_write(cam, 0x08, ctrl->value);
91 break;
92 case SN9C102_V4L2_CID_DAC_MAGNITUDE:
93 err += sn9c102_i2c_write(cam, 0x0c, ctrl->value);
94 break;
95 default:
96 return -EINVAL;
97 }
98 err += sn9c102_i2c_write(cam, 0x11, 0x01);
99
100 return err ? -EIO : 0;
101}
102
103
104static int pas202bca_set_crop(struct sn9c102_device* cam,
105 const struct v4l2_rect* rect)
106{
107 struct sn9c102_sensor* s = &pas202bca;
108 int err = 0;
109 u8 h_start = (u8)(rect->left - s->cropcap.bounds.left) + 3,
110 v_start = (u8)(rect->top - s->cropcap.bounds.top) + 3;
111
112 err += sn9c102_write_reg(cam, h_start, 0x12);
113 err += sn9c102_write_reg(cam, v_start, 0x13);
114
115 return err;
116}
117
118
119static struct sn9c102_sensor pas202bca = {
120 .name = "PAS202BCA",
121 .maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>",
122 .sysfs_ops = SN9C102_I2C_READ | SN9C102_I2C_WRITE,
123 .frequency = SN9C102_I2C_400KHZ | SN9C102_I2C_100KHZ,
124 .interface = SN9C102_I2C_2WIRES,
125 .i2c_slave_id = 0x40,
126 .init = &pas202bca_init,
127 .qctrl = {
128 {
129 .id = V4L2_CID_EXPOSURE,
130 .type = V4L2_CTRL_TYPE_INTEGER,
131 .name = "exposure",
132 .minimum = 0x01e5,
133 .maximum = 0x3fff,
134 .step = 0x0001,
135 .default_value = 0x01e5,
136 .flags = 0,
137 },
138 {
139 .id = V4L2_CID_GAIN,
140 .type = V4L2_CTRL_TYPE_INTEGER,
141 .name = "global gain",
142 .minimum = 0x00,
143 .maximum = 0x1f,
144 .step = 0x01,
145 .default_value = 0x0c,
146 .flags = 0,
147 },
148 {
149 .id = V4L2_CID_RED_BALANCE,
150 .type = V4L2_CTRL_TYPE_INTEGER,
151 .name = "red balance",
152 .minimum = 0x00,
153 .maximum = 0x0f,
154 .step = 0x01,
155 .default_value = 0x01,
156 .flags = 0,
157 },
158 {
159 .id = V4L2_CID_BLUE_BALANCE,
160 .type = V4L2_CTRL_TYPE_INTEGER,
161 .name = "blue balance",
162 .minimum = 0x00,
163 .maximum = 0x0f,
164 .step = 0x01,
165 .default_value = 0x05,
166 .flags = 0,
167 },
168 {
169 .id = SN9C102_V4L2_CID_GREEN_BALANCE,
170 .type = V4L2_CTRL_TYPE_INTEGER,
171 .name = "green balance",
172 .minimum = 0x00,
173 .maximum = 0x0f,
174 .step = 0x01,
175 .default_value = 0x00,
176 .flags = 0,
177 },
178 {
179 .id = SN9C102_V4L2_CID_DAC_MAGNITUDE,
180 .type = V4L2_CTRL_TYPE_INTEGER,
181 .name = "DAC magnitude",
182 .minimum = 0x00,
183 .maximum = 0xff,
184 .step = 0x01,
185 .default_value = 0x04,
186 .flags = 0,
187 },
188 },
189 .set_ctrl = &pas202bca_set_ctrl,
190 .cropcap = {
191 .bounds = {
192 .left = 0,
193 .top = 0,
194 .width = 640,
195 .height = 480,
196 },
197 .defrect = {
198 .left = 0,
199 .top = 0,
200 .width = 640,
201 .height = 480,
202 },
203 },
204 .set_crop = &pas202bca_set_crop,
205 .pix_format = {
206 .width = 640,
207 .height = 480,
208 .pixelformat = V4L2_PIX_FMT_SBGGR8,
209 .priv = 8,
210 },
211 .set_pix_format = &pas202bca_set_pix_format
212};
213
214
215int sn9c102_probe_pas202bca(struct sn9c102_device* cam)
216{
217 const struct usb_device_id pas202bca_id_table[] = {
218 { USB_DEVICE(0x0c45, 0x60af), },
219 { }
220 };
221 int err = 0;
222
223 if (!sn9c102_match_id(cam,pas202bca_id_table))
224 return -ENODEV;
225
226 err += sn9c102_write_reg(cam, 0x01, 0x01);
227 err += sn9c102_write_reg(cam, 0x40, 0x01);
228 err += sn9c102_write_reg(cam, 0x28, 0x17);
229 if (err)
230 return -EIO;
231
232 if (sn9c102_i2c_try_write(cam, &pas202bca, 0x10, 0)) /* try to write */
233 return -ENODEV;
234
235 sn9c102_attach_sensor(cam, &pas202bca);
236
237 return 0;
238}
diff --git a/drivers/media/video/sn9c102/sn9c102_pas202bcb.c b/drivers/media/video/sn9c102/sn9c102_pas202bcb.c
new file mode 100644
index 000000000000..d068616ab337
--- /dev/null
+++ b/drivers/media/video/sn9c102/sn9c102_pas202bcb.c
@@ -0,0 +1,293 @@
1/***************************************************************************
2 * Plug-in for PAS202BCB image sensor connected to the SN9C10x PC Camera *
3 * Controllers *
4 * *
5 * Copyright (C) 2004 by Carlos Eduardo Medaglia Dyonisio *
6 * <medaglia@undl.org.br> *
7 * http://cadu.homelinux.com:8080/ *
8 * *
9 * DAC Magnitude, exposure and green gain controls added by *
10 * Luca Risolia <luca.risolia@studio.unibo.it> *
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., 675 Mass Ave, Cambridge, MA 02139, USA. *
25 ***************************************************************************/
26
27#include <linux/delay.h>
28#include "sn9c102_sensor.h"
29
30
31static struct sn9c102_sensor pas202bcb;
32
33
34static int pas202bcb_init(struct sn9c102_device* cam)
35{
36 int err = 0;
37
38 err += sn9c102_write_reg(cam, 0x00, 0x10);
39 err += sn9c102_write_reg(cam, 0x00, 0x11);
40 err += sn9c102_write_reg(cam, 0x00, 0x14);
41 err += sn9c102_write_reg(cam, 0x20, 0x17);
42 err += sn9c102_write_reg(cam, 0x30, 0x19);
43 err += sn9c102_write_reg(cam, 0x09, 0x18);
44
45 err += sn9c102_i2c_write(cam, 0x02, 0x14);
46 err += sn9c102_i2c_write(cam, 0x03, 0x40);
47 err += sn9c102_i2c_write(cam, 0x0d, 0x2c);
48 err += sn9c102_i2c_write(cam, 0x0e, 0x01);
49 err += sn9c102_i2c_write(cam, 0x0f, 0xa9);
50 err += sn9c102_i2c_write(cam, 0x10, 0x08);
51 err += sn9c102_i2c_write(cam, 0x13, 0x63);
52 err += sn9c102_i2c_write(cam, 0x15, 0x70);
53 err += sn9c102_i2c_write(cam, 0x11, 0x01);
54
55 msleep(400);
56
57 return err;
58}
59
60
61static int pas202bcb_get_ctrl(struct sn9c102_device* cam,
62 struct v4l2_control* ctrl)
63{
64 switch (ctrl->id) {
65 case V4L2_CID_EXPOSURE:
66 {
67 int r1 = sn9c102_i2c_read(cam, 0x04),
68 r2 = sn9c102_i2c_read(cam, 0x05);
69 if (r1 < 0 || r2 < 0)
70 return -EIO;
71 ctrl->value = (r1 << 6) | (r2 & 0x3f);
72 }
73 return 0;
74 case V4L2_CID_RED_BALANCE:
75 if ((ctrl->value = sn9c102_i2c_read(cam, 0x09)) < 0)
76 return -EIO;
77 ctrl->value &= 0x0f;
78 return 0;
79 case V4L2_CID_BLUE_BALANCE:
80 if ((ctrl->value = sn9c102_i2c_read(cam, 0x07)) < 0)
81 return -EIO;
82 ctrl->value &= 0x0f;
83 return 0;
84 case V4L2_CID_GAIN:
85 if ((ctrl->value = sn9c102_i2c_read(cam, 0x10)) < 0)
86 return -EIO;
87 ctrl->value &= 0x1f;
88 return 0;
89 case SN9C102_V4L2_CID_GREEN_BALANCE:
90 if ((ctrl->value = sn9c102_i2c_read(cam, 0x08)) < 0)
91 return -EIO;
92 ctrl->value &= 0x0f;
93 return 0;
94 case SN9C102_V4L2_CID_DAC_MAGNITUDE:
95 if ((ctrl->value = sn9c102_i2c_read(cam, 0x0c)) < 0)
96 return -EIO;
97 return 0;
98 default:
99 return -EINVAL;
100 }
101}
102
103
104static int pas202bcb_set_pix_format(struct sn9c102_device* cam,
105 const struct v4l2_pix_format* pix)
106{
107 int err = 0;
108
109 if (pix->pixelformat == V4L2_PIX_FMT_SN9C10X)
110 err += sn9c102_write_reg(cam, 0x24, 0x17);
111 else
112 err += sn9c102_write_reg(cam, 0x20, 0x17);
113
114 return err;
115}
116
117
118static int pas202bcb_set_ctrl(struct sn9c102_device* cam,
119 const struct v4l2_control* ctrl)
120{
121 int err = 0;
122
123 switch (ctrl->id) {
124 case V4L2_CID_EXPOSURE:
125 err += sn9c102_i2c_write(cam, 0x04, ctrl->value >> 6);
126 err += sn9c102_i2c_write(cam, 0x05, ctrl->value & 0x3f);
127 break;
128 case V4L2_CID_RED_BALANCE:
129 err += sn9c102_i2c_write(cam, 0x09, ctrl->value);
130 break;
131 case V4L2_CID_BLUE_BALANCE:
132 err += sn9c102_i2c_write(cam, 0x07, ctrl->value);
133 break;
134 case V4L2_CID_GAIN:
135 err += sn9c102_i2c_write(cam, 0x10, ctrl->value);
136 break;
137 case SN9C102_V4L2_CID_GREEN_BALANCE:
138 err += sn9c102_i2c_write(cam, 0x08, ctrl->value);
139 break;
140 case SN9C102_V4L2_CID_DAC_MAGNITUDE:
141 err += sn9c102_i2c_write(cam, 0x0c, ctrl->value);
142 break;
143 default:
144 return -EINVAL;
145 }
146 err += sn9c102_i2c_write(cam, 0x11, 0x01);
147
148 return err ? -EIO : 0;
149}
150
151
152static int pas202bcb_set_crop(struct sn9c102_device* cam,
153 const struct v4l2_rect* rect)
154{
155 struct sn9c102_sensor* s = &pas202bcb;
156 int err = 0;
157 u8 h_start = (u8)(rect->left - s->cropcap.bounds.left) + 4,
158 v_start = (u8)(rect->top - s->cropcap.bounds.top) + 3;
159
160 err += sn9c102_write_reg(cam, h_start, 0x12);
161 err += sn9c102_write_reg(cam, v_start, 0x13);
162
163 return err;
164}
165
166
167static struct sn9c102_sensor pas202bcb = {
168 .name = "PAS202BCB",
169 .maintainer = "Carlos Eduardo Medaglia Dyonisio "
170 "<medaglia@undl.org.br>",
171 .sysfs_ops = SN9C102_I2C_READ | SN9C102_I2C_WRITE,
172 .frequency = SN9C102_I2C_400KHZ | SN9C102_I2C_100KHZ,
173 .interface = SN9C102_I2C_2WIRES,
174 .i2c_slave_id = 0x40,
175 .init = &pas202bcb_init,
176 .qctrl = {
177 {
178 .id = V4L2_CID_EXPOSURE,
179 .type = V4L2_CTRL_TYPE_INTEGER,
180 .name = "exposure",
181 .minimum = 0x01e5,
182 .maximum = 0x3fff,
183 .step = 0x0001,
184 .default_value = 0x01e5,
185 .flags = 0,
186 },
187 {
188 .id = V4L2_CID_GAIN,
189 .type = V4L2_CTRL_TYPE_INTEGER,
190 .name = "global gain",
191 .minimum = 0x00,
192 .maximum = 0x1f,
193 .step = 0x01,
194 .default_value = 0x0c,
195 .flags = 0,
196 },
197 {
198 .id = V4L2_CID_RED_BALANCE,
199 .type = V4L2_CTRL_TYPE_INTEGER,
200 .name = "red balance",
201 .minimum = 0x00,
202 .maximum = 0x0f,
203 .step = 0x01,
204 .default_value = 0x01,
205 .flags = 0,
206 },
207 {
208 .id = V4L2_CID_BLUE_BALANCE,
209 .type = V4L2_CTRL_TYPE_INTEGER,
210 .name = "blue balance",
211 .minimum = 0x00,
212 .maximum = 0x0f,
213 .step = 0x01,
214 .default_value = 0x05,
215 .flags = 0,
216 },
217 {
218 .id = SN9C102_V4L2_CID_GREEN_BALANCE,
219 .type = V4L2_CTRL_TYPE_INTEGER,
220 .name = "green balance",
221 .minimum = 0x00,
222 .maximum = 0x0f,
223 .step = 0x01,
224 .default_value = 0x00,
225 .flags = 0,
226 },
227 {
228 .id = SN9C102_V4L2_CID_DAC_MAGNITUDE,
229 .type = V4L2_CTRL_TYPE_INTEGER,
230 .name = "DAC magnitude",
231 .minimum = 0x00,
232 .maximum = 0xff,
233 .step = 0x01,
234 .default_value = 0x04,
235 .flags = 0,
236 },
237 },
238 .get_ctrl = &pas202bcb_get_ctrl,
239 .set_ctrl = &pas202bcb_set_ctrl,
240 .cropcap = {
241 .bounds = {
242 .left = 0,
243 .top = 0,
244 .width = 640,
245 .height = 480,
246 },
247 .defrect = {
248 .left = 0,
249 .top = 0,
250 .width = 640,
251 .height = 480,
252 },
253 },
254 .set_crop = &pas202bcb_set_crop,
255 .pix_format = {
256 .width = 640,
257 .height = 480,
258 .pixelformat = V4L2_PIX_FMT_SBGGR8,
259 .priv = 8,
260 },
261 .set_pix_format = &pas202bcb_set_pix_format
262};
263
264
265int sn9c102_probe_pas202bcb(struct sn9c102_device* cam)
266{
267 int r0 = 0, r1 = 0, err = 0;
268 unsigned int pid = 0;
269
270 /*
271 * Minimal initialization to enable the I2C communication
272 * NOTE: do NOT change the values!
273 */
274 err += sn9c102_write_reg(cam, 0x01, 0x01); /* sensor power down */
275 err += sn9c102_write_reg(cam, 0x40, 0x01); /* sensor power on */
276 err += sn9c102_write_reg(cam, 0x28, 0x17); /* sensor clock at 24 MHz */
277 if (err)
278 return -EIO;
279
280 r0 = sn9c102_i2c_try_read(cam, &pas202bcb, 0x00);
281 r1 = sn9c102_i2c_try_read(cam, &pas202bcb, 0x01);
282
283 if (r0 < 0 || r1 < 0)
284 return -EIO;
285
286 pid = (r0 << 4) | ((r1 & 0xf0) >> 4);
287 if (pid != 0x017)
288 return -ENODEV;
289
290 sn9c102_attach_sensor(cam, &pas202bcb);
291
292 return 0;
293}
diff --git a/drivers/media/video/sn9c102/sn9c102_sensor.h b/drivers/media/video/sn9c102/sn9c102_sensor.h
new file mode 100644
index 000000000000..2afd9e9d09bb
--- /dev/null
+++ b/drivers/media/video/sn9c102/sn9c102_sensor.h
@@ -0,0 +1,389 @@
1/***************************************************************************
2 * API for image sensors connected to the SN9C10x PC Camera Controllers *
3 * *
4 * Copyright (C) 2004-2006 by Luca Risolia <luca.risolia@studio.unibo.it> *
5 * *
6 * This program is free software; you can redistribute it and/or modify *
7 * it under the terms of the GNU General Public License as published by *
8 * the Free Software Foundation; either version 2 of the License, or *
9 * (at your option) any later version. *
10 * *
11 * This program is distributed in the hope that it will be useful, *
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14 * GNU General Public License for more details. *
15 * *
16 * You should have received a copy of the GNU General Public License *
17 * along with this program; if not, write to the Free Software *
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
19 ***************************************************************************/
20
21#ifndef _SN9C102_SENSOR_H_
22#define _SN9C102_SENSOR_H_
23
24#include <linux/usb.h>
25#include <linux/videodev.h>
26#include <linux/device.h>
27#include <linux/stddef.h>
28#include <linux/errno.h>
29#include <asm/types.h>
30
31struct sn9c102_device;
32struct sn9c102_sensor;
33
34/*****************************************************************************/
35
36/*
37 OVERVIEW.
38 This is a small interface that allows you to add support for any CCD/CMOS
39 image sensors connected to the SN9C10X bridges. The entire API is documented
40 below. In the most general case, to support a sensor there are three steps
41 you have to follow:
42 1) define the main "sn9c102_sensor" structure by setting the basic fields;
43 2) write a probing function to be called by the core module when the USB
44 camera is recognized, then add both the USB ids and the name of that
45 function to the two corresponding tables SENSOR_TABLE and ID_TABLE (see
46 below);
47 3) implement the methods that you want/need (and fill the rest of the main
48 structure accordingly).
49 "sn9c102_pas106b.c" is an example of all this stuff. Remember that you do
50 NOT need to touch the source code of the core module for the things to work
51 properly, unless you find bugs or flaws in it. Finally, do not forget to
52 read the V4L2 API for completeness.
53*/
54
55/*****************************************************************************/
56
57/*
58 Probing functions: on success, you must attach the sensor to the camera
59 by calling sn9c102_attach_sensor() provided below.
60 To enable the I2C communication, you might need to perform a really basic
61 initialization of the SN9C10X chip by using the write function declared
62 ahead.
63 Functions must return 0 on success, the appropriate error otherwise.
64*/
65extern int sn9c102_probe_hv7131d(struct sn9c102_device* cam);
66extern int sn9c102_probe_mi0343(struct sn9c102_device* cam);
67extern int sn9c102_probe_ov7630(struct sn9c102_device* cam);
68extern int sn9c102_probe_pas106b(struct sn9c102_device* cam);
69extern int sn9c102_probe_pas202bca(struct sn9c102_device* cam);
70extern int sn9c102_probe_pas202bcb(struct sn9c102_device* cam);
71extern int sn9c102_probe_tas5110c1b(struct sn9c102_device* cam);
72extern int sn9c102_probe_tas5130d1b(struct sn9c102_device* cam);
73
74/*
75 Add the above entries to this table. Be sure to add the entry in the right
76 place, since, on failure, the next probing routine is called according to
77 the order of the list below, from top to bottom.
78*/
79#define SN9C102_SENSOR_TABLE \
80static int (*sn9c102_sensor_table[])(struct sn9c102_device*) = { \
81 &sn9c102_probe_mi0343, /* strong detection based on SENSOR ids */ \
82 &sn9c102_probe_pas106b, /* strong detection based on SENSOR ids */ \
83 &sn9c102_probe_pas202bcb, /* strong detection based on SENSOR ids */ \
84 &sn9c102_probe_hv7131d, /* strong detection based on SENSOR ids */ \
85 &sn9c102_probe_pas202bca, /* detection mostly based on USB pid/vid */ \
86 &sn9c102_probe_ov7630, /* detection mostly based on USB pid/vid */ \
87 &sn9c102_probe_tas5110c1b, /* detection based on USB pid/vid */ \
88 &sn9c102_probe_tas5130d1b, /* detection based on USB pid/vid */ \
89 NULL, \
90};
91
92/* Device identification */
93extern struct sn9c102_device*
94sn9c102_match_id(struct sn9c102_device* cam, const struct usb_device_id *id);
95
96/* Attach a probed sensor to the camera. */
97extern void
98sn9c102_attach_sensor(struct sn9c102_device* cam,
99 struct sn9c102_sensor* sensor);
100
101/*
102 Each SN9C10x camera has proper PID/VID identifiers.
103 SN9C103 supports multiple interfaces, but we only handle the video class
104 interface.
105*/
106#define SN9C102_USB_DEVICE(vend, prod, intclass) \
107 .match_flags = USB_DEVICE_ID_MATCH_DEVICE | \
108 USB_DEVICE_ID_MATCH_INT_CLASS, \
109 .idVendor = (vend), \
110 .idProduct = (prod), \
111 .bInterfaceClass = (intclass)
112
113#define SN9C102_ID_TABLE \
114static const struct usb_device_id sn9c102_id_table[] = { \
115 { USB_DEVICE(0x0c45, 0x6001), }, /* TAS5110C1B */ \
116 { USB_DEVICE(0x0c45, 0x6005), }, /* TAS5110C1B */ \
117 { USB_DEVICE(0x0c45, 0x6007), }, \
118 { USB_DEVICE(0x0c45, 0x6009), }, /* PAS106B */ \
119 { USB_DEVICE(0x0c45, 0x600d), }, /* PAS106B */ \
120 { USB_DEVICE(0x0c45, 0x6024), }, \
121 { USB_DEVICE(0x0c45, 0x6025), }, /* TAS5130D1B and TAS5110C1B */ \
122 { USB_DEVICE(0x0c45, 0x6028), }, /* PAS202BCB */ \
123 { USB_DEVICE(0x0c45, 0x6029), }, /* PAS106B */ \
124 { USB_DEVICE(0x0c45, 0x602a), }, /* HV7131D */ \
125 { USB_DEVICE(0x0c45, 0x602b), }, /* MI-0343 */ \
126 { USB_DEVICE(0x0c45, 0x602c), }, /* OV7630 */ \
127 { USB_DEVICE(0x0c45, 0x602d), }, \
128 { USB_DEVICE(0x0c45, 0x602e), }, /* OV7630 */ \
129 { USB_DEVICE(0x0c45, 0x6030), }, /* MI03x */ \
130 { SN9C102_USB_DEVICE(0x0c45, 0x6080, 0xff), }, \
131 { SN9C102_USB_DEVICE(0x0c45, 0x6082, 0xff), }, /* MI0343 & MI0360 */ \
132 { SN9C102_USB_DEVICE(0x0c45, 0x6083, 0xff), }, /* HV7131[D|E1] */ \
133 { SN9C102_USB_DEVICE(0x0c45, 0x6088, 0xff), }, \
134 { SN9C102_USB_DEVICE(0x0c45, 0x608a, 0xff), }, \
135 { SN9C102_USB_DEVICE(0x0c45, 0x608b, 0xff), }, \
136 { SN9C102_USB_DEVICE(0x0c45, 0x608c, 0xff), }, /* HV7131/R */ \
137 { SN9C102_USB_DEVICE(0x0c45, 0x608e, 0xff), }, /* CIS-VF10 */ \
138 { SN9C102_USB_DEVICE(0x0c45, 0x608f, 0xff), }, /* OV7630 */ \
139 { SN9C102_USB_DEVICE(0x0c45, 0x60a0, 0xff), }, \
140 { SN9C102_USB_DEVICE(0x0c45, 0x60a2, 0xff), }, \
141 { SN9C102_USB_DEVICE(0x0c45, 0x60a3, 0xff), }, \
142 { SN9C102_USB_DEVICE(0x0c45, 0x60a8, 0xff), }, /* PAS106B */ \
143 { SN9C102_USB_DEVICE(0x0c45, 0x60aa, 0xff), }, /* TAS5130D1B */ \
144 { SN9C102_USB_DEVICE(0x0c45, 0x60ab, 0xff), }, /* TAS5110C1B */ \
145 { SN9C102_USB_DEVICE(0x0c45, 0x60ac, 0xff), }, \
146 { SN9C102_USB_DEVICE(0x0c45, 0x60ae, 0xff), }, \
147 { SN9C102_USB_DEVICE(0x0c45, 0x60af, 0xff), }, /* PAS202BCB */ \
148 { SN9C102_USB_DEVICE(0x0c45, 0x60b0, 0xff), }, /* OV7630 (?) */ \
149 { SN9C102_USB_DEVICE(0x0c45, 0x60b2, 0xff), }, \
150 { SN9C102_USB_DEVICE(0x0c45, 0x60b3, 0xff), }, \
151 { SN9C102_USB_DEVICE(0x0c45, 0x60b8, 0xff), }, \
152 { SN9C102_USB_DEVICE(0x0c45, 0x60ba, 0xff), }, \
153 { SN9C102_USB_DEVICE(0x0c45, 0x60bb, 0xff), }, \
154 { SN9C102_USB_DEVICE(0x0c45, 0x60bc, 0xff), }, \
155 { SN9C102_USB_DEVICE(0x0c45, 0x60be, 0xff), }, \
156 { } \
157};
158
159/*****************************************************************************/
160
161/*
162 Read/write routines: they always return -1 on error, 0 or the read value
163 otherwise. NOTE that a real read operation is not supported by the SN9C10X
164 chip for some of its registers. To work around this problem, a pseudo-read
165 call is provided instead: it returns the last successfully written value
166 on the register (0 if it has never been written), the usual -1 on error.
167*/
168
169/* The "try" I2C I/O versions are used when probing the sensor */
170extern int sn9c102_i2c_try_write(struct sn9c102_device*,struct sn9c102_sensor*,
171 u8 address, u8 value);
172extern int sn9c102_i2c_try_read(struct sn9c102_device*,struct sn9c102_sensor*,
173 u8 address);
174
175/*
176 These must be used if and only if the sensor doesn't implement the standard
177 I2C protocol. There are a number of good reasons why you must use the
178 single-byte versions of these functions: do not abuse. The first function
179 writes n bytes, from data0 to datan, to registers 0x09 - 0x09+n of SN9C10X
180 chip. The second one programs the registers 0x09 and 0x10 with data0 and
181 data1, and places the n bytes read from the sensor register table in the
182 buffer pointed by 'buffer'. Both the functions return -1 on error; the write
183 version returns 0 on success, while the read version returns the first read
184 byte.
185*/
186extern int sn9c102_i2c_try_raw_write(struct sn9c102_device* cam,
187 struct sn9c102_sensor* sensor, u8 n,
188 u8 data0, u8 data1, u8 data2, u8 data3,
189 u8 data4, u8 data5);
190extern int sn9c102_i2c_try_raw_read(struct sn9c102_device* cam,
191 struct sn9c102_sensor* sensor, u8 data0,
192 u8 data1, u8 n, u8 buffer[]);
193
194/* To be used after the sensor struct has been attached to the camera struct */
195extern int sn9c102_i2c_write(struct sn9c102_device*, u8 address, u8 value);
196extern int sn9c102_i2c_read(struct sn9c102_device*, u8 address);
197
198/* I/O on registers in the bridge. Could be used by the sensor methods too */
199extern int sn9c102_write_regs(struct sn9c102_device*, u8* buff, u16 index);
200extern int sn9c102_write_reg(struct sn9c102_device*, u8 value, u16 index);
201extern int sn9c102_pread_reg(struct sn9c102_device*, u16 index);
202
203/*
204 NOTE: there are no exported debugging functions. To uniform the output you
205 must use the dev_info()/dev_warn()/dev_err() macros defined in device.h,
206 already included here, the argument being the struct device '&usbdev->dev'
207 of the sensor structure. Do NOT use these macros before the sensor is
208 attached or the kernel will crash! However, you should not need to notify
209 the user about common errors or other messages, since this is done by the
210 master module.
211*/
212
213/*****************************************************************************/
214
215enum sn9c102_i2c_sysfs_ops {
216 SN9C102_I2C_READ = 0x01,
217 SN9C102_I2C_WRITE = 0x02,
218};
219
220enum sn9c102_i2c_frequency { /* sensors may support both the frequencies */
221 SN9C102_I2C_100KHZ = 0x01,
222 SN9C102_I2C_400KHZ = 0x02,
223};
224
225enum sn9c102_i2c_interface {
226 SN9C102_I2C_2WIRES,
227 SN9C102_I2C_3WIRES,
228};
229
230#define SN9C102_MAX_CTRLS V4L2_CID_LASTP1-V4L2_CID_BASE+10
231
232struct sn9c102_sensor {
233 char name[32], /* sensor name */
234 maintainer[64]; /* name of the mantainer <email> */
235
236 /* Supported operations through the 'sysfs' interface */
237 enum sn9c102_i2c_sysfs_ops sysfs_ops;
238
239 /*
240 These sensor capabilities must be provided if the SN9C10X controller
241 needs to communicate through the sensor serial interface by using
242 at least one of the i2c functions available.
243 */
244 enum sn9c102_i2c_frequency frequency;
245 enum sn9c102_i2c_interface interface;
246
247 /*
248 This identifier must be provided if the image sensor implements
249 the standard I2C protocol.
250 */
251 u8 i2c_slave_id; /* reg. 0x09 */
252
253 /*
254 NOTE: Where not noted,most of the functions below are not mandatory.
255 Set to null if you do not implement them. If implemented,
256 they must return 0 on success, the proper error otherwise.
257 */
258
259 int (*init)(struct sn9c102_device* cam);
260 /*
261 This function will be called after the sensor has been attached.
262 It should be used to initialize the sensor only, but may also
263 configure part of the SN9C10X chip if necessary. You don't need to
264 setup picture settings like brightness, contrast, etc.. here, if
265 the corrisponding controls are implemented (see below), since
266 they are adjusted in the core driver by calling the set_ctrl()
267 method after init(), where the arguments are the default values
268 specified in the v4l2_queryctrl list of supported controls;
269 Same suggestions apply for other settings, _if_ the corresponding
270 methods are present; if not, the initialization must configure the
271 sensor according to the default configuration structures below.
272 */
273
274 struct v4l2_queryctrl qctrl[SN9C102_MAX_CTRLS];
275 /*
276 Optional list of default controls, defined as indicated in the
277 V4L2 API. Menu type controls are not handled by this interface.
278 */
279
280 int (*get_ctrl)(struct sn9c102_device* cam, struct v4l2_control* ctrl);
281 int (*set_ctrl)(struct sn9c102_device* cam,
282 const struct v4l2_control* ctrl);
283 /*
284 You must implement at least the set_ctrl method if you have defined
285 the list above. The returned value must follow the V4L2
286 specifications for the VIDIOC_G|C_CTRL ioctls. V4L2_CID_H|VCENTER
287 are not supported by this driver, so do not implement them. Also,
288 you don't have to check whether the passed values are out of bounds,
289 given that this is done by the core module.
290 */
291
292 struct v4l2_cropcap cropcap;
293 /*
294 Think the image sensor as a grid of R,G,B monochromatic pixels
295 disposed according to a particular Bayer pattern, which describes
296 the complete array of pixels, from (0,0) to (xmax, ymax). We will
297 use this coordinate system from now on. It is assumed the sensor
298 chip can be programmed to capture/transmit a subsection of that
299 array of pixels: we will call this subsection "active window".
300 It is not always true that the largest achievable active window can
301 cover the whole array of pixels. The V4L2 API defines another
302 area called "source rectangle", which, in turn, is a subrectangle of
303 the active window. The SN9C10X chip is always programmed to read the
304 source rectangle.
305 The bounds of both the active window and the source rectangle are
306 specified in the cropcap substructures 'bounds' and 'defrect'.
307 By default, the source rectangle should cover the largest possible
308 area. Again, it is not always true that the largest source rectangle
309 can cover the entire active window, although it is a rare case for
310 the hardware we have. The bounds of the source rectangle _must_ be
311 multiple of 16 and must use the same coordinate system as indicated
312 before; their centers shall align initially.
313 If necessary, the sensor chip must be initialized during init() to
314 set the bounds of the active sensor window; however, by default, it
315 usually covers the largest achievable area (maxwidth x maxheight)
316 of pixels, so no particular initialization is needed, if you have
317 defined the correct default bounds in the structures.
318 See the V4L2 API for further details.
319 NOTE: once you have defined the bounds of the active window
320 (struct cropcap.bounds) you must not change them.anymore.
321 Only 'bounds' and 'defrect' fields are mandatory, other fields
322 will be ignored.
323 */
324
325 int (*set_crop)(struct sn9c102_device* cam,
326 const struct v4l2_rect* rect);
327 /*
328 To be called on VIDIOC_C_SETCROP. The core module always calls a
329 default routine which configures the appropriate SN9C10X regs (also
330 scaling), but you may need to override/adjust specific stuff.
331 'rect' contains width and height values that are multiple of 16: in
332 case you override the default function, you always have to program
333 the chip to match those values; on error return the corresponding
334 error code without rolling back.
335 NOTE: in case, you must program the SN9C10X chip to get rid of
336 blank pixels or blank lines at the _start_ of each line or
337 frame after each HSYNC or VSYNC, so that the image starts with
338 real RGB data (see regs 0x12, 0x13) (having set H_SIZE and,
339 V_SIZE you don't have to care about blank pixels or blank
340 lines at the end of each line or frame).
341 */
342
343 struct v4l2_pix_format pix_format;
344 /*
345 What you have to define here are: 1) initial 'width' and 'height' of
346 the target rectangle 2) the initial 'pixelformat', which can be
347 either V4L2_PIX_FMT_SN9C10X (for compressed video) or
348 V4L2_PIX_FMT_SBGGR8 3) 'priv', which we'll be used to indicate the
349 number of bits per pixel for uncompressed video, 8 or 9 (despite the
350 current value of 'pixelformat').
351 NOTE 1: both 'width' and 'height' _must_ be either 1/1 or 1/2 or 1/4
352 of cropcap.defrect.width and cropcap.defrect.height. I
353 suggest 1/1.
354 NOTE 2: The initial compression quality is defined by the first bit
355 of reg 0x17 during the initialization of the image sensor.
356 NOTE 3: as said above, you have to program the SN9C10X chip to get
357 rid of any blank pixels, so that the output of the sensor
358 matches the RGB bayer sequence (i.e. BGBGBG...GRGRGR).
359 */
360
361 int (*set_pix_format)(struct sn9c102_device* cam,
362 const struct v4l2_pix_format* pix);
363 /*
364 To be called on VIDIOC_S_FMT, when switching from the SBGGR8 to
365 SN9C10X pixel format or viceversa. On error return the corresponding
366 error code without rolling back.
367 */
368
369 /*
370 Do NOT write to the data below, it's READ ONLY. It is used by the
371 core module to store successfully updated values of the above
372 settings, for rollbacks..etc..in case of errors during atomic I/O
373 */
374 struct v4l2_queryctrl _qctrl[SN9C102_MAX_CTRLS];
375 struct v4l2_rect _rect;
376};
377
378/*****************************************************************************/
379
380/* Private ioctl's for control settings supported by some image sensors */
381#define SN9C102_V4L2_CID_DAC_MAGNITUDE V4L2_CID_PRIVATE_BASE
382#define SN9C102_V4L2_CID_GREEN_BALANCE V4L2_CID_PRIVATE_BASE + 1
383#define SN9C102_V4L2_CID_RESET_LEVEL V4L2_CID_PRIVATE_BASE + 2
384#define SN9C102_V4L2_CID_PIXEL_BIAS_VOLTAGE V4L2_CID_PRIVATE_BASE + 3
385#define SN9C102_V4L2_CID_GAMMA V4L2_CID_PRIVATE_BASE + 4
386#define SN9C102_V4L2_CID_BAND_FILTER V4L2_CID_PRIVATE_BASE + 5
387#define SN9C102_V4L2_CID_BRIGHT_LEVEL V4L2_CID_PRIVATE_BASE + 6
388
389#endif /* _SN9C102_SENSOR_H_ */
diff --git a/drivers/media/video/sn9c102/sn9c102_tas5110c1b.c b/drivers/media/video/sn9c102/sn9c102_tas5110c1b.c
new file mode 100644
index 000000000000..2e08c552f40a
--- /dev/null
+++ b/drivers/media/video/sn9c102/sn9c102_tas5110c1b.c
@@ -0,0 +1,159 @@
1/***************************************************************************
2 * Plug-in for TAS5110C1B image sensor connected to the SN9C10x PC Camera *
3 * Controllers *
4 * *
5 * Copyright (C) 2004-2006 by Luca Risolia <luca.risolia@studio.unibo.it> *
6 * *
7 * This program is free software; you can redistribute it and/or modify *
8 * it under the terms of the GNU General Public License as published by *
9 * the Free Software Foundation; either version 2 of the License, or *
10 * (at your option) any later version. *
11 * *
12 * This program is distributed in the hope that it will be useful, *
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15 * GNU General Public License for more details. *
16 * *
17 * You should have received a copy of the GNU General Public License *
18 * along with this program; if not, write to the Free Software *
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
20 ***************************************************************************/
21
22#include "sn9c102_sensor.h"
23
24
25static struct sn9c102_sensor tas5110c1b;
26
27
28static int tas5110c1b_init(struct sn9c102_device* cam)
29{
30 int err = 0;
31
32 err += sn9c102_write_reg(cam, 0x01, 0x01);
33 err += sn9c102_write_reg(cam, 0x44, 0x01);
34 err += sn9c102_write_reg(cam, 0x00, 0x10);
35 err += sn9c102_write_reg(cam, 0x00, 0x11);
36 err += sn9c102_write_reg(cam, 0x0a, 0x14);
37 err += sn9c102_write_reg(cam, 0x60, 0x17);
38 err += sn9c102_write_reg(cam, 0x06, 0x18);
39 err += sn9c102_write_reg(cam, 0xfb, 0x19);
40
41 err += sn9c102_i2c_write(cam, 0xc0, 0x80);
42
43 return err;
44}
45
46
47static int tas5110c1b_set_ctrl(struct sn9c102_device* cam,
48 const struct v4l2_control* ctrl)
49{
50 int err = 0;
51
52 switch (ctrl->id) {
53 case V4L2_CID_GAIN:
54 err += sn9c102_i2c_write(cam, 0x20, 0xf6 - ctrl->value);
55 break;
56 default:
57 return -EINVAL;
58 }
59
60 return err ? -EIO : 0;
61}
62
63
64static int tas5110c1b_set_crop(struct sn9c102_device* cam,
65 const struct v4l2_rect* rect)
66{
67 struct sn9c102_sensor* s = &tas5110c1b;
68 int err = 0;
69 u8 h_start = (u8)(rect->left - s->cropcap.bounds.left) + 69,
70 v_start = (u8)(rect->top - s->cropcap.bounds.top) + 9;
71
72 err += sn9c102_write_reg(cam, h_start, 0x12);
73 err += sn9c102_write_reg(cam, v_start, 0x13);
74
75 /* Don't change ! */
76 err += sn9c102_write_reg(cam, 0x14, 0x1a);
77 err += sn9c102_write_reg(cam, 0x0a, 0x1b);
78 err += sn9c102_write_reg(cam, sn9c102_pread_reg(cam, 0x19), 0x19);
79
80 return err;
81}
82
83
84static int tas5110c1b_set_pix_format(struct sn9c102_device* cam,
85 const struct v4l2_pix_format* pix)
86{
87 int err = 0;
88
89 if (pix->pixelformat == V4L2_PIX_FMT_SN9C10X)
90 err += sn9c102_write_reg(cam, 0x2b, 0x19);
91 else
92 err += sn9c102_write_reg(cam, 0xfb, 0x19);
93
94 return err;
95}
96
97
98static struct sn9c102_sensor tas5110c1b = {
99 .name = "TAS5110C1B",
100 .maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>",
101 .sysfs_ops = SN9C102_I2C_WRITE,
102 .frequency = SN9C102_I2C_100KHZ,
103 .interface = SN9C102_I2C_3WIRES,
104 .init = &tas5110c1b_init,
105 .qctrl = {
106 {
107 .id = V4L2_CID_GAIN,
108 .type = V4L2_CTRL_TYPE_INTEGER,
109 .name = "global gain",
110 .minimum = 0x00,
111 .maximum = 0xf6,
112 .step = 0x01,
113 .default_value = 0x40,
114 .flags = 0,
115 },
116 },
117 .set_ctrl = &tas5110c1b_set_ctrl,
118 .cropcap = {
119 .bounds = {
120 .left = 0,
121 .top = 0,
122 .width = 352,
123 .height = 288,
124 },
125 .defrect = {
126 .left = 0,
127 .top = 0,
128 .width = 352,
129 .height = 288,
130 },
131 },
132 .set_crop = &tas5110c1b_set_crop,
133 .pix_format = {
134 .width = 352,
135 .height = 288,
136 .pixelformat = V4L2_PIX_FMT_SBGGR8,
137 .priv = 8,
138 },
139 .set_pix_format = &tas5110c1b_set_pix_format
140};
141
142
143int sn9c102_probe_tas5110c1b(struct sn9c102_device* cam)
144{
145 const struct usb_device_id tas5110c1b_id_table[] = {
146 { USB_DEVICE(0x0c45, 0x6001), },
147 { USB_DEVICE(0x0c45, 0x6005), },
148 { USB_DEVICE(0x0c45, 0x60ab), },
149 { }
150 };
151
152 /* Sensor detection is based on USB pid/vid */
153 if (!sn9c102_match_id(cam, tas5110c1b_id_table))
154 return -ENODEV;
155
156 sn9c102_attach_sensor(cam, &tas5110c1b);
157
158 return 0;
159}
diff --git a/drivers/media/video/sn9c102/sn9c102_tas5130d1b.c b/drivers/media/video/sn9c102/sn9c102_tas5130d1b.c
new file mode 100644
index 000000000000..c7b339740bbf
--- /dev/null
+++ b/drivers/media/video/sn9c102/sn9c102_tas5130d1b.c
@@ -0,0 +1,169 @@
1/***************************************************************************
2 * Plug-in for TAS5130D1B image sensor connected to the SN9C10x PC Camera *
3 * Controllers *
4 * *
5 * Copyright (C) 2004-2006 by Luca Risolia <luca.risolia@studio.unibo.it> *
6 * *
7 * This program is free software; you can redistribute it and/or modify *
8 * it under the terms of the GNU General Public License as published by *
9 * the Free Software Foundation; either version 2 of the License, or *
10 * (at your option) any later version. *
11 * *
12 * This program is distributed in the hope that it will be useful, *
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15 * GNU General Public License for more details. *
16 * *
17 * You should have received a copy of the GNU General Public License *
18 * along with this program; if not, write to the Free Software *
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
20 ***************************************************************************/
21
22#include "sn9c102_sensor.h"
23
24
25static struct sn9c102_sensor tas5130d1b;
26
27
28static int tas5130d1b_init(struct sn9c102_device* cam)
29{
30 int err = 0;
31
32 err += sn9c102_write_reg(cam, 0x01, 0x01);
33 err += sn9c102_write_reg(cam, 0x20, 0x17);
34 err += sn9c102_write_reg(cam, 0x04, 0x01);
35 err += sn9c102_write_reg(cam, 0x01, 0x10);
36 err += sn9c102_write_reg(cam, 0x00, 0x11);
37 err += sn9c102_write_reg(cam, 0x00, 0x14);
38 err += sn9c102_write_reg(cam, 0x60, 0x17);
39 err += sn9c102_write_reg(cam, 0x07, 0x18);
40
41 return err;
42}
43
44
45static int tas5130d1b_set_ctrl(struct sn9c102_device* cam,
46 const struct v4l2_control* ctrl)
47{
48 int err = 0;
49
50 switch (ctrl->id) {
51 case V4L2_CID_GAIN:
52 err += sn9c102_i2c_write(cam, 0x20, 0xf6 - ctrl->value);
53 break;
54 case V4L2_CID_EXPOSURE:
55 err += sn9c102_i2c_write(cam, 0x40, 0x47 - ctrl->value);
56 break;
57 default:
58 return -EINVAL;
59 }
60
61 return err ? -EIO : 0;
62}
63
64
65static int tas5130d1b_set_crop(struct sn9c102_device* cam,
66 const struct v4l2_rect* rect)
67{
68 struct sn9c102_sensor* s = &tas5130d1b;
69 u8 h_start = (u8)(rect->left - s->cropcap.bounds.left) + 104,
70 v_start = (u8)(rect->top - s->cropcap.bounds.top) + 12;
71 int err = 0;
72
73 err += sn9c102_write_reg(cam, h_start, 0x12);
74 err += sn9c102_write_reg(cam, v_start, 0x13);
75
76 /* Do NOT change! */
77 err += sn9c102_write_reg(cam, 0x1f, 0x1a);
78 err += sn9c102_write_reg(cam, 0x1a, 0x1b);
79 err += sn9c102_write_reg(cam, sn9c102_pread_reg(cam, 0x19), 0x19);
80
81 return err;
82}
83
84
85static int tas5130d1b_set_pix_format(struct sn9c102_device* cam,
86 const struct v4l2_pix_format* pix)
87{
88 int err = 0;
89
90 if (pix->pixelformat == V4L2_PIX_FMT_SN9C10X)
91 err += sn9c102_write_reg(cam, 0x63, 0x19);
92 else
93 err += sn9c102_write_reg(cam, 0xf3, 0x19);
94
95 return err;
96}
97
98
99static struct sn9c102_sensor tas5130d1b = {
100 .name = "TAS5130D1B",
101 .maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>",
102 .sysfs_ops = SN9C102_I2C_WRITE,
103 .frequency = SN9C102_I2C_100KHZ,
104 .interface = SN9C102_I2C_3WIRES,
105 .init = &tas5130d1b_init,
106 .qctrl = {
107 {
108 .id = V4L2_CID_GAIN,
109 .type = V4L2_CTRL_TYPE_INTEGER,
110 .name = "global gain",
111 .minimum = 0x00,
112 .maximum = 0xf6,
113 .step = 0x02,
114 .default_value = 0x00,
115 .flags = 0,
116 },
117 {
118 .id = V4L2_CID_EXPOSURE,
119 .type = V4L2_CTRL_TYPE_INTEGER,
120 .name = "exposure",
121 .minimum = 0x00,
122 .maximum = 0x47,
123 .step = 0x01,
124 .default_value = 0x00,
125 .flags = 0,
126 },
127 },
128 .set_ctrl = &tas5130d1b_set_ctrl,
129 .cropcap = {
130 .bounds = {
131 .left = 0,
132 .top = 0,
133 .width = 640,
134 .height = 480,
135 },
136 .defrect = {
137 .left = 0,
138 .top = 0,
139 .width = 640,
140 .height = 480,
141 },
142 },
143 .set_crop = &tas5130d1b_set_crop,
144 .pix_format = {
145 .width = 640,
146 .height = 480,
147 .pixelformat = V4L2_PIX_FMT_SBGGR8,
148 .priv = 8,
149 },
150 .set_pix_format = &tas5130d1b_set_pix_format
151};
152
153
154int sn9c102_probe_tas5130d1b(struct sn9c102_device* cam)
155{
156 const struct usb_device_id tas5130d1b_id_table[] = {
157 { USB_DEVICE(0x0c45, 0x6025), },
158 { USB_DEVICE(0x0c45, 0x60aa), },
159 { }
160 };
161
162 /* Sensor detection is based on USB pid/vid */
163 if (!sn9c102_match_id(cam, tas5130d1b_id_table))
164 return -ENODEV;
165
166 sn9c102_attach_sensor(cam, &tas5130d1b);
167
168 return 0;
169}
diff --git a/drivers/media/video/stv680.c b/drivers/media/video/stv680.c
new file mode 100644
index 000000000000..9636da20748d
--- /dev/null
+++ b/drivers/media/video/stv680.c
@@ -0,0 +1,1508 @@
1/*
2 * STV0680 USB Camera Driver, by Kevin Sisson (kjsisson@bellsouth.net)
3 *
4 * Thanks to STMicroelectronics for information on the usb commands, and
5 * to Steve Miller at STM for his help and encouragement while I was
6 * writing this driver.
7 *
8 * This driver is based heavily on the
9 * Endpoints (formerly known as AOX) se401 USB Camera Driver
10 * Copyright (c) 2000 Jeroen B. Vreeken (pe1rxq@amsat.org)
11 *
12 * Still somewhat based on the Linux ov511 driver.
13 *
14 * This program is free software; you can redistribute it and/or modify it
15 * under the terms of the GNU General Public License as published by the
16 * Free Software Foundation; either version 2 of the License, or (at your
17 * option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful, but
20 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
21 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22 * for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software Foundation,
26 * Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27 *
28 * History:
29 * ver 0.1 October, 2001. Initial attempt.
30 *
31 * ver 0.2 November, 2001. Fixed asbility to resize, added brightness
32 * function, made more stable (?)
33 *
34 * ver 0.21 Nov, 2001. Added gamma correction and white balance,
35 * due to Alexander Schwartz. Still trying to
36 * improve stablility. Moved stuff into stv680.h
37 *
38 * ver 0.22 Nov, 2001. Added sharpen function (by Michael Sweet,
39 * mike@easysw.com) from GIMP, also used in pencam.
40 * Simple, fast, good integer math routine.
41 *
42 * ver 0.23 Dec, 2001 (gkh)
43 * Took out sharpen function, ran code through
44 * Lindent, and did other minor tweaks to get
45 * things to work properly with 2.5.1
46 *
47 * ver 0.24 Jan, 2002 (kjs)
48 * Fixed the problem with webcam crashing after
49 * two pictures. Changed the way pic is halved to
50 * improve quality. Got rid of green line around
51 * frame. Fix brightness reset when changing size
52 * bug. Adjusted gamma filters slightly.
53 *
54 * ver 0.25 Jan, 2002 (kjs)
55 * Fixed a bug in which the driver sometimes attempted
56 * to set to a non-supported size. This allowed
57 * gnomemeeting to work.
58 * Fixed proc entry removal bug.
59 */
60
61#include <linux/config.h>
62#include <linux/module.h>
63#include <linux/init.h>
64#include <linux/vmalloc.h>
65#include <linux/slab.h>
66#include <linux/pagemap.h>
67#include <linux/errno.h>
68#include <linux/videodev.h>
69#include <linux/usb.h>
70#include <linux/mutex.h>
71
72#include "stv680.h"
73
74static int video_nr = -1;
75static int swapRGB = 0; /* default for auto sleect */
76static int swapRGB_on = 0; /* default to allow auto select; -1=swap never, +1= swap always */
77
78static unsigned int debug = 0;
79
80#define PDEBUG(level, fmt, args...) \
81 do { \
82 if (debug >= level) \
83 info("[%s:%d] " fmt, __FUNCTION__, __LINE__ , ## args); \
84 } while (0)
85
86
87/*
88 * Version Information
89 */
90#define DRIVER_VERSION "v0.25"
91#define DRIVER_AUTHOR "Kevin Sisson <kjsisson@bellsouth.net>"
92#define DRIVER_DESC "STV0680 USB Camera Driver"
93
94MODULE_AUTHOR (DRIVER_AUTHOR);
95MODULE_DESCRIPTION (DRIVER_DESC);
96MODULE_LICENSE ("GPL");
97module_param(debug, int, S_IRUGO | S_IWUSR);
98MODULE_PARM_DESC (debug, "Debug enabled or not");
99module_param(swapRGB_on, int, 0);
100MODULE_PARM_DESC (swapRGB_on, "Red/blue swap: 1=always, 0=auto, -1=never");
101module_param(video_nr, int, 0);
102
103/********************************************************************
104 *
105 * Memory management
106 *
107 * This is a shameless copy from the USB-cpia driver (linux kernel
108 * version 2.3.29 or so, I have no idea what this code actually does ;).
109 * Actually it seems to be a copy of a shameless copy of the bttv-driver.
110 * Or that is a copy of a shameless copy of ... (To the powers: is there
111 * no generic kernel-function to do this sort of stuff?)
112 *
113 * Yes, it was a shameless copy from the bttv-driver. IIRC, Alan says
114 * there will be one, but apparentely not yet -jerdfelt
115 *
116 * So I copied it again for the ov511 driver -claudio
117 *
118 * Same for the se401 driver -Jeroen
119 *
120 * And the STV0680 driver - Kevin
121 ********************************************************************/
122static void *rvmalloc (unsigned long size)
123{
124 void *mem;
125 unsigned long adr;
126
127 size = PAGE_ALIGN(size);
128 mem = vmalloc_32 (size);
129 if (!mem)
130 return NULL;
131
132 memset (mem, 0, size); /* Clear the ram out, no junk to the user */
133 adr = (unsigned long) mem;
134 while (size > 0) {
135 SetPageReserved(vmalloc_to_page((void *)adr));
136 adr += PAGE_SIZE;
137 size -= PAGE_SIZE;
138 }
139 return mem;
140}
141
142static void rvfree (void *mem, unsigned long size)
143{
144 unsigned long adr;
145
146 if (!mem)
147 return;
148
149 adr = (unsigned long) mem;
150 while ((long) size > 0) {
151 ClearPageReserved(vmalloc_to_page((void *)adr));
152 adr += PAGE_SIZE;
153 size -= PAGE_SIZE;
154 }
155 vfree (mem);
156}
157
158
159/*********************************************************************
160 * pencam read/write functions
161 ********************************************************************/
162
163static int stv_sndctrl (int set, struct usb_stv *stv680, unsigned short req, unsigned short value, unsigned char *buffer, int size)
164{
165 int ret = -1;
166
167 switch (set) {
168 case 0: /* 0xc1 */
169 ret = usb_control_msg (stv680->udev,
170 usb_rcvctrlpipe (stv680->udev, 0),
171 req,
172 (USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_ENDPOINT),
173 value, 0, buffer, size, PENCAM_TIMEOUT);
174 break;
175
176 case 1: /* 0x41 */
177 ret = usb_control_msg (stv680->udev,
178 usb_sndctrlpipe (stv680->udev, 0),
179 req,
180 (USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_ENDPOINT),
181 value, 0, buffer, size, PENCAM_TIMEOUT);
182 break;
183
184 case 2: /* 0x80 */
185 ret = usb_control_msg (stv680->udev,
186 usb_rcvctrlpipe (stv680->udev, 0),
187 req,
188 (USB_DIR_IN | USB_RECIP_DEVICE),
189 value, 0, buffer, size, PENCAM_TIMEOUT);
190 break;
191
192 case 3: /* 0x40 */
193 ret = usb_control_msg (stv680->udev,
194 usb_sndctrlpipe (stv680->udev, 0),
195 req,
196 (USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE),
197 value, 0, buffer, size, PENCAM_TIMEOUT);
198 break;
199
200 }
201 if ((ret < 0) && (req != 0x0a)) {
202 PDEBUG (1, "STV(e): usb_control_msg error %i, request = 0x%x, error = %i", set, req, ret);
203 }
204 return ret;
205}
206
207static int stv_set_config (struct usb_stv *dev, int configuration, int interface, int alternate)
208{
209
210 if (configuration != dev->udev->actconfig->desc.bConfigurationValue
211 || usb_reset_configuration (dev->udev) < 0) {
212 PDEBUG (1, "STV(e): FAILED to reset configuration %i", configuration);
213 return -1;
214 }
215 if (usb_set_interface (dev->udev, interface, alternate) < 0) {
216 PDEBUG (1, "STV(e): FAILED to set alternate interface %i", alternate);
217 return -1;
218 }
219 return 0;
220}
221
222static int stv_stop_video (struct usb_stv *dev)
223{
224 int i;
225 unsigned char *buf;
226
227 buf = kmalloc (40, GFP_KERNEL);
228 if (buf == NULL) {
229 PDEBUG (0, "STV(e): Out of (small buf) memory");
230 return -1;
231 }
232
233 /* this is a high priority command; it stops all lower order commands */
234 if ((i = stv_sndctrl (1, dev, 0x04, 0x0000, buf, 0x0)) < 0) {
235 i = stv_sndctrl (0, dev, 0x80, 0, buf, 0x02); /* Get Last Error; 2 = busy */
236 PDEBUG (1, "STV(i): last error: %i, command = 0x%x", buf[0], buf[1]);
237 } else {
238 PDEBUG (1, "STV(i): Camera reset to idle mode.");
239 }
240
241 if ((i = stv_set_config (dev, 1, 0, 0)) < 0)
242 PDEBUG (1, "STV(e): Reset config during exit failed");
243
244 /* get current mode */
245 buf[0] = 0xf0;
246 if ((i = stv_sndctrl (0, dev, 0x87, 0, buf, 0x08)) != 0x08) /* get mode */
247 PDEBUG (0, "STV(e): Stop_video: problem setting original mode");
248 if (dev->origMode != buf[0]) {
249 memset (buf, 0, 8);
250 buf[0] = (unsigned char) dev->origMode;
251 if ((i = stv_sndctrl (3, dev, 0x07, 0x0100, buf, 0x08)) != 0x08) {
252 PDEBUG (0, "STV(e): Stop_video: Set_Camera_Mode failed");
253 i = -1;
254 }
255 buf[0] = 0xf0;
256 i = stv_sndctrl (0, dev, 0x87, 0, buf, 0x08);
257 if ((i != 0x08) || (buf[0] != dev->origMode)) {
258 PDEBUG (0, "STV(e): camera NOT set to original resolution.");
259 i = -1;
260 } else
261 PDEBUG (0, "STV(i): Camera set to original resolution");
262 }
263 /* origMode */
264 kfree(buf);
265 return i;
266}
267
268static int stv_set_video_mode (struct usb_stv *dev)
269{
270 int i, stop_video = 1;
271 unsigned char *buf;
272
273 buf = kmalloc (40, GFP_KERNEL);
274 if (buf == NULL) {
275 PDEBUG (0, "STV(e): Out of (small buf) memory");
276 return -1;
277 }
278
279 if ((i = stv_set_config (dev, 1, 0, 0)) < 0) {
280 kfree(buf);
281 return i;
282 }
283
284 i = stv_sndctrl (2, dev, 0x06, 0x0100, buf, 0x12);
285 if (!(i > 0) && (buf[8] == 0x53) && (buf[9] == 0x05)) {
286 PDEBUG (1, "STV(e): Could not get descriptor 0100.");
287 goto error;
288 }
289
290 /* set alternate interface 1 */
291 if ((i = stv_set_config (dev, 1, 0, 1)) < 0)
292 goto error;
293
294 if ((i = stv_sndctrl (0, dev, 0x85, 0, buf, 0x10)) != 0x10)
295 goto error;
296 PDEBUG (1, "STV(i): Setting video mode.");
297 /* Switch to Video mode: 0x0100 = VGA (640x480), 0x0000 = CIF (352x288) 0x0300 = QVGA (320x240) */
298 if ((i = stv_sndctrl (1, dev, 0x09, dev->VideoMode, buf, 0x0)) < 0) {
299 stop_video = 0;
300 goto error;
301 }
302 goto exit;
303
304error:
305 kfree(buf);
306 if (stop_video == 1)
307 stv_stop_video (dev);
308 return -1;
309
310exit:
311 kfree(buf);
312 return 0;
313}
314
315static int stv_init (struct usb_stv *stv680)
316{
317 int i = 0;
318 unsigned char *buffer;
319 unsigned long int bufsize;
320
321 buffer = kzalloc (40, GFP_KERNEL);
322 if (buffer == NULL) {
323 PDEBUG (0, "STV(e): Out of (small buf) memory");
324 return -1;
325 }
326 udelay (100);
327
328 /* set config 1, interface 0, alternate 0 */
329 if ((i = stv_set_config (stv680, 1, 0, 0)) < 0) {
330 kfree(buffer);
331 PDEBUG (0, "STV(e): set config 1,0,0 failed");
332 return -1;
333 }
334 /* ping camera to be sure STV0680 is present */
335 if ((i = stv_sndctrl (0, stv680, 0x88, 0x5678, buffer, 0x02)) != 0x02)
336 goto error;
337 if ((buffer[0] != 0x56) || (buffer[1] != 0x78)) {
338 PDEBUG (1, "STV(e): camera ping failed!!");
339 goto error;
340 }
341
342 /* get camera descriptor */
343 if ((i = stv_sndctrl (2, stv680, 0x06, 0x0200, buffer, 0x09)) != 0x09)
344 goto error;
345 i = stv_sndctrl (2, stv680, 0x06, 0x0200, buffer, 0x22);
346 if (!(i >= 0) && (buffer[7] == 0xa0) && (buffer[8] == 0x23)) {
347 PDEBUG (1, "STV(e): Could not get descriptor 0200.");
348 goto error;
349 }
350 if ((i = stv_sndctrl (0, stv680, 0x8a, 0, buffer, 0x02)) != 0x02)
351 goto error;
352 if ((i = stv_sndctrl (0, stv680, 0x8b, 0, buffer, 0x24)) != 0x24)
353 goto error;
354 if ((i = stv_sndctrl (0, stv680, 0x85, 0, buffer, 0x10)) != 0x10)
355 goto error;
356
357 stv680->SupportedModes = buffer[7];
358 i = stv680->SupportedModes;
359 stv680->CIF = 0;
360 stv680->VGA = 0;
361 stv680->QVGA = 0;
362 if (i & 1)
363 stv680->CIF = 1;
364 if (i & 2)
365 stv680->VGA = 1;
366 if (i & 8)
367 stv680->QVGA = 1;
368 if (stv680->SupportedModes == 0) {
369 PDEBUG (0, "STV(e): There are NO supported STV680 modes!!");
370 i = -1;
371 goto error;
372 } else {
373 if (stv680->CIF)
374 PDEBUG (0, "STV(i): CIF is supported");
375 if (stv680->QVGA)
376 PDEBUG (0, "STV(i): QVGA is supported");
377 }
378 /* FW rev, ASIC rev, sensor ID */
379 PDEBUG (1, "STV(i): Firmware rev is %i.%i", buffer[0], buffer[1]);
380 PDEBUG (1, "STV(i): ASIC rev is %i.%i", buffer[2], buffer[3]);
381 PDEBUG (1, "STV(i): Sensor ID is %i", (buffer[4]*16) + (buffer[5]>>4));
382
383 /* set alternate interface 1 */
384 if ((i = stv_set_config (stv680, 1, 0, 1)) < 0)
385 goto error;
386
387 if ((i = stv_sndctrl (0, stv680, 0x85, 0, buffer, 0x10)) != 0x10)
388 goto error;
389 if ((i = stv_sndctrl (0, stv680, 0x8d, 0, buffer, 0x08)) != 0x08)
390 goto error;
391 i = buffer[3];
392 PDEBUG (0, "STV(i): Camera has %i pictures.", i);
393
394 /* get current mode */
395 if ((i = stv_sndctrl (0, stv680, 0x87, 0, buffer, 0x08)) != 0x08)
396 goto error;
397 stv680->origMode = buffer[0]; /* 01 = VGA, 03 = QVGA, 00 = CIF */
398
399 /* This will attemp CIF mode, if supported. If not, set to QVGA */
400 memset (buffer, 0, 8);
401 if (stv680->CIF)
402 buffer[0] = 0x00;
403 else if (stv680->QVGA)
404 buffer[0] = 0x03;
405 if ((i = stv_sndctrl (3, stv680, 0x07, 0x0100, buffer, 0x08)) != 0x08) {
406 PDEBUG (0, "STV(i): Set_Camera_Mode failed");
407 i = -1;
408 goto error;
409 }
410 buffer[0] = 0xf0;
411 stv_sndctrl (0, stv680, 0x87, 0, buffer, 0x08);
412 if (((stv680->CIF == 1) && (buffer[0] != 0x00)) || ((stv680->QVGA == 1) && (buffer[0] != 0x03))) {
413 PDEBUG (0, "STV(e): Error setting camera video mode!");
414 i = -1;
415 goto error;
416 } else {
417 if (buffer[0] == 0) {
418 stv680->VideoMode = 0x0000;
419 PDEBUG (0, "STV(i): Video Mode set to CIF");
420 }
421 if (buffer[0] == 0x03) {
422 stv680->VideoMode = 0x0300;
423 PDEBUG (0, "STV(i): Video Mode set to QVGA");
424 }
425 }
426 if ((i = stv_sndctrl (0, stv680, 0x8f, 0, buffer, 0x10)) != 0x10)
427 goto error;
428 bufsize = (buffer[0] << 24) | (buffer[1] << 16) | (buffer[2] << 8) | (buffer[3]);
429 stv680->cwidth = (buffer[4] << 8) | (buffer[5]); /* ->camera = 322, 356, 644 */
430 stv680->cheight = (buffer[6] << 8) | (buffer[7]); /* ->camera = 242, 292, 484 */
431 stv680->origGain = buffer[12];
432
433 goto exit;
434
435error:
436 i = stv_sndctrl (0, stv680, 0x80, 0, buffer, 0x02); /* Get Last Error */
437 PDEBUG (1, "STV(i): last error: %i, command = 0x%x", buffer[0], buffer[1]);
438 kfree(buffer);
439 return -1;
440
441exit:
442 kfree(buffer);
443
444 /* video = 320x240, 352x288 */
445 if (stv680->CIF == 1) {
446 stv680->maxwidth = 352;
447 stv680->maxheight = 288;
448 stv680->vwidth = 352;
449 stv680->vheight = 288;
450 }
451 if (stv680->QVGA == 1) {
452 stv680->maxwidth = 320;
453 stv680->maxheight = 240;
454 stv680->vwidth = 320;
455 stv680->vheight = 240;
456 }
457
458 stv680->rawbufsize = bufsize; /* must be ./. by 8 */
459 stv680->maxframesize = bufsize * 3; /* RGB size */
460 PDEBUG (2, "STV(i): cwidth = %i, cheight = %i", stv680->cwidth, stv680->cheight);
461 PDEBUG (1, "STV(i): width = %i, height = %i, rawbufsize = %li", stv680->vwidth, stv680->vheight, stv680->rawbufsize);
462
463 /* some default values */
464 stv680->bulk_in_endpointAddr = 0x82;
465 stv680->dropped = 0;
466 stv680->error = 0;
467 stv680->framecount = 0;
468 stv680->readcount = 0;
469 stv680->streaming = 0;
470 /* bright, white, colour, hue, contrast are set by software, not in stv0680 */
471 stv680->brightness = 32767;
472 stv680->chgbright = 0;
473 stv680->whiteness = 0; /* only for greyscale */
474 stv680->colour = 32767;
475 stv680->contrast = 32767;
476 stv680->hue = 32767;
477 stv680->palette = STV_VIDEO_PALETTE;
478 stv680->depth = 24; /* rgb24 bits */
479 if ((swapRGB_on == 0) && (swapRGB == 0))
480 PDEBUG (1, "STV(i): swapRGB is (auto) OFF");
481 else if ((swapRGB_on == 0) && (swapRGB == 1))
482 PDEBUG (1, "STV(i): swapRGB is (auto) ON");
483 else if (swapRGB_on == 1)
484 PDEBUG (1, "STV(i): swapRGB is (forced) ON");
485 else if (swapRGB_on == -1)
486 PDEBUG (1, "STV(i): swapRGB is (forced) OFF");
487
488 if (stv_set_video_mode (stv680) < 0) {
489 PDEBUG (0, "STV(e): Could not set video mode in stv_init");
490 return -1;
491 }
492
493 return 0;
494}
495
496/***************** last of pencam routines *******************/
497
498/****************************************************************************
499 * sysfs
500 ***************************************************************************/
501#define stv680_file(name, variable, field) \
502static ssize_t show_##name(struct class_device *class_dev, char *buf) \
503{ \
504 struct video_device *vdev = to_video_device(class_dev); \
505 struct usb_stv *stv = video_get_drvdata(vdev); \
506 return sprintf(buf, field, stv->variable); \
507} \
508static CLASS_DEVICE_ATTR(name, S_IRUGO, show_##name, NULL);
509
510stv680_file(model, camera_name, "%s\n");
511stv680_file(in_use, user, "%d\n");
512stv680_file(streaming, streaming, "%d\n");
513stv680_file(palette, palette, "%i\n");
514stv680_file(frames_total, readcount, "%d\n");
515stv680_file(frames_read, framecount, "%d\n");
516stv680_file(packets_dropped, dropped, "%d\n");
517stv680_file(decoding_errors, error, "%d\n");
518
519static void stv680_create_sysfs_files(struct video_device *vdev)
520{
521 video_device_create_file(vdev, &class_device_attr_model);
522 video_device_create_file(vdev, &class_device_attr_in_use);
523 video_device_create_file(vdev, &class_device_attr_streaming);
524 video_device_create_file(vdev, &class_device_attr_palette);
525 video_device_create_file(vdev, &class_device_attr_frames_total);
526 video_device_create_file(vdev, &class_device_attr_frames_read);
527 video_device_create_file(vdev, &class_device_attr_packets_dropped);
528 video_device_create_file(vdev, &class_device_attr_decoding_errors);
529}
530
531static void stv680_remove_sysfs_files(struct video_device *vdev)
532{
533 video_device_remove_file(vdev, &class_device_attr_model);
534 video_device_remove_file(vdev, &class_device_attr_in_use);
535 video_device_remove_file(vdev, &class_device_attr_streaming);
536 video_device_remove_file(vdev, &class_device_attr_palette);
537 video_device_remove_file(vdev, &class_device_attr_frames_total);
538 video_device_remove_file(vdev, &class_device_attr_frames_read);
539 video_device_remove_file(vdev, &class_device_attr_packets_dropped);
540 video_device_remove_file(vdev, &class_device_attr_decoding_errors);
541}
542
543/********************************************************************
544 * Camera control
545 *******************************************************************/
546
547static int stv680_get_pict (struct usb_stv *stv680, struct video_picture *p)
548{
549 /* This sets values for v4l interface. max/min = 65535/0 */
550
551 p->brightness = stv680->brightness;
552 p->whiteness = stv680->whiteness; /* greyscale */
553 p->colour = stv680->colour;
554 p->contrast = stv680->contrast;
555 p->hue = stv680->hue;
556 p->palette = stv680->palette;
557 p->depth = stv680->depth;
558 return 0;
559}
560
561static int stv680_set_pict (struct usb_stv *stv680, struct video_picture *p)
562{
563 /* See above stv680_get_pict */
564
565 if (p->palette != STV_VIDEO_PALETTE) {
566 PDEBUG (2, "STV(e): Palette set error in _set_pic");
567 return 1;
568 }
569
570 if (stv680->brightness != p->brightness) {
571 stv680->chgbright = 1;
572 stv680->brightness = p->brightness;
573 }
574
575 stv680->whiteness = p->whiteness; /* greyscale */
576 stv680->colour = p->colour;
577 stv680->contrast = p->contrast;
578 stv680->hue = p->hue;
579 stv680->palette = p->palette;
580 stv680->depth = p->depth;
581
582 return 0;
583}
584
585static void stv680_video_irq (struct urb *urb, struct pt_regs *regs)
586{
587 struct usb_stv *stv680 = urb->context;
588 int length = urb->actual_length;
589
590 if (length < stv680->rawbufsize)
591 PDEBUG (2, "STV(i): Lost data in transfer: exp %li, got %i", stv680->rawbufsize, length);
592
593 /* ohoh... */
594 if (!stv680->streaming)
595 return;
596
597 if (!stv680->udev) {
598 PDEBUG (0, "STV(e): device vapourished in video_irq");
599 return;
600 }
601
602 /* 0 sized packets happen if we are to fast, but sometimes the camera
603 keeps sending them forever...
604 */
605 if (length && !urb->status) {
606 stv680->nullpackets = 0;
607 switch (stv680->scratch[stv680->scratch_next].state) {
608 case BUFFER_READY:
609 case BUFFER_BUSY:
610 stv680->dropped++;
611 break;
612
613 case BUFFER_UNUSED:
614 memcpy (stv680->scratch[stv680->scratch_next].data,
615 (unsigned char *) urb->transfer_buffer, length);
616 stv680->scratch[stv680->scratch_next].state = BUFFER_READY;
617 stv680->scratch[stv680->scratch_next].length = length;
618 if (waitqueue_active (&stv680->wq)) {
619 wake_up_interruptible (&stv680->wq);
620 }
621 stv680->scratch_overflow = 0;
622 stv680->scratch_next++;
623 if (stv680->scratch_next >= STV680_NUMSCRATCH)
624 stv680->scratch_next = 0;
625 break;
626 } /* switch */
627 } else {
628 stv680->nullpackets++;
629 if (stv680->nullpackets > STV680_MAX_NULLPACKETS) {
630 if (waitqueue_active (&stv680->wq)) {
631 wake_up_interruptible (&stv680->wq);
632 }
633 }
634 } /* if - else */
635
636 /* Resubmit urb for new data */
637 urb->status = 0;
638 urb->dev = stv680->udev;
639 if (usb_submit_urb (urb, GFP_ATOMIC))
640 PDEBUG (0, "STV(e): urb burned down in video irq");
641 return;
642} /* _video_irq */
643
644static int stv680_start_stream (struct usb_stv *stv680)
645{
646 struct urb *urb;
647 int err = 0, i;
648
649 stv680->streaming = 1;
650
651 /* Do some memory allocation */
652 for (i = 0; i < STV680_NUMFRAMES; i++) {
653 stv680->frame[i].data = stv680->fbuf + i * stv680->maxframesize;
654 stv680->frame[i].curpix = 0;
655 }
656 /* packet size = 4096 */
657 for (i = 0; i < STV680_NUMSBUF; i++) {
658 stv680->sbuf[i].data = kmalloc (stv680->rawbufsize, GFP_KERNEL);
659 if (stv680->sbuf[i].data == NULL) {
660 PDEBUG (0, "STV(e): Could not kmalloc raw data buffer %i", i);
661 return -1;
662 }
663 }
664
665 stv680->scratch_next = 0;
666 stv680->scratch_use = 0;
667 stv680->scratch_overflow = 0;
668 for (i = 0; i < STV680_NUMSCRATCH; i++) {
669 stv680->scratch[i].data = kmalloc (stv680->rawbufsize, GFP_KERNEL);
670 if (stv680->scratch[i].data == NULL) {
671 PDEBUG (0, "STV(e): Could not kmalloc raw scratch buffer %i", i);
672 return -1;
673 }
674 stv680->scratch[i].state = BUFFER_UNUSED;
675 }
676
677 for (i = 0; i < STV680_NUMSBUF; i++) {
678 urb = usb_alloc_urb (0, GFP_KERNEL);
679 if (!urb)
680 return -ENOMEM;
681
682 /* sbuf is urb->transfer_buffer, later gets memcpyed to scratch */
683 usb_fill_bulk_urb (urb, stv680->udev,
684 usb_rcvbulkpipe (stv680->udev, stv680->bulk_in_endpointAddr),
685 stv680->sbuf[i].data, stv680->rawbufsize,
686 stv680_video_irq, stv680);
687 stv680->urb[i] = urb;
688 err = usb_submit_urb (stv680->urb[i], GFP_KERNEL);
689 if (err)
690 PDEBUG (0, "STV(e): urb burned down in start stream");
691 } /* i STV680_NUMSBUF */
692
693 stv680->framecount = 0;
694 return 0;
695}
696
697static int stv680_stop_stream (struct usb_stv *stv680)
698{
699 int i;
700
701 if (!stv680->streaming || !stv680->udev)
702 return 1;
703
704 stv680->streaming = 0;
705
706 for (i = 0; i < STV680_NUMSBUF; i++)
707 if (stv680->urb[i]) {
708 usb_kill_urb (stv680->urb[i]);
709 usb_free_urb (stv680->urb[i]);
710 stv680->urb[i] = NULL;
711 kfree(stv680->sbuf[i].data);
712 }
713 for (i = 0; i < STV680_NUMSCRATCH; i++) {
714 kfree(stv680->scratch[i].data);
715 stv680->scratch[i].data = NULL;
716 }
717
718 return 0;
719}
720
721static int stv680_set_size (struct usb_stv *stv680, int width, int height)
722{
723 int wasstreaming = stv680->streaming;
724
725 /* Check to see if we need to change */
726 if ((stv680->vwidth == width) && (stv680->vheight == height))
727 return 0;
728
729 PDEBUG (1, "STV(i): size request for %i x %i", width, height);
730 /* Check for a valid mode */
731 if ((!width || !height) || ((width & 1) || (height & 1))) {
732 PDEBUG (1, "STV(e): set_size error: request: v.width = %i, v.height = %i actual: stv.width = %i, stv.height = %i", width, height, stv680->vwidth, stv680->vheight);
733 return 1;
734 }
735
736 if ((width < (stv680->maxwidth / 2)) || (height < (stv680->maxheight / 2))) {
737 width = stv680->maxwidth / 2;
738 height = stv680->maxheight / 2;
739 } else if ((width >= 158) && (width <= 166) && (stv680->QVGA == 1)) {
740 width = 160;
741 height = 120;
742 } else if ((width >= 172) && (width <= 180) && (stv680->CIF == 1)) {
743 width = 176;
744 height = 144;
745 } else if ((width >= 318) && (width <= 350) && (stv680->QVGA == 1)) {
746 width = 320;
747 height = 240;
748 } else if ((width >= 350) && (width <= 358) && (stv680->CIF == 1)) {
749 width = 352;
750 height = 288;
751 } else {
752 PDEBUG (1, "STV(e): request for non-supported size: request: v.width = %i, v.height = %i actual: stv.width = %i, stv.height = %i", width, height, stv680->vwidth, stv680->vheight);
753 return 1;
754 }
755
756 /* Stop a current stream and start it again at the new size */
757 if (wasstreaming)
758 stv680_stop_stream (stv680);
759 stv680->vwidth = width;
760 stv680->vheight = height;
761 PDEBUG (1, "STV(i): size set to %i x %i", stv680->vwidth, stv680->vheight);
762 if (wasstreaming)
763 stv680_start_stream (stv680);
764
765 return 0;
766}
767
768/**********************************************************************
769 * Video Decoding
770 **********************************************************************/
771
772/******* routines from the pencam program; hey, they work! ********/
773
774/*
775 * STV0680 Vision Camera Chipset Driver
776 * Copyright (C) 2000 Adam Harrison <adam@antispin.org>
777*/
778
779#define RED 0
780#define GREEN 1
781#define BLUE 2
782#define AD(x, y, w) (((y)*(w)+(x))*3)
783
784static void bayer_unshuffle (struct usb_stv *stv680, struct stv680_scratch *buffer)
785{
786 int x, y, i;
787 int w = stv680->cwidth;
788 int vw = stv680->cwidth, vh = stv680->cheight;
789 unsigned int p = 0;
790 int colour = 0, bayer = 0;
791 unsigned char *raw = buffer->data;
792 struct stv680_frame *frame = &stv680->frame[stv680->curframe];
793 unsigned char *output = frame->data;
794 unsigned char *temp = frame->data;
795 int offset = buffer->offset;
796
797 if (frame->curpix == 0) {
798 if (frame->grabstate == FRAME_READY) {
799 frame->grabstate = FRAME_GRABBING;
800 }
801 }
802 if (offset != frame->curpix) { /* Regard frame as lost :( */
803 frame->curpix = 0;
804 stv680->error++;
805 return;
806 }
807
808 if ((stv680->vwidth == 320) || (stv680->vwidth == 160)) {
809 vw = 320;
810 vh = 240;
811 }
812 if ((stv680->vwidth == 352) || (stv680->vwidth == 176)) {
813 vw = 352;
814 vh = 288;
815 }
816
817 memset (output, 0, 3 * vw * vh); /* clear output matrix. */
818
819 for (y = 0; y < vh; y++) {
820 for (x = 0; x < vw; x++) {
821 if (x & 1)
822 p = *(raw + y * w + (x >> 1));
823 else
824 p = *(raw + y * w + (x >> 1) + (w >> 1));
825
826 if (y & 1)
827 bayer = 2;
828 else
829 bayer = 0;
830 if (x & 1)
831 bayer++;
832
833 switch (bayer) {
834 case 0:
835 case 3:
836 colour = 1;
837 break;
838 case 1:
839 colour = 0;
840 break;
841 case 2:
842 colour = 2;
843 break;
844 }
845 i = (y * vw + x) * 3;
846 *(output + i + colour) = (unsigned char) p;
847 } /* for x */
848
849 } /* for y */
850
851 /****** gamma correction plus hardcoded white balance */
852 /* Thanks to Alexander Schwartx <alexander.schwartx@gmx.net> for this code.
853 Correction values red[], green[], blue[], are generated by
854 (pow(i/256.0, GAMMA)*255.0)*white balanceRGB where GAMMA=0.55, 1<i<255.
855 White balance (RGB)= 1.0, 1.17, 1.48. Values are calculated as double float and
856 converted to unsigned char. Values are in stv680.h */
857
858 for (y = 0; y < vh; y++) {
859 for (x = 0; x < vw; x++) {
860 i = (y * vw + x) * 3;
861 *(output + i) = red[*(output + i)];
862 *(output + i + 1) = green[*(output + i + 1)];
863 *(output + i + 2) = blue[*(output + i + 2)];
864 }
865 }
866
867 /****** bayer demosaic ******/
868 for (y = 1; y < (vh - 1); y++) {
869 for (x = 1; x < (vw - 1); x++) { /* work out pixel type */
870 if (y & 1)
871 bayer = 0;
872 else
873 bayer = 2;
874 if (!(x & 1))
875 bayer++;
876
877 switch (bayer) {
878 case 0: /* green. blue lr, red tb */
879 *(output + AD (x, y, vw) + BLUE) = ((int) *(output + AD (x - 1, y, vw) + BLUE) + (int) *(output + AD (x + 1, y, vw) + BLUE)) >> 1;
880 *(output + AD (x, y, vw) + RED) = ((int) *(output + AD (x, y - 1, vw) + RED) + (int) *(output + AD (x, y + 1, vw) + RED)) >> 1;
881 break;
882
883 case 1: /* blue. green lrtb, red diagonals */
884 *(output + AD (x, y, vw) + GREEN) = ((int) *(output + AD (x - 1, y, vw) + GREEN) + (int) *(output + AD (x + 1, y, vw) + GREEN) + (int) *(output + AD (x, y - 1, vw) + GREEN) + (int) *(output + AD (x, y + 1, vw) + GREEN)) >> 2;
885 *(output + AD (x, y, vw) + RED) = ((int) *(output + AD (x - 1, y - 1, vw) + RED) + (int) *(output + AD (x - 1, y + 1, vw) + RED) + (int) *(output + AD (x + 1, y - 1, vw) + RED) + (int) *(output + AD (x + 1, y + 1, vw) + RED)) >> 2;
886 break;
887
888 case 2: /* red. green lrtb, blue diagonals */
889 *(output + AD (x, y, vw) + GREEN) = ((int) *(output + AD (x - 1, y, vw) + GREEN) + (int) *(output + AD (x + 1, y, vw) + GREEN) + (int) *(output + AD (x, y - 1, vw) + GREEN) + (int) *(output + AD (x, y + 1, vw) + GREEN)) >> 2;
890 *(output + AD (x, y, vw) + BLUE) = ((int) *(output + AD (x - 1, y - 1, vw) + BLUE) + (int) *(output + AD (x + 1, y - 1, vw) + BLUE) + (int) *(output + AD (x - 1, y + 1, vw) + BLUE) + (int) *(output + AD (x + 1, y + 1, vw) + BLUE)) >> 2;
891 break;
892
893 case 3: /* green. red lr, blue tb */
894 *(output + AD (x, y, vw) + RED) = ((int) *(output + AD (x - 1, y, vw) + RED) + (int) *(output + AD (x + 1, y, vw) + RED)) >> 1;
895 *(output + AD (x, y, vw) + BLUE) = ((int) *(output + AD (x, y - 1, vw) + BLUE) + (int) *(output + AD (x, y + 1, vw) + BLUE)) >> 1;
896 break;
897 } /* switch */
898 } /* for x */
899 } /* for y - end demosaic */
900
901 /* fix top and bottom row, left and right side */
902 i = vw * 3;
903 memcpy (output, (output + i), i);
904 memcpy ((output + (vh * i)), (output + ((vh - 1) * i)), i);
905 for (y = 0; y < vh; y++) {
906 i = y * vw * 3;
907 memcpy ((output + i), (output + i + 3), 3);
908 memcpy ((output + i + (vw * 3)), (output + i + (vw - 1) * 3), 3);
909 }
910
911 /* process all raw data, then trim to size if necessary */
912 if ((stv680->vwidth == 160) || (stv680->vwidth == 176)) {
913 i = 0;
914 for (y = 0; y < vh; y++) {
915 if (!(y & 1)) {
916 for (x = 0; x < vw; x++) {
917 p = (y * vw + x) * 3;
918 if (!(x & 1)) {
919 *(output + i) = *(output + p);
920 *(output + i + 1) = *(output + p + 1);
921 *(output + i + 2) = *(output + p + 2);
922 i += 3;
923 }
924 } /* for x */
925 }
926 } /* for y */
927 }
928 /* reset to proper width */
929 if ((stv680->vwidth == 160)) {
930 vw = 160;
931 vh = 120;
932 }
933 if ((stv680->vwidth == 176)) {
934 vw = 176;
935 vh = 144;
936 }
937
938 /* output is RGB; some programs want BGR */
939 /* swapRGB_on=0 -> program decides; swapRGB_on=1, always swap */
940 /* swapRGB_on=-1, never swap */
941 if (((swapRGB == 1) && (swapRGB_on != -1)) || (swapRGB_on == 1)) {
942 for (y = 0; y < vh; y++) {
943 for (x = 0; x < vw; x++) {
944 i = (y * vw + x) * 3;
945 *(temp) = *(output + i);
946 *(output + i) = *(output + i + 2);
947 *(output + i + 2) = *(temp);
948 }
949 }
950 }
951 /* brightness */
952 if (stv680->chgbright == 1) {
953 if (stv680->brightness >= 32767) {
954 p = (stv680->brightness - 32767) / 256;
955 for (x = 0; x < (vw * vh * 3); x++) {
956 if ((*(output + x) + (unsigned char) p) > 255)
957 *(output + x) = 255;
958 else
959 *(output + x) += (unsigned char) p;
960 } /* for */
961 } else {
962 p = (32767 - stv680->brightness) / 256;
963 for (x = 0; x < (vw * vh * 3); x++) {
964 if ((unsigned char) p > *(output + x))
965 *(output + x) = 0;
966 else
967 *(output + x) -= (unsigned char) p;
968 } /* for */
969 } /* else */
970 }
971 /* if */
972 frame->curpix = 0;
973 frame->curlinepix = 0;
974 frame->grabstate = FRAME_DONE;
975 stv680->framecount++;
976 stv680->readcount++;
977 if (stv680->frame[(stv680->curframe + 1) & (STV680_NUMFRAMES - 1)].grabstate == FRAME_READY) {
978 stv680->curframe = (stv680->curframe + 1) & (STV680_NUMFRAMES - 1);
979 }
980
981} /* bayer_unshuffle */
982
983/******* end routines from the pencam program *********/
984
985static int stv680_newframe (struct usb_stv *stv680, int framenr)
986{
987 int errors = 0;
988
989 while (stv680->streaming && (stv680->frame[framenr].grabstate == FRAME_READY || stv680->frame[framenr].grabstate == FRAME_GRABBING)) {
990 if (!stv680->frame[framenr].curpix) {
991 errors++;
992 }
993 wait_event_interruptible (stv680->wq, (stv680->scratch[stv680->scratch_use].state == BUFFER_READY));
994
995 if (stv680->nullpackets > STV680_MAX_NULLPACKETS) {
996 stv680->nullpackets = 0;
997 PDEBUG (2, "STV(i): too many null length packets, restarting capture");
998 stv680_stop_stream (stv680);
999 stv680_start_stream (stv680);
1000 } else {
1001 if (stv680->scratch[stv680->scratch_use].state != BUFFER_READY) {
1002 stv680->frame[framenr].grabstate = FRAME_ERROR;
1003 PDEBUG (2, "STV(e): FRAME_ERROR in _newframe");
1004 return -EIO;
1005 }
1006 stv680->scratch[stv680->scratch_use].state = BUFFER_BUSY;
1007
1008 bayer_unshuffle (stv680, &stv680->scratch[stv680->scratch_use]);
1009
1010 stv680->scratch[stv680->scratch_use].state = BUFFER_UNUSED;
1011 stv680->scratch_use++;
1012 if (stv680->scratch_use >= STV680_NUMSCRATCH)
1013 stv680->scratch_use = 0;
1014 if (errors > STV680_MAX_ERRORS) {
1015 errors = 0;
1016 PDEBUG (2, "STV(i): too many errors, restarting capture");
1017 stv680_stop_stream (stv680);
1018 stv680_start_stream (stv680);
1019 }
1020 } /* else */
1021 } /* while */
1022 return 0;
1023}
1024
1025/*********************************************************************
1026 * Video4Linux
1027 *********************************************************************/
1028
1029static int stv_open (struct inode *inode, struct file *file)
1030{
1031 struct video_device *dev = video_devdata(file);
1032 struct usb_stv *stv680 = video_get_drvdata(dev);
1033 int err = 0;
1034
1035 /* we are called with the BKL held */
1036 stv680->user = 1;
1037 err = stv_init (stv680); /* main initialization routine for camera */
1038
1039 if (err >= 0) {
1040 stv680->fbuf = rvmalloc (stv680->maxframesize * STV680_NUMFRAMES);
1041 if (!stv680->fbuf) {
1042 PDEBUG (0, "STV(e): Could not rvmalloc frame bufer");
1043 err = -ENOMEM;
1044 }
1045 file->private_data = dev;
1046 }
1047 if (err)
1048 stv680->user = 0;
1049
1050 return err;
1051}
1052
1053static int stv_close (struct inode *inode, struct file *file)
1054{
1055 struct video_device *dev = file->private_data;
1056 struct usb_stv *stv680 = video_get_drvdata(dev);
1057 int i;
1058
1059 for (i = 0; i < STV680_NUMFRAMES; i++)
1060 stv680->frame[i].grabstate = FRAME_UNUSED;
1061 if (stv680->streaming)
1062 stv680_stop_stream (stv680);
1063
1064 if ((i = stv_stop_video (stv680)) < 0)
1065 PDEBUG (1, "STV(e): stop_video failed in stv_close");
1066
1067 rvfree (stv680->fbuf, stv680->maxframesize * STV680_NUMFRAMES);
1068 stv680->user = 0;
1069
1070 if (stv680->removed) {
1071 kfree(stv680);
1072 stv680 = NULL;
1073 PDEBUG (0, "STV(i): device unregistered");
1074 }
1075 file->private_data = NULL;
1076 return 0;
1077}
1078
1079static int stv680_do_ioctl (struct inode *inode, struct file *file,
1080 unsigned int cmd, void *arg)
1081{
1082 struct video_device *vdev = file->private_data;
1083 struct usb_stv *stv680 = video_get_drvdata(vdev);
1084
1085 if (!stv680->udev)
1086 return -EIO;
1087
1088 switch (cmd) {
1089 case VIDIOCGCAP:{
1090 struct video_capability *b = arg;
1091
1092 strcpy (b->name, stv680->camera_name);
1093 b->type = VID_TYPE_CAPTURE;
1094 b->channels = 1;
1095 b->audios = 0;
1096 b->maxwidth = stv680->maxwidth;
1097 b->maxheight = stv680->maxheight;
1098 b->minwidth = stv680->maxwidth / 2;
1099 b->minheight = stv680->maxheight / 2;
1100 return 0;
1101 }
1102 case VIDIOCGCHAN:{
1103 struct video_channel *v = arg;
1104
1105 if (v->channel != 0)
1106 return -EINVAL;
1107 v->flags = 0;
1108 v->tuners = 0;
1109 v->type = VIDEO_TYPE_CAMERA;
1110 strcpy (v->name, "STV Camera");
1111 return 0;
1112 }
1113 case VIDIOCSCHAN:{
1114 struct video_channel *v = arg;
1115 if (v->channel != 0)
1116 return -EINVAL;
1117 return 0;
1118 }
1119 case VIDIOCGPICT:{
1120 struct video_picture *p = arg;
1121
1122 stv680_get_pict (stv680, p);
1123 return 0;
1124 }
1125 case VIDIOCSPICT:{
1126 struct video_picture *p = arg;
1127
1128 if (stv680_set_pict (stv680, p))
1129 return -EINVAL;
1130 return 0;
1131 }
1132 case VIDIOCSWIN:{
1133 struct video_window *vw = arg;
1134
1135 if (vw->flags)
1136 return -EINVAL;
1137 if (vw->clipcount)
1138 return -EINVAL;
1139 if (vw->width != stv680->vwidth) {
1140 if (stv680_set_size (stv680, vw->width, vw->height)) {
1141 PDEBUG (2, "STV(e): failed (from user) set size in VIDIOCSWIN");
1142 return -EINVAL;
1143 }
1144 }
1145 return 0;
1146 }
1147 case VIDIOCGWIN:{
1148 struct video_window *vw = arg;
1149
1150 vw->x = 0; /* FIXME */
1151 vw->y = 0;
1152 vw->chromakey = 0;
1153 vw->flags = 0;
1154 vw->clipcount = 0;
1155 vw->width = stv680->vwidth;
1156 vw->height = stv680->vheight;
1157 return 0;
1158 }
1159 case VIDIOCGMBUF:{
1160 struct video_mbuf *vm = arg;
1161 int i;
1162
1163 memset (vm, 0, sizeof (*vm));
1164 vm->size = STV680_NUMFRAMES * stv680->maxframesize;
1165 vm->frames = STV680_NUMFRAMES;
1166 for (i = 0; i < STV680_NUMFRAMES; i++)
1167 vm->offsets[i] = stv680->maxframesize * i;
1168 return 0;
1169 }
1170 case VIDIOCMCAPTURE:{
1171 struct video_mmap *vm = arg;
1172
1173 if (vm->format != STV_VIDEO_PALETTE) {
1174 PDEBUG (2, "STV(i): VIDIOCMCAPTURE vm.format (%i) != VIDEO_PALETTE (%i)",
1175 vm->format, STV_VIDEO_PALETTE);
1176 if ((vm->format == 3) && (swapRGB_on == 0)) {
1177 PDEBUG (2, "STV(i): VIDIOCMCAPTURE swapRGB is (auto) ON");
1178 /* this may fix those apps (e.g., xawtv) that want BGR */
1179 swapRGB = 1;
1180 }
1181 return -EINVAL;
1182 }
1183 if (vm->frame >= STV680_NUMFRAMES) {
1184 PDEBUG (2, "STV(e): VIDIOCMCAPTURE vm.frame > NUMFRAMES");
1185 return -EINVAL;
1186 }
1187 if ((stv680->frame[vm->frame].grabstate == FRAME_ERROR)
1188 || (stv680->frame[vm->frame].grabstate == FRAME_GRABBING)) {
1189 PDEBUG (2, "STV(e): VIDIOCMCAPTURE grabstate (%i) error",
1190 stv680->frame[vm->frame].grabstate);
1191 return -EBUSY;
1192 }
1193 /* Is this according to the v4l spec??? */
1194 if (stv680->vwidth != vm->width) {
1195 if (stv680_set_size (stv680, vm->width, vm->height)) {
1196 PDEBUG (2, "STV(e): VIDIOCMCAPTURE set_size failed");
1197 return -EINVAL;
1198 }
1199 }
1200 stv680->frame[vm->frame].grabstate = FRAME_READY;
1201
1202 if (!stv680->streaming)
1203 stv680_start_stream (stv680);
1204
1205 return 0;
1206 }
1207 case VIDIOCSYNC:{
1208 int *frame = arg;
1209 int ret = 0;
1210
1211 if (*frame < 0 || *frame >= STV680_NUMFRAMES) {
1212 PDEBUG (2, "STV(e): Bad frame # in VIDIOCSYNC");
1213 return -EINVAL;
1214 }
1215 ret = stv680_newframe (stv680, *frame);
1216 stv680->frame[*frame].grabstate = FRAME_UNUSED;
1217 return ret;
1218 }
1219 case VIDIOCGFBUF:{
1220 struct video_buffer *vb = arg;
1221
1222 memset (vb, 0, sizeof (*vb));
1223 return 0;
1224 }
1225 case VIDIOCKEY:
1226 return 0;
1227 case VIDIOCCAPTURE:
1228 {
1229 PDEBUG (2, "STV(e): VIDIOCCAPTURE failed");
1230 return -EINVAL;
1231 }
1232 case VIDIOCSFBUF:
1233 case VIDIOCGTUNER:
1234 case VIDIOCSTUNER:
1235 case VIDIOCGFREQ:
1236 case VIDIOCSFREQ:
1237 case VIDIOCGAUDIO:
1238 case VIDIOCSAUDIO:
1239 return -EINVAL;
1240 default:
1241 return -ENOIOCTLCMD;
1242 } /* end switch */
1243
1244 return 0;
1245}
1246
1247static int stv680_ioctl(struct inode *inode, struct file *file,
1248 unsigned int cmd, unsigned long arg)
1249{
1250 return video_usercopy(inode, file, cmd, arg, stv680_do_ioctl);
1251}
1252
1253static int stv680_mmap (struct file *file, struct vm_area_struct *vma)
1254{
1255 struct video_device *dev = file->private_data;
1256 struct usb_stv *stv680 = video_get_drvdata(dev);
1257 unsigned long start = vma->vm_start;
1258 unsigned long size = vma->vm_end-vma->vm_start;
1259 unsigned long page, pos;
1260
1261 mutex_lock(&stv680->lock);
1262
1263 if (stv680->udev == NULL) {
1264 mutex_unlock(&stv680->lock);
1265 return -EIO;
1266 }
1267 if (size > (((STV680_NUMFRAMES * stv680->maxframesize) + PAGE_SIZE - 1)
1268 & ~(PAGE_SIZE - 1))) {
1269 mutex_unlock(&stv680->lock);
1270 return -EINVAL;
1271 }
1272 pos = (unsigned long) stv680->fbuf;
1273 while (size > 0) {
1274 page = vmalloc_to_pfn((void *)pos);
1275 if (remap_pfn_range(vma, start, page, PAGE_SIZE, PAGE_SHARED)) {
1276 mutex_unlock(&stv680->lock);
1277 return -EAGAIN;
1278 }
1279 start += PAGE_SIZE;
1280 pos += PAGE_SIZE;
1281 if (size > PAGE_SIZE)
1282 size -= PAGE_SIZE;
1283 else
1284 size = 0;
1285 }
1286 mutex_unlock(&stv680->lock);
1287
1288 return 0;
1289}
1290
1291static ssize_t stv680_read (struct file *file, char __user *buf,
1292 size_t count, loff_t *ppos)
1293{
1294 struct video_device *dev = file->private_data;
1295 unsigned long int realcount = count;
1296 int ret = 0;
1297 struct usb_stv *stv680 = video_get_drvdata(dev);
1298 unsigned long int i;
1299
1300 if (STV680_NUMFRAMES != 2) {
1301 PDEBUG (0, "STV(e): STV680_NUMFRAMES needs to be 2!");
1302 return -1;
1303 }
1304 if (stv680->udev == NULL)
1305 return -EIO;
1306 if (realcount > (stv680->vwidth * stv680->vheight * 3))
1307 realcount = stv680->vwidth * stv680->vheight * 3;
1308
1309 /* Shouldn't happen: */
1310 if (stv680->frame[0].grabstate == FRAME_GRABBING) {
1311 PDEBUG (2, "STV(e): FRAME_GRABBING in stv680_read");
1312 return -EBUSY;
1313 }
1314 stv680->frame[0].grabstate = FRAME_READY;
1315 stv680->frame[1].grabstate = FRAME_UNUSED;
1316 stv680->curframe = 0;
1317
1318 if (!stv680->streaming)
1319 stv680_start_stream (stv680);
1320
1321 if (!stv680->streaming) {
1322 ret = stv680_newframe (stv680, 0); /* ret should = 0 */
1323 }
1324
1325 ret = stv680_newframe (stv680, 0);
1326
1327 if (!ret) {
1328 if ((i = copy_to_user (buf, stv680->frame[0].data, realcount)) != 0) {
1329 PDEBUG (2, "STV(e): copy_to_user frame 0 failed, ret count = %li", i);
1330 return -EFAULT;
1331 }
1332 } else {
1333 realcount = ret;
1334 }
1335 stv680->frame[0].grabstate = FRAME_UNUSED;
1336 return realcount;
1337} /* stv680_read */
1338
1339static struct file_operations stv680_fops = {
1340 .owner = THIS_MODULE,
1341 .open = stv_open,
1342 .release = stv_close,
1343 .read = stv680_read,
1344 .mmap = stv680_mmap,
1345 .ioctl = stv680_ioctl,
1346 .compat_ioctl = v4l_compat_ioctl32,
1347 .llseek = no_llseek,
1348};
1349static struct video_device stv680_template = {
1350 .owner = THIS_MODULE,
1351 .name = "STV0680 USB camera",
1352 .type = VID_TYPE_CAPTURE,
1353 .hardware = VID_HARDWARE_SE401,
1354 .fops = &stv680_fops,
1355 .release = video_device_release,
1356 .minor = -1,
1357};
1358
1359static int stv680_probe (struct usb_interface *intf, const struct usb_device_id *id)
1360{
1361 struct usb_device *dev = interface_to_usbdev(intf);
1362 struct usb_host_interface *interface;
1363 struct usb_stv *stv680 = NULL;
1364 char *camera_name = NULL;
1365 int retval = 0;
1366
1367 /* We don't handle multi-config cameras */
1368 if (dev->descriptor.bNumConfigurations != 1) {
1369 PDEBUG (0, "STV(e): Number of Configurations != 1");
1370 return -ENODEV;
1371 }
1372
1373 interface = &intf->altsetting[0];
1374 /* Is it a STV680? */
1375 if ((le16_to_cpu(dev->descriptor.idVendor) == USB_PENCAM_VENDOR_ID) &&
1376 (le16_to_cpu(dev->descriptor.idProduct) == USB_PENCAM_PRODUCT_ID)) {
1377 camera_name = "STV0680";
1378 PDEBUG (0, "STV(i): STV0680 camera found.");
1379 } else if ((le16_to_cpu(dev->descriptor.idVendor) == USB_CREATIVEGOMINI_VENDOR_ID) &&
1380 (le16_to_cpu(dev->descriptor.idProduct) == USB_CREATIVEGOMINI_PRODUCT_ID)) {
1381 camera_name = "Creative WebCam Go Mini";
1382 PDEBUG (0, "STV(i): Creative WebCam Go Mini found.");
1383 } else {
1384 PDEBUG (0, "STV(e): Vendor/Product ID do not match STV0680 or Creative WebCam Go Mini values.");
1385 PDEBUG (0, "STV(e): Check that the STV0680 or Creative WebCam Go Mini camera is connected to the computer.");
1386 retval = -ENODEV;
1387 goto error;
1388 }
1389 /* We found one */
1390 if ((stv680 = kzalloc (sizeof (*stv680), GFP_KERNEL)) == NULL) {
1391 PDEBUG (0, "STV(e): couldn't kmalloc stv680 struct.");
1392 retval = -ENOMEM;
1393 goto error;
1394 }
1395
1396 stv680->udev = dev;
1397 stv680->camera_name = camera_name;
1398
1399 stv680->vdev = video_device_alloc();
1400 if (!stv680->vdev) {
1401 retval = -ENOMEM;
1402 goto error;
1403 }
1404 memcpy(stv680->vdev, &stv680_template, sizeof(stv680_template));
1405 stv680->vdev->dev = &intf->dev;
1406 video_set_drvdata(stv680->vdev, stv680);
1407
1408 memcpy (stv680->vdev->name, stv680->camera_name, strlen (stv680->camera_name));
1409 init_waitqueue_head (&stv680->wq);
1410 mutex_init (&stv680->lock);
1411 wmb ();
1412
1413 if (video_register_device (stv680->vdev, VFL_TYPE_GRABBER, video_nr) == -1) {
1414 PDEBUG (0, "STV(e): video_register_device failed");
1415 retval = -EIO;
1416 goto error_vdev;
1417 }
1418 PDEBUG (0, "STV(i): registered new video device: video%d", stv680->vdev->minor);
1419
1420 usb_set_intfdata (intf, stv680);
1421 stv680_create_sysfs_files(stv680->vdev);
1422 return 0;
1423
1424error_vdev:
1425 video_device_release(stv680->vdev);
1426error:
1427 kfree(stv680);
1428 return retval;
1429}
1430
1431static inline void usb_stv680_remove_disconnected (struct usb_stv *stv680)
1432{
1433 int i;
1434
1435 stv680->udev = NULL;
1436 stv680->frame[0].grabstate = FRAME_ERROR;
1437 stv680->frame[1].grabstate = FRAME_ERROR;
1438 stv680->streaming = 0;
1439
1440 wake_up_interruptible (&stv680->wq);
1441
1442 for (i = 0; i < STV680_NUMSBUF; i++)
1443 if (stv680->urb[i]) {
1444 usb_kill_urb (stv680->urb[i]);
1445 usb_free_urb (stv680->urb[i]);
1446 stv680->urb[i] = NULL;
1447 kfree(stv680->sbuf[i].data);
1448 }
1449 for (i = 0; i < STV680_NUMSCRATCH; i++)
1450 kfree(stv680->scratch[i].data);
1451 PDEBUG (0, "STV(i): %s disconnected", stv680->camera_name);
1452
1453 /* Free the memory */
1454 kfree(stv680);
1455}
1456
1457static void stv680_disconnect (struct usb_interface *intf)
1458{
1459 struct usb_stv *stv680 = usb_get_intfdata (intf);
1460
1461 usb_set_intfdata (intf, NULL);
1462
1463 if (stv680) {
1464 /* We don't want people trying to open up the device */
1465 if (stv680->vdev) {
1466 stv680_remove_sysfs_files(stv680->vdev);
1467 video_unregister_device(stv680->vdev);
1468 stv680->vdev = NULL;
1469 }
1470 if (!stv680->user) {
1471 usb_stv680_remove_disconnected (stv680);
1472 } else {
1473 stv680->removed = 1;
1474 }
1475 }
1476}
1477
1478static struct usb_driver stv680_driver = {
1479 .name = "stv680",
1480 .probe = stv680_probe,
1481 .disconnect = stv680_disconnect,
1482 .id_table = device_table
1483};
1484
1485/********************************************************************
1486 * Module routines
1487 ********************************************************************/
1488
1489static int __init usb_stv680_init (void)
1490{
1491 if (usb_register (&stv680_driver) < 0) {
1492 PDEBUG (0, "STV(e): Could not setup STV0680 driver");
1493 return -1;
1494 }
1495 PDEBUG (0, "STV(i): usb camera driver version %s registering", DRIVER_VERSION);
1496
1497 info(DRIVER_DESC " " DRIVER_VERSION);
1498 return 0;
1499}
1500
1501static void __exit usb_stv680_exit (void)
1502{
1503 usb_deregister (&stv680_driver);
1504 PDEBUG (0, "STV(i): driver deregistered");
1505}
1506
1507module_init (usb_stv680_init);
1508module_exit (usb_stv680_exit);
diff --git a/drivers/media/video/stv680.h b/drivers/media/video/stv680.h
new file mode 100644
index 000000000000..ea46e0001e6d
--- /dev/null
+++ b/drivers/media/video/stv680.h
@@ -0,0 +1,227 @@
1/****************************************************************************
2 *
3 * Filename: stv680.h
4 *
5 * Description:
6 * This is a USB driver for STV0680 based usb video cameras.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 *
22 ****************************************************************************/
23
24/* size of usb transfers */
25#define STV680_PACKETSIZE 4096
26
27/* number of queued bulk transfers to use, may have problems if > 1 */
28#define STV680_NUMSBUF 1
29
30/* number of frames supported by the v4l part */
31#define STV680_NUMFRAMES 2
32
33/* scratch buffers for passing data to the decoders: 2 or 4 are good */
34#define STV680_NUMSCRATCH 2
35
36/* number of nul sized packets to receive before kicking the camera */
37#define STV680_MAX_NULLPACKETS 200
38
39/* number of decoding errors before kicking the camera */
40#define STV680_MAX_ERRORS 100
41
42#define USB_PENCAM_VENDOR_ID 0x0553
43#define USB_PENCAM_PRODUCT_ID 0x0202
44
45#define USB_CREATIVEGOMINI_VENDOR_ID 0x041e
46#define USB_CREATIVEGOMINI_PRODUCT_ID 0x4007
47
48#define PENCAM_TIMEOUT 1000
49/* fmt 4 */
50#define STV_VIDEO_PALETTE VIDEO_PALETTE_RGB24
51
52static struct usb_device_id device_table[] = {
53 {USB_DEVICE (USB_PENCAM_VENDOR_ID, USB_PENCAM_PRODUCT_ID)},
54 {USB_DEVICE (USB_CREATIVEGOMINI_VENDOR_ID, USB_CREATIVEGOMINI_PRODUCT_ID)},
55 {}
56};
57MODULE_DEVICE_TABLE (usb, device_table);
58
59struct stv680_sbuf {
60 unsigned char *data;
61};
62
63enum {
64 FRAME_UNUSED, /* Unused (no MCAPTURE) */
65 FRAME_READY, /* Ready to start grabbing */
66 FRAME_GRABBING, /* In the process of being grabbed into */
67 FRAME_DONE, /* Finished grabbing, but not been synced yet */
68 FRAME_ERROR, /* Something bad happened while processing */
69};
70
71enum {
72 BUFFER_UNUSED,
73 BUFFER_READY,
74 BUFFER_BUSY,
75 BUFFER_DONE,
76};
77
78/* raw camera data <- sbuf (urb transfer buf) */
79struct stv680_scratch {
80 unsigned char *data;
81 volatile int state;
82 int offset;
83 int length;
84};
85
86/* processed data for display ends up here, after bayer */
87struct stv680_frame {
88 unsigned char *data; /* Frame buffer */
89 volatile int grabstate; /* State of grabbing */
90 unsigned char *curline;
91 int curlinepix;
92 int curpix;
93};
94
95/* this is almost the video structure uvd_t, with extra parameters for stv */
96struct usb_stv {
97 struct video_device *vdev;
98
99 struct usb_device *udev;
100
101 unsigned char bulk_in_endpointAddr; /* __u8 the address of the bulk in endpoint */
102 char *camera_name;
103
104 unsigned int VideoMode; /* 0x0100 = VGA, 0x0000 = CIF, 0x0300 = QVGA */
105 int SupportedModes;
106 int CIF;
107 int VGA;
108 int QVGA;
109 int cwidth; /* camera width */
110 int cheight; /* camera height */
111 int maxwidth; /* max video width */
112 int maxheight; /* max video height */
113 int vwidth; /* current width for video window */
114 int vheight; /* current height for video window */
115 unsigned long int rawbufsize;
116 unsigned long int maxframesize; /* rawbufsize * 3 for RGB */
117
118 int origGain;
119 int origMode; /* original camera mode */
120
121 struct mutex lock; /* to lock the structure */
122 int user; /* user count for exclusive use */
123 int removed; /* device disconnected */
124 int streaming; /* Are we streaming video? */
125 char *fbuf; /* Videodev buffer area */
126 struct urb *urb[STV680_NUMSBUF]; /* # of queued bulk transfers */
127 int curframe; /* Current receiving frame */
128 struct stv680_frame frame[STV680_NUMFRAMES]; /* # frames supported by v4l part */
129 int readcount;
130 int framecount;
131 int error;
132 int dropped;
133 int scratch_next;
134 int scratch_use;
135 int scratch_overflow;
136 struct stv680_scratch scratch[STV680_NUMSCRATCH]; /* for decoders */
137 struct stv680_sbuf sbuf[STV680_NUMSBUF];
138
139 unsigned int brightness;
140 unsigned int chgbright;
141 unsigned int whiteness;
142 unsigned int colour;
143 unsigned int contrast;
144 unsigned int hue;
145 unsigned int palette;
146 unsigned int depth; /* rgb24 in bits */
147
148 wait_queue_head_t wq; /* Processes waiting */
149
150 int nullpackets;
151};
152
153
154static const unsigned char red[256] = {
155 0, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
156 18, 18, 18, 18, 18, 18, 18, 25, 30, 35, 38, 42,
157 44, 47, 50, 53, 54, 57, 59, 61, 63, 65, 67, 69,
158 71, 71, 73, 75, 77, 78, 80, 81, 82, 84, 85, 87,
159 88, 89, 90, 91, 93, 94, 95, 97, 98, 98, 99, 101,
160 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113,
161 114, 115, 116, 116, 117, 118, 119, 120, 121, 122, 123, 124,
162 125, 125, 126, 127, 128, 129, 129, 130, 131, 132, 133, 134,
163 134, 135, 135, 136, 137, 138, 139, 140, 140, 141, 142, 143,
164 143, 143, 144, 145, 146, 147, 147, 148, 149, 150, 150, 151,
165 152, 152, 152, 153, 154, 154, 155, 156, 157, 157, 158, 159,
166 159, 160, 161, 161, 161, 162, 163, 163, 164, 165, 165, 166,
167 167, 167, 168, 168, 169, 170, 170, 170, 171, 171, 172, 173,
168 173, 174, 174, 175, 176, 176, 177, 178, 178, 179, 179, 179,
169 180, 180, 181, 181, 182, 183, 183, 184, 184, 185, 185, 186,
170 187, 187, 188, 188, 188, 188, 189, 190, 190, 191, 191, 192,
171 192, 193, 193, 194, 195, 195, 196, 196, 197, 197, 197, 197,
172 198, 198, 199, 199, 200, 201, 201, 202, 202, 203, 203, 204,
173 204, 205, 205, 206, 206, 206, 206, 207, 207, 208, 208, 209,
174 209, 210, 210, 211, 211, 212, 212, 213, 213, 214, 214, 215,
175 215, 215, 215, 216, 216, 217, 217, 218, 218, 218, 219, 219,
176 220, 220, 221, 221
177};
178
179static const unsigned char green[256] = {
180 0, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
181 21, 21, 21, 21, 21, 21, 21, 28, 34, 39, 43, 47,
182 50, 53, 56, 59, 61, 64, 66, 68, 71, 73, 75, 77,
183 79, 80, 82, 84, 86, 87, 89, 91, 92, 94, 95, 97,
184 98, 100, 101, 102, 104, 105, 106, 108, 109, 110, 111, 113,
185 114, 115, 116, 117, 118, 120, 121, 122, 123, 124, 125, 126,
186 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138,
187 139, 140, 141, 142, 143, 144, 144, 145, 146, 147, 148, 149,
188 150, 151, 151, 152, 153, 154, 155, 156, 156, 157, 158, 159,
189 160, 160, 161, 162, 163, 164, 164, 165, 166, 167, 167, 168,
190 169, 170, 170, 171, 172, 172, 173, 174, 175, 175, 176, 177,
191 177, 178, 179, 179, 180, 181, 182, 182, 183, 184, 184, 185,
192 186, 186, 187, 187, 188, 189, 189, 190, 191, 191, 192, 193,
193 193, 194, 194, 195, 196, 196, 197, 198, 198, 199, 199, 200,
194 201, 201, 202, 202, 203, 204, 204, 205, 205, 206, 206, 207,
195 208, 208, 209, 209, 210, 210, 211, 212, 212, 213, 213, 214,
196 214, 215, 215, 216, 217, 217, 218, 218, 219, 219, 220, 220,
197 221, 221, 222, 222, 223, 224, 224, 225, 225, 226, 226, 227,
198 227, 228, 228, 229, 229, 230, 230, 231, 231, 232, 232, 233,
199 233, 234, 234, 235, 235, 236, 236, 237, 237, 238, 238, 239,
200 239, 240, 240, 241, 241, 242, 242, 243, 243, 243, 244, 244,
201 245, 245, 246, 246
202};
203
204static const unsigned char blue[256] = {
205 0, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
206 23, 23, 23, 23, 23, 23, 23, 30, 37, 42, 47, 51,
207 55, 58, 61, 64, 67, 70, 72, 74, 78, 80, 82, 84,
208 86, 88, 90, 92, 94, 95, 97, 100, 101, 103, 104, 106,
209 107, 110, 111, 112, 114, 115, 116, 118, 119, 121, 122, 124,
210 125, 126, 127, 128, 129, 132, 133, 134, 135, 136, 137, 138,
211 139, 140, 141, 143, 144, 145, 146, 147, 148, 149, 150, 151,
212 152, 154, 155, 156, 157, 158, 158, 159, 160, 161, 162, 163,
213 165, 166, 166, 167, 168, 169, 170, 171, 171, 172, 173, 174,
214 176, 176, 177, 178, 179, 180, 180, 181, 182, 183, 183, 184,
215 185, 187, 187, 188, 189, 189, 190, 191, 192, 192, 193, 194,
216 194, 195, 196, 196, 198, 199, 200, 200, 201, 202, 202, 203,
217 204, 204, 205, 205, 206, 207, 207, 209, 210, 210, 211, 212,
218 212, 213, 213, 214, 215, 215, 216, 217, 217, 218, 218, 220,
219 221, 221, 222, 222, 223, 224, 224, 225, 225, 226, 226, 227,
220 228, 228, 229, 229, 231, 231, 232, 233, 233, 234, 234, 235,
221 235, 236, 236, 237, 238, 238, 239, 239, 240, 240, 242, 242,
222 243, 243, 244, 244, 245, 246, 246, 247, 247, 248, 248, 249,
223 249, 250, 250, 251, 251, 253, 253, 254, 254, 255, 255, 255,
224 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
225 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
226 255, 255, 255, 255
227};
diff --git a/drivers/media/video/usbvideo/Makefile b/drivers/media/video/usbvideo/Makefile
new file mode 100644
index 000000000000..ed410a5ee8c9
--- /dev/null
+++ b/drivers/media/video/usbvideo/Makefile
@@ -0,0 +1,4 @@
1obj-$(CONFIG_USB_IBMCAM) += ibmcam.o usbvideo.o ultracam.o
2obj-$(CONFIG_USB_KONICAWC) += konicawc.o usbvideo.o
3obj-$(CONFIG_USB_VICAM) += vicam.o usbvideo.o
4
diff --git a/drivers/media/video/usbvideo/ibmcam.c b/drivers/media/video/usbvideo/ibmcam.c
new file mode 100644
index 000000000000..a42c22294124
--- /dev/null
+++ b/drivers/media/video/usbvideo/ibmcam.c
@@ -0,0 +1,3932 @@
1/*
2 * USB IBM C-It Video Camera driver
3 *
4 * Supports Xirlink C-It Video Camera, IBM PC Camera,
5 * IBM NetCamera and Veo Stingray.
6 *
7 * This driver is based on earlier work of:
8 *
9 * (C) Copyright 1999 Johannes Erdfelt
10 * (C) Copyright 1999 Randy Dunlap
11 *
12 * 5/24/00 Removed optional (and unnecessary) locking of the driver while
13 * the device remains plugged in. Corrected race conditions in ibmcam_open
14 * and ibmcam_probe() routines using this as a guideline:
15 */
16
17#include <linux/kernel.h>
18#include <linux/sched.h>
19#include <linux/module.h>
20#include <linux/init.h>
21
22#include "usbvideo.h"
23
24#define IBMCAM_VENDOR_ID 0x0545
25#define IBMCAM_PRODUCT_ID 0x8080
26#define NETCAM_PRODUCT_ID 0x8002 /* IBM NetCamera, close to model 2 */
27#define VEO_800C_PRODUCT_ID 0x800C /* Veo Stingray, repackaged Model 2 */
28#define VEO_800D_PRODUCT_ID 0x800D /* Veo Stingray, repackaged Model 4 */
29
30#define MAX_IBMCAM 4 /* How many devices we allow to connect */
31#define USES_IBMCAM_PUTPIXEL 0 /* 0=Fast/oops 1=Slow/secure */
32
33/* Header signatures */
34
35/* Model 1 header: 00 FF 00 xx */
36#define HDRSIG_MODEL1_128x96 0x06 /* U Y V Y ... */
37#define HDRSIG_MODEL1_176x144 0x0e /* U Y V Y ... */
38#define HDRSIG_MODEL1_352x288 0x00 /* V Y U Y ... */
39
40#define IBMCAM_MODEL_1 1 /* XVP-501, 3 interfaces, rev. 0.02 */
41#define IBMCAM_MODEL_2 2 /* KSX-X9903, 2 interfaces, rev. 3.0a */
42#define IBMCAM_MODEL_3 3 /* KSX-X9902, 2 interfaces, rev. 3.01 */
43#define IBMCAM_MODEL_4 4 /* IBM NetCamera, 0545/8002/3.0a */
44
45/* Video sizes supported */
46#define VIDEOSIZE_128x96 VIDEOSIZE(128, 96)
47#define VIDEOSIZE_176x144 VIDEOSIZE(176,144)
48#define VIDEOSIZE_352x288 VIDEOSIZE(352,288)
49#define VIDEOSIZE_320x240 VIDEOSIZE(320,240)
50#define VIDEOSIZE_352x240 VIDEOSIZE(352,240)
51#define VIDEOSIZE_640x480 VIDEOSIZE(640,480)
52#define VIDEOSIZE_160x120 VIDEOSIZE(160,120)
53
54/* Video sizes supported */
55enum {
56 SIZE_128x96 = 0,
57 SIZE_160x120,
58 SIZE_176x144,
59 SIZE_320x240,
60 SIZE_352x240,
61 SIZE_352x288,
62 SIZE_640x480,
63 /* Add/remove/rearrange items before this line */
64 SIZE_LastItem
65};
66
67/*
68 * This structure lives in uvd->user field.
69 */
70typedef struct {
71 int initialized; /* Had we already sent init sequence? */
72 int camera_model; /* What type of IBM camera we got? */
73 int has_hdr;
74} ibmcam_t;
75#define IBMCAM_T(uvd) ((ibmcam_t *)((uvd)->user_data))
76
77static struct usbvideo *cams;
78
79static int debug;
80
81static int flags; /* = FLAGS_DISPLAY_HINTS | FLAGS_OVERLAY_STATS; */
82
83static const int min_canvasWidth = 8;
84static const int min_canvasHeight = 4;
85
86static int lighting = 1; /* Medium */
87
88#define SHARPNESS_MIN 0
89#define SHARPNESS_MAX 6
90static int sharpness = 4; /* Low noise, good details */
91
92#define FRAMERATE_MIN 0
93#define FRAMERATE_MAX 6
94static int framerate = -1;
95
96static int size = SIZE_352x288;
97
98/*
99 * Here we define several initialization variables. They may
100 * be used to automatically set color, hue, brightness and
101 * contrast to desired values. This is particularly useful in
102 * case of webcams (which have no controls and no on-screen
103 * output) and also when a client V4L software is used that
104 * does not have some of those controls. In any case it's
105 * good to have startup values as options.
106 *
107 * These values are all in [0..255] range. This simplifies
108 * operation. Note that actual values of V4L variables may
109 * be scaled up (as much as << 8). User can see that only
110 * on overlay output, however, or through a V4L client.
111 */
112static int init_brightness = 128;
113static int init_contrast = 192;
114static int init_color = 128;
115static int init_hue = 128;
116static int hue_correction = 128;
117
118/* Settings for camera model 2 */
119static int init_model2_rg2 = -1;
120static int init_model2_sat = -1;
121static int init_model2_yb = -1;
122
123/* 01.01.08 - Added for RCA video in support -LO */
124/* Settings for camera model 3 */
125static int init_model3_input = 0;
126
127module_param(debug, int, 0);
128MODULE_PARM_DESC(debug, "Debug level: 0-9 (default=0)");
129module_param(flags, int, 0);
130MODULE_PARM_DESC(flags, "Bitfield: 0=VIDIOCSYNC, 1=B/W, 2=show hints, 3=show stats, 4=test pattern, 5=separate frames, 6=clean frames");
131module_param(framerate, int, 0);
132MODULE_PARM_DESC(framerate, "Framerate setting: 0=slowest, 6=fastest (default=2)");
133module_param(lighting, int, 0);
134MODULE_PARM_DESC(lighting, "Photosensitivity: 0=bright, 1=medium (default), 2=low light");
135module_param(sharpness, int, 0);
136MODULE_PARM_DESC(sharpness, "Model1 noise reduction: 0=smooth, 6=sharp (default=4)");
137module_param(size, int, 0);
138MODULE_PARM_DESC(size, "Image size: 0=128x96 1=160x120 2=176x144 3=320x240 4=352x240 5=352x288 6=640x480 (default=5)");
139module_param(init_brightness, int, 0);
140MODULE_PARM_DESC(init_brightness, "Brightness preconfiguration: 0-255 (default=128)");
141module_param(init_contrast, int, 0);
142MODULE_PARM_DESC(init_contrast, "Contrast preconfiguration: 0-255 (default=192)");
143module_param(init_color, int, 0);
144MODULE_PARM_DESC(init_color, "Color preconfiguration: 0-255 (default=128)");
145module_param(init_hue, int, 0);
146MODULE_PARM_DESC(init_hue, "Hue preconfiguration: 0-255 (default=128)");
147module_param(hue_correction, int, 0);
148MODULE_PARM_DESC(hue_correction, "YUV colorspace regulation: 0-255 (default=128)");
149
150module_param(init_model2_rg2, int, 0);
151MODULE_PARM_DESC(init_model2_rg2, "Model2 preconfiguration: 0-255 (default=47)");
152module_param(init_model2_sat, int, 0);
153MODULE_PARM_DESC(init_model2_sat, "Model2 preconfiguration: 0-255 (default=52)");
154module_param(init_model2_yb, int, 0);
155MODULE_PARM_DESC(init_model2_yb, "Model2 preconfiguration: 0-255 (default=160)");
156
157/* 01.01.08 - Added for RCA video in support -LO */
158module_param(init_model3_input, int, 0);
159MODULE_PARM_DESC(init_model3_input, "Model3 input: 0=CCD 1=RCA");
160
161MODULE_AUTHOR ("Dmitri");
162MODULE_DESCRIPTION ("IBM/Xirlink C-it USB Camera Driver for Linux (c) 2000");
163MODULE_LICENSE("GPL");
164
165/* Still mysterious i2c commands */
166static const unsigned short unknown_88 = 0x0088;
167static const unsigned short unknown_89 = 0x0089;
168static const unsigned short bright_3x[3] = { 0x0031, 0x0032, 0x0033 };
169static const unsigned short contrast_14 = 0x0014;
170static const unsigned short light_27 = 0x0027;
171static const unsigned short sharp_13 = 0x0013;
172
173/* i2c commands for Model 2 cameras */
174static const unsigned short mod2_brightness = 0x001a; /* $5b .. $ee; default=$5a */
175static const unsigned short mod2_set_framerate = 0x001c; /* 0 (fast).. $1F (slow) */
176static const unsigned short mod2_color_balance_rg2 = 0x001e; /* 0 (red) .. $7F (green) */
177static const unsigned short mod2_saturation = 0x0020; /* 0 (b/w) - $7F (full color) */
178static const unsigned short mod2_color_balance_yb = 0x0022; /* 0..$7F, $50 is about right */
179static const unsigned short mod2_hue = 0x0024; /* 0..$7F, $70 is about right */
180static const unsigned short mod2_sensitivity = 0x0028; /* 0 (min) .. $1F (max) */
181
182struct struct_initData {
183 unsigned char req;
184 unsigned short value;
185 unsigned short index;
186};
187
188/*
189 * ibmcam_size_to_videosize()
190 *
191 * This procedure converts module option 'size' into the actual
192 * videosize_t that defines the image size in pixels. We need
193 * simplified 'size' because user wants a simple enumerated list
194 * of choices, not an infinite set of possibilities.
195 */
196static videosize_t ibmcam_size_to_videosize(int size)
197{
198 videosize_t vs = VIDEOSIZE_352x288;
199 RESTRICT_TO_RANGE(size, 0, (SIZE_LastItem-1));
200 switch (size) {
201 case SIZE_128x96:
202 vs = VIDEOSIZE_128x96;
203 break;
204 case SIZE_160x120:
205 vs = VIDEOSIZE_160x120;
206 break;
207 case SIZE_176x144:
208 vs = VIDEOSIZE_176x144;
209 break;
210 case SIZE_320x240:
211 vs = VIDEOSIZE_320x240;
212 break;
213 case SIZE_352x240:
214 vs = VIDEOSIZE_352x240;
215 break;
216 case SIZE_352x288:
217 vs = VIDEOSIZE_352x288;
218 break;
219 case SIZE_640x480:
220 vs = VIDEOSIZE_640x480;
221 break;
222 default:
223 err("size=%d. is not valid", size);
224 break;
225 }
226 return vs;
227}
228
229/*
230 * ibmcam_find_header()
231 *
232 * Locate one of supported header markers in the queue.
233 * Once found, remove all preceding bytes AND the marker (4 bytes)
234 * from the data pump queue. Whatever follows must be video lines.
235 *
236 * History:
237 * 1/21/00 Created.
238 */
239static enum ParseState ibmcam_find_header(struct uvd *uvd) /* FIXME: Add frame here */
240{
241 struct usbvideo_frame *frame;
242 ibmcam_t *icam;
243
244 if ((uvd->curframe) < 0 || (uvd->curframe >= USBVIDEO_NUMFRAMES)) {
245 err("ibmcam_find_header: Illegal frame %d.", uvd->curframe);
246 return scan_EndParse;
247 }
248 icam = IBMCAM_T(uvd);
249 assert(icam != NULL);
250 frame = &uvd->frame[uvd->curframe];
251 icam->has_hdr = 0;
252 switch (icam->camera_model) {
253 case IBMCAM_MODEL_1:
254 {
255 const int marker_len = 4;
256 while (RingQueue_GetLength(&uvd->dp) >= marker_len) {
257 if ((RING_QUEUE_PEEK(&uvd->dp, 0) == 0x00) &&
258 (RING_QUEUE_PEEK(&uvd->dp, 1) == 0xFF) &&
259 (RING_QUEUE_PEEK(&uvd->dp, 2) == 0x00))
260 {
261#if 0 /* This code helps to detect new frame markers */
262 info("Header sig: 00 FF 00 %02X", RING_QUEUE_PEEK(&uvd->dp, 3));
263#endif
264 frame->header = RING_QUEUE_PEEK(&uvd->dp, 3);
265 if ((frame->header == HDRSIG_MODEL1_128x96) ||
266 (frame->header == HDRSIG_MODEL1_176x144) ||
267 (frame->header == HDRSIG_MODEL1_352x288))
268 {
269#if 0
270 info("Header found.");
271#endif
272 RING_QUEUE_DEQUEUE_BYTES(&uvd->dp, marker_len);
273 icam->has_hdr = 1;
274 break;
275 }
276 }
277 /* If we are still here then this doesn't look like a header */
278 RING_QUEUE_DEQUEUE_BYTES(&uvd->dp, 1);
279 }
280 break;
281 }
282 case IBMCAM_MODEL_2:
283case IBMCAM_MODEL_4:
284 {
285 int marker_len = 0;
286 switch (uvd->videosize) {
287 case VIDEOSIZE_176x144:
288 marker_len = 10;
289 break;
290 default:
291 marker_len = 2;
292 break;
293 }
294 while (RingQueue_GetLength(&uvd->dp) >= marker_len) {
295 if ((RING_QUEUE_PEEK(&uvd->dp, 0) == 0x00) &&
296 (RING_QUEUE_PEEK(&uvd->dp, 1) == 0xFF))
297 {
298#if 0
299 info("Header found.");
300#endif
301 RING_QUEUE_DEQUEUE_BYTES(&uvd->dp, marker_len);
302 icam->has_hdr = 1;
303 frame->header = HDRSIG_MODEL1_176x144;
304 break;
305 }
306 /* If we are still here then this doesn't look like a header */
307 RING_QUEUE_DEQUEUE_BYTES(&uvd->dp, 1);
308 }
309 break;
310 }
311 case IBMCAM_MODEL_3:
312 { /*
313 * Headers: (one precedes every frame). nc=no compression,
314 * bq=best quality bf=best frame rate.
315 *
316 * 176x144: 00 FF 02 { 0A=nc CA=bq EA=bf }
317 * 320x240: 00 FF 02 { 08=nc 28=bq 68=bf }
318 * 640x480: 00 FF 03 { 08=nc 28=bq 68=bf }
319 *
320 * Bytes '00 FF' seem to indicate header. Other two bytes
321 * encode the frame type. This is a set of bit fields that
322 * encode image size, compression type etc. These fields
323 * do NOT contain frame number because all frames carry
324 * the same header.
325 */
326 const int marker_len = 4;
327 while (RingQueue_GetLength(&uvd->dp) >= marker_len) {
328 if ((RING_QUEUE_PEEK(&uvd->dp, 0) == 0x00) &&
329 (RING_QUEUE_PEEK(&uvd->dp, 1) == 0xFF) &&
330 (RING_QUEUE_PEEK(&uvd->dp, 2) != 0xFF))
331 {
332 /*
333 * Combine 2 bytes of frame type into one
334 * easy to use value
335 */
336 unsigned long byte3, byte4;
337
338 byte3 = RING_QUEUE_PEEK(&uvd->dp, 2);
339 byte4 = RING_QUEUE_PEEK(&uvd->dp, 3);
340 frame->header = (byte3 << 8) | byte4;
341#if 0
342 info("Header found.");
343#endif
344 RING_QUEUE_DEQUEUE_BYTES(&uvd->dp, marker_len);
345 icam->has_hdr = 1;
346 break;
347 }
348 /* If we are still here then this doesn't look like a header */
349 RING_QUEUE_DEQUEUE_BYTES(&uvd->dp, 1);
350 }
351 break;
352 }
353 default:
354 break;
355 }
356 if (!icam->has_hdr) {
357 if (uvd->debug > 2)
358 info("Skipping frame, no header");
359 return scan_EndParse;
360 }
361
362 /* Header found */
363 icam->has_hdr = 1;
364 uvd->stats.header_count++;
365 frame->scanstate = ScanState_Lines;
366 frame->curline = 0;
367
368 if (flags & FLAGS_FORCE_TESTPATTERN) {
369 usbvideo_TestPattern(uvd, 1, 1);
370 return scan_NextFrame;
371 }
372 return scan_Continue;
373}
374
375/*
376 * ibmcam_parse_lines()
377 *
378 * Parse one line (interlaced) from the buffer, put
379 * decoded RGB value into the current frame buffer
380 * and add the written number of bytes (RGB) to
381 * the *pcopylen.
382 *
383 * History:
384 * 21-Jan-2000 Created.
385 * 12-Oct-2000 Reworked to reflect interlaced nature of the data.
386 */
387static enum ParseState ibmcam_parse_lines(
388 struct uvd *uvd,
389 struct usbvideo_frame *frame,
390 long *pcopylen)
391{
392 unsigned char *f;
393 ibmcam_t *icam;
394 unsigned int len, scanLength, scanHeight, order_uv, order_yc;
395 int v4l_linesize; /* V4L line offset */
396 const int hue_corr = (uvd->vpic.hue - 0x8000) >> 10; /* -32..+31 */
397 const int hue2_corr = (hue_correction - 128) / 4; /* -32..+31 */
398 const int ccm = 128; /* Color correction median - see below */
399 int y, u, v, i, frame_done=0, color_corr;
400 static unsigned char lineBuffer[640*3];
401 unsigned const char *chromaLine, *lumaLine;
402
403 assert(uvd != NULL);
404 assert(frame != NULL);
405 icam = IBMCAM_T(uvd);
406 assert(icam != NULL);
407 color_corr = (uvd->vpic.colour - 0x8000) >> 8; /* -128..+127 = -ccm..+(ccm-1)*/
408 RESTRICT_TO_RANGE(color_corr, -ccm, ccm+1);
409
410 v4l_linesize = VIDEOSIZE_X(frame->request) * V4L_BYTES_PER_PIXEL;
411
412 if (IBMCAM_T(uvd)->camera_model == IBMCAM_MODEL_4) {
413 /* Model 4 frame markers do not carry image size identification */
414 switch (uvd->videosize) {
415 case VIDEOSIZE_128x96:
416 case VIDEOSIZE_160x120:
417 case VIDEOSIZE_176x144:
418 scanLength = VIDEOSIZE_X(uvd->videosize);
419 scanHeight = VIDEOSIZE_Y(uvd->videosize);
420 break;
421 default:
422 err("ibmcam_parse_lines: Wrong mode.");
423 return scan_Out;
424 }
425 order_yc = 1; /* order_yc: true=Yc false=cY ('c'=either U or V) */
426 order_uv = 1; /* Always true in this algorithm */
427 } else {
428 switch (frame->header) {
429 case HDRSIG_MODEL1_128x96:
430 scanLength = 128;
431 scanHeight = 96;
432 order_uv = 1; /* U Y V Y ... */
433 break;
434 case HDRSIG_MODEL1_176x144:
435 scanLength = 176;
436 scanHeight = 144;
437 order_uv = 1; /* U Y V Y ... */
438 break;
439 case HDRSIG_MODEL1_352x288:
440 scanLength = 352;
441 scanHeight = 288;
442 order_uv = 0; /* Y V Y V ... */
443 break;
444 default:
445 err("Unknown header signature 00 FF 00 %02lX", frame->header);
446 return scan_NextFrame;
447 }
448 /* order_yc: true=Yc false=cY ('c'=either U or V) */
449 order_yc = (IBMCAM_T(uvd)->camera_model == IBMCAM_MODEL_2);
450 }
451
452 len = scanLength * 3;
453 assert(len <= sizeof(lineBuffer));
454
455 /*
456 * Lines are organized this way:
457 *
458 * I420:
459 * ~~~~
460 * <scanLength->
461 * ___________________________________
462 * |-----Y-----|---UVUVUV...UVUV-----| \
463 * |-----------+---------------------| \
464 * |<-- 176 -->|<------ 176*2 ------>| Total 72. lines (interlaced)
465 * |... ... | ... | /
466 * |<-- 352 -->|<------ 352*2 ------>| Total 144. lines (interlaced)
467 * |___________|_____________________| /
468 * \ \
469 * lumaLine chromaLine
470 */
471
472 /* Make sure there's enough data for the entire line */
473 if (RingQueue_GetLength(&uvd->dp) < len)
474 return scan_Out;
475
476 /* Suck one line out of the ring queue */
477 RingQueue_Dequeue(&uvd->dp, lineBuffer, len);
478
479 /*
480 * Make sure that our writing into output buffer
481 * will not exceed the buffer. Mind that we may write
482 * not into current output scanline but in several after
483 * it as well (if we enlarge image vertically.)
484 */
485 if ((frame->curline + 2) >= VIDEOSIZE_Y(frame->request))
486 return scan_NextFrame;
487
488 /*
489 * Now we are sure that entire line (representing all 'scanLength'
490 * pixels from the camera) is available in the buffer. We
491 * start copying the line left-aligned to the V4L buffer.
492 * If the camera line is shorter then we should pad the V4L
493 * buffer with something (black) to complete the line.
494 */
495 assert(frame->data != NULL);
496 f = frame->data + (v4l_linesize * frame->curline);
497
498 /*
499 * To obtain chrominance data from the 'chromaLine' use this:
500 * v = chromaLine[0]; // 0-1:[0], 2-3:[4], 4-5:[8]...
501 * u = chromaLine[2]; // 0-1:[2], 2-3:[6], 4-5:[10]...
502 *
503 * Indices must be calculated this way:
504 * v_index = (i >> 1) << 2;
505 * u_index = (i >> 1) << 2 + 2;
506 *
507 * where 'i' is the column number [0..VIDEOSIZE_X(frame->request)-1]
508 */
509 lumaLine = lineBuffer;
510 chromaLine = lineBuffer + scanLength;
511 for (i = 0; i < VIDEOSIZE_X(frame->request); i++)
512 {
513 unsigned char rv, gv, bv; /* RGB components */
514
515 /* Check for various visual debugging hints (colorized pixels) */
516 if ((flags & FLAGS_DISPLAY_HINTS) && (icam->has_hdr)) {
517 /*
518 * This is bad and should not happen. This means that
519 * we somehow overshoot the line and encountered new
520 * frame! Obviously our camera/V4L frame size is out
521 * of whack. This cyan dot will help you to figure
522 * out where exactly the new frame arrived.
523 */
524 if (icam->has_hdr == 1) {
525 bv = 0; /* Yellow marker */
526 gv = 0xFF;
527 rv = 0xFF;
528 } else {
529 bv = 0xFF; /* Cyan marker */
530 gv = 0xFF;
531 rv = 0;
532 }
533 icam->has_hdr = 0;
534 goto make_pixel;
535 }
536
537 /*
538 * Check if we are still in range. We may be out of range if our
539 * V4L canvas is wider or taller than the camera "native" image.
540 * Then we quickly fill the remainder of the line with zeros to
541 * make black color and quit the horizontal scanning loop.
542 */
543 if (((frame->curline + 2) >= scanHeight) || (i >= scanLength)) {
544 const int j = i * V4L_BYTES_PER_PIXEL;
545#if USES_IBMCAM_PUTPIXEL
546 /* Refresh 'f' because we don't use it much with PUTPIXEL */
547 f = frame->data + (v4l_linesize * frame->curline) + j;
548#endif
549 memset(f, 0, v4l_linesize - j);
550 break;
551 }
552
553 y = lumaLine[i];
554 if (flags & FLAGS_MONOCHROME) /* Use monochrome for debugging */
555 rv = gv = bv = y;
556 else {
557 int off_0, off_2;
558
559 off_0 = (i >> 1) << 2;
560 off_2 = off_0 + 2;
561
562 if (order_yc) {
563 off_0++;
564 off_2++;
565 }
566 if (!order_uv) {
567 off_0 += 2;
568 off_2 -= 2;
569 }
570 u = chromaLine[off_0] + hue_corr;
571 v = chromaLine[off_2] + hue2_corr;
572
573 /* Apply color correction */
574 if (color_corr != 0) {
575 /* Magnify up to 2 times, reduce down to zero saturation */
576 u = 128 + ((ccm + color_corr) * (u - 128)) / ccm;
577 v = 128 + ((ccm + color_corr) * (v - 128)) / ccm;
578 }
579 YUV_TO_RGB_BY_THE_BOOK(y, u, v, rv, gv, bv);
580 }
581
582 make_pixel:
583 /*
584 * The purpose of creating the pixel here, in one,
585 * dedicated place is that we may need to make the
586 * pixel wider and taller than it actually is. This
587 * may be used if camera generates small frames for
588 * sake of frame rate (or any other reason.)
589 *
590 * The output data consists of B, G, R bytes
591 * (in this order).
592 */
593#if USES_IBMCAM_PUTPIXEL
594 RGB24_PUTPIXEL(frame, i, frame->curline, rv, gv, bv);
595#else
596 *f++ = bv;
597 *f++ = gv;
598 *f++ = rv;
599#endif
600 /*
601 * Typically we do not decide within a legitimate frame
602 * that we want to end the frame. However debugging code
603 * may detect marker of new frame within the data. Then
604 * this condition activates. The 'data' pointer is already
605 * pointing at the new marker, so we'd better leave it as is.
606 */
607 if (frame_done)
608 break; /* End scanning of lines */
609 }
610 /*
611 * Account for number of bytes that we wrote into output V4L frame.
612 * We do it here, after we are done with the scanline, because we
613 * may fill more than one output scanline if we do vertical
614 * enlargement.
615 */
616 frame->curline += 2;
617 if (pcopylen != NULL)
618 *pcopylen += 2 * v4l_linesize;
619 frame->deinterlace = Deinterlace_FillOddLines;
620
621 if (frame_done || (frame->curline >= VIDEOSIZE_Y(frame->request)))
622 return scan_NextFrame;
623 else
624 return scan_Continue;
625}
626
627/*
628 * ibmcam_model2_320x240_parse_lines()
629 *
630 * This procedure deals with a weird RGB format that is produced by IBM
631 * camera model 2 in modes 320x240 and above; 'x' below is 159 or 175,
632 * depending on horizontal size of the picture:
633 *
634 * <--- 160 or 176 pairs of RA,RB bytes ----->
635 * *-----------------------------------------* \
636 * | RA0 | RB0 | RA1 | RB1 | ... | RAx | RBx | \ This is pair of horizontal lines,
637 * |-----+-----+-----+-----+ ... +-----+-----| *- or one interlaced line, total
638 * | B0 | G0 | B1 | G1 | ... | Bx | Gx | / 120 or 144 such pairs which yield
639 * |=====+=====+=====+=====+ ... +=====+=====| / 240 or 288 lines after deinterlacing.
640 *
641 * Each group of FOUR bytes (RAi, RBi, Bi, Gi) where i=0..frame_width/2-1
642 * defines ONE pixel. Therefore this format yields 176x144 "decoded"
643 * resolution at best. I do not know why camera sends such format - the
644 * previous model (1) just used interlaced I420 and everyone was happy.
645 *
646 * I do not know what is the difference between RAi and RBi bytes. Both
647 * seemingly represent R component, but slightly vary in value (so that
648 * the picture looks a bit colored if one or another is used). I use
649 * them both as R component in attempt to at least partially recover the
650 * lost resolution.
651 */
652static enum ParseState ibmcam_model2_320x240_parse_lines(
653 struct uvd *uvd,
654 struct usbvideo_frame *frame,
655 long *pcopylen)
656{
657 unsigned char *f, *la, *lb;
658 unsigned int len;
659 int v4l_linesize; /* V4L line offset */
660 int i, j, frame_done=0, color_corr;
661 int scanLength, scanHeight;
662 static unsigned char lineBuffer[352*2];
663
664 switch (uvd->videosize) {
665 case VIDEOSIZE_320x240:
666 case VIDEOSIZE_352x240:
667 case VIDEOSIZE_352x288:
668 scanLength = VIDEOSIZE_X(uvd->videosize);
669 scanHeight = VIDEOSIZE_Y(uvd->videosize);
670 break;
671 default:
672 err("ibmcam_model2_320x240_parse_lines: Wrong mode.");
673 return scan_Out;
674 }
675
676 color_corr = (uvd->vpic.colour) >> 8; /* 0..+255 */
677 v4l_linesize = VIDEOSIZE_X(frame->request) * V4L_BYTES_PER_PIXEL;
678
679 len = scanLength * 2; /* See explanation above */
680 assert(len <= sizeof(lineBuffer));
681
682 /* Make sure there's enough data for the entire line */
683 if (RingQueue_GetLength(&uvd->dp) < len)
684 return scan_Out;
685
686 /* Suck one line out of the ring queue */
687 RingQueue_Dequeue(&uvd->dp, lineBuffer, len);
688
689 /*
690 * Make sure that our writing into output buffer
691 * will not exceed the buffer. Mind that we may write
692 * not into current output scanline but in several after
693 * it as well (if we enlarge image vertically.)
694 */
695 if ((frame->curline + 2) >= VIDEOSIZE_Y(frame->request))
696 return scan_NextFrame;
697
698 la = lineBuffer;
699 lb = lineBuffer + scanLength;
700
701 /*
702 * Now we are sure that entire line (representing all
703 * VIDEOSIZE_X(frame->request)
704 * pixels from the camera) is available in the scratch buffer. We
705 * start copying the line left-aligned to the V4L buffer (which
706 * might be larger - not smaller, hopefully). If the camera
707 * line is shorter then we should pad the V4L buffer with something
708 * (black in this case) to complete the line.
709 */
710 f = frame->data + (v4l_linesize * frame->curline);
711
712 /* Fill the 2-line strip */
713 for (i = 0; i < VIDEOSIZE_X(frame->request); i++) {
714 int y, rv, gv, bv; /* RGB components */
715
716 j = i & (~1);
717
718 /* Check for various visual debugging hints (colorized pixels) */
719 if ((flags & FLAGS_DISPLAY_HINTS) && (IBMCAM_T(uvd)->has_hdr)) {
720 if (IBMCAM_T(uvd)->has_hdr == 1) {
721 bv = 0; /* Yellow marker */
722 gv = 0xFF;
723 rv = 0xFF;
724 } else {
725 bv = 0xFF; /* Cyan marker */
726 gv = 0xFF;
727 rv = 0;
728 }
729 IBMCAM_T(uvd)->has_hdr = 0;
730 goto make_pixel;
731 }
732
733 /*
734 * Check if we are still in range. We may be out of range if our
735 * V4L canvas is wider or taller than the camera "native" image.
736 * Then we quickly fill the remainder of the line with zeros to
737 * make black color and quit the horizontal scanning loop.
738 */
739 if (((frame->curline + 2) >= scanHeight) || (i >= scanLength)) {
740 const int j = i * V4L_BYTES_PER_PIXEL;
741#if USES_IBMCAM_PUTPIXEL
742 /* Refresh 'f' because we don't use it much with PUTPIXEL */
743 f = frame->data + (v4l_linesize * frame->curline) + j;
744#endif
745 memset(f, 0, v4l_linesize - j);
746 break;
747 }
748
749 /*
750 * Here I use RA and RB components, one per physical pixel.
751 * This causes fine vertical grid on the picture but may improve
752 * horizontal resolution. If you prefer replicating, use this:
753 * rv = la[j + 0]; ... or ... rv = la[j + 1];
754 * then the pixel will be replicated.
755 */
756 rv = la[i];
757 gv = lb[j + 1];
758 bv = lb[j + 0];
759
760 y = (rv + gv + bv) / 3; /* Brightness (badly calculated) */
761
762 if (flags & FLAGS_MONOCHROME) /* Use monochrome for debugging */
763 rv = gv = bv = y;
764 else if (color_corr != 128) {
765
766 /* Calculate difference between color and brightness */
767 rv -= y;
768 gv -= y;
769 bv -= y;
770
771 /* Scale differences */
772 rv = (rv * color_corr) / 128;
773 gv = (gv * color_corr) / 128;
774 bv = (bv * color_corr) / 128;
775
776 /* Reapply brightness */
777 rv += y;
778 gv += y;
779 bv += y;
780
781 /* Watch for overflows */
782 RESTRICT_TO_RANGE(rv, 0, 255);
783 RESTRICT_TO_RANGE(gv, 0, 255);
784 RESTRICT_TO_RANGE(bv, 0, 255);
785 }
786
787 make_pixel:
788 RGB24_PUTPIXEL(frame, i, frame->curline, rv, gv, bv);
789 }
790 /*
791 * Account for number of bytes that we wrote into output V4L frame.
792 * We do it here, after we are done with the scanline, because we
793 * may fill more than one output scanline if we do vertical
794 * enlargement.
795 */
796 frame->curline += 2;
797 *pcopylen += v4l_linesize * 2;
798 frame->deinterlace = Deinterlace_FillOddLines;
799
800 if (frame_done || (frame->curline >= VIDEOSIZE_Y(frame->request)))
801 return scan_NextFrame;
802 else
803 return scan_Continue;
804}
805
806static enum ParseState ibmcam_model3_parse_lines(
807 struct uvd *uvd,
808 struct usbvideo_frame *frame,
809 long *pcopylen)
810{
811 unsigned char *data;
812 const unsigned char *color;
813 unsigned int len;
814 int v4l_linesize; /* V4L line offset */
815 const int hue_corr = (uvd->vpic.hue - 0x8000) >> 10; /* -32..+31 */
816 const int hue2_corr = (hue_correction - 128) / 4; /* -32..+31 */
817 const int ccm = 128; /* Color correction median - see below */
818 int i, u, v, rw, data_w=0, data_h=0, color_corr;
819 static unsigned char lineBuffer[640*3];
820
821 color_corr = (uvd->vpic.colour - 0x8000) >> 8; /* -128..+127 = -ccm..+(ccm-1)*/
822 RESTRICT_TO_RANGE(color_corr, -ccm, ccm+1);
823
824 v4l_linesize = VIDEOSIZE_X(frame->request) * V4L_BYTES_PER_PIXEL;
825
826 /* The header tells us what sort of data is in this frame */
827 switch (frame->header) {
828 /*
829 * Uncompressed modes (that are easy to decode).
830 */
831 case 0x0308:
832 data_w = 640;
833 data_h = 480;
834 break;
835 case 0x0208:
836 data_w = 320;
837 data_h = 240;
838 break;
839 case 0x020A:
840 data_w = 160;
841 data_h = 120;
842 break;
843 /*
844 * Compressed modes (ViCE - that I don't know how to decode).
845 */
846 case 0x0328: /* 640x480, best quality compression */
847 case 0x0368: /* 640x480, best frame rate compression */
848 case 0x0228: /* 320x240, best quality compression */
849 case 0x0268: /* 320x240, best frame rate compression */
850 case 0x02CA: /* 160x120, best quality compression */
851 case 0x02EA: /* 160x120, best frame rate compression */
852 /* Do nothing with this - not supported */
853 err("Unsupported mode $%04lx", frame->header);
854 return scan_NextFrame;
855 default:
856 /* Catch unknown headers, may help in learning new headers */
857 err("Strange frame->header=$%08lx", frame->header);
858 return scan_NextFrame;
859 }
860
861 /*
862 * Make sure that our writing into output buffer
863 * will not exceed the buffer. Note that we may write
864 * not into current output scanline but in several after
865 * it as well (if we enlarge image vertically.)
866 */
867 if ((frame->curline + 1) >= data_h) {
868 if (uvd->debug >= 3)
869 info("Reached line %d. (frame is done)", frame->curline);
870 return scan_NextFrame;
871 }
872
873 /* Make sure there's enough data for the entire line */
874 len = 3 * data_w; /* <y-data> <uv-data> */
875 assert(len <= sizeof(lineBuffer));
876
877 /* Make sure there's enough data for the entire line */
878 if (RingQueue_GetLength(&uvd->dp) < len)
879 return scan_Out;
880
881 /* Suck one line out of the ring queue */
882 RingQueue_Dequeue(&uvd->dp, lineBuffer, len);
883
884 data = lineBuffer;
885 color = data + data_w; /* Point to where color planes begin */
886
887 /* Bottom-to-top scanning */
888 rw = (int)VIDEOSIZE_Y(frame->request) - (int)(frame->curline) - 1;
889 RESTRICT_TO_RANGE(rw, 0, VIDEOSIZE_Y(frame->request)-1);
890
891 for (i = 0; i < VIDEOSIZE_X(frame->request); i++) {
892 int y, rv, gv, bv; /* RGB components */
893
894 if (i < data_w) {
895 y = data[i]; /* Luminosity is the first line */
896
897 /* Apply static color correction */
898 u = color[i*2] + hue_corr;
899 v = color[i*2 + 1] + hue2_corr;
900
901 /* Apply color correction */
902 if (color_corr != 0) {
903 /* Magnify up to 2 times, reduce down to zero saturation */
904 u = 128 + ((ccm + color_corr) * (u - 128)) / ccm;
905 v = 128 + ((ccm + color_corr) * (v - 128)) / ccm;
906 }
907 } else
908 y = 0, u = v = 128;
909
910 YUV_TO_RGB_BY_THE_BOOK(y, u, v, rv, gv, bv);
911 RGB24_PUTPIXEL(frame, i, rw, rv, gv, bv); /* Done by deinterlacing now */
912 }
913 frame->deinterlace = Deinterlace_FillEvenLines;
914
915 /*
916 * Account for number of bytes that we wrote into output V4L frame.
917 * We do it here, after we are done with the scanline, because we
918 * may fill more than one output scanline if we do vertical
919 * enlargement.
920 */
921 frame->curline += 2;
922 *pcopylen += 2 * v4l_linesize;
923
924 if (frame->curline >= VIDEOSIZE_Y(frame->request)) {
925 if (uvd->debug >= 3) {
926 info("All requested lines (%ld.) done.",
927 VIDEOSIZE_Y(frame->request));
928 }
929 return scan_NextFrame;
930 } else
931 return scan_Continue;
932}
933
934/*
935 * ibmcam_model4_128x96_parse_lines()
936 *
937 * This decoder is for one strange data format that is produced by Model 4
938 * camera only in 128x96 mode. This is RGB format and here is its description.
939 * First of all, this is non-interlaced stream, meaning that all scan lines
940 * are present in the datastream. There are 96 consecutive blocks of data
941 * that describe all 96 lines of the image. Each block is 5*128 bytes long
942 * and carries R, G, B components. The format of the block is shown in the
943 * code below. First 128*2 bytes are interleaved R and G components. Then
944 * we have a gap (junk data) 64 bytes long. Then follow B and something
945 * else, also interleaved (this makes another 128*2 bytes). After that
946 * probably another 64 bytes of junk follow.
947 *
948 * History:
949 * 10-Feb-2001 Created.
950 */
951static enum ParseState ibmcam_model4_128x96_parse_lines(
952 struct uvd *uvd,
953 struct usbvideo_frame *frame,
954 long *pcopylen)
955{
956 const unsigned char *data_rv, *data_gv, *data_bv;
957 unsigned int len;
958 int i, v4l_linesize; /* V4L line offset */
959 const int data_w=128, data_h=96;
960 static unsigned char lineBuffer[128*5];
961
962 v4l_linesize = VIDEOSIZE_X(frame->request) * V4L_BYTES_PER_PIXEL;
963
964 /*
965 * Make sure that our writing into output buffer
966 * will not exceed the buffer. Note that we may write
967 * not into current output scanline but in several after
968 * it as well (if we enlarge image vertically.)
969 */
970 if ((frame->curline + 1) >= data_h) {
971 if (uvd->debug >= 3)
972 info("Reached line %d. (frame is done)", frame->curline);
973 return scan_NextFrame;
974 }
975
976 /*
977 * RGRGRG .... RGRG_____________B?B?B? ... B?B?____________
978 * <---- 128*2 ---><---- 64 ---><--- 128*2 ---><--- 64 --->
979 */
980
981 /* Make sure there's enough data for the entire line */
982 len = 5 * data_w;
983 assert(len <= sizeof(lineBuffer));
984
985 /* Make sure there's enough data for the entire line */
986 if (RingQueue_GetLength(&uvd->dp) < len)
987 return scan_Out;
988
989 /* Suck one line out of the ring queue */
990 RingQueue_Dequeue(&uvd->dp, lineBuffer, len);
991
992 data_rv = lineBuffer;
993 data_gv = lineBuffer + 1;
994 data_bv = lineBuffer + data_w*2 + data_w/2;
995 for (i = 0; i < VIDEOSIZE_X(frame->request); i++) {
996 int rv, gv, bv; /* RGB components */
997 if (i < data_w) {
998 const int j = i * 2;
999 gv = data_rv[j];
1000 rv = data_gv[j];
1001 bv = data_bv[j];
1002 if (flags & FLAGS_MONOCHROME) {
1003 unsigned long y;
1004 y = rv + gv + bv;
1005 y /= 3;
1006 if (y > 0xFF)
1007 y = 0xFF;
1008 rv = gv = bv = (unsigned char) y;
1009 }
1010 } else {
1011 rv = gv = bv = 0;
1012 }
1013 RGB24_PUTPIXEL(frame, i, frame->curline, rv, gv, bv);
1014 }
1015 frame->deinterlace = Deinterlace_None;
1016 frame->curline++;
1017 *pcopylen += v4l_linesize;
1018
1019 if (frame->curline >= VIDEOSIZE_Y(frame->request)) {
1020 if (uvd->debug >= 3) {
1021 info("All requested lines (%ld.) done.",
1022 VIDEOSIZE_Y(frame->request));
1023 }
1024 return scan_NextFrame;
1025 } else
1026 return scan_Continue;
1027}
1028
1029/*
1030 * ibmcam_ProcessIsocData()
1031 *
1032 * Generic routine to parse the ring queue data. It employs either
1033 * ibmcam_find_header() or ibmcam_parse_lines() to do most
1034 * of work.
1035 *
1036 * History:
1037 * 1/21/00 Created.
1038 */
1039static void ibmcam_ProcessIsocData(struct uvd *uvd,
1040 struct usbvideo_frame *frame)
1041{
1042 enum ParseState newstate;
1043 long copylen = 0;
1044 int mod = IBMCAM_T(uvd)->camera_model;
1045
1046 while (1) {
1047 newstate = scan_Out;
1048 if (RingQueue_GetLength(&uvd->dp) > 0) {
1049 if (frame->scanstate == ScanState_Scanning) {
1050 newstate = ibmcam_find_header(uvd);
1051 } else if (frame->scanstate == ScanState_Lines) {
1052 if ((mod == IBMCAM_MODEL_2) &&
1053 ((uvd->videosize == VIDEOSIZE_352x288) ||
1054 (uvd->videosize == VIDEOSIZE_320x240) ||
1055 (uvd->videosize == VIDEOSIZE_352x240)))
1056 {
1057 newstate = ibmcam_model2_320x240_parse_lines(
1058 uvd, frame, &copylen);
1059 } else if (mod == IBMCAM_MODEL_4) {
1060 /*
1061 * Model 4 cameras (IBM NetCamera) use Model 2 decoder (RGB)
1062 * for 320x240 and above; 160x120 and 176x144 uses Model 1
1063 * decoder (YUV), and 128x96 mode uses ???
1064 */
1065 if ((uvd->videosize == VIDEOSIZE_352x288) ||
1066 (uvd->videosize == VIDEOSIZE_320x240) ||
1067 (uvd->videosize == VIDEOSIZE_352x240))
1068 {
1069 newstate = ibmcam_model2_320x240_parse_lines(uvd, frame, &copylen);
1070 } else if (uvd->videosize == VIDEOSIZE_128x96) {
1071 newstate = ibmcam_model4_128x96_parse_lines(uvd, frame, &copylen);
1072 } else {
1073 newstate = ibmcam_parse_lines(uvd, frame, &copylen);
1074 }
1075 } else if (mod == IBMCAM_MODEL_3) {
1076 newstate = ibmcam_model3_parse_lines(uvd, frame, &copylen);
1077 } else {
1078 newstate = ibmcam_parse_lines(uvd, frame, &copylen);
1079 }
1080 }
1081 }
1082 if (newstate == scan_Continue)
1083 continue;
1084 else if ((newstate == scan_NextFrame) || (newstate == scan_Out))
1085 break;
1086 else
1087 return; /* scan_EndParse */
1088 }
1089
1090 if (newstate == scan_NextFrame) {
1091 frame->frameState = FrameState_Done;
1092 uvd->curframe = -1;
1093 uvd->stats.frame_num++;
1094 if ((mod == IBMCAM_MODEL_2) || (mod == IBMCAM_MODEL_4)) {
1095 /* Need software contrast adjustment for those cameras */
1096 frame->flags |= USBVIDEO_FRAME_FLAG_SOFTWARE_CONTRAST;
1097 }
1098 }
1099
1100 /* Update the frame's uncompressed length. */
1101 frame->seqRead_Length += copylen;
1102
1103#if 0
1104 {
1105 static unsigned char j=0;
1106 memset(frame->data, j++, uvd->max_frame_size);
1107 frame->frameState = FrameState_Ready;
1108 }
1109#endif
1110}
1111
1112/*
1113 * ibmcam_veio()
1114 *
1115 * History:
1116 * 1/27/00 Added check for dev == NULL; this happens if camera is unplugged.
1117 */
1118static int ibmcam_veio(
1119 struct uvd *uvd,
1120 unsigned char req,
1121 unsigned short value,
1122 unsigned short index)
1123{
1124 static const char proc[] = "ibmcam_veio";
1125 unsigned char cp[8] /* = { 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef } */;
1126 int i;
1127
1128 if (!CAMERA_IS_OPERATIONAL(uvd))
1129 return 0;
1130
1131 if (req == 1) {
1132 i = usb_control_msg(
1133 uvd->dev,
1134 usb_rcvctrlpipe(uvd->dev, 0),
1135 req,
1136 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_ENDPOINT,
1137 value,
1138 index,
1139 cp,
1140 sizeof(cp),
1141 1000);
1142#if 0
1143 info("USB => %02x%02x%02x%02x%02x%02x%02x%02x "
1144 "(req=$%02x val=$%04x ind=$%04x)",
1145 cp[0],cp[1],cp[2],cp[3],cp[4],cp[5],cp[6],cp[7],
1146 req, value, index);
1147#endif
1148 } else {
1149 i = usb_control_msg(
1150 uvd->dev,
1151 usb_sndctrlpipe(uvd->dev, 0),
1152 req,
1153 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_ENDPOINT,
1154 value,
1155 index,
1156 NULL,
1157 0,
1158 1000);
1159 }
1160 if (i < 0) {
1161 err("%s: ERROR=%d. Camera stopped; Reconnect or reload driver.",
1162 proc, i);
1163 uvd->last_error = i;
1164 }
1165 return i;
1166}
1167
1168/*
1169 * ibmcam_calculate_fps()
1170 *
1171 * This procedure roughly calculates the real frame rate based
1172 * on FPS code (framerate=NNN option). Actual FPS differs
1173 * slightly depending on lighting conditions, so that actual frame
1174 * rate is determined by the camera. Since I don't know how to ask
1175 * the camera what FPS is now I have to use the FPS code instead.
1176 *
1177 * The FPS code is in range [0..6], 0 is slowest, 6 is fastest.
1178 * Corresponding real FPS should be in range [3..30] frames per second.
1179 * The conversion formula is obvious:
1180 *
1181 * real_fps = 3 + (fps_code * 4.5)
1182 *
1183 * History:
1184 * 1/18/00 Created.
1185 */
1186static int ibmcam_calculate_fps(struct uvd *uvd)
1187{
1188 return 3 + framerate*4 + framerate/2;
1189}
1190
1191/*
1192 * ibmcam_send_FF_04_02()
1193 *
1194 * This procedure sends magic 3-command prefix to the camera.
1195 * The purpose of this prefix is not known.
1196 *
1197 * History:
1198 * 1/2/00 Created.
1199 */
1200static void ibmcam_send_FF_04_02(struct uvd *uvd)
1201{
1202 ibmcam_veio(uvd, 0, 0x00FF, 0x0127);
1203 ibmcam_veio(uvd, 0, 0x0004, 0x0124);
1204 ibmcam_veio(uvd, 0, 0x0002, 0x0124);
1205}
1206
1207static void ibmcam_send_00_04_06(struct uvd *uvd)
1208{
1209 ibmcam_veio(uvd, 0, 0x0000, 0x0127);
1210 ibmcam_veio(uvd, 0, 0x0004, 0x0124);
1211 ibmcam_veio(uvd, 0, 0x0006, 0x0124);
1212}
1213
1214static void ibmcam_send_x_00(struct uvd *uvd, unsigned short x)
1215{
1216 ibmcam_veio(uvd, 0, x, 0x0127);
1217 ibmcam_veio(uvd, 0, 0x0000, 0x0124);
1218}
1219
1220static void ibmcam_send_x_00_05(struct uvd *uvd, unsigned short x)
1221{
1222 ibmcam_send_x_00(uvd, x);
1223 ibmcam_veio(uvd, 0, 0x0005, 0x0124);
1224}
1225
1226static void ibmcam_send_x_00_05_02(struct uvd *uvd, unsigned short x)
1227{
1228 ibmcam_veio(uvd, 0, x, 0x0127);
1229 ibmcam_veio(uvd, 0, 0x0000, 0x0124);
1230 ibmcam_veio(uvd, 0, 0x0005, 0x0124);
1231 ibmcam_veio(uvd, 0, 0x0002, 0x0124);
1232}
1233
1234static void ibmcam_send_x_01_00_05(struct uvd *uvd, unsigned short x)
1235{
1236 ibmcam_veio(uvd, 0, x, 0x0127);
1237 ibmcam_veio(uvd, 0, 0x0001, 0x0124);
1238 ibmcam_veio(uvd, 0, 0x0000, 0x0124);
1239 ibmcam_veio(uvd, 0, 0x0005, 0x0124);
1240}
1241
1242static void ibmcam_send_x_00_05_02_01(struct uvd *uvd, unsigned short x)
1243{
1244 ibmcam_veio(uvd, 0, x, 0x0127);
1245 ibmcam_veio(uvd, 0, 0x0000, 0x0124);
1246 ibmcam_veio(uvd, 0, 0x0005, 0x0124);
1247 ibmcam_veio(uvd, 0, 0x0002, 0x0124);
1248 ibmcam_veio(uvd, 0, 0x0001, 0x0124);
1249}
1250
1251static void ibmcam_send_x_00_05_02_08_01(struct uvd *uvd, unsigned short x)
1252{
1253 ibmcam_veio(uvd, 0, x, 0x0127);
1254 ibmcam_veio(uvd, 0, 0x0000, 0x0124);
1255 ibmcam_veio(uvd, 0, 0x0005, 0x0124);
1256 ibmcam_veio(uvd, 0, 0x0002, 0x0124);
1257 ibmcam_veio(uvd, 0, 0x0008, 0x0124);
1258 ibmcam_veio(uvd, 0, 0x0001, 0x0124);
1259}
1260
1261static void ibmcam_Packet_Format1(struct uvd *uvd, unsigned char fkey, unsigned char val)
1262{
1263 ibmcam_send_x_01_00_05(uvd, unknown_88);
1264 ibmcam_send_x_00_05(uvd, fkey);
1265 ibmcam_send_x_00_05_02_08_01(uvd, val);
1266 ibmcam_send_x_00_05(uvd, unknown_88);
1267 ibmcam_send_x_00_05_02_01(uvd, fkey);
1268 ibmcam_send_x_00_05(uvd, unknown_89);
1269 ibmcam_send_x_00(uvd, fkey);
1270 ibmcam_send_00_04_06(uvd);
1271 ibmcam_veio(uvd, 1, 0x0000, 0x0126);
1272 ibmcam_send_FF_04_02(uvd);
1273}
1274
1275static void ibmcam_PacketFormat2(struct uvd *uvd, unsigned char fkey, unsigned char val)
1276{
1277 ibmcam_send_x_01_00_05 (uvd, unknown_88);
1278 ibmcam_send_x_00_05 (uvd, fkey);
1279 ibmcam_send_x_00_05_02 (uvd, val);
1280}
1281
1282static void ibmcam_model2_Packet2(struct uvd *uvd)
1283{
1284 ibmcam_veio(uvd, 0, 0x00ff, 0x012d);
1285 ibmcam_veio(uvd, 0, 0xfea3, 0x0124);
1286}
1287
1288static void ibmcam_model2_Packet1(struct uvd *uvd, unsigned short v1, unsigned short v2)
1289{
1290 ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
1291 ibmcam_veio(uvd, 0, 0x00ff, 0x012e);
1292 ibmcam_veio(uvd, 0, v1, 0x012f);
1293 ibmcam_veio(uvd, 0, 0x00ff, 0x0130);
1294 ibmcam_veio(uvd, 0, 0xc719, 0x0124);
1295 ibmcam_veio(uvd, 0, v2, 0x0127);
1296
1297 ibmcam_model2_Packet2(uvd);
1298}
1299
1300/*
1301 * ibmcam_model3_Packet1()
1302 *
1303 * 00_0078_012d
1304 * 00_0097_012f
1305 * 00_d141_0124
1306 * 00_0096_0127
1307 * 00_fea8_0124
1308*/
1309static void ibmcam_model3_Packet1(struct uvd *uvd, unsigned short v1, unsigned short v2)
1310{
1311 ibmcam_veio(uvd, 0, 0x0078, 0x012d);
1312 ibmcam_veio(uvd, 0, v1, 0x012f);
1313 ibmcam_veio(uvd, 0, 0xd141, 0x0124);
1314 ibmcam_veio(uvd, 0, v2, 0x0127);
1315 ibmcam_veio(uvd, 0, 0xfea8, 0x0124);
1316}
1317
1318static void ibmcam_model4_BrightnessPacket(struct uvd *uvd, int i)
1319{
1320 ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
1321 ibmcam_veio(uvd, 0, 0x0026, 0x012f);
1322 ibmcam_veio(uvd, 0, 0xd141, 0x0124);
1323 ibmcam_veio(uvd, 0, i, 0x0127);
1324 ibmcam_veio(uvd, 0, 0x00aa, 0x0130);
1325 ibmcam_veio(uvd, 0, 0x82a8, 0x0124);
1326 ibmcam_veio(uvd, 0, 0x0038, 0x012d);
1327 ibmcam_veio(uvd, 0, 0x0004, 0x012f);
1328 ibmcam_veio(uvd, 0, 0xd145, 0x0124);
1329 ibmcam_veio(uvd, 0, 0xfffa, 0x0124);
1330}
1331
1332/*
1333 * ibmcam_adjust_contrast()
1334 *
1335 * The contrast value changes from 0 (high contrast) to 15 (low contrast).
1336 * This is in reverse to usual order of things (such as TV controls), so
1337 * we reverse it again here.
1338 *
1339 * TODO: we probably don't need to send the setup 5 times...
1340 *
1341 * History:
1342 * 1/2/00 Created.
1343 */
1344static void ibmcam_adjust_contrast(struct uvd *uvd)
1345{
1346 unsigned char a_contrast = uvd->vpic.contrast >> 12;
1347 unsigned char new_contrast;
1348
1349 if (a_contrast >= 16)
1350 a_contrast = 15;
1351 new_contrast = 15 - a_contrast;
1352 if (new_contrast == uvd->vpic_old.contrast)
1353 return;
1354 uvd->vpic_old.contrast = new_contrast;
1355 switch (IBMCAM_T(uvd)->camera_model) {
1356 case IBMCAM_MODEL_1:
1357 {
1358 const int ntries = 5;
1359 int i;
1360 for (i=0; i < ntries; i++) {
1361 ibmcam_Packet_Format1(uvd, contrast_14, new_contrast);
1362 ibmcam_send_FF_04_02(uvd);
1363 }
1364 break;
1365 }
1366 case IBMCAM_MODEL_2:
1367 case IBMCAM_MODEL_4:
1368 /* Models 2, 4 do not have this control; implemented in software. */
1369 break;
1370 case IBMCAM_MODEL_3:
1371 { /* Preset hardware values */
1372 static const struct {
1373 unsigned short cv1;
1374 unsigned short cv2;
1375 unsigned short cv3;
1376 } cv[7] = {
1377 { 0x05, 0x05, 0x0f }, /* Minimum */
1378 { 0x04, 0x04, 0x16 },
1379 { 0x02, 0x03, 0x16 },
1380 { 0x02, 0x08, 0x16 },
1381 { 0x01, 0x0c, 0x16 },
1382 { 0x01, 0x0e, 0x16 },
1383 { 0x01, 0x10, 0x16 } /* Maximum */
1384 };
1385 int i = a_contrast / 2;
1386 RESTRICT_TO_RANGE(i, 0, 6);
1387 ibmcam_veio(uvd, 0, 0x0000, 0x010c); /* Stop */
1388 ibmcam_model3_Packet1(uvd, 0x0067, cv[i].cv1);
1389 ibmcam_model3_Packet1(uvd, 0x005b, cv[i].cv2);
1390 ibmcam_model3_Packet1(uvd, 0x005c, cv[i].cv3);
1391 ibmcam_veio(uvd, 0, 0x0001, 0x0114);
1392 ibmcam_veio(uvd, 0, 0x00c0, 0x010c); /* Go! */
1393 usb_clear_halt(uvd->dev, usb_rcvisocpipe(uvd->dev, uvd->video_endp));
1394 break;
1395 }
1396 default:
1397 break;
1398 }
1399}
1400
1401/*
1402 * ibmcam_change_lighting_conditions()
1403 *
1404 * Camera model 1:
1405 * We have 3 levels of lighting conditions: 0=Bright, 1=Medium, 2=Low.
1406 *
1407 * Camera model 2:
1408 * We have 16 levels of lighting, 0 for bright light and up to 15 for
1409 * low light. But values above 5 or so are useless because camera is
1410 * not really capable to produce anything worth viewing at such light.
1411 * This setting may be altered only in certain camera state.
1412 *
1413 * Low lighting forces slower FPS. Lighting is set as a module parameter.
1414 *
1415 * History:
1416 * 1/5/00 Created.
1417 * 2/20/00 Added support for Model 2 cameras.
1418 */
1419static void ibmcam_change_lighting_conditions(struct uvd *uvd)
1420{
1421 static const char proc[] = "ibmcam_change_lighting_conditions";
1422
1423 if (debug > 0)
1424 info("%s: Set lighting to %hu.", proc, lighting);
1425
1426 switch (IBMCAM_T(uvd)->camera_model) {
1427 case IBMCAM_MODEL_1:
1428 {
1429 const int ntries = 5;
1430 int i;
1431 for (i=0; i < ntries; i++)
1432 ibmcam_Packet_Format1(uvd, light_27, (unsigned short) lighting);
1433 break;
1434 }
1435 case IBMCAM_MODEL_2:
1436#if 0
1437 /*
1438 * This command apparently requires camera to be stopped. My
1439 * experiments showed that it -is- possible to alter the lighting
1440 * conditions setting "on the fly", but why bother? This setting does
1441 * not work reliably in all cases, so I decided simply to leave the
1442 * setting where Xirlink put it - in the camera setup phase. This code
1443 * is commented out because it does not work at -any- moment, so its
1444 * presence makes no sense. You may use it for experiments.
1445 */
1446 ibmcam_veio(uvd, 0, 0x0000, 0x010c); /* Stop camera */
1447 ibmcam_model2_Packet1(uvd, mod2_sensitivity, lighting);
1448 ibmcam_veio(uvd, 0, 0x00c0, 0x010c); /* Start camera */
1449#endif
1450 break;
1451 case IBMCAM_MODEL_3:
1452 case IBMCAM_MODEL_4:
1453 default:
1454 break;
1455 }
1456}
1457
1458/*
1459 * ibmcam_set_sharpness()
1460 *
1461 * Cameras model 1 have internal smoothing feature. It is controlled by value in
1462 * range [0..6], where 0 is most smooth and 6 is most sharp (raw image, I guess).
1463 * Recommended value is 4. Cameras model 2 do not have this feature at all.
1464 */
1465static void ibmcam_set_sharpness(struct uvd *uvd)
1466{
1467 static const char proc[] = "ibmcam_set_sharpness";
1468
1469 switch (IBMCAM_T(uvd)->camera_model) {
1470 case IBMCAM_MODEL_1:
1471 {
1472 static const unsigned short sa[] = { 0x11, 0x13, 0x16, 0x18, 0x1a, 0x8, 0x0a };
1473 unsigned short i, sv;
1474
1475 RESTRICT_TO_RANGE(sharpness, SHARPNESS_MIN, SHARPNESS_MAX);
1476 if (debug > 0)
1477 info("%s: Set sharpness to %hu.", proc, sharpness);
1478
1479 sv = sa[sharpness - SHARPNESS_MIN];
1480 for (i=0; i < 2; i++) {
1481 ibmcam_send_x_01_00_05 (uvd, unknown_88);
1482 ibmcam_send_x_00_05 (uvd, sharp_13);
1483 ibmcam_send_x_00_05_02 (uvd, sv);
1484 }
1485 break;
1486 }
1487 case IBMCAM_MODEL_2:
1488 case IBMCAM_MODEL_4:
1489 /* Models 2, 4 do not have this control */
1490 break;
1491 case IBMCAM_MODEL_3:
1492 { /*
1493 * "Use a table of magic numbers.
1494 * This setting doesn't really change much.
1495 * But that's how Windows does it."
1496 */
1497 static const struct {
1498 unsigned short sv1;
1499 unsigned short sv2;
1500 unsigned short sv3;
1501 unsigned short sv4;
1502 } sv[7] = {
1503 { 0x00, 0x00, 0x05, 0x14 }, /* Smoothest */
1504 { 0x01, 0x04, 0x05, 0x14 },
1505 { 0x02, 0x04, 0x05, 0x14 },
1506 { 0x03, 0x04, 0x05, 0x14 },
1507 { 0x03, 0x05, 0x05, 0x14 },
1508 { 0x03, 0x06, 0x05, 0x14 },
1509 { 0x03, 0x07, 0x05, 0x14 } /* Sharpest */
1510 };
1511 RESTRICT_TO_RANGE(sharpness, SHARPNESS_MIN, SHARPNESS_MAX);
1512 RESTRICT_TO_RANGE(sharpness, 0, 6);
1513 ibmcam_veio(uvd, 0, 0x0000, 0x010c); /* Stop */
1514 ibmcam_model3_Packet1(uvd, 0x0060, sv[sharpness].sv1);
1515 ibmcam_model3_Packet1(uvd, 0x0061, sv[sharpness].sv2);
1516 ibmcam_model3_Packet1(uvd, 0x0062, sv[sharpness].sv3);
1517 ibmcam_model3_Packet1(uvd, 0x0063, sv[sharpness].sv4);
1518 ibmcam_veio(uvd, 0, 0x0001, 0x0114);
1519 ibmcam_veio(uvd, 0, 0x00c0, 0x010c); /* Go! */
1520 usb_clear_halt(uvd->dev, usb_rcvisocpipe(uvd->dev, uvd->video_endp));
1521 ibmcam_veio(uvd, 0, 0x0001, 0x0113);
1522 break;
1523 }
1524 default:
1525 break;
1526 }
1527}
1528
1529/*
1530 * ibmcam_set_brightness()
1531 *
1532 * This procedure changes brightness of the picture.
1533 */
1534static void ibmcam_set_brightness(struct uvd *uvd)
1535{
1536 static const char proc[] = "ibmcam_set_brightness";
1537 static const unsigned short n = 1;
1538
1539 if (debug > 0)
1540 info("%s: Set brightness to %hu.", proc, uvd->vpic.brightness);
1541
1542 switch (IBMCAM_T(uvd)->camera_model) {
1543 case IBMCAM_MODEL_1:
1544 {
1545 unsigned short i, j, bv[3];
1546 bv[0] = bv[1] = bv[2] = uvd->vpic.brightness >> 10;
1547 if (bv[0] == (uvd->vpic_old.brightness >> 10))
1548 return;
1549 uvd->vpic_old.brightness = bv[0];
1550 for (j=0; j < 3; j++)
1551 for (i=0; i < n; i++)
1552 ibmcam_Packet_Format1(uvd, bright_3x[j], bv[j]);
1553 break;
1554 }
1555 case IBMCAM_MODEL_2:
1556 {
1557 unsigned short i, j;
1558 i = uvd->vpic.brightness >> 12; /* 0 .. 15 */
1559 j = 0x60 + i * ((0xee - 0x60) / 16); /* 0x60 .. 0xee or so */
1560 if (uvd->vpic_old.brightness == j)
1561 break;
1562 uvd->vpic_old.brightness = j;
1563 ibmcam_model2_Packet1(uvd, mod2_brightness, j);
1564 break;
1565 }
1566 case IBMCAM_MODEL_3:
1567 {
1568 /* Model 3: Brightness range 'i' in [0x0C..0x3F] */
1569 unsigned short i =
1570 0x0C + (uvd->vpic.brightness / (0xFFFF / (0x3F - 0x0C + 1)));
1571 RESTRICT_TO_RANGE(i, 0x0C, 0x3F);
1572 if (uvd->vpic_old.brightness == i)
1573 break;
1574 uvd->vpic_old.brightness = i;
1575 ibmcam_veio(uvd, 0, 0x0000, 0x010c); /* Stop */
1576 ibmcam_model3_Packet1(uvd, 0x0036, i);
1577 ibmcam_veio(uvd, 0, 0x0001, 0x0114);
1578 ibmcam_veio(uvd, 0, 0x00c0, 0x010c); /* Go! */
1579 usb_clear_halt(uvd->dev, usb_rcvisocpipe(uvd->dev, uvd->video_endp));
1580 ibmcam_veio(uvd, 0, 0x0001, 0x0113);
1581 break;
1582 }
1583 case IBMCAM_MODEL_4:
1584 {
1585 /* Model 4: Brightness range 'i' in [0x04..0xb4] */
1586 unsigned short i = 0x04 + (uvd->vpic.brightness / (0xFFFF / (0xb4 - 0x04 + 1)));
1587 RESTRICT_TO_RANGE(i, 0x04, 0xb4);
1588 if (uvd->vpic_old.brightness == i)
1589 break;
1590 uvd->vpic_old.brightness = i;
1591 ibmcam_model4_BrightnessPacket(uvd, i);
1592 break;
1593 }
1594 default:
1595 break;
1596 }
1597}
1598
1599static void ibmcam_set_hue(struct uvd *uvd)
1600{
1601 switch (IBMCAM_T(uvd)->camera_model) {
1602 case IBMCAM_MODEL_2:
1603 {
1604 unsigned short hue = uvd->vpic.hue >> 9; /* 0 .. 7F */
1605 if (uvd->vpic_old.hue == hue)
1606 return;
1607 uvd->vpic_old.hue = hue;
1608 ibmcam_model2_Packet1(uvd, mod2_hue, hue);
1609 /* ibmcam_model2_Packet1(uvd, mod2_saturation, sat); */
1610 break;
1611 }
1612 case IBMCAM_MODEL_3:
1613 {
1614#if 0 /* This seems not to work. No problem, will fix programmatically */
1615 unsigned short hue = 0x05 + (uvd->vpic.hue / (0xFFFF / (0x37 - 0x05 + 1)));
1616 RESTRICT_TO_RANGE(hue, 0x05, 0x37);
1617 if (uvd->vpic_old.hue == hue)
1618 return;
1619 uvd->vpic_old.hue = hue;
1620 ibmcam_veio(uvd, 0, 0x0000, 0x010c); /* Stop */
1621 ibmcam_model3_Packet1(uvd, 0x007e, hue);
1622 ibmcam_veio(uvd, 0, 0x0001, 0x0114);
1623 ibmcam_veio(uvd, 0, 0x00c0, 0x010c); /* Go! */
1624 usb_clear_halt(uvd->dev, usb_rcvisocpipe(uvd->dev, uvd->video_endp));
1625 ibmcam_veio(uvd, 0, 0x0001, 0x0113);
1626#endif
1627 break;
1628 }
1629 case IBMCAM_MODEL_4:
1630 {
1631 unsigned short r_gain, g_gain, b_gain, hue;
1632
1633 /*
1634 * I am not sure r/g/b_gain variables exactly control gain
1635 * of those channels. Most likely they subtly change some
1636 * very internal image processing settings in the camera.
1637 * In any case, here is what they do, and feel free to tweak:
1638 *
1639 * r_gain: seriously affects red gain
1640 * g_gain: seriously affects green gain
1641 * b_gain: seriously affects blue gain
1642 * hue: changes average color from violet (0) to red (0xFF)
1643 *
1644 * These settings are preset for a decent white balance in
1645 * 320x240, 352x288 modes. Low-res modes exhibit higher contrast
1646 * and therefore may need different values here.
1647 */
1648 hue = 20 + (uvd->vpic.hue >> 9);
1649 switch (uvd->videosize) {
1650 case VIDEOSIZE_128x96:
1651 r_gain = 90;
1652 g_gain = 166;
1653 b_gain = 175;
1654 break;
1655 case VIDEOSIZE_160x120:
1656 r_gain = 70;
1657 g_gain = 166;
1658 b_gain = 185;
1659 break;
1660 case VIDEOSIZE_176x144:
1661 r_gain = 160;
1662 g_gain = 175;
1663 b_gain = 185;
1664 break;
1665 default:
1666 r_gain = 120;
1667 g_gain = 166;
1668 b_gain = 175;
1669 break;
1670 }
1671 RESTRICT_TO_RANGE(hue, 1, 0x7f);
1672
1673 ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
1674 ibmcam_veio(uvd, 0, 0x001e, 0x012f);
1675 ibmcam_veio(uvd, 0, 0xd141, 0x0124);
1676 ibmcam_veio(uvd, 0, g_gain, 0x0127); /* Green gain */
1677 ibmcam_veio(uvd, 0, r_gain, 0x012e); /* Red gain */
1678 ibmcam_veio(uvd, 0, b_gain, 0x0130); /* Blue gain */
1679 ibmcam_veio(uvd, 0, 0x8a28, 0x0124);
1680 ibmcam_veio(uvd, 0, hue, 0x012d); /* Hue */
1681 ibmcam_veio(uvd, 0, 0xf545, 0x0124);
1682 break;
1683 }
1684 default:
1685 break;
1686 }
1687}
1688
1689/*
1690 * ibmcam_adjust_picture()
1691 *
1692 * This procedure gets called from V4L interface to update picture settings.
1693 * Here we change brightness and contrast.
1694 */
1695static void ibmcam_adjust_picture(struct uvd *uvd)
1696{
1697 ibmcam_adjust_contrast(uvd);
1698 ibmcam_set_brightness(uvd);
1699 ibmcam_set_hue(uvd);
1700}
1701
1702static int ibmcam_model1_setup(struct uvd *uvd)
1703{
1704 const int ntries = 5;
1705 int i;
1706
1707 ibmcam_veio(uvd, 1, 0x00, 0x0128);
1708 ibmcam_veio(uvd, 1, 0x00, 0x0100);
1709 ibmcam_veio(uvd, 0, 0x01, 0x0100); /* LED On */
1710 ibmcam_veio(uvd, 1, 0x00, 0x0100);
1711 ibmcam_veio(uvd, 0, 0x81, 0x0100); /* LED Off */
1712 ibmcam_veio(uvd, 1, 0x00, 0x0100);
1713 ibmcam_veio(uvd, 0, 0x01, 0x0100); /* LED On */
1714 ibmcam_veio(uvd, 0, 0x01, 0x0108);
1715
1716 ibmcam_veio(uvd, 0, 0x03, 0x0112);
1717 ibmcam_veio(uvd, 1, 0x00, 0x0115);
1718 ibmcam_veio(uvd, 0, 0x06, 0x0115);
1719 ibmcam_veio(uvd, 1, 0x00, 0x0116);
1720 ibmcam_veio(uvd, 0, 0x44, 0x0116);
1721 ibmcam_veio(uvd, 1, 0x00, 0x0116);
1722 ibmcam_veio(uvd, 0, 0x40, 0x0116);
1723 ibmcam_veio(uvd, 1, 0x00, 0x0115);
1724 ibmcam_veio(uvd, 0, 0x0e, 0x0115);
1725 ibmcam_veio(uvd, 0, 0x19, 0x012c);
1726
1727 ibmcam_Packet_Format1(uvd, 0x00, 0x1e);
1728 ibmcam_Packet_Format1(uvd, 0x39, 0x0d);
1729 ibmcam_Packet_Format1(uvd, 0x39, 0x09);
1730 ibmcam_Packet_Format1(uvd, 0x3b, 0x00);
1731 ibmcam_Packet_Format1(uvd, 0x28, 0x22);
1732 ibmcam_Packet_Format1(uvd, light_27, 0);
1733 ibmcam_Packet_Format1(uvd, 0x2b, 0x1f);
1734 ibmcam_Packet_Format1(uvd, 0x39, 0x08);
1735
1736 for (i=0; i < ntries; i++)
1737 ibmcam_Packet_Format1(uvd, 0x2c, 0x00);
1738
1739 for (i=0; i < ntries; i++)
1740 ibmcam_Packet_Format1(uvd, 0x30, 0x14);
1741
1742 ibmcam_PacketFormat2(uvd, 0x39, 0x02);
1743 ibmcam_PacketFormat2(uvd, 0x01, 0xe1);
1744 ibmcam_PacketFormat2(uvd, 0x02, 0xcd);
1745 ibmcam_PacketFormat2(uvd, 0x03, 0xcd);
1746 ibmcam_PacketFormat2(uvd, 0x04, 0xfa);
1747 ibmcam_PacketFormat2(uvd, 0x3f, 0xff);
1748 ibmcam_PacketFormat2(uvd, 0x39, 0x00);
1749
1750 ibmcam_PacketFormat2(uvd, 0x39, 0x02);
1751 ibmcam_PacketFormat2(uvd, 0x0a, 0x37);
1752 ibmcam_PacketFormat2(uvd, 0x0b, 0xb8);
1753 ibmcam_PacketFormat2(uvd, 0x0c, 0xf3);
1754 ibmcam_PacketFormat2(uvd, 0x0d, 0xe3);
1755 ibmcam_PacketFormat2(uvd, 0x0e, 0x0d);
1756 ibmcam_PacketFormat2(uvd, 0x0f, 0xf2);
1757 ibmcam_PacketFormat2(uvd, 0x10, 0xd5);
1758 ibmcam_PacketFormat2(uvd, 0x11, 0xba);
1759 ibmcam_PacketFormat2(uvd, 0x12, 0x53);
1760 ibmcam_PacketFormat2(uvd, 0x3f, 0xff);
1761 ibmcam_PacketFormat2(uvd, 0x39, 0x00);
1762
1763 ibmcam_PacketFormat2(uvd, 0x39, 0x02);
1764 ibmcam_PacketFormat2(uvd, 0x16, 0x00);
1765 ibmcam_PacketFormat2(uvd, 0x17, 0x28);
1766 ibmcam_PacketFormat2(uvd, 0x18, 0x7d);
1767 ibmcam_PacketFormat2(uvd, 0x19, 0xbe);
1768 ibmcam_PacketFormat2(uvd, 0x3f, 0xff);
1769 ibmcam_PacketFormat2(uvd, 0x39, 0x00);
1770
1771 for (i=0; i < ntries; i++)
1772 ibmcam_Packet_Format1(uvd, 0x00, 0x18);
1773 for (i=0; i < ntries; i++)
1774 ibmcam_Packet_Format1(uvd, 0x13, 0x18);
1775 for (i=0; i < ntries; i++)
1776 ibmcam_Packet_Format1(uvd, 0x14, 0x06);
1777
1778 /* This is default brightness */
1779 for (i=0; i < ntries; i++)
1780 ibmcam_Packet_Format1(uvd, 0x31, 0x37);
1781 for (i=0; i < ntries; i++)
1782 ibmcam_Packet_Format1(uvd, 0x32, 0x46);
1783 for (i=0; i < ntries; i++)
1784 ibmcam_Packet_Format1(uvd, 0x33, 0x55);
1785
1786 ibmcam_Packet_Format1(uvd, 0x2e, 0x04);
1787 for (i=0; i < ntries; i++)
1788 ibmcam_Packet_Format1(uvd, 0x2d, 0x04);
1789 for (i=0; i < ntries; i++)
1790 ibmcam_Packet_Format1(uvd, 0x29, 0x80);
1791 ibmcam_Packet_Format1(uvd, 0x2c, 0x01);
1792 ibmcam_Packet_Format1(uvd, 0x30, 0x17);
1793 ibmcam_Packet_Format1(uvd, 0x39, 0x08);
1794 for (i=0; i < ntries; i++)
1795 ibmcam_Packet_Format1(uvd, 0x34, 0x00);
1796
1797 ibmcam_veio(uvd, 0, 0x00, 0x0101);
1798 ibmcam_veio(uvd, 0, 0x00, 0x010a);
1799
1800 switch (uvd->videosize) {
1801 case VIDEOSIZE_128x96:
1802 ibmcam_veio(uvd, 0, 0x80, 0x0103);
1803 ibmcam_veio(uvd, 0, 0x60, 0x0105);
1804 ibmcam_veio(uvd, 0, 0x0c, 0x010b);
1805 ibmcam_veio(uvd, 0, 0x04, 0x011b); /* Same everywhere */
1806 ibmcam_veio(uvd, 0, 0x0b, 0x011d);
1807 ibmcam_veio(uvd, 0, 0x00, 0x011e); /* Same everywhere */
1808 ibmcam_veio(uvd, 0, 0x00, 0x0129);
1809 break;
1810 case VIDEOSIZE_176x144:
1811 ibmcam_veio(uvd, 0, 0xb0, 0x0103);
1812 ibmcam_veio(uvd, 0, 0x8f, 0x0105);
1813 ibmcam_veio(uvd, 0, 0x06, 0x010b);
1814 ibmcam_veio(uvd, 0, 0x04, 0x011b); /* Same everywhere */
1815 ibmcam_veio(uvd, 0, 0x0d, 0x011d);
1816 ibmcam_veio(uvd, 0, 0x00, 0x011e); /* Same everywhere */
1817 ibmcam_veio(uvd, 0, 0x03, 0x0129);
1818 break;
1819 case VIDEOSIZE_352x288:
1820 ibmcam_veio(uvd, 0, 0xb0, 0x0103);
1821 ibmcam_veio(uvd, 0, 0x90, 0x0105);
1822 ibmcam_veio(uvd, 0, 0x02, 0x010b);
1823 ibmcam_veio(uvd, 0, 0x04, 0x011b); /* Same everywhere */
1824 ibmcam_veio(uvd, 0, 0x05, 0x011d);
1825 ibmcam_veio(uvd, 0, 0x00, 0x011e); /* Same everywhere */
1826 ibmcam_veio(uvd, 0, 0x00, 0x0129);
1827 break;
1828 }
1829
1830 ibmcam_veio(uvd, 0, 0xff, 0x012b);
1831
1832 /* This is another brightness - don't know why */
1833 for (i=0; i < ntries; i++)
1834 ibmcam_Packet_Format1(uvd, 0x31, 0xc3);
1835 for (i=0; i < ntries; i++)
1836 ibmcam_Packet_Format1(uvd, 0x32, 0xd2);
1837 for (i=0; i < ntries; i++)
1838 ibmcam_Packet_Format1(uvd, 0x33, 0xe1);
1839
1840 /* Default contrast */
1841 for (i=0; i < ntries; i++)
1842 ibmcam_Packet_Format1(uvd, contrast_14, 0x0a);
1843
1844 /* Default sharpness */
1845 for (i=0; i < 2; i++)
1846 ibmcam_PacketFormat2(uvd, sharp_13, 0x1a); /* Level 4 FIXME */
1847
1848 /* Default lighting conditions */
1849 ibmcam_Packet_Format1(uvd, light_27, lighting); /* 0=Bright 2=Low */
1850
1851 /* Assorted init */
1852
1853 switch (uvd->videosize) {
1854 case VIDEOSIZE_128x96:
1855 ibmcam_Packet_Format1(uvd, 0x2b, 0x1e);
1856 ibmcam_veio(uvd, 0, 0xc9, 0x0119); /* Same everywhere */
1857 ibmcam_veio(uvd, 0, 0x80, 0x0109); /* Same everywhere */
1858 ibmcam_veio(uvd, 0, 0x36, 0x0102);
1859 ibmcam_veio(uvd, 0, 0x1a, 0x0104);
1860 ibmcam_veio(uvd, 0, 0x04, 0x011a); /* Same everywhere */
1861 ibmcam_veio(uvd, 0, 0x2b, 0x011c);
1862 ibmcam_veio(uvd, 0, 0x23, 0x012a); /* Same everywhere */
1863#if 0
1864 ibmcam_veio(uvd, 0, 0x00, 0x0106);
1865 ibmcam_veio(uvd, 0, 0x38, 0x0107);
1866#else
1867 ibmcam_veio(uvd, 0, 0x02, 0x0106);
1868 ibmcam_veio(uvd, 0, 0x2a, 0x0107);
1869#endif
1870 break;
1871 case VIDEOSIZE_176x144:
1872 ibmcam_Packet_Format1(uvd, 0x2b, 0x1e);
1873 ibmcam_veio(uvd, 0, 0xc9, 0x0119); /* Same everywhere */
1874 ibmcam_veio(uvd, 0, 0x80, 0x0109); /* Same everywhere */
1875 ibmcam_veio(uvd, 0, 0x04, 0x0102);
1876 ibmcam_veio(uvd, 0, 0x02, 0x0104);
1877 ibmcam_veio(uvd, 0, 0x04, 0x011a); /* Same everywhere */
1878 ibmcam_veio(uvd, 0, 0x2b, 0x011c);
1879 ibmcam_veio(uvd, 0, 0x23, 0x012a); /* Same everywhere */
1880 ibmcam_veio(uvd, 0, 0x01, 0x0106);
1881 ibmcam_veio(uvd, 0, 0xca, 0x0107);
1882 break;
1883 case VIDEOSIZE_352x288:
1884 ibmcam_Packet_Format1(uvd, 0x2b, 0x1f);
1885 ibmcam_veio(uvd, 0, 0xc9, 0x0119); /* Same everywhere */
1886 ibmcam_veio(uvd, 0, 0x80, 0x0109); /* Same everywhere */
1887 ibmcam_veio(uvd, 0, 0x08, 0x0102);
1888 ibmcam_veio(uvd, 0, 0x01, 0x0104);
1889 ibmcam_veio(uvd, 0, 0x04, 0x011a); /* Same everywhere */
1890 ibmcam_veio(uvd, 0, 0x2f, 0x011c);
1891 ibmcam_veio(uvd, 0, 0x23, 0x012a); /* Same everywhere */
1892 ibmcam_veio(uvd, 0, 0x03, 0x0106);
1893 ibmcam_veio(uvd, 0, 0xf6, 0x0107);
1894 break;
1895 }
1896 return (CAMERA_IS_OPERATIONAL(uvd) ? 0 : -EFAULT);
1897}
1898
1899static int ibmcam_model2_setup(struct uvd *uvd)
1900{
1901 ibmcam_veio(uvd, 0, 0x0000, 0x0100); /* LED on */
1902 ibmcam_veio(uvd, 1, 0x0000, 0x0116);
1903 ibmcam_veio(uvd, 0, 0x0060, 0x0116);
1904 ibmcam_veio(uvd, 0, 0x0002, 0x0112);
1905 ibmcam_veio(uvd, 0, 0x00bc, 0x012c);
1906 ibmcam_veio(uvd, 0, 0x0008, 0x012b);
1907 ibmcam_veio(uvd, 0, 0x0000, 0x0108);
1908 ibmcam_veio(uvd, 0, 0x0001, 0x0133);
1909 ibmcam_veio(uvd, 0, 0x0001, 0x0102);
1910 switch (uvd->videosize) {
1911 case VIDEOSIZE_176x144:
1912 ibmcam_veio(uvd, 0, 0x002c, 0x0103); /* All except 320x240 */
1913 ibmcam_veio(uvd, 0, 0x0000, 0x0104); /* Same */
1914 ibmcam_veio(uvd, 0, 0x0024, 0x0105); /* 176x144, 352x288 */
1915 ibmcam_veio(uvd, 0, 0x00b9, 0x010a); /* Unique to this mode */
1916 ibmcam_veio(uvd, 0, 0x0038, 0x0119); /* Unique to this mode */
1917 ibmcam_veio(uvd, 0, 0x0003, 0x0106); /* Same */
1918 ibmcam_veio(uvd, 0, 0x0090, 0x0107); /* Unique to every mode*/
1919 break;
1920 case VIDEOSIZE_320x240:
1921 ibmcam_veio(uvd, 0, 0x0028, 0x0103); /* Unique to this mode */
1922 ibmcam_veio(uvd, 0, 0x0000, 0x0104); /* Same */
1923 ibmcam_veio(uvd, 0, 0x001e, 0x0105); /* 320x240, 352x240 */
1924 ibmcam_veio(uvd, 0, 0x0039, 0x010a); /* All except 176x144 */
1925 ibmcam_veio(uvd, 0, 0x0070, 0x0119); /* All except 176x144 */
1926 ibmcam_veio(uvd, 0, 0x0003, 0x0106); /* Same */
1927 ibmcam_veio(uvd, 0, 0x0098, 0x0107); /* Unique to every mode*/
1928 break;
1929 case VIDEOSIZE_352x240:
1930 ibmcam_veio(uvd, 0, 0x002c, 0x0103); /* All except 320x240 */
1931 ibmcam_veio(uvd, 0, 0x0000, 0x0104); /* Same */
1932 ibmcam_veio(uvd, 0, 0x001e, 0x0105); /* 320x240, 352x240 */
1933 ibmcam_veio(uvd, 0, 0x0039, 0x010a); /* All except 176x144 */
1934 ibmcam_veio(uvd, 0, 0x0070, 0x0119); /* All except 176x144 */
1935 ibmcam_veio(uvd, 0, 0x0003, 0x0106); /* Same */
1936 ibmcam_veio(uvd, 0, 0x00da, 0x0107); /* Unique to every mode*/
1937 break;
1938 case VIDEOSIZE_352x288:
1939 ibmcam_veio(uvd, 0, 0x002c, 0x0103); /* All except 320x240 */
1940 ibmcam_veio(uvd, 0, 0x0000, 0x0104); /* Same */
1941 ibmcam_veio(uvd, 0, 0x0024, 0x0105); /* 176x144, 352x288 */
1942 ibmcam_veio(uvd, 0, 0x0039, 0x010a); /* All except 176x144 */
1943 ibmcam_veio(uvd, 0, 0x0070, 0x0119); /* All except 176x144 */
1944 ibmcam_veio(uvd, 0, 0x0003, 0x0106); /* Same */
1945 ibmcam_veio(uvd, 0, 0x00fe, 0x0107); /* Unique to every mode*/
1946 break;
1947 }
1948 return (CAMERA_IS_OPERATIONAL(uvd) ? 0 : -EFAULT);
1949}
1950
1951/*
1952 * ibmcam_model1_setup_after_video_if()
1953 *
1954 * This code adds finishing touches to the video data interface.
1955 * Here we configure the frame rate and turn on the LED.
1956 */
1957static void ibmcam_model1_setup_after_video_if(struct uvd *uvd)
1958{
1959 unsigned short internal_frame_rate;
1960
1961 RESTRICT_TO_RANGE(framerate, FRAMERATE_MIN, FRAMERATE_MAX);
1962 internal_frame_rate = FRAMERATE_MAX - framerate; /* 0=Fast 6=Slow */
1963 ibmcam_veio(uvd, 0, 0x01, 0x0100); /* LED On */
1964 ibmcam_veio(uvd, 0, internal_frame_rate, 0x0111);
1965 ibmcam_veio(uvd, 0, 0x01, 0x0114);
1966 ibmcam_veio(uvd, 0, 0xc0, 0x010c);
1967}
1968
1969static void ibmcam_model2_setup_after_video_if(struct uvd *uvd)
1970{
1971 unsigned short setup_model2_rg2, setup_model2_sat, setup_model2_yb;
1972
1973 ibmcam_veio(uvd, 0, 0x0000, 0x0100); /* LED on */
1974
1975 switch (uvd->videosize) {
1976 case VIDEOSIZE_176x144:
1977 ibmcam_veio(uvd, 0, 0x0050, 0x0111);
1978 ibmcam_veio(uvd, 0, 0x00d0, 0x0111);
1979 break;
1980 case VIDEOSIZE_320x240:
1981 case VIDEOSIZE_352x240:
1982 case VIDEOSIZE_352x288:
1983 ibmcam_veio(uvd, 0, 0x0040, 0x0111);
1984 ibmcam_veio(uvd, 0, 0x00c0, 0x0111);
1985 break;
1986 }
1987 ibmcam_veio(uvd, 0, 0x009b, 0x010f);
1988 ibmcam_veio(uvd, 0, 0x00bb, 0x010f);
1989
1990 /*
1991 * Hardware settings, may affect CMOS sensor; not user controls!
1992 * -------------------------------------------------------------
1993 * 0x0004: no effect
1994 * 0x0006: hardware effect
1995 * 0x0008: no effect
1996 * 0x000a: stops video stream, probably important h/w setting
1997 * 0x000c: changes color in hardware manner (not user setting)
1998 * 0x0012: changes number of colors (does not affect speed)
1999 * 0x002a: no effect
2000 * 0x002c: hardware setting (related to scan lines)
2001 * 0x002e: stops video stream, probably important h/w setting
2002 */
2003 ibmcam_model2_Packet1(uvd, 0x000a, 0x005c);
2004 ibmcam_model2_Packet1(uvd, 0x0004, 0x0000);
2005 ibmcam_model2_Packet1(uvd, 0x0006, 0x00fb);
2006 ibmcam_model2_Packet1(uvd, 0x0008, 0x0000);
2007 ibmcam_model2_Packet1(uvd, 0x000c, 0x0009);
2008 ibmcam_model2_Packet1(uvd, 0x0012, 0x000a);
2009 ibmcam_model2_Packet1(uvd, 0x002a, 0x0000);
2010 ibmcam_model2_Packet1(uvd, 0x002c, 0x0000);
2011 ibmcam_model2_Packet1(uvd, 0x002e, 0x0008);
2012
2013 /*
2014 * Function 0x0030 pops up all over the place. Apparently
2015 * it is a hardware control register, with every bit assigned to
2016 * do something.
2017 */
2018 ibmcam_model2_Packet1(uvd, 0x0030, 0x0000);
2019
2020 /*
2021 * Magic control of CMOS sensor. Only lower values like
2022 * 0-3 work, and picture shifts left or right. Don't change.
2023 */
2024 switch (uvd->videosize) {
2025 case VIDEOSIZE_176x144:
2026 ibmcam_model2_Packet1(uvd, 0x0014, 0x0002);
2027 ibmcam_model2_Packet1(uvd, 0x0016, 0x0002); /* Horizontal shift */
2028 ibmcam_model2_Packet1(uvd, 0x0018, 0x004a); /* Another hardware setting */
2029 break;
2030 case VIDEOSIZE_320x240:
2031 ibmcam_model2_Packet1(uvd, 0x0014, 0x0009);
2032 ibmcam_model2_Packet1(uvd, 0x0016, 0x0005); /* Horizontal shift */
2033 ibmcam_model2_Packet1(uvd, 0x0018, 0x0044); /* Another hardware setting */
2034 break;
2035 case VIDEOSIZE_352x240:
2036 /* This mode doesn't work as Windows programs it; changed to work */
2037 ibmcam_model2_Packet1(uvd, 0x0014, 0x0009); /* Windows sets this to 8 */
2038 ibmcam_model2_Packet1(uvd, 0x0016, 0x0003); /* Horizontal shift */
2039 ibmcam_model2_Packet1(uvd, 0x0018, 0x0044); /* Windows sets this to 0x0045 */
2040 break;
2041 case VIDEOSIZE_352x288:
2042 ibmcam_model2_Packet1(uvd, 0x0014, 0x0003);
2043 ibmcam_model2_Packet1(uvd, 0x0016, 0x0002); /* Horizontal shift */
2044 ibmcam_model2_Packet1(uvd, 0x0018, 0x004a); /* Another hardware setting */
2045 break;
2046 }
2047
2048 ibmcam_model2_Packet1(uvd, mod2_brightness, 0x005a);
2049
2050 /*
2051 * We have our own frame rate setting varying from 0 (slowest) to 6 (fastest).
2052 * The camera model 2 allows frame rate in range [0..0x1F] where 0 is also the
2053 * slowest setting. However for all practical reasons high settings make no
2054 * sense because USB is not fast enough to support high FPS. Be aware that
2055 * the picture datastream will be severely disrupted if you ask for
2056 * frame rate faster than allowed for the video size - see below:
2057 *
2058 * Allowable ranges (obtained experimentally on OHCI, K6-3, 450 MHz):
2059 * -----------------------------------------------------------------
2060 * 176x144: [6..31]
2061 * 320x240: [8..31]
2062 * 352x240: [10..31]
2063 * 352x288: [16..31] I have to raise lower threshold for stability...
2064 *
2065 * As usual, slower FPS provides better sensitivity.
2066 */
2067 {
2068 short hw_fps=31, i_framerate;
2069
2070 RESTRICT_TO_RANGE(framerate, FRAMERATE_MIN, FRAMERATE_MAX);
2071 i_framerate = FRAMERATE_MAX - framerate + FRAMERATE_MIN;
2072 switch (uvd->videosize) {
2073 case VIDEOSIZE_176x144:
2074 hw_fps = 6 + i_framerate*4;
2075 break;
2076 case VIDEOSIZE_320x240:
2077 hw_fps = 8 + i_framerate*3;
2078 break;
2079 case VIDEOSIZE_352x240:
2080 hw_fps = 10 + i_framerate*2;
2081 break;
2082 case VIDEOSIZE_352x288:
2083 hw_fps = 28 + i_framerate/2;
2084 break;
2085 }
2086 if (uvd->debug > 0)
2087 info("Framerate (hardware): %hd.", hw_fps);
2088 RESTRICT_TO_RANGE(hw_fps, 0, 31);
2089 ibmcam_model2_Packet1(uvd, mod2_set_framerate, hw_fps);
2090 }
2091
2092 /*
2093 * This setting does not visibly affect pictures; left it here
2094 * because it was present in Windows USB data stream. This function
2095 * does not allow arbitrary values and apparently is a bit mask, to
2096 * be activated only at appropriate time. Don't change it randomly!
2097 */
2098 switch (uvd->videosize) {
2099 case VIDEOSIZE_176x144:
2100 ibmcam_model2_Packet1(uvd, 0x0026, 0x00c2);
2101 break;
2102 case VIDEOSIZE_320x240:
2103 ibmcam_model2_Packet1(uvd, 0x0026, 0x0044);
2104 break;
2105 case VIDEOSIZE_352x240:
2106 ibmcam_model2_Packet1(uvd, 0x0026, 0x0046);
2107 break;
2108 case VIDEOSIZE_352x288:
2109 ibmcam_model2_Packet1(uvd, 0x0026, 0x0048);
2110 break;
2111 }
2112
2113 ibmcam_model2_Packet1(uvd, mod2_sensitivity, lighting);
2114
2115 if (init_model2_rg2 >= 0) {
2116 RESTRICT_TO_RANGE(init_model2_rg2, 0, 255);
2117 setup_model2_rg2 = init_model2_rg2;
2118 } else
2119 setup_model2_rg2 = 0x002f;
2120
2121 if (init_model2_sat >= 0) {
2122 RESTRICT_TO_RANGE(init_model2_sat, 0, 255);
2123 setup_model2_sat = init_model2_sat;
2124 } else
2125 setup_model2_sat = 0x0034;
2126
2127 if (init_model2_yb >= 0) {
2128 RESTRICT_TO_RANGE(init_model2_yb, 0, 255);
2129 setup_model2_yb = init_model2_yb;
2130 } else
2131 setup_model2_yb = 0x00a0;
2132
2133 ibmcam_model2_Packet1(uvd, mod2_color_balance_rg2, setup_model2_rg2);
2134 ibmcam_model2_Packet1(uvd, mod2_saturation, setup_model2_sat);
2135 ibmcam_model2_Packet1(uvd, mod2_color_balance_yb, setup_model2_yb);
2136 ibmcam_model2_Packet1(uvd, mod2_hue, uvd->vpic.hue >> 9); /* 0 .. 7F */;
2137
2138 /* Hardware control command */
2139 ibmcam_model2_Packet1(uvd, 0x0030, 0x0004);
2140
2141 ibmcam_veio(uvd, 0, 0x00c0, 0x010c); /* Go camera, go! */
2142 usb_clear_halt(uvd->dev, usb_rcvisocpipe(uvd->dev, uvd->video_endp));
2143}
2144
2145static void ibmcam_model4_setup_after_video_if(struct uvd *uvd)
2146{
2147 switch (uvd->videosize) {
2148 case VIDEOSIZE_128x96:
2149 ibmcam_veio(uvd, 0, 0x0000, 0x0100);
2150 ibmcam_veio(uvd, 0, 0x00c0, 0x0111);
2151 ibmcam_veio(uvd, 0, 0x00bc, 0x012c);
2152 ibmcam_veio(uvd, 0, 0x0080, 0x012b);
2153 ibmcam_veio(uvd, 0, 0x0000, 0x0108);
2154 ibmcam_veio(uvd, 0, 0x0001, 0x0133);
2155 ibmcam_veio(uvd, 0, 0x009b, 0x010f);
2156 ibmcam_veio(uvd, 0, 0x00bb, 0x010f);
2157 ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
2158 ibmcam_veio(uvd, 0, 0x0038, 0x012f);
2159 ibmcam_veio(uvd, 0, 0xd141, 0x0124);
2160 ibmcam_veio(uvd, 0, 0x0000, 0x0127);
2161 ibmcam_veio(uvd, 0, 0xfea8, 0x0124);
2162 ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
2163 ibmcam_veio(uvd, 0, 0x000a, 0x012f);
2164 ibmcam_veio(uvd, 0, 0xd141, 0x0124);
2165 ibmcam_veio(uvd, 0, 0x005c, 0x0127);
2166 ibmcam_veio(uvd, 0, 0xfea8, 0x0124);
2167 ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
2168 ibmcam_veio(uvd, 0, 0x0004, 0x012f);
2169 ibmcam_veio(uvd, 0, 0xd141, 0x0124);
2170 ibmcam_veio(uvd, 0, 0x0000, 0x0127);
2171 ibmcam_veio(uvd, 0, 0x00fb, 0x012e);
2172 ibmcam_veio(uvd, 0, 0x0000, 0x0130);
2173 ibmcam_veio(uvd, 0, 0x8a28, 0x0124);
2174 ibmcam_veio(uvd, 0, 0x00aa, 0x012f);
2175 ibmcam_veio(uvd, 0, 0xd055, 0x0124);
2176 ibmcam_veio(uvd, 0, 0x000c, 0x0127);
2177 ibmcam_veio(uvd, 0, 0x0009, 0x012e);
2178 ibmcam_veio(uvd, 0, 0xaa28, 0x0124);
2179 ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
2180 ibmcam_veio(uvd, 0, 0x0012, 0x012f);
2181 ibmcam_veio(uvd, 0, 0xd141, 0x0124);
2182 ibmcam_veio(uvd, 0, 0x0008, 0x0127);
2183 ibmcam_veio(uvd, 0, 0x00aa, 0x0130);
2184 ibmcam_veio(uvd, 0, 0x82a8, 0x0124);
2185 ibmcam_veio(uvd, 0, 0x002a, 0x012d);
2186 ibmcam_veio(uvd, 0, 0x0000, 0x012f);
2187 ibmcam_veio(uvd, 0, 0xd145, 0x0124);
2188 ibmcam_veio(uvd, 0, 0xfffa, 0x0124);
2189 ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
2190 ibmcam_veio(uvd, 0, 0x0034, 0x012f);
2191 ibmcam_veio(uvd, 0, 0xd141, 0x0124);
2192 ibmcam_veio(uvd, 0, 0x0000, 0x0127);
2193 ibmcam_veio(uvd, 0, 0xfea8, 0x0124);
2194 ibmcam_veio(uvd, 0, 0x0070, 0x0119);
2195 ibmcam_veio(uvd, 0, 0x00d2, 0x0107);
2196 ibmcam_veio(uvd, 0, 0x0003, 0x0106);
2197 ibmcam_veio(uvd, 0, 0x005e, 0x0107);
2198 ibmcam_veio(uvd, 0, 0x0003, 0x0106);
2199 ibmcam_veio(uvd, 0, 0x00d0, 0x0111);
2200 ibmcam_veio(uvd, 0, 0x0039, 0x010a);
2201 ibmcam_veio(uvd, 0, 0x0001, 0x0102);
2202 ibmcam_veio(uvd, 0, 0x0028, 0x0103);
2203 ibmcam_veio(uvd, 0, 0x0000, 0x0104);
2204 ibmcam_veio(uvd, 0, 0x001e, 0x0105);
2205 ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
2206 ibmcam_veio(uvd, 0, 0x0016, 0x012f);
2207 ibmcam_veio(uvd, 0, 0xd141, 0x0124);
2208 ibmcam_veio(uvd, 0, 0x000a, 0x0127);
2209 ibmcam_veio(uvd, 0, 0x00aa, 0x0130);
2210 ibmcam_veio(uvd, 0, 0x82a8, 0x0124);
2211 ibmcam_veio(uvd, 0, 0x0014, 0x012d);
2212 ibmcam_veio(uvd, 0, 0x0008, 0x012f);
2213 ibmcam_veio(uvd, 0, 0xd145, 0x0124);
2214 ibmcam_veio(uvd, 0, 0x00aa, 0x012e);
2215 ibmcam_veio(uvd, 0, 0x001a, 0x0130);
2216 ibmcam_veio(uvd, 0, 0x8a0a, 0x0124);
2217 ibmcam_veio(uvd, 0, 0x005a, 0x012d);
2218 ibmcam_veio(uvd, 0, 0x9545, 0x0124);
2219 ibmcam_veio(uvd, 0, 0x00aa, 0x0127);
2220 ibmcam_veio(uvd, 0, 0x0018, 0x012e);
2221 ibmcam_veio(uvd, 0, 0x0043, 0x0130);
2222 ibmcam_veio(uvd, 0, 0x8a28, 0x0124);
2223 ibmcam_veio(uvd, 0, 0x00aa, 0x012f);
2224 ibmcam_veio(uvd, 0, 0xd055, 0x0124);
2225 ibmcam_veio(uvd, 0, 0x001c, 0x0127);
2226 ibmcam_veio(uvd, 0, 0x00eb, 0x012e);
2227 ibmcam_veio(uvd, 0, 0xaa28, 0x0124);
2228 ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
2229 ibmcam_veio(uvd, 0, 0x0032, 0x012f);
2230 ibmcam_veio(uvd, 0, 0xd141, 0x0124);
2231 ibmcam_veio(uvd, 0, 0x0000, 0x0127);
2232 ibmcam_veio(uvd, 0, 0x00aa, 0x0130);
2233 ibmcam_veio(uvd, 0, 0x82a8, 0x0124);
2234 ibmcam_veio(uvd, 0, 0x0036, 0x012d);
2235 ibmcam_veio(uvd, 0, 0x0008, 0x012f);
2236 ibmcam_veio(uvd, 0, 0xd145, 0x0124);
2237 ibmcam_veio(uvd, 0, 0xfffa, 0x0124);
2238 ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
2239 ibmcam_veio(uvd, 0, 0x001e, 0x012f);
2240 ibmcam_veio(uvd, 0, 0xd141, 0x0124);
2241 ibmcam_veio(uvd, 0, 0x0017, 0x0127);
2242 ibmcam_veio(uvd, 0, 0x0013, 0x012e);
2243 ibmcam_veio(uvd, 0, 0x0031, 0x0130);
2244 ibmcam_veio(uvd, 0, 0x8a28, 0x0124);
2245 ibmcam_veio(uvd, 0, 0x0017, 0x012d);
2246 ibmcam_veio(uvd, 0, 0x0078, 0x012f);
2247 ibmcam_veio(uvd, 0, 0xd145, 0x0124);
2248 ibmcam_veio(uvd, 0, 0x0000, 0x0127);
2249 ibmcam_veio(uvd, 0, 0xfea8, 0x0124);
2250 ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
2251 ibmcam_veio(uvd, 0, 0x0038, 0x012f);
2252 ibmcam_veio(uvd, 0, 0xd141, 0x0124);
2253 ibmcam_veio(uvd, 0, 0x0004, 0x0127);
2254 ibmcam_veio(uvd, 0, 0xfea8, 0x0124);
2255 ibmcam_veio(uvd, 0, 0x00c0, 0x010c);
2256 break;
2257 case VIDEOSIZE_160x120:
2258 ibmcam_veio(uvd, 0, 0x0000, 0x0100);
2259 ibmcam_veio(uvd, 0, 0x00c0, 0x0111);
2260 ibmcam_veio(uvd, 0, 0x00bc, 0x012c);
2261 ibmcam_veio(uvd, 0, 0x0080, 0x012b);
2262 ibmcam_veio(uvd, 0, 0x0000, 0x0108);
2263 ibmcam_veio(uvd, 0, 0x0001, 0x0133);
2264 ibmcam_veio(uvd, 0, 0x009b, 0x010f);
2265 ibmcam_veio(uvd, 0, 0x00bb, 0x010f);
2266 ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
2267 ibmcam_veio(uvd, 0, 0x0038, 0x012f);
2268 ibmcam_veio(uvd, 0, 0xd141, 0x0124);
2269 ibmcam_veio(uvd, 0, 0x0000, 0x0127);
2270 ibmcam_veio(uvd, 0, 0xfea8, 0x0124);
2271 ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
2272 ibmcam_veio(uvd, 0, 0x000a, 0x012f);
2273 ibmcam_veio(uvd, 0, 0xd141, 0x0124);
2274 ibmcam_veio(uvd, 0, 0x005c, 0x0127);
2275 ibmcam_veio(uvd, 0, 0xfea8, 0x0124);
2276 ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
2277 ibmcam_veio(uvd, 0, 0x0004, 0x012f);
2278 ibmcam_veio(uvd, 0, 0xd141, 0x0124);
2279 ibmcam_veio(uvd, 0, 0x0000, 0x0127);
2280 ibmcam_veio(uvd, 0, 0x00fb, 0x012e);
2281 ibmcam_veio(uvd, 0, 0x0000, 0x0130);
2282 ibmcam_veio(uvd, 0, 0x8a28, 0x0124);
2283 ibmcam_veio(uvd, 0, 0x00aa, 0x012f);
2284 ibmcam_veio(uvd, 0, 0xd055, 0x0124);
2285 ibmcam_veio(uvd, 0, 0x000c, 0x0127);
2286 ibmcam_veio(uvd, 0, 0x0009, 0x012e);
2287 ibmcam_veio(uvd, 0, 0xaa28, 0x0124);
2288 ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
2289 ibmcam_veio(uvd, 0, 0x0012, 0x012f);
2290 ibmcam_veio(uvd, 0, 0xd141, 0x0124);
2291 ibmcam_veio(uvd, 0, 0x0008, 0x0127);
2292 ibmcam_veio(uvd, 0, 0x00aa, 0x0130);
2293 ibmcam_veio(uvd, 0, 0x82a8, 0x0124);
2294 ibmcam_veio(uvd, 0, 0x002a, 0x012d);
2295 ibmcam_veio(uvd, 0, 0x0000, 0x012f);
2296 ibmcam_veio(uvd, 0, 0xd145, 0x0124);
2297 ibmcam_veio(uvd, 0, 0xfffa, 0x0124);
2298 ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
2299 ibmcam_veio(uvd, 0, 0x0034, 0x012f);
2300 ibmcam_veio(uvd, 0, 0xd141, 0x0124);
2301 ibmcam_veio(uvd, 0, 0x0000, 0x0127);
2302 ibmcam_veio(uvd, 0, 0xfea8, 0x0124);
2303 ibmcam_veio(uvd, 0, 0x0038, 0x0119);
2304 ibmcam_veio(uvd, 0, 0x00d8, 0x0107);
2305 ibmcam_veio(uvd, 0, 0x0002, 0x0106);
2306 ibmcam_veio(uvd, 0, 0x00d0, 0x0111);
2307 ibmcam_veio(uvd, 0, 0x00b9, 0x010a);
2308 ibmcam_veio(uvd, 0, 0x0001, 0x0102);
2309 ibmcam_veio(uvd, 0, 0x0028, 0x0103);
2310 ibmcam_veio(uvd, 0, 0x0000, 0x0104);
2311 ibmcam_veio(uvd, 0, 0x001e, 0x0105);
2312 ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
2313 ibmcam_veio(uvd, 0, 0x0016, 0x012f);
2314 ibmcam_veio(uvd, 0, 0xd141, 0x0124);
2315 ibmcam_veio(uvd, 0, 0x000b, 0x0127);
2316 ibmcam_veio(uvd, 0, 0x00aa, 0x0130);
2317 ibmcam_veio(uvd, 0, 0x82a8, 0x0124);
2318 ibmcam_veio(uvd, 0, 0x0014, 0x012d);
2319 ibmcam_veio(uvd, 0, 0x0008, 0x012f);
2320 ibmcam_veio(uvd, 0, 0xd145, 0x0124);
2321 ibmcam_veio(uvd, 0, 0x00aa, 0x012e);
2322 ibmcam_veio(uvd, 0, 0x001a, 0x0130);
2323 ibmcam_veio(uvd, 0, 0x8a0a, 0x0124);
2324 ibmcam_veio(uvd, 0, 0x005a, 0x012d);
2325 ibmcam_veio(uvd, 0, 0x9545, 0x0124);
2326 ibmcam_veio(uvd, 0, 0x00aa, 0x0127);
2327 ibmcam_veio(uvd, 0, 0x0018, 0x012e);
2328 ibmcam_veio(uvd, 0, 0x0043, 0x0130);
2329 ibmcam_veio(uvd, 0, 0x8a28, 0x0124);
2330 ibmcam_veio(uvd, 0, 0x00aa, 0x012f);
2331 ibmcam_veio(uvd, 0, 0xd055, 0x0124);
2332 ibmcam_veio(uvd, 0, 0x001c, 0x0127);
2333 ibmcam_veio(uvd, 0, 0x00c7, 0x012e);
2334 ibmcam_veio(uvd, 0, 0xaa28, 0x0124);
2335 ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
2336 ibmcam_veio(uvd, 0, 0x0032, 0x012f);
2337 ibmcam_veio(uvd, 0, 0xd141, 0x0124);
2338 ibmcam_veio(uvd, 0, 0x0025, 0x0127);
2339 ibmcam_veio(uvd, 0, 0x00aa, 0x0130);
2340 ibmcam_veio(uvd, 0, 0x82a8, 0x0124);
2341 ibmcam_veio(uvd, 0, 0x0036, 0x012d);
2342 ibmcam_veio(uvd, 0, 0x0008, 0x012f);
2343 ibmcam_veio(uvd, 0, 0xd145, 0x0124);
2344 ibmcam_veio(uvd, 0, 0xfffa, 0x0124);
2345 ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
2346 ibmcam_veio(uvd, 0, 0x001e, 0x012f);
2347 ibmcam_veio(uvd, 0, 0xd141, 0x0124);
2348 ibmcam_veio(uvd, 0, 0x0048, 0x0127);
2349 ibmcam_veio(uvd, 0, 0x0035, 0x012e);
2350 ibmcam_veio(uvd, 0, 0x00d0, 0x0130);
2351 ibmcam_veio(uvd, 0, 0x8a28, 0x0124);
2352 ibmcam_veio(uvd, 0, 0x0048, 0x012d);
2353 ibmcam_veio(uvd, 0, 0x0090, 0x012f);
2354 ibmcam_veio(uvd, 0, 0xd145, 0x0124);
2355 ibmcam_veio(uvd, 0, 0x0001, 0x0127);
2356 ibmcam_veio(uvd, 0, 0xfea8, 0x0124);
2357 ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
2358 ibmcam_veio(uvd, 0, 0x0038, 0x012f);
2359 ibmcam_veio(uvd, 0, 0xd141, 0x0124);
2360 ibmcam_veio(uvd, 0, 0x0004, 0x0127);
2361 ibmcam_veio(uvd, 0, 0xfea8, 0x0124);
2362 ibmcam_veio(uvd, 0, 0x00c0, 0x010c);
2363 break;
2364 case VIDEOSIZE_176x144:
2365 ibmcam_veio(uvd, 0, 0x0000, 0x0100);
2366 ibmcam_veio(uvd, 0, 0x00c0, 0x0111);
2367 ibmcam_veio(uvd, 0, 0x00bc, 0x012c);
2368 ibmcam_veio(uvd, 0, 0x0080, 0x012b);
2369 ibmcam_veio(uvd, 0, 0x0000, 0x0108);
2370 ibmcam_veio(uvd, 0, 0x0001, 0x0133);
2371 ibmcam_veio(uvd, 0, 0x009b, 0x010f);
2372 ibmcam_veio(uvd, 0, 0x00bb, 0x010f);
2373 ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
2374 ibmcam_veio(uvd, 0, 0x0038, 0x012f);
2375 ibmcam_veio(uvd, 0, 0xd141, 0x0124);
2376 ibmcam_veio(uvd, 0, 0x0000, 0x0127);
2377 ibmcam_veio(uvd, 0, 0xfea8, 0x0124);
2378 ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
2379 ibmcam_veio(uvd, 0, 0x000a, 0x012f);
2380 ibmcam_veio(uvd, 0, 0xd141, 0x0124);
2381 ibmcam_veio(uvd, 0, 0x005c, 0x0127);
2382 ibmcam_veio(uvd, 0, 0xfea8, 0x0124);
2383 ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
2384 ibmcam_veio(uvd, 0, 0x0004, 0x012f);
2385 ibmcam_veio(uvd, 0, 0xd141, 0x0124);
2386 ibmcam_veio(uvd, 0, 0x0000, 0x0127);
2387 ibmcam_veio(uvd, 0, 0x00fb, 0x012e);
2388 ibmcam_veio(uvd, 0, 0x0000, 0x0130);
2389 ibmcam_veio(uvd, 0, 0x8a28, 0x0124);
2390 ibmcam_veio(uvd, 0, 0x00aa, 0x012f);
2391 ibmcam_veio(uvd, 0, 0xd055, 0x0124);
2392 ibmcam_veio(uvd, 0, 0x000c, 0x0127);
2393 ibmcam_veio(uvd, 0, 0x0009, 0x012e);
2394 ibmcam_veio(uvd, 0, 0xaa28, 0x0124);
2395 ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
2396 ibmcam_veio(uvd, 0, 0x0012, 0x012f);
2397 ibmcam_veio(uvd, 0, 0xd141, 0x0124);
2398 ibmcam_veio(uvd, 0, 0x0008, 0x0127);
2399 ibmcam_veio(uvd, 0, 0x00aa, 0x0130);
2400 ibmcam_veio(uvd, 0, 0x82a8, 0x0124);
2401 ibmcam_veio(uvd, 0, 0x002a, 0x012d);
2402 ibmcam_veio(uvd, 0, 0x0000, 0x012f);
2403 ibmcam_veio(uvd, 0, 0xd145, 0x0124);
2404 ibmcam_veio(uvd, 0, 0xfffa, 0x0124);
2405 ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
2406 ibmcam_veio(uvd, 0, 0x0034, 0x012f);
2407 ibmcam_veio(uvd, 0, 0xd141, 0x0124);
2408 ibmcam_veio(uvd, 0, 0x0000, 0x0127);
2409 ibmcam_veio(uvd, 0, 0xfea8, 0x0124);
2410 ibmcam_veio(uvd, 0, 0x0038, 0x0119);
2411 ibmcam_veio(uvd, 0, 0x00d6, 0x0107);
2412 ibmcam_veio(uvd, 0, 0x0003, 0x0106);
2413 ibmcam_veio(uvd, 0, 0x0018, 0x0107);
2414 ibmcam_veio(uvd, 0, 0x0003, 0x0106);
2415 ibmcam_veio(uvd, 0, 0x00d0, 0x0111);
2416 ibmcam_veio(uvd, 0, 0x00b9, 0x010a);
2417 ibmcam_veio(uvd, 0, 0x0001, 0x0102);
2418 ibmcam_veio(uvd, 0, 0x002c, 0x0103);
2419 ibmcam_veio(uvd, 0, 0x0000, 0x0104);
2420 ibmcam_veio(uvd, 0, 0x0024, 0x0105);
2421 ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
2422 ibmcam_veio(uvd, 0, 0x0016, 0x012f);
2423 ibmcam_veio(uvd, 0, 0xd141, 0x0124);
2424 ibmcam_veio(uvd, 0, 0x0007, 0x0127);
2425 ibmcam_veio(uvd, 0, 0x00aa, 0x0130);
2426 ibmcam_veio(uvd, 0, 0x82a8, 0x0124);
2427 ibmcam_veio(uvd, 0, 0x0014, 0x012d);
2428 ibmcam_veio(uvd, 0, 0x0001, 0x012f);
2429 ibmcam_veio(uvd, 0, 0xd145, 0x0124);
2430 ibmcam_veio(uvd, 0, 0x00aa, 0x012e);
2431 ibmcam_veio(uvd, 0, 0x001a, 0x0130);
2432 ibmcam_veio(uvd, 0, 0x8a0a, 0x0124);
2433 ibmcam_veio(uvd, 0, 0x005e, 0x012d);
2434 ibmcam_veio(uvd, 0, 0x9545, 0x0124);
2435 ibmcam_veio(uvd, 0, 0x00aa, 0x0127);
2436 ibmcam_veio(uvd, 0, 0x0018, 0x012e);
2437 ibmcam_veio(uvd, 0, 0x0049, 0x0130);
2438 ibmcam_veio(uvd, 0, 0x8a28, 0x0124);
2439 ibmcam_veio(uvd, 0, 0x00aa, 0x012f);
2440 ibmcam_veio(uvd, 0, 0xd055, 0x0124);
2441 ibmcam_veio(uvd, 0, 0x001c, 0x0127);
2442 ibmcam_veio(uvd, 0, 0x00c7, 0x012e);
2443 ibmcam_veio(uvd, 0, 0xaa28, 0x0124);
2444 ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
2445 ibmcam_veio(uvd, 0, 0x0032, 0x012f);
2446 ibmcam_veio(uvd, 0, 0xd141, 0x0124);
2447 ibmcam_veio(uvd, 0, 0x0028, 0x0127);
2448 ibmcam_veio(uvd, 0, 0x00aa, 0x0130);
2449 ibmcam_veio(uvd, 0, 0x82a8, 0x0124);
2450 ibmcam_veio(uvd, 0, 0x0036, 0x012d);
2451 ibmcam_veio(uvd, 0, 0x0008, 0x012f);
2452 ibmcam_veio(uvd, 0, 0xd145, 0x0124);
2453 ibmcam_veio(uvd, 0, 0xfffa, 0x0124);
2454 ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
2455 ibmcam_veio(uvd, 0, 0x001e, 0x012f);
2456 ibmcam_veio(uvd, 0, 0xd141, 0x0124);
2457 ibmcam_veio(uvd, 0, 0x0010, 0x0127);
2458 ibmcam_veio(uvd, 0, 0x0013, 0x012e);
2459 ibmcam_veio(uvd, 0, 0x002a, 0x0130);
2460 ibmcam_veio(uvd, 0, 0x8a28, 0x0124);
2461 ibmcam_veio(uvd, 0, 0x0010, 0x012d);
2462 ibmcam_veio(uvd, 0, 0x006d, 0x012f);
2463 ibmcam_veio(uvd, 0, 0xd145, 0x0124);
2464 ibmcam_veio(uvd, 0, 0x0001, 0x0127);
2465 ibmcam_veio(uvd, 0, 0xfea8, 0x0124);
2466 ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
2467 ibmcam_veio(uvd, 0, 0x0038, 0x012f);
2468 ibmcam_veio(uvd, 0, 0xd141, 0x0124);
2469 ibmcam_veio(uvd, 0, 0x0004, 0x0127);
2470 ibmcam_veio(uvd, 0, 0xfea8, 0x0124);
2471 ibmcam_veio(uvd, 0, 0x00c0, 0x010c);
2472 break;
2473 case VIDEOSIZE_320x240:
2474 ibmcam_veio(uvd, 0, 0x0000, 0x0100);
2475 ibmcam_veio(uvd, 0, 0x00c0, 0x0111);
2476 ibmcam_veio(uvd, 0, 0x00bc, 0x012c);
2477 ibmcam_veio(uvd, 0, 0x0080, 0x012b);
2478 ibmcam_veio(uvd, 0, 0x0000, 0x0108);
2479 ibmcam_veio(uvd, 0, 0x0001, 0x0133);
2480 ibmcam_veio(uvd, 0, 0x009b, 0x010f);
2481 ibmcam_veio(uvd, 0, 0x00bb, 0x010f);
2482 ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
2483 ibmcam_veio(uvd, 0, 0x0038, 0x012f);
2484 ibmcam_veio(uvd, 0, 0xd141, 0x0124);
2485 ibmcam_veio(uvd, 0, 0x0000, 0x0127);
2486 ibmcam_veio(uvd, 0, 0xfea8, 0x0124);
2487 ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
2488 ibmcam_veio(uvd, 0, 0x000a, 0x012f);
2489 ibmcam_veio(uvd, 0, 0xd141, 0x0124);
2490 ibmcam_veio(uvd, 0, 0x005c, 0x0127);
2491 ibmcam_veio(uvd, 0, 0xfea8, 0x0124);
2492 ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
2493 ibmcam_veio(uvd, 0, 0x0004, 0x012f);
2494 ibmcam_veio(uvd, 0, 0xd141, 0x0124);
2495 ibmcam_veio(uvd, 0, 0x0000, 0x0127);
2496 ibmcam_veio(uvd, 0, 0x00fb, 0x012e);
2497 ibmcam_veio(uvd, 0, 0x0000, 0x0130);
2498 ibmcam_veio(uvd, 0, 0x8a28, 0x0124);
2499 ibmcam_veio(uvd, 0, 0x00aa, 0x012f);
2500 ibmcam_veio(uvd, 0, 0xd055, 0x0124);
2501 ibmcam_veio(uvd, 0, 0x000c, 0x0127);
2502 ibmcam_veio(uvd, 0, 0x0009, 0x012e);
2503 ibmcam_veio(uvd, 0, 0xaa28, 0x0124);
2504 ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
2505 ibmcam_veio(uvd, 0, 0x0012, 0x012f);
2506 ibmcam_veio(uvd, 0, 0xd141, 0x0124);
2507 ibmcam_veio(uvd, 0, 0x0008, 0x0127);
2508 ibmcam_veio(uvd, 0, 0x00aa, 0x0130);
2509 ibmcam_veio(uvd, 0, 0x82a8, 0x0124);
2510 ibmcam_veio(uvd, 0, 0x002a, 0x012d);
2511 ibmcam_veio(uvd, 0, 0x0000, 0x012f);
2512 ibmcam_veio(uvd, 0, 0xd145, 0x0124);
2513 ibmcam_veio(uvd, 0, 0xfffa, 0x0124);
2514 ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
2515 ibmcam_veio(uvd, 0, 0x0034, 0x012f);
2516 ibmcam_veio(uvd, 0, 0xd141, 0x0124);
2517 ibmcam_veio(uvd, 0, 0x0000, 0x0127);
2518 ibmcam_veio(uvd, 0, 0xfea8, 0x0124);
2519 ibmcam_veio(uvd, 0, 0x0070, 0x0119);
2520 ibmcam_veio(uvd, 0, 0x00d2, 0x0107);
2521 ibmcam_veio(uvd, 0, 0x0003, 0x0106);
2522 ibmcam_veio(uvd, 0, 0x005e, 0x0107);
2523 ibmcam_veio(uvd, 0, 0x0003, 0x0106);
2524 ibmcam_veio(uvd, 0, 0x00d0, 0x0111);
2525 ibmcam_veio(uvd, 0, 0x0039, 0x010a);
2526 ibmcam_veio(uvd, 0, 0x0001, 0x0102);
2527 ibmcam_veio(uvd, 0, 0x0028, 0x0103);
2528 ibmcam_veio(uvd, 0, 0x0000, 0x0104);
2529 ibmcam_veio(uvd, 0, 0x001e, 0x0105);
2530 ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
2531 ibmcam_veio(uvd, 0, 0x0016, 0x012f);
2532 ibmcam_veio(uvd, 0, 0xd141, 0x0124);
2533 ibmcam_veio(uvd, 0, 0x000a, 0x0127);
2534 ibmcam_veio(uvd, 0, 0x00aa, 0x0130);
2535 ibmcam_veio(uvd, 0, 0x82a8, 0x0124);
2536 ibmcam_veio(uvd, 0, 0x0014, 0x012d);
2537 ibmcam_veio(uvd, 0, 0x0008, 0x012f);
2538 ibmcam_veio(uvd, 0, 0xd145, 0x0124);
2539 ibmcam_veio(uvd, 0, 0x00aa, 0x012e);
2540 ibmcam_veio(uvd, 0, 0x001a, 0x0130);
2541 ibmcam_veio(uvd, 0, 0x8a0a, 0x0124);
2542 ibmcam_veio(uvd, 0, 0x005a, 0x012d);
2543 ibmcam_veio(uvd, 0, 0x9545, 0x0124);
2544 ibmcam_veio(uvd, 0, 0x00aa, 0x0127);
2545 ibmcam_veio(uvd, 0, 0x0018, 0x012e);
2546 ibmcam_veio(uvd, 0, 0x0043, 0x0130);
2547 ibmcam_veio(uvd, 0, 0x8a28, 0x0124);
2548 ibmcam_veio(uvd, 0, 0x00aa, 0x012f);
2549 ibmcam_veio(uvd, 0, 0xd055, 0x0124);
2550 ibmcam_veio(uvd, 0, 0x001c, 0x0127);
2551 ibmcam_veio(uvd, 0, 0x00eb, 0x012e);
2552 ibmcam_veio(uvd, 0, 0xaa28, 0x0124);
2553 ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
2554 ibmcam_veio(uvd, 0, 0x0032, 0x012f);
2555 ibmcam_veio(uvd, 0, 0xd141, 0x0124);
2556 ibmcam_veio(uvd, 0, 0x0000, 0x0127);
2557 ibmcam_veio(uvd, 0, 0x00aa, 0x0130);
2558 ibmcam_veio(uvd, 0, 0x82a8, 0x0124);
2559 ibmcam_veio(uvd, 0, 0x0036, 0x012d);
2560 ibmcam_veio(uvd, 0, 0x0008, 0x012f);
2561 ibmcam_veio(uvd, 0, 0xd145, 0x0124);
2562 ibmcam_veio(uvd, 0, 0xfffa, 0x0124);
2563 ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
2564 ibmcam_veio(uvd, 0, 0x001e, 0x012f);
2565 ibmcam_veio(uvd, 0, 0xd141, 0x0124);
2566 ibmcam_veio(uvd, 0, 0x0017, 0x0127);
2567 ibmcam_veio(uvd, 0, 0x0013, 0x012e);
2568 ibmcam_veio(uvd, 0, 0x0031, 0x0130);
2569 ibmcam_veio(uvd, 0, 0x8a28, 0x0124);
2570 ibmcam_veio(uvd, 0, 0x0017, 0x012d);
2571 ibmcam_veio(uvd, 0, 0x0078, 0x012f);
2572 ibmcam_veio(uvd, 0, 0xd145, 0x0124);
2573 ibmcam_veio(uvd, 0, 0x0000, 0x0127);
2574 ibmcam_veio(uvd, 0, 0xfea8, 0x0124);
2575 ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
2576 ibmcam_veio(uvd, 0, 0x0038, 0x012f);
2577 ibmcam_veio(uvd, 0, 0xd141, 0x0124);
2578 ibmcam_veio(uvd, 0, 0x0004, 0x0127);
2579 ibmcam_veio(uvd, 0, 0xfea8, 0x0124);
2580 ibmcam_veio(uvd, 0, 0x00c0, 0x010c);
2581 break;
2582 case VIDEOSIZE_352x288:
2583 ibmcam_veio(uvd, 0, 0x0000, 0x0100);
2584 ibmcam_veio(uvd, 0, 0x00c0, 0x0111);
2585 ibmcam_veio(uvd, 0, 0x00bc, 0x012c);
2586 ibmcam_veio(uvd, 0, 0x0080, 0x012b);
2587 ibmcam_veio(uvd, 0, 0x0000, 0x0108);
2588 ibmcam_veio(uvd, 0, 0x0001, 0x0133);
2589 ibmcam_veio(uvd, 0, 0x009b, 0x010f);
2590 ibmcam_veio(uvd, 0, 0x00bb, 0x010f);
2591 ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
2592 ibmcam_veio(uvd, 0, 0x0038, 0x012f);
2593 ibmcam_veio(uvd, 0, 0xd141, 0x0124);
2594 ibmcam_veio(uvd, 0, 0x0000, 0x0127);
2595 ibmcam_veio(uvd, 0, 0xfea8, 0x0124);
2596 ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
2597 ibmcam_veio(uvd, 0, 0x000a, 0x012f);
2598 ibmcam_veio(uvd, 0, 0xd141, 0x0124);
2599 ibmcam_veio(uvd, 0, 0x005c, 0x0127);
2600 ibmcam_veio(uvd, 0, 0xfea8, 0x0124);
2601 ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
2602 ibmcam_veio(uvd, 0, 0x0004, 0x012f);
2603 ibmcam_veio(uvd, 0, 0xd141, 0x0124);
2604 ibmcam_veio(uvd, 0, 0x0000, 0x0127);
2605 ibmcam_veio(uvd, 0, 0x00fb, 0x012e);
2606 ibmcam_veio(uvd, 0, 0x0000, 0x0130);
2607 ibmcam_veio(uvd, 0, 0x8a28, 0x0124);
2608 ibmcam_veio(uvd, 0, 0x00aa, 0x012f);
2609 ibmcam_veio(uvd, 0, 0xd055, 0x0124);
2610 ibmcam_veio(uvd, 0, 0x000c, 0x0127);
2611 ibmcam_veio(uvd, 0, 0x0009, 0x012e);
2612 ibmcam_veio(uvd, 0, 0xaa28, 0x0124);
2613 ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
2614 ibmcam_veio(uvd, 0, 0x0012, 0x012f);
2615 ibmcam_veio(uvd, 0, 0xd141, 0x0124);
2616 ibmcam_veio(uvd, 0, 0x0008, 0x0127);
2617 ibmcam_veio(uvd, 0, 0x00aa, 0x0130);
2618 ibmcam_veio(uvd, 0, 0x82a8, 0x0124);
2619 ibmcam_veio(uvd, 0, 0x002a, 0x012d);
2620 ibmcam_veio(uvd, 0, 0x0000, 0x012f);
2621 ibmcam_veio(uvd, 0, 0xd145, 0x0124);
2622 ibmcam_veio(uvd, 0, 0xfffa, 0x0124);
2623 ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
2624 ibmcam_veio(uvd, 0, 0x0034, 0x012f);
2625 ibmcam_veio(uvd, 0, 0xd141, 0x0124);
2626 ibmcam_veio(uvd, 0, 0x0000, 0x0127);
2627 ibmcam_veio(uvd, 0, 0xfea8, 0x0124);
2628 ibmcam_veio(uvd, 0, 0x0070, 0x0119);
2629 ibmcam_veio(uvd, 0, 0x00f2, 0x0107);
2630 ibmcam_veio(uvd, 0, 0x0003, 0x0106);
2631 ibmcam_veio(uvd, 0, 0x008c, 0x0107);
2632 ibmcam_veio(uvd, 0, 0x0003, 0x0106);
2633 ibmcam_veio(uvd, 0, 0x00c0, 0x0111);
2634 ibmcam_veio(uvd, 0, 0x0039, 0x010a);
2635 ibmcam_veio(uvd, 0, 0x0001, 0x0102);
2636 ibmcam_veio(uvd, 0, 0x002c, 0x0103);
2637 ibmcam_veio(uvd, 0, 0x0000, 0x0104);
2638 ibmcam_veio(uvd, 0, 0x0024, 0x0105);
2639 ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
2640 ibmcam_veio(uvd, 0, 0x0016, 0x012f);
2641 ibmcam_veio(uvd, 0, 0xd141, 0x0124);
2642 ibmcam_veio(uvd, 0, 0x0006, 0x0127);
2643 ibmcam_veio(uvd, 0, 0x00aa, 0x0130);
2644 ibmcam_veio(uvd, 0, 0x82a8, 0x0124);
2645 ibmcam_veio(uvd, 0, 0x0014, 0x012d);
2646 ibmcam_veio(uvd, 0, 0x0002, 0x012f);
2647 ibmcam_veio(uvd, 0, 0xd145, 0x0124);
2648 ibmcam_veio(uvd, 0, 0x00aa, 0x012e);
2649 ibmcam_veio(uvd, 0, 0x001a, 0x0130);
2650 ibmcam_veio(uvd, 0, 0x8a0a, 0x0124);
2651 ibmcam_veio(uvd, 0, 0x005e, 0x012d);
2652 ibmcam_veio(uvd, 0, 0x9545, 0x0124);
2653 ibmcam_veio(uvd, 0, 0x00aa, 0x0127);
2654 ibmcam_veio(uvd, 0, 0x0018, 0x012e);
2655 ibmcam_veio(uvd, 0, 0x0049, 0x0130);
2656 ibmcam_veio(uvd, 0, 0x8a28, 0x0124);
2657 ibmcam_veio(uvd, 0, 0x00aa, 0x012f);
2658 ibmcam_veio(uvd, 0, 0xd055, 0x0124);
2659 ibmcam_veio(uvd, 0, 0x001c, 0x0127);
2660 ibmcam_veio(uvd, 0, 0x00cf, 0x012e);
2661 ibmcam_veio(uvd, 0, 0xaa28, 0x0124);
2662 ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
2663 ibmcam_veio(uvd, 0, 0x0032, 0x012f);
2664 ibmcam_veio(uvd, 0, 0xd141, 0x0124);
2665 ibmcam_veio(uvd, 0, 0x0000, 0x0127);
2666 ibmcam_veio(uvd, 0, 0x00aa, 0x0130);
2667 ibmcam_veio(uvd, 0, 0x82a8, 0x0124);
2668 ibmcam_veio(uvd, 0, 0x0036, 0x012d);
2669 ibmcam_veio(uvd, 0, 0x0008, 0x012f);
2670 ibmcam_veio(uvd, 0, 0xd145, 0x0124);
2671 ibmcam_veio(uvd, 0, 0xfffa, 0x0124);
2672 ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
2673 ibmcam_veio(uvd, 0, 0x001e, 0x012f);
2674 ibmcam_veio(uvd, 0, 0xd141, 0x0124);
2675 ibmcam_veio(uvd, 0, 0x0010, 0x0127);
2676 ibmcam_veio(uvd, 0, 0x0013, 0x012e);
2677 ibmcam_veio(uvd, 0, 0x0025, 0x0130);
2678 ibmcam_veio(uvd, 0, 0x8a28, 0x0124);
2679 ibmcam_veio(uvd, 0, 0x0010, 0x012d);
2680 ibmcam_veio(uvd, 0, 0x0048, 0x012f);
2681 ibmcam_veio(uvd, 0, 0xd145, 0x0124);
2682 ibmcam_veio(uvd, 0, 0x0000, 0x0127);
2683 ibmcam_veio(uvd, 0, 0xfea8, 0x0124);
2684 ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
2685 ibmcam_veio(uvd, 0, 0x0038, 0x012f);
2686 ibmcam_veio(uvd, 0, 0xd141, 0x0124);
2687 ibmcam_veio(uvd, 0, 0x0004, 0x0127);
2688 ibmcam_veio(uvd, 0, 0xfea8, 0x0124);
2689 ibmcam_veio(uvd, 0, 0x00c0, 0x010c);
2690 break;
2691 }
2692 usb_clear_halt(uvd->dev, usb_rcvisocpipe(uvd->dev, uvd->video_endp));
2693}
2694
2695static void ibmcam_model3_setup_after_video_if(struct uvd *uvd)
2696{
2697 int i;
2698 /*
2699 * 01.01.08 - Added for RCA video in support -LO
2700 * This struct is used to init the Model3 cam to use the RCA video in port
2701 * instead of the CCD sensor.
2702 */
2703 static const struct struct_initData initData[] = {
2704 {0, 0x0000, 0x010c},
2705 {0, 0x0006, 0x012c},
2706 {0, 0x0078, 0x012d},
2707 {0, 0x0046, 0x012f},
2708 {0, 0xd141, 0x0124},
2709 {0, 0x0000, 0x0127},
2710 {0, 0xfea8, 0x0124},
2711 {1, 0x0000, 0x0116},
2712 {0, 0x0064, 0x0116},
2713 {1, 0x0000, 0x0115},
2714 {0, 0x0003, 0x0115},
2715 {0, 0x0008, 0x0123},
2716 {0, 0x0000, 0x0117},
2717 {0, 0x0000, 0x0112},
2718 {0, 0x0080, 0x0100},
2719 {0, 0x0000, 0x0100},
2720 {1, 0x0000, 0x0116},
2721 {0, 0x0060, 0x0116},
2722 {0, 0x0002, 0x0112},
2723 {0, 0x0000, 0x0123},
2724 {0, 0x0001, 0x0117},
2725 {0, 0x0040, 0x0108},
2726 {0, 0x0019, 0x012c},
2727 {0, 0x0040, 0x0116},
2728 {0, 0x000a, 0x0115},
2729 {0, 0x000b, 0x0115},
2730 {0, 0x0078, 0x012d},
2731 {0, 0x0046, 0x012f},
2732 {0, 0xd141, 0x0124},
2733 {0, 0x0000, 0x0127},
2734 {0, 0xfea8, 0x0124},
2735 {0, 0x0064, 0x0116},
2736 {0, 0x0000, 0x0115},
2737 {0, 0x0001, 0x0115},
2738 {0, 0xffff, 0x0124},
2739 {0, 0xfff9, 0x0124},
2740 {0, 0x0086, 0x0127},
2741 {0, 0xfff8, 0x0124},
2742 {0, 0xfffd, 0x0124},
2743 {0, 0x00aa, 0x0127},
2744 {0, 0xfff8, 0x0124},
2745 {0, 0xfffd, 0x0124},
2746 {0, 0x0000, 0x0127},
2747 {0, 0xfff8, 0x0124},
2748 {0, 0xfffd, 0x0124},
2749 {0, 0xfffa, 0x0124},
2750 {0, 0xffff, 0x0124},
2751 {0, 0xfff9, 0x0124},
2752 {0, 0x0086, 0x0127},
2753 {0, 0xfff8, 0x0124},
2754 {0, 0xfffd, 0x0124},
2755 {0, 0x00f2, 0x0127},
2756 {0, 0xfff8, 0x0124},
2757 {0, 0xfffd, 0x0124},
2758 {0, 0x000f, 0x0127},
2759 {0, 0xfff8, 0x0124},
2760 {0, 0xfffd, 0x0124},
2761 {0, 0xfffa, 0x0124},
2762 {0, 0xffff, 0x0124},
2763 {0, 0xfff9, 0x0124},
2764 {0, 0x0086, 0x0127},
2765 {0, 0xfff8, 0x0124},
2766 {0, 0xfffd, 0x0124},
2767 {0, 0x00f8, 0x0127},
2768 {0, 0xfff8, 0x0124},
2769 {0, 0xfffd, 0x0124},
2770 {0, 0x00fc, 0x0127},
2771 {0, 0xfff8, 0x0124},
2772 {0, 0xfffd, 0x0124},
2773 {0, 0xfffa, 0x0124},
2774 {0, 0xffff, 0x0124},
2775 {0, 0xfff9, 0x0124},
2776 {0, 0x0086, 0x0127},
2777 {0, 0xfff8, 0x0124},
2778 {0, 0xfffd, 0x0124},
2779 {0, 0x00f9, 0x0127},
2780 {0, 0xfff8, 0x0124},
2781 {0, 0xfffd, 0x0124},
2782 {0, 0x003c, 0x0127},
2783 {0, 0xfff8, 0x0124},
2784 {0, 0xfffd, 0x0124},
2785 {0, 0xfffa, 0x0124},
2786 {0, 0xffff, 0x0124},
2787 {0, 0xfff9, 0x0124},
2788 {0, 0x0086, 0x0127},
2789 {0, 0xfff8, 0x0124},
2790 {0, 0xfffd, 0x0124},
2791 {0, 0x0027, 0x0127},
2792 {0, 0xfff8, 0x0124},
2793 {0, 0xfffd, 0x0124},
2794 {0, 0x0019, 0x0127},
2795 {0, 0xfff8, 0x0124},
2796 {0, 0xfffd, 0x0124},
2797 {0, 0xfffa, 0x0124},
2798 {0, 0xfff9, 0x0124},
2799 {0, 0x0086, 0x0127},
2800 {0, 0xfff8, 0x0124},
2801 {0, 0xfffd, 0x0124},
2802 {0, 0x0037, 0x0127},
2803 {0, 0xfff8, 0x0124},
2804 {0, 0xfffd, 0x0124},
2805 {0, 0x0000, 0x0127},
2806 {0, 0xfff8, 0x0124},
2807 {0, 0xfffd, 0x0124},
2808 {0, 0x0021, 0x0127},
2809 {0, 0xfff8, 0x0124},
2810 {0, 0xfffd, 0x0124},
2811 {0, 0xfffa, 0x0124},
2812 {0, 0xfff9, 0x0124},
2813 {0, 0x0086, 0x0127},
2814 {0, 0xfff8, 0x0124},
2815 {0, 0xfffd, 0x0124},
2816 {0, 0x0038, 0x0127},
2817 {0, 0xfff8, 0x0124},
2818 {0, 0xfffd, 0x0124},
2819 {0, 0x0006, 0x0127},
2820 {0, 0xfff8, 0x0124},
2821 {0, 0xfffd, 0x0124},
2822 {0, 0x0045, 0x0127},
2823 {0, 0xfff8, 0x0124},
2824 {0, 0xfffd, 0x0124},
2825 {0, 0xfffa, 0x0124},
2826 {0, 0xfff9, 0x0124},
2827 {0, 0x0086, 0x0127},
2828 {0, 0xfff8, 0x0124},
2829 {0, 0xfffd, 0x0124},
2830 {0, 0x0037, 0x0127},
2831 {0, 0xfff8, 0x0124},
2832 {0, 0xfffd, 0x0124},
2833 {0, 0x0001, 0x0127},
2834 {0, 0xfff8, 0x0124},
2835 {0, 0xfffd, 0x0124},
2836 {0, 0x002a, 0x0127},
2837 {0, 0xfff8, 0x0124},
2838 {0, 0xfffd, 0x0124},
2839 {0, 0xfffa, 0x0124},
2840 {0, 0xfff9, 0x0124},
2841 {0, 0x0086, 0x0127},
2842 {0, 0xfff8, 0x0124},
2843 {0, 0xfffd, 0x0124},
2844 {0, 0x0038, 0x0127},
2845 {0, 0xfff8, 0x0124},
2846 {0, 0xfffd, 0x0124},
2847 {0, 0x0000, 0x0127},
2848 {0, 0xfff8, 0x0124},
2849 {0, 0xfffd, 0x0124},
2850 {0, 0x000e, 0x0127},
2851 {0, 0xfff8, 0x0124},
2852 {0, 0xfffd, 0x0124},
2853 {0, 0xfffa, 0x0124},
2854 {0, 0xfff9, 0x0124},
2855 {0, 0x0086, 0x0127},
2856 {0, 0xfff8, 0x0124},
2857 {0, 0xfffd, 0x0124},
2858 {0, 0x0037, 0x0127},
2859 {0, 0xfff8, 0x0124},
2860 {0, 0xfffd, 0x0124},
2861 {0, 0x0001, 0x0127},
2862 {0, 0xfff8, 0x0124},
2863 {0, 0xfffd, 0x0124},
2864 {0, 0x002b, 0x0127},
2865 {0, 0xfff8, 0x0124},
2866 {0, 0xfffd, 0x0124},
2867 {0, 0xfffa, 0x0124},
2868 {0, 0xfff9, 0x0124},
2869 {0, 0x0086, 0x0127},
2870 {0, 0xfff8, 0x0124},
2871 {0, 0xfffd, 0x0124},
2872 {0, 0x0038, 0x0127},
2873 {0, 0xfff8, 0x0124},
2874 {0, 0xfffd, 0x0124},
2875 {0, 0x0001, 0x0127},
2876 {0, 0xfff8, 0x0124},
2877 {0, 0xfffd, 0x0124},
2878 {0, 0x00f4, 0x0127},
2879 {0, 0xfff8, 0x0124},
2880 {0, 0xfffd, 0x0124},
2881 {0, 0xfffa, 0x0124},
2882 {0, 0xfff9, 0x0124},
2883 {0, 0x0086, 0x0127},
2884 {0, 0xfff8, 0x0124},
2885 {0, 0xfffd, 0x0124},
2886 {0, 0x0037, 0x0127},
2887 {0, 0xfff8, 0x0124},
2888 {0, 0xfffd, 0x0124},
2889 {0, 0x0001, 0x0127},
2890 {0, 0xfff8, 0x0124},
2891 {0, 0xfffd, 0x0124},
2892 {0, 0x002c, 0x0127},
2893 {0, 0xfff8, 0x0124},
2894 {0, 0xfffd, 0x0124},
2895 {0, 0xfffa, 0x0124},
2896 {0, 0xfff9, 0x0124},
2897 {0, 0x0086, 0x0127},
2898 {0, 0xfff8, 0x0124},
2899 {0, 0xfffd, 0x0124},
2900 {0, 0x0038, 0x0127},
2901 {0, 0xfff8, 0x0124},
2902 {0, 0xfffd, 0x0124},
2903 {0, 0x0001, 0x0127},
2904 {0, 0xfff8, 0x0124},
2905 {0, 0xfffd, 0x0124},
2906 {0, 0x0004, 0x0127},
2907 {0, 0xfff8, 0x0124},
2908 {0, 0xfffd, 0x0124},
2909 {0, 0xfffa, 0x0124},
2910 {0, 0xfff9, 0x0124},
2911 {0, 0x0086, 0x0127},
2912 {0, 0xfff8, 0x0124},
2913 {0, 0xfffd, 0x0124},
2914 {0, 0x0037, 0x0127},
2915 {0, 0xfff8, 0x0124},
2916 {0, 0xfffd, 0x0124},
2917 {0, 0x0001, 0x0127},
2918 {0, 0xfff8, 0x0124},
2919 {0, 0xfffd, 0x0124},
2920 {0, 0x002d, 0x0127},
2921 {0, 0xfff8, 0x0124},
2922 {0, 0xfffd, 0x0124},
2923 {0, 0xfffa, 0x0124},
2924 {0, 0xfff9, 0x0124},
2925 {0, 0x0086, 0x0127},
2926 {0, 0xfff8, 0x0124},
2927 {0, 0xfffd, 0x0124},
2928 {0, 0x0038, 0x0127},
2929 {0, 0xfff8, 0x0124},
2930 {0, 0xfffd, 0x0124},
2931 {0, 0x0000, 0x0127},
2932 {0, 0xfff8, 0x0124},
2933 {0, 0xfffd, 0x0124},
2934 {0, 0x0014, 0x0127},
2935 {0, 0xfff8, 0x0124},
2936 {0, 0xfffd, 0x0124},
2937 {0, 0xfffa, 0x0124},
2938 {0, 0xfff9, 0x0124},
2939 {0, 0x0086, 0x0127},
2940 {0, 0xfff8, 0x0124},
2941 {0, 0xfffd, 0x0124},
2942 {0, 0x0037, 0x0127},
2943 {0, 0xfff8, 0x0124},
2944 {0, 0xfffd, 0x0124},
2945 {0, 0x0001, 0x0127},
2946 {0, 0xfff8, 0x0124},
2947 {0, 0xfffd, 0x0124},
2948 {0, 0x002e, 0x0127},
2949 {0, 0xfff8, 0x0124},
2950 {0, 0xfffd, 0x0124},
2951 {0, 0xfffa, 0x0124},
2952 {0, 0xfff9, 0x0124},
2953 {0, 0x0086, 0x0127},
2954 {0, 0xfff8, 0x0124},
2955 {0, 0xfffd, 0x0124},
2956 {0, 0x0038, 0x0127},
2957 {0, 0xfff8, 0x0124},
2958 {0, 0xfffd, 0x0124},
2959 {0, 0x0003, 0x0127},
2960 {0, 0xfff8, 0x0124},
2961 {0, 0xfffd, 0x0124},
2962 {0, 0x0000, 0x0127},
2963 {0, 0xfff8, 0x0124},
2964 {0, 0xfffd, 0x0124},
2965 {0, 0xfffa, 0x0124},
2966 {0, 0xfff9, 0x0124},
2967 {0, 0x0086, 0x0127},
2968 {0, 0xfff8, 0x0124},
2969 {0, 0xfffd, 0x0124},
2970 {0, 0x0037, 0x0127},
2971 {0, 0xfff8, 0x0124},
2972 {0, 0xfffd, 0x0124},
2973 {0, 0x0001, 0x0127},
2974 {0, 0xfff8, 0x0124},
2975 {0, 0xfffd, 0x0124},
2976 {0, 0x002f, 0x0127},
2977 {0, 0xfff8, 0x0124},
2978 {0, 0xfffd, 0x0124},
2979 {0, 0xfffa, 0x0124},
2980 {0, 0xfff9, 0x0124},
2981 {0, 0x0086, 0x0127},
2982 {0, 0xfff8, 0x0124},
2983 {0, 0xfffd, 0x0124},
2984 {0, 0x0038, 0x0127},
2985 {0, 0xfff8, 0x0124},
2986 {0, 0xfffd, 0x0124},
2987 {0, 0x0003, 0x0127},
2988 {0, 0xfff8, 0x0124},
2989 {0, 0xfffd, 0x0124},
2990 {0, 0x0014, 0x0127},
2991 {0, 0xfff8, 0x0124},
2992 {0, 0xfffd, 0x0124},
2993 {0, 0xfffa, 0x0124},
2994 {0, 0xfff9, 0x0124},
2995 {0, 0x0086, 0x0127},
2996 {0, 0xfff8, 0x0124},
2997 {0, 0xfffd, 0x0124},
2998 {0, 0x0037, 0x0127},
2999 {0, 0xfff8, 0x0124},
3000 {0, 0xfffd, 0x0124},
3001 {0, 0x0001, 0x0127},
3002 {0, 0xfff8, 0x0124},
3003 {0, 0xfffd, 0x0124},
3004 {0, 0x0040, 0x0127},
3005 {0, 0xfff8, 0x0124},
3006 {0, 0xfffd, 0x0124},
3007 {0, 0xfffa, 0x0124},
3008 {0, 0xfff9, 0x0124},
3009 {0, 0x0086, 0x0127},
3010 {0, 0xfff8, 0x0124},
3011 {0, 0xfffd, 0x0124},
3012 {0, 0x0038, 0x0127},
3013 {0, 0xfff8, 0x0124},
3014 {0, 0xfffd, 0x0124},
3015 {0, 0x0000, 0x0127},
3016 {0, 0xfff8, 0x0124},
3017 {0, 0xfffd, 0x0124},
3018 {0, 0x0040, 0x0127},
3019 {0, 0xfff8, 0x0124},
3020 {0, 0xfffd, 0x0124},
3021 {0, 0xfffa, 0x0124},
3022 {0, 0xfff9, 0x0124},
3023 {0, 0x0086, 0x0127},
3024 {0, 0xfff8, 0x0124},
3025 {0, 0xfffd, 0x0124},
3026 {0, 0x0037, 0x0127},
3027 {0, 0xfff8, 0x0124},
3028 {0, 0xfffd, 0x0124},
3029 {0, 0x0001, 0x0127},
3030 {0, 0xfff8, 0x0124},
3031 {0, 0xfffd, 0x0124},
3032 {0, 0x0053, 0x0127},
3033 {0, 0xfff8, 0x0124},
3034 {0, 0xfffd, 0x0124},
3035 {0, 0xfffa, 0x0124},
3036 {0, 0xfff9, 0x0124},
3037 {0, 0x0086, 0x0127},
3038 {0, 0xfff8, 0x0124},
3039 {0, 0xfffd, 0x0124},
3040 {0, 0x0038, 0x0127},
3041 {0, 0xfff8, 0x0124},
3042 {0, 0xfffd, 0x0124},
3043 {0, 0x0000, 0x0127},
3044 {0, 0xfff8, 0x0124},
3045 {0, 0xfffd, 0x0124},
3046 {0, 0x0038, 0x0127},
3047 {0, 0xfff8, 0x0124},
3048 {0, 0xfffd, 0x0124},
3049 {0, 0xfffa, 0x0124},
3050 {0, 0x0000, 0x0101},
3051 {0, 0x00a0, 0x0103},
3052 {0, 0x0078, 0x0105},
3053 {0, 0x0000, 0x010a},
3054 {0, 0x0024, 0x010b},
3055 {0, 0x0028, 0x0119},
3056 {0, 0x0088, 0x011b},
3057 {0, 0x0002, 0x011d},
3058 {0, 0x0003, 0x011e},
3059 {0, 0x0000, 0x0129},
3060 {0, 0x00fc, 0x012b},
3061 {0, 0x0008, 0x0102},
3062 {0, 0x0000, 0x0104},
3063 {0, 0x0008, 0x011a},
3064 {0, 0x0028, 0x011c},
3065 {0, 0x0021, 0x012a},
3066 {0, 0x0000, 0x0118},
3067 {0, 0x0000, 0x0132},
3068 {0, 0x0000, 0x0109},
3069 {0, 0xfff9, 0x0124},
3070 {0, 0x0086, 0x0127},
3071 {0, 0xfff8, 0x0124},
3072 {0, 0xfffd, 0x0124},
3073 {0, 0x0037, 0x0127},
3074 {0, 0xfff8, 0x0124},
3075 {0, 0xfffd, 0x0124},
3076 {0, 0x0001, 0x0127},
3077 {0, 0xfff8, 0x0124},
3078 {0, 0xfffd, 0x0124},
3079 {0, 0x0031, 0x0127},
3080 {0, 0xfff8, 0x0124},
3081 {0, 0xfffd, 0x0124},
3082 {0, 0xfffa, 0x0124},
3083 {0, 0xfff9, 0x0124},
3084 {0, 0x0086, 0x0127},
3085 {0, 0xfff8, 0x0124},
3086 {0, 0xfffd, 0x0124},
3087 {0, 0x0038, 0x0127},
3088 {0, 0xfff8, 0x0124},
3089 {0, 0xfffd, 0x0124},
3090 {0, 0x0000, 0x0127},
3091 {0, 0xfff8, 0x0124},
3092 {0, 0xfffd, 0x0124},
3093 {0, 0x0000, 0x0127},
3094 {0, 0xfff8, 0x0124},
3095 {0, 0xfffd, 0x0124},
3096 {0, 0xfffa, 0x0124},
3097 {0, 0xfff9, 0x0124},
3098 {0, 0x0086, 0x0127},
3099 {0, 0xfff8, 0x0124},
3100 {0, 0xfffd, 0x0124},
3101 {0, 0x0037, 0x0127},
3102 {0, 0xfff8, 0x0124},
3103 {0, 0xfffd, 0x0124},
3104 {0, 0x0001, 0x0127},
3105 {0, 0xfff8, 0x0124},
3106 {0, 0xfffd, 0x0124},
3107 {0, 0x0040, 0x0127},
3108 {0, 0xfff8, 0x0124},
3109 {0, 0xfffd, 0x0124},
3110 {0, 0xfffa, 0x0124},
3111 {0, 0xfff9, 0x0124},
3112 {0, 0x0086, 0x0127},
3113 {0, 0xfff8, 0x0124},
3114 {0, 0xfffd, 0x0124},
3115 {0, 0x0038, 0x0127},
3116 {0, 0xfff8, 0x0124},
3117 {0, 0xfffd, 0x0124},
3118 {0, 0x0000, 0x0127},
3119 {0, 0xfff8, 0x0124},
3120 {0, 0xfffd, 0x0124},
3121 {0, 0x0040, 0x0127},
3122 {0, 0xfff8, 0x0124},
3123 {0, 0xfffd, 0x0124},
3124 {0, 0xfffa, 0x0124},
3125 {0, 0xfff9, 0x0124},
3126 {0, 0x0086, 0x0127},
3127 {0, 0xfff8, 0x0124},
3128 {0, 0xfffd, 0x0124},
3129 {0, 0x0037, 0x0127},
3130 {0, 0xfff8, 0x0124},
3131 {0, 0xfffd, 0x0124},
3132 {0, 0x0000, 0x0127},
3133 {0, 0xfff8, 0x0124},
3134 {0, 0xfffd, 0x0124},
3135 {0, 0x00dc, 0x0127},
3136 {0, 0xfff8, 0x0124},
3137 {0, 0xfffd, 0x0124},
3138 {0, 0xfffa, 0x0124},
3139 {0, 0xfff9, 0x0124},
3140 {0, 0x0086, 0x0127},
3141 {0, 0xfff8, 0x0124},
3142 {0, 0xfffd, 0x0124},
3143 {0, 0x0038, 0x0127},
3144 {0, 0xfff8, 0x0124},
3145 {0, 0xfffd, 0x0124},
3146 {0, 0x0000, 0x0127},
3147 {0, 0xfff8, 0x0124},
3148 {0, 0xfffd, 0x0124},
3149 {0, 0x0000, 0x0127},
3150 {0, 0xfff8, 0x0124},
3151 {0, 0xfffd, 0x0124},
3152 {0, 0xfffa, 0x0124},
3153 {0, 0xfff9, 0x0124},
3154 {0, 0x0086, 0x0127},
3155 {0, 0xfff8, 0x0124},
3156 {0, 0xfffd, 0x0124},
3157 {0, 0x0037, 0x0127},
3158 {0, 0xfff8, 0x0124},
3159 {0, 0xfffd, 0x0124},
3160 {0, 0x0001, 0x0127},
3161 {0, 0xfff8, 0x0124},
3162 {0, 0xfffd, 0x0124},
3163 {0, 0x0032, 0x0127},
3164 {0, 0xfff8, 0x0124},
3165 {0, 0xfffd, 0x0124},
3166 {0, 0xfffa, 0x0124},
3167 {0, 0xfff9, 0x0124},
3168 {0, 0x0086, 0x0127},
3169 {0, 0xfff8, 0x0124},
3170 {0, 0xfffd, 0x0124},
3171 {0, 0x0038, 0x0127},
3172 {0, 0xfff8, 0x0124},
3173 {0, 0xfffd, 0x0124},
3174 {0, 0x0001, 0x0127},
3175 {0, 0xfff8, 0x0124},
3176 {0, 0xfffd, 0x0124},
3177 {0, 0x0020, 0x0127},
3178 {0, 0xfff8, 0x0124},
3179 {0, 0xfffd, 0x0124},
3180 {0, 0xfffa, 0x0124},
3181 {0, 0xfff9, 0x0124},
3182 {0, 0x0086, 0x0127},
3183 {0, 0xfff8, 0x0124},
3184 {0, 0xfffd, 0x0124},
3185 {0, 0x0037, 0x0127},
3186 {0, 0xfff8, 0x0124},
3187 {0, 0xfffd, 0x0124},
3188 {0, 0x0001, 0x0127},
3189 {0, 0xfff8, 0x0124},
3190 {0, 0xfffd, 0x0124},
3191 {0, 0x0040, 0x0127},
3192 {0, 0xfff8, 0x0124},
3193 {0, 0xfffd, 0x0124},
3194 {0, 0xfffa, 0x0124},
3195 {0, 0xfff9, 0x0124},
3196 {0, 0x0086, 0x0127},
3197 {0, 0xfff8, 0x0124},
3198 {0, 0xfffd, 0x0124},
3199 {0, 0x0038, 0x0127},
3200 {0, 0xfff8, 0x0124},
3201 {0, 0xfffd, 0x0124},
3202 {0, 0x0000, 0x0127},
3203 {0, 0xfff8, 0x0124},
3204 {0, 0xfffd, 0x0124},
3205 {0, 0x0040, 0x0127},
3206 {0, 0xfff8, 0x0124},
3207 {0, 0xfffd, 0x0124},
3208 {0, 0xfffa, 0x0124},
3209 {0, 0xfff9, 0x0124},
3210 {0, 0x0086, 0x0127},
3211 {0, 0xfff8, 0x0124},
3212 {0, 0xfffd, 0x0124},
3213 {0, 0x0037, 0x0127},
3214 {0, 0xfff8, 0x0124},
3215 {0, 0xfffd, 0x0124},
3216 {0, 0x0000, 0x0127},
3217 {0, 0xfff8, 0x0124},
3218 {0, 0xfffd, 0x0124},
3219 {0, 0x0030, 0x0127},
3220 {0, 0xfff8, 0x0124},
3221 {0, 0xfffd, 0x0124},
3222 {0, 0xfffa, 0x0124},
3223 {0, 0xfff9, 0x0124},
3224 {0, 0x0086, 0x0127},
3225 {0, 0xfff8, 0x0124},
3226 {0, 0xfffd, 0x0124},
3227 {0, 0x0038, 0x0127},
3228 {0, 0xfff8, 0x0124},
3229 {0, 0xfffd, 0x0124},
3230 {0, 0x0008, 0x0127},
3231 {0, 0xfff8, 0x0124},
3232 {0, 0xfffd, 0x0124},
3233 {0, 0x0000, 0x0127},
3234 {0, 0xfff8, 0x0124},
3235 {0, 0xfffd, 0x0124},
3236 {0, 0xfffa, 0x0124},
3237 {0, 0x0003, 0x0106},
3238 {0, 0x0062, 0x0107},
3239 {0, 0x0003, 0x0111},
3240 };
3241#define NUM_INIT_DATA
3242
3243 unsigned short compression = 0; /* 0=none, 7=best frame rate */
3244 int f_rate; /* 0=Fastest 7=slowest */
3245
3246 if (IBMCAM_T(uvd)->initialized)
3247 return;
3248
3249 /* Internal frame rate is controlled by f_rate value */
3250 f_rate = 7 - framerate;
3251 RESTRICT_TO_RANGE(f_rate, 0, 7);
3252
3253 ibmcam_veio(uvd, 0, 0x0000, 0x0100);
3254 ibmcam_veio(uvd, 1, 0x0000, 0x0116);
3255 ibmcam_veio(uvd, 0, 0x0060, 0x0116);
3256 ibmcam_veio(uvd, 0, 0x0002, 0x0112);
3257 ibmcam_veio(uvd, 0, 0x0000, 0x0123);
3258 ibmcam_veio(uvd, 0, 0x0001, 0x0117);
3259 ibmcam_veio(uvd, 0, 0x0040, 0x0108);
3260 ibmcam_veio(uvd, 0, 0x0019, 0x012c);
3261 ibmcam_veio(uvd, 0, 0x0060, 0x0116);
3262 ibmcam_veio(uvd, 0, 0x0002, 0x0115);
3263 ibmcam_veio(uvd, 0, 0x0003, 0x0115);
3264 ibmcam_veio(uvd, 1, 0x0000, 0x0115);
3265 ibmcam_veio(uvd, 0, 0x000b, 0x0115);
3266 ibmcam_model3_Packet1(uvd, 0x000a, 0x0040);
3267 ibmcam_model3_Packet1(uvd, 0x000b, 0x00f6);
3268 ibmcam_model3_Packet1(uvd, 0x000c, 0x0002);
3269 ibmcam_model3_Packet1(uvd, 0x000d, 0x0020);
3270 ibmcam_model3_Packet1(uvd, 0x000e, 0x0033);
3271 ibmcam_model3_Packet1(uvd, 0x000f, 0x0007);
3272 ibmcam_model3_Packet1(uvd, 0x0010, 0x0000);
3273 ibmcam_model3_Packet1(uvd, 0x0011, 0x0070);
3274 ibmcam_model3_Packet1(uvd, 0x0012, 0x0030);
3275 ibmcam_model3_Packet1(uvd, 0x0013, 0x0000);
3276 ibmcam_model3_Packet1(uvd, 0x0014, 0x0001);
3277 ibmcam_model3_Packet1(uvd, 0x0015, 0x0001);
3278 ibmcam_model3_Packet1(uvd, 0x0016, 0x0001);
3279 ibmcam_model3_Packet1(uvd, 0x0017, 0x0001);
3280 ibmcam_model3_Packet1(uvd, 0x0018, 0x0000);
3281 ibmcam_model3_Packet1(uvd, 0x001e, 0x00c3);
3282 ibmcam_model3_Packet1(uvd, 0x0020, 0x0000);
3283 ibmcam_model3_Packet1(uvd, 0x0028, 0x0010);
3284 ibmcam_model3_Packet1(uvd, 0x0029, 0x0054);
3285 ibmcam_model3_Packet1(uvd, 0x002a, 0x0013);
3286 ibmcam_model3_Packet1(uvd, 0x002b, 0x0007);
3287 ibmcam_model3_Packet1(uvd, 0x002d, 0x0028);
3288 ibmcam_model3_Packet1(uvd, 0x002e, 0x0000);
3289 ibmcam_model3_Packet1(uvd, 0x0031, 0x0000);
3290 ibmcam_model3_Packet1(uvd, 0x0032, 0x0000);
3291 ibmcam_model3_Packet1(uvd, 0x0033, 0x0000);
3292 ibmcam_model3_Packet1(uvd, 0x0034, 0x0000);
3293 ibmcam_model3_Packet1(uvd, 0x0035, 0x0038);
3294 ibmcam_model3_Packet1(uvd, 0x003a, 0x0001);
3295 ibmcam_model3_Packet1(uvd, 0x003c, 0x001e);
3296 ibmcam_model3_Packet1(uvd, 0x003f, 0x000a);
3297 ibmcam_model3_Packet1(uvd, 0x0041, 0x0000);
3298 ibmcam_model3_Packet1(uvd, 0x0046, 0x003f);
3299 ibmcam_model3_Packet1(uvd, 0x0047, 0x0000);
3300 ibmcam_model3_Packet1(uvd, 0x0050, 0x0005);
3301 ibmcam_model3_Packet1(uvd, 0x0052, 0x001a);
3302 ibmcam_model3_Packet1(uvd, 0x0053, 0x0003);
3303 ibmcam_model3_Packet1(uvd, 0x005a, 0x006b);
3304 ibmcam_model3_Packet1(uvd, 0x005d, 0x001e);
3305 ibmcam_model3_Packet1(uvd, 0x005e, 0x0030);
3306 ibmcam_model3_Packet1(uvd, 0x005f, 0x0041);
3307 ibmcam_model3_Packet1(uvd, 0x0064, 0x0008);
3308 ibmcam_model3_Packet1(uvd, 0x0065, 0x0015);
3309 ibmcam_model3_Packet1(uvd, 0x0068, 0x000f);
3310 ibmcam_model3_Packet1(uvd, 0x0079, 0x0000);
3311 ibmcam_model3_Packet1(uvd, 0x007a, 0x0000);
3312 ibmcam_model3_Packet1(uvd, 0x007c, 0x003f);
3313 ibmcam_model3_Packet1(uvd, 0x0082, 0x000f);
3314 ibmcam_model3_Packet1(uvd, 0x0085, 0x0000);
3315 ibmcam_model3_Packet1(uvd, 0x0099, 0x0000);
3316 ibmcam_model3_Packet1(uvd, 0x009b, 0x0023);
3317 ibmcam_model3_Packet1(uvd, 0x009c, 0x0022);
3318 ibmcam_model3_Packet1(uvd, 0x009d, 0x0096);
3319 ibmcam_model3_Packet1(uvd, 0x009e, 0x0096);
3320 ibmcam_model3_Packet1(uvd, 0x009f, 0x000a);
3321
3322 switch (uvd->videosize) {
3323 case VIDEOSIZE_160x120:
3324 ibmcam_veio(uvd, 0, 0x0000, 0x0101); /* Same on 176x144, 320x240 */
3325 ibmcam_veio(uvd, 0, 0x00a0, 0x0103); /* Same on 176x144, 320x240 */
3326 ibmcam_veio(uvd, 0, 0x0078, 0x0105); /* Same on 176x144, 320x240 */
3327 ibmcam_veio(uvd, 0, 0x0000, 0x010a); /* Same */
3328 ibmcam_veio(uvd, 0, 0x0024, 0x010b); /* Differs everywhere */
3329 ibmcam_veio(uvd, 0, 0x00a9, 0x0119);
3330 ibmcam_veio(uvd, 0, 0x0016, 0x011b);
3331 ibmcam_veio(uvd, 0, 0x0002, 0x011d); /* Same on 176x144, 320x240 */
3332 ibmcam_veio(uvd, 0, 0x0003, 0x011e); /* Same on 176x144, 640x480 */
3333 ibmcam_veio(uvd, 0, 0x0000, 0x0129); /* Same */
3334 ibmcam_veio(uvd, 0, 0x00fc, 0x012b); /* Same */
3335 ibmcam_veio(uvd, 0, 0x0018, 0x0102);
3336 ibmcam_veio(uvd, 0, 0x0004, 0x0104);
3337 ibmcam_veio(uvd, 0, 0x0004, 0x011a);
3338 ibmcam_veio(uvd, 0, 0x0028, 0x011c);
3339 ibmcam_veio(uvd, 0, 0x0022, 0x012a); /* Same */
3340 ibmcam_veio(uvd, 0, 0x0000, 0x0118);
3341 ibmcam_veio(uvd, 0, 0x0000, 0x0132);
3342 ibmcam_model3_Packet1(uvd, 0x0021, 0x0001); /* Same */
3343 ibmcam_veio(uvd, 0, compression, 0x0109);
3344 break;
3345 case VIDEOSIZE_320x240:
3346 ibmcam_veio(uvd, 0, 0x0000, 0x0101); /* Same on 176x144, 320x240 */
3347 ibmcam_veio(uvd, 0, 0x00a0, 0x0103); /* Same on 176x144, 320x240 */
3348 ibmcam_veio(uvd, 0, 0x0078, 0x0105); /* Same on 176x144, 320x240 */
3349 ibmcam_veio(uvd, 0, 0x0000, 0x010a); /* Same */
3350 ibmcam_veio(uvd, 0, 0x0028, 0x010b); /* Differs everywhere */
3351 ibmcam_veio(uvd, 0, 0x0002, 0x011d); /* Same */
3352 ibmcam_veio(uvd, 0, 0x0000, 0x011e);
3353 ibmcam_veio(uvd, 0, 0x0000, 0x0129); /* Same */
3354 ibmcam_veio(uvd, 0, 0x00fc, 0x012b); /* Same */
3355 /* 4 commands from 160x120 skipped */
3356 ibmcam_veio(uvd, 0, 0x0022, 0x012a); /* Same */
3357 ibmcam_model3_Packet1(uvd, 0x0021, 0x0001); /* Same */
3358 ibmcam_veio(uvd, 0, compression, 0x0109);
3359 ibmcam_veio(uvd, 0, 0x00d9, 0x0119);
3360 ibmcam_veio(uvd, 0, 0x0006, 0x011b);
3361 ibmcam_veio(uvd, 0, 0x0021, 0x0102); /* Same on 320x240, 640x480 */
3362 ibmcam_veio(uvd, 0, 0x0010, 0x0104);
3363 ibmcam_veio(uvd, 0, 0x0004, 0x011a);
3364 ibmcam_veio(uvd, 0, 0x003f, 0x011c);
3365 ibmcam_veio(uvd, 0, 0x001c, 0x0118);
3366 ibmcam_veio(uvd, 0, 0x0000, 0x0132);
3367 break;
3368 case VIDEOSIZE_640x480:
3369 ibmcam_veio(uvd, 0, 0x00f0, 0x0105);
3370 ibmcam_veio(uvd, 0, 0x0000, 0x010a); /* Same */
3371 ibmcam_veio(uvd, 0, 0x0038, 0x010b); /* Differs everywhere */
3372 ibmcam_veio(uvd, 0, 0x00d9, 0x0119); /* Same on 320x240, 640x480 */
3373 ibmcam_veio(uvd, 0, 0x0006, 0x011b); /* Same on 320x240, 640x480 */
3374 ibmcam_veio(uvd, 0, 0x0004, 0x011d); /* NC */
3375 ibmcam_veio(uvd, 0, 0x0003, 0x011e); /* Same on 176x144, 640x480 */
3376 ibmcam_veio(uvd, 0, 0x0000, 0x0129); /* Same */
3377 ibmcam_veio(uvd, 0, 0x00fc, 0x012b); /* Same */
3378 ibmcam_veio(uvd, 0, 0x0021, 0x0102); /* Same on 320x240, 640x480 */
3379 ibmcam_veio(uvd, 0, 0x0016, 0x0104); /* NC */
3380 ibmcam_veio(uvd, 0, 0x0004, 0x011a); /* Same on 320x240, 640x480 */
3381 ibmcam_veio(uvd, 0, 0x003f, 0x011c); /* Same on 320x240, 640x480 */
3382 ibmcam_veio(uvd, 0, 0x0022, 0x012a); /* Same */
3383 ibmcam_veio(uvd, 0, 0x001c, 0x0118); /* Same on 320x240, 640x480 */
3384 ibmcam_model3_Packet1(uvd, 0x0021, 0x0001); /* Same */
3385 ibmcam_veio(uvd, 0, compression, 0x0109);
3386 ibmcam_veio(uvd, 0, 0x0040, 0x0101);
3387 ibmcam_veio(uvd, 0, 0x0040, 0x0103);
3388 ibmcam_veio(uvd, 0, 0x0000, 0x0132); /* Same on 320x240, 640x480 */
3389 break;
3390 }
3391 ibmcam_model3_Packet1(uvd, 0x007e, 0x000e); /* Hue */
3392 ibmcam_model3_Packet1(uvd, 0x0036, 0x0011); /* Brightness */
3393 ibmcam_model3_Packet1(uvd, 0x0060, 0x0002); /* Sharpness */
3394 ibmcam_model3_Packet1(uvd, 0x0061, 0x0004); /* Sharpness */
3395 ibmcam_model3_Packet1(uvd, 0x0062, 0x0005); /* Sharpness */
3396 ibmcam_model3_Packet1(uvd, 0x0063, 0x0014); /* Sharpness */
3397 ibmcam_model3_Packet1(uvd, 0x0096, 0x00a0); /* Red gain */
3398 ibmcam_model3_Packet1(uvd, 0x0097, 0x0096); /* Blue gain */
3399 ibmcam_model3_Packet1(uvd, 0x0067, 0x0001); /* Contrast */
3400 ibmcam_model3_Packet1(uvd, 0x005b, 0x000c); /* Contrast */
3401 ibmcam_model3_Packet1(uvd, 0x005c, 0x0016); /* Contrast */
3402 ibmcam_model3_Packet1(uvd, 0x0098, 0x000b);
3403 ibmcam_model3_Packet1(uvd, 0x002c, 0x0003); /* Was 1, broke 640x480 */
3404 ibmcam_model3_Packet1(uvd, 0x002f, 0x002a);
3405 ibmcam_model3_Packet1(uvd, 0x0030, 0x0029);
3406 ibmcam_model3_Packet1(uvd, 0x0037, 0x0002);
3407 ibmcam_model3_Packet1(uvd, 0x0038, 0x0059);
3408 ibmcam_model3_Packet1(uvd, 0x003d, 0x002e);
3409 ibmcam_model3_Packet1(uvd, 0x003e, 0x0028);
3410 ibmcam_model3_Packet1(uvd, 0x0078, 0x0005);
3411 ibmcam_model3_Packet1(uvd, 0x007b, 0x0011);
3412 ibmcam_model3_Packet1(uvd, 0x007d, 0x004b);
3413 ibmcam_model3_Packet1(uvd, 0x007f, 0x0022);
3414 ibmcam_model3_Packet1(uvd, 0x0080, 0x000c);
3415 ibmcam_model3_Packet1(uvd, 0x0081, 0x000b);
3416 ibmcam_model3_Packet1(uvd, 0x0083, 0x00fd);
3417 ibmcam_model3_Packet1(uvd, 0x0086, 0x000b);
3418 ibmcam_model3_Packet1(uvd, 0x0087, 0x000b);
3419 ibmcam_model3_Packet1(uvd, 0x007e, 0x000e);
3420 ibmcam_model3_Packet1(uvd, 0x0096, 0x00a0); /* Red gain */
3421 ibmcam_model3_Packet1(uvd, 0x0097, 0x0096); /* Blue gain */
3422 ibmcam_model3_Packet1(uvd, 0x0098, 0x000b);
3423
3424 switch (uvd->videosize) {
3425 case VIDEOSIZE_160x120:
3426 ibmcam_veio(uvd, 0, 0x0002, 0x0106);
3427 ibmcam_veio(uvd, 0, 0x0008, 0x0107);
3428 ibmcam_veio(uvd, 0, f_rate, 0x0111); /* Frame rate */
3429 ibmcam_model3_Packet1(uvd, 0x001f, 0x0000); /* Same */
3430 ibmcam_model3_Packet1(uvd, 0x0039, 0x001f); /* Same */
3431 ibmcam_model3_Packet1(uvd, 0x003b, 0x003c); /* Same */
3432 ibmcam_model3_Packet1(uvd, 0x0040, 0x000a);
3433 ibmcam_model3_Packet1(uvd, 0x0051, 0x000a);
3434 break;
3435 case VIDEOSIZE_320x240:
3436 ibmcam_veio(uvd, 0, 0x0003, 0x0106);
3437 ibmcam_veio(uvd, 0, 0x0062, 0x0107);
3438 ibmcam_veio(uvd, 0, f_rate, 0x0111); /* Frame rate */
3439 ibmcam_model3_Packet1(uvd, 0x001f, 0x0000); /* Same */
3440 ibmcam_model3_Packet1(uvd, 0x0039, 0x001f); /* Same */
3441 ibmcam_model3_Packet1(uvd, 0x003b, 0x003c); /* Same */
3442 ibmcam_model3_Packet1(uvd, 0x0040, 0x0008);
3443 ibmcam_model3_Packet1(uvd, 0x0051, 0x000b);
3444 break;
3445 case VIDEOSIZE_640x480:
3446 ibmcam_veio(uvd, 0, 0x0002, 0x0106); /* Adjustments */
3447 ibmcam_veio(uvd, 0, 0x00b4, 0x0107); /* Adjustments */
3448 ibmcam_veio(uvd, 0, f_rate, 0x0111); /* Frame rate */
3449 ibmcam_model3_Packet1(uvd, 0x001f, 0x0002); /* !Same */
3450 ibmcam_model3_Packet1(uvd, 0x0039, 0x003e); /* !Same */
3451 ibmcam_model3_Packet1(uvd, 0x0040, 0x0008);
3452 ibmcam_model3_Packet1(uvd, 0x0051, 0x000a);
3453 break;
3454 }
3455
3456 /* 01.01.08 - Added for RCA video in support -LO */
3457 if(init_model3_input) {
3458 if (debug > 0)
3459 info("Setting input to RCA.");
3460 for (i=0; i < ARRAY_SIZE(initData); i++) {
3461 ibmcam_veio(uvd, initData[i].req, initData[i].value, initData[i].index);
3462 }
3463 }
3464
3465 ibmcam_veio(uvd, 0, 0x0001, 0x0114);
3466 ibmcam_veio(uvd, 0, 0x00c0, 0x010c);
3467 usb_clear_halt(uvd->dev, usb_rcvisocpipe(uvd->dev, uvd->video_endp));
3468}
3469
3470/*
3471 * ibmcam_video_stop()
3472 *
3473 * This code tells camera to stop streaming. The interface remains
3474 * configured and bandwidth - claimed.
3475 */
3476static void ibmcam_video_stop(struct uvd *uvd)
3477{
3478 switch (IBMCAM_T(uvd)->camera_model) {
3479 case IBMCAM_MODEL_1:
3480 ibmcam_veio(uvd, 0, 0x00, 0x010c);
3481 ibmcam_veio(uvd, 0, 0x00, 0x010c);
3482 ibmcam_veio(uvd, 0, 0x01, 0x0114);
3483 ibmcam_veio(uvd, 0, 0xc0, 0x010c);
3484 ibmcam_veio(uvd, 0, 0x00, 0x010c);
3485 ibmcam_send_FF_04_02(uvd);
3486 ibmcam_veio(uvd, 1, 0x00, 0x0100);
3487 ibmcam_veio(uvd, 0, 0x81, 0x0100); /* LED Off */
3488 break;
3489 case IBMCAM_MODEL_2:
3490case IBMCAM_MODEL_4:
3491 ibmcam_veio(uvd, 0, 0x0000, 0x010c); /* Stop the camera */
3492
3493 ibmcam_model2_Packet1(uvd, 0x0030, 0x0004);
3494
3495 ibmcam_veio(uvd, 0, 0x0080, 0x0100); /* LED Off */
3496 ibmcam_veio(uvd, 0, 0x0020, 0x0111);
3497 ibmcam_veio(uvd, 0, 0x00a0, 0x0111);
3498
3499 ibmcam_model2_Packet1(uvd, 0x0030, 0x0002);
3500
3501 ibmcam_veio(uvd, 0, 0x0020, 0x0111);
3502 ibmcam_veio(uvd, 0, 0x0000, 0x0112);
3503 break;
3504 case IBMCAM_MODEL_3:
3505#if 1
3506 ibmcam_veio(uvd, 0, 0x0000, 0x010c);
3507
3508 /* Here we are supposed to select video interface alt. setting 0 */
3509 ibmcam_veio(uvd, 0, 0x0006, 0x012c);
3510
3511 ibmcam_model3_Packet1(uvd, 0x0046, 0x0000);
3512
3513 ibmcam_veio(uvd, 1, 0x0000, 0x0116);
3514 ibmcam_veio(uvd, 0, 0x0064, 0x0116);
3515 ibmcam_veio(uvd, 1, 0x0000, 0x0115);
3516 ibmcam_veio(uvd, 0, 0x0003, 0x0115);
3517 ibmcam_veio(uvd, 0, 0x0008, 0x0123);
3518 ibmcam_veio(uvd, 0, 0x0000, 0x0117);
3519 ibmcam_veio(uvd, 0, 0x0000, 0x0112);
3520 ibmcam_veio(uvd, 0, 0x0080, 0x0100);
3521 IBMCAM_T(uvd)->initialized = 0;
3522#endif
3523 break;
3524 } /* switch */
3525}
3526
3527/*
3528 * ibmcam_reinit_iso()
3529 *
3530 * This procedure sends couple of commands to the camera and then
3531 * resets the video pipe. This sequence was observed to reinit the
3532 * camera or, at least, to initiate ISO data stream.
3533 *
3534 * History:
3535 * 1/2/00 Created.
3536 */
3537static void ibmcam_reinit_iso(struct uvd *uvd, int do_stop)
3538{
3539 switch (IBMCAM_T(uvd)->camera_model) {
3540 case IBMCAM_MODEL_1:
3541 if (do_stop)
3542 ibmcam_video_stop(uvd);
3543 ibmcam_veio(uvd, 0, 0x0001, 0x0114);
3544 ibmcam_veio(uvd, 0, 0x00c0, 0x010c);
3545 usb_clear_halt(uvd->dev, usb_rcvisocpipe(uvd->dev, uvd->video_endp));
3546 ibmcam_model1_setup_after_video_if(uvd);
3547 break;
3548 case IBMCAM_MODEL_2:
3549 ibmcam_model2_setup_after_video_if(uvd);
3550 break;
3551 case IBMCAM_MODEL_3:
3552 ibmcam_video_stop(uvd);
3553 ibmcam_model3_setup_after_video_if(uvd);
3554 break;
3555 case IBMCAM_MODEL_4:
3556 ibmcam_model4_setup_after_video_if(uvd);
3557 break;
3558 }
3559}
3560
3561static void ibmcam_video_start(struct uvd *uvd)
3562{
3563 ibmcam_change_lighting_conditions(uvd);
3564 ibmcam_set_sharpness(uvd);
3565 ibmcam_reinit_iso(uvd, 0);
3566}
3567
3568/*
3569 * Return negative code on failure, 0 on success.
3570 */
3571static int ibmcam_setup_on_open(struct uvd *uvd)
3572{
3573 int setup_ok = 0; /* Success by default */
3574 /* Send init sequence only once, it's large! */
3575 if (!IBMCAM_T(uvd)->initialized) { /* FIXME rename */
3576 switch (IBMCAM_T(uvd)->camera_model) {
3577 case IBMCAM_MODEL_1:
3578 setup_ok = ibmcam_model1_setup(uvd);
3579 break;
3580 case IBMCAM_MODEL_2:
3581 setup_ok = ibmcam_model2_setup(uvd);
3582 break;
3583 case IBMCAM_MODEL_3:
3584 case IBMCAM_MODEL_4:
3585 /* We do all setup when Isoc stream is requested */
3586 break;
3587 }
3588 IBMCAM_T(uvd)->initialized = (setup_ok != 0);
3589 }
3590 return setup_ok;
3591}
3592
3593static void ibmcam_configure_video(struct uvd *uvd)
3594{
3595 if (uvd == NULL)
3596 return;
3597
3598 RESTRICT_TO_RANGE(init_brightness, 0, 255);
3599 RESTRICT_TO_RANGE(init_contrast, 0, 255);
3600 RESTRICT_TO_RANGE(init_color, 0, 255);
3601 RESTRICT_TO_RANGE(init_hue, 0, 255);
3602 RESTRICT_TO_RANGE(hue_correction, 0, 255);
3603
3604 memset(&uvd->vpic, 0, sizeof(uvd->vpic));
3605 memset(&uvd->vpic_old, 0x55, sizeof(uvd->vpic_old));
3606
3607 uvd->vpic.colour = init_color << 8;
3608 uvd->vpic.hue = init_hue << 8;
3609 uvd->vpic.brightness = init_brightness << 8;
3610 uvd->vpic.contrast = init_contrast << 8;
3611 uvd->vpic.whiteness = 105 << 8; /* This one isn't used */
3612 uvd->vpic.depth = 24;
3613 uvd->vpic.palette = VIDEO_PALETTE_RGB24;
3614
3615 memset(&uvd->vcap, 0, sizeof(uvd->vcap));
3616 strcpy(uvd->vcap.name, "IBM USB Camera");
3617 uvd->vcap.type = VID_TYPE_CAPTURE;
3618 uvd->vcap.channels = 1;
3619 uvd->vcap.audios = 0;
3620 uvd->vcap.maxwidth = VIDEOSIZE_X(uvd->canvas);
3621 uvd->vcap.maxheight = VIDEOSIZE_Y(uvd->canvas);
3622 uvd->vcap.minwidth = min_canvasWidth;
3623 uvd->vcap.minheight = min_canvasHeight;
3624
3625 memset(&uvd->vchan, 0, sizeof(uvd->vchan));
3626 uvd->vchan.flags = 0;
3627 uvd->vchan.tuners = 0;
3628 uvd->vchan.channel = 0;
3629 uvd->vchan.type = VIDEO_TYPE_CAMERA;
3630 strcpy(uvd->vchan.name, "Camera");
3631}
3632
3633/*
3634 * ibmcam_probe()
3635 *
3636 * This procedure queries device descriptor and accepts the interface
3637 * if it looks like IBM C-it camera.
3638 *
3639 * History:
3640 * 22-Jan-2000 Moved camera init code to ibmcam_open()
3641 * 27=Jan-2000 Changed to use static structures, added locking.
3642 * 24-May-2000 Corrected to prevent race condition (MOD_xxx_USE_COUNT).
3643 * 03-Jul-2000 Fixed endianness bug.
3644 * 12-Nov-2000 Reworked to comply with new probe() signature.
3645 * 23-Jan-2001 Added compatibility with 2.2.x kernels.
3646 */
3647static int ibmcam_probe(struct usb_interface *intf, const struct usb_device_id *devid)
3648{
3649 struct usb_device *dev = interface_to_usbdev(intf);
3650 struct uvd *uvd = NULL;
3651 int ix, i, nas, model=0, canvasX=0, canvasY=0;
3652 int actInterface=-1, inactInterface=-1, maxPS=0;
3653 __u8 ifnum = intf->altsetting->desc.bInterfaceNumber;
3654 unsigned char video_ep = 0;
3655
3656 if (debug >= 1)
3657 info("ibmcam_probe(%p,%u.)", intf, ifnum);
3658
3659 /* We don't handle multi-config cameras */
3660 if (dev->descriptor.bNumConfigurations != 1)
3661 return -ENODEV;
3662
3663 /* Check the version/revision */
3664 switch (le16_to_cpu(dev->descriptor.bcdDevice)) {
3665 case 0x0002:
3666 if (ifnum != 2)
3667 return -ENODEV;
3668 model = IBMCAM_MODEL_1;
3669 break;
3670 case 0x030A:
3671 if (ifnum != 0)
3672 return -ENODEV;
3673 if ((le16_to_cpu(dev->descriptor.idProduct) == NETCAM_PRODUCT_ID) ||
3674 (le16_to_cpu(dev->descriptor.idProduct) == VEO_800D_PRODUCT_ID))
3675 model = IBMCAM_MODEL_4;
3676 else
3677 model = IBMCAM_MODEL_2;
3678 break;
3679 case 0x0301:
3680 if (ifnum != 0)
3681 return -ENODEV;
3682 model = IBMCAM_MODEL_3;
3683 break;
3684 default:
3685 err("IBM camera with revision 0x%04x is not supported.",
3686 le16_to_cpu(dev->descriptor.bcdDevice));
3687 return -ENODEV;
3688 }
3689
3690 /* Print detailed info on what we found so far */
3691 do {
3692 char *brand = NULL;
3693 switch (le16_to_cpu(dev->descriptor.idProduct)) {
3694 case NETCAM_PRODUCT_ID:
3695 brand = "IBM NetCamera";
3696 break;
3697 case VEO_800C_PRODUCT_ID:
3698 brand = "Veo Stingray [800C]";
3699 break;
3700 case VEO_800D_PRODUCT_ID:
3701 brand = "Veo Stingray [800D]";
3702 break;
3703 case IBMCAM_PRODUCT_ID:
3704 default:
3705 brand = "IBM PC Camera"; /* a.k.a. Xirlink C-It */
3706 break;
3707 }
3708 info("%s USB camera found (model %d, rev. 0x%04x)",
3709 brand, model, le16_to_cpu(dev->descriptor.bcdDevice));
3710 } while (0);
3711
3712 /* Validate found interface: must have one ISO endpoint */
3713 nas = intf->num_altsetting;
3714 if (debug > 0)
3715 info("Number of alternate settings=%d.", nas);
3716 if (nas < 2) {
3717 err("Too few alternate settings for this camera!");
3718 return -ENODEV;
3719 }
3720 /* Validate all alternate settings */
3721 for (ix=0; ix < nas; ix++) {
3722 const struct usb_host_interface *interface;
3723 const struct usb_endpoint_descriptor *endpoint;
3724
3725 interface = &intf->altsetting[ix];
3726 i = interface->desc.bAlternateSetting;
3727 if (interface->desc.bNumEndpoints != 1) {
3728 err("Interface %d. has %u. endpoints!",
3729 ifnum, (unsigned)(interface->desc.bNumEndpoints));
3730 return -ENODEV;
3731 }
3732 endpoint = &interface->endpoint[0].desc;
3733 if (video_ep == 0)
3734 video_ep = endpoint->bEndpointAddress;
3735 else if (video_ep != endpoint->bEndpointAddress) {
3736 err("Alternate settings have different endpoint addresses!");
3737 return -ENODEV;
3738 }
3739 if ((endpoint->bmAttributes & 0x03) != 0x01) {
3740 err("Interface %d. has non-ISO endpoint!", ifnum);
3741 return -ENODEV;
3742 }
3743 if ((endpoint->bEndpointAddress & 0x80) == 0) {
3744 err("Interface %d. has ISO OUT endpoint!", ifnum);
3745 return -ENODEV;
3746 }
3747 if (le16_to_cpu(endpoint->wMaxPacketSize) == 0) {
3748 if (inactInterface < 0)
3749 inactInterface = i;
3750 else {
3751 err("More than one inactive alt. setting!");
3752 return -ENODEV;
3753 }
3754 } else {
3755 if (actInterface < 0) {
3756 actInterface = i;
3757 maxPS = le16_to_cpu(endpoint->wMaxPacketSize);
3758 if (debug > 0)
3759 info("Active setting=%d. maxPS=%d.", i, maxPS);
3760 } else
3761 err("More than one active alt. setting! Ignoring #%d.", i);
3762 }
3763 }
3764 if ((maxPS <= 0) || (actInterface < 0) || (inactInterface < 0)) {
3765 err("Failed to recognize the camera!");
3766 return -ENODEV;
3767 }
3768
3769 /* Validate options */
3770 switch (model) {
3771 case IBMCAM_MODEL_1:
3772 RESTRICT_TO_RANGE(lighting, 0, 2);
3773 RESTRICT_TO_RANGE(size, SIZE_128x96, SIZE_352x288);
3774 if (framerate < 0)
3775 framerate = 2;
3776 canvasX = 352;
3777 canvasY = 288;
3778 break;
3779 case IBMCAM_MODEL_2:
3780 RESTRICT_TO_RANGE(lighting, 0, 15);
3781 RESTRICT_TO_RANGE(size, SIZE_176x144, SIZE_352x240);
3782 if (framerate < 0)
3783 framerate = 2;
3784 canvasX = 352;
3785 canvasY = 240;
3786 break;
3787 case IBMCAM_MODEL_3:
3788 RESTRICT_TO_RANGE(lighting, 0, 15); /* FIXME */
3789 switch (size) {
3790 case SIZE_160x120:
3791 canvasX = 160;
3792 canvasY = 120;
3793 if (framerate < 0)
3794 framerate = 2;
3795 RESTRICT_TO_RANGE(framerate, 0, 5);
3796 break;
3797 default:
3798 info("IBM camera: using 320x240");
3799 size = SIZE_320x240;
3800 /* No break here */
3801 case SIZE_320x240:
3802 canvasX = 320;
3803 canvasY = 240;
3804 if (framerate < 0)
3805 framerate = 3;
3806 RESTRICT_TO_RANGE(framerate, 0, 5);
3807 break;
3808 case SIZE_640x480:
3809 canvasX = 640;
3810 canvasY = 480;
3811 framerate = 0; /* Slowest, and maybe even that is too fast */
3812 break;
3813 }
3814 break;
3815 case IBMCAM_MODEL_4:
3816 RESTRICT_TO_RANGE(lighting, 0, 2);
3817 switch (size) {
3818 case SIZE_128x96:
3819 canvasX = 128;
3820 canvasY = 96;
3821 break;
3822 case SIZE_160x120:
3823 canvasX = 160;
3824 canvasY = 120;
3825 break;
3826 default:
3827 info("IBM NetCamera: using 176x144");
3828 size = SIZE_176x144;
3829 /* No break here */
3830 case SIZE_176x144:
3831 canvasX = 176;
3832 canvasY = 144;
3833 break;
3834 case SIZE_320x240:
3835 canvasX = 320;
3836 canvasY = 240;
3837 break;
3838 case SIZE_352x288:
3839 canvasX = 352;
3840 canvasY = 288;
3841 break;
3842 }
3843 break;
3844 default:
3845 err("IBM camera: Model %d. not supported!", model);
3846 return -ENODEV;
3847 }
3848
3849 uvd = usbvideo_AllocateDevice(cams);
3850 if (uvd != NULL) {
3851 /* Here uvd is a fully allocated uvd object */
3852 uvd->flags = flags;
3853 uvd->debug = debug;
3854 uvd->dev = dev;
3855 uvd->iface = ifnum;
3856 uvd->ifaceAltInactive = inactInterface;
3857 uvd->ifaceAltActive = actInterface;
3858 uvd->video_endp = video_ep;
3859 uvd->iso_packet_len = maxPS;
3860 uvd->paletteBits = 1L << VIDEO_PALETTE_RGB24;
3861 uvd->defaultPalette = VIDEO_PALETTE_RGB24;
3862 uvd->canvas = VIDEOSIZE(canvasX, canvasY);
3863 uvd->videosize = ibmcam_size_to_videosize(size);
3864
3865 /* Initialize ibmcam-specific data */
3866 assert(IBMCAM_T(uvd) != NULL);
3867 IBMCAM_T(uvd)->camera_model = model;
3868 IBMCAM_T(uvd)->initialized = 0;
3869
3870 ibmcam_configure_video(uvd);
3871
3872 i = usbvideo_RegisterVideoDevice(uvd);
3873 if (i != 0) {
3874 err("usbvideo_RegisterVideoDevice() failed.");
3875 uvd = NULL;
3876 }
3877 }
3878 usb_set_intfdata (intf, uvd);
3879 return 0;
3880}
3881
3882
3883static struct usb_device_id id_table[] = {
3884 { USB_DEVICE_VER(IBMCAM_VENDOR_ID, IBMCAM_PRODUCT_ID, 0x0002, 0x0002) }, /* Model 1 */
3885 { USB_DEVICE_VER(IBMCAM_VENDOR_ID, IBMCAM_PRODUCT_ID, 0x030a, 0x030a) }, /* Model 2 */
3886 { USB_DEVICE_VER(IBMCAM_VENDOR_ID, IBMCAM_PRODUCT_ID, 0x0301, 0x0301) }, /* Model 3 */
3887 { USB_DEVICE_VER(IBMCAM_VENDOR_ID, NETCAM_PRODUCT_ID, 0x030a, 0x030a) }, /* Model 4 */
3888 { USB_DEVICE_VER(IBMCAM_VENDOR_ID, VEO_800C_PRODUCT_ID, 0x030a, 0x030a) }, /* Model 2 */
3889 { USB_DEVICE_VER(IBMCAM_VENDOR_ID, VEO_800D_PRODUCT_ID, 0x030a, 0x030a) }, /* Model 4 */
3890 { } /* Terminating entry */
3891};
3892
3893/*
3894 * ibmcam_init()
3895 *
3896 * This code is run to initialize the driver.
3897 *
3898 * History:
3899 * 1/27/00 Reworked to use statically allocated ibmcam structures.
3900 * 21/10/00 Completely redesigned to use usbvideo services.
3901 */
3902static int __init ibmcam_init(void)
3903{
3904 struct usbvideo_cb cbTbl;
3905 memset(&cbTbl, 0, sizeof(cbTbl));
3906 cbTbl.probe = ibmcam_probe;
3907 cbTbl.setupOnOpen = ibmcam_setup_on_open;
3908 cbTbl.videoStart = ibmcam_video_start;
3909 cbTbl.videoStop = ibmcam_video_stop;
3910 cbTbl.processData = ibmcam_ProcessIsocData;
3911 cbTbl.postProcess = usbvideo_DeinterlaceFrame;
3912 cbTbl.adjustPicture = ibmcam_adjust_picture;
3913 cbTbl.getFPS = ibmcam_calculate_fps;
3914 return usbvideo_register(
3915 &cams,
3916 MAX_IBMCAM,
3917 sizeof(ibmcam_t),
3918 "ibmcam",
3919 &cbTbl,
3920 THIS_MODULE,
3921 id_table);
3922}
3923
3924static void __exit ibmcam_cleanup(void)
3925{
3926 usbvideo_Deregister(&cams);
3927}
3928
3929MODULE_DEVICE_TABLE(usb, id_table);
3930
3931module_init(ibmcam_init);
3932module_exit(ibmcam_cleanup);
diff --git a/drivers/media/video/usbvideo/konicawc.c b/drivers/media/video/usbvideo/konicawc.c
new file mode 100644
index 000000000000..e2ede583518f
--- /dev/null
+++ b/drivers/media/video/usbvideo/konicawc.c
@@ -0,0 +1,978 @@
1/*
2 * konicawc.c - konica webcam driver
3 *
4 * Author: Simon Evans <spse@secret.org.uk>
5 *
6 * Copyright (C) 2002 Simon Evans
7 *
8 * Licence: GPL
9 *
10 * Driver for USB webcams based on Konica chipset. This
11 * chipset is used in Intel YC76 camera.
12 *
13 */
14
15#include <linux/kernel.h>
16#include <linux/module.h>
17#include <linux/init.h>
18#include <linux/input.h>
19#include <linux/usb_input.h>
20
21#include "usbvideo.h"
22
23#define MAX_BRIGHTNESS 108
24#define MAX_CONTRAST 108
25#define MAX_SATURATION 108
26#define MAX_SHARPNESS 108
27#define MAX_WHITEBAL 372
28#define MAX_SPEED 6
29
30
31#define MAX_CAMERAS 1
32
33#define DRIVER_VERSION "v1.4"
34#define DRIVER_DESC "Konica Webcam driver"
35
36enum ctrl_req {
37 SetWhitebal = 0x01,
38 SetBrightness = 0x02,
39 SetSharpness = 0x03,
40 SetContrast = 0x04,
41 SetSaturation = 0x05,
42};
43
44
45enum frame_sizes {
46 SIZE_160X120 = 0,
47 SIZE_160X136 = 1,
48 SIZE_176X144 = 2,
49 SIZE_320X240 = 3,
50
51};
52
53#define MAX_FRAME_SIZE SIZE_320X240
54
55static struct usbvideo *cams;
56
57#ifdef CONFIG_USB_DEBUG
58static int debug;
59#define DEBUG(n, format, arg...) \
60 if (n <= debug) { \
61 printk(KERN_DEBUG __FILE__ ":%s(): " format "\n", __FUNCTION__ , ## arg); \
62 }
63#else
64#define DEBUG(n, arg...)
65static const int debug = 0;
66#endif
67
68
69/* Some default values for initial camera settings,
70 can be set by modprobe */
71
72static int size;
73static int speed = 6; /* Speed (fps) 0 (slowest) to 6 (fastest) */
74static int brightness = MAX_BRIGHTNESS/2;
75static int contrast = MAX_CONTRAST/2;
76static int saturation = MAX_SATURATION/2;
77static int sharpness = MAX_SHARPNESS/2;
78static int whitebal = 3*(MAX_WHITEBAL/4);
79
80static const int spd_to_iface[] = { 1, 0, 3, 2, 4, 5, 6 };
81
82/* These FPS speeds are from the windows config box. They are
83 * indexed on size (0-2) and speed (0-6). Divide by 3 to get the
84 * real fps.
85 */
86
87static const int spd_to_fps[][7] = { { 24, 40, 48, 60, 72, 80, 100 },
88 { 24, 40, 48, 60, 72, 80, 100 },
89 { 18, 30, 36, 45, 54, 60, 75 },
90 { 6, 10, 12, 15, 18, 21, 25 } };
91
92struct cam_size {
93 u16 width;
94 u16 height;
95 u8 cmd;
96};
97
98static const struct cam_size camera_sizes[] = { { 160, 120, 0x7 },
99 { 160, 136, 0xa },
100 { 176, 144, 0x4 },
101 { 320, 240, 0x5 } };
102
103struct konicawc {
104 u8 brightness; /* camera uses 0 - 9, x11 for real value */
105 u8 contrast; /* as above */
106 u8 saturation; /* as above */
107 u8 sharpness; /* as above */
108 u8 white_bal; /* 0 - 33, x11 for real value */
109 u8 speed; /* Stored as 0 - 6, used as index in spd_to_* (above) */
110 u8 size; /* Frame Size */
111 int height;
112 int width;
113 struct urb *sts_urb[USBVIDEO_NUMSBUF];
114 u8 sts_buf[USBVIDEO_NUMSBUF][FRAMES_PER_DESC];
115 struct urb *last_data_urb;
116 int lastframe;
117 int cur_frame_size; /* number of bytes in current frame size */
118 int maxline; /* number of lines per frame */
119 int yplanesz; /* Number of bytes in the Y plane */
120 unsigned int buttonsts:1;
121#ifdef CONFIG_INPUT
122 struct input_dev *input;
123 char input_physname[64];
124#endif
125};
126
127
128#define konicawc_set_misc(uvd, req, value, index) konicawc_ctrl_msg(uvd, USB_DIR_OUT, req, value, index, NULL, 0)
129#define konicawc_get_misc(uvd, req, value, index, buf, sz) konicawc_ctrl_msg(uvd, USB_DIR_IN, req, value, index, buf, sz)
130#define konicawc_set_value(uvd, value, index) konicawc_ctrl_msg(uvd, USB_DIR_OUT, 2, value, index, NULL, 0)
131
132
133static int konicawc_ctrl_msg(struct uvd *uvd, u8 dir, u8 request, u16 value, u16 index, void *buf, int len)
134{
135 int retval = usb_control_msg(uvd->dev,
136 dir ? usb_rcvctrlpipe(uvd->dev, 0) : usb_sndctrlpipe(uvd->dev, 0),
137 request, 0x40 | dir, value, index, buf, len, 1000);
138 return retval < 0 ? retval : 0;
139}
140
141
142static inline void konicawc_camera_on(struct uvd *uvd)
143{
144 DEBUG(0, "camera on");
145 konicawc_set_misc(uvd, 0x2, 1, 0x0b);
146}
147
148
149static inline void konicawc_camera_off(struct uvd *uvd)
150{
151 DEBUG(0, "camera off");
152 konicawc_set_misc(uvd, 0x2, 0, 0x0b);
153}
154
155
156static void konicawc_set_camera_size(struct uvd *uvd)
157{
158 struct konicawc *cam = (struct konicawc *)uvd->user_data;
159
160 konicawc_set_misc(uvd, 0x2, camera_sizes[cam->size].cmd, 0x08);
161 cam->width = camera_sizes[cam->size].width;
162 cam->height = camera_sizes[cam->size].height;
163 cam->yplanesz = cam->height * cam->width;
164 cam->cur_frame_size = (cam->yplanesz * 3) / 2;
165 cam->maxline = cam->yplanesz / 256;
166 uvd->videosize = VIDEOSIZE(cam->width, cam->height);
167}
168
169
170static int konicawc_setup_on_open(struct uvd *uvd)
171{
172 struct konicawc *cam = (struct konicawc *)uvd->user_data;
173
174 DEBUG(1, "setting brightness to %d (%d)", cam->brightness,
175 cam->brightness * 11);
176 konicawc_set_value(uvd, cam->brightness, SetBrightness);
177 DEBUG(1, "setting white balance to %d (%d)", cam->white_bal,
178 cam->white_bal * 11);
179 konicawc_set_value(uvd, cam->white_bal, SetWhitebal);
180 DEBUG(1, "setting contrast to %d (%d)", cam->contrast,
181 cam->contrast * 11);
182 konicawc_set_value(uvd, cam->contrast, SetContrast);
183 DEBUG(1, "setting saturation to %d (%d)", cam->saturation,
184 cam->saturation * 11);
185 konicawc_set_value(uvd, cam->saturation, SetSaturation);
186 DEBUG(1, "setting sharpness to %d (%d)", cam->sharpness,
187 cam->sharpness * 11);
188 konicawc_set_value(uvd, cam->sharpness, SetSharpness);
189 konicawc_set_camera_size(uvd);
190 cam->lastframe = -2;
191 cam->buttonsts = 0;
192 return 0;
193}
194
195
196static void konicawc_adjust_picture(struct uvd *uvd)
197{
198 struct konicawc *cam = (struct konicawc *)uvd->user_data;
199
200 konicawc_camera_off(uvd);
201 DEBUG(1, "new brightness: %d", uvd->vpic.brightness);
202 uvd->vpic.brightness = (uvd->vpic.brightness > MAX_BRIGHTNESS) ? MAX_BRIGHTNESS : uvd->vpic.brightness;
203 if(cam->brightness != uvd->vpic.brightness / 11) {
204 cam->brightness = uvd->vpic.brightness / 11;
205 DEBUG(1, "setting brightness to %d (%d)", cam->brightness,
206 cam->brightness * 11);
207 konicawc_set_value(uvd, cam->brightness, SetBrightness);
208 }
209
210 DEBUG(1, "new contrast: %d", uvd->vpic.contrast);
211 uvd->vpic.contrast = (uvd->vpic.contrast > MAX_CONTRAST) ? MAX_CONTRAST : uvd->vpic.contrast;
212 if(cam->contrast != uvd->vpic.contrast / 11) {
213 cam->contrast = uvd->vpic.contrast / 11;
214 DEBUG(1, "setting contrast to %d (%d)", cam->contrast,
215 cam->contrast * 11);
216 konicawc_set_value(uvd, cam->contrast, SetContrast);
217 }
218 konicawc_camera_on(uvd);
219}
220
221#ifdef CONFIG_INPUT
222
223static void konicawc_register_input(struct konicawc *cam, struct usb_device *dev)
224{
225 struct input_dev *input_dev;
226
227 usb_make_path(dev, cam->input_physname, sizeof(cam->input_physname));
228 strncat(cam->input_physname, "/input0", sizeof(cam->input_physname));
229
230 cam->input = input_dev = input_allocate_device();
231 if (!input_dev) {
232 warn("Not enough memory for camera's input device\n");
233 return;
234 }
235
236 input_dev->name = "Konicawc snapshot button";
237 input_dev->phys = cam->input_physname;
238 usb_to_input_id(dev, &input_dev->id);
239 input_dev->cdev.dev = &dev->dev;
240
241 input_dev->evbit[0] = BIT(EV_KEY);
242 input_dev->keybit[LONG(BTN_0)] = BIT(BTN_0);
243
244 input_dev->private = cam;
245
246 input_register_device(cam->input);
247}
248
249static void konicawc_unregister_input(struct konicawc *cam)
250{
251 if (cam->input) {
252 input_unregister_device(cam->input);
253 cam->input = NULL;
254 }
255}
256
257static void konicawc_report_buttonstat(struct konicawc *cam)
258{
259 if (cam->input) {
260 input_report_key(cam->input, BTN_0, cam->buttonsts);
261 input_sync(cam->input);
262 }
263}
264
265#else
266
267static inline void konicawc_register_input(struct konicawc *cam, struct usb_device *dev) { }
268static inline void konicawc_unregister_input(struct konicawc *cam) { }
269static inline void konicawc_report_buttonstat(struct konicawc *cam) { }
270
271#endif /* CONFIG_INPUT */
272
273static int konicawc_compress_iso(struct uvd *uvd, struct urb *dataurb, struct urb *stsurb)
274{
275 char *cdata;
276 int i, totlen = 0;
277 unsigned char *status = stsurb->transfer_buffer;
278 int keep = 0, discard = 0, bad = 0;
279 struct konicawc *cam = (struct konicawc *)uvd->user_data;
280
281 for (i = 0; i < dataurb->number_of_packets; i++) {
282 int button = cam->buttonsts;
283 unsigned char sts;
284 int n = dataurb->iso_frame_desc[i].actual_length;
285 int st = dataurb->iso_frame_desc[i].status;
286 cdata = dataurb->transfer_buffer +
287 dataurb->iso_frame_desc[i].offset;
288
289 /* Detect and ignore errored packets */
290 if (st < 0) {
291 DEBUG(1, "Data error: packet=%d. len=%d. status=%d.",
292 i, n, st);
293 uvd->stats.iso_err_count++;
294 continue;
295 }
296
297 /* Detect and ignore empty packets */
298 if (n <= 0) {
299 uvd->stats.iso_skip_count++;
300 continue;
301 }
302
303 /* See what the status data said about the packet */
304 sts = *(status+stsurb->iso_frame_desc[i].offset);
305
306 /* sts: 0x80-0xff: frame start with frame number (ie 0-7f)
307 * otherwise:
308 * bit 0 0: keep packet
309 * 1: drop packet (padding data)
310 *
311 * bit 4 0 button not clicked
312 * 1 button clicked
313 * button is used to `take a picture' (in software)
314 */
315
316 if(sts < 0x80) {
317 button = !!(sts & 0x40);
318 sts &= ~0x40;
319 }
320
321 /* work out the button status, but don't do
322 anything with it for now */
323
324 if(button != cam->buttonsts) {
325 DEBUG(2, "button: %sclicked", button ? "" : "un");
326 cam->buttonsts = button;
327 konicawc_report_buttonstat(cam);
328 }
329
330 if(sts == 0x01) { /* drop frame */
331 discard++;
332 continue;
333 }
334
335 if((sts > 0x01) && (sts < 0x80)) {
336 info("unknown status %2.2x", sts);
337 bad++;
338 continue;
339 }
340 if(!sts && cam->lastframe == -2) {
341 DEBUG(2, "dropping frame looking for image start");
342 continue;
343 }
344
345 keep++;
346 if(sts & 0x80) { /* frame start */
347 unsigned char marker[] = { 0, 0xff, 0, 0x00 };
348
349 if(cam->lastframe == -2) {
350 DEBUG(2, "found initial image");
351 cam->lastframe = -1;
352 }
353
354 marker[3] = sts & 0x7F;
355 RingQueue_Enqueue(&uvd->dp, marker, 4);
356 totlen += 4;
357 }
358
359 totlen += n; /* Little local accounting */
360 RingQueue_Enqueue(&uvd->dp, cdata, n);
361 }
362 DEBUG(8, "finished: keep = %d discard = %d bad = %d added %d bytes",
363 keep, discard, bad, totlen);
364 return totlen;
365}
366
367
368static void resubmit_urb(struct uvd *uvd, struct urb *urb)
369{
370 int i, ret;
371 for (i = 0; i < FRAMES_PER_DESC; i++) {
372 urb->iso_frame_desc[i].status = 0;
373 }
374 urb->dev = uvd->dev;
375 urb->status = 0;
376 ret = usb_submit_urb(urb, GFP_ATOMIC);
377 DEBUG(3, "submitting urb of length %d", urb->transfer_buffer_length);
378 if(ret)
379 err("usb_submit_urb error (%d)", ret);
380
381}
382
383
384static void konicawc_isoc_irq(struct urb *urb, struct pt_regs *regs)
385{
386 struct uvd *uvd = urb->context;
387 struct konicawc *cam = (struct konicawc *)uvd->user_data;
388
389 /* We don't want to do anything if we are about to be removed! */
390 if (!CAMERA_IS_OPERATIONAL(uvd))
391 return;
392
393 if (!uvd->streaming) {
394 DEBUG(1, "Not streaming, but interrupt!");
395 return;
396 }
397
398 DEBUG(3, "got frame %d len = %d buflen =%d", urb->start_frame, urb->actual_length, urb->transfer_buffer_length);
399
400 uvd->stats.urb_count++;
401
402 if (urb->transfer_buffer_length > 32) {
403 cam->last_data_urb = urb;
404 return;
405 }
406 /* Copy the data received into ring queue */
407 if(cam->last_data_urb) {
408 int len = 0;
409 if(urb->start_frame != cam->last_data_urb->start_frame)
410 err("Lost sync on frames");
411 else if (!urb->status && !cam->last_data_urb->status)
412 len = konicawc_compress_iso(uvd, cam->last_data_urb, urb);
413
414 resubmit_urb(uvd, cam->last_data_urb);
415 resubmit_urb(uvd, urb);
416 cam->last_data_urb = NULL;
417 uvd->stats.urb_length = len;
418 uvd->stats.data_count += len;
419 if(len)
420 RingQueue_WakeUpInterruptible(&uvd->dp);
421 return;
422 }
423 return;
424}
425
426
427static int konicawc_start_data(struct uvd *uvd)
428{
429 struct usb_device *dev = uvd->dev;
430 int i, errFlag;
431 struct konicawc *cam = (struct konicawc *)uvd->user_data;
432 int pktsz;
433 struct usb_interface *intf;
434 struct usb_host_interface *interface = NULL;
435
436 intf = usb_ifnum_to_if(dev, uvd->iface);
437 if (intf)
438 interface = usb_altnum_to_altsetting(intf,
439 spd_to_iface[cam->speed]);
440 if (!interface)
441 return -ENXIO;
442 pktsz = le16_to_cpu(interface->endpoint[1].desc.wMaxPacketSize);
443 DEBUG(1, "pktsz = %d", pktsz);
444 if (!CAMERA_IS_OPERATIONAL(uvd)) {
445 err("Camera is not operational");
446 return -EFAULT;
447 }
448 uvd->curframe = -1;
449 konicawc_camera_on(uvd);
450 /* Alternate interface 1 is is the biggest frame size */
451 i = usb_set_interface(dev, uvd->iface, uvd->ifaceAltActive);
452 if (i < 0) {
453 err("usb_set_interface error");
454 uvd->last_error = i;
455 return -EBUSY;
456 }
457
458 /* We double buffer the Iso lists */
459 for (i=0; i < USBVIDEO_NUMSBUF; i++) {
460 int j, k;
461 struct urb *urb = uvd->sbuf[i].urb;
462 urb->dev = dev;
463 urb->context = uvd;
464 urb->pipe = usb_rcvisocpipe(dev, uvd->video_endp);
465 urb->interval = 1;
466 urb->transfer_flags = URB_ISO_ASAP;
467 urb->transfer_buffer = uvd->sbuf[i].data;
468 urb->complete = konicawc_isoc_irq;
469 urb->number_of_packets = FRAMES_PER_DESC;
470 urb->transfer_buffer_length = pktsz * FRAMES_PER_DESC;
471 for (j=k=0; j < FRAMES_PER_DESC; j++, k += pktsz) {
472 urb->iso_frame_desc[j].offset = k;
473 urb->iso_frame_desc[j].length = pktsz;
474 }
475
476 urb = cam->sts_urb[i];
477 urb->dev = dev;
478 urb->context = uvd;
479 urb->pipe = usb_rcvisocpipe(dev, uvd->video_endp-1);
480 urb->interval = 1;
481 urb->transfer_flags = URB_ISO_ASAP;
482 urb->transfer_buffer = cam->sts_buf[i];
483 urb->complete = konicawc_isoc_irq;
484 urb->number_of_packets = FRAMES_PER_DESC;
485 urb->transfer_buffer_length = FRAMES_PER_DESC;
486 for (j=0; j < FRAMES_PER_DESC; j++) {
487 urb->iso_frame_desc[j].offset = j;
488 urb->iso_frame_desc[j].length = 1;
489 }
490 }
491
492 cam->last_data_urb = NULL;
493
494 /* Submit all URBs */
495 for (i=0; i < USBVIDEO_NUMSBUF; i++) {
496 errFlag = usb_submit_urb(cam->sts_urb[i], GFP_KERNEL);
497 if (errFlag)
498 err("usb_submit_isoc(%d) ret %d", i, errFlag);
499
500 errFlag = usb_submit_urb(uvd->sbuf[i].urb, GFP_KERNEL);
501 if (errFlag)
502 err ("usb_submit_isoc(%d) ret %d", i, errFlag);
503 }
504
505 uvd->streaming = 1;
506 DEBUG(1, "streaming=1 video_endp=$%02x", uvd->video_endp);
507 return 0;
508}
509
510
511static void konicawc_stop_data(struct uvd *uvd)
512{
513 int i, j;
514 struct konicawc *cam;
515
516 if ((uvd == NULL) || (!uvd->streaming) || (uvd->dev == NULL))
517 return;
518
519 konicawc_camera_off(uvd);
520 uvd->streaming = 0;
521 cam = (struct konicawc *)uvd->user_data;
522 cam->last_data_urb = NULL;
523
524 /* Unschedule all of the iso td's */
525 for (i=0; i < USBVIDEO_NUMSBUF; i++) {
526 usb_kill_urb(uvd->sbuf[i].urb);
527 usb_kill_urb(cam->sts_urb[i]);
528 }
529
530 if (!uvd->remove_pending) {
531 /* Set packet size to 0 */
532 j = usb_set_interface(uvd->dev, uvd->iface, uvd->ifaceAltInactive);
533 if (j < 0) {
534 err("usb_set_interface() error %d.", j);
535 uvd->last_error = j;
536 }
537 }
538}
539
540
541static void konicawc_process_isoc(struct uvd *uvd, struct usbvideo_frame *frame)
542{
543 struct konicawc *cam = (struct konicawc *)uvd->user_data;
544 int maxline = cam->maxline;
545 int yplanesz = cam->yplanesz;
546
547 assert(frame != NULL);
548
549 DEBUG(5, "maxline = %d yplanesz = %d", maxline, yplanesz);
550 DEBUG(3, "Frame state = %d", frame->scanstate);
551
552 if(frame->scanstate == ScanState_Scanning) {
553 int drop = 0;
554 int curframe;
555 int fdrops = 0;
556 DEBUG(3, "Searching for marker, queue len = %d", RingQueue_GetLength(&uvd->dp));
557 while(RingQueue_GetLength(&uvd->dp) >= 4) {
558 if ((RING_QUEUE_PEEK(&uvd->dp, 0) == 0x00) &&
559 (RING_QUEUE_PEEK(&uvd->dp, 1) == 0xff) &&
560 (RING_QUEUE_PEEK(&uvd->dp, 2) == 0x00) &&
561 (RING_QUEUE_PEEK(&uvd->dp, 3) < 0x80)) {
562 curframe = RING_QUEUE_PEEK(&uvd->dp, 3);
563 if(cam->lastframe >= 0) {
564 fdrops = (0x80 + curframe - cam->lastframe) & 0x7F;
565 fdrops--;
566 if(fdrops) {
567 info("Dropped %d frames (%d -> %d)", fdrops,
568 cam->lastframe, curframe);
569 }
570 }
571 cam->lastframe = curframe;
572 frame->curline = 0;
573 frame->scanstate = ScanState_Lines;
574 RING_QUEUE_DEQUEUE_BYTES(&uvd->dp, 4);
575 break;
576 }
577 RING_QUEUE_DEQUEUE_BYTES(&uvd->dp, 1);
578 drop++;
579 }
580 if(drop)
581 DEBUG(2, "dropped %d bytes looking for new frame", drop);
582 }
583
584 if(frame->scanstate == ScanState_Scanning)
585 return;
586
587 /* Try to move data from queue into frame buffer
588 * We get data in blocks of 384 bytes made up of:
589 * 256 Y, 64 U, 64 V.
590 * This needs to be written out as a Y plane, a U plane and a V plane.
591 */
592
593 while ( frame->curline < maxline && (RingQueue_GetLength(&uvd->dp) >= 384)) {
594 /* Y */
595 RingQueue_Dequeue(&uvd->dp, frame->data + (frame->curline * 256), 256);
596 /* U */
597 RingQueue_Dequeue(&uvd->dp, frame->data + yplanesz + (frame->curline * 64), 64);
598 /* V */
599 RingQueue_Dequeue(&uvd->dp, frame->data + (5 * yplanesz)/4 + (frame->curline * 64), 64);
600 frame->seqRead_Length += 384;
601 frame->curline++;
602 }
603 /* See if we filled the frame */
604 if (frame->curline == maxline) {
605 DEBUG(5, "got whole frame");
606
607 frame->frameState = FrameState_Done_Hold;
608 frame->curline = 0;
609 uvd->curframe = -1;
610 uvd->stats.frame_num++;
611 }
612}
613
614
615static int konicawc_find_fps(int size, int fps)
616{
617 int i;
618
619 fps *= 3;
620 DEBUG(1, "konica_find_fps: size = %d fps = %d", size, fps);
621 if(fps <= spd_to_fps[size][0])
622 return 0;
623
624 if(fps >= spd_to_fps[size][MAX_SPEED])
625 return MAX_SPEED;
626
627 for(i = 0; i < MAX_SPEED; i++) {
628 if((fps >= spd_to_fps[size][i]) && (fps <= spd_to_fps[size][i+1])) {
629 DEBUG(2, "fps %d between %d and %d", fps, i, i+1);
630 if( (fps - spd_to_fps[size][i]) < (spd_to_fps[size][i+1] - fps))
631 return i;
632 else
633 return i+1;
634 }
635 }
636 return MAX_SPEED+1;
637}
638
639
640static int konicawc_set_video_mode(struct uvd *uvd, struct video_window *vw)
641{
642 struct konicawc *cam = (struct konicawc *)uvd->user_data;
643 int newspeed = cam->speed;
644 int newsize;
645 int x = vw->width;
646 int y = vw->height;
647 int fps = vw->flags;
648
649 if(x > 0 && y > 0) {
650 DEBUG(2, "trying to find size %d,%d", x, y);
651 for(newsize = 0; newsize <= MAX_FRAME_SIZE; newsize++) {
652 if((camera_sizes[newsize].width == x) && (camera_sizes[newsize].height == y))
653 break;
654 }
655 } else {
656 newsize = cam->size;
657 }
658
659 if(newsize > MAX_FRAME_SIZE) {
660 DEBUG(1, "couldn't find size %d,%d", x, y);
661 return -EINVAL;
662 }
663
664 if(fps > 0) {
665 DEBUG(1, "trying to set fps to %d", fps);
666 newspeed = konicawc_find_fps(newsize, fps);
667 DEBUG(1, "find_fps returned %d (%d)", newspeed, spd_to_fps[newsize][newspeed]);
668 }
669
670 if(newspeed > MAX_SPEED)
671 return -EINVAL;
672
673 DEBUG(1, "setting size to %d speed to %d", newsize, newspeed);
674 if((newsize == cam->size) && (newspeed == cam->speed)) {
675 DEBUG(1, "Nothing to do");
676 return 0;
677 }
678 DEBUG(0, "setting to %dx%d @ %d fps", camera_sizes[newsize].width,
679 camera_sizes[newsize].height, spd_to_fps[newsize][newspeed]/3);
680
681 konicawc_stop_data(uvd);
682 uvd->ifaceAltActive = spd_to_iface[newspeed];
683 DEBUG(1, "new interface = %d", uvd->ifaceAltActive);
684 cam->speed = newspeed;
685
686 if(cam->size != newsize) {
687 cam->size = newsize;
688 konicawc_set_camera_size(uvd);
689 }
690
691 /* Flush the input queue and clear any current frame in progress */
692
693 RingQueue_Flush(&uvd->dp);
694 cam->lastframe = -2;
695 if(uvd->curframe != -1) {
696 uvd->frame[uvd->curframe].curline = 0;
697 uvd->frame[uvd->curframe].seqRead_Length = 0;
698 uvd->frame[uvd->curframe].seqRead_Index = 0;
699 }
700
701 konicawc_start_data(uvd);
702 return 0;
703}
704
705
706static int konicawc_calculate_fps(struct uvd *uvd)
707{
708 struct konicawc *cam = uvd->user_data;
709 return spd_to_fps[cam->size][cam->speed]/3;
710}
711
712
713static void konicawc_configure_video(struct uvd *uvd)
714{
715 struct konicawc *cam = (struct konicawc *)uvd->user_data;
716 u8 buf[2];
717
718 memset(&uvd->vpic, 0, sizeof(uvd->vpic));
719 memset(&uvd->vpic_old, 0x55, sizeof(uvd->vpic_old));
720
721 RESTRICT_TO_RANGE(brightness, 0, MAX_BRIGHTNESS);
722 RESTRICT_TO_RANGE(contrast, 0, MAX_CONTRAST);
723 RESTRICT_TO_RANGE(saturation, 0, MAX_SATURATION);
724 RESTRICT_TO_RANGE(sharpness, 0, MAX_SHARPNESS);
725 RESTRICT_TO_RANGE(whitebal, 0, MAX_WHITEBAL);
726
727 cam->brightness = brightness / 11;
728 cam->contrast = contrast / 11;
729 cam->saturation = saturation / 11;
730 cam->sharpness = sharpness / 11;
731 cam->white_bal = whitebal / 11;
732
733 uvd->vpic.colour = 108;
734 uvd->vpic.hue = 108;
735 uvd->vpic.brightness = brightness;
736 uvd->vpic.contrast = contrast;
737 uvd->vpic.whiteness = whitebal;
738 uvd->vpic.depth = 6;
739 uvd->vpic.palette = VIDEO_PALETTE_YUV420P;
740
741 memset(&uvd->vcap, 0, sizeof(uvd->vcap));
742 strcpy(uvd->vcap.name, "Konica Webcam");
743 uvd->vcap.type = VID_TYPE_CAPTURE;
744 uvd->vcap.channels = 1;
745 uvd->vcap.audios = 0;
746 uvd->vcap.minwidth = camera_sizes[SIZE_160X120].width;
747 uvd->vcap.minheight = camera_sizes[SIZE_160X120].height;
748 uvd->vcap.maxwidth = camera_sizes[SIZE_320X240].width;
749 uvd->vcap.maxheight = camera_sizes[SIZE_320X240].height;
750
751 memset(&uvd->vchan, 0, sizeof(uvd->vchan));
752 uvd->vchan.flags = 0 ;
753 uvd->vchan.tuners = 0;
754 uvd->vchan.channel = 0;
755 uvd->vchan.type = VIDEO_TYPE_CAMERA;
756 strcpy(uvd->vchan.name, "Camera");
757
758 /* Talk to device */
759 DEBUG(1, "device init");
760 if(!konicawc_get_misc(uvd, 0x3, 0, 0x10, buf, 2))
761 DEBUG(2, "3,10 -> %2.2x %2.2x", buf[0], buf[1]);
762 if(!konicawc_get_misc(uvd, 0x3, 0, 0x10, buf, 2))
763 DEBUG(2, "3,10 -> %2.2x %2.2x", buf[0], buf[1]);
764 if(konicawc_set_misc(uvd, 0x2, 0, 0xd))
765 DEBUG(2, "2,0,d failed");
766 DEBUG(1, "setting initial values");
767}
768
769static int konicawc_probe(struct usb_interface *intf, const struct usb_device_id *devid)
770{
771 struct usb_device *dev = interface_to_usbdev(intf);
772 struct uvd *uvd = NULL;
773 int ix, i, nas;
774 int actInterface=-1, inactInterface=-1, maxPS=0;
775 unsigned char video_ep = 0;
776
777 DEBUG(1, "konicawc_probe(%p)", intf);
778
779 /* We don't handle multi-config cameras */
780 if (dev->descriptor.bNumConfigurations != 1)
781 return -ENODEV;
782
783 info("Konica Webcam (rev. 0x%04x)", le16_to_cpu(dev->descriptor.bcdDevice));
784 RESTRICT_TO_RANGE(speed, 0, MAX_SPEED);
785
786 /* Validate found interface: must have one ISO endpoint */
787 nas = intf->num_altsetting;
788 if (nas != 8) {
789 err("Incorrect number of alternate settings (%d) for this camera!", nas);
790 return -ENODEV;
791 }
792 /* Validate all alternate settings */
793 for (ix=0; ix < nas; ix++) {
794 const struct usb_host_interface *interface;
795 const struct usb_endpoint_descriptor *endpoint;
796
797 interface = &intf->altsetting[ix];
798 i = interface->desc.bAlternateSetting;
799 if (interface->desc.bNumEndpoints != 2) {
800 err("Interface %d. has %u. endpoints!",
801 interface->desc.bInterfaceNumber,
802 (unsigned)(interface->desc.bNumEndpoints));
803 return -ENODEV;
804 }
805 endpoint = &interface->endpoint[1].desc;
806 DEBUG(1, "found endpoint: addr: 0x%2.2x maxps = 0x%4.4x",
807 endpoint->bEndpointAddress, le16_to_cpu(endpoint->wMaxPacketSize));
808 if (video_ep == 0)
809 video_ep = endpoint->bEndpointAddress;
810 else if (video_ep != endpoint->bEndpointAddress) {
811 err("Alternate settings have different endpoint addresses!");
812 return -ENODEV;
813 }
814 if ((endpoint->bmAttributes & 0x03) != 0x01) {
815 err("Interface %d. has non-ISO endpoint!",
816 interface->desc.bInterfaceNumber);
817 return -ENODEV;
818 }
819 if ((endpoint->bEndpointAddress & 0x80) == 0) {
820 err("Interface %d. has ISO OUT endpoint!",
821 interface->desc.bInterfaceNumber);
822 return -ENODEV;
823 }
824 if (le16_to_cpu(endpoint->wMaxPacketSize) == 0) {
825 if (inactInterface < 0)
826 inactInterface = i;
827 else {
828 err("More than one inactive alt. setting!");
829 return -ENODEV;
830 }
831 } else {
832 if (i == spd_to_iface[speed]) {
833 /* This one is the requested one */
834 actInterface = i;
835 }
836 }
837 if (le16_to_cpu(endpoint->wMaxPacketSize) > maxPS)
838 maxPS = le16_to_cpu(endpoint->wMaxPacketSize);
839 }
840 if(actInterface == -1) {
841 err("Cant find required endpoint");
842 return -ENODEV;
843 }
844
845 DEBUG(1, "Selecting requested active setting=%d. maxPS=%d.", actInterface, maxPS);
846
847 uvd = usbvideo_AllocateDevice(cams);
848 if (uvd != NULL) {
849 struct konicawc *cam = (struct konicawc *)(uvd->user_data);
850 /* Here uvd is a fully allocated uvd object */
851 for(i = 0; i < USBVIDEO_NUMSBUF; i++) {
852 cam->sts_urb[i] = usb_alloc_urb(FRAMES_PER_DESC, GFP_KERNEL);
853 if(cam->sts_urb[i] == NULL) {
854 while(i--) {
855 usb_free_urb(cam->sts_urb[i]);
856 }
857 err("can't allocate urbs");
858 return -ENOMEM;
859 }
860 }
861 cam->speed = speed;
862 RESTRICT_TO_RANGE(size, SIZE_160X120, SIZE_320X240);
863 cam->width = camera_sizes[size].width;
864 cam->height = camera_sizes[size].height;
865 cam->size = size;
866
867 uvd->flags = 0;
868 uvd->debug = debug;
869 uvd->dev = dev;
870 uvd->iface = intf->altsetting->desc.bInterfaceNumber;
871 uvd->ifaceAltInactive = inactInterface;
872 uvd->ifaceAltActive = actInterface;
873 uvd->video_endp = video_ep;
874 uvd->iso_packet_len = maxPS;
875 uvd->paletteBits = 1L << VIDEO_PALETTE_YUV420P;
876 uvd->defaultPalette = VIDEO_PALETTE_YUV420P;
877 uvd->canvas = VIDEOSIZE(320, 240);
878 uvd->videosize = VIDEOSIZE(cam->width, cam->height);
879
880 /* Initialize konicawc specific data */
881 konicawc_configure_video(uvd);
882
883 i = usbvideo_RegisterVideoDevice(uvd);
884 uvd->max_frame_size = (320 * 240 * 3)/2;
885 if (i != 0) {
886 err("usbvideo_RegisterVideoDevice() failed.");
887 uvd = NULL;
888 }
889
890 konicawc_register_input(cam, dev);
891 }
892
893 if (uvd) {
894 usb_set_intfdata (intf, uvd);
895 return 0;
896 }
897 return -EIO;
898}
899
900
901static void konicawc_free_uvd(struct uvd *uvd)
902{
903 int i;
904 struct konicawc *cam = (struct konicawc *)uvd->user_data;
905
906 konicawc_unregister_input(cam);
907
908 for (i = 0; i < USBVIDEO_NUMSBUF; i++) {
909 usb_free_urb(cam->sts_urb[i]);
910 cam->sts_urb[i] = NULL;
911 }
912}
913
914
915static struct usb_device_id id_table[] = {
916 { USB_DEVICE(0x04c8, 0x0720) }, /* Intel YC 76 */
917 { } /* Terminating entry */
918};
919
920
921static int __init konicawc_init(void)
922{
923 struct usbvideo_cb cbTbl;
924 info(DRIVER_DESC " " DRIVER_VERSION);
925 memset(&cbTbl, 0, sizeof(cbTbl));
926 cbTbl.probe = konicawc_probe;
927 cbTbl.setupOnOpen = konicawc_setup_on_open;
928 cbTbl.processData = konicawc_process_isoc;
929 cbTbl.getFPS = konicawc_calculate_fps;
930 cbTbl.setVideoMode = konicawc_set_video_mode;
931 cbTbl.startDataPump = konicawc_start_data;
932 cbTbl.stopDataPump = konicawc_stop_data;
933 cbTbl.adjustPicture = konicawc_adjust_picture;
934 cbTbl.userFree = konicawc_free_uvd;
935 return usbvideo_register(
936 &cams,
937 MAX_CAMERAS,
938 sizeof(struct konicawc),
939 "konicawc",
940 &cbTbl,
941 THIS_MODULE,
942 id_table);
943}
944
945
946static void __exit konicawc_cleanup(void)
947{
948 usbvideo_Deregister(&cams);
949}
950
951
952MODULE_DEVICE_TABLE(usb, id_table);
953
954MODULE_LICENSE("GPL");
955MODULE_AUTHOR("Simon Evans <spse@secret.org.uk>");
956MODULE_DESCRIPTION(DRIVER_DESC);
957module_param(speed, int, 0);
958MODULE_PARM_DESC(speed, "Initial speed: 0 (slowest) - 6 (fastest)");
959module_param(size, int, 0);
960MODULE_PARM_DESC(size, "Initial Size 0: 160x120 1: 160x136 2: 176x144 3: 320x240");
961module_param(brightness, int, 0);
962MODULE_PARM_DESC(brightness, "Initial brightness 0 - 108");
963module_param(contrast, int, 0);
964MODULE_PARM_DESC(contrast, "Initial contrast 0 - 108");
965module_param(saturation, int, 0);
966MODULE_PARM_DESC(saturation, "Initial saturation 0 - 108");
967module_param(sharpness, int, 0);
968MODULE_PARM_DESC(sharpness, "Initial brightness 0 - 108");
969module_param(whitebal, int, 0);
970MODULE_PARM_DESC(whitebal, "Initial white balance 0 - 363");
971
972#ifdef CONFIG_USB_DEBUG
973module_param(debug, int, S_IRUGO | S_IWUSR);
974MODULE_PARM_DESC(debug, "Debug level: 0-9 (default=0)");
975#endif
976
977module_init(konicawc_init);
978module_exit(konicawc_cleanup);
diff --git a/drivers/media/video/usbvideo/ultracam.c b/drivers/media/video/usbvideo/ultracam.c
new file mode 100644
index 000000000000..75ff755224df
--- /dev/null
+++ b/drivers/media/video/usbvideo/ultracam.c
@@ -0,0 +1,679 @@
1/*
2 * USB NB Camera driver
3 *
4 * HISTORY:
5 * 25-Dec-2002 Dmitri Removed lighting, sharpness parameters, methods.
6 */
7
8#include <linux/kernel.h>
9#include <linux/sched.h>
10#include <linux/module.h>
11#include <linux/init.h>
12
13#include "usbvideo.h"
14
15#define ULTRACAM_VENDOR_ID 0x0461
16#define ULTRACAM_PRODUCT_ID 0x0813
17
18#define MAX_CAMERAS 4 /* How many devices we allow to connect */
19
20/*
21 * This structure lives in uvd_t->user field.
22 */
23typedef struct {
24 int initialized; /* Had we already sent init sequence? */
25 int camera_model; /* What type of IBM camera we got? */
26 int has_hdr;
27} ultracam_t;
28#define ULTRACAM_T(uvd) ((ultracam_t *)((uvd)->user_data))
29
30static struct usbvideo *cams = NULL;
31
32static int debug = 0;
33
34static int flags = 0; /* FLAGS_DISPLAY_HINTS | FLAGS_OVERLAY_STATS; */
35
36static const int min_canvasWidth = 8;
37static const int min_canvasHeight = 4;
38
39#define FRAMERATE_MIN 0
40#define FRAMERATE_MAX 6
41static int framerate = -1;
42
43/*
44 * Here we define several initialization variables. They may
45 * be used to automatically set color, hue, brightness and
46 * contrast to desired values. This is particularly useful in
47 * case of webcams (which have no controls and no on-screen
48 * output) and also when a client V4L software is used that
49 * does not have some of those controls. In any case it's
50 * good to have startup values as options.
51 *
52 * These values are all in [0..255] range. This simplifies
53 * operation. Note that actual values of V4L variables may
54 * be scaled up (as much as << 8). User can see that only
55 * on overlay output, however, or through a V4L client.
56 */
57static int init_brightness = 128;
58static int init_contrast = 192;
59static int init_color = 128;
60static int init_hue = 128;
61static int hue_correction = 128;
62
63module_param(debug, int, S_IRUGO | S_IWUSR);
64MODULE_PARM_DESC(debug, "Debug level: 0-9 (default=0)");
65module_param(flags, int, 0);
66MODULE_PARM_DESC(flags,
67 "Bitfield: 0=VIDIOCSYNC, "
68 "1=B/W, "
69 "2=show hints, "
70 "3=show stats, "
71 "4=test pattern, "
72 "5=separate frames, "
73 "6=clean frames");
74module_param(framerate, int, 0);
75MODULE_PARM_DESC(framerate, "Framerate setting: 0=slowest, 6=fastest (default=2)");
76
77module_param(init_brightness, int, 0);
78MODULE_PARM_DESC(init_brightness, "Brightness preconfiguration: 0-255 (default=128)");
79module_param(init_contrast, int, 0);
80MODULE_PARM_DESC(init_contrast, "Contrast preconfiguration: 0-255 (default=192)");
81module_param(init_color, int, 0);
82MODULE_PARM_DESC(init_color, "Color preconfiguration: 0-255 (default=128)");
83module_param(init_hue, int, 0);
84MODULE_PARM_DESC(init_hue, "Hue preconfiguration: 0-255 (default=128)");
85module_param(hue_correction, int, 0);
86MODULE_PARM_DESC(hue_correction, "YUV colorspace regulation: 0-255 (default=128)");
87
88/*
89 * ultracam_ProcessIsocData()
90 *
91 * Generic routine to parse the ring queue data. It employs either
92 * ultracam_find_header() or ultracam_parse_lines() to do most
93 * of work.
94 *
95 * 02-Nov-2000 First (mostly dummy) version.
96 * 06-Nov-2000 Rewrote to dump all data into frame.
97 */
98static void ultracam_ProcessIsocData(struct uvd *uvd, struct usbvideo_frame *frame)
99{
100 int n;
101
102 assert(uvd != NULL);
103 assert(frame != NULL);
104
105 /* Try to move data from queue into frame buffer */
106 n = RingQueue_GetLength(&uvd->dp);
107 if (n > 0) {
108 int m;
109 /* See how much spare we have left */
110 m = uvd->max_frame_size - frame->seqRead_Length;
111 if (n > m)
112 n = m;
113 /* Now move that much data into frame buffer */
114 RingQueue_Dequeue(
115 &uvd->dp,
116 frame->data + frame->seqRead_Length,
117 m);
118 frame->seqRead_Length += m;
119 }
120 /* See if we filled the frame */
121 if (frame->seqRead_Length >= uvd->max_frame_size) {
122 frame->frameState = FrameState_Done;
123 uvd->curframe = -1;
124 uvd->stats.frame_num++;
125 }
126}
127
128/*
129 * ultracam_veio()
130 *
131 * History:
132 * 1/27/00 Added check for dev == NULL; this happens if camera is unplugged.
133 */
134static int ultracam_veio(
135 struct uvd *uvd,
136 unsigned char req,
137 unsigned short value,
138 unsigned short index,
139 int is_out)
140{
141 static const char proc[] = "ultracam_veio";
142 unsigned char cp[8] /* = { 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef } */;
143 int i;
144
145 if (!CAMERA_IS_OPERATIONAL(uvd))
146 return 0;
147
148 if (!is_out) {
149 i = usb_control_msg(
150 uvd->dev,
151 usb_rcvctrlpipe(uvd->dev, 0),
152 req,
153 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
154 value,
155 index,
156 cp,
157 sizeof(cp),
158 1000);
159#if 1
160 info("USB => %02x%02x%02x%02x%02x%02x%02x%02x "
161 "(req=$%02x val=$%04x ind=$%04x)",
162 cp[0],cp[1],cp[2],cp[3],cp[4],cp[5],cp[6],cp[7],
163 req, value, index);
164#endif
165 } else {
166 i = usb_control_msg(
167 uvd->dev,
168 usb_sndctrlpipe(uvd->dev, 0),
169 req,
170 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
171 value,
172 index,
173 NULL,
174 0,
175 1000);
176 }
177 if (i < 0) {
178 err("%s: ERROR=%d. Camera stopped; Reconnect or reload driver.",
179 proc, i);
180 uvd->last_error = i;
181 }
182 return i;
183}
184
185/*
186 * ultracam_calculate_fps()
187 */
188static int ultracam_calculate_fps(struct uvd *uvd)
189{
190 return 3 + framerate*4 + framerate/2;
191}
192
193/*
194 * ultracam_adjust_contrast()
195 */
196static void ultracam_adjust_contrast(struct uvd *uvd)
197{
198}
199
200/*
201 * ultracam_set_brightness()
202 *
203 * This procedure changes brightness of the picture.
204 */
205static void ultracam_set_brightness(struct uvd *uvd)
206{
207}
208
209static void ultracam_set_hue(struct uvd *uvd)
210{
211}
212
213/*
214 * ultracam_adjust_picture()
215 *
216 * This procedure gets called from V4L interface to update picture settings.
217 * Here we change brightness and contrast.
218 */
219static void ultracam_adjust_picture(struct uvd *uvd)
220{
221 ultracam_adjust_contrast(uvd);
222 ultracam_set_brightness(uvd);
223 ultracam_set_hue(uvd);
224}
225
226/*
227 * ultracam_video_stop()
228 *
229 * This code tells camera to stop streaming. The interface remains
230 * configured and bandwidth - claimed.
231 */
232static void ultracam_video_stop(struct uvd *uvd)
233{
234}
235
236/*
237 * ultracam_reinit_iso()
238 *
239 * This procedure sends couple of commands to the camera and then
240 * resets the video pipe. This sequence was observed to reinit the
241 * camera or, at least, to initiate ISO data stream.
242 */
243static void ultracam_reinit_iso(struct uvd *uvd, int do_stop)
244{
245}
246
247static void ultracam_video_start(struct uvd *uvd)
248{
249 ultracam_reinit_iso(uvd, 0);
250}
251
252static int ultracam_resetPipe(struct uvd *uvd)
253{
254 usb_clear_halt(uvd->dev, uvd->video_endp);
255 return 0;
256}
257
258static int ultracam_alternateSetting(struct uvd *uvd, int setting)
259{
260 static const char proc[] = "ultracam_alternateSetting";
261 int i;
262 i = usb_set_interface(uvd->dev, uvd->iface, setting);
263 if (i < 0) {
264 err("%s: usb_set_interface error", proc);
265 uvd->last_error = i;
266 return -EBUSY;
267 }
268 return 0;
269}
270
271/*
272 * Return negative code on failure, 0 on success.
273 */
274static int ultracam_setup_on_open(struct uvd *uvd)
275{
276 int setup_ok = 0; /* Success by default */
277 /* Send init sequence only once, it's large! */
278 if (!ULTRACAM_T(uvd)->initialized) {
279 ultracam_alternateSetting(uvd, 0x04);
280 ultracam_alternateSetting(uvd, 0x00);
281 ultracam_veio(uvd, 0x02, 0x0004, 0x000b, 1);
282 ultracam_veio(uvd, 0x02, 0x0001, 0x0005, 1);
283 ultracam_veio(uvd, 0x02, 0x8000, 0x0000, 1);
284 ultracam_veio(uvd, 0x00, 0x0000, 0x0000, 1);
285 ultracam_veio(uvd, 0x00, 0x00b0, 0x0001, 1);
286 ultracam_veio(uvd, 0x00, 0x0000, 0x0002, 1);
287 ultracam_veio(uvd, 0x00, 0x000c, 0x0003, 1);
288 ultracam_veio(uvd, 0x00, 0x000b, 0x0004, 1);
289 ultracam_veio(uvd, 0x00, 0x0000, 0x0005, 1);
290 ultracam_veio(uvd, 0x00, 0x0000, 0x0006, 1);
291 ultracam_veio(uvd, 0x00, 0x0079, 0x0007, 1);
292 ultracam_veio(uvd, 0x00, 0x003b, 0x0008, 1);
293 ultracam_veio(uvd, 0x00, 0x0002, 0x000f, 1);
294 ultracam_veio(uvd, 0x00, 0x0001, 0x0010, 1);
295 ultracam_veio(uvd, 0x00, 0x0000, 0x0011, 1);
296 ultracam_veio(uvd, 0x00, 0x0000, 0x00bf, 1);
297 ultracam_veio(uvd, 0x00, 0x0001, 0x00c0, 1);
298 ultracam_veio(uvd, 0x00, 0x0010, 0x00cb, 1);
299 ultracam_veio(uvd, 0x01, 0x00a4, 0x0001, 1);
300 ultracam_veio(uvd, 0x01, 0x0010, 0x0002, 1);
301 ultracam_veio(uvd, 0x01, 0x0066, 0x0007, 1);
302 ultracam_veio(uvd, 0x01, 0x000b, 0x0008, 1);
303 ultracam_veio(uvd, 0x01, 0x0034, 0x0009, 1);
304 ultracam_veio(uvd, 0x01, 0x0000, 0x000a, 1);
305 ultracam_veio(uvd, 0x01, 0x002e, 0x000b, 1);
306 ultracam_veio(uvd, 0x01, 0x00d6, 0x000c, 1);
307 ultracam_veio(uvd, 0x01, 0x00fc, 0x000d, 1);
308 ultracam_veio(uvd, 0x01, 0x00f1, 0x000e, 1);
309 ultracam_veio(uvd, 0x01, 0x00da, 0x000f, 1);
310 ultracam_veio(uvd, 0x01, 0x0036, 0x0010, 1);
311 ultracam_veio(uvd, 0x01, 0x000b, 0x0011, 1);
312 ultracam_veio(uvd, 0x01, 0x0001, 0x0012, 1);
313 ultracam_veio(uvd, 0x01, 0x0000, 0x0013, 1);
314 ultracam_veio(uvd, 0x01, 0x0000, 0x0014, 1);
315 ultracam_veio(uvd, 0x01, 0x0087, 0x0051, 1);
316 ultracam_veio(uvd, 0x01, 0x0040, 0x0052, 1);
317 ultracam_veio(uvd, 0x01, 0x0058, 0x0053, 1);
318 ultracam_veio(uvd, 0x01, 0x0040, 0x0054, 1);
319 ultracam_veio(uvd, 0x01, 0x0000, 0x0040, 1);
320 ultracam_veio(uvd, 0x01, 0x0010, 0x0041, 1);
321 ultracam_veio(uvd, 0x01, 0x0020, 0x0042, 1);
322 ultracam_veio(uvd, 0x01, 0x0030, 0x0043, 1);
323 ultracam_veio(uvd, 0x01, 0x0040, 0x0044, 1);
324 ultracam_veio(uvd, 0x01, 0x0050, 0x0045, 1);
325 ultracam_veio(uvd, 0x01, 0x0060, 0x0046, 1);
326 ultracam_veio(uvd, 0x01, 0x0070, 0x0047, 1);
327 ultracam_veio(uvd, 0x01, 0x0080, 0x0048, 1);
328 ultracam_veio(uvd, 0x01, 0x0090, 0x0049, 1);
329 ultracam_veio(uvd, 0x01, 0x00a0, 0x004a, 1);
330 ultracam_veio(uvd, 0x01, 0x00b0, 0x004b, 1);
331 ultracam_veio(uvd, 0x01, 0x00c0, 0x004c, 1);
332 ultracam_veio(uvd, 0x01, 0x00d0, 0x004d, 1);
333 ultracam_veio(uvd, 0x01, 0x00e0, 0x004e, 1);
334 ultracam_veio(uvd, 0x01, 0x00f0, 0x004f, 1);
335 ultracam_veio(uvd, 0x01, 0x00ff, 0x0050, 1);
336 ultracam_veio(uvd, 0x01, 0x0000, 0x0056, 1);
337 ultracam_veio(uvd, 0x00, 0x0080, 0x00c1, 1);
338 ultracam_veio(uvd, 0x00, 0x0000, 0x00c2, 1);
339 ultracam_veio(uvd, 0x00, 0x0000, 0x00ca, 1);
340 ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
341 ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
342 ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
343 ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
344 ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
345 ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
346 ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
347 ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
348 ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
349 ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
350 ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
351 ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
352 ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
353 ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
354 ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
355 ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
356 ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
357 ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
358 ultracam_veio(uvd, 0x00, 0x0080, 0x00c1, 1);
359 ultracam_veio(uvd, 0x00, 0x0004, 0x00c2, 1);
360 ultracam_veio(uvd, 0x00, 0x0000, 0x00ca, 1);
361 ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
362 ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
363 ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
364 ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
365 ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
366 ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
367 ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
368 ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
369 ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
370 ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
371 ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
372 ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
373 ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
374 ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
375 ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
376 ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
377 ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
378 ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
379 ultracam_veio(uvd, 0x00, 0x0002, 0x00c1, 1);
380 ultracam_veio(uvd, 0x00, 0x0020, 0x00c2, 1);
381 ultracam_veio(uvd, 0x00, 0x0000, 0x00ca, 1);
382 ultracam_veio(uvd, 0x00, 0x0000, 0x00c3, 1);
383 ultracam_veio(uvd, 0x00, 0x0000, 0x00c4, 1);
384 ultracam_veio(uvd, 0x00, 0x0000, 0x00c5, 1);
385 ultracam_veio(uvd, 0x00, 0x0000, 0x00c6, 1);
386 ultracam_veio(uvd, 0x00, 0x0000, 0x00c7, 1);
387 ultracam_veio(uvd, 0x00, 0x0000, 0x00c8, 1);
388 ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
389 ultracam_veio(uvd, 0x00, 0x0000, 0x00c3, 1);
390 ultracam_veio(uvd, 0x00, 0x0000, 0x00c4, 1);
391 ultracam_veio(uvd, 0x00, 0x0000, 0x00c5, 1);
392 ultracam_veio(uvd, 0x00, 0x0000, 0x00c6, 1);
393 ultracam_veio(uvd, 0x00, 0x0000, 0x00c7, 1);
394 ultracam_veio(uvd, 0x00, 0x0000, 0x00c8, 1);
395 ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
396 ultracam_veio(uvd, 0x00, 0x0040, 0x00c1, 1);
397 ultracam_veio(uvd, 0x00, 0x0017, 0x00c2, 1);
398 ultracam_veio(uvd, 0x00, 0x0000, 0x00ca, 1);
399 ultracam_veio(uvd, 0x00, 0x0000, 0x00c3, 1);
400 ultracam_veio(uvd, 0x00, 0x0000, 0x00c4, 1);
401 ultracam_veio(uvd, 0x00, 0x0000, 0x00c5, 1);
402 ultracam_veio(uvd, 0x00, 0x0000, 0x00c6, 1);
403 ultracam_veio(uvd, 0x00, 0x0000, 0x00c7, 1);
404 ultracam_veio(uvd, 0x00, 0x0000, 0x00c8, 1);
405 ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
406 ultracam_veio(uvd, 0x00, 0x0000, 0x00c3, 1);
407 ultracam_veio(uvd, 0x00, 0x0000, 0x00c4, 1);
408 ultracam_veio(uvd, 0x00, 0x0000, 0x00c5, 1);
409 ultracam_veio(uvd, 0x00, 0x0000, 0x00c6, 1);
410 ultracam_veio(uvd, 0x00, 0x0000, 0x00c7, 1);
411 ultracam_veio(uvd, 0x00, 0x0000, 0x00c8, 1);
412 ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
413 ultracam_veio(uvd, 0x00, 0x00c0, 0x00c1, 1);
414 ultracam_veio(uvd, 0x00, 0x0000, 0x00c2, 1);
415 ultracam_veio(uvd, 0x00, 0x0000, 0x00ca, 1);
416 ultracam_veio(uvd, 0x02, 0xc040, 0x0001, 1);
417 ultracam_veio(uvd, 0x01, 0x0000, 0x0008, 0);
418 ultracam_veio(uvd, 0x01, 0x0000, 0x0009, 0);
419 ultracam_veio(uvd, 0x01, 0x0000, 0x000a, 0);
420 ultracam_veio(uvd, 0x01, 0x0000, 0x000b, 0);
421 ultracam_veio(uvd, 0x01, 0x0000, 0x000c, 0);
422 ultracam_veio(uvd, 0x01, 0x0000, 0x000d, 0);
423 ultracam_veio(uvd, 0x01, 0x0000, 0x000e, 0);
424 ultracam_veio(uvd, 0x01, 0x0000, 0x000f, 0);
425 ultracam_veio(uvd, 0x01, 0x0000, 0x0010, 0);
426 ultracam_veio(uvd, 0x01, 0x000b, 0x0008, 1);
427 ultracam_veio(uvd, 0x01, 0x0034, 0x0009, 1);
428 ultracam_veio(uvd, 0x01, 0x0000, 0x000a, 1);
429 ultracam_veio(uvd, 0x01, 0x002e, 0x000b, 1);
430 ultracam_veio(uvd, 0x01, 0x00d6, 0x000c, 1);
431 ultracam_veio(uvd, 0x01, 0x00fc, 0x000d, 1);
432 ultracam_veio(uvd, 0x01, 0x00f1, 0x000e, 1);
433 ultracam_veio(uvd, 0x01, 0x00da, 0x000f, 1);
434 ultracam_veio(uvd, 0x01, 0x0036, 0x0010, 1);
435 ultracam_veio(uvd, 0x01, 0x0000, 0x0001, 0);
436 ultracam_veio(uvd, 0x01, 0x0064, 0x0001, 1);
437 ultracam_veio(uvd, 0x01, 0x0059, 0x0051, 1);
438 ultracam_veio(uvd, 0x01, 0x003f, 0x0052, 1);
439 ultracam_veio(uvd, 0x01, 0x0094, 0x0053, 1);
440 ultracam_veio(uvd, 0x01, 0x00ff, 0x0011, 1);
441 ultracam_veio(uvd, 0x01, 0x0003, 0x0012, 1);
442 ultracam_veio(uvd, 0x01, 0x00f7, 0x0013, 1);
443 ultracam_veio(uvd, 0x00, 0x0009, 0x0011, 1);
444 ultracam_veio(uvd, 0x00, 0x0000, 0x0001, 1);
445 ultracam_veio(uvd, 0x00, 0x0000, 0x0000, 1);
446 ultracam_veio(uvd, 0x00, 0x0020, 0x00c1, 1);
447 ultracam_veio(uvd, 0x00, 0x0010, 0x00c2, 1);
448 ultracam_veio(uvd, 0x00, 0x0000, 0x00ca, 1);
449 ultracam_alternateSetting(uvd, 0x04);
450 ultracam_veio(uvd, 0x02, 0x0000, 0x0001, 1);
451 ultracam_veio(uvd, 0x02, 0x0000, 0x0001, 1);
452 ultracam_veio(uvd, 0x02, 0x0000, 0x0006, 1);
453 ultracam_veio(uvd, 0x02, 0x9000, 0x0007, 1);
454 ultracam_veio(uvd, 0x02, 0x0042, 0x0001, 1);
455 ultracam_veio(uvd, 0x02, 0x0000, 0x000b, 0);
456 ultracam_resetPipe(uvd);
457 ULTRACAM_T(uvd)->initialized = (setup_ok != 0);
458 }
459 return setup_ok;
460}
461
462static void ultracam_configure_video(struct uvd *uvd)
463{
464 if (uvd == NULL)
465 return;
466
467 RESTRICT_TO_RANGE(init_brightness, 0, 255);
468 RESTRICT_TO_RANGE(init_contrast, 0, 255);
469 RESTRICT_TO_RANGE(init_color, 0, 255);
470 RESTRICT_TO_RANGE(init_hue, 0, 255);
471 RESTRICT_TO_RANGE(hue_correction, 0, 255);
472
473 memset(&uvd->vpic, 0, sizeof(uvd->vpic));
474 memset(&uvd->vpic_old, 0x55, sizeof(uvd->vpic_old));
475
476 uvd->vpic.colour = init_color << 8;
477 uvd->vpic.hue = init_hue << 8;
478 uvd->vpic.brightness = init_brightness << 8;
479 uvd->vpic.contrast = init_contrast << 8;
480 uvd->vpic.whiteness = 105 << 8; /* This one isn't used */
481 uvd->vpic.depth = 24;
482 uvd->vpic.palette = VIDEO_PALETTE_RGB24;
483
484 memset(&uvd->vcap, 0, sizeof(uvd->vcap));
485 strcpy(uvd->vcap.name, "IBM Ultra Camera");
486 uvd->vcap.type = VID_TYPE_CAPTURE;
487 uvd->vcap.channels = 1;
488 uvd->vcap.audios = 0;
489 uvd->vcap.maxwidth = VIDEOSIZE_X(uvd->canvas);
490 uvd->vcap.maxheight = VIDEOSIZE_Y(uvd->canvas);
491 uvd->vcap.minwidth = min_canvasWidth;
492 uvd->vcap.minheight = min_canvasHeight;
493
494 memset(&uvd->vchan, 0, sizeof(uvd->vchan));
495 uvd->vchan.flags = 0;
496 uvd->vchan.tuners = 0;
497 uvd->vchan.channel = 0;
498 uvd->vchan.type = VIDEO_TYPE_CAMERA;
499 strcpy(uvd->vchan.name, "Camera");
500}
501
502/*
503 * ultracam_probe()
504 *
505 * This procedure queries device descriptor and accepts the interface
506 * if it looks like our camera.
507 *
508 * History:
509 * 12-Nov-2000 Reworked to comply with new probe() signature.
510 * 23-Jan-2001 Added compatibility with 2.2.x kernels.
511 */
512static int ultracam_probe(struct usb_interface *intf, const struct usb_device_id *devid)
513{
514 struct usb_device *dev = interface_to_usbdev(intf);
515 struct uvd *uvd = NULL;
516 int ix, i, nas;
517 int actInterface=-1, inactInterface=-1, maxPS=0;
518 unsigned char video_ep = 0;
519
520 if (debug >= 1)
521 info("ultracam_probe(%p)", intf);
522
523 /* We don't handle multi-config cameras */
524 if (dev->descriptor.bNumConfigurations != 1)
525 return -ENODEV;
526
527 info("IBM Ultra camera found (rev. 0x%04x)",
528 le16_to_cpu(dev->descriptor.bcdDevice));
529
530 /* Validate found interface: must have one ISO endpoint */
531 nas = intf->num_altsetting;
532 if (debug > 0)
533 info("Number of alternate settings=%d.", nas);
534 if (nas < 8) {
535 err("Too few alternate settings for this camera!");
536 return -ENODEV;
537 }
538 /* Validate all alternate settings */
539 for (ix=0; ix < nas; ix++) {
540 const struct usb_host_interface *interface;
541 const struct usb_endpoint_descriptor *endpoint;
542
543 interface = &intf->altsetting[ix];
544 i = interface->desc.bAlternateSetting;
545 if (interface->desc.bNumEndpoints != 1) {
546 err("Interface %d. has %u. endpoints!",
547 interface->desc.bInterfaceNumber,
548 (unsigned)(interface->desc.bNumEndpoints));
549 return -ENODEV;
550 }
551 endpoint = &interface->endpoint[0].desc;
552 if (video_ep == 0)
553 video_ep = endpoint->bEndpointAddress;
554 else if (video_ep != endpoint->bEndpointAddress) {
555 err("Alternate settings have different endpoint addresses!");
556 return -ENODEV;
557 }
558 if ((endpoint->bmAttributes & 0x03) != 0x01) {
559 err("Interface %d. has non-ISO endpoint!",
560 interface->desc.bInterfaceNumber);
561 return -ENODEV;
562 }
563 if ((endpoint->bEndpointAddress & 0x80) == 0) {
564 err("Interface %d. has ISO OUT endpoint!",
565 interface->desc.bInterfaceNumber);
566 return -ENODEV;
567 }
568 if (le16_to_cpu(endpoint->wMaxPacketSize) == 0) {
569 if (inactInterface < 0)
570 inactInterface = i;
571 else {
572 err("More than one inactive alt. setting!");
573 return -ENODEV;
574 }
575 } else {
576 if (actInterface < 0) {
577 actInterface = i;
578 maxPS = le16_to_cpu(endpoint->wMaxPacketSize);
579 if (debug > 0)
580 info("Active setting=%d. maxPS=%d.", i, maxPS);
581 } else {
582 /* Got another active alt. setting */
583 if (maxPS < le16_to_cpu(endpoint->wMaxPacketSize)) {
584 /* This one is better! */
585 actInterface = i;
586 maxPS = le16_to_cpu(endpoint->wMaxPacketSize);
587 if (debug > 0) {
588 info("Even better ctive setting=%d. maxPS=%d.",
589 i, maxPS);
590 }
591 }
592 }
593 }
594 }
595 if ((maxPS <= 0) || (actInterface < 0) || (inactInterface < 0)) {
596 err("Failed to recognize the camera!");
597 return -ENODEV;
598 }
599
600 uvd = usbvideo_AllocateDevice(cams);
601 if (uvd != NULL) {
602 /* Here uvd is a fully allocated uvd object */
603 uvd->flags = flags;
604 uvd->debug = debug;
605 uvd->dev = dev;
606 uvd->iface = intf->altsetting->desc.bInterfaceNumber;
607 uvd->ifaceAltInactive = inactInterface;
608 uvd->ifaceAltActive = actInterface;
609 uvd->video_endp = video_ep;
610 uvd->iso_packet_len = maxPS;
611 uvd->paletteBits = 1L << VIDEO_PALETTE_RGB24;
612 uvd->defaultPalette = VIDEO_PALETTE_RGB24;
613 uvd->canvas = VIDEOSIZE(640, 480); /* FIXME */
614 uvd->videosize = uvd->canvas; /* ultracam_size_to_videosize(size);*/
615
616 /* Initialize ibmcam-specific data */
617 assert(ULTRACAM_T(uvd) != NULL);
618 ULTRACAM_T(uvd)->camera_model = 0; /* Not used yet */
619 ULTRACAM_T(uvd)->initialized = 0;
620
621 ultracam_configure_video(uvd);
622
623 i = usbvideo_RegisterVideoDevice(uvd);
624 if (i != 0) {
625 err("usbvideo_RegisterVideoDevice() failed.");
626 uvd = NULL;
627 }
628 }
629
630 if (uvd) {
631 usb_set_intfdata (intf, uvd);
632 return 0;
633 }
634 return -EIO;
635}
636
637
638static struct usb_device_id id_table[] = {
639 { USB_DEVICE(ULTRACAM_VENDOR_ID, ULTRACAM_PRODUCT_ID) },
640 { } /* Terminating entry */
641};
642
643/*
644 * ultracam_init()
645 *
646 * This code is run to initialize the driver.
647 */
648static int __init ultracam_init(void)
649{
650 struct usbvideo_cb cbTbl;
651 memset(&cbTbl, 0, sizeof(cbTbl));
652 cbTbl.probe = ultracam_probe;
653 cbTbl.setupOnOpen = ultracam_setup_on_open;
654 cbTbl.videoStart = ultracam_video_start;
655 cbTbl.videoStop = ultracam_video_stop;
656 cbTbl.processData = ultracam_ProcessIsocData;
657 cbTbl.postProcess = usbvideo_DeinterlaceFrame;
658 cbTbl.adjustPicture = ultracam_adjust_picture;
659 cbTbl.getFPS = ultracam_calculate_fps;
660 return usbvideo_register(
661 &cams,
662 MAX_CAMERAS,
663 sizeof(ultracam_t),
664 "ultracam",
665 &cbTbl,
666 THIS_MODULE,
667 id_table);
668}
669
670static void __exit ultracam_cleanup(void)
671{
672 usbvideo_Deregister(&cams);
673}
674
675MODULE_DEVICE_TABLE(usb, id_table);
676MODULE_LICENSE("GPL");
677
678module_init(ultracam_init);
679module_exit(ultracam_cleanup);
diff --git a/drivers/media/video/usbvideo/usbvideo.c b/drivers/media/video/usbvideo/usbvideo.c
new file mode 100644
index 000000000000..0b51fae720a9
--- /dev/null
+++ b/drivers/media/video/usbvideo/usbvideo.c
@@ -0,0 +1,2190 @@
1/*
2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation; either version 2, or (at your option)
5 * any later version.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
15 */
16
17#include <linux/kernel.h>
18#include <linux/sched.h>
19#include <linux/list.h>
20#include <linux/slab.h>
21#include <linux/module.h>
22#include <linux/mm.h>
23#include <linux/smp_lock.h>
24#include <linux/vmalloc.h>
25#include <linux/init.h>
26#include <linux/spinlock.h>
27
28#include <asm/io.h>
29
30#include "usbvideo.h"
31
32#if defined(MAP_NR)
33#define virt_to_page(v) MAP_NR(v) /* Kernels 2.2.x */
34#endif
35
36static int video_nr = -1;
37module_param(video_nr, int, 0);
38
39/*
40 * Local prototypes.
41 */
42static void usbvideo_Disconnect(struct usb_interface *intf);
43static void usbvideo_CameraRelease(struct uvd *uvd);
44
45static int usbvideo_v4l_ioctl(struct inode *inode, struct file *file,
46 unsigned int cmd, unsigned long arg);
47static int usbvideo_v4l_mmap(struct file *file, struct vm_area_struct *vma);
48static int usbvideo_v4l_open(struct inode *inode, struct file *file);
49static ssize_t usbvideo_v4l_read(struct file *file, char __user *buf,
50 size_t count, loff_t *ppos);
51static int usbvideo_v4l_close(struct inode *inode, struct file *file);
52
53static int usbvideo_StartDataPump(struct uvd *uvd);
54static void usbvideo_StopDataPump(struct uvd *uvd);
55static int usbvideo_GetFrame(struct uvd *uvd, int frameNum);
56static int usbvideo_NewFrame(struct uvd *uvd, int framenum);
57static void usbvideo_SoftwareContrastAdjustment(struct uvd *uvd,
58 struct usbvideo_frame *frame);
59
60/*******************************/
61/* Memory management functions */
62/*******************************/
63static void *usbvideo_rvmalloc(unsigned long size)
64{
65 void *mem;
66 unsigned long adr;
67
68 size = PAGE_ALIGN(size);
69 mem = vmalloc_32(size);
70 if (!mem)
71 return NULL;
72
73 memset(mem, 0, size); /* Clear the ram out, no junk to the user */
74 adr = (unsigned long) mem;
75 while (size > 0) {
76 SetPageReserved(vmalloc_to_page((void *)adr));
77 adr += PAGE_SIZE;
78 size -= PAGE_SIZE;
79 }
80
81 return mem;
82}
83
84static void usbvideo_rvfree(void *mem, unsigned long size)
85{
86 unsigned long adr;
87
88 if (!mem)
89 return;
90
91 adr = (unsigned long) mem;
92 while ((long) size > 0) {
93 ClearPageReserved(vmalloc_to_page((void *)adr));
94 adr += PAGE_SIZE;
95 size -= PAGE_SIZE;
96 }
97 vfree(mem);
98}
99
100static void RingQueue_Initialize(struct RingQueue *rq)
101{
102 assert(rq != NULL);
103 init_waitqueue_head(&rq->wqh);
104}
105
106static void RingQueue_Allocate(struct RingQueue *rq, int rqLen)
107{
108 /* Make sure the requested size is a power of 2 and
109 round up if necessary. This allows index wrapping
110 using masks rather than modulo */
111
112 int i = 1;
113 assert(rq != NULL);
114 assert(rqLen > 0);
115
116 while(rqLen >> i)
117 i++;
118 if(rqLen != 1 << (i-1))
119 rqLen = 1 << i;
120
121 rq->length = rqLen;
122 rq->ri = rq->wi = 0;
123 rq->queue = usbvideo_rvmalloc(rq->length);
124 assert(rq->queue != NULL);
125}
126
127static int RingQueue_IsAllocated(const struct RingQueue *rq)
128{
129 if (rq == NULL)
130 return 0;
131 return (rq->queue != NULL) && (rq->length > 0);
132}
133
134static void RingQueue_Free(struct RingQueue *rq)
135{
136 assert(rq != NULL);
137 if (RingQueue_IsAllocated(rq)) {
138 usbvideo_rvfree(rq->queue, rq->length);
139 rq->queue = NULL;
140 rq->length = 0;
141 }
142}
143
144int RingQueue_Dequeue(struct RingQueue *rq, unsigned char *dst, int len)
145{
146 int rql, toread;
147
148 assert(rq != NULL);
149 assert(dst != NULL);
150
151 rql = RingQueue_GetLength(rq);
152 if(!rql)
153 return 0;
154
155 /* Clip requested length to available data */
156 if(len > rql)
157 len = rql;
158
159 toread = len;
160 if(rq->ri > rq->wi) {
161 /* Read data from tail */
162 int read = (toread < (rq->length - rq->ri)) ? toread : rq->length - rq->ri;
163 memcpy(dst, rq->queue + rq->ri, read);
164 toread -= read;
165 dst += read;
166 rq->ri = (rq->ri + read) & (rq->length-1);
167 }
168 if(toread) {
169 /* Read data from head */
170 memcpy(dst, rq->queue + rq->ri, toread);
171 rq->ri = (rq->ri + toread) & (rq->length-1);
172 }
173 return len;
174}
175
176EXPORT_SYMBOL(RingQueue_Dequeue);
177
178int RingQueue_Enqueue(struct RingQueue *rq, const unsigned char *cdata, int n)
179{
180 int enqueued = 0;
181
182 assert(rq != NULL);
183 assert(cdata != NULL);
184 assert(rq->length > 0);
185 while (n > 0) {
186 int m, q_avail;
187
188 /* Calculate the largest chunk that fits the tail of the ring */
189 q_avail = rq->length - rq->wi;
190 if (q_avail <= 0) {
191 rq->wi = 0;
192 q_avail = rq->length;
193 }
194 m = n;
195 assert(q_avail > 0);
196 if (m > q_avail)
197 m = q_avail;
198
199 memcpy(rq->queue + rq->wi, cdata, m);
200 RING_QUEUE_ADVANCE_INDEX(rq, wi, m);
201 cdata += m;
202 enqueued += m;
203 n -= m;
204 }
205 return enqueued;
206}
207
208EXPORT_SYMBOL(RingQueue_Enqueue);
209
210static void RingQueue_InterruptibleSleepOn(struct RingQueue *rq)
211{
212 assert(rq != NULL);
213 interruptible_sleep_on(&rq->wqh);
214}
215
216void RingQueue_WakeUpInterruptible(struct RingQueue *rq)
217{
218 assert(rq != NULL);
219 if (waitqueue_active(&rq->wqh))
220 wake_up_interruptible(&rq->wqh);
221}
222
223EXPORT_SYMBOL(RingQueue_WakeUpInterruptible);
224
225void RingQueue_Flush(struct RingQueue *rq)
226{
227 assert(rq != NULL);
228 rq->ri = 0;
229 rq->wi = 0;
230}
231
232EXPORT_SYMBOL(RingQueue_Flush);
233
234
235/*
236 * usbvideo_VideosizeToString()
237 *
238 * This procedure converts given videosize value to readable string.
239 *
240 * History:
241 * 07-Aug-2000 Created.
242 * 19-Oct-2000 Reworked for usbvideo module.
243 */
244static void usbvideo_VideosizeToString(char *buf, int bufLen, videosize_t vs)
245{
246 char tmp[40];
247 int n;
248
249 n = 1 + sprintf(tmp, "%ldx%ld", VIDEOSIZE_X(vs), VIDEOSIZE_Y(vs));
250 assert(n < sizeof(tmp));
251 if ((buf == NULL) || (bufLen < n))
252 err("usbvideo_VideosizeToString: buffer is too small.");
253 else
254 memmove(buf, tmp, n);
255}
256
257/*
258 * usbvideo_OverlayChar()
259 *
260 * History:
261 * 01-Feb-2000 Created.
262 */
263static void usbvideo_OverlayChar(struct uvd *uvd, struct usbvideo_frame *frame,
264 int x, int y, int ch)
265{
266 static const unsigned short digits[16] = {
267 0xF6DE, /* 0 */
268 0x2492, /* 1 */
269 0xE7CE, /* 2 */
270 0xE79E, /* 3 */
271 0xB792, /* 4 */
272 0xF39E, /* 5 */
273 0xF3DE, /* 6 */
274 0xF492, /* 7 */
275 0xF7DE, /* 8 */
276 0xF79E, /* 9 */
277 0x77DA, /* a */
278 0xD75C, /* b */
279 0xF24E, /* c */
280 0xD6DC, /* d */
281 0xF34E, /* e */
282 0xF348 /* f */
283 };
284 unsigned short digit;
285 int ix, iy;
286
287 if ((uvd == NULL) || (frame == NULL))
288 return;
289
290 if (ch >= '0' && ch <= '9')
291 ch -= '0';
292 else if (ch >= 'A' && ch <= 'F')
293 ch = 10 + (ch - 'A');
294 else if (ch >= 'a' && ch <= 'f')
295 ch = 10 + (ch - 'a');
296 else
297 return;
298 digit = digits[ch];
299
300 for (iy=0; iy < 5; iy++) {
301 for (ix=0; ix < 3; ix++) {
302 if (digit & 0x8000) {
303 if (uvd->paletteBits & (1L << VIDEO_PALETTE_RGB24)) {
304/* TODO */ RGB24_PUTPIXEL(frame, x+ix, y+iy, 0xFF, 0xFF, 0xFF);
305 }
306 }
307 digit = digit << 1;
308 }
309 }
310}
311
312/*
313 * usbvideo_OverlayString()
314 *
315 * History:
316 * 01-Feb-2000 Created.
317 */
318static void usbvideo_OverlayString(struct uvd *uvd, struct usbvideo_frame *frame,
319 int x, int y, const char *str)
320{
321 while (*str) {
322 usbvideo_OverlayChar(uvd, frame, x, y, *str);
323 str++;
324 x += 4; /* 3 pixels character + 1 space */
325 }
326}
327
328/*
329 * usbvideo_OverlayStats()
330 *
331 * Overlays important debugging information.
332 *
333 * History:
334 * 01-Feb-2000 Created.
335 */
336static void usbvideo_OverlayStats(struct uvd *uvd, struct usbvideo_frame *frame)
337{
338 const int y_diff = 8;
339 char tmp[16];
340 int x = 10, y=10;
341 long i, j, barLength;
342 const int qi_x1 = 60, qi_y1 = 10;
343 const int qi_x2 = VIDEOSIZE_X(frame->request) - 10, qi_h = 10;
344
345 /* Call the user callback, see if we may proceed after that */
346 if (VALID_CALLBACK(uvd, overlayHook)) {
347 if (GET_CALLBACK(uvd, overlayHook)(uvd, frame) < 0)
348 return;
349 }
350
351 /*
352 * We draw a (mostly) hollow rectangle with qi_xxx coordinates.
353 * Left edge symbolizes the queue index 0; right edge symbolizes
354 * the full capacity of the queue.
355 */
356 barLength = qi_x2 - qi_x1 - 2;
357 if ((barLength > 10) && (uvd->paletteBits & (1L << VIDEO_PALETTE_RGB24))) {
358/* TODO */ long u_lo, u_hi, q_used;
359 long m_ri, m_wi, m_lo, m_hi;
360
361 /*
362 * Determine fill zones (used areas of the queue):
363 * 0 xxxxxxx u_lo ...... uvd->dp.ri xxxxxxxx u_hi ..... uvd->dp.length
364 *
365 * if u_lo < 0 then there is no first filler.
366 */
367
368 q_used = RingQueue_GetLength(&uvd->dp);
369 if ((uvd->dp.ri + q_used) >= uvd->dp.length) {
370 u_hi = uvd->dp.length;
371 u_lo = (q_used + uvd->dp.ri) & (uvd->dp.length-1);
372 } else {
373 u_hi = (q_used + uvd->dp.ri);
374 u_lo = -1;
375 }
376
377 /* Convert byte indices into screen units */
378 m_ri = qi_x1 + ((barLength * uvd->dp.ri) / uvd->dp.length);
379 m_wi = qi_x1 + ((barLength * uvd->dp.wi) / uvd->dp.length);
380 m_lo = (u_lo > 0) ? (qi_x1 + ((barLength * u_lo) / uvd->dp.length)) : -1;
381 m_hi = qi_x1 + ((barLength * u_hi) / uvd->dp.length);
382
383 for (j=qi_y1; j < (qi_y1 + qi_h); j++) {
384 for (i=qi_x1; i < qi_x2; i++) {
385 /* Draw border lines */
386 if ((j == qi_y1) || (j == (qi_y1 + qi_h - 1)) ||
387 (i == qi_x1) || (i == (qi_x2 - 1))) {
388 RGB24_PUTPIXEL(frame, i, j, 0xFF, 0xFF, 0xFF);
389 continue;
390 }
391 /* For all other points the Y coordinate does not matter */
392 if ((i >= m_ri) && (i <= (m_ri + 3))) {
393 RGB24_PUTPIXEL(frame, i, j, 0x00, 0xFF, 0x00);
394 } else if ((i >= m_wi) && (i <= (m_wi + 3))) {
395 RGB24_PUTPIXEL(frame, i, j, 0xFF, 0x00, 0x00);
396 } else if ((i < m_lo) || ((i > m_ri) && (i < m_hi)))
397 RGB24_PUTPIXEL(frame, i, j, 0x00, 0x00, 0xFF);
398 }
399 }
400 }
401
402 sprintf(tmp, "%8lx", uvd->stats.frame_num);
403 usbvideo_OverlayString(uvd, frame, x, y, tmp);
404 y += y_diff;
405
406 sprintf(tmp, "%8lx", uvd->stats.urb_count);
407 usbvideo_OverlayString(uvd, frame, x, y, tmp);
408 y += y_diff;
409
410 sprintf(tmp, "%8lx", uvd->stats.urb_length);
411 usbvideo_OverlayString(uvd, frame, x, y, tmp);
412 y += y_diff;
413
414 sprintf(tmp, "%8lx", uvd->stats.data_count);
415 usbvideo_OverlayString(uvd, frame, x, y, tmp);
416 y += y_diff;
417
418 sprintf(tmp, "%8lx", uvd->stats.header_count);
419 usbvideo_OverlayString(uvd, frame, x, y, tmp);
420 y += y_diff;
421
422 sprintf(tmp, "%8lx", uvd->stats.iso_skip_count);
423 usbvideo_OverlayString(uvd, frame, x, y, tmp);
424 y += y_diff;
425
426 sprintf(tmp, "%8lx", uvd->stats.iso_err_count);
427 usbvideo_OverlayString(uvd, frame, x, y, tmp);
428 y += y_diff;
429
430 sprintf(tmp, "%8x", uvd->vpic.colour);
431 usbvideo_OverlayString(uvd, frame, x, y, tmp);
432 y += y_diff;
433
434 sprintf(tmp, "%8x", uvd->vpic.hue);
435 usbvideo_OverlayString(uvd, frame, x, y, tmp);
436 y += y_diff;
437
438 sprintf(tmp, "%8x", uvd->vpic.brightness >> 8);
439 usbvideo_OverlayString(uvd, frame, x, y, tmp);
440 y += y_diff;
441
442 sprintf(tmp, "%8x", uvd->vpic.contrast >> 12);
443 usbvideo_OverlayString(uvd, frame, x, y, tmp);
444 y += y_diff;
445
446 sprintf(tmp, "%8d", uvd->vpic.whiteness >> 8);
447 usbvideo_OverlayString(uvd, frame, x, y, tmp);
448 y += y_diff;
449}
450
451/*
452 * usbvideo_ReportStatistics()
453 *
454 * This procedure prints packet and transfer statistics.
455 *
456 * History:
457 * 14-Jan-2000 Corrected default multiplier.
458 */
459static void usbvideo_ReportStatistics(const struct uvd *uvd)
460{
461 if ((uvd != NULL) && (uvd->stats.urb_count > 0)) {
462 unsigned long allPackets, badPackets, goodPackets, percent;
463 allPackets = uvd->stats.urb_count * CAMERA_URB_FRAMES;
464 badPackets = uvd->stats.iso_skip_count + uvd->stats.iso_err_count;
465 goodPackets = allPackets - badPackets;
466 /* Calculate percentage wisely, remember integer limits */
467 assert(allPackets != 0);
468 if (goodPackets < (((unsigned long)-1)/100))
469 percent = (100 * goodPackets) / allPackets;
470 else
471 percent = goodPackets / (allPackets / 100);
472 info("Packet Statistics: Total=%lu. Empty=%lu. Usage=%lu%%",
473 allPackets, badPackets, percent);
474 if (uvd->iso_packet_len > 0) {
475 unsigned long allBytes, xferBytes;
476 char multiplier = ' ';
477 allBytes = allPackets * uvd->iso_packet_len;
478 xferBytes = uvd->stats.data_count;
479 assert(allBytes != 0);
480 if (xferBytes < (((unsigned long)-1)/100))
481 percent = (100 * xferBytes) / allBytes;
482 else
483 percent = xferBytes / (allBytes / 100);
484 /* Scale xferBytes for easy reading */
485 if (xferBytes > 10*1024) {
486 xferBytes /= 1024;
487 multiplier = 'K';
488 if (xferBytes > 10*1024) {
489 xferBytes /= 1024;
490 multiplier = 'M';
491 if (xferBytes > 10*1024) {
492 xferBytes /= 1024;
493 multiplier = 'G';
494 if (xferBytes > 10*1024) {
495 xferBytes /= 1024;
496 multiplier = 'T';
497 }
498 }
499 }
500 }
501 info("Transfer Statistics: Transferred=%lu%cB Usage=%lu%%",
502 xferBytes, multiplier, percent);
503 }
504 }
505}
506
507/*
508 * usbvideo_TestPattern()
509 *
510 * Procedure forms a test pattern (yellow grid on blue background).
511 *
512 * Parameters:
513 * fullframe: if TRUE then entire frame is filled, otherwise the procedure
514 * continues from the current scanline.
515 * pmode 0: fill the frame with solid blue color (like on VCR or TV)
516 * 1: Draw a colored grid
517 *
518 * History:
519 * 01-Feb-2000 Created.
520 */
521void usbvideo_TestPattern(struct uvd *uvd, int fullframe, int pmode)
522{
523 struct usbvideo_frame *frame;
524 int num_cell = 0;
525 int scan_length = 0;
526 static int num_pass = 0;
527
528 if (uvd == NULL) {
529 err("%s: uvd == NULL", __FUNCTION__);
530 return;
531 }
532 if ((uvd->curframe < 0) || (uvd->curframe >= USBVIDEO_NUMFRAMES)) {
533 err("%s: uvd->curframe=%d.", __FUNCTION__, uvd->curframe);
534 return;
535 }
536
537 /* Grab the current frame */
538 frame = &uvd->frame[uvd->curframe];
539
540 /* Optionally start at the beginning */
541 if (fullframe) {
542 frame->curline = 0;
543 frame->seqRead_Length = 0;
544 }
545#if 0
546 { /* For debugging purposes only */
547 char tmp[20];
548 usbvideo_VideosizeToString(tmp, sizeof(tmp), frame->request);
549 info("testpattern: frame=%s", tmp);
550 }
551#endif
552 /* Form every scan line */
553 for (; frame->curline < VIDEOSIZE_Y(frame->request); frame->curline++) {
554 int i;
555 unsigned char *f = frame->data +
556 (VIDEOSIZE_X(frame->request) * V4L_BYTES_PER_PIXEL * frame->curline);
557 for (i=0; i < VIDEOSIZE_X(frame->request); i++) {
558 unsigned char cb=0x80;
559 unsigned char cg = 0;
560 unsigned char cr = 0;
561
562 if (pmode == 1) {
563 if (frame->curline % 32 == 0)
564 cb = 0, cg = cr = 0xFF;
565 else if (i % 32 == 0) {
566 if (frame->curline % 32 == 1)
567 num_cell++;
568 cb = 0, cg = cr = 0xFF;
569 } else {
570 cb = ((num_cell*7) + num_pass) & 0xFF;
571 cg = ((num_cell*5) + num_pass*2) & 0xFF;
572 cr = ((num_cell*3) + num_pass*3) & 0xFF;
573 }
574 } else {
575 /* Just the blue screen */
576 }
577
578 *f++ = cb;
579 *f++ = cg;
580 *f++ = cr;
581 scan_length += 3;
582 }
583 }
584
585 frame->frameState = FrameState_Done;
586 frame->seqRead_Length += scan_length;
587 ++num_pass;
588
589 /* We do this unconditionally, regardless of FLAGS_OVERLAY_STATS */
590 usbvideo_OverlayStats(uvd, frame);
591}
592
593EXPORT_SYMBOL(usbvideo_TestPattern);
594
595
596#ifdef DEBUG
597/*
598 * usbvideo_HexDump()
599 *
600 * A debugging tool. Prints hex dumps.
601 *
602 * History:
603 * 29-Jul-2000 Added printing of offsets.
604 */
605void usbvideo_HexDump(const unsigned char *data, int len)
606{
607 const int bytes_per_line = 32;
608 char tmp[128]; /* 32*3 + 5 */
609 int i, k;
610
611 for (i=k=0; len > 0; i++, len--) {
612 if (i > 0 && ((i % bytes_per_line) == 0)) {
613 printk("%s\n", tmp);
614 k=0;
615 }
616 if ((i % bytes_per_line) == 0)
617 k += sprintf(&tmp[k], "%04x: ", i);
618 k += sprintf(&tmp[k], "%02x ", data[i]);
619 }
620 if (k > 0)
621 printk("%s\n", tmp);
622}
623
624EXPORT_SYMBOL(usbvideo_HexDump);
625
626#endif
627
628/* ******************************************************************** */
629
630/* XXX: this piece of crap really wants some error handling.. */
631static void usbvideo_ClientIncModCount(struct uvd *uvd)
632{
633 if (uvd == NULL) {
634 err("%s: uvd == NULL", __FUNCTION__);
635 return;
636 }
637 if (uvd->handle == NULL) {
638 err("%s: uvd->handle == NULL", __FUNCTION__);
639 return;
640 }
641 if (uvd->handle->md_module == NULL) {
642 err("%s: uvd->handle->md_module == NULL", __FUNCTION__);
643 return;
644 }
645 if (!try_module_get(uvd->handle->md_module)) {
646 err("%s: try_module_get() == 0", __FUNCTION__);
647 return;
648 }
649}
650
651static void usbvideo_ClientDecModCount(struct uvd *uvd)
652{
653 if (uvd == NULL) {
654 err("%s: uvd == NULL", __FUNCTION__);
655 return;
656 }
657 if (uvd->handle == NULL) {
658 err("%s: uvd->handle == NULL", __FUNCTION__);
659 return;
660 }
661 if (uvd->handle->md_module == NULL) {
662 err("%s: uvd->handle->md_module == NULL", __FUNCTION__);
663 return;
664 }
665 module_put(uvd->handle->md_module);
666}
667
668int usbvideo_register(
669 struct usbvideo **pCams,
670 const int num_cams,
671 const int num_extra,
672 const char *driverName,
673 const struct usbvideo_cb *cbTbl,
674 struct module *md,
675 const struct usb_device_id *id_table)
676{
677 struct usbvideo *cams;
678 int i, base_size, result;
679
680 /* Check parameters for sanity */
681 if ((num_cams <= 0) || (pCams == NULL) || (cbTbl == NULL)) {
682 err("%s: Illegal call", __FUNCTION__);
683 return -EINVAL;
684 }
685
686 /* Check registration callback - must be set! */
687 if (cbTbl->probe == NULL) {
688 err("%s: probe() is required!", __FUNCTION__);
689 return -EINVAL;
690 }
691
692 base_size = num_cams * sizeof(struct uvd) + sizeof(struct usbvideo);
693 cams = (struct usbvideo *) kzalloc(base_size, GFP_KERNEL);
694 if (cams == NULL) {
695 err("Failed to allocate %d. bytes for usbvideo struct", base_size);
696 return -ENOMEM;
697 }
698 dbg("%s: Allocated $%p (%d. bytes) for %d. cameras",
699 __FUNCTION__, cams, base_size, num_cams);
700
701 /* Copy callbacks, apply defaults for those that are not set */
702 memmove(&cams->cb, cbTbl, sizeof(cams->cb));
703 if (cams->cb.getFrame == NULL)
704 cams->cb.getFrame = usbvideo_GetFrame;
705 if (cams->cb.disconnect == NULL)
706 cams->cb.disconnect = usbvideo_Disconnect;
707 if (cams->cb.startDataPump == NULL)
708 cams->cb.startDataPump = usbvideo_StartDataPump;
709 if (cams->cb.stopDataPump == NULL)
710 cams->cb.stopDataPump = usbvideo_StopDataPump;
711
712 cams->num_cameras = num_cams;
713 cams->cam = (struct uvd *) &cams[1];
714 cams->md_module = md;
715 if (cams->md_module == NULL)
716 warn("%s: module == NULL!", __FUNCTION__);
717 mutex_init(&cams->lock); /* to 1 == available */
718
719 for (i = 0; i < num_cams; i++) {
720 struct uvd *up = &cams->cam[i];
721
722 up->handle = cams;
723
724 /* Allocate user_data separately because of kmalloc's limits */
725 if (num_extra > 0) {
726 up->user_size = num_cams * num_extra;
727 up->user_data = kmalloc(up->user_size, GFP_KERNEL);
728 if (up->user_data == NULL) {
729 err("%s: Failed to allocate user_data (%d. bytes)",
730 __FUNCTION__, up->user_size);
731 while (i) {
732 up = &cams->cam[--i];
733 kfree(up->user_data);
734 }
735 kfree(cams);
736 return -ENOMEM;
737 }
738 dbg("%s: Allocated cams[%d].user_data=$%p (%d. bytes)",
739 __FUNCTION__, i, up->user_data, up->user_size);
740 }
741 }
742
743 /*
744 * Register ourselves with USB stack.
745 */
746 strcpy(cams->drvName, (driverName != NULL) ? driverName : "Unknown");
747 cams->usbdrv.name = cams->drvName;
748 cams->usbdrv.probe = cams->cb.probe;
749 cams->usbdrv.disconnect = cams->cb.disconnect;
750 cams->usbdrv.id_table = id_table;
751
752 /*
753 * Update global handle to usbvideo. This is very important
754 * because probe() can be called before usb_register() returns.
755 * If the handle is not yet updated then the probe() will fail.
756 */
757 *pCams = cams;
758 result = usb_register(&cams->usbdrv);
759 if (result) {
760 for (i = 0; i < num_cams; i++) {
761 struct uvd *up = &cams->cam[i];
762 kfree(up->user_data);
763 }
764 kfree(cams);
765 }
766
767 return result;
768}
769
770EXPORT_SYMBOL(usbvideo_register);
771
772/*
773 * usbvideo_Deregister()
774 *
775 * Procedure frees all usbvideo and user data structures. Be warned that
776 * if you had some dynamically allocated components in ->user field then
777 * you should free them before calling here.
778 */
779void usbvideo_Deregister(struct usbvideo **pCams)
780{
781 struct usbvideo *cams;
782 int i;
783
784 if (pCams == NULL) {
785 err("%s: pCams == NULL", __FUNCTION__);
786 return;
787 }
788 cams = *pCams;
789 if (cams == NULL) {
790 err("%s: cams == NULL", __FUNCTION__);
791 return;
792 }
793
794 dbg("%s: Deregistering %s driver.", __FUNCTION__, cams->drvName);
795 usb_deregister(&cams->usbdrv);
796
797 dbg("%s: Deallocating cams=$%p (%d. cameras)", __FUNCTION__, cams, cams->num_cameras);
798 for (i=0; i < cams->num_cameras; i++) {
799 struct uvd *up = &cams->cam[i];
800 int warning = 0;
801
802 if (up->user_data != NULL) {
803 if (up->user_size <= 0)
804 ++warning;
805 } else {
806 if (up->user_size > 0)
807 ++warning;
808 }
809 if (warning) {
810 err("%s: Warning: user_data=$%p user_size=%d.",
811 __FUNCTION__, up->user_data, up->user_size);
812 } else {
813 dbg("%s: Freeing %d. $%p->user_data=$%p",
814 __FUNCTION__, i, up, up->user_data);
815 kfree(up->user_data);
816 }
817 }
818 /* Whole array was allocated in one chunk */
819 dbg("%s: Freed %d uvd structures",
820 __FUNCTION__, cams->num_cameras);
821 kfree(cams);
822 *pCams = NULL;
823}
824
825EXPORT_SYMBOL(usbvideo_Deregister);
826
827/*
828 * usbvideo_Disconnect()
829 *
830 * This procedure stops all driver activity. Deallocation of
831 * the interface-private structure (pointed by 'ptr') is done now
832 * (if we don't have any open files) or later, when those files
833 * are closed. After that driver should be removable.
834 *
835 * This code handles surprise removal. The uvd->user is a counter which
836 * increments on open() and decrements on close(). If we see here that
837 * this counter is not 0 then we have a client who still has us opened.
838 * We set uvd->remove_pending flag as early as possible, and after that
839 * all access to the camera will gracefully fail. These failures should
840 * prompt client to (eventually) close the video device, and then - in
841 * usbvideo_v4l_close() - we decrement uvd->uvd_used and usage counter.
842 *
843 * History:
844 * 22-Jan-2000 Added polling of MOD_IN_USE to delay removal until all users gone.
845 * 27-Jan-2000 Reworked to allow pending disconnects; see xxx_close()
846 * 24-May-2000 Corrected to prevent race condition (MOD_xxx_USE_COUNT).
847 * 19-Oct-2000 Moved to usbvideo module.
848 */
849static void usbvideo_Disconnect(struct usb_interface *intf)
850{
851 struct uvd *uvd = usb_get_intfdata (intf);
852 int i;
853
854 if (uvd == NULL) {
855 err("%s($%p): Illegal call.", __FUNCTION__, intf);
856 return;
857 }
858
859 usb_set_intfdata (intf, NULL);
860
861 usbvideo_ClientIncModCount(uvd);
862 if (uvd->debug > 0)
863 info("%s(%p.)", __FUNCTION__, intf);
864
865 mutex_lock(&uvd->lock);
866 uvd->remove_pending = 1; /* Now all ISO data will be ignored */
867
868 /* At this time we ask to cancel outstanding URBs */
869 GET_CALLBACK(uvd, stopDataPump)(uvd);
870
871 for (i=0; i < USBVIDEO_NUMSBUF; i++)
872 usb_free_urb(uvd->sbuf[i].urb);
873
874 usb_put_dev(uvd->dev);
875 uvd->dev = NULL; /* USB device is no more */
876
877 video_unregister_device(&uvd->vdev);
878 if (uvd->debug > 0)
879 info("%s: Video unregistered.", __FUNCTION__);
880
881 if (uvd->user)
882 info("%s: In use, disconnect pending.", __FUNCTION__);
883 else
884 usbvideo_CameraRelease(uvd);
885 mutex_unlock(&uvd->lock);
886 info("USB camera disconnected.");
887
888 usbvideo_ClientDecModCount(uvd);
889}
890
891/*
892 * usbvideo_CameraRelease()
893 *
894 * This code does final release of uvd. This happens
895 * after the device is disconnected -and- all clients
896 * closed their files.
897 *
898 * History:
899 * 27-Jan-2000 Created.
900 */
901static void usbvideo_CameraRelease(struct uvd *uvd)
902{
903 if (uvd == NULL) {
904 err("%s: Illegal call", __FUNCTION__);
905 return;
906 }
907
908 RingQueue_Free(&uvd->dp);
909 if (VALID_CALLBACK(uvd, userFree))
910 GET_CALLBACK(uvd, userFree)(uvd);
911 uvd->uvd_used = 0; /* This is atomic, no need to take mutex */
912}
913
914/*
915 * usbvideo_find_struct()
916 *
917 * This code searches the array of preallocated (static) structures
918 * and returns index of the first one that isn't in use. Returns -1
919 * if there are no free structures.
920 *
921 * History:
922 * 27-Jan-2000 Created.
923 */
924static int usbvideo_find_struct(struct usbvideo *cams)
925{
926 int u, rv = -1;
927
928 if (cams == NULL) {
929 err("No usbvideo handle?");
930 return -1;
931 }
932 mutex_lock(&cams->lock);
933 for (u = 0; u < cams->num_cameras; u++) {
934 struct uvd *uvd = &cams->cam[u];
935 if (!uvd->uvd_used) /* This one is free */
936 {
937 uvd->uvd_used = 1; /* In use now */
938 mutex_init(&uvd->lock); /* to 1 == available */
939 uvd->dev = NULL;
940 rv = u;
941 break;
942 }
943 }
944 mutex_unlock(&cams->lock);
945 return rv;
946}
947
948static struct file_operations usbvideo_fops = {
949 .owner = THIS_MODULE,
950 .open = usbvideo_v4l_open,
951 .release =usbvideo_v4l_close,
952 .read = usbvideo_v4l_read,
953 .mmap = usbvideo_v4l_mmap,
954 .ioctl = usbvideo_v4l_ioctl,
955 .compat_ioctl = v4l_compat_ioctl32,
956 .llseek = no_llseek,
957};
958static const struct video_device usbvideo_template = {
959 .owner = THIS_MODULE,
960 .type = VID_TYPE_CAPTURE,
961 .hardware = VID_HARDWARE_CPIA,
962 .fops = &usbvideo_fops,
963};
964
965struct uvd *usbvideo_AllocateDevice(struct usbvideo *cams)
966{
967 int i, devnum;
968 struct uvd *uvd = NULL;
969
970 if (cams == NULL) {
971 err("No usbvideo handle?");
972 return NULL;
973 }
974
975 devnum = usbvideo_find_struct(cams);
976 if (devnum == -1) {
977 err("IBM USB camera driver: Too many devices!");
978 return NULL;
979 }
980 uvd = &cams->cam[devnum];
981 dbg("Device entry #%d. at $%p", devnum, uvd);
982
983 /* Not relying upon caller we increase module counter ourselves */
984 usbvideo_ClientIncModCount(uvd);
985
986 mutex_lock(&uvd->lock);
987 for (i=0; i < USBVIDEO_NUMSBUF; i++) {
988 uvd->sbuf[i].urb = usb_alloc_urb(FRAMES_PER_DESC, GFP_KERNEL);
989 if (uvd->sbuf[i].urb == NULL) {
990 err("usb_alloc_urb(%d.) failed.", FRAMES_PER_DESC);
991 uvd->uvd_used = 0;
992 uvd = NULL;
993 goto allocate_done;
994 }
995 }
996 uvd->user=0;
997 uvd->remove_pending = 0;
998 uvd->last_error = 0;
999 RingQueue_Initialize(&uvd->dp);
1000
1001 /* Initialize video device structure */
1002 uvd->vdev = usbvideo_template;
1003 sprintf(uvd->vdev.name, "%.20s USB Camera", cams->drvName);
1004 /*
1005 * The client is free to overwrite those because we
1006 * return control to the client's probe function right now.
1007 */
1008allocate_done:
1009 mutex_unlock(&uvd->lock);
1010 usbvideo_ClientDecModCount(uvd);
1011 return uvd;
1012}
1013
1014EXPORT_SYMBOL(usbvideo_AllocateDevice);
1015
1016int usbvideo_RegisterVideoDevice(struct uvd *uvd)
1017{
1018 char tmp1[20], tmp2[20]; /* Buffers for printing */
1019
1020 if (uvd == NULL) {
1021 err("%s: Illegal call.", __FUNCTION__);
1022 return -EINVAL;
1023 }
1024 if (uvd->video_endp == 0) {
1025 info("%s: No video endpoint specified; data pump disabled.", __FUNCTION__);
1026 }
1027 if (uvd->paletteBits == 0) {
1028 err("%s: No palettes specified!", __FUNCTION__);
1029 return -EINVAL;
1030 }
1031 if (uvd->defaultPalette == 0) {
1032 info("%s: No default palette!", __FUNCTION__);
1033 }
1034
1035 uvd->max_frame_size = VIDEOSIZE_X(uvd->canvas) *
1036 VIDEOSIZE_Y(uvd->canvas) * V4L_BYTES_PER_PIXEL;
1037 usbvideo_VideosizeToString(tmp1, sizeof(tmp1), uvd->videosize);
1038 usbvideo_VideosizeToString(tmp2, sizeof(tmp2), uvd->canvas);
1039
1040 if (uvd->debug > 0) {
1041 info("%s: iface=%d. endpoint=$%02x paletteBits=$%08lx",
1042 __FUNCTION__, uvd->iface, uvd->video_endp, uvd->paletteBits);
1043 }
1044 if (video_register_device(&uvd->vdev, VFL_TYPE_GRABBER, video_nr) == -1) {
1045 err("%s: video_register_device failed", __FUNCTION__);
1046 return -EPIPE;
1047 }
1048 if (uvd->debug > 1) {
1049 info("%s: video_register_device() successful", __FUNCTION__);
1050 }
1051 if (uvd->dev == NULL) {
1052 err("%s: uvd->dev == NULL", __FUNCTION__);
1053 return -EINVAL;
1054 }
1055
1056 info("%s on /dev/video%d: canvas=%s videosize=%s",
1057 (uvd->handle != NULL) ? uvd->handle->drvName : "???",
1058 uvd->vdev.minor, tmp2, tmp1);
1059
1060 usb_get_dev(uvd->dev);
1061 return 0;
1062}
1063
1064EXPORT_SYMBOL(usbvideo_RegisterVideoDevice);
1065
1066/* ******************************************************************** */
1067
1068static int usbvideo_v4l_mmap(struct file *file, struct vm_area_struct *vma)
1069{
1070 struct uvd *uvd = file->private_data;
1071 unsigned long start = vma->vm_start;
1072 unsigned long size = vma->vm_end-vma->vm_start;
1073 unsigned long page, pos;
1074
1075 if (!CAMERA_IS_OPERATIONAL(uvd))
1076 return -EFAULT;
1077
1078 if (size > (((USBVIDEO_NUMFRAMES * uvd->max_frame_size) + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1)))
1079 return -EINVAL;
1080
1081 pos = (unsigned long) uvd->fbuf;
1082 while (size > 0) {
1083 page = vmalloc_to_pfn((void *)pos);
1084 if (remap_pfn_range(vma, start, page, PAGE_SIZE, PAGE_SHARED))
1085 return -EAGAIN;
1086
1087 start += PAGE_SIZE;
1088 pos += PAGE_SIZE;
1089 if (size > PAGE_SIZE)
1090 size -= PAGE_SIZE;
1091 else
1092 size = 0;
1093 }
1094
1095 return 0;
1096}
1097
1098/*
1099 * usbvideo_v4l_open()
1100 *
1101 * This is part of Video 4 Linux API. The driver can be opened by one
1102 * client only (checks internal counter 'uvdser'). The procedure
1103 * then allocates buffers needed for video processing.
1104 *
1105 * History:
1106 * 22-Jan-2000 Rewrote, moved scratch buffer allocation here. Now the
1107 * camera is also initialized here (once per connect), at
1108 * expense of V4L client (it waits on open() call).
1109 * 27-Jan-2000 Used USBVIDEO_NUMSBUF as number of URB buffers.
1110 * 24-May-2000 Corrected to prevent race condition (MOD_xxx_USE_COUNT).
1111 */
1112static int usbvideo_v4l_open(struct inode *inode, struct file *file)
1113{
1114 struct video_device *dev = video_devdata(file);
1115 struct uvd *uvd = (struct uvd *) dev;
1116 const int sb_size = FRAMES_PER_DESC * uvd->iso_packet_len;
1117 int i, errCode = 0;
1118
1119 if (uvd->debug > 1)
1120 info("%s($%p)", __FUNCTION__, dev);
1121
1122 usbvideo_ClientIncModCount(uvd);
1123 mutex_lock(&uvd->lock);
1124
1125 if (uvd->user) {
1126 err("%s: Someone tried to open an already opened device!", __FUNCTION__);
1127 errCode = -EBUSY;
1128 } else {
1129 /* Clear statistics */
1130 memset(&uvd->stats, 0, sizeof(uvd->stats));
1131
1132 /* Clean pointers so we know if we allocated something */
1133 for (i=0; i < USBVIDEO_NUMSBUF; i++)
1134 uvd->sbuf[i].data = NULL;
1135
1136 /* Allocate memory for the frame buffers */
1137 uvd->fbuf_size = USBVIDEO_NUMFRAMES * uvd->max_frame_size;
1138 uvd->fbuf = usbvideo_rvmalloc(uvd->fbuf_size);
1139 RingQueue_Allocate(&uvd->dp, RING_QUEUE_SIZE);
1140 if ((uvd->fbuf == NULL) ||
1141 (!RingQueue_IsAllocated(&uvd->dp))) {
1142 err("%s: Failed to allocate fbuf or dp", __FUNCTION__);
1143 errCode = -ENOMEM;
1144 } else {
1145 /* Allocate all buffers */
1146 for (i=0; i < USBVIDEO_NUMFRAMES; i++) {
1147 uvd->frame[i].frameState = FrameState_Unused;
1148 uvd->frame[i].data = uvd->fbuf + i*(uvd->max_frame_size);
1149 /*
1150 * Set default sizes in case IOCTL (VIDIOCMCAPTURE)
1151 * is not used (using read() instead).
1152 */
1153 uvd->frame[i].canvas = uvd->canvas;
1154 uvd->frame[i].seqRead_Index = 0;
1155 }
1156 for (i=0; i < USBVIDEO_NUMSBUF; i++) {
1157 uvd->sbuf[i].data = kmalloc(sb_size, GFP_KERNEL);
1158 if (uvd->sbuf[i].data == NULL) {
1159 errCode = -ENOMEM;
1160 break;
1161 }
1162 }
1163 }
1164 if (errCode != 0) {
1165 /* Have to free all that memory */
1166 if (uvd->fbuf != NULL) {
1167 usbvideo_rvfree(uvd->fbuf, uvd->fbuf_size);
1168 uvd->fbuf = NULL;
1169 }
1170 RingQueue_Free(&uvd->dp);
1171 for (i=0; i < USBVIDEO_NUMSBUF; i++) {
1172 kfree(uvd->sbuf[i].data);
1173 uvd->sbuf[i].data = NULL;
1174 }
1175 }
1176 }
1177
1178 /* If so far no errors then we shall start the camera */
1179 if (errCode == 0) {
1180 /* Start data pump if we have valid endpoint */
1181 if (uvd->video_endp != 0)
1182 errCode = GET_CALLBACK(uvd, startDataPump)(uvd);
1183 if (errCode == 0) {
1184 if (VALID_CALLBACK(uvd, setupOnOpen)) {
1185 if (uvd->debug > 1)
1186 info("%s: setupOnOpen callback", __FUNCTION__);
1187 errCode = GET_CALLBACK(uvd, setupOnOpen)(uvd);
1188 if (errCode < 0) {
1189 err("%s: setupOnOpen callback failed (%d.).",
1190 __FUNCTION__, errCode);
1191 } else if (uvd->debug > 1) {
1192 info("%s: setupOnOpen callback successful", __FUNCTION__);
1193 }
1194 }
1195 if (errCode == 0) {
1196 uvd->settingsAdjusted = 0;
1197 if (uvd->debug > 1)
1198 info("%s: Open succeeded.", __FUNCTION__);
1199 uvd->user++;
1200 file->private_data = uvd;
1201 }
1202 }
1203 }
1204 mutex_unlock(&uvd->lock);
1205 if (errCode != 0)
1206 usbvideo_ClientDecModCount(uvd);
1207 if (uvd->debug > 0)
1208 info("%s: Returning %d.", __FUNCTION__, errCode);
1209 return errCode;
1210}
1211
1212/*
1213 * usbvideo_v4l_close()
1214 *
1215 * This is part of Video 4 Linux API. The procedure
1216 * stops streaming and deallocates all buffers that were earlier
1217 * allocated in usbvideo_v4l_open().
1218 *
1219 * History:
1220 * 22-Jan-2000 Moved scratch buffer deallocation here.
1221 * 27-Jan-2000 Used USBVIDEO_NUMSBUF as number of URB buffers.
1222 * 24-May-2000 Moved MOD_DEC_USE_COUNT outside of code that can sleep.
1223 */
1224static int usbvideo_v4l_close(struct inode *inode, struct file *file)
1225{
1226 struct video_device *dev = file->private_data;
1227 struct uvd *uvd = (struct uvd *) dev;
1228 int i;
1229
1230 if (uvd->debug > 1)
1231 info("%s($%p)", __FUNCTION__, dev);
1232
1233 mutex_lock(&uvd->lock);
1234 GET_CALLBACK(uvd, stopDataPump)(uvd);
1235 usbvideo_rvfree(uvd->fbuf, uvd->fbuf_size);
1236 uvd->fbuf = NULL;
1237 RingQueue_Free(&uvd->dp);
1238
1239 for (i=0; i < USBVIDEO_NUMSBUF; i++) {
1240 kfree(uvd->sbuf[i].data);
1241 uvd->sbuf[i].data = NULL;
1242 }
1243
1244#if USBVIDEO_REPORT_STATS
1245 usbvideo_ReportStatistics(uvd);
1246#endif
1247
1248 uvd->user--;
1249 if (uvd->remove_pending) {
1250 if (uvd->debug > 0)
1251 info("usbvideo_v4l_close: Final disconnect.");
1252 usbvideo_CameraRelease(uvd);
1253 }
1254 mutex_unlock(&uvd->lock);
1255 usbvideo_ClientDecModCount(uvd);
1256
1257 if (uvd->debug > 1)
1258 info("%s: Completed.", __FUNCTION__);
1259 file->private_data = NULL;
1260 return 0;
1261}
1262
1263/*
1264 * usbvideo_v4l_ioctl()
1265 *
1266 * This is part of Video 4 Linux API. The procedure handles ioctl() calls.
1267 *
1268 * History:
1269 * 22-Jan-2000 Corrected VIDIOCSPICT to reject unsupported settings.
1270 */
1271static int usbvideo_v4l_do_ioctl(struct inode *inode, struct file *file,
1272 unsigned int cmd, void *arg)
1273{
1274 struct uvd *uvd = file->private_data;
1275
1276 if (!CAMERA_IS_OPERATIONAL(uvd))
1277 return -EIO;
1278
1279 switch (cmd) {
1280 case VIDIOCGCAP:
1281 {
1282 struct video_capability *b = arg;
1283 *b = uvd->vcap;
1284 return 0;
1285 }
1286 case VIDIOCGCHAN:
1287 {
1288 struct video_channel *v = arg;
1289 *v = uvd->vchan;
1290 return 0;
1291 }
1292 case VIDIOCSCHAN:
1293 {
1294 struct video_channel *v = arg;
1295 if (v->channel != 0)
1296 return -EINVAL;
1297 return 0;
1298 }
1299 case VIDIOCGPICT:
1300 {
1301 struct video_picture *pic = arg;
1302 *pic = uvd->vpic;
1303 return 0;
1304 }
1305 case VIDIOCSPICT:
1306 {
1307 struct video_picture *pic = arg;
1308 /*
1309 * Use temporary 'video_picture' structure to preserve our
1310 * own settings (such as color depth, palette) that we
1311 * aren't allowing everyone (V4L client) to change.
1312 */
1313 uvd->vpic.brightness = pic->brightness;
1314 uvd->vpic.hue = pic->hue;
1315 uvd->vpic.colour = pic->colour;
1316 uvd->vpic.contrast = pic->contrast;
1317 uvd->settingsAdjusted = 0; /* Will force new settings */
1318 return 0;
1319 }
1320 case VIDIOCSWIN:
1321 {
1322 struct video_window *vw = arg;
1323
1324 if(VALID_CALLBACK(uvd, setVideoMode)) {
1325 return GET_CALLBACK(uvd, setVideoMode)(uvd, vw);
1326 }
1327
1328 if (vw->flags)
1329 return -EINVAL;
1330 if (vw->clipcount)
1331 return -EINVAL;
1332 if (vw->width != VIDEOSIZE_X(uvd->canvas))
1333 return -EINVAL;
1334 if (vw->height != VIDEOSIZE_Y(uvd->canvas))
1335 return -EINVAL;
1336
1337 return 0;
1338 }
1339 case VIDIOCGWIN:
1340 {
1341 struct video_window *vw = arg;
1342
1343 vw->x = 0;
1344 vw->y = 0;
1345 vw->width = VIDEOSIZE_X(uvd->videosize);
1346 vw->height = VIDEOSIZE_Y(uvd->videosize);
1347 vw->chromakey = 0;
1348 if (VALID_CALLBACK(uvd, getFPS))
1349 vw->flags = GET_CALLBACK(uvd, getFPS)(uvd);
1350 else
1351 vw->flags = 10; /* FIXME: do better! */
1352 return 0;
1353 }
1354 case VIDIOCGMBUF:
1355 {
1356 struct video_mbuf *vm = arg;
1357 int i;
1358
1359 memset(vm, 0, sizeof(*vm));
1360 vm->size = uvd->max_frame_size * USBVIDEO_NUMFRAMES;
1361 vm->frames = USBVIDEO_NUMFRAMES;
1362 for(i = 0; i < USBVIDEO_NUMFRAMES; i++)
1363 vm->offsets[i] = i * uvd->max_frame_size;
1364
1365 return 0;
1366 }
1367 case VIDIOCMCAPTURE:
1368 {
1369 struct video_mmap *vm = arg;
1370
1371 if (uvd->debug >= 1) {
1372 info("VIDIOCMCAPTURE: frame=%d. size=%dx%d, format=%d.",
1373 vm->frame, vm->width, vm->height, vm->format);
1374 }
1375 /*
1376 * Check if the requested size is supported. If the requestor
1377 * requests too big a frame then we may be tricked into accessing
1378 * outside of own preallocated frame buffer (in uvd->frame).
1379 * This will cause oops or a security hole. Theoretically, we
1380 * could only clamp the size down to acceptable bounds, but then
1381 * we'd need to figure out how to insert our smaller buffer into
1382 * larger caller's buffer... this is not an easy question. So we
1383 * here just flatly reject too large requests, assuming that the
1384 * caller will resubmit with smaller size. Callers should know
1385 * what size we support (returned by VIDIOCGCAP). However vidcat,
1386 * for one, does not care and allows to ask for any size.
1387 */
1388 if ((vm->width > VIDEOSIZE_X(uvd->canvas)) ||
1389 (vm->height > VIDEOSIZE_Y(uvd->canvas))) {
1390 if (uvd->debug > 0) {
1391 info("VIDIOCMCAPTURE: Size=%dx%d too large; "
1392 "allowed only up to %ldx%ld", vm->width, vm->height,
1393 VIDEOSIZE_X(uvd->canvas), VIDEOSIZE_Y(uvd->canvas));
1394 }
1395 return -EINVAL;
1396 }
1397 /* Check if the palette is supported */
1398 if (((1L << vm->format) & uvd->paletteBits) == 0) {
1399 if (uvd->debug > 0) {
1400 info("VIDIOCMCAPTURE: format=%d. not supported"
1401 " (paletteBits=$%08lx)",
1402 vm->format, uvd->paletteBits);
1403 }
1404 return -EINVAL;
1405 }
1406 if ((vm->frame < 0) || (vm->frame >= USBVIDEO_NUMFRAMES)) {
1407 err("VIDIOCMCAPTURE: vm.frame=%d. !E [0-%d]", vm->frame, USBVIDEO_NUMFRAMES-1);
1408 return -EINVAL;
1409 }
1410 if (uvd->frame[vm->frame].frameState == FrameState_Grabbing) {
1411 /* Not an error - can happen */
1412 }
1413 uvd->frame[vm->frame].request = VIDEOSIZE(vm->width, vm->height);
1414 uvd->frame[vm->frame].palette = vm->format;
1415
1416 /* Mark it as ready */
1417 uvd->frame[vm->frame].frameState = FrameState_Ready;
1418
1419 return usbvideo_NewFrame(uvd, vm->frame);
1420 }
1421 case VIDIOCSYNC:
1422 {
1423 int *frameNum = arg;
1424 int ret;
1425
1426 if (*frameNum < 0 || *frameNum >= USBVIDEO_NUMFRAMES)
1427 return -EINVAL;
1428
1429 if (uvd->debug >= 1)
1430 info("VIDIOCSYNC: syncing to frame %d.", *frameNum);
1431 if (uvd->flags & FLAGS_NO_DECODING)
1432 ret = usbvideo_GetFrame(uvd, *frameNum);
1433 else if (VALID_CALLBACK(uvd, getFrame)) {
1434 ret = GET_CALLBACK(uvd, getFrame)(uvd, *frameNum);
1435 if ((ret < 0) && (uvd->debug >= 1)) {
1436 err("VIDIOCSYNC: getFrame() returned %d.", ret);
1437 }
1438 } else {
1439 err("VIDIOCSYNC: getFrame is not set");
1440 ret = -EFAULT;
1441 }
1442
1443 /*
1444 * The frame is in FrameState_Done_Hold state. Release it
1445 * right now because its data is already mapped into
1446 * the user space and it's up to the application to
1447 * make use of it until it asks for another frame.
1448 */
1449 uvd->frame[*frameNum].frameState = FrameState_Unused;
1450 return ret;
1451 }
1452 case VIDIOCGFBUF:
1453 {
1454 struct video_buffer *vb = arg;
1455
1456 memset(vb, 0, sizeof(*vb));
1457 return 0;
1458 }
1459 case VIDIOCKEY:
1460 return 0;
1461
1462 case VIDIOCCAPTURE:
1463 return -EINVAL;
1464
1465 case VIDIOCSFBUF:
1466
1467 case VIDIOCGTUNER:
1468 case VIDIOCSTUNER:
1469
1470 case VIDIOCGFREQ:
1471 case VIDIOCSFREQ:
1472
1473 case VIDIOCGAUDIO:
1474 case VIDIOCSAUDIO:
1475 return -EINVAL;
1476
1477 default:
1478 return -ENOIOCTLCMD;
1479 }
1480 return 0;
1481}
1482
1483static int usbvideo_v4l_ioctl(struct inode *inode, struct file *file,
1484 unsigned int cmd, unsigned long arg)
1485{
1486 return video_usercopy(inode, file, cmd, arg, usbvideo_v4l_do_ioctl);
1487}
1488
1489/*
1490 * usbvideo_v4l_read()
1491 *
1492 * This is mostly boring stuff. We simply ask for a frame and when it
1493 * arrives copy all the video data from it into user space. There is
1494 * no obvious need to override this method.
1495 *
1496 * History:
1497 * 20-Oct-2000 Created.
1498 * 01-Nov-2000 Added mutex (uvd->lock).
1499 */
1500static ssize_t usbvideo_v4l_read(struct file *file, char __user *buf,
1501 size_t count, loff_t *ppos)
1502{
1503 struct uvd *uvd = file->private_data;
1504 int noblock = file->f_flags & O_NONBLOCK;
1505 int frmx = -1, i;
1506 struct usbvideo_frame *frame;
1507
1508 if (!CAMERA_IS_OPERATIONAL(uvd) || (buf == NULL))
1509 return -EFAULT;
1510
1511 if (uvd->debug >= 1)
1512 info("%s: %Zd. bytes, noblock=%d.", __FUNCTION__, count, noblock);
1513
1514 mutex_lock(&uvd->lock);
1515
1516 /* See if a frame is completed, then use it. */
1517 for(i = 0; i < USBVIDEO_NUMFRAMES; i++) {
1518 if ((uvd->frame[i].frameState == FrameState_Done) ||
1519 (uvd->frame[i].frameState == FrameState_Done_Hold) ||
1520 (uvd->frame[i].frameState == FrameState_Error)) {
1521 frmx = i;
1522 break;
1523 }
1524 }
1525
1526 /* FIXME: If we don't start a frame here then who ever does? */
1527 if (noblock && (frmx == -1)) {
1528 count = -EAGAIN;
1529 goto read_done;
1530 }
1531
1532 /*
1533 * If no FrameState_Done, look for a FrameState_Grabbing state.
1534 * See if a frame is in process (grabbing), then use it.
1535 * We will need to wait until it becomes cooked, of course.
1536 */
1537 if (frmx == -1) {
1538 for(i = 0; i < USBVIDEO_NUMFRAMES; i++) {
1539 if (uvd->frame[i].frameState == FrameState_Grabbing) {
1540 frmx = i;
1541 break;
1542 }
1543 }
1544 }
1545
1546 /*
1547 * If no frame is active, start one. We don't care which one
1548 * it will be, so #0 is as good as any.
1549 * In read access mode we don't have convenience of VIDIOCMCAPTURE
1550 * to specify the requested palette (video format) on per-frame
1551 * basis. This means that we have to return data in -some- format
1552 * and just hope that the client knows what to do with it.
1553 * The default format is configured in uvd->defaultPalette field
1554 * as one of VIDEO_PALETTE_xxx values. We stuff it into the new
1555 * frame and initiate the frame filling process.
1556 */
1557 if (frmx == -1) {
1558 if (uvd->defaultPalette == 0) {
1559 err("%s: No default palette; don't know what to do!", __FUNCTION__);
1560 count = -EFAULT;
1561 goto read_done;
1562 }
1563 frmx = 0;
1564 /*
1565 * We have no per-frame control over video size.
1566 * Therefore we only can use whatever size was
1567 * specified as default.
1568 */
1569 uvd->frame[frmx].request = uvd->videosize;
1570 uvd->frame[frmx].palette = uvd->defaultPalette;
1571 uvd->frame[frmx].frameState = FrameState_Ready;
1572 usbvideo_NewFrame(uvd, frmx);
1573 /* Now frame 0 is supposed to start filling... */
1574 }
1575
1576 /*
1577 * Get a pointer to the active frame. It is either previously
1578 * completed frame or frame in progress but not completed yet.
1579 */
1580 frame = &uvd->frame[frmx];
1581
1582 /*
1583 * Sit back & wait until the frame gets filled and postprocessed.
1584 * If we fail to get the picture [in time] then return the error.
1585 * In this call we specify that we want the frame to be waited for,
1586 * postprocessed and switched into FrameState_Done_Hold state. This
1587 * state is used to hold the frame as "fully completed" between
1588 * subsequent partial reads of the same frame.
1589 */
1590 if (frame->frameState != FrameState_Done_Hold) {
1591 long rv = -EFAULT;
1592 if (uvd->flags & FLAGS_NO_DECODING)
1593 rv = usbvideo_GetFrame(uvd, frmx);
1594 else if (VALID_CALLBACK(uvd, getFrame))
1595 rv = GET_CALLBACK(uvd, getFrame)(uvd, frmx);
1596 else
1597 err("getFrame is not set");
1598 if ((rv != 0) || (frame->frameState != FrameState_Done_Hold)) {
1599 count = rv;
1600 goto read_done;
1601 }
1602 }
1603
1604 /*
1605 * Copy bytes to user space. We allow for partial reads, which
1606 * means that the user application can request read less than
1607 * the full frame size. It is up to the application to issue
1608 * subsequent calls until entire frame is read.
1609 *
1610 * First things first, make sure we don't copy more than we
1611 * have - even if the application wants more. That would be
1612 * a big security embarassment!
1613 */
1614 if ((count + frame->seqRead_Index) > frame->seqRead_Length)
1615 count = frame->seqRead_Length - frame->seqRead_Index;
1616
1617 /*
1618 * Copy requested amount of data to user space. We start
1619 * copying from the position where we last left it, which
1620 * will be zero for a new frame (not read before).
1621 */
1622 if (copy_to_user(buf, frame->data + frame->seqRead_Index, count)) {
1623 count = -EFAULT;
1624 goto read_done;
1625 }
1626
1627 /* Update last read position */
1628 frame->seqRead_Index += count;
1629 if (uvd->debug >= 1) {
1630 err("%s: {copy} count used=%Zd, new seqRead_Index=%ld",
1631 __FUNCTION__, count, frame->seqRead_Index);
1632 }
1633
1634 /* Finally check if the frame is done with and "release" it */
1635 if (frame->seqRead_Index >= frame->seqRead_Length) {
1636 /* All data has been read */
1637 frame->seqRead_Index = 0;
1638
1639 /* Mark it as available to be used again. */
1640 uvd->frame[frmx].frameState = FrameState_Unused;
1641 if (usbvideo_NewFrame(uvd, (frmx + 1) % USBVIDEO_NUMFRAMES)) {
1642 err("%s: usbvideo_NewFrame failed.", __FUNCTION__);
1643 }
1644 }
1645read_done:
1646 mutex_unlock(&uvd->lock);
1647 return count;
1648}
1649
1650/*
1651 * Make all of the blocks of data contiguous
1652 */
1653static int usbvideo_CompressIsochronous(struct uvd *uvd, struct urb *urb)
1654{
1655 char *cdata;
1656 int i, totlen = 0;
1657
1658 for (i = 0; i < urb->number_of_packets; i++) {
1659 int n = urb->iso_frame_desc[i].actual_length;
1660 int st = urb->iso_frame_desc[i].status;
1661
1662 cdata = urb->transfer_buffer + urb->iso_frame_desc[i].offset;
1663
1664 /* Detect and ignore errored packets */
1665 if (st < 0) {
1666 if (uvd->debug >= 1)
1667 err("Data error: packet=%d. len=%d. status=%d.", i, n, st);
1668 uvd->stats.iso_err_count++;
1669 continue;
1670 }
1671
1672 /* Detect and ignore empty packets */
1673 if (n <= 0) {
1674 uvd->stats.iso_skip_count++;
1675 continue;
1676 }
1677 totlen += n; /* Little local accounting */
1678 RingQueue_Enqueue(&uvd->dp, cdata, n);
1679 }
1680 return totlen;
1681}
1682
1683static void usbvideo_IsocIrq(struct urb *urb, struct pt_regs *regs)
1684{
1685 int i, ret, len;
1686 struct uvd *uvd = urb->context;
1687
1688 /* We don't want to do anything if we are about to be removed! */
1689 if (!CAMERA_IS_OPERATIONAL(uvd))
1690 return;
1691#if 0
1692 if (urb->actual_length > 0) {
1693 info("urb=$%p status=%d. errcount=%d. length=%d.",
1694 urb, urb->status, urb->error_count, urb->actual_length);
1695 } else {
1696 static int c = 0;
1697 if (c++ % 100 == 0)
1698 info("No Isoc data");
1699 }
1700#endif
1701
1702 if (!uvd->streaming) {
1703 if (uvd->debug >= 1)
1704 info("Not streaming, but interrupt!");
1705 return;
1706 }
1707
1708 uvd->stats.urb_count++;
1709 if (urb->actual_length <= 0)
1710 goto urb_done_with;
1711
1712 /* Copy the data received into ring queue */
1713 len = usbvideo_CompressIsochronous(uvd, urb);
1714 uvd->stats.urb_length = len;
1715 if (len <= 0)
1716 goto urb_done_with;
1717
1718 /* Here we got some data */
1719 uvd->stats.data_count += len;
1720 RingQueue_WakeUpInterruptible(&uvd->dp);
1721
1722urb_done_with:
1723 for (i = 0; i < FRAMES_PER_DESC; i++) {
1724 urb->iso_frame_desc[i].status = 0;
1725 urb->iso_frame_desc[i].actual_length = 0;
1726 }
1727 urb->status = 0;
1728 urb->dev = uvd->dev;
1729 ret = usb_submit_urb (urb, GFP_KERNEL);
1730 if(ret)
1731 err("usb_submit_urb error (%d)", ret);
1732 return;
1733}
1734
1735/*
1736 * usbvideo_StartDataPump()
1737 *
1738 * History:
1739 * 27-Jan-2000 Used ibmcam->iface, ibmcam->ifaceAltActive instead
1740 * of hardcoded values. Simplified by using for loop,
1741 * allowed any number of URBs.
1742 */
1743static int usbvideo_StartDataPump(struct uvd *uvd)
1744{
1745 struct usb_device *dev = uvd->dev;
1746 int i, errFlag;
1747
1748 if (uvd->debug > 1)
1749 info("%s($%p)", __FUNCTION__, uvd);
1750
1751 if (!CAMERA_IS_OPERATIONAL(uvd)) {
1752 err("%s: Camera is not operational", __FUNCTION__);
1753 return -EFAULT;
1754 }
1755 uvd->curframe = -1;
1756
1757 /* Alternate interface 1 is is the biggest frame size */
1758 i = usb_set_interface(dev, uvd->iface, uvd->ifaceAltActive);
1759 if (i < 0) {
1760 err("%s: usb_set_interface error", __FUNCTION__);
1761 uvd->last_error = i;
1762 return -EBUSY;
1763 }
1764 if (VALID_CALLBACK(uvd, videoStart))
1765 GET_CALLBACK(uvd, videoStart)(uvd);
1766 else
1767 err("%s: videoStart not set", __FUNCTION__);
1768
1769 /* We double buffer the Iso lists */
1770 for (i=0; i < USBVIDEO_NUMSBUF; i++) {
1771 int j, k;
1772 struct urb *urb = uvd->sbuf[i].urb;
1773 urb->dev = dev;
1774 urb->context = uvd;
1775 urb->pipe = usb_rcvisocpipe(dev, uvd->video_endp);
1776 urb->interval = 1;
1777 urb->transfer_flags = URB_ISO_ASAP;
1778 urb->transfer_buffer = uvd->sbuf[i].data;
1779 urb->complete = usbvideo_IsocIrq;
1780 urb->number_of_packets = FRAMES_PER_DESC;
1781 urb->transfer_buffer_length = uvd->iso_packet_len * FRAMES_PER_DESC;
1782 for (j=k=0; j < FRAMES_PER_DESC; j++, k += uvd->iso_packet_len) {
1783 urb->iso_frame_desc[j].offset = k;
1784 urb->iso_frame_desc[j].length = uvd->iso_packet_len;
1785 }
1786 }
1787
1788 /* Submit all URBs */
1789 for (i=0; i < USBVIDEO_NUMSBUF; i++) {
1790 errFlag = usb_submit_urb(uvd->sbuf[i].urb, GFP_KERNEL);
1791 if (errFlag)
1792 err("%s: usb_submit_isoc(%d) ret %d", __FUNCTION__, i, errFlag);
1793 }
1794
1795 uvd->streaming = 1;
1796 if (uvd->debug > 1)
1797 info("%s: streaming=1 video_endp=$%02x", __FUNCTION__, uvd->video_endp);
1798 return 0;
1799}
1800
1801/*
1802 * usbvideo_StopDataPump()
1803 *
1804 * This procedure stops streaming and deallocates URBs. Then it
1805 * activates zero-bandwidth alt. setting of the video interface.
1806 *
1807 * History:
1808 * 22-Jan-2000 Corrected order of actions to work after surprise removal.
1809 * 27-Jan-2000 Used uvd->iface, uvd->ifaceAltInactive instead of hardcoded values.
1810 */
1811static void usbvideo_StopDataPump(struct uvd *uvd)
1812{
1813 int i, j;
1814
1815 if ((uvd == NULL) || (!uvd->streaming) || (uvd->dev == NULL))
1816 return;
1817
1818 if (uvd->debug > 1)
1819 info("%s($%p)", __FUNCTION__, uvd);
1820
1821 /* Unschedule all of the iso td's */
1822 for (i=0; i < USBVIDEO_NUMSBUF; i++) {
1823 usb_kill_urb(uvd->sbuf[i].urb);
1824 }
1825 if (uvd->debug > 1)
1826 info("%s: streaming=0", __FUNCTION__);
1827 uvd->streaming = 0;
1828
1829 if (!uvd->remove_pending) {
1830 /* Invoke minidriver's magic to stop the camera */
1831 if (VALID_CALLBACK(uvd, videoStop))
1832 GET_CALLBACK(uvd, videoStop)(uvd);
1833 else
1834 err("%s: videoStop not set", __FUNCTION__);
1835
1836 /* Set packet size to 0 */
1837 j = usb_set_interface(uvd->dev, uvd->iface, uvd->ifaceAltInactive);
1838 if (j < 0) {
1839 err("%s: usb_set_interface() error %d.", __FUNCTION__, j);
1840 uvd->last_error = j;
1841 }
1842 }
1843}
1844
1845/*
1846 * usbvideo_NewFrame()
1847 *
1848 * History:
1849 * 29-Mar-00 Added copying of previous frame into the current one.
1850 * 6-Aug-00 Added model 3 video sizes, removed redundant width, height.
1851 */
1852static int usbvideo_NewFrame(struct uvd *uvd, int framenum)
1853{
1854 struct usbvideo_frame *frame;
1855 int n;
1856
1857 if (uvd->debug > 1)
1858 info("usbvideo_NewFrame($%p,%d.)", uvd, framenum);
1859
1860 /* If we're not grabbing a frame right now and the other frame is */
1861 /* ready to be grabbed into, then use it instead */
1862 if (uvd->curframe != -1)
1863 return 0;
1864
1865 /* If necessary we adjust picture settings between frames */
1866 if (!uvd->settingsAdjusted) {
1867 if (VALID_CALLBACK(uvd, adjustPicture))
1868 GET_CALLBACK(uvd, adjustPicture)(uvd);
1869 uvd->settingsAdjusted = 1;
1870 }
1871
1872 n = (framenum + 1) % USBVIDEO_NUMFRAMES;
1873 if (uvd->frame[n].frameState == FrameState_Ready)
1874 framenum = n;
1875
1876 frame = &uvd->frame[framenum];
1877
1878 frame->frameState = FrameState_Grabbing;
1879 frame->scanstate = ScanState_Scanning;
1880 frame->seqRead_Length = 0; /* Accumulated in xxx_parse_data() */
1881 frame->deinterlace = Deinterlace_None;
1882 frame->flags = 0; /* No flags yet, up to minidriver (or us) to set them */
1883 uvd->curframe = framenum;
1884
1885 /*
1886 * Normally we would want to copy previous frame into the current one
1887 * before we even start filling it with data; this allows us to stop
1888 * filling at any moment; top portion of the frame will be new and
1889 * bottom portion will stay as it was in previous frame. If we don't
1890 * do that then missing chunks of video stream will result in flickering
1891 * portions of old data whatever it was before.
1892 *
1893 * If we choose not to copy previous frame (to, for example, save few
1894 * bus cycles - the frame can be pretty large!) then we have an option
1895 * to clear the frame before using. If we experience losses in this
1896 * mode then missing picture will be black (no flickering).
1897 *
1898 * Finally, if user chooses not to clean the current frame before
1899 * filling it with data then the old data will be visible if we fail
1900 * to refill entire frame with new data.
1901 */
1902 if (!(uvd->flags & FLAGS_SEPARATE_FRAMES)) {
1903 /* This copies previous frame into this one to mask losses */
1904 int prev = (framenum - 1 + USBVIDEO_NUMFRAMES) % USBVIDEO_NUMFRAMES;
1905 memmove(frame->data, uvd->frame[prev].data, uvd->max_frame_size);
1906 } else {
1907 if (uvd->flags & FLAGS_CLEAN_FRAMES) {
1908 /* This provides a "clean" frame but slows things down */
1909 memset(frame->data, 0, uvd->max_frame_size);
1910 }
1911 }
1912 return 0;
1913}
1914
1915/*
1916 * usbvideo_CollectRawData()
1917 *
1918 * This procedure can be used instead of 'processData' callback if you
1919 * only want to dump the raw data from the camera into the output
1920 * device (frame buffer). You can look at it with V4L client, but the
1921 * image will be unwatchable. The main purpose of this code and of the
1922 * mode FLAGS_NO_DECODING is debugging and capturing of datastreams from
1923 * new, unknown cameras. This procedure will be automatically invoked
1924 * instead of the specified callback handler when uvd->flags has bit
1925 * FLAGS_NO_DECODING set. Therefore, any regular build of any driver
1926 * based on usbvideo can use this feature at any time.
1927 */
1928static void usbvideo_CollectRawData(struct uvd *uvd, struct usbvideo_frame *frame)
1929{
1930 int n;
1931
1932 assert(uvd != NULL);
1933 assert(frame != NULL);
1934
1935 /* Try to move data from queue into frame buffer */
1936 n = RingQueue_GetLength(&uvd->dp);
1937 if (n > 0) {
1938 int m;
1939 /* See how much space we have left */
1940 m = uvd->max_frame_size - frame->seqRead_Length;
1941 if (n > m)
1942 n = m;
1943 /* Now move that much data into frame buffer */
1944 RingQueue_Dequeue(
1945 &uvd->dp,
1946 frame->data + frame->seqRead_Length,
1947 m);
1948 frame->seqRead_Length += m;
1949 }
1950 /* See if we filled the frame */
1951 if (frame->seqRead_Length >= uvd->max_frame_size) {
1952 frame->frameState = FrameState_Done;
1953 uvd->curframe = -1;
1954 uvd->stats.frame_num++;
1955 }
1956}
1957
1958static int usbvideo_GetFrame(struct uvd *uvd, int frameNum)
1959{
1960 struct usbvideo_frame *frame = &uvd->frame[frameNum];
1961
1962 if (uvd->debug >= 2)
1963 info("%s($%p,%d.)", __FUNCTION__, uvd, frameNum);
1964
1965 switch (frame->frameState) {
1966 case FrameState_Unused:
1967 if (uvd->debug >= 2)
1968 info("%s: FrameState_Unused", __FUNCTION__);
1969 return -EINVAL;
1970 case FrameState_Ready:
1971 case FrameState_Grabbing:
1972 case FrameState_Error:
1973 {
1974 int ntries, signalPending;
1975 redo:
1976 if (!CAMERA_IS_OPERATIONAL(uvd)) {
1977 if (uvd->debug >= 2)
1978 info("%s: Camera is not operational (1)", __FUNCTION__);
1979 return -EIO;
1980 }
1981 ntries = 0;
1982 do {
1983 RingQueue_InterruptibleSleepOn(&uvd->dp);
1984 signalPending = signal_pending(current);
1985 if (!CAMERA_IS_OPERATIONAL(uvd)) {
1986 if (uvd->debug >= 2)
1987 info("%s: Camera is not operational (2)", __FUNCTION__);
1988 return -EIO;
1989 }
1990 assert(uvd->fbuf != NULL);
1991 if (signalPending) {
1992 if (uvd->debug >= 2)
1993 info("%s: Signal=$%08x", __FUNCTION__, signalPending);
1994 if (uvd->flags & FLAGS_RETRY_VIDIOCSYNC) {
1995 usbvideo_TestPattern(uvd, 1, 0);
1996 uvd->curframe = -1;
1997 uvd->stats.frame_num++;
1998 if (uvd->debug >= 2)
1999 info("%s: Forced test pattern screen", __FUNCTION__);
2000 return 0;
2001 } else {
2002 /* Standard answer: Interrupted! */
2003 if (uvd->debug >= 2)
2004 info("%s: Interrupted!", __FUNCTION__);
2005 return -EINTR;
2006 }
2007 } else {
2008 /* No signals - we just got new data in dp queue */
2009 if (uvd->flags & FLAGS_NO_DECODING)
2010 usbvideo_CollectRawData(uvd, frame);
2011 else if (VALID_CALLBACK(uvd, processData))
2012 GET_CALLBACK(uvd, processData)(uvd, frame);
2013 else
2014 err("%s: processData not set", __FUNCTION__);
2015 }
2016 } while (frame->frameState == FrameState_Grabbing);
2017 if (uvd->debug >= 2) {
2018 info("%s: Grabbing done; state=%d. (%lu. bytes)",
2019 __FUNCTION__, frame->frameState, frame->seqRead_Length);
2020 }
2021 if (frame->frameState == FrameState_Error) {
2022 int ret = usbvideo_NewFrame(uvd, frameNum);
2023 if (ret < 0) {
2024 err("%s: usbvideo_NewFrame() failed (%d.)", __FUNCTION__, ret);
2025 return ret;
2026 }
2027 goto redo;
2028 }
2029 /* Note that we fall through to meet our destiny below */
2030 }
2031 case FrameState_Done:
2032 /*
2033 * Do all necessary postprocessing of data prepared in
2034 * "interrupt" code and the collecting code above. The
2035 * frame gets marked as FrameState_Done by queue parsing code.
2036 * This status means that we collected enough data and
2037 * most likely processed it as we went through. However
2038 * the data may need postprocessing, such as deinterlacing
2039 * or picture adjustments implemented in software (horror!)
2040 *
2041 * As soon as the frame becomes "final" it gets promoted to
2042 * FrameState_Done_Hold status where it will remain until the
2043 * caller consumed all the video data from the frame. Then
2044 * the empty shell of ex-frame is thrown out for dogs to eat.
2045 * But we, worried about pets, will recycle the frame!
2046 */
2047 uvd->stats.frame_num++;
2048 if ((uvd->flags & FLAGS_NO_DECODING) == 0) {
2049 if (VALID_CALLBACK(uvd, postProcess))
2050 GET_CALLBACK(uvd, postProcess)(uvd, frame);
2051 if (frame->flags & USBVIDEO_FRAME_FLAG_SOFTWARE_CONTRAST)
2052 usbvideo_SoftwareContrastAdjustment(uvd, frame);
2053 }
2054 frame->frameState = FrameState_Done_Hold;
2055 if (uvd->debug >= 2)
2056 info("%s: Entered FrameState_Done_Hold state.", __FUNCTION__);
2057 return 0;
2058
2059 case FrameState_Done_Hold:
2060 /*
2061 * We stay in this state indefinitely until someone external,
2062 * like ioctl() or read() call finishes digesting the frame
2063 * data. Then it will mark the frame as FrameState_Unused and
2064 * it will be released back into the wild to roam freely.
2065 */
2066 if (uvd->debug >= 2)
2067 info("%s: FrameState_Done_Hold state.", __FUNCTION__);
2068 return 0;
2069 }
2070
2071 /* Catch-all for other cases. We shall not be here. */
2072 err("%s: Invalid state %d.", __FUNCTION__, frame->frameState);
2073 frame->frameState = FrameState_Unused;
2074 return 0;
2075}
2076
2077/*
2078 * usbvideo_DeinterlaceFrame()
2079 *
2080 * This procedure deinterlaces the given frame. Some cameras produce
2081 * only half of scanlines - sometimes only even lines, sometimes only
2082 * odd lines. The deinterlacing method is stored in frame->deinterlace
2083 * variable.
2084 *
2085 * Here we scan the frame vertically and replace missing scanlines with
2086 * average between surrounding ones - before and after. If we have no
2087 * line above then we just copy next line. Similarly, if we need to
2088 * create a last line then preceding line is used.
2089 */
2090void usbvideo_DeinterlaceFrame(struct uvd *uvd, struct usbvideo_frame *frame)
2091{
2092 if ((uvd == NULL) || (frame == NULL))
2093 return;
2094
2095 if ((frame->deinterlace == Deinterlace_FillEvenLines) ||
2096 (frame->deinterlace == Deinterlace_FillOddLines))
2097 {
2098 const int v4l_linesize = VIDEOSIZE_X(frame->request) * V4L_BYTES_PER_PIXEL;
2099 int i = (frame->deinterlace == Deinterlace_FillEvenLines) ? 0 : 1;
2100
2101 for (; i < VIDEOSIZE_Y(frame->request); i += 2) {
2102 const unsigned char *fs1, *fs2;
2103 unsigned char *fd;
2104 int ip, in, j; /* Previous and next lines */
2105
2106 /*
2107 * Need to average lines before and after 'i'.
2108 * If we go out of bounds seeking those lines then
2109 * we point back to existing line.
2110 */
2111 ip = i - 1; /* First, get rough numbers */
2112 in = i + 1;
2113
2114 /* Now validate */
2115 if (ip < 0)
2116 ip = in;
2117 if (in >= VIDEOSIZE_Y(frame->request))
2118 in = ip;
2119
2120 /* Sanity check */
2121 if ((ip < 0) || (in < 0) ||
2122 (ip >= VIDEOSIZE_Y(frame->request)) ||
2123 (in >= VIDEOSIZE_Y(frame->request)))
2124 {
2125 err("Error: ip=%d. in=%d. req.height=%ld.",
2126 ip, in, VIDEOSIZE_Y(frame->request));
2127 break;
2128 }
2129
2130 /* Now we need to average lines 'ip' and 'in' to produce line 'i' */
2131 fs1 = frame->data + (v4l_linesize * ip);
2132 fs2 = frame->data + (v4l_linesize * in);
2133 fd = frame->data + (v4l_linesize * i);
2134
2135 /* Average lines around destination */
2136 for (j=0; j < v4l_linesize; j++) {
2137 fd[j] = (unsigned char)((((unsigned) fs1[j]) +
2138 ((unsigned)fs2[j])) >> 1);
2139 }
2140 }
2141 }
2142
2143 /* Optionally display statistics on the screen */
2144 if (uvd->flags & FLAGS_OVERLAY_STATS)
2145 usbvideo_OverlayStats(uvd, frame);
2146}
2147
2148EXPORT_SYMBOL(usbvideo_DeinterlaceFrame);
2149
2150/*
2151 * usbvideo_SoftwareContrastAdjustment()
2152 *
2153 * This code adjusts the contrast of the frame, assuming RGB24 format.
2154 * As most software image processing, this job is CPU-intensive.
2155 * Get a camera that supports hardware adjustment!
2156 *
2157 * History:
2158 * 09-Feb-2001 Created.
2159 */
2160static void usbvideo_SoftwareContrastAdjustment(struct uvd *uvd,
2161 struct usbvideo_frame *frame)
2162{
2163 int i, j, v4l_linesize;
2164 signed long adj;
2165 const int ccm = 128; /* Color correction median - see below */
2166
2167 if ((uvd == NULL) || (frame == NULL)) {
2168 err("%s: Illegal call.", __FUNCTION__);
2169 return;
2170 }
2171 adj = (uvd->vpic.contrast - 0x8000) >> 8; /* -128..+127 = -ccm..+(ccm-1)*/
2172 RESTRICT_TO_RANGE(adj, -ccm, ccm+1);
2173 if (adj == 0) {
2174 /* In rare case of no adjustment */
2175 return;
2176 }
2177 v4l_linesize = VIDEOSIZE_X(frame->request) * V4L_BYTES_PER_PIXEL;
2178 for (i=0; i < VIDEOSIZE_Y(frame->request); i++) {
2179 unsigned char *fd = frame->data + (v4l_linesize * i);
2180 for (j=0; j < v4l_linesize; j++) {
2181 signed long v = (signed long) fd[j];
2182 /* Magnify up to 2 times, reduce down to zero */
2183 v = 128 + ((ccm + adj) * (v - 128)) / ccm;
2184 RESTRICT_TO_RANGE(v, 0, 0xFF); /* Must flatten tails */
2185 fd[j] = (unsigned char) v;
2186 }
2187 }
2188}
2189
2190MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/usbvideo/usbvideo.h b/drivers/media/video/usbvideo/usbvideo.h
new file mode 100644
index 000000000000..135433c2680a
--- /dev/null
+++ b/drivers/media/video/usbvideo/usbvideo.h
@@ -0,0 +1,394 @@
1/*
2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation; either version 2, or (at your option)
5 * any later version.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
15 */
16#ifndef usbvideo_h
17#define usbvideo_h
18
19#include <linux/config.h>
20#include <linux/videodev.h>
21#include <linux/usb.h>
22#include <linux/mutex.h>
23
24/* Most helpful debugging aid */
25#define assert(expr) ((void) ((expr) ? 0 : (err("assert failed at line %d",__LINE__))))
26
27#define USBVIDEO_REPORT_STATS 1 /* Set to 0 to block statistics on close */
28
29/* Bit flags (options) */
30#define FLAGS_RETRY_VIDIOCSYNC (1 << 0)
31#define FLAGS_MONOCHROME (1 << 1)
32#define FLAGS_DISPLAY_HINTS (1 << 2)
33#define FLAGS_OVERLAY_STATS (1 << 3)
34#define FLAGS_FORCE_TESTPATTERN (1 << 4)
35#define FLAGS_SEPARATE_FRAMES (1 << 5)
36#define FLAGS_CLEAN_FRAMES (1 << 6)
37#define FLAGS_NO_DECODING (1 << 7)
38
39/* Bit flags for frames (apply to the frame where they are specified) */
40#define USBVIDEO_FRAME_FLAG_SOFTWARE_CONTRAST (1 << 0)
41
42/* Camera capabilities (maximum) */
43#define CAMERA_URB_FRAMES 32
44#define CAMERA_MAX_ISO_PACKET 1023 /* 1022 actually sent by camera */
45#define FRAMES_PER_DESC (CAMERA_URB_FRAMES)
46#define FRAME_SIZE_PER_DESC (CAMERA_MAX_ISO_PACKET)
47
48/* This macro restricts an int variable to an inclusive range */
49#define RESTRICT_TO_RANGE(v,mi,ma) { if ((v) < (mi)) (v) = (mi); else if ((v) > (ma)) (v) = (ma); }
50
51#define V4L_BYTES_PER_PIXEL 3 /* Because we produce RGB24 */
52
53/*
54 * Use this macro to construct constants for different video sizes.
55 * We have to deal with different video sizes that have to be
56 * configured in the device or compared against when we receive
57 * a data. Normally one would define a bunch of VIDEOSIZE_x_by_y
58 * #defines and that's the end of story. However this solution
59 * does not allow to convert between real pixel sizes and the
60 * constant (integer) value that may be used to tag a frame or
61 * whatever. The set of macros below constructs videosize constants
62 * from the pixel size and allows to reconstruct the pixel size
63 * from the combined value later.
64 */
65#define VIDEOSIZE(x,y) (((x) & 0xFFFFL) | (((y) & 0xFFFFL) << 16))
66#define VIDEOSIZE_X(vs) ((vs) & 0xFFFFL)
67#define VIDEOSIZE_Y(vs) (((vs) >> 16) & 0xFFFFL)
68typedef unsigned long videosize_t;
69
70/*
71 * This macro checks if the camera is still operational. The 'uvd'
72 * pointer must be valid, uvd->dev must be valid, we are not
73 * removing the device and the device has not erred on us.
74 */
75#define CAMERA_IS_OPERATIONAL(uvd) (\
76 (uvd != NULL) && \
77 ((uvd)->dev != NULL) && \
78 ((uvd)->last_error == 0) && \
79 (!(uvd)->remove_pending))
80
81/*
82 * We use macros to do YUV -> RGB conversion because this is
83 * very important for speed and totally unimportant for size.
84 *
85 * YUV -> RGB Conversion
86 * ---------------------
87 *
88 * B = 1.164*(Y-16) + 2.018*(V-128)
89 * G = 1.164*(Y-16) - 0.813*(U-128) - 0.391*(V-128)
90 * R = 1.164*(Y-16) + 1.596*(U-128)
91 *
92 * If you fancy integer arithmetics (as you should), hear this:
93 *
94 * 65536*B = 76284*(Y-16) + 132252*(V-128)
95 * 65536*G = 76284*(Y-16) - 53281*(U-128) - 25625*(V-128)
96 * 65536*R = 76284*(Y-16) + 104595*(U-128)
97 *
98 * Make sure the output values are within [0..255] range.
99 */
100#define LIMIT_RGB(x) (((x) < 0) ? 0 : (((x) > 255) ? 255 : (x)))
101#define YUV_TO_RGB_BY_THE_BOOK(my,mu,mv,mr,mg,mb) { \
102 int mm_y, mm_yc, mm_u, mm_v, mm_r, mm_g, mm_b; \
103 mm_y = (my) - 16; \
104 mm_u = (mu) - 128; \
105 mm_v = (mv) - 128; \
106 mm_yc= mm_y * 76284; \
107 mm_b = (mm_yc + 132252*mm_v ) >> 16; \
108 mm_g = (mm_yc - 53281*mm_u - 25625*mm_v ) >> 16; \
109 mm_r = (mm_yc + 104595*mm_u ) >> 16; \
110 mb = LIMIT_RGB(mm_b); \
111 mg = LIMIT_RGB(mm_g); \
112 mr = LIMIT_RGB(mm_r); \
113}
114
115#define RING_QUEUE_SIZE (128*1024) /* Must be a power of 2 */
116#define RING_QUEUE_ADVANCE_INDEX(rq,ind,n) (rq)->ind = ((rq)->ind + (n)) & ((rq)->length-1)
117#define RING_QUEUE_DEQUEUE_BYTES(rq,n) RING_QUEUE_ADVANCE_INDEX(rq,ri,n)
118#define RING_QUEUE_PEEK(rq,ofs) ((rq)->queue[((ofs) + (rq)->ri) & ((rq)->length-1)])
119
120struct RingQueue {
121 unsigned char *queue; /* Data from the Isoc data pump */
122 int length; /* How many bytes allocated for the queue */
123 int wi; /* That's where we write */
124 int ri; /* Read from here until you hit write index */
125 wait_queue_head_t wqh; /* Processes waiting */
126};
127
128enum ScanState {
129 ScanState_Scanning, /* Scanning for header */
130 ScanState_Lines /* Parsing lines */
131};
132
133/* Completion states of the data parser */
134enum ParseState {
135 scan_Continue, /* Just parse next item */
136 scan_NextFrame, /* Frame done, send it to V4L */
137 scan_Out, /* Not enough data for frame */
138 scan_EndParse /* End parsing */
139};
140
141enum FrameState {
142 FrameState_Unused, /* Unused (no MCAPTURE) */
143 FrameState_Ready, /* Ready to start grabbing */
144 FrameState_Grabbing, /* In the process of being grabbed into */
145 FrameState_Done, /* Finished grabbing, but not been synced yet */
146 FrameState_Done_Hold, /* Are syncing or reading */
147 FrameState_Error, /* Something bad happened while processing */
148};
149
150/*
151 * Some frames may contain only even or odd lines. This type
152 * specifies what type of deinterlacing is required.
153 */
154enum Deinterlace {
155 Deinterlace_None=0,
156 Deinterlace_FillOddLines,
157 Deinterlace_FillEvenLines
158};
159
160#define USBVIDEO_NUMFRAMES 2 /* How many frames we work with */
161#define USBVIDEO_NUMSBUF 2 /* How many URBs linked in a ring */
162
163/* This structure represents one Isoc request - URB and buffer */
164struct usbvideo_sbuf {
165 char *data;
166 struct urb *urb;
167};
168
169struct usbvideo_frame {
170 char *data; /* Frame buffer */
171 unsigned long header; /* Significant bits from the header */
172
173 videosize_t canvas; /* The canvas (max. image) allocated */
174 videosize_t request; /* That's what the application asked for */
175 unsigned short palette; /* The desired format */
176
177 enum FrameState frameState;/* State of grabbing */
178 enum ScanState scanstate; /* State of scanning */
179 enum Deinterlace deinterlace;
180 int flags; /* USBVIDEO_FRAME_FLAG_xxx bit flags */
181
182 int curline; /* Line of frame we're working on */
183
184 long seqRead_Length; /* Raw data length of frame */
185 long seqRead_Index; /* Amount of data that has been already read */
186
187 void *user; /* Additional data that user may need */
188};
189
190/* Statistics that can be overlaid on screen */
191struct usbvideo_statistics {
192 unsigned long frame_num; /* Sequential number of the frame */
193 unsigned long urb_count; /* How many URBs we received so far */
194 unsigned long urb_length; /* Length of last URB */
195 unsigned long data_count; /* How many bytes we received */
196 unsigned long header_count; /* How many frame headers we found */
197 unsigned long iso_skip_count; /* How many empty ISO packets received */
198 unsigned long iso_err_count; /* How many bad ISO packets received */
199};
200
201struct usbvideo;
202
203struct uvd {
204 struct video_device vdev; /* Must be the first field! */
205 struct usb_device *dev;
206 struct usbvideo *handle; /* Points back to the struct usbvideo */
207 void *user_data; /* Camera-dependent data */
208 int user_size; /* Size of that camera-dependent data */
209 int debug; /* Debug level for usbvideo */
210 unsigned char iface; /* Video interface number */
211 unsigned char video_endp;
212 unsigned char ifaceAltActive;
213 unsigned char ifaceAltInactive; /* Alt settings */
214 unsigned long flags; /* FLAGS_USBVIDEO_xxx */
215 unsigned long paletteBits; /* Which palettes we accept? */
216 unsigned short defaultPalette; /* What palette to use for read() */
217 struct mutex lock;
218 int user; /* user count for exclusive use */
219
220 videosize_t videosize; /* Current setting */
221 videosize_t canvas; /* This is the width,height of the V4L canvas */
222 int max_frame_size; /* Bytes in one video frame */
223
224 int uvd_used; /* Is this structure in use? */
225 int streaming; /* Are we streaming Isochronous? */
226 int grabbing; /* Are we grabbing? */
227 int settingsAdjusted; /* Have we adjusted contrast etc.? */
228 int last_error; /* What calamity struck us? */
229
230 char *fbuf; /* Videodev buffer area */
231 int fbuf_size; /* Videodev buffer size */
232
233 int curframe;
234 int iso_packet_len; /* Videomode-dependent, saves bus bandwidth */
235
236 struct RingQueue dp; /* Isoc data pump */
237 struct usbvideo_frame frame[USBVIDEO_NUMFRAMES];
238 struct usbvideo_sbuf sbuf[USBVIDEO_NUMSBUF];
239
240 volatile int remove_pending; /* If set then about to exit */
241
242 struct video_picture vpic, vpic_old; /* Picture settings */
243 struct video_capability vcap; /* Video capabilities */
244 struct video_channel vchan; /* May be used for tuner support */
245 struct usbvideo_statistics stats;
246 char videoName[32]; /* Holds name like "video7" */
247};
248
249/*
250 * usbvideo callbacks (virtual methods). They are set when usbvideo
251 * services are registered. All of these default to NULL, except those
252 * that default to usbvideo-provided methods.
253 */
254struct usbvideo_cb {
255 int (*probe)(struct usb_interface *, const struct usb_device_id *);
256 void (*userFree)(struct uvd *);
257 void (*disconnect)(struct usb_interface *);
258 int (*setupOnOpen)(struct uvd *);
259 void (*videoStart)(struct uvd *);
260 void (*videoStop)(struct uvd *);
261 void (*processData)(struct uvd *, struct usbvideo_frame *);
262 void (*postProcess)(struct uvd *, struct usbvideo_frame *);
263 void (*adjustPicture)(struct uvd *);
264 int (*getFPS)(struct uvd *);
265 int (*overlayHook)(struct uvd *, struct usbvideo_frame *);
266 int (*getFrame)(struct uvd *, int);
267 int (*startDataPump)(struct uvd *uvd);
268 void (*stopDataPump)(struct uvd *uvd);
269 int (*setVideoMode)(struct uvd *uvd, struct video_window *vw);
270};
271
272struct usbvideo {
273 int num_cameras; /* As allocated */
274 struct usb_driver usbdrv; /* Interface to the USB stack */
275 char drvName[80]; /* Driver name */
276 struct mutex lock; /* Mutex protecting camera structures */
277 struct usbvideo_cb cb; /* Table of callbacks (virtual methods) */
278 struct video_device vdt; /* Video device template */
279 struct uvd *cam; /* Array of camera structures */
280 struct module *md_module; /* Minidriver module */
281};
282
283
284/*
285 * This macro retrieves callback address from the struct uvd object.
286 * No validity checks are done here, so be sure to check the
287 * callback beforehand with VALID_CALLBACK.
288 */
289#define GET_CALLBACK(uvd,cbName) ((uvd)->handle->cb.cbName)
290
291/*
292 * This macro returns either callback pointer or NULL. This is safe
293 * macro, meaning that most of components of data structures involved
294 * may be NULL - this only results in NULL being returned. You may
295 * wish to use this macro to make sure that the callback is callable.
296 * However keep in mind that those checks take time.
297 */
298#define VALID_CALLBACK(uvd,cbName) ((((uvd) != NULL) && \
299 ((uvd)->handle != NULL)) ? GET_CALLBACK(uvd,cbName) : NULL)
300
301int RingQueue_Dequeue(struct RingQueue *rq, unsigned char *dst, int len);
302int RingQueue_Enqueue(struct RingQueue *rq, const unsigned char *cdata, int n);
303void RingQueue_WakeUpInterruptible(struct RingQueue *rq);
304void RingQueue_Flush(struct RingQueue *rq);
305
306static inline int RingQueue_GetLength(const struct RingQueue *rq)
307{
308 return (rq->wi - rq->ri + rq->length) & (rq->length-1);
309}
310
311static inline int RingQueue_GetFreeSpace(const struct RingQueue *rq)
312{
313 return rq->length - RingQueue_GetLength(rq);
314}
315
316void usbvideo_DrawLine(
317 struct usbvideo_frame *frame,
318 int x1, int y1,
319 int x2, int y2,
320 unsigned char cr, unsigned char cg, unsigned char cb);
321void usbvideo_HexDump(const unsigned char *data, int len);
322void usbvideo_SayAndWait(const char *what);
323void usbvideo_TestPattern(struct uvd *uvd, int fullframe, int pmode);
324
325/* Memory allocation routines */
326unsigned long usbvideo_kvirt_to_pa(unsigned long adr);
327
328int usbvideo_register(
329 struct usbvideo **pCams,
330 const int num_cams,
331 const int num_extra,
332 const char *driverName,
333 const struct usbvideo_cb *cbTable,
334 struct module *md,
335 const struct usb_device_id *id_table);
336struct uvd *usbvideo_AllocateDevice(struct usbvideo *cams);
337int usbvideo_RegisterVideoDevice(struct uvd *uvd);
338void usbvideo_Deregister(struct usbvideo **uvt);
339
340int usbvideo_v4l_initialize(struct video_device *dev);
341
342void usbvideo_DeinterlaceFrame(struct uvd *uvd, struct usbvideo_frame *frame);
343
344/*
345 * This code performs bounds checking - use it when working with
346 * new formats, or else you may get oopses all over the place.
347 * If pixel falls out of bounds then it gets shoved back (as close
348 * to place of offence as possible) and is painted bright red.
349 *
350 * There are two important concepts: frame width, height and
351 * V4L canvas width, height. The former is the area requested by
352 * the application -for this very frame-. The latter is the largest
353 * possible frame that we can serve (we advertise that via V4L ioctl).
354 * The frame data is expected to be formatted as lines of length
355 * VIDEOSIZE_X(fr->request), total VIDEOSIZE_Y(frame->request) lines.
356 */
357static inline void RGB24_PUTPIXEL(
358 struct usbvideo_frame *fr,
359 int ix, int iy,
360 unsigned char vr,
361 unsigned char vg,
362 unsigned char vb)
363{
364 register unsigned char *pf;
365 int limiter = 0, mx, my;
366 mx = ix;
367 my = iy;
368 if (mx < 0) {
369 mx=0;
370 limiter++;
371 } else if (mx >= VIDEOSIZE_X((fr)->request)) {
372 mx= VIDEOSIZE_X((fr)->request) - 1;
373 limiter++;
374 }
375 if (my < 0) {
376 my = 0;
377 limiter++;
378 } else if (my >= VIDEOSIZE_Y((fr)->request)) {
379 my = VIDEOSIZE_Y((fr)->request) - 1;
380 limiter++;
381 }
382 pf = (fr)->data + V4L_BYTES_PER_PIXEL*((iy)*VIDEOSIZE_X((fr)->request) + (ix));
383 if (limiter) {
384 *pf++ = 0;
385 *pf++ = 0;
386 *pf++ = 0xFF;
387 } else {
388 *pf++ = (vb);
389 *pf++ = (vg);
390 *pf++ = (vr);
391 }
392}
393
394#endif /* usbvideo_h */
diff --git a/drivers/media/video/usbvideo/vicam.c b/drivers/media/video/usbvideo/vicam.c
new file mode 100644
index 000000000000..1d06e53ec7c5
--- /dev/null
+++ b/drivers/media/video/usbvideo/vicam.c
@@ -0,0 +1,1411 @@
1/*
2 * USB ViCam WebCam driver
3 * Copyright (c) 2002 Joe Burks (jburks@wavicle.org),
4 * Christopher L Cheney (ccheney@cheney.cx),
5 * Pavel Machek (pavel@suse.cz),
6 * John Tyner (jtyner@cs.ucr.edu),
7 * Monroe Williams (monroe@pobox.com)
8 *
9 * Supports 3COM HomeConnect PC Digital WebCam
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., 675 Mass Ave, Cambridge, MA 02139, USA.
24 *
25 * This source code is based heavily on the CPiA webcam driver which was
26 * written by Peter Pregler, Scott J. Bertin and Johannes Erdfelt
27 *
28 * Portions of this code were also copied from usbvideo.c
29 *
30 * Special thanks to the the whole team at Sourceforge for help making
31 * this driver become a reality. Notably:
32 * Andy Armstrong who reverse engineered the color encoding and
33 * Pavel Machek and Chris Cheney who worked on reverse engineering the
34 * camera controls and wrote the first generation driver.
35 */
36
37#include <linux/kernel.h>
38#include <linux/module.h>
39#include <linux/init.h>
40#include <linux/videodev.h>
41#include <linux/usb.h>
42#include <linux/vmalloc.h>
43#include <linux/slab.h>
44#include <linux/proc_fs.h>
45#include <linux/mutex.h>
46#include "usbvideo.h"
47
48// #define VICAM_DEBUG
49
50#ifdef VICAM_DEBUG
51#define ADBG(lineno,fmt,args...) printk(fmt, jiffies, __FUNCTION__, lineno, ##args)
52#define DBG(fmt,args...) ADBG((__LINE__),KERN_DEBUG __FILE__"(%ld):%s (%d):"fmt,##args)
53#else
54#define DBG(fmn,args...) do {} while(0)
55#endif
56
57#define DRIVER_AUTHOR "Joe Burks, jburks@wavicle.org"
58#define DRIVER_DESC "ViCam WebCam Driver"
59
60/* Define these values to match your device */
61#define USB_VICAM_VENDOR_ID 0x04c1
62#define USB_VICAM_PRODUCT_ID 0x009d
63
64#define VICAM_BYTES_PER_PIXEL 3
65#define VICAM_MAX_READ_SIZE (512*242+128)
66#define VICAM_MAX_FRAME_SIZE (VICAM_BYTES_PER_PIXEL*320*240)
67#define VICAM_FRAMES 2
68
69#define VICAM_HEADER_SIZE 64
70
71#define clamp( x, l, h ) max_t( __typeof__( x ), \
72 ( l ), \
73 min_t( __typeof__( x ), \
74 ( h ), \
75 ( x ) ) )
76
77/* Not sure what all the bytes in these char
78 * arrays do, but they're necessary to make
79 * the camera work.
80 */
81
82static unsigned char setup1[] = {
83 0xB6, 0xC3, 0x1F, 0x00, 0x02, 0x64, 0xE7, 0x67,
84 0xFD, 0xFF, 0x0E, 0xC0, 0xE7, 0x09, 0xDE, 0x00,
85 0x8E, 0x00, 0xC0, 0x09, 0x40, 0x03, 0xC0, 0x17,
86 0x44, 0x03, 0x4B, 0xAF, 0xC0, 0x07, 0x00, 0x00,
87 0x4B, 0xAF, 0x97, 0xCF, 0x00, 0x00
88};
89
90static unsigned char setup2[] = {
91 0xB6, 0xC3, 0x03, 0x00, 0x03, 0x64, 0x18, 0x00,
92 0x00, 0x00
93};
94
95static unsigned char setup3[] = {
96 0xB6, 0xC3, 0x01, 0x00, 0x06, 0x64, 0x00, 0x00
97};
98
99static unsigned char setup4[] = {
100 0xB6, 0xC3, 0x8F, 0x06, 0x02, 0x64, 0xE7, 0x07,
101 0x00, 0x00, 0x08, 0xC0, 0xE7, 0x07, 0x00, 0x00,
102 0x3E, 0xC0, 0xE7, 0x07, 0x54, 0x01, 0xAA, 0x00,
103 0xE7, 0x07, 0xC8, 0x05, 0xB6, 0x00, 0xE7, 0x07,
104 0x42, 0x01, 0xD2, 0x00, 0xE7, 0x07, 0x7C, 0x00,
105 0x16, 0x00, 0xE7, 0x07, 0x56, 0x00, 0x18, 0x00,
106 0xE7, 0x07, 0x06, 0x00, 0x92, 0xC0, 0xE7, 0x07,
107 0x00, 0x00, 0x1E, 0xC0, 0xE7, 0x07, 0xFF, 0xFF,
108 0x22, 0xC0, 0xE7, 0x07, 0x04, 0x00, 0x24, 0xC0,
109 0xE7, 0x07, 0xEC, 0x27, 0x28, 0xC0, 0xE7, 0x07,
110 0x16, 0x01, 0x8E, 0x00, 0xE7, 0x87, 0x01, 0x00,
111 0x0E, 0xC0, 0x97, 0xCF, 0xD7, 0x09, 0x00, 0xC0,
112 0xE7, 0x77, 0x01, 0x00, 0x92, 0xC0, 0x09, 0xC1,
113 0xE7, 0x09, 0xFE, 0x05, 0x24, 0x01, 0xE7, 0x09,
114 0x04, 0x06, 0x26, 0x01, 0xE7, 0x07, 0x07, 0x00,
115 0x92, 0xC0, 0xE7, 0x05, 0x00, 0xC0, 0xC0, 0xDF,
116 0x97, 0xCF, 0x17, 0x00, 0x57, 0x00, 0x17, 0x02,
117 0xD7, 0x09, 0x00, 0xC0, 0xE7, 0x77, 0x01, 0x00,
118 0x92, 0xC0, 0x0A, 0xC1, 0xE7, 0x57, 0xFF, 0xFF,
119 0xFA, 0x05, 0x0D, 0xC0, 0xE7, 0x57, 0x00, 0x00,
120 0xFA, 0x05, 0x0F, 0xC0, 0x9F, 0xAF, 0xC6, 0x00,
121 0xE7, 0x05, 0x00, 0xC0, 0xC8, 0x05, 0xC1, 0x05,
122 0xC0, 0x05, 0xC0, 0xDF, 0x97, 0xCF, 0x27, 0xDA,
123 0xFA, 0x05, 0xEF, 0x07, 0x01, 0x00, 0x0B, 0x06,
124 0x73, 0xCF, 0x9F, 0xAF, 0x78, 0x01, 0x9F, 0xAF,
125 0x1A, 0x03, 0x6E, 0xCF, 0xE7, 0x09, 0xFC, 0x05,
126 0x24, 0x01, 0xE7, 0x09, 0x02, 0x06, 0x26, 0x01,
127 0xE7, 0x07, 0x07, 0x00, 0x92, 0xC0, 0xE7, 0x09,
128 0xFC, 0x05, 0xFE, 0x05, 0xE7, 0x09, 0x02, 0x06,
129 0x04, 0x06, 0xE7, 0x09, 0x00, 0x06, 0xFC, 0x05,
130 0xE7, 0x09, 0xFE, 0x05, 0x00, 0x06, 0x27, 0xDA,
131 0xFA, 0x05, 0xE7, 0x57, 0x01, 0x00, 0xFA, 0x05,
132 0x02, 0xCA, 0x04, 0xC0, 0x97, 0xCF, 0x9F, 0xAF,
133 0x66, 0x05, 0x97, 0xCF, 0xE7, 0x07, 0x40, 0x00,
134 0x02, 0x06, 0xC8, 0x09, 0xFC, 0x05, 0x9F, 0xAF,
135 0xDA, 0x02, 0x97, 0xCF, 0xCF, 0x17, 0x02, 0x00,
136 0xEF, 0x57, 0x81, 0x00, 0x09, 0x06, 0x9F, 0xA0,
137 0xB6, 0x01, 0xEF, 0x57, 0x80, 0x00, 0x09, 0x06,
138 0x9F, 0xA0, 0x40, 0x02, 0xEF, 0x57, 0x01, 0x00,
139 0x0B, 0x06, 0x9F, 0xA0, 0x46, 0x03, 0xE7, 0x07,
140 0x01, 0x00, 0x0A, 0xC0, 0x46, 0xAF, 0x47, 0xAF,
141 0x9F, 0xAF, 0x40, 0x02, 0xE7, 0x07, 0x2E, 0x00,
142 0x0A, 0xC0, 0xEF, 0x87, 0x80, 0x00, 0x09, 0x06,
143 0x97, 0xCF, 0x00, 0x0E, 0x01, 0x00, 0xC0, 0x57,
144 0x51, 0x00, 0x9F, 0xC0, 0x9E, 0x02, 0xC0, 0x57,
145 0x50, 0x00, 0x20, 0xC0, 0xC0, 0x57, 0x55, 0x00,
146 0x12, 0xC0, 0xC0, 0x57, 0x56, 0x00, 0x9F, 0xC0,
147 0x72, 0x02, 0x9F, 0xCF, 0xD6, 0x02, 0xC1, 0x0B,
148 0x08, 0x06, 0x01, 0xD0, 0x6F, 0x90, 0x08, 0x06,
149 0xC0, 0x07, 0x08, 0x00, 0xC1, 0x0B, 0x08, 0x06,
150 0x9F, 0xAF, 0x28, 0x05, 0x97, 0xCF, 0x2F, 0x0E,
151 0x02, 0x00, 0x08, 0x06, 0xC0, 0x07, 0x08, 0x00,
152 0xC1, 0x0B, 0x08, 0x06, 0x9F, 0xAF, 0x28, 0x05,
153 0x9F, 0xCF, 0xD6, 0x02, 0x2F, 0x0E, 0x02, 0x00,
154 0x09, 0x06, 0xEF, 0x87, 0x80, 0x00, 0x09, 0x06,
155 0x9F, 0xCF, 0xD6, 0x02, 0xEF, 0x67, 0x7F, 0xFF,
156 0x09, 0x06, 0xE7, 0x67, 0xFF, 0xFD, 0x22, 0xC0,
157 0xE7, 0x67, 0xEF, 0xFF, 0x24, 0xC0, 0xE7, 0x87,
158 0x10, 0x00, 0x28, 0xC0, 0x9F, 0xAF, 0xB8, 0x05,
159 0xE7, 0x87, 0xE0, 0x21, 0x24, 0xC0, 0x9F, 0xAF,
160 0xA8, 0x05, 0xE7, 0x87, 0x08, 0x00, 0x24, 0xC0,
161 0xE7, 0x67, 0xDF, 0xFF, 0x24, 0xC0, 0xC8, 0x07,
162 0x0A, 0x00, 0xC0, 0x07, 0x00, 0x00, 0xC1, 0x07,
163 0x01, 0x00, 0x9F, 0xAF, 0x28, 0x05, 0x9F, 0xAF,
164 0xB8, 0x05, 0xC0, 0x07, 0x9E, 0x00, 0x9F, 0xAF,
165 0x44, 0x05, 0xE7, 0x67, 0xFF, 0xFE, 0x24, 0xC0,
166 0xC0, 0x09, 0x20, 0xC0, 0xE7, 0x87, 0x00, 0x01,
167 0x24, 0xC0, 0xC0, 0x77, 0x00, 0x02, 0x0F, 0xC1,
168 0xE7, 0x67, 0xF7, 0xFF, 0x24, 0xC0, 0xE7, 0x67,
169 0xF7, 0xFF, 0x24, 0xC0, 0xE7, 0x87, 0x08, 0x00,
170 0x24, 0xC0, 0x08, 0xDA, 0x5E, 0xC1, 0xEF, 0x07,
171 0x80, 0x00, 0x09, 0x06, 0x97, 0xCF, 0xEF, 0x07,
172 0x01, 0x00, 0x0A, 0x06, 0x97, 0xCF, 0xEF, 0x07,
173 0x00, 0x00, 0x0B, 0x06, 0xEF, 0x07, 0x00, 0x00,
174 0x0A, 0x06, 0xEF, 0x67, 0x7F, 0xFF, 0x09, 0x06,
175 0xEF, 0x07, 0x00, 0x00, 0x0D, 0x06, 0xE7, 0x67,
176 0xEF, 0xFF, 0x28, 0xC0, 0xE7, 0x67, 0x17, 0xD8,
177 0x24, 0xC0, 0xE7, 0x07, 0x00, 0x00, 0x1E, 0xC0,
178 0xE7, 0x07, 0xFF, 0xFF, 0x22, 0xC0, 0x97, 0xCF,
179 0xC8, 0x07, 0x0E, 0x06, 0x9F, 0xAF, 0xDA, 0x02,
180 0xE7, 0x07, 0x00, 0x00, 0xF2, 0x05, 0xE7, 0x07,
181 0x10, 0x00, 0xF6, 0x05, 0xE7, 0x07, 0x0E, 0x06,
182 0xF4, 0x05, 0xE7, 0x07, 0xD6, 0x02, 0xF8, 0x05,
183 0xC8, 0x07, 0xF2, 0x05, 0xC1, 0x07, 0x00, 0x80,
184 0x50, 0xAF, 0x97, 0xCF, 0x2F, 0x0C, 0x02, 0x00,
185 0x07, 0x06, 0x2F, 0x0C, 0x04, 0x00, 0x06, 0x06,
186 0xE7, 0x07, 0x00, 0x00, 0xF2, 0x05, 0xE7, 0x07,
187 0x10, 0x00, 0xF6, 0x05, 0xE7, 0x07, 0xE2, 0x05,
188 0xF4, 0x05, 0xE7, 0x07, 0xCE, 0x02, 0xF8, 0x05,
189 0xC8, 0x07, 0xF2, 0x05, 0xC1, 0x07, 0x00, 0x80,
190 0x51, 0xAF, 0x97, 0xCF, 0x9F, 0xAF, 0x66, 0x04,
191 0x9F, 0xAF, 0x1A, 0x03, 0x59, 0xAF, 0x97, 0xCF,
192 0xC0, 0x07, 0x0E, 0x00, 0xC1, 0x0B, 0x0C, 0x06,
193 0x41, 0xD1, 0x9F, 0xAF, 0x28, 0x05, 0xC0, 0x07,
194 0x3C, 0x00, 0x9F, 0xAF, 0x44, 0x05, 0x68, 0x00,
195 0xC0, 0x07, 0x3B, 0x00, 0x9F, 0xAF, 0x44, 0x05,
196 0x6F, 0x00, 0x0C, 0x06, 0x68, 0x00, 0xE0, 0x07,
197 0x04, 0x01, 0xE8, 0x0B, 0x0A, 0x06, 0xE8, 0x07,
198 0x00, 0x00, 0xE0, 0x07, 0x00, 0x02, 0xE0, 0x07,
199 0xEC, 0x01, 0xE0, 0x07, 0xFC, 0xFF, 0x97, 0xCF,
200 0xE7, 0x07, 0xFF, 0xFF, 0xFA, 0x05, 0xEF, 0x07,
201 0x00, 0x00, 0x0B, 0x06, 0xE7, 0x07, 0x0E, 0x06,
202 0x24, 0x01, 0xE7, 0x07, 0x0E, 0x06, 0xFE, 0x05,
203 0xE7, 0x07, 0x40, 0x00, 0x26, 0x01, 0xE7, 0x07,
204 0x40, 0x00, 0x04, 0x06, 0xE7, 0x07, 0x07, 0x00,
205 0x92, 0xC0, 0x97, 0xCF, 0xEF, 0x07, 0x02, 0x00,
206 0x0B, 0x06, 0x9F, 0xAF, 0x78, 0x01, 0xEF, 0x77,
207 0x80, 0x00, 0x07, 0x06, 0x9F, 0xC0, 0x14, 0x04,
208 0xEF, 0x77, 0x01, 0x00, 0x07, 0x06, 0x37, 0xC0,
209 0xEF, 0x77, 0x01, 0x00, 0x0D, 0x06, 0x0F, 0xC1,
210 0xEF, 0x07, 0x01, 0x00, 0x0D, 0x06, 0xC0, 0x07,
211 0x02, 0x00, 0xC1, 0x07, 0x30, 0x00, 0x9F, 0xAF,
212 0x28, 0x05, 0xC0, 0x07, 0x01, 0x00, 0xC1, 0x07,
213 0x02, 0x00, 0x9F, 0xAF, 0x28, 0x05, 0xC8, 0x07,
214 0xFF, 0x4F, 0x9F, 0xAF, 0xA8, 0x05, 0xC0, 0x07,
215 0x38, 0x00, 0x9F, 0xAF, 0x44, 0x05, 0xC1, 0x77,
216 0x03, 0x00, 0x02, 0xC1, 0x08, 0xDA, 0x75, 0xC1,
217 0xC1, 0x77, 0x01, 0x00, 0x0A, 0xC1, 0xC0, 0x07,
218 0x01, 0x00, 0xC1, 0x07, 0x02, 0x00, 0x9F, 0xAF,
219 0x28, 0x05, 0xEF, 0x07, 0x01, 0x00, 0x06, 0x06,
220 0x2C, 0xCF, 0xC0, 0x07, 0x01, 0x00, 0xC1, 0x07,
221 0x04, 0x00, 0x9F, 0xAF, 0x28, 0x05, 0xEF, 0x07,
222 0x00, 0x00, 0x06, 0x06, 0x22, 0xCF, 0xEF, 0x07,
223 0x00, 0x00, 0x0D, 0x06, 0xEF, 0x57, 0x01, 0x00,
224 0x06, 0x06, 0x1B, 0xC0, 0xC0, 0x07, 0x01, 0x00,
225 0xC1, 0x07, 0x01, 0x00, 0x9F, 0xAF, 0x28, 0x05,
226 0xC0, 0x07, 0x02, 0x00, 0xC1, 0x07, 0x30, 0x00,
227 0x9F, 0xAF, 0x28, 0x05, 0xC8, 0x07, 0xFF, 0x4F,
228 0x9F, 0xAF, 0xA8, 0x05, 0xC0, 0x07, 0x38, 0x00,
229 0x9F, 0xAF, 0x44, 0x05, 0xC1, 0x67, 0x03, 0x00,
230 0xC1, 0x57, 0x03, 0x00, 0x02, 0xC0, 0x08, 0xDA,
231 0x73, 0xC1, 0xC0, 0x07, 0x02, 0x00, 0xC1, 0x07,
232 0x12, 0x00, 0xEF, 0x57, 0x00, 0x00, 0x06, 0x06,
233 0x02, 0xC0, 0xC1, 0x07, 0x23, 0x00, 0x9F, 0xAF,
234 0x28, 0x05, 0xC0, 0x07, 0x14, 0x00, 0xC1, 0x0B,
235 0xEA, 0x05, 0x9F, 0xAF, 0x28, 0x05, 0xC0, 0x07,
236 0x3E, 0x00, 0x9F, 0xAF, 0x0A, 0x05, 0xE7, 0x09,
237 0xE4, 0x05, 0xFA, 0x05, 0x27, 0xD8, 0xFA, 0x05,
238 0xE7, 0x07, 0x0E, 0x06, 0xFC, 0x05, 0xE7, 0x07,
239 0x4E, 0x06, 0x00, 0x06, 0xE7, 0x07, 0x40, 0x00,
240 0x02, 0x06, 0x9F, 0xAF, 0x66, 0x05, 0x9F, 0xAF,
241 0xC6, 0x00, 0x97, 0xCF, 0xC1, 0x0B, 0xE2, 0x05,
242 0x41, 0xD0, 0x01, 0xD2, 0xC1, 0x17, 0x23, 0x00,
243 0x9F, 0xAF, 0xDC, 0x04, 0xC0, 0x07, 0x04, 0x00,
244 0xC1, 0x0B, 0xE3, 0x05, 0x9F, 0xAF, 0x28, 0x05,
245 0xC0, 0x07, 0x06, 0x00, 0xC1, 0x09, 0xE6, 0x05,
246 0x9F, 0xAF, 0x28, 0x05, 0xC0, 0x07, 0x07, 0x00,
247 0xC1, 0x09, 0xE6, 0x05, 0xC1, 0xD1, 0x9F, 0xAF,
248 0x28, 0x05, 0xC0, 0x07, 0x0B, 0x00, 0xC1, 0x09,
249 0xE8, 0x05, 0x9F, 0xAF, 0x28, 0x05, 0xC0, 0x07,
250 0x0C, 0x00, 0xC1, 0x09, 0xE8, 0x05, 0xC1, 0xD1,
251 0x9F, 0xAF, 0x28, 0x05, 0xC0, 0x07, 0x0D, 0x00,
252 0xC1, 0x07, 0x09, 0x00, 0x9F, 0xAF, 0x28, 0x05,
253 0xC0, 0x07, 0x03, 0x00, 0xC1, 0x07, 0x32, 0x00,
254 0x9F, 0xAF, 0x28, 0x05, 0xC0, 0x07, 0x0F, 0x00,
255 0xC1, 0x07, 0x00, 0x00, 0x9F, 0xAF, 0x28, 0x05,
256 0x97, 0xCF, 0xE7, 0x67, 0xFF, 0xD9, 0x24, 0xC0,
257 0xC8, 0x07, 0x0A, 0x00, 0x40, 0x00, 0xC0, 0x67,
258 0x00, 0x02, 0x27, 0x80, 0x24, 0xC0, 0xE7, 0x87,
259 0x00, 0x04, 0x24, 0xC0, 0xE7, 0x67, 0xFF, 0xF9,
260 0x24, 0xC0, 0x01, 0xD2, 0x08, 0xDA, 0x72, 0xC1,
261 0xE7, 0x87, 0x00, 0x20, 0x24, 0xC0, 0x97, 0xCF,
262 0x27, 0x00, 0x1E, 0xC0, 0xE7, 0x87, 0xFF, 0x00,
263 0x22, 0xC0, 0xE7, 0x67, 0x7F, 0xFF, 0x24, 0xC0,
264 0xE7, 0x87, 0x80, 0x00, 0x24, 0xC0, 0xE7, 0x87,
265 0x80, 0x00, 0x24, 0xC0, 0x97, 0xCF, 0x9F, 0xAF,
266 0x0A, 0x05, 0x67, 0x00, 0x1E, 0xC0, 0xE7, 0x67,
267 0xBF, 0xFF, 0x24, 0xC0, 0xE7, 0x87, 0x40, 0x00,
268 0x24, 0xC0, 0xE7, 0x87, 0x40, 0x00, 0x24, 0xC0,
269 0x97, 0xCF, 0x9F, 0xAF, 0x0A, 0x05, 0xE7, 0x67,
270 0x00, 0xFF, 0x22, 0xC0, 0xE7, 0x67, 0xFF, 0xFE,
271 0x24, 0xC0, 0xE7, 0x67, 0xFF, 0xFE, 0x24, 0xC0,
272 0xC1, 0x09, 0x20, 0xC0, 0xE7, 0x87, 0x00, 0x01,
273 0x24, 0xC0, 0x97, 0xCF, 0xC0, 0x07, 0x40, 0x00,
274 0xC8, 0x09, 0xFC, 0x05, 0xE7, 0x67, 0x00, 0xFF,
275 0x22, 0xC0, 0xE7, 0x67, 0xFF, 0xFE, 0x24, 0xC0,
276 0xE7, 0x67, 0xBF, 0xFF, 0x24, 0xC0, 0xE7, 0x67,
277 0xBF, 0xFF, 0x24, 0xC0, 0x00, 0xDA, 0xE8, 0x09,
278 0x20, 0xC0, 0xE7, 0x87, 0x40, 0x00, 0x24, 0xC0,
279 0xE7, 0x87, 0x40, 0x00, 0x24, 0xC0, 0x00, 0xDA,
280 0xE8, 0x09, 0x20, 0xC0, 0x6D, 0xC1, 0xE7, 0x87,
281 0x00, 0x01, 0x24, 0xC0, 0x97, 0xCF, 0xE7, 0x07,
282 0x32, 0x00, 0x12, 0xC0, 0xE7, 0x77, 0x00, 0x80,
283 0x12, 0xC0, 0x7C, 0xC0, 0x97, 0xCF, 0xE7, 0x07,
284 0x20, 0x4E, 0x12, 0xC0, 0xE7, 0x77, 0x00, 0x80,
285 0x12, 0xC0, 0x7C, 0xC0, 0x97, 0xCF, 0x09, 0x02,
286 0x19, 0x00, 0x01, 0x01, 0x00, 0x80, 0x96, 0x09,
287 0x04, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
288 0x07, 0x05, 0x81, 0x02, 0x40, 0x00, 0x00, 0x00,
289 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
290 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
291 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
292 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
293 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
294 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
295 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
296 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
297 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
298 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
299 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
300 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
301 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
302 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
303 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
304 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
305 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
306 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
307 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
308 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
309 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
310 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
311};
312
313static unsigned char setup5[] = {
314 0xB6, 0xC3, 0x2F, 0x01, 0x03, 0x64, 0x0E, 0x00,
315 0x14, 0x00, 0x1A, 0x00, 0x20, 0x00, 0x26, 0x00,
316 0x4A, 0x00, 0x64, 0x00, 0x6A, 0x00, 0x92, 0x00,
317 0x9A, 0x00, 0xA0, 0x00, 0xB2, 0x00, 0xB8, 0x00,
318 0xBE, 0x00, 0xC2, 0x00, 0xC8, 0x00, 0xCE, 0x00,
319 0xDC, 0x00, 0xDA, 0x00, 0xE2, 0x00, 0xE0, 0x00,
320 0xE8, 0x00, 0xE6, 0x00, 0xEE, 0x00, 0xEC, 0x00,
321 0xF2, 0x00, 0xF8, 0x00, 0x02, 0x01, 0x0A, 0x01,
322 0x0E, 0x01, 0x12, 0x01, 0x1E, 0x01, 0x22, 0x01,
323 0x28, 0x01, 0x2C, 0x01, 0x32, 0x01, 0x36, 0x01,
324 0x44, 0x01, 0x50, 0x01, 0x5E, 0x01, 0x72, 0x01,
325 0x76, 0x01, 0x7A, 0x01, 0x80, 0x01, 0x88, 0x01,
326 0x8C, 0x01, 0x94, 0x01, 0x9C, 0x01, 0xA0, 0x01,
327 0xA4, 0x01, 0xAA, 0x01, 0xB0, 0x01, 0xB4, 0x01,
328 0xBA, 0x01, 0xD0, 0x01, 0xDA, 0x01, 0xF6, 0x01,
329 0xFA, 0x01, 0x02, 0x02, 0x34, 0x02, 0x3C, 0x02,
330 0x44, 0x02, 0x4A, 0x02, 0x50, 0x02, 0x56, 0x02,
331 0x74, 0x02, 0x78, 0x02, 0x7E, 0x02, 0x84, 0x02,
332 0x8A, 0x02, 0x88, 0x02, 0x90, 0x02, 0x8E, 0x02,
333 0x94, 0x02, 0xA2, 0x02, 0xA8, 0x02, 0xAE, 0x02,
334 0xB4, 0x02, 0xBA, 0x02, 0xB8, 0x02, 0xC0, 0x02,
335 0xBE, 0x02, 0xC4, 0x02, 0xD0, 0x02, 0xD4, 0x02,
336 0xE0, 0x02, 0xE6, 0x02, 0xEE, 0x02, 0xF8, 0x02,
337 0xFC, 0x02, 0x06, 0x03, 0x1E, 0x03, 0x24, 0x03,
338 0x28, 0x03, 0x30, 0x03, 0x2E, 0x03, 0x3C, 0x03,
339 0x4A, 0x03, 0x4E, 0x03, 0x54, 0x03, 0x58, 0x03,
340 0x5E, 0x03, 0x66, 0x03, 0x6E, 0x03, 0x7A, 0x03,
341 0x86, 0x03, 0x8E, 0x03, 0x96, 0x03, 0xB2, 0x03,
342 0xB8, 0x03, 0xC6, 0x03, 0xCC, 0x03, 0xD4, 0x03,
343 0xDA, 0x03, 0xE8, 0x03, 0xF4, 0x03, 0xFC, 0x03,
344 0x04, 0x04, 0x20, 0x04, 0x2A, 0x04, 0x32, 0x04,
345 0x36, 0x04, 0x3E, 0x04, 0x44, 0x04, 0x42, 0x04,
346 0x48, 0x04, 0x4E, 0x04, 0x4C, 0x04, 0x54, 0x04,
347 0x52, 0x04, 0x5A, 0x04, 0x5E, 0x04, 0x62, 0x04,
348 0x68, 0x04, 0x74, 0x04, 0x7C, 0x04, 0x80, 0x04,
349 0x88, 0x04, 0x8C, 0x04, 0x94, 0x04, 0x9A, 0x04,
350 0xA2, 0x04, 0xA6, 0x04, 0xAE, 0x04, 0xB4, 0x04,
351 0xC0, 0x04, 0xCC, 0x04, 0xD8, 0x04, 0x2A, 0x05,
352 0x46, 0x05, 0x6C, 0x05, 0x00, 0x00
353};
354
355/* rvmalloc / rvfree copied from usbvideo.c
356 *
357 * Not sure why these are not yet non-statics which I can reference through
358 * usbvideo.h the same as it is in 2.4.20. I bet this will get fixed sometime
359 * in the future.
360 *
361*/
362static void *rvmalloc(unsigned long size)
363{
364 void *mem;
365 unsigned long adr;
366
367 size = PAGE_ALIGN(size);
368 mem = vmalloc_32(size);
369 if (!mem)
370 return NULL;
371
372 memset(mem, 0, size); /* Clear the ram out, no junk to the user */
373 adr = (unsigned long) mem;
374 while (size > 0) {
375 SetPageReserved(vmalloc_to_page((void *)adr));
376 adr += PAGE_SIZE;
377 size -= PAGE_SIZE;
378 }
379
380 return mem;
381}
382
383static void rvfree(void *mem, unsigned long size)
384{
385 unsigned long adr;
386
387 if (!mem)
388 return;
389
390 adr = (unsigned long) mem;
391 while ((long) size > 0) {
392 ClearPageReserved(vmalloc_to_page((void *)adr));
393 adr += PAGE_SIZE;
394 size -= PAGE_SIZE;
395 }
396 vfree(mem);
397}
398
399struct vicam_camera {
400 u16 shutter_speed; // capture shutter speed
401 u16 gain; // capture gain
402
403 u8 *raw_image; // raw data captured from the camera
404 u8 *framebuf; // processed data in RGB24 format
405 u8 *cntrlbuf; // area used to send control msgs
406
407 struct video_device vdev; // v4l video device
408 struct usb_device *udev; // usb device
409
410 /* guard against simultaneous accesses to the camera */
411 struct mutex cam_lock;
412
413 int is_initialized;
414 u8 open_count;
415 u8 bulkEndpoint;
416 int needsDummyRead;
417
418#if defined(CONFIG_VIDEO_PROC_FS)
419 struct proc_dir_entry *proc_dir;
420#endif
421
422};
423
424static int vicam_probe( struct usb_interface *intf, const struct usb_device_id *id);
425static void vicam_disconnect(struct usb_interface *intf);
426static void read_frame(struct vicam_camera *cam, int framenum);
427static void vicam_decode_color(const u8 *, u8 *);
428
429static int __send_control_msg(struct vicam_camera *cam,
430 u8 request,
431 u16 value,
432 u16 index,
433 unsigned char *cp,
434 u16 size)
435{
436 int status;
437
438 /* cp must be memory that has been allocated by kmalloc */
439
440 status = usb_control_msg(cam->udev,
441 usb_sndctrlpipe(cam->udev, 0),
442 request,
443 USB_DIR_OUT | USB_TYPE_VENDOR |
444 USB_RECIP_DEVICE, value, index,
445 cp, size, 1000);
446
447 status = min(status, 0);
448
449 if (status < 0) {
450 printk(KERN_INFO "Failed sending control message, error %d.\n",
451 status);
452 }
453
454 return status;
455}
456
457static int send_control_msg(struct vicam_camera *cam,
458 u8 request,
459 u16 value,
460 u16 index,
461 unsigned char *cp,
462 u16 size)
463{
464 int status = -ENODEV;
465 mutex_lock(&cam->cam_lock);
466 if (cam->udev) {
467 status = __send_control_msg(cam, request, value,
468 index, cp, size);
469 }
470 mutex_unlock(&cam->cam_lock);
471 return status;
472}
473static int
474initialize_camera(struct vicam_camera *cam)
475{
476 const struct {
477 u8 *data;
478 u32 size;
479 } firmware[] = {
480 { .data = setup1, .size = sizeof(setup1) },
481 { .data = setup2, .size = sizeof(setup2) },
482 { .data = setup3, .size = sizeof(setup3) },
483 { .data = setup4, .size = sizeof(setup4) },
484 { .data = setup5, .size = sizeof(setup5) },
485 { .data = setup3, .size = sizeof(setup3) },
486 { .data = NULL, .size = 0 }
487 };
488
489 int err, i;
490
491 for (i = 0, err = 0; firmware[i].data && !err; i++) {
492 memcpy(cam->cntrlbuf, firmware[i].data, firmware[i].size);
493
494 err = send_control_msg(cam, 0xff, 0, 0,
495 cam->cntrlbuf, firmware[i].size);
496 }
497
498 return err;
499}
500
501static int
502set_camera_power(struct vicam_camera *cam, int state)
503{
504 int status;
505
506 if ((status = send_control_msg(cam, 0x50, state, 0, NULL, 0)) < 0)
507 return status;
508
509 if (state) {
510 send_control_msg(cam, 0x55, 1, 0, NULL, 0);
511 }
512
513 return 0;
514}
515
516static int
517vicam_ioctl(struct inode *inode, struct file *file, unsigned int ioctlnr, unsigned long arg)
518{
519 void __user *user_arg = (void __user *)arg;
520 struct vicam_camera *cam = file->private_data;
521 int retval = 0;
522
523 if (!cam)
524 return -ENODEV;
525
526 switch (ioctlnr) {
527 /* query capabilities */
528 case VIDIOCGCAP:
529 {
530 struct video_capability b;
531
532 DBG("VIDIOCGCAP\n");
533 memset(&b, 0, sizeof(b));
534 strcpy(b.name, "ViCam-based Camera");
535 b.type = VID_TYPE_CAPTURE;
536 b.channels = 1;
537 b.audios = 0;
538 b.maxwidth = 320; /* VIDEOSIZE_CIF */
539 b.maxheight = 240;
540 b.minwidth = 320; /* VIDEOSIZE_48_48 */
541 b.minheight = 240;
542
543 if (copy_to_user(user_arg, &b, sizeof(b)))
544 retval = -EFAULT;
545
546 break;
547 }
548 /* get/set video source - we are a camera and nothing else */
549 case VIDIOCGCHAN:
550 {
551 struct video_channel v;
552
553 DBG("VIDIOCGCHAN\n");
554 if (copy_from_user(&v, user_arg, sizeof(v))) {
555 retval = -EFAULT;
556 break;
557 }
558 if (v.channel != 0) {
559 retval = -EINVAL;
560 break;
561 }
562
563 v.channel = 0;
564 strcpy(v.name, "Camera");
565 v.tuners = 0;
566 v.flags = 0;
567 v.type = VIDEO_TYPE_CAMERA;
568 v.norm = 0;
569
570 if (copy_to_user(user_arg, &v, sizeof(v)))
571 retval = -EFAULT;
572 break;
573 }
574
575 case VIDIOCSCHAN:
576 {
577 int v;
578
579 if (copy_from_user(&v, user_arg, sizeof(v)))
580 retval = -EFAULT;
581 DBG("VIDIOCSCHAN %d\n", v);
582
583 if (retval == 0 && v != 0)
584 retval = -EINVAL;
585
586 break;
587 }
588
589 /* image properties */
590 case VIDIOCGPICT:
591 {
592 struct video_picture vp;
593 DBG("VIDIOCGPICT\n");
594 memset(&vp, 0, sizeof (struct video_picture));
595 vp.brightness = cam->gain << 8;
596 vp.depth = 24;
597 vp.palette = VIDEO_PALETTE_RGB24;
598 if (copy_to_user(user_arg, &vp, sizeof (struct video_picture)))
599 retval = -EFAULT;
600 break;
601 }
602
603 case VIDIOCSPICT:
604 {
605 struct video_picture vp;
606
607 if (copy_from_user(&vp, user_arg, sizeof(vp))) {
608 retval = -EFAULT;
609 break;
610 }
611
612 DBG("VIDIOCSPICT depth = %d, pal = %d\n", vp.depth,
613 vp.palette);
614
615 cam->gain = vp.brightness >> 8;
616
617 if (vp.depth != 24
618 || vp.palette != VIDEO_PALETTE_RGB24)
619 retval = -EINVAL;
620
621 break;
622 }
623
624 /* get/set capture window */
625 case VIDIOCGWIN:
626 {
627 struct video_window vw;
628 vw.x = 0;
629 vw.y = 0;
630 vw.width = 320;
631 vw.height = 240;
632 vw.chromakey = 0;
633 vw.flags = 0;
634 vw.clips = NULL;
635 vw.clipcount = 0;
636
637 DBG("VIDIOCGWIN\n");
638
639 if (copy_to_user(user_arg, (void *)&vw, sizeof(vw)))
640 retval = -EFAULT;
641
642 // I'm not sure what the deal with a capture window is, it is very poorly described
643 // in the doc. So I won't support it now.
644 break;
645 }
646
647 case VIDIOCSWIN:
648 {
649
650 struct video_window vw;
651
652 if (copy_from_user(&vw, user_arg, sizeof(vw))) {
653 retval = -EFAULT;
654 break;
655 }
656
657 DBG("VIDIOCSWIN %d x %d\n", vw.width, vw.height);
658
659 if ( vw.width != 320 || vw.height != 240 )
660 retval = -EFAULT;
661
662 break;
663 }
664
665 /* mmap interface */
666 case VIDIOCGMBUF:
667 {
668 struct video_mbuf vm;
669 int i;
670
671 DBG("VIDIOCGMBUF\n");
672 memset(&vm, 0, sizeof (vm));
673 vm.size =
674 VICAM_MAX_FRAME_SIZE * VICAM_FRAMES;
675 vm.frames = VICAM_FRAMES;
676 for (i = 0; i < VICAM_FRAMES; i++)
677 vm.offsets[i] = VICAM_MAX_FRAME_SIZE * i;
678
679 if (copy_to_user(user_arg, (void *)&vm, sizeof(vm)))
680 retval = -EFAULT;
681
682 break;
683 }
684
685 case VIDIOCMCAPTURE:
686 {
687 struct video_mmap vm;
688 // int video_size;
689
690 if (copy_from_user((void *)&vm, user_arg, sizeof(vm))) {
691 retval = -EFAULT;
692 break;
693 }
694
695 DBG("VIDIOCMCAPTURE frame=%d, height=%d, width=%d, format=%d.\n",vm.frame,vm.width,vm.height,vm.format);
696
697 if ( vm.frame >= VICAM_FRAMES || vm.format != VIDEO_PALETTE_RGB24 )
698 retval = -EINVAL;
699
700 // in theory right here we'd start the image capturing
701 // (fill in a bulk urb and submit it asynchronously)
702 //
703 // Instead we're going to do a total hack job for now and
704 // retrieve the frame in VIDIOCSYNC
705
706 break;
707 }
708
709 case VIDIOCSYNC:
710 {
711 int frame;
712
713 if (copy_from_user((void *)&frame, user_arg, sizeof(int))) {
714 retval = -EFAULT;
715 break;
716 }
717 DBG("VIDIOCSYNC: %d\n", frame);
718
719 read_frame(cam, frame);
720 vicam_decode_color(cam->raw_image,
721 cam->framebuf +
722 frame * VICAM_MAX_FRAME_SIZE );
723
724 break;
725 }
726
727 /* pointless to implement overlay with this camera */
728 case VIDIOCCAPTURE:
729 case VIDIOCGFBUF:
730 case VIDIOCSFBUF:
731 case VIDIOCKEY:
732 retval = -EINVAL;
733 break;
734
735 /* tuner interface - we have none */
736 case VIDIOCGTUNER:
737 case VIDIOCSTUNER:
738 case VIDIOCGFREQ:
739 case VIDIOCSFREQ:
740 retval = -EINVAL;
741 break;
742
743 /* audio interface - we have none */
744 case VIDIOCGAUDIO:
745 case VIDIOCSAUDIO:
746 retval = -EINVAL;
747 break;
748 default:
749 retval = -ENOIOCTLCMD;
750 break;
751 }
752
753 return retval;
754}
755
756static int
757vicam_open(struct inode *inode, struct file *file)
758{
759 struct video_device *dev = video_devdata(file);
760 struct vicam_camera *cam =
761 (struct vicam_camera *) dev->priv;
762 DBG("open\n");
763
764 if (!cam) {
765 printk(KERN_ERR
766 "vicam video_device improperly initialized");
767 return -EINVAL;
768 }
769
770 /* the videodev_lock held above us protects us from
771 * simultaneous opens...for now. we probably shouldn't
772 * rely on this fact forever.
773 */
774
775 if (cam->open_count > 0) {
776 printk(KERN_INFO
777 "vicam_open called on already opened camera");
778 return -EBUSY;
779 }
780
781 cam->raw_image = kmalloc(VICAM_MAX_READ_SIZE, GFP_KERNEL);
782 if (!cam->raw_image) {
783 return -ENOMEM;
784 }
785
786 cam->framebuf = rvmalloc(VICAM_MAX_FRAME_SIZE * VICAM_FRAMES);
787 if (!cam->framebuf) {
788 kfree(cam->raw_image);
789 return -ENOMEM;
790 }
791
792 cam->cntrlbuf = kmalloc(PAGE_SIZE, GFP_KERNEL);
793 if (!cam->cntrlbuf) {
794 kfree(cam->raw_image);
795 rvfree(cam->framebuf, VICAM_MAX_FRAME_SIZE * VICAM_FRAMES);
796 return -ENOMEM;
797 }
798
799 // First upload firmware, then turn the camera on
800
801 if (!cam->is_initialized) {
802 initialize_camera(cam);
803
804 cam->is_initialized = 1;
805 }
806
807 set_camera_power(cam, 1);
808
809 cam->needsDummyRead = 1;
810 cam->open_count++;
811
812 file->private_data = cam;
813
814 return 0;
815}
816
817static int
818vicam_close(struct inode *inode, struct file *file)
819{
820 struct vicam_camera *cam = file->private_data;
821 int open_count;
822 struct usb_device *udev;
823
824 DBG("close\n");
825
826 /* it's not the end of the world if
827 * we fail to turn the camera off.
828 */
829
830 set_camera_power(cam, 0);
831
832 kfree(cam->raw_image);
833 rvfree(cam->framebuf, VICAM_MAX_FRAME_SIZE * VICAM_FRAMES);
834 kfree(cam->cntrlbuf);
835
836 mutex_lock(&cam->cam_lock);
837
838 cam->open_count--;
839 open_count = cam->open_count;
840 udev = cam->udev;
841
842 mutex_unlock(&cam->cam_lock);
843
844 if (!open_count && !udev) {
845 kfree(cam);
846 }
847
848 return 0;
849}
850
851static void vicam_decode_color(const u8 *data, u8 *rgb)
852{
853 /* vicam_decode_color - Convert from Vicam Y-Cr-Cb to RGB
854 * Copyright (C) 2002 Monroe Williams (monroe@pobox.com)
855 */
856
857 int i, prevY, nextY;
858
859 prevY = 512;
860 nextY = 512;
861
862 data += VICAM_HEADER_SIZE;
863
864 for( i = 0; i < 240; i++, data += 512 ) {
865 const int y = ( i * 242 ) / 240;
866
867 int j, prevX, nextX;
868 int Y, Cr, Cb;
869
870 if ( y == 242 - 1 ) {
871 nextY = -512;
872 }
873
874 prevX = 1;
875 nextX = 1;
876
877 for ( j = 0; j < 320; j++, rgb += 3 ) {
878 const int x = ( j * 512 ) / 320;
879 const u8 * const src = &data[x];
880
881 if ( x == 512 - 1 ) {
882 nextX = -1;
883 }
884
885 Cr = ( src[prevX] - src[0] ) +
886 ( src[nextX] - src[0] );
887 Cr /= 2;
888
889 Cb = ( src[prevY] - src[prevX + prevY] ) +
890 ( src[prevY] - src[nextX + prevY] ) +
891 ( src[nextY] - src[prevX + nextY] ) +
892 ( src[nextY] - src[nextX + nextY] );
893 Cb /= 4;
894
895 Y = 1160 * ( src[0] + ( Cr / 2 ) - 16 );
896
897 if ( i & 1 ) {
898 int Ct = Cr;
899 Cr = Cb;
900 Cb = Ct;
901 }
902
903 if ( ( x ^ i ) & 1 ) {
904 Cr = -Cr;
905 Cb = -Cb;
906 }
907
908 rgb[0] = clamp( ( ( Y + ( 2017 * Cb ) ) +
909 500 ) / 900, 0, 255 );
910 rgb[1] = clamp( ( ( Y - ( 392 * Cb ) -
911 ( 813 * Cr ) ) +
912 500 ) / 1000, 0, 255 );
913 rgb[2] = clamp( ( ( Y + ( 1594 * Cr ) ) +
914 500 ) / 1300, 0, 255 );
915
916 prevX = -1;
917 }
918
919 prevY = -512;
920 }
921}
922
923static void
924read_frame(struct vicam_camera *cam, int framenum)
925{
926 unsigned char *request = cam->cntrlbuf;
927 int realShutter;
928 int n;
929 int actual_length;
930
931 if (cam->needsDummyRead) {
932 cam->needsDummyRead = 0;
933 read_frame(cam, framenum);
934 }
935
936 memset(request, 0, 16);
937 request[0] = cam->gain; // 0 = 0% gain, FF = 100% gain
938
939 request[1] = 0; // 512x242 capture
940
941 request[2] = 0x90; // the function of these two bytes
942 request[3] = 0x07; // is not yet understood
943
944 if (cam->shutter_speed > 60) {
945 // Short exposure
946 realShutter =
947 ((-15631900 / cam->shutter_speed) + 260533) / 1000;
948 request[4] = realShutter & 0xFF;
949 request[5] = (realShutter >> 8) & 0xFF;
950 request[6] = 0x03;
951 request[7] = 0x01;
952 } else {
953 // Long exposure
954 realShutter = 15600 / cam->shutter_speed - 1;
955 request[4] = 0;
956 request[5] = 0;
957 request[6] = realShutter & 0xFF;
958 request[7] = realShutter >> 8;
959 }
960
961 // Per John Markus Bjørndalen, byte at index 8 causes problems if it isn't 0
962 request[8] = 0;
963 // bytes 9-15 do not seem to affect exposure or image quality
964
965 mutex_lock(&cam->cam_lock);
966
967 if (!cam->udev) {
968 goto done;
969 }
970
971 n = __send_control_msg(cam, 0x51, 0x80, 0, request, 16);
972
973 if (n < 0) {
974 printk(KERN_ERR
975 " Problem sending frame capture control message");
976 goto done;
977 }
978
979 n = usb_bulk_msg(cam->udev,
980 usb_rcvbulkpipe(cam->udev, cam->bulkEndpoint),
981 cam->raw_image,
982 512 * 242 + 128, &actual_length, 10000);
983
984 if (n < 0) {
985 printk(KERN_ERR "Problem during bulk read of frame data: %d\n",
986 n);
987 }
988
989 done:
990 mutex_unlock(&cam->cam_lock);
991}
992
993static ssize_t
994vicam_read( struct file *file, char __user *buf, size_t count, loff_t *ppos )
995{
996 struct vicam_camera *cam = file->private_data;
997
998 DBG("read %d bytes.\n", (int) count);
999
1000 if (*ppos >= VICAM_MAX_FRAME_SIZE) {
1001 *ppos = 0;
1002 return 0;
1003 }
1004
1005 if (*ppos == 0) {
1006 read_frame(cam, 0);
1007 vicam_decode_color(cam->raw_image,
1008 cam->framebuf +
1009 0 * VICAM_MAX_FRAME_SIZE);
1010 }
1011
1012 count = min_t(size_t, count, VICAM_MAX_FRAME_SIZE - *ppos);
1013
1014 if (copy_to_user(buf, &cam->framebuf[*ppos], count)) {
1015 count = -EFAULT;
1016 } else {
1017 *ppos += count;
1018 }
1019
1020 if (count == VICAM_MAX_FRAME_SIZE) {
1021 *ppos = 0;
1022 }
1023
1024 return count;
1025}
1026
1027
1028static int
1029vicam_mmap(struct file *file, struct vm_area_struct *vma)
1030{
1031 // TODO: allocate the raw frame buffer if necessary
1032 unsigned long page, pos;
1033 unsigned long start = vma->vm_start;
1034 unsigned long size = vma->vm_end-vma->vm_start;
1035 struct vicam_camera *cam = file->private_data;
1036
1037 if (!cam)
1038 return -ENODEV;
1039
1040 DBG("vicam_mmap: %ld\n", size);
1041
1042 /* We let mmap allocate as much as it wants because Linux was adding 2048 bytes
1043 * to the size the application requested for mmap and it was screwing apps up.
1044 if (size > VICAM_FRAMES*VICAM_MAX_FRAME_SIZE)
1045 return -EINVAL;
1046 */
1047
1048 pos = (unsigned long)cam->framebuf;
1049 while (size > 0) {
1050 page = vmalloc_to_pfn((void *)pos);
1051 if (remap_pfn_range(vma, start, page, PAGE_SIZE, PAGE_SHARED))
1052 return -EAGAIN;
1053
1054 start += PAGE_SIZE;
1055 pos += PAGE_SIZE;
1056 if (size > PAGE_SIZE)
1057 size -= PAGE_SIZE;
1058 else
1059 size = 0;
1060 }
1061
1062 return 0;
1063}
1064
1065#if defined(CONFIG_VIDEO_PROC_FS)
1066
1067static struct proc_dir_entry *vicam_proc_root = NULL;
1068
1069static int vicam_read_helper(char *page, char **start, off_t off,
1070 int count, int *eof, int value)
1071{
1072 char *out = page;
1073 int len;
1074
1075 out += sprintf(out, "%d",value);
1076
1077 len = out - page;
1078 len -= off;
1079 if (len < count) {
1080 *eof = 1;
1081 if (len <= 0)
1082 return 0;
1083 } else
1084 len = count;
1085
1086 *start = page + off;
1087 return len;
1088}
1089
1090static int vicam_read_proc_shutter(char *page, char **start, off_t off,
1091 int count, int *eof, void *data)
1092{
1093 return vicam_read_helper(page,start,off,count,eof,
1094 ((struct vicam_camera *)data)->shutter_speed);
1095}
1096
1097static int vicam_read_proc_gain(char *page, char **start, off_t off,
1098 int count, int *eof, void *data)
1099{
1100 return vicam_read_helper(page,start,off,count,eof,
1101 ((struct vicam_camera *)data)->gain);
1102}
1103
1104static int
1105vicam_write_proc_shutter(struct file *file, const char *buffer,
1106 unsigned long count, void *data)
1107{
1108 u16 stmp;
1109 char kbuf[8];
1110 struct vicam_camera *cam = (struct vicam_camera *) data;
1111
1112 if (count > 6)
1113 return -EINVAL;
1114
1115 if (copy_from_user(kbuf, buffer, count))
1116 return -EFAULT;
1117
1118 stmp = (u16) simple_strtoul(kbuf, NULL, 10);
1119 if (stmp < 4 || stmp > 32000)
1120 return -EINVAL;
1121
1122 cam->shutter_speed = stmp;
1123
1124 return count;
1125}
1126
1127static int
1128vicam_write_proc_gain(struct file *file, const char *buffer,
1129 unsigned long count, void *data)
1130{
1131 u16 gtmp;
1132 char kbuf[8];
1133
1134 struct vicam_camera *cam = (struct vicam_camera *) data;
1135
1136 if (count > 4)
1137 return -EINVAL;
1138
1139 if (copy_from_user(kbuf, buffer, count))
1140 return -EFAULT;
1141
1142 gtmp = (u16) simple_strtoul(kbuf, NULL, 10);
1143 if (gtmp > 255)
1144 return -EINVAL;
1145 cam->gain = gtmp;
1146
1147 return count;
1148}
1149
1150static void
1151vicam_create_proc_root(void)
1152{
1153 vicam_proc_root = proc_mkdir("video/vicam", NULL);
1154
1155 if (vicam_proc_root)
1156 vicam_proc_root->owner = THIS_MODULE;
1157 else
1158 printk(KERN_ERR
1159 "could not create /proc entry for vicam!");
1160}
1161
1162static void
1163vicam_destroy_proc_root(void)
1164{
1165 if (vicam_proc_root)
1166 remove_proc_entry("video/vicam", 0);
1167}
1168
1169static void
1170vicam_create_proc_entry(struct vicam_camera *cam)
1171{
1172 char name[64];
1173 struct proc_dir_entry *ent;
1174
1175 DBG(KERN_INFO "vicam: creating proc entry\n");
1176
1177 if (!vicam_proc_root || !cam) {
1178 printk(KERN_INFO
1179 "vicam: could not create proc entry, %s pointer is null.\n",
1180 (!cam ? "camera" : "root"));
1181 return;
1182 }
1183
1184 sprintf(name, "video%d", cam->vdev.minor);
1185
1186 cam->proc_dir = proc_mkdir(name, vicam_proc_root);
1187
1188 if ( !cam->proc_dir )
1189 return; // FIXME: We should probably return an error here
1190
1191 ent = create_proc_entry("shutter", S_IFREG | S_IRUGO | S_IWUSR,
1192 cam->proc_dir);
1193 if (ent) {
1194 ent->data = cam;
1195 ent->read_proc = vicam_read_proc_shutter;
1196 ent->write_proc = vicam_write_proc_shutter;
1197 ent->size = 64;
1198 }
1199
1200 ent = create_proc_entry("gain", S_IFREG | S_IRUGO | S_IWUSR,
1201 cam->proc_dir);
1202 if (ent) {
1203 ent->data = cam;
1204 ent->read_proc = vicam_read_proc_gain;
1205 ent->write_proc = vicam_write_proc_gain;
1206 ent->size = 64;
1207 }
1208}
1209
1210static void
1211vicam_destroy_proc_entry(void *ptr)
1212{
1213 struct vicam_camera *cam = (struct vicam_camera *) ptr;
1214 char name[16];
1215
1216 if ( !cam->proc_dir )
1217 return;
1218
1219 sprintf(name, "video%d", cam->vdev.minor);
1220 remove_proc_entry("shutter", cam->proc_dir);
1221 remove_proc_entry("gain", cam->proc_dir);
1222 remove_proc_entry(name,vicam_proc_root);
1223 cam->proc_dir = NULL;
1224
1225}
1226
1227#else
1228static inline void vicam_create_proc_root(void) { }
1229static inline void vicam_destroy_proc_root(void) { }
1230static inline void vicam_create_proc_entry(struct vicam_camera *cam) { }
1231static inline void vicam_destroy_proc_entry(void *ptr) { }
1232#endif
1233
1234static struct file_operations vicam_fops = {
1235 .owner = THIS_MODULE,
1236 .open = vicam_open,
1237 .release = vicam_close,
1238 .read = vicam_read,
1239 .mmap = vicam_mmap,
1240 .ioctl = vicam_ioctl,
1241 .compat_ioctl = v4l_compat_ioctl32,
1242 .llseek = no_llseek,
1243};
1244
1245static struct video_device vicam_template = {
1246 .owner = THIS_MODULE,
1247 .name = "ViCam-based USB Camera",
1248 .type = VID_TYPE_CAPTURE,
1249 .hardware = VID_HARDWARE_VICAM,
1250 .fops = &vicam_fops,
1251 .minor = -1,
1252};
1253
1254/* table of devices that work with this driver */
1255static struct usb_device_id vicam_table[] = {
1256 {USB_DEVICE(USB_VICAM_VENDOR_ID, USB_VICAM_PRODUCT_ID)},
1257 {} /* Terminating entry */
1258};
1259
1260MODULE_DEVICE_TABLE(usb, vicam_table);
1261
1262static struct usb_driver vicam_driver = {
1263 .name = "vicam",
1264 .probe = vicam_probe,
1265 .disconnect = vicam_disconnect,
1266 .id_table = vicam_table
1267};
1268
1269/**
1270 * vicam_probe
1271 * @intf: the interface
1272 * @id: the device id
1273 *
1274 * Called by the usb core when a new device is connected that it thinks
1275 * this driver might be interested in.
1276 */
1277static int
1278vicam_probe( struct usb_interface *intf, const struct usb_device_id *id)
1279{
1280 struct usb_device *dev = interface_to_usbdev(intf);
1281 int bulkEndpoint = 0;
1282 const struct usb_host_interface *interface;
1283 const struct usb_endpoint_descriptor *endpoint;
1284 struct vicam_camera *cam;
1285
1286 printk(KERN_INFO "ViCam based webcam connected\n");
1287
1288 interface = intf->cur_altsetting;
1289
1290 DBG(KERN_DEBUG "Interface %d. has %u. endpoints!\n",
1291 interface->desc.bInterfaceNumber, (unsigned) (interface->desc.bNumEndpoints));
1292 endpoint = &interface->endpoint[0].desc;
1293
1294 if ((endpoint->bEndpointAddress & 0x80) &&
1295 ((endpoint->bmAttributes & 3) == 0x02)) {
1296 /* we found a bulk in endpoint */
1297 bulkEndpoint = endpoint->bEndpointAddress;
1298 } else {
1299 printk(KERN_ERR
1300 "No bulk in endpoint was found ?! (this is bad)\n");
1301 }
1302
1303 if ((cam =
1304 kmalloc(sizeof (struct vicam_camera), GFP_KERNEL)) == NULL) {
1305 printk(KERN_WARNING
1306 "could not allocate kernel memory for vicam_camera struct\n");
1307 return -ENOMEM;
1308 }
1309
1310 memset(cam, 0, sizeof (struct vicam_camera));
1311
1312 cam->shutter_speed = 15;
1313
1314 mutex_init(&cam->cam_lock);
1315
1316 memcpy(&cam->vdev, &vicam_template,
1317 sizeof (vicam_template));
1318 cam->vdev.priv = cam; // sort of a reverse mapping for those functions that get vdev only
1319
1320 cam->udev = dev;
1321 cam->bulkEndpoint = bulkEndpoint;
1322
1323 if (video_register_device(&cam->vdev, VFL_TYPE_GRABBER, -1) == -1) {
1324 kfree(cam);
1325 printk(KERN_WARNING "video_register_device failed\n");
1326 return -EIO;
1327 }
1328
1329 vicam_create_proc_entry(cam);
1330
1331 printk(KERN_INFO "ViCam webcam driver now controlling video device %d\n",cam->vdev.minor);
1332
1333 usb_set_intfdata (intf, cam);
1334
1335 return 0;
1336}
1337
1338static void
1339vicam_disconnect(struct usb_interface *intf)
1340{
1341 int open_count;
1342 struct vicam_camera *cam = usb_get_intfdata (intf);
1343 usb_set_intfdata (intf, NULL);
1344
1345 /* we must unregister the device before taking its
1346 * cam_lock. This is because the video open call
1347 * holds the same lock as video unregister. if we
1348 * unregister inside of the cam_lock and open also
1349 * uses the cam_lock, we get deadlock.
1350 */
1351
1352 video_unregister_device(&cam->vdev);
1353
1354 /* stop the camera from being used */
1355
1356 mutex_lock(&cam->cam_lock);
1357
1358 /* mark the camera as gone */
1359
1360 cam->udev = NULL;
1361
1362 vicam_destroy_proc_entry(cam);
1363
1364 /* the only thing left to do is synchronize with
1365 * our close/release function on who should release
1366 * the camera memory. if there are any users using the
1367 * camera, it's their job. if there are no users,
1368 * it's ours.
1369 */
1370
1371 open_count = cam->open_count;
1372
1373 mutex_unlock(&cam->cam_lock);
1374
1375 if (!open_count) {
1376 kfree(cam);
1377 }
1378
1379 printk(KERN_DEBUG "ViCam-based WebCam disconnected\n");
1380}
1381
1382/*
1383 */
1384static int __init
1385usb_vicam_init(void)
1386{
1387 int retval;
1388 DBG(KERN_INFO "ViCam-based WebCam driver startup\n");
1389 vicam_create_proc_root();
1390 retval = usb_register(&vicam_driver);
1391 if (retval)
1392 printk(KERN_WARNING "usb_register failed!\n");
1393 return retval;
1394}
1395
1396static void __exit
1397usb_vicam_exit(void)
1398{
1399 DBG(KERN_INFO
1400 "ViCam-based WebCam driver shutdown\n");
1401
1402 usb_deregister(&vicam_driver);
1403 vicam_destroy_proc_root();
1404}
1405
1406module_init(usb_vicam_init);
1407module_exit(usb_vicam_exit);
1408
1409MODULE_AUTHOR(DRIVER_AUTHOR);
1410MODULE_DESCRIPTION(DRIVER_DESC);
1411MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/w9968cf.c b/drivers/media/video/w9968cf.c
new file mode 100644
index 000000000000..b57dec3782e0
--- /dev/null
+++ b/drivers/media/video/w9968cf.c
@@ -0,0 +1,3691 @@
1/***************************************************************************
2 * Video4Linux driver for W996[87]CF JPEG USB Dual Mode Camera Chip. *
3 * *
4 * Copyright (C) 2002-2004 by Luca Risolia <luca.risolia@studio.unibo.it> *
5 * *
6 * - Memory management code from bttv driver by Ralph Metzler, *
7 * Marcus Metzler and Gerd Knorr. *
8 * - I2C interface to kernel, high-level image sensor control routines and *
9 * some symbolic names from OV511 driver by Mark W. McClelland. *
10 * - Low-level I2C fast write function by Piotr Czerczak. *
11 * - Low-level I2C read function by Frederic Jouault. *
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., 675 Mass Ave, Cambridge, MA 02139, USA. *
26 ***************************************************************************/
27
28#include <linux/module.h>
29#include <linux/kernel.h>
30#include <linux/kmod.h>
31#include <linux/init.h>
32#include <linux/fs.h>
33#include <linux/vmalloc.h>
34#include <linux/slab.h>
35#include <linux/mm.h>
36#include <linux/string.h>
37#include <linux/errno.h>
38#include <linux/sched.h>
39#include <linux/ioctl.h>
40#include <linux/delay.h>
41#include <linux/stddef.h>
42#include <asm/page.h>
43#include <asm/uaccess.h>
44#include <linux/page-flags.h>
45#include <linux/moduleparam.h>
46
47#include "w9968cf.h"
48#include "w9968cf_decoder.h"
49
50static struct w9968cf_vpp_t* w9968cf_vpp;
51static DECLARE_WAIT_QUEUE_HEAD(w9968cf_vppmod_wait);
52
53static LIST_HEAD(w9968cf_dev_list); /* head of V4L registered cameras list */
54static DEFINE_MUTEX(w9968cf_devlist_mutex); /* semaphore for list traversal */
55
56static DECLARE_RWSEM(w9968cf_disconnect); /* prevent races with open() */
57
58
59/****************************************************************************
60 * Module macros and parameters *
61 ****************************************************************************/
62
63MODULE_DEVICE_TABLE(usb, winbond_id_table);
64
65MODULE_AUTHOR(W9968CF_MODULE_AUTHOR" "W9968CF_AUTHOR_EMAIL);
66MODULE_DESCRIPTION(W9968CF_MODULE_NAME);
67MODULE_VERSION(W9968CF_MODULE_VERSION);
68MODULE_LICENSE(W9968CF_MODULE_LICENSE);
69MODULE_SUPPORTED_DEVICE("Video");
70
71static int ovmod_load = W9968CF_OVMOD_LOAD;
72static unsigned short simcams = W9968CF_SIMCAMS;
73static short video_nr[]={[0 ... W9968CF_MAX_DEVICES-1] = -1}; /*-1=first free*/
74static unsigned int packet_size[] = {[0 ... W9968CF_MAX_DEVICES-1] =
75 W9968CF_PACKET_SIZE};
76static unsigned short max_buffers[] = {[0 ... W9968CF_MAX_DEVICES-1] =
77 W9968CF_BUFFERS};
78static int double_buffer[] = {[0 ... W9968CF_MAX_DEVICES-1] =
79 W9968CF_DOUBLE_BUFFER};
80static int clamping[] = {[0 ... W9968CF_MAX_DEVICES-1] = W9968CF_CLAMPING};
81static unsigned short filter_type[]= {[0 ... W9968CF_MAX_DEVICES-1] =
82 W9968CF_FILTER_TYPE};
83static int largeview[]= {[0 ... W9968CF_MAX_DEVICES-1] = W9968CF_LARGEVIEW};
84static unsigned short decompression[] = {[0 ... W9968CF_MAX_DEVICES-1] =
85 W9968CF_DECOMPRESSION};
86static int upscaling[]= {[0 ... W9968CF_MAX_DEVICES-1] = W9968CF_UPSCALING};
87static unsigned short force_palette[] = {[0 ... W9968CF_MAX_DEVICES-1] = 0};
88static int force_rgb[] = {[0 ... W9968CF_MAX_DEVICES-1] = W9968CF_FORCE_RGB};
89static int autobright[] = {[0 ... W9968CF_MAX_DEVICES-1] = W9968CF_AUTOBRIGHT};
90static int autoexp[] = {[0 ... W9968CF_MAX_DEVICES-1] = W9968CF_AUTOEXP};
91static unsigned short lightfreq[] = {[0 ... W9968CF_MAX_DEVICES-1] =
92 W9968CF_LIGHTFREQ};
93static int bandingfilter[] = {[0 ... W9968CF_MAX_DEVICES-1]=
94 W9968CF_BANDINGFILTER};
95static short clockdiv[] = {[0 ... W9968CF_MAX_DEVICES-1] = W9968CF_CLOCKDIV};
96static int backlight[] = {[0 ... W9968CF_MAX_DEVICES-1] = W9968CF_BACKLIGHT};
97static int mirror[] = {[0 ... W9968CF_MAX_DEVICES-1] = W9968CF_MIRROR};
98static int monochrome[] = {[0 ... W9968CF_MAX_DEVICES-1]=W9968CF_MONOCHROME};
99static unsigned int brightness[] = {[0 ... W9968CF_MAX_DEVICES-1] =
100 W9968CF_BRIGHTNESS};
101static unsigned int hue[] = {[0 ... W9968CF_MAX_DEVICES-1] = W9968CF_HUE};
102static unsigned int colour[]={[0 ... W9968CF_MAX_DEVICES-1] = W9968CF_COLOUR};
103static unsigned int contrast[] = {[0 ... W9968CF_MAX_DEVICES-1] =
104 W9968CF_CONTRAST};
105static unsigned int whiteness[] = {[0 ... W9968CF_MAX_DEVICES-1] =
106 W9968CF_WHITENESS};
107#ifdef W9968CF_DEBUG
108static unsigned short debug = W9968CF_DEBUG_LEVEL;
109static int specific_debug = W9968CF_SPECIFIC_DEBUG;
110#endif
111
112static unsigned int param_nv[24]; /* number of values per parameter */
113
114#ifdef CONFIG_KMOD
115module_param(ovmod_load, bool, 0644);
116#endif
117module_param(simcams, ushort, 0644);
118module_param_array(video_nr, short, &param_nv[0], 0444);
119module_param_array(packet_size, uint, &param_nv[1], 0444);
120module_param_array(max_buffers, ushort, &param_nv[2], 0444);
121module_param_array(double_buffer, bool, &param_nv[3], 0444);
122module_param_array(clamping, bool, &param_nv[4], 0444);
123module_param_array(filter_type, ushort, &param_nv[5], 0444);
124module_param_array(largeview, bool, &param_nv[6], 0444);
125module_param_array(decompression, ushort, &param_nv[7], 0444);
126module_param_array(upscaling, bool, &param_nv[8], 0444);
127module_param_array(force_palette, ushort, &param_nv[9], 0444);
128module_param_array(force_rgb, ushort, &param_nv[10], 0444);
129module_param_array(autobright, bool, &param_nv[11], 0444);
130module_param_array(autoexp, bool, &param_nv[12], 0444);
131module_param_array(lightfreq, ushort, &param_nv[13], 0444);
132module_param_array(bandingfilter, bool, &param_nv[14], 0444);
133module_param_array(clockdiv, short, &param_nv[15], 0444);
134module_param_array(backlight, bool, &param_nv[16], 0444);
135module_param_array(mirror, bool, &param_nv[17], 0444);
136module_param_array(monochrome, bool, &param_nv[18], 0444);
137module_param_array(brightness, uint, &param_nv[19], 0444);
138module_param_array(hue, uint, &param_nv[20], 0444);
139module_param_array(colour, uint, &param_nv[21], 0444);
140module_param_array(contrast, uint, &param_nv[22], 0444);
141module_param_array(whiteness, uint, &param_nv[23], 0444);
142#ifdef W9968CF_DEBUG
143module_param(debug, ushort, 0644);
144module_param(specific_debug, bool, 0644);
145#endif
146
147#ifdef CONFIG_KMOD
148MODULE_PARM_DESC(ovmod_load,
149 "\n<0|1> Automatic 'ovcamchip' module loading."
150 "\n0 disabled, 1 enabled."
151 "\nIf enabled,'insmod' searches for the required 'ovcamchip'"
152 "\nmodule in the system, according to its configuration, and"
153 "\nattempts to load that module automatically. This action is"
154 "\nperformed once as soon as the 'w9968cf' module is loaded"
155 "\ninto memory."
156 "\nDefault value is "__MODULE_STRING(W9968CF_OVMOD_LOAD)"."
157 "\n");
158#endif
159MODULE_PARM_DESC(simcams,
160 "\n<n> Number of cameras allowed to stream simultaneously."
161 "\nn may vary from 0 to "
162 __MODULE_STRING(W9968CF_MAX_DEVICES)"."
163 "\nDefault value is "__MODULE_STRING(W9968CF_SIMCAMS)"."
164 "\n");
165MODULE_PARM_DESC(video_nr,
166 "\n<-1|n[,...]> Specify V4L minor mode number."
167 "\n -1 = use next available (default)"
168 "\n n = use minor number n (integer >= 0)"
169 "\nYou can specify up to "__MODULE_STRING(W9968CF_MAX_DEVICES)
170 " cameras this way."
171 "\nFor example:"
172 "\nvideo_nr=-1,2,-1 would assign minor number 2 to"
173 "\nthe second camera and use auto for the first"
174 "\none and for every other camera."
175 "\n");
176MODULE_PARM_DESC(packet_size,
177 "\n<n[,...]> Specify the maximum data payload"
178 "\nsize in bytes for alternate settings, for each device."
179 "\nn is scaled between 63 and 1023 "
180 "(default is "__MODULE_STRING(W9968CF_PACKET_SIZE)")."
181 "\n");
182MODULE_PARM_DESC(max_buffers,
183 "\n<n[,...]> For advanced users."
184 "\nSpecify the maximum number of video frame buffers"
185 "\nto allocate for each device, from 2 to "
186 __MODULE_STRING(W9968CF_MAX_BUFFERS)
187 ". (default is "__MODULE_STRING(W9968CF_BUFFERS)")."
188 "\n");
189MODULE_PARM_DESC(double_buffer,
190 "\n<0|1[,...]> "
191 "Hardware double buffering: 0 disabled, 1 enabled."
192 "\nIt should be enabled if you want smooth video output: if"
193 "\nyou obtain out of sync. video, disable it, or try to"
194 "\ndecrease the 'clockdiv' module parameter value."
195 "\nDefault value is "__MODULE_STRING(W9968CF_DOUBLE_BUFFER)
196 " for every device."
197 "\n");
198MODULE_PARM_DESC(clamping,
199 "\n<0|1[,...]> Video data clamping: 0 disabled, 1 enabled."
200 "\nDefault value is "__MODULE_STRING(W9968CF_CLAMPING)
201 " for every device."
202 "\n");
203MODULE_PARM_DESC(filter_type,
204 "\n<0|1|2[,...]> Video filter type."
205 "\n0 none, 1 (1-2-1) 3-tap filter, "
206 "2 (2-3-6-3-2) 5-tap filter."
207 "\nDefault value is "__MODULE_STRING(W9968CF_FILTER_TYPE)
208 " for every device."
209 "\nThe filter is used to reduce noise and aliasing artifacts"
210 "\nproduced by the CCD or CMOS image sensor, and the scaling"
211 " process."
212 "\n");
213MODULE_PARM_DESC(largeview,
214 "\n<0|1[,...]> Large view: 0 disabled, 1 enabled."
215 "\nDefault value is "__MODULE_STRING(W9968CF_LARGEVIEW)
216 " for every device."
217 "\n");
218MODULE_PARM_DESC(upscaling,
219 "\n<0|1[,...]> Software scaling (for non-compressed video):"
220 "\n0 disabled, 1 enabled."
221 "\nDisable it if you have a slow CPU or you don't have"
222 " enough memory."
223 "\nDefault value is "__MODULE_STRING(W9968CF_UPSCALING)
224 " for every device."
225 "\nIf 'w9968cf-vpp' is not present, this parameter is"
226 " set to 0."
227 "\n");
228MODULE_PARM_DESC(decompression,
229 "\n<0|1|2[,...]> Software video decompression:"
230 "\n- 0 disables decompression (doesn't allow formats needing"
231 " decompression)"
232 "\n- 1 forces decompression (allows formats needing"
233 " decompression only);"
234 "\n- 2 allows any permitted formats."
235 "\nFormats supporting compressed video are YUV422P and"
236 " YUV420P/YUV420 "
237 "\nin any resolutions where both width and height are "
238 "a multiple of 16."
239 "\nDefault value is "__MODULE_STRING(W9968CF_DECOMPRESSION)
240 " for every device."
241 "\nIf 'w9968cf-vpp' is not present, forcing decompression is "
242 "\nnot allowed; in this case this parameter is set to 2."
243 "\n");
244MODULE_PARM_DESC(force_palette,
245 "\n<0"
246 "|" __MODULE_STRING(VIDEO_PALETTE_UYVY)
247 "|" __MODULE_STRING(VIDEO_PALETTE_YUV420)
248 "|" __MODULE_STRING(VIDEO_PALETTE_YUV422P)
249 "|" __MODULE_STRING(VIDEO_PALETTE_YUV420P)
250 "|" __MODULE_STRING(VIDEO_PALETTE_YUYV)
251 "|" __MODULE_STRING(VIDEO_PALETTE_YUV422)
252 "|" __MODULE_STRING(VIDEO_PALETTE_GREY)
253 "|" __MODULE_STRING(VIDEO_PALETTE_RGB555)
254 "|" __MODULE_STRING(VIDEO_PALETTE_RGB565)
255 "|" __MODULE_STRING(VIDEO_PALETTE_RGB24)
256 "|" __MODULE_STRING(VIDEO_PALETTE_RGB32)
257 "[,...]>"
258 " Force picture palette."
259 "\nIn order:"
260 "\n- 0 allows any of the following formats:"
261 "\n- UYVY 16 bpp - Original video, compression disabled"
262 "\n- YUV420 12 bpp - Original video, compression enabled"
263 "\n- YUV422P 16 bpp - Original video, compression enabled"
264 "\n- YUV420P 12 bpp - Original video, compression enabled"
265 "\n- YUVY 16 bpp - Software conversion from UYVY"
266 "\n- YUV422 16 bpp - Software conversion from UYVY"
267 "\n- GREY 8 bpp - Software conversion from UYVY"
268 "\n- RGB555 16 bpp - Software conversion from UYVY"
269 "\n- RGB565 16 bpp - Software conversion from UYVY"
270 "\n- RGB24 24 bpp - Software conversion from UYVY"
271 "\n- RGB32 32 bpp - Software conversion from UYVY"
272 "\nWhen not 0, this parameter will override 'decompression'."
273 "\nDefault value is 0 for every device."
274 "\nInitial palette is "
275 __MODULE_STRING(W9968CF_PALETTE_DECOMP_ON)"."
276 "\nIf 'w9968cf-vpp' is not present, this parameter is"
277 " set to 9 (UYVY)."
278 "\n");
279MODULE_PARM_DESC(force_rgb,
280 "\n<0|1[,...]> Read RGB video data instead of BGR:"
281 "\n 1 = use RGB component ordering."
282 "\n 0 = use BGR component ordering."
283 "\nThis parameter has effect when using RGBX palettes only."
284 "\nDefault value is "__MODULE_STRING(W9968CF_FORCE_RGB)
285 " for every device."
286 "\n");
287MODULE_PARM_DESC(autobright,
288 "\n<0|1[,...]> Image sensor automatically changes brightness:"
289 "\n 0 = no, 1 = yes"
290 "\nDefault value is "__MODULE_STRING(W9968CF_AUTOBRIGHT)
291 " for every device."
292 "\n");
293MODULE_PARM_DESC(autoexp,
294 "\n<0|1[,...]> Image sensor automatically changes exposure:"
295 "\n 0 = no, 1 = yes"
296 "\nDefault value is "__MODULE_STRING(W9968CF_AUTOEXP)
297 " for every device."
298 "\n");
299MODULE_PARM_DESC(lightfreq,
300 "\n<50|60[,...]> Light frequency in Hz:"
301 "\n 50 for European and Asian lighting,"
302 " 60 for American lighting."
303 "\nDefault value is "__MODULE_STRING(W9968CF_LIGHTFREQ)
304 " for every device."
305 "\n");
306MODULE_PARM_DESC(bandingfilter,
307 "\n<0|1[,...]> Banding filter to reduce effects of"
308 " fluorescent lighting:"
309 "\n 0 disabled, 1 enabled."
310 "\nThis filter tries to reduce the pattern of horizontal"
311 "\nlight/dark bands caused by some (usually fluorescent)"
312 " lighting."
313 "\nDefault value is "__MODULE_STRING(W9968CF_BANDINGFILTER)
314 " for every device."
315 "\n");
316MODULE_PARM_DESC(clockdiv,
317 "\n<-1|n[,...]> "
318 "Force pixel clock divisor to a specific value (for experts):"
319 "\n n may vary from 0 to 127."
320 "\n -1 for automatic value."
321 "\nSee also the 'double_buffer' module parameter."
322 "\nDefault value is "__MODULE_STRING(W9968CF_CLOCKDIV)
323 " for every device."
324 "\n");
325MODULE_PARM_DESC(backlight,
326 "\n<0|1[,...]> Objects are lit from behind:"
327 "\n 0 = no, 1 = yes"
328 "\nDefault value is "__MODULE_STRING(W9968CF_BACKLIGHT)
329 " for every device."
330 "\n");
331MODULE_PARM_DESC(mirror,
332 "\n<0|1[,...]> Reverse image horizontally:"
333 "\n 0 = no, 1 = yes"
334 "\nDefault value is "__MODULE_STRING(W9968CF_MIRROR)
335 " for every device."
336 "\n");
337MODULE_PARM_DESC(monochrome,
338 "\n<0|1[,...]> Use image sensor as monochrome sensor:"
339 "\n 0 = no, 1 = yes"
340 "\nNot all the sensors support monochrome color."
341 "\nDefault value is "__MODULE_STRING(W9968CF_MONOCHROME)
342 " for every device."
343 "\n");
344MODULE_PARM_DESC(brightness,
345 "\n<n[,...]> Set picture brightness (0-65535)."
346 "\nDefault value is "__MODULE_STRING(W9968CF_BRIGHTNESS)
347 " for every device."
348 "\nThis parameter has no effect if 'autobright' is enabled."
349 "\n");
350MODULE_PARM_DESC(hue,
351 "\n<n[,...]> Set picture hue (0-65535)."
352 "\nDefault value is "__MODULE_STRING(W9968CF_HUE)
353 " for every device."
354 "\n");
355MODULE_PARM_DESC(colour,
356 "\n<n[,...]> Set picture saturation (0-65535)."
357 "\nDefault value is "__MODULE_STRING(W9968CF_COLOUR)
358 " for every device."
359 "\n");
360MODULE_PARM_DESC(contrast,
361 "\n<n[,...]> Set picture contrast (0-65535)."
362 "\nDefault value is "__MODULE_STRING(W9968CF_CONTRAST)
363 " for every device."
364 "\n");
365MODULE_PARM_DESC(whiteness,
366 "\n<n[,...]> Set picture whiteness (0-65535)."
367 "\nDefault value is "__MODULE_STRING(W9968CF_WHITENESS)
368 " for every device."
369 "\n");
370#ifdef W9968CF_DEBUG
371MODULE_PARM_DESC(debug,
372 "\n<n> Debugging information level, from 0 to 6:"
373 "\n0 = none (use carefully)"
374 "\n1 = critical errors"
375 "\n2 = significant informations"
376 "\n3 = configuration or general messages"
377 "\n4 = warnings"
378 "\n5 = called functions"
379 "\n6 = function internals"
380 "\nLevel 5 and 6 are useful for testing only, when only "
381 "one device is used."
382 "\nDefault value is "__MODULE_STRING(W9968CF_DEBUG_LEVEL)"."
383 "\n");
384MODULE_PARM_DESC(specific_debug,
385 "\n<0|1> Enable or disable specific debugging messages:"
386 "\n0 = print messages concerning every level"
387 " <= 'debug' level."
388 "\n1 = print messages concerning the level"
389 " indicated by 'debug'."
390 "\nDefault value is "
391 __MODULE_STRING(W9968CF_SPECIFIC_DEBUG)"."
392 "\n");
393#endif /* W9968CF_DEBUG */
394
395
396
397/****************************************************************************
398 * Some prototypes *
399 ****************************************************************************/
400
401/* Video4linux interface */
402static struct file_operations w9968cf_fops;
403static int w9968cf_open(struct inode*, struct file*);
404static int w9968cf_release(struct inode*, struct file*);
405static int w9968cf_mmap(struct file*, struct vm_area_struct*);
406static int w9968cf_ioctl(struct inode*, struct file*, unsigned, unsigned long);
407static ssize_t w9968cf_read(struct file*, char __user *, size_t, loff_t*);
408static int w9968cf_v4l_ioctl(struct inode*, struct file*, unsigned int,
409 void __user *);
410
411/* USB-specific */
412static int w9968cf_start_transfer(struct w9968cf_device*);
413static int w9968cf_stop_transfer(struct w9968cf_device*);
414static int w9968cf_write_reg(struct w9968cf_device*, u16 value, u16 index);
415static int w9968cf_read_reg(struct w9968cf_device*, u16 index);
416static int w9968cf_write_fsb(struct w9968cf_device*, u16* data);
417static int w9968cf_write_sb(struct w9968cf_device*, u16 value);
418static int w9968cf_read_sb(struct w9968cf_device*);
419static int w9968cf_upload_quantizationtables(struct w9968cf_device*);
420static void w9968cf_urb_complete(struct urb *urb, struct pt_regs *regs);
421
422/* Low-level I2C (SMBus) I/O */
423static int w9968cf_smbus_start(struct w9968cf_device*);
424static int w9968cf_smbus_stop(struct w9968cf_device*);
425static int w9968cf_smbus_write_byte(struct w9968cf_device*, u8 v);
426static int w9968cf_smbus_read_byte(struct w9968cf_device*, u8* v);
427static int w9968cf_smbus_write_ack(struct w9968cf_device*);
428static int w9968cf_smbus_read_ack(struct w9968cf_device*);
429static int w9968cf_smbus_refresh_bus(struct w9968cf_device*);
430static int w9968cf_i2c_adap_read_byte(struct w9968cf_device* cam,
431 u16 address, u8* value);
432static int w9968cf_i2c_adap_read_byte_data(struct w9968cf_device*, u16 address,
433 u8 subaddress, u8* value);
434static int w9968cf_i2c_adap_write_byte(struct w9968cf_device*,
435 u16 address, u8 subaddress);
436static int w9968cf_i2c_adap_fastwrite_byte_data(struct w9968cf_device*,
437 u16 address, u8 subaddress,
438 u8 value);
439
440/* I2C interface to kernel */
441static int w9968cf_i2c_init(struct w9968cf_device*);
442static int w9968cf_i2c_smbus_xfer(struct i2c_adapter*, u16 addr,
443 unsigned short flags, char read_write,
444 u8 command, int size, union i2c_smbus_data*);
445static u32 w9968cf_i2c_func(struct i2c_adapter*);
446static int w9968cf_i2c_attach_inform(struct i2c_client*);
447static int w9968cf_i2c_detach_inform(struct i2c_client*);
448static int w9968cf_i2c_control(struct i2c_adapter*, unsigned int cmd,
449 unsigned long arg);
450
451/* Memory management */
452static void* rvmalloc(unsigned long size);
453static void rvfree(void *mem, unsigned long size);
454static void w9968cf_deallocate_memory(struct w9968cf_device*);
455static int w9968cf_allocate_memory(struct w9968cf_device*);
456
457/* High-level image sensor control functions */
458static int w9968cf_sensor_set_control(struct w9968cf_device*,int cid,int val);
459static int w9968cf_sensor_get_control(struct w9968cf_device*,int cid,int *val);
460static int w9968cf_sensor_cmd(struct w9968cf_device*,
461 unsigned int cmd, void *arg);
462static int w9968cf_sensor_init(struct w9968cf_device*);
463static int w9968cf_sensor_update_settings(struct w9968cf_device*);
464static int w9968cf_sensor_get_picture(struct w9968cf_device*);
465static int w9968cf_sensor_update_picture(struct w9968cf_device*,
466 struct video_picture pict);
467
468/* Other helper functions */
469static void w9968cf_configure_camera(struct w9968cf_device*,struct usb_device*,
470 enum w9968cf_model_id,
471 const unsigned short dev_nr);
472static void w9968cf_adjust_configuration(struct w9968cf_device*);
473static int w9968cf_turn_on_led(struct w9968cf_device*);
474static int w9968cf_init_chip(struct w9968cf_device*);
475static inline u16 w9968cf_valid_palette(u16 palette);
476static inline u16 w9968cf_valid_depth(u16 palette);
477static inline u8 w9968cf_need_decompression(u16 palette);
478static int w9968cf_set_picture(struct w9968cf_device*, struct video_picture);
479static int w9968cf_set_window(struct w9968cf_device*, struct video_window);
480static int w9968cf_postprocess_frame(struct w9968cf_device*,
481 struct w9968cf_frame_t*);
482static int w9968cf_adjust_window_size(struct w9968cf_device*, u16* w, u16* h);
483static void w9968cf_init_framelist(struct w9968cf_device*);
484static void w9968cf_push_frame(struct w9968cf_device*, u8 f_num);
485static void w9968cf_pop_frame(struct w9968cf_device*,struct w9968cf_frame_t**);
486static void w9968cf_release_resources(struct w9968cf_device*);
487
488
489
490/****************************************************************************
491 * Symbolic names *
492 ****************************************************************************/
493
494/* Used to represent a list of values and their respective symbolic names */
495struct w9968cf_symbolic_list {
496 const int num;
497 const char *name;
498};
499
500/*--------------------------------------------------------------------------
501 Returns the name of the matching element in the symbolic_list array. The
502 end of the list must be marked with an element that has a NULL name.
503 --------------------------------------------------------------------------*/
504static inline const char *
505symbolic(struct w9968cf_symbolic_list list[], const int num)
506{
507 int i;
508
509 for (i = 0; list[i].name != NULL; i++)
510 if (list[i].num == num)
511 return (list[i].name);
512
513 return "Unknown";
514}
515
516static struct w9968cf_symbolic_list camlist[] = {
517 { W9968CF_MOD_GENERIC, "W996[87]CF JPEG USB Dual Mode Camera" },
518 { W9968CF_MOD_CLVBWGP, "Creative Labs Video Blaster WebCam Go Plus" },
519
520 /* Other cameras (having the same descriptors as Generic W996[87]CF) */
521 { W9968CF_MOD_ADPVDMA, "Aroma Digi Pen VGA Dual Mode ADG-5000" },
522 { W9986CF_MOD_AAU, "AVerMedia AVerTV USB" },
523 { W9968CF_MOD_CLVBWG, "Creative Labs Video Blaster WebCam Go" },
524 { W9968CF_MOD_LL, "Lebon LDC-035A" },
525 { W9968CF_MOD_EEEMC, "Ezonics EZ-802 EZMega Cam" },
526 { W9968CF_MOD_OOE, "OmniVision OV8610-EDE" },
527 { W9968CF_MOD_ODPVDMPC, "OPCOM Digi Pen VGA Dual Mode Pen Camera" },
528 { W9968CF_MOD_PDPII, "Pretec Digi Pen-II" },
529 { W9968CF_MOD_PDP480, "Pretec DigiPen-480" },
530
531 { -1, NULL }
532};
533
534static struct w9968cf_symbolic_list senlist[] = {
535 { CC_OV76BE, "OV76BE" },
536 { CC_OV7610, "OV7610" },
537 { CC_OV7620, "OV7620" },
538 { CC_OV7620AE, "OV7620AE" },
539 { CC_OV6620, "OV6620" },
540 { CC_OV6630, "OV6630" },
541 { CC_OV6630AE, "OV6630AE" },
542 { CC_OV6630AF, "OV6630AF" },
543 { -1, NULL }
544};
545
546/* Video4Linux1 palettes */
547static struct w9968cf_symbolic_list v4l1_plist[] = {
548 { VIDEO_PALETTE_GREY, "GREY" },
549 { VIDEO_PALETTE_HI240, "HI240" },
550 { VIDEO_PALETTE_RGB565, "RGB565" },
551 { VIDEO_PALETTE_RGB24, "RGB24" },
552 { VIDEO_PALETTE_RGB32, "RGB32" },
553 { VIDEO_PALETTE_RGB555, "RGB555" },
554 { VIDEO_PALETTE_YUV422, "YUV422" },
555 { VIDEO_PALETTE_YUYV, "YUYV" },
556 { VIDEO_PALETTE_UYVY, "UYVY" },
557 { VIDEO_PALETTE_YUV420, "YUV420" },
558 { VIDEO_PALETTE_YUV411, "YUV411" },
559 { VIDEO_PALETTE_RAW, "RAW" },
560 { VIDEO_PALETTE_YUV422P, "YUV422P" },
561 { VIDEO_PALETTE_YUV411P, "YUV411P" },
562 { VIDEO_PALETTE_YUV420P, "YUV420P" },
563 { VIDEO_PALETTE_YUV410P, "YUV410P" },
564 { -1, NULL }
565};
566
567/* Decoder error codes: */
568static struct w9968cf_symbolic_list decoder_errlist[] = {
569 { W9968CF_DEC_ERR_CORRUPTED_DATA, "Corrupted data" },
570 { W9968CF_DEC_ERR_BUF_OVERFLOW, "Buffer overflow" },
571 { W9968CF_DEC_ERR_NO_SOI, "SOI marker not found" },
572 { W9968CF_DEC_ERR_NO_SOF0, "SOF0 marker not found" },
573 { W9968CF_DEC_ERR_NO_SOS, "SOS marker not found" },
574 { W9968CF_DEC_ERR_NO_EOI, "EOI marker not found" },
575 { -1, NULL }
576};
577
578/* URB error codes: */
579static struct w9968cf_symbolic_list urb_errlist[] = {
580 { -ENOMEM, "No memory for allocation of internal structures" },
581 { -ENOSPC, "The host controller's bandwidth is already consumed" },
582 { -ENOENT, "URB was canceled by unlink_urb" },
583 { -EXDEV, "ISO transfer only partially completed" },
584 { -EAGAIN, "Too match scheduled for the future" },
585 { -ENXIO, "URB already queued" },
586 { -EFBIG, "Too much ISO frames requested" },
587 { -ENOSR, "Buffer error (overrun)" },
588 { -EPIPE, "Specified endpoint is stalled (device not responding)"},
589 { -EOVERFLOW, "Babble (bad cable?)" },
590 { -EPROTO, "Bit-stuff error (bad cable?)" },
591 { -EILSEQ, "CRC/Timeout" },
592 { -ETIMEDOUT, "NAK (device does not respond)" },
593 { -1, NULL }
594};
595
596
597
598/****************************************************************************
599 * Memory management functions *
600 ****************************************************************************/
601static void* rvmalloc(unsigned long size)
602{
603 void* mem;
604 unsigned long adr;
605
606 size = PAGE_ALIGN(size);
607 mem = vmalloc_32(size);
608 if (!mem)
609 return NULL;
610
611 memset(mem, 0, size); /* Clear the ram out, no junk to the user */
612 adr = (unsigned long) mem;
613 while (size > 0) {
614 SetPageReserved(vmalloc_to_page((void *)adr));
615 adr += PAGE_SIZE;
616 size -= PAGE_SIZE;
617 }
618
619 return mem;
620}
621
622
623static void rvfree(void* mem, unsigned long size)
624{
625 unsigned long adr;
626
627 if (!mem)
628 return;
629
630 adr = (unsigned long) mem;
631 while ((long) size > 0) {
632 ClearPageReserved(vmalloc_to_page((void *)adr));
633 adr += PAGE_SIZE;
634 size -= PAGE_SIZE;
635 }
636 vfree(mem);
637}
638
639
640/*--------------------------------------------------------------------------
641 Deallocate previously allocated memory.
642 --------------------------------------------------------------------------*/
643static void w9968cf_deallocate_memory(struct w9968cf_device* cam)
644{
645 u8 i;
646
647 /* Free the isochronous transfer buffers */
648 for (i = 0; i < W9968CF_URBS; i++) {
649 kfree(cam->transfer_buffer[i]);
650 cam->transfer_buffer[i] = NULL;
651 }
652
653 /* Free temporary frame buffer */
654 if (cam->frame_tmp.buffer) {
655 rvfree(cam->frame_tmp.buffer, cam->frame_tmp.size);
656 cam->frame_tmp.buffer = NULL;
657 }
658
659 /* Free helper buffer */
660 if (cam->frame_vpp.buffer) {
661 rvfree(cam->frame_vpp.buffer, cam->frame_vpp.size);
662 cam->frame_vpp.buffer = NULL;
663 }
664
665 /* Free video frame buffers */
666 if (cam->frame[0].buffer) {
667 rvfree(cam->frame[0].buffer, cam->nbuffers*cam->frame[0].size);
668 cam->frame[0].buffer = NULL;
669 }
670
671 cam->nbuffers = 0;
672
673 DBG(5, "Memory successfully deallocated")
674}
675
676
677/*--------------------------------------------------------------------------
678 Allocate memory buffers for USB transfers and video frames.
679 This function is called by open() only.
680 Return 0 on success, a negative number otherwise.
681 --------------------------------------------------------------------------*/
682static int w9968cf_allocate_memory(struct w9968cf_device* cam)
683{
684 const u16 p_size = wMaxPacketSize[cam->altsetting-1];
685 void* buff = NULL;
686 unsigned long hw_bufsize, vpp_bufsize;
687 u8 i, bpp;
688
689 /* NOTE: Deallocation is done elsewhere in case of error */
690
691 /* Calculate the max amount of raw data per frame from the device */
692 hw_bufsize = cam->maxwidth*cam->maxheight*2;
693
694 /* Calculate the max buf. size needed for post-processing routines */
695 bpp = (w9968cf_vpp) ? 4 : 2;
696 if (cam->upscaling)
697 vpp_bufsize = max(W9968CF_MAX_WIDTH*W9968CF_MAX_HEIGHT*bpp,
698 cam->maxwidth*cam->maxheight*bpp);
699 else
700 vpp_bufsize = cam->maxwidth*cam->maxheight*bpp;
701
702 /* Allocate memory for the isochronous transfer buffers */
703 for (i = 0; i < W9968CF_URBS; i++) {
704 if (!(cam->transfer_buffer[i] =
705 kzalloc(W9968CF_ISO_PACKETS*p_size, GFP_KERNEL))) {
706 DBG(1, "Couldn't allocate memory for the isochronous "
707 "transfer buffers (%u bytes)",
708 p_size * W9968CF_ISO_PACKETS)
709 return -ENOMEM;
710 }
711 }
712
713 /* Allocate memory for the temporary frame buffer */
714 if (!(cam->frame_tmp.buffer = rvmalloc(hw_bufsize))) {
715 DBG(1, "Couldn't allocate memory for the temporary "
716 "video frame buffer (%lu bytes)", hw_bufsize)
717 return -ENOMEM;
718 }
719 cam->frame_tmp.size = hw_bufsize;
720 cam->frame_tmp.number = -1;
721
722 /* Allocate memory for the helper buffer */
723 if (w9968cf_vpp) {
724 if (!(cam->frame_vpp.buffer = rvmalloc(vpp_bufsize))) {
725 DBG(1, "Couldn't allocate memory for the helper buffer"
726 " (%lu bytes)", vpp_bufsize)
727 return -ENOMEM;
728 }
729 cam->frame_vpp.size = vpp_bufsize;
730 } else
731 cam->frame_vpp.buffer = NULL;
732
733 /* Allocate memory for video frame buffers */
734 cam->nbuffers = cam->max_buffers;
735 while (cam->nbuffers >= 2) {
736 if ((buff = rvmalloc(cam->nbuffers * vpp_bufsize)))
737 break;
738 else
739 cam->nbuffers--;
740 }
741
742 if (!buff) {
743 DBG(1, "Couldn't allocate memory for the video frame buffers")
744 cam->nbuffers = 0;
745 return -ENOMEM;
746 }
747
748 if (cam->nbuffers != cam->max_buffers)
749 DBG(2, "Couldn't allocate memory for %u video frame buffers. "
750 "Only memory for %u buffers has been allocated",
751 cam->max_buffers, cam->nbuffers)
752
753 for (i = 0; i < cam->nbuffers; i++) {
754 cam->frame[i].buffer = buff + i*vpp_bufsize;
755 cam->frame[i].size = vpp_bufsize;
756 cam->frame[i].number = i;
757 /* Circular list */
758 if (i != cam->nbuffers-1)
759 cam->frame[i].next = &cam->frame[i+1];
760 else
761 cam->frame[i].next = &cam->frame[0];
762 cam->frame[i].status = F_UNUSED;
763 }
764
765 DBG(5, "Memory successfully allocated")
766 return 0;
767}
768
769
770
771/****************************************************************************
772 * USB-specific functions *
773 ****************************************************************************/
774
775/*--------------------------------------------------------------------------
776 This is an handler function which is called after the URBs are completed.
777 It collects multiple data packets coming from the camera by putting them
778 into frame buffers: one or more zero data length data packets are used to
779 mark the end of a video frame; the first non-zero data packet is the start
780 of the next video frame; if an error is encountered in a packet, the entire
781 video frame is discarded and grabbed again.
782 If there are no requested frames in the FIFO list, packets are collected into
783 a temporary buffer.
784 --------------------------------------------------------------------------*/
785static void w9968cf_urb_complete(struct urb *urb, struct pt_regs *regs)
786{
787 struct w9968cf_device* cam = (struct w9968cf_device*)urb->context;
788 struct w9968cf_frame_t** f;
789 unsigned int len, status;
790 void* pos;
791 u8 i;
792 int err = 0;
793
794 if ((!cam->streaming) || cam->disconnected) {
795 DBG(4, "Got interrupt, but not streaming")
796 return;
797 }
798
799 /* "(*f)" will be used instead of "cam->frame_current" */
800 f = &cam->frame_current;
801
802 /* If a frame has been requested and we are grabbing into
803 the temporary frame, we'll switch to that requested frame */
804 if ((*f) == &cam->frame_tmp && *cam->requested_frame) {
805 if (cam->frame_tmp.status == F_GRABBING) {
806 w9968cf_pop_frame(cam, &cam->frame_current);
807 (*f)->status = F_GRABBING;
808 (*f)->length = cam->frame_tmp.length;
809 memcpy((*f)->buffer, cam->frame_tmp.buffer,
810 (*f)->length);
811 DBG(6, "Switched from temp. frame to frame #%d",
812 (*f)->number)
813 }
814 }
815
816 for (i = 0; i < urb->number_of_packets; i++) {
817 len = urb->iso_frame_desc[i].actual_length;
818 status = urb->iso_frame_desc[i].status;
819 pos = urb->iso_frame_desc[i].offset + urb->transfer_buffer;
820
821 if (status && len != 0) {
822 DBG(4, "URB failed, error in data packet "
823 "(error #%u, %s)",
824 status, symbolic(urb_errlist, status))
825 (*f)->status = F_ERROR;
826 continue;
827 }
828
829 if (len) { /* start of frame */
830
831 if ((*f)->status == F_UNUSED) {
832 (*f)->status = F_GRABBING;
833 (*f)->length = 0;
834 }
835
836 /* Buffer overflows shouldn't happen, however...*/
837 if ((*f)->length + len > (*f)->size) {
838 DBG(4, "Buffer overflow: bad data packets")
839 (*f)->status = F_ERROR;
840 }
841
842 if ((*f)->status == F_GRABBING) {
843 memcpy((*f)->buffer + (*f)->length, pos, len);
844 (*f)->length += len;
845 }
846
847 } else if ((*f)->status == F_GRABBING) { /* end of frame */
848
849 DBG(6, "Frame #%d successfully grabbed", (*f)->number)
850
851 if (cam->vpp_flag & VPP_DECOMPRESSION) {
852 err = w9968cf_vpp->check_headers((*f)->buffer,
853 (*f)->length);
854 if (err) {
855 DBG(4, "Skip corrupted frame: %s",
856 symbolic(decoder_errlist, err))
857 (*f)->status = F_UNUSED;
858 continue; /* grab this frame again */
859 }
860 }
861
862 (*f)->status = F_READY;
863 (*f)->queued = 0;
864
865 /* Take a pointer to the new frame from the FIFO list.
866 If the list is empty,we'll use the temporary frame*/
867 if (*cam->requested_frame)
868 w9968cf_pop_frame(cam, &cam->frame_current);
869 else {
870 cam->frame_current = &cam->frame_tmp;
871 (*f)->status = F_UNUSED;
872 }
873
874 } else if ((*f)->status == F_ERROR)
875 (*f)->status = F_UNUSED; /* grab it again */
876
877 PDBGG("Frame length %lu | pack.#%u | pack.len. %u | state %d",
878 (unsigned long)(*f)->length, i, len, (*f)->status)
879
880 } /* end for */
881
882 /* Resubmit this URB */
883 urb->dev = cam->usbdev;
884 urb->status = 0;
885 spin_lock(&cam->urb_lock);
886 if (cam->streaming)
887 if ((err = usb_submit_urb(urb, GFP_ATOMIC))) {
888 cam->misconfigured = 1;
889 DBG(1, "Couldn't resubmit the URB: error %d, %s",
890 err, symbolic(urb_errlist, err))
891 }
892 spin_unlock(&cam->urb_lock);
893
894 /* Wake up the user process */
895 wake_up_interruptible(&cam->wait_queue);
896}
897
898
899/*---------------------------------------------------------------------------
900 Setup the URB structures for the isochronous transfer.
901 Submit the URBs so that the data transfer begins.
902 Return 0 on success, a negative number otherwise.
903 ---------------------------------------------------------------------------*/
904static int w9968cf_start_transfer(struct w9968cf_device* cam)
905{
906 struct usb_device *udev = cam->usbdev;
907 struct urb* urb;
908 const u16 p_size = wMaxPacketSize[cam->altsetting-1];
909 u16 w, h, d;
910 int vidcapt;
911 u32 t_size;
912 int err = 0;
913 s8 i, j;
914
915 for (i = 0; i < W9968CF_URBS; i++) {
916 urb = usb_alloc_urb(W9968CF_ISO_PACKETS, GFP_KERNEL);
917 cam->urb[i] = urb;
918 if (!urb) {
919 for (j = 0; j < i; j++)
920 usb_free_urb(cam->urb[j]);
921 DBG(1, "Couldn't allocate the URB structures")
922 return -ENOMEM;
923 }
924
925 urb->dev = udev;
926 urb->context = (void*)cam;
927 urb->pipe = usb_rcvisocpipe(udev, 1);
928 urb->transfer_flags = URB_ISO_ASAP;
929 urb->number_of_packets = W9968CF_ISO_PACKETS;
930 urb->complete = w9968cf_urb_complete;
931 urb->transfer_buffer = cam->transfer_buffer[i];
932 urb->transfer_buffer_length = p_size*W9968CF_ISO_PACKETS;
933 urb->interval = 1;
934 for (j = 0; j < W9968CF_ISO_PACKETS; j++) {
935 urb->iso_frame_desc[j].offset = p_size*j;
936 urb->iso_frame_desc[j].length = p_size;
937 }
938 }
939
940 /* Transfer size per frame, in WORD ! */
941 d = cam->hw_depth;
942 w = cam->hw_width;
943 h = cam->hw_height;
944
945 t_size = (w*h*d)/16;
946
947 err = w9968cf_write_reg(cam, 0xbf17, 0x00); /* reset everything */
948 err += w9968cf_write_reg(cam, 0xbf10, 0x00); /* normal operation */
949
950 /* Transfer size */
951 err += w9968cf_write_reg(cam, t_size & 0xffff, 0x3d); /* low bits */
952 err += w9968cf_write_reg(cam, t_size >> 16, 0x3e); /* high bits */
953
954 if (cam->vpp_flag & VPP_DECOMPRESSION)
955 err += w9968cf_upload_quantizationtables(cam);
956
957 vidcapt = w9968cf_read_reg(cam, 0x16); /* read picture settings */
958 err += w9968cf_write_reg(cam, vidcapt|0x8000, 0x16); /* capt. enable */
959
960 err += usb_set_interface(udev, 0, cam->altsetting);
961 err += w9968cf_write_reg(cam, 0x8a05, 0x3c); /* USB FIFO enable */
962
963 if (err || (vidcapt < 0)) {
964 for (i = 0; i < W9968CF_URBS; i++)
965 usb_free_urb(cam->urb[i]);
966 DBG(1, "Couldn't tell the camera to start the data transfer")
967 return err;
968 }
969
970 w9968cf_init_framelist(cam);
971
972 /* Begin to grab into the temporary buffer */
973 cam->frame_tmp.status = F_UNUSED;
974 cam->frame_tmp.queued = 0;
975 cam->frame_current = &cam->frame_tmp;
976
977 if (!(cam->vpp_flag & VPP_DECOMPRESSION))
978 DBG(5, "Isochronous transfer size: %lu bytes/frame",
979 (unsigned long)t_size*2)
980
981 DBG(5, "Starting the isochronous transfer...")
982
983 cam->streaming = 1;
984
985 /* Submit the URBs */
986 for (i = 0; i < W9968CF_URBS; i++) {
987 err = usb_submit_urb(cam->urb[i], GFP_KERNEL);
988 if (err) {
989 cam->streaming = 0;
990 for (j = i-1; j >= 0; j--) {
991 usb_kill_urb(cam->urb[j]);
992 usb_free_urb(cam->urb[j]);
993 }
994 DBG(1, "Couldn't send a transfer request to the "
995 "USB core (error #%d, %s)", err,
996 symbolic(urb_errlist, err))
997 return err;
998 }
999 }
1000
1001 return 0;
1002}
1003
1004
1005/*--------------------------------------------------------------------------
1006 Stop the isochronous transfer and set alternate setting to 0 (0Mb/s).
1007 Return 0 on success, a negative number otherwise.
1008 --------------------------------------------------------------------------*/
1009static int w9968cf_stop_transfer(struct w9968cf_device* cam)
1010{
1011 struct usb_device *udev = cam->usbdev;
1012 unsigned long lock_flags;
1013 int err = 0;
1014 s8 i;
1015
1016 if (!cam->streaming)
1017 return 0;
1018
1019 /* This avoids race conditions with usb_submit_urb()
1020 in the URB completition handler */
1021 spin_lock_irqsave(&cam->urb_lock, lock_flags);
1022 cam->streaming = 0;
1023 spin_unlock_irqrestore(&cam->urb_lock, lock_flags);
1024
1025 for (i = W9968CF_URBS-1; i >= 0; i--)
1026 if (cam->urb[i]) {
1027 usb_kill_urb(cam->urb[i]);
1028 usb_free_urb(cam->urb[i]);
1029 cam->urb[i] = NULL;
1030 }
1031
1032 if (cam->disconnected)
1033 goto exit;
1034
1035 err = w9968cf_write_reg(cam, 0x0a05, 0x3c); /* stop USB transfer */
1036 err += usb_set_interface(udev, 0, 0); /* 0 Mb/s */
1037 err += w9968cf_write_reg(cam, 0x0000, 0x39); /* disable JPEG encoder */
1038 err += w9968cf_write_reg(cam, 0x0000, 0x16); /* stop video capture */
1039
1040 if (err) {
1041 DBG(2, "Failed to tell the camera to stop the isochronous "
1042 "transfer. However this is not a critical error.")
1043 return -EIO;
1044 }
1045
1046exit:
1047 DBG(5, "Isochronous transfer stopped")
1048 return 0;
1049}
1050
1051
1052/*--------------------------------------------------------------------------
1053 Write a W9968CF register.
1054 Return 0 on success, -1 otherwise.
1055 --------------------------------------------------------------------------*/
1056static int w9968cf_write_reg(struct w9968cf_device* cam, u16 value, u16 index)
1057{
1058 struct usb_device* udev = cam->usbdev;
1059 int res;
1060
1061 res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0,
1062 USB_TYPE_VENDOR | USB_DIR_OUT | USB_RECIP_DEVICE,
1063 value, index, NULL, 0, W9968CF_USB_CTRL_TIMEOUT);
1064
1065 if (res < 0)
1066 DBG(4, "Failed to write a register "
1067 "(value 0x%04X, index 0x%02X, error #%d, %s)",
1068 value, index, res, symbolic(urb_errlist, res))
1069
1070 return (res >= 0) ? 0 : -1;
1071}
1072
1073
1074/*--------------------------------------------------------------------------
1075 Read a W9968CF register.
1076 Return the register value on success, -1 otherwise.
1077 --------------------------------------------------------------------------*/
1078static int w9968cf_read_reg(struct w9968cf_device* cam, u16 index)
1079{
1080 struct usb_device* udev = cam->usbdev;
1081 u16* buff = cam->control_buffer;
1082 int res;
1083
1084 res = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), 1,
1085 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
1086 0, index, buff, 2, W9968CF_USB_CTRL_TIMEOUT);
1087
1088 if (res < 0)
1089 DBG(4, "Failed to read a register "
1090 "(index 0x%02X, error #%d, %s)",
1091 index, res, symbolic(urb_errlist, res))
1092
1093 return (res >= 0) ? (int)(*buff) : -1;
1094}
1095
1096
1097/*--------------------------------------------------------------------------
1098 Write 64-bit data to the fast serial bus registers.
1099 Return 0 on success, -1 otherwise.
1100 --------------------------------------------------------------------------*/
1101static int w9968cf_write_fsb(struct w9968cf_device* cam, u16* data)
1102{
1103 struct usb_device* udev = cam->usbdev;
1104 u16 value;
1105 int res;
1106
1107 value = *data++;
1108
1109 res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0,
1110 USB_TYPE_VENDOR | USB_DIR_OUT | USB_RECIP_DEVICE,
1111 value, 0x06, data, 6, W9968CF_USB_CTRL_TIMEOUT);
1112
1113 if (res < 0)
1114 DBG(4, "Failed to write the FSB registers "
1115 "(error #%d, %s)", res, symbolic(urb_errlist, res))
1116
1117 return (res >= 0) ? 0 : -1;
1118}
1119
1120
1121/*--------------------------------------------------------------------------
1122 Write data to the serial bus control register.
1123 Return 0 on success, a negative number otherwise.
1124 --------------------------------------------------------------------------*/
1125static int w9968cf_write_sb(struct w9968cf_device* cam, u16 value)
1126{
1127 int err = 0;
1128
1129 err = w9968cf_write_reg(cam, value, 0x01);
1130 udelay(W9968CF_I2C_BUS_DELAY);
1131
1132 return err;
1133}
1134
1135
1136/*--------------------------------------------------------------------------
1137 Read data from the serial bus control register.
1138 Return 0 on success, a negative number otherwise.
1139 --------------------------------------------------------------------------*/
1140static int w9968cf_read_sb(struct w9968cf_device* cam)
1141{
1142 int v = 0;
1143
1144 v = w9968cf_read_reg(cam, 0x01);
1145 udelay(W9968CF_I2C_BUS_DELAY);
1146
1147 return v;
1148}
1149
1150
1151/*--------------------------------------------------------------------------
1152 Upload quantization tables for the JPEG compression.
1153 This function is called by w9968cf_start_transfer().
1154 Return 0 on success, a negative number otherwise.
1155 --------------------------------------------------------------------------*/
1156static int w9968cf_upload_quantizationtables(struct w9968cf_device* cam)
1157{
1158 u16 a, b;
1159 int err = 0, i, j;
1160
1161 err += w9968cf_write_reg(cam, 0x0010, 0x39); /* JPEG clock enable */
1162
1163 for (i = 0, j = 0; i < 32; i++, j += 2) {
1164 a = Y_QUANTABLE[j] | ((unsigned)(Y_QUANTABLE[j+1]) << 8);
1165 b = UV_QUANTABLE[j] | ((unsigned)(UV_QUANTABLE[j+1]) << 8);
1166 err += w9968cf_write_reg(cam, a, 0x40+i);
1167 err += w9968cf_write_reg(cam, b, 0x60+i);
1168 }
1169 err += w9968cf_write_reg(cam, 0x0012, 0x39); /* JPEG encoder enable */
1170
1171 return err;
1172}
1173
1174
1175
1176/****************************************************************************
1177 * Low-level I2C I/O functions. *
1178 * The adapter supports the following I2C transfer functions: *
1179 * i2c_adap_fastwrite_byte_data() (at 400 kHz bit frequency only) *
1180 * i2c_adap_read_byte_data() *
1181 * i2c_adap_read_byte() *
1182 ****************************************************************************/
1183
1184static int w9968cf_smbus_start(struct w9968cf_device* cam)
1185{
1186 int err = 0;
1187
1188 err += w9968cf_write_sb(cam, 0x0011); /* SDE=1, SDA=0, SCL=1 */
1189 err += w9968cf_write_sb(cam, 0x0010); /* SDE=1, SDA=0, SCL=0 */
1190
1191 return err;
1192}
1193
1194
1195static int w9968cf_smbus_stop(struct w9968cf_device* cam)
1196{
1197 int err = 0;
1198
1199 err += w9968cf_write_sb(cam, 0x0011); /* SDE=1, SDA=0, SCL=1 */
1200 err += w9968cf_write_sb(cam, 0x0013); /* SDE=1, SDA=1, SCL=1 */
1201
1202 return err;
1203}
1204
1205
1206static int w9968cf_smbus_write_byte(struct w9968cf_device* cam, u8 v)
1207{
1208 u8 bit;
1209 int err = 0, sda;
1210
1211 for (bit = 0 ; bit < 8 ; bit++) {
1212 sda = (v & 0x80) ? 2 : 0;
1213 v <<= 1;
1214 /* SDE=1, SDA=sda, SCL=0 */
1215 err += w9968cf_write_sb(cam, 0x10 | sda);
1216 /* SDE=1, SDA=sda, SCL=1 */
1217 err += w9968cf_write_sb(cam, 0x11 | sda);
1218 /* SDE=1, SDA=sda, SCL=0 */
1219 err += w9968cf_write_sb(cam, 0x10 | sda);
1220 }
1221
1222 return err;
1223}
1224
1225
1226static int w9968cf_smbus_read_byte(struct w9968cf_device* cam, u8* v)
1227{
1228 u8 bit;
1229 int err = 0;
1230
1231 *v = 0;
1232 for (bit = 0 ; bit < 8 ; bit++) {
1233 *v <<= 1;
1234 err += w9968cf_write_sb(cam, 0x0013);
1235 *v |= (w9968cf_read_sb(cam) & 0x0008) ? 1 : 0;
1236 err += w9968cf_write_sb(cam, 0x0012);
1237 }
1238
1239 return err;
1240}
1241
1242
1243static int w9968cf_smbus_write_ack(struct w9968cf_device* cam)
1244{
1245 int err = 0;
1246
1247 err += w9968cf_write_sb(cam, 0x0010); /* SDE=1, SDA=0, SCL=0 */
1248 err += w9968cf_write_sb(cam, 0x0011); /* SDE=1, SDA=0, SCL=1 */
1249 err += w9968cf_write_sb(cam, 0x0010); /* SDE=1, SDA=0, SCL=0 */
1250
1251 return err;
1252}
1253
1254
1255static int w9968cf_smbus_read_ack(struct w9968cf_device* cam)
1256{
1257 int err = 0, sda;
1258
1259 err += w9968cf_write_sb(cam, 0x0013); /* SDE=1, SDA=1, SCL=1 */
1260 sda = (w9968cf_read_sb(cam) & 0x08) ? 1 : 0; /* sda = SDA */
1261 err += w9968cf_write_sb(cam, 0x0012); /* SDE=1, SDA=1, SCL=0 */
1262 if (sda < 0)
1263 err += sda;
1264 if (sda == 1) {
1265 DBG(6, "Couldn't receive the ACK")
1266 err += -1;
1267 }
1268
1269 return err;
1270}
1271
1272
1273/* This seems to refresh the communication through the serial bus */
1274static int w9968cf_smbus_refresh_bus(struct w9968cf_device* cam)
1275{
1276 int err = 0, j;
1277
1278 for (j = 1; j <= 10; j++) {
1279 err = w9968cf_write_reg(cam, 0x0020, 0x01);
1280 err += w9968cf_write_reg(cam, 0x0000, 0x01);
1281 if (err)
1282 break;
1283 }
1284
1285 return err;
1286}
1287
1288
1289/* SMBus protocol: S Addr Wr [A] Subaddr [A] Value [A] P */
1290static int
1291w9968cf_i2c_adap_fastwrite_byte_data(struct w9968cf_device* cam,
1292 u16 address, u8 subaddress,u8 value)
1293{
1294 u16* data = cam->data_buffer;
1295 int err = 0;
1296
1297 err += w9968cf_smbus_refresh_bus(cam);
1298
1299 /* Enable SBUS outputs */
1300 err += w9968cf_write_sb(cam, 0x0020);
1301
1302 data[0] = 0x082f | ((address & 0x80) ? 0x1500 : 0x0);
1303 data[0] |= (address & 0x40) ? 0x4000 : 0x0;
1304 data[1] = 0x2082 | ((address & 0x40) ? 0x0005 : 0x0);
1305 data[1] |= (address & 0x20) ? 0x0150 : 0x0;
1306 data[1] |= (address & 0x10) ? 0x5400 : 0x0;
1307 data[2] = 0x8208 | ((address & 0x08) ? 0x0015 : 0x0);
1308 data[2] |= (address & 0x04) ? 0x0540 : 0x0;
1309 data[2] |= (address & 0x02) ? 0x5000 : 0x0;
1310 data[3] = 0x1d20 | ((address & 0x02) ? 0x0001 : 0x0);
1311 data[3] |= (address & 0x01) ? 0x0054 : 0x0;
1312
1313 err += w9968cf_write_fsb(cam, data);
1314
1315 data[0] = 0x8208 | ((subaddress & 0x80) ? 0x0015 : 0x0);
1316 data[0] |= (subaddress & 0x40) ? 0x0540 : 0x0;
1317 data[0] |= (subaddress & 0x20) ? 0x5000 : 0x0;
1318 data[1] = 0x0820 | ((subaddress & 0x20) ? 0x0001 : 0x0);
1319 data[1] |= (subaddress & 0x10) ? 0x0054 : 0x0;
1320 data[1] |= (subaddress & 0x08) ? 0x1500 : 0x0;
1321 data[1] |= (subaddress & 0x04) ? 0x4000 : 0x0;
1322 data[2] = 0x2082 | ((subaddress & 0x04) ? 0x0005 : 0x0);
1323 data[2] |= (subaddress & 0x02) ? 0x0150 : 0x0;
1324 data[2] |= (subaddress & 0x01) ? 0x5400 : 0x0;
1325 data[3] = 0x001d;
1326
1327 err += w9968cf_write_fsb(cam, data);
1328
1329 data[0] = 0x8208 | ((value & 0x80) ? 0x0015 : 0x0);
1330 data[0] |= (value & 0x40) ? 0x0540 : 0x0;
1331 data[0] |= (value & 0x20) ? 0x5000 : 0x0;
1332 data[1] = 0x0820 | ((value & 0x20) ? 0x0001 : 0x0);
1333 data[1] |= (value & 0x10) ? 0x0054 : 0x0;
1334 data[1] |= (value & 0x08) ? 0x1500 : 0x0;
1335 data[1] |= (value & 0x04) ? 0x4000 : 0x0;
1336 data[2] = 0x2082 | ((value & 0x04) ? 0x0005 : 0x0);
1337 data[2] |= (value & 0x02) ? 0x0150 : 0x0;
1338 data[2] |= (value & 0x01) ? 0x5400 : 0x0;
1339 data[3] = 0xfe1d;
1340
1341 err += w9968cf_write_fsb(cam, data);
1342
1343 /* Disable SBUS outputs */
1344 err += w9968cf_write_sb(cam, 0x0000);
1345
1346 if (!err)
1347 DBG(5, "I2C write byte data done, addr.0x%04X, subaddr.0x%02X "
1348 "value 0x%02X", address, subaddress, value)
1349 else
1350 DBG(5, "I2C write byte data failed, addr.0x%04X, "
1351 "subaddr.0x%02X, value 0x%02X",
1352 address, subaddress, value)
1353
1354 return err;
1355}
1356
1357
1358/* SMBus protocol: S Addr Wr [A] Subaddr [A] P S Addr+1 Rd [A] [Value] NA P */
1359static int
1360w9968cf_i2c_adap_read_byte_data(struct w9968cf_device* cam,
1361 u16 address, u8 subaddress,
1362 u8* value)
1363{
1364 int err = 0;
1365
1366 /* Serial data enable */
1367 err += w9968cf_write_sb(cam, 0x0013); /* don't change ! */
1368
1369 err += w9968cf_smbus_start(cam);
1370 err += w9968cf_smbus_write_byte(cam, address);
1371 err += w9968cf_smbus_read_ack(cam);
1372 err += w9968cf_smbus_write_byte(cam, subaddress);
1373 err += w9968cf_smbus_read_ack(cam);
1374 err += w9968cf_smbus_stop(cam);
1375 err += w9968cf_smbus_start(cam);
1376 err += w9968cf_smbus_write_byte(cam, address + 1);
1377 err += w9968cf_smbus_read_ack(cam);
1378 err += w9968cf_smbus_read_byte(cam, value);
1379 err += w9968cf_smbus_write_ack(cam);
1380 err += w9968cf_smbus_stop(cam);
1381
1382 /* Serial data disable */
1383 err += w9968cf_write_sb(cam, 0x0000);
1384
1385 if (!err)
1386 DBG(5, "I2C read byte data done, addr.0x%04X, "
1387 "subaddr.0x%02X, value 0x%02X",
1388 address, subaddress, *value)
1389 else
1390 DBG(5, "I2C read byte data failed, addr.0x%04X, "
1391 "subaddr.0x%02X, wrong value 0x%02X",
1392 address, subaddress, *value)
1393
1394 return err;
1395}
1396
1397
1398/* SMBus protocol: S Addr+1 Rd [A] [Value] NA P */
1399static int
1400w9968cf_i2c_adap_read_byte(struct w9968cf_device* cam,
1401 u16 address, u8* value)
1402{
1403 int err = 0;
1404
1405 /* Serial data enable */
1406 err += w9968cf_write_sb(cam, 0x0013);
1407
1408 err += w9968cf_smbus_start(cam);
1409 err += w9968cf_smbus_write_byte(cam, address + 1);
1410 err += w9968cf_smbus_read_ack(cam);
1411 err += w9968cf_smbus_read_byte(cam, value);
1412 err += w9968cf_smbus_write_ack(cam);
1413 err += w9968cf_smbus_stop(cam);
1414
1415 /* Serial data disable */
1416 err += w9968cf_write_sb(cam, 0x0000);
1417
1418 if (!err)
1419 DBG(5, "I2C read byte done, addr.0x%04X, "
1420 "value 0x%02X", address, *value)
1421 else
1422 DBG(5, "I2C read byte failed, addr.0x%04X, "
1423 "wrong value 0x%02X", address, *value)
1424
1425 return err;
1426}
1427
1428
1429/* SMBus protocol: S Addr Wr [A] Value [A] P */
1430static int
1431w9968cf_i2c_adap_write_byte(struct w9968cf_device* cam,
1432 u16 address, u8 value)
1433{
1434 DBG(4, "i2c_write_byte() is an unsupported transfer mode")
1435 return -EINVAL;
1436}
1437
1438
1439
1440/****************************************************************************
1441 * I2C interface to kernel *
1442 ****************************************************************************/
1443
1444static int
1445w9968cf_i2c_smbus_xfer(struct i2c_adapter *adapter, u16 addr,
1446 unsigned short flags, char read_write, u8 command,
1447 int size, union i2c_smbus_data *data)
1448{
1449 struct w9968cf_device* cam = i2c_get_adapdata(adapter);
1450 u8 i;
1451 int err = 0;
1452
1453 switch (addr) {
1454 case OV6xx0_SID:
1455 case OV7xx0_SID:
1456 break;
1457 default:
1458 DBG(4, "Rejected slave ID 0x%04X", addr)
1459 return -EINVAL;
1460 }
1461
1462 if (size == I2C_SMBUS_BYTE) {
1463 /* Why addr <<= 1? See OVXXX0_SID defines in ovcamchip.h */
1464 addr <<= 1;
1465
1466 if (read_write == I2C_SMBUS_WRITE)
1467 err = w9968cf_i2c_adap_write_byte(cam, addr, command);
1468 else if (read_write == I2C_SMBUS_READ)
1469 err = w9968cf_i2c_adap_read_byte(cam,addr,&data->byte);
1470
1471 } else if (size == I2C_SMBUS_BYTE_DATA) {
1472 addr <<= 1;
1473
1474 if (read_write == I2C_SMBUS_WRITE)
1475 err = w9968cf_i2c_adap_fastwrite_byte_data(cam, addr,
1476 command, data->byte);
1477 else if (read_write == I2C_SMBUS_READ) {
1478 for (i = 1; i <= W9968CF_I2C_RW_RETRIES; i++) {
1479 err = w9968cf_i2c_adap_read_byte_data(cam,addr,
1480 command, &data->byte);
1481 if (err) {
1482 if (w9968cf_smbus_refresh_bus(cam)) {
1483 err = -EIO;
1484 break;
1485 }
1486 } else
1487 break;
1488 }
1489
1490 } else
1491 return -EINVAL;
1492
1493 } else {
1494 DBG(4, "Unsupported I2C transfer mode (%d)", size)
1495 return -EINVAL;
1496 }
1497
1498 return err;
1499}
1500
1501
1502static u32 w9968cf_i2c_func(struct i2c_adapter* adap)
1503{
1504 return I2C_FUNC_SMBUS_READ_BYTE |
1505 I2C_FUNC_SMBUS_READ_BYTE_DATA |
1506 I2C_FUNC_SMBUS_WRITE_BYTE_DATA;
1507}
1508
1509
1510static int w9968cf_i2c_attach_inform(struct i2c_client* client)
1511{
1512 struct w9968cf_device* cam = i2c_get_adapdata(client->adapter);
1513 int id = client->driver->id, err = 0;
1514
1515 if (id == I2C_DRIVERID_OVCAMCHIP) {
1516 cam->sensor_client = client;
1517 err = w9968cf_sensor_init(cam);
1518 if (err) {
1519 cam->sensor_client = NULL;
1520 return err;
1521 }
1522 } else {
1523 DBG(4, "Rejected client [%s] with driver [%s]",
1524 client->name, client->driver->driver.name)
1525 return -EINVAL;
1526 }
1527
1528 DBG(5, "I2C attach client [%s] with driver [%s]",
1529 client->name, client->driver->driver.name)
1530
1531 return 0;
1532}
1533
1534
1535static int w9968cf_i2c_detach_inform(struct i2c_client* client)
1536{
1537 struct w9968cf_device* cam = i2c_get_adapdata(client->adapter);
1538
1539 if (cam->sensor_client == client)
1540 cam->sensor_client = NULL;
1541
1542 DBG(5, "I2C detach client [%s]", client->name)
1543
1544 return 0;
1545}
1546
1547
1548static int
1549w9968cf_i2c_control(struct i2c_adapter* adapter, unsigned int cmd,
1550 unsigned long arg)
1551{
1552 return 0;
1553}
1554
1555
1556static int w9968cf_i2c_init(struct w9968cf_device* cam)
1557{
1558 int err = 0;
1559
1560 static struct i2c_algorithm algo = {
1561 .smbus_xfer = w9968cf_i2c_smbus_xfer,
1562 .algo_control = w9968cf_i2c_control,
1563 .functionality = w9968cf_i2c_func,
1564 };
1565
1566 static struct i2c_adapter adap = {
1567 .id = I2C_HW_SMBUS_W9968CF,
1568 .class = I2C_CLASS_CAM_DIGITAL,
1569 .owner = THIS_MODULE,
1570 .client_register = w9968cf_i2c_attach_inform,
1571 .client_unregister = w9968cf_i2c_detach_inform,
1572 .algo = &algo,
1573 };
1574
1575 memcpy(&cam->i2c_adapter, &adap, sizeof(struct i2c_adapter));
1576 strcpy(cam->i2c_adapter.name, "w9968cf");
1577 i2c_set_adapdata(&cam->i2c_adapter, cam);
1578
1579 DBG(6, "Registering I2C adapter with kernel...")
1580
1581 err = i2c_add_adapter(&cam->i2c_adapter);
1582 if (err)
1583 DBG(1, "Failed to register the I2C adapter")
1584 else
1585 DBG(5, "I2C adapter registered")
1586
1587 return err;
1588}
1589
1590
1591
1592/****************************************************************************
1593 * Helper functions *
1594 ****************************************************************************/
1595
1596/*--------------------------------------------------------------------------
1597 Turn on the LED on some webcams. A beep should be heard too.
1598 Return 0 on success, a negative number otherwise.
1599 --------------------------------------------------------------------------*/
1600static int w9968cf_turn_on_led(struct w9968cf_device* cam)
1601{
1602 int err = 0;
1603
1604 err += w9968cf_write_reg(cam, 0xff00, 0x00); /* power-down */
1605 err += w9968cf_write_reg(cam, 0xbf17, 0x00); /* reset everything */
1606 err += w9968cf_write_reg(cam, 0xbf10, 0x00); /* normal operation */
1607 err += w9968cf_write_reg(cam, 0x0010, 0x01); /* serial bus, SDS high */
1608 err += w9968cf_write_reg(cam, 0x0000, 0x01); /* serial bus, SDS low */
1609 err += w9968cf_write_reg(cam, 0x0010, 0x01); /* ..high 'beep-beep' */
1610
1611 if (err)
1612 DBG(2, "Couldn't turn on the LED")
1613
1614 DBG(5, "LED turned on")
1615
1616 return err;
1617}
1618
1619
1620/*--------------------------------------------------------------------------
1621 Write some registers for the device initialization.
1622 This function is called once on open().
1623 Return 0 on success, a negative number otherwise.
1624 --------------------------------------------------------------------------*/
1625static int w9968cf_init_chip(struct w9968cf_device* cam)
1626{
1627 unsigned long hw_bufsize = cam->maxwidth*cam->maxheight*2,
1628 y0 = 0x0000,
1629 u0 = y0 + hw_bufsize/2,
1630 v0 = u0 + hw_bufsize/4,
1631 y1 = v0 + hw_bufsize/4,
1632 u1 = y1 + hw_bufsize/2,
1633 v1 = u1 + hw_bufsize/4;
1634 int err = 0;
1635
1636 err += w9968cf_write_reg(cam, 0xff00, 0x00); /* power off */
1637 err += w9968cf_write_reg(cam, 0xbf10, 0x00); /* power on */
1638
1639 err += w9968cf_write_reg(cam, 0x405d, 0x03); /* DRAM timings */
1640 err += w9968cf_write_reg(cam, 0x0030, 0x04); /* SDRAM timings */
1641
1642 err += w9968cf_write_reg(cam, y0 & 0xffff, 0x20); /* Y buf.0, low */
1643 err += w9968cf_write_reg(cam, y0 >> 16, 0x21); /* Y buf.0, high */
1644 err += w9968cf_write_reg(cam, u0 & 0xffff, 0x24); /* U buf.0, low */
1645 err += w9968cf_write_reg(cam, u0 >> 16, 0x25); /* U buf.0, high */
1646 err += w9968cf_write_reg(cam, v0 & 0xffff, 0x28); /* V buf.0, low */
1647 err += w9968cf_write_reg(cam, v0 >> 16, 0x29); /* V buf.0, high */
1648
1649 err += w9968cf_write_reg(cam, y1 & 0xffff, 0x22); /* Y buf.1, low */
1650 err += w9968cf_write_reg(cam, y1 >> 16, 0x23); /* Y buf.1, high */
1651 err += w9968cf_write_reg(cam, u1 & 0xffff, 0x26); /* U buf.1, low */
1652 err += w9968cf_write_reg(cam, u1 >> 16, 0x27); /* U buf.1, high */
1653 err += w9968cf_write_reg(cam, v1 & 0xffff, 0x2a); /* V buf.1, low */
1654 err += w9968cf_write_reg(cam, v1 >> 16, 0x2b); /* V buf.1, high */
1655
1656 err += w9968cf_write_reg(cam, y1 & 0xffff, 0x32); /* JPEG buf 0 low */
1657 err += w9968cf_write_reg(cam, y1 >> 16, 0x33); /* JPEG buf 0 high */
1658
1659 err += w9968cf_write_reg(cam, y1 & 0xffff, 0x34); /* JPEG buf 1 low */
1660 err += w9968cf_write_reg(cam, y1 >> 16, 0x35); /* JPEG bug 1 high */
1661
1662 err += w9968cf_write_reg(cam, 0x0000, 0x36);/* JPEG restart interval */
1663 err += w9968cf_write_reg(cam, 0x0804, 0x37);/*JPEG VLE FIFO threshold*/
1664 err += w9968cf_write_reg(cam, 0x0000, 0x38);/* disable hw up-scaling */
1665 err += w9968cf_write_reg(cam, 0x0000, 0x3f); /* JPEG/MCTL test data */
1666
1667 err += w9968cf_set_picture(cam, cam->picture); /* this before */
1668 err += w9968cf_set_window(cam, cam->window);
1669
1670 if (err)
1671 DBG(1, "Chip initialization failed")
1672 else
1673 DBG(5, "Chip successfully initialized")
1674
1675 return err;
1676}
1677
1678
1679/*--------------------------------------------------------------------------
1680 Return non-zero if the palette is supported, 0 otherwise.
1681 --------------------------------------------------------------------------*/
1682static inline u16 w9968cf_valid_palette(u16 palette)
1683{
1684 u8 i = 0;
1685 while (w9968cf_formatlist[i].palette != 0) {
1686 if (palette == w9968cf_formatlist[i].palette)
1687 return palette;
1688 i++;
1689 }
1690 return 0;
1691}
1692
1693
1694/*--------------------------------------------------------------------------
1695 Return the depth corresponding to the given palette.
1696 Palette _must_ be supported !
1697 --------------------------------------------------------------------------*/
1698static inline u16 w9968cf_valid_depth(u16 palette)
1699{
1700 u8 i=0;
1701 while (w9968cf_formatlist[i].palette != palette)
1702 i++;
1703
1704 return w9968cf_formatlist[i].depth;
1705}
1706
1707
1708/*--------------------------------------------------------------------------
1709 Return non-zero if the format requires decompression, 0 otherwise.
1710 --------------------------------------------------------------------------*/
1711static inline u8 w9968cf_need_decompression(u16 palette)
1712{
1713 u8 i = 0;
1714 while (w9968cf_formatlist[i].palette != 0) {
1715 if (palette == w9968cf_formatlist[i].palette)
1716 return w9968cf_formatlist[i].compression;
1717 i++;
1718 }
1719 return 0;
1720}
1721
1722
1723/*--------------------------------------------------------------------------
1724 Change the picture settings of the camera.
1725 Return 0 on success, a negative number otherwise.
1726 --------------------------------------------------------------------------*/
1727static int
1728w9968cf_set_picture(struct w9968cf_device* cam, struct video_picture pict)
1729{
1730 u16 fmt, hw_depth, hw_palette, reg_v = 0x0000;
1731 int err = 0;
1732
1733 /* Make sure we are using a valid depth */
1734 pict.depth = w9968cf_valid_depth(pict.palette);
1735
1736 fmt = pict.palette;
1737
1738 hw_depth = pict.depth; /* depth used by the winbond chip */
1739 hw_palette = pict.palette; /* palette used by the winbond chip */
1740
1741 /* VS & HS polarities */
1742 reg_v = (cam->vs_polarity << 12) | (cam->hs_polarity << 11);
1743
1744 switch (fmt)
1745 {
1746 case VIDEO_PALETTE_UYVY:
1747 reg_v |= 0x0000;
1748 cam->vpp_flag = VPP_NONE;
1749 break;
1750 case VIDEO_PALETTE_YUV422P:
1751 reg_v |= 0x0002;
1752 cam->vpp_flag = VPP_DECOMPRESSION;
1753 break;
1754 case VIDEO_PALETTE_YUV420:
1755 case VIDEO_PALETTE_YUV420P:
1756 reg_v |= 0x0003;
1757 cam->vpp_flag = VPP_DECOMPRESSION;
1758 break;
1759 case VIDEO_PALETTE_YUYV:
1760 case VIDEO_PALETTE_YUV422:
1761 reg_v |= 0x0000;
1762 cam->vpp_flag = VPP_SWAP_YUV_BYTES;
1763 hw_palette = VIDEO_PALETTE_UYVY;
1764 break;
1765 /* Original video is used instead of RGBX palettes.
1766 Software conversion later. */
1767 case VIDEO_PALETTE_GREY:
1768 case VIDEO_PALETTE_RGB555:
1769 case VIDEO_PALETTE_RGB565:
1770 case VIDEO_PALETTE_RGB24:
1771 case VIDEO_PALETTE_RGB32:
1772 reg_v |= 0x0000; /* UYVY 16 bit is used */
1773 hw_depth = 16;
1774 hw_palette = VIDEO_PALETTE_UYVY;
1775 cam->vpp_flag = VPP_UYVY_TO_RGBX;
1776 break;
1777 }
1778
1779 /* NOTE: due to memory issues, it is better to disable the hardware
1780 double buffering during compression */
1781 if (cam->double_buffer && !(cam->vpp_flag & VPP_DECOMPRESSION))
1782 reg_v |= 0x0080;
1783
1784 if (cam->clamping)
1785 reg_v |= 0x0020;
1786
1787 if (cam->filter_type == 1)
1788 reg_v |= 0x0008;
1789 else if (cam->filter_type == 2)
1790 reg_v |= 0x000c;
1791
1792 if ((err = w9968cf_write_reg(cam, reg_v, 0x16)))
1793 goto error;
1794
1795 if ((err = w9968cf_sensor_update_picture(cam, pict)))
1796 goto error;
1797
1798 /* If all went well, update the device data structure */
1799 memcpy(&cam->picture, &pict, sizeof(pict));
1800 cam->hw_depth = hw_depth;
1801 cam->hw_palette = hw_palette;
1802
1803 /* Settings changed, so we clear the frame buffers */
1804 memset(cam->frame[0].buffer, 0, cam->nbuffers*cam->frame[0].size);
1805
1806 DBG(4, "Palette is %s, depth is %u bpp",
1807 symbolic(v4l1_plist, pict.palette), pict.depth)
1808
1809 return 0;
1810
1811error:
1812 DBG(1, "Failed to change picture settings")
1813 return err;
1814}
1815
1816
1817/*--------------------------------------------------------------------------
1818 Change the capture area size of the camera.
1819 This function _must_ be called _after_ w9968cf_set_picture().
1820 Return 0 on success, a negative number otherwise.
1821 --------------------------------------------------------------------------*/
1822static int
1823w9968cf_set_window(struct w9968cf_device* cam, struct video_window win)
1824{
1825 u16 x, y, w, h, scx, scy, cw, ch, ax, ay;
1826 unsigned long fw, fh;
1827 struct ovcamchip_window s_win;
1828 int err = 0;
1829
1830 /* Work around to avoid FP arithmetics */
1831 #define __SC(x) ((x) << 10)
1832 #define __UNSC(x) ((x) >> 10)
1833
1834 /* Make sure we are using a supported resolution */
1835 if ((err = w9968cf_adjust_window_size(cam, (u16*)&win.width,
1836 (u16*)&win.height)))
1837 goto error;
1838
1839 /* Scaling factors */
1840 fw = __SC(win.width) / cam->maxwidth;
1841 fh = __SC(win.height) / cam->maxheight;
1842
1843 /* Set up the width and height values used by the chip */
1844 if ((win.width > cam->maxwidth) || (win.height > cam->maxheight)) {
1845 cam->vpp_flag |= VPP_UPSCALE;
1846 /* Calculate largest w,h mantaining the same w/h ratio */
1847 w = (fw >= fh) ? cam->maxwidth : __SC(win.width)/fh;
1848 h = (fw >= fh) ? __SC(win.height)/fw : cam->maxheight;
1849 if (w < cam->minwidth) /* just in case */
1850 w = cam->minwidth;
1851 if (h < cam->minheight) /* just in case */
1852 h = cam->minheight;
1853 } else {
1854 cam->vpp_flag &= ~VPP_UPSCALE;
1855 w = win.width;
1856 h = win.height;
1857 }
1858
1859 /* x,y offsets of the cropped area */
1860 scx = cam->start_cropx;
1861 scy = cam->start_cropy;
1862
1863 /* Calculate cropped area manteining the right w/h ratio */
1864 if (cam->largeview && !(cam->vpp_flag & VPP_UPSCALE)) {
1865 cw = (fw >= fh) ? cam->maxwidth : __SC(win.width)/fh;
1866 ch = (fw >= fh) ? __SC(win.height)/fw : cam->maxheight;
1867 } else {
1868 cw = w;
1869 ch = h;
1870 }
1871
1872 /* Setup the window of the sensor */
1873 s_win.format = VIDEO_PALETTE_UYVY;
1874 s_win.width = cam->maxwidth;
1875 s_win.height = cam->maxheight;
1876 s_win.quarter = 0; /* full progressive video */
1877
1878 /* Center it */
1879 s_win.x = (s_win.width - cw) / 2;
1880 s_win.y = (s_win.height - ch) / 2;
1881
1882 /* Clock divisor */
1883 if (cam->clockdiv >= 0)
1884 s_win.clockdiv = cam->clockdiv; /* manual override */
1885 else
1886 switch (cam->sensor) {
1887 case CC_OV6620:
1888 s_win.clockdiv = 0;
1889 break;
1890 case CC_OV6630:
1891 s_win.clockdiv = 0;
1892 break;
1893 case CC_OV76BE:
1894 case CC_OV7610:
1895 case CC_OV7620:
1896 s_win.clockdiv = 0;
1897 break;
1898 default:
1899 s_win.clockdiv = W9968CF_DEF_CLOCKDIVISOR;
1900 }
1901
1902 /* We have to scale win.x and win.y offsets */
1903 if ( (cam->largeview && !(cam->vpp_flag & VPP_UPSCALE))
1904 || (cam->vpp_flag & VPP_UPSCALE) ) {
1905 ax = __SC(win.x)/fw;
1906 ay = __SC(win.y)/fh;
1907 } else {
1908 ax = win.x;
1909 ay = win.y;
1910 }
1911
1912 if ((ax + cw) > cam->maxwidth)
1913 ax = cam->maxwidth - cw;
1914
1915 if ((ay + ch) > cam->maxheight)
1916 ay = cam->maxheight - ch;
1917
1918 /* Adjust win.x, win.y */
1919 if ( (cam->largeview && !(cam->vpp_flag & VPP_UPSCALE))
1920 || (cam->vpp_flag & VPP_UPSCALE) ) {
1921 win.x = __UNSC(ax*fw);
1922 win.y = __UNSC(ay*fh);
1923 } else {
1924 win.x = ax;
1925 win.y = ay;
1926 }
1927
1928 /* Offsets used by the chip */
1929 x = ax + s_win.x;
1930 y = ay + s_win.y;
1931
1932 /* Go ! */
1933 if ((err = w9968cf_sensor_cmd(cam, OVCAMCHIP_CMD_S_MODE, &s_win)))
1934 goto error;
1935
1936 err += w9968cf_write_reg(cam, scx + x, 0x10);
1937 err += w9968cf_write_reg(cam, scy + y, 0x11);
1938 err += w9968cf_write_reg(cam, scx + x + cw, 0x12);
1939 err += w9968cf_write_reg(cam, scy + y + ch, 0x13);
1940 err += w9968cf_write_reg(cam, w, 0x14);
1941 err += w9968cf_write_reg(cam, h, 0x15);
1942
1943 /* JPEG width & height */
1944 err += w9968cf_write_reg(cam, w, 0x30);
1945 err += w9968cf_write_reg(cam, h, 0x31);
1946
1947 /* Y & UV frame buffer strides (in WORD) */
1948 if (cam->vpp_flag & VPP_DECOMPRESSION) {
1949 err += w9968cf_write_reg(cam, w/2, 0x2c);
1950 err += w9968cf_write_reg(cam, w/4, 0x2d);
1951 } else
1952 err += w9968cf_write_reg(cam, w, 0x2c);
1953
1954 if (err)
1955 goto error;
1956
1957 /* If all went well, update the device data structure */
1958 memcpy(&cam->window, &win, sizeof(win));
1959 cam->hw_width = w;
1960 cam->hw_height = h;
1961
1962 /* Settings changed, so we clear the frame buffers */
1963 memset(cam->frame[0].buffer, 0, cam->nbuffers*cam->frame[0].size);
1964
1965 DBG(4, "The capture area is %dx%d, Offset (x,y)=(%u,%u)",
1966 win.width, win.height, win.x, win.y)
1967
1968 PDBGG("x=%u ,y=%u, w=%u, h=%u, ax=%u, ay=%u, s_win.x=%u, s_win.y=%u, "
1969 "cw=%u, ch=%u, win.x=%u, win.y=%u, win.width=%u, win.height=%u",
1970 x, y, w, h, ax, ay, s_win.x, s_win.y, cw, ch, win.x, win.y,
1971 win.width, win.height)
1972
1973 return 0;
1974
1975error:
1976 DBG(1, "Failed to change the capture area size")
1977 return err;
1978}
1979
1980
1981/*--------------------------------------------------------------------------
1982 Adjust the asked values for window width and height.
1983 Return 0 on success, -1 otherwise.
1984 --------------------------------------------------------------------------*/
1985static int
1986w9968cf_adjust_window_size(struct w9968cf_device* cam, u16* width, u16* height)
1987{
1988 u16 maxw, maxh;
1989
1990 if ((*width < cam->minwidth) || (*height < cam->minheight))
1991 return -ERANGE;
1992
1993 maxw = cam->upscaling && !(cam->vpp_flag & VPP_DECOMPRESSION) &&
1994 w9968cf_vpp ? max((u16)W9968CF_MAX_WIDTH, cam->maxwidth)
1995 : cam->maxwidth;
1996 maxh = cam->upscaling && !(cam->vpp_flag & VPP_DECOMPRESSION) &&
1997 w9968cf_vpp ? max((u16)W9968CF_MAX_HEIGHT, cam->maxheight)
1998 : cam->maxheight;
1999
2000 if (*width > maxw)
2001 *width = maxw;
2002 if (*height > maxh)
2003 *height = maxh;
2004
2005 if (cam->vpp_flag & VPP_DECOMPRESSION) {
2006 *width &= ~15L; /* multiple of 16 */
2007 *height &= ~15L;
2008 }
2009
2010 PDBGG("Window size adjusted w=%u, h=%u ", *width, *height)
2011
2012 return 0;
2013}
2014
2015
2016/*--------------------------------------------------------------------------
2017 Initialize the FIFO list of requested frames.
2018 --------------------------------------------------------------------------*/
2019static void w9968cf_init_framelist(struct w9968cf_device* cam)
2020{
2021 u8 i;
2022
2023 for (i = 0; i < cam->nbuffers; i++) {
2024 cam->requested_frame[i] = NULL;
2025 cam->frame[i].queued = 0;
2026 cam->frame[i].status = F_UNUSED;
2027 }
2028}
2029
2030
2031/*--------------------------------------------------------------------------
2032 Add a frame in the FIFO list of requested frames.
2033 This function is called in process context.
2034 --------------------------------------------------------------------------*/
2035static void w9968cf_push_frame(struct w9968cf_device* cam, u8 f_num)
2036{
2037 u8 f;
2038 unsigned long lock_flags;
2039
2040 spin_lock_irqsave(&cam->flist_lock, lock_flags);
2041
2042 for (f=0; cam->requested_frame[f] != NULL; f++);
2043 cam->requested_frame[f] = &cam->frame[f_num];
2044 cam->frame[f_num].queued = 1;
2045 cam->frame[f_num].status = F_UNUSED; /* clear the status */
2046
2047 spin_unlock_irqrestore(&cam->flist_lock, lock_flags);
2048
2049 DBG(6, "Frame #%u pushed into the FIFO list. Position %u", f_num, f)
2050}
2051
2052
2053/*--------------------------------------------------------------------------
2054 Read, store and remove the first pointer in the FIFO list of requested
2055 frames. This function is called in interrupt context.
2056 --------------------------------------------------------------------------*/
2057static void
2058w9968cf_pop_frame(struct w9968cf_device* cam, struct w9968cf_frame_t** framep)
2059{
2060 u8 i;
2061
2062 spin_lock(&cam->flist_lock);
2063
2064 *framep = cam->requested_frame[0];
2065
2066 /* Shift the list of pointers */
2067 for (i = 0; i < cam->nbuffers-1; i++)
2068 cam->requested_frame[i] = cam->requested_frame[i+1];
2069 cam->requested_frame[i] = NULL;
2070
2071 spin_unlock(&cam->flist_lock);
2072
2073 DBG(6,"Popped frame #%d from the list", (*framep)->number)
2074}
2075
2076
2077/*--------------------------------------------------------------------------
2078 High-level video post-processing routine on grabbed frames.
2079 Return 0 on success, a negative number otherwise.
2080 --------------------------------------------------------------------------*/
2081static int
2082w9968cf_postprocess_frame(struct w9968cf_device* cam,
2083 struct w9968cf_frame_t* fr)
2084{
2085 void *pIn = fr->buffer, *pOut = cam->frame_vpp.buffer, *tmp;
2086 u16 w = cam->window.width,
2087 h = cam->window.height,
2088 d = cam->picture.depth,
2089 fmt = cam->picture.palette,
2090 rgb = cam->force_rgb,
2091 hw_w = cam->hw_width,
2092 hw_h = cam->hw_height,
2093 hw_d = cam->hw_depth;
2094 int err = 0;
2095
2096 #define _PSWAP(pIn, pOut) {tmp = (pIn); (pIn) = (pOut); (pOut) = tmp;}
2097
2098 if (cam->vpp_flag & VPP_DECOMPRESSION) {
2099 memcpy(pOut, pIn, fr->length);
2100 _PSWAP(pIn, pOut)
2101 err = w9968cf_vpp->decode(pIn, fr->length, hw_w, hw_h, pOut);
2102 PDBGG("Compressed frame length: %lu",(unsigned long)fr->length)
2103 fr->length = (hw_w*hw_h*hw_d)/8;
2104 _PSWAP(pIn, pOut)
2105 if (err) {
2106 DBG(4, "An error occurred while decoding the frame: "
2107 "%s", symbolic(decoder_errlist, err))
2108 return err;
2109 } else
2110 DBG(6, "Frame decoded")
2111 }
2112
2113 if (cam->vpp_flag & VPP_SWAP_YUV_BYTES) {
2114 w9968cf_vpp->swap_yuvbytes(pIn, fr->length);
2115 DBG(6, "Original UYVY component ordering changed")
2116 }
2117
2118 if (cam->vpp_flag & VPP_UPSCALE) {
2119 w9968cf_vpp->scale_up(pIn, pOut, hw_w, hw_h, hw_d, w, h);
2120 fr->length = (w*h*hw_d)/8;
2121 _PSWAP(pIn, pOut)
2122 DBG(6, "Vertical up-scaling done: %u,%u,%ubpp->%u,%u",
2123 hw_w, hw_h, hw_d, w, h)
2124 }
2125
2126 if (cam->vpp_flag & VPP_UYVY_TO_RGBX) {
2127 w9968cf_vpp->uyvy_to_rgbx(pIn, fr->length, pOut, fmt, rgb);
2128 fr->length = (w*h*d)/8;
2129 _PSWAP(pIn, pOut)
2130 DBG(6, "UYVY-16bit to %s conversion done",
2131 symbolic(v4l1_plist, fmt))
2132 }
2133
2134 if (pOut == fr->buffer)
2135 memcpy(fr->buffer, cam->frame_vpp.buffer, fr->length);
2136
2137 return 0;
2138}
2139
2140
2141
2142/****************************************************************************
2143 * Image sensor control routines *
2144 ****************************************************************************/
2145
2146static int
2147w9968cf_sensor_set_control(struct w9968cf_device* cam, int cid, int val)
2148{
2149 struct ovcamchip_control ctl;
2150 int err;
2151
2152 ctl.id = cid;
2153 ctl.value = val;
2154
2155 err = w9968cf_sensor_cmd(cam, OVCAMCHIP_CMD_S_CTRL, &ctl);
2156
2157 return err;
2158}
2159
2160
2161static int
2162w9968cf_sensor_get_control(struct w9968cf_device* cam, int cid, int* val)
2163{
2164 struct ovcamchip_control ctl;
2165 int err;
2166
2167 ctl.id = cid;
2168
2169 err = w9968cf_sensor_cmd(cam, OVCAMCHIP_CMD_G_CTRL, &ctl);
2170 if (!err)
2171 *val = ctl.value;
2172
2173 return err;
2174}
2175
2176
2177static int
2178w9968cf_sensor_cmd(struct w9968cf_device* cam, unsigned int cmd, void* arg)
2179{
2180 struct i2c_client* c = cam->sensor_client;
2181 int rc = 0;
2182
2183 if (!c || !c->driver || !c->driver->command)
2184 return -EINVAL;
2185
2186 rc = c->driver->command(c, cmd, arg);
2187 /* The I2C driver returns -EPERM on non-supported controls */
2188 return (rc < 0 && rc != -EPERM) ? rc : 0;
2189}
2190
2191
2192/*--------------------------------------------------------------------------
2193 Update some settings of the image sensor.
2194 Returns: 0 on success, a negative number otherwise.
2195 --------------------------------------------------------------------------*/
2196static int w9968cf_sensor_update_settings(struct w9968cf_device* cam)
2197{
2198 int err = 0;
2199
2200 /* Auto brightness */
2201 err = w9968cf_sensor_set_control(cam, OVCAMCHIP_CID_AUTOBRIGHT,
2202 cam->auto_brt);
2203 if (err)
2204 return err;
2205
2206 /* Auto exposure */
2207 err = w9968cf_sensor_set_control(cam, OVCAMCHIP_CID_AUTOEXP,
2208 cam->auto_exp);
2209 if (err)
2210 return err;
2211
2212 /* Banding filter */
2213 err = w9968cf_sensor_set_control(cam, OVCAMCHIP_CID_BANDFILT,
2214 cam->bandfilt);
2215 if (err)
2216 return err;
2217
2218 /* Light frequency */
2219 err = w9968cf_sensor_set_control(cam, OVCAMCHIP_CID_FREQ,
2220 cam->lightfreq);
2221 if (err)
2222 return err;
2223
2224 /* Back light */
2225 err = w9968cf_sensor_set_control(cam, OVCAMCHIP_CID_BACKLIGHT,
2226 cam->backlight);
2227 if (err)
2228 return err;
2229
2230 /* Mirror */
2231 err = w9968cf_sensor_set_control(cam, OVCAMCHIP_CID_MIRROR,
2232 cam->mirror);
2233 if (err)
2234 return err;
2235
2236 return 0;
2237}
2238
2239
2240/*--------------------------------------------------------------------------
2241 Get some current picture settings from the image sensor and update the
2242 internal 'picture' structure of the camera.
2243 Returns: 0 on success, a negative number otherwise.
2244 --------------------------------------------------------------------------*/
2245static int w9968cf_sensor_get_picture(struct w9968cf_device* cam)
2246{
2247 int err, v;
2248
2249 err = w9968cf_sensor_get_control(cam, OVCAMCHIP_CID_CONT, &v);
2250 if (err)
2251 return err;
2252 cam->picture.contrast = v;
2253
2254 err = w9968cf_sensor_get_control(cam, OVCAMCHIP_CID_BRIGHT, &v);
2255 if (err)
2256 return err;
2257 cam->picture.brightness = v;
2258
2259 err = w9968cf_sensor_get_control(cam, OVCAMCHIP_CID_SAT, &v);
2260 if (err)
2261 return err;
2262 cam->picture.colour = v;
2263
2264 err = w9968cf_sensor_get_control(cam, OVCAMCHIP_CID_HUE, &v);
2265 if (err)
2266 return err;
2267 cam->picture.hue = v;
2268
2269 DBG(5, "Got picture settings from the image sensor")
2270
2271 PDBGG("Brightness, contrast, hue, colour, whiteness are "
2272 "%u,%u,%u,%u,%u", cam->picture.brightness,cam->picture.contrast,
2273 cam->picture.hue, cam->picture.colour, cam->picture.whiteness)
2274
2275 return 0;
2276}
2277
2278
2279/*--------------------------------------------------------------------------
2280 Update picture settings of the image sensor.
2281 Returns: 0 on success, a negative number otherwise.
2282 --------------------------------------------------------------------------*/
2283static int
2284w9968cf_sensor_update_picture(struct w9968cf_device* cam,
2285 struct video_picture pict)
2286{
2287 int err = 0;
2288
2289 if ((!cam->sensor_initialized)
2290 || pict.contrast != cam->picture.contrast) {
2291 err = w9968cf_sensor_set_control(cam, OVCAMCHIP_CID_CONT,
2292 pict.contrast);
2293 if (err)
2294 goto fail;
2295 DBG(4, "Contrast changed from %u to %u",
2296 cam->picture.contrast, pict.contrast)
2297 cam->picture.contrast = pict.contrast;
2298 }
2299
2300 if (((!cam->sensor_initialized) ||
2301 pict.brightness != cam->picture.brightness) && (!cam->auto_brt)) {
2302 err = w9968cf_sensor_set_control(cam, OVCAMCHIP_CID_BRIGHT,
2303 pict.brightness);
2304 if (err)
2305 goto fail;
2306 DBG(4, "Brightness changed from %u to %u",
2307 cam->picture.brightness, pict.brightness)
2308 cam->picture.brightness = pict.brightness;
2309 }
2310
2311 if ((!cam->sensor_initialized) || pict.colour != cam->picture.colour) {
2312 err = w9968cf_sensor_set_control(cam, OVCAMCHIP_CID_SAT,
2313 pict.colour);
2314 if (err)
2315 goto fail;
2316 DBG(4, "Colour changed from %u to %u",
2317 cam->picture.colour, pict.colour)
2318 cam->picture.colour = pict.colour;
2319 }
2320
2321 if ((!cam->sensor_initialized) || pict.hue != cam->picture.hue) {
2322 err = w9968cf_sensor_set_control(cam, OVCAMCHIP_CID_HUE,
2323 pict.hue);
2324 if (err)
2325 goto fail;
2326 DBG(4, "Hue changed from %u to %u",
2327 cam->picture.hue, pict.hue)
2328 cam->picture.hue = pict.hue;
2329 }
2330
2331 return 0;
2332
2333fail:
2334 DBG(4, "Failed to change sensor picture setting")
2335 return err;
2336}
2337
2338
2339
2340/****************************************************************************
2341 * Camera configuration *
2342 ****************************************************************************/
2343
2344/*--------------------------------------------------------------------------
2345 This function is called when a supported image sensor is detected.
2346 Return 0 if the initialization succeeds, a negative number otherwise.
2347 --------------------------------------------------------------------------*/
2348static int w9968cf_sensor_init(struct w9968cf_device* cam)
2349{
2350 int err = 0;
2351
2352 if ((err = w9968cf_sensor_cmd(cam, OVCAMCHIP_CMD_INITIALIZE,
2353 &cam->monochrome)))
2354 goto error;
2355
2356 if ((err = w9968cf_sensor_cmd(cam, OVCAMCHIP_CMD_Q_SUBTYPE,
2357 &cam->sensor)))
2358 goto error;
2359
2360 /* NOTE: Make sure width and height are a multiple of 16 */
2361 switch (cam->sensor_client->addr) {
2362 case OV6xx0_SID:
2363 cam->maxwidth = 352;
2364 cam->maxheight = 288;
2365 cam->minwidth = 64;
2366 cam->minheight = 48;
2367 break;
2368 case OV7xx0_SID:
2369 cam->maxwidth = 640;
2370 cam->maxheight = 480;
2371 cam->minwidth = 64;
2372 cam->minheight = 48;
2373 break;
2374 default:
2375 DBG(1, "Not supported image sensor detected for %s",
2376 symbolic(camlist, cam->id))
2377 return -EINVAL;
2378 }
2379
2380 /* These values depend on the ones in the ovxxx0.c sources */
2381 switch (cam->sensor) {
2382 case CC_OV7620:
2383 cam->start_cropx = 287;
2384 cam->start_cropy = 35;
2385 /* Seems to work around a bug in the image sensor */
2386 cam->vs_polarity = 1;
2387 cam->hs_polarity = 1;
2388 break;
2389 default:
2390 cam->start_cropx = 320;
2391 cam->start_cropy = 35;
2392 cam->vs_polarity = 1;
2393 cam->hs_polarity = 0;
2394 }
2395
2396 if ((err = w9968cf_sensor_update_settings(cam)))
2397 goto error;
2398
2399 if ((err = w9968cf_sensor_update_picture(cam, cam->picture)))
2400 goto error;
2401
2402 cam->sensor_initialized = 1;
2403
2404 DBG(2, "%s image sensor initialized", symbolic(senlist, cam->sensor))
2405 return 0;
2406
2407error:
2408 cam->sensor_initialized = 0;
2409 cam->sensor = CC_UNKNOWN;
2410 DBG(1, "Image sensor initialization failed for %s (/dev/video%d). "
2411 "Try to detach and attach this device again",
2412 symbolic(camlist, cam->id), cam->v4ldev->minor)
2413 return err;
2414}
2415
2416
2417/*--------------------------------------------------------------------------
2418 Fill some basic fields in the main device data structure.
2419 This function is called once on w9968cf_usb_probe() for each recognized
2420 camera.
2421 --------------------------------------------------------------------------*/
2422static void
2423w9968cf_configure_camera(struct w9968cf_device* cam,
2424 struct usb_device* udev,
2425 enum w9968cf_model_id mod_id,
2426 const unsigned short dev_nr)
2427{
2428 mutex_init(&cam->fileop_mutex);
2429 init_waitqueue_head(&cam->open);
2430 spin_lock_init(&cam->urb_lock);
2431 spin_lock_init(&cam->flist_lock);
2432
2433 cam->users = 0;
2434 cam->disconnected = 0;
2435 cam->id = mod_id;
2436 cam->sensor = CC_UNKNOWN;
2437 cam->sensor_initialized = 0;
2438
2439 /* Calculate the alternate setting number (from 1 to 16)
2440 according to the 'packet_size' module parameter */
2441 if (packet_size[dev_nr] < W9968CF_MIN_PACKET_SIZE)
2442 packet_size[dev_nr] = W9968CF_MIN_PACKET_SIZE;
2443 for (cam->altsetting = 1;
2444 packet_size[dev_nr] < wMaxPacketSize[cam->altsetting-1];
2445 cam->altsetting++);
2446
2447 cam->max_buffers = (max_buffers[dev_nr] < 2 ||
2448 max_buffers[dev_nr] > W9968CF_MAX_BUFFERS)
2449 ? W9968CF_BUFFERS : (u8)max_buffers[dev_nr];
2450
2451 cam->double_buffer = (double_buffer[dev_nr] == 0 ||
2452 double_buffer[dev_nr] == 1)
2453 ? (u8)double_buffer[dev_nr]:W9968CF_DOUBLE_BUFFER;
2454
2455 cam->clamping = (clamping[dev_nr] == 0 || clamping[dev_nr] == 1)
2456 ? (u8)clamping[dev_nr] : W9968CF_CLAMPING;
2457
2458 cam->filter_type = (filter_type[dev_nr] == 0 ||
2459 filter_type[dev_nr] == 1 ||
2460 filter_type[dev_nr] == 2)
2461 ? (u8)filter_type[dev_nr] : W9968CF_FILTER_TYPE;
2462
2463 cam->capture = 1;
2464
2465 cam->largeview = (largeview[dev_nr] == 0 || largeview[dev_nr] == 1)
2466 ? (u8)largeview[dev_nr] : W9968CF_LARGEVIEW;
2467
2468 cam->decompression = (decompression[dev_nr] == 0 ||
2469 decompression[dev_nr] == 1 ||
2470 decompression[dev_nr] == 2)
2471 ? (u8)decompression[dev_nr]:W9968CF_DECOMPRESSION;
2472
2473 cam->upscaling = (upscaling[dev_nr] == 0 ||
2474 upscaling[dev_nr] == 1)
2475 ? (u8)upscaling[dev_nr] : W9968CF_UPSCALING;
2476
2477 cam->auto_brt = (autobright[dev_nr] == 0 || autobright[dev_nr] == 1)
2478 ? (u8)autobright[dev_nr] : W9968CF_AUTOBRIGHT;
2479
2480 cam->auto_exp = (autoexp[dev_nr] == 0 || autoexp[dev_nr] == 1)
2481 ? (u8)autoexp[dev_nr] : W9968CF_AUTOEXP;
2482
2483 cam->lightfreq = (lightfreq[dev_nr] == 50 || lightfreq[dev_nr] == 60)
2484 ? (u8)lightfreq[dev_nr] : W9968CF_LIGHTFREQ;
2485
2486 cam->bandfilt = (bandingfilter[dev_nr] == 0 ||
2487 bandingfilter[dev_nr] == 1)
2488 ? (u8)bandingfilter[dev_nr] : W9968CF_BANDINGFILTER;
2489
2490 cam->backlight = (backlight[dev_nr] == 0 || backlight[dev_nr] == 1)
2491 ? (u8)backlight[dev_nr] : W9968CF_BACKLIGHT;
2492
2493 cam->clockdiv = (clockdiv[dev_nr] == -1 || clockdiv[dev_nr] >= 0)
2494 ? (s8)clockdiv[dev_nr] : W9968CF_CLOCKDIV;
2495
2496 cam->mirror = (mirror[dev_nr] == 0 || mirror[dev_nr] == 1)
2497 ? (u8)mirror[dev_nr] : W9968CF_MIRROR;
2498
2499 cam->monochrome = (monochrome[dev_nr] == 0 || monochrome[dev_nr] == 1)
2500 ? monochrome[dev_nr] : W9968CF_MONOCHROME;
2501
2502 cam->picture.brightness = (u16)brightness[dev_nr];
2503 cam->picture.hue = (u16)hue[dev_nr];
2504 cam->picture.colour = (u16)colour[dev_nr];
2505 cam->picture.contrast = (u16)contrast[dev_nr];
2506 cam->picture.whiteness = (u16)whiteness[dev_nr];
2507 if (w9968cf_valid_palette((u16)force_palette[dev_nr])) {
2508 cam->picture.palette = (u16)force_palette[dev_nr];
2509 cam->force_palette = 1;
2510 } else {
2511 cam->force_palette = 0;
2512 if (cam->decompression == 0)
2513 cam->picture.palette = W9968CF_PALETTE_DECOMP_OFF;
2514 else if (cam->decompression == 1)
2515 cam->picture.palette = W9968CF_PALETTE_DECOMP_FORCE;
2516 else
2517 cam->picture.palette = W9968CF_PALETTE_DECOMP_ON;
2518 }
2519 cam->picture.depth = w9968cf_valid_depth(cam->picture.palette);
2520
2521 cam->force_rgb = (force_rgb[dev_nr] == 0 || force_rgb[dev_nr] == 1)
2522 ? (u8)force_rgb[dev_nr] : W9968CF_FORCE_RGB;
2523
2524 cam->window.x = 0;
2525 cam->window.y = 0;
2526 cam->window.width = W9968CF_WIDTH;
2527 cam->window.height = W9968CF_HEIGHT;
2528 cam->window.chromakey = 0;
2529 cam->window.clipcount = 0;
2530 cam->window.flags = 0;
2531
2532 DBG(3, "%s configured with settings #%u:",
2533 symbolic(camlist, cam->id), dev_nr)
2534
2535 DBG(3, "- Data packet size for USB isochrnous transfer: %u bytes",
2536 wMaxPacketSize[cam->altsetting-1])
2537
2538 DBG(3, "- Number of requested video frame buffers: %u",
2539 cam->max_buffers)
2540
2541 if (cam->double_buffer)
2542 DBG(3, "- Hardware double buffering enabled")
2543 else
2544 DBG(3, "- Hardware double buffering disabled")
2545
2546 if (cam->filter_type == 0)
2547 DBG(3, "- Video filtering disabled")
2548 else if (cam->filter_type == 1)
2549 DBG(3, "- Video filtering enabled: type 1-2-1")
2550 else if (cam->filter_type == 2)
2551 DBG(3, "- Video filtering enabled: type 2-3-6-3-2")
2552
2553 if (cam->clamping)
2554 DBG(3, "- Video data clamping (CCIR-601 format) enabled")
2555 else
2556 DBG(3, "- Video data clamping (CCIR-601 format) disabled")
2557
2558 if (cam->largeview)
2559 DBG(3, "- Large view enabled")
2560 else
2561 DBG(3, "- Large view disabled")
2562
2563 if ((cam->decompression) == 0 && (!cam->force_palette))
2564 DBG(3, "- Decompression disabled")
2565 else if ((cam->decompression) == 1 && (!cam->force_palette))
2566 DBG(3, "- Decompression forced")
2567 else if ((cam->decompression) == 2 && (!cam->force_palette))
2568 DBG(3, "- Decompression allowed")
2569
2570 if (cam->upscaling)
2571 DBG(3, "- Software image scaling enabled")
2572 else
2573 DBG(3, "- Software image scaling disabled")
2574
2575 if (cam->force_palette)
2576 DBG(3, "- Image palette forced to %s",
2577 symbolic(v4l1_plist, cam->picture.palette))
2578
2579 if (cam->force_rgb)
2580 DBG(3, "- RGB component ordering will be used instead of BGR")
2581
2582 if (cam->auto_brt)
2583 DBG(3, "- Auto brightness enabled")
2584 else
2585 DBG(3, "- Auto brightness disabled")
2586
2587 if (cam->auto_exp)
2588 DBG(3, "- Auto exposure enabled")
2589 else
2590 DBG(3, "- Auto exposure disabled")
2591
2592 if (cam->backlight)
2593 DBG(3, "- Backlight exposure algorithm enabled")
2594 else
2595 DBG(3, "- Backlight exposure algorithm disabled")
2596
2597 if (cam->mirror)
2598 DBG(3, "- Mirror enabled")
2599 else
2600 DBG(3, "- Mirror disabled")
2601
2602 if (cam->bandfilt)
2603 DBG(3, "- Banding filter enabled")
2604 else
2605 DBG(3, "- Banding filter disabled")
2606
2607 DBG(3, "- Power lighting frequency: %u", cam->lightfreq)
2608
2609 if (cam->clockdiv == -1)
2610 DBG(3, "- Automatic clock divisor enabled")
2611 else
2612 DBG(3, "- Clock divisor: %d", cam->clockdiv)
2613
2614 if (cam->monochrome)
2615 DBG(3, "- Image sensor used as monochrome")
2616 else
2617 DBG(3, "- Image sensor not used as monochrome")
2618}
2619
2620
2621/*--------------------------------------------------------------------------
2622 If the video post-processing module is not loaded, some parameters
2623 must be overridden.
2624 --------------------------------------------------------------------------*/
2625static void w9968cf_adjust_configuration(struct w9968cf_device* cam)
2626{
2627 if (!w9968cf_vpp) {
2628 if (cam->decompression == 1) {
2629 cam->decompression = 2;
2630 DBG(2, "Video post-processing module not found: "
2631 "'decompression' parameter forced to 2")
2632 }
2633 if (cam->upscaling) {
2634 cam->upscaling = 0;
2635 DBG(2, "Video post-processing module not found: "
2636 "'upscaling' parameter forced to 0")
2637 }
2638 if (cam->picture.palette != VIDEO_PALETTE_UYVY) {
2639 cam->force_palette = 0;
2640 DBG(2, "Video post-processing module not found: "
2641 "'force_palette' parameter forced to 0")
2642 }
2643 cam->picture.palette = VIDEO_PALETTE_UYVY;
2644 cam->picture.depth = w9968cf_valid_depth(cam->picture.palette);
2645 }
2646}
2647
2648
2649/*--------------------------------------------------------------------------
2650 Release the resources used by the driver.
2651 This function is called on disconnect
2652 (or on close if deallocation has been deferred)
2653 --------------------------------------------------------------------------*/
2654static void w9968cf_release_resources(struct w9968cf_device* cam)
2655{
2656 mutex_lock(&w9968cf_devlist_mutex);
2657
2658 DBG(2, "V4L device deregistered: /dev/video%d", cam->v4ldev->minor)
2659
2660 video_unregister_device(cam->v4ldev);
2661 list_del(&cam->v4llist);
2662 i2c_del_adapter(&cam->i2c_adapter);
2663 w9968cf_deallocate_memory(cam);
2664 kfree(cam->control_buffer);
2665 kfree(cam->data_buffer);
2666
2667 mutex_unlock(&w9968cf_devlist_mutex);
2668}
2669
2670
2671
2672/****************************************************************************
2673 * Video4Linux interface *
2674 ****************************************************************************/
2675
2676static int w9968cf_open(struct inode* inode, struct file* filp)
2677{
2678 struct w9968cf_device* cam;
2679 int err;
2680
2681 /* This the only safe way to prevent race conditions with disconnect */
2682 if (!down_read_trylock(&w9968cf_disconnect))
2683 return -ERESTARTSYS;
2684
2685 cam = (struct w9968cf_device*)video_get_drvdata(video_devdata(filp));
2686
2687 mutex_lock(&cam->dev_mutex);
2688
2689 if (cam->sensor == CC_UNKNOWN) {
2690 DBG(2, "No supported image sensor has been detected by the "
2691 "'ovcamchip' module for the %s (/dev/video%d). Make "
2692 "sure it is loaded *before* (re)connecting the camera.",
2693 symbolic(camlist, cam->id), cam->v4ldev->minor)
2694 mutex_unlock(&cam->dev_mutex);
2695 up_read(&w9968cf_disconnect);
2696 return -ENODEV;
2697 }
2698
2699 if (cam->users) {
2700 DBG(2, "%s (/dev/video%d) has been already occupied by '%s'",
2701 symbolic(camlist, cam->id),cam->v4ldev->minor,cam->command)
2702 if ((filp->f_flags & O_NONBLOCK)||(filp->f_flags & O_NDELAY)) {
2703 mutex_unlock(&cam->dev_mutex);
2704 up_read(&w9968cf_disconnect);
2705 return -EWOULDBLOCK;
2706 }
2707 mutex_unlock(&cam->dev_mutex);
2708 err = wait_event_interruptible_exclusive(cam->open,
2709 cam->disconnected ||
2710 !cam->users);
2711 if (err) {
2712 up_read(&w9968cf_disconnect);
2713 return err;
2714 }
2715 if (cam->disconnected) {
2716 up_read(&w9968cf_disconnect);
2717 return -ENODEV;
2718 }
2719 mutex_lock(&cam->dev_mutex);
2720 }
2721
2722 DBG(5, "Opening '%s', /dev/video%d ...",
2723 symbolic(camlist, cam->id), cam->v4ldev->minor)
2724
2725 cam->streaming = 0;
2726 cam->misconfigured = 0;
2727
2728 w9968cf_adjust_configuration(cam);
2729
2730 if ((err = w9968cf_allocate_memory(cam)))
2731 goto deallocate_memory;
2732
2733 if ((err = w9968cf_init_chip(cam)))
2734 goto deallocate_memory;
2735
2736 if ((err = w9968cf_start_transfer(cam)))
2737 goto deallocate_memory;
2738
2739 filp->private_data = cam;
2740
2741 cam->users++;
2742 strcpy(cam->command, current->comm);
2743
2744 init_waitqueue_head(&cam->wait_queue);
2745
2746 DBG(5, "Video device is open")
2747
2748 mutex_unlock(&cam->dev_mutex);
2749 up_read(&w9968cf_disconnect);
2750
2751 return 0;
2752
2753deallocate_memory:
2754 w9968cf_deallocate_memory(cam);
2755 DBG(2, "Failed to open the video device")
2756 mutex_unlock(&cam->dev_mutex);
2757 up_read(&w9968cf_disconnect);
2758 return err;
2759}
2760
2761
2762static int w9968cf_release(struct inode* inode, struct file* filp)
2763{
2764 struct w9968cf_device* cam;
2765
2766 cam = (struct w9968cf_device*)video_get_drvdata(video_devdata(filp));
2767
2768 mutex_lock(&cam->dev_mutex); /* prevent disconnect() to be called */
2769
2770 w9968cf_stop_transfer(cam);
2771
2772 if (cam->disconnected) {
2773 w9968cf_release_resources(cam);
2774 mutex_unlock(&cam->dev_mutex);
2775 kfree(cam);
2776 return 0;
2777 }
2778
2779 cam->users--;
2780 w9968cf_deallocate_memory(cam);
2781 wake_up_interruptible_nr(&cam->open, 1);
2782
2783 DBG(5, "Video device closed")
2784 mutex_unlock(&cam->dev_mutex);
2785 return 0;
2786}
2787
2788
2789static ssize_t
2790w9968cf_read(struct file* filp, char __user * buf, size_t count, loff_t* f_pos)
2791{
2792 struct w9968cf_device* cam;
2793 struct w9968cf_frame_t* fr;
2794 int err = 0;
2795
2796 cam = (struct w9968cf_device*)video_get_drvdata(video_devdata(filp));
2797
2798 if (filp->f_flags & O_NONBLOCK)
2799 return -EWOULDBLOCK;
2800
2801 if (mutex_lock_interruptible(&cam->fileop_mutex))
2802 return -ERESTARTSYS;
2803
2804 if (cam->disconnected) {
2805 DBG(2, "Device not present")
2806 mutex_unlock(&cam->fileop_mutex);
2807 return -ENODEV;
2808 }
2809
2810 if (cam->misconfigured) {
2811 DBG(2, "The camera is misconfigured. Close and open it again.")
2812 mutex_unlock(&cam->fileop_mutex);
2813 return -EIO;
2814 }
2815
2816 if (!cam->frame[0].queued)
2817 w9968cf_push_frame(cam, 0);
2818
2819 if (!cam->frame[1].queued)
2820 w9968cf_push_frame(cam, 1);
2821
2822 err = wait_event_interruptible(cam->wait_queue,
2823 cam->frame[0].status == F_READY ||
2824 cam->frame[1].status == F_READY ||
2825 cam->disconnected);
2826 if (err) {
2827 mutex_unlock(&cam->fileop_mutex);
2828 return err;
2829 }
2830 if (cam->disconnected) {
2831 mutex_unlock(&cam->fileop_mutex);
2832 return -ENODEV;
2833 }
2834
2835 fr = (cam->frame[0].status == F_READY) ? &cam->frame[0]:&cam->frame[1];
2836
2837 if (w9968cf_vpp)
2838 w9968cf_postprocess_frame(cam, fr);
2839
2840 if (count > fr->length)
2841 count = fr->length;
2842
2843 if (copy_to_user(buf, fr->buffer, count)) {
2844 fr->status = F_UNUSED;
2845 mutex_unlock(&cam->fileop_mutex);
2846 return -EFAULT;
2847 }
2848 *f_pos += count;
2849
2850 fr->status = F_UNUSED;
2851
2852 DBG(5, "%zu bytes read", count)
2853
2854 mutex_unlock(&cam->fileop_mutex);
2855 return count;
2856}
2857
2858
2859static int w9968cf_mmap(struct file* filp, struct vm_area_struct *vma)
2860{
2861 struct w9968cf_device* cam = (struct w9968cf_device*)
2862 video_get_drvdata(video_devdata(filp));
2863 unsigned long vsize = vma->vm_end - vma->vm_start,
2864 psize = cam->nbuffers * cam->frame[0].size,
2865 start = vma->vm_start,
2866 pos = (unsigned long)cam->frame[0].buffer,
2867 page;
2868
2869 if (cam->disconnected) {
2870 DBG(2, "Device not present")
2871 return -ENODEV;
2872 }
2873
2874 if (cam->misconfigured) {
2875 DBG(2, "The camera is misconfigured. Close and open it again")
2876 return -EIO;
2877 }
2878
2879 PDBGG("mmapping %lu bytes...", vsize)
2880
2881 if (vsize > psize - (vma->vm_pgoff << PAGE_SHIFT))
2882 return -EINVAL;
2883
2884 while (vsize > 0) {
2885 page = vmalloc_to_pfn((void *)pos);
2886 if (remap_pfn_range(vma, start, page + vma->vm_pgoff,
2887 PAGE_SIZE, vma->vm_page_prot))
2888 return -EAGAIN;
2889 start += PAGE_SIZE;
2890 pos += PAGE_SIZE;
2891 vsize -= PAGE_SIZE;
2892 }
2893
2894 DBG(5, "mmap method successfully called")
2895 return 0;
2896}
2897
2898
2899static int
2900w9968cf_ioctl(struct inode* inode, struct file* filp,
2901 unsigned int cmd, unsigned long arg)
2902{
2903 struct w9968cf_device* cam;
2904 int err;
2905
2906 cam = (struct w9968cf_device*)video_get_drvdata(video_devdata(filp));
2907
2908 if (mutex_lock_interruptible(&cam->fileop_mutex))
2909 return -ERESTARTSYS;
2910
2911 if (cam->disconnected) {
2912 DBG(2, "Device not present")
2913 mutex_unlock(&cam->fileop_mutex);
2914 return -ENODEV;
2915 }
2916
2917 if (cam->misconfigured) {
2918 DBG(2, "The camera is misconfigured. Close and open it again.")
2919 mutex_unlock(&cam->fileop_mutex);
2920 return -EIO;
2921 }
2922
2923 err = w9968cf_v4l_ioctl(inode, filp, cmd, (void __user *)arg);
2924
2925 mutex_unlock(&cam->fileop_mutex);
2926 return err;
2927}
2928
2929
2930static int w9968cf_v4l_ioctl(struct inode* inode, struct file* filp,
2931 unsigned int cmd, void __user * arg)
2932{
2933 struct w9968cf_device* cam;
2934 const char* v4l1_ioctls[] = {
2935 "?", "CGAP", "GCHAN", "SCHAN", "GTUNER", "STUNER",
2936 "GPICT", "SPICT", "CCAPTURE", "GWIN", "SWIN", "GFBUF",
2937 "SFBUF", "KEY", "GFREQ", "SFREQ", "GAUDIO", "SAUDIO",
2938 "SYNC", "MCAPTURE", "GMBUF", "GUNIT", "GCAPTURE", "SCAPTURE",
2939 "SPLAYMODE", "SWRITEMODE", "GPLAYINFO", "SMICROCODE",
2940 "GVBIFMT", "SVBIFMT"
2941 };
2942
2943 #define V4L1_IOCTL(cmd) \
2944 ((_IOC_NR((cmd)) < ARRAY_SIZE(v4l1_ioctls)) ? \
2945 v4l1_ioctls[_IOC_NR((cmd))] : "?")
2946
2947 cam = (struct w9968cf_device*)video_get_drvdata(video_devdata(filp));
2948
2949 switch (cmd) {
2950
2951 case VIDIOCGCAP: /* get video capability */
2952 {
2953 struct video_capability cap = {
2954 .type = VID_TYPE_CAPTURE | VID_TYPE_SCALES,
2955 .channels = 1,
2956 .audios = 0,
2957 .minwidth = cam->minwidth,
2958 .minheight = cam->minheight,
2959 };
2960 sprintf(cap.name, "W996[87]CF USB Camera #%d",
2961 cam->v4ldev->minor);
2962 cap.maxwidth = (cam->upscaling && w9968cf_vpp)
2963 ? max((u16)W9968CF_MAX_WIDTH, cam->maxwidth)
2964 : cam->maxwidth;
2965 cap.maxheight = (cam->upscaling && w9968cf_vpp)
2966 ? max((u16)W9968CF_MAX_HEIGHT, cam->maxheight)
2967 : cam->maxheight;
2968
2969 if (copy_to_user(arg, &cap, sizeof(cap)))
2970 return -EFAULT;
2971
2972 DBG(5, "VIDIOCGCAP successfully called")
2973 return 0;
2974 }
2975
2976 case VIDIOCGCHAN: /* get video channel informations */
2977 {
2978 struct video_channel chan;
2979 if (copy_from_user(&chan, arg, sizeof(chan)))
2980 return -EFAULT;
2981
2982 if (chan.channel != 0)
2983 return -EINVAL;
2984
2985 strcpy(chan.name, "Camera");
2986 chan.tuners = 0;
2987 chan.flags = 0;
2988 chan.type = VIDEO_TYPE_CAMERA;
2989 chan.norm = VIDEO_MODE_AUTO;
2990
2991 if (copy_to_user(arg, &chan, sizeof(chan)))
2992 return -EFAULT;
2993
2994 DBG(5, "VIDIOCGCHAN successfully called")
2995 return 0;
2996 }
2997
2998 case VIDIOCSCHAN: /* set active channel */
2999 {
3000 struct video_channel chan;
3001
3002 if (copy_from_user(&chan, arg, sizeof(chan)))
3003 return -EFAULT;
3004
3005 if (chan.channel != 0)
3006 return -EINVAL;
3007
3008 DBG(5, "VIDIOCSCHAN successfully called")
3009 return 0;
3010 }
3011
3012 case VIDIOCGPICT: /* get image properties of the picture */
3013 {
3014 if (w9968cf_sensor_get_picture(cam))
3015 return -EIO;
3016
3017 if (copy_to_user(arg, &cam->picture, sizeof(cam->picture)))
3018 return -EFAULT;
3019
3020 DBG(5, "VIDIOCGPICT successfully called")
3021 return 0;
3022 }
3023
3024 case VIDIOCSPICT: /* change picture settings */
3025 {
3026 struct video_picture pict;
3027 int err = 0;
3028
3029 if (copy_from_user(&pict, arg, sizeof(pict)))
3030 return -EFAULT;
3031
3032 if ( (cam->force_palette || !w9968cf_vpp)
3033 && pict.palette != cam->picture.palette ) {
3034 DBG(4, "Palette %s rejected: only %s is allowed",
3035 symbolic(v4l1_plist, pict.palette),
3036 symbolic(v4l1_plist, cam->picture.palette))
3037 return -EINVAL;
3038 }
3039
3040 if (!w9968cf_valid_palette(pict.palette)) {
3041 DBG(4, "Palette %s not supported. VIDIOCSPICT failed",
3042 symbolic(v4l1_plist, pict.palette))
3043 return -EINVAL;
3044 }
3045
3046 if (!cam->force_palette) {
3047 if (cam->decompression == 0) {
3048 if (w9968cf_need_decompression(pict.palette)) {
3049 DBG(4, "Decompression disabled: palette %s is not "
3050 "allowed. VIDIOCSPICT failed",
3051 symbolic(v4l1_plist, pict.palette))
3052 return -EINVAL;
3053 }
3054 } else if (cam->decompression == 1) {
3055 if (!w9968cf_need_decompression(pict.palette)) {
3056 DBG(4, "Decompression forced: palette %s is not "
3057 "allowed. VIDIOCSPICT failed",
3058 symbolic(v4l1_plist, pict.palette))
3059 return -EINVAL;
3060 }
3061 }
3062 }
3063
3064 if (pict.depth != w9968cf_valid_depth(pict.palette)) {
3065 DBG(4, "Requested depth %u bpp is not valid for %s "
3066 "palette: ignored and changed to %u bpp",
3067 pict.depth, symbolic(v4l1_plist, pict.palette),
3068 w9968cf_valid_depth(pict.palette))
3069 pict.depth = w9968cf_valid_depth(pict.palette);
3070 }
3071
3072 if (pict.palette != cam->picture.palette) {
3073 if(*cam->requested_frame
3074 || cam->frame_current->queued) {
3075 err = wait_event_interruptible
3076 ( cam->wait_queue,
3077 cam->disconnected ||
3078 (!*cam->requested_frame &&
3079 !cam->frame_current->queued) );
3080 if (err)
3081 return err;
3082 if (cam->disconnected)
3083 return -ENODEV;
3084 }
3085
3086 if (w9968cf_stop_transfer(cam))
3087 goto ioctl_fail;
3088
3089 if (w9968cf_set_picture(cam, pict))
3090 goto ioctl_fail;
3091
3092 if (w9968cf_start_transfer(cam))
3093 goto ioctl_fail;
3094
3095 } else if (w9968cf_sensor_update_picture(cam, pict))
3096 return -EIO;
3097
3098
3099 DBG(5, "VIDIOCSPICT successfully called")
3100 return 0;
3101 }
3102
3103 case VIDIOCSWIN: /* set capture area */
3104 {
3105 struct video_window win;
3106 int err = 0;
3107
3108 if (copy_from_user(&win, arg, sizeof(win)))
3109 return -EFAULT;
3110
3111 DBG(6, "VIDIOCSWIN called: clipcount=%d, flags=%u, "
3112 "x=%u, y=%u, %ux%u", win.clipcount, win.flags,
3113 win.x, win.y, win.width, win.height)
3114
3115 if (win.clipcount != 0 || win.flags != 0)
3116 return -EINVAL;
3117
3118 if ((err = w9968cf_adjust_window_size(cam, (u16*)&win.width,
3119 (u16*)&win.height))) {
3120 DBG(4, "Resolution not supported (%ux%u). "
3121 "VIDIOCSWIN failed", win.width, win.height)
3122 return err;
3123 }
3124
3125 if (win.x != cam->window.x ||
3126 win.y != cam->window.y ||
3127 win.width != cam->window.width ||
3128 win.height != cam->window.height) {
3129 if(*cam->requested_frame
3130 || cam->frame_current->queued) {
3131 err = wait_event_interruptible
3132 ( cam->wait_queue,
3133 cam->disconnected ||
3134 (!*cam->requested_frame &&
3135 !cam->frame_current->queued) );
3136 if (err)
3137 return err;
3138 if (cam->disconnected)
3139 return -ENODEV;
3140 }
3141
3142 if (w9968cf_stop_transfer(cam))
3143 goto ioctl_fail;
3144
3145 /* This _must_ be called before set_window() */
3146 if (w9968cf_set_picture(cam, cam->picture))
3147 goto ioctl_fail;
3148
3149 if (w9968cf_set_window(cam, win))
3150 goto ioctl_fail;
3151
3152 if (w9968cf_start_transfer(cam))
3153 goto ioctl_fail;
3154 }
3155
3156 DBG(5, "VIDIOCSWIN successfully called. ")
3157 return 0;
3158 }
3159
3160 case VIDIOCGWIN: /* get current window properties */
3161 {
3162 if (copy_to_user(arg,&cam->window,sizeof(struct video_window)))
3163 return -EFAULT;
3164
3165 DBG(5, "VIDIOCGWIN successfully called")
3166 return 0;
3167 }
3168
3169 case VIDIOCGMBUF: /* request for memory (mapped) buffer */
3170 {
3171 struct video_mbuf mbuf;
3172 u8 i;
3173
3174 mbuf.size = cam->nbuffers * cam->frame[0].size;
3175 mbuf.frames = cam->nbuffers;
3176 for (i = 0; i < cam->nbuffers; i++)
3177 mbuf.offsets[i] = (unsigned long)cam->frame[i].buffer -
3178 (unsigned long)cam->frame[0].buffer;
3179
3180 if (copy_to_user(arg, &mbuf, sizeof(mbuf)))
3181 return -EFAULT;
3182
3183 DBG(5, "VIDIOCGMBUF successfully called")
3184 return 0;
3185 }
3186
3187 case VIDIOCMCAPTURE: /* start the capture to a frame */
3188 {
3189 struct video_mmap mmap;
3190 struct w9968cf_frame_t* fr;
3191 int err = 0;
3192
3193 if (copy_from_user(&mmap, arg, sizeof(mmap)))
3194 return -EFAULT;
3195
3196 DBG(6, "VIDIOCMCAPTURE called: frame #%u, format=%s, %dx%d",
3197 mmap.frame, symbolic(v4l1_plist, mmap.format),
3198 mmap.width, mmap.height)
3199
3200 if (mmap.frame >= cam->nbuffers) {
3201 DBG(4, "Invalid frame number (%u). "
3202 "VIDIOCMCAPTURE failed", mmap.frame)
3203 return -EINVAL;
3204 }
3205
3206 if (mmap.format!=cam->picture.palette &&
3207 (cam->force_palette || !w9968cf_vpp)) {
3208 DBG(4, "Palette %s rejected: only %s is allowed",
3209 symbolic(v4l1_plist, mmap.format),
3210 symbolic(v4l1_plist, cam->picture.palette))
3211 return -EINVAL;
3212 }
3213
3214 if (!w9968cf_valid_palette(mmap.format)) {
3215 DBG(4, "Palette %s not supported. "
3216 "VIDIOCMCAPTURE failed",
3217 symbolic(v4l1_plist, mmap.format))
3218 return -EINVAL;
3219 }
3220
3221 if (!cam->force_palette) {
3222 if (cam->decompression == 0) {
3223 if (w9968cf_need_decompression(mmap.format)) {
3224 DBG(4, "Decompression disabled: palette %s is not "
3225 "allowed. VIDIOCSPICT failed",
3226 symbolic(v4l1_plist, mmap.format))
3227 return -EINVAL;
3228 }
3229 } else if (cam->decompression == 1) {
3230 if (!w9968cf_need_decompression(mmap.format)) {
3231 DBG(4, "Decompression forced: palette %s is not "
3232 "allowed. VIDIOCSPICT failed",
3233 symbolic(v4l1_plist, mmap.format))
3234 return -EINVAL;
3235 }
3236 }
3237 }
3238
3239 if ((err = w9968cf_adjust_window_size(cam, (u16*)&mmap.width,
3240 (u16*)&mmap.height))) {
3241 DBG(4, "Resolution not supported (%dx%d). "
3242 "VIDIOCMCAPTURE failed",
3243 mmap.width, mmap.height)
3244 return err;
3245 }
3246
3247 fr = &cam->frame[mmap.frame];
3248
3249 if (mmap.width != cam->window.width ||
3250 mmap.height != cam->window.height ||
3251 mmap.format != cam->picture.palette) {
3252
3253 struct video_window win;
3254 struct video_picture pict;
3255
3256 if(*cam->requested_frame
3257 || cam->frame_current->queued) {
3258 DBG(6, "VIDIOCMCAPTURE. Change settings for "
3259 "frame #%u: %dx%d, format %s. Wait...",
3260 mmap.frame, mmap.width, mmap.height,
3261 symbolic(v4l1_plist, mmap.format))
3262 err = wait_event_interruptible
3263 ( cam->wait_queue,
3264 cam->disconnected ||
3265 (!*cam->requested_frame &&
3266 !cam->frame_current->queued) );
3267 if (err)
3268 return err;
3269 if (cam->disconnected)
3270 return -ENODEV;
3271 }
3272
3273 memcpy(&win, &cam->window, sizeof(win));
3274 memcpy(&pict, &cam->picture, sizeof(pict));
3275 win.width = mmap.width;
3276 win.height = mmap.height;
3277 pict.palette = mmap.format;
3278
3279 if (w9968cf_stop_transfer(cam))
3280 goto ioctl_fail;
3281
3282 /* This before set_window */
3283 if (w9968cf_set_picture(cam, pict))
3284 goto ioctl_fail;
3285
3286 if (w9968cf_set_window(cam, win))
3287 goto ioctl_fail;
3288
3289 if (w9968cf_start_transfer(cam))
3290 goto ioctl_fail;
3291
3292 } else if (fr->queued) {
3293
3294 DBG(6, "Wait until frame #%u is free", mmap.frame)
3295
3296 err = wait_event_interruptible(cam->wait_queue,
3297 cam->disconnected ||
3298 (!fr->queued));
3299 if (err)
3300 return err;
3301 if (cam->disconnected)
3302 return -ENODEV;
3303 }
3304
3305 w9968cf_push_frame(cam, mmap.frame);
3306 DBG(5, "VIDIOCMCAPTURE(%u): successfully called", mmap.frame)
3307 return 0;
3308 }
3309
3310 case VIDIOCSYNC: /* wait until the capture of a frame is finished */
3311 {
3312 unsigned int f_num;
3313 struct w9968cf_frame_t* fr;
3314 int err = 0;
3315
3316 if (copy_from_user(&f_num, arg, sizeof(f_num)))
3317 return -EFAULT;
3318
3319 if (f_num >= cam->nbuffers) {
3320 DBG(4, "Invalid frame number (%u). "
3321 "VIDIOCMCAPTURE failed", f_num)
3322 return -EINVAL;
3323 }
3324
3325 DBG(6, "VIDIOCSYNC called for frame #%u", f_num)
3326
3327 fr = &cam->frame[f_num];
3328
3329 switch (fr->status) {
3330 case F_UNUSED:
3331 if (!fr->queued) {
3332 DBG(4, "VIDIOSYNC: Frame #%u not requested!",
3333 f_num)
3334 return -EFAULT;
3335 }
3336 case F_ERROR:
3337 case F_GRABBING:
3338 err = wait_event_interruptible(cam->wait_queue,
3339 (fr->status == F_READY)
3340 || cam->disconnected);
3341 if (err)
3342 return err;
3343 if (cam->disconnected)
3344 return -ENODEV;
3345 break;
3346 case F_READY:
3347 break;
3348 }
3349
3350 if (w9968cf_vpp)
3351 w9968cf_postprocess_frame(cam, fr);
3352
3353 fr->status = F_UNUSED;
3354
3355 DBG(5, "VIDIOCSYNC(%u) successfully called", f_num)
3356 return 0;
3357 }
3358
3359 case VIDIOCGUNIT:/* report the unit numbers of the associated devices*/
3360 {
3361 struct video_unit unit = {
3362 .video = cam->v4ldev->minor,
3363 .vbi = VIDEO_NO_UNIT,
3364 .radio = VIDEO_NO_UNIT,
3365 .audio = VIDEO_NO_UNIT,
3366 .teletext = VIDEO_NO_UNIT,
3367 };
3368
3369 if (copy_to_user(arg, &unit, sizeof(unit)))
3370 return -EFAULT;
3371
3372 DBG(5, "VIDIOCGUNIT successfully called")
3373 return 0;
3374 }
3375
3376 case VIDIOCKEY:
3377 return 0;
3378
3379 case VIDIOCGFBUF:
3380 {
3381 if (clear_user(arg, sizeof(struct video_buffer)))
3382 return -EFAULT;
3383
3384 DBG(5, "VIDIOCGFBUF successfully called")
3385 return 0;
3386 }
3387
3388 case VIDIOCGTUNER:
3389 {
3390 struct video_tuner tuner;
3391 if (copy_from_user(&tuner, arg, sizeof(tuner)))
3392 return -EFAULT;
3393
3394 if (tuner.tuner != 0)
3395 return -EINVAL;
3396
3397 strcpy(tuner.name, "no_tuner");
3398 tuner.rangelow = 0;
3399 tuner.rangehigh = 0;
3400 tuner.flags = VIDEO_TUNER_NORM;
3401 tuner.mode = VIDEO_MODE_AUTO;
3402 tuner.signal = 0xffff;
3403
3404 if (copy_to_user(arg, &tuner, sizeof(tuner)))
3405 return -EFAULT;
3406
3407 DBG(5, "VIDIOCGTUNER successfully called")
3408 return 0;
3409 }
3410
3411 case VIDIOCSTUNER:
3412 {
3413 struct video_tuner tuner;
3414 if (copy_from_user(&tuner, arg, sizeof(tuner)))
3415 return -EFAULT;
3416
3417 if (tuner.tuner != 0)
3418 return -EINVAL;
3419
3420 if (tuner.mode != VIDEO_MODE_AUTO)
3421 return -EINVAL;
3422
3423 DBG(5, "VIDIOCSTUNER successfully called")
3424 return 0;
3425 }
3426
3427 case VIDIOCSFBUF:
3428 case VIDIOCCAPTURE:
3429 case VIDIOCGFREQ:
3430 case VIDIOCSFREQ:
3431 case VIDIOCGAUDIO:
3432 case VIDIOCSAUDIO:
3433 case VIDIOCSPLAYMODE:
3434 case VIDIOCSWRITEMODE:
3435 case VIDIOCGPLAYINFO:
3436 case VIDIOCSMICROCODE:
3437 case VIDIOCGVBIFMT:
3438 case VIDIOCSVBIFMT:
3439 DBG(4, "Unsupported V4L1 IOCtl: VIDIOC%s "
3440 "(type 0x%01X, "
3441 "n. 0x%01X, "
3442 "dir. 0x%01X, "
3443 "size 0x%02X)",
3444 V4L1_IOCTL(cmd),
3445 _IOC_TYPE(cmd),_IOC_NR(cmd),_IOC_DIR(cmd),_IOC_SIZE(cmd))
3446
3447 return -EINVAL;
3448
3449 default:
3450 DBG(4, "Invalid V4L1 IOCtl: VIDIOC%s "
3451 "type 0x%01X, "
3452 "n. 0x%01X, "
3453 "dir. 0x%01X, "
3454 "size 0x%02X",
3455 V4L1_IOCTL(cmd),
3456 _IOC_TYPE(cmd),_IOC_NR(cmd),_IOC_DIR(cmd),_IOC_SIZE(cmd))
3457
3458 return -ENOIOCTLCMD;
3459
3460 } /* end of switch */
3461
3462ioctl_fail:
3463 cam->misconfigured = 1;
3464 DBG(1, "VIDIOC%s failed because of hardware problems. "
3465 "To use the camera, close and open it again.", V4L1_IOCTL(cmd))
3466 return -EFAULT;
3467}
3468
3469
3470static struct file_operations w9968cf_fops = {
3471 .owner = THIS_MODULE,
3472 .open = w9968cf_open,
3473 .release = w9968cf_release,
3474 .read = w9968cf_read,
3475 .ioctl = w9968cf_ioctl,
3476 .compat_ioctl = v4l_compat_ioctl32,
3477 .mmap = w9968cf_mmap,
3478 .llseek = no_llseek,
3479};
3480
3481
3482
3483/****************************************************************************
3484 * USB probe and V4L registration, disconnect and id_table[] definition *
3485 ****************************************************************************/
3486
3487static int
3488w9968cf_usb_probe(struct usb_interface* intf, const struct usb_device_id* id)
3489{
3490 struct usb_device *udev = interface_to_usbdev(intf);
3491 struct w9968cf_device* cam;
3492 int err = 0;
3493 enum w9968cf_model_id mod_id;
3494 struct list_head* ptr;
3495 u8 sc = 0; /* number of simultaneous cameras */
3496 static unsigned short dev_nr = 0; /* we are handling device number n */
3497
3498 if (le16_to_cpu(udev->descriptor.idVendor) == winbond_id_table[0].idVendor &&
3499 le16_to_cpu(udev->descriptor.idProduct) == winbond_id_table[0].idProduct)
3500 mod_id = W9968CF_MOD_CLVBWGP; /* see camlist[] table */
3501 else if (le16_to_cpu(udev->descriptor.idVendor) == winbond_id_table[1].idVendor &&
3502 le16_to_cpu(udev->descriptor.idProduct) == winbond_id_table[1].idProduct)
3503 mod_id = W9968CF_MOD_GENERIC; /* see camlist[] table */
3504 else
3505 return -ENODEV;
3506
3507 cam = (struct w9968cf_device*)
3508 kzalloc(sizeof(struct w9968cf_device), GFP_KERNEL);
3509 if (!cam)
3510 return -ENOMEM;
3511
3512 mutex_init(&cam->dev_mutex);
3513 mutex_lock(&cam->dev_mutex);
3514
3515 cam->usbdev = udev;
3516 /* NOTE: a local copy is used to avoid possible race conditions */
3517 memcpy(&cam->dev, &udev->dev, sizeof(struct device));
3518
3519 DBG(2, "%s detected", symbolic(camlist, mod_id))
3520
3521 if (simcams > W9968CF_MAX_DEVICES)
3522 simcams = W9968CF_SIMCAMS;
3523
3524 /* How many cameras are connected ? */
3525 mutex_lock(&w9968cf_devlist_mutex);
3526 list_for_each(ptr, &w9968cf_dev_list)
3527 sc++;
3528 mutex_unlock(&w9968cf_devlist_mutex);
3529
3530 if (sc >= simcams) {
3531 DBG(2, "Device rejected: too many connected cameras "
3532 "(max. %u)", simcams)
3533 err = -EPERM;
3534 goto fail;
3535 }
3536
3537
3538 /* Allocate 2 bytes of memory for camera control USB transfers */
3539 if (!(cam->control_buffer = kzalloc(2, GFP_KERNEL))) {
3540 DBG(1,"Couldn't allocate memory for camera control transfers")
3541 err = -ENOMEM;
3542 goto fail;
3543 }
3544
3545 /* Allocate 8 bytes of memory for USB data transfers to the FSB */
3546 if (!(cam->data_buffer = kzalloc(8, GFP_KERNEL))) {
3547 DBG(1, "Couldn't allocate memory for data "
3548 "transfers to the FSB")
3549 err = -ENOMEM;
3550 goto fail;
3551 }
3552
3553 /* Register the V4L device */
3554 cam->v4ldev = video_device_alloc();
3555 if (!cam->v4ldev) {
3556 DBG(1, "Could not allocate memory for a V4L structure")
3557 err = -ENOMEM;
3558 goto fail;
3559 }
3560
3561 strcpy(cam->v4ldev->name, symbolic(camlist, mod_id));
3562 cam->v4ldev->owner = THIS_MODULE;
3563 cam->v4ldev->type = VID_TYPE_CAPTURE | VID_TYPE_SCALES;
3564 cam->v4ldev->hardware = VID_HARDWARE_W9968CF;
3565 cam->v4ldev->fops = &w9968cf_fops;
3566 cam->v4ldev->minor = video_nr[dev_nr];
3567 cam->v4ldev->release = video_device_release;
3568 video_set_drvdata(cam->v4ldev, cam);
3569 cam->v4ldev->dev = &cam->dev;
3570
3571 err = video_register_device(cam->v4ldev, VFL_TYPE_GRABBER,
3572 video_nr[dev_nr]);
3573 if (err) {
3574 DBG(1, "V4L device registration failed")
3575 if (err == -ENFILE && video_nr[dev_nr] == -1)
3576 DBG(2, "Couldn't find a free /dev/videoX node")
3577 video_nr[dev_nr] = -1;
3578 dev_nr = (dev_nr < W9968CF_MAX_DEVICES-1) ? dev_nr+1 : 0;
3579 goto fail;
3580 }
3581
3582 DBG(2, "V4L device registered as /dev/video%d", cam->v4ldev->minor)
3583
3584 /* Set some basic constants */
3585 w9968cf_configure_camera(cam, udev, mod_id, dev_nr);
3586
3587 /* Add a new entry into the list of V4L registered devices */
3588 mutex_lock(&w9968cf_devlist_mutex);
3589 list_add(&cam->v4llist, &w9968cf_dev_list);
3590 mutex_unlock(&w9968cf_devlist_mutex);
3591 dev_nr = (dev_nr < W9968CF_MAX_DEVICES-1) ? dev_nr+1 : 0;
3592
3593 w9968cf_turn_on_led(cam);
3594
3595 w9968cf_i2c_init(cam);
3596
3597 usb_set_intfdata(intf, cam);
3598 mutex_unlock(&cam->dev_mutex);
3599 return 0;
3600
3601fail: /* Free unused memory */
3602 kfree(cam->control_buffer);
3603 kfree(cam->data_buffer);
3604 if (cam->v4ldev)
3605 video_device_release(cam->v4ldev);
3606 mutex_unlock(&cam->dev_mutex);
3607 kfree(cam);
3608 return err;
3609}
3610
3611
3612static void w9968cf_usb_disconnect(struct usb_interface* intf)
3613{
3614 struct w9968cf_device* cam =
3615 (struct w9968cf_device*)usb_get_intfdata(intf);
3616
3617 down_write(&w9968cf_disconnect);
3618
3619 if (cam) {
3620 /* Prevent concurrent accesses to data */
3621 mutex_lock(&cam->dev_mutex);
3622
3623 cam->disconnected = 1;
3624
3625 DBG(2, "Disconnecting %s...", symbolic(camlist, cam->id))
3626
3627 wake_up_interruptible_all(&cam->open);
3628
3629 if (cam->users) {
3630 DBG(2, "The device is open (/dev/video%d)! "
3631 "Process name: %s. Deregistration and memory "
3632 "deallocation are deferred on close.",
3633 cam->v4ldev->minor, cam->command)
3634 cam->misconfigured = 1;
3635 w9968cf_stop_transfer(cam);
3636 wake_up_interruptible(&cam->wait_queue);
3637 } else
3638 w9968cf_release_resources(cam);
3639
3640 mutex_unlock(&cam->dev_mutex);
3641
3642 if (!cam->users)
3643 kfree(cam);
3644 }
3645
3646 up_write(&w9968cf_disconnect);
3647}
3648
3649
3650static struct usb_driver w9968cf_usb_driver = {
3651 .name = "w9968cf",
3652 .id_table = winbond_id_table,
3653 .probe = w9968cf_usb_probe,
3654 .disconnect = w9968cf_usb_disconnect,
3655};
3656
3657
3658
3659/****************************************************************************
3660 * Module init, exit and intermodule communication *
3661 ****************************************************************************/
3662
3663static int __init w9968cf_module_init(void)
3664{
3665 int err;
3666
3667 KDBG(2, W9968CF_MODULE_NAME" "W9968CF_MODULE_VERSION)
3668 KDBG(3, W9968CF_MODULE_AUTHOR)
3669
3670 if (ovmod_load)
3671 request_module("ovcamchip");
3672
3673 if ((err = usb_register(&w9968cf_usb_driver)))
3674 return err;
3675
3676 return 0;
3677}
3678
3679
3680static void __exit w9968cf_module_exit(void)
3681{
3682 /* w9968cf_usb_disconnect() will be called */
3683 usb_deregister(&w9968cf_usb_driver);
3684
3685 KDBG(2, W9968CF_MODULE_NAME" deregistered")
3686}
3687
3688
3689module_init(w9968cf_module_init);
3690module_exit(w9968cf_module_exit);
3691
diff --git a/drivers/media/video/w9968cf.h b/drivers/media/video/w9968cf.h
new file mode 100644
index 000000000000..a87be719a281
--- /dev/null
+++ b/drivers/media/video/w9968cf.h
@@ -0,0 +1,330 @@
1/***************************************************************************
2 * Video4Linux driver for W996[87]CF JPEG USB Dual Mode Camera Chip. *
3 * *
4 * Copyright (C) 2002-2004 by Luca Risolia <luca.risolia@studio.unibo.it> *
5 * *
6 * This program is free software; you can redistribute it and/or modify *
7 * it under the terms of the GNU General Public License as published by *
8 * the Free Software Foundation; either version 2 of the License, or *
9 * (at your option) any later version. *
10 * *
11 * This program is distributed in the hope that it will be useful, *
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14 * GNU General Public License for more details. *
15 * *
16 * You should have received a copy of the GNU General Public License *
17 * along with this program; if not, write to the Free Software *
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
19 ***************************************************************************/
20
21#ifndef _W9968CF_H_
22#define _W9968CF_H_
23
24#include <linux/videodev.h>
25#include <linux/usb.h>
26#include <linux/i2c.h>
27#include <linux/device.h>
28#include <linux/spinlock.h>
29#include <linux/list.h>
30#include <linux/wait.h>
31#include <linux/config.h>
32#include <linux/param.h>
33#include <linux/types.h>
34#include <linux/rwsem.h>
35#include <linux/mutex.h>
36
37#include <media/ovcamchip.h>
38
39#include "w9968cf_vpp.h"
40
41
42/****************************************************************************
43 * Default values *
44 ****************************************************************************/
45
46#define W9968CF_OVMOD_LOAD 1 /* automatic 'ovcamchip' module loading */
47#define W9968CF_VPPMOD_LOAD 1 /* automatic 'w9968cf-vpp' module loading */
48
49/* Comment/uncomment the following line to enable/disable debugging messages */
50#define W9968CF_DEBUG
51
52/* These have effect only if W9968CF_DEBUG is defined */
53#define W9968CF_DEBUG_LEVEL 2 /* from 0 to 6. 0 for no debug informations */
54#define W9968CF_SPECIFIC_DEBUG 0 /* 0 or 1 */
55
56#define W9968CF_MAX_DEVICES 32
57#define W9968CF_SIMCAMS W9968CF_MAX_DEVICES /* simultaneous cameras */
58
59#define W9968CF_MAX_BUFFERS 32
60#define W9968CF_BUFFERS 2 /* n. of frame buffers from 2 to MAX_BUFFERS */
61
62/* Maximum data payload sizes in bytes for alternate settings */
63static const u16 wMaxPacketSize[] = {1023, 959, 895, 831, 767, 703, 639, 575,
64 511, 447, 383, 319, 255, 191, 127, 63};
65#define W9968CF_PACKET_SIZE 1023 /* according to wMaxPacketSizes[] */
66#define W9968CF_MIN_PACKET_SIZE 63 /* minimum value */
67#define W9968CF_ISO_PACKETS 5 /* n.of packets for isochronous transfers */
68#define W9968CF_USB_CTRL_TIMEOUT 1000 /* timeout (ms) for usb control commands */
69#define W9968CF_URBS 2 /* n. of scheduled URBs for ISO transfer */
70
71#define W9968CF_I2C_BUS_DELAY 4 /* delay in us for I2C bit r/w operations */
72#define W9968CF_I2C_RW_RETRIES 15 /* number of max I2C r/w retries */
73
74/* Available video formats */
75struct w9968cf_format {
76 const u16 palette;
77 const u16 depth;
78 const u8 compression;
79};
80
81static const struct w9968cf_format w9968cf_formatlist[] = {
82 { VIDEO_PALETTE_UYVY, 16, 0 }, /* original video */
83 { VIDEO_PALETTE_YUV422P, 16, 1 }, /* with JPEG compression */
84 { VIDEO_PALETTE_YUV420P, 12, 1 }, /* with JPEG compression */
85 { VIDEO_PALETTE_YUV420, 12, 1 }, /* same as YUV420P */
86 { VIDEO_PALETTE_YUYV, 16, 0 }, /* software conversion */
87 { VIDEO_PALETTE_YUV422, 16, 0 }, /* software conversion */
88 { VIDEO_PALETTE_GREY, 8, 0 }, /* software conversion */
89 { VIDEO_PALETTE_RGB555, 16, 0 }, /* software conversion */
90 { VIDEO_PALETTE_RGB565, 16, 0 }, /* software conversion */
91 { VIDEO_PALETTE_RGB24, 24, 0 }, /* software conversion */
92 { VIDEO_PALETTE_RGB32, 32, 0 }, /* software conversion */
93 { 0, 0, 0 } /* 0 is a terminating entry */
94};
95
96#define W9968CF_DECOMPRESSION 2 /* decomp:0=disable,1=force,2=any formats */
97#define W9968CF_PALETTE_DECOMP_OFF VIDEO_PALETTE_UYVY /* when decomp=0 */
98#define W9968CF_PALETTE_DECOMP_FORCE VIDEO_PALETTE_YUV420P /* when decomp=1 */
99#define W9968CF_PALETTE_DECOMP_ON VIDEO_PALETTE_UYVY /* when decomp=2 */
100
101#define W9968CF_FORCE_RGB 0 /* read RGB instead of BGR, yes=1/no=0 */
102
103#define W9968CF_MAX_WIDTH 800 /* Has effect if up-scaling is on */
104#define W9968CF_MAX_HEIGHT 600 /* Has effect if up-scaling is on */
105#define W9968CF_WIDTH 320 /* from 128 to 352, multiple of 16 */
106#define W9968CF_HEIGHT 240 /* from 96 to 288, multiple of 16 */
107
108#define W9968CF_CLAMPING 0 /* 0 disable, 1 enable video data clamping */
109#define W9968CF_FILTER_TYPE 0 /* 0 disable 1 (1-2-1), 2 (2-3-6-3-2) */
110#define W9968CF_DOUBLE_BUFFER 1 /* 0 disable, 1 enable double buffer */
111#define W9968CF_LARGEVIEW 1 /* 0 disable, 1 enable */
112#define W9968CF_UPSCALING 0 /* 0 disable, 1 enable */
113
114#define W9968CF_MONOCHROME 0 /* 0 not monochrome, 1 monochrome sensor */
115#define W9968CF_BRIGHTNESS 31000 /* from 0 to 65535 */
116#define W9968CF_HUE 32768 /* from 0 to 65535 */
117#define W9968CF_COLOUR 32768 /* from 0 to 65535 */
118#define W9968CF_CONTRAST 50000 /* from 0 to 65535 */
119#define W9968CF_WHITENESS 32768 /* from 0 to 65535 */
120
121#define W9968CF_AUTOBRIGHT 0 /* 0 disable, 1 enable automatic brightness */
122#define W9968CF_AUTOEXP 1 /* 0 disable, 1 enable automatic exposure */
123#define W9968CF_LIGHTFREQ 50 /* light frequency. 50Hz (Europe) or 60Hz */
124#define W9968CF_BANDINGFILTER 0 /* 0 disable, 1 enable banding filter */
125#define W9968CF_BACKLIGHT 0 /* 0 or 1, 1=object is lit from behind */
126#define W9968CF_MIRROR 0 /* 0 or 1 [don't] reverse image horizontally*/
127
128#define W9968CF_CLOCKDIV -1 /* -1 = automatic clock divisor */
129#define W9968CF_DEF_CLOCKDIVISOR 0 /* default sensor clock divisor value */
130
131
132/****************************************************************************
133 * Globals *
134 ****************************************************************************/
135
136#define W9968CF_MODULE_NAME "V4L driver for W996[87]CF JPEG USB " \
137 "Dual Mode Camera Chip"
138#define W9968CF_MODULE_VERSION "1:1.33-basic"
139#define W9968CF_MODULE_AUTHOR "(C) 2002-2004 Luca Risolia"
140#define W9968CF_AUTHOR_EMAIL "<luca.risolia@studio.unibo.it>"
141#define W9968CF_MODULE_LICENSE "GPL"
142
143static const struct usb_device_id winbond_id_table[] = {
144 {
145 /* Creative Labs Video Blaster WebCam Go Plus */
146 USB_DEVICE(0x041e, 0x4003),
147 .driver_info = (unsigned long)"w9968cf",
148 },
149 {
150 /* Generic W996[87]CF JPEG USB Dual Mode Camera */
151 USB_DEVICE(0x1046, 0x9967),
152 .driver_info = (unsigned long)"w9968cf",
153 },
154 { } /* terminating entry */
155};
156
157/* W996[87]CF camera models, internal ids: */
158enum w9968cf_model_id {
159 W9968CF_MOD_GENERIC = 1, /* Generic W996[87]CF based device */
160 W9968CF_MOD_CLVBWGP = 11,/*Creative Labs Video Blaster WebCam Go Plus*/
161 W9968CF_MOD_ADPVDMA = 21, /* Aroma Digi Pen VGA Dual Mode ADG-5000 */
162 W9986CF_MOD_AAU = 31, /* AVerMedia AVerTV USB */
163 W9968CF_MOD_CLVBWG = 34, /* Creative Labs Video Blaster WebCam Go */
164 W9968CF_MOD_LL = 37, /* Lebon LDC-035A */
165 W9968CF_MOD_EEEMC = 40, /* Ezonics EZ-802 EZMega Cam */
166 W9968CF_MOD_OOE = 42, /* OmniVision OV8610-EDE */
167 W9968CF_MOD_ODPVDMPC = 43,/* OPCOM Digi Pen VGA Dual Mode Pen Camera */
168 W9968CF_MOD_PDPII = 46, /* Pretec Digi Pen-II */
169 W9968CF_MOD_PDP480 = 49, /* Pretec DigiPen-480 */
170};
171
172enum w9968cf_frame_status {
173 F_READY, /* finished grabbing & ready to be read/synced */
174 F_GRABBING, /* in the process of being grabbed into */
175 F_ERROR, /* something bad happened while processing */
176 F_UNUSED /* unused (no VIDIOCMCAPTURE) */
177};
178
179struct w9968cf_frame_t {
180 void* buffer;
181 unsigned long size;
182 u32 length;
183 int number;
184 enum w9968cf_frame_status status;
185 struct w9968cf_frame_t* next;
186 u8 queued;
187};
188
189enum w9968cf_vpp_flag {
190 VPP_NONE = 0x00,
191 VPP_UPSCALE = 0x01,
192 VPP_SWAP_YUV_BYTES = 0x02,
193 VPP_DECOMPRESSION = 0x04,
194 VPP_UYVY_TO_RGBX = 0x08,
195};
196
197/* Main device driver structure */
198struct w9968cf_device {
199 struct device dev; /* device structure */
200
201 enum w9968cf_model_id id; /* private device identifier */
202
203 struct video_device* v4ldev; /* -> V4L structure */
204 struct list_head v4llist; /* entry of the list of V4L cameras */
205
206 struct usb_device* usbdev; /* -> main USB structure */
207 struct urb* urb[W9968CF_URBS]; /* -> USB request block structs */
208 void* transfer_buffer[W9968CF_URBS]; /* -> ISO transfer buffers */
209 u16* control_buffer; /* -> buffer for control req.*/
210 u16* data_buffer; /* -> data to send to the FSB */
211
212 struct w9968cf_frame_t frame[W9968CF_MAX_BUFFERS];
213 struct w9968cf_frame_t frame_tmp; /* temporary frame */
214 struct w9968cf_frame_t frame_vpp; /* helper frame.*/
215 struct w9968cf_frame_t* frame_current; /* -> frame being grabbed */
216 struct w9968cf_frame_t* requested_frame[W9968CF_MAX_BUFFERS];
217
218 u8 max_buffers, /* number of requested buffers */
219 force_palette, /* yes=1/no=0 */
220 force_rgb, /* read RGB instead of BGR, yes=1, no=0 */
221 double_buffer, /* hardware double buffering yes=1/no=0 */
222 clamping, /* video data clamping yes=1/no=0 */
223 filter_type, /* 0=disabled, 1=3 tap, 2=5 tap filter */
224 capture, /* 0=disabled, 1=enabled */
225 largeview, /* 0=disabled, 1=enabled */
226 decompression, /* 0=disabled, 1=forced, 2=allowed */
227 upscaling; /* software image scaling, 0=enabled, 1=disabled */
228
229 struct video_picture picture; /* current picture settings */
230 struct video_window window; /* current window settings */
231
232 u16 hw_depth, /* depth (used by the chip) */
233 hw_palette, /* palette (used by the chip) */
234 hw_width, /* width (used by the chip) */
235 hw_height, /* height (used by the chip) */
236 hs_polarity, /* 0=negative sync pulse, 1=positive sync pulse */
237 vs_polarity, /* 0=negative sync pulse, 1=positive sync pulse */
238 start_cropx, /* pixels from HS inactive edge to 1st cropped pixel*/
239 start_cropy; /* pixels from VS inactive edge to 1st cropped pixel*/
240
241 enum w9968cf_vpp_flag vpp_flag; /* post-processing routines in use */
242
243 u8 nbuffers, /* number of allocated frame buffers */
244 altsetting, /* camera alternate setting */
245 disconnected, /* flag: yes=1, no=0 */
246 misconfigured, /* flag: yes=1, no=0 */
247 users, /* flag: number of users holding the device */
248 streaming; /* flag: yes=1, no=0 */
249
250 u8 sensor_initialized; /* flag: yes=1, no=0 */
251
252 /* Determined by the image sensor type: */
253 int sensor, /* type of image sensor chip (CC_*) */
254 monochrome; /* image sensor is (probably) monochrome */
255 u16 maxwidth, /* maximum width supported by the image sensor */
256 maxheight, /* maximum height supported by the image sensor */
257 minwidth, /* minimum width supported by the image sensor */
258 minheight; /* minimum height supported by the image sensor */
259 u8 auto_brt, /* auto brightness enabled flag */
260 auto_exp, /* auto exposure enabled flag */
261 backlight, /* backlight exposure algorithm flag */
262 mirror, /* image is reversed horizontally */
263 lightfreq, /* power (lighting) frequency */
264 bandfilt; /* banding filter enabled flag */
265 s8 clockdiv; /* clock divisor */
266
267 /* I2C interface to kernel */
268 struct i2c_adapter i2c_adapter;
269 struct i2c_client* sensor_client;
270
271 /* Locks */
272 struct mutex dev_mutex, /* for probe, disconnect,open and close */
273 fileop_mutex; /* for read and ioctl */
274 spinlock_t urb_lock, /* for submit_urb() and unlink_urb() */
275 flist_lock; /* for requested frame list accesses */
276 wait_queue_head_t open, wait_queue;
277
278 char command[16]; /* name of the program holding the device */
279};
280
281
282/****************************************************************************
283 * Macros for debugging *
284 ****************************************************************************/
285
286#undef DBG
287#undef KDBG
288#ifdef W9968CF_DEBUG
289/* For device specific debugging messages */
290# define DBG(level, fmt, args...) \
291{ \
292 if ( ((specific_debug) && (debug == (level))) || \
293 ((!specific_debug) && (debug >= (level))) ) { \
294 if ((level) == 1) \
295 dev_err(&cam->dev, fmt "\n", ## args); \
296 else if ((level) == 2 || (level) == 3) \
297 dev_info(&cam->dev, fmt "\n", ## args); \
298 else if ((level) == 4) \
299 dev_warn(&cam->dev, fmt "\n", ## args); \
300 else if ((level) >= 5) \
301 dev_info(&cam->dev, "[%s:%d] " fmt "\n", \
302 __FUNCTION__, __LINE__ , ## args); \
303 } \
304}
305/* For generic kernel (not device specific) messages */
306# define KDBG(level, fmt, args...) \
307{ \
308 if ( ((specific_debug) && (debug == (level))) || \
309 ((!specific_debug) && (debug >= (level))) ) { \
310 if ((level) >= 1 && (level) <= 4) \
311 pr_info("w9968cf: " fmt "\n", ## args); \
312 else if ((level) >= 5) \
313 pr_debug("w9968cf: [%s:%d] " fmt "\n", __FUNCTION__, \
314 __LINE__ , ## args); \
315 } \
316}
317#else
318 /* Not debugging: nothing */
319# define DBG(level, fmt, args...) do {;} while(0);
320# define KDBG(level, fmt, args...) do {;} while(0);
321#endif
322
323#undef PDBG
324#define PDBG(fmt, args...) \
325dev_info(&cam->dev, "[%s:%d] " fmt "\n", __FUNCTION__, __LINE__ , ## args);
326
327#undef PDBGG
328#define PDBGG(fmt, args...) do {;} while(0); /* nothing: it's a placeholder */
329
330#endif /* _W9968CF_H_ */
diff --git a/drivers/media/video/w9968cf_decoder.h b/drivers/media/video/w9968cf_decoder.h
new file mode 100644
index 000000000000..31faccbe8f03
--- /dev/null
+++ b/drivers/media/video/w9968cf_decoder.h
@@ -0,0 +1,86 @@
1/***************************************************************************
2 * Video decoder for the W996[87]CF driver for Linux. *
3 * *
4 * Copyright (C) 2003 2004 by Luca Risolia <luca.risolia@studio.unibo.it> *
5 * *
6 * This program is free software; you can redistribute it and/or modify *
7 * it under the terms of the GNU General Public License as published by *
8 * the Free Software Foundation; either version 2 of the License, or *
9 * (at your option) any later version. *
10 * *
11 * This program is distributed in the hope that it will be useful, *
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14 * GNU General Public License for more details. *
15 * *
16 * You should have received a copy of the GNU General Public License *
17 * along with this program; if not, write to the Free Software *
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
19 ***************************************************************************/
20
21#ifndef _W9968CF_DECODER_H_
22#define _W9968CF_DECODER_H_
23
24/* Comment/uncomment this for high/low quality of compressed video */
25#define W9968CF_DEC_FAST_LOWQUALITY_VIDEO
26
27#ifdef W9968CF_DEC_FAST_LOWQUALITY_VIDEO
28static const unsigned char Y_QUANTABLE[64] = {
29 16, 11, 10, 16, 24, 40, 51, 61,
30 12, 12, 14, 19, 26, 58, 60, 55,
31 14, 13, 16, 24, 40, 57, 69, 56,
32 14, 17, 22, 29, 51, 87, 80, 62,
33 18, 22, 37, 56, 68, 109, 103, 77,
34 24, 35, 55, 64, 81, 104, 113, 92,
35 49, 64, 78, 87, 103, 121, 120, 101,
36 72, 92, 95, 98, 112, 100, 103, 99
37};
38
39static const unsigned char UV_QUANTABLE[64] = {
40 17, 18, 24, 47, 99, 99, 99, 99,
41 18, 21, 26, 66, 99, 99, 99, 99,
42 24, 26, 56, 99, 99, 99, 99, 99,
43 47, 66, 99, 99, 99, 99, 99, 99,
44 99, 99, 99, 99, 99, 99, 99, 99,
45 99, 99, 99, 99, 99, 99, 99, 99,
46 99, 99, 99, 99, 99, 99, 99, 99,
47 99, 99, 99, 99, 99, 99, 99, 99
48};
49#else
50static const unsigned char Y_QUANTABLE[64] = {
51 8, 5, 5, 8, 12, 20, 25, 30,
52 6, 6, 7, 9, 13, 29, 30, 27,
53 7, 6, 8, 12, 20, 28, 34, 28,
54 7, 8, 11, 14, 25, 43, 40, 31,
55 9, 11, 18, 28, 34, 54, 51, 38,
56 12, 17, 27, 32, 40, 52, 56, 46,
57 24, 32, 39, 43, 51, 60, 60, 50,
58 36, 46, 47, 49, 56, 50, 51, 49
59};
60
61static const unsigned char UV_QUANTABLE[64] = {
62 8, 9, 12, 23, 49, 49, 49, 49,
63 9, 10, 13, 33, 49, 49, 49, 49,
64 12, 13, 28, 49, 49, 49, 49, 49,
65 23, 33, 49, 49, 49, 49, 49, 49,
66 49, 49, 49, 49, 49, 49, 49, 49,
67 49, 49, 49, 49, 49, 49, 49, 49,
68 49, 49, 49, 49, 49, 49, 49, 49,
69 49, 49, 49, 49, 49, 49, 49, 49
70};
71#endif
72
73#define W9968CF_DEC_ERR_CORRUPTED_DATA -1
74#define W9968CF_DEC_ERR_BUF_OVERFLOW -2
75#define W9968CF_DEC_ERR_NO_SOI -3
76#define W9968CF_DEC_ERR_NO_SOF0 -4
77#define W9968CF_DEC_ERR_NO_SOS -5
78#define W9968CF_DEC_ERR_NO_EOI -6
79
80extern void w9968cf_init_decoder(void);
81extern int w9968cf_check_headers(const unsigned char* Pin,
82 const unsigned long BUF_SIZE);
83extern int w9968cf_decode(const char* Pin, const unsigned long BUF_SIZE,
84 const unsigned W, const unsigned H, char* Pout);
85
86#endif /* _W9968CF_DECODER_H_ */
diff --git a/drivers/media/video/w9968cf_vpp.h b/drivers/media/video/w9968cf_vpp.h
new file mode 100644
index 000000000000..f3b91b782671
--- /dev/null
+++ b/drivers/media/video/w9968cf_vpp.h
@@ -0,0 +1,40 @@
1/***************************************************************************
2 * Interface for video post-processing functions for the W996[87]CF driver *
3 * for Linux. *
4 * *
5 * Copyright (C) 2002-2004 by Luca Risolia <luca.risolia@studio.unibo.it> *
6 * *
7 * This program is free software; you can redistribute it and/or modify *
8 * it under the terms of the GNU General Public License as published by *
9 * the Free Software Foundation; either version 2 of the License, or *
10 * (at your option) any later version. *
11 * *
12 * This program is distributed in the hope that it will be useful, *
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15 * GNU General Public License for more details. *
16 * *
17 * You should have received a copy of the GNU General Public License *
18 * along with this program; if not, write to the Free Software *
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
20 ***************************************************************************/
21
22#ifndef _W9968CF_VPP_H_
23#define _W9968CF_VPP_H_
24
25#include <linux/module.h>
26#include <asm/types.h>
27
28struct w9968cf_vpp_t {
29 struct module* owner;
30 int (*check_headers)(const unsigned char*, const unsigned long);
31 int (*decode)(const char*, const unsigned long, const unsigned,
32 const unsigned, char*);
33 void (*swap_yuvbytes)(void*, unsigned long);
34 void (*uyvy_to_rgbx)(u8*, unsigned long, u8*, u16, u8);
35 void (*scale_up)(u8*, u8*, u16, u16, u16, u16, u16);
36
37 u8 busy; /* read-only flag: module is/is not in use */
38};
39
40#endif /* _W9968CF_VPP_H_ */
diff --git a/drivers/media/video/zc0301/Makefile b/drivers/media/video/zc0301/Makefile
new file mode 100644
index 000000000000..d749199d8f06
--- /dev/null
+++ b/drivers/media/video/zc0301/Makefile
@@ -0,0 +1,3 @@
1zc0301-objs := zc0301_core.o zc0301_pas202bcb.o
2
3obj-$(CONFIG_USB_ZC0301) += zc0301.o
diff --git a/drivers/media/video/zc0301/zc0301.h b/drivers/media/video/zc0301/zc0301.h
new file mode 100644
index 000000000000..8e0655140e60
--- /dev/null
+++ b/drivers/media/video/zc0301/zc0301.h
@@ -0,0 +1,192 @@
1/***************************************************************************
2 * V4L2 driver for ZC0301 Image Processor and Control Chip *
3 * *
4 * Copyright (C) 2006 by Luca Risolia <luca.risolia@studio.unibo.it> *
5 * *
6 * This program is free software; you can redistribute it and/or modify *
7 * it under the terms of the GNU General Public License as published by *
8 * the Free Software Foundation; either version 2 of the License, or *
9 * (at your option) any later version. *
10 * *
11 * This program is distributed in the hope that it will be useful, *
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14 * GNU General Public License for more details. *
15 * *
16 * You should have received a copy of the GNU General Public License *
17 * along with this program; if not, write to the Free Software *
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
19 ***************************************************************************/
20
21#ifndef _ZC0301_H_
22#define _ZC0301_H_
23
24#include <linux/version.h>
25#include <linux/usb.h>
26#include <linux/videodev2.h>
27#include <media/v4l2-common.h>
28#include <linux/device.h>
29#include <linux/list.h>
30#include <linux/spinlock.h>
31#include <linux/time.h>
32#include <linux/wait.h>
33#include <linux/types.h>
34#include <linux/param.h>
35#include <linux/mutex.h>
36#include <linux/rwsem.h>
37#include <linux/stddef.h>
38#include <linux/string.h>
39
40#include "zc0301_sensor.h"
41
42/*****************************************************************************/
43
44#define ZC0301_DEBUG
45#define ZC0301_DEBUG_LEVEL 2
46#define ZC0301_MAX_DEVICES 64
47#define ZC0301_FORCE_MUNMAP 0
48#define ZC0301_MAX_FRAMES 32
49#define ZC0301_COMPRESSION_QUALITY 0
50#define ZC0301_URBS 2
51#define ZC0301_ISO_PACKETS 7
52#define ZC0301_ALTERNATE_SETTING 7
53#define ZC0301_URB_TIMEOUT msecs_to_jiffies(2 * ZC0301_ISO_PACKETS)
54#define ZC0301_CTRL_TIMEOUT 100
55#define ZC0301_FRAME_TIMEOUT 2
56
57/*****************************************************************************/
58
59ZC0301_ID_TABLE
60ZC0301_SENSOR_TABLE
61
62enum zc0301_frame_state {
63 F_UNUSED,
64 F_QUEUED,
65 F_GRABBING,
66 F_DONE,
67 F_ERROR,
68};
69
70struct zc0301_frame_t {
71 void* bufmem;
72 struct v4l2_buffer buf;
73 enum zc0301_frame_state state;
74 struct list_head frame;
75 unsigned long vma_use_count;
76};
77
78enum zc0301_dev_state {
79 DEV_INITIALIZED = 0x01,
80 DEV_DISCONNECTED = 0x02,
81 DEV_MISCONFIGURED = 0x04,
82};
83
84enum zc0301_io_method {
85 IO_NONE,
86 IO_READ,
87 IO_MMAP,
88};
89
90enum zc0301_stream_state {
91 STREAM_OFF,
92 STREAM_INTERRUPT,
93 STREAM_ON,
94};
95
96struct zc0301_module_param {
97 u8 force_munmap;
98 u16 frame_timeout;
99};
100
101static DECLARE_RWSEM(zc0301_disconnect);
102
103struct zc0301_device {
104 struct video_device* v4ldev;
105
106 struct zc0301_sensor sensor;
107
108 struct usb_device* usbdev;
109 struct urb* urb[ZC0301_URBS];
110 void* transfer_buffer[ZC0301_URBS];
111 u8* control_buffer;
112
113 struct zc0301_frame_t *frame_current, frame[ZC0301_MAX_FRAMES];
114 struct list_head inqueue, outqueue;
115 u32 frame_count, nbuffers, nreadbuffers;
116
117 enum zc0301_io_method io;
118 enum zc0301_stream_state stream;
119
120 struct v4l2_jpegcompression compression;
121
122 struct zc0301_module_param module_param;
123
124 enum zc0301_dev_state state;
125 u8 users;
126
127 struct mutex dev_mutex, fileop_mutex;
128 spinlock_t queue_lock;
129 wait_queue_head_t open, wait_frame, wait_stream;
130};
131
132/*****************************************************************************/
133
134struct zc0301_device*
135zc0301_match_id(struct zc0301_device* cam, const struct usb_device_id *id)
136{
137 return usb_match_id(usb_ifnum_to_if(cam->usbdev, 0), id) ? cam : NULL;
138}
139
140void
141zc0301_attach_sensor(struct zc0301_device* cam, struct zc0301_sensor* sensor)
142{
143 memcpy(&cam->sensor, sensor, sizeof(struct zc0301_sensor));
144}
145
146/*****************************************************************************/
147
148#undef DBG
149#undef KDBG
150#ifdef ZC0301_DEBUG
151# define DBG(level, fmt, args...) \
152do { \
153 if (debug >= (level)) { \
154 if ((level) == 1) \
155 dev_err(&cam->usbdev->dev, fmt "\n", ## args); \
156 else if ((level) == 2) \
157 dev_info(&cam->usbdev->dev, fmt "\n", ## args); \
158 else if ((level) >= 3) \
159 dev_info(&cam->usbdev->dev, "[%s:%d] " fmt "\n", \
160 __FUNCTION__, __LINE__ , ## args); \
161 } \
162} while (0)
163# define KDBG(level, fmt, args...) \
164do { \
165 if (debug >= (level)) { \
166 if ((level) == 1 || (level) == 2) \
167 pr_info("zc0301: " fmt "\n", ## args); \
168 else if ((level) == 3) \
169 pr_debug("zc0301: [%s:%d] " fmt "\n", __FUNCTION__, \
170 __LINE__ , ## args); \
171 } \
172} while (0)
173# define V4LDBG(level, name, cmd) \
174do { \
175 if (debug >= (level)) \
176 v4l_print_ioctl(name, cmd); \
177} while (0)
178#else
179# define DBG(level, fmt, args...) do {;} while(0)
180# define KDBG(level, fmt, args...) do {;} while(0)
181# define V4LDBG(level, name, cmd) do {;} while(0)
182#endif
183
184#undef PDBG
185#define PDBG(fmt, args...) \
186dev_info(&cam->usbdev->dev, "[%s:%d] " fmt "\n", \
187 __FUNCTION__, __LINE__ , ## args)
188
189#undef PDBGG
190#define PDBGG(fmt, args...) do {;} while(0) /* placeholder */
191
192#endif /* _ZC0301_H_ */
diff --git a/drivers/media/video/zc0301/zc0301_core.c b/drivers/media/video/zc0301/zc0301_core.c
new file mode 100644
index 000000000000..4036c6268bff
--- /dev/null
+++ b/drivers/media/video/zc0301/zc0301_core.c
@@ -0,0 +1,2055 @@
1/***************************************************************************
2 * Video4Linux2 driver for ZC0301 Image Processor and Control Chip *
3 * *
4 * Copyright (C) 2006 by Luca Risolia <luca.risolia@studio.unibo.it> *
5 * *
6 * Informations about the chip internals needed to enable the I2C protocol *
7 * have been taken from the documentation of the ZC030x Video4Linux1 *
8 * driver written by Andrew Birkett <andy@nobugs.org> *
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., 675 Mass Ave, Cambridge, MA 02139, USA. *
23 ***************************************************************************/
24
25#include <linux/module.h>
26#include <linux/init.h>
27#include <linux/kernel.h>
28#include <linux/param.h>
29#include <linux/moduleparam.h>
30#include <linux/errno.h>
31#include <linux/slab.h>
32#include <linux/device.h>
33#include <linux/fs.h>
34#include <linux/delay.h>
35#include <linux/compiler.h>
36#include <linux/ioctl.h>
37#include <linux/poll.h>
38#include <linux/stat.h>
39#include <linux/mm.h>
40#include <linux/vmalloc.h>
41#include <linux/page-flags.h>
42#include <linux/byteorder/generic.h>
43#include <asm/page.h>
44#include <asm/uaccess.h>
45
46#include "zc0301.h"
47
48/*****************************************************************************/
49
50#define ZC0301_MODULE_NAME "V4L2 driver for ZC0301 " \
51 "Image Processor and Control Chip"
52#define ZC0301_MODULE_AUTHOR "(C) 2006 Luca Risolia"
53#define ZC0301_AUTHOR_EMAIL "<luca.risolia@studio.unibo.it>"
54#define ZC0301_MODULE_LICENSE "GPL"
55#define ZC0301_MODULE_VERSION "1:1.03"
56#define ZC0301_MODULE_VERSION_CODE KERNEL_VERSION(1, 0, 3)
57
58/*****************************************************************************/
59
60MODULE_DEVICE_TABLE(usb, zc0301_id_table);
61
62MODULE_AUTHOR(ZC0301_MODULE_AUTHOR " " ZC0301_AUTHOR_EMAIL);
63MODULE_DESCRIPTION(ZC0301_MODULE_NAME);
64MODULE_VERSION(ZC0301_MODULE_VERSION);
65MODULE_LICENSE(ZC0301_MODULE_LICENSE);
66
67static short video_nr[] = {[0 ... ZC0301_MAX_DEVICES-1] = -1};
68module_param_array(video_nr, short, NULL, 0444);
69MODULE_PARM_DESC(video_nr,
70 "\n<-1|n[,...]> Specify V4L2 minor mode number."
71 "\n -1 = use next available (default)"
72 "\n n = use minor number n (integer >= 0)"
73 "\nYou can specify up to "
74 __MODULE_STRING(ZC0301_MAX_DEVICES) " cameras this way."
75 "\nFor example:"
76 "\nvideo_nr=-1,2,-1 would assign minor number 2 to"
77 "\nthe second registered camera and use auto for the first"
78 "\none and for every other camera."
79 "\n");
80
81static short force_munmap[] = {[0 ... ZC0301_MAX_DEVICES-1] =
82 ZC0301_FORCE_MUNMAP};
83module_param_array(force_munmap, bool, NULL, 0444);
84MODULE_PARM_DESC(force_munmap,
85 "\n<0|1[,...]> Force the application to unmap previously"
86 "\nmapped buffer memory before calling any VIDIOC_S_CROP or"
87 "\nVIDIOC_S_FMT ioctl's. Not all the applications support"
88 "\nthis feature. This parameter is specific for each"
89 "\ndetected camera."
90 "\n 0 = do not force memory unmapping"
91 "\n 1 = force memory unmapping (save memory)"
92 "\nDefault value is "__MODULE_STRING(SN9C102_FORCE_MUNMAP)"."
93 "\n");
94
95static unsigned int frame_timeout[] = {[0 ... ZC0301_MAX_DEVICES-1] =
96 ZC0301_FRAME_TIMEOUT};
97module_param_array(frame_timeout, uint, NULL, 0644);
98MODULE_PARM_DESC(frame_timeout,
99 "\n<n[,...]> Timeout for a video frame in seconds."
100 "\nThis parameter is specific for each detected camera."
101 "\nDefault value is "__MODULE_STRING(ZC0301_FRAME_TIMEOUT)"."
102 "\n");
103
104#ifdef ZC0301_DEBUG
105static unsigned short debug = ZC0301_DEBUG_LEVEL;
106module_param(debug, ushort, 0644);
107MODULE_PARM_DESC(debug,
108 "\n<n> Debugging information level, from 0 to 3:"
109 "\n0 = none (use carefully)"
110 "\n1 = critical errors"
111 "\n2 = significant informations"
112 "\n3 = more verbose messages"
113 "\nLevel 3 is useful for testing only, when only "
114 "one device is used."
115 "\nDefault value is "__MODULE_STRING(ZC0301_DEBUG_LEVEL)"."
116 "\n");
117#endif
118
119/*****************************************************************************/
120
121static u32
122zc0301_request_buffers(struct zc0301_device* cam, u32 count,
123 enum zc0301_io_method io)
124{
125 struct v4l2_pix_format* p = &(cam->sensor.pix_format);
126 struct v4l2_rect* r = &(cam->sensor.cropcap.bounds);
127 const size_t imagesize = cam->module_param.force_munmap ||
128 io == IO_READ ?
129 (p->width * p->height * p->priv) / 8 :
130 (r->width * r->height * p->priv) / 8;
131 void* buff = NULL;
132 u32 i;
133
134 if (count > ZC0301_MAX_FRAMES)
135 count = ZC0301_MAX_FRAMES;
136
137 cam->nbuffers = count;
138 while (cam->nbuffers > 0) {
139 if ((buff = vmalloc_32(cam->nbuffers * PAGE_ALIGN(imagesize))))
140 break;
141 cam->nbuffers--;
142 }
143
144 for (i = 0; i < cam->nbuffers; i++) {
145 cam->frame[i].bufmem = buff + i*PAGE_ALIGN(imagesize);
146 cam->frame[i].buf.index = i;
147 cam->frame[i].buf.m.offset = i*PAGE_ALIGN(imagesize);
148 cam->frame[i].buf.length = imagesize;
149 cam->frame[i].buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
150 cam->frame[i].buf.sequence = 0;
151 cam->frame[i].buf.field = V4L2_FIELD_NONE;
152 cam->frame[i].buf.memory = V4L2_MEMORY_MMAP;
153 cam->frame[i].buf.flags = 0;
154 }
155
156 return cam->nbuffers;
157}
158
159
160static void zc0301_release_buffers(struct zc0301_device* cam)
161{
162 if (cam->nbuffers) {
163 vfree(cam->frame[0].bufmem);
164 cam->nbuffers = 0;
165 }
166 cam->frame_current = NULL;
167}
168
169
170static void zc0301_empty_framequeues(struct zc0301_device* cam)
171{
172 u32 i;
173
174 INIT_LIST_HEAD(&cam->inqueue);
175 INIT_LIST_HEAD(&cam->outqueue);
176
177 for (i = 0; i < ZC0301_MAX_FRAMES; i++) {
178 cam->frame[i].state = F_UNUSED;
179 cam->frame[i].buf.bytesused = 0;
180 }
181}
182
183
184static void zc0301_requeue_outqueue(struct zc0301_device* cam)
185{
186 struct zc0301_frame_t *i;
187
188 list_for_each_entry(i, &cam->outqueue, frame) {
189 i->state = F_QUEUED;
190 list_add(&i->frame, &cam->inqueue);
191 }
192
193 INIT_LIST_HEAD(&cam->outqueue);
194}
195
196
197static void zc0301_queue_unusedframes(struct zc0301_device* cam)
198{
199 unsigned long lock_flags;
200 u32 i;
201
202 for (i = 0; i < cam->nbuffers; i++)
203 if (cam->frame[i].state == F_UNUSED) {
204 cam->frame[i].state = F_QUEUED;
205 spin_lock_irqsave(&cam->queue_lock, lock_flags);
206 list_add_tail(&cam->frame[i].frame, &cam->inqueue);
207 spin_unlock_irqrestore(&cam->queue_lock, lock_flags);
208 }
209}
210
211/*****************************************************************************/
212
213int zc0301_write_reg(struct zc0301_device* cam, u16 index, u16 value)
214{
215 struct usb_device* udev = cam->usbdev;
216 int res;
217
218 res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0xa0, 0x40,
219 value, index, NULL, 0, ZC0301_CTRL_TIMEOUT);
220 if (res < 0) {
221 DBG(3, "Failed to write a register (index 0x%04X, "
222 "value 0x%02X, error %d)",index, value, res);
223 return -1;
224 }
225
226 return 0;
227}
228
229
230int zc0301_read_reg(struct zc0301_device* cam, u16 index)
231{
232 struct usb_device* udev = cam->usbdev;
233 u8* buff = cam->control_buffer;
234 int res;
235
236 res = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), 0xa1, 0xc0,
237 0x0001, index, buff, 1, ZC0301_CTRL_TIMEOUT);
238 if (res < 0)
239 DBG(3, "Failed to read a register (index 0x%04X, error %d)",
240 index, res);
241
242 PDBGG("Read: index 0x%04X, value: 0x%04X", index, (int)(*buff));
243
244 return (res >= 0) ? (int)(*buff) : -1;
245}
246
247
248int zc0301_i2c_read(struct zc0301_device* cam, u16 address, u8 length)
249{
250 int err = 0, res, r0, r1;
251
252 err += zc0301_write_reg(cam, 0x0092, address);
253 err += zc0301_write_reg(cam, 0x0090, 0x02);
254
255 msleep(1);
256
257 res = zc0301_read_reg(cam, 0x0091);
258 if (res < 0)
259 err += res;
260 r0 = zc0301_read_reg(cam, 0x0095);
261 if (r0 < 0)
262 err += r0;
263 r1 = zc0301_read_reg(cam, 0x0096);
264 if (r1 < 0)
265 err += r1;
266
267 res = (length <= 1) ? r0 : r0 | (r1 << 8);
268
269 if (err)
270 DBG(3, "I2C read failed at address 0x%04X, value: 0x%04X",
271 address, res);
272
273
274 PDBGG("I2C read: address 0x%04X, value: 0x%04X", address, res);
275
276 return err ? -1 : res;
277}
278
279
280int zc0301_i2c_write(struct zc0301_device* cam, u16 address, u16 value)
281{
282 int err = 0, res;
283
284 err += zc0301_write_reg(cam, 0x0092, address);
285 err += zc0301_write_reg(cam, 0x0093, value & 0xff);
286 err += zc0301_write_reg(cam, 0x0094, value >> 8);
287 err += zc0301_write_reg(cam, 0x0090, 0x01);
288
289 msleep(1);
290
291 res = zc0301_read_reg(cam, 0x0091);
292 if (res < 0)
293 err += res;
294
295 if (err)
296 DBG(3, "I2C write failed at address 0x%04X, value: 0x%04X",
297 address, value);
298
299 PDBGG("I2C write: address 0x%04X, value: 0x%04X", address, value);
300
301 return err ? -1 : 0;
302}
303
304/*****************************************************************************/
305
306static void zc0301_urb_complete(struct urb *urb, struct pt_regs* regs)
307{
308 struct zc0301_device* cam = urb->context;
309 struct zc0301_frame_t** f;
310 size_t imagesize;
311 u8 i;
312 int err = 0;
313
314 if (urb->status == -ENOENT)
315 return;
316
317 f = &cam->frame_current;
318
319 if (cam->stream == STREAM_INTERRUPT) {
320 cam->stream = STREAM_OFF;
321 if ((*f))
322 (*f)->state = F_QUEUED;
323 DBG(3, "Stream interrupted");
324 wake_up(&cam->wait_stream);
325 }
326
327 if (cam->state & DEV_DISCONNECTED)
328 return;
329
330 if (cam->state & DEV_MISCONFIGURED) {
331 wake_up_interruptible(&cam->wait_frame);
332 return;
333 }
334
335 if (cam->stream == STREAM_OFF || list_empty(&cam->inqueue))
336 goto resubmit_urb;
337
338 if (!(*f))
339 (*f) = list_entry(cam->inqueue.next, struct zc0301_frame_t,
340 frame);
341
342 imagesize = (cam->sensor.pix_format.width *
343 cam->sensor.pix_format.height *
344 cam->sensor.pix_format.priv) / 8;
345
346 for (i = 0; i < urb->number_of_packets; i++) {
347 unsigned int len, status;
348 void *pos;
349 u16* soi;
350 u8 sof;
351
352 len = urb->iso_frame_desc[i].actual_length;
353 status = urb->iso_frame_desc[i].status;
354 pos = urb->iso_frame_desc[i].offset + urb->transfer_buffer;
355
356 if (status) {
357 DBG(3, "Error in isochronous frame");
358 (*f)->state = F_ERROR;
359 continue;
360 }
361
362 sof = (*(soi = pos) == 0xd8ff);
363
364 PDBGG("Isochrnous frame: length %u, #%u i,", len, i);
365
366 if ((*f)->state == F_QUEUED || (*f)->state == F_ERROR)
367start_of_frame:
368 if (sof) {
369 (*f)->state = F_GRABBING;
370 (*f)->buf.bytesused = 0;
371 do_gettimeofday(&(*f)->buf.timestamp);
372 DBG(3, "SOF detected: new video frame");
373 }
374
375 if ((*f)->state == F_GRABBING) {
376 if (sof && (*f)->buf.bytesused)
377 goto end_of_frame;
378
379 if ((*f)->buf.bytesused + len > imagesize) {
380 DBG(3, "Video frame size exceeded");
381 (*f)->state = F_ERROR;
382 continue;
383 }
384
385 memcpy((*f)->bufmem+(*f)->buf.bytesused, pos, len);
386 (*f)->buf.bytesused += len;
387
388 if ((*f)->buf.bytesused == imagesize) {
389 u32 b;
390end_of_frame:
391 b = (*f)->buf.bytesused;
392 (*f)->state = F_DONE;
393 (*f)->buf.sequence= ++cam->frame_count;
394 spin_lock(&cam->queue_lock);
395 list_move_tail(&(*f)->frame, &cam->outqueue);
396 if (!list_empty(&cam->inqueue))
397 (*f) = list_entry(cam->inqueue.next,
398 struct zc0301_frame_t,
399 frame);
400 else
401 (*f) = NULL;
402 spin_unlock(&cam->queue_lock);
403 DBG(3, "Video frame captured: : %lu bytes",
404 (unsigned long)(b));
405
406 if (!(*f))
407 goto resubmit_urb;
408
409 if (sof)
410 goto start_of_frame;
411 }
412 }
413 }
414
415resubmit_urb:
416 urb->dev = cam->usbdev;
417 err = usb_submit_urb(urb, GFP_ATOMIC);
418 if (err < 0 && err != -EPERM) {
419 cam->state |= DEV_MISCONFIGURED;
420 DBG(1, "usb_submit_urb() failed");
421 }
422
423 wake_up_interruptible(&cam->wait_frame);
424}
425
426
427static int zc0301_start_transfer(struct zc0301_device* cam)
428{
429 struct usb_device *udev = cam->usbdev;
430 struct urb* urb;
431 const unsigned int wMaxPacketSize[] = {0, 128, 192, 256, 384,
432 512, 768, 1023};
433 const unsigned int psz = wMaxPacketSize[ZC0301_ALTERNATE_SETTING];
434 s8 i, j;
435 int err = 0;
436
437 for (i = 0; i < ZC0301_URBS; i++) {
438 cam->transfer_buffer[i] = kzalloc(ZC0301_ISO_PACKETS * psz,
439 GFP_KERNEL);
440 if (!cam->transfer_buffer[i]) {
441 err = -ENOMEM;
442 DBG(1, "Not enough memory");
443 goto free_buffers;
444 }
445 }
446
447 for (i = 0; i < ZC0301_URBS; i++) {
448 urb = usb_alloc_urb(ZC0301_ISO_PACKETS, GFP_KERNEL);
449 cam->urb[i] = urb;
450 if (!urb) {
451 err = -ENOMEM;
452 DBG(1, "usb_alloc_urb() failed");
453 goto free_urbs;
454 }
455 urb->dev = udev;
456 urb->context = cam;
457 urb->pipe = usb_rcvisocpipe(udev, 1);
458 urb->transfer_flags = URB_ISO_ASAP;
459 urb->number_of_packets = ZC0301_ISO_PACKETS;
460 urb->complete = zc0301_urb_complete;
461 urb->transfer_buffer = cam->transfer_buffer[i];
462 urb->transfer_buffer_length = psz * ZC0301_ISO_PACKETS;
463 urb->interval = 1;
464 for (j = 0; j < ZC0301_ISO_PACKETS; j++) {
465 urb->iso_frame_desc[j].offset = psz * j;
466 urb->iso_frame_desc[j].length = psz;
467 }
468 }
469
470 err = usb_set_interface(udev, 0, ZC0301_ALTERNATE_SETTING);
471 if (err) {
472 DBG(1, "usb_set_interface() failed");
473 goto free_urbs;
474 }
475
476 cam->frame_current = NULL;
477
478 for (i = 0; i < ZC0301_URBS; i++) {
479 err = usb_submit_urb(cam->urb[i], GFP_KERNEL);
480 if (err) {
481 for (j = i-1; j >= 0; j--)
482 usb_kill_urb(cam->urb[j]);
483 DBG(1, "usb_submit_urb() failed, error %d", err);
484 goto free_urbs;
485 }
486 }
487
488 return 0;
489
490free_urbs:
491 for (i = 0; (i < ZC0301_URBS) && cam->urb[i]; i++)
492 usb_free_urb(cam->urb[i]);
493
494free_buffers:
495 for (i = 0; (i < ZC0301_URBS) && cam->transfer_buffer[i]; i++)
496 kfree(cam->transfer_buffer[i]);
497
498 return err;
499}
500
501
502static int zc0301_stop_transfer(struct zc0301_device* cam)
503{
504 struct usb_device *udev = cam->usbdev;
505 s8 i;
506 int err = 0;
507
508 if (cam->state & DEV_DISCONNECTED)
509 return 0;
510
511 for (i = ZC0301_URBS-1; i >= 0; i--) {
512 usb_kill_urb(cam->urb[i]);
513 usb_free_urb(cam->urb[i]);
514 kfree(cam->transfer_buffer[i]);
515 }
516
517 err = usb_set_interface(udev, 0, 0); /* 0 Mb/s */
518 if (err)
519 DBG(3, "usb_set_interface() failed");
520
521 return err;
522}
523
524
525static int zc0301_stream_interrupt(struct zc0301_device* cam)
526{
527 long timeout;
528
529 cam->stream = STREAM_INTERRUPT;
530 timeout = wait_event_timeout(cam->wait_stream,
531 (cam->stream == STREAM_OFF) ||
532 (cam->state & DEV_DISCONNECTED),
533 ZC0301_URB_TIMEOUT);
534 if (cam->state & DEV_DISCONNECTED)
535 return -ENODEV;
536 else if (cam->stream != STREAM_OFF) {
537 cam->state |= DEV_MISCONFIGURED;
538 DBG(1, "URB timeout reached. The camera is misconfigured. To "
539 "use it, close and open /dev/video%d again.",
540 cam->v4ldev->minor);
541 return -EIO;
542 }
543
544 return 0;
545}
546
547/*****************************************************************************/
548
549static int
550zc0301_set_compression(struct zc0301_device* cam,
551 struct v4l2_jpegcompression* compression)
552{
553 int r, err = 0;
554
555 if ((r = zc0301_read_reg(cam, 0x0008)) < 0)
556 err += r;
557 err += zc0301_write_reg(cam, 0x0008, r | 0x11 | compression->quality);
558
559 return err ? -EIO : 0;
560}
561
562
563static int zc0301_init(struct zc0301_device* cam)
564{
565 struct zc0301_sensor* s = &cam->sensor;
566 struct v4l2_control ctrl;
567 struct v4l2_queryctrl *qctrl;
568 struct v4l2_rect* rect;
569 u8 i = 0;
570 int err = 0;
571
572 if (!(cam->state & DEV_INITIALIZED)) {
573 init_waitqueue_head(&cam->open);
574 qctrl = s->qctrl;
575 rect = &(s->cropcap.defrect);
576 cam->compression.quality = ZC0301_COMPRESSION_QUALITY;
577 } else { /* use current values */
578 qctrl = s->_qctrl;
579 rect = &(s->_rect);
580 }
581
582 if (s->init) {
583 err = s->init(cam);
584 if (err) {
585 DBG(3, "Sensor initialization failed");
586 return err;
587 }
588 }
589
590 if ((err = zc0301_set_compression(cam, &cam->compression))) {
591 DBG(3, "set_compression() failed");
592 return err;
593 }
594
595 if (s->set_crop)
596 if ((err = s->set_crop(cam, rect))) {
597 DBG(3, "set_crop() failed");
598 return err;
599 }
600
601 if (s->set_ctrl) {
602 for (i = 0; i < ARRAY_SIZE(s->qctrl); i++)
603 if (s->qctrl[i].id != 0 &&
604 !(s->qctrl[i].flags & V4L2_CTRL_FLAG_DISABLED)) {
605 ctrl.id = s->qctrl[i].id;
606 ctrl.value = qctrl[i].default_value;
607 err = s->set_ctrl(cam, &ctrl);
608 if (err) {
609 DBG(3, "Set %s control failed",
610 s->qctrl[i].name);
611 return err;
612 }
613 DBG(3, "Image sensor supports '%s' control",
614 s->qctrl[i].name);
615 }
616 }
617
618 if (!(cam->state & DEV_INITIALIZED)) {
619 mutex_init(&cam->fileop_mutex);
620 spin_lock_init(&cam->queue_lock);
621 init_waitqueue_head(&cam->wait_frame);
622 init_waitqueue_head(&cam->wait_stream);
623 cam->nreadbuffers = 2;
624 memcpy(s->_qctrl, s->qctrl, sizeof(s->qctrl));
625 memcpy(&(s->_rect), &(s->cropcap.defrect),
626 sizeof(struct v4l2_rect));
627 cam->state |= DEV_INITIALIZED;
628 }
629
630 DBG(2, "Initialization succeeded");
631 return 0;
632}
633
634
635static void zc0301_release_resources(struct zc0301_device* cam)
636{
637 DBG(2, "V4L2 device /dev/video%d deregistered", cam->v4ldev->minor);
638 video_set_drvdata(cam->v4ldev, NULL);
639 video_unregister_device(cam->v4ldev);
640 kfree(cam->control_buffer);
641}
642
643/*****************************************************************************/
644
645static int zc0301_open(struct inode* inode, struct file* filp)
646{
647 struct zc0301_device* cam;
648 int err = 0;
649
650 /*
651 This is the only safe way to prevent race conditions with
652 disconnect
653 */
654 if (!down_read_trylock(&zc0301_disconnect))
655 return -ERESTARTSYS;
656
657 cam = video_get_drvdata(video_devdata(filp));
658
659 if (mutex_lock_interruptible(&cam->dev_mutex)) {
660 up_read(&zc0301_disconnect);
661 return -ERESTARTSYS;
662 }
663
664 if (cam->users) {
665 DBG(2, "Device /dev/video%d is busy...", cam->v4ldev->minor);
666 if ((filp->f_flags & O_NONBLOCK) ||
667 (filp->f_flags & O_NDELAY)) {
668 err = -EWOULDBLOCK;
669 goto out;
670 }
671 mutex_unlock(&cam->dev_mutex);
672 err = wait_event_interruptible_exclusive(cam->open,
673 cam->state & DEV_DISCONNECTED
674 || !cam->users);
675 if (err) {
676 up_read(&zc0301_disconnect);
677 return err;
678 }
679 if (cam->state & DEV_DISCONNECTED) {
680 up_read(&zc0301_disconnect);
681 return -ENODEV;
682 }
683 mutex_lock(&cam->dev_mutex);
684 }
685
686
687 if (cam->state & DEV_MISCONFIGURED) {
688 err = zc0301_init(cam);
689 if (err) {
690 DBG(1, "Initialization failed again. "
691 "I will retry on next open().");
692 goto out;
693 }
694 cam->state &= ~DEV_MISCONFIGURED;
695 }
696
697 if ((err = zc0301_start_transfer(cam)))
698 goto out;
699
700 filp->private_data = cam;
701 cam->users++;
702 cam->io = IO_NONE;
703 cam->stream = STREAM_OFF;
704 cam->nbuffers = 0;
705 cam->frame_count = 0;
706 zc0301_empty_framequeues(cam);
707
708 DBG(3, "Video device /dev/video%d is open", cam->v4ldev->minor);
709
710out:
711 mutex_unlock(&cam->dev_mutex);
712 up_read(&zc0301_disconnect);
713 return err;
714}
715
716
717static int zc0301_release(struct inode* inode, struct file* filp)
718{
719 struct zc0301_device* cam = video_get_drvdata(video_devdata(filp));
720
721 mutex_lock(&cam->dev_mutex); /* prevent disconnect() to be called */
722
723 zc0301_stop_transfer(cam);
724
725 zc0301_release_buffers(cam);
726
727 if (cam->state & DEV_DISCONNECTED) {
728 zc0301_release_resources(cam);
729 usb_put_dev(cam->usbdev);
730 mutex_unlock(&cam->dev_mutex);
731 kfree(cam);
732 return 0;
733 }
734
735 cam->users--;
736 wake_up_interruptible_nr(&cam->open, 1);
737
738 DBG(3, "Video device /dev/video%d closed", cam->v4ldev->minor);
739
740 mutex_unlock(&cam->dev_mutex);
741
742 return 0;
743}
744
745
746static ssize_t
747zc0301_read(struct file* filp, char __user * buf, size_t count, loff_t* f_pos)
748{
749 struct zc0301_device* cam = video_get_drvdata(video_devdata(filp));
750 struct zc0301_frame_t* f, * i;
751 unsigned long lock_flags;
752 long timeout;
753 int err = 0;
754
755 if (mutex_lock_interruptible(&cam->fileop_mutex))
756 return -ERESTARTSYS;
757
758 if (cam->state & DEV_DISCONNECTED) {
759 DBG(1, "Device not present");
760 mutex_unlock(&cam->fileop_mutex);
761 return -ENODEV;
762 }
763
764 if (cam->state & DEV_MISCONFIGURED) {
765 DBG(1, "The camera is misconfigured. Close and open it "
766 "again.");
767 mutex_unlock(&cam->fileop_mutex);
768 return -EIO;
769 }
770
771 if (cam->io == IO_MMAP) {
772 DBG(3, "Close and open the device again to choose the read "
773 "method");
774 mutex_unlock(&cam->fileop_mutex);
775 return -EINVAL;
776 }
777
778 if (cam->io == IO_NONE) {
779 if (!zc0301_request_buffers(cam, cam->nreadbuffers, IO_READ)) {
780 DBG(1, "read() failed, not enough memory");
781 mutex_unlock(&cam->fileop_mutex);
782 return -ENOMEM;
783 }
784 cam->io = IO_READ;
785 cam->stream = STREAM_ON;
786 }
787
788 if (list_empty(&cam->inqueue)) {
789 if (!list_empty(&cam->outqueue))
790 zc0301_empty_framequeues(cam);
791 zc0301_queue_unusedframes(cam);
792 }
793
794 if (!count) {
795 mutex_unlock(&cam->fileop_mutex);
796 return 0;
797 }
798
799 if (list_empty(&cam->outqueue)) {
800 if (filp->f_flags & O_NONBLOCK) {
801 mutex_unlock(&cam->fileop_mutex);
802 return -EAGAIN;
803 }
804 timeout = wait_event_interruptible_timeout
805 ( cam->wait_frame,
806 (!list_empty(&cam->outqueue)) ||
807 (cam->state & DEV_DISCONNECTED) ||
808 (cam->state & DEV_MISCONFIGURED),
809 cam->module_param.frame_timeout *
810 1000 * msecs_to_jiffies(1) );
811 if (timeout < 0) {
812 mutex_unlock(&cam->fileop_mutex);
813 return timeout;
814 }
815 if (cam->state & DEV_DISCONNECTED) {
816 mutex_unlock(&cam->fileop_mutex);
817 return -ENODEV;
818 }
819 if (!timeout || (cam->state & DEV_MISCONFIGURED)) {
820 mutex_unlock(&cam->fileop_mutex);
821 return -EIO;
822 }
823 }
824
825 f = list_entry(cam->outqueue.prev, struct zc0301_frame_t, frame);
826
827 if (count > f->buf.bytesused)
828 count = f->buf.bytesused;
829
830 if (copy_to_user(buf, f->bufmem, count)) {
831 err = -EFAULT;
832 goto exit;
833 }
834 *f_pos += count;
835
836exit:
837 spin_lock_irqsave(&cam->queue_lock, lock_flags);
838 list_for_each_entry(i, &cam->outqueue, frame)
839 i->state = F_UNUSED;
840 INIT_LIST_HEAD(&cam->outqueue);
841 spin_unlock_irqrestore(&cam->queue_lock, lock_flags);
842
843 zc0301_queue_unusedframes(cam);
844
845 PDBGG("Frame #%lu, bytes read: %zu",
846 (unsigned long)f->buf.index, count);
847
848 mutex_unlock(&cam->fileop_mutex);
849
850 return err ? err : count;
851}
852
853
854static unsigned int zc0301_poll(struct file *filp, poll_table *wait)
855{
856 struct zc0301_device* cam = video_get_drvdata(video_devdata(filp));
857 struct zc0301_frame_t* f;
858 unsigned long lock_flags;
859 unsigned int mask = 0;
860
861 if (mutex_lock_interruptible(&cam->fileop_mutex))
862 return POLLERR;
863
864 if (cam->state & DEV_DISCONNECTED) {
865 DBG(1, "Device not present");
866 goto error;
867 }
868
869 if (cam->state & DEV_MISCONFIGURED) {
870 DBG(1, "The camera is misconfigured. Close and open it "
871 "again.");
872 goto error;
873 }
874
875 if (cam->io == IO_NONE) {
876 if (!zc0301_request_buffers(cam, cam->nreadbuffers, IO_READ)) {
877 DBG(1, "poll() failed, not enough memory");
878 goto error;
879 }
880 cam->io = IO_READ;
881 cam->stream = STREAM_ON;
882 }
883
884 if (cam->io == IO_READ) {
885 spin_lock_irqsave(&cam->queue_lock, lock_flags);
886 list_for_each_entry(f, &cam->outqueue, frame)
887 f->state = F_UNUSED;
888 INIT_LIST_HEAD(&cam->outqueue);
889 spin_unlock_irqrestore(&cam->queue_lock, lock_flags);
890 zc0301_queue_unusedframes(cam);
891 }
892
893 poll_wait(filp, &cam->wait_frame, wait);
894
895 if (!list_empty(&cam->outqueue))
896 mask |= POLLIN | POLLRDNORM;
897
898 mutex_unlock(&cam->fileop_mutex);
899
900 return mask;
901
902error:
903 mutex_unlock(&cam->fileop_mutex);
904 return POLLERR;
905}
906
907
908static void zc0301_vm_open(struct vm_area_struct* vma)
909{
910 struct zc0301_frame_t* f = vma->vm_private_data;
911 f->vma_use_count++;
912}
913
914
915static void zc0301_vm_close(struct vm_area_struct* vma)
916{
917 /* NOTE: buffers are not freed here */
918 struct zc0301_frame_t* f = vma->vm_private_data;
919 f->vma_use_count--;
920}
921
922
923static struct vm_operations_struct zc0301_vm_ops = {
924 .open = zc0301_vm_open,
925 .close = zc0301_vm_close,
926};
927
928
929static int zc0301_mmap(struct file* filp, struct vm_area_struct *vma)
930{
931 struct zc0301_device* cam = video_get_drvdata(video_devdata(filp));
932 unsigned long size = vma->vm_end - vma->vm_start,
933 start = vma->vm_start;
934 void *pos;
935 u32 i;
936
937 if (mutex_lock_interruptible(&cam->fileop_mutex))
938 return -ERESTARTSYS;
939
940 if (cam->state & DEV_DISCONNECTED) {
941 DBG(1, "Device not present");
942 mutex_unlock(&cam->fileop_mutex);
943 return -ENODEV;
944 }
945
946 if (cam->state & DEV_MISCONFIGURED) {
947 DBG(1, "The camera is misconfigured. Close and open it "
948 "again.");
949 mutex_unlock(&cam->fileop_mutex);
950 return -EIO;
951 }
952
953 if (cam->io != IO_MMAP || !(vma->vm_flags & VM_WRITE) ||
954 size != PAGE_ALIGN(cam->frame[0].buf.length)) {
955 mutex_unlock(&cam->fileop_mutex);
956 return -EINVAL;
957 }
958
959 for (i = 0; i < cam->nbuffers; i++) {
960 if ((cam->frame[i].buf.m.offset>>PAGE_SHIFT) == vma->vm_pgoff)
961 break;
962 }
963 if (i == cam->nbuffers) {
964 mutex_unlock(&cam->fileop_mutex);
965 return -EINVAL;
966 }
967
968 vma->vm_flags |= VM_IO;
969 vma->vm_flags |= VM_RESERVED;
970
971 pos = cam->frame[i].bufmem;
972 while (size > 0) { /* size is page-aligned */
973 if (vm_insert_page(vma, start, vmalloc_to_page(pos))) {
974 mutex_unlock(&cam->fileop_mutex);
975 return -EAGAIN;
976 }
977 start += PAGE_SIZE;
978 pos += PAGE_SIZE;
979 size -= PAGE_SIZE;
980 }
981
982 vma->vm_ops = &zc0301_vm_ops;
983 vma->vm_private_data = &cam->frame[i];
984
985 zc0301_vm_open(vma);
986
987 mutex_unlock(&cam->fileop_mutex);
988
989 return 0;
990}
991
992/*****************************************************************************/
993
994static int
995zc0301_vidioc_querycap(struct zc0301_device* cam, void __user * arg)
996{
997 struct v4l2_capability cap = {
998 .driver = "zc0301",
999 .version = ZC0301_MODULE_VERSION_CODE,
1000 .capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE |
1001 V4L2_CAP_STREAMING,
1002 };
1003
1004 strlcpy(cap.card, cam->v4ldev->name, sizeof(cap.card));
1005 if (usb_make_path(cam->usbdev, cap.bus_info, sizeof(cap.bus_info)) < 0)
1006 strlcpy(cap.bus_info, cam->usbdev->dev.bus_id,
1007 sizeof(cap.bus_info));
1008
1009 if (copy_to_user(arg, &cap, sizeof(cap)))
1010 return -EFAULT;
1011
1012 return 0;
1013}
1014
1015
1016static int
1017zc0301_vidioc_enuminput(struct zc0301_device* cam, void __user * arg)
1018{
1019 struct v4l2_input i;
1020
1021 if (copy_from_user(&i, arg, sizeof(i)))
1022 return -EFAULT;
1023
1024 if (i.index)
1025 return -EINVAL;
1026
1027 memset(&i, 0, sizeof(i));
1028 strcpy(i.name, "Camera");
1029 i.type = V4L2_INPUT_TYPE_CAMERA;
1030
1031 if (copy_to_user(arg, &i, sizeof(i)))
1032 return -EFAULT;
1033
1034 return 0;
1035}
1036
1037
1038static int
1039zc0301_vidioc_g_input(struct zc0301_device* cam, void __user * arg)
1040{
1041 int index = 0;
1042
1043 if (copy_to_user(arg, &index, sizeof(index)))
1044 return -EFAULT;
1045
1046 return 0;
1047}
1048
1049
1050static int
1051zc0301_vidioc_s_input(struct zc0301_device* cam, void __user * arg)
1052{
1053 int index;
1054
1055 if (copy_from_user(&index, arg, sizeof(index)))
1056 return -EFAULT;
1057
1058 if (index != 0)
1059 return -EINVAL;
1060
1061 return 0;
1062}
1063
1064
1065static int
1066zc0301_vidioc_query_ctrl(struct zc0301_device* cam, void __user * arg)
1067{
1068 struct zc0301_sensor* s = &cam->sensor;
1069 struct v4l2_queryctrl qc;
1070 u8 i;
1071
1072 if (copy_from_user(&qc, arg, sizeof(qc)))
1073 return -EFAULT;
1074
1075 for (i = 0; i < ARRAY_SIZE(s->qctrl); i++)
1076 if (qc.id && qc.id == s->qctrl[i].id) {
1077 memcpy(&qc, &(s->qctrl[i]), sizeof(qc));
1078 if (copy_to_user(arg, &qc, sizeof(qc)))
1079 return -EFAULT;
1080 return 0;
1081 }
1082
1083 return -EINVAL;
1084}
1085
1086
1087static int
1088zc0301_vidioc_g_ctrl(struct zc0301_device* cam, void __user * arg)
1089{
1090 struct zc0301_sensor* s = &cam->sensor;
1091 struct v4l2_control ctrl;
1092 int err = 0;
1093 u8 i;
1094
1095 if (!s->get_ctrl && !s->set_ctrl)
1096 return -EINVAL;
1097
1098 if (copy_from_user(&ctrl, arg, sizeof(ctrl)))
1099 return -EFAULT;
1100
1101 if (!s->get_ctrl) {
1102 for (i = 0; i < ARRAY_SIZE(s->qctrl); i++)
1103 if (ctrl.id == s->qctrl[i].id) {
1104 ctrl.value = s->_qctrl[i].default_value;
1105 goto exit;
1106 }
1107 return -EINVAL;
1108 } else
1109 err = s->get_ctrl(cam, &ctrl);
1110
1111exit:
1112 if (copy_to_user(arg, &ctrl, sizeof(ctrl)))
1113 return -EFAULT;
1114
1115 return err;
1116}
1117
1118
1119static int
1120zc0301_vidioc_s_ctrl(struct zc0301_device* cam, void __user * arg)
1121{
1122 struct zc0301_sensor* s = &cam->sensor;
1123 struct v4l2_control ctrl;
1124 u8 i;
1125 int err = 0;
1126
1127 if (!s->set_ctrl)
1128 return -EINVAL;
1129
1130 if (copy_from_user(&ctrl, arg, sizeof(ctrl)))
1131 return -EFAULT;
1132
1133 for (i = 0; i < ARRAY_SIZE(s->qctrl); i++)
1134 if (ctrl.id == s->qctrl[i].id) {
1135 if (s->qctrl[i].flags & V4L2_CTRL_FLAG_DISABLED)
1136 return -EINVAL;
1137 if (ctrl.value < s->qctrl[i].minimum ||
1138 ctrl.value > s->qctrl[i].maximum)
1139 return -ERANGE;
1140 ctrl.value -= ctrl.value % s->qctrl[i].step;
1141 break;
1142 }
1143
1144 if ((err = s->set_ctrl(cam, &ctrl)))
1145 return err;
1146
1147 s->_qctrl[i].default_value = ctrl.value;
1148
1149 return 0;
1150}
1151
1152
1153static int
1154zc0301_vidioc_cropcap(struct zc0301_device* cam, void __user * arg)
1155{
1156 struct v4l2_cropcap* cc = &(cam->sensor.cropcap);
1157
1158 cc->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1159 cc->pixelaspect.numerator = 1;
1160 cc->pixelaspect.denominator = 1;
1161
1162 if (copy_to_user(arg, cc, sizeof(*cc)))
1163 return -EFAULT;
1164
1165 return 0;
1166}
1167
1168
1169static int
1170zc0301_vidioc_g_crop(struct zc0301_device* cam, void __user * arg)
1171{
1172 struct zc0301_sensor* s = &cam->sensor;
1173 struct v4l2_crop crop = {
1174 .type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
1175 };
1176
1177 memcpy(&(crop.c), &(s->_rect), sizeof(struct v4l2_rect));
1178
1179 if (copy_to_user(arg, &crop, sizeof(crop)))
1180 return -EFAULT;
1181
1182 return 0;
1183}
1184
1185
1186static int
1187zc0301_vidioc_s_crop(struct zc0301_device* cam, void __user * arg)
1188{
1189 struct zc0301_sensor* s = &cam->sensor;
1190 struct v4l2_crop crop;
1191 struct v4l2_rect* rect;
1192 struct v4l2_rect* bounds = &(s->cropcap.bounds);
1193 const enum zc0301_stream_state stream = cam->stream;
1194 const u32 nbuffers = cam->nbuffers;
1195 u32 i;
1196 int err = 0;
1197
1198 if (copy_from_user(&crop, arg, sizeof(crop)))
1199 return -EFAULT;
1200
1201 rect = &(crop.c);
1202
1203 if (crop.type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1204 return -EINVAL;
1205
1206 if (cam->module_param.force_munmap)
1207 for (i = 0; i < cam->nbuffers; i++)
1208 if (cam->frame[i].vma_use_count) {
1209 DBG(3, "VIDIOC_S_CROP failed. "
1210 "Unmap the buffers first.");
1211 return -EINVAL;
1212 }
1213
1214 if (!s->set_crop) {
1215 memcpy(rect, &(s->_rect), sizeof(*rect));
1216 if (copy_to_user(arg, &crop, sizeof(crop)))
1217 return -EFAULT;
1218 return 0;
1219 }
1220
1221 rect->left &= ~7L;
1222 rect->top &= ~7L;
1223 if (rect->width < 8)
1224 rect->width = 8;
1225 if (rect->height < 8)
1226 rect->height = 8;
1227 if (rect->width > bounds->width)
1228 rect->width = bounds->width;
1229 if (rect->height > bounds->height)
1230 rect->height = bounds->height;
1231 if (rect->left < bounds->left)
1232 rect->left = bounds->left;
1233 if (rect->top < bounds->top)
1234 rect->top = bounds->top;
1235 if (rect->left + rect->width > bounds->left + bounds->width)
1236 rect->left = bounds->left+bounds->width - rect->width;
1237 if (rect->top + rect->height > bounds->top + bounds->height)
1238 rect->top = bounds->top+bounds->height - rect->height;
1239 rect->width &= ~7L;
1240 rect->height &= ~7L;
1241
1242 if (cam->stream == STREAM_ON)
1243 if ((err = zc0301_stream_interrupt(cam)))
1244 return err;
1245
1246 if (copy_to_user(arg, &crop, sizeof(crop))) {
1247 cam->stream = stream;
1248 return -EFAULT;
1249 }
1250
1251 if (cam->module_param.force_munmap || cam->io == IO_READ)
1252 zc0301_release_buffers(cam);
1253
1254 if (s->set_crop)
1255 err += s->set_crop(cam, rect);
1256
1257 if (err) { /* atomic, no rollback in ioctl() */
1258 cam->state |= DEV_MISCONFIGURED;
1259 DBG(1, "VIDIOC_S_CROP failed because of hardware problems. To "
1260 "use the camera, close and open /dev/video%d again.",
1261 cam->v4ldev->minor);
1262 return -EIO;
1263 }
1264
1265 s->pix_format.width = rect->width;
1266 s->pix_format.height = rect->height;
1267 memcpy(&(s->_rect), rect, sizeof(*rect));
1268
1269 if ((cam->module_param.force_munmap || cam->io == IO_READ) &&
1270 nbuffers != zc0301_request_buffers(cam, nbuffers, cam->io)) {
1271 cam->state |= DEV_MISCONFIGURED;
1272 DBG(1, "VIDIOC_S_CROP failed because of not enough memory. To "
1273 "use the camera, close and open /dev/video%d again.",
1274 cam->v4ldev->minor);
1275 return -ENOMEM;
1276 }
1277
1278 if (cam->io == IO_READ)
1279 zc0301_empty_framequeues(cam);
1280 else if (cam->module_param.force_munmap)
1281 zc0301_requeue_outqueue(cam);
1282
1283 cam->stream = stream;
1284
1285 return 0;
1286}
1287
1288
1289static int
1290zc0301_vidioc_enum_fmt(struct zc0301_device* cam, void __user * arg)
1291{
1292 struct v4l2_fmtdesc fmtd;
1293
1294 if (copy_from_user(&fmtd, arg, sizeof(fmtd)))
1295 return -EFAULT;
1296
1297 if (fmtd.index == 0) {
1298 strcpy(fmtd.description, "JPEG");
1299 fmtd.pixelformat = V4L2_PIX_FMT_JPEG;
1300 fmtd.flags = V4L2_FMT_FLAG_COMPRESSED;
1301 } else
1302 return -EINVAL;
1303
1304 fmtd.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1305 memset(&fmtd.reserved, 0, sizeof(fmtd.reserved));
1306
1307 if (copy_to_user(arg, &fmtd, sizeof(fmtd)))
1308 return -EFAULT;
1309
1310 return 0;
1311}
1312
1313
1314static int
1315zc0301_vidioc_g_fmt(struct zc0301_device* cam, void __user * arg)
1316{
1317 struct v4l2_format format;
1318 struct v4l2_pix_format* pfmt = &(cam->sensor.pix_format);
1319
1320 if (copy_from_user(&format, arg, sizeof(format)))
1321 return -EFAULT;
1322
1323 if (format.type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1324 return -EINVAL;
1325
1326 pfmt->bytesperline = 0;
1327 pfmt->sizeimage = pfmt->height * ((pfmt->width*pfmt->priv)/8);
1328 pfmt->field = V4L2_FIELD_NONE;
1329 memcpy(&(format.fmt.pix), pfmt, sizeof(*pfmt));
1330
1331 if (copy_to_user(arg, &format, sizeof(format)))
1332 return -EFAULT;
1333
1334 return 0;
1335}
1336
1337
1338static int
1339zc0301_vidioc_try_s_fmt(struct zc0301_device* cam, unsigned int cmd,
1340 void __user * arg)
1341{
1342 struct zc0301_sensor* s = &cam->sensor;
1343 struct v4l2_format format;
1344 struct v4l2_pix_format* pix;
1345 struct v4l2_pix_format* pfmt = &(s->pix_format);
1346 struct v4l2_rect* bounds = &(s->cropcap.bounds);
1347 struct v4l2_rect rect;
1348 const enum zc0301_stream_state stream = cam->stream;
1349 const u32 nbuffers = cam->nbuffers;
1350 u32 i;
1351 int err = 0;
1352
1353 if (copy_from_user(&format, arg, sizeof(format)))
1354 return -EFAULT;
1355
1356 pix = &(format.fmt.pix);
1357
1358 if (format.type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1359 return -EINVAL;
1360
1361 memcpy(&rect, &(s->_rect), sizeof(rect));
1362
1363 if (!s->set_crop) {
1364 pix->width = rect.width;
1365 pix->height = rect.height;
1366 } else {
1367 rect.width = pix->width;
1368 rect.height = pix->height;
1369 }
1370
1371 if (rect.width < 8)
1372 rect.width = 8;
1373 if (rect.height < 8)
1374 rect.height = 8;
1375 if (rect.width > bounds->left + bounds->width - rect.left)
1376 rect.width = bounds->left + bounds->width - rect.left;
1377 if (rect.height > bounds->top + bounds->height - rect.top)
1378 rect.height = bounds->top + bounds->height - rect.top;
1379 rect.width &= ~7L;
1380 rect.height &= ~7L;
1381
1382 pix->width = rect.width;
1383 pix->height = rect.height;
1384 pix->pixelformat = pfmt->pixelformat;
1385 pix->priv = pfmt->priv;
1386 pix->colorspace = pfmt->colorspace;
1387 pix->bytesperline = 0;
1388 pix->sizeimage = pix->height * ((pix->width * pix->priv) / 8);
1389 pix->field = V4L2_FIELD_NONE;
1390
1391 if (cmd == VIDIOC_TRY_FMT) {
1392 if (copy_to_user(arg, &format, sizeof(format)))
1393 return -EFAULT;
1394 return 0;
1395 }
1396
1397 if (cam->module_param.force_munmap)
1398 for (i = 0; i < cam->nbuffers; i++)
1399 if (cam->frame[i].vma_use_count) {
1400 DBG(3, "VIDIOC_S_FMT failed. "
1401 "Unmap the buffers first.");
1402 return -EINVAL;
1403 }
1404
1405 if (cam->stream == STREAM_ON)
1406 if ((err = zc0301_stream_interrupt(cam)))
1407 return err;
1408
1409 if (copy_to_user(arg, &format, sizeof(format))) {
1410 cam->stream = stream;
1411 return -EFAULT;
1412 }
1413
1414 if (cam->module_param.force_munmap || cam->io == IO_READ)
1415 zc0301_release_buffers(cam);
1416
1417 if (s->set_crop)
1418 err += s->set_crop(cam, &rect);
1419
1420 if (err) { /* atomic, no rollback in ioctl() */
1421 cam->state |= DEV_MISCONFIGURED;
1422 DBG(1, "VIDIOC_S_FMT failed because of hardware problems. To "
1423 "use the camera, close and open /dev/video%d again.",
1424 cam->v4ldev->minor);
1425 return -EIO;
1426 }
1427
1428 memcpy(pfmt, pix, sizeof(*pix));
1429 memcpy(&(s->_rect), &rect, sizeof(rect));
1430
1431 if ((cam->module_param.force_munmap || cam->io == IO_READ) &&
1432 nbuffers != zc0301_request_buffers(cam, nbuffers, cam->io)) {
1433 cam->state |= DEV_MISCONFIGURED;
1434 DBG(1, "VIDIOC_S_FMT failed because of not enough memory. To "
1435 "use the camera, close and open /dev/video%d again.",
1436 cam->v4ldev->minor);
1437 return -ENOMEM;
1438 }
1439
1440 if (cam->io == IO_READ)
1441 zc0301_empty_framequeues(cam);
1442 else if (cam->module_param.force_munmap)
1443 zc0301_requeue_outqueue(cam);
1444
1445 cam->stream = stream;
1446
1447 return 0;
1448}
1449
1450
1451static int
1452zc0301_vidioc_g_jpegcomp(struct zc0301_device* cam, void __user * arg)
1453{
1454 if (copy_to_user(arg, &cam->compression, sizeof(cam->compression)))
1455 return -EFAULT;
1456
1457 return 0;
1458}
1459
1460
1461static int
1462zc0301_vidioc_s_jpegcomp(struct zc0301_device* cam, void __user * arg)
1463{
1464 struct v4l2_jpegcompression jc;
1465 const enum zc0301_stream_state stream = cam->stream;
1466 int err = 0;
1467
1468 if (copy_from_user(&jc, arg, sizeof(jc)))
1469 return -EFAULT;
1470
1471 if (jc.quality != 0)
1472 return -EINVAL;
1473
1474 if (cam->stream == STREAM_ON)
1475 if ((err = zc0301_stream_interrupt(cam)))
1476 return err;
1477
1478 err += zc0301_set_compression(cam, &jc);
1479 if (err) { /* atomic, no rollback in ioctl() */
1480 cam->state |= DEV_MISCONFIGURED;
1481 DBG(1, "VIDIOC_S_JPEGCOMP failed because of hardware "
1482 "problems. To use the camera, close and open "
1483 "/dev/video%d again.", cam->v4ldev->minor);
1484 return -EIO;
1485 }
1486
1487 cam->compression.quality = jc.quality;
1488
1489 cam->stream = stream;
1490
1491 return 0;
1492}
1493
1494
1495static int
1496zc0301_vidioc_reqbufs(struct zc0301_device* cam, void __user * arg)
1497{
1498 struct v4l2_requestbuffers rb;
1499 u32 i;
1500 int err;
1501
1502 if (copy_from_user(&rb, arg, sizeof(rb)))
1503 return -EFAULT;
1504
1505 if (rb.type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
1506 rb.memory != V4L2_MEMORY_MMAP)
1507 return -EINVAL;
1508
1509 if (cam->io == IO_READ) {
1510 DBG(3, "Close and open the device again to choose the mmap "
1511 "I/O method");
1512 return -EINVAL;
1513 }
1514
1515 for (i = 0; i < cam->nbuffers; i++)
1516 if (cam->frame[i].vma_use_count) {
1517 DBG(3, "VIDIOC_REQBUFS failed. "
1518 "Previous buffers are still mapped.");
1519 return -EINVAL;
1520 }
1521
1522 if (cam->stream == STREAM_ON)
1523 if ((err = zc0301_stream_interrupt(cam)))
1524 return err;
1525
1526 zc0301_empty_framequeues(cam);
1527
1528 zc0301_release_buffers(cam);
1529 if (rb.count)
1530 rb.count = zc0301_request_buffers(cam, rb.count, IO_MMAP);
1531
1532 if (copy_to_user(arg, &rb, sizeof(rb))) {
1533 zc0301_release_buffers(cam);
1534 cam->io = IO_NONE;
1535 return -EFAULT;
1536 }
1537
1538 cam->io = rb.count ? IO_MMAP : IO_NONE;
1539
1540 return 0;
1541}
1542
1543
1544static int
1545zc0301_vidioc_querybuf(struct zc0301_device* cam, void __user * arg)
1546{
1547 struct v4l2_buffer b;
1548
1549 if (copy_from_user(&b, arg, sizeof(b)))
1550 return -EFAULT;
1551
1552 if (b.type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
1553 b.index >= cam->nbuffers || cam->io != IO_MMAP)
1554 return -EINVAL;
1555
1556 memcpy(&b, &cam->frame[b.index].buf, sizeof(b));
1557
1558 if (cam->frame[b.index].vma_use_count)
1559 b.flags |= V4L2_BUF_FLAG_MAPPED;
1560
1561 if (cam->frame[b.index].state == F_DONE)
1562 b.flags |= V4L2_BUF_FLAG_DONE;
1563 else if (cam->frame[b.index].state != F_UNUSED)
1564 b.flags |= V4L2_BUF_FLAG_QUEUED;
1565
1566 if (copy_to_user(arg, &b, sizeof(b)))
1567 return -EFAULT;
1568
1569 return 0;
1570}
1571
1572
1573static int
1574zc0301_vidioc_qbuf(struct zc0301_device* cam, void __user * arg)
1575{
1576 struct v4l2_buffer b;
1577 unsigned long lock_flags;
1578
1579 if (copy_from_user(&b, arg, sizeof(b)))
1580 return -EFAULT;
1581
1582 if (b.type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
1583 b.index >= cam->nbuffers || cam->io != IO_MMAP)
1584 return -EINVAL;
1585
1586 if (cam->frame[b.index].state != F_UNUSED)
1587 return -EINVAL;
1588
1589 cam->frame[b.index].state = F_QUEUED;
1590
1591 spin_lock_irqsave(&cam->queue_lock, lock_flags);
1592 list_add_tail(&cam->frame[b.index].frame, &cam->inqueue);
1593 spin_unlock_irqrestore(&cam->queue_lock, lock_flags);
1594
1595 PDBGG("Frame #%lu queued", (unsigned long)b.index);
1596
1597 return 0;
1598}
1599
1600
1601static int
1602zc0301_vidioc_dqbuf(struct zc0301_device* cam, struct file* filp,
1603 void __user * arg)
1604{
1605 struct v4l2_buffer b;
1606 struct zc0301_frame_t *f;
1607 unsigned long lock_flags;
1608 long timeout;
1609
1610 if (copy_from_user(&b, arg, sizeof(b)))
1611 return -EFAULT;
1612
1613 if (b.type != V4L2_BUF_TYPE_VIDEO_CAPTURE || cam->io!= IO_MMAP)
1614 return -EINVAL;
1615
1616 if (list_empty(&cam->outqueue)) {
1617 if (cam->stream == STREAM_OFF)
1618 return -EINVAL;
1619 if (filp->f_flags & O_NONBLOCK)
1620 return -EAGAIN;
1621 timeout = wait_event_interruptible_timeout
1622 ( cam->wait_frame,
1623 (!list_empty(&cam->outqueue)) ||
1624 (cam->state & DEV_DISCONNECTED) ||
1625 (cam->state & DEV_MISCONFIGURED),
1626 cam->module_param.frame_timeout *
1627 1000 * msecs_to_jiffies(1) );
1628 if (timeout < 0)
1629 return timeout;
1630 if (cam->state & DEV_DISCONNECTED)
1631 return -ENODEV;
1632 if (!timeout || (cam->state & DEV_MISCONFIGURED))
1633 return -EIO;
1634 }
1635
1636 spin_lock_irqsave(&cam->queue_lock, lock_flags);
1637 f = list_entry(cam->outqueue.next, struct zc0301_frame_t, frame);
1638 list_del(cam->outqueue.next);
1639 spin_unlock_irqrestore(&cam->queue_lock, lock_flags);
1640
1641 f->state = F_UNUSED;
1642
1643 memcpy(&b, &f->buf, sizeof(b));
1644 if (f->vma_use_count)
1645 b.flags |= V4L2_BUF_FLAG_MAPPED;
1646
1647 if (copy_to_user(arg, &b, sizeof(b)))
1648 return -EFAULT;
1649
1650 PDBGG("Frame #%lu dequeued", (unsigned long)f->buf.index);
1651
1652 return 0;
1653}
1654
1655
1656static int
1657zc0301_vidioc_streamon(struct zc0301_device* cam, void __user * arg)
1658{
1659 int type;
1660
1661 if (copy_from_user(&type, arg, sizeof(type)))
1662 return -EFAULT;
1663
1664 if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE || cam->io != IO_MMAP)
1665 return -EINVAL;
1666
1667 if (list_empty(&cam->inqueue))
1668 return -EINVAL;
1669
1670 cam->stream = STREAM_ON;
1671
1672 DBG(3, "Stream on");
1673
1674 return 0;
1675}
1676
1677
1678static int
1679zc0301_vidioc_streamoff(struct zc0301_device* cam, void __user * arg)
1680{
1681 int type, err;
1682
1683 if (copy_from_user(&type, arg, sizeof(type)))
1684 return -EFAULT;
1685
1686 if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE || cam->io != IO_MMAP)
1687 return -EINVAL;
1688
1689 if (cam->stream == STREAM_ON)
1690 if ((err = zc0301_stream_interrupt(cam)))
1691 return err;
1692
1693 zc0301_empty_framequeues(cam);
1694
1695 DBG(3, "Stream off");
1696
1697 return 0;
1698}
1699
1700
1701static int
1702zc0301_vidioc_g_parm(struct zc0301_device* cam, void __user * arg)
1703{
1704 struct v4l2_streamparm sp;
1705
1706 if (copy_from_user(&sp, arg, sizeof(sp)))
1707 return -EFAULT;
1708
1709 if (sp.type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1710 return -EINVAL;
1711
1712 sp.parm.capture.extendedmode = 0;
1713 sp.parm.capture.readbuffers = cam->nreadbuffers;
1714
1715 if (copy_to_user(arg, &sp, sizeof(sp)))
1716 return -EFAULT;
1717
1718 return 0;
1719}
1720
1721
1722static int
1723zc0301_vidioc_s_parm(struct zc0301_device* cam, void __user * arg)
1724{
1725 struct v4l2_streamparm sp;
1726
1727 if (copy_from_user(&sp, arg, sizeof(sp)))
1728 return -EFAULT;
1729
1730 if (sp.type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1731 return -EINVAL;
1732
1733 sp.parm.capture.extendedmode = 0;
1734
1735 if (sp.parm.capture.readbuffers == 0)
1736 sp.parm.capture.readbuffers = cam->nreadbuffers;
1737
1738 if (sp.parm.capture.readbuffers > ZC0301_MAX_FRAMES)
1739 sp.parm.capture.readbuffers = ZC0301_MAX_FRAMES;
1740
1741 if (copy_to_user(arg, &sp, sizeof(sp)))
1742 return -EFAULT;
1743
1744 cam->nreadbuffers = sp.parm.capture.readbuffers;
1745
1746 return 0;
1747}
1748
1749
1750static int zc0301_ioctl_v4l2(struct inode* inode, struct file* filp,
1751 unsigned int cmd, void __user * arg)
1752{
1753 struct zc0301_device* cam = video_get_drvdata(video_devdata(filp));
1754
1755 switch (cmd) {
1756
1757 case VIDIOC_QUERYCAP:
1758 return zc0301_vidioc_querycap(cam, arg);
1759
1760 case VIDIOC_ENUMINPUT:
1761 return zc0301_vidioc_enuminput(cam, arg);
1762
1763 case VIDIOC_G_INPUT:
1764 return zc0301_vidioc_g_input(cam, arg);
1765
1766 case VIDIOC_S_INPUT:
1767 return zc0301_vidioc_s_input(cam, arg);
1768
1769 case VIDIOC_QUERYCTRL:
1770 return zc0301_vidioc_query_ctrl(cam, arg);
1771
1772 case VIDIOC_G_CTRL:
1773 return zc0301_vidioc_g_ctrl(cam, arg);
1774
1775 case VIDIOC_S_CTRL_OLD:
1776 case VIDIOC_S_CTRL:
1777 return zc0301_vidioc_s_ctrl(cam, arg);
1778
1779 case VIDIOC_CROPCAP_OLD:
1780 case VIDIOC_CROPCAP:
1781 return zc0301_vidioc_cropcap(cam, arg);
1782
1783 case VIDIOC_G_CROP:
1784 return zc0301_vidioc_g_crop(cam, arg);
1785
1786 case VIDIOC_S_CROP:
1787 return zc0301_vidioc_s_crop(cam, arg);
1788
1789 case VIDIOC_ENUM_FMT:
1790 return zc0301_vidioc_enum_fmt(cam, arg);
1791
1792 case VIDIOC_G_FMT:
1793 return zc0301_vidioc_g_fmt(cam, arg);
1794
1795 case VIDIOC_TRY_FMT:
1796 case VIDIOC_S_FMT:
1797 return zc0301_vidioc_try_s_fmt(cam, cmd, arg);
1798
1799 case VIDIOC_G_JPEGCOMP:
1800 return zc0301_vidioc_g_jpegcomp(cam, arg);
1801
1802 case VIDIOC_S_JPEGCOMP:
1803 return zc0301_vidioc_s_jpegcomp(cam, arg);
1804
1805 case VIDIOC_REQBUFS:
1806 return zc0301_vidioc_reqbufs(cam, arg);
1807
1808 case VIDIOC_QUERYBUF:
1809 return zc0301_vidioc_querybuf(cam, arg);
1810
1811 case VIDIOC_QBUF:
1812 return zc0301_vidioc_qbuf(cam, arg);
1813
1814 case VIDIOC_DQBUF:
1815 return zc0301_vidioc_dqbuf(cam, filp, arg);
1816
1817 case VIDIOC_STREAMON:
1818 return zc0301_vidioc_streamon(cam, arg);
1819
1820 case VIDIOC_STREAMOFF:
1821 return zc0301_vidioc_streamoff(cam, arg);
1822
1823 case VIDIOC_G_PARM:
1824 return zc0301_vidioc_g_parm(cam, arg);
1825
1826 case VIDIOC_S_PARM_OLD:
1827 case VIDIOC_S_PARM:
1828 return zc0301_vidioc_s_parm(cam, arg);
1829
1830 case VIDIOC_G_STD:
1831 case VIDIOC_S_STD:
1832 case VIDIOC_QUERYSTD:
1833 case VIDIOC_ENUMSTD:
1834 case VIDIOC_QUERYMENU:
1835 return -EINVAL;
1836
1837 default:
1838 return -EINVAL;
1839
1840 }
1841}
1842
1843
1844static int zc0301_ioctl(struct inode* inode, struct file* filp,
1845 unsigned int cmd, unsigned long arg)
1846{
1847 struct zc0301_device* cam = video_get_drvdata(video_devdata(filp));
1848 int err = 0;
1849
1850 if (mutex_lock_interruptible(&cam->fileop_mutex))
1851 return -ERESTARTSYS;
1852
1853 if (cam->state & DEV_DISCONNECTED) {
1854 DBG(1, "Device not present");
1855 mutex_unlock(&cam->fileop_mutex);
1856 return -ENODEV;
1857 }
1858
1859 if (cam->state & DEV_MISCONFIGURED) {
1860 DBG(1, "The camera is misconfigured. Close and open it "
1861 "again.");
1862 mutex_unlock(&cam->fileop_mutex);
1863 return -EIO;
1864 }
1865
1866 V4LDBG(3, "zc0301", cmd);
1867
1868 err = zc0301_ioctl_v4l2(inode, filp, cmd, (void __user *)arg);
1869
1870 mutex_unlock(&cam->fileop_mutex);
1871
1872 return err;
1873}
1874
1875
1876static struct file_operations zc0301_fops = {
1877 .owner = THIS_MODULE,
1878 .open = zc0301_open,
1879 .release = zc0301_release,
1880 .ioctl = zc0301_ioctl,
1881 .read = zc0301_read,
1882 .poll = zc0301_poll,
1883 .mmap = zc0301_mmap,
1884 .llseek = no_llseek,
1885};
1886
1887/*****************************************************************************/
1888
1889static int
1890zc0301_usb_probe(struct usb_interface* intf, const struct usb_device_id* id)
1891{
1892 struct usb_device *udev = interface_to_usbdev(intf);
1893 struct zc0301_device* cam;
1894 static unsigned int dev_nr = 0;
1895 unsigned int i;
1896 int err = 0;
1897
1898 if (!(cam = kzalloc(sizeof(struct zc0301_device), GFP_KERNEL)))
1899 return -ENOMEM;
1900
1901 cam->usbdev = udev;
1902
1903 if (!(cam->control_buffer = kzalloc(4, GFP_KERNEL))) {
1904 DBG(1, "kmalloc() failed");
1905 err = -ENOMEM;
1906 goto fail;
1907 }
1908
1909 if (!(cam->v4ldev = video_device_alloc())) {
1910 DBG(1, "video_device_alloc() failed");
1911 err = -ENOMEM;
1912 goto fail;
1913 }
1914
1915 mutex_init(&cam->dev_mutex);
1916
1917 DBG(2, "ZC0301 Image Processor and Control Chip detected "
1918 "(vid/pid 0x%04X/0x%04X)",id->idVendor, id->idProduct);
1919
1920 for (i = 0; zc0301_sensor_table[i]; i++) {
1921 err = zc0301_sensor_table[i](cam);
1922 if (!err)
1923 break;
1924 }
1925
1926 if (!err)
1927 DBG(2, "%s image sensor detected", cam->sensor.name);
1928 else {
1929 DBG(1, "No supported image sensor detected");
1930 err = -ENODEV;
1931 goto fail;
1932 }
1933
1934 if (zc0301_init(cam)) {
1935 DBG(1, "Initialization failed. I will retry on open().");
1936 cam->state |= DEV_MISCONFIGURED;
1937 }
1938
1939 strcpy(cam->v4ldev->name, "ZC0301 PC Camera");
1940 cam->v4ldev->owner = THIS_MODULE;
1941 cam->v4ldev->type = VID_TYPE_CAPTURE | VID_TYPE_SCALES;
1942 cam->v4ldev->hardware = 0;
1943 cam->v4ldev->fops = &zc0301_fops;
1944 cam->v4ldev->minor = video_nr[dev_nr];
1945 cam->v4ldev->release = video_device_release;
1946 video_set_drvdata(cam->v4ldev, cam);
1947
1948 mutex_lock(&cam->dev_mutex);
1949
1950 err = video_register_device(cam->v4ldev, VFL_TYPE_GRABBER,
1951 video_nr[dev_nr]);
1952 if (err) {
1953 DBG(1, "V4L2 device registration failed");
1954 if (err == -ENFILE && video_nr[dev_nr] == -1)
1955 DBG(1, "Free /dev/videoX node not found");
1956 video_nr[dev_nr] = -1;
1957 dev_nr = (dev_nr < ZC0301_MAX_DEVICES-1) ? dev_nr+1 : 0;
1958 mutex_unlock(&cam->dev_mutex);
1959 goto fail;
1960 }
1961
1962 DBG(2, "V4L2 device registered as /dev/video%d", cam->v4ldev->minor);
1963
1964 cam->module_param.force_munmap = force_munmap[dev_nr];
1965 cam->module_param.frame_timeout = frame_timeout[dev_nr];
1966
1967 dev_nr = (dev_nr < ZC0301_MAX_DEVICES-1) ? dev_nr+1 : 0;
1968
1969 usb_set_intfdata(intf, cam);
1970
1971 mutex_unlock(&cam->dev_mutex);
1972
1973 return 0;
1974
1975fail:
1976 if (cam) {
1977 kfree(cam->control_buffer);
1978 if (cam->v4ldev)
1979 video_device_release(cam->v4ldev);
1980 kfree(cam);
1981 }
1982 return err;
1983}
1984
1985
1986static void zc0301_usb_disconnect(struct usb_interface* intf)
1987{
1988 struct zc0301_device* cam = usb_get_intfdata(intf);
1989
1990 if (!cam)
1991 return;
1992
1993 down_write(&zc0301_disconnect);
1994
1995 mutex_lock(&cam->dev_mutex);
1996
1997 DBG(2, "Disconnecting %s...", cam->v4ldev->name);
1998
1999 wake_up_interruptible_all(&cam->open);
2000
2001 if (cam->users) {
2002 DBG(2, "Device /dev/video%d is open! Deregistration and "
2003 "memory deallocation are deferred on close.",
2004 cam->v4ldev->minor);
2005 cam->state |= DEV_MISCONFIGURED;
2006 zc0301_stop_transfer(cam);
2007 cam->state |= DEV_DISCONNECTED;
2008 wake_up_interruptible(&cam->wait_frame);
2009 wake_up(&cam->wait_stream);
2010 usb_get_dev(cam->usbdev);
2011 } else {
2012 cam->state |= DEV_DISCONNECTED;
2013 zc0301_release_resources(cam);
2014 }
2015
2016 mutex_unlock(&cam->dev_mutex);
2017
2018 if (!cam->users)
2019 kfree(cam);
2020
2021 up_write(&zc0301_disconnect);
2022}
2023
2024
2025static struct usb_driver zc0301_usb_driver = {
2026 .name = "zc0301",
2027 .id_table = zc0301_id_table,
2028 .probe = zc0301_usb_probe,
2029 .disconnect = zc0301_usb_disconnect,
2030};
2031
2032/*****************************************************************************/
2033
2034static int __init zc0301_module_init(void)
2035{
2036 int err = 0;
2037
2038 KDBG(2, ZC0301_MODULE_NAME " v" ZC0301_MODULE_VERSION);
2039 KDBG(3, ZC0301_MODULE_AUTHOR);
2040
2041 if ((err = usb_register(&zc0301_usb_driver)))
2042 KDBG(1, "usb_register() failed");
2043
2044 return err;
2045}
2046
2047
2048static void __exit zc0301_module_exit(void)
2049{
2050 usb_deregister(&zc0301_usb_driver);
2051}
2052
2053
2054module_init(zc0301_module_init);
2055module_exit(zc0301_module_exit);
diff --git a/drivers/media/video/zc0301/zc0301_pas202bcb.c b/drivers/media/video/zc0301/zc0301_pas202bcb.c
new file mode 100644
index 000000000000..9d282a22c15f
--- /dev/null
+++ b/drivers/media/video/zc0301/zc0301_pas202bcb.c
@@ -0,0 +1,361 @@
1/***************************************************************************
2 * Plug-in for PAS202BCB image sensor connected to the ZC030! Image *
3 * Processor and Control Chip *
4 * *
5 * Copyright (C) 2006 by Luca Risolia <luca.risolia@studio.unibo.it> *
6 * *
7 * Initialization values of the ZC0301 have been taken from the SPCA5XX *
8 * driver maintained by Michel Xhaard <mxhaard@magic.fr> *
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., 675 Mass Ave, Cambridge, MA 02139, USA. *
23 ***************************************************************************/
24
25/*
26 NOTE: Sensor controls are disabled for now, becouse changing them while
27 streaming sometimes results in out-of-sync video frames. We'll use
28 the default initialization, until we know how to stop and start video
29 in the chip. However, the image quality still looks good under various
30 light conditions.
31*/
32
33#include <linux/delay.h>
34#include "zc0301_sensor.h"
35
36
37static struct zc0301_sensor pas202bcb;
38
39
40static int pas202bcb_init(struct zc0301_device* cam)
41{
42 int err = 0;
43
44 err += zc0301_write_reg(cam, 0x0002, 0x00);
45 err += zc0301_write_reg(cam, 0x0003, 0x02);
46 err += zc0301_write_reg(cam, 0x0004, 0x80);
47 err += zc0301_write_reg(cam, 0x0005, 0x01);
48 err += zc0301_write_reg(cam, 0x0006, 0xE0);
49 err += zc0301_write_reg(cam, 0x0098, 0x00);
50 err += zc0301_write_reg(cam, 0x009A, 0x03);
51 err += zc0301_write_reg(cam, 0x011A, 0x00);
52 err += zc0301_write_reg(cam, 0x011C, 0x03);
53 err += zc0301_write_reg(cam, 0x009B, 0x01);
54 err += zc0301_write_reg(cam, 0x009C, 0xE6);
55 err += zc0301_write_reg(cam, 0x009D, 0x02);
56 err += zc0301_write_reg(cam, 0x009E, 0x86);
57
58 err += zc0301_i2c_write(cam, 0x02, 0x02);
59 err += zc0301_i2c_write(cam, 0x0A, 0x01);
60 err += zc0301_i2c_write(cam, 0x0B, 0x01);
61 err += zc0301_i2c_write(cam, 0x0D, 0x00);
62 err += zc0301_i2c_write(cam, 0x12, 0x05);
63 err += zc0301_i2c_write(cam, 0x13, 0x63);
64 err += zc0301_i2c_write(cam, 0x15, 0x70);
65
66 err += zc0301_write_reg(cam, 0x0101, 0xB7);
67 err += zc0301_write_reg(cam, 0x0100, 0x0D);
68 err += zc0301_write_reg(cam, 0x0189, 0x06);
69 err += zc0301_write_reg(cam, 0x01AD, 0x00);
70 err += zc0301_write_reg(cam, 0x01C5, 0x03);
71 err += zc0301_write_reg(cam, 0x01CB, 0x13);
72 err += zc0301_write_reg(cam, 0x0250, 0x08);
73 err += zc0301_write_reg(cam, 0x0301, 0x08);
74 err += zc0301_write_reg(cam, 0x018D, 0x70);
75 err += zc0301_write_reg(cam, 0x0008, 0x03);
76 err += zc0301_write_reg(cam, 0x01C6, 0x04);
77 err += zc0301_write_reg(cam, 0x01CB, 0x07);
78 err += zc0301_write_reg(cam, 0x0120, 0x11);
79 err += zc0301_write_reg(cam, 0x0121, 0x37);
80 err += zc0301_write_reg(cam, 0x0122, 0x58);
81 err += zc0301_write_reg(cam, 0x0123, 0x79);
82 err += zc0301_write_reg(cam, 0x0124, 0x91);
83 err += zc0301_write_reg(cam, 0x0125, 0xA6);
84 err += zc0301_write_reg(cam, 0x0126, 0xB8);
85 err += zc0301_write_reg(cam, 0x0127, 0xC7);
86 err += zc0301_write_reg(cam, 0x0128, 0xD3);
87 err += zc0301_write_reg(cam, 0x0129, 0xDE);
88 err += zc0301_write_reg(cam, 0x012A, 0xE6);
89 err += zc0301_write_reg(cam, 0x012B, 0xED);
90 err += zc0301_write_reg(cam, 0x012C, 0xF3);
91 err += zc0301_write_reg(cam, 0x012D, 0xF8);
92 err += zc0301_write_reg(cam, 0x012E, 0xFB);
93 err += zc0301_write_reg(cam, 0x012F, 0xFF);
94 err += zc0301_write_reg(cam, 0x0130, 0x26);
95 err += zc0301_write_reg(cam, 0x0131, 0x23);
96 err += zc0301_write_reg(cam, 0x0132, 0x20);
97 err += zc0301_write_reg(cam, 0x0133, 0x1C);
98 err += zc0301_write_reg(cam, 0x0134, 0x16);
99 err += zc0301_write_reg(cam, 0x0135, 0x13);
100 err += zc0301_write_reg(cam, 0x0136, 0x10);
101 err += zc0301_write_reg(cam, 0x0137, 0x0D);
102 err += zc0301_write_reg(cam, 0x0138, 0x0B);
103 err += zc0301_write_reg(cam, 0x0139, 0x09);
104 err += zc0301_write_reg(cam, 0x013A, 0x07);
105 err += zc0301_write_reg(cam, 0x013B, 0x06);
106 err += zc0301_write_reg(cam, 0x013C, 0x05);
107 err += zc0301_write_reg(cam, 0x013D, 0x04);
108 err += zc0301_write_reg(cam, 0x013E, 0x03);
109 err += zc0301_write_reg(cam, 0x013F, 0x02);
110 err += zc0301_write_reg(cam, 0x010A, 0x4C);
111 err += zc0301_write_reg(cam, 0x010B, 0xF5);
112 err += zc0301_write_reg(cam, 0x010C, 0xFF);
113 err += zc0301_write_reg(cam, 0x010D, 0xF9);
114 err += zc0301_write_reg(cam, 0x010E, 0x51);
115 err += zc0301_write_reg(cam, 0x010F, 0xF5);
116 err += zc0301_write_reg(cam, 0x0110, 0xFB);
117 err += zc0301_write_reg(cam, 0x0111, 0xED);
118 err += zc0301_write_reg(cam, 0x0112, 0x5F);
119 err += zc0301_write_reg(cam, 0x0180, 0x00);
120 err += zc0301_write_reg(cam, 0x0019, 0x00);
121 err += zc0301_write_reg(cam, 0x0087, 0x20);
122 err += zc0301_write_reg(cam, 0x0088, 0x21);
123
124 err += zc0301_i2c_write(cam, 0x20, 0x02);
125 err += zc0301_i2c_write(cam, 0x21, 0x1B);
126 err += zc0301_i2c_write(cam, 0x03, 0x44);
127 err += zc0301_i2c_write(cam, 0x0E, 0x01);
128 err += zc0301_i2c_write(cam, 0x0F, 0x00);
129
130 err += zc0301_write_reg(cam, 0x01A9, 0x14);
131 err += zc0301_write_reg(cam, 0x01AA, 0x24);
132 err += zc0301_write_reg(cam, 0x0190, 0x00);
133 err += zc0301_write_reg(cam, 0x0191, 0x02);
134 err += zc0301_write_reg(cam, 0x0192, 0x1B);
135 err += zc0301_write_reg(cam, 0x0195, 0x00);
136 err += zc0301_write_reg(cam, 0x0196, 0x00);
137 err += zc0301_write_reg(cam, 0x0197, 0x4D);
138 err += zc0301_write_reg(cam, 0x018C, 0x10);
139 err += zc0301_write_reg(cam, 0x018F, 0x20);
140 err += zc0301_write_reg(cam, 0x001D, 0x44);
141 err += zc0301_write_reg(cam, 0x001E, 0x6F);
142 err += zc0301_write_reg(cam, 0x001F, 0xAD);
143 err += zc0301_write_reg(cam, 0x0020, 0xEB);
144 err += zc0301_write_reg(cam, 0x0087, 0x0F);
145 err += zc0301_write_reg(cam, 0x0088, 0x0E);
146 err += zc0301_write_reg(cam, 0x0180, 0x40);
147 err += zc0301_write_reg(cam, 0x0192, 0x1B);
148 err += zc0301_write_reg(cam, 0x0191, 0x02);
149 err += zc0301_write_reg(cam, 0x0190, 0x00);
150 err += zc0301_write_reg(cam, 0x0116, 0x1D);
151 err += zc0301_write_reg(cam, 0x0117, 0x40);
152 err += zc0301_write_reg(cam, 0x0118, 0x99);
153 err += zc0301_write_reg(cam, 0x0180, 0x42);
154 err += zc0301_write_reg(cam, 0x0116, 0x1D);
155 err += zc0301_write_reg(cam, 0x0117, 0x40);
156 err += zc0301_write_reg(cam, 0x0118, 0x99);
157 err += zc0301_write_reg(cam, 0x0007, 0x00);
158
159 err += zc0301_i2c_write(cam, 0x11, 0x01);
160
161 msleep(100);
162
163 return err;
164}
165
166
167static int pas202bcb_get_ctrl(struct zc0301_device* cam,
168 struct v4l2_control* ctrl)
169{
170 switch (ctrl->id) {
171 case V4L2_CID_EXPOSURE:
172 {
173 int r1 = zc0301_i2c_read(cam, 0x04, 1),
174 r2 = zc0301_i2c_read(cam, 0x05, 1);
175 if (r1 < 0 || r2 < 0)
176 return -EIO;
177 ctrl->value = (r1 << 6) | (r2 & 0x3f);
178 }
179 return 0;
180 case V4L2_CID_RED_BALANCE:
181 if ((ctrl->value = zc0301_i2c_read(cam, 0x09, 1)) < 0)
182 return -EIO;
183 ctrl->value &= 0x0f;
184 return 0;
185 case V4L2_CID_BLUE_BALANCE:
186 if ((ctrl->value = zc0301_i2c_read(cam, 0x07, 1)) < 0)
187 return -EIO;
188 ctrl->value &= 0x0f;
189 return 0;
190 case V4L2_CID_GAIN:
191 if ((ctrl->value = zc0301_i2c_read(cam, 0x10, 1)) < 0)
192 return -EIO;
193 ctrl->value &= 0x1f;
194 return 0;
195 case ZC0301_V4L2_CID_GREEN_BALANCE:
196 if ((ctrl->value = zc0301_i2c_read(cam, 0x08, 1)) < 0)
197 return -EIO;
198 ctrl->value &= 0x0f;
199 return 0;
200 case ZC0301_V4L2_CID_DAC_MAGNITUDE:
201 if ((ctrl->value = zc0301_i2c_read(cam, 0x0c, 1)) < 0)
202 return -EIO;
203 return 0;
204 default:
205 return -EINVAL;
206 }
207}
208
209
210static int pas202bcb_set_ctrl(struct zc0301_device* cam,
211 const struct v4l2_control* ctrl)
212{
213 int err = 0;
214
215 switch (ctrl->id) {
216 case V4L2_CID_EXPOSURE:
217 err += zc0301_i2c_write(cam, 0x04, ctrl->value >> 6);
218 err += zc0301_i2c_write(cam, 0x05, ctrl->value & 0x3f);
219 break;
220 case V4L2_CID_RED_BALANCE:
221 err += zc0301_i2c_write(cam, 0x09, ctrl->value);
222 break;
223 case V4L2_CID_BLUE_BALANCE:
224 err += zc0301_i2c_write(cam, 0x07, ctrl->value);
225 break;
226 case V4L2_CID_GAIN:
227 err += zc0301_i2c_write(cam, 0x10, ctrl->value);
228 break;
229 case ZC0301_V4L2_CID_GREEN_BALANCE:
230 err += zc0301_i2c_write(cam, 0x08, ctrl->value);
231 break;
232 case ZC0301_V4L2_CID_DAC_MAGNITUDE:
233 err += zc0301_i2c_write(cam, 0x0c, ctrl->value);
234 break;
235 default:
236 return -EINVAL;
237 }
238 err += zc0301_i2c_write(cam, 0x11, 0x01);
239
240 return err ? -EIO : 0;
241}
242
243
244static struct zc0301_sensor pas202bcb = {
245 .name = "PAS202BCB",
246 .init = &pas202bcb_init,
247 .qctrl = {
248 {
249 .id = V4L2_CID_EXPOSURE,
250 .type = V4L2_CTRL_TYPE_INTEGER,
251 .name = "exposure",
252 .minimum = 0x01e5,
253 .maximum = 0x3fff,
254 .step = 0x0001,
255 .default_value = 0x01e5,
256 .flags = V4L2_CTRL_FLAG_DISABLED,
257 },
258 {
259 .id = V4L2_CID_GAIN,
260 .type = V4L2_CTRL_TYPE_INTEGER,
261 .name = "global gain",
262 .minimum = 0x00,
263 .maximum = 0x1f,
264 .step = 0x01,
265 .default_value = 0x0c,
266 .flags = V4L2_CTRL_FLAG_DISABLED,
267 },
268 {
269 .id = ZC0301_V4L2_CID_DAC_MAGNITUDE,
270 .type = V4L2_CTRL_TYPE_INTEGER,
271 .name = "DAC magnitude",
272 .minimum = 0x00,
273 .maximum = 0xff,
274 .step = 0x01,
275 .default_value = 0x00,
276 .flags = V4L2_CTRL_FLAG_DISABLED,
277 },
278 {
279 .id = V4L2_CID_RED_BALANCE,
280 .type = V4L2_CTRL_TYPE_INTEGER,
281 .name = "red balance",
282 .minimum = 0x00,
283 .maximum = 0x0f,
284 .step = 0x01,
285 .default_value = 0x01,
286 .flags = V4L2_CTRL_FLAG_DISABLED,
287 },
288 {
289 .id = V4L2_CID_BLUE_BALANCE,
290 .type = V4L2_CTRL_TYPE_INTEGER,
291 .name = "blue balance",
292 .minimum = 0x00,
293 .maximum = 0x0f,
294 .step = 0x01,
295 .default_value = 0x05,
296 .flags = V4L2_CTRL_FLAG_DISABLED,
297 },
298 {
299 .id = ZC0301_V4L2_CID_GREEN_BALANCE,
300 .type = V4L2_CTRL_TYPE_INTEGER,
301 .name = "green balance",
302 .minimum = 0x00,
303 .maximum = 0x0f,
304 .step = 0x01,
305 .default_value = 0x00,
306 .flags = V4L2_CTRL_FLAG_DISABLED,
307 },
308 },
309 .get_ctrl = &pas202bcb_get_ctrl,
310 .set_ctrl = &pas202bcb_set_ctrl,
311 .cropcap = {
312 .bounds = {
313 .left = 0,
314 .top = 0,
315 .width = 640,
316 .height = 480,
317 },
318 .defrect = {
319 .left = 0,
320 .top = 0,
321 .width = 640,
322 .height = 480,
323 },
324 },
325 .pix_format = {
326 .width = 640,
327 .height = 480,
328 .pixelformat = V4L2_PIX_FMT_JPEG,
329 .priv = 8,
330 },
331};
332
333
334int zc0301_probe_pas202bcb(struct zc0301_device* cam)
335{
336 int r0 = 0, r1 = 0, err = 0;
337 unsigned int pid = 0;
338
339 err += zc0301_write_reg(cam, 0x0000, 0x01);
340 err += zc0301_write_reg(cam, 0x0010, 0x0e);
341 err += zc0301_write_reg(cam, 0x0001, 0x01);
342 err += zc0301_write_reg(cam, 0x0012, 0x03);
343 err += zc0301_write_reg(cam, 0x0012, 0x01);
344 err += zc0301_write_reg(cam, 0x008d, 0x08);
345
346 msleep(10);
347
348 r0 = zc0301_i2c_read(cam, 0x00, 1);
349 r1 = zc0301_i2c_read(cam, 0x01, 1);
350
351 if (r0 < 0 || r1 < 0 || err)
352 return -EIO;
353
354 pid = (r0 << 4) | ((r1 & 0xf0) >> 4);
355 if (pid != 0x017)
356 return -ENODEV;
357
358 zc0301_attach_sensor(cam, &pas202bcb);
359
360 return 0;
361}
diff --git a/drivers/media/video/zc0301/zc0301_sensor.h b/drivers/media/video/zc0301/zc0301_sensor.h
new file mode 100644
index 000000000000..cf0965a81d01
--- /dev/null
+++ b/drivers/media/video/zc0301/zc0301_sensor.h
@@ -0,0 +1,103 @@
1/***************************************************************************
2 * API for image sensors connected to the ZC030! Image Processor and *
3 * Control Chip *
4 * *
5 * Copyright (C) 2006 by Luca Risolia <luca.risolia@studio.unibo.it> *
6 * *
7 * This program is free software; you can redistribute it and/or modify *
8 * it under the terms of the GNU General Public License as published by *
9 * the Free Software Foundation; either version 2 of the License, or *
10 * (at your option) any later version. *
11 * *
12 * This program is distributed in the hope that it will be useful, *
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15 * GNU General Public License for more details. *
16 * *
17 * You should have received a copy of the GNU General Public License *
18 * along with this program; if not, write to the Free Software *
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
20 ***************************************************************************/
21
22#ifndef _ZC0301_SENSOR_H_
23#define _ZC0301_SENSOR_H_
24
25#include <linux/usb.h>
26#include <linux/videodev.h>
27#include <linux/device.h>
28#include <linux/stddef.h>
29#include <linux/errno.h>
30#include <asm/types.h>
31
32struct zc0301_device;
33struct zc0301_sensor;
34
35/*****************************************************************************/
36
37extern int zc0301_probe_pas202bcb(struct zc0301_device* cam);
38
39#define ZC0301_SENSOR_TABLE \
40/* Weak detections must go at the end of the list */ \
41static int (*zc0301_sensor_table[])(struct zc0301_device*) = { \
42 &zc0301_probe_pas202bcb, \
43 NULL, \
44};
45
46extern struct zc0301_device*
47zc0301_match_id(struct zc0301_device* cam, const struct usb_device_id *id);
48
49extern void
50zc0301_attach_sensor(struct zc0301_device* cam, struct zc0301_sensor* sensor);
51
52#define ZC0301_USB_DEVICE(vend, prod, intclass) \
53 .match_flags = USB_DEVICE_ID_MATCH_DEVICE | \
54 USB_DEVICE_ID_MATCH_INT_CLASS, \
55 .idVendor = (vend), \
56 .idProduct = (prod), \
57 .bInterfaceClass = (intclass)
58
59#define ZC0301_ID_TABLE \
60static const struct usb_device_id zc0301_id_table[] = { \
61 { ZC0301_USB_DEVICE(0x041e, 0x4017, 0xff), }, \
62 { ZC0301_USB_DEVICE(0x041e, 0x401c, 0xff), }, /* PAS106 */ \
63 { ZC0301_USB_DEVICE(0x041e, 0x401e, 0xff), }, /* HV7131B */ \
64 { ZC0301_USB_DEVICE(0x041e, 0x4034, 0xff), }, /* PAS106 */ \
65 { ZC0301_USB_DEVICE(0x041e, 0x4035, 0xff), }, /* PAS106 */ \
66 { ZC0301_USB_DEVICE(0x046d, 0x08ae, 0xff), }, /* PAS202BCB */ \
67 { ZC0301_USB_DEVICE(0x0ac8, 0x0301, 0xff), }, \
68 { ZC0301_USB_DEVICE(0x10fd, 0x8050, 0xff), }, /* TAS5130D */ \
69 { } \
70};
71
72/*****************************************************************************/
73
74extern int zc0301_write_reg(struct zc0301_device*, u16 index, u16 value);
75extern int zc0301_read_reg(struct zc0301_device*, u16 index);
76extern int zc0301_i2c_write(struct zc0301_device*, u16 address, u16 value);
77extern int zc0301_i2c_read(struct zc0301_device*, u16 address, u8 length);
78
79/*****************************************************************************/
80
81#define ZC0301_MAX_CTRLS V4L2_CID_LASTP1-V4L2_CID_BASE+10
82#define ZC0301_V4L2_CID_DAC_MAGNITUDE V4L2_CID_PRIVATE_BASE
83#define ZC0301_V4L2_CID_GREEN_BALANCE V4L2_CID_PRIVATE_BASE + 1
84
85struct zc0301_sensor {
86 char name[32];
87
88 struct v4l2_queryctrl qctrl[ZC0301_MAX_CTRLS];
89 struct v4l2_cropcap cropcap;
90 struct v4l2_pix_format pix_format;
91
92 int (*init)(struct zc0301_device*);
93 int (*get_ctrl)(struct zc0301_device*, struct v4l2_control* ctrl);
94 int (*set_ctrl)(struct zc0301_device*,
95 const struct v4l2_control* ctrl);
96 int (*set_crop)(struct zc0301_device*, const struct v4l2_rect* rect);
97
98 /* Private */
99 struct v4l2_queryctrl _qctrl[ZC0301_MAX_CTRLS];
100 struct v4l2_rect _rect;
101};
102
103#endif /* _ZC0301_SENSOR_H_ */