aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video
diff options
context:
space:
mode:
authorTony Lindgren <tony@atomide.com>2010-03-01 17:19:05 -0500
committerTony Lindgren <tony@atomide.com>2010-03-01 17:19:05 -0500
commitd702d12167a2c05a346f49aac7a311d597762495 (patch)
treebaae42c299cce34d6df24b5d01f8b1d0b481bd9a /drivers/media/video
parent9418c65f9bd861d0f7e39aab9cfb3aa6f2275d11 (diff)
parentac0f6f927db539e03e1f3f61bcd4ed57d5cde7a9 (diff)
Merge with mainline to remove plat-omap/Kconfig conflict
Conflicts: arch/arm/plat-omap/Kconfig
Diffstat (limited to 'drivers/media/video')
-rw-r--r--drivers/media/video/Kconfig36
-rw-r--r--drivers/media/video/Makefile2
-rw-r--r--drivers/media/video/bt819.c10
-rw-r--r--drivers/media/video/bt8xx/bttv-driver.c8
-rw-r--r--drivers/media/video/bt8xx/bttv-i2c.c8
-rw-r--r--drivers/media/video/bt8xx/bttv-input.c4
-rw-r--r--drivers/media/video/bt8xx/bttvp.h1
-rw-r--r--drivers/media/video/cafe_ccic.c6
-rw-r--r--drivers/media/video/cpia.c3
-rw-r--r--drivers/media/video/cx18/Kconfig11
-rw-r--r--drivers/media/video/cx18/Makefile2
-rw-r--r--drivers/media/video/cx18/cx18-alsa-main.c293
-rw-r--r--drivers/media/video/cx18/cx18-alsa-mixer.c175
-rw-r--r--drivers/media/video/cx18/cx18-alsa-mixer.h23
-rw-r--r--drivers/media/video/cx18/cx18-alsa-pcm.c354
-rw-r--r--drivers/media/video/cx18/cx18-alsa-pcm.h27
-rw-r--r--drivers/media/video/cx18/cx18-alsa.h75
-rw-r--r--drivers/media/video/cx18/cx18-cards.c2
-rw-r--r--drivers/media/video/cx18/cx18-driver.c70
-rw-r--r--drivers/media/video/cx18/cx18-driver.h50
-rw-r--r--drivers/media/video/cx18/cx18-dvb.c22
-rw-r--r--drivers/media/video/cx18/cx18-fileops.c205
-rw-r--r--drivers/media/video/cx18/cx18-fileops.h3
-rw-r--r--drivers/media/video/cx18/cx18-ioctl.c135
-rw-r--r--drivers/media/video/cx18/cx18-mailbox.c45
-rw-r--r--drivers/media/video/cx18/cx18-queue.c3
-rw-r--r--drivers/media/video/cx18/cx18-streams.c72
-rw-r--r--drivers/media/video/cx18/cx18-streams.h10
-rw-r--r--drivers/media/video/cx18/cx18-version.h2
-rw-r--r--drivers/media/video/cx18/cx23418.h3
-rw-r--r--drivers/media/video/cx231xx/cx231xx-dvb.c8
-rw-r--r--drivers/media/video/cx231xx/cx231xx-input.c2
-rw-r--r--drivers/media/video/cx23885/cx23885-417.c4
-rw-r--r--drivers/media/video/cx23885/cx23885-cards.c32
-rw-r--r--drivers/media/video/cx23885/cx23885-dvb.c17
-rw-r--r--drivers/media/video/cx23885/cx23885-input.c2
-rw-r--r--drivers/media/video/cx23885/cx23885-video.c13
-rw-r--r--drivers/media/video/cx23885/cx23885.h1
-rw-r--r--drivers/media/video/cx25840/cx25840-core.c54
-rw-r--r--drivers/media/video/cx88/cx88-alsa.c10
-rw-r--r--drivers/media/video/cx88/cx88-cards.c23
-rw-r--r--drivers/media/video/cx88/cx88-dvb.c214
-rw-r--r--drivers/media/video/cx88/cx88-input.c4
-rw-r--r--drivers/media/video/cx88/cx88-mpeg.c3
-rw-r--r--drivers/media/video/cx88/cx88.h1
-rw-r--r--drivers/media/video/dabusb.c2
-rw-r--r--drivers/media/video/davinci/Makefile1
-rw-r--r--drivers/media/video/davinci/dm355_ccdc.c410
-rw-r--r--drivers/media/video/davinci/dm644x_ccdc.c361
-rw-r--r--drivers/media/video/davinci/isif.c1172
-rw-r--r--drivers/media/video/davinci/isif_regs.h269
-rw-r--r--drivers/media/video/davinci/vpfe_capture.c131
-rw-r--r--drivers/media/video/davinci/vpss.c289
-rw-r--r--drivers/media/video/em28xx/em28xx-cards.c80
-rw-r--r--drivers/media/video/em28xx/em28xx-core.c19
-rw-r--r--drivers/media/video/em28xx/em28xx-dvb.c3
-rw-r--r--drivers/media/video/em28xx/em28xx-input.c113
-rw-r--r--drivers/media/video/em28xx/em28xx-reg.h4
-rw-r--r--drivers/media/video/em28xx/em28xx-vbi.c17
-rw-r--r--drivers/media/video/em28xx/em28xx-video.c58
-rw-r--r--drivers/media/video/em28xx/em28xx.h6
-rw-r--r--drivers/media/video/et61x251/Kconfig6
-rw-r--r--drivers/media/video/gspca/Kconfig46
-rw-r--r--drivers/media/video/gspca/Makefile8
-rw-r--r--drivers/media/video/gspca/benq.c322
-rw-r--r--drivers/media/video/gspca/coarse_expo_autogain.h116
-rw-r--r--drivers/media/video/gspca/conex.c4
-rw-r--r--drivers/media/video/gspca/cpia1.c2022
-rw-r--r--drivers/media/video/gspca/etoms.c4
-rw-r--r--drivers/media/video/gspca/gl860/gl860.c10
-rw-r--r--drivers/media/video/gspca/gspca.c259
-rw-r--r--drivers/media/video/gspca/gspca.h30
-rw-r--r--drivers/media/video/gspca/m5602/m5602_mt9m111.c4
-rw-r--r--drivers/media/video/gspca/m5602/m5602_ov7660.c2
-rw-r--r--drivers/media/video/gspca/m5602/m5602_ov7660.h2
-rw-r--r--drivers/media/video/gspca/m5602/m5602_ov9650.c2
-rw-r--r--drivers/media/video/gspca/m5602/m5602_po1030.c2
-rw-r--r--drivers/media/video/gspca/m5602/m5602_s5k4aa.c2
-rw-r--r--drivers/media/video/gspca/m5602/m5602_s5k83a.c2
-rw-r--r--drivers/media/video/gspca/mars.c2
-rw-r--r--drivers/media/video/gspca/mr97310a.c226
-rw-r--r--drivers/media/video/gspca/ov519.c151
-rw-r--r--drivers/media/video/gspca/ov534.c1253
-rw-r--r--drivers/media/video/gspca/ov534_9.c1477
-rw-r--r--drivers/media/video/gspca/pac207.c25
-rw-r--r--drivers/media/video/gspca/pac7302.c411
-rw-r--r--drivers/media/video/gspca/pac7311.c251
-rw-r--r--drivers/media/video/gspca/pac_common.h9
-rw-r--r--drivers/media/video/gspca/sn9c2028.c757
-rw-r--r--drivers/media/video/gspca/sn9c2028.h51
-rw-r--r--drivers/media/video/gspca/sn9c20x.c33
-rw-r--r--drivers/media/video/gspca/sonixb.c451
-rw-r--r--drivers/media/video/gspca/sonixj.c341
-rw-r--r--drivers/media/video/gspca/spca500.c4
-rw-r--r--drivers/media/video/gspca/spca501.c2
-rw-r--r--drivers/media/video/gspca/spca505.c2
-rw-r--r--drivers/media/video/gspca/spca506.c4
-rw-r--r--drivers/media/video/gspca/spca508.c2
-rw-r--r--drivers/media/video/gspca/spca561.c4
-rw-r--r--drivers/media/video/gspca/sq905c.c45
-rw-r--r--drivers/media/video/gspca/stk014.c2
-rw-r--r--drivers/media/video/gspca/stv0680.c16
-rw-r--r--drivers/media/video/gspca/stv06xx/stv06xx.c32
-rw-r--r--drivers/media/video/gspca/sunplus.c186
-rw-r--r--drivers/media/video/gspca/t613.c51
-rw-r--r--drivers/media/video/gspca/tv8532.c2
-rw-r--r--drivers/media/video/gspca/vc032x.c694
-rw-r--r--drivers/media/video/gspca/zc3xx.c679
-rw-r--r--drivers/media/video/hdpvr/hdpvr-core.c5
-rw-r--r--drivers/media/video/hdpvr/hdpvr-video.c5
-rw-r--r--drivers/media/video/hdpvr/hdpvr.h1
-rw-r--r--drivers/media/video/hexium_gemini.c9
-rw-r--r--drivers/media/video/hexium_orion.c4
-rw-r--r--drivers/media/video/ir-kbd-i2c.c5
-rw-r--r--drivers/media/video/ivtv/ivtv-cards.c48
-rw-r--r--drivers/media/video/ivtv/ivtv-cards.h4
-rw-r--r--drivers/media/video/ivtv/ivtv-driver.c1
-rw-r--r--drivers/media/video/ivtv/ivtv-firmware.c2
-rw-r--r--drivers/media/video/ivtv/ivtv-irq.c14
-rw-r--r--drivers/media/video/ivtv/ivtv-mailbox.c9
-rw-r--r--drivers/media/video/ivtv/ivtv-mailbox.h3
-rw-r--r--drivers/media/video/ivtv/ivtv-streams.c6
-rw-r--r--drivers/media/video/ivtv/ivtv-udma.c1
-rw-r--r--drivers/media/video/mt9t112.c2
-rw-r--r--drivers/media/video/mt9v022.c17
-rw-r--r--drivers/media/video/mxb.c10
-rw-r--r--drivers/media/video/ov772x.c22
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h12
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-hdw.c53
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-hdw.h1
-rw-r--r--drivers/media/video/pwc/pwc-ctrl.c2
-rw-r--r--drivers/media/video/pxa_camera.c10
-rw-r--r--drivers/media/video/rj54n1cb0c.c12
-rw-r--r--drivers/media/video/saa7115.c27
-rw-r--r--drivers/media/video/saa7127.c47
-rw-r--r--drivers/media/video/saa7134/saa7134-cards.c52
-rw-r--r--drivers/media/video/saa7134/saa7134-input.c7
-rw-r--r--drivers/media/video/saa7134/saa7134-video.c2
-rw-r--r--drivers/media/video/saa7134/saa7134.h3
-rw-r--r--drivers/media/video/saa7164/saa7164-api.c2
-rw-r--r--drivers/media/video/sh_mobile_ceu_camera.c18
-rw-r--r--drivers/media/video/sn9c102/Kconfig5
-rw-r--r--drivers/media/video/sn9c102/sn9c102_devtable.h6
-rw-r--r--drivers/media/video/soc_camera.c36
-rw-r--r--drivers/media/video/soc_mediabus.c48
-rw-r--r--drivers/media/video/tlg2300/Kconfig16
-rw-r--r--drivers/media/video/tlg2300/Makefile9
-rw-r--r--drivers/media/video/tlg2300/pd-alsa.c332
-rw-r--r--drivers/media/video/tlg2300/pd-common.h282
-rw-r--r--drivers/media/video/tlg2300/pd-dvb.c593
-rw-r--r--drivers/media/video/tlg2300/pd-main.c539
-rw-r--r--drivers/media/video/tlg2300/pd-radio.c420
-rw-r--r--drivers/media/video/tlg2300/pd-video.c1667
-rw-r--r--drivers/media/video/tlg2300/vendorcmds.h243
-rw-r--r--drivers/media/video/tuner-core.c1
-rw-r--r--drivers/media/video/tveeprom.c5
-rw-r--r--drivers/media/video/tvp7002.c1187
-rw-r--r--drivers/media/video/tvp7002_reg.h150
-rw-r--r--drivers/media/video/tw9910.c8
-rw-r--r--drivers/media/video/usbvision/usbvision-video.c2
-rw-r--r--drivers/media/video/uvc/uvc_ctrl.c242
-rw-r--r--drivers/media/video/uvc/uvc_driver.c74
-rw-r--r--drivers/media/video/uvc/uvc_queue.c1
-rw-r--r--drivers/media/video/uvc/uvc_v4l2.c4
-rw-r--r--drivers/media/video/uvc/uvc_video.c10
-rw-r--r--drivers/media/video/uvc/uvcvideo.h19
-rw-r--r--drivers/media/video/v4l2-compat-ioctl32.c5
-rw-r--r--drivers/media/video/videobuf-dma-sg.c2
-rw-r--r--drivers/media/video/videobuf-vmalloc.c2
-rw-r--r--drivers/media/video/vivi.c2
-rw-r--r--drivers/media/video/zc0301/Kconfig6
-rw-r--r--drivers/media/video/zoran/zoran_device.c6
-rw-r--r--drivers/media/video/zoran/zoran_driver.c4
-rw-r--r--drivers/media/video/zr364xx.c37
174 files changed, 17982 insertions, 3386 deletions
diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig
index 2f83be766d9f..f8fc8654693d 100644
--- a/drivers/media/video/Kconfig
+++ b/drivers/media/video/Kconfig
@@ -388,6 +388,15 @@ config VIDEO_TVP5150
388 To compile this driver as a module, choose M here: the 388 To compile this driver as a module, choose M here: the
389 module will be called tvp5150. 389 module will be called tvp5150.
390 390
391config VIDEO_TVP7002
392 tristate "Texas Instruments TVP7002 video decoder"
393 depends on VIDEO_V4L2 && I2C
394 ---help---
395 Support for the Texas Instruments TVP7002 video decoder.
396
397 To compile this driver as a module, choose M here: the
398 module will be called tvp7002.
399
391config VIDEO_VPX3220 400config VIDEO_VPX3220
392 tristate "vpx3220a, vpx3216b & vpx3214c video decoders" 401 tristate "vpx3220a, vpx3216b & vpx3214c video decoders"
393 depends on VIDEO_V4L2 && I2C 402 depends on VIDEO_V4L2 && I2C
@@ -548,7 +557,6 @@ config VIDEO_VPSS_SYSTEM
548 depends on ARCH_DAVINCI 557 depends on ARCH_DAVINCI
549 help 558 help
550 Support for vpss system module for video driver 559 Support for vpss system module for video driver
551 default y
552 560
553config VIDEO_VPFE_CAPTURE 561config VIDEO_VPFE_CAPTURE
554 tristate "VPFE Video Capture Driver" 562 tristate "VPFE Video Capture Driver"
@@ -592,6 +600,19 @@ config VIDEO_DM355_CCDC
592 To compile this driver as a module, choose M here: the 600 To compile this driver as a module, choose M here: the
593 module will be called vpfe. 601 module will be called vpfe.
594 602
603config VIDEO_ISIF
604 tristate "ISIF HW module"
605 depends on ARCH_DAVINCI_DM365 && VIDEO_VPFE_CAPTURE
606 select VIDEO_VPSS_SYSTEM
607 default y
608 help
609 Enables ISIF hw module. This is the hardware module for
610 configuring ISIF in VPFE to capture Raw Bayer RGB data from
611 a image sensor or YUV data from a YUV source.
612
613 To compile this driver as a module, choose M here: the
614 module will be called vpfe.
615
595source "drivers/media/video/bt8xx/Kconfig" 616source "drivers/media/video/bt8xx/Kconfig"
596 617
597config VIDEO_PMS 618config VIDEO_PMS
@@ -638,9 +659,14 @@ config VIDEO_W9966
638 information. 659 information.
639 660
640config VIDEO_CPIA 661config VIDEO_CPIA
641 tristate "CPiA Video For Linux" 662 tristate "CPiA Video For Linux (DEPRECATED)"
642 depends on VIDEO_V4L1 663 depends on VIDEO_V4L1
664 default n
643 ---help--- 665 ---help---
666 This driver is DEPRECATED please use the gspca cpia1 module
667 instead. Note that you need atleast version 0.6.4 of libv4l for
668 the cpia1 gspca module.
669
644 This is the video4linux driver for cameras based on Vision's CPiA 670 This is the video4linux driver for cameras based on Vision's CPiA
645 (Colour Processor Interface ASIC), such as the Creative Labs Video 671 (Colour Processor Interface ASIC), such as the Creative Labs Video
646 Blaster Webcam II. If you have one of these cameras, say Y here 672 Blaster Webcam II. If you have one of these cameras, say Y here
@@ -944,6 +970,8 @@ source "drivers/media/video/hdpvr/Kconfig"
944 970
945source "drivers/media/video/em28xx/Kconfig" 971source "drivers/media/video/em28xx/Kconfig"
946 972
973source "drivers/media/video/tlg2300/Kconfig"
974
947source "drivers/media/video/cx231xx/Kconfig" 975source "drivers/media/video/cx231xx/Kconfig"
948 976
949source "drivers/media/video/usbvision/Kconfig" 977source "drivers/media/video/usbvision/Kconfig"
@@ -955,6 +983,7 @@ source "drivers/media/video/et61x251/Kconfig"
955config VIDEO_OVCAMCHIP 983config VIDEO_OVCAMCHIP
956 tristate "OmniVision Camera Chip support (DEPRECATED)" 984 tristate "OmniVision Camera Chip support (DEPRECATED)"
957 depends on I2C && VIDEO_V4L1 985 depends on I2C && VIDEO_V4L1
986 default n
958 ---help--- 987 ---help---
959 This driver is DEPRECATED please use the gspca ov519 module 988 This driver is DEPRECATED please use the gspca ov519 module
960 instead. Note that for the ov511 / ov518 support of the gspca module 989 instead. Note that for the ov511 / ov518 support of the gspca module
@@ -971,6 +1000,7 @@ config VIDEO_OVCAMCHIP
971config USB_W9968CF 1000config USB_W9968CF
972 tristate "USB W996[87]CF JPEG Dual Mode Camera support (DEPRECATED)" 1001 tristate "USB W996[87]CF JPEG Dual Mode Camera support (DEPRECATED)"
973 depends on VIDEO_V4L1 && I2C && VIDEO_OVCAMCHIP 1002 depends on VIDEO_V4L1 && I2C && VIDEO_OVCAMCHIP
1003 default n
974 ---help--- 1004 ---help---
975 This driver is DEPRECATED please use the gspca ov519 module 1005 This driver is DEPRECATED please use the gspca ov519 module
976 instead. Note that for the w9968cf support of the gspca module 1006 instead. Note that for the w9968cf support of the gspca module
@@ -992,6 +1022,7 @@ config USB_W9968CF
992config USB_OV511 1022config USB_OV511
993 tristate "USB OV511 Camera support (DEPRECATED)" 1023 tristate "USB OV511 Camera support (DEPRECATED)"
994 depends on VIDEO_V4L1 1024 depends on VIDEO_V4L1
1025 default n
995 ---help--- 1026 ---help---
996 This driver is DEPRECATED please use the gspca ov519 module 1027 This driver is DEPRECATED please use the gspca ov519 module
997 instead. Note that for the ov511 / ov518 support of the gspca module 1028 instead. Note that for the ov511 / ov518 support of the gspca module
@@ -1020,6 +1051,7 @@ source "drivers/media/video/sn9c102/Kconfig"
1020config USB_STV680 1051config USB_STV680
1021 tristate "USB STV680 (Pencam) Camera support (DEPRECATED)" 1052 tristate "USB STV680 (Pencam) Camera support (DEPRECATED)"
1022 depends on VIDEO_V4L1 1053 depends on VIDEO_V4L1
1054 default n
1023 ---help--- 1055 ---help---
1024 This driver is DEPRECATED please use the gspca stv0680 module 1056 This driver is DEPRECATED please use the gspca stv0680 module
1025 instead. Note that for the gspca stv0680 module you need 1057 instead. Note that for the gspca stv0680 module you need
diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile
index 2af68ee84122..b88b6174a331 100644
--- a/drivers/media/video/Makefile
+++ b/drivers/media/video/Makefile
@@ -56,6 +56,7 @@ obj-$(CONFIG_VIDEO_THS7303) += ths7303.o
56obj-$(CONFIG_VIDEO_VINO) += indycam.o 56obj-$(CONFIG_VIDEO_VINO) += indycam.o
57obj-$(CONFIG_VIDEO_TVP5150) += tvp5150.o 57obj-$(CONFIG_VIDEO_TVP5150) += tvp5150.o
58obj-$(CONFIG_VIDEO_TVP514X) += tvp514x.o 58obj-$(CONFIG_VIDEO_TVP514X) += tvp514x.o
59obj-$(CONFIG_VIDEO_TVP7002) += tvp7002.o
59obj-$(CONFIG_VIDEO_MSP3400) += msp3400.o 60obj-$(CONFIG_VIDEO_MSP3400) += msp3400.o
60obj-$(CONFIG_VIDEO_CS5345) += cs5345.o 61obj-$(CONFIG_VIDEO_CS5345) += cs5345.o
61obj-$(CONFIG_VIDEO_CS53L32A) += cs53l32a.o 62obj-$(CONFIG_VIDEO_CS53L32A) += cs53l32a.o
@@ -99,6 +100,7 @@ obj-$(CONFIG_VIDEO_MEYE) += meye.o
99obj-$(CONFIG_VIDEO_SAA7134) += saa7134/ 100obj-$(CONFIG_VIDEO_SAA7134) += saa7134/
100obj-$(CONFIG_VIDEO_CX88) += cx88/ 101obj-$(CONFIG_VIDEO_CX88) += cx88/
101obj-$(CONFIG_VIDEO_EM28XX) += em28xx/ 102obj-$(CONFIG_VIDEO_EM28XX) += em28xx/
103obj-$(CONFIG_VIDEO_TLG2300) += tlg2300/
102obj-$(CONFIG_VIDEO_CX231XX) += cx231xx/ 104obj-$(CONFIG_VIDEO_CX231XX) += cx231xx/
103obj-$(CONFIG_VIDEO_USBVISION) += usbvision/ 105obj-$(CONFIG_VIDEO_USBVISION) += usbvision/
104obj-$(CONFIG_VIDEO_PVRUSB2) += pvrusb2/ 106obj-$(CONFIG_VIDEO_PVRUSB2) += pvrusb2/
diff --git a/drivers/media/video/bt819.c b/drivers/media/video/bt819.c
index 5bb0f9e71583..547e1a93c421 100644
--- a/drivers/media/video/bt819.c
+++ b/drivers/media/video/bt819.c
@@ -254,7 +254,7 @@ static int bt819_s_std(struct v4l2_subdev *sd, v4l2_std_id std)
254 v4l2_err(sd, "no notify found!\n"); 254 v4l2_err(sd, "no notify found!\n");
255 255
256 if (std & V4L2_STD_NTSC) { 256 if (std & V4L2_STD_NTSC) {
257 v4l2_subdev_notify(sd, BT819_FIFO_RESET_LOW, 0); 257 v4l2_subdev_notify(sd, BT819_FIFO_RESET_LOW, NULL);
258 bt819_setbit(decoder, 0x01, 0, 1); 258 bt819_setbit(decoder, 0x01, 0, 1);
259 bt819_setbit(decoder, 0x01, 1, 0); 259 bt819_setbit(decoder, 0x01, 1, 0);
260 bt819_setbit(decoder, 0x01, 5, 0); 260 bt819_setbit(decoder, 0x01, 5, 0);
@@ -263,7 +263,7 @@ static int bt819_s_std(struct v4l2_subdev *sd, v4l2_std_id std)
263 /* bt819_setbit(decoder, 0x1a, 5, 1); */ 263 /* bt819_setbit(decoder, 0x1a, 5, 1); */
264 timing = &timing_data[1]; 264 timing = &timing_data[1];
265 } else if (std & V4L2_STD_PAL) { 265 } else if (std & V4L2_STD_PAL) {
266 v4l2_subdev_notify(sd, BT819_FIFO_RESET_LOW, 0); 266 v4l2_subdev_notify(sd, BT819_FIFO_RESET_LOW, NULL);
267 bt819_setbit(decoder, 0x01, 0, 1); 267 bt819_setbit(decoder, 0x01, 0, 1);
268 bt819_setbit(decoder, 0x01, 1, 1); 268 bt819_setbit(decoder, 0x01, 1, 1);
269 bt819_setbit(decoder, 0x01, 5, 1); 269 bt819_setbit(decoder, 0x01, 5, 1);
@@ -288,7 +288,7 @@ static int bt819_s_std(struct v4l2_subdev *sd, v4l2_std_id std)
288 bt819_write(decoder, 0x08, (timing->hscale >> 8) & 0xff); 288 bt819_write(decoder, 0x08, (timing->hscale >> 8) & 0xff);
289 bt819_write(decoder, 0x09, timing->hscale & 0xff); 289 bt819_write(decoder, 0x09, timing->hscale & 0xff);
290 decoder->norm = std; 290 decoder->norm = std;
291 v4l2_subdev_notify(sd, BT819_FIFO_RESET_HIGH, 0); 291 v4l2_subdev_notify(sd, BT819_FIFO_RESET_HIGH, NULL);
292 return 0; 292 return 0;
293} 293}
294 294
@@ -306,7 +306,7 @@ static int bt819_s_routing(struct v4l2_subdev *sd,
306 v4l2_err(sd, "no notify found!\n"); 306 v4l2_err(sd, "no notify found!\n");
307 307
308 if (decoder->input != input) { 308 if (decoder->input != input) {
309 v4l2_subdev_notify(sd, BT819_FIFO_RESET_LOW, 0); 309 v4l2_subdev_notify(sd, BT819_FIFO_RESET_LOW, NULL);
310 decoder->input = input; 310 decoder->input = input;
311 /* select mode */ 311 /* select mode */
312 if (decoder->input == 0) { 312 if (decoder->input == 0) {
@@ -316,7 +316,7 @@ static int bt819_s_routing(struct v4l2_subdev *sd,
316 bt819_setbit(decoder, 0x0b, 6, 1); 316 bt819_setbit(decoder, 0x0b, 6, 1);
317 bt819_setbit(decoder, 0x1a, 1, 0); 317 bt819_setbit(decoder, 0x1a, 1, 0);
318 } 318 }
319 v4l2_subdev_notify(sd, BT819_FIFO_RESET_HIGH, 0); 319 v4l2_subdev_notify(sd, BT819_FIFO_RESET_HIGH, NULL);
320 } 320 }
321 return 0; 321 return 0;
322} 322}
diff --git a/drivers/media/video/bt8xx/bttv-driver.c b/drivers/media/video/bt8xx/bttv-driver.c
index 3182a406bdd1..cb46e8fa8aaa 100644
--- a/drivers/media/video/bt8xx/bttv-driver.c
+++ b/drivers/media/video/bt8xx/bttv-driver.c
@@ -81,6 +81,7 @@ static int video_nr[BTTV_MAX] = { [0 ... (BTTV_MAX-1)] = -1 };
81static int radio_nr[BTTV_MAX] = { [0 ... (BTTV_MAX-1)] = -1 }; 81static int radio_nr[BTTV_MAX] = { [0 ... (BTTV_MAX-1)] = -1 };
82static int vbi_nr[BTTV_MAX] = { [0 ... (BTTV_MAX-1)] = -1 }; 82static int vbi_nr[BTTV_MAX] = { [0 ... (BTTV_MAX-1)] = -1 };
83static int debug_latency; 83static int debug_latency;
84static int disable_ir;
84 85
85static unsigned int fdsr; 86static unsigned int fdsr;
86 87
@@ -107,6 +108,7 @@ module_param(bttv_gpio, int, 0644);
107module_param(bttv_debug, int, 0644); 108module_param(bttv_debug, int, 0644);
108module_param(irq_debug, int, 0644); 109module_param(irq_debug, int, 0644);
109module_param(debug_latency, int, 0644); 110module_param(debug_latency, int, 0644);
111module_param(disable_ir, int, 0444);
110 112
111module_param(fdsr, int, 0444); 113module_param(fdsr, int, 0444);
112module_param(gbuffers, int, 0444); 114module_param(gbuffers, int, 0444);
@@ -139,6 +141,7 @@ MODULE_PARM_DESC(bttv_verbose,"verbose startup messages, default is 1 (yes)");
139MODULE_PARM_DESC(bttv_gpio,"log gpio changes, default is 0 (no)"); 141MODULE_PARM_DESC(bttv_gpio,"log gpio changes, default is 0 (no)");
140MODULE_PARM_DESC(bttv_debug,"debug messages, default is 0 (no)"); 142MODULE_PARM_DESC(bttv_debug,"debug messages, default is 0 (no)");
141MODULE_PARM_DESC(irq_debug,"irq handler debug messages, default is 0 (no)"); 143MODULE_PARM_DESC(irq_debug,"irq handler debug messages, default is 0 (no)");
144MODULE_PARM_DESC(disable_ir, "disable infrared remote support");
142MODULE_PARM_DESC(gbuffers,"number of capture buffers. range 2-32, default 8"); 145MODULE_PARM_DESC(gbuffers,"number of capture buffers. range 2-32, default 8");
143MODULE_PARM_DESC(gbufsize,"size of the capture buffers, default is 0x208000"); 146MODULE_PARM_DESC(gbufsize,"size of the capture buffers, default is 0x208000");
144MODULE_PARM_DESC(reset_crop,"reset cropping parameters at open(), default " 147MODULE_PARM_DESC(reset_crop,"reset cropping parameters at open(), default "
@@ -4461,7 +4464,10 @@ static int __devinit bttv_probe(struct pci_dev *dev,
4461 request_modules(btv); 4464 request_modules(btv);
4462 } 4465 }
4463 4466
4464 bttv_input_init(btv); 4467 if (!disable_ir) {
4468 init_bttv_i2c_ir(btv);
4469 bttv_input_init(btv);
4470 }
4465 4471
4466 /* everything is fine */ 4472 /* everything is fine */
4467 bttv_num++; 4473 bttv_num++;
diff --git a/drivers/media/video/bt8xx/bttv-i2c.c b/drivers/media/video/bt8xx/bttv-i2c.c
index 63aa31a041e8..407fa61e4cda 100644
--- a/drivers/media/video/bt8xx/bttv-i2c.c
+++ b/drivers/media/video/bt8xx/bttv-i2c.c
@@ -388,7 +388,12 @@ int __devinit init_bttv_i2c(struct bttv *btv)
388 if (0 == btv->i2c_rc && i2c_scan) 388 if (0 == btv->i2c_rc && i2c_scan)
389 do_i2c_scan(btv->c.v4l2_dev.name, &btv->i2c_client); 389 do_i2c_scan(btv->c.v4l2_dev.name, &btv->i2c_client);
390 390
391 /* Instantiate the IR receiver device, if present */ 391 return btv->i2c_rc;
392}
393
394/* Instantiate the I2C IR receiver device, if present */
395void __devinit init_bttv_i2c_ir(struct bttv *btv)
396{
392 if (0 == btv->i2c_rc) { 397 if (0 == btv->i2c_rc) {
393 struct i2c_board_info info; 398 struct i2c_board_info info;
394 /* The external IR receiver is at i2c address 0x34 (0x35 for 399 /* The external IR receiver is at i2c address 0x34 (0x35 for
@@ -408,7 +413,6 @@ int __devinit init_bttv_i2c(struct bttv *btv)
408 strlcpy(info.type, "ir_video", I2C_NAME_SIZE); 413 strlcpy(info.type, "ir_video", I2C_NAME_SIZE);
409 i2c_new_probed_device(&btv->c.i2c_adap, &info, addr_list); 414 i2c_new_probed_device(&btv->c.i2c_adap, &info, addr_list);
410 } 415 }
411 return btv->i2c_rc;
412} 416}
413 417
414int __devexit fini_bttv_i2c(struct bttv *btv) 418int __devexit fini_bttv_i2c(struct bttv *btv)
diff --git a/drivers/media/video/bt8xx/bttv-input.c b/drivers/media/video/bt8xx/bttv-input.c
index 277a092e1214..b320dbd635aa 100644
--- a/drivers/media/video/bt8xx/bttv-input.c
+++ b/drivers/media/video/bt8xx/bttv-input.c
@@ -247,7 +247,7 @@ int bttv_input_init(struct bttv *btv)
247 struct card_ir *ir; 247 struct card_ir *ir;
248 struct ir_scancode_table *ir_codes = NULL; 248 struct ir_scancode_table *ir_codes = NULL;
249 struct input_dev *input_dev; 249 struct input_dev *input_dev;
250 int ir_type = IR_TYPE_OTHER; 250 u64 ir_type = IR_TYPE_OTHER;
251 int err = -ENOMEM; 251 int err = -ENOMEM;
252 252
253 if (!btv->has_remote) 253 if (!btv->has_remote)
@@ -389,7 +389,7 @@ int bttv_input_init(struct bttv *btv)
389 bttv_ir_start(btv, ir); 389 bttv_ir_start(btv, ir);
390 390
391 /* all done */ 391 /* all done */
392 err = ir_input_register(btv->remote->dev, ir_codes); 392 err = ir_input_register(btv->remote->dev, ir_codes, NULL);
393 if (err) 393 if (err)
394 goto err_out_stop; 394 goto err_out_stop;
395 395
diff --git a/drivers/media/video/bt8xx/bttvp.h b/drivers/media/video/bt8xx/bttvp.h
index a1d0e9c9f286..6cccc2a17eee 100644
--- a/drivers/media/video/bt8xx/bttvp.h
+++ b/drivers/media/video/bt8xx/bttvp.h
@@ -279,6 +279,7 @@ extern unsigned int bttv_debug;
279extern unsigned int bttv_gpio; 279extern unsigned int bttv_gpio;
280extern void bttv_gpio_tracking(struct bttv *btv, char *comment); 280extern void bttv_gpio_tracking(struct bttv *btv, char *comment);
281extern int init_bttv_i2c(struct bttv *btv); 281extern int init_bttv_i2c(struct bttv *btv);
282extern void init_bttv_i2c_ir(struct bttv *btv);
282extern int fini_bttv_i2c(struct bttv *btv); 283extern int fini_bttv_i2c(struct bttv *btv);
283 284
284#define bttv_printk if (bttv_verbose) printk 285#define bttv_printk if (bttv_verbose) printk
diff --git a/drivers/media/video/cafe_ccic.c b/drivers/media/video/cafe_ccic.c
index 7bb9c1ec7819..cbbf7e80d2cf 100644
--- a/drivers/media/video/cafe_ccic.c
+++ b/drivers/media/video/cafe_ccic.c
@@ -1907,7 +1907,6 @@ static int cafe_pci_probe(struct pci_dev *pdev,
1907 goto out_free; 1907 goto out_free;
1908 1908
1909 mutex_init(&cam->s_mutex); 1909 mutex_init(&cam->s_mutex);
1910 mutex_lock(&cam->s_mutex);
1911 spin_lock_init(&cam->dev_lock); 1910 spin_lock_init(&cam->dev_lock);
1912 cam->state = S_NOTREADY; 1911 cam->state = S_NOTREADY;
1913 cafe_set_config_needed(cam, 1); 1912 cafe_set_config_needed(cam, 1);
@@ -1947,7 +1946,6 @@ static int cafe_pci_probe(struct pci_dev *pdev,
1947 * because the sensor could attach in this call chain, leading to 1946 * because the sensor could attach in this call chain, leading to
1948 * unsightly deadlocks. 1947 * unsightly deadlocks.
1949 */ 1948 */
1950 mutex_unlock(&cam->s_mutex); /* attach can deadlock */
1951 ret = cafe_smbus_setup(cam); 1949 ret = cafe_smbus_setup(cam);
1952 if (ret) 1950 if (ret)
1953 goto out_freeirq; 1951 goto out_freeirq;
@@ -1973,7 +1971,7 @@ static int cafe_pci_probe(struct pci_dev *pdev,
1973 cam->vdev.v4l2_dev = &cam->v4l2_dev; 1971 cam->vdev.v4l2_dev = &cam->v4l2_dev;
1974 ret = video_register_device(&cam->vdev, VFL_TYPE_GRABBER, -1); 1972 ret = video_register_device(&cam->vdev, VFL_TYPE_GRABBER, -1);
1975 if (ret) 1973 if (ret)
1976 goto out_smbus; 1974 goto out_unlock;
1977 video_set_drvdata(&cam->vdev, cam); 1975 video_set_drvdata(&cam->vdev, cam);
1978 1976
1979 /* 1977 /*
@@ -1988,6 +1986,8 @@ static int cafe_pci_probe(struct pci_dev *pdev,
1988 mutex_unlock(&cam->s_mutex); 1986 mutex_unlock(&cam->s_mutex);
1989 return 0; 1987 return 0;
1990 1988
1989out_unlock:
1990 mutex_unlock(&cam->s_mutex);
1991out_smbus: 1991out_smbus:
1992 cafe_smbus_shutdown(cam); 1992 cafe_smbus_shutdown(cam);
1993out_freeirq: 1993out_freeirq:
diff --git a/drivers/media/video/cpia.c b/drivers/media/video/cpia.c
index 551ddf216a4b..933ae4c8cb9a 100644
--- a/drivers/media/video/cpia.c
+++ b/drivers/media/video/cpia.c
@@ -3737,9 +3737,6 @@ static int cpia_mmap(struct file *file, struct vm_area_struct *vma)
3737 if (size > FRAME_NUM*CPIA_MAX_FRAME_SIZE) 3737 if (size > FRAME_NUM*CPIA_MAX_FRAME_SIZE)
3738 return -EINVAL; 3738 return -EINVAL;
3739 3739
3740 if (!cam || !cam->ops)
3741 return -ENODEV;
3742
3743 /* make this _really_ smp-safe */ 3740 /* make this _really_ smp-safe */
3744 if (mutex_lock_interruptible(&cam->busy_lock)) 3741 if (mutex_lock_interruptible(&cam->busy_lock))
3745 return -EINTR; 3742 return -EINTR;
diff --git a/drivers/media/video/cx18/Kconfig b/drivers/media/video/cx18/Kconfig
index e8a50a611ebc..baf7e91ee0f5 100644
--- a/drivers/media/video/cx18/Kconfig
+++ b/drivers/media/video/cx18/Kconfig
@@ -19,3 +19,14 @@ config VIDEO_CX18
19 19
20 To compile this driver as a module, choose M here: the 20 To compile this driver as a module, choose M here: the
21 module will be called cx18. 21 module will be called cx18.
22
23config VIDEO_CX18_ALSA
24 tristate "Conexant 23418 DMA audio support"
25 depends on VIDEO_CX18 && SND && EXPERIMENTAL
26 select SND_PCM
27 ---help---
28 This is a video4linux driver for direct (DMA) audio on
29 Conexant 23418 based TV cards using ALSA.
30
31 To compile this driver as a module, choose M here: the
32 module will be called cx18-alsa.
diff --git a/drivers/media/video/cx18/Makefile b/drivers/media/video/cx18/Makefile
index f7bf0edf93f9..2fadd9ded340 100644
--- a/drivers/media/video/cx18/Makefile
+++ b/drivers/media/video/cx18/Makefile
@@ -3,8 +3,10 @@ cx18-objs := cx18-driver.o cx18-cards.o cx18-i2c.o cx18-firmware.o cx18-gpio.
3 cx18-mailbox.o cx18-vbi.o cx18-audio.o cx18-video.o cx18-irq.o \ 3 cx18-mailbox.o cx18-vbi.o cx18-audio.o cx18-video.o cx18-irq.o \
4 cx18-av-core.o cx18-av-audio.o cx18-av-firmware.o cx18-av-vbi.o cx18-scb.o \ 4 cx18-av-core.o cx18-av-audio.o cx18-av-firmware.o cx18-av-vbi.o cx18-scb.o \
5 cx18-dvb.o cx18-io.o 5 cx18-dvb.o cx18-io.o
6cx18-alsa-objs := cx18-alsa-main.o cx18-alsa-pcm.o
6 7
7obj-$(CONFIG_VIDEO_CX18) += cx18.o 8obj-$(CONFIG_VIDEO_CX18) += cx18.o
9obj-$(CONFIG_VIDEO_CX18_ALSA) += cx18-alsa.o
8 10
9EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core 11EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core
10EXTRA_CFLAGS += -Idrivers/media/dvb/frontends 12EXTRA_CFLAGS += -Idrivers/media/dvb/frontends
diff --git a/drivers/media/video/cx18/cx18-alsa-main.c b/drivers/media/video/cx18/cx18-alsa-main.c
new file mode 100644
index 000000000000..eb41d7ec65b9
--- /dev/null
+++ b/drivers/media/video/cx18/cx18-alsa-main.c
@@ -0,0 +1,293 @@
1/*
2 * ALSA interface to cx18 PCM capture streams
3 *
4 * Copyright (C) 2009 Andy Walls <awalls@radix.net>
5 * Copyright (C) 2009 Devin Heitmueller <dheitmueller@kernellabs.com>
6 *
7 * Portions of this work were sponsored by ONELAN Limited.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
22 * 02111-1307 USA
23 */
24
25#include <linux/init.h>
26#include <linux/module.h>
27#include <linux/kernel.h>
28#include <linux/device.h>
29#include <linux/spinlock.h>
30
31#include <media/v4l2-device.h>
32
33#include <sound/core.h>
34#include <sound/initval.h>
35
36#include "cx18-driver.h"
37#include "cx18-version.h"
38#include "cx18-alsa.h"
39#include "cx18-alsa-mixer.h"
40#include "cx18-alsa-pcm.h"
41
42int cx18_alsa_debug;
43
44#define CX18_DEBUG_ALSA_INFO(fmt, arg...) \
45 do { \
46 if (cx18_alsa_debug & 2) \
47 printk(KERN_INFO "%s: " fmt, "cx18-alsa", ## arg); \
48 } while (0);
49
50module_param_named(debug, cx18_alsa_debug, int, 0644);
51MODULE_PARM_DESC(debug,
52 "Debug level (bitmask). Default: 0\n"
53 "\t\t\t 1/0x0001: warning\n"
54 "\t\t\t 2/0x0002: info\n");
55
56MODULE_AUTHOR("Andy Walls");
57MODULE_DESCRIPTION("CX23418 ALSA Interface");
58MODULE_SUPPORTED_DEVICE("CX23418 MPEG2 encoder");
59MODULE_LICENSE("GPL");
60
61MODULE_VERSION(CX18_VERSION);
62
63static inline
64struct snd_cx18_card *to_snd_cx18_card(struct v4l2_device *v4l2_dev)
65{
66 return to_cx18(v4l2_dev)->alsa;
67}
68
69static inline
70struct snd_cx18_card *p_to_snd_cx18_card(struct v4l2_device **v4l2_dev)
71{
72 return container_of(v4l2_dev, struct snd_cx18_card, v4l2_dev);
73}
74
75static void snd_cx18_card_free(struct snd_cx18_card *cxsc)
76{
77 if (cxsc == NULL)
78 return;
79
80 if (cxsc->v4l2_dev != NULL)
81 to_cx18(cxsc->v4l2_dev)->alsa = NULL;
82
83 /* FIXME - take any other stopping actions needed */
84
85 kfree(cxsc);
86}
87
88static void snd_cx18_card_private_free(struct snd_card *sc)
89{
90 if (sc == NULL)
91 return;
92 snd_cx18_card_free(sc->private_data);
93 sc->private_data = NULL;
94 sc->private_free = NULL;
95}
96
97static int snd_cx18_card_create(struct v4l2_device *v4l2_dev,
98 struct snd_card *sc,
99 struct snd_cx18_card **cxsc)
100{
101 *cxsc = kzalloc(sizeof(struct snd_cx18_card), GFP_KERNEL);
102 if (*cxsc == NULL)
103 return -ENOMEM;
104
105 (*cxsc)->v4l2_dev = v4l2_dev;
106 (*cxsc)->sc = sc;
107
108 sc->private_data = *cxsc;
109 sc->private_free = snd_cx18_card_private_free;
110
111 return 0;
112}
113
114static int snd_cx18_card_set_names(struct snd_cx18_card *cxsc)
115{
116 struct cx18 *cx = to_cx18(cxsc->v4l2_dev);
117 struct snd_card *sc = cxsc->sc;
118
119 /* sc->driver is used by alsa-lib's configurator: simple, unique */
120 strlcpy(sc->driver, "CX23418", sizeof(sc->driver));
121
122 /* sc->shortname is a symlink in /proc/asound: CX18-M -> cardN */
123 snprintf(sc->shortname, sizeof(sc->shortname), "CX18-%d",
124 cx->instance);
125
126 /* sc->longname is read from /proc/asound/cards */
127 snprintf(sc->longname, sizeof(sc->longname),
128 "CX23418 #%d %s TV/FM Radio/Line-In Capture",
129 cx->instance, cx->card_name);
130
131 return 0;
132}
133
134static int snd_cx18_init(struct v4l2_device *v4l2_dev)
135{
136 struct cx18 *cx = to_cx18(v4l2_dev);
137 struct snd_card *sc = NULL;
138 struct snd_cx18_card *cxsc;
139 int ret;
140
141 /* Numbrs steps from "Writing an ALSA Driver" by Takashi Iwai */
142
143 /* (1) Check and increment the device index */
144 /* This is a no-op for us. We'll use the cx->instance */
145
146 /* (2) Create a card instance */
147 ret = snd_card_create(SNDRV_DEFAULT_IDX1, /* use first available id */
148 SNDRV_DEFAULT_STR1, /* xid from end of shortname*/
149 THIS_MODULE, 0, &sc);
150 if (ret) {
151 CX18_ALSA_ERR("%s: snd_card_create() failed with err %d\n",
152 __func__, ret);
153 goto err_exit;
154 }
155
156 /* (3) Create a main component */
157 ret = snd_cx18_card_create(v4l2_dev, sc, &cxsc);
158 if (ret) {
159 CX18_ALSA_ERR("%s: snd_cx18_card_create() failed with err %d\n",
160 __func__, ret);
161 goto err_exit_free;
162 }
163
164 /* (4) Set the driver ID and name strings */
165 snd_cx18_card_set_names(cxsc);
166
167
168 ret = snd_cx18_pcm_create(cxsc);
169 if (ret) {
170 CX18_ALSA_ERR("%s: snd_cx18_pcm_create() failed with err %d\n",
171 __func__, ret);
172 goto err_exit_free;
173 }
174 /* FIXME - proc files */
175
176 /* (7) Set the driver data and return 0 */
177 /* We do this out of normal order for PCI drivers to avoid races */
178 cx->alsa = cxsc;
179
180 /* (6) Register the card instance */
181 ret = snd_card_register(sc);
182 if (ret) {
183 cx->alsa = NULL;
184 CX18_ALSA_ERR("%s: snd_card_register() failed with err %d\n",
185 __func__, ret);
186 goto err_exit_free;
187 }
188
189 return 0;
190
191err_exit_free:
192 if (sc != NULL)
193 snd_card_free(sc);
194err_exit:
195 return ret;
196}
197
198int cx18_alsa_load(struct cx18 *cx)
199{
200 struct v4l2_device *v4l2_dev = &cx->v4l2_dev;
201 struct cx18_stream *s;
202
203 if (v4l2_dev == NULL) {
204 printk(KERN_ERR "cx18-alsa: %s: struct v4l2_device * is NULL\n",
205 __func__);
206 return 0;
207 }
208
209 cx = to_cx18(v4l2_dev);
210 if (cx == NULL) {
211 printk(KERN_ERR "cx18-alsa cx is NULL\n");
212 return 0;
213 }
214
215 s = &cx->streams[CX18_ENC_STREAM_TYPE_PCM];
216 if (s->video_dev == NULL) {
217 CX18_DEBUG_ALSA_INFO("%s: PCM stream for card is disabled - "
218 "skipping\n", __func__);
219 return 0;
220 }
221
222 if (cx->alsa != NULL) {
223 CX18_ALSA_ERR("%s: struct snd_cx18_card * already exists\n",
224 __func__);
225 return 0;
226 }
227
228 if (snd_cx18_init(v4l2_dev)) {
229 CX18_ALSA_ERR("%s: failed to create struct snd_cx18_card\n",
230 __func__);
231 } else {
232 CX18_DEBUG_ALSA_INFO("%s: created cx18 ALSA interface instance "
233 "\n", __func__);
234 }
235 return 0;
236}
237
238static int __init cx18_alsa_init(void)
239{
240 printk(KERN_INFO "cx18-alsa: module loading...\n");
241 cx18_ext_init = &cx18_alsa_load;
242 return 0;
243}
244
245static void __exit snd_cx18_exit(struct snd_cx18_card *cxsc)
246{
247 struct cx18 *cx = to_cx18(cxsc->v4l2_dev);
248
249 /* FIXME - pointer checks & shutdown cxsc */
250
251 snd_card_free(cxsc->sc);
252 cx->alsa = NULL;
253}
254
255static int __exit cx18_alsa_exit_callback(struct device *dev, void *data)
256{
257 struct v4l2_device *v4l2_dev = dev_get_drvdata(dev);
258 struct snd_cx18_card *cxsc;
259
260 if (v4l2_dev == NULL) {
261 printk(KERN_ERR "cx18-alsa: %s: struct v4l2_device * is NULL\n",
262 __func__);
263 return 0;
264 }
265
266 cxsc = to_snd_cx18_card(v4l2_dev);
267 if (cxsc == NULL) {
268 CX18_ALSA_WARN("%s: struct snd_cx18_card * is NULL\n",
269 __func__);
270 return 0;
271 }
272
273 snd_cx18_exit(cxsc);
274 return 0;
275}
276
277static void __exit cx18_alsa_exit(void)
278{
279 struct device_driver *drv;
280 int ret;
281
282 printk(KERN_INFO "cx18-alsa: module unloading...\n");
283
284 drv = driver_find("cx18", &pci_bus_type);
285 ret = driver_for_each_device(drv, NULL, NULL, cx18_alsa_exit_callback);
286 put_driver(drv);
287
288 cx18_ext_init = NULL;
289 printk(KERN_INFO "cx18-alsa: module unload complete\n");
290}
291
292module_init(cx18_alsa_init);
293module_exit(cx18_alsa_exit);
diff --git a/drivers/media/video/cx18/cx18-alsa-mixer.c b/drivers/media/video/cx18/cx18-alsa-mixer.c
new file mode 100644
index 000000000000..ef21114309fe
--- /dev/null
+++ b/drivers/media/video/cx18/cx18-alsa-mixer.c
@@ -0,0 +1,175 @@
1/*
2 * ALSA mixer controls for the
3 * ALSA interface to cx18 PCM capture streams
4 *
5 * Copyright (C) 2009 Andy Walls <awalls@radix.net>
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., 59 Temple Place, Suite 330, Boston, MA
20 * 02111-1307 USA
21 */
22
23#include <linux/init.h>
24#include <linux/kernel.h>
25#include <linux/device.h>
26#include <linux/spinlock.h>
27#include <linux/videodev2.h>
28
29#include <media/v4l2-device.h>
30
31#include <sound/core.h>
32#include <sound/control.h>
33#include <sound/tlv.h>
34
35#include "cx18-alsa.h"
36#include "cx18-driver.h"
37
38/*
39 * Note the cx18-av-core volume scale is funny, due to the alignment of the
40 * scale with another chip's range:
41 *
42 * v4l2_control value /512 indicated dB actual dB reg 0x8d4
43 * 0x0000 - 0x01ff 0 -119 -96 228
44 * 0x0200 - 0x02ff 1 -118 -96 228
45 * ...
46 * 0x2c00 - 0x2dff 22 -97 -96 228
47 * 0x2e00 - 0x2fff 23 -96 -96 228
48 * 0x3000 - 0x31ff 24 -95 -95 226
49 * ...
50 * 0xee00 - 0xefff 119 0 0 36
51 * ...
52 * 0xfe00 - 0xffff 127 +8 +8 20
53 */
54static inline int dB_to_cx18_av_vol(int dB)
55{
56 if (dB < -96)
57 dB = -96;
58 else if (dB > 8)
59 dB = 8;
60 return (dB + 119) << 9;
61}
62
63static inline int cx18_av_vol_to_dB(int v)
64{
65 if (v < (23 << 9))
66 v = (23 << 9);
67 else if (v > (127 << 9))
68 v = (127 << 9);
69 return (v >> 9) - 119;
70}
71
72static int snd_cx18_mixer_tv_vol_info(struct snd_kcontrol *kcontrol,
73 struct snd_ctl_elem_info *uinfo)
74{
75 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
76 uinfo->count = 1;
77 /* We're already translating values, just keep this control in dB */
78 uinfo->value.integer.min = -96;
79 uinfo->value.integer.max = 8;
80 uinfo->value.integer.step = 1;
81 return 0;
82}
83
84static int snd_cx18_mixer_tv_vol_get(struct snd_kcontrol *kctl,
85 struct snd_ctl_elem_value *uctl)
86{
87 struct snd_cx18_card *cxsc = snd_kcontrol_chip(kctl);
88 struct cx18 *cx = to_cx18(cxsc->v4l2_dev);
89 struct v4l2_control vctrl;
90 int ret;
91
92 vctrl.id = V4L2_CID_AUDIO_VOLUME;
93 vctrl.value = dB_to_cx18_av_vol(uctl->value.integer.value[0]);
94
95 snd_cx18_lock(cxsc);
96 ret = v4l2_subdev_call(cx->sd_av, core, g_ctrl, &vctrl);
97 snd_cx18_unlock(cxsc);
98
99 if (!ret)
100 uctl->value.integer.value[0] = cx18_av_vol_to_dB(vctrl.value);
101 return ret;
102}
103
104static int snd_cx18_mixer_tv_vol_put(struct snd_kcontrol *kctl,
105 struct snd_ctl_elem_value *uctl)
106{
107 struct snd_cx18_card *cxsc = snd_kcontrol_chip(kctl);
108 struct cx18 *cx = to_cx18(cxsc->v4l2_dev);
109 struct v4l2_control vctrl;
110 int ret;
111
112 vctrl.id = V4L2_CID_AUDIO_VOLUME;
113 vctrl.value = dB_to_cx18_av_vol(uctl->value.integer.value[0]);
114
115 snd_cx18_lock(cxsc);
116
117 /* Fetch current state */
118 ret = v4l2_subdev_call(cx->sd_av, core, g_ctrl, &vctrl);
119
120 if (ret ||
121 (cx18_av_vol_to_dB(vctrl.value) != uctl->value.integer.value[0])) {
122
123 /* Set, if needed */
124 vctrl.value = dB_to_cx18_av_vol(uctl->value.integer.value[0]);
125 ret = v4l2_subdev_call(cx->sd_av, core, s_ctrl, &vctrl);
126 if (!ret)
127 ret = 1; /* Indicate control was changed w/o error */
128 }
129 snd_cx18_unlock(cxsc);
130
131 return ret;
132}
133
134
135/* This is a bit of overkill, the slider is already in dB internally */
136static DECLARE_TLV_DB_SCALE(snd_cx18_mixer_tv_vol_db_scale, -9600, 100, 0);
137
138static struct snd_kcontrol_new snd_cx18_mixer_tv_vol __initdata = {
139 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
140 .name = "Analog TV Capture Volume",
141 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
142 SNDRV_CTL_ELEM_ACCESS_TLV_READ,
143 .info = snd_cx18_mixer_tv_volume_info,
144 .get = snd_cx18_mixer_tv_volume_get,
145 .put = snd_cx18_mixer_tv_volume_put,
146 .tlv.p = snd_cx18_mixer_tv_vol_db_scale
147};
148
149/* FIXME - add mute switch and balance, bass, treble sliders:
150 V4L2_CID_AUDIO_MUTE
151
152 V4L2_CID_AUDIO_BALANCE
153
154 V4L2_CID_AUDIO_BASS
155 V4L2_CID_AUDIO_TREBLE
156*/
157
158/* FIXME - add stereo, lang1, lang2, mono menu */
159/* FIXME - add CS5345 I2S volume for HVR-1600 */
160
161int __init snd_cx18_mixer_create(struct snd_cx18_card *cxsc)
162{
163 struct v4l2_device *v4l2_dev = cxsc->v4l2_dev;
164 struct snd_card *sc = cxsc->sc;
165 int ret;
166
167 strlcpy(sc->mixername, "CX23418 Mixer", sizeof(sc->mixername));
168
169 ret = snd_ctl_add(sc, snd_ctl_new1(snd_cx18_mixer_tv_vol, cxsc));
170 if (ret) {
171 CX18_ALSA_WARN("%s: failed to add %s control, err %d\n",
172 __func__, snd_cx18_mixer_tv_vol.name, ret);
173 }
174 return ret;
175}
diff --git a/drivers/media/video/cx18/cx18-alsa-mixer.h b/drivers/media/video/cx18/cx18-alsa-mixer.h
new file mode 100644
index 000000000000..2d418db000fe
--- /dev/null
+++ b/drivers/media/video/cx18/cx18-alsa-mixer.h
@@ -0,0 +1,23 @@
1/*
2 * ALSA mixer controls for the
3 * ALSA interface to cx18 PCM capture streams
4 *
5 * Copyright (C) 2009 Andy Walls <awalls@radix.net>
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., 59 Temple Place, Suite 330, Boston, MA
20 * 02111-1307 USA
21 */
22
23int __init snd_cx18_mixer_create(struct snd_cx18_card *cxsc);
diff --git a/drivers/media/video/cx18/cx18-alsa-pcm.c b/drivers/media/video/cx18/cx18-alsa-pcm.c
new file mode 100644
index 000000000000..2bd312daeb1e
--- /dev/null
+++ b/drivers/media/video/cx18/cx18-alsa-pcm.c
@@ -0,0 +1,354 @@
1/*
2 * ALSA PCM device for the
3 * ALSA interface to cx18 PCM capture streams
4 *
5 * Copyright (C) 2009 Andy Walls <awalls@radix.net>
6 * Copyright (C) 2009 Devin Heitmueller <dheitmueller@kernellabs.com>
7 *
8 * Portions of this work were sponsored by ONELAN Limited.
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
23 * 02111-1307 USA
24 */
25
26#include <linux/init.h>
27#include <linux/kernel.h>
28#include <linux/vmalloc.h>
29
30#include <media/v4l2-device.h>
31
32#include <sound/core.h>
33#include <sound/pcm.h>
34
35#include "cx18-driver.h"
36#include "cx18-queue.h"
37#include "cx18-streams.h"
38#include "cx18-fileops.h"
39#include "cx18-alsa.h"
40
41static unsigned int pcm_debug;
42module_param(pcm_debug, int, 0644);
43MODULE_PARM_DESC(pcm_debug, "enable debug messages for pcm");
44
45#define dprintk(fmt, arg...) do { \
46 if (pcm_debug) \
47 printk(KERN_INFO "cx18-alsa-pcm %s: " fmt, \
48 __func__, ##arg); \
49 } while (0)
50
51static struct snd_pcm_hardware snd_cx18_hw_capture = {
52 .info = SNDRV_PCM_INFO_BLOCK_TRANSFER |
53 SNDRV_PCM_INFO_MMAP |
54 SNDRV_PCM_INFO_INTERLEAVED |
55 SNDRV_PCM_INFO_MMAP_VALID,
56
57 .formats = SNDRV_PCM_FMTBIT_S16_LE,
58
59 .rates = SNDRV_PCM_RATE_48000,
60
61 .rate_min = 48000,
62 .rate_max = 48000,
63 .channels_min = 2,
64 .channels_max = 2,
65 .buffer_bytes_max = 62720 * 8, /* just about the value in usbaudio.c */
66 .period_bytes_min = 64, /* 12544/2, */
67 .period_bytes_max = 12544,
68 .periods_min = 2,
69 .periods_max = 98, /* 12544, */
70};
71
72void cx18_alsa_announce_pcm_data(struct snd_cx18_card *cxsc, u8 *pcm_data,
73 size_t num_bytes)
74{
75 struct snd_pcm_substream *substream;
76 struct snd_pcm_runtime *runtime;
77 unsigned int oldptr;
78 unsigned int stride;
79 int period_elapsed = 0;
80 int length;
81
82 dprintk("cx18 alsa announce ptr=%p data=%p num_bytes=%zd\n", cxsc,
83 pcm_data, num_bytes);
84
85 substream = cxsc->capture_pcm_substream;
86 if (substream == NULL) {
87 dprintk("substream was NULL\n");
88 return;
89 }
90
91 runtime = substream->runtime;
92 if (runtime == NULL) {
93 dprintk("runtime was NULL\n");
94 return;
95 }
96
97 stride = runtime->frame_bits >> 3;
98 if (stride == 0) {
99 dprintk("stride is zero\n");
100 return;
101 }
102
103 length = num_bytes / stride;
104 if (length == 0) {
105 dprintk("%s: length was zero\n", __func__);
106 return;
107 }
108
109 if (runtime->dma_area == NULL) {
110 dprintk("dma area was NULL - ignoring\n");
111 return;
112 }
113
114 oldptr = cxsc->hwptr_done_capture;
115 if (oldptr + length >= runtime->buffer_size) {
116 unsigned int cnt =
117 runtime->buffer_size - oldptr;
118 memcpy(runtime->dma_area + oldptr * stride, pcm_data,
119 cnt * stride);
120 memcpy(runtime->dma_area, pcm_data + cnt * stride,
121 length * stride - cnt * stride);
122 } else {
123 memcpy(runtime->dma_area + oldptr * stride, pcm_data,
124 length * stride);
125 }
126 snd_pcm_stream_lock(substream);
127
128 cxsc->hwptr_done_capture += length;
129 if (cxsc->hwptr_done_capture >=
130 runtime->buffer_size)
131 cxsc->hwptr_done_capture -=
132 runtime->buffer_size;
133
134 cxsc->capture_transfer_done += length;
135 if (cxsc->capture_transfer_done >=
136 runtime->period_size) {
137 cxsc->capture_transfer_done -=
138 runtime->period_size;
139 period_elapsed = 1;
140 }
141
142 snd_pcm_stream_unlock(substream);
143
144 if (period_elapsed)
145 snd_pcm_period_elapsed(substream);
146}
147
148static int snd_cx18_pcm_capture_open(struct snd_pcm_substream *substream)
149{
150 struct snd_cx18_card *cxsc = snd_pcm_substream_chip(substream);
151 struct snd_pcm_runtime *runtime = substream->runtime;
152 struct v4l2_device *v4l2_dev = cxsc->v4l2_dev;
153 struct cx18 *cx = to_cx18(v4l2_dev);
154 struct cx18_stream *s;
155 struct cx18_open_id item;
156 int ret;
157
158 /* Instruct the cx18 to start sending packets */
159 snd_cx18_lock(cxsc);
160 s = &cx->streams[CX18_ENC_STREAM_TYPE_PCM];
161
162 item.cx = cx;
163 item.type = s->type;
164 item.open_id = cx->open_id++;
165
166 /* See if the stream is available */
167 if (cx18_claim_stream(&item, item.type)) {
168 /* No, it's already in use */
169 snd_cx18_unlock(cxsc);
170 return -EBUSY;
171 }
172
173 if (test_bit(CX18_F_S_STREAMOFF, &s->s_flags) ||
174 test_and_set_bit(CX18_F_S_STREAMING, &s->s_flags)) {
175 /* We're already streaming. No additional action required */
176 snd_cx18_unlock(cxsc);
177 return 0;
178 }
179
180
181 runtime->hw = snd_cx18_hw_capture;
182 snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
183 cxsc->capture_pcm_substream = substream;
184 runtime->private_data = cx;
185
186 cx->pcm_announce_callback = cx18_alsa_announce_pcm_data;
187
188 /* Not currently streaming, so start it up */
189 set_bit(CX18_F_S_STREAMING, &s->s_flags);
190 ret = cx18_start_v4l2_encode_stream(s);
191 snd_cx18_unlock(cxsc);
192
193 return 0;
194}
195
196static int snd_cx18_pcm_capture_close(struct snd_pcm_substream *substream)
197{
198 struct snd_cx18_card *cxsc = snd_pcm_substream_chip(substream);
199 struct v4l2_device *v4l2_dev = cxsc->v4l2_dev;
200 struct cx18 *cx = to_cx18(v4l2_dev);
201 struct cx18_stream *s;
202 int ret;
203
204 /* Instruct the cx18 to stop sending packets */
205 snd_cx18_lock(cxsc);
206 s = &cx->streams[CX18_ENC_STREAM_TYPE_PCM];
207 ret = cx18_stop_v4l2_encode_stream(s, 0);
208 clear_bit(CX18_F_S_STREAMING, &s->s_flags);
209
210 cx18_release_stream(s);
211
212 cx->pcm_announce_callback = NULL;
213 snd_cx18_unlock(cxsc);
214
215 return 0;
216}
217
218static int snd_cx18_pcm_ioctl(struct snd_pcm_substream *substream,
219 unsigned int cmd, void *arg)
220{
221 return snd_pcm_lib_ioctl(substream, cmd, arg);
222}
223
224
225static int snd_pcm_alloc_vmalloc_buffer(struct snd_pcm_substream *subs,
226 size_t size)
227{
228 struct snd_pcm_runtime *runtime = subs->runtime;
229
230 dprintk("Allocating vbuffer\n");
231 if (runtime->dma_area) {
232 if (runtime->dma_bytes > size)
233 return 0;
234
235 vfree(runtime->dma_area);
236 }
237 runtime->dma_area = vmalloc(size);
238 if (!runtime->dma_area)
239 return -ENOMEM;
240
241 runtime->dma_bytes = size;
242
243 return 0;
244}
245
246static int snd_cx18_pcm_hw_params(struct snd_pcm_substream *substream,
247 struct snd_pcm_hw_params *params)
248{
249 int ret;
250
251 dprintk("%s called\n", __func__);
252
253 ret = snd_pcm_alloc_vmalloc_buffer(substream,
254 params_buffer_bytes(params));
255 return 0;
256}
257
258static int snd_cx18_pcm_hw_free(struct snd_pcm_substream *substream)
259{
260 struct snd_cx18_card *cxsc = snd_pcm_substream_chip(substream);
261 unsigned long flags;
262
263 spin_lock_irqsave(&cxsc->slock, flags);
264 if (substream->runtime->dma_area) {
265 dprintk("freeing pcm capture region\n");
266 vfree(substream->runtime->dma_area);
267 substream->runtime->dma_area = NULL;
268 }
269 spin_unlock_irqrestore(&cxsc->slock, flags);
270
271 return 0;
272}
273
274static int snd_cx18_pcm_prepare(struct snd_pcm_substream *substream)
275{
276 struct snd_cx18_card *cxsc = snd_pcm_substream_chip(substream);
277
278 cxsc->hwptr_done_capture = 0;
279 cxsc->capture_transfer_done = 0;
280
281 return 0;
282}
283
284static int snd_cx18_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
285{
286 return 0;
287}
288
289static
290snd_pcm_uframes_t snd_cx18_pcm_pointer(struct snd_pcm_substream *substream)
291{
292 unsigned long flags;
293 snd_pcm_uframes_t hwptr_done;
294 struct snd_cx18_card *cxsc = snd_pcm_substream_chip(substream);
295
296 spin_lock_irqsave(&cxsc->slock, flags);
297 hwptr_done = cxsc->hwptr_done_capture;
298 spin_unlock_irqrestore(&cxsc->slock, flags);
299
300 return hwptr_done;
301}
302
303static struct page *snd_pcm_get_vmalloc_page(struct snd_pcm_substream *subs,
304 unsigned long offset)
305{
306 void *pageptr = subs->runtime->dma_area + offset;
307
308 return vmalloc_to_page(pageptr);
309}
310
311static struct snd_pcm_ops snd_cx18_pcm_capture_ops = {
312 .open = snd_cx18_pcm_capture_open,
313 .close = snd_cx18_pcm_capture_close,
314 .ioctl = snd_cx18_pcm_ioctl,
315 .hw_params = snd_cx18_pcm_hw_params,
316 .hw_free = snd_cx18_pcm_hw_free,
317 .prepare = snd_cx18_pcm_prepare,
318 .trigger = snd_cx18_pcm_trigger,
319 .pointer = snd_cx18_pcm_pointer,
320 .page = snd_pcm_get_vmalloc_page,
321};
322
323int snd_cx18_pcm_create(struct snd_cx18_card *cxsc)
324{
325 struct snd_pcm *sp;
326 struct snd_card *sc = cxsc->sc;
327 struct v4l2_device *v4l2_dev = cxsc->v4l2_dev;
328 struct cx18 *cx = to_cx18(v4l2_dev);
329 int ret;
330
331 ret = snd_pcm_new(sc, "CX23418 PCM",
332 0, /* PCM device 0, the only one for this card */
333 0, /* 0 playback substreams */
334 1, /* 1 capture substream */
335 &sp);
336 if (ret) {
337 CX18_ALSA_ERR("%s: snd_cx18_pcm_create() failed with err %d\n",
338 __func__, ret);
339 goto err_exit;
340 }
341
342 spin_lock_init(&cxsc->slock);
343
344 snd_pcm_set_ops(sp, SNDRV_PCM_STREAM_CAPTURE,
345 &snd_cx18_pcm_capture_ops);
346 sp->info_flags = 0;
347 sp->private_data = cxsc;
348 strlcpy(sp->name, cx->card_name, sizeof(sp->name));
349
350 return 0;
351
352err_exit:
353 return ret;
354}
diff --git a/drivers/media/video/cx18/cx18-alsa-pcm.h b/drivers/media/video/cx18/cx18-alsa-pcm.h
new file mode 100644
index 000000000000..325662c647a0
--- /dev/null
+++ b/drivers/media/video/cx18/cx18-alsa-pcm.h
@@ -0,0 +1,27 @@
1/*
2 * ALSA PCM device for the
3 * ALSA interface to cx18 PCM capture streams
4 *
5 * Copyright (C) 2009 Andy Walls <awalls@radix.net>
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., 59 Temple Place, Suite 330, Boston, MA
20 * 02111-1307 USA
21 */
22
23int __init snd_cx18_pcm_create(struct snd_cx18_card *cxsc);
24
25/* Used by cx18-mailbox to announce the PCM data to the module */
26void cx18_alsa_announce_pcm_data(struct snd_cx18_card *card, u8 *pcm_data,
27 size_t num_bytes);
diff --git a/drivers/media/video/cx18/cx18-alsa.h b/drivers/media/video/cx18/cx18-alsa.h
new file mode 100644
index 000000000000..88a1cde7540b
--- /dev/null
+++ b/drivers/media/video/cx18/cx18-alsa.h
@@ -0,0 +1,75 @@
1/*
2 * ALSA interface to cx18 PCM capture streams
3 *
4 * Copyright (C) 2009 Andy Walls <awalls@radix.net>
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., 59 Temple Place, Suite 330, Boston, MA
19 * 02111-1307 USA
20 */
21
22struct snd_card;
23
24struct snd_cx18_card {
25 struct v4l2_device *v4l2_dev;
26 struct snd_card *sc;
27 unsigned int capture_transfer_done;
28 unsigned int hwptr_done_capture;
29 struct snd_pcm_substream *capture_pcm_substream;
30 spinlock_t slock;
31};
32
33extern int cx18_alsa_debug;
34
35/*
36 * File operations that manipulate the encoder or video or audio subdevices
37 * need to be serialized. Use the same lock we use for v4l2 file ops.
38 */
39static inline void snd_cx18_lock(struct snd_cx18_card *cxsc)
40{
41 struct cx18 *cx = to_cx18(cxsc->v4l2_dev);
42 mutex_lock(&cx->serialize_lock);
43}
44
45static inline void snd_cx18_unlock(struct snd_cx18_card *cxsc)
46{
47 struct cx18 *cx = to_cx18(cxsc->v4l2_dev);
48 mutex_unlock(&cx->serialize_lock);
49}
50
51#define CX18_ALSA_DBGFLG_WARN (1 << 0)
52#define CX18_ALSA_DBGFLG_WARN (1 << 0)
53#define CX18_ALSA_DBGFLG_INFO (1 << 1)
54
55#define CX18_ALSA_DEBUG(x, type, fmt, args...) \
56 do { \
57 if ((x) & cx18_alsa_debug) \
58 printk(KERN_INFO "%s-alsa: " type ": " fmt, \
59 v4l2_dev->name , ## args); \
60 } while (0)
61
62#define CX18_ALSA_DEBUG_WARN(fmt, args...) \
63 CX18_ALSA_DEBUG(CX18_ALSA_DBGFLG_WARN, "warning", fmt , ## args)
64
65#define CX18_ALSA_DEBUG_INFO(fmt, args...) \
66 CX18_ALSA_DEBUG(CX18_ALSA_DBGFLG_INFO, "info", fmt , ## args)
67
68#define CX18_ALSA_ERR(fmt, args...) \
69 printk(KERN_ERR "%s-alsa: " fmt, v4l2_dev->name , ## args)
70
71#define CX18_ALSA_WARN(fmt, args...) \
72 printk(KERN_WARNING "%s-alsa: " fmt, v4l2_dev->name , ## args)
73
74#define CX18_ALSA_INFO(fmt, args...) \
75 printk(KERN_INFO "%s-alsa: " fmt, v4l2_dev->name , ## args)
diff --git a/drivers/media/video/cx18/cx18-cards.c b/drivers/media/video/cx18/cx18-cards.c
index f11e47a58286..f808fb6fc1c1 100644
--- a/drivers/media/video/cx18/cx18-cards.c
+++ b/drivers/media/video/cx18/cx18-cards.c
@@ -393,7 +393,7 @@ static const struct cx18_card cx18_card_leadtek_pvr2100 = {
393 .gpio_init.direction = 0x7, 393 .gpio_init.direction = 0x7,
394 .gpio_audio_input = { .mask = 0x7, 394 .gpio_audio_input = { .mask = 0x7,
395 .tuner = 0x6, .linein = 0x2, .radio = 0x2 }, 395 .tuner = 0x6, .linein = 0x2, .radio = 0x2 },
396 .xceive_pin = 15, 396 .xceive_pin = 1,
397 .pci_list = cx18_pci_leadtek_pvr2100, 397 .pci_list = cx18_pci_leadtek_pvr2100,
398 .i2c = &cx18_i2c_std, 398 .i2c = &cx18_i2c_std,
399}; 399};
diff --git a/drivers/media/video/cx18/cx18-driver.c b/drivers/media/video/cx18/cx18-driver.c
index 7f65a47f12e1..c95a86ba33b0 100644
--- a/drivers/media/video/cx18/cx18-driver.c
+++ b/drivers/media/video/cx18/cx18-driver.c
@@ -47,6 +47,10 @@
47 setting this to 1 you ensure that radio0 is now also radio1. */ 47 setting this to 1 you ensure that radio0 is now also radio1. */
48int cx18_first_minor; 48int cx18_first_minor;
49 49
50/* Callback for registering extensions */
51int (*cx18_ext_init)(struct cx18 *);
52EXPORT_SYMBOL(cx18_ext_init);
53
50/* add your revision and whatnot here */ 54/* add your revision and whatnot here */
51static struct pci_device_id cx18_pci_tbl[] __devinitdata = { 55static struct pci_device_id cx18_pci_tbl[] __devinitdata = {
52 {PCI_VENDOR_ID_CX, PCI_DEVICE_ID_CX23418, 56 {PCI_VENDOR_ID_CX, PCI_DEVICE_ID_CX23418,
@@ -91,7 +95,7 @@ static int enc_pcm_bufsize = CX18_DEFAULT_ENC_PCM_BUFSIZE;
91 95
92static int enc_ts_bufs = -1; 96static int enc_ts_bufs = -1;
93static int enc_mpg_bufs = -1; 97static int enc_mpg_bufs = -1;
94static int enc_idx_bufs = -1; 98static int enc_idx_bufs = CX18_MAX_FW_MDLS_PER_STREAM;
95static int enc_yuv_bufs = -1; 99static int enc_yuv_bufs = -1;
96static int enc_vbi_bufs = -1; 100static int enc_vbi_bufs = -1;
97static int enc_pcm_bufs = -1; 101static int enc_pcm_bufs = -1;
@@ -196,14 +200,17 @@ MODULE_PARM_DESC(enc_mpg_bufs,
196 "Number of encoder MPG buffers\n" 200 "Number of encoder MPG buffers\n"
197 "\t\t\tDefault is computed from other enc_mpg_* parameters"); 201 "\t\t\tDefault is computed from other enc_mpg_* parameters");
198MODULE_PARM_DESC(enc_idx_buffers, 202MODULE_PARM_DESC(enc_idx_buffers,
199 "Encoder IDX buffer memory (MB). (enc_idx_bufs can override)\n" 203 "(Deprecated) Encoder IDX buffer memory (MB)\n"
200 "\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_IDX_BUFFERS)); 204 "\t\t\tIgnored, except 0 disables IDX buffer allocations\n"
205 "\t\t\tDefault: 1 [Enabled]");
201MODULE_PARM_DESC(enc_idx_bufsize, 206MODULE_PARM_DESC(enc_idx_bufsize,
202 "Size of an encoder IDX buffer (kB)\n" 207 "Size of an encoder IDX buffer (kB)\n"
203 "\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_IDX_BUFSIZE)); 208 "\t\t\tAllowed values are multiples of 1.5 kB rounded up\n"
209 "\t\t\t(multiples of size required for 64 index entries)\n"
210 "\t\t\tDefault: 2");
204MODULE_PARM_DESC(enc_idx_bufs, 211MODULE_PARM_DESC(enc_idx_bufs,
205 "Number of encoder IDX buffers\n" 212 "Number of encoder IDX buffers\n"
206 "\t\t\tDefault is computed from other enc_idx_* parameters"); 213 "\t\t\tDefault: " __stringify(CX18_MAX_FW_MDLS_PER_STREAM));
207MODULE_PARM_DESC(enc_yuv_buffers, 214MODULE_PARM_DESC(enc_yuv_buffers,
208 "Encoder YUV buffer memory (MB). (enc_yuv_bufs can override)\n" 215 "Encoder YUV buffer memory (MB). (enc_yuv_bufs can override)\n"
209 "\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_YUV_BUFFERS)); 216 "\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_YUV_BUFFERS));
@@ -231,7 +238,8 @@ MODULE_PARM_DESC(enc_pcm_bufs,
231 "Number of encoder PCM buffers\n" 238 "Number of encoder PCM buffers\n"
232 "\t\t\tDefault is computed from other enc_pcm_* parameters"); 239 "\t\t\tDefault is computed from other enc_pcm_* parameters");
233 240
234MODULE_PARM_DESC(cx18_first_minor, "Set device node number assigned to first card"); 241MODULE_PARM_DESC(cx18_first_minor,
242 "Set device node number assigned to first card");
235 243
236MODULE_AUTHOR("Hans Verkuil"); 244MODULE_AUTHOR("Hans Verkuil");
237MODULE_DESCRIPTION("CX23418 driver"); 245MODULE_DESCRIPTION("CX23418 driver");
@@ -240,6 +248,28 @@ MODULE_LICENSE("GPL");
240 248
241MODULE_VERSION(CX18_VERSION); 249MODULE_VERSION(CX18_VERSION);
242 250
251#if defined(CONFIG_MODULES) && defined(MODULE)
252static void request_module_async(struct work_struct *work)
253{
254 struct cx18 *dev = container_of(work, struct cx18, request_module_wk);
255
256 /* Make sure cx18-alsa module is loaded */
257 request_module("cx18-alsa");
258
259 /* Initialize cx18-alsa for this instance of the cx18 device */
260 if (cx18_ext_init != NULL)
261 cx18_ext_init(dev);
262}
263
264static void request_modules(struct cx18 *dev)
265{
266 INIT_WORK(&dev->request_module_wk, request_module_async);
267 schedule_work(&dev->request_module_wk);
268}
269#else
270#define request_modules(dev)
271#endif /* CONFIG_MODULES */
272
243/* Generic utility functions */ 273/* Generic utility functions */
244int cx18_msleep_timeout(unsigned int msecs, int intr) 274int cx18_msleep_timeout(unsigned int msecs, int intr)
245{ 275{
@@ -501,7 +531,12 @@ static void cx18_process_options(struct cx18 *cx)
501 /* 531 /*
502 * YUV is a special case where the stream_buf_size needs to be 532 * YUV is a special case where the stream_buf_size needs to be
503 * an integral multiple of 33.75 kB (storage for 32 screens 533 * an integral multiple of 33.75 kB (storage for 32 screens
504 * lines to maintain alignment in case of lost buffers 534 * lines to maintain alignment in case of lost buffers).
535 *
536 * IDX is a special case where the stream_buf_size should be
537 * an integral multiple of 1.5 kB (storage for 64 index entries
538 * to maintain alignment in case of lost buffers).
539 *
505 */ 540 */
506 if (i == CX18_ENC_STREAM_TYPE_YUV) { 541 if (i == CX18_ENC_STREAM_TYPE_YUV) {
507 cx->stream_buf_size[i] *= 1024; 542 cx->stream_buf_size[i] *= 1024;
@@ -511,15 +546,24 @@ static void cx18_process_options(struct cx18 *cx)
511 if (cx->stream_buf_size[i] < CX18_UNIT_ENC_YUV_BUFSIZE) 546 if (cx->stream_buf_size[i] < CX18_UNIT_ENC_YUV_BUFSIZE)
512 cx->stream_buf_size[i] = 547 cx->stream_buf_size[i] =
513 CX18_UNIT_ENC_YUV_BUFSIZE; 548 CX18_UNIT_ENC_YUV_BUFSIZE;
549 } else if (i == CX18_ENC_STREAM_TYPE_IDX) {
550 cx->stream_buf_size[i] *= 1024;
551 cx->stream_buf_size[i] -=
552 (cx->stream_buf_size[i] % CX18_UNIT_ENC_IDX_BUFSIZE);
553
554 if (cx->stream_buf_size[i] < CX18_UNIT_ENC_IDX_BUFSIZE)
555 cx->stream_buf_size[i] =
556 CX18_UNIT_ENC_IDX_BUFSIZE;
514 } 557 }
515 /* 558 /*
516 * YUV is a special case where the stream_buf_size is 559 * YUV and IDX are special cases where the stream_buf_size is
517 * now in bytes. 560 * now in bytes.
518 * VBI is a special case where the stream_buf_size is fixed 561 * VBI is a special case where the stream_buf_size is fixed
519 * and already in bytes 562 * and already in bytes
520 */ 563 */
521 if (i == CX18_ENC_STREAM_TYPE_VBI || 564 if (i == CX18_ENC_STREAM_TYPE_VBI ||
522 i == CX18_ENC_STREAM_TYPE_YUV) { 565 i == CX18_ENC_STREAM_TYPE_YUV ||
566 i == CX18_ENC_STREAM_TYPE_IDX) {
523 if (cx->stream_buffers[i] < 0) { 567 if (cx->stream_buffers[i] < 0) {
524 cx->stream_buffers[i] = 568 cx->stream_buffers[i] =
525 cx->options.megabytes[i] * 1024 * 1024 569 cx->options.megabytes[i] * 1024 * 1024
@@ -1032,6 +1076,10 @@ static int __devinit cx18_probe(struct pci_dev *pci_dev,
1032 } 1076 }
1033 1077
1034 CX18_INFO("Initialized card: %s\n", cx->card_name); 1078 CX18_INFO("Initialized card: %s\n", cx->card_name);
1079
1080 /* Load cx18 submodules (cx18-alsa) */
1081 request_modules(cx);
1082
1035 return 0; 1083 return 0;
1036 1084
1037free_streams: 1085free_streams:
@@ -1220,6 +1268,7 @@ static void cx18_remove(struct pci_dev *pci_dev)
1220 kfree(cx); 1268 kfree(cx);
1221} 1269}
1222 1270
1271
1223/* define a pci_driver for card detection */ 1272/* define a pci_driver for card detection */
1224static struct pci_driver cx18_pci_driver = { 1273static struct pci_driver cx18_pci_driver = {
1225 .name = "cx18", 1274 .name = "cx18",
@@ -1230,7 +1279,8 @@ static struct pci_driver cx18_pci_driver = {
1230 1279
1231static int __init module_start(void) 1280static int __init module_start(void)
1232{ 1281{
1233 printk(KERN_INFO "cx18: Start initialization, version %s\n", CX18_VERSION); 1282 printk(KERN_INFO "cx18: Start initialization, version %s\n",
1283 CX18_VERSION);
1234 1284
1235 /* Validate parameters */ 1285 /* Validate parameters */
1236 if (cx18_first_minor < 0 || cx18_first_minor >= CX18_MAX_CARDS) { 1286 if (cx18_first_minor < 0 || cx18_first_minor >= CX18_MAX_CARDS) {
diff --git a/drivers/media/video/cx18/cx18-driver.h b/drivers/media/video/cx18/cx18-driver.h
index e3f7911a7385..23ad6d548dc5 100644
--- a/drivers/media/video/cx18/cx18-driver.h
+++ b/drivers/media/video/cx18/cx18-driver.h
@@ -126,10 +126,22 @@
126#define CX18_625_LINE_ENC_YUV_BUFSIZE (CX18_UNIT_ENC_YUV_BUFSIZE * 576/32) 126#define CX18_625_LINE_ENC_YUV_BUFSIZE (CX18_UNIT_ENC_YUV_BUFSIZE * 576/32)
127#define CX18_525_LINE_ENC_YUV_BUFSIZE (CX18_UNIT_ENC_YUV_BUFSIZE * 480/32) 127#define CX18_525_LINE_ENC_YUV_BUFSIZE (CX18_UNIT_ENC_YUV_BUFSIZE * 480/32)
128 128
129/* IDX buffer size should be a multiple of the index entry size from the chip */
130struct cx18_enc_idx_entry {
131 __le32 length;
132 __le32 offset_low;
133 __le32 offset_high;
134 __le32 flags;
135 __le32 pts_low;
136 __le32 pts_high;
137} __attribute__ ((packed));
138#define CX18_UNIT_ENC_IDX_BUFSIZE \
139 (sizeof(struct cx18_enc_idx_entry) * V4L2_ENC_IDX_ENTRIES)
140
129/* DMA buffer, default size in kB allocated */ 141/* DMA buffer, default size in kB allocated */
130#define CX18_DEFAULT_ENC_TS_BUFSIZE 32 142#define CX18_DEFAULT_ENC_TS_BUFSIZE 32
131#define CX18_DEFAULT_ENC_MPG_BUFSIZE 32 143#define CX18_DEFAULT_ENC_MPG_BUFSIZE 32
132#define CX18_DEFAULT_ENC_IDX_BUFSIZE 32 144#define CX18_DEFAULT_ENC_IDX_BUFSIZE (CX18_UNIT_ENC_IDX_BUFSIZE * 1 / 1024 + 1)
133#define CX18_DEFAULT_ENC_YUV_BUFSIZE (CX18_UNIT_ENC_YUV_BUFSIZE * 3 / 1024 + 1) 145#define CX18_DEFAULT_ENC_YUV_BUFSIZE (CX18_UNIT_ENC_YUV_BUFSIZE * 3 / 1024 + 1)
134#define CX18_DEFAULT_ENC_PCM_BUFSIZE 4 146#define CX18_DEFAULT_ENC_PCM_BUFSIZE 4
135 147
@@ -234,16 +246,8 @@
234#define CX18_WARN_DEV(dev, fmt, args...) v4l2_warn(dev, fmt , ## args) 246#define CX18_WARN_DEV(dev, fmt, args...) v4l2_warn(dev, fmt , ## args)
235#define CX18_INFO_DEV(dev, fmt, args...) v4l2_info(dev, fmt , ## args) 247#define CX18_INFO_DEV(dev, fmt, args...) v4l2_info(dev, fmt , ## args)
236 248
237/* Values for CX18_API_DEC_PLAYBACK_SPEED mpeg_frame_type_mask parameter: */
238#define MPEG_FRAME_TYPE_IFRAME 1
239#define MPEG_FRAME_TYPE_IFRAME_PFRAME 3
240#define MPEG_FRAME_TYPE_ALL 7
241
242#define CX18_MAX_PGM_INDEX (400)
243
244extern int cx18_debug; 249extern int cx18_debug;
245 250
246
247struct cx18_options { 251struct cx18_options {
248 int megabytes[CX18_MAX_STREAMS]; /* Size in megabytes of each stream */ 252 int megabytes[CX18_MAX_STREAMS]; /* Size in megabytes of each stream */
249 int cardtype; /* force card type on load */ 253 int cardtype; /* force card type on load */
@@ -276,6 +280,18 @@ struct cx18_options {
276#define CX18_SLICED_TYPE_WSS_625 (5) 280#define CX18_SLICED_TYPE_WSS_625 (5)
277#define CX18_SLICED_TYPE_VPS (7) 281#define CX18_SLICED_TYPE_VPS (7)
278 282
283/**
284 * list_entry_is_past_end - check if a previous loop cursor is off list end
285 * @pos: the type * previously used as a loop cursor.
286 * @head: the head for your list.
287 * @member: the name of the list_struct within the struct.
288 *
289 * Check if the entry's list_head is the head of the list, thus it's not a
290 * real entry but was the loop cursor that walked past the end
291 */
292#define list_entry_is_past_end(pos, head, member) \
293 (&pos->member == (head))
294
279struct cx18_buffer { 295struct cx18_buffer {
280 struct list_head list; 296 struct list_head list;
281 dma_addr_t dma_handle; 297 dma_addr_t dma_handle;
@@ -558,6 +574,10 @@ struct cx18 {
558 int stream_buffers[CX18_MAX_STREAMS]; /* # of buffers for each stream */ 574 int stream_buffers[CX18_MAX_STREAMS]; /* # of buffers for each stream */
559 int stream_buf_size[CX18_MAX_STREAMS]; /* Stream buffer size */ 575 int stream_buf_size[CX18_MAX_STREAMS]; /* Stream buffer size */
560 struct cx18_stream streams[CX18_MAX_STREAMS]; /* Stream data */ 576 struct cx18_stream streams[CX18_MAX_STREAMS]; /* Stream data */
577 struct snd_cx18_card *alsa; /* ALSA interface for PCM capture stream */
578 void (*pcm_announce_callback)(struct snd_cx18_card *card, u8 *pcm_data,
579 size_t num_bytes);
580
561 unsigned long i_flags; /* global cx18 flags */ 581 unsigned long i_flags; /* global cx18 flags */
562 atomic_t ana_capturing; /* count number of active analog capture streams */ 582 atomic_t ana_capturing; /* count number of active analog capture streams */
563 atomic_t tot_capturing; /* total count number of active capture streams */ 583 atomic_t tot_capturing; /* total count number of active capture streams */
@@ -575,12 +595,6 @@ struct cx18 {
575 595
576 struct vbi_info vbi; 596 struct vbi_info vbi;
577 597
578 u32 pgm_info_offset;
579 u32 pgm_info_num;
580 u32 pgm_info_write_idx;
581 u32 pgm_info_read_idx;
582 struct v4l2_enc_idx_entry pgm_info[CX18_MAX_PGM_INDEX];
583
584 u64 mpg_data_received; 598 u64 mpg_data_received;
585 u64 vbi_data_inserted; 599 u64 vbi_data_inserted;
586 600
@@ -623,6 +637,9 @@ struct cx18 {
623 u32 active_input; 637 u32 active_input;
624 v4l2_std_id std; 638 v4l2_std_id std;
625 v4l2_std_id tuner_std; /* The norm of the tuner (fixed) */ 639 v4l2_std_id tuner_std; /* The norm of the tuner (fixed) */
640
641 /* Used for cx18-alsa module loading */
642 struct work_struct request_module_wk;
626}; 643};
627 644
628static inline struct cx18 *to_cx18(struct v4l2_device *v4l2_dev) 645static inline struct cx18 *to_cx18(struct v4l2_device *v4l2_dev)
@@ -630,6 +647,9 @@ static inline struct cx18 *to_cx18(struct v4l2_device *v4l2_dev)
630 return container_of(v4l2_dev, struct cx18, v4l2_dev); 647 return container_of(v4l2_dev, struct cx18, v4l2_dev);
631} 648}
632 649
650/* cx18 extensions to be loaded */
651extern int (*cx18_ext_init)(struct cx18 *);
652
633/* Globals */ 653/* Globals */
634extern int cx18_first_minor; 654extern int cx18_first_minor;
635 655
diff --git a/drivers/media/video/cx18/cx18-dvb.c b/drivers/media/video/cx18/cx18-dvb.c
index 71ad2d1b4c2c..0ae2c2e1eab5 100644
--- a/drivers/media/video/cx18/cx18-dvb.c
+++ b/drivers/media/video/cx18/cx18-dvb.c
@@ -213,10 +213,14 @@ static int cx18_dvb_start_feed(struct dvb_demux_feed *feed)
213{ 213{
214 struct dvb_demux *demux = feed->demux; 214 struct dvb_demux *demux = feed->demux;
215 struct cx18_stream *stream = (struct cx18_stream *) demux->priv; 215 struct cx18_stream *stream = (struct cx18_stream *) demux->priv;
216 struct cx18 *cx = stream->cx; 216 struct cx18 *cx;
217 int ret; 217 int ret;
218 u32 v; 218 u32 v;
219 219
220 if (!stream)
221 return -EINVAL;
222
223 cx = stream->cx;
220 CX18_DEBUG_INFO("Start feed: pid = 0x%x index = %d\n", 224 CX18_DEBUG_INFO("Start feed: pid = 0x%x index = %d\n",
221 feed->pid, feed->index); 225 feed->pid, feed->index);
222 226
@@ -253,12 +257,10 @@ static int cx18_dvb_start_feed(struct dvb_demux_feed *feed)
253 if (!demux->dmx.frontend) 257 if (!demux->dmx.frontend)
254 return -EINVAL; 258 return -EINVAL;
255 259
256 if (!stream)
257 return -EINVAL;
258
259 mutex_lock(&stream->dvb.feedlock); 260 mutex_lock(&stream->dvb.feedlock);
260 if (stream->dvb.feeding++ == 0) { 261 if (stream->dvb.feeding++ == 0) {
261 CX18_DEBUG_INFO("Starting Transport DMA\n"); 262 CX18_DEBUG_INFO("Starting Transport DMA\n");
263 mutex_lock(&cx->serialize_lock);
262 set_bit(CX18_F_S_STREAMING, &stream->s_flags); 264 set_bit(CX18_F_S_STREAMING, &stream->s_flags);
263 ret = cx18_start_v4l2_encode_stream(stream); 265 ret = cx18_start_v4l2_encode_stream(stream);
264 if (ret < 0) { 266 if (ret < 0) {
@@ -267,6 +269,7 @@ static int cx18_dvb_start_feed(struct dvb_demux_feed *feed)
267 if (stream->dvb.feeding == 0) 269 if (stream->dvb.feeding == 0)
268 clear_bit(CX18_F_S_STREAMING, &stream->s_flags); 270 clear_bit(CX18_F_S_STREAMING, &stream->s_flags);
269 } 271 }
272 mutex_unlock(&cx->serialize_lock);
270 } else 273 } else
271 ret = 0; 274 ret = 0;
272 mutex_unlock(&stream->dvb.feedlock); 275 mutex_unlock(&stream->dvb.feedlock);
@@ -279,17 +282,20 @@ static int cx18_dvb_stop_feed(struct dvb_demux_feed *feed)
279{ 282{
280 struct dvb_demux *demux = feed->demux; 283 struct dvb_demux *demux = feed->demux;
281 struct cx18_stream *stream = (struct cx18_stream *)demux->priv; 284 struct cx18_stream *stream = (struct cx18_stream *)demux->priv;
282 struct cx18 *cx = stream->cx; 285 struct cx18 *cx;
283 int ret = -EINVAL; 286 int ret = -EINVAL;
284 287
285 CX18_DEBUG_INFO("Stop feed: pid = 0x%x index = %d\n",
286 feed->pid, feed->index);
287
288 if (stream) { 288 if (stream) {
289 cx = stream->cx;
290 CX18_DEBUG_INFO("Stop feed: pid = 0x%x index = %d\n",
291 feed->pid, feed->index);
292
289 mutex_lock(&stream->dvb.feedlock); 293 mutex_lock(&stream->dvb.feedlock);
290 if (--stream->dvb.feeding == 0) { 294 if (--stream->dvb.feeding == 0) {
291 CX18_DEBUG_INFO("Stopping Transport DMA\n"); 295 CX18_DEBUG_INFO("Stopping Transport DMA\n");
296 mutex_lock(&cx->serialize_lock);
292 ret = cx18_stop_v4l2_encode_stream(stream, 0); 297 ret = cx18_stop_v4l2_encode_stream(stream, 0);
298 mutex_unlock(&cx->serialize_lock);
293 } else 299 } else
294 ret = 0; 300 ret = 0;
295 mutex_unlock(&stream->dvb.feedlock); 301 mutex_unlock(&stream->dvb.feedlock);
diff --git a/drivers/media/video/cx18/cx18-fileops.c b/drivers/media/video/cx18/cx18-fileops.c
index c0885c69fd89..863ce7758239 100644
--- a/drivers/media/video/cx18/cx18-fileops.c
+++ b/drivers/media/video/cx18/cx18-fileops.c
@@ -37,15 +37,21 @@
37 37
38/* This function tries to claim the stream for a specific file descriptor. 38/* This function tries to claim the stream for a specific file descriptor.
39 If no one else is using this stream then the stream is claimed and 39 If no one else is using this stream then the stream is claimed and
40 associated VBI streams are also automatically claimed. 40 associated VBI and IDX streams are also automatically claimed.
41 Possible error returns: -EBUSY if someone else has claimed 41 Possible error returns: -EBUSY if someone else has claimed
42 the stream or 0 on success. */ 42 the stream or 0 on success. */
43static int cx18_claim_stream(struct cx18_open_id *id, int type) 43int cx18_claim_stream(struct cx18_open_id *id, int type)
44{ 44{
45 struct cx18 *cx = id->cx; 45 struct cx18 *cx = id->cx;
46 struct cx18_stream *s = &cx->streams[type]; 46 struct cx18_stream *s = &cx->streams[type];
47 struct cx18_stream *s_vbi; 47 struct cx18_stream *s_assoc;
48 int vbi_type; 48
49 /* Nothing should ever try to directly claim the IDX stream */
50 if (type == CX18_ENC_STREAM_TYPE_IDX) {
51 CX18_WARN("MPEG Index stream cannot be claimed "
52 "directly, but something tried.\n");
53 return -EINVAL;
54 }
49 55
50 if (test_and_set_bit(CX18_F_S_CLAIMED, &s->s_flags)) { 56 if (test_and_set_bit(CX18_F_S_CLAIMED, &s->s_flags)) {
51 /* someone already claimed this stream */ 57 /* someone already claimed this stream */
@@ -67,32 +73,47 @@ static int cx18_claim_stream(struct cx18_open_id *id, int type)
67 } 73 }
68 s->id = id->open_id; 74 s->id = id->open_id;
69 75
70 /* CX18_ENC_STREAM_TYPE_MPG needs to claim CX18_ENC_STREAM_TYPE_VBI 76 /*
71 (provided VBI insertion is on and sliced VBI is selected), for all 77 * CX18_ENC_STREAM_TYPE_MPG needs to claim:
72 other streams we're done */ 78 * CX18_ENC_STREAM_TYPE_VBI, if VBI insertion is on for sliced VBI, or
73 if (type == CX18_ENC_STREAM_TYPE_MPG && 79 * CX18_ENC_STREAM_TYPE_IDX, if VBI insertion is off for sliced VBI
74 cx->vbi.insert_mpeg && !cx18_raw_vbi(cx)) { 80 * (We don't yet fix up MPEG Index entries for our inserted packets).
75 vbi_type = CX18_ENC_STREAM_TYPE_VBI; 81 *
76 } else { 82 * For all other streams we're done.
83 */
84 if (type != CX18_ENC_STREAM_TYPE_MPG)
77 return 0; 85 return 0;
78 }
79 s_vbi = &cx->streams[vbi_type];
80 86
81 set_bit(CX18_F_S_CLAIMED, &s_vbi->s_flags); 87 s_assoc = &cx->streams[CX18_ENC_STREAM_TYPE_IDX];
88 if (cx->vbi.insert_mpeg && !cx18_raw_vbi(cx))
89 s_assoc = &cx->streams[CX18_ENC_STREAM_TYPE_VBI];
90 else if (!cx18_stream_enabled(s_assoc))
91 return 0;
92
93 set_bit(CX18_F_S_CLAIMED, &s_assoc->s_flags);
82 94
83 /* mark that it is used internally */ 95 /* mark that it is used internally */
84 set_bit(CX18_F_S_INTERNAL_USE, &s_vbi->s_flags); 96 set_bit(CX18_F_S_INTERNAL_USE, &s_assoc->s_flags);
85 return 0; 97 return 0;
86} 98}
99EXPORT_SYMBOL(cx18_claim_stream);
87 100
88/* This function releases a previously claimed stream. It will take into 101/* This function releases a previously claimed stream. It will take into
89 account associated VBI streams. */ 102 account associated VBI streams. */
90static void cx18_release_stream(struct cx18_stream *s) 103void cx18_release_stream(struct cx18_stream *s)
91{ 104{
92 struct cx18 *cx = s->cx; 105 struct cx18 *cx = s->cx;
93 struct cx18_stream *s_vbi; 106 struct cx18_stream *s_assoc;
94 107
95 s->id = -1; 108 s->id = -1;
109 if (s->type == CX18_ENC_STREAM_TYPE_IDX) {
110 /*
111 * The IDX stream is only used internally, and can
112 * only be indirectly unclaimed by unclaiming the MPG stream.
113 */
114 return;
115 }
116
96 if (s->type == CX18_ENC_STREAM_TYPE_VBI && 117 if (s->type == CX18_ENC_STREAM_TYPE_VBI &&
97 test_bit(CX18_F_S_INTERNAL_USE, &s->s_flags)) { 118 test_bit(CX18_F_S_INTERNAL_USE, &s->s_flags)) {
98 /* this stream is still in use internally */ 119 /* this stream is still in use internally */
@@ -105,25 +126,36 @@ static void cx18_release_stream(struct cx18_stream *s)
105 126
106 cx18_flush_queues(s); 127 cx18_flush_queues(s);
107 128
108 /* CX18_ENC_STREAM_TYPE_MPG needs to release CX18_ENC_STREAM_TYPE_VBI, 129 /*
109 for all other streams we're done */ 130 * CX18_ENC_STREAM_TYPE_MPG needs to release the
110 if (s->type == CX18_ENC_STREAM_TYPE_MPG) 131 * CX18_ENC_STREAM_TYPE_VBI and/or CX18_ENC_STREAM_TYPE_IDX streams.
111 s_vbi = &cx->streams[CX18_ENC_STREAM_TYPE_VBI]; 132 *
112 else 133 * For all other streams we're done.
134 */
135 if (s->type != CX18_ENC_STREAM_TYPE_MPG)
113 return; 136 return;
114 137
115 /* clear internal use flag */ 138 /* Unclaim the associated MPEG Index stream */
116 if (!test_and_clear_bit(CX18_F_S_INTERNAL_USE, &s_vbi->s_flags)) { 139 s_assoc = &cx->streams[CX18_ENC_STREAM_TYPE_IDX];
117 /* was already cleared */ 140 if (test_and_clear_bit(CX18_F_S_INTERNAL_USE, &s_assoc->s_flags)) {
118 return; 141 clear_bit(CX18_F_S_CLAIMED, &s_assoc->s_flags);
142 cx18_flush_queues(s_assoc);
119 } 143 }
120 if (s_vbi->id != -1) { 144
121 /* VBI stream still claimed by a file descriptor */ 145 /* Unclaim the associated VBI stream */
122 return; 146 s_assoc = &cx->streams[CX18_ENC_STREAM_TYPE_VBI];
147 if (test_and_clear_bit(CX18_F_S_INTERNAL_USE, &s_assoc->s_flags)) {
148 if (s_assoc->id == -1) {
149 /*
150 * The VBI stream is not still claimed by a file
151 * descriptor, so completely unclaim it.
152 */
153 clear_bit(CX18_F_S_CLAIMED, &s_assoc->s_flags);
154 cx18_flush_queues(s_assoc);
155 }
123 } 156 }
124 clear_bit(CX18_F_S_CLAIMED, &s_vbi->s_flags);
125 cx18_flush_queues(s_vbi);
126} 157}
158EXPORT_SYMBOL(cx18_release_stream);
127 159
128static void cx18_dualwatch(struct cx18 *cx) 160static void cx18_dualwatch(struct cx18 *cx)
129{ 161{
@@ -177,9 +209,7 @@ static struct cx18_mdl *cx18_get_mdl(struct cx18_stream *s, int non_block,
177 *err = 0; 209 *err = 0;
178 while (1) { 210 while (1) {
179 if (s->type == CX18_ENC_STREAM_TYPE_MPG) { 211 if (s->type == CX18_ENC_STREAM_TYPE_MPG) {
180 /* Process pending program info updates and pending 212 /* Process pending program updates and VBI data */
181 VBI data */
182
183 if (time_after(jiffies, cx->dualwatch_jiffies + msecs_to_jiffies(1000))) { 213 if (time_after(jiffies, cx->dualwatch_jiffies + msecs_to_jiffies(1000))) {
184 cx->dualwatch_jiffies = jiffies; 214 cx->dualwatch_jiffies = jiffies;
185 cx18_dualwatch(cx); 215 cx18_dualwatch(cx);
@@ -362,18 +392,6 @@ static size_t cx18_copy_buf_to_user(struct cx18_stream *s,
362 return len; 392 return len;
363} 393}
364 394
365/**
366 * list_entry_is_past_end - check if a previous loop cursor is off list end
367 * @pos: the type * previously used as a loop cursor.
368 * @head: the head for your list.
369 * @member: the name of the list_struct within the struct.
370 *
371 * Check if the entry's list_head is the head of the list, thus it's not a
372 * real entry but was the loop cursor that walked past the end
373 */
374#define list_entry_is_past_end(pos, head, member) \
375 (&pos->member == (head))
376
377static size_t cx18_copy_mdl_to_user(struct cx18_stream *s, 395static size_t cx18_copy_mdl_to_user(struct cx18_stream *s,
378 struct cx18_mdl *mdl, char __user *ubuf, size_t ucount) 396 struct cx18_mdl *mdl, char __user *ubuf, size_t ucount)
379{ 397{
@@ -498,6 +516,7 @@ int cx18_start_capture(struct cx18_open_id *id)
498 struct cx18 *cx = id->cx; 516 struct cx18 *cx = id->cx;
499 struct cx18_stream *s = &cx->streams[id->type]; 517 struct cx18_stream *s = &cx->streams[id->type];
500 struct cx18_stream *s_vbi; 518 struct cx18_stream *s_vbi;
519 struct cx18_stream *s_idx;
501 520
502 if (s->type == CX18_ENC_STREAM_TYPE_RAD) { 521 if (s->type == CX18_ENC_STREAM_TYPE_RAD) {
503 /* you cannot read from these stream types. */ 522 /* you cannot read from these stream types. */
@@ -516,25 +535,33 @@ int cx18_start_capture(struct cx18_open_id *id)
516 return 0; 535 return 0;
517 } 536 }
518 537
519 /* Start VBI capture if required */ 538 /* Start associated VBI or IDX stream capture if required */
520 s_vbi = &cx->streams[CX18_ENC_STREAM_TYPE_VBI]; 539 s_vbi = &cx->streams[CX18_ENC_STREAM_TYPE_VBI];
521 if (s->type == CX18_ENC_STREAM_TYPE_MPG && 540 s_idx = &cx->streams[CX18_ENC_STREAM_TYPE_IDX];
522 test_bit(CX18_F_S_INTERNAL_USE, &s_vbi->s_flags) && 541 if (s->type == CX18_ENC_STREAM_TYPE_MPG) {
523 !test_and_set_bit(CX18_F_S_STREAMING, &s_vbi->s_flags)) { 542 /*
524 /* Note: the CX18_ENC_STREAM_TYPE_VBI is claimed 543 * The VBI and IDX streams should have been claimed
525 automatically when the MPG stream is claimed. 544 * automatically, if for internal use, when the MPG stream was
526 We only need to start the VBI capturing. */ 545 * claimed. We only need to start these streams capturing.
527 if (cx18_start_v4l2_encode_stream(s_vbi)) { 546 */
528 CX18_DEBUG_WARN("VBI capture start failed\n"); 547 if (test_bit(CX18_F_S_INTERNAL_USE, &s_idx->s_flags) &&
529 548 !test_and_set_bit(CX18_F_S_STREAMING, &s_idx->s_flags)) {
530 /* Failure, clean up and return an error */ 549 if (cx18_start_v4l2_encode_stream(s_idx)) {
531 clear_bit(CX18_F_S_STREAMING, &s_vbi->s_flags); 550 CX18_DEBUG_WARN("IDX capture start failed\n");
532 clear_bit(CX18_F_S_STREAMING, &s->s_flags); 551 clear_bit(CX18_F_S_STREAMING, &s_idx->s_flags);
533 /* also releases the associated VBI stream */ 552 goto start_failed;
534 cx18_release_stream(s); 553 }
535 return -EIO; 554 CX18_DEBUG_INFO("IDX capture started\n");
555 }
556 if (test_bit(CX18_F_S_INTERNAL_USE, &s_vbi->s_flags) &&
557 !test_and_set_bit(CX18_F_S_STREAMING, &s_vbi->s_flags)) {
558 if (cx18_start_v4l2_encode_stream(s_vbi)) {
559 CX18_DEBUG_WARN("VBI capture start failed\n");
560 clear_bit(CX18_F_S_STREAMING, &s_vbi->s_flags);
561 goto start_failed;
562 }
563 CX18_DEBUG_INFO("VBI insertion started\n");
536 } 564 }
537 CX18_DEBUG_INFO("VBI insertion started\n");
538 } 565 }
539 566
540 /* Tell the card to start capturing */ 567 /* Tell the card to start capturing */
@@ -547,19 +574,29 @@ int cx18_start_capture(struct cx18_open_id *id)
547 return 0; 574 return 0;
548 } 575 }
549 576
550 /* failure, clean up */ 577start_failed:
551 CX18_DEBUG_WARN("Failed to start capturing for stream %s\n", s->name); 578 CX18_DEBUG_WARN("Failed to start capturing for stream %s\n", s->name);
552 579
553 /* Note: the CX18_ENC_STREAM_TYPE_VBI is released 580 /*
554 automatically when the MPG stream is released. 581 * The associated VBI and IDX streams for internal use are released
555 We only need to stop the VBI capturing. */ 582 * automatically when the MPG stream is released. We only need to stop
556 if (s->type == CX18_ENC_STREAM_TYPE_MPG && 583 * the associated stream.
557 test_bit(CX18_F_S_STREAMING, &s_vbi->s_flags)) { 584 */
558 cx18_stop_v4l2_encode_stream(s_vbi, 0); 585 if (s->type == CX18_ENC_STREAM_TYPE_MPG) {
559 clear_bit(CX18_F_S_STREAMING, &s_vbi->s_flags); 586 /* Stop the IDX stream which is always for internal use */
587 if (test_bit(CX18_F_S_STREAMING, &s_idx->s_flags)) {
588 cx18_stop_v4l2_encode_stream(s_idx, 0);
589 clear_bit(CX18_F_S_STREAMING, &s_idx->s_flags);
590 }
591 /* Stop the VBI stream, if only running for internal use */
592 if (test_bit(CX18_F_S_STREAMING, &s_vbi->s_flags) &&
593 !test_bit(CX18_F_S_APPL_IO, &s_vbi->s_flags)) {
594 cx18_stop_v4l2_encode_stream(s_vbi, 0);
595 clear_bit(CX18_F_S_STREAMING, &s_vbi->s_flags);
596 }
560 } 597 }
561 clear_bit(CX18_F_S_STREAMING, &s->s_flags); 598 clear_bit(CX18_F_S_STREAMING, &s->s_flags);
562 cx18_release_stream(s); 599 cx18_release_stream(s); /* Also releases associated streams */
563 return -EIO; 600 return -EIO;
564} 601}
565 602
@@ -618,6 +655,8 @@ void cx18_stop_capture(struct cx18_open_id *id, int gop_end)
618{ 655{
619 struct cx18 *cx = id->cx; 656 struct cx18 *cx = id->cx;
620 struct cx18_stream *s = &cx->streams[id->type]; 657 struct cx18_stream *s = &cx->streams[id->type];
658 struct cx18_stream *s_vbi = &cx->streams[CX18_ENC_STREAM_TYPE_VBI];
659 struct cx18_stream *s_idx = &cx->streams[CX18_ENC_STREAM_TYPE_IDX];
621 660
622 CX18_DEBUG_IOCTL("close() of %s\n", s->name); 661 CX18_DEBUG_IOCTL("close() of %s\n", s->name);
623 662
@@ -625,17 +664,19 @@ void cx18_stop_capture(struct cx18_open_id *id, int gop_end)
625 664
626 /* Stop capturing */ 665 /* Stop capturing */
627 if (test_bit(CX18_F_S_STREAMING, &s->s_flags)) { 666 if (test_bit(CX18_F_S_STREAMING, &s->s_flags)) {
628 struct cx18_stream *s_vbi =
629 &cx->streams[CX18_ENC_STREAM_TYPE_VBI];
630
631 CX18_DEBUG_INFO("close stopping capture\n"); 667 CX18_DEBUG_INFO("close stopping capture\n");
632 /* Special case: a running VBI capture for VBI insertion 668 if (id->type == CX18_ENC_STREAM_TYPE_MPG) {
633 in the mpeg stream. Need to stop that too. */ 669 /* Stop internal use associated VBI and IDX streams */
634 if (id->type == CX18_ENC_STREAM_TYPE_MPG && 670 if (test_bit(CX18_F_S_STREAMING, &s_vbi->s_flags) &&
635 test_bit(CX18_F_S_STREAMING, &s_vbi->s_flags) && 671 !test_bit(CX18_F_S_APPL_IO, &s_vbi->s_flags)) {
636 !test_bit(CX18_F_S_APPL_IO, &s_vbi->s_flags)) { 672 CX18_DEBUG_INFO("close stopping embedded VBI "
637 CX18_DEBUG_INFO("close stopping embedded VBI capture\n"); 673 "capture\n");
638 cx18_stop_v4l2_encode_stream(s_vbi, 0); 674 cx18_stop_v4l2_encode_stream(s_vbi, 0);
675 }
676 if (test_bit(CX18_F_S_STREAMING, &s_idx->s_flags)) {
677 CX18_DEBUG_INFO("close stopping IDX capture\n");
678 cx18_stop_v4l2_encode_stream(s_idx, 0);
679 }
639 } 680 }
640 if (id->type == CX18_ENC_STREAM_TYPE_VBI && 681 if (id->type == CX18_ENC_STREAM_TYPE_VBI &&
641 test_bit(CX18_F_S_INTERNAL_USE, &s->s_flags)) 682 test_bit(CX18_F_S_INTERNAL_USE, &s->s_flags))
diff --git a/drivers/media/video/cx18/cx18-fileops.h b/drivers/media/video/cx18/cx18-fileops.h
index 92e2d5dab936..5c8fcb884f0a 100644
--- a/drivers/media/video/cx18/cx18-fileops.h
+++ b/drivers/media/video/cx18/cx18-fileops.h
@@ -34,3 +34,6 @@ void cx18_stop_capture(struct cx18_open_id *id, int gop_end);
34void cx18_mute(struct cx18 *cx); 34void cx18_mute(struct cx18 *cx);
35void cx18_unmute(struct cx18 *cx); 35void cx18_unmute(struct cx18 *cx);
36 36
37/* Shared with cx18-alsa module */
38int cx18_claim_stream(struct cx18_open_id *id, int type);
39void cx18_release_stream(struct cx18_stream *s);
diff --git a/drivers/media/video/cx18/cx18-ioctl.c b/drivers/media/video/cx18/cx18-ioctl.c
index 3e4fc192fdec..b81dd0ea8eb9 100644
--- a/drivers/media/video/cx18/cx18-ioctl.c
+++ b/drivers/media/video/cx18/cx18-ioctl.c
@@ -775,10 +775,143 @@ static int cx18_g_sliced_vbi_cap(struct file *file, void *fh,
775 return 0; 775 return 0;
776} 776}
777 777
778static int _cx18_process_idx_data(struct cx18_buffer *buf,
779 struct v4l2_enc_idx *idx)
780{
781 int consumed, remaining;
782 struct v4l2_enc_idx_entry *e_idx;
783 struct cx18_enc_idx_entry *e_buf;
784
785 /* Frame type lookup: 1=I, 2=P, 4=B */
786 const int mapping[8] = {
787 -1, V4L2_ENC_IDX_FRAME_I, V4L2_ENC_IDX_FRAME_P,
788 -1, V4L2_ENC_IDX_FRAME_B, -1, -1, -1
789 };
790
791 /*
792 * Assumption here is that a buf holds an integral number of
793 * struct cx18_enc_idx_entry objects and is properly aligned.
794 * This is enforced by the module options on IDX buffer sizes.
795 */
796 remaining = buf->bytesused - buf->readpos;
797 consumed = 0;
798 e_idx = &idx->entry[idx->entries];
799 e_buf = (struct cx18_enc_idx_entry *) &buf->buf[buf->readpos];
800
801 while (remaining >= sizeof(struct cx18_enc_idx_entry) &&
802 idx->entries < V4L2_ENC_IDX_ENTRIES) {
803
804 e_idx->offset = (((u64) le32_to_cpu(e_buf->offset_high)) << 32)
805 | le32_to_cpu(e_buf->offset_low);
806
807 e_idx->pts = (((u64) (le32_to_cpu(e_buf->pts_high) & 1)) << 32)
808 | le32_to_cpu(e_buf->pts_low);
809
810 e_idx->length = le32_to_cpu(e_buf->length);
811
812 e_idx->flags = mapping[le32_to_cpu(e_buf->flags) & 0x7];
813
814 e_idx->reserved[0] = 0;
815 e_idx->reserved[1] = 0;
816
817 idx->entries++;
818 e_idx = &idx->entry[idx->entries];
819 e_buf++;
820
821 remaining -= sizeof(struct cx18_enc_idx_entry);
822 consumed += sizeof(struct cx18_enc_idx_entry);
823 }
824
825 /* Swallow any partial entries at the end, if there are any */
826 if (remaining > 0 && remaining < sizeof(struct cx18_enc_idx_entry))
827 consumed += remaining;
828
829 buf->readpos += consumed;
830 return consumed;
831}
832
833static int cx18_process_idx_data(struct cx18_stream *s, struct cx18_mdl *mdl,
834 struct v4l2_enc_idx *idx)
835{
836 if (s->type != CX18_ENC_STREAM_TYPE_IDX)
837 return -EINVAL;
838
839 if (mdl->curr_buf == NULL)
840 mdl->curr_buf = list_first_entry(&mdl->buf_list,
841 struct cx18_buffer, list);
842
843 if (list_entry_is_past_end(mdl->curr_buf, &mdl->buf_list, list)) {
844 /*
845 * For some reason we've exhausted the buffers, but the MDL
846 * object still said some data was unread.
847 * Fix that and bail out.
848 */
849 mdl->readpos = mdl->bytesused;
850 return 0;
851 }
852
853 list_for_each_entry_from(mdl->curr_buf, &mdl->buf_list, list) {
854
855 /* Skip any empty buffers in the MDL */
856 if (mdl->curr_buf->readpos >= mdl->curr_buf->bytesused)
857 continue;
858
859 mdl->readpos += _cx18_process_idx_data(mdl->curr_buf, idx);
860
861 /* exit when MDL drained or request satisfied */
862 if (idx->entries >= V4L2_ENC_IDX_ENTRIES ||
863 mdl->curr_buf->readpos < mdl->curr_buf->bytesused ||
864 mdl->readpos >= mdl->bytesused)
865 break;
866 }
867 return 0;
868}
869
778static int cx18_g_enc_index(struct file *file, void *fh, 870static int cx18_g_enc_index(struct file *file, void *fh,
779 struct v4l2_enc_idx *idx) 871 struct v4l2_enc_idx *idx)
780{ 872{
781 return -EINVAL; 873 struct cx18 *cx = ((struct cx18_open_id *)fh)->cx;
874 struct cx18_stream *s = &cx->streams[CX18_ENC_STREAM_TYPE_IDX];
875 s32 tmp;
876 struct cx18_mdl *mdl;
877
878 if (!cx18_stream_enabled(s)) /* Module options inhibited IDX stream */
879 return -EINVAL;
880
881 /* Compute the best case number of entries we can buffer */
882 tmp = s->buffers -
883 s->bufs_per_mdl * CX18_ENC_STREAM_TYPE_IDX_FW_MDL_MIN;
884 if (tmp <= 0)
885 tmp = 1;
886 tmp = tmp * s->buf_size / sizeof(struct cx18_enc_idx_entry);
887
888 /* Fill out the header of the return structure */
889 idx->entries = 0;
890 idx->entries_cap = tmp;
891 memset(idx->reserved, 0, sizeof(idx->reserved));
892
893 /* Pull IDX MDLs and buffers from q_full and populate the entries */
894 do {
895 mdl = cx18_dequeue(s, &s->q_full);
896 if (mdl == NULL) /* No more IDX data right now */
897 break;
898
899 /* Extract the Index entry data from the MDL and buffers */
900 cx18_process_idx_data(s, mdl, idx);
901 if (mdl->readpos < mdl->bytesused) {
902 /* We finished with data remaining, push the MDL back */
903 cx18_push(s, mdl, &s->q_full);
904 break;
905 }
906
907 /* We drained this MDL, schedule it to go to the firmware */
908 cx18_enqueue(s, mdl, &s->q_free);
909
910 } while (idx->entries < V4L2_ENC_IDX_ENTRIES);
911
912 /* Tell the work handler to send free IDX MDLs to the firmware */
913 cx18_stream_load_fw_queue(s);
914 return 0;
782} 915}
783 916
784static int cx18_encoder_cmd(struct file *file, void *fh, 917static int cx18_encoder_cmd(struct file *file, void *fh,
diff --git a/drivers/media/video/cx18/cx18-mailbox.c b/drivers/media/video/cx18/cx18-mailbox.c
index f231dd09c720..6dcce297752f 100644
--- a/drivers/media/video/cx18/cx18-mailbox.c
+++ b/drivers/media/video/cx18/cx18-mailbox.c
@@ -29,6 +29,7 @@
29#include "cx18-mailbox.h" 29#include "cx18-mailbox.h"
30#include "cx18-queue.h" 30#include "cx18-queue.h"
31#include "cx18-streams.h" 31#include "cx18-streams.h"
32#include "cx18-alsa-pcm.h" /* FIXME make configurable */
32 33
33static const char *rpu_str[] = { "APU", "CPU", "EPU", "HPU" }; 34static const char *rpu_str[] = { "APU", "CPU", "EPU", "HPU" };
34 35
@@ -157,6 +158,34 @@ static void cx18_mdl_send_to_dvb(struct cx18_stream *s, struct cx18_mdl *mdl)
157 } 158 }
158} 159}
159 160
161
162static void cx18_mdl_send_to_alsa(struct cx18 *cx, struct cx18_stream *s,
163 struct cx18_mdl *mdl)
164{
165 struct cx18_buffer *buf;
166
167 if (mdl->bytesused == 0)
168 return;
169
170 /* We ignore mdl and buf readpos accounting here - it doesn't matter */
171
172 /* The likely case */
173 if (list_is_singular(&mdl->buf_list)) {
174 buf = list_first_entry(&mdl->buf_list, struct cx18_buffer,
175 list);
176 if (buf->bytesused)
177 cx->pcm_announce_callback(cx->alsa, buf->buf,
178 buf->bytesused);
179 return;
180 }
181
182 list_for_each_entry(buf, &mdl->buf_list, list) {
183 if (buf->bytesused == 0)
184 break;
185 cx->pcm_announce_callback(cx->alsa, buf->buf, buf->bytesused);
186 }
187}
188
160static void epu_dma_done(struct cx18 *cx, struct cx18_in_work_order *order) 189static void epu_dma_done(struct cx18 *cx, struct cx18_in_work_order *order)
161{ 190{
162 u32 handle, mdl_ack_count, id; 191 u32 handle, mdl_ack_count, id;
@@ -223,11 +252,21 @@ static void epu_dma_done(struct cx18 *cx, struct cx18_in_work_order *order)
223 CX18_DEBUG_HI_DMA("%s recv bytesused = %d\n", 252 CX18_DEBUG_HI_DMA("%s recv bytesused = %d\n",
224 s->name, mdl->bytesused); 253 s->name, mdl->bytesused);
225 254
226 if (s->type != CX18_ENC_STREAM_TYPE_TS) 255 if (s->type == CX18_ENC_STREAM_TYPE_TS) {
227 cx18_enqueue(s, mdl, &s->q_full);
228 else {
229 cx18_mdl_send_to_dvb(s, mdl); 256 cx18_mdl_send_to_dvb(s, mdl);
230 cx18_enqueue(s, mdl, &s->q_free); 257 cx18_enqueue(s, mdl, &s->q_free);
258 } else if (s->type == CX18_ENC_STREAM_TYPE_PCM) {
259 /* Pass the data to cx18-alsa */
260 if (cx->pcm_announce_callback != NULL) {
261 cx18_mdl_send_to_alsa(cx, s, mdl);
262 cx18_enqueue(s, mdl, &s->q_free);
263 } else {
264 cx18_enqueue(s, mdl, &s->q_full);
265 }
266 } else {
267 cx18_enqueue(s, mdl, &s->q_full);
268 if (s->type == CX18_ENC_STREAM_TYPE_IDX)
269 cx18_stream_rotate_idx_mdls(cx);
231 } 270 }
232 } 271 }
233 /* Put as many MDLs as possible back into fw use */ 272 /* Put as many MDLs as possible back into fw use */
diff --git a/drivers/media/video/cx18/cx18-queue.c b/drivers/media/video/cx18/cx18-queue.c
index 63304823cef5..aefc8c8cf3c1 100644
--- a/drivers/media/video/cx18/cx18-queue.c
+++ b/drivers/media/video/cx18/cx18-queue.c
@@ -419,6 +419,9 @@ void cx18_stream_free(struct cx18_stream *s)
419{ 419{
420 struct cx18_mdl *mdl; 420 struct cx18_mdl *mdl;
421 struct cx18_buffer *buf; 421 struct cx18_buffer *buf;
422 struct cx18 *cx = s->cx;
423
424 CX18_DEBUG_INFO("Deallocating buffers for %s stream\n", s->name);
422 425
423 /* move all buffers to buf_pool and all MDLs to q_idle */ 426 /* move all buffers to buf_pool and all MDLs to q_idle */
424 cx18_unload_queues(s); 427 cx18_unload_queues(s);
diff --git a/drivers/media/video/cx18/cx18-streams.c b/drivers/media/video/cx18/cx18-streams.c
index 987a9308d938..054450f65a60 100644
--- a/drivers/media/video/cx18/cx18-streams.c
+++ b/drivers/media/video/cx18/cx18-streams.c
@@ -319,11 +319,27 @@ void cx18_streams_cleanup(struct cx18 *cx, int unregister)
319 319
320 /* Teardown all streams */ 320 /* Teardown all streams */
321 for (type = 0; type < CX18_MAX_STREAMS; type++) { 321 for (type = 0; type < CX18_MAX_STREAMS; type++) {
322 if (cx->streams[type].dvb.enabled) { 322
323 cx18_dvb_unregister(&cx->streams[type]); 323 /* No struct video_device, but can have buffers allocated */
324 cx->streams[type].dvb.enabled = false; 324 if (type == CX18_ENC_STREAM_TYPE_TS) {
325 if (cx->streams[type].dvb.enabled) {
326 cx18_dvb_unregister(&cx->streams[type]);
327 cx->streams[type].dvb.enabled = false;
328 cx18_stream_free(&cx->streams[type]);
329 }
330 continue;
331 }
332
333 /* No struct video_device, but can have buffers allocated */
334 if (type == CX18_ENC_STREAM_TYPE_IDX) {
335 if (cx->stream_buffers[type] != 0) {
336 cx->stream_buffers[type] = 0;
337 cx18_stream_free(&cx->streams[type]);
338 }
339 continue;
325 } 340 }
326 341
342 /* If struct video_device exists, can have buffers allocated */
327 vdev = cx->streams[type].video_dev; 343 vdev = cx->streams[type].video_dev;
328 344
329 cx->streams[type].video_dev = NULL; 345 cx->streams[type].video_dev = NULL;
@@ -447,6 +463,32 @@ static void cx18_vbi_setup(struct cx18_stream *s)
447 cx18_api(cx, CX18_CPU_SET_RAW_VBI_PARAM, 6, data); 463 cx18_api(cx, CX18_CPU_SET_RAW_VBI_PARAM, 6, data);
448} 464}
449 465
466void cx18_stream_rotate_idx_mdls(struct cx18 *cx)
467{
468 struct cx18_stream *s = &cx->streams[CX18_ENC_STREAM_TYPE_IDX];
469 struct cx18_mdl *mdl;
470
471 if (!cx18_stream_enabled(s))
472 return;
473
474 /* Return if the firmware is not running low on MDLs */
475 if ((atomic_read(&s->q_free.depth) + atomic_read(&s->q_busy.depth)) >=
476 CX18_ENC_STREAM_TYPE_IDX_FW_MDL_MIN)
477 return;
478
479 /* Return if there are no MDLs to rotate back to the firmware */
480 if (atomic_read(&s->q_full.depth) < 2)
481 return;
482
483 /*
484 * Take the oldest IDX MDL still holding data, and discard its index
485 * entries by scheduling the MDL to go back to the firmware
486 */
487 mdl = cx18_dequeue(s, &s->q_full);
488 if (mdl != NULL)
489 cx18_enqueue(s, mdl, &s->q_free);
490}
491
450static 492static
451struct cx18_queue *_cx18_stream_put_mdl_fw(struct cx18_stream *s, 493struct cx18_queue *_cx18_stream_put_mdl_fw(struct cx18_stream *s,
452 struct cx18_mdl *mdl) 494 struct cx18_mdl *mdl)
@@ -546,8 +588,9 @@ int cx18_start_v4l2_encode_stream(struct cx18_stream *s)
546 struct cx18 *cx = s->cx; 588 struct cx18 *cx = s->cx;
547 int captype = 0; 589 int captype = 0;
548 struct cx18_api_func_private priv; 590 struct cx18_api_func_private priv;
591 struct cx18_stream *s_idx;
549 592
550 if (s->video_dev == NULL && s->dvb.enabled == 0) 593 if (!cx18_stream_enabled(s))
551 return -EINVAL; 594 return -EINVAL;
552 595
553 CX18_DEBUG_INFO("Start encoder stream %s\n", s->name); 596 CX18_DEBUG_INFO("Start encoder stream %s\n", s->name);
@@ -561,6 +604,9 @@ int cx18_start_v4l2_encode_stream(struct cx18_stream *s)
561 cx->search_pack_header = 0; 604 cx->search_pack_header = 0;
562 break; 605 break;
563 606
607 case CX18_ENC_STREAM_TYPE_IDX:
608 captype = CAPTURE_CHANNEL_TYPE_INDEX;
609 break;
564 case CX18_ENC_STREAM_TYPE_TS: 610 case CX18_ENC_STREAM_TYPE_TS:
565 captype = CAPTURE_CHANNEL_TYPE_TS; 611 captype = CAPTURE_CHANNEL_TYPE_TS;
566 break; 612 break;
@@ -635,11 +681,13 @@ int cx18_start_v4l2_encode_stream(struct cx18_stream *s)
635 cx18_vbi_setup(s); 681 cx18_vbi_setup(s);
636 682
637 /* 683 /*
638 * assign program index info. 684 * Select to receive I, P, and B frame index entries, if the
639 * Mask 7: select I/P/B, Num_req: 400 max 685 * index stream is enabled. Otherwise disable index entry
640 * FIXME - currently we have this hardcoded as disabled 686 * generation.
641 */ 687 */
642 cx18_vapi_result(cx, data, CX18_CPU_SET_INDEXTABLE, 1, 0); 688 s_idx = &cx->streams[CX18_ENC_STREAM_TYPE_IDX];
689 cx18_vapi_result(cx, data, CX18_CPU_SET_INDEXTABLE, 2,
690 s->handle, cx18_stream_enabled(s_idx) ? 7 : 0);
643 691
644 /* Call out to the common CX2341x API setup for user controls */ 692 /* Call out to the common CX2341x API setup for user controls */
645 priv.cx = cx; 693 priv.cx = cx;
@@ -697,6 +745,7 @@ int cx18_start_v4l2_encode_stream(struct cx18_stream *s)
697 atomic_inc(&cx->tot_capturing); 745 atomic_inc(&cx->tot_capturing);
698 return 0; 746 return 0;
699} 747}
748EXPORT_SYMBOL(cx18_start_v4l2_encode_stream);
700 749
701void cx18_stop_all_captures(struct cx18 *cx) 750void cx18_stop_all_captures(struct cx18 *cx)
702{ 751{
@@ -705,7 +754,7 @@ void cx18_stop_all_captures(struct cx18 *cx)
705 for (i = CX18_MAX_STREAMS - 1; i >= 0; i--) { 754 for (i = CX18_MAX_STREAMS - 1; i >= 0; i--) {
706 struct cx18_stream *s = &cx->streams[i]; 755 struct cx18_stream *s = &cx->streams[i];
707 756
708 if (s->video_dev == NULL && s->dvb.enabled == 0) 757 if (!cx18_stream_enabled(s))
709 continue; 758 continue;
710 if (test_bit(CX18_F_S_STREAMING, &s->s_flags)) 759 if (test_bit(CX18_F_S_STREAMING, &s->s_flags))
711 cx18_stop_v4l2_encode_stream(s, 0); 760 cx18_stop_v4l2_encode_stream(s, 0);
@@ -717,7 +766,7 @@ int cx18_stop_v4l2_encode_stream(struct cx18_stream *s, int gop_end)
717 struct cx18 *cx = s->cx; 766 struct cx18 *cx = s->cx;
718 unsigned long then; 767 unsigned long then;
719 768
720 if (s->video_dev == NULL && s->dvb.enabled == 0) 769 if (!cx18_stream_enabled(s))
721 return -EINVAL; 770 return -EINVAL;
722 771
723 /* This function assumes that you are allowed to stop the capture 772 /* This function assumes that you are allowed to stop the capture
@@ -762,6 +811,7 @@ int cx18_stop_v4l2_encode_stream(struct cx18_stream *s, int gop_end)
762 811
763 return 0; 812 return 0;
764} 813}
814EXPORT_SYMBOL(cx18_stop_v4l2_encode_stream);
765 815
766u32 cx18_find_handle(struct cx18 *cx) 816u32 cx18_find_handle(struct cx18 *cx)
767{ 817{
@@ -789,7 +839,7 @@ struct cx18_stream *cx18_handle_to_stream(struct cx18 *cx, u32 handle)
789 s = &cx->streams[i]; 839 s = &cx->streams[i];
790 if (s->handle != handle) 840 if (s->handle != handle)
791 continue; 841 continue;
792 if (s->video_dev || s->dvb.enabled) 842 if (cx18_stream_enabled(s))
793 return s; 843 return s;
794 } 844 }
795 return NULL; 845 return NULL;
diff --git a/drivers/media/video/cx18/cx18-streams.h b/drivers/media/video/cx18/cx18-streams.h
index 4a01db5e5a35..0bff0fa29763 100644
--- a/drivers/media/video/cx18/cx18-streams.h
+++ b/drivers/media/video/cx18/cx18-streams.h
@@ -28,6 +28,16 @@ int cx18_streams_setup(struct cx18 *cx);
28int cx18_streams_register(struct cx18 *cx); 28int cx18_streams_register(struct cx18 *cx);
29void cx18_streams_cleanup(struct cx18 *cx, int unregister); 29void cx18_streams_cleanup(struct cx18 *cx, int unregister);
30 30
31#define CX18_ENC_STREAM_TYPE_IDX_FW_MDL_MIN (3)
32void cx18_stream_rotate_idx_mdls(struct cx18 *cx);
33
34static inline bool cx18_stream_enabled(struct cx18_stream *s)
35{
36 return s->video_dev || s->dvb.enabled ||
37 (s->type == CX18_ENC_STREAM_TYPE_IDX &&
38 s->cx->stream_buffers[CX18_ENC_STREAM_TYPE_IDX] != 0);
39}
40
31/* Related to submission of mdls to firmware */ 41/* Related to submission of mdls to firmware */
32static inline void cx18_stream_load_fw_queue(struct cx18_stream *s) 42static inline void cx18_stream_load_fw_queue(struct cx18_stream *s)
33{ 43{
diff --git a/drivers/media/video/cx18/cx18-version.h b/drivers/media/video/cx18/cx18-version.h
index 9c0b5bb1b019..3e1aec4bcfde 100644
--- a/drivers/media/video/cx18/cx18-version.h
+++ b/drivers/media/video/cx18/cx18-version.h
@@ -24,7 +24,7 @@
24 24
25#define CX18_DRIVER_NAME "cx18" 25#define CX18_DRIVER_NAME "cx18"
26#define CX18_DRIVER_VERSION_MAJOR 1 26#define CX18_DRIVER_VERSION_MAJOR 1
27#define CX18_DRIVER_VERSION_MINOR 3 27#define CX18_DRIVER_VERSION_MINOR 4
28#define CX18_DRIVER_VERSION_PATCHLEVEL 0 28#define CX18_DRIVER_VERSION_PATCHLEVEL 0
29 29
30#define CX18_VERSION __stringify(CX18_DRIVER_VERSION_MAJOR) "." __stringify(CX18_DRIVER_VERSION_MINOR) "." __stringify(CX18_DRIVER_VERSION_PATCHLEVEL) 30#define CX18_VERSION __stringify(CX18_DRIVER_VERSION_MAJOR) "." __stringify(CX18_DRIVER_VERSION_MINOR) "." __stringify(CX18_DRIVER_VERSION_PATCHLEVEL)
diff --git a/drivers/media/video/cx18/cx23418.h b/drivers/media/video/cx18/cx23418.h
index 868806effdcf..2c00980acfcb 100644
--- a/drivers/media/video/cx18/cx23418.h
+++ b/drivers/media/video/cx18/cx23418.h
@@ -191,7 +191,8 @@
191#define CX18_CPU_SET_MEDIAN_CORING (CPU_CMD_MASK_CAPTURE | 0x000E) 191#define CX18_CPU_SET_MEDIAN_CORING (CPU_CMD_MASK_CAPTURE | 0x000E)
192 192
193/* Description: This command set the picture type mask for index file 193/* Description: This command set the picture type mask for index file
194 IN[0] - 0 = disable index file output 194 IN[0] - Task handle (ignored by firmware)
195 IN[1] - 0 = disable index file output
195 1 = output I picture 196 1 = output I picture
196 2 = P picture 197 2 = P picture
197 4 = B picture 198 4 = B picture
diff --git a/drivers/media/video/cx231xx/cx231xx-dvb.c b/drivers/media/video/cx231xx/cx231xx-dvb.c
index c5082a4e8ced..64e025e2bdf1 100644
--- a/drivers/media/video/cx231xx/cx231xx-dvb.c
+++ b/drivers/media/video/cx231xx/cx231xx-dvb.c
@@ -464,9 +464,9 @@ static int dvb_init(struct cx231xx *dev)
464 /* define general-purpose callback pointer */ 464 /* define general-purpose callback pointer */
465 dvb->frontend->callback = cx231xx_tuner_callback; 465 dvb->frontend->callback = cx231xx_tuner_callback;
466 466
467 if (dvb_attach(xc5000_attach, dev->dvb->frontend, 467 if (!dvb_attach(xc5000_attach, dev->dvb->frontend,
468 &dev->i2c_bus[1].i2c_adap, 468 &dev->i2c_bus[1].i2c_adap,
469 &cnxt_rde250_tunerconfig) < 0) { 469 &cnxt_rde250_tunerconfig)) {
470 result = -EINVAL; 470 result = -EINVAL;
471 goto out_free; 471 goto out_free;
472 } 472 }
@@ -486,9 +486,9 @@ static int dvb_init(struct cx231xx *dev)
486 /* define general-purpose callback pointer */ 486 /* define general-purpose callback pointer */
487 dvb->frontend->callback = cx231xx_tuner_callback; 487 dvb->frontend->callback = cx231xx_tuner_callback;
488 488
489 if (dvb_attach(xc5000_attach, dev->dvb->frontend, 489 if (!dvb_attach(xc5000_attach, dev->dvb->frontend,
490 &dev->i2c_bus[1].i2c_adap, 490 &dev->i2c_bus[1].i2c_adap,
491 &cnxt_rde250_tunerconfig) < 0) { 491 &cnxt_rde250_tunerconfig)) {
492 result = -EINVAL; 492 result = -EINVAL;
493 goto out_free; 493 goto out_free;
494 } 494 }
diff --git a/drivers/media/video/cx231xx/cx231xx-input.c b/drivers/media/video/cx231xx/cx231xx-input.c
index 15826f98b688..c5771db3bfce 100644
--- a/drivers/media/video/cx231xx/cx231xx-input.c
+++ b/drivers/media/video/cx231xx/cx231xx-input.c
@@ -216,7 +216,7 @@ int cx231xx_ir_init(struct cx231xx *dev)
216 cx231xx_ir_start(ir); 216 cx231xx_ir_start(ir);
217 217
218 /* all done */ 218 /* all done */
219 err = ir_input_register(ir->input, dev->board.ir_codes); 219 err = ir_input_register(ir->input, dev->board.ir_codes, NULL);
220 if (err) 220 if (err)
221 goto err_out_stop; 221 goto err_out_stop;
222 222
diff --git a/drivers/media/video/cx23885/cx23885-417.c b/drivers/media/video/cx23885/cx23885-417.c
index 88c0d2481118..2ab97ad7b6fb 100644
--- a/drivers/media/video/cx23885/cx23885-417.c
+++ b/drivers/media/video/cx23885/cx23885-417.c
@@ -681,7 +681,7 @@ static char *cmd_to_str(int cmd)
681 case CX2341X_ENC_SET_VIDEO_ID: 681 case CX2341X_ENC_SET_VIDEO_ID:
682 return "SET_VIDEO_ID"; 682 return "SET_VIDEO_ID";
683 case CX2341X_ENC_SET_PCR_ID: 683 case CX2341X_ENC_SET_PCR_ID:
684 return "SET_PCR_PID"; 684 return "SET_PCR_ID";
685 case CX2341X_ENC_SET_FRAME_RATE: 685 case CX2341X_ENC_SET_FRAME_RATE:
686 return "SET_FRAME_RATE"; 686 return "SET_FRAME_RATE";
687 case CX2341X_ENC_SET_FRAME_SIZE: 687 case CX2341X_ENC_SET_FRAME_SIZE:
@@ -693,7 +693,7 @@ static char *cmd_to_str(int cmd)
693 case CX2341X_ENC_SET_ASPECT_RATIO: 693 case CX2341X_ENC_SET_ASPECT_RATIO:
694 return "SET_ASPECT_RATIO"; 694 return "SET_ASPECT_RATIO";
695 case CX2341X_ENC_SET_DNR_FILTER_MODE: 695 case CX2341X_ENC_SET_DNR_FILTER_MODE:
696 return "SET_DNR_FILTER_PROPS"; 696 return "SET_DNR_FILTER_MODE";
697 case CX2341X_ENC_SET_DNR_FILTER_PROPS: 697 case CX2341X_ENC_SET_DNR_FILTER_PROPS:
698 return "SET_DNR_FILTER_PROPS"; 698 return "SET_DNR_FILTER_PROPS";
699 case CX2341X_ENC_SET_CORING_LEVELS: 699 case CX2341X_ENC_SET_CORING_LEVELS:
diff --git a/drivers/media/video/cx23885/cx23885-cards.c b/drivers/media/video/cx23885/cx23885-cards.c
index 1ec48169277d..d639186f645d 100644
--- a/drivers/media/video/cx23885/cx23885-cards.c
+++ b/drivers/media/video/cx23885/cx23885-cards.c
@@ -274,6 +274,31 @@ struct cx23885_board cx23885_boards[] = {
274 .portb = CX23885_MPEG_DVB, 274 .portb = CX23885_MPEG_DVB,
275 .portc = CX23885_MPEG_DVB, 275 .portc = CX23885_MPEG_DVB,
276 }, 276 },
277 [CX23885_BOARD_LEADTEK_WINFAST_PXTV1200] = {
278 .name = "LEADTEK WinFast PxTV1200",
279 .porta = CX23885_ANALOG_VIDEO,
280 .tuner_type = TUNER_XC2028,
281 .tuner_addr = 0x61,
282 .input = {{
283 .type = CX23885_VMUX_TELEVISION,
284 .vmux = CX25840_VIN2_CH1 |
285 CX25840_VIN5_CH2 |
286 CX25840_NONE0_CH3,
287 }, {
288 .type = CX23885_VMUX_COMPOSITE1,
289 .vmux = CX25840_COMPOSITE1,
290 }, {
291 .type = CX23885_VMUX_SVIDEO,
292 .vmux = CX25840_SVIDEO_LUMA3 |
293 CX25840_SVIDEO_CHROMA4,
294 }, {
295 .type = CX23885_VMUX_COMPONENT,
296 .vmux = CX25840_VIN7_CH1 |
297 CX25840_VIN6_CH2 |
298 CX25840_VIN8_CH3 |
299 CX25840_COMPONENT_ON,
300 } },
301 },
277}; 302};
278const unsigned int cx23885_bcount = ARRAY_SIZE(cx23885_boards); 303const unsigned int cx23885_bcount = ARRAY_SIZE(cx23885_boards);
279 304
@@ -417,6 +442,10 @@ struct cx23885_subid cx23885_subids[] = {
417 .subvendor = 0x14f1, 442 .subvendor = 0x14f1,
418 .subdevice = 0x8578, 443 .subdevice = 0x8578,
419 .card = CX23885_BOARD_MYGICA_X8558PRO, 444 .card = CX23885_BOARD_MYGICA_X8558PRO,
445 }, {
446 .subvendor = 0x107d,
447 .subdevice = 0x6f22,
448 .card = CX23885_BOARD_LEADTEK_WINFAST_PXTV1200,
420 }, 449 },
421}; 450};
422const unsigned int cx23885_idcount = ARRAY_SIZE(cx23885_subids); 451const unsigned int cx23885_idcount = ARRAY_SIZE(cx23885_subids);
@@ -617,6 +646,7 @@ int cx23885_tuner_callback(void *priv, int component, int command, int arg)
617 case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H: 646 case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H:
618 case CX23885_BOARD_COMPRO_VIDEOMATE_E650F: 647 case CX23885_BOARD_COMPRO_VIDEOMATE_E650F:
619 case CX23885_BOARD_COMPRO_VIDEOMATE_E800: 648 case CX23885_BOARD_COMPRO_VIDEOMATE_E800:
649 case CX23885_BOARD_LEADTEK_WINFAST_PXTV1200:
620 /* Tuner Reset Command */ 650 /* Tuner Reset Command */
621 bitmask = 0x04; 651 bitmask = 0x04;
622 break; 652 break;
@@ -769,6 +799,7 @@ void cx23885_gpio_setup(struct cx23885_dev *dev)
769 case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H: 799 case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H:
770 case CX23885_BOARD_COMPRO_VIDEOMATE_E650F: 800 case CX23885_BOARD_COMPRO_VIDEOMATE_E650F:
771 case CX23885_BOARD_COMPRO_VIDEOMATE_E800: 801 case CX23885_BOARD_COMPRO_VIDEOMATE_E800:
802 case CX23885_BOARD_LEADTEK_WINFAST_PXTV1200:
772 /* GPIO-2 xc3028 tuner reset */ 803 /* GPIO-2 xc3028 tuner reset */
773 804
774 /* The following GPIO's are on the internal AVCore (cx25840) */ 805 /* The following GPIO's are on the internal AVCore (cx25840) */
@@ -1076,6 +1107,7 @@ void cx23885_card_setup(struct cx23885_dev *dev)
1076 case CX23885_BOARD_MYGICA_X8506: 1107 case CX23885_BOARD_MYGICA_X8506:
1077 case CX23885_BOARD_MAGICPRO_PROHDTVE2: 1108 case CX23885_BOARD_MAGICPRO_PROHDTVE2:
1078 case CX23885_BOARD_HAUPPAUGE_HVR1290: 1109 case CX23885_BOARD_HAUPPAUGE_HVR1290:
1110 case CX23885_BOARD_LEADTEK_WINFAST_PXTV1200:
1079 dev->sd_cx25840 = v4l2_i2c_new_subdev(&dev->v4l2_dev, 1111 dev->sd_cx25840 = v4l2_i2c_new_subdev(&dev->v4l2_dev,
1080 &dev->i2c_bus[2].i2c_adap, 1112 &dev->i2c_bus[2].i2c_adap,
1081 "cx25840", "cx25840", 0x88 >> 1, NULL); 1113 "cx25840", "cx25840", 0x88 >> 1, NULL);
diff --git a/drivers/media/video/cx23885/cx23885-dvb.c b/drivers/media/video/cx23885/cx23885-dvb.c
index e45d2df08138..939079d7bbb9 100644
--- a/drivers/media/video/cx23885/cx23885-dvb.c
+++ b/drivers/media/video/cx23885/cx23885-dvb.c
@@ -542,6 +542,9 @@ static struct atbm8830_config mygica_x8558pro_atbm8830_cfg1 = {
542 .osc_clk_freq = 30400, /* in kHz */ 542 .osc_clk_freq = 30400, /* in kHz */
543 .if_freq = 0, /* zero IF */ 543 .if_freq = 0, /* zero IF */
544 .zif_swap_iq = 1, 544 .zif_swap_iq = 1,
545 .agc_min = 0x2E,
546 .agc_max = 0xFF,
547 .agc_hold_loop = 0,
545}; 548};
546 549
547static struct max2165_config mygic_x8558pro_max2165_cfg1 = { 550static struct max2165_config mygic_x8558pro_max2165_cfg1 = {
@@ -558,6 +561,9 @@ static struct atbm8830_config mygica_x8558pro_atbm8830_cfg2 = {
558 .osc_clk_freq = 30400, /* in kHz */ 561 .osc_clk_freq = 30400, /* in kHz */
559 .if_freq = 0, /* zero IF */ 562 .if_freq = 0, /* zero IF */
560 .zif_swap_iq = 1, 563 .zif_swap_iq = 1,
564 .agc_min = 0x2E,
565 .agc_max = 0xFF,
566 .agc_hold_loop = 0,
561}; 567};
562 568
563static struct max2165_config mygic_x8558pro_max2165_cfg2 = { 569static struct max2165_config mygic_x8558pro_max2165_cfg2 = {
@@ -994,15 +1000,8 @@ static int dvb_register(struct cx23885_tsport *port)
994 netup_get_card_info(&dev->i2c_bus[0].i2c_adap, &cinfo); 1000 netup_get_card_info(&dev->i2c_bus[0].i2c_adap, &cinfo);
995 memcpy(port->frontends.adapter.proposed_mac, 1001 memcpy(port->frontends.adapter.proposed_mac,
996 cinfo.port[port->nr - 1].mac, 6); 1002 cinfo.port[port->nr - 1].mac, 6);
997 printk(KERN_INFO "NetUP Dual DVB-S2 CI card port%d MAC=" 1003 printk(KERN_INFO "NetUP Dual DVB-S2 CI card port%d MAC=%pM\n",
998 "%02X:%02X:%02X:%02X:%02X:%02X\n", 1004 port->nr, port->frontends.adapter.proposed_mac);
999 port->nr,
1000 port->frontends.adapter.proposed_mac[0],
1001 port->frontends.adapter.proposed_mac[1],
1002 port->frontends.adapter.proposed_mac[2],
1003 port->frontends.adapter.proposed_mac[3],
1004 port->frontends.adapter.proposed_mac[4],
1005 port->frontends.adapter.proposed_mac[5]);
1006 1005
1007 netup_ci_init(port); 1006 netup_ci_init(port);
1008 break; 1007 break;
diff --git a/drivers/media/video/cx23885/cx23885-input.c b/drivers/media/video/cx23885/cx23885-input.c
index 768eec92ccf9..9c6620f86dca 100644
--- a/drivers/media/video/cx23885/cx23885-input.c
+++ b/drivers/media/video/cx23885/cx23885-input.c
@@ -397,7 +397,7 @@ int cx23885_input_init(struct cx23885_dev *dev)
397 dev->ir_input = ir; 397 dev->ir_input = ir;
398 cx23885_input_ir_start(dev); 398 cx23885_input_ir_start(dev);
399 399
400 ret = ir_input_register(ir->dev, ir_codes); 400 ret = ir_input_register(ir->dev, ir_codes, NULL);
401 if (ret) 401 if (ret)
402 goto err_out_stop; 402 goto err_out_stop;
403 403
diff --git a/drivers/media/video/cx23885/cx23885-video.c b/drivers/media/video/cx23885/cx23885-video.c
index 8934d61cf660..2d3ac8b83dc3 100644
--- a/drivers/media/video/cx23885/cx23885-video.c
+++ b/drivers/media/video/cx23885/cx23885-video.c
@@ -36,6 +36,7 @@
36#include <media/v4l2-common.h> 36#include <media/v4l2-common.h>
37#include <media/v4l2-ioctl.h> 37#include <media/v4l2-ioctl.h>
38#include "cx23885-ioctl.h" 38#include "cx23885-ioctl.h"
39#include "tuner-xc2028.h"
39 40
40MODULE_DESCRIPTION("v4l2 driver module for cx23885 based TV cards"); 41MODULE_DESCRIPTION("v4l2 driver module for cx23885 based TV cards");
41MODULE_AUTHOR("Steven Toth <stoth@linuxtv.org>"); 42MODULE_AUTHOR("Steven Toth <stoth@linuxtv.org>");
@@ -1505,6 +1506,18 @@ int cx23885_video_register(struct cx23885_dev *dev)
1505 tun_setup.tuner_callback = cx23885_tuner_callback; 1506 tun_setup.tuner_callback = cx23885_tuner_callback;
1506 1507
1507 v4l2_subdev_call(sd, tuner, s_type_addr, &tun_setup); 1508 v4l2_subdev_call(sd, tuner, s_type_addr, &tun_setup);
1509
1510 if (dev->board == CX23885_BOARD_LEADTEK_WINFAST_PXTV1200) {
1511 struct xc2028_ctrl ctrl = {
1512 .fname = XC2028_DEFAULT_FIRMWARE,
1513 .max_len = 64
1514 };
1515 struct v4l2_priv_tun_config cfg = {
1516 .tuner = dev->tuner_type,
1517 .priv = &ctrl
1518 };
1519 v4l2_subdev_call(sd, tuner, s_config, &cfg);
1520 }
1508 } 1521 }
1509 } 1522 }
1510 1523
diff --git a/drivers/media/video/cx23885/cx23885.h b/drivers/media/video/cx23885/cx23885.h
index 08b3f6b136a0..0e3a98d243c5 100644
--- a/drivers/media/video/cx23885/cx23885.h
+++ b/drivers/media/video/cx23885/cx23885.h
@@ -81,6 +81,7 @@
81#define CX23885_BOARD_COMPRO_VIDEOMATE_E800 25 81#define CX23885_BOARD_COMPRO_VIDEOMATE_E800 25
82#define CX23885_BOARD_HAUPPAUGE_HVR1290 26 82#define CX23885_BOARD_HAUPPAUGE_HVR1290 26
83#define CX23885_BOARD_MYGICA_X8558PRO 27 83#define CX23885_BOARD_MYGICA_X8558PRO 27
84#define CX23885_BOARD_LEADTEK_WINFAST_PXTV1200 28
84 85
85#define GPIO_0 0x00000001 86#define GPIO_0 0x00000001
86#define GPIO_1 0x00000002 87#define GPIO_1 0x00000002
diff --git a/drivers/media/video/cx25840/cx25840-core.c b/drivers/media/video/cx25840/cx25840-core.c
index 385ecd58f1c0..f2461cd3de5a 100644
--- a/drivers/media/video/cx25840/cx25840-core.c
+++ b/drivers/media/video/cx25840/cx25840-core.c
@@ -734,10 +734,8 @@ static int set_input(struct i2c_client *client, enum cx25840_video_input vid_inp
734 v4l_dbg(1, cx25840_debug, client, "vid_input 0x%x\n", 734 v4l_dbg(1, cx25840_debug, client, "vid_input 0x%x\n",
735 vid_input); 735 vid_input);
736 reg = vid_input & 0xff; 736 reg = vid_input & 0xff;
737 if ((vid_input & CX25840_SVIDEO_ON) == CX25840_SVIDEO_ON) 737 is_composite = !is_component &&
738 is_composite = 0; 738 ((vid_input & CX25840_SVIDEO_ON) != CX25840_SVIDEO_ON);
739 else if ((vid_input & CX25840_COMPONENT_ON) == 0)
740 is_composite = 1;
741 739
742 v4l_dbg(1, cx25840_debug, client, "mux cfg 0x%x comp=%d\n", 740 v4l_dbg(1, cx25840_debug, client, "mux cfg 0x%x comp=%d\n",
743 reg, is_composite); 741 reg, is_composite);
@@ -1347,30 +1345,59 @@ static int cx25840_s_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *
1347} 1345}
1348#endif 1346#endif
1349 1347
1348static int cx25840_s_audio_stream(struct v4l2_subdev *sd, int enable)
1349{
1350 struct cx25840_state *state = to_state(sd);
1351 struct i2c_client *client = v4l2_get_subdevdata(sd);
1352 u8 v;
1353
1354 if (is_cx2583x(state) || is_cx2388x(state) || is_cx231xx(state))
1355 return 0;
1356
1357 v4l_dbg(1, cx25840_debug, client, "%s audio output\n",
1358 enable ? "enable" : "disable");
1359
1360 if (enable) {
1361 v = cx25840_read(client, 0x115) | 0x80;
1362 cx25840_write(client, 0x115, v);
1363 v = cx25840_read(client, 0x116) | 0x03;
1364 cx25840_write(client, 0x116, v);
1365 } else {
1366 v = cx25840_read(client, 0x115) & ~(0x80);
1367 cx25840_write(client, 0x115, v);
1368 v = cx25840_read(client, 0x116) & ~(0x03);
1369 cx25840_write(client, 0x116, v);
1370 }
1371 return 0;
1372}
1373
1350static int cx25840_s_stream(struct v4l2_subdev *sd, int enable) 1374static int cx25840_s_stream(struct v4l2_subdev *sd, int enable)
1351{ 1375{
1352 struct cx25840_state *state = to_state(sd); 1376 struct cx25840_state *state = to_state(sd);
1353 struct i2c_client *client = v4l2_get_subdevdata(sd); 1377 struct i2c_client *client = v4l2_get_subdevdata(sd);
1378 u8 v;
1354 1379
1355 v4l_dbg(1, cx25840_debug, client, "%s output\n", 1380 v4l_dbg(1, cx25840_debug, client, "%s video output\n",
1356 enable ? "enable" : "disable"); 1381 enable ? "enable" : "disable");
1357 if (enable) { 1382 if (enable) {
1358 if (is_cx2388x(state) || is_cx231xx(state)) { 1383 if (is_cx2388x(state) || is_cx231xx(state)) {
1359 u8 v = (cx25840_read(client, 0x421) | 0x0b); 1384 v = cx25840_read(client, 0x421) | 0x0b;
1360 cx25840_write(client, 0x421, v); 1385 cx25840_write(client, 0x421, v);
1361 } else { 1386 } else {
1362 cx25840_write(client, 0x115, 1387 v = cx25840_read(client, 0x115) | 0x0c;
1363 is_cx2583x(state) ? 0x0c : 0x8c); 1388 cx25840_write(client, 0x115, v);
1364 cx25840_write(client, 0x116, 1389 v = cx25840_read(client, 0x116) | 0x04;
1365 is_cx2583x(state) ? 0x04 : 0x07); 1390 cx25840_write(client, 0x116, v);
1366 } 1391 }
1367 } else { 1392 } else {
1368 if (is_cx2388x(state) || is_cx231xx(state)) { 1393 if (is_cx2388x(state) || is_cx231xx(state)) {
1369 u8 v = cx25840_read(client, 0x421) & ~(0x0b); 1394 v = cx25840_read(client, 0x421) & ~(0x0b);
1370 cx25840_write(client, 0x421, v); 1395 cx25840_write(client, 0x421, v);
1371 } else { 1396 } else {
1372 cx25840_write(client, 0x115, 0x00); 1397 v = cx25840_read(client, 0x115) & ~(0x0c);
1373 cx25840_write(client, 0x116, 0x00); 1398 cx25840_write(client, 0x115, v);
1399 v = cx25840_read(client, 0x116) & ~(0x04);
1400 cx25840_write(client, 0x116, v);
1374 } 1401 }
1375 } 1402 }
1376 return 0; 1403 return 0;
@@ -1601,6 +1628,7 @@ static const struct v4l2_subdev_tuner_ops cx25840_tuner_ops = {
1601static const struct v4l2_subdev_audio_ops cx25840_audio_ops = { 1628static const struct v4l2_subdev_audio_ops cx25840_audio_ops = {
1602 .s_clock_freq = cx25840_s_clock_freq, 1629 .s_clock_freq = cx25840_s_clock_freq,
1603 .s_routing = cx25840_s_audio_routing, 1630 .s_routing = cx25840_s_audio_routing,
1631 .s_stream = cx25840_s_audio_stream,
1604}; 1632};
1605 1633
1606static const struct v4l2_subdev_video_ops cx25840_video_ops = { 1634static const struct v4l2_subdev_video_ops cx25840_video_ops = {
diff --git a/drivers/media/video/cx88/cx88-alsa.c b/drivers/media/video/cx88/cx88-alsa.c
index 5a67445dd6ed..64b350df78e3 100644
--- a/drivers/media/video/cx88/cx88-alsa.c
+++ b/drivers/media/video/cx88/cx88-alsa.c
@@ -583,16 +583,18 @@ static int snd_cx88_volume_put(struct snd_kcontrol *kcontrol,
583{ 583{
584 snd_cx88_card_t *chip = snd_kcontrol_chip(kcontrol); 584 snd_cx88_card_t *chip = snd_kcontrol_chip(kcontrol);
585 struct cx88_core *core=chip->core; 585 struct cx88_core *core=chip->core;
586 int v, b; 586 int left, right, v, b;
587 int changed = 0; 587 int changed = 0;
588 u32 old; 588 u32 old;
589 589
590 b = value->value.integer.value[1] - value->value.integer.value[0]; 590 left = value->value.integer.value[0] & 0x3f;
591 right = value->value.integer.value[1] & 0x3f;
592 b = right - left;
591 if (b < 0) { 593 if (b < 0) {
592 v = 0x3f - value->value.integer.value[0]; 594 v = 0x3f - left;
593 b = (-b) | 0x40; 595 b = (-b) | 0x40;
594 } else { 596 } else {
595 v = 0x3f - value->value.integer.value[1]; 597 v = 0x3f - right;
596 } 598 }
597 /* Do we really know this will always be called with IRQs on? */ 599 /* Do we really know this will always be called with IRQs on? */
598 spin_lock_irq(&chip->reg_lock); 600 spin_lock_irq(&chip->reg_lock);
diff --git a/drivers/media/video/cx88/cx88-cards.c b/drivers/media/video/cx88/cx88-cards.c
index d844f2aaa01d..eaf0ee7de832 100644
--- a/drivers/media/video/cx88/cx88-cards.c
+++ b/drivers/media/video/cx88/cx88-cards.c
@@ -1466,6 +1466,18 @@ static const struct cx88_board cx88_boards[] = {
1466 .audioroute = 8, 1466 .audioroute = 8,
1467 }, 1467 },
1468 }, 1468 },
1469 [CX88_BOARD_SAMSUNG_SMT_7020] = {
1470 .name = "Samsung SMT 7020 DVB-S",
1471 .tuner_type = TUNER_ABSENT,
1472 .radio_type = UNSET,
1473 .tuner_addr = ADDR_UNSET,
1474 .radio_addr = ADDR_UNSET,
1475 .input = { {
1476 .type = CX88_VMUX_DVB,
1477 .vmux = 0,
1478 } },
1479 .mpeg = CX88_MPEG_DVB,
1480 },
1469 [CX88_BOARD_ADSTECH_PTV_390] = { 1481 [CX88_BOARD_ADSTECH_PTV_390] = {
1470 .name = "ADS Tech Instant Video PCI", 1482 .name = "ADS Tech Instant Video PCI",
1471 .tuner_type = TUNER_ABSENT, 1483 .tuner_type = TUNER_ABSENT,
@@ -2355,6 +2367,14 @@ static const struct cx88_subid cx88_subids[] = {
2355 .subvendor = 0x0070, 2367 .subvendor = 0x0070,
2356 .subdevice = 0x1404, 2368 .subdevice = 0x1404,
2357 .card = CX88_BOARD_HAUPPAUGE_HVR3000, 2369 .card = CX88_BOARD_HAUPPAUGE_HVR3000,
2370 }, {
2371 .subvendor = 0x18ac,
2372 .subdevice = 0xdc00,
2373 .card = CX88_BOARD_SAMSUNG_SMT_7020,
2374 }, {
2375 .subvendor = 0x18ac,
2376 .subdevice = 0xdccd,
2377 .card = CX88_BOARD_SAMSUNG_SMT_7020,
2358 },{ 2378 },{
2359 .subvendor = 0x1461, 2379 .subvendor = 0x1461,
2360 .subdevice = 0xc111, /* AverMedia M150-D */ 2380 .subdevice = 0xc111, /* AverMedia M150-D */
@@ -2633,6 +2653,9 @@ static void hauppauge_eeprom(struct cx88_core *core, u8 *eeprom_data)
2633 case 98559: /* WinTV-HVR1100LP (Video no IR, Retail - Low Profile) */ 2653 case 98559: /* WinTV-HVR1100LP (Video no IR, Retail - Low Profile) */
2634 /* known */ 2654 /* known */
2635 break; 2655 break;
2656 case CX88_BOARD_SAMSUNG_SMT_7020:
2657 cx_set(MO_GP0_IO, 0x008989FF);
2658 break;
2636 default: 2659 default:
2637 warn_printk(core, "warning: unknown hauppauge model #%d\n", 2660 warn_printk(core, "warning: unknown hauppauge model #%d\n",
2638 tv.model); 2661 tv.model);
diff --git a/drivers/media/video/cx88/cx88-dvb.c b/drivers/media/video/cx88/cx88-dvb.c
index b14296923250..94ab862f0219 100644
--- a/drivers/media/video/cx88/cx88-dvb.c
+++ b/drivers/media/video/cx88/cx88-dvb.c
@@ -674,6 +674,194 @@ static int cx8802_alloc_frontends(struct cx8802_dev *dev)
674 return 0; 674 return 0;
675} 675}
676 676
677
678
679static u8 samsung_smt_7020_inittab[] = {
680 0x01, 0x15,
681 0x02, 0x00,
682 0x03, 0x00,
683 0x04, 0x7D,
684 0x05, 0x0F,
685 0x06, 0x02,
686 0x07, 0x00,
687 0x08, 0x60,
688
689 0x0A, 0xC2,
690 0x0B, 0x00,
691 0x0C, 0x01,
692 0x0D, 0x81,
693 0x0E, 0x44,
694 0x0F, 0x09,
695 0x10, 0x3C,
696 0x11, 0x84,
697 0x12, 0xDA,
698 0x13, 0x99,
699 0x14, 0x8D,
700 0x15, 0xCE,
701 0x16, 0xE8,
702 0x17, 0x43,
703 0x18, 0x1C,
704 0x19, 0x1B,
705 0x1A, 0x1D,
706
707 0x1C, 0x12,
708 0x1D, 0x00,
709 0x1E, 0x00,
710 0x1F, 0x00,
711 0x20, 0x00,
712 0x21, 0x00,
713 0x22, 0x00,
714 0x23, 0x00,
715
716 0x28, 0x02,
717 0x29, 0x28,
718 0x2A, 0x14,
719 0x2B, 0x0F,
720 0x2C, 0x09,
721 0x2D, 0x05,
722
723 0x31, 0x1F,
724 0x32, 0x19,
725 0x33, 0xFC,
726 0x34, 0x13,
727 0xff, 0xff,
728};
729
730
731static int samsung_smt_7020_tuner_set_params(struct dvb_frontend *fe,
732 struct dvb_frontend_parameters *params)
733{
734 struct cx8802_dev *dev = fe->dvb->priv;
735 u8 buf[4];
736 u32 div;
737 struct i2c_msg msg = {
738 .addr = 0x61,
739 .flags = 0,
740 .buf = buf,
741 .len = sizeof(buf) };
742
743 div = params->frequency / 125;
744
745 buf[0] = (div >> 8) & 0x7f;
746 buf[1] = div & 0xff;
747 buf[2] = 0x84; /* 0xC4 */
748 buf[3] = 0x00;
749
750 if (params->frequency < 1500000)
751 buf[3] |= 0x10;
752
753 if (fe->ops.i2c_gate_ctrl)
754 fe->ops.i2c_gate_ctrl(fe, 1);
755
756 if (i2c_transfer(&dev->core->i2c_adap, &msg, 1) != 1)
757 return -EIO;
758
759 return 0;
760}
761
762static int samsung_smt_7020_set_tone(struct dvb_frontend *fe,
763 fe_sec_tone_mode_t tone)
764{
765 struct cx8802_dev *dev = fe->dvb->priv;
766 struct cx88_core *core = dev->core;
767
768 cx_set(MO_GP0_IO, 0x0800);
769
770 switch (tone) {
771 case SEC_TONE_ON:
772 cx_set(MO_GP0_IO, 0x08);
773 break;
774 case SEC_TONE_OFF:
775 cx_clear(MO_GP0_IO, 0x08);
776 break;
777 default:
778 return -EINVAL;
779 }
780
781 return 0;
782}
783
784static int samsung_smt_7020_set_voltage(struct dvb_frontend *fe,
785 fe_sec_voltage_t voltage)
786{
787 struct cx8802_dev *dev = fe->dvb->priv;
788 struct cx88_core *core = dev->core;
789
790 u8 data;
791 struct i2c_msg msg = {
792 .addr = 8,
793 .flags = 0,
794 .buf = &data,
795 .len = sizeof(data) };
796
797 cx_set(MO_GP0_IO, 0x8000);
798
799 switch (voltage) {
800 case SEC_VOLTAGE_OFF:
801 break;
802 case SEC_VOLTAGE_13:
803 data = ISL6421_EN1 | ISL6421_LLC1;
804 cx_clear(MO_GP0_IO, 0x80);
805 break;
806 case SEC_VOLTAGE_18:
807 data = ISL6421_EN1 | ISL6421_LLC1 | ISL6421_VSEL1;
808 cx_clear(MO_GP0_IO, 0x80);
809 break;
810 default:
811 return -EINVAL;
812 };
813
814 return (i2c_transfer(&dev->core->i2c_adap, &msg, 1) == 1) ? 0 : -EIO;
815}
816
817static int samsung_smt_7020_stv0299_set_symbol_rate(struct dvb_frontend *fe,
818 u32 srate, u32 ratio)
819{
820 u8 aclk = 0;
821 u8 bclk = 0;
822
823 if (srate < 1500000) {
824 aclk = 0xb7;
825 bclk = 0x47;
826 } else if (srate < 3000000) {
827 aclk = 0xb7;
828 bclk = 0x4b;
829 } else if (srate < 7000000) {
830 aclk = 0xb7;
831 bclk = 0x4f;
832 } else if (srate < 14000000) {
833 aclk = 0xb7;
834 bclk = 0x53;
835 } else if (srate < 30000000) {
836 aclk = 0xb6;
837 bclk = 0x53;
838 } else if (srate < 45000000) {
839 aclk = 0xb4;
840 bclk = 0x51;
841 }
842
843 stv0299_writereg(fe, 0x13, aclk);
844 stv0299_writereg(fe, 0x14, bclk);
845 stv0299_writereg(fe, 0x1f, (ratio >> 16) & 0xff);
846 stv0299_writereg(fe, 0x20, (ratio >> 8) & 0xff);
847 stv0299_writereg(fe, 0x21, ratio & 0xf0);
848
849 return 0;
850}
851
852
853static struct stv0299_config samsung_stv0299_config = {
854 .demod_address = 0x68,
855 .inittab = samsung_smt_7020_inittab,
856 .mclk = 88000000UL,
857 .invert = 0,
858 .skip_reinit = 0,
859 .lock_output = STV0299_LOCKOUTPUT_LK,
860 .volt13_op0_op1 = STV0299_VOLT13_OP1,
861 .min_delay_ms = 100,
862 .set_symbol_rate = samsung_smt_7020_stv0299_set_symbol_rate,
863};
864
677static int dvb_register(struct cx8802_dev *dev) 865static int dvb_register(struct cx8802_dev *dev)
678{ 866{
679 struct cx88_core *core = dev->core; 867 struct cx88_core *core = dev->core;
@@ -1203,6 +1391,32 @@ static int dvb_register(struct cx8802_dev *dev)
1203 } 1391 }
1204 break; 1392 break;
1205 } 1393 }
1394 case CX88_BOARD_SAMSUNG_SMT_7020:
1395 dev->ts_gen_cntrl = 0x08;
1396
1397 cx_set(MO_GP0_IO, 0x0101);
1398
1399 cx_clear(MO_GP0_IO, 0x01);
1400 mdelay(100);
1401 cx_set(MO_GP0_IO, 0x01);
1402 mdelay(200);
1403
1404 fe0->dvb.frontend = dvb_attach(stv0299_attach,
1405 &samsung_stv0299_config,
1406 &dev->core->i2c_adap);
1407 if (fe0->dvb.frontend) {
1408 fe0->dvb.frontend->ops.tuner_ops.set_params =
1409 samsung_smt_7020_tuner_set_params;
1410 fe0->dvb.frontend->tuner_priv =
1411 &dev->core->i2c_adap;
1412 fe0->dvb.frontend->ops.set_voltage =
1413 samsung_smt_7020_set_voltage;
1414 fe0->dvb.frontend->ops.set_tone =
1415 samsung_smt_7020_set_tone;
1416 }
1417
1418 break;
1419
1206 default: 1420 default:
1207 printk(KERN_ERR "%s/2: The frontend of your DVB/ATSC card isn't supported yet\n", 1421 printk(KERN_ERR "%s/2: The frontend of your DVB/ATSC card isn't supported yet\n",
1208 core->name); 1422 core->name);
diff --git a/drivers/media/video/cx88/cx88-input.c b/drivers/media/video/cx88/cx88-input.c
index f9fda18b410c..de180d4d5a21 100644
--- a/drivers/media/video/cx88/cx88-input.c
+++ b/drivers/media/video/cx88/cx88-input.c
@@ -192,7 +192,7 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci)
192 struct cx88_IR *ir; 192 struct cx88_IR *ir;
193 struct input_dev *input_dev; 193 struct input_dev *input_dev;
194 struct ir_scancode_table *ir_codes = NULL; 194 struct ir_scancode_table *ir_codes = NULL;
195 int ir_type = IR_TYPE_OTHER; 195 u64 ir_type = IR_TYPE_OTHER;
196 int err = -ENOMEM; 196 int err = -ENOMEM;
197 197
198 ir = kzalloc(sizeof(*ir), GFP_KERNEL); 198 ir = kzalloc(sizeof(*ir), GFP_KERNEL);
@@ -383,7 +383,7 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci)
383 cx88_ir_start(core, ir); 383 cx88_ir_start(core, ir);
384 384
385 /* all done */ 385 /* all done */
386 err = ir_input_register(ir->input, ir_codes); 386 err = ir_input_register(ir->input, ir_codes, NULL);
387 if (err) 387 if (err)
388 goto err_out_stop; 388 goto err_out_stop;
389 389
diff --git a/drivers/media/video/cx88/cx88-mpeg.c b/drivers/media/video/cx88/cx88-mpeg.c
index bb5104893411..338af77f7f01 100644
--- a/drivers/media/video/cx88/cx88-mpeg.c
+++ b/drivers/media/video/cx88/cx88-mpeg.c
@@ -110,6 +110,9 @@ static int cx8802_start_dma(struct cx8802_dev *dev,
110 case CX88_BOARD_PCHDTV_HD5500: 110 case CX88_BOARD_PCHDTV_HD5500:
111 cx_write(TS_SOP_STAT, 1<<13); 111 cx_write(TS_SOP_STAT, 1<<13);
112 break; 112 break;
113 case CX88_BOARD_SAMSUNG_SMT_7020:
114 cx_write(TS_SOP_STAT, 0x00);
115 break;
113 case CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1: 116 case CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1:
114 case CX88_BOARD_HAUPPAUGE_NOVASE2_S1: 117 case CX88_BOARD_HAUPPAUGE_NOVASE2_S1:
115 cx_write(MO_PINMUX_IO, 0x88); /* Enable MPEG parallel IO and video signal pins */ 118 cx_write(MO_PINMUX_IO, 0x88); /* Enable MPEG parallel IO and video signal pins */
diff --git a/drivers/media/video/cx88/cx88.h b/drivers/media/video/cx88/cx88.h
index b1499bf604ea..48b6c04fb497 100644
--- a/drivers/media/video/cx88/cx88.h
+++ b/drivers/media/video/cx88/cx88.h
@@ -239,6 +239,7 @@ extern struct sram_channel cx88_sram_channels[];
239#define CX88_BOARD_WINFAST_DTV1800H 81 239#define CX88_BOARD_WINFAST_DTV1800H 81
240#define CX88_BOARD_WINFAST_DTV2000H_J 82 240#define CX88_BOARD_WINFAST_DTV2000H_J 82
241#define CX88_BOARD_PROF_7301 83 241#define CX88_BOARD_PROF_7301 83
242#define CX88_BOARD_SAMSUNG_SMT_7020 84
242 243
243enum cx88_itype { 244enum cx88_itype {
244 CX88_VMUX_COMPOSITE1 = 1, 245 CX88_VMUX_COMPOSITE1 = 1,
diff --git a/drivers/media/video/dabusb.c b/drivers/media/video/dabusb.c
index ee43876adb06..9b413a35e048 100644
--- a/drivers/media/video/dabusb.c
+++ b/drivers/media/video/dabusb.c
@@ -913,6 +913,8 @@ static void __exit dabusb_cleanup (void)
913MODULE_AUTHOR( DRIVER_AUTHOR ); 913MODULE_AUTHOR( DRIVER_AUTHOR );
914MODULE_DESCRIPTION( DRIVER_DESC ); 914MODULE_DESCRIPTION( DRIVER_DESC );
915MODULE_LICENSE("GPL"); 915MODULE_LICENSE("GPL");
916MODULE_FIRMWARE("dabusb/firmware.fw");
917MODULE_FIRMWARE("dabusb/bitstream.bin");
916 918
917module_param(buffers, int, 0); 919module_param(buffers, int, 0);
918MODULE_PARM_DESC (buffers, "Number of buffers (default=256)"); 920MODULE_PARM_DESC (buffers, "Number of buffers (default=256)");
diff --git a/drivers/media/video/davinci/Makefile b/drivers/media/video/davinci/Makefile
index 1a8b8f3f182e..a37955745aaa 100644
--- a/drivers/media/video/davinci/Makefile
+++ b/drivers/media/video/davinci/Makefile
@@ -15,3 +15,4 @@ obj-$(CONFIG_VIDEO_VPSS_SYSTEM) += vpss.o
15obj-$(CONFIG_VIDEO_VPFE_CAPTURE) += vpfe_capture.o 15obj-$(CONFIG_VIDEO_VPFE_CAPTURE) += vpfe_capture.o
16obj-$(CONFIG_VIDEO_DM6446_CCDC) += dm644x_ccdc.o 16obj-$(CONFIG_VIDEO_DM6446_CCDC) += dm644x_ccdc.o
17obj-$(CONFIG_VIDEO_DM355_CCDC) += dm355_ccdc.o 17obj-$(CONFIG_VIDEO_DM355_CCDC) += dm355_ccdc.o
18obj-$(CONFIG_VIDEO_ISIF) += isif.o
diff --git a/drivers/media/video/davinci/dm355_ccdc.c b/drivers/media/video/davinci/dm355_ccdc.c
index 314390016370..c29ac88ffd78 100644
--- a/drivers/media/video/davinci/dm355_ccdc.c
+++ b/drivers/media/video/davinci/dm355_ccdc.c
@@ -37,8 +37,12 @@
37#include <linux/platform_device.h> 37#include <linux/platform_device.h>
38#include <linux/uaccess.h> 38#include <linux/uaccess.h>
39#include <linux/videodev2.h> 39#include <linux/videodev2.h>
40#include <linux/clk.h>
41#include <linux/err.h>
42
40#include <media/davinci/dm355_ccdc.h> 43#include <media/davinci/dm355_ccdc.h>
41#include <media/davinci/vpss.h> 44#include <media/davinci/vpss.h>
45
42#include "dm355_ccdc_regs.h" 46#include "dm355_ccdc_regs.h"
43#include "ccdc_hw_device.h" 47#include "ccdc_hw_device.h"
44 48
@@ -46,67 +50,75 @@ MODULE_LICENSE("GPL");
46MODULE_DESCRIPTION("CCDC Driver for DM355"); 50MODULE_DESCRIPTION("CCDC Driver for DM355");
47MODULE_AUTHOR("Texas Instruments"); 51MODULE_AUTHOR("Texas Instruments");
48 52
49static struct device *dev; 53static struct ccdc_oper_config {
50 54 struct device *dev;
51/* Object for CCDC raw mode */ 55 /* CCDC interface type */
52static struct ccdc_params_raw ccdc_hw_params_raw = { 56 enum vpfe_hw_if_type if_type;
53 .pix_fmt = CCDC_PIXFMT_RAW, 57 /* Raw Bayer configuration */
54 .frm_fmt = CCDC_FRMFMT_PROGRESSIVE, 58 struct ccdc_params_raw bayer;
55 .win = CCDC_WIN_VGA, 59 /* YCbCr configuration */
56 .fid_pol = VPFE_PINPOL_POSITIVE, 60 struct ccdc_params_ycbcr ycbcr;
57 .vd_pol = VPFE_PINPOL_POSITIVE, 61 /* Master clock */
58 .hd_pol = VPFE_PINPOL_POSITIVE, 62 struct clk *mclk;
59 .gain = { 63 /* slave clock */
60 .r_ye = 256, 64 struct clk *sclk;
61 .gb_g = 256, 65 /* ccdc base address */
62 .gr_cy = 256, 66 void __iomem *base_addr;
63 .b_mg = 256 67} ccdc_cfg = {
64 }, 68 /* Raw configurations */
65 .config_params = { 69 .bayer = {
66 .datasft = 2, 70 .pix_fmt = CCDC_PIXFMT_RAW,
67 .data_sz = CCDC_DATA_10BITS, 71 .frm_fmt = CCDC_FRMFMT_PROGRESSIVE,
68 .mfilt1 = CCDC_NO_MEDIAN_FILTER1, 72 .win = CCDC_WIN_VGA,
69 .mfilt2 = CCDC_NO_MEDIAN_FILTER2, 73 .fid_pol = VPFE_PINPOL_POSITIVE,
70 .alaw = { 74 .vd_pol = VPFE_PINPOL_POSITIVE,
71 .gama_wd = 2, 75 .hd_pol = VPFE_PINPOL_POSITIVE,
76 .gain = {
77 .r_ye = 256,
78 .gb_g = 256,
79 .gr_cy = 256,
80 .b_mg = 256
72 }, 81 },
73 .blk_clamp = { 82 .config_params = {
74 .sample_pixel = 1, 83 .datasft = 2,
75 .dc_sub = 25 84 .mfilt1 = CCDC_NO_MEDIAN_FILTER1,
76 }, 85 .mfilt2 = CCDC_NO_MEDIAN_FILTER2,
77 .col_pat_field0 = { 86 .alaw = {
78 .olop = CCDC_GREEN_BLUE, 87 .gama_wd = 2,
79 .olep = CCDC_BLUE, 88 },
80 .elop = CCDC_RED, 89 .blk_clamp = {
81 .elep = CCDC_GREEN_RED 90 .sample_pixel = 1,
82 }, 91 .dc_sub = 25
83 .col_pat_field1 = { 92 },
84 .olop = CCDC_GREEN_BLUE, 93 .col_pat_field0 = {
85 .olep = CCDC_BLUE, 94 .olop = CCDC_GREEN_BLUE,
86 .elop = CCDC_RED, 95 .olep = CCDC_BLUE,
87 .elep = CCDC_GREEN_RED 96 .elop = CCDC_RED,
97 .elep = CCDC_GREEN_RED
98 },
99 .col_pat_field1 = {
100 .olop = CCDC_GREEN_BLUE,
101 .olep = CCDC_BLUE,
102 .elop = CCDC_RED,
103 .elep = CCDC_GREEN_RED
104 },
88 }, 105 },
89 }, 106 },
107 /* YCbCr configuration */
108 .ycbcr = {
109 .win = CCDC_WIN_PAL,
110 .pix_fmt = CCDC_PIXFMT_YCBCR_8BIT,
111 .frm_fmt = CCDC_FRMFMT_INTERLACED,
112 .fid_pol = VPFE_PINPOL_POSITIVE,
113 .vd_pol = VPFE_PINPOL_POSITIVE,
114 .hd_pol = VPFE_PINPOL_POSITIVE,
115 .bt656_enable = 1,
116 .pix_order = CCDC_PIXORDER_CBYCRY,
117 .buf_type = CCDC_BUFTYPE_FLD_INTERLEAVED
118 },
90}; 119};
91 120
92 121
93/* Object for CCDC ycbcr mode */
94static struct ccdc_params_ycbcr ccdc_hw_params_ycbcr = {
95 .win = CCDC_WIN_PAL,
96 .pix_fmt = CCDC_PIXFMT_YCBCR_8BIT,
97 .frm_fmt = CCDC_FRMFMT_INTERLACED,
98 .fid_pol = VPFE_PINPOL_POSITIVE,
99 .vd_pol = VPFE_PINPOL_POSITIVE,
100 .hd_pol = VPFE_PINPOL_POSITIVE,
101 .bt656_enable = 1,
102 .pix_order = CCDC_PIXORDER_CBYCRY,
103 .buf_type = CCDC_BUFTYPE_FLD_INTERLEAVED
104};
105
106static enum vpfe_hw_if_type ccdc_if_type;
107static void *__iomem ccdc_base_addr;
108static int ccdc_addr_size;
109
110/* Raw Bayer formats */ 122/* Raw Bayer formats */
111static u32 ccdc_raw_bayer_pix_formats[] = 123static u32 ccdc_raw_bayer_pix_formats[] =
112 {V4L2_PIX_FMT_SBGGR8, V4L2_PIX_FMT_SBGGR16}; 124 {V4L2_PIX_FMT_SBGGR8, V4L2_PIX_FMT_SBGGR16};
@@ -118,18 +130,12 @@ static u32 ccdc_raw_yuv_pix_formats[] =
118/* register access routines */ 130/* register access routines */
119static inline u32 regr(u32 offset) 131static inline u32 regr(u32 offset)
120{ 132{
121 return __raw_readl(ccdc_base_addr + offset); 133 return __raw_readl(ccdc_cfg.base_addr + offset);
122} 134}
123 135
124static inline void regw(u32 val, u32 offset) 136static inline void regw(u32 val, u32 offset)
125{ 137{
126 __raw_writel(val, ccdc_base_addr + offset); 138 __raw_writel(val, ccdc_cfg.base_addr + offset);
127}
128
129static void ccdc_set_ccdc_base(void *addr, int size)
130{
131 ccdc_base_addr = addr;
132 ccdc_addr_size = size;
133} 139}
134 140
135static void ccdc_enable(int en) 141static void ccdc_enable(int en)
@@ -153,12 +159,12 @@ static void ccdc_enable_output_to_sdram(int en)
153static void ccdc_config_gain_offset(void) 159static void ccdc_config_gain_offset(void)
154{ 160{
155 /* configure gain */ 161 /* configure gain */
156 regw(ccdc_hw_params_raw.gain.r_ye, RYEGAIN); 162 regw(ccdc_cfg.bayer.gain.r_ye, RYEGAIN);
157 regw(ccdc_hw_params_raw.gain.gr_cy, GRCYGAIN); 163 regw(ccdc_cfg.bayer.gain.gr_cy, GRCYGAIN);
158 regw(ccdc_hw_params_raw.gain.gb_g, GBGGAIN); 164 regw(ccdc_cfg.bayer.gain.gb_g, GBGGAIN);
159 regw(ccdc_hw_params_raw.gain.b_mg, BMGGAIN); 165 regw(ccdc_cfg.bayer.gain.b_mg, BMGGAIN);
160 /* configure offset */ 166 /* configure offset */
161 regw(ccdc_hw_params_raw.ccdc_offset, OFFSET); 167 regw(ccdc_cfg.bayer.ccdc_offset, OFFSET);
162} 168}
163 169
164/* 170/*
@@ -169,7 +175,7 @@ static int ccdc_restore_defaults(void)
169{ 175{
170 int i; 176 int i;
171 177
172 dev_dbg(dev, "\nstarting ccdc_restore_defaults..."); 178 dev_dbg(ccdc_cfg.dev, "\nstarting ccdc_restore_defaults...");
173 /* set all registers to zero */ 179 /* set all registers to zero */
174 for (i = 0; i <= CCDC_REG_LAST; i += 4) 180 for (i = 0; i <= CCDC_REG_LAST; i += 4)
175 regw(0, i); 181 regw(0, i);
@@ -180,30 +186,29 @@ static int ccdc_restore_defaults(void)
180 regw(CULH_DEFAULT, CULH); 186 regw(CULH_DEFAULT, CULH);
181 regw(CULV_DEFAULT, CULV); 187 regw(CULV_DEFAULT, CULV);
182 /* Set default Gain and Offset */ 188 /* Set default Gain and Offset */
183 ccdc_hw_params_raw.gain.r_ye = GAIN_DEFAULT; 189 ccdc_cfg.bayer.gain.r_ye = GAIN_DEFAULT;
184 ccdc_hw_params_raw.gain.gb_g = GAIN_DEFAULT; 190 ccdc_cfg.bayer.gain.gb_g = GAIN_DEFAULT;
185 ccdc_hw_params_raw.gain.gr_cy = GAIN_DEFAULT; 191 ccdc_cfg.bayer.gain.gr_cy = GAIN_DEFAULT;
186 ccdc_hw_params_raw.gain.b_mg = GAIN_DEFAULT; 192 ccdc_cfg.bayer.gain.b_mg = GAIN_DEFAULT;
187 ccdc_config_gain_offset(); 193 ccdc_config_gain_offset();
188 regw(OUTCLIP_DEFAULT, OUTCLIP); 194 regw(OUTCLIP_DEFAULT, OUTCLIP);
189 regw(LSCCFG2_DEFAULT, LSCCFG2); 195 regw(LSCCFG2_DEFAULT, LSCCFG2);
190 /* select ccdc input */ 196 /* select ccdc input */
191 if (vpss_select_ccdc_source(VPSS_CCDCIN)) { 197 if (vpss_select_ccdc_source(VPSS_CCDCIN)) {
192 dev_dbg(dev, "\ncouldn't select ccdc input source"); 198 dev_dbg(ccdc_cfg.dev, "\ncouldn't select ccdc input source");
193 return -EFAULT; 199 return -EFAULT;
194 } 200 }
195 /* select ccdc clock */ 201 /* select ccdc clock */
196 if (vpss_enable_clock(VPSS_CCDC_CLOCK, 1) < 0) { 202 if (vpss_enable_clock(VPSS_CCDC_CLOCK, 1) < 0) {
197 dev_dbg(dev, "\ncouldn't enable ccdc clock"); 203 dev_dbg(ccdc_cfg.dev, "\ncouldn't enable ccdc clock");
198 return -EFAULT; 204 return -EFAULT;
199 } 205 }
200 dev_dbg(dev, "\nEnd of ccdc_restore_defaults..."); 206 dev_dbg(ccdc_cfg.dev, "\nEnd of ccdc_restore_defaults...");
201 return 0; 207 return 0;
202} 208}
203 209
204static int ccdc_open(struct device *device) 210static int ccdc_open(struct device *device)
205{ 211{
206 dev = device;
207 return ccdc_restore_defaults(); 212 return ccdc_restore_defaults();
208} 213}
209 214
@@ -226,7 +231,7 @@ static void ccdc_setwin(struct v4l2_rect *image_win,
226 int vert_start, vert_nr_lines; 231 int vert_start, vert_nr_lines;
227 int mid_img = 0; 232 int mid_img = 0;
228 233
229 dev_dbg(dev, "\nStarting ccdc_setwin..."); 234 dev_dbg(ccdc_cfg.dev, "\nStarting ccdc_setwin...");
230 235
231 /* 236 /*
232 * ppc - per pixel count. indicates how many pixels per cell 237 * ppc - per pixel count. indicates how many pixels per cell
@@ -260,45 +265,46 @@ static void ccdc_setwin(struct v4l2_rect *image_win,
260 regw(vert_start & CCDC_START_VER_ONE_MASK, SLV0); 265 regw(vert_start & CCDC_START_VER_ONE_MASK, SLV0);
261 regw(vert_start & CCDC_START_VER_TWO_MASK, SLV1); 266 regw(vert_start & CCDC_START_VER_TWO_MASK, SLV1);
262 regw(vert_nr_lines & CCDC_NUM_LINES_VER, NLV); 267 regw(vert_nr_lines & CCDC_NUM_LINES_VER, NLV);
263 dev_dbg(dev, "\nEnd of ccdc_setwin..."); 268 dev_dbg(ccdc_cfg.dev, "\nEnd of ccdc_setwin...");
264} 269}
265 270
266static int validate_ccdc_param(struct ccdc_config_params_raw *ccdcparam) 271static int validate_ccdc_param(struct ccdc_config_params_raw *ccdcparam)
267{ 272{
268 if (ccdcparam->datasft < CCDC_DATA_NO_SHIFT || 273 if (ccdcparam->datasft < CCDC_DATA_NO_SHIFT ||
269 ccdcparam->datasft > CCDC_DATA_SHIFT_6BIT) { 274 ccdcparam->datasft > CCDC_DATA_SHIFT_6BIT) {
270 dev_dbg(dev, "Invalid value of data shift\n"); 275 dev_dbg(ccdc_cfg.dev, "Invalid value of data shift\n");
271 return -EINVAL; 276 return -EINVAL;
272 } 277 }
273 278
274 if (ccdcparam->mfilt1 < CCDC_NO_MEDIAN_FILTER1 || 279 if (ccdcparam->mfilt1 < CCDC_NO_MEDIAN_FILTER1 ||
275 ccdcparam->mfilt1 > CCDC_MEDIAN_FILTER1) { 280 ccdcparam->mfilt1 > CCDC_MEDIAN_FILTER1) {
276 dev_dbg(dev, "Invalid value of median filter1\n"); 281 dev_dbg(ccdc_cfg.dev, "Invalid value of median filter1\n");
277 return -EINVAL; 282 return -EINVAL;
278 } 283 }
279 284
280 if (ccdcparam->mfilt2 < CCDC_NO_MEDIAN_FILTER2 || 285 if (ccdcparam->mfilt2 < CCDC_NO_MEDIAN_FILTER2 ||
281 ccdcparam->mfilt2 > CCDC_MEDIAN_FILTER2) { 286 ccdcparam->mfilt2 > CCDC_MEDIAN_FILTER2) {
282 dev_dbg(dev, "Invalid value of median filter2\n"); 287 dev_dbg(ccdc_cfg.dev, "Invalid value of median filter2\n");
283 return -EINVAL; 288 return -EINVAL;
284 } 289 }
285 290
286 if ((ccdcparam->med_filt_thres < 0) || 291 if ((ccdcparam->med_filt_thres < 0) ||
287 (ccdcparam->med_filt_thres > CCDC_MED_FILT_THRESH)) { 292 (ccdcparam->med_filt_thres > CCDC_MED_FILT_THRESH)) {
288 dev_dbg(dev, "Invalid value of median filter threshold\n"); 293 dev_dbg(ccdc_cfg.dev,
294 "Invalid value of median filter thresold\n");
289 return -EINVAL; 295 return -EINVAL;
290 } 296 }
291 297
292 if (ccdcparam->data_sz < CCDC_DATA_16BITS || 298 if (ccdcparam->data_sz < CCDC_DATA_16BITS ||
293 ccdcparam->data_sz > CCDC_DATA_8BITS) { 299 ccdcparam->data_sz > CCDC_DATA_8BITS) {
294 dev_dbg(dev, "Invalid value of data size\n"); 300 dev_dbg(ccdc_cfg.dev, "Invalid value of data size\n");
295 return -EINVAL; 301 return -EINVAL;
296 } 302 }
297 303
298 if (ccdcparam->alaw.enable) { 304 if (ccdcparam->alaw.enable) {
299 if (ccdcparam->alaw.gama_wd < CCDC_GAMMA_BITS_13_4 || 305 if (ccdcparam->alaw.gama_wd < CCDC_GAMMA_BITS_13_4 ||
300 ccdcparam->alaw.gama_wd > CCDC_GAMMA_BITS_09_0) { 306 ccdcparam->alaw.gama_wd > CCDC_GAMMA_BITS_09_0) {
301 dev_dbg(dev, "Invalid value of ALAW\n"); 307 dev_dbg(ccdc_cfg.dev, "Invalid value of ALAW\n");
302 return -EINVAL; 308 return -EINVAL;
303 } 309 }
304 } 310 }
@@ -306,12 +312,14 @@ static int validate_ccdc_param(struct ccdc_config_params_raw *ccdcparam)
306 if (ccdcparam->blk_clamp.b_clamp_enable) { 312 if (ccdcparam->blk_clamp.b_clamp_enable) {
307 if (ccdcparam->blk_clamp.sample_pixel < CCDC_SAMPLE_1PIXELS || 313 if (ccdcparam->blk_clamp.sample_pixel < CCDC_SAMPLE_1PIXELS ||
308 ccdcparam->blk_clamp.sample_pixel > CCDC_SAMPLE_16PIXELS) { 314 ccdcparam->blk_clamp.sample_pixel > CCDC_SAMPLE_16PIXELS) {
309 dev_dbg(dev, "Invalid value of sample pixel\n"); 315 dev_dbg(ccdc_cfg.dev,
316 "Invalid value of sample pixel\n");
310 return -EINVAL; 317 return -EINVAL;
311 } 318 }
312 if (ccdcparam->blk_clamp.sample_ln < CCDC_SAMPLE_1LINES || 319 if (ccdcparam->blk_clamp.sample_ln < CCDC_SAMPLE_1LINES ||
313 ccdcparam->blk_clamp.sample_ln > CCDC_SAMPLE_16LINES) { 320 ccdcparam->blk_clamp.sample_ln > CCDC_SAMPLE_16LINES) {
314 dev_dbg(dev, "Invalid value of sample lines\n"); 321 dev_dbg(ccdc_cfg.dev,
322 "Invalid value of sample lines\n");
315 return -EINVAL; 323 return -EINVAL;
316 } 324 }
317 } 325 }
@@ -325,18 +333,18 @@ static int ccdc_set_params(void __user *params)
325 int x; 333 int x;
326 334
327 /* only raw module parameters can be set through the IOCTL */ 335 /* only raw module parameters can be set through the IOCTL */
328 if (ccdc_if_type != VPFE_RAW_BAYER) 336 if (ccdc_cfg.if_type != VPFE_RAW_BAYER)
329 return -EINVAL; 337 return -EINVAL;
330 338
331 x = copy_from_user(&ccdc_raw_params, params, sizeof(ccdc_raw_params)); 339 x = copy_from_user(&ccdc_raw_params, params, sizeof(ccdc_raw_params));
332 if (x) { 340 if (x) {
333 dev_dbg(dev, "ccdc_set_params: error in copying ccdc" 341 dev_dbg(ccdc_cfg.dev, "ccdc_set_params: error in copying ccdc"
334 "params, %d\n", x); 342 "params, %d\n", x);
335 return -EFAULT; 343 return -EFAULT;
336 } 344 }
337 345
338 if (!validate_ccdc_param(&ccdc_raw_params)) { 346 if (!validate_ccdc_param(&ccdc_raw_params)) {
339 memcpy(&ccdc_hw_params_raw.config_params, 347 memcpy(&ccdc_cfg.bayer.config_params,
340 &ccdc_raw_params, 348 &ccdc_raw_params,
341 sizeof(ccdc_raw_params)); 349 sizeof(ccdc_raw_params));
342 return 0; 350 return 0;
@@ -347,11 +355,11 @@ static int ccdc_set_params(void __user *params)
347/* This function will configure CCDC for YCbCr video capture */ 355/* This function will configure CCDC for YCbCr video capture */
348static void ccdc_config_ycbcr(void) 356static void ccdc_config_ycbcr(void)
349{ 357{
350 struct ccdc_params_ycbcr *params = &ccdc_hw_params_ycbcr; 358 struct ccdc_params_ycbcr *params = &ccdc_cfg.ycbcr;
351 u32 temp; 359 u32 temp;
352 360
353 /* first set the CCDC power on defaults values in all registers */ 361 /* first set the CCDC power on defaults values in all registers */
354 dev_dbg(dev, "\nStarting ccdc_config_ycbcr..."); 362 dev_dbg(ccdc_cfg.dev, "\nStarting ccdc_config_ycbcr...");
355 ccdc_restore_defaults(); 363 ccdc_restore_defaults();
356 364
357 /* configure pixel format & video frame format */ 365 /* configure pixel format & video frame format */
@@ -403,7 +411,7 @@ static void ccdc_config_ycbcr(void)
403 regw(CCDC_SDOFST_FIELD_INTERLEAVED, SDOFST); 411 regw(CCDC_SDOFST_FIELD_INTERLEAVED, SDOFST);
404 } 412 }
405 413
406 dev_dbg(dev, "\nEnd of ccdc_config_ycbcr...\n"); 414 dev_dbg(ccdc_cfg.dev, "\nEnd of ccdc_config_ycbcr...\n");
407} 415}
408 416
409/* 417/*
@@ -483,7 +491,7 @@ int ccdc_write_dfc_entry(int index, struct ccdc_vertical_dft *dfc)
483 */ 491 */
484 492
485 if (count) { 493 if (count) {
486 dev_err(dev, "defect table write timeout !!!\n"); 494 dev_err(ccdc_cfg.dev, "defect table write timeout !!!\n");
487 return -1; 495 return -1;
488 } 496 }
489 return 0; 497 return 0;
@@ -605,12 +613,12 @@ static void ccdc_config_color_patterns(struct ccdc_col_pat *pat0,
605/* This function will configure CCDC for Raw mode image capture */ 613/* This function will configure CCDC for Raw mode image capture */
606static int ccdc_config_raw(void) 614static int ccdc_config_raw(void)
607{ 615{
608 struct ccdc_params_raw *params = &ccdc_hw_params_raw; 616 struct ccdc_params_raw *params = &ccdc_cfg.bayer;
609 struct ccdc_config_params_raw *config_params = 617 struct ccdc_config_params_raw *config_params =
610 &ccdc_hw_params_raw.config_params; 618 &ccdc_cfg.bayer.config_params;
611 unsigned int val; 619 unsigned int val;
612 620
613 dev_dbg(dev, "\nStarting ccdc_config_raw..."); 621 dev_dbg(ccdc_cfg.dev, "\nStarting ccdc_config_raw...");
614 622
615 /* restore power on defaults to register */ 623 /* restore power on defaults to register */
616 ccdc_restore_defaults(); 624 ccdc_restore_defaults();
@@ -659,7 +667,7 @@ static int ccdc_config_raw(void)
659 val |= (config_params->datasft & CCDC_DATASFT_MASK) << 667 val |= (config_params->datasft & CCDC_DATASFT_MASK) <<
660 CCDC_DATASFT_SHIFT; 668 CCDC_DATASFT_SHIFT;
661 regw(val , MODESET); 669 regw(val , MODESET);
662 dev_dbg(dev, "\nWriting 0x%x to MODESET...\n", val); 670 dev_dbg(ccdc_cfg.dev, "\nWriting 0x%x to MODESET...\n", val);
663 671
664 /* Configure the Median Filter threshold */ 672 /* Configure the Median Filter threshold */
665 regw((config_params->med_filt_thres) & CCDC_MED_FILT_THRESH, MEDFILT); 673 regw((config_params->med_filt_thres) & CCDC_MED_FILT_THRESH, MEDFILT);
@@ -681,7 +689,7 @@ static int ccdc_config_raw(void)
681 (config_params->mfilt2 << CCDC_MFILT2_SHIFT)); 689 (config_params->mfilt2 << CCDC_MFILT2_SHIFT));
682 690
683 regw(val, GAMMAWD); 691 regw(val, GAMMAWD);
684 dev_dbg(dev, "\nWriting 0x%x to GAMMAWD...\n", val); 692 dev_dbg(ccdc_cfg.dev, "\nWriting 0x%x to GAMMAWD...\n", val);
685 693
686 /* configure video window */ 694 /* configure video window */
687 ccdc_setwin(&params->win, params->frm_fmt, 1); 695 ccdc_setwin(&params->win, params->frm_fmt, 1);
@@ -706,7 +714,7 @@ static int ccdc_config_raw(void)
706 /* Configure the Gain & offset control */ 714 /* Configure the Gain & offset control */
707 ccdc_config_gain_offset(); 715 ccdc_config_gain_offset();
708 716
709 dev_dbg(dev, "\nWriting %x to COLPTN...\n", val); 717 dev_dbg(ccdc_cfg.dev, "\nWriting %x to COLPTN...\n", val);
710 718
711 /* Configure DATAOFST register */ 719 /* Configure DATAOFST register */
712 val = (config_params->data_offset.horz_offset & CCDC_DATAOFST_MASK) << 720 val = (config_params->data_offset.horz_offset & CCDC_DATAOFST_MASK) <<
@@ -726,7 +734,7 @@ static int ccdc_config_raw(void)
726 CCDC_HSIZE_VAL_MASK; 734 CCDC_HSIZE_VAL_MASK;
727 735
728 /* adjust to multiple of 32 */ 736 /* adjust to multiple of 32 */
729 dev_dbg(dev, "\nWriting 0x%x to HSIZE...\n", 737 dev_dbg(ccdc_cfg.dev, "\nWriting 0x%x to HSIZE...\n",
730 (((params->win.width) + 31) >> 5) & 738 (((params->win.width) + 31) >> 5) &
731 CCDC_HSIZE_VAL_MASK); 739 CCDC_HSIZE_VAL_MASK);
732 } else { 740 } else {
@@ -734,7 +742,7 @@ static int ccdc_config_raw(void)
734 val |= (((params->win.width * 2) + 31) >> 5) & 742 val |= (((params->win.width * 2) + 31) >> 5) &
735 CCDC_HSIZE_VAL_MASK; 743 CCDC_HSIZE_VAL_MASK;
736 744
737 dev_dbg(dev, "\nWriting 0x%x to HSIZE...\n", 745 dev_dbg(ccdc_cfg.dev, "\nWriting 0x%x to HSIZE...\n",
738 (((params->win.width * 2) + 31) >> 5) & 746 (((params->win.width * 2) + 31) >> 5) &
739 CCDC_HSIZE_VAL_MASK); 747 CCDC_HSIZE_VAL_MASK);
740 } 748 }
@@ -745,34 +753,34 @@ static int ccdc_config_raw(void)
745 if (params->image_invert_enable) { 753 if (params->image_invert_enable) {
746 /* For interlace inverse mode */ 754 /* For interlace inverse mode */
747 regw(CCDC_SDOFST_INTERLACE_INVERSE, SDOFST); 755 regw(CCDC_SDOFST_INTERLACE_INVERSE, SDOFST);
748 dev_dbg(dev, "\nWriting %x to SDOFST...\n", 756 dev_dbg(ccdc_cfg.dev, "\nWriting %x to SDOFST...\n",
749 CCDC_SDOFST_INTERLACE_INVERSE); 757 CCDC_SDOFST_INTERLACE_INVERSE);
750 } else { 758 } else {
751 /* For interlace non inverse mode */ 759 /* For interlace non inverse mode */
752 regw(CCDC_SDOFST_INTERLACE_NORMAL, SDOFST); 760 regw(CCDC_SDOFST_INTERLACE_NORMAL, SDOFST);
753 dev_dbg(dev, "\nWriting %x to SDOFST...\n", 761 dev_dbg(ccdc_cfg.dev, "\nWriting %x to SDOFST...\n",
754 CCDC_SDOFST_INTERLACE_NORMAL); 762 CCDC_SDOFST_INTERLACE_NORMAL);
755 } 763 }
756 } else if (params->frm_fmt == CCDC_FRMFMT_PROGRESSIVE) { 764 } else if (params->frm_fmt == CCDC_FRMFMT_PROGRESSIVE) {
757 if (params->image_invert_enable) { 765 if (params->image_invert_enable) {
758 /* For progessive inverse mode */ 766 /* For progessive inverse mode */
759 regw(CCDC_SDOFST_PROGRESSIVE_INVERSE, SDOFST); 767 regw(CCDC_SDOFST_PROGRESSIVE_INVERSE, SDOFST);
760 dev_dbg(dev, "\nWriting %x to SDOFST...\n", 768 dev_dbg(ccdc_cfg.dev, "\nWriting %x to SDOFST...\n",
761 CCDC_SDOFST_PROGRESSIVE_INVERSE); 769 CCDC_SDOFST_PROGRESSIVE_INVERSE);
762 } else { 770 } else {
763 /* For progessive non inverse mode */ 771 /* For progessive non inverse mode */
764 regw(CCDC_SDOFST_PROGRESSIVE_NORMAL, SDOFST); 772 regw(CCDC_SDOFST_PROGRESSIVE_NORMAL, SDOFST);
765 dev_dbg(dev, "\nWriting %x to SDOFST...\n", 773 dev_dbg(ccdc_cfg.dev, "\nWriting %x to SDOFST...\n",
766 CCDC_SDOFST_PROGRESSIVE_NORMAL); 774 CCDC_SDOFST_PROGRESSIVE_NORMAL);
767 } 775 }
768 } 776 }
769 dev_dbg(dev, "\nend of ccdc_config_raw..."); 777 dev_dbg(ccdc_cfg.dev, "\nend of ccdc_config_raw...");
770 return 0; 778 return 0;
771} 779}
772 780
773static int ccdc_configure(void) 781static int ccdc_configure(void)
774{ 782{
775 if (ccdc_if_type == VPFE_RAW_BAYER) 783 if (ccdc_cfg.if_type == VPFE_RAW_BAYER)
776 return ccdc_config_raw(); 784 return ccdc_config_raw();
777 else 785 else
778 ccdc_config_ycbcr(); 786 ccdc_config_ycbcr();
@@ -781,23 +789,23 @@ static int ccdc_configure(void)
781 789
782static int ccdc_set_buftype(enum ccdc_buftype buf_type) 790static int ccdc_set_buftype(enum ccdc_buftype buf_type)
783{ 791{
784 if (ccdc_if_type == VPFE_RAW_BAYER) 792 if (ccdc_cfg.if_type == VPFE_RAW_BAYER)
785 ccdc_hw_params_raw.buf_type = buf_type; 793 ccdc_cfg.bayer.buf_type = buf_type;
786 else 794 else
787 ccdc_hw_params_ycbcr.buf_type = buf_type; 795 ccdc_cfg.ycbcr.buf_type = buf_type;
788 return 0; 796 return 0;
789} 797}
790static enum ccdc_buftype ccdc_get_buftype(void) 798static enum ccdc_buftype ccdc_get_buftype(void)
791{ 799{
792 if (ccdc_if_type == VPFE_RAW_BAYER) 800 if (ccdc_cfg.if_type == VPFE_RAW_BAYER)
793 return ccdc_hw_params_raw.buf_type; 801 return ccdc_cfg.bayer.buf_type;
794 return ccdc_hw_params_ycbcr.buf_type; 802 return ccdc_cfg.ycbcr.buf_type;
795} 803}
796 804
797static int ccdc_enum_pix(u32 *pix, int i) 805static int ccdc_enum_pix(u32 *pix, int i)
798{ 806{
799 int ret = -EINVAL; 807 int ret = -EINVAL;
800 if (ccdc_if_type == VPFE_RAW_BAYER) { 808 if (ccdc_cfg.if_type == VPFE_RAW_BAYER) {
801 if (i < ARRAY_SIZE(ccdc_raw_bayer_pix_formats)) { 809 if (i < ARRAY_SIZE(ccdc_raw_bayer_pix_formats)) {
802 *pix = ccdc_raw_bayer_pix_formats[i]; 810 *pix = ccdc_raw_bayer_pix_formats[i];
803 ret = 0; 811 ret = 0;
@@ -813,20 +821,19 @@ static int ccdc_enum_pix(u32 *pix, int i)
813 821
814static int ccdc_set_pixel_format(u32 pixfmt) 822static int ccdc_set_pixel_format(u32 pixfmt)
815{ 823{
816 struct ccdc_a_law *alaw = 824 struct ccdc_a_law *alaw = &ccdc_cfg.bayer.config_params.alaw;
817 &ccdc_hw_params_raw.config_params.alaw;
818 825
819 if (ccdc_if_type == VPFE_RAW_BAYER) { 826 if (ccdc_cfg.if_type == VPFE_RAW_BAYER) {
820 ccdc_hw_params_raw.pix_fmt = CCDC_PIXFMT_RAW; 827 ccdc_cfg.bayer.pix_fmt = CCDC_PIXFMT_RAW;
821 if (pixfmt == V4L2_PIX_FMT_SBGGR8) 828 if (pixfmt == V4L2_PIX_FMT_SBGGR8)
822 alaw->enable = 1; 829 alaw->enable = 1;
823 else if (pixfmt != V4L2_PIX_FMT_SBGGR16) 830 else if (pixfmt != V4L2_PIX_FMT_SBGGR16)
824 return -EINVAL; 831 return -EINVAL;
825 } else { 832 } else {
826 if (pixfmt == V4L2_PIX_FMT_YUYV) 833 if (pixfmt == V4L2_PIX_FMT_YUYV)
827 ccdc_hw_params_ycbcr.pix_order = CCDC_PIXORDER_YCBYCR; 834 ccdc_cfg.ycbcr.pix_order = CCDC_PIXORDER_YCBYCR;
828 else if (pixfmt == V4L2_PIX_FMT_UYVY) 835 else if (pixfmt == V4L2_PIX_FMT_UYVY)
829 ccdc_hw_params_ycbcr.pix_order = CCDC_PIXORDER_CBYCRY; 836 ccdc_cfg.ycbcr.pix_order = CCDC_PIXORDER_CBYCRY;
830 else 837 else
831 return -EINVAL; 838 return -EINVAL;
832 } 839 }
@@ -834,17 +841,16 @@ static int ccdc_set_pixel_format(u32 pixfmt)
834} 841}
835static u32 ccdc_get_pixel_format(void) 842static u32 ccdc_get_pixel_format(void)
836{ 843{
837 struct ccdc_a_law *alaw = 844 struct ccdc_a_law *alaw = &ccdc_cfg.bayer.config_params.alaw;
838 &ccdc_hw_params_raw.config_params.alaw;
839 u32 pixfmt; 845 u32 pixfmt;
840 846
841 if (ccdc_if_type == VPFE_RAW_BAYER) 847 if (ccdc_cfg.if_type == VPFE_RAW_BAYER)
842 if (alaw->enable) 848 if (alaw->enable)
843 pixfmt = V4L2_PIX_FMT_SBGGR8; 849 pixfmt = V4L2_PIX_FMT_SBGGR8;
844 else 850 else
845 pixfmt = V4L2_PIX_FMT_SBGGR16; 851 pixfmt = V4L2_PIX_FMT_SBGGR16;
846 else { 852 else {
847 if (ccdc_hw_params_ycbcr.pix_order == CCDC_PIXORDER_YCBYCR) 853 if (ccdc_cfg.ycbcr.pix_order == CCDC_PIXORDER_YCBYCR)
848 pixfmt = V4L2_PIX_FMT_YUYV; 854 pixfmt = V4L2_PIX_FMT_YUYV;
849 else 855 else
850 pixfmt = V4L2_PIX_FMT_UYVY; 856 pixfmt = V4L2_PIX_FMT_UYVY;
@@ -853,53 +859,53 @@ static u32 ccdc_get_pixel_format(void)
853} 859}
854static int ccdc_set_image_window(struct v4l2_rect *win) 860static int ccdc_set_image_window(struct v4l2_rect *win)
855{ 861{
856 if (ccdc_if_type == VPFE_RAW_BAYER) 862 if (ccdc_cfg.if_type == VPFE_RAW_BAYER)
857 ccdc_hw_params_raw.win = *win; 863 ccdc_cfg.bayer.win = *win;
858 else 864 else
859 ccdc_hw_params_ycbcr.win = *win; 865 ccdc_cfg.ycbcr.win = *win;
860 return 0; 866 return 0;
861} 867}
862 868
863static void ccdc_get_image_window(struct v4l2_rect *win) 869static void ccdc_get_image_window(struct v4l2_rect *win)
864{ 870{
865 if (ccdc_if_type == VPFE_RAW_BAYER) 871 if (ccdc_cfg.if_type == VPFE_RAW_BAYER)
866 *win = ccdc_hw_params_raw.win; 872 *win = ccdc_cfg.bayer.win;
867 else 873 else
868 *win = ccdc_hw_params_ycbcr.win; 874 *win = ccdc_cfg.ycbcr.win;
869} 875}
870 876
871static unsigned int ccdc_get_line_length(void) 877static unsigned int ccdc_get_line_length(void)
872{ 878{
873 struct ccdc_config_params_raw *config_params = 879 struct ccdc_config_params_raw *config_params =
874 &ccdc_hw_params_raw.config_params; 880 &ccdc_cfg.bayer.config_params;
875 unsigned int len; 881 unsigned int len;
876 882
877 if (ccdc_if_type == VPFE_RAW_BAYER) { 883 if (ccdc_cfg.if_type == VPFE_RAW_BAYER) {
878 if ((config_params->alaw.enable) || 884 if ((config_params->alaw.enable) ||
879 (config_params->data_sz == CCDC_DATA_8BITS)) 885 (config_params->data_sz == CCDC_DATA_8BITS))
880 len = ccdc_hw_params_raw.win.width; 886 len = ccdc_cfg.bayer.win.width;
881 else 887 else
882 len = ccdc_hw_params_raw.win.width * 2; 888 len = ccdc_cfg.bayer.win.width * 2;
883 } else 889 } else
884 len = ccdc_hw_params_ycbcr.win.width * 2; 890 len = ccdc_cfg.ycbcr.win.width * 2;
885 return ALIGN(len, 32); 891 return ALIGN(len, 32);
886} 892}
887 893
888static int ccdc_set_frame_format(enum ccdc_frmfmt frm_fmt) 894static int ccdc_set_frame_format(enum ccdc_frmfmt frm_fmt)
889{ 895{
890 if (ccdc_if_type == VPFE_RAW_BAYER) 896 if (ccdc_cfg.if_type == VPFE_RAW_BAYER)
891 ccdc_hw_params_raw.frm_fmt = frm_fmt; 897 ccdc_cfg.bayer.frm_fmt = frm_fmt;
892 else 898 else
893 ccdc_hw_params_ycbcr.frm_fmt = frm_fmt; 899 ccdc_cfg.ycbcr.frm_fmt = frm_fmt;
894 return 0; 900 return 0;
895} 901}
896 902
897static enum ccdc_frmfmt ccdc_get_frame_format(void) 903static enum ccdc_frmfmt ccdc_get_frame_format(void)
898{ 904{
899 if (ccdc_if_type == VPFE_RAW_BAYER) 905 if (ccdc_cfg.if_type == VPFE_RAW_BAYER)
900 return ccdc_hw_params_raw.frm_fmt; 906 return ccdc_cfg.bayer.frm_fmt;
901 else 907 else
902 return ccdc_hw_params_ycbcr.frm_fmt; 908 return ccdc_cfg.ycbcr.frm_fmt;
903} 909}
904 910
905static int ccdc_getfid(void) 911static int ccdc_getfid(void)
@@ -916,14 +922,14 @@ static inline void ccdc_setfbaddr(unsigned long addr)
916 922
917static int ccdc_set_hw_if_params(struct vpfe_hw_if_param *params) 923static int ccdc_set_hw_if_params(struct vpfe_hw_if_param *params)
918{ 924{
919 ccdc_if_type = params->if_type; 925 ccdc_cfg.if_type = params->if_type;
920 926
921 switch (params->if_type) { 927 switch (params->if_type) {
922 case VPFE_BT656: 928 case VPFE_BT656:
923 case VPFE_YCBCR_SYNC_16: 929 case VPFE_YCBCR_SYNC_16:
924 case VPFE_YCBCR_SYNC_8: 930 case VPFE_YCBCR_SYNC_8:
925 ccdc_hw_params_ycbcr.vd_pol = params->vdpol; 931 ccdc_cfg.ycbcr.vd_pol = params->vdpol;
926 ccdc_hw_params_ycbcr.hd_pol = params->hdpol; 932 ccdc_cfg.ycbcr.hd_pol = params->hdpol;
927 break; 933 break;
928 default: 934 default:
929 /* TODO add support for raw bayer here */ 935 /* TODO add support for raw bayer here */
@@ -938,7 +944,6 @@ static struct ccdc_hw_device ccdc_hw_dev = {
938 .hw_ops = { 944 .hw_ops = {
939 .open = ccdc_open, 945 .open = ccdc_open,
940 .close = ccdc_close, 946 .close = ccdc_close,
941 .set_ccdc_base = ccdc_set_ccdc_base,
942 .enable = ccdc_enable, 947 .enable = ccdc_enable,
943 .enable_out_to_sdram = ccdc_enable_output_to_sdram, 948 .enable_out_to_sdram = ccdc_enable_output_to_sdram,
944 .set_hw_if_params = ccdc_set_hw_if_params, 949 .set_hw_if_params = ccdc_set_hw_if_params,
@@ -959,19 +964,118 @@ static struct ccdc_hw_device ccdc_hw_dev = {
959 }, 964 },
960}; 965};
961 966
962static int __init dm355_ccdc_init(void) 967static int __init dm355_ccdc_probe(struct platform_device *pdev)
963{ 968{
964 printk(KERN_NOTICE "dm355_ccdc_init\n"); 969 void (*setup_pinmux)(void);
965 if (vpfe_register_ccdc_device(&ccdc_hw_dev) < 0) 970 struct resource *res;
966 return -1; 971 int status = 0;
967 printk(KERN_NOTICE "%s is registered with vpfe.\n", 972
968 ccdc_hw_dev.name); 973 /*
974 * first try to register with vpfe. If not correct platform, then we
975 * don't have to iomap
976 */
977 status = vpfe_register_ccdc_device(&ccdc_hw_dev);
978 if (status < 0)
979 return status;
980
981 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
982 if (!res) {
983 status = -ENODEV;
984 goto fail_nores;
985 }
986
987 res = request_mem_region(res->start, resource_size(res), res->name);
988 if (!res) {
989 status = -EBUSY;
990 goto fail_nores;
991 }
992
993 ccdc_cfg.base_addr = ioremap_nocache(res->start, resource_size(res));
994 if (!ccdc_cfg.base_addr) {
995 status = -ENOMEM;
996 goto fail_nomem;
997 }
998
999 /* Get and enable Master clock */
1000 ccdc_cfg.mclk = clk_get(&pdev->dev, "master");
1001 if (IS_ERR(ccdc_cfg.mclk)) {
1002 status = PTR_ERR(ccdc_cfg.mclk);
1003 goto fail_nomap;
1004 }
1005 if (clk_enable(ccdc_cfg.mclk)) {
1006 status = -ENODEV;
1007 goto fail_mclk;
1008 }
1009
1010 /* Get and enable Slave clock */
1011 ccdc_cfg.sclk = clk_get(&pdev->dev, "slave");
1012 if (IS_ERR(ccdc_cfg.sclk)) {
1013 status = PTR_ERR(ccdc_cfg.sclk);
1014 goto fail_mclk;
1015 }
1016 if (clk_enable(ccdc_cfg.sclk)) {
1017 status = -ENODEV;
1018 goto fail_sclk;
1019 }
1020
1021 /* Platform data holds setup_pinmux function ptr */
1022 if (NULL == pdev->dev.platform_data) {
1023 status = -ENODEV;
1024 goto fail_sclk;
1025 }
1026 setup_pinmux = pdev->dev.platform_data;
1027 /*
1028 * setup Mux configuration for ccdc which may be different for
1029 * different SoCs using this CCDC
1030 */
1031 setup_pinmux();
1032 ccdc_cfg.dev = &pdev->dev;
1033 printk(KERN_NOTICE "%s is registered with vpfe.\n", ccdc_hw_dev.name);
969 return 0; 1034 return 0;
1035fail_sclk:
1036 clk_put(ccdc_cfg.sclk);
1037fail_mclk:
1038 clk_put(ccdc_cfg.mclk);
1039fail_nomap:
1040 iounmap(ccdc_cfg.base_addr);
1041fail_nomem:
1042 release_mem_region(res->start, resource_size(res));
1043fail_nores:
1044 vpfe_unregister_ccdc_device(&ccdc_hw_dev);
1045 return status;
970} 1046}
971 1047
972static void __exit dm355_ccdc_exit(void) 1048static int dm355_ccdc_remove(struct platform_device *pdev)
973{ 1049{
1050 struct resource *res;
1051
1052 clk_put(ccdc_cfg.mclk);
1053 clk_put(ccdc_cfg.sclk);
1054 iounmap(ccdc_cfg.base_addr);
1055 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1056 if (res)
1057 release_mem_region(res->start, resource_size(res));
974 vpfe_unregister_ccdc_device(&ccdc_hw_dev); 1058 vpfe_unregister_ccdc_device(&ccdc_hw_dev);
1059 return 0;
1060}
1061
1062static struct platform_driver dm355_ccdc_driver = {
1063 .driver = {
1064 .name = "dm355_ccdc",
1065 .owner = THIS_MODULE,
1066 },
1067 .remove = __devexit_p(dm355_ccdc_remove),
1068 .probe = dm355_ccdc_probe,
1069};
1070
1071static int __init dm355_ccdc_init(void)
1072{
1073 return platform_driver_register(&dm355_ccdc_driver);
1074}
1075
1076static void __exit dm355_ccdc_exit(void)
1077{
1078 platform_driver_unregister(&dm355_ccdc_driver);
975} 1079}
976 1080
977module_init(dm355_ccdc_init); 1081module_init(dm355_ccdc_init);
diff --git a/drivers/media/video/davinci/dm644x_ccdc.c b/drivers/media/video/davinci/dm644x_ccdc.c
index d5fa193f32d2..0c394cade22a 100644
--- a/drivers/media/video/davinci/dm644x_ccdc.c
+++ b/drivers/media/video/davinci/dm644x_ccdc.c
@@ -37,8 +37,12 @@
37#include <linux/platform_device.h> 37#include <linux/platform_device.h>
38#include <linux/uaccess.h> 38#include <linux/uaccess.h>
39#include <linux/videodev2.h> 39#include <linux/videodev2.h>
40#include <linux/clk.h>
41#include <linux/err.h>
42
40#include <media/davinci/dm644x_ccdc.h> 43#include <media/davinci/dm644x_ccdc.h>
41#include <media/davinci/vpss.h> 44#include <media/davinci/vpss.h>
45
42#include "dm644x_ccdc_regs.h" 46#include "dm644x_ccdc_regs.h"
43#include "ccdc_hw_device.h" 47#include "ccdc_hw_device.h"
44 48
@@ -46,32 +50,44 @@ MODULE_LICENSE("GPL");
46MODULE_DESCRIPTION("CCDC Driver for DM6446"); 50MODULE_DESCRIPTION("CCDC Driver for DM6446");
47MODULE_AUTHOR("Texas Instruments"); 51MODULE_AUTHOR("Texas Instruments");
48 52
49static struct device *dev; 53static struct ccdc_oper_config {
50 54 struct device *dev;
51/* Object for CCDC raw mode */ 55 /* CCDC interface type */
52static struct ccdc_params_raw ccdc_hw_params_raw = { 56 enum vpfe_hw_if_type if_type;
53 .pix_fmt = CCDC_PIXFMT_RAW, 57 /* Raw Bayer configuration */
54 .frm_fmt = CCDC_FRMFMT_PROGRESSIVE, 58 struct ccdc_params_raw bayer;
55 .win = CCDC_WIN_VGA, 59 /* YCbCr configuration */
56 .fid_pol = VPFE_PINPOL_POSITIVE, 60 struct ccdc_params_ycbcr ycbcr;
57 .vd_pol = VPFE_PINPOL_POSITIVE, 61 /* Master clock */
58 .hd_pol = VPFE_PINPOL_POSITIVE, 62 struct clk *mclk;
59 .config_params = { 63 /* slave clock */
60 .data_sz = CCDC_DATA_10BITS, 64 struct clk *sclk;
65 /* ccdc base address */
66 void __iomem *base_addr;
67} ccdc_cfg = {
68 /* Raw configurations */
69 .bayer = {
70 .pix_fmt = CCDC_PIXFMT_RAW,
71 .frm_fmt = CCDC_FRMFMT_PROGRESSIVE,
72 .win = CCDC_WIN_VGA,
73 .fid_pol = VPFE_PINPOL_POSITIVE,
74 .vd_pol = VPFE_PINPOL_POSITIVE,
75 .hd_pol = VPFE_PINPOL_POSITIVE,
76 .config_params = {
77 .data_sz = CCDC_DATA_10BITS,
78 },
79 },
80 .ycbcr = {
81 .pix_fmt = CCDC_PIXFMT_YCBCR_8BIT,
82 .frm_fmt = CCDC_FRMFMT_INTERLACED,
83 .win = CCDC_WIN_PAL,
84 .fid_pol = VPFE_PINPOL_POSITIVE,
85 .vd_pol = VPFE_PINPOL_POSITIVE,
86 .hd_pol = VPFE_PINPOL_POSITIVE,
87 .bt656_enable = 1,
88 .pix_order = CCDC_PIXORDER_CBYCRY,
89 .buf_type = CCDC_BUFTYPE_FLD_INTERLEAVED
61 }, 90 },
62};
63
64/* Object for CCDC ycbcr mode */
65static struct ccdc_params_ycbcr ccdc_hw_params_ycbcr = {
66 .pix_fmt = CCDC_PIXFMT_YCBCR_8BIT,
67 .frm_fmt = CCDC_FRMFMT_INTERLACED,
68 .win = CCDC_WIN_PAL,
69 .fid_pol = VPFE_PINPOL_POSITIVE,
70 .vd_pol = VPFE_PINPOL_POSITIVE,
71 .hd_pol = VPFE_PINPOL_POSITIVE,
72 .bt656_enable = 1,
73 .pix_order = CCDC_PIXORDER_CBYCRY,
74 .buf_type = CCDC_BUFTYPE_FLD_INTERLEAVED
75}; 91};
76 92
77#define CCDC_MAX_RAW_YUV_FORMATS 2 93#define CCDC_MAX_RAW_YUV_FORMATS 2
@@ -84,25 +100,15 @@ static u32 ccdc_raw_bayer_pix_formats[] =
84static u32 ccdc_raw_yuv_pix_formats[] = 100static u32 ccdc_raw_yuv_pix_formats[] =
85 {V4L2_PIX_FMT_UYVY, V4L2_PIX_FMT_YUYV}; 101 {V4L2_PIX_FMT_UYVY, V4L2_PIX_FMT_YUYV};
86 102
87static void *__iomem ccdc_base_addr;
88static int ccdc_addr_size;
89static enum vpfe_hw_if_type ccdc_if_type;
90
91/* register access routines */ 103/* register access routines */
92static inline u32 regr(u32 offset) 104static inline u32 regr(u32 offset)
93{ 105{
94 return __raw_readl(ccdc_base_addr + offset); 106 return __raw_readl(ccdc_cfg.base_addr + offset);
95} 107}
96 108
97static inline void regw(u32 val, u32 offset) 109static inline void regw(u32 val, u32 offset)
98{ 110{
99 __raw_writel(val, ccdc_base_addr + offset); 111 __raw_writel(val, ccdc_cfg.base_addr + offset);
100}
101
102static void ccdc_set_ccdc_base(void *addr, int size)
103{
104 ccdc_base_addr = addr;
105 ccdc_addr_size = size;
106} 112}
107 113
108static void ccdc_enable(int flag) 114static void ccdc_enable(int flag)
@@ -132,7 +138,7 @@ void ccdc_setwin(struct v4l2_rect *image_win,
132 int vert_start, vert_nr_lines; 138 int vert_start, vert_nr_lines;
133 int val = 0, mid_img = 0; 139 int val = 0, mid_img = 0;
134 140
135 dev_dbg(dev, "\nStarting ccdc_setwin..."); 141 dev_dbg(ccdc_cfg.dev, "\nStarting ccdc_setwin...");
136 /* 142 /*
137 * ppc - per pixel count. indicates how many pixels per cell 143 * ppc - per pixel count. indicates how many pixels per cell
138 * output to SDRAM. example, for ycbcr, it is one y and one c, so 2. 144 * output to SDRAM. example, for ycbcr, it is one y and one c, so 2.
@@ -171,7 +177,7 @@ void ccdc_setwin(struct v4l2_rect *image_win,
171 regw((vert_start << CCDC_VERT_START_SLV0_SHIFT) | vert_start, 177 regw((vert_start << CCDC_VERT_START_SLV0_SHIFT) | vert_start,
172 CCDC_VERT_START); 178 CCDC_VERT_START);
173 regw(vert_nr_lines, CCDC_VERT_LINES); 179 regw(vert_nr_lines, CCDC_VERT_LINES);
174 dev_dbg(dev, "\nEnd of ccdc_setwin..."); 180 dev_dbg(ccdc_cfg.dev, "\nEnd of ccdc_setwin...");
175} 181}
176 182
177static void ccdc_readregs(void) 183static void ccdc_readregs(void)
@@ -179,39 +185,39 @@ static void ccdc_readregs(void)
179 unsigned int val = 0; 185 unsigned int val = 0;
180 186
181 val = regr(CCDC_ALAW); 187 val = regr(CCDC_ALAW);
182 dev_notice(dev, "\nReading 0x%x to ALAW...\n", val); 188 dev_notice(ccdc_cfg.dev, "\nReading 0x%x to ALAW...\n", val);
183 val = regr(CCDC_CLAMP); 189 val = regr(CCDC_CLAMP);
184 dev_notice(dev, "\nReading 0x%x to CLAMP...\n", val); 190 dev_notice(ccdc_cfg.dev, "\nReading 0x%x to CLAMP...\n", val);
185 val = regr(CCDC_DCSUB); 191 val = regr(CCDC_DCSUB);
186 dev_notice(dev, "\nReading 0x%x to DCSUB...\n", val); 192 dev_notice(ccdc_cfg.dev, "\nReading 0x%x to DCSUB...\n", val);
187 val = regr(CCDC_BLKCMP); 193 val = regr(CCDC_BLKCMP);
188 dev_notice(dev, "\nReading 0x%x to BLKCMP...\n", val); 194 dev_notice(ccdc_cfg.dev, "\nReading 0x%x to BLKCMP...\n", val);
189 val = regr(CCDC_FPC_ADDR); 195 val = regr(CCDC_FPC_ADDR);
190 dev_notice(dev, "\nReading 0x%x to FPC_ADDR...\n", val); 196 dev_notice(ccdc_cfg.dev, "\nReading 0x%x to FPC_ADDR...\n", val);
191 val = regr(CCDC_FPC); 197 val = regr(CCDC_FPC);
192 dev_notice(dev, "\nReading 0x%x to FPC...\n", val); 198 dev_notice(ccdc_cfg.dev, "\nReading 0x%x to FPC...\n", val);
193 val = regr(CCDC_FMTCFG); 199 val = regr(CCDC_FMTCFG);
194 dev_notice(dev, "\nReading 0x%x to FMTCFG...\n", val); 200 dev_notice(ccdc_cfg.dev, "\nReading 0x%x to FMTCFG...\n", val);
195 val = regr(CCDC_COLPTN); 201 val = regr(CCDC_COLPTN);
196 dev_notice(dev, "\nReading 0x%x to COLPTN...\n", val); 202 dev_notice(ccdc_cfg.dev, "\nReading 0x%x to COLPTN...\n", val);
197 val = regr(CCDC_FMT_HORZ); 203 val = regr(CCDC_FMT_HORZ);
198 dev_notice(dev, "\nReading 0x%x to FMT_HORZ...\n", val); 204 dev_notice(ccdc_cfg.dev, "\nReading 0x%x to FMT_HORZ...\n", val);
199 val = regr(CCDC_FMT_VERT); 205 val = regr(CCDC_FMT_VERT);
200 dev_notice(dev, "\nReading 0x%x to FMT_VERT...\n", val); 206 dev_notice(ccdc_cfg.dev, "\nReading 0x%x to FMT_VERT...\n", val);
201 val = regr(CCDC_HSIZE_OFF); 207 val = regr(CCDC_HSIZE_OFF);
202 dev_notice(dev, "\nReading 0x%x to HSIZE_OFF...\n", val); 208 dev_notice(ccdc_cfg.dev, "\nReading 0x%x to HSIZE_OFF...\n", val);
203 val = regr(CCDC_SDOFST); 209 val = regr(CCDC_SDOFST);
204 dev_notice(dev, "\nReading 0x%x to SDOFST...\n", val); 210 dev_notice(ccdc_cfg.dev, "\nReading 0x%x to SDOFST...\n", val);
205 val = regr(CCDC_VP_OUT); 211 val = regr(CCDC_VP_OUT);
206 dev_notice(dev, "\nReading 0x%x to VP_OUT...\n", val); 212 dev_notice(ccdc_cfg.dev, "\nReading 0x%x to VP_OUT...\n", val);
207 val = regr(CCDC_SYN_MODE); 213 val = regr(CCDC_SYN_MODE);
208 dev_notice(dev, "\nReading 0x%x to SYN_MODE...\n", val); 214 dev_notice(ccdc_cfg.dev, "\nReading 0x%x to SYN_MODE...\n", val);
209 val = regr(CCDC_HORZ_INFO); 215 val = regr(CCDC_HORZ_INFO);
210 dev_notice(dev, "\nReading 0x%x to HORZ_INFO...\n", val); 216 dev_notice(ccdc_cfg.dev, "\nReading 0x%x to HORZ_INFO...\n", val);
211 val = regr(CCDC_VERT_START); 217 val = regr(CCDC_VERT_START);
212 dev_notice(dev, "\nReading 0x%x to VERT_START...\n", val); 218 dev_notice(ccdc_cfg.dev, "\nReading 0x%x to VERT_START...\n", val);
213 val = regr(CCDC_VERT_LINES); 219 val = regr(CCDC_VERT_LINES);
214 dev_notice(dev, "\nReading 0x%x to VERT_LINES...\n", val); 220 dev_notice(ccdc_cfg.dev, "\nReading 0x%x to VERT_LINES...\n", val);
215} 221}
216 222
217static int validate_ccdc_param(struct ccdc_config_params_raw *ccdcparam) 223static int validate_ccdc_param(struct ccdc_config_params_raw *ccdcparam)
@@ -220,7 +226,7 @@ static int validate_ccdc_param(struct ccdc_config_params_raw *ccdcparam)
220 if ((ccdcparam->alaw.gama_wd > CCDC_GAMMA_BITS_09_0) || 226 if ((ccdcparam->alaw.gama_wd > CCDC_GAMMA_BITS_09_0) ||
221 (ccdcparam->alaw.gama_wd < CCDC_GAMMA_BITS_15_6) || 227 (ccdcparam->alaw.gama_wd < CCDC_GAMMA_BITS_15_6) ||
222 (ccdcparam->alaw.gama_wd < ccdcparam->data_sz)) { 228 (ccdcparam->alaw.gama_wd < ccdcparam->data_sz)) {
223 dev_dbg(dev, "\nInvalid data line select"); 229 dev_dbg(ccdc_cfg.dev, "\nInvalid data line select");
224 return -1; 230 return -1;
225 } 231 }
226 } 232 }
@@ -230,7 +236,7 @@ static int validate_ccdc_param(struct ccdc_config_params_raw *ccdcparam)
230static int ccdc_update_raw_params(struct ccdc_config_params_raw *raw_params) 236static int ccdc_update_raw_params(struct ccdc_config_params_raw *raw_params)
231{ 237{
232 struct ccdc_config_params_raw *config_params = 238 struct ccdc_config_params_raw *config_params =
233 &ccdc_hw_params_raw.config_params; 239 &ccdc_cfg.bayer.config_params;
234 unsigned int *fpc_virtaddr = NULL; 240 unsigned int *fpc_virtaddr = NULL;
235 unsigned int *fpc_physaddr = NULL; 241 unsigned int *fpc_physaddr = NULL;
236 242
@@ -266,7 +272,7 @@ static int ccdc_update_raw_params(struct ccdc_config_params_raw *raw_params)
266 FP_NUM_BYTES)); 272 FP_NUM_BYTES));
267 273
268 if (fpc_virtaddr == NULL) { 274 if (fpc_virtaddr == NULL) {
269 dev_dbg(dev, 275 dev_dbg(ccdc_cfg.dev,
270 "\nUnable to allocate memory for FPC"); 276 "\nUnable to allocate memory for FPC");
271 return -EFAULT; 277 return -EFAULT;
272 } 278 }
@@ -279,7 +285,7 @@ static int ccdc_update_raw_params(struct ccdc_config_params_raw *raw_params)
279 if (copy_from_user(fpc_virtaddr, 285 if (copy_from_user(fpc_virtaddr,
280 (void __user *)raw_params->fault_pxl.fpc_table_addr, 286 (void __user *)raw_params->fault_pxl.fpc_table_addr,
281 config_params->fault_pxl.fp_num * FP_NUM_BYTES)) { 287 config_params->fault_pxl.fp_num * FP_NUM_BYTES)) {
282 dev_dbg(dev, "\n copy_from_user failed"); 288 dev_dbg(ccdc_cfg.dev, "\n copy_from_user failed");
283 return -EFAULT; 289 return -EFAULT;
284 } 290 }
285 config_params->fault_pxl.fpc_table_addr = (unsigned int)fpc_physaddr; 291 config_params->fault_pxl.fpc_table_addr = (unsigned int)fpc_physaddr;
@@ -289,7 +295,7 @@ static int ccdc_update_raw_params(struct ccdc_config_params_raw *raw_params)
289static int ccdc_close(struct device *dev) 295static int ccdc_close(struct device *dev)
290{ 296{
291 struct ccdc_config_params_raw *config_params = 297 struct ccdc_config_params_raw *config_params =
292 &ccdc_hw_params_raw.config_params; 298 &ccdc_cfg.bayer.config_params;
293 unsigned int *fpc_physaddr = NULL, *fpc_virtaddr = NULL; 299 unsigned int *fpc_physaddr = NULL, *fpc_virtaddr = NULL;
294 300
295 fpc_physaddr = (unsigned int *)config_params->fault_pxl.fpc_table_addr; 301 fpc_physaddr = (unsigned int *)config_params->fault_pxl.fpc_table_addr;
@@ -323,9 +329,8 @@ static void ccdc_restore_defaults(void)
323 329
324static int ccdc_open(struct device *device) 330static int ccdc_open(struct device *device)
325{ 331{
326 dev = device;
327 ccdc_restore_defaults(); 332 ccdc_restore_defaults();
328 if (ccdc_if_type == VPFE_RAW_BAYER) 333 if (ccdc_cfg.if_type == VPFE_RAW_BAYER)
329 ccdc_enable_vport(1); 334 ccdc_enable_vport(1);
330 return 0; 335 return 0;
331} 336}
@@ -341,12 +346,12 @@ static int ccdc_set_params(void __user *params)
341 struct ccdc_config_params_raw ccdc_raw_params; 346 struct ccdc_config_params_raw ccdc_raw_params;
342 int x; 347 int x;
343 348
344 if (ccdc_if_type != VPFE_RAW_BAYER) 349 if (ccdc_cfg.if_type != VPFE_RAW_BAYER)
345 return -EINVAL; 350 return -EINVAL;
346 351
347 x = copy_from_user(&ccdc_raw_params, params, sizeof(ccdc_raw_params)); 352 x = copy_from_user(&ccdc_raw_params, params, sizeof(ccdc_raw_params));
348 if (x) { 353 if (x) {
349 dev_dbg(dev, "ccdc_set_params: error in copying" 354 dev_dbg(ccdc_cfg.dev, "ccdc_set_params: error in copying"
350 "ccdc params, %d\n", x); 355 "ccdc params, %d\n", x);
351 return -EFAULT; 356 return -EFAULT;
352 } 357 }
@@ -364,10 +369,10 @@ static int ccdc_set_params(void __user *params)
364 */ 369 */
365void ccdc_config_ycbcr(void) 370void ccdc_config_ycbcr(void)
366{ 371{
367 struct ccdc_params_ycbcr *params = &ccdc_hw_params_ycbcr; 372 struct ccdc_params_ycbcr *params = &ccdc_cfg.ycbcr;
368 u32 syn_mode; 373 u32 syn_mode;
369 374
370 dev_dbg(dev, "\nStarting ccdc_config_ycbcr..."); 375 dev_dbg(ccdc_cfg.dev, "\nStarting ccdc_config_ycbcr...");
371 /* 376 /*
372 * first restore the CCDC registers to default values 377 * first restore the CCDC registers to default values
373 * This is important since we assume default values to be set in 378 * This is important since we assume default values to be set in
@@ -428,7 +433,7 @@ void ccdc_config_ycbcr(void)
428 regw(CCDC_SDOFST_FIELD_INTERLEAVED, CCDC_SDOFST); 433 regw(CCDC_SDOFST_FIELD_INTERLEAVED, CCDC_SDOFST);
429 434
430 ccdc_sbl_reset(); 435 ccdc_sbl_reset();
431 dev_dbg(dev, "\nEnd of ccdc_config_ycbcr...\n"); 436 dev_dbg(ccdc_cfg.dev, "\nEnd of ccdc_config_ycbcr...\n");
432 ccdc_readregs(); 437 ccdc_readregs();
433} 438}
434 439
@@ -440,9 +445,9 @@ static void ccdc_config_black_clamp(struct ccdc_black_clamp *bclamp)
440 /* configure DCSub */ 445 /* configure DCSub */
441 val = (bclamp->dc_sub) & CCDC_BLK_DC_SUB_MASK; 446 val = (bclamp->dc_sub) & CCDC_BLK_DC_SUB_MASK;
442 regw(val, CCDC_DCSUB); 447 regw(val, CCDC_DCSUB);
443 dev_dbg(dev, "\nWriting 0x%x to DCSUB...\n", val); 448 dev_dbg(ccdc_cfg.dev, "\nWriting 0x%x to DCSUB...\n", val);
444 regw(CCDC_CLAMP_DEFAULT_VAL, CCDC_CLAMP); 449 regw(CCDC_CLAMP_DEFAULT_VAL, CCDC_CLAMP);
445 dev_dbg(dev, "\nWriting 0x0000 to CLAMP...\n"); 450 dev_dbg(ccdc_cfg.dev, "\nWriting 0x0000 to CLAMP...\n");
446 return; 451 return;
447 } 452 }
448 /* 453 /*
@@ -457,10 +462,10 @@ static void ccdc_config_black_clamp(struct ccdc_black_clamp *bclamp)
457 ((bclamp->sample_pixel & CCDC_BLK_SAMPLE_LN_MASK) << 462 ((bclamp->sample_pixel & CCDC_BLK_SAMPLE_LN_MASK) <<
458 CCDC_BLK_SAMPLE_LN_SHIFT) | CCDC_BLK_CLAMP_ENABLE); 463 CCDC_BLK_SAMPLE_LN_SHIFT) | CCDC_BLK_CLAMP_ENABLE);
459 regw(val, CCDC_CLAMP); 464 regw(val, CCDC_CLAMP);
460 dev_dbg(dev, "\nWriting 0x%x to CLAMP...\n", val); 465 dev_dbg(ccdc_cfg.dev, "\nWriting 0x%x to CLAMP...\n", val);
461 /* If Black clamping is enable then make dcsub 0 */ 466 /* If Black clamping is enable then make dcsub 0 */
462 regw(CCDC_DCSUB_DEFAULT_VAL, CCDC_DCSUB); 467 regw(CCDC_DCSUB_DEFAULT_VAL, CCDC_DCSUB);
463 dev_dbg(dev, "\nWriting 0x00000000 to DCSUB...\n"); 468 dev_dbg(ccdc_cfg.dev, "\nWriting 0x00000000 to DCSUB...\n");
464} 469}
465 470
466static void ccdc_config_black_compense(struct ccdc_black_compensation *bcomp) 471static void ccdc_config_black_compense(struct ccdc_black_compensation *bcomp)
@@ -490,17 +495,17 @@ static void ccdc_config_fpc(struct ccdc_fault_pixel *fpc)
490 495
491 /* Configure Fault pixel if needed */ 496 /* Configure Fault pixel if needed */
492 regw(fpc->fpc_table_addr, CCDC_FPC_ADDR); 497 regw(fpc->fpc_table_addr, CCDC_FPC_ADDR);
493 dev_dbg(dev, "\nWriting 0x%x to FPC_ADDR...\n", 498 dev_dbg(ccdc_cfg.dev, "\nWriting 0x%x to FPC_ADDR...\n",
494 (fpc->fpc_table_addr)); 499 (fpc->fpc_table_addr));
495 /* Write the FPC params with FPC disable */ 500 /* Write the FPC params with FPC disable */
496 val = fpc->fp_num & CCDC_FPC_FPC_NUM_MASK; 501 val = fpc->fp_num & CCDC_FPC_FPC_NUM_MASK;
497 regw(val, CCDC_FPC); 502 regw(val, CCDC_FPC);
498 503
499 dev_dbg(dev, "\nWriting 0x%x to FPC...\n", val); 504 dev_dbg(ccdc_cfg.dev, "\nWriting 0x%x to FPC...\n", val);
500 /* read the FPC register */ 505 /* read the FPC register */
501 val = regr(CCDC_FPC) | CCDC_FPC_ENABLE; 506 val = regr(CCDC_FPC) | CCDC_FPC_ENABLE;
502 regw(val, CCDC_FPC); 507 regw(val, CCDC_FPC);
503 dev_dbg(dev, "\nWriting 0x%x to FPC...\n", val); 508 dev_dbg(ccdc_cfg.dev, "\nWriting 0x%x to FPC...\n", val);
504} 509}
505 510
506/* 511/*
@@ -509,13 +514,13 @@ static void ccdc_config_fpc(struct ccdc_fault_pixel *fpc)
509 */ 514 */
510void ccdc_config_raw(void) 515void ccdc_config_raw(void)
511{ 516{
512 struct ccdc_params_raw *params = &ccdc_hw_params_raw; 517 struct ccdc_params_raw *params = &ccdc_cfg.bayer;
513 struct ccdc_config_params_raw *config_params = 518 struct ccdc_config_params_raw *config_params =
514 &ccdc_hw_params_raw.config_params; 519 &ccdc_cfg.bayer.config_params;
515 unsigned int syn_mode = 0; 520 unsigned int syn_mode = 0;
516 unsigned int val; 521 unsigned int val;
517 522
518 dev_dbg(dev, "\nStarting ccdc_config_raw..."); 523 dev_dbg(ccdc_cfg.dev, "\nStarting ccdc_config_raw...");
519 524
520 /* Reset CCDC */ 525 /* Reset CCDC */
521 ccdc_restore_defaults(); 526 ccdc_restore_defaults();
@@ -545,7 +550,7 @@ void ccdc_config_raw(void)
545 val = ((config_params->alaw.gama_wd & 550 val = ((config_params->alaw.gama_wd &
546 CCDC_ALAW_GAMA_WD_MASK) | CCDC_ALAW_ENABLE); 551 CCDC_ALAW_GAMA_WD_MASK) | CCDC_ALAW_ENABLE);
547 regw(val, CCDC_ALAW); 552 regw(val, CCDC_ALAW);
548 dev_dbg(dev, "\nWriting 0x%x to ALAW...\n", val); 553 dev_dbg(ccdc_cfg.dev, "\nWriting 0x%x to ALAW...\n", val);
549 } 554 }
550 555
551 /* Configure video window */ 556 /* Configure video window */
@@ -582,11 +587,11 @@ void ccdc_config_raw(void)
582 /* Write value in FMTCFG */ 587 /* Write value in FMTCFG */
583 regw(val, CCDC_FMTCFG); 588 regw(val, CCDC_FMTCFG);
584 589
585 dev_dbg(dev, "\nWriting 0x%x to FMTCFG...\n", val); 590 dev_dbg(ccdc_cfg.dev, "\nWriting 0x%x to FMTCFG...\n", val);
586 /* Configure the color pattern according to mt9t001 sensor */ 591 /* Configure the color pattern according to mt9t001 sensor */
587 regw(CCDC_COLPTN_VAL, CCDC_COLPTN); 592 regw(CCDC_COLPTN_VAL, CCDC_COLPTN);
588 593
589 dev_dbg(dev, "\nWriting 0xBB11BB11 to COLPTN...\n"); 594 dev_dbg(ccdc_cfg.dev, "\nWriting 0xBB11BB11 to COLPTN...\n");
590 /* 595 /*
591 * Configure Data formatter(Video port) pixel selection 596 * Configure Data formatter(Video port) pixel selection
592 * (FMT_HORZ, FMT_VERT) 597 * (FMT_HORZ, FMT_VERT)
@@ -596,7 +601,7 @@ void ccdc_config_raw(void)
596 (params->win.width & CCDC_FMT_HORZ_FMTLNH_MASK); 601 (params->win.width & CCDC_FMT_HORZ_FMTLNH_MASK);
597 regw(val, CCDC_FMT_HORZ); 602 regw(val, CCDC_FMT_HORZ);
598 603
599 dev_dbg(dev, "\nWriting 0x%x to FMT_HORZ...\n", val); 604 dev_dbg(ccdc_cfg.dev, "\nWriting 0x%x to FMT_HORZ...\n", val);
600 val = (params->win.top & CCDC_FMT_VERT_FMTSLV_MASK) 605 val = (params->win.top & CCDC_FMT_VERT_FMTSLV_MASK)
601 << CCDC_FMT_VERT_FMTSLV_SHIFT; 606 << CCDC_FMT_VERT_FMTSLV_SHIFT;
602 if (params->frm_fmt == CCDC_FRMFMT_PROGRESSIVE) 607 if (params->frm_fmt == CCDC_FRMFMT_PROGRESSIVE)
@@ -604,13 +609,13 @@ void ccdc_config_raw(void)
604 else 609 else
605 val |= (params->win.height >> 1) & CCDC_FMT_VERT_FMTLNV_MASK; 610 val |= (params->win.height >> 1) & CCDC_FMT_VERT_FMTLNV_MASK;
606 611
607 dev_dbg(dev, "\nparams->win.height 0x%x ...\n", 612 dev_dbg(ccdc_cfg.dev, "\nparams->win.height 0x%x ...\n",
608 params->win.height); 613 params->win.height);
609 regw(val, CCDC_FMT_VERT); 614 regw(val, CCDC_FMT_VERT);
610 615
611 dev_dbg(dev, "\nWriting 0x%x to FMT_VERT...\n", val); 616 dev_dbg(ccdc_cfg.dev, "\nWriting 0x%x to FMT_VERT...\n", val);
612 617
613 dev_dbg(dev, "\nbelow regw(val, FMT_VERT)..."); 618 dev_dbg(ccdc_cfg.dev, "\nbelow regw(val, FMT_VERT)...");
614 619
615 /* 620 /*
616 * Configure Horizontal offset register. If pack 8 is enabled then 621 * Configure Horizontal offset register. If pack 8 is enabled then
@@ -631,17 +636,17 @@ void ccdc_config_raw(void)
631 if (params->image_invert_enable) { 636 if (params->image_invert_enable) {
632 /* For intelace inverse mode */ 637 /* For intelace inverse mode */
633 regw(CCDC_INTERLACED_IMAGE_INVERT, CCDC_SDOFST); 638 regw(CCDC_INTERLACED_IMAGE_INVERT, CCDC_SDOFST);
634 dev_dbg(dev, "\nWriting 0x4B6D to SDOFST...\n"); 639 dev_dbg(ccdc_cfg.dev, "\nWriting 0x4B6D to SDOFST..\n");
635 } 640 }
636 641
637 else { 642 else {
638 /* For intelace non inverse mode */ 643 /* For intelace non inverse mode */
639 regw(CCDC_INTERLACED_NO_IMAGE_INVERT, CCDC_SDOFST); 644 regw(CCDC_INTERLACED_NO_IMAGE_INVERT, CCDC_SDOFST);
640 dev_dbg(dev, "\nWriting 0x0249 to SDOFST...\n"); 645 dev_dbg(ccdc_cfg.dev, "\nWriting 0x0249 to SDOFST..\n");
641 } 646 }
642 } else if (params->frm_fmt == CCDC_FRMFMT_PROGRESSIVE) { 647 } else if (params->frm_fmt == CCDC_FRMFMT_PROGRESSIVE) {
643 regw(CCDC_PROGRESSIVE_NO_IMAGE_INVERT, CCDC_SDOFST); 648 regw(CCDC_PROGRESSIVE_NO_IMAGE_INVERT, CCDC_SDOFST);
644 dev_dbg(dev, "\nWriting 0x0000 to SDOFST...\n"); 649 dev_dbg(ccdc_cfg.dev, "\nWriting 0x0000 to SDOFST...\n");
645 } 650 }
646 651
647 /* 652 /*
@@ -662,18 +667,18 @@ void ccdc_config_raw(void)
662 val |= (params->win.left) & CCDC_VP_OUT_HORZ_ST_MASK; 667 val |= (params->win.left) & CCDC_VP_OUT_HORZ_ST_MASK;
663 regw(val, CCDC_VP_OUT); 668 regw(val, CCDC_VP_OUT);
664 669
665 dev_dbg(dev, "\nWriting 0x%x to VP_OUT...\n", val); 670 dev_dbg(ccdc_cfg.dev, "\nWriting 0x%x to VP_OUT...\n", val);
666 regw(syn_mode, CCDC_SYN_MODE); 671 regw(syn_mode, CCDC_SYN_MODE);
667 dev_dbg(dev, "\nWriting 0x%x to SYN_MODE...\n", syn_mode); 672 dev_dbg(ccdc_cfg.dev, "\nWriting 0x%x to SYN_MODE...\n", syn_mode);
668 673
669 ccdc_sbl_reset(); 674 ccdc_sbl_reset();
670 dev_dbg(dev, "\nend of ccdc_config_raw..."); 675 dev_dbg(ccdc_cfg.dev, "\nend of ccdc_config_raw...");
671 ccdc_readregs(); 676 ccdc_readregs();
672} 677}
673 678
674static int ccdc_configure(void) 679static int ccdc_configure(void)
675{ 680{
676 if (ccdc_if_type == VPFE_RAW_BAYER) 681 if (ccdc_cfg.if_type == VPFE_RAW_BAYER)
677 ccdc_config_raw(); 682 ccdc_config_raw();
678 else 683 else
679 ccdc_config_ycbcr(); 684 ccdc_config_ycbcr();
@@ -682,24 +687,24 @@ static int ccdc_configure(void)
682 687
683static int ccdc_set_buftype(enum ccdc_buftype buf_type) 688static int ccdc_set_buftype(enum ccdc_buftype buf_type)
684{ 689{
685 if (ccdc_if_type == VPFE_RAW_BAYER) 690 if (ccdc_cfg.if_type == VPFE_RAW_BAYER)
686 ccdc_hw_params_raw.buf_type = buf_type; 691 ccdc_cfg.bayer.buf_type = buf_type;
687 else 692 else
688 ccdc_hw_params_ycbcr.buf_type = buf_type; 693 ccdc_cfg.ycbcr.buf_type = buf_type;
689 return 0; 694 return 0;
690} 695}
691 696
692static enum ccdc_buftype ccdc_get_buftype(void) 697static enum ccdc_buftype ccdc_get_buftype(void)
693{ 698{
694 if (ccdc_if_type == VPFE_RAW_BAYER) 699 if (ccdc_cfg.if_type == VPFE_RAW_BAYER)
695 return ccdc_hw_params_raw.buf_type; 700 return ccdc_cfg.bayer.buf_type;
696 return ccdc_hw_params_ycbcr.buf_type; 701 return ccdc_cfg.ycbcr.buf_type;
697} 702}
698 703
699static int ccdc_enum_pix(u32 *pix, int i) 704static int ccdc_enum_pix(u32 *pix, int i)
700{ 705{
701 int ret = -EINVAL; 706 int ret = -EINVAL;
702 if (ccdc_if_type == VPFE_RAW_BAYER) { 707 if (ccdc_cfg.if_type == VPFE_RAW_BAYER) {
703 if (i < ARRAY_SIZE(ccdc_raw_bayer_pix_formats)) { 708 if (i < ARRAY_SIZE(ccdc_raw_bayer_pix_formats)) {
704 *pix = ccdc_raw_bayer_pix_formats[i]; 709 *pix = ccdc_raw_bayer_pix_formats[i];
705 ret = 0; 710 ret = 0;
@@ -715,17 +720,17 @@ static int ccdc_enum_pix(u32 *pix, int i)
715 720
716static int ccdc_set_pixel_format(u32 pixfmt) 721static int ccdc_set_pixel_format(u32 pixfmt)
717{ 722{
718 if (ccdc_if_type == VPFE_RAW_BAYER) { 723 if (ccdc_cfg.if_type == VPFE_RAW_BAYER) {
719 ccdc_hw_params_raw.pix_fmt = CCDC_PIXFMT_RAW; 724 ccdc_cfg.bayer.pix_fmt = CCDC_PIXFMT_RAW;
720 if (pixfmt == V4L2_PIX_FMT_SBGGR8) 725 if (pixfmt == V4L2_PIX_FMT_SBGGR8)
721 ccdc_hw_params_raw.config_params.alaw.enable = 1; 726 ccdc_cfg.bayer.config_params.alaw.enable = 1;
722 else if (pixfmt != V4L2_PIX_FMT_SBGGR16) 727 else if (pixfmt != V4L2_PIX_FMT_SBGGR16)
723 return -EINVAL; 728 return -EINVAL;
724 } else { 729 } else {
725 if (pixfmt == V4L2_PIX_FMT_YUYV) 730 if (pixfmt == V4L2_PIX_FMT_YUYV)
726 ccdc_hw_params_ycbcr.pix_order = CCDC_PIXORDER_YCBYCR; 731 ccdc_cfg.ycbcr.pix_order = CCDC_PIXORDER_YCBYCR;
727 else if (pixfmt == V4L2_PIX_FMT_UYVY) 732 else if (pixfmt == V4L2_PIX_FMT_UYVY)
728 ccdc_hw_params_ycbcr.pix_order = CCDC_PIXORDER_CBYCRY; 733 ccdc_cfg.ycbcr.pix_order = CCDC_PIXORDER_CBYCRY;
729 else 734 else
730 return -EINVAL; 735 return -EINVAL;
731 } 736 }
@@ -734,17 +739,16 @@ static int ccdc_set_pixel_format(u32 pixfmt)
734 739
735static u32 ccdc_get_pixel_format(void) 740static u32 ccdc_get_pixel_format(void)
736{ 741{
737 struct ccdc_a_law *alaw = 742 struct ccdc_a_law *alaw = &ccdc_cfg.bayer.config_params.alaw;
738 &ccdc_hw_params_raw.config_params.alaw;
739 u32 pixfmt; 743 u32 pixfmt;
740 744
741 if (ccdc_if_type == VPFE_RAW_BAYER) 745 if (ccdc_cfg.if_type == VPFE_RAW_BAYER)
742 if (alaw->enable) 746 if (alaw->enable)
743 pixfmt = V4L2_PIX_FMT_SBGGR8; 747 pixfmt = V4L2_PIX_FMT_SBGGR8;
744 else 748 else
745 pixfmt = V4L2_PIX_FMT_SBGGR16; 749 pixfmt = V4L2_PIX_FMT_SBGGR16;
746 else { 750 else {
747 if (ccdc_hw_params_ycbcr.pix_order == CCDC_PIXORDER_YCBYCR) 751 if (ccdc_cfg.ycbcr.pix_order == CCDC_PIXORDER_YCBYCR)
748 pixfmt = V4L2_PIX_FMT_YUYV; 752 pixfmt = V4L2_PIX_FMT_YUYV;
749 else 753 else
750 pixfmt = V4L2_PIX_FMT_UYVY; 754 pixfmt = V4L2_PIX_FMT_UYVY;
@@ -754,53 +758,53 @@ static u32 ccdc_get_pixel_format(void)
754 758
755static int ccdc_set_image_window(struct v4l2_rect *win) 759static int ccdc_set_image_window(struct v4l2_rect *win)
756{ 760{
757 if (ccdc_if_type == VPFE_RAW_BAYER) 761 if (ccdc_cfg.if_type == VPFE_RAW_BAYER)
758 ccdc_hw_params_raw.win = *win; 762 ccdc_cfg.bayer.win = *win;
759 else 763 else
760 ccdc_hw_params_ycbcr.win = *win; 764 ccdc_cfg.ycbcr.win = *win;
761 return 0; 765 return 0;
762} 766}
763 767
764static void ccdc_get_image_window(struct v4l2_rect *win) 768static void ccdc_get_image_window(struct v4l2_rect *win)
765{ 769{
766 if (ccdc_if_type == VPFE_RAW_BAYER) 770 if (ccdc_cfg.if_type == VPFE_RAW_BAYER)
767 *win = ccdc_hw_params_raw.win; 771 *win = ccdc_cfg.bayer.win;
768 else 772 else
769 *win = ccdc_hw_params_ycbcr.win; 773 *win = ccdc_cfg.ycbcr.win;
770} 774}
771 775
772static unsigned int ccdc_get_line_length(void) 776static unsigned int ccdc_get_line_length(void)
773{ 777{
774 struct ccdc_config_params_raw *config_params = 778 struct ccdc_config_params_raw *config_params =
775 &ccdc_hw_params_raw.config_params; 779 &ccdc_cfg.bayer.config_params;
776 unsigned int len; 780 unsigned int len;
777 781
778 if (ccdc_if_type == VPFE_RAW_BAYER) { 782 if (ccdc_cfg.if_type == VPFE_RAW_BAYER) {
779 if ((config_params->alaw.enable) || 783 if ((config_params->alaw.enable) ||
780 (config_params->data_sz == CCDC_DATA_8BITS)) 784 (config_params->data_sz == CCDC_DATA_8BITS))
781 len = ccdc_hw_params_raw.win.width; 785 len = ccdc_cfg.bayer.win.width;
782 else 786 else
783 len = ccdc_hw_params_raw.win.width * 2; 787 len = ccdc_cfg.bayer.win.width * 2;
784 } else 788 } else
785 len = ccdc_hw_params_ycbcr.win.width * 2; 789 len = ccdc_cfg.ycbcr.win.width * 2;
786 return ALIGN(len, 32); 790 return ALIGN(len, 32);
787} 791}
788 792
789static int ccdc_set_frame_format(enum ccdc_frmfmt frm_fmt) 793static int ccdc_set_frame_format(enum ccdc_frmfmt frm_fmt)
790{ 794{
791 if (ccdc_if_type == VPFE_RAW_BAYER) 795 if (ccdc_cfg.if_type == VPFE_RAW_BAYER)
792 ccdc_hw_params_raw.frm_fmt = frm_fmt; 796 ccdc_cfg.bayer.frm_fmt = frm_fmt;
793 else 797 else
794 ccdc_hw_params_ycbcr.frm_fmt = frm_fmt; 798 ccdc_cfg.ycbcr.frm_fmt = frm_fmt;
795 return 0; 799 return 0;
796} 800}
797 801
798static enum ccdc_frmfmt ccdc_get_frame_format(void) 802static enum ccdc_frmfmt ccdc_get_frame_format(void)
799{ 803{
800 if (ccdc_if_type == VPFE_RAW_BAYER) 804 if (ccdc_cfg.if_type == VPFE_RAW_BAYER)
801 return ccdc_hw_params_raw.frm_fmt; 805 return ccdc_cfg.bayer.frm_fmt;
802 else 806 else
803 return ccdc_hw_params_ycbcr.frm_fmt; 807 return ccdc_cfg.ycbcr.frm_fmt;
804} 808}
805 809
806static int ccdc_getfid(void) 810static int ccdc_getfid(void)
@@ -816,14 +820,14 @@ static inline void ccdc_setfbaddr(unsigned long addr)
816 820
817static int ccdc_set_hw_if_params(struct vpfe_hw_if_param *params) 821static int ccdc_set_hw_if_params(struct vpfe_hw_if_param *params)
818{ 822{
819 ccdc_if_type = params->if_type; 823 ccdc_cfg.if_type = params->if_type;
820 824
821 switch (params->if_type) { 825 switch (params->if_type) {
822 case VPFE_BT656: 826 case VPFE_BT656:
823 case VPFE_YCBCR_SYNC_16: 827 case VPFE_YCBCR_SYNC_16:
824 case VPFE_YCBCR_SYNC_8: 828 case VPFE_YCBCR_SYNC_8:
825 ccdc_hw_params_ycbcr.vd_pol = params->vdpol; 829 ccdc_cfg.ycbcr.vd_pol = params->vdpol;
826 ccdc_hw_params_ycbcr.hd_pol = params->hdpol; 830 ccdc_cfg.ycbcr.hd_pol = params->hdpol;
827 break; 831 break;
828 default: 832 default:
829 /* TODO add support for raw bayer here */ 833 /* TODO add support for raw bayer here */
@@ -838,7 +842,6 @@ static struct ccdc_hw_device ccdc_hw_dev = {
838 .hw_ops = { 842 .hw_ops = {
839 .open = ccdc_open, 843 .open = ccdc_open,
840 .close = ccdc_close, 844 .close = ccdc_close,
841 .set_ccdc_base = ccdc_set_ccdc_base,
842 .reset = ccdc_sbl_reset, 845 .reset = ccdc_sbl_reset,
843 .enable = ccdc_enable, 846 .enable = ccdc_enable,
844 .set_hw_if_params = ccdc_set_hw_if_params, 847 .set_hw_if_params = ccdc_set_hw_if_params,
@@ -859,19 +862,105 @@ static struct ccdc_hw_device ccdc_hw_dev = {
859 }, 862 },
860}; 863};
861 864
862static int __init dm644x_ccdc_init(void) 865static int __init dm644x_ccdc_probe(struct platform_device *pdev)
863{ 866{
864 printk(KERN_NOTICE "dm644x_ccdc_init\n"); 867 struct resource *res;
865 if (vpfe_register_ccdc_device(&ccdc_hw_dev) < 0) 868 int status = 0;
866 return -1; 869
867 printk(KERN_NOTICE "%s is registered with vpfe.\n", 870 /*
868 ccdc_hw_dev.name); 871 * first try to register with vpfe. If not correct platform, then we
872 * don't have to iomap
873 */
874 status = vpfe_register_ccdc_device(&ccdc_hw_dev);
875 if (status < 0)
876 return status;
877
878 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
879 if (!res) {
880 status = -ENODEV;
881 goto fail_nores;
882 }
883
884 res = request_mem_region(res->start, resource_size(res), res->name);
885 if (!res) {
886 status = -EBUSY;
887 goto fail_nores;
888 }
889
890 ccdc_cfg.base_addr = ioremap_nocache(res->start, resource_size(res));
891 if (!ccdc_cfg.base_addr) {
892 status = -ENOMEM;
893 goto fail_nomem;
894 }
895
896 /* Get and enable Master clock */
897 ccdc_cfg.mclk = clk_get(&pdev->dev, "master");
898 if (IS_ERR(ccdc_cfg.mclk)) {
899 status = PTR_ERR(ccdc_cfg.mclk);
900 goto fail_nomap;
901 }
902 if (clk_enable(ccdc_cfg.mclk)) {
903 status = -ENODEV;
904 goto fail_mclk;
905 }
906
907 /* Get and enable Slave clock */
908 ccdc_cfg.sclk = clk_get(&pdev->dev, "slave");
909 if (IS_ERR(ccdc_cfg.sclk)) {
910 status = PTR_ERR(ccdc_cfg.sclk);
911 goto fail_mclk;
912 }
913 if (clk_enable(ccdc_cfg.sclk)) {
914 status = -ENODEV;
915 goto fail_sclk;
916 }
917 ccdc_cfg.dev = &pdev->dev;
918 printk(KERN_NOTICE "%s is registered with vpfe.\n", ccdc_hw_dev.name);
869 return 0; 919 return 0;
920fail_sclk:
921 clk_put(ccdc_cfg.sclk);
922fail_mclk:
923 clk_put(ccdc_cfg.mclk);
924fail_nomap:
925 iounmap(ccdc_cfg.base_addr);
926fail_nomem:
927 release_mem_region(res->start, resource_size(res));
928fail_nores:
929 vpfe_unregister_ccdc_device(&ccdc_hw_dev);
930 return status;
870} 931}
871 932
872static void __exit dm644x_ccdc_exit(void) 933static int dm644x_ccdc_remove(struct platform_device *pdev)
873{ 934{
935 struct resource *res;
936
937 clk_put(ccdc_cfg.mclk);
938 clk_put(ccdc_cfg.sclk);
939 iounmap(ccdc_cfg.base_addr);
940 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
941 if (res)
942 release_mem_region(res->start, resource_size(res));
874 vpfe_unregister_ccdc_device(&ccdc_hw_dev); 943 vpfe_unregister_ccdc_device(&ccdc_hw_dev);
944 return 0;
945}
946
947static struct platform_driver dm644x_ccdc_driver = {
948 .driver = {
949 .name = "dm644x_ccdc",
950 .owner = THIS_MODULE,
951 },
952 .remove = __devexit_p(dm644x_ccdc_remove),
953 .probe = dm644x_ccdc_probe,
954};
955
956static int __init dm644x_ccdc_init(void)
957{
958 return platform_driver_register(&dm644x_ccdc_driver);
959}
960
961static void __exit dm644x_ccdc_exit(void)
962{
963 platform_driver_unregister(&dm644x_ccdc_driver);
875} 964}
876 965
877module_init(dm644x_ccdc_init); 966module_init(dm644x_ccdc_init);
diff --git a/drivers/media/video/davinci/isif.c b/drivers/media/video/davinci/isif.c
new file mode 100644
index 000000000000..29c29c668596
--- /dev/null
+++ b/drivers/media/video/davinci/isif.c
@@ -0,0 +1,1172 @@
1/*
2 * Copyright (C) 2008-2009 Texas Instruments Inc
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 *
18 * Image Sensor Interface (ISIF) driver
19 *
20 * This driver is for configuring the ISIF IP available on DM365 or any other
21 * TI SoCs. This is used for capturing yuv or bayer video or image data
22 * from a decoder or sensor. This IP is similar to the CCDC IP on DM355
23 * and DM6446, but with enhanced or additional ip blocks. The driver
24 * configures the ISIF upon commands from the vpfe bridge driver through
25 * ccdc_hw_device interface.
26 *
27 * TODO: 1) Raw bayer parameter settings and bayer capture
28 * 2) Add support for control ioctl
29 */
30#include <linux/delay.h>
31#include <linux/platform_device.h>
32#include <linux/uaccess.h>
33#include <linux/io.h>
34#include <linux/videodev2.h>
35#include <linux/clk.h>
36#include <linux/err.h>
37
38#include <mach/mux.h>
39
40#include <media/davinci/isif.h>
41#include <media/davinci/vpss.h>
42
43#include "isif_regs.h"
44#include "ccdc_hw_device.h"
45
46/* Defaults for module configuration parameters */
47static struct isif_config_params_raw isif_config_defaults = {
48 .linearize = {
49 .en = 0,
50 .corr_shft = ISIF_NO_SHIFT,
51 .scale_fact = {1, 0},
52 },
53 .df_csc = {
54 .df_or_csc = 0,
55 .csc = {
56 .en = 0,
57 },
58 },
59 .dfc = {
60 .en = 0,
61 },
62 .bclamp = {
63 .en = 0,
64 },
65 .gain_offset = {
66 .gain = {
67 .r_ye = {1, 0},
68 .gr_cy = {1, 0},
69 .gb_g = {1, 0},
70 .b_mg = {1, 0},
71 },
72 },
73 .culling = {
74 .hcpat_odd = 0xff,
75 .hcpat_even = 0xff,
76 .vcpat = 0xff,
77 },
78 .compress = {
79 .alg = ISIF_ALAW,
80 },
81};
82
83/* ISIF operation configuration */
84static struct isif_oper_config {
85 struct device *dev;
86 enum vpfe_hw_if_type if_type;
87 struct isif_ycbcr_config ycbcr;
88 struct isif_params_raw bayer;
89 enum isif_data_pack data_pack;
90 /* Master clock */
91 struct clk *mclk;
92 /* ISIF base address */
93 void __iomem *base_addr;
94 /* ISIF Linear Table 0 */
95 void __iomem *linear_tbl0_addr;
96 /* ISIF Linear Table 1 */
97 void __iomem *linear_tbl1_addr;
98} isif_cfg = {
99 .ycbcr = {
100 .pix_fmt = CCDC_PIXFMT_YCBCR_8BIT,
101 .frm_fmt = CCDC_FRMFMT_INTERLACED,
102 .win = ISIF_WIN_NTSC,
103 .fid_pol = VPFE_PINPOL_POSITIVE,
104 .vd_pol = VPFE_PINPOL_POSITIVE,
105 .hd_pol = VPFE_PINPOL_POSITIVE,
106 .pix_order = CCDC_PIXORDER_CBYCRY,
107 .buf_type = CCDC_BUFTYPE_FLD_INTERLEAVED,
108 },
109 .bayer = {
110 .pix_fmt = CCDC_PIXFMT_RAW,
111 .frm_fmt = CCDC_FRMFMT_PROGRESSIVE,
112 .win = ISIF_WIN_VGA,
113 .fid_pol = VPFE_PINPOL_POSITIVE,
114 .vd_pol = VPFE_PINPOL_POSITIVE,
115 .hd_pol = VPFE_PINPOL_POSITIVE,
116 .gain = {
117 .r_ye = {1, 0},
118 .gr_cy = {1, 0},
119 .gb_g = {1, 0},
120 .b_mg = {1, 0},
121 },
122 .cfa_pat = ISIF_CFA_PAT_MOSAIC,
123 .data_msb = ISIF_BIT_MSB_11,
124 .config_params = {
125 .data_shift = ISIF_NO_SHIFT,
126 .col_pat_field0 = {
127 .olop = ISIF_GREEN_BLUE,
128 .olep = ISIF_BLUE,
129 .elop = ISIF_RED,
130 .elep = ISIF_GREEN_RED,
131 },
132 .col_pat_field1 = {
133 .olop = ISIF_GREEN_BLUE,
134 .olep = ISIF_BLUE,
135 .elop = ISIF_RED,
136 .elep = ISIF_GREEN_RED,
137 },
138 .test_pat_gen = 0,
139 },
140 },
141 .data_pack = ISIF_DATA_PACK8,
142};
143
144/* Raw Bayer formats */
145static const u32 isif_raw_bayer_pix_formats[] = {
146 V4L2_PIX_FMT_SBGGR8, V4L2_PIX_FMT_SBGGR16};
147
148/* Raw YUV formats */
149static const u32 isif_raw_yuv_pix_formats[] = {
150 V4L2_PIX_FMT_UYVY, V4L2_PIX_FMT_YUYV};
151
152/* register access routines */
153static inline u32 regr(u32 offset)
154{
155 return __raw_readl(isif_cfg.base_addr + offset);
156}
157
158static inline void regw(u32 val, u32 offset)
159{
160 __raw_writel(val, isif_cfg.base_addr + offset);
161}
162
163/* reg_modify() - read, modify and write register */
164static inline u32 reg_modify(u32 mask, u32 val, u32 offset)
165{
166 u32 new_val = (regr(offset) & ~mask) | (val & mask);
167
168 regw(new_val, offset);
169 return new_val;
170}
171
172static inline void regw_lin_tbl(u32 val, u32 offset, int i)
173{
174 if (!i)
175 __raw_writel(val, isif_cfg.linear_tbl0_addr + offset);
176 else
177 __raw_writel(val, isif_cfg.linear_tbl1_addr + offset);
178}
179
180static void isif_disable_all_modules(void)
181{
182 /* disable BC */
183 regw(0, CLAMPCFG);
184 /* disable vdfc */
185 regw(0, DFCCTL);
186 /* disable CSC */
187 regw(0, CSCCTL);
188 /* disable linearization */
189 regw(0, LINCFG0);
190 /* disable other modules here as they are supported */
191}
192
193static void isif_enable(int en)
194{
195 if (!en) {
196 /* Before disable isif, disable all ISIF modules */
197 isif_disable_all_modules();
198 /*
199 * wait for next VD. Assume lowest scan rate is 12 Hz. So
200 * 100 msec delay is good enough
201 */
202 msleep(100);
203 }
204 reg_modify(ISIF_SYNCEN_VDHDEN_MASK, en, SYNCEN);
205}
206
207static void isif_enable_output_to_sdram(int en)
208{
209 reg_modify(ISIF_SYNCEN_WEN_MASK, en << ISIF_SYNCEN_WEN_SHIFT, SYNCEN);
210}
211
212static void isif_config_culling(struct isif_cul *cul)
213{
214 u32 val;
215
216 /* Horizontal pattern */
217 val = (cul->hcpat_even << CULL_PAT_EVEN_LINE_SHIFT) | cul->hcpat_odd;
218 regw(val, CULH);
219
220 /* vertical pattern */
221 regw(cul->vcpat, CULV);
222
223 /* LPF */
224 reg_modify(ISIF_LPF_MASK << ISIF_LPF_SHIFT,
225 cul->en_lpf << ISIF_LPF_SHIFT, MODESET);
226}
227
228static void isif_config_gain_offset(void)
229{
230 struct isif_gain_offsets_adj *gain_off_p =
231 &isif_cfg.bayer.config_params.gain_offset;
232 u32 val;
233
234 val = (!!gain_off_p->gain_sdram_en << GAIN_SDRAM_EN_SHIFT) |
235 (!!gain_off_p->gain_ipipe_en << GAIN_IPIPE_EN_SHIFT) |
236 (!!gain_off_p->gain_h3a_en << GAIN_H3A_EN_SHIFT) |
237 (!!gain_off_p->offset_sdram_en << OFST_SDRAM_EN_SHIFT) |
238 (!!gain_off_p->offset_ipipe_en << OFST_IPIPE_EN_SHIFT) |
239 (!!gain_off_p->offset_h3a_en << OFST_H3A_EN_SHIFT);
240
241 reg_modify(GAIN_OFFSET_EN_MASK, val, CGAMMAWD);
242
243 val = (gain_off_p->gain.r_ye.integer << GAIN_INTEGER_SHIFT) |
244 gain_off_p->gain.r_ye.decimal;
245 regw(val, CRGAIN);
246
247 val = (gain_off_p->gain.gr_cy.integer << GAIN_INTEGER_SHIFT) |
248 gain_off_p->gain.gr_cy.decimal;
249 regw(val, CGRGAIN);
250
251 val = (gain_off_p->gain.gb_g.integer << GAIN_INTEGER_SHIFT) |
252 gain_off_p->gain.gb_g.decimal;
253 regw(val, CGBGAIN);
254
255 val = (gain_off_p->gain.b_mg.integer << GAIN_INTEGER_SHIFT) |
256 gain_off_p->gain.b_mg.decimal;
257 regw(val, CBGAIN);
258
259 regw(gain_off_p->offset, COFSTA);
260}
261
262static void isif_restore_defaults(void)
263{
264 enum vpss_ccdc_source_sel source = VPSS_CCDCIN;
265
266 dev_dbg(isif_cfg.dev, "\nstarting isif_restore_defaults...");
267 isif_cfg.bayer.config_params = isif_config_defaults;
268 /* Enable clock to ISIF, IPIPEIF and BL */
269 vpss_enable_clock(VPSS_CCDC_CLOCK, 1);
270 vpss_enable_clock(VPSS_IPIPEIF_CLOCK, 1);
271 vpss_enable_clock(VPSS_BL_CLOCK, 1);
272 /* Set default offset and gain */
273 isif_config_gain_offset();
274 vpss_select_ccdc_source(source);
275 dev_dbg(isif_cfg.dev, "\nEnd of isif_restore_defaults...");
276}
277
278static int isif_open(struct device *device)
279{
280 isif_restore_defaults();
281 return 0;
282}
283
284/* This function will configure the window size to be capture in ISIF reg */
285static void isif_setwin(struct v4l2_rect *image_win,
286 enum ccdc_frmfmt frm_fmt, int ppc)
287{
288 int horz_start, horz_nr_pixels;
289 int vert_start, vert_nr_lines;
290 int mid_img = 0;
291
292 dev_dbg(isif_cfg.dev, "\nStarting isif_setwin...");
293 /*
294 * ppc - per pixel count. indicates how many pixels per cell
295 * output to SDRAM. example, for ycbcr, it is one y and one c, so 2.
296 * raw capture this is 1
297 */
298 horz_start = image_win->left << (ppc - 1);
299 horz_nr_pixels = ((image_win->width) << (ppc - 1)) - 1;
300
301 /* Writing the horizontal info into the registers */
302 regw(horz_start & START_PX_HOR_MASK, SPH);
303 regw(horz_nr_pixels & NUM_PX_HOR_MASK, LNH);
304 vert_start = image_win->top;
305
306 if (frm_fmt == CCDC_FRMFMT_INTERLACED) {
307 vert_nr_lines = (image_win->height >> 1) - 1;
308 vert_start >>= 1;
309 /* To account for VD since line 0 doesn't have any data */
310 vert_start += 1;
311 } else {
312 /* To account for VD since line 0 doesn't have any data */
313 vert_start += 1;
314 vert_nr_lines = image_win->height - 1;
315 /* configure VDINT0 and VDINT1 */
316 mid_img = vert_start + (image_win->height / 2);
317 regw(mid_img, VDINT1);
318 }
319
320 regw(0, VDINT0);
321 regw(vert_start & START_VER_ONE_MASK, SLV0);
322 regw(vert_start & START_VER_TWO_MASK, SLV1);
323 regw(vert_nr_lines & NUM_LINES_VER, LNV);
324}
325
326static void isif_config_bclamp(struct isif_black_clamp *bc)
327{
328 u32 val;
329
330 /*
331 * DC Offset is always added to image data irrespective of bc enable
332 * status
333 */
334 regw(bc->dc_offset, CLDCOFST);
335
336 if (bc->en) {
337 val = bc->bc_mode_color << ISIF_BC_MODE_COLOR_SHIFT;
338
339 /* Enable BC and horizontal clamp caculation paramaters */
340 val = val | 1 | (bc->horz.mode << ISIF_HORZ_BC_MODE_SHIFT);
341
342 regw(val, CLAMPCFG);
343
344 if (bc->horz.mode != ISIF_HORZ_BC_DISABLE) {
345 /*
346 * Window count for calculation
347 * Base window selection
348 * pixel limit
349 * Horizontal size of window
350 * vertical size of the window
351 * Horizontal start position of the window
352 * Vertical start position of the window
353 */
354 val = bc->horz.win_count_calc |
355 ((!!bc->horz.base_win_sel_calc) <<
356 ISIF_HORZ_BC_WIN_SEL_SHIFT) |
357 ((!!bc->horz.clamp_pix_limit) <<
358 ISIF_HORZ_BC_PIX_LIMIT_SHIFT) |
359 (bc->horz.win_h_sz_calc <<
360 ISIF_HORZ_BC_WIN_H_SIZE_SHIFT) |
361 (bc->horz.win_v_sz_calc <<
362 ISIF_HORZ_BC_WIN_V_SIZE_SHIFT);
363 regw(val, CLHWIN0);
364
365 regw(bc->horz.win_start_h_calc, CLHWIN1);
366 regw(bc->horz.win_start_v_calc, CLHWIN2);
367 }
368
369 /* vertical clamp caculation paramaters */
370
371 /* Reset clamp value sel for previous line */
372 val |=
373 (bc->vert.reset_val_sel << ISIF_VERT_BC_RST_VAL_SEL_SHIFT) |
374 (bc->vert.line_ave_coef << ISIF_VERT_BC_LINE_AVE_COEF_SHIFT);
375 regw(val, CLVWIN0);
376
377 /* Optical Black horizontal start position */
378 regw(bc->vert.ob_start_h, CLVWIN1);
379 /* Optical Black vertical start position */
380 regw(bc->vert.ob_start_v, CLVWIN2);
381 /* Optical Black vertical size for calculation */
382 regw(bc->vert.ob_v_sz_calc, CLVWIN3);
383 /* Vertical start position for BC subtraction */
384 regw(bc->vert_start_sub, CLSV);
385 }
386}
387
388static void isif_config_linearization(struct isif_linearize *linearize)
389{
390 u32 val, i;
391
392 if (!linearize->en) {
393 regw(0, LINCFG0);
394 return;
395 }
396
397 /* shift value for correction & enable linearization (set lsb) */
398 val = (linearize->corr_shft << ISIF_LIN_CORRSFT_SHIFT) | 1;
399 regw(val, LINCFG0);
400
401 /* Scale factor */
402 val = ((!!linearize->scale_fact.integer) <<
403 ISIF_LIN_SCALE_FACT_INTEG_SHIFT) |
404 linearize->scale_fact.decimal;
405 regw(val, LINCFG1);
406
407 for (i = 0; i < ISIF_LINEAR_TAB_SIZE; i++) {
408 if (i % 2)
409 regw_lin_tbl(linearize->table[i], ((i >> 1) << 2), 1);
410 else
411 regw_lin_tbl(linearize->table[i], ((i >> 1) << 2), 0);
412 }
413}
414
415static int isif_config_dfc(struct isif_dfc *vdfc)
416{
417 /* initialize retries to loop for max ~ 250 usec */
418 u32 val, count, retries = loops_per_jiffy / (4000/HZ);
419 int i;
420
421 if (!vdfc->en)
422 return 0;
423
424 /* Correction mode */
425 val = (vdfc->corr_mode << ISIF_VDFC_CORR_MOD_SHIFT);
426
427 /* Correct whole line or partial */
428 if (vdfc->corr_whole_line)
429 val |= 1 << ISIF_VDFC_CORR_WHOLE_LN_SHIFT;
430
431 /* level shift value */
432 val |= vdfc->def_level_shift << ISIF_VDFC_LEVEL_SHFT_SHIFT;
433
434 regw(val, DFCCTL);
435
436 /* Defect saturation level */
437 regw(vdfc->def_sat_level, VDFSATLV);
438
439 regw(vdfc->table[0].pos_vert, DFCMEM0);
440 regw(vdfc->table[0].pos_horz, DFCMEM1);
441 if (vdfc->corr_mode == ISIF_VDFC_NORMAL ||
442 vdfc->corr_mode == ISIF_VDFC_HORZ_INTERPOL_IF_SAT) {
443 regw(vdfc->table[0].level_at_pos, DFCMEM2);
444 regw(vdfc->table[0].level_up_pixels, DFCMEM3);
445 regw(vdfc->table[0].level_low_pixels, DFCMEM4);
446 }
447
448 /* set DFCMARST and set DFCMWR */
449 val = regr(DFCMEMCTL) | (1 << ISIF_DFCMEMCTL_DFCMARST_SHIFT) | 1;
450 regw(val, DFCMEMCTL);
451
452 count = retries;
453 while (count && (regr(DFCMEMCTL) & 0x1))
454 count--;
455
456 if (!count) {
457 dev_dbg(isif_cfg.dev, "defect table write timeout !!!\n");
458 return -1;
459 }
460
461 for (i = 1; i < vdfc->num_vdefects; i++) {
462 regw(vdfc->table[i].pos_vert, DFCMEM0);
463 regw(vdfc->table[i].pos_horz, DFCMEM1);
464 if (vdfc->corr_mode == ISIF_VDFC_NORMAL ||
465 vdfc->corr_mode == ISIF_VDFC_HORZ_INTERPOL_IF_SAT) {
466 regw(vdfc->table[i].level_at_pos, DFCMEM2);
467 regw(vdfc->table[i].level_up_pixels, DFCMEM3);
468 regw(vdfc->table[i].level_low_pixels, DFCMEM4);
469 }
470 val = regr(DFCMEMCTL);
471 /* clear DFCMARST and set DFCMWR */
472 val &= ~BIT(ISIF_DFCMEMCTL_DFCMARST_SHIFT);
473 val |= 1;
474 regw(val, DFCMEMCTL);
475
476 count = retries;
477 while (count && (regr(DFCMEMCTL) & 0x1))
478 count--;
479
480 if (!count) {
481 dev_err(isif_cfg.dev,
482 "defect table write timeout !!!\n");
483 return -1;
484 }
485 }
486 if (vdfc->num_vdefects < ISIF_VDFC_TABLE_SIZE) {
487 /* Extra cycle needed */
488 regw(0, DFCMEM0);
489 regw(0x1FFF, DFCMEM1);
490 regw(1, DFCMEMCTL);
491 }
492
493 /* enable VDFC */
494 reg_modify((1 << ISIF_VDFC_EN_SHIFT), (1 << ISIF_VDFC_EN_SHIFT),
495 DFCCTL);
496 return 0;
497}
498
499static void isif_config_csc(struct isif_df_csc *df_csc)
500{
501 u32 val1 = 0, val2 = 0, i;
502
503 if (!df_csc->csc.en) {
504 regw(0, CSCCTL);
505 return;
506 }
507 for (i = 0; i < ISIF_CSC_NUM_COEFF; i++) {
508 if ((i % 2) == 0) {
509 /* CSCM - LSB */
510 val1 = (df_csc->csc.coeff[i].integer <<
511 ISIF_CSC_COEF_INTEG_SHIFT) |
512 df_csc->csc.coeff[i].decimal;
513 } else {
514
515 /* CSCM - MSB */
516 val2 = (df_csc->csc.coeff[i].integer <<
517 ISIF_CSC_COEF_INTEG_SHIFT) |
518 df_csc->csc.coeff[i].decimal;
519 val2 <<= ISIF_CSCM_MSB_SHIFT;
520 val2 |= val1;
521 regw(val2, (CSCM0 + ((i - 1) << 1)));
522 }
523 }
524
525 /* program the active area */
526 regw(df_csc->start_pix, FMTSPH);
527 /*
528 * one extra pixel as required for CSC. Actually number of
529 * pixel - 1 should be configured in this register. So we
530 * need to subtract 1 before writing to FMTSPH, but we will
531 * not do this since csc requires one extra pixel
532 */
533 regw(df_csc->num_pixels, FMTLNH);
534 regw(df_csc->start_line, FMTSLV);
535 /*
536 * one extra line as required for CSC. See reason documented for
537 * num_pixels
538 */
539 regw(df_csc->num_lines, FMTLNV);
540
541 /* Enable CSC */
542 regw(1, CSCCTL);
543}
544
545static int isif_config_raw(void)
546{
547 struct isif_params_raw *params = &isif_cfg.bayer;
548 struct isif_config_params_raw *module_params =
549 &isif_cfg.bayer.config_params;
550 struct vpss_pg_frame_size frame_size;
551 struct vpss_sync_pol sync;
552 u32 val;
553
554 dev_dbg(isif_cfg.dev, "\nStarting isif_config_raw..\n");
555
556 /*
557 * Configure CCDCFG register:-
558 * Set CCD Not to swap input since input is RAW data
559 * Set FID detection function to Latch at V-Sync
560 * Set WENLOG - isif valid area
561 * Set TRGSEL
562 * Set EXTRG
563 * Packed to 8 or 16 bits
564 */
565
566 val = ISIF_YCINSWP_RAW | ISIF_CCDCFG_FIDMD_LATCH_VSYNC |
567 ISIF_CCDCFG_WENLOG_AND | ISIF_CCDCFG_TRGSEL_WEN |
568 ISIF_CCDCFG_EXTRG_DISABLE | isif_cfg.data_pack;
569
570 dev_dbg(isif_cfg.dev, "Writing 0x%x to ...CCDCFG \n", val);
571 regw(val, CCDCFG);
572
573 /*
574 * Configure the vertical sync polarity(MODESET.VDPOL)
575 * Configure the horizontal sync polarity (MODESET.HDPOL)
576 * Configure frame id polarity (MODESET.FLDPOL)
577 * Configure data polarity
578 * Configure External WEN Selection
579 * Configure frame format(progressive or interlace)
580 * Configure pixel format (Input mode)
581 * Configure the data shift
582 */
583
584 val = ISIF_VDHDOUT_INPUT | (params->vd_pol << ISIF_VD_POL_SHIFT) |
585 (params->hd_pol << ISIF_HD_POL_SHIFT) |
586 (params->fid_pol << ISIF_FID_POL_SHIFT) |
587 (ISIF_DATAPOL_NORMAL << ISIF_DATAPOL_SHIFT) |
588 (ISIF_EXWEN_DISABLE << ISIF_EXWEN_SHIFT) |
589 (params->frm_fmt << ISIF_FRM_FMT_SHIFT) |
590 (params->pix_fmt << ISIF_INPUT_SHIFT) |
591 (params->config_params.data_shift << ISIF_DATASFT_SHIFT);
592
593 regw(val, MODESET);
594 dev_dbg(isif_cfg.dev, "Writing 0x%x to MODESET...\n", val);
595
596 /*
597 * Configure GAMMAWD register
598 * CFA pattern setting
599 */
600 val = params->cfa_pat << ISIF_GAMMAWD_CFA_SHIFT;
601
602 /* Gamma msb */
603 if (module_params->compress.alg == ISIF_ALAW)
604 val |= ISIF_ALAW_ENABLE;
605
606 val |= (params->data_msb << ISIF_ALAW_GAMA_WD_SHIFT);
607 regw(val, CGAMMAWD);
608
609 /* Configure DPCM compression settings */
610 if (module_params->compress.alg == ISIF_DPCM) {
611 val = BIT(ISIF_DPCM_EN_SHIFT) |
612 (module_params->compress.pred <<
613 ISIF_DPCM_PREDICTOR_SHIFT);
614 }
615
616 regw(val, MISC);
617
618 /* Configure Gain & Offset */
619 isif_config_gain_offset();
620
621 /* Configure Color pattern */
622 val = (params->config_params.col_pat_field0.olop) |
623 (params->config_params.col_pat_field0.olep << 2) |
624 (params->config_params.col_pat_field0.elop << 4) |
625 (params->config_params.col_pat_field0.elep << 6) |
626 (params->config_params.col_pat_field1.olop << 8) |
627 (params->config_params.col_pat_field1.olep << 10) |
628 (params->config_params.col_pat_field1.elop << 12) |
629 (params->config_params.col_pat_field1.elep << 14);
630 regw(val, CCOLP);
631 dev_dbg(isif_cfg.dev, "Writing %x to CCOLP ...\n", val);
632
633 /* Configure HSIZE register */
634 val = (!!params->horz_flip_en) << ISIF_HSIZE_FLIP_SHIFT;
635
636 /* calculate line offset in 32 bytes based on pack value */
637 if (isif_cfg.data_pack == ISIF_PACK_8BIT)
638 val |= ((params->win.width + 31) >> 5);
639 else if (isif_cfg.data_pack == ISIF_PACK_12BIT)
640 val |= (((params->win.width +
641 (params->win.width >> 2)) + 31) >> 5);
642 else
643 val |= (((params->win.width * 2) + 31) >> 5);
644 regw(val, HSIZE);
645
646 /* Configure SDOFST register */
647 if (params->frm_fmt == CCDC_FRMFMT_INTERLACED) {
648 if (params->image_invert_en) {
649 /* For interlace inverse mode */
650 regw(0x4B6D, SDOFST);
651 dev_dbg(isif_cfg.dev, "Writing 0x4B6D to SDOFST...\n");
652 } else {
653 /* For interlace non inverse mode */
654 regw(0x0B6D, SDOFST);
655 dev_dbg(isif_cfg.dev, "Writing 0x0B6D to SDOFST...\n");
656 }
657 } else if (params->frm_fmt == CCDC_FRMFMT_PROGRESSIVE) {
658 if (params->image_invert_en) {
659 /* For progressive inverse mode */
660 regw(0x4000, SDOFST);
661 dev_dbg(isif_cfg.dev, "Writing 0x4000 to SDOFST...\n");
662 } else {
663 /* For progressive non inverse mode */
664 regw(0x0000, SDOFST);
665 dev_dbg(isif_cfg.dev, "Writing 0x0000 to SDOFST...\n");
666 }
667 }
668
669 /* Configure video window */
670 isif_setwin(&params->win, params->frm_fmt, 1);
671
672 /* Configure Black Clamp */
673 isif_config_bclamp(&module_params->bclamp);
674
675 /* Configure Vertical Defection Pixel Correction */
676 if (isif_config_dfc(&module_params->dfc) < 0)
677 return -EFAULT;
678
679 if (!module_params->df_csc.df_or_csc)
680 /* Configure Color Space Conversion */
681 isif_config_csc(&module_params->df_csc);
682
683 isif_config_linearization(&module_params->linearize);
684
685 /* Configure Culling */
686 isif_config_culling(&module_params->culling);
687
688 /* Configure horizontal and vertical offsets(DFC,LSC,Gain) */
689 regw(module_params->horz_offset, DATAHOFST);
690 regw(module_params->vert_offset, DATAVOFST);
691
692 /* Setup test pattern if enabled */
693 if (params->config_params.test_pat_gen) {
694 /* Use the HD/VD pol settings from user */
695 sync.ccdpg_hdpol = params->hd_pol;
696 sync.ccdpg_vdpol = params->vd_pol;
697 dm365_vpss_set_sync_pol(sync);
698 frame_size.hlpfr = isif_cfg.bayer.win.width;
699 frame_size.pplen = isif_cfg.bayer.win.height;
700 dm365_vpss_set_pg_frame_size(frame_size);
701 vpss_select_ccdc_source(VPSS_PGLPBK);
702 }
703
704 dev_dbg(isif_cfg.dev, "\nEnd of isif_config_ycbcr...\n");
705 return 0;
706}
707
708static int isif_set_buftype(enum ccdc_buftype buf_type)
709{
710 if (isif_cfg.if_type == VPFE_RAW_BAYER)
711 isif_cfg.bayer.buf_type = buf_type;
712 else
713 isif_cfg.ycbcr.buf_type = buf_type;
714
715 return 0;
716
717}
718static enum ccdc_buftype isif_get_buftype(void)
719{
720 if (isif_cfg.if_type == VPFE_RAW_BAYER)
721 return isif_cfg.bayer.buf_type;
722
723 return isif_cfg.ycbcr.buf_type;
724}
725
726static int isif_enum_pix(u32 *pix, int i)
727{
728 int ret = -EINVAL;
729
730 if (isif_cfg.if_type == VPFE_RAW_BAYER) {
731 if (i < ARRAY_SIZE(isif_raw_bayer_pix_formats)) {
732 *pix = isif_raw_bayer_pix_formats[i];
733 ret = 0;
734 }
735 } else {
736 if (i < ARRAY_SIZE(isif_raw_yuv_pix_formats)) {
737 *pix = isif_raw_yuv_pix_formats[i];
738 ret = 0;
739 }
740 }
741
742 return ret;
743}
744
745static int isif_set_pixel_format(unsigned int pixfmt)
746{
747 if (isif_cfg.if_type == VPFE_RAW_BAYER) {
748 if (pixfmt == V4L2_PIX_FMT_SBGGR8) {
749 if ((isif_cfg.bayer.config_params.compress.alg !=
750 ISIF_ALAW) &&
751 (isif_cfg.bayer.config_params.compress.alg !=
752 ISIF_DPCM)) {
753 dev_dbg(isif_cfg.dev,
754 "Either configure A-Law or DPCM\n");
755 return -EINVAL;
756 }
757 isif_cfg.data_pack = ISIF_PACK_8BIT;
758 } else if (pixfmt == V4L2_PIX_FMT_SBGGR16) {
759 isif_cfg.bayer.config_params.compress.alg =
760 ISIF_NO_COMPRESSION;
761 isif_cfg.data_pack = ISIF_PACK_16BIT;
762 } else
763 return -EINVAL;
764 isif_cfg.bayer.pix_fmt = CCDC_PIXFMT_RAW;
765 } else {
766 if (pixfmt == V4L2_PIX_FMT_YUYV)
767 isif_cfg.ycbcr.pix_order = CCDC_PIXORDER_YCBYCR;
768 else if (pixfmt == V4L2_PIX_FMT_UYVY)
769 isif_cfg.ycbcr.pix_order = CCDC_PIXORDER_CBYCRY;
770 else
771 return -EINVAL;
772 isif_cfg.data_pack = ISIF_PACK_8BIT;
773 }
774 return 0;
775}
776
777static u32 isif_get_pixel_format(void)
778{
779 u32 pixfmt;
780
781 if (isif_cfg.if_type == VPFE_RAW_BAYER)
782 if (isif_cfg.bayer.config_params.compress.alg == ISIF_ALAW ||
783 isif_cfg.bayer.config_params.compress.alg == ISIF_DPCM)
784 pixfmt = V4L2_PIX_FMT_SBGGR8;
785 else
786 pixfmt = V4L2_PIX_FMT_SBGGR16;
787 else {
788 if (isif_cfg.ycbcr.pix_order == CCDC_PIXORDER_YCBYCR)
789 pixfmt = V4L2_PIX_FMT_YUYV;
790 else
791 pixfmt = V4L2_PIX_FMT_UYVY;
792 }
793 return pixfmt;
794}
795
796static int isif_set_image_window(struct v4l2_rect *win)
797{
798 if (isif_cfg.if_type == VPFE_RAW_BAYER) {
799 isif_cfg.bayer.win.top = win->top;
800 isif_cfg.bayer.win.left = win->left;
801 isif_cfg.bayer.win.width = win->width;
802 isif_cfg.bayer.win.height = win->height;
803 } else {
804 isif_cfg.ycbcr.win.top = win->top;
805 isif_cfg.ycbcr.win.left = win->left;
806 isif_cfg.ycbcr.win.width = win->width;
807 isif_cfg.ycbcr.win.height = win->height;
808 }
809 return 0;
810}
811
812static void isif_get_image_window(struct v4l2_rect *win)
813{
814 if (isif_cfg.if_type == VPFE_RAW_BAYER)
815 *win = isif_cfg.bayer.win;
816 else
817 *win = isif_cfg.ycbcr.win;
818}
819
820static unsigned int isif_get_line_length(void)
821{
822 unsigned int len;
823
824 if (isif_cfg.if_type == VPFE_RAW_BAYER) {
825 if (isif_cfg.data_pack == ISIF_PACK_8BIT)
826 len = ((isif_cfg.bayer.win.width));
827 else if (isif_cfg.data_pack == ISIF_PACK_12BIT)
828 len = (((isif_cfg.bayer.win.width * 2) +
829 (isif_cfg.bayer.win.width >> 2)));
830 else
831 len = (((isif_cfg.bayer.win.width * 2)));
832 } else
833 len = (((isif_cfg.ycbcr.win.width * 2)));
834 return ALIGN(len, 32);
835}
836
837static int isif_set_frame_format(enum ccdc_frmfmt frm_fmt)
838{
839 if (isif_cfg.if_type == VPFE_RAW_BAYER)
840 isif_cfg.bayer.frm_fmt = frm_fmt;
841 else
842 isif_cfg.ycbcr.frm_fmt = frm_fmt;
843 return 0;
844}
845static enum ccdc_frmfmt isif_get_frame_format(void)
846{
847 if (isif_cfg.if_type == VPFE_RAW_BAYER)
848 return isif_cfg.bayer.frm_fmt;
849 return isif_cfg.ycbcr.frm_fmt;
850}
851
852static int isif_getfid(void)
853{
854 return (regr(MODESET) >> 15) & 0x1;
855}
856
857/* misc operations */
858static void isif_setfbaddr(unsigned long addr)
859{
860 regw((addr >> 21) & 0x07ff, CADU);
861 regw((addr >> 5) & 0x0ffff, CADL);
862}
863
864static int isif_set_hw_if_params(struct vpfe_hw_if_param *params)
865{
866 isif_cfg.if_type = params->if_type;
867
868 switch (params->if_type) {
869 case VPFE_BT656:
870 case VPFE_BT656_10BIT:
871 case VPFE_YCBCR_SYNC_8:
872 isif_cfg.ycbcr.pix_fmt = CCDC_PIXFMT_YCBCR_8BIT;
873 isif_cfg.ycbcr.pix_order = CCDC_PIXORDER_CBYCRY;
874 break;
875 case VPFE_BT1120:
876 case VPFE_YCBCR_SYNC_16:
877 isif_cfg.ycbcr.pix_fmt = CCDC_PIXFMT_YCBCR_16BIT;
878 isif_cfg.ycbcr.pix_order = CCDC_PIXORDER_CBYCRY;
879 break;
880 case VPFE_RAW_BAYER:
881 isif_cfg.bayer.pix_fmt = CCDC_PIXFMT_RAW;
882 break;
883 default:
884 dev_dbg(isif_cfg.dev, "Invalid interface type\n");
885 return -EINVAL;
886 }
887
888 return 0;
889}
890
891/* This function will configure ISIF for YCbCr parameters. */
892static int isif_config_ycbcr(void)
893{
894 struct isif_ycbcr_config *params = &isif_cfg.ycbcr;
895 struct vpss_pg_frame_size frame_size;
896 u32 modeset = 0, ccdcfg = 0;
897 struct vpss_sync_pol sync;
898
899 dev_dbg(isif_cfg.dev, "\nStarting isif_config_ycbcr...");
900
901 /* configure pixel format or input mode */
902 modeset = modeset | (params->pix_fmt << ISIF_INPUT_SHIFT) |
903 (params->frm_fmt << ISIF_FRM_FMT_SHIFT) |
904 (params->fid_pol << ISIF_FID_POL_SHIFT) |
905 (params->hd_pol << ISIF_HD_POL_SHIFT) |
906 (params->vd_pol << ISIF_VD_POL_SHIFT);
907
908 /* pack the data to 8-bit ISIFCFG */
909 switch (isif_cfg.if_type) {
910 case VPFE_BT656:
911 if (params->pix_fmt != CCDC_PIXFMT_YCBCR_8BIT) {
912 dev_dbg(isif_cfg.dev, "Invalid pix_fmt(input mode)\n");
913 return -EINVAL;
914 }
915 modeset |= (VPFE_PINPOL_NEGATIVE << ISIF_VD_POL_SHIFT);
916 regw(3, REC656IF);
917 ccdcfg = ccdcfg | ISIF_DATA_PACK8 | ISIF_YCINSWP_YCBCR;
918 break;
919 case VPFE_BT656_10BIT:
920 if (params->pix_fmt != CCDC_PIXFMT_YCBCR_8BIT) {
921 dev_dbg(isif_cfg.dev, "Invalid pix_fmt(input mode)\n");
922 return -EINVAL;
923 }
924 /* setup BT.656, embedded sync */
925 regw(3, REC656IF);
926 /* enable 10 bit mode in ccdcfg */
927 ccdcfg = ccdcfg | ISIF_DATA_PACK8 | ISIF_YCINSWP_YCBCR |
928 ISIF_BW656_ENABLE;
929 break;
930 case VPFE_BT1120:
931 if (params->pix_fmt != CCDC_PIXFMT_YCBCR_16BIT) {
932 dev_dbg(isif_cfg.dev, "Invalid pix_fmt(input mode)\n");
933 return -EINVAL;
934 }
935 regw(3, REC656IF);
936 break;
937
938 case VPFE_YCBCR_SYNC_8:
939 ccdcfg |= ISIF_DATA_PACK8;
940 ccdcfg |= ISIF_YCINSWP_YCBCR;
941 if (params->pix_fmt != CCDC_PIXFMT_YCBCR_8BIT) {
942 dev_dbg(isif_cfg.dev, "Invalid pix_fmt(input mode)\n");
943 return -EINVAL;
944 }
945 break;
946 case VPFE_YCBCR_SYNC_16:
947 if (params->pix_fmt != CCDC_PIXFMT_YCBCR_16BIT) {
948 dev_dbg(isif_cfg.dev, "Invalid pix_fmt(input mode)\n");
949 return -EINVAL;
950 }
951 break;
952 default:
953 /* should never come here */
954 dev_dbg(isif_cfg.dev, "Invalid interface type\n");
955 return -EINVAL;
956 }
957
958 regw(modeset, MODESET);
959
960 /* Set up pix order */
961 ccdcfg |= params->pix_order << ISIF_PIX_ORDER_SHIFT;
962
963 regw(ccdcfg, CCDCFG);
964
965 /* configure video window */
966 if ((isif_cfg.if_type == VPFE_BT1120) ||
967 (isif_cfg.if_type == VPFE_YCBCR_SYNC_16))
968 isif_setwin(&params->win, params->frm_fmt, 1);
969 else
970 isif_setwin(&params->win, params->frm_fmt, 2);
971
972 /*
973 * configure the horizontal line offset
974 * this is done by rounding up width to a multiple of 16 pixels
975 * and multiply by two to account for y:cb:cr 4:2:2 data
976 */
977 regw(((((params->win.width * 2) + 31) & 0xffffffe0) >> 5), HSIZE);
978
979 /* configure the memory line offset */
980 if ((params->frm_fmt == CCDC_FRMFMT_INTERLACED) &&
981 (params->buf_type == CCDC_BUFTYPE_FLD_INTERLEAVED))
982 /* two fields are interleaved in memory */
983 regw(0x00000249, SDOFST);
984
985 /* Setup test pattern if enabled */
986 if (isif_cfg.bayer.config_params.test_pat_gen) {
987 sync.ccdpg_hdpol = params->hd_pol;
988 sync.ccdpg_vdpol = params->vd_pol;
989 dm365_vpss_set_sync_pol(sync);
990 dm365_vpss_set_pg_frame_size(frame_size);
991 }
992 return 0;
993}
994
995static int isif_configure(void)
996{
997 if (isif_cfg.if_type == VPFE_RAW_BAYER)
998 return isif_config_raw();
999 return isif_config_ycbcr();
1000}
1001
1002static int isif_close(struct device *device)
1003{
1004 /* copy defaults to module params */
1005 isif_cfg.bayer.config_params = isif_config_defaults;
1006 return 0;
1007}
1008
1009static struct ccdc_hw_device isif_hw_dev = {
1010 .name = "ISIF",
1011 .owner = THIS_MODULE,
1012 .hw_ops = {
1013 .open = isif_open,
1014 .close = isif_close,
1015 .enable = isif_enable,
1016 .enable_out_to_sdram = isif_enable_output_to_sdram,
1017 .set_hw_if_params = isif_set_hw_if_params,
1018 .configure = isif_configure,
1019 .set_buftype = isif_set_buftype,
1020 .get_buftype = isif_get_buftype,
1021 .enum_pix = isif_enum_pix,
1022 .set_pixel_format = isif_set_pixel_format,
1023 .get_pixel_format = isif_get_pixel_format,
1024 .set_frame_format = isif_set_frame_format,
1025 .get_frame_format = isif_get_frame_format,
1026 .set_image_window = isif_set_image_window,
1027 .get_image_window = isif_get_image_window,
1028 .get_line_length = isif_get_line_length,
1029 .setfbaddr = isif_setfbaddr,
1030 .getfid = isif_getfid,
1031 },
1032};
1033
1034static int __init isif_probe(struct platform_device *pdev)
1035{
1036 void (*setup_pinmux)(void);
1037 struct resource *res;
1038 void *__iomem addr;
1039 int status = 0, i;
1040
1041 /*
1042 * first try to register with vpfe. If not correct platform, then we
1043 * don't have to iomap
1044 */
1045 status = vpfe_register_ccdc_device(&isif_hw_dev);
1046 if (status < 0)
1047 return status;
1048
1049 /* Get and enable Master clock */
1050 isif_cfg.mclk = clk_get(&pdev->dev, "master");
1051 if (IS_ERR(isif_cfg.mclk)) {
1052 status = PTR_ERR(isif_cfg.mclk);
1053 goto fail_mclk;
1054 }
1055 if (clk_enable(isif_cfg.mclk)) {
1056 status = -ENODEV;
1057 goto fail_mclk;
1058 }
1059
1060 /* Platform data holds setup_pinmux function ptr */
1061 if (NULL == pdev->dev.platform_data) {
1062 status = -ENODEV;
1063 goto fail_mclk;
1064 }
1065 setup_pinmux = pdev->dev.platform_data;
1066 /*
1067 * setup Mux configuration for ccdc which may be different for
1068 * different SoCs using this CCDC
1069 */
1070 setup_pinmux();
1071
1072 i = 0;
1073 /* Get the ISIF base address, linearization table0 and table1 addr. */
1074 while (i < 3) {
1075 res = platform_get_resource(pdev, IORESOURCE_MEM, i);
1076 if (!res) {
1077 status = -ENODEV;
1078 goto fail_nobase_res;
1079 }
1080 res = request_mem_region(res->start, resource_size(res),
1081 res->name);
1082 if (!res) {
1083 status = -EBUSY;
1084 goto fail_nobase_res;
1085 }
1086 addr = ioremap_nocache(res->start, resource_size(res));
1087 if (!addr) {
1088 status = -ENOMEM;
1089 goto fail_base_iomap;
1090 }
1091 switch (i) {
1092 case 0:
1093 /* ISIF base address */
1094 isif_cfg.base_addr = addr;
1095 break;
1096 case 1:
1097 /* ISIF linear tbl0 address */
1098 isif_cfg.linear_tbl0_addr = addr;
1099 break;
1100 default:
1101 /* ISIF linear tbl0 address */
1102 isif_cfg.linear_tbl1_addr = addr;
1103 break;
1104 }
1105 i++;
1106 }
1107 isif_cfg.dev = &pdev->dev;
1108
1109 printk(KERN_NOTICE "%s is registered with vpfe.\n",
1110 isif_hw_dev.name);
1111 return 0;
1112fail_base_iomap:
1113 release_mem_region(res->start, resource_size(res));
1114 i--;
1115fail_nobase_res:
1116 if (isif_cfg.base_addr)
1117 iounmap(isif_cfg.base_addr);
1118 if (isif_cfg.linear_tbl0_addr)
1119 iounmap(isif_cfg.linear_tbl0_addr);
1120
1121 while (i >= 0) {
1122 res = platform_get_resource(pdev, IORESOURCE_MEM, i);
1123 release_mem_region(res->start, resource_size(res));
1124 i--;
1125 }
1126fail_mclk:
1127 clk_put(isif_cfg.mclk);
1128 vpfe_unregister_ccdc_device(&isif_hw_dev);
1129 return status;
1130}
1131
1132static int isif_remove(struct platform_device *pdev)
1133{
1134 struct resource *res;
1135 int i = 0;
1136
1137 iounmap(isif_cfg.base_addr);
1138 iounmap(isif_cfg.linear_tbl0_addr);
1139 iounmap(isif_cfg.linear_tbl1_addr);
1140 while (i < 3) {
1141 res = platform_get_resource(pdev, IORESOURCE_MEM, i);
1142 if (res)
1143 release_mem_region(res->start, resource_size(res));
1144 i++;
1145 }
1146 vpfe_unregister_ccdc_device(&isif_hw_dev);
1147 return 0;
1148}
1149
1150static struct platform_driver isif_driver = {
1151 .driver = {
1152 .name = "isif",
1153 .owner = THIS_MODULE,
1154 },
1155 .remove = __devexit_p(isif_remove),
1156 .probe = isif_probe,
1157};
1158
1159static int __init isif_init(void)
1160{
1161 return platform_driver_register(&isif_driver);
1162}
1163
1164static void isif_exit(void)
1165{
1166 platform_driver_unregister(&isif_driver);
1167}
1168
1169module_init(isif_init);
1170module_exit(isif_exit);
1171
1172MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/davinci/isif_regs.h b/drivers/media/video/davinci/isif_regs.h
new file mode 100644
index 000000000000..f7b8893a2957
--- /dev/null
+++ b/drivers/media/video/davinci/isif_regs.h
@@ -0,0 +1,269 @@
1/*
2 * Copyright (C) 2008-2009 Texas Instruments Inc
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 */
18#ifndef _ISIF_REGS_H
19#define _ISIF_REGS_H
20
21/* ISIF registers relative offsets */
22#define SYNCEN 0x00
23#define MODESET 0x04
24#define HDW 0x08
25#define VDW 0x0c
26#define PPLN 0x10
27#define LPFR 0x14
28#define SPH 0x18
29#define LNH 0x1c
30#define SLV0 0x20
31#define SLV1 0x24
32#define LNV 0x28
33#define CULH 0x2c
34#define CULV 0x30
35#define HSIZE 0x34
36#define SDOFST 0x38
37#define CADU 0x3c
38#define CADL 0x40
39#define LINCFG0 0x44
40#define LINCFG1 0x48
41#define CCOLP 0x4c
42#define CRGAIN 0x50
43#define CGRGAIN 0x54
44#define CGBGAIN 0x58
45#define CBGAIN 0x5c
46#define COFSTA 0x60
47#define FLSHCFG0 0x64
48#define FLSHCFG1 0x68
49#define FLSHCFG2 0x6c
50#define VDINT0 0x70
51#define VDINT1 0x74
52#define VDINT2 0x78
53#define MISC 0x7c
54#define CGAMMAWD 0x80
55#define REC656IF 0x84
56#define CCDCFG 0x88
57/*****************************************************
58* Defect Correction registers
59*****************************************************/
60#define DFCCTL 0x8c
61#define VDFSATLV 0x90
62#define DFCMEMCTL 0x94
63#define DFCMEM0 0x98
64#define DFCMEM1 0x9c
65#define DFCMEM2 0xa0
66#define DFCMEM3 0xa4
67#define DFCMEM4 0xa8
68/****************************************************
69* Black Clamp registers
70****************************************************/
71#define CLAMPCFG 0xac
72#define CLDCOFST 0xb0
73#define CLSV 0xb4
74#define CLHWIN0 0xb8
75#define CLHWIN1 0xbc
76#define CLHWIN2 0xc0
77#define CLVRV 0xc4
78#define CLVWIN0 0xc8
79#define CLVWIN1 0xcc
80#define CLVWIN2 0xd0
81#define CLVWIN3 0xd4
82/****************************************************
83* Lense Shading Correction
84****************************************************/
85#define DATAHOFST 0xd8
86#define DATAVOFST 0xdc
87#define LSCHVAL 0xe0
88#define LSCVVAL 0xe4
89#define TWODLSCCFG 0xe8
90#define TWODLSCOFST 0xec
91#define TWODLSCINI 0xf0
92#define TWODLSCGRBU 0xf4
93#define TWODLSCGRBL 0xf8
94#define TWODLSCGROF 0xfc
95#define TWODLSCORBU 0x100
96#define TWODLSCORBL 0x104
97#define TWODLSCOROF 0x108
98#define TWODLSCIRQEN 0x10c
99#define TWODLSCIRQST 0x110
100/****************************************************
101* Data formatter
102****************************************************/
103#define FMTCFG 0x114
104#define FMTPLEN 0x118
105#define FMTSPH 0x11c
106#define FMTLNH 0x120
107#define FMTSLV 0x124
108#define FMTLNV 0x128
109#define FMTRLEN 0x12c
110#define FMTHCNT 0x130
111#define FMTAPTR_BASE 0x134
112/* Below macro for addresses FMTAPTR0 - FMTAPTR15 */
113#define FMTAPTR(i) (FMTAPTR_BASE + (i * 4))
114#define FMTPGMVF0 0x174
115#define FMTPGMVF1 0x178
116#define FMTPGMAPU0 0x17c
117#define FMTPGMAPU1 0x180
118#define FMTPGMAPS0 0x184
119#define FMTPGMAPS1 0x188
120#define FMTPGMAPS2 0x18c
121#define FMTPGMAPS3 0x190
122#define FMTPGMAPS4 0x194
123#define FMTPGMAPS5 0x198
124#define FMTPGMAPS6 0x19c
125#define FMTPGMAPS7 0x1a0
126/************************************************
127* Color Space Converter
128************************************************/
129#define CSCCTL 0x1a4
130#define CSCM0 0x1a8
131#define CSCM1 0x1ac
132#define CSCM2 0x1b0
133#define CSCM3 0x1b4
134#define CSCM4 0x1b8
135#define CSCM5 0x1bc
136#define CSCM6 0x1c0
137#define CSCM7 0x1c4
138#define OBWIN0 0x1c8
139#define OBWIN1 0x1cc
140#define OBWIN2 0x1d0
141#define OBWIN3 0x1d4
142#define OBVAL0 0x1d8
143#define OBVAL1 0x1dc
144#define OBVAL2 0x1e0
145#define OBVAL3 0x1e4
146#define OBVAL4 0x1e8
147#define OBVAL5 0x1ec
148#define OBVAL6 0x1f0
149#define OBVAL7 0x1f4
150#define CLKCTL 0x1f8
151
152/* Masks & Shifts below */
153#define START_PX_HOR_MASK 0x7FFF
154#define NUM_PX_HOR_MASK 0x7FFF
155#define START_VER_ONE_MASK 0x7FFF
156#define START_VER_TWO_MASK 0x7FFF
157#define NUM_LINES_VER 0x7FFF
158
159/* gain - offset masks */
160#define GAIN_INTEGER_SHIFT 9
161#define OFFSET_MASK 0xFFF
162#define GAIN_SDRAM_EN_SHIFT 12
163#define GAIN_IPIPE_EN_SHIFT 13
164#define GAIN_H3A_EN_SHIFT 14
165#define OFST_SDRAM_EN_SHIFT 8
166#define OFST_IPIPE_EN_SHIFT 9
167#define OFST_H3A_EN_SHIFT 10
168#define GAIN_OFFSET_EN_MASK 0x7700
169
170/* Culling */
171#define CULL_PAT_EVEN_LINE_SHIFT 8
172
173/* CCDCFG register */
174#define ISIF_YCINSWP_RAW (0x00 << 4)
175#define ISIF_YCINSWP_YCBCR (0x01 << 4)
176#define ISIF_CCDCFG_FIDMD_LATCH_VSYNC (0x00 << 6)
177#define ISIF_CCDCFG_WENLOG_AND (0x00 << 8)
178#define ISIF_CCDCFG_TRGSEL_WEN (0x00 << 9)
179#define ISIF_CCDCFG_EXTRG_DISABLE (0x00 << 10)
180#define ISIF_LATCH_ON_VSYNC_DISABLE (0x01 << 15)
181#define ISIF_LATCH_ON_VSYNC_ENABLE (0x00 << 15)
182#define ISIF_DATA_PACK_MASK 3
183#define ISIF_DATA_PACK16 0
184#define ISIF_DATA_PACK12 1
185#define ISIF_DATA_PACK8 2
186#define ISIF_PIX_ORDER_SHIFT 11
187#define ISIF_BW656_ENABLE (0x01 << 5)
188
189/* MODESET registers */
190#define ISIF_VDHDOUT_INPUT (0x00 << 0)
191#define ISIF_INPUT_SHIFT 12
192#define ISIF_RAW_INPUT_MODE 0
193#define ISIF_FID_POL_SHIFT 4
194#define ISIF_HD_POL_SHIFT 3
195#define ISIF_VD_POL_SHIFT 2
196#define ISIF_DATAPOL_NORMAL 0
197#define ISIF_DATAPOL_SHIFT 6
198#define ISIF_EXWEN_DISABLE 0
199#define ISIF_EXWEN_SHIFT 5
200#define ISIF_FRM_FMT_SHIFT 7
201#define ISIF_DATASFT_SHIFT 8
202#define ISIF_LPF_SHIFT 14
203#define ISIF_LPF_MASK 1
204
205/* GAMMAWD registers */
206#define ISIF_ALAW_GAMA_WD_MASK 0xF
207#define ISIF_ALAW_GAMA_WD_SHIFT 1
208#define ISIF_ALAW_ENABLE 1
209#define ISIF_GAMMAWD_CFA_SHIFT 5
210
211/* HSIZE registers */
212#define ISIF_HSIZE_FLIP_MASK 1
213#define ISIF_HSIZE_FLIP_SHIFT 12
214
215/* MISC registers */
216#define ISIF_DPCM_EN_SHIFT 12
217#define ISIF_DPCM_PREDICTOR_SHIFT 13
218
219/* Black clamp related */
220#define ISIF_BC_MODE_COLOR_SHIFT 4
221#define ISIF_HORZ_BC_MODE_SHIFT 1
222#define ISIF_HORZ_BC_WIN_SEL_SHIFT 5
223#define ISIF_HORZ_BC_PIX_LIMIT_SHIFT 6
224#define ISIF_HORZ_BC_WIN_H_SIZE_SHIFT 8
225#define ISIF_HORZ_BC_WIN_V_SIZE_SHIFT 12
226#define ISIF_VERT_BC_RST_VAL_SEL_SHIFT 4
227#define ISIF_VERT_BC_LINE_AVE_COEF_SHIFT 8
228
229/* VDFC registers */
230#define ISIF_VDFC_EN_SHIFT 4
231#define ISIF_VDFC_CORR_MOD_SHIFT 5
232#define ISIF_VDFC_CORR_WHOLE_LN_SHIFT 7
233#define ISIF_VDFC_LEVEL_SHFT_SHIFT 8
234#define ISIF_VDFC_POS_MASK 0x1FFF
235#define ISIF_DFCMEMCTL_DFCMARST_SHIFT 2
236
237/* CSC registers */
238#define ISIF_CSC_COEF_INTEG_MASK 7
239#define ISIF_CSC_COEF_DECIMAL_MASK 0x1f
240#define ISIF_CSC_COEF_INTEG_SHIFT 5
241#define ISIF_CSCM_MSB_SHIFT 8
242#define ISIF_DF_CSC_SPH_MASK 0x1FFF
243#define ISIF_DF_CSC_LNH_MASK 0x1FFF
244#define ISIF_DF_CSC_SLV_MASK 0x1FFF
245#define ISIF_DF_CSC_LNV_MASK 0x1FFF
246#define ISIF_DF_NUMLINES 0x7FFF
247#define ISIF_DF_NUMPIX 0x1FFF
248
249/* Offsets for LSC/DFC/Gain */
250#define ISIF_DATA_H_OFFSET_MASK 0x1FFF
251#define ISIF_DATA_V_OFFSET_MASK 0x1FFF
252
253/* Linearization */
254#define ISIF_LIN_CORRSFT_SHIFT 4
255#define ISIF_LIN_SCALE_FACT_INTEG_SHIFT 10
256
257
258/* Pattern registers */
259#define ISIF_PG_EN (1 << 3)
260#define ISIF_SEL_PG_SRC (3 << 4)
261#define ISIF_PG_VD_POL_SHIFT 0
262#define ISIF_PG_HD_POL_SHIFT 1
263
264/*random other junk*/
265#define ISIF_SYNCEN_VDHDEN_MASK (1 << 0)
266#define ISIF_SYNCEN_WEN_MASK (1 << 1)
267#define ISIF_SYNCEN_WEN_SHIFT 1
268
269#endif
diff --git a/drivers/media/video/davinci/vpfe_capture.c b/drivers/media/video/davinci/vpfe_capture.c
index de22bc9faf21..885cd54499cf 100644
--- a/drivers/media/video/davinci/vpfe_capture.c
+++ b/drivers/media/video/davinci/vpfe_capture.c
@@ -107,9 +107,6 @@ struct ccdc_config {
107 int vpfe_probed; 107 int vpfe_probed;
108 /* name of ccdc device */ 108 /* name of ccdc device */
109 char name[32]; 109 char name[32];
110 /* for storing mem maps for CCDC */
111 int ccdc_addr_size;
112 void *__iomem ccdc_addr;
113}; 110};
114 111
115/* data structures */ 112/* data structures */
@@ -229,7 +226,6 @@ int vpfe_register_ccdc_device(struct ccdc_hw_device *dev)
229 BUG_ON(!dev->hw_ops.set_image_window); 226 BUG_ON(!dev->hw_ops.set_image_window);
230 BUG_ON(!dev->hw_ops.get_image_window); 227 BUG_ON(!dev->hw_ops.get_image_window);
231 BUG_ON(!dev->hw_ops.get_line_length); 228 BUG_ON(!dev->hw_ops.get_line_length);
232 BUG_ON(!dev->hw_ops.setfbaddr);
233 BUG_ON(!dev->hw_ops.getfid); 229 BUG_ON(!dev->hw_ops.getfid);
234 230
235 mutex_lock(&ccdc_lock); 231 mutex_lock(&ccdc_lock);
@@ -240,25 +236,23 @@ int vpfe_register_ccdc_device(struct ccdc_hw_device *dev)
240 * walk through it during vpfe probe 236 * walk through it during vpfe probe
241 */ 237 */
242 printk(KERN_ERR "vpfe capture not initialized\n"); 238 printk(KERN_ERR "vpfe capture not initialized\n");
243 ret = -1; 239 ret = -EFAULT;
244 goto unlock; 240 goto unlock;
245 } 241 }
246 242
247 if (strcmp(dev->name, ccdc_cfg->name)) { 243 if (strcmp(dev->name, ccdc_cfg->name)) {
248 /* ignore this ccdc */ 244 /* ignore this ccdc */
249 ret = -1; 245 ret = -EINVAL;
250 goto unlock; 246 goto unlock;
251 } 247 }
252 248
253 if (ccdc_dev) { 249 if (ccdc_dev) {
254 printk(KERN_ERR "ccdc already registered\n"); 250 printk(KERN_ERR "ccdc already registered\n");
255 ret = -1; 251 ret = -EINVAL;
256 goto unlock; 252 goto unlock;
257 } 253 }
258 254
259 ccdc_dev = dev; 255 ccdc_dev = dev;
260 dev->hw_ops.set_ccdc_base(ccdc_cfg->ccdc_addr,
261 ccdc_cfg->ccdc_addr_size);
262unlock: 256unlock:
263 mutex_unlock(&ccdc_lock); 257 mutex_unlock(&ccdc_lock);
264 return ret; 258 return ret;
@@ -1786,61 +1780,6 @@ static struct vpfe_device *vpfe_initialize(void)
1786 return vpfe_dev; 1780 return vpfe_dev;
1787} 1781}
1788 1782
1789static void vpfe_disable_clock(struct vpfe_device *vpfe_dev)
1790{
1791 struct vpfe_config *vpfe_cfg = vpfe_dev->cfg;
1792
1793 clk_disable(vpfe_cfg->vpssclk);
1794 clk_put(vpfe_cfg->vpssclk);
1795 clk_disable(vpfe_cfg->slaveclk);
1796 clk_put(vpfe_cfg->slaveclk);
1797 v4l2_info(vpfe_dev->pdev->driver,
1798 "vpfe vpss master & slave clocks disabled\n");
1799}
1800
1801static int vpfe_enable_clock(struct vpfe_device *vpfe_dev)
1802{
1803 struct vpfe_config *vpfe_cfg = vpfe_dev->cfg;
1804 int ret = -ENOENT;
1805
1806 vpfe_cfg->vpssclk = clk_get(vpfe_dev->pdev, "vpss_master");
1807 if (NULL == vpfe_cfg->vpssclk) {
1808 v4l2_err(vpfe_dev->pdev->driver, "No clock defined for"
1809 "vpss_master\n");
1810 return ret;
1811 }
1812
1813 if (clk_enable(vpfe_cfg->vpssclk)) {
1814 v4l2_err(vpfe_dev->pdev->driver,
1815 "vpfe vpss master clock not enabled\n");
1816 goto out;
1817 }
1818 v4l2_info(vpfe_dev->pdev->driver,
1819 "vpfe vpss master clock enabled\n");
1820
1821 vpfe_cfg->slaveclk = clk_get(vpfe_dev->pdev, "vpss_slave");
1822 if (NULL == vpfe_cfg->slaveclk) {
1823 v4l2_err(vpfe_dev->pdev->driver,
1824 "No clock defined for vpss slave\n");
1825 goto out;
1826 }
1827
1828 if (clk_enable(vpfe_cfg->slaveclk)) {
1829 v4l2_err(vpfe_dev->pdev->driver,
1830 "vpfe vpss slave clock not enabled\n");
1831 goto out;
1832 }
1833 v4l2_info(vpfe_dev->pdev->driver, "vpfe vpss slave clock enabled\n");
1834 return 0;
1835out:
1836 if (vpfe_cfg->vpssclk)
1837 clk_put(vpfe_cfg->vpssclk);
1838 if (vpfe_cfg->slaveclk)
1839 clk_put(vpfe_cfg->slaveclk);
1840
1841 return -1;
1842}
1843
1844/* 1783/*
1845 * vpfe_probe : This function creates device entries by register 1784 * vpfe_probe : This function creates device entries by register
1846 * itself to the V4L2 driver and initializes fields of each 1785 * itself to the V4L2 driver and initializes fields of each
@@ -1870,7 +1809,7 @@ static __init int vpfe_probe(struct platform_device *pdev)
1870 1809
1871 if (NULL == pdev->dev.platform_data) { 1810 if (NULL == pdev->dev.platform_data) {
1872 v4l2_err(pdev->dev.driver, "Unable to get vpfe config\n"); 1811 v4l2_err(pdev->dev.driver, "Unable to get vpfe config\n");
1873 ret = -ENOENT; 1812 ret = -ENODEV;
1874 goto probe_free_dev_mem; 1813 goto probe_free_dev_mem;
1875 } 1814 }
1876 1815
@@ -1884,18 +1823,13 @@ static __init int vpfe_probe(struct platform_device *pdev)
1884 goto probe_free_dev_mem; 1823 goto probe_free_dev_mem;
1885 } 1824 }
1886 1825
1887 /* enable vpss clocks */
1888 ret = vpfe_enable_clock(vpfe_dev);
1889 if (ret)
1890 goto probe_free_dev_mem;
1891
1892 mutex_lock(&ccdc_lock); 1826 mutex_lock(&ccdc_lock);
1893 /* Allocate memory for ccdc configuration */ 1827 /* Allocate memory for ccdc configuration */
1894 ccdc_cfg = kmalloc(sizeof(struct ccdc_config), GFP_KERNEL); 1828 ccdc_cfg = kmalloc(sizeof(struct ccdc_config), GFP_KERNEL);
1895 if (NULL == ccdc_cfg) { 1829 if (NULL == ccdc_cfg) {
1896 v4l2_err(pdev->dev.driver, 1830 v4l2_err(pdev->dev.driver,
1897 "Memory allocation failed for ccdc_cfg\n"); 1831 "Memory allocation failed for ccdc_cfg\n");
1898 goto probe_disable_clock; 1832 goto probe_free_dev_mem;
1899 } 1833 }
1900 1834
1901 strncpy(ccdc_cfg->name, vpfe_cfg->ccdc, 32); 1835 strncpy(ccdc_cfg->name, vpfe_cfg->ccdc, 32);
@@ -1904,61 +1838,34 @@ static __init int vpfe_probe(struct platform_device *pdev)
1904 if (!res1) { 1838 if (!res1) {
1905 v4l2_err(pdev->dev.driver, 1839 v4l2_err(pdev->dev.driver,
1906 "Unable to get interrupt for VINT0\n"); 1840 "Unable to get interrupt for VINT0\n");
1907 ret = -ENOENT; 1841 ret = -ENODEV;
1908 goto probe_disable_clock; 1842 goto probe_free_ccdc_cfg_mem;
1909 } 1843 }
1910 vpfe_dev->ccdc_irq0 = res1->start; 1844 vpfe_dev->ccdc_irq0 = res1->start;
1911 1845
1912 /* Get VINT1 irq resource */ 1846 /* Get VINT1 irq resource */
1913 res1 = platform_get_resource(pdev, 1847 res1 = platform_get_resource(pdev, IORESOURCE_IRQ, 1);
1914 IORESOURCE_IRQ, 1);
1915 if (!res1) { 1848 if (!res1) {
1916 v4l2_err(pdev->dev.driver, 1849 v4l2_err(pdev->dev.driver,
1917 "Unable to get interrupt for VINT1\n"); 1850 "Unable to get interrupt for VINT1\n");
1918 ret = -ENOENT; 1851 ret = -ENODEV;
1919 goto probe_disable_clock; 1852 goto probe_free_ccdc_cfg_mem;
1920 } 1853 }
1921 vpfe_dev->ccdc_irq1 = res1->start; 1854 vpfe_dev->ccdc_irq1 = res1->start;
1922 1855
1923 /* Get address base of CCDC */
1924 res1 = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1925 if (!res1) {
1926 v4l2_err(pdev->dev.driver,
1927 "Unable to get register address map\n");
1928 ret = -ENOENT;
1929 goto probe_disable_clock;
1930 }
1931
1932 ccdc_cfg->ccdc_addr_size = res1->end - res1->start + 1;
1933 if (!request_mem_region(res1->start, ccdc_cfg->ccdc_addr_size,
1934 pdev->dev.driver->name)) {
1935 v4l2_err(pdev->dev.driver,
1936 "Failed request_mem_region for ccdc base\n");
1937 ret = -ENXIO;
1938 goto probe_disable_clock;
1939 }
1940 ccdc_cfg->ccdc_addr = ioremap_nocache(res1->start,
1941 ccdc_cfg->ccdc_addr_size);
1942 if (!ccdc_cfg->ccdc_addr) {
1943 v4l2_err(pdev->dev.driver, "Unable to ioremap ccdc addr\n");
1944 ret = -ENXIO;
1945 goto probe_out_release_mem1;
1946 }
1947
1948 ret = request_irq(vpfe_dev->ccdc_irq0, vpfe_isr, IRQF_DISABLED, 1856 ret = request_irq(vpfe_dev->ccdc_irq0, vpfe_isr, IRQF_DISABLED,
1949 "vpfe_capture0", vpfe_dev); 1857 "vpfe_capture0", vpfe_dev);
1950 1858
1951 if (0 != ret) { 1859 if (0 != ret) {
1952 v4l2_err(pdev->dev.driver, "Unable to request interrupt\n"); 1860 v4l2_err(pdev->dev.driver, "Unable to request interrupt\n");
1953 goto probe_out_unmap1; 1861 goto probe_free_ccdc_cfg_mem;
1954 } 1862 }
1955 1863
1956 /* Allocate memory for video device */ 1864 /* Allocate memory for video device */
1957 vfd = video_device_alloc(); 1865 vfd = video_device_alloc();
1958 if (NULL == vfd) { 1866 if (NULL == vfd) {
1959 ret = -ENOMEM; 1867 ret = -ENOMEM;
1960 v4l2_err(pdev->dev.driver, 1868 v4l2_err(pdev->dev.driver, "Unable to alloc video device\n");
1961 "Unable to alloc video device\n");
1962 goto probe_out_release_irq; 1869 goto probe_out_release_irq;
1963 } 1870 }
1964 1871
@@ -2073,12 +1980,7 @@ probe_out_video_release:
2073 video_device_release(vpfe_dev->video_dev); 1980 video_device_release(vpfe_dev->video_dev);
2074probe_out_release_irq: 1981probe_out_release_irq:
2075 free_irq(vpfe_dev->ccdc_irq0, vpfe_dev); 1982 free_irq(vpfe_dev->ccdc_irq0, vpfe_dev);
2076probe_out_unmap1: 1983probe_free_ccdc_cfg_mem:
2077 iounmap(ccdc_cfg->ccdc_addr);
2078probe_out_release_mem1:
2079 release_mem_region(res1->start, res1->end - res1->start + 1);
2080probe_disable_clock:
2081 vpfe_disable_clock(vpfe_dev);
2082 mutex_unlock(&ccdc_lock); 1984 mutex_unlock(&ccdc_lock);
2083 kfree(ccdc_cfg); 1985 kfree(ccdc_cfg);
2084probe_free_dev_mem: 1986probe_free_dev_mem:
@@ -2092,7 +1994,6 @@ probe_free_dev_mem:
2092static int __devexit vpfe_remove(struct platform_device *pdev) 1994static int __devexit vpfe_remove(struct platform_device *pdev)
2093{ 1995{
2094 struct vpfe_device *vpfe_dev = platform_get_drvdata(pdev); 1996 struct vpfe_device *vpfe_dev = platform_get_drvdata(pdev);
2095 struct resource *res;
2096 1997
2097 v4l2_info(pdev->dev.driver, "vpfe_remove\n"); 1998 v4l2_info(pdev->dev.driver, "vpfe_remove\n");
2098 1999
@@ -2100,12 +2001,6 @@ static int __devexit vpfe_remove(struct platform_device *pdev)
2100 kfree(vpfe_dev->sd); 2001 kfree(vpfe_dev->sd);
2101 v4l2_device_unregister(&vpfe_dev->v4l2_dev); 2002 v4l2_device_unregister(&vpfe_dev->v4l2_dev);
2102 video_unregister_device(vpfe_dev->video_dev); 2003 video_unregister_device(vpfe_dev->video_dev);
2103 mutex_lock(&ccdc_lock);
2104 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
2105 release_mem_region(res->start, res->end - res->start + 1);
2106 iounmap(ccdc_cfg->ccdc_addr);
2107 mutex_unlock(&ccdc_lock);
2108 vpfe_disable_clock(vpfe_dev);
2109 kfree(vpfe_dev); 2004 kfree(vpfe_dev);
2110 kfree(ccdc_cfg); 2005 kfree(ccdc_cfg);
2111 return 0; 2006 return 0;
diff --git a/drivers/media/video/davinci/vpss.c b/drivers/media/video/davinci/vpss.c
index 7ee72ecd3d81..7918680917d0 100644
--- a/drivers/media/video/davinci/vpss.c
+++ b/drivers/media/video/davinci/vpss.c
@@ -15,7 +15,7 @@
15 * along with this program; if not, write to the Free Software 15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 16 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17 * 17 *
18 * common vpss driver for all video drivers. 18 * common vpss system module platform driver for all video drivers.
19 */ 19 */
20#include <linux/kernel.h> 20#include <linux/kernel.h>
21#include <linux/sched.h> 21#include <linux/sched.h>
@@ -35,12 +35,52 @@ MODULE_AUTHOR("Texas Instruments");
35/* DM644x defines */ 35/* DM644x defines */
36#define DM644X_SBL_PCR_VPSS (4) 36#define DM644X_SBL_PCR_VPSS (4)
37 37
38#define DM355_VPSSBL_INTSEL 0x10
39#define DM355_VPSSBL_EVTSEL 0x14
38/* vpss BL register offsets */ 40/* vpss BL register offsets */
39#define DM355_VPSSBL_CCDCMUX 0x1c 41#define DM355_VPSSBL_CCDCMUX 0x1c
40/* vpss CLK register offsets */ 42/* vpss CLK register offsets */
41#define DM355_VPSSCLK_CLKCTRL 0x04 43#define DM355_VPSSCLK_CLKCTRL 0x04
42/* masks and shifts */ 44/* masks and shifts */
43#define VPSS_HSSISEL_SHIFT 4 45#define VPSS_HSSISEL_SHIFT 4
46/*
47 * VDINT0 - vpss_int0, VDINT1 - vpss_int1, H3A - vpss_int4,
48 * IPIPE_INT1_SDR - vpss_int5
49 */
50#define DM355_VPSSBL_INTSEL_DEFAULT 0xff83ff10
51/* VENCINT - vpss_int8 */
52#define DM355_VPSSBL_EVTSEL_DEFAULT 0x4
53
54#define DM365_ISP5_PCCR 0x04
55#define DM365_ISP5_INTSEL1 0x10
56#define DM365_ISP5_INTSEL2 0x14
57#define DM365_ISP5_INTSEL3 0x18
58#define DM365_ISP5_CCDCMUX 0x20
59#define DM365_ISP5_PG_FRAME_SIZE 0x28
60#define DM365_VPBE_CLK_CTRL 0x00
61/*
62 * vpss interrupts. VDINT0 - vpss_int0, VDINT1 - vpss_int1,
63 * AF - vpss_int3
64 */
65#define DM365_ISP5_INTSEL1_DEFAULT 0x0b1f0100
66/* AEW - vpss_int6, RSZ_INT_DMA - vpss_int5 */
67#define DM365_ISP5_INTSEL2_DEFAULT 0x1f0a0f1f
68/* VENC - vpss_int8 */
69#define DM365_ISP5_INTSEL3_DEFAULT 0x00000015
70
71/* masks and shifts for DM365*/
72#define DM365_CCDC_PG_VD_POL_SHIFT 0
73#define DM365_CCDC_PG_HD_POL_SHIFT 1
74
75#define CCD_SRC_SEL_MASK (BIT_MASK(5) | BIT_MASK(4))
76#define CCD_SRC_SEL_SHIFT 4
77
78/* Different SoC platforms supported by this driver */
79enum vpss_platform_type {
80 DM644X,
81 DM355,
82 DM365,
83};
44 84
45/* 85/*
46 * vpss operations. Depends on platform. Not all functions are available 86 * vpss operations. Depends on platform. Not all functions are available
@@ -59,13 +99,9 @@ struct vpss_hw_ops {
59 99
60/* vpss configuration */ 100/* vpss configuration */
61struct vpss_oper_config { 101struct vpss_oper_config {
62 __iomem void *vpss_bl_regs_base; 102 __iomem void *vpss_regs_base0;
63 __iomem void *vpss_regs_base; 103 __iomem void *vpss_regs_base1;
64 struct resource *r1; 104 enum vpss_platform_type platform;
65 resource_size_t len1;
66 struct resource *r2;
67 resource_size_t len2;
68 char vpss_name[32];
69 spinlock_t vpss_lock; 105 spinlock_t vpss_lock;
70 struct vpss_hw_ops hw_ops; 106 struct vpss_hw_ops hw_ops;
71}; 107};
@@ -75,22 +111,46 @@ static struct vpss_oper_config oper_cfg;
75/* register access routines */ 111/* register access routines */
76static inline u32 bl_regr(u32 offset) 112static inline u32 bl_regr(u32 offset)
77{ 113{
78 return __raw_readl(oper_cfg.vpss_bl_regs_base + offset); 114 return __raw_readl(oper_cfg.vpss_regs_base0 + offset);
79} 115}
80 116
81static inline void bl_regw(u32 val, u32 offset) 117static inline void bl_regw(u32 val, u32 offset)
82{ 118{
83 __raw_writel(val, oper_cfg.vpss_bl_regs_base + offset); 119 __raw_writel(val, oper_cfg.vpss_regs_base0 + offset);
84} 120}
85 121
86static inline u32 vpss_regr(u32 offset) 122static inline u32 vpss_regr(u32 offset)
87{ 123{
88 return __raw_readl(oper_cfg.vpss_regs_base + offset); 124 return __raw_readl(oper_cfg.vpss_regs_base1 + offset);
89} 125}
90 126
91static inline void vpss_regw(u32 val, u32 offset) 127static inline void vpss_regw(u32 val, u32 offset)
92{ 128{
93 __raw_writel(val, oper_cfg.vpss_regs_base + offset); 129 __raw_writel(val, oper_cfg.vpss_regs_base1 + offset);
130}
131
132/* For DM365 only */
133static inline u32 isp5_read(u32 offset)
134{
135 return __raw_readl(oper_cfg.vpss_regs_base0 + offset);
136}
137
138/* For DM365 only */
139static inline void isp5_write(u32 val, u32 offset)
140{
141 __raw_writel(val, oper_cfg.vpss_regs_base0 + offset);
142}
143
144static void dm365_select_ccdc_source(enum vpss_ccdc_source_sel src_sel)
145{
146 u32 temp = isp5_read(DM365_ISP5_CCDCMUX) & ~CCD_SRC_SEL_MASK;
147
148 /* if we are using pattern generator, enable it */
149 if (src_sel == VPSS_PGLPBK || src_sel == VPSS_CCDCPG)
150 temp |= 0x08;
151
152 temp |= (src_sel << CCD_SRC_SEL_SHIFT);
153 isp5_write(temp, DM365_ISP5_CCDCMUX);
94} 154}
95 155
96static void dm355_select_ccdc_source(enum vpss_ccdc_source_sel src_sel) 156static void dm355_select_ccdc_source(enum vpss_ccdc_source_sel src_sel)
@@ -101,9 +161,9 @@ static void dm355_select_ccdc_source(enum vpss_ccdc_source_sel src_sel)
101int vpss_select_ccdc_source(enum vpss_ccdc_source_sel src_sel) 161int vpss_select_ccdc_source(enum vpss_ccdc_source_sel src_sel)
102{ 162{
103 if (!oper_cfg.hw_ops.select_ccdc_source) 163 if (!oper_cfg.hw_ops.select_ccdc_source)
104 return -1; 164 return -EINVAL;
105 165
106 dm355_select_ccdc_source(src_sel); 166 oper_cfg.hw_ops.select_ccdc_source(src_sel);
107 return 0; 167 return 0;
108} 168}
109EXPORT_SYMBOL(vpss_select_ccdc_source); 169EXPORT_SYMBOL(vpss_select_ccdc_source);
@@ -114,7 +174,7 @@ static int dm644x_clear_wbl_overflow(enum vpss_wbl_sel wbl_sel)
114 174
115 if (wbl_sel < VPSS_PCR_AEW_WBL_0 || 175 if (wbl_sel < VPSS_PCR_AEW_WBL_0 ||
116 wbl_sel > VPSS_PCR_CCDC_WBL_O) 176 wbl_sel > VPSS_PCR_CCDC_WBL_O)
117 return -1; 177 return -EINVAL;
118 178
119 /* writing a 0 clear the overflow */ 179 /* writing a 0 clear the overflow */
120 mask = ~(mask << wbl_sel); 180 mask = ~(mask << wbl_sel);
@@ -126,7 +186,7 @@ static int dm644x_clear_wbl_overflow(enum vpss_wbl_sel wbl_sel)
126int vpss_clear_wbl_overflow(enum vpss_wbl_sel wbl_sel) 186int vpss_clear_wbl_overflow(enum vpss_wbl_sel wbl_sel)
127{ 187{
128 if (!oper_cfg.hw_ops.clear_wbl_overflow) 188 if (!oper_cfg.hw_ops.clear_wbl_overflow)
129 return -1; 189 return -EINVAL;
130 190
131 return oper_cfg.hw_ops.clear_wbl_overflow(wbl_sel); 191 return oper_cfg.hw_ops.clear_wbl_overflow(wbl_sel);
132} 192}
@@ -166,7 +226,7 @@ static int dm355_enable_clock(enum vpss_clock_sel clock_sel, int en)
166 default: 226 default:
167 printk(KERN_ERR "dm355_enable_clock:" 227 printk(KERN_ERR "dm355_enable_clock:"
168 " Invalid selector: %d\n", clock_sel); 228 " Invalid selector: %d\n", clock_sel);
169 return -1; 229 return -EINVAL;
170 } 230 }
171 231
172 spin_lock_irqsave(&oper_cfg.vpss_lock, flags); 232 spin_lock_irqsave(&oper_cfg.vpss_lock, flags);
@@ -181,100 +241,221 @@ static int dm355_enable_clock(enum vpss_clock_sel clock_sel, int en)
181 return 0; 241 return 0;
182} 242}
183 243
244static int dm365_enable_clock(enum vpss_clock_sel clock_sel, int en)
245{
246 unsigned long flags;
247 u32 utemp, mask = 0x1, shift = 0, offset = DM365_ISP5_PCCR;
248 u32 (*read)(u32 offset) = isp5_read;
249 void(*write)(u32 val, u32 offset) = isp5_write;
250
251 switch (clock_sel) {
252 case VPSS_BL_CLOCK:
253 break;
254 case VPSS_CCDC_CLOCK:
255 shift = 1;
256 break;
257 case VPSS_H3A_CLOCK:
258 shift = 2;
259 break;
260 case VPSS_RSZ_CLOCK:
261 shift = 3;
262 break;
263 case VPSS_IPIPE_CLOCK:
264 shift = 4;
265 break;
266 case VPSS_IPIPEIF_CLOCK:
267 shift = 5;
268 break;
269 case VPSS_PCLK_INTERNAL:
270 shift = 6;
271 break;
272 case VPSS_PSYNC_CLOCK_SEL:
273 shift = 7;
274 break;
275 case VPSS_VPBE_CLOCK:
276 read = vpss_regr;
277 write = vpss_regw;
278 offset = DM365_VPBE_CLK_CTRL;
279 break;
280 case VPSS_VENC_CLOCK_SEL:
281 shift = 2;
282 read = vpss_regr;
283 write = vpss_regw;
284 offset = DM365_VPBE_CLK_CTRL;
285 break;
286 case VPSS_LDC_CLOCK:
287 shift = 3;
288 read = vpss_regr;
289 write = vpss_regw;
290 offset = DM365_VPBE_CLK_CTRL;
291 break;
292 case VPSS_FDIF_CLOCK:
293 shift = 4;
294 read = vpss_regr;
295 write = vpss_regw;
296 offset = DM365_VPBE_CLK_CTRL;
297 break;
298 case VPSS_OSD_CLOCK_SEL:
299 shift = 6;
300 read = vpss_regr;
301 write = vpss_regw;
302 offset = DM365_VPBE_CLK_CTRL;
303 break;
304 case VPSS_LDC_CLOCK_SEL:
305 shift = 7;
306 read = vpss_regr;
307 write = vpss_regw;
308 offset = DM365_VPBE_CLK_CTRL;
309 break;
310 default:
311 printk(KERN_ERR "dm365_enable_clock: Invalid selector: %d\n",
312 clock_sel);
313 return -1;
314 }
315
316 spin_lock_irqsave(&oper_cfg.vpss_lock, flags);
317 utemp = read(offset);
318 if (!en) {
319 mask = ~mask;
320 utemp &= (mask << shift);
321 } else
322 utemp |= (mask << shift);
323
324 write(utemp, offset);
325 spin_unlock_irqrestore(&oper_cfg.vpss_lock, flags);
326
327 return 0;
328}
329
184int vpss_enable_clock(enum vpss_clock_sel clock_sel, int en) 330int vpss_enable_clock(enum vpss_clock_sel clock_sel, int en)
185{ 331{
186 if (!oper_cfg.hw_ops.enable_clock) 332 if (!oper_cfg.hw_ops.enable_clock)
187 return -1; 333 return -EINVAL;
188 334
189 return oper_cfg.hw_ops.enable_clock(clock_sel, en); 335 return oper_cfg.hw_ops.enable_clock(clock_sel, en);
190} 336}
191EXPORT_SYMBOL(vpss_enable_clock); 337EXPORT_SYMBOL(vpss_enable_clock);
192 338
339void dm365_vpss_set_sync_pol(struct vpss_sync_pol sync)
340{
341 int val = 0;
342 val = isp5_read(DM365_ISP5_CCDCMUX);
343
344 val |= (sync.ccdpg_hdpol << DM365_CCDC_PG_HD_POL_SHIFT);
345 val |= (sync.ccdpg_vdpol << DM365_CCDC_PG_VD_POL_SHIFT);
346
347 isp5_write(val, DM365_ISP5_CCDCMUX);
348}
349EXPORT_SYMBOL(dm365_vpss_set_sync_pol);
350
351void dm365_vpss_set_pg_frame_size(struct vpss_pg_frame_size frame_size)
352{
353 int current_reg = ((frame_size.hlpfr >> 1) - 1) << 16;
354
355 current_reg |= (frame_size.pplen - 1);
356 isp5_write(current_reg, DM365_ISP5_PG_FRAME_SIZE);
357}
358EXPORT_SYMBOL(dm365_vpss_set_pg_frame_size);
359
193static int __init vpss_probe(struct platform_device *pdev) 360static int __init vpss_probe(struct platform_device *pdev)
194{ 361{
195 int status, dm355 = 0; 362 struct resource *r1, *r2;
363 char *platform_name;
364 int status;
196 365
197 if (!pdev->dev.platform_data) { 366 if (!pdev->dev.platform_data) {
198 dev_err(&pdev->dev, "no platform data\n"); 367 dev_err(&pdev->dev, "no platform data\n");
199 return -ENOENT; 368 return -ENOENT;
200 } 369 }
201 strcpy(oper_cfg.vpss_name, pdev->dev.platform_data);
202 370
203 if (!strcmp(oper_cfg.vpss_name, "dm355_vpss")) 371 platform_name = pdev->dev.platform_data;
204 dm355 = 1; 372 if (!strcmp(platform_name, "dm355_vpss"))
205 else if (strcmp(oper_cfg.vpss_name, "dm644x_vpss")) { 373 oper_cfg.platform = DM355;
374 else if (!strcmp(platform_name, "dm365_vpss"))
375 oper_cfg.platform = DM365;
376 else if (!strcmp(platform_name, "dm644x_vpss"))
377 oper_cfg.platform = DM644X;
378 else {
206 dev_err(&pdev->dev, "vpss driver not supported on" 379 dev_err(&pdev->dev, "vpss driver not supported on"
207 " this platform\n"); 380 " this platform\n");
208 return -ENODEV; 381 return -ENODEV;
209 } 382 }
210 383
211 dev_info(&pdev->dev, "%s vpss probed\n", oper_cfg.vpss_name); 384 dev_info(&pdev->dev, "%s vpss probed\n", platform_name);
212 oper_cfg.r1 = platform_get_resource(pdev, IORESOURCE_MEM, 0); 385 r1 = platform_get_resource(pdev, IORESOURCE_MEM, 0);
213 if (!oper_cfg.r1) 386 if (!r1)
214 return -ENOENT; 387 return -ENOENT;
215 388
216 oper_cfg.len1 = oper_cfg.r1->end - oper_cfg.r1->start + 1; 389 r1 = request_mem_region(r1->start, resource_size(r1), r1->name);
217 390 if (!r1)
218 oper_cfg.r1 = request_mem_region(oper_cfg.r1->start, oper_cfg.len1,
219 oper_cfg.r1->name);
220 if (!oper_cfg.r1)
221 return -EBUSY; 391 return -EBUSY;
222 392
223 oper_cfg.vpss_bl_regs_base = ioremap(oper_cfg.r1->start, oper_cfg.len1); 393 oper_cfg.vpss_regs_base0 = ioremap(r1->start, resource_size(r1));
224 if (!oper_cfg.vpss_bl_regs_base) { 394 if (!oper_cfg.vpss_regs_base0) {
225 status = -EBUSY; 395 status = -EBUSY;
226 goto fail1; 396 goto fail1;
227 } 397 }
228 398
229 if (dm355) { 399 if (oper_cfg.platform == DM355 || oper_cfg.platform == DM365) {
230 oper_cfg.r2 = platform_get_resource(pdev, IORESOURCE_MEM, 1); 400 r2 = platform_get_resource(pdev, IORESOURCE_MEM, 1);
231 if (!oper_cfg.r2) { 401 if (!r2) {
232 status = -ENOENT; 402 status = -ENOENT;
233 goto fail2; 403 goto fail2;
234 } 404 }
235 oper_cfg.len2 = oper_cfg.r2->end - oper_cfg.r2->start + 1; 405 r2 = request_mem_region(r2->start, resource_size(r2), r2->name);
236 oper_cfg.r2 = request_mem_region(oper_cfg.r2->start, 406 if (!r2) {
237 oper_cfg.len2,
238 oper_cfg.r2->name);
239 if (!oper_cfg.r2) {
240 status = -EBUSY; 407 status = -EBUSY;
241 goto fail2; 408 goto fail2;
242 } 409 }
243 410
244 oper_cfg.vpss_regs_base = ioremap(oper_cfg.r2->start, 411 oper_cfg.vpss_regs_base1 = ioremap(r2->start,
245 oper_cfg.len2); 412 resource_size(r2));
246 if (!oper_cfg.vpss_regs_base) { 413 if (!oper_cfg.vpss_regs_base1) {
247 status = -EBUSY; 414 status = -EBUSY;
248 goto fail3; 415 goto fail3;
249 } 416 }
250 } 417 }
251 418
252 if (dm355) { 419 if (oper_cfg.platform == DM355) {
253 oper_cfg.hw_ops.enable_clock = dm355_enable_clock; 420 oper_cfg.hw_ops.enable_clock = dm355_enable_clock;
254 oper_cfg.hw_ops.select_ccdc_source = dm355_select_ccdc_source; 421 oper_cfg.hw_ops.select_ccdc_source = dm355_select_ccdc_source;
422 /* Setup vpss interrupts */
423 bl_regw(DM355_VPSSBL_INTSEL_DEFAULT, DM355_VPSSBL_INTSEL);
424 bl_regw(DM355_VPSSBL_EVTSEL_DEFAULT, DM355_VPSSBL_EVTSEL);
425 } else if (oper_cfg.platform == DM365) {
426 oper_cfg.hw_ops.enable_clock = dm365_enable_clock;
427 oper_cfg.hw_ops.select_ccdc_source = dm365_select_ccdc_source;
428 /* Setup vpss interrupts */
429 isp5_write(DM365_ISP5_INTSEL1_DEFAULT, DM365_ISP5_INTSEL1);
430 isp5_write(DM365_ISP5_INTSEL2_DEFAULT, DM365_ISP5_INTSEL2);
431 isp5_write(DM365_ISP5_INTSEL3_DEFAULT, DM365_ISP5_INTSEL3);
255 } else 432 } else
256 oper_cfg.hw_ops.clear_wbl_overflow = dm644x_clear_wbl_overflow; 433 oper_cfg.hw_ops.clear_wbl_overflow = dm644x_clear_wbl_overflow;
257 434
258 spin_lock_init(&oper_cfg.vpss_lock); 435 spin_lock_init(&oper_cfg.vpss_lock);
259 dev_info(&pdev->dev, "%s vpss probe success\n", oper_cfg.vpss_name); 436 dev_info(&pdev->dev, "%s vpss probe success\n", platform_name);
260 return 0; 437 return 0;
261 438
262fail3: 439fail3:
263 release_mem_region(oper_cfg.r2->start, oper_cfg.len2); 440 release_mem_region(r2->start, resource_size(r2));
264fail2: 441fail2:
265 iounmap(oper_cfg.vpss_bl_regs_base); 442 iounmap(oper_cfg.vpss_regs_base0);
266fail1: 443fail1:
267 release_mem_region(oper_cfg.r1->start, oper_cfg.len1); 444 release_mem_region(r1->start, resource_size(r1));
268 return status; 445 return status;
269} 446}
270 447
271static int __devexit vpss_remove(struct platform_device *pdev) 448static int __devexit vpss_remove(struct platform_device *pdev)
272{ 449{
273 iounmap(oper_cfg.vpss_bl_regs_base); 450 struct resource *res;
274 release_mem_region(oper_cfg.r1->start, oper_cfg.len1); 451
275 if (!strcmp(oper_cfg.vpss_name, "dm355_vpss")) { 452 iounmap(oper_cfg.vpss_regs_base0);
276 iounmap(oper_cfg.vpss_regs_base); 453 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
277 release_mem_region(oper_cfg.r2->start, oper_cfg.len2); 454 release_mem_region(res->start, resource_size(res));
455 if (oper_cfg.platform == DM355 || oper_cfg.platform == DM365) {
456 iounmap(oper_cfg.vpss_regs_base1);
457 res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
458 release_mem_region(res->start, resource_size(res));
278 } 459 }
279 return 0; 460 return 0;
280} 461}
diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c
index 25100001ffff..ecbcefb08739 100644
--- a/drivers/media/video/em28xx/em28xx-cards.c
+++ b/drivers/media/video/em28xx/em28xx-cards.c
@@ -232,6 +232,12 @@ static struct em28xx_reg_seq vc211a_enable[] = {
232 { -1, -1, -1, -1}, 232 { -1, -1, -1, -1},
233}; 233};
234 234
235static struct em28xx_reg_seq dikom_dk300_digital[] = {
236 {EM28XX_R08_GPIO, 0x6e, ~EM_GPIO_4, 10},
237 {EM2880_R04_GPO, 0x08, 0xff, 10},
238 { -1, -1, -1, -1},
239};
240
235 241
236/* 242/*
237 * Board definitions 243 * Board definitions
@@ -461,21 +467,30 @@ struct em28xx_board em28xx_boards[] = {
461 .name = "Leadtek Winfast USB II Deluxe", 467 .name = "Leadtek Winfast USB II Deluxe",
462 .valid = EM28XX_BOARD_NOT_VALIDATED, 468 .valid = EM28XX_BOARD_NOT_VALIDATED,
463 .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, 469 .tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
464 .tda9887_conf = TDA9887_PRESENT, 470 .has_ir_i2c = 1,
471 .tvaudio_addr = 0x58,
472 .tda9887_conf = TDA9887_PRESENT |
473 TDA9887_PORT2_ACTIVE |
474 TDA9887_QSS,
465 .decoder = EM28XX_SAA711X, 475 .decoder = EM28XX_SAA711X,
476 .adecoder = EM28XX_TVAUDIO,
466 .input = { { 477 .input = { {
467 .type = EM28XX_VMUX_TELEVISION, 478 .type = EM28XX_VMUX_TELEVISION,
468 .vmux = SAA7115_COMPOSITE2, 479 .vmux = SAA7115_COMPOSITE4,
469 .amux = EM28XX_AMUX_VIDEO, 480 .amux = EM28XX_AMUX_AUX,
470 }, { 481 }, {
471 .type = EM28XX_VMUX_COMPOSITE1, 482 .type = EM28XX_VMUX_COMPOSITE1,
472 .vmux = SAA7115_COMPOSITE0, 483 .vmux = SAA7115_COMPOSITE5,
473 .amux = EM28XX_AMUX_LINE_IN, 484 .amux = EM28XX_AMUX_LINE_IN,
474 }, { 485 }, {
475 .type = EM28XX_VMUX_SVIDEO, 486 .type = EM28XX_VMUX_SVIDEO,
476 .vmux = SAA7115_COMPOSITE0, 487 .vmux = SAA7115_SVIDEO3,
477 .amux = EM28XX_AMUX_LINE_IN, 488 .amux = EM28XX_AMUX_LINE_IN,
478 } }, 489 } },
490 .radio = {
491 .type = EM28XX_RADIO,
492 .amux = EM28XX_AMUX_AUX,
493 }
479 }, 494 },
480 [EM2820_BOARD_VIDEOLOGY_20K14XUSB] = { 495 [EM2820_BOARD_VIDEOLOGY_20K14XUSB] = {
481 .name = "Videology 20K14XUSB USB2.0", 496 .name = "Videology 20K14XUSB USB2.0",
@@ -730,11 +745,12 @@ struct em28xx_board em28xx_boards[] = {
730 745
731 [EM2880_BOARD_TERRATEC_HYBRID_XS_FR] = { 746 [EM2880_BOARD_TERRATEC_HYBRID_XS_FR] = {
732 .name = "Terratec Hybrid XS Secam", 747 .name = "Terratec Hybrid XS Secam",
733 .valid = EM28XX_BOARD_NOT_VALIDATED,
734 .has_msp34xx = 1, 748 .has_msp34xx = 1,
735 .tuner_type = TUNER_XC2028, 749 .tuner_type = TUNER_XC2028,
736 .tuner_gpio = default_tuner_gpio, 750 .tuner_gpio = default_tuner_gpio,
737 .decoder = EM28XX_TVP5150, 751 .decoder = EM28XX_TVP5150,
752 .has_dvb = 1,
753 .dvb_gpio = default_digital,
738 .input = { { 754 .input = { {
739 .type = EM28XX_VMUX_TELEVISION, 755 .type = EM28XX_VMUX_TELEVISION,
740 .vmux = TVP5150_COMPOSITE0, 756 .vmux = TVP5150_COMPOSITE0,
@@ -1265,6 +1281,7 @@ struct em28xx_board em28xx_boards[] = {
1265 .decoder = EM28XX_SAA711X, 1281 .decoder = EM28XX_SAA711X,
1266 .has_dvb = 1, 1282 .has_dvb = 1,
1267 .dvb_gpio = em2882_kworld_315u_digital, 1283 .dvb_gpio = em2882_kworld_315u_digital,
1284 .ir_codes = &ir_codes_kworld_315u_table,
1268 .xclk = EM28XX_XCLK_FREQUENCY_12MHZ, 1285 .xclk = EM28XX_XCLK_FREQUENCY_12MHZ,
1269 .i2c_speed = EM28XX_I2C_CLK_WAIT_ENABLE, 1286 .i2c_speed = EM28XX_I2C_CLK_WAIT_ENABLE,
1270 /* Analog mode - still not ready */ 1287 /* Analog mode - still not ready */
@@ -1431,6 +1448,21 @@ struct em28xx_board em28xx_boards[] = {
1431 .gpio = hauppauge_wintv_hvr_900_analog, 1448 .gpio = hauppauge_wintv_hvr_900_analog,
1432 } }, 1449 } },
1433 }, 1450 },
1451 [EM2882_BOARD_DIKOM_DK300] = {
1452 .name = "Dikom DK300",
1453 .tuner_type = TUNER_XC2028,
1454 .tuner_gpio = default_tuner_gpio,
1455 .decoder = EM28XX_TVP5150,
1456 .mts_firmware = 1,
1457 .has_dvb = 1,
1458 .dvb_gpio = dikom_dk300_digital,
1459 .input = { {
1460 .type = EM28XX_VMUX_TELEVISION,
1461 .vmux = TVP5150_COMPOSITE0,
1462 .amux = EM28XX_AMUX_VIDEO,
1463 .gpio = default_analog,
1464 } },
1465 },
1434 [EM2883_BOARD_KWORLD_HYBRID_330U] = { 1466 [EM2883_BOARD_KWORLD_HYBRID_330U] = {
1435 .name = "Kworld PlusTV HD Hybrid 330", 1467 .name = "Kworld PlusTV HD Hybrid 330",
1436 .tuner_type = TUNER_XC2028, 1468 .tuner_type = TUNER_XC2028,
@@ -1751,6 +1783,7 @@ static struct em28xx_hash_table em28xx_eeprom_hash[] = {
1751 {0xcee44a99, EM2882_BOARD_EVGA_INDTUBE, TUNER_XC2028}, 1783 {0xcee44a99, EM2882_BOARD_EVGA_INDTUBE, TUNER_XC2028},
1752 {0xb8846b20, EM2881_BOARD_PINNACLE_HYBRID_PRO, TUNER_XC2028}, 1784 {0xb8846b20, EM2881_BOARD_PINNACLE_HYBRID_PRO, TUNER_XC2028},
1753 {0x63f653bd, EM2870_BOARD_REDDO_DVB_C_USB_BOX, TUNER_ABSENT}, 1785 {0x63f653bd, EM2870_BOARD_REDDO_DVB_C_USB_BOX, TUNER_ABSENT},
1786 {0x4e913442, EM2882_BOARD_DIKOM_DK300, TUNER_XC2028},
1754}; 1787};
1755 1788
1756/* I2C devicelist hash table for devices with generic USB IDs */ 1789/* I2C devicelist hash table for devices with generic USB IDs */
@@ -2103,6 +2136,7 @@ static void em28xx_setup_xc3028(struct em28xx *dev, struct xc2028_ctrl *ctl)
2103 ctl->demod = XC3028_FE_DEFAULT; 2136 ctl->demod = XC3028_FE_DEFAULT;
2104 break; 2137 break;
2105 case EM2883_BOARD_KWORLD_HYBRID_330U: 2138 case EM2883_BOARD_KWORLD_HYBRID_330U:
2139 case EM2882_BOARD_DIKOM_DK300:
2106 ctl->demod = XC3028_FE_CHINA; 2140 ctl->demod = XC3028_FE_CHINA;
2107 ctl->fname = XC2028_DEFAULT_FIRMWARE; 2141 ctl->fname = XC2028_DEFAULT_FIRMWARE;
2108 break; 2142 break;
@@ -2259,9 +2293,12 @@ static int em28xx_hint_board(struct em28xx *dev)
2259/* ----------------------------------------------------------------------- */ 2293/* ----------------------------------------------------------------------- */
2260void em28xx_register_i2c_ir(struct em28xx *dev) 2294void em28xx_register_i2c_ir(struct em28xx *dev)
2261{ 2295{
2296 /* Leadtek winfast tv USBII deluxe can find a non working IR-device */
2297 /* at address 0x18, so if that address is needed for another board in */
2298 /* the future, please put it after 0x1f. */
2262 struct i2c_board_info info; 2299 struct i2c_board_info info;
2263 const unsigned short addr_list[] = { 2300 const unsigned short addr_list[] = {
2264 0x30, 0x47, I2C_CLIENT_END 2301 0x1f, 0x30, 0x47, I2C_CLIENT_END
2265 }; 2302 };
2266 2303
2267 if (disable_ir) 2304 if (disable_ir)
@@ -2288,6 +2325,10 @@ void em28xx_register_i2c_ir(struct em28xx *dev)
2288 dev->init_data.ir_codes = &ir_codes_rc5_hauppauge_new_table; 2325 dev->init_data.ir_codes = &ir_codes_rc5_hauppauge_new_table;
2289 dev->init_data.get_key = em28xx_get_key_em_haup; 2326 dev->init_data.get_key = em28xx_get_key_em_haup;
2290 dev->init_data.name = "i2c IR (EM2840 Hauppauge)"; 2327 dev->init_data.name = "i2c IR (EM2840 Hauppauge)";
2328 case EM2820_BOARD_LEADTEK_WINFAST_USBII_DELUXE:
2329 dev->init_data.ir_codes = &ir_codes_winfast_usbii_deluxe_table;;
2330 dev->init_data.get_key = em28xx_get_key_winfast_usbii_deluxe;
2331 dev->init_data.name = "i2c IR (EM2820 Winfast TV USBII Deluxe)";
2291 break; 2332 break;
2292 } 2333 }
2293 2334
@@ -2381,6 +2422,31 @@ void em28xx_card_setup(struct em28xx *dev)
2381 em28xx_gpio_set(dev, dev->board.tuner_gpio); 2422 em28xx_gpio_set(dev, dev->board.tuner_gpio);
2382 em28xx_set_mode(dev, EM28XX_ANALOG_MODE); 2423 em28xx_set_mode(dev, EM28XX_ANALOG_MODE);
2383 break; 2424 break;
2425
2426/*
2427 * The Dikom DK300 is detected as an Kworld VS-DVB-T 323UR.
2428 *
2429 * This occurs because they share identical USB vendor and
2430 * product IDs.
2431 *
2432 * What we do here is look up the EEPROM hash of the Dikom
2433 * and if it is found then we decide that we do not have
2434 * a Kworld and reset the device to the Dikom instead.
2435 *
2436 * This solution is only valid if they do not share eeprom
2437 * hash identities which has not been determined as yet.
2438 */
2439 case EM2882_BOARD_KWORLD_VS_DVBT:
2440 if (!em28xx_hint_board(dev))
2441 em28xx_set_model(dev);
2442
2443 /* In cases where we had to use a board hint, the call to
2444 em28xx_set_mode() in em28xx_pre_card_setup() was a no-op,
2445 so make the call now so the analog GPIOs are set properly
2446 before probing the i2c bus. */
2447 em28xx_gpio_set(dev, dev->board.tuner_gpio);
2448 em28xx_set_mode(dev, EM28XX_ANALOG_MODE);
2449 break;
2384 } 2450 }
2385 2451
2386#if defined(CONFIG_MODULES) && defined(MODULE) 2452#if defined(CONFIG_MODULES) && defined(MODULE)
diff --git a/drivers/media/video/em28xx/em28xx-core.c b/drivers/media/video/em28xx/em28xx-core.c
index b311d4514bdf..5a37eccbd7d6 100644
--- a/drivers/media/video/em28xx/em28xx-core.c
+++ b/drivers/media/video/em28xx/em28xx-core.c
@@ -691,9 +691,15 @@ int em28xx_set_outfmt(struct em28xx *dev)
691 if (em28xx_vbi_supported(dev) == 1) { 691 if (em28xx_vbi_supported(dev) == 1) {
692 vinctrl |= EM28XX_VINCTRL_VBI_RAW; 692 vinctrl |= EM28XX_VINCTRL_VBI_RAW;
693 em28xx_write_reg(dev, EM28XX_R34_VBI_START_H, 0x00); 693 em28xx_write_reg(dev, EM28XX_R34_VBI_START_H, 0x00);
694 em28xx_write_reg(dev, EM28XX_R35_VBI_START_V, 0x09); 694 em28xx_write_reg(dev, EM28XX_R36_VBI_WIDTH, dev->vbi_width/4);
695 em28xx_write_reg(dev, EM28XX_R36_VBI_WIDTH, 0xb4); 695 em28xx_write_reg(dev, EM28XX_R37_VBI_HEIGHT, dev->vbi_height);
696 em28xx_write_reg(dev, EM28XX_R37_VBI_HEIGHT, 0x0c); 696 if (dev->norm & V4L2_STD_525_60) {
697 /* NTSC */
698 em28xx_write_reg(dev, EM28XX_R35_VBI_START_V, 0x09);
699 } else if (dev->norm & V4L2_STD_625_50) {
700 /* PAL */
701 em28xx_write_reg(dev, EM28XX_R35_VBI_START_V, 0x07);
702 }
697 } 703 }
698 704
699 return em28xx_write_reg(dev, EM28XX_R11_VINCTRL, vinctrl); 705 return em28xx_write_reg(dev, EM28XX_R11_VINCTRL, vinctrl);
@@ -760,6 +766,13 @@ int em28xx_resolution_set(struct em28xx *dev)
760 width = norm_maxw(dev); 766 width = norm_maxw(dev);
761 height = norm_maxh(dev); 767 height = norm_maxh(dev);
762 768
769 /* Properly setup VBI */
770 dev->vbi_width = 720;
771 if (dev->norm & V4L2_STD_525_60)
772 dev->vbi_height = 12;
773 else
774 dev->vbi_height = 18;
775
763 if (!dev->progressive) 776 if (!dev->progressive)
764 height >>= norm_maxh(dev); 777 height >>= norm_maxh(dev);
765 778
diff --git a/drivers/media/video/em28xx/em28xx-dvb.c b/drivers/media/video/em28xx/em28xx-dvb.c
index cc0505eb900f..1b96356b3ab2 100644
--- a/drivers/media/video/em28xx/em28xx-dvb.c
+++ b/drivers/media/video/em28xx/em28xx-dvb.c
@@ -502,7 +502,9 @@ static int dvb_init(struct em28xx *dev)
502 } 502 }
503 break; 503 break;
504 case EM2880_BOARD_TERRATEC_HYBRID_XS: 504 case EM2880_BOARD_TERRATEC_HYBRID_XS:
505 case EM2880_BOARD_TERRATEC_HYBRID_XS_FR:
505 case EM2881_BOARD_PINNACLE_HYBRID_PRO: 506 case EM2881_BOARD_PINNACLE_HYBRID_PRO:
507 case EM2882_BOARD_DIKOM_DK300:
506 dvb->frontend = dvb_attach(zl10353_attach, 508 dvb->frontend = dvb_attach(zl10353_attach,
507 &em28xx_zl10353_xc3028_no_i2c_gate, 509 &em28xx_zl10353_xc3028_no_i2c_gate,
508 &dev->i2c_adap); 510 &dev->i2c_adap);
@@ -606,6 +608,7 @@ static int dvb_fini(struct em28xx *dev)
606 608
607 if (dev->dvb) { 609 if (dev->dvb) {
608 unregister_dvb(dev->dvb); 610 unregister_dvb(dev->dvb);
611 kfree(dev->dvb);
609 dev->dvb = NULL; 612 dev->dvb = NULL;
610 } 613 }
611 614
diff --git a/drivers/media/video/em28xx/em28xx-input.c b/drivers/media/video/em28xx/em28xx-input.c
index af0d935c29be..1fb754e20875 100644
--- a/drivers/media/video/em28xx/em28xx-input.c
+++ b/drivers/media/video/em28xx/em28xx-input.c
@@ -75,6 +75,10 @@ struct em28xx_IR {
75 unsigned int repeat_interval; 75 unsigned int repeat_interval;
76 76
77 int (*get_key)(struct em28xx_IR *, struct em28xx_ir_poll_result *); 77 int (*get_key)(struct em28xx_IR *, struct em28xx_ir_poll_result *);
78
79 /* IR device properties */
80
81 struct ir_dev_props props;
78}; 82};
79 83
80/********************************************************** 84/**********************************************************
@@ -180,6 +184,36 @@ int em28xx_get_key_pinnacle_usb_grey(struct IR_i2c *ir, u32 *ir_key,
180 return 1; 184 return 1;
181} 185}
182 186
187int em28xx_get_key_winfast_usbii_deluxe(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
188{
189 unsigned char subaddr, keydetect, key;
190
191 struct i2c_msg msg[] = { { .addr = ir->c->addr, .flags = 0, .buf = &subaddr, .len = 1},
192
193 { .addr = ir->c->addr, .flags = I2C_M_RD, .buf = &keydetect, .len = 1} };
194
195 subaddr = 0x10;
196 if (2 != i2c_transfer(ir->c->adapter, msg, 2)) {
197 i2cdprintk("read error\n");
198 return -EIO;
199 }
200 if (keydetect == 0x00)
201 return 0;
202
203 subaddr = 0x00;
204 msg[1].buf = &key;
205 if (2 != i2c_transfer(ir->c->adapter, msg, 2)) {
206 i2cdprintk("read error\n");
207 return -EIO;
208 }
209 if (key == 0x00)
210 return 0;
211
212 *ir_key = key;
213 *ir_raw = key;
214 return 1;
215}
216
183/********************************************************** 217/**********************************************************
184 Poll based get keycode functions 218 Poll based get keycode functions
185 **********************************************************/ 219 **********************************************************/
@@ -336,35 +370,28 @@ static void em28xx_ir_stop(struct em28xx_IR *ir)
336 cancel_delayed_work_sync(&ir->work); 370 cancel_delayed_work_sync(&ir->work);
337} 371}
338 372
339int em28xx_ir_init(struct em28xx *dev) 373int em28xx_ir_change_protocol(void *priv, u64 ir_type)
340{ 374{
341 struct em28xx_IR *ir; 375 int rc = 0;
342 struct input_dev *input_dev; 376 struct em28xx_IR *ir = priv;
343 u8 ir_config; 377 struct em28xx *dev = ir->dev;
344 int err = -ENOMEM; 378 u8 ir_config = EM2874_IR_RC5;
345
346 if (dev->board.ir_codes == NULL) {
347 /* No remote control support */
348 return 0;
349 }
350
351 ir = kzalloc(sizeof(*ir), GFP_KERNEL);
352 input_dev = input_allocate_device();
353 if (!ir || !input_dev)
354 goto err_out_free;
355
356 ir->input = input_dev;
357 ir_config = EM2874_IR_RC5;
358 379
359 /* Adjust xclk based o IR table for RC5/NEC tables */ 380 /* Adjust xclk based o IR table for RC5/NEC tables */
360 if (dev->board.ir_codes->ir_type == IR_TYPE_RC5) { 381
382 dev->board.ir_codes->ir_type = IR_TYPE_OTHER;
383 if (ir_type == IR_TYPE_RC5) {
361 dev->board.xclk |= EM28XX_XCLK_IR_RC5_MODE; 384 dev->board.xclk |= EM28XX_XCLK_IR_RC5_MODE;
362 ir->full_code = 1; 385 ir->full_code = 1;
363 } else if (dev->board.ir_codes->ir_type == IR_TYPE_NEC) { 386 } else if (ir_type == IR_TYPE_NEC) {
364 dev->board.xclk &= ~EM28XX_XCLK_IR_RC5_MODE; 387 dev->board.xclk &= ~EM28XX_XCLK_IR_RC5_MODE;
365 ir_config = EM2874_IR_NEC; 388 ir_config = EM2874_IR_NEC;
366 ir->full_code = 1; 389 ir->full_code = 1;
367 } 390 } else
391 rc = -EINVAL;
392
393 dev->board.ir_codes->ir_type = ir_type;
394
368 em28xx_write_reg_bits(dev, EM28XX_R0F_XCLK, dev->board.xclk, 395 em28xx_write_reg_bits(dev, EM28XX_R0F_XCLK, dev->board.xclk,
369 EM28XX_XCLK_IR_RC5_MODE); 396 EM28XX_XCLK_IR_RC5_MODE);
370 397
@@ -380,9 +407,42 @@ int em28xx_ir_init(struct em28xx *dev)
380 break; 407 break;
381 default: 408 default:
382 printk("Unrecognized em28xx chip id: IR not supported\n"); 409 printk("Unrecognized em28xx chip id: IR not supported\n");
383 goto err_out_free; 410 rc = -EINVAL;
411 }
412
413 return rc;
414}
415
416int em28xx_ir_init(struct em28xx *dev)
417{
418 struct em28xx_IR *ir;
419 struct input_dev *input_dev;
420 int err = -ENOMEM;
421
422 if (dev->board.ir_codes == NULL) {
423 /* No remote control support */
424 return 0;
384 } 425 }
385 426
427 ir = kzalloc(sizeof(*ir), GFP_KERNEL);
428 input_dev = input_allocate_device();
429 if (!ir || !input_dev)
430 goto err_out_free;
431
432 /* record handles to ourself */
433 ir->dev = dev;
434 dev->ir = ir;
435
436 ir->input = input_dev;
437
438 /*
439 * em2874 supports more protocols. For now, let's just announce
440 * the two protocols that were already tested
441 */
442 ir->props.allowed_protos = IR_TYPE_RC5 | IR_TYPE_NEC;
443 ir->props.priv = ir;
444 ir->props.change_protocol = em28xx_ir_change_protocol;
445
386 /* This is how often we ask the chip for IR information */ 446 /* This is how often we ask the chip for IR information */
387 ir->polling = 100; /* ms */ 447 ir->polling = 100; /* ms */
388 448
@@ -393,6 +453,8 @@ int em28xx_ir_init(struct em28xx *dev)
393 usb_make_path(dev->udev, ir->phys, sizeof(ir->phys)); 453 usb_make_path(dev->udev, ir->phys, sizeof(ir->phys));
394 strlcat(ir->phys, "/input0", sizeof(ir->phys)); 454 strlcat(ir->phys, "/input0", sizeof(ir->phys));
395 455
456 /* Set IR protocol */
457 em28xx_ir_change_protocol(ir, dev->board.ir_codes->ir_type);
396 err = ir_input_init(input_dev, &ir->ir, IR_TYPE_OTHER); 458 err = ir_input_init(input_dev, &ir->ir, IR_TYPE_OTHER);
397 if (err < 0) 459 if (err < 0)
398 goto err_out_free; 460 goto err_out_free;
@@ -405,14 +467,13 @@ int em28xx_ir_init(struct em28xx *dev)
405 input_dev->id.product = le16_to_cpu(dev->udev->descriptor.idProduct); 467 input_dev->id.product = le16_to_cpu(dev->udev->descriptor.idProduct);
406 468
407 input_dev->dev.parent = &dev->udev->dev; 469 input_dev->dev.parent = &dev->udev->dev;
408 /* record handles to ourself */ 470
409 ir->dev = dev;
410 dev->ir = ir;
411 471
412 em28xx_ir_start(ir); 472 em28xx_ir_start(ir);
413 473
414 /* all done */ 474 /* all done */
415 err = ir_input_register(ir->input, dev->board.ir_codes); 475 err = ir_input_register(ir->input, dev->board.ir_codes,
476 &ir->props);
416 if (err) 477 if (err)
417 goto err_out_stop; 478 goto err_out_stop;
418 479
diff --git a/drivers/media/video/em28xx/em28xx-reg.h b/drivers/media/video/em28xx/em28xx-reg.h
index 058ac87639ce..91e90559642b 100644
--- a/drivers/media/video/em28xx/em28xx-reg.h
+++ b/drivers/media/video/em28xx/em28xx-reg.h
@@ -173,8 +173,8 @@
173/* em2874 IR config register (0x50) */ 173/* em2874 IR config register (0x50) */
174#define EM2874_IR_NEC 0x00 174#define EM2874_IR_NEC 0x00
175#define EM2874_IR_RC5 0x04 175#define EM2874_IR_RC5 0x04
176#define EM2874_IR_RC5_MODE_0 0x08 176#define EM2874_IR_RC6_MODE_0 0x08
177#define EM2874_IR_RC5_MODE_6A 0x0b 177#define EM2874_IR_RC6_MODE_6A 0x0b
178 178
179/* em2874 Transport Stream Enable Register (0x5f) */ 179/* em2874 Transport Stream Enable Register (0x5f) */
180#define EM2874_TS1_CAPTURE_ENABLE (1 << 0) 180#define EM2874_TS1_CAPTURE_ENABLE (1 << 0)
diff --git a/drivers/media/video/em28xx/em28xx-vbi.c b/drivers/media/video/em28xx/em28xx-vbi.c
index 94943e5a1529..c7dce39823d8 100644
--- a/drivers/media/video/em28xx/em28xx-vbi.c
+++ b/drivers/media/video/em28xx/em28xx-vbi.c
@@ -71,7 +71,11 @@ free_buffer(struct videobuf_queue *vq, struct em28xx_buffer *buf)
71static int 71static int
72vbi_setup(struct videobuf_queue *q, unsigned int *count, unsigned int *size) 72vbi_setup(struct videobuf_queue *q, unsigned int *count, unsigned int *size)
73{ 73{
74 *size = 720 * 12 * 2; 74 struct em28xx_fh *fh = q->priv_data;
75 struct em28xx *dev = fh->dev;
76
77 *size = dev->vbi_width * dev->vbi_height * 2;
78
75 if (0 == *count) 79 if (0 == *count)
76 *count = vbibufs; 80 *count = vbibufs;
77 if (*count < 2) 81 if (*count < 2)
@@ -85,19 +89,18 @@ static int
85vbi_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb, 89vbi_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
86 enum v4l2_field field) 90 enum v4l2_field field)
87{ 91{
92 struct em28xx_fh *fh = q->priv_data;
93 struct em28xx *dev = fh->dev;
88 struct em28xx_buffer *buf = container_of(vb, struct em28xx_buffer, vb); 94 struct em28xx_buffer *buf = container_of(vb, struct em28xx_buffer, vb);
89 int rc = 0; 95 int rc = 0;
90 unsigned int size;
91
92 size = 720 * 12 * 2;
93 96
94 buf->vb.size = size; 97 buf->vb.size = dev->vbi_width * dev->vbi_height * 2;
95 98
96 if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size) 99 if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size)
97 return -EINVAL; 100 return -EINVAL;
98 101
99 buf->vb.width = 720; 102 buf->vb.width = dev->vbi_width;
100 buf->vb.height = 12; 103 buf->vb.height = dev->vbi_height;
101 buf->vb.field = field; 104 buf->vb.field = field;
102 105
103 if (VIDEOBUF_NEEDS_INIT == buf->vb.state) { 106 if (VIDEOBUF_NEEDS_INIT == buf->vb.state) {
diff --git a/drivers/media/video/em28xx/em28xx-video.c b/drivers/media/video/em28xx/em28xx-video.c
index 849b18c94037..ac2bd935927e 100644
--- a/drivers/media/video/em28xx/em28xx-video.c
+++ b/drivers/media/video/em28xx/em28xx-video.c
@@ -282,7 +282,7 @@ static void em28xx_copy_vbi(struct em28xx *dev,
282{ 282{
283 void *startwrite, *startread; 283 void *startwrite, *startread;
284 int offset; 284 int offset;
285 int bytesperline = 720; 285 int bytesperline = dev->vbi_width;
286 286
287 if (dev == NULL) { 287 if (dev == NULL) {
288 em28xx_isocdbg("dev is null\n"); 288 em28xx_isocdbg("dev is null\n");
@@ -323,8 +323,8 @@ static void em28xx_copy_vbi(struct em28xx *dev,
323 323
324 /* Make sure the bottom field populates the second half of the frame */ 324 /* Make sure the bottom field populates the second half of the frame */
325 if (buf->top_field == 0) { 325 if (buf->top_field == 0) {
326 startwrite += bytesperline * 0x0c; 326 startwrite += bytesperline * dev->vbi_height;
327 offset += bytesperline * 0x0c; 327 offset += bytesperline * dev->vbi_height;
328 } 328 }
329 329
330 memcpy(startwrite, startread, len); 330 memcpy(startwrite, startread, len);
@@ -578,8 +578,7 @@ static inline int em28xx_isoc_copy_vbi(struct em28xx *dev, struct urb *urb)
578 dev->cur_field = p[2]; 578 dev->cur_field = p[2];
579 } 579 }
580 580
581 /* FIXME: get rid of hard-coded value */ 581 vbi_size = dev->vbi_width * dev->vbi_height;
582 vbi_size = 720 * 0x0c;
583 582
584 if (dev->capture_type == 0) { 583 if (dev->capture_type == 0) {
585 if (dev->vbi_read >= vbi_size) { 584 if (dev->vbi_read >= vbi_size) {
@@ -1850,18 +1849,27 @@ static int vidioc_try_set_sliced_vbi_cap(struct file *file, void *priv,
1850static int vidioc_g_fmt_vbi_cap(struct file *file, void *priv, 1849static int vidioc_g_fmt_vbi_cap(struct file *file, void *priv,
1851 struct v4l2_format *format) 1850 struct v4l2_format *format)
1852{ 1851{
1853 format->fmt.vbi.samples_per_line = 720; 1852 struct em28xx_fh *fh = priv;
1853 struct em28xx *dev = fh->dev;
1854
1855 format->fmt.vbi.samples_per_line = dev->vbi_width;
1854 format->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY; 1856 format->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY;
1855 format->fmt.vbi.offset = 0; 1857 format->fmt.vbi.offset = 0;
1856 format->fmt.vbi.flags = 0; 1858 format->fmt.vbi.flags = 0;
1859 format->fmt.vbi.sampling_rate = 6750000 * 4 / 2;
1860 format->fmt.vbi.count[0] = dev->vbi_height;
1861 format->fmt.vbi.count[1] = dev->vbi_height;
1857 1862
1858 /* Varies by video standard (NTSC, PAL, etc.) */ 1863 /* Varies by video standard (NTSC, PAL, etc.) */
1859 /* FIXME: hard-coded for NTSC support */ 1864 if (dev->norm & V4L2_STD_525_60) {
1860 format->fmt.vbi.sampling_rate = 6750000 * 4 / 2; /* FIXME: ??? */ 1865 /* NTSC */
1861 format->fmt.vbi.count[0] = 12; 1866 format->fmt.vbi.start[0] = 10;
1862 format->fmt.vbi.count[1] = 12; 1867 format->fmt.vbi.start[1] = 273;
1863 format->fmt.vbi.start[0] = 10; 1868 } else if (dev->norm & V4L2_STD_625_50) {
1864 format->fmt.vbi.start[1] = 273; 1869 /* PAL */
1870 format->fmt.vbi.start[0] = 6;
1871 format->fmt.vbi.start[1] = 318;
1872 }
1865 1873
1866 return 0; 1874 return 0;
1867} 1875}
@@ -1869,18 +1877,27 @@ static int vidioc_g_fmt_vbi_cap(struct file *file, void *priv,
1869static int vidioc_s_fmt_vbi_cap(struct file *file, void *priv, 1877static int vidioc_s_fmt_vbi_cap(struct file *file, void *priv,
1870 struct v4l2_format *format) 1878 struct v4l2_format *format)
1871{ 1879{
1872 format->fmt.vbi.samples_per_line = 720; 1880 struct em28xx_fh *fh = priv;
1881 struct em28xx *dev = fh->dev;
1882
1883 format->fmt.vbi.samples_per_line = dev->vbi_width;
1873 format->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY; 1884 format->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY;
1874 format->fmt.vbi.offset = 0; 1885 format->fmt.vbi.offset = 0;
1875 format->fmt.vbi.flags = 0; 1886 format->fmt.vbi.flags = 0;
1887 format->fmt.vbi.sampling_rate = 6750000 * 4 / 2;
1888 format->fmt.vbi.count[0] = dev->vbi_height;
1889 format->fmt.vbi.count[1] = dev->vbi_height;
1876 1890
1877 /* Varies by video standard (NTSC, PAL, etc.) */ 1891 /* Varies by video standard (NTSC, PAL, etc.) */
1878 /* FIXME: hard-coded for NTSC support */ 1892 if (dev->norm & V4L2_STD_525_60) {
1879 format->fmt.vbi.sampling_rate = 6750000 * 4 / 2; /* FIXME: ??? */ 1893 /* NTSC */
1880 format->fmt.vbi.count[0] = 12; 1894 format->fmt.vbi.start[0] = 10;
1881 format->fmt.vbi.count[1] = 12; 1895 format->fmt.vbi.start[1] = 273;
1882 format->fmt.vbi.start[0] = 10; 1896 } else if (dev->norm & V4L2_STD_625_50) {
1883 format->fmt.vbi.start[1] = 273; 1897 /* PAL */
1898 format->fmt.vbi.start[0] = 6;
1899 format->fmt.vbi.start[1] = 318;
1900 }
1884 1901
1885 return 0; 1902 return 0;
1886} 1903}
@@ -1922,7 +1939,8 @@ static int vidioc_querybuf(struct file *file, void *priv,
1922 At a minimum, it causes a crash in zvbi since it does 1939 At a minimum, it causes a crash in zvbi since it does
1923 a memcpy based on the source buffer length */ 1940 a memcpy based on the source buffer length */
1924 int result = videobuf_querybuf(&fh->vb_vbiq, b); 1941 int result = videobuf_querybuf(&fh->vb_vbiq, b);
1925 b->length = 17280; 1942 b->length = dev->vbi_width * dev->vbi_height * 2;
1943
1926 return result; 1944 return result;
1927 } 1945 }
1928} 1946}
diff --git a/drivers/media/video/em28xx/em28xx.h b/drivers/media/video/em28xx/em28xx.h
index 80d9b4fa1b97..ba6fe5daff84 100644
--- a/drivers/media/video/em28xx/em28xx.h
+++ b/drivers/media/video/em28xx/em28xx.h
@@ -111,6 +111,7 @@
111#define EM2861_BOARD_GADMEI_UTV330PLUS 72 111#define EM2861_BOARD_GADMEI_UTV330PLUS 72
112#define EM2870_BOARD_REDDO_DVB_C_USB_BOX 73 112#define EM2870_BOARD_REDDO_DVB_C_USB_BOX 73
113#define EM2800_BOARD_VC211A 74 113#define EM2800_BOARD_VC211A 74
114#define EM2882_BOARD_DIKOM_DK300 75
114 115
115/* Limits minimum and default number of buffers */ 116/* Limits minimum and default number of buffers */
116#define EM28XX_MIN_BUF 4 117#define EM28XX_MIN_BUF 4
@@ -552,7 +553,8 @@ struct em28xx {
552 int capture_type; 553 int capture_type;
553 int vbi_read; 554 int vbi_read;
554 unsigned char cur_field; 555 unsigned char cur_field;
555 556 unsigned int vbi_width;
557 unsigned int vbi_height; /* lines per field */
556 558
557 struct work_struct request_module_wk; 559 struct work_struct request_module_wk;
558 560
@@ -693,6 +695,8 @@ int em28xx_get_key_terratec(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw);
693int em28xx_get_key_em_haup(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw); 695int em28xx_get_key_em_haup(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw);
694int em28xx_get_key_pinnacle_usb_grey(struct IR_i2c *ir, u32 *ir_key, 696int em28xx_get_key_pinnacle_usb_grey(struct IR_i2c *ir, u32 *ir_key,
695 u32 *ir_raw); 697 u32 *ir_raw);
698int em28xx_get_key_winfast_usbii_deluxe(struct IR_i2c *ir, u32 *ir_key,
699 u32 *ir_raw);
696void em28xx_register_snapshot_button(struct em28xx *dev); 700void em28xx_register_snapshot_button(struct em28xx *dev);
697void em28xx_deregister_snapshot_button(struct em28xx *dev); 701void em28xx_deregister_snapshot_button(struct em28xx *dev);
698 702
diff --git a/drivers/media/video/et61x251/Kconfig b/drivers/media/video/et61x251/Kconfig
index dcc1a0335440..87981b078fe6 100644
--- a/drivers/media/video/et61x251/Kconfig
+++ b/drivers/media/video/et61x251/Kconfig
@@ -1,7 +1,11 @@
1config USB_ET61X251 1config USB_ET61X251
2 tristate "USB ET61X[12]51 PC Camera Controller support" 2 tristate "USB ET61X[12]51 PC Camera Controller support (DEPRECATED)"
3 depends on VIDEO_V4L2 3 depends on VIDEO_V4L2
4 default n
4 ---help--- 5 ---help---
6 This driver is DEPRECATED please use the gspca zc3xx module
7 instead.
8
5 Say Y here if you want support for cameras based on Etoms ET61X151 9 Say Y here if you want support for cameras based on Etoms ET61X151
6 or ET61X251 PC Camera Controllers. 10 or ET61X251 PC Camera Controllers.
7 11
diff --git a/drivers/media/video/gspca/Kconfig b/drivers/media/video/gspca/Kconfig
index 609d65b0b10d..e0060c1f0544 100644
--- a/drivers/media/video/gspca/Kconfig
+++ b/drivers/media/video/gspca/Kconfig
@@ -21,6 +21,15 @@ source "drivers/media/video/gspca/m5602/Kconfig"
21source "drivers/media/video/gspca/stv06xx/Kconfig" 21source "drivers/media/video/gspca/stv06xx/Kconfig"
22source "drivers/media/video/gspca/gl860/Kconfig" 22source "drivers/media/video/gspca/gl860/Kconfig"
23 23
24config USB_GSPCA_BENQ
25 tristate "Benq USB Camera Driver"
26 depends on VIDEO_V4L2 && USB_GSPCA
27 help
28 Say Y here if you want support for the Benq DC E300 camera.
29
30 To compile this driver as a module, choose M here: the
31 module will be called gspca_benq.
32
24config USB_GSPCA_CONEX 33config USB_GSPCA_CONEX
25 tristate "Conexant Camera Driver" 34 tristate "Conexant Camera Driver"
26 depends on VIDEO_V4L2 && USB_GSPCA 35 depends on VIDEO_V4L2 && USB_GSPCA
@@ -30,6 +39,17 @@ config USB_GSPCA_CONEX
30 To compile this driver as a module, choose M here: the 39 To compile this driver as a module, choose M here: the
31 module will be called gspca_conex. 40 module will be called gspca_conex.
32 41
42config USB_GSPCA_CPIA1
43 tristate "cpia CPiA (version 1) Camera Driver"
44 depends on VIDEO_V4L2 && USB_GSPCA
45 help
46 Say Y here if you want support for USB cameras based on the cpia
47 CPiA chip. Note that you need atleast version 0.6.4 of libv4l for
48 applications to understand the videoformat generated by this driver.
49
50 To compile this driver as a module, choose M here: the
51 module will be called gspca_cpia1.
52
33config USB_GSPCA_ETOMS 53config USB_GSPCA_ETOMS
34 tristate "Etoms USB Camera Driver" 54 tristate "Etoms USB Camera Driver"
35 depends on VIDEO_V4L2 && USB_GSPCA 55 depends on VIDEO_V4L2 && USB_GSPCA
@@ -86,15 +106,25 @@ config USB_GSPCA_OV519
86 module will be called gspca_ov519. 106 module will be called gspca_ov519.
87 107
88config USB_GSPCA_OV534 108config USB_GSPCA_OV534
89 tristate "OV534 USB Camera Driver" 109 tristate "OV534 OV772x USB Camera Driver"
90 depends on VIDEO_V4L2 && USB_GSPCA 110 depends on VIDEO_V4L2 && USB_GSPCA
91 help 111 help
92 Say Y here if you want support for cameras based on the OV534 chip. 112 Say Y here if you want support for cameras based on the OV534 chip
93 (e.g. Sony Playstation EYE) 113 and sensor OV772x (e.g. Sony Playstation EYE)
94 114
95 To compile this driver as a module, choose M here: the 115 To compile this driver as a module, choose M here: the
96 module will be called gspca_ov534. 116 module will be called gspca_ov534.
97 117
118config USB_GSPCA_OV534_9
119 tristate "OV534 OV965x USB Camera Driver"
120 depends on VIDEO_V4L2 && USB_GSPCA
121 help
122 Say Y here if you want support for cameras based on the OV534 chip
123 and sensor OV965x (e.g. Hercules Dualpix)
124
125 To compile this driver as a module, choose M here: the
126 module will be called gspca_ov534_9.
127
98config USB_GSPCA_PAC207 128config USB_GSPCA_PAC207
99 tristate "Pixart PAC207 USB Camera Driver" 129 tristate "Pixart PAC207 USB Camera Driver"
100 depends on VIDEO_V4L2 && USB_GSPCA 130 depends on VIDEO_V4L2 && USB_GSPCA
@@ -122,6 +152,16 @@ config USB_GSPCA_PAC7311
122 To compile this driver as a module, choose M here: the 152 To compile this driver as a module, choose M here: the
123 module will be called gspca_pac7311. 153 module will be called gspca_pac7311.
124 154
155config USB_GSPCA_SN9C2028
156 tristate "SONIX Dual-Mode USB Camera Driver"
157 depends on VIDEO_V4L2 && USB_GSPCA
158 help
159 Say Y here if you want streaming support for Sonix SN9C2028 cameras.
160 These are supported as stillcams in libgphoto2/camlibs/sonix.
161
162 To compile this driver as a module, choose M here: the
163 module will be called gspca_sn9c2028.
164
125config USB_GSPCA_SN9C20X 165config USB_GSPCA_SN9C20X
126 tristate "SN9C20X USB Camera Driver" 166 tristate "SN9C20X USB Camera Driver"
127 depends on VIDEO_V4L2 && USB_GSPCA 167 depends on VIDEO_V4L2 && USB_GSPCA
diff --git a/drivers/media/video/gspca/Makefile b/drivers/media/video/gspca/Makefile
index ff2c7279d82e..6e4cf1ce01c9 100644
--- a/drivers/media/video/gspca/Makefile
+++ b/drivers/media/video/gspca/Makefile
@@ -1,5 +1,7 @@
1obj-$(CONFIG_USB_GSPCA) += gspca_main.o 1obj-$(CONFIG_USB_GSPCA) += gspca_main.o
2obj-$(CONFIG_USB_GSPCA_BENQ) += gspca_benq.o
2obj-$(CONFIG_USB_GSPCA_CONEX) += gspca_conex.o 3obj-$(CONFIG_USB_GSPCA_CONEX) += gspca_conex.o
4obj-$(CONFIG_USB_GSPCA_CPIA1) += gspca_cpia1.o
3obj-$(CONFIG_USB_GSPCA_ETOMS) += gspca_etoms.o 5obj-$(CONFIG_USB_GSPCA_ETOMS) += gspca_etoms.o
4obj-$(CONFIG_USB_GSPCA_FINEPIX) += gspca_finepix.o 6obj-$(CONFIG_USB_GSPCA_FINEPIX) += gspca_finepix.o
5obj-$(CONFIG_USB_GSPCA_JEILINJ) += gspca_jeilinj.o 7obj-$(CONFIG_USB_GSPCA_JEILINJ) += gspca_jeilinj.o
@@ -7,9 +9,11 @@ obj-$(CONFIG_USB_GSPCA_MARS) += gspca_mars.o
7obj-$(CONFIG_USB_GSPCA_MR97310A) += gspca_mr97310a.o 9obj-$(CONFIG_USB_GSPCA_MR97310A) += gspca_mr97310a.o
8obj-$(CONFIG_USB_GSPCA_OV519) += gspca_ov519.o 10obj-$(CONFIG_USB_GSPCA_OV519) += gspca_ov519.o
9obj-$(CONFIG_USB_GSPCA_OV534) += gspca_ov534.o 11obj-$(CONFIG_USB_GSPCA_OV534) += gspca_ov534.o
12obj-$(CONFIG_USB_GSPCA_OV534_9) += gspca_ov534_9.o
10obj-$(CONFIG_USB_GSPCA_PAC207) += gspca_pac207.o 13obj-$(CONFIG_USB_GSPCA_PAC207) += gspca_pac207.o
11obj-$(CONFIG_USB_GSPCA_PAC7302) += gspca_pac7302.o 14obj-$(CONFIG_USB_GSPCA_PAC7302) += gspca_pac7302.o
12obj-$(CONFIG_USB_GSPCA_PAC7311) += gspca_pac7311.o 15obj-$(CONFIG_USB_GSPCA_PAC7311) += gspca_pac7311.o
16obj-$(CONFIG_USB_GSPCA_SN9C2028) += gspca_sn9c2028.o
13obj-$(CONFIG_USB_GSPCA_SN9C20X) += gspca_sn9c20x.o 17obj-$(CONFIG_USB_GSPCA_SN9C20X) += gspca_sn9c20x.o
14obj-$(CONFIG_USB_GSPCA_SONIXB) += gspca_sonixb.o 18obj-$(CONFIG_USB_GSPCA_SONIXB) += gspca_sonixb.o
15obj-$(CONFIG_USB_GSPCA_SONIXJ) += gspca_sonixj.o 19obj-$(CONFIG_USB_GSPCA_SONIXJ) += gspca_sonixj.o
@@ -30,7 +34,9 @@ obj-$(CONFIG_USB_GSPCA_VC032X) += gspca_vc032x.o
30obj-$(CONFIG_USB_GSPCA_ZC3XX) += gspca_zc3xx.o 34obj-$(CONFIG_USB_GSPCA_ZC3XX) += gspca_zc3xx.o
31 35
32gspca_main-objs := gspca.o 36gspca_main-objs := gspca.o
37gspca_benq-objs := benq.o
33gspca_conex-objs := conex.o 38gspca_conex-objs := conex.o
39gspca_cpia1-objs := cpia1.o
34gspca_etoms-objs := etoms.o 40gspca_etoms-objs := etoms.o
35gspca_finepix-objs := finepix.o 41gspca_finepix-objs := finepix.o
36gspca_jeilinj-objs := jeilinj.o 42gspca_jeilinj-objs := jeilinj.o
@@ -38,9 +44,11 @@ gspca_mars-objs := mars.o
38gspca_mr97310a-objs := mr97310a.o 44gspca_mr97310a-objs := mr97310a.o
39gspca_ov519-objs := ov519.o 45gspca_ov519-objs := ov519.o
40gspca_ov534-objs := ov534.o 46gspca_ov534-objs := ov534.o
47gspca_ov534_9-objs := ov534_9.o
41gspca_pac207-objs := pac207.o 48gspca_pac207-objs := pac207.o
42gspca_pac7302-objs := pac7302.o 49gspca_pac7302-objs := pac7302.o
43gspca_pac7311-objs := pac7311.o 50gspca_pac7311-objs := pac7311.o
51gspca_sn9c2028-objs := sn9c2028.o
44gspca_sn9c20x-objs := sn9c20x.o 52gspca_sn9c20x-objs := sn9c20x.o
45gspca_sonixb-objs := sonixb.o 53gspca_sonixb-objs := sonixb.o
46gspca_sonixj-objs := sonixj.o 54gspca_sonixj-objs := sonixj.o
diff --git a/drivers/media/video/gspca/benq.c b/drivers/media/video/gspca/benq.c
new file mode 100644
index 000000000000..43ac4af8d3ed
--- /dev/null
+++ b/drivers/media/video/gspca/benq.c
@@ -0,0 +1,322 @@
1/*
2 * Benq DC E300 subdriver
3 *
4 * Copyright (C) 2009 Jean-Francois Moine (http://moinejf.free.fr)
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 * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21#define MODULE_NAME "benq"
22
23#include "gspca.h"
24
25MODULE_AUTHOR("Jean-Francois Moine <http://moinejf.free.fr>");
26MODULE_DESCRIPTION("Benq DC E300 USB Camera Driver");
27MODULE_LICENSE("GPL");
28
29/* specific webcam descriptor */
30struct sd {
31 struct gspca_dev gspca_dev; /* !! must be the first item */
32};
33
34/* V4L2 controls supported by the driver */
35static const struct ctrl sd_ctrls[] = {
36};
37
38static const struct v4l2_pix_format vga_mode[] = {
39 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
40 .bytesperline = 320,
41 .sizeimage = 320 * 240 * 3 / 8 + 590,
42 .colorspace = V4L2_COLORSPACE_JPEG},
43};
44
45static void sd_isoc_irq(struct urb *urb);
46
47/* -- write a register -- */
48static void reg_w(struct gspca_dev *gspca_dev,
49 u16 value, u16 index)
50{
51 struct usb_device *dev = gspca_dev->dev;
52 int ret;
53
54 if (gspca_dev->usb_err < 0)
55 return;
56 ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
57 0x02,
58 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
59 value,
60 index,
61 NULL,
62 0,
63 500);
64 if (ret < 0) {
65 PDEBUG(D_ERR, "reg_w err %d", ret);
66 gspca_dev->usb_err = ret;
67 }
68}
69
70/* this function is called at probe time */
71static int sd_config(struct gspca_dev *gspca_dev,
72 const struct usb_device_id *id)
73{
74 gspca_dev->cam.cam_mode = vga_mode;
75 gspca_dev->cam.nmodes = ARRAY_SIZE(vga_mode);
76 gspca_dev->cam.no_urb_create = 1;
77 gspca_dev->cam.reverse_alts = 1;
78 return 0;
79}
80
81/* this function is called at probe and resume time */
82static int sd_init(struct gspca_dev *gspca_dev)
83{
84 return 0;
85}
86
87static int sd_isoc_init(struct gspca_dev *gspca_dev)
88{
89 int ret;
90
91 ret = usb_set_interface(gspca_dev->dev, gspca_dev->iface,
92 gspca_dev->nbalt - 1);
93 if (ret < 0) {
94 err("usb_set_interface failed");
95 return ret;
96 }
97/* reg_w(gspca_dev, 0x0003, 0x0002); */
98 return 0;
99}
100
101/* -- start the camera -- */
102static int sd_start(struct gspca_dev *gspca_dev)
103{
104 struct urb *urb;
105 int i, n;
106
107 /* create 4 URBs - 2 on endpoint 0x83 and 2 on 0x082 */
108#if MAX_NURBS < 4
109#error "Not enough URBs in the gspca table"
110#endif
111#define SD_PKT_SZ 64
112#define SD_NPKT 32
113 for (n = 0; n < 4; n++) {
114 urb = usb_alloc_urb(SD_NPKT, GFP_KERNEL);
115 if (!urb) {
116 err("usb_alloc_urb failed");
117 return -ENOMEM;
118 }
119 gspca_dev->urb[n] = urb;
120 urb->transfer_buffer = usb_buffer_alloc(gspca_dev->dev,
121 SD_PKT_SZ * SD_NPKT,
122 GFP_KERNEL,
123 &urb->transfer_dma);
124
125 if (urb->transfer_buffer == NULL) {
126 err("usb_buffer_alloc failed");
127 return -ENOMEM;
128 }
129 urb->dev = gspca_dev->dev;
130 urb->context = gspca_dev;
131 urb->transfer_buffer_length = SD_PKT_SZ * SD_NPKT;
132 urb->pipe = usb_rcvisocpipe(gspca_dev->dev,
133 n & 1 ? 0x82 : 0x83);
134 urb->transfer_flags = URB_ISO_ASAP
135 | URB_NO_TRANSFER_DMA_MAP;
136 urb->interval = 1;
137 urb->complete = sd_isoc_irq;
138 urb->number_of_packets = SD_NPKT;
139 for (i = 0; i < SD_NPKT; i++) {
140 urb->iso_frame_desc[i].length = SD_PKT_SZ;
141 urb->iso_frame_desc[i].offset = SD_PKT_SZ * i;
142 }
143 }
144
145 return gspca_dev->usb_err;
146}
147
148static void sd_stopN(struct gspca_dev *gspca_dev)
149{
150 reg_w(gspca_dev, 0x003c, 0x0003);
151 reg_w(gspca_dev, 0x003c, 0x0004);
152 reg_w(gspca_dev, 0x003c, 0x0005);
153 reg_w(gspca_dev, 0x003c, 0x0006);
154 reg_w(gspca_dev, 0x003c, 0x0007);
155 usb_set_interface(gspca_dev->dev, gspca_dev->iface, gspca_dev->nbalt - 1);
156}
157
158static void sd_pkt_scan(struct gspca_dev *gspca_dev,
159 u8 *data, /* isoc packet */
160 int len) /* iso packet length */
161{
162 /* unused */
163}
164
165/* reception of an URB */
166static void sd_isoc_irq(struct urb *urb)
167{
168 struct gspca_dev *gspca_dev = (struct gspca_dev *) urb->context;
169 struct urb *urb0;
170 u8 *data;
171 int i, st;
172
173 PDEBUG(D_PACK, "sd isoc irq");
174 if (!gspca_dev->streaming)
175 return;
176 if (urb->status != 0) {
177 if (urb->status == -ESHUTDOWN)
178 return; /* disconnection */
179#ifdef CONFIG_PM
180 if (gspca_dev->frozen)
181 return;
182#endif
183 PDEBUG(D_ERR|D_PACK, "urb status: %d", urb->status);
184 return;
185 }
186
187 /* if this is a control URN (ep 0x83), wait */
188 if (urb == gspca_dev->urb[0] || urb == gspca_dev->urb[2])
189 return;
190
191 /* scan both received URBs */
192 if (urb == gspca_dev->urb[1])
193 urb0 = gspca_dev->urb[0];
194 else
195 urb0 = gspca_dev->urb[2];
196 for (i = 0; i < urb->number_of_packets; i++) {
197
198 /* check the packet status and length */
199 if (urb0->iso_frame_desc[i].actual_length != SD_PKT_SZ
200 || urb->iso_frame_desc[i].actual_length != SD_PKT_SZ) {
201 PDEBUG(D_ERR, "ISOC bad lengths %d / %d",
202 urb0->iso_frame_desc[i].actual_length,
203 urb->iso_frame_desc[i].actual_length);
204 gspca_dev->last_packet_type = DISCARD_PACKET;
205 continue;
206 }
207 st = urb0->iso_frame_desc[i].status;
208 if (st == 0)
209 st = urb->iso_frame_desc[i].status;
210 if (st) {
211 PDEBUG(D_ERR,
212 "ISOC data error: [%d] status=%d",
213 i, st);
214 gspca_dev->last_packet_type = DISCARD_PACKET;
215 continue;
216 }
217
218 /*
219 * The images are received in URBs of different endpoints
220 * (0x83 and 0x82).
221 * Image pieces in URBs of ep 0x83 are continuated in URBs of
222 * ep 0x82 of the same index.
223 * The packets in the URBs of endpoint 0x83 start with:
224 * - 80 ba/bb 00 00 = start of image followed by 'ff d8'
225 * - 04 ba/bb oo oo = image piece
226 * where 'oo oo' is the image offset
227 (not cheked)
228 * - (other -> bad frame)
229 * The images are JPEG encoded with full header and
230 * normal ff escape.
231 * The end of image ('ff d9') may occur in any URB.
232 * (not cheked)
233 */
234 data = (u8 *) urb0->transfer_buffer
235 + urb0->iso_frame_desc[i].offset;
236 if (data[0] == 0x80 && (data[1] & 0xfe) == 0xba) {
237
238 /* new image */
239 gspca_frame_add(gspca_dev, LAST_PACKET,
240 NULL, 0);
241 gspca_frame_add(gspca_dev, FIRST_PACKET,
242 data + 4, SD_PKT_SZ - 4);
243 } else if (data[0] == 0x04 && (data[1] & 0xfe) == 0xba) {
244 gspca_frame_add(gspca_dev, INTER_PACKET,
245 data + 4, SD_PKT_SZ - 4);
246 } else {
247 gspca_dev->last_packet_type = DISCARD_PACKET;
248 continue;
249 }
250 data = (u8 *) urb->transfer_buffer
251 + urb->iso_frame_desc[i].offset;
252 gspca_frame_add(gspca_dev, INTER_PACKET,
253 data, SD_PKT_SZ);
254 }
255
256 /* resubmit the URBs */
257 st = usb_submit_urb(urb0, GFP_ATOMIC);
258 if (st < 0)
259 PDEBUG(D_ERR|D_PACK, "usb_submit_urb(0) ret %d", st);
260 st = usb_submit_urb(urb, GFP_ATOMIC);
261 if (st < 0)
262 PDEBUG(D_ERR|D_PACK, "usb_submit_urb() ret %d", st);
263}
264
265/* sub-driver description */
266static const struct sd_desc sd_desc = {
267 .name = MODULE_NAME,
268 .ctrls = sd_ctrls,
269 .nctrls = ARRAY_SIZE(sd_ctrls),
270 .config = sd_config,
271 .init = sd_init,
272 .isoc_init = sd_isoc_init,
273 .start = sd_start,
274 .stopN = sd_stopN,
275 .pkt_scan = sd_pkt_scan,
276};
277
278/* -- module initialisation -- */
279static const __devinitdata struct usb_device_id device_table[] = {
280 {USB_DEVICE(0x04a5, 0x3035)},
281 {}
282};
283MODULE_DEVICE_TABLE(usb, device_table);
284
285/* -- device connect -- */
286static int sd_probe(struct usb_interface *intf,
287 const struct usb_device_id *id)
288{
289 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
290 THIS_MODULE);
291}
292
293static struct usb_driver sd_driver = {
294 .name = MODULE_NAME,
295 .id_table = device_table,
296 .probe = sd_probe,
297 .disconnect = gspca_disconnect,
298#ifdef CONFIG_PM
299 .suspend = gspca_suspend,
300 .resume = gspca_resume,
301#endif
302};
303
304/* -- module insert / remove -- */
305static int __init sd_mod_init(void)
306{
307 int ret;
308
309 ret = usb_register(&sd_driver);
310 if (ret < 0)
311 return ret;
312 info("registered");
313 return 0;
314}
315static void __exit sd_mod_exit(void)
316{
317 usb_deregister(&sd_driver);
318 info("deregistered");
319}
320
321module_init(sd_mod_init);
322module_exit(sd_mod_exit);
diff --git a/drivers/media/video/gspca/coarse_expo_autogain.h b/drivers/media/video/gspca/coarse_expo_autogain.h
new file mode 100644
index 000000000000..1cb9d941eaf6
--- /dev/null
+++ b/drivers/media/video/gspca/coarse_expo_autogain.h
@@ -0,0 +1,116 @@
1/*
2 * Auto gain algorithm for camera's with a coarse exposure control
3 *
4 * Copyright (C) 2010 Hans de Goede <hdegoede@redhat.com>
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21/* Autogain + exposure algorithm for cameras with a coarse exposure control
22 (usually this means we can only control the clockdiv to change exposure)
23 As changing the clockdiv so that the fps drops from 30 to 15 fps for
24 example, will lead to a huge exposure change (it effectively doubles),
25 this algorithm normally tries to only adjust the gain (between 40 and
26 80 %) and if that does not help, only then changes exposure. This leads
27 to a much more stable image then using the knee algorithm which at
28 certain points of the knee graph will only try to adjust exposure,
29 which leads to oscilating as one exposure step is huge.
30
31 Note this assumes that the sd struct for the cam in question has
32 exp_too_high_cnt and exp_too_high_cnt int members for use by this function.
33
34 Returns 0 if no changes were made, 1 if the gain and or exposure settings
35 where changed. */
36static int gspca_coarse_grained_expo_autogain(struct gspca_dev *gspca_dev,
37 int avg_lum, int desired_avg_lum, int deadzone)
38{
39 int i, steps, gain, orig_gain, exposure, orig_exposure;
40 int gain_low, gain_high;
41 const struct ctrl *gain_ctrl = NULL;
42 const struct ctrl *exposure_ctrl = NULL;
43 struct sd *sd = (struct sd *) gspca_dev;
44 int retval = 0;
45
46 for (i = 0; i < gspca_dev->sd_desc->nctrls; i++) {
47 if (gspca_dev->ctrl_dis & (1 << i))
48 continue;
49 if (gspca_dev->sd_desc->ctrls[i].qctrl.id == V4L2_CID_GAIN)
50 gain_ctrl = &gspca_dev->sd_desc->ctrls[i];
51 if (gspca_dev->sd_desc->ctrls[i].qctrl.id == V4L2_CID_EXPOSURE)
52 exposure_ctrl = &gspca_dev->sd_desc->ctrls[i];
53 }
54 if (!gain_ctrl || !exposure_ctrl) {
55 PDEBUG(D_ERR, "Error: gspca_coarse_grained_expo_autogain "
56 "called on cam without gain or exposure");
57 return 0;
58 }
59
60 if (gain_ctrl->get(gspca_dev, &gain) ||
61 exposure_ctrl->get(gspca_dev, &exposure))
62 return 0;
63
64 orig_gain = gain;
65 orig_exposure = exposure;
66 gain_low =
67 (gain_ctrl->qctrl.maximum - gain_ctrl->qctrl.minimum) / 5 * 2;
68 gain_low += gain_ctrl->qctrl.minimum;
69 gain_high =
70 (gain_ctrl->qctrl.maximum - gain_ctrl->qctrl.minimum) / 5 * 4;
71 gain_high += gain_ctrl->qctrl.minimum;
72
73 /* If we are of a multiple of deadzone, do multiple steps to reach the
74 desired lumination fast (with the risc of a slight overshoot) */
75 steps = (desired_avg_lum - avg_lum) / deadzone;
76
77 PDEBUG(D_FRAM, "autogain: lum: %d, desired: %d, steps: %d",
78 avg_lum, desired_avg_lum, steps);
79
80 if ((gain + steps) > gain_high &&
81 sd->exposure < exposure_ctrl->qctrl.maximum) {
82 gain = gain_high;
83 sd->exp_too_low_cnt++;
84 } else if ((gain + steps) < gain_low &&
85 sd->exposure > exposure_ctrl->qctrl.minimum) {
86 gain = gain_low;
87 sd->exp_too_high_cnt++;
88 } else {
89 gain += steps;
90 if (gain > gain_ctrl->qctrl.maximum)
91 gain = gain_ctrl->qctrl.maximum;
92 else if (gain < gain_ctrl->qctrl.minimum)
93 gain = gain_ctrl->qctrl.minimum;
94 sd->exp_too_high_cnt = 0;
95 sd->exp_too_low_cnt = 0;
96 }
97
98 if (sd->exp_too_high_cnt > 3) {
99 exposure--;
100 sd->exp_too_high_cnt = 0;
101 } else if (sd->exp_too_low_cnt > 3) {
102 exposure++;
103 sd->exp_too_low_cnt = 0;
104 }
105
106 if (gain != orig_gain) {
107 gain_ctrl->set(gspca_dev, gain);
108 retval = 1;
109 }
110 if (exposure != orig_exposure) {
111 exposure_ctrl->set(gspca_dev, exposure);
112 retval = 1;
113 }
114
115 return retval;
116}
diff --git a/drivers/media/video/gspca/conex.c b/drivers/media/video/gspca/conex.c
index c98b5d69c438..19fe6b24c9a3 100644
--- a/drivers/media/video/gspca/conex.c
+++ b/drivers/media/video/gspca/conex.c
@@ -52,7 +52,7 @@ static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
52static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val); 52static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val);
53static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val); 53static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val);
54 54
55static struct ctrl sd_ctrls[] = { 55static const struct ctrl sd_ctrls[] = {
56 { 56 {
57 { 57 {
58 .id = V4L2_CID_BRIGHTNESS, 58 .id = V4L2_CID_BRIGHTNESS,
@@ -1032,7 +1032,7 @@ static int sd_get_jcomp(struct gspca_dev *gspca_dev,
1032} 1032}
1033 1033
1034/* sub-driver description */ 1034/* sub-driver description */
1035static struct sd_desc sd_desc = { 1035static const struct sd_desc sd_desc = {
1036 .name = MODULE_NAME, 1036 .name = MODULE_NAME,
1037 .ctrls = sd_ctrls, 1037 .ctrls = sd_ctrls,
1038 .nctrls = ARRAY_SIZE(sd_ctrls), 1038 .nctrls = ARRAY_SIZE(sd_ctrls),
diff --git a/drivers/media/video/gspca/cpia1.c b/drivers/media/video/gspca/cpia1.c
new file mode 100644
index 000000000000..82945ed5cbe5
--- /dev/null
+++ b/drivers/media/video/gspca/cpia1.c
@@ -0,0 +1,2022 @@
1/*
2 * cpia CPiA (1) gspca driver
3 *
4 * Copyright (C) 2010 Hans de Goede <hdgoede@redhat.com>
5 *
6 * This module is adapted from the in kernel v4l1 cpia driver which is :
7 *
8 * (C) Copyright 1999-2000 Peter Pregler
9 * (C) Copyright 1999-2000 Scott J. Bertin
10 * (C) Copyright 1999-2000 Johannes Erdfelt <johannes@erdfelt.com>
11 * (C) Copyright 2000 STMicroelectronics
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
17 *
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26 *
27 */
28
29#define MODULE_NAME "cpia1"
30
31#include "gspca.h"
32
33MODULE_AUTHOR("Hans de Goede <hdgoede@redhat.com>");
34MODULE_DESCRIPTION("Vision CPiA");
35MODULE_LICENSE("GPL");
36
37/* constant value's */
38#define MAGIC_0 0x19
39#define MAGIC_1 0x68
40#define DATA_IN 0xC0
41#define DATA_OUT 0x40
42#define VIDEOSIZE_QCIF 0 /* 176x144 */
43#define VIDEOSIZE_CIF 1 /* 352x288 */
44#define SUBSAMPLE_420 0
45#define SUBSAMPLE_422 1
46#define YUVORDER_YUYV 0
47#define YUVORDER_UYVY 1
48#define NOT_COMPRESSED 0
49#define COMPRESSED 1
50#define NO_DECIMATION 0
51#define DECIMATION_ENAB 1
52#define EOI 0xff /* End Of Image */
53#define EOL 0xfd /* End Of Line */
54#define FRAME_HEADER_SIZE 64
55
56/* Image grab modes */
57#define CPIA_GRAB_SINGLE 0
58#define CPIA_GRAB_CONTINEOUS 1
59
60/* Compression parameters */
61#define CPIA_COMPRESSION_NONE 0
62#define CPIA_COMPRESSION_AUTO 1
63#define CPIA_COMPRESSION_MANUAL 2
64#define CPIA_COMPRESSION_TARGET_QUALITY 0
65#define CPIA_COMPRESSION_TARGET_FRAMERATE 1
66
67/* Return offsets for GetCameraState */
68#define SYSTEMSTATE 0
69#define GRABSTATE 1
70#define STREAMSTATE 2
71#define FATALERROR 3
72#define CMDERROR 4
73#define DEBUGFLAGS 5
74#define VPSTATUS 6
75#define ERRORCODE 7
76
77/* SystemState */
78#define UNINITIALISED_STATE 0
79#define PASS_THROUGH_STATE 1
80#define LO_POWER_STATE 2
81#define HI_POWER_STATE 3
82#define WARM_BOOT_STATE 4
83
84/* GrabState */
85#define GRAB_IDLE 0
86#define GRAB_ACTIVE 1
87#define GRAB_DONE 2
88
89/* StreamState */
90#define STREAM_NOT_READY 0
91#define STREAM_READY 1
92#define STREAM_OPEN 2
93#define STREAM_PAUSED 3
94#define STREAM_FINISHED 4
95
96/* Fatal Error, CmdError, and DebugFlags */
97#define CPIA_FLAG 1
98#define SYSTEM_FLAG 2
99#define INT_CTRL_FLAG 4
100#define PROCESS_FLAG 8
101#define COM_FLAG 16
102#define VP_CTRL_FLAG 32
103#define CAPTURE_FLAG 64
104#define DEBUG_FLAG 128
105
106/* VPStatus */
107#define VP_STATE_OK 0x00
108
109#define VP_STATE_FAILED_VIDEOINIT 0x01
110#define VP_STATE_FAILED_AECACBINIT 0x02
111#define VP_STATE_AEC_MAX 0x04
112#define VP_STATE_ACB_BMAX 0x08
113
114#define VP_STATE_ACB_RMIN 0x10
115#define VP_STATE_ACB_GMIN 0x20
116#define VP_STATE_ACB_RMAX 0x40
117#define VP_STATE_ACB_GMAX 0x80
118
119/* default (minimum) compensation values */
120#define COMP_RED 220
121#define COMP_GREEN1 214
122#define COMP_GREEN2 COMP_GREEN1
123#define COMP_BLUE 230
124
125/* exposure status */
126#define EXPOSURE_VERY_LIGHT 0
127#define EXPOSURE_LIGHT 1
128#define EXPOSURE_NORMAL 2
129#define EXPOSURE_DARK 3
130#define EXPOSURE_VERY_DARK 4
131
132#define CPIA_MODULE_CPIA (0 << 5)
133#define CPIA_MODULE_SYSTEM (1 << 5)
134#define CPIA_MODULE_VP_CTRL (5 << 5)
135#define CPIA_MODULE_CAPTURE (6 << 5)
136#define CPIA_MODULE_DEBUG (7 << 5)
137
138#define INPUT (DATA_IN << 8)
139#define OUTPUT (DATA_OUT << 8)
140
141#define CPIA_COMMAND_GetCPIAVersion (INPUT | CPIA_MODULE_CPIA | 1)
142#define CPIA_COMMAND_GetPnPID (INPUT | CPIA_MODULE_CPIA | 2)
143#define CPIA_COMMAND_GetCameraStatus (INPUT | CPIA_MODULE_CPIA | 3)
144#define CPIA_COMMAND_GotoHiPower (OUTPUT | CPIA_MODULE_CPIA | 4)
145#define CPIA_COMMAND_GotoLoPower (OUTPUT | CPIA_MODULE_CPIA | 5)
146#define CPIA_COMMAND_GotoSuspend (OUTPUT | CPIA_MODULE_CPIA | 7)
147#define CPIA_COMMAND_GotoPassThrough (OUTPUT | CPIA_MODULE_CPIA | 8)
148#define CPIA_COMMAND_ModifyCameraStatus (OUTPUT | CPIA_MODULE_CPIA | 10)
149
150#define CPIA_COMMAND_ReadVCRegs (INPUT | CPIA_MODULE_SYSTEM | 1)
151#define CPIA_COMMAND_WriteVCReg (OUTPUT | CPIA_MODULE_SYSTEM | 2)
152#define CPIA_COMMAND_ReadMCPorts (INPUT | CPIA_MODULE_SYSTEM | 3)
153#define CPIA_COMMAND_WriteMCPort (OUTPUT | CPIA_MODULE_SYSTEM | 4)
154#define CPIA_COMMAND_SetBaudRate (OUTPUT | CPIA_MODULE_SYSTEM | 5)
155#define CPIA_COMMAND_SetECPTiming (OUTPUT | CPIA_MODULE_SYSTEM | 6)
156#define CPIA_COMMAND_ReadIDATA (INPUT | CPIA_MODULE_SYSTEM | 7)
157#define CPIA_COMMAND_WriteIDATA (OUTPUT | CPIA_MODULE_SYSTEM | 8)
158#define CPIA_COMMAND_GenericCall (OUTPUT | CPIA_MODULE_SYSTEM | 9)
159#define CPIA_COMMAND_I2CStart (OUTPUT | CPIA_MODULE_SYSTEM | 10)
160#define CPIA_COMMAND_I2CStop (OUTPUT | CPIA_MODULE_SYSTEM | 11)
161#define CPIA_COMMAND_I2CWrite (OUTPUT | CPIA_MODULE_SYSTEM | 12)
162#define CPIA_COMMAND_I2CRead (INPUT | CPIA_MODULE_SYSTEM | 13)
163
164#define CPIA_COMMAND_GetVPVersion (INPUT | CPIA_MODULE_VP_CTRL | 1)
165#define CPIA_COMMAND_ResetFrameCounter (INPUT | CPIA_MODULE_VP_CTRL | 2)
166#define CPIA_COMMAND_SetColourParams (OUTPUT | CPIA_MODULE_VP_CTRL | 3)
167#define CPIA_COMMAND_SetExposure (OUTPUT | CPIA_MODULE_VP_CTRL | 4)
168#define CPIA_COMMAND_SetColourBalance (OUTPUT | CPIA_MODULE_VP_CTRL | 6)
169#define CPIA_COMMAND_SetSensorFPS (OUTPUT | CPIA_MODULE_VP_CTRL | 7)
170#define CPIA_COMMAND_SetVPDefaults (OUTPUT | CPIA_MODULE_VP_CTRL | 8)
171#define CPIA_COMMAND_SetApcor (OUTPUT | CPIA_MODULE_VP_CTRL | 9)
172#define CPIA_COMMAND_SetFlickerCtrl (OUTPUT | CPIA_MODULE_VP_CTRL | 10)
173#define CPIA_COMMAND_SetVLOffset (OUTPUT | CPIA_MODULE_VP_CTRL | 11)
174#define CPIA_COMMAND_GetColourParams (INPUT | CPIA_MODULE_VP_CTRL | 16)
175#define CPIA_COMMAND_GetColourBalance (INPUT | CPIA_MODULE_VP_CTRL | 17)
176#define CPIA_COMMAND_GetExposure (INPUT | CPIA_MODULE_VP_CTRL | 18)
177#define CPIA_COMMAND_SetSensorMatrix (OUTPUT | CPIA_MODULE_VP_CTRL | 19)
178#define CPIA_COMMAND_ColourBars (OUTPUT | CPIA_MODULE_VP_CTRL | 25)
179#define CPIA_COMMAND_ReadVPRegs (INPUT | CPIA_MODULE_VP_CTRL | 30)
180#define CPIA_COMMAND_WriteVPReg (OUTPUT | CPIA_MODULE_VP_CTRL | 31)
181
182#define CPIA_COMMAND_GrabFrame (OUTPUT | CPIA_MODULE_CAPTURE | 1)
183#define CPIA_COMMAND_UploadFrame (OUTPUT | CPIA_MODULE_CAPTURE | 2)
184#define CPIA_COMMAND_SetGrabMode (OUTPUT | CPIA_MODULE_CAPTURE | 3)
185#define CPIA_COMMAND_InitStreamCap (OUTPUT | CPIA_MODULE_CAPTURE | 4)
186#define CPIA_COMMAND_FiniStreamCap (OUTPUT | CPIA_MODULE_CAPTURE | 5)
187#define CPIA_COMMAND_StartStreamCap (OUTPUT | CPIA_MODULE_CAPTURE | 6)
188#define CPIA_COMMAND_EndStreamCap (OUTPUT | CPIA_MODULE_CAPTURE | 7)
189#define CPIA_COMMAND_SetFormat (OUTPUT | CPIA_MODULE_CAPTURE | 8)
190#define CPIA_COMMAND_SetROI (OUTPUT | CPIA_MODULE_CAPTURE | 9)
191#define CPIA_COMMAND_SetCompression (OUTPUT | CPIA_MODULE_CAPTURE | 10)
192#define CPIA_COMMAND_SetCompressionTarget (OUTPUT | CPIA_MODULE_CAPTURE | 11)
193#define CPIA_COMMAND_SetYUVThresh (OUTPUT | CPIA_MODULE_CAPTURE | 12)
194#define CPIA_COMMAND_SetCompressionParams (OUTPUT | CPIA_MODULE_CAPTURE | 13)
195#define CPIA_COMMAND_DiscardFrame (OUTPUT | CPIA_MODULE_CAPTURE | 14)
196#define CPIA_COMMAND_GrabReset (OUTPUT | CPIA_MODULE_CAPTURE | 15)
197
198#define CPIA_COMMAND_OutputRS232 (OUTPUT | CPIA_MODULE_DEBUG | 1)
199#define CPIA_COMMAND_AbortProcess (OUTPUT | CPIA_MODULE_DEBUG | 4)
200#define CPIA_COMMAND_SetDramPage (OUTPUT | CPIA_MODULE_DEBUG | 5)
201#define CPIA_COMMAND_StartDramUpload (OUTPUT | CPIA_MODULE_DEBUG | 6)
202#define CPIA_COMMAND_StartDummyDtream (OUTPUT | CPIA_MODULE_DEBUG | 8)
203#define CPIA_COMMAND_AbortStream (OUTPUT | CPIA_MODULE_DEBUG | 9)
204#define CPIA_COMMAND_DownloadDRAM (OUTPUT | CPIA_MODULE_DEBUG | 10)
205#define CPIA_COMMAND_Null (OUTPUT | CPIA_MODULE_DEBUG | 11)
206
207#define ROUND_UP_EXP_FOR_FLICKER 15
208
209/* Constants for automatic frame rate adjustment */
210#define MAX_EXP 302
211#define MAX_EXP_102 255
212#define LOW_EXP 140
213#define VERY_LOW_EXP 70
214#define TC 94
215#define EXP_ACC_DARK 50
216#define EXP_ACC_LIGHT 90
217#define HIGH_COMP_102 160
218#define MAX_COMP 239
219#define DARK_TIME 3
220#define LIGHT_TIME 3
221
222#define FIRMWARE_VERSION(x, y) (sd->params.version.firmwareVersion == (x) && \
223 sd->params.version.firmwareRevision == (y))
224
225/* Developer's Guide Table 5 p 3-34
226 * indexed by [mains][sensorFps.baserate][sensorFps.divisor]*/
227static u8 flicker_jumps[2][2][4] =
228{ { { 76, 38, 19, 9 }, { 92, 46, 23, 11 } },
229 { { 64, 32, 16, 8 }, { 76, 38, 19, 9} }
230};
231
232struct cam_params {
233 struct {
234 u8 firmwareVersion;
235 u8 firmwareRevision;
236 u8 vcVersion;
237 u8 vcRevision;
238 } version;
239 struct {
240 u16 vendor;
241 u16 product;
242 u16 deviceRevision;
243 } pnpID;
244 struct {
245 u8 vpVersion;
246 u8 vpRevision;
247 u16 cameraHeadID;
248 } vpVersion;
249 struct {
250 u8 systemState;
251 u8 grabState;
252 u8 streamState;
253 u8 fatalError;
254 u8 cmdError;
255 u8 debugFlags;
256 u8 vpStatus;
257 u8 errorCode;
258 } status;
259 struct {
260 u8 brightness;
261 u8 contrast;
262 u8 saturation;
263 } colourParams;
264 struct {
265 u8 gainMode;
266 u8 expMode;
267 u8 compMode;
268 u8 centreWeight;
269 u8 gain;
270 u8 fineExp;
271 u8 coarseExpLo;
272 u8 coarseExpHi;
273 u8 redComp;
274 u8 green1Comp;
275 u8 green2Comp;
276 u8 blueComp;
277 } exposure;
278 struct {
279 u8 balanceMode;
280 u8 redGain;
281 u8 greenGain;
282 u8 blueGain;
283 } colourBalance;
284 struct {
285 u8 divisor;
286 u8 baserate;
287 } sensorFps;
288 struct {
289 u8 gain1;
290 u8 gain2;
291 u8 gain4;
292 u8 gain8;
293 } apcor;
294 struct {
295 u8 disabled;
296 u8 flickerMode;
297 u8 coarseJump;
298 u8 allowableOverExposure;
299 } flickerControl;
300 struct {
301 u8 gain1;
302 u8 gain2;
303 u8 gain4;
304 u8 gain8;
305 } vlOffset;
306 struct {
307 u8 mode;
308 u8 decimation;
309 } compression;
310 struct {
311 u8 frTargeting;
312 u8 targetFR;
313 u8 targetQ;
314 } compressionTarget;
315 struct {
316 u8 yThreshold;
317 u8 uvThreshold;
318 } yuvThreshold;
319 struct {
320 u8 hysteresis;
321 u8 threshMax;
322 u8 smallStep;
323 u8 largeStep;
324 u8 decimationHysteresis;
325 u8 frDiffStepThresh;
326 u8 qDiffStepThresh;
327 u8 decimationThreshMod;
328 } compressionParams;
329 struct {
330 u8 videoSize; /* CIF/QCIF */
331 u8 subSample;
332 u8 yuvOrder;
333 } format;
334 struct { /* Intel QX3 specific data */
335 u8 qx3_detected; /* a QX3 is present */
336 u8 toplight; /* top light lit , R/W */
337 u8 bottomlight; /* bottom light lit, R/W */
338 u8 button; /* snapshot button pressed (R/O) */
339 u8 cradled; /* microscope is in cradle (R/O) */
340 } qx3;
341 struct {
342 u8 colStart; /* skip first 8*colStart pixels */
343 u8 colEnd; /* finish at 8*colEnd pixels */
344 u8 rowStart; /* skip first 4*rowStart lines */
345 u8 rowEnd; /* finish at 4*rowEnd lines */
346 } roi;
347 u8 ecpTiming;
348 u8 streamStartLine;
349};
350
351/* specific webcam descriptor */
352struct sd {
353 struct gspca_dev gspca_dev; /* !! must be the first item */
354 struct cam_params params; /* camera settings */
355
356 atomic_t cam_exposure;
357 atomic_t fps;
358 int exposure_count;
359 u8 exposure_status;
360 u8 mainsFreq; /* 0 = 50hz, 1 = 60hz */
361 u8 first_frame;
362 u8 freq;
363};
364
365/* V4L2 controls supported by the driver */
366static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
367static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
368static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
369static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
370static int sd_setsaturation(struct gspca_dev *gspca_dev, __s32 val);
371static int sd_getsaturation(struct gspca_dev *gspca_dev, __s32 *val);
372static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val);
373static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val);
374static int sd_setcomptarget(struct gspca_dev *gspca_dev, __s32 val);
375static int sd_getcomptarget(struct gspca_dev *gspca_dev, __s32 *val);
376
377static struct ctrl sd_ctrls[] = {
378 {
379 {
380 .id = V4L2_CID_BRIGHTNESS,
381 .type = V4L2_CTRL_TYPE_INTEGER,
382 .name = "Brightness",
383 .minimum = 0,
384 .maximum = 100,
385 .step = 1,
386#define BRIGHTNESS_DEF 50
387 .default_value = BRIGHTNESS_DEF,
388 .flags = 0,
389 },
390 .set = sd_setbrightness,
391 .get = sd_getbrightness,
392 },
393 {
394 {
395 .id = V4L2_CID_CONTRAST,
396 .type = V4L2_CTRL_TYPE_INTEGER,
397 .name = "Contrast",
398 .minimum = 0,
399 .maximum = 96,
400 .step = 8,
401#define CONTRAST_DEF 48
402 .default_value = CONTRAST_DEF,
403 },
404 .set = sd_setcontrast,
405 .get = sd_getcontrast,
406 },
407 {
408 {
409 .id = V4L2_CID_SATURATION,
410 .type = V4L2_CTRL_TYPE_INTEGER,
411 .name = "Saturation",
412 .minimum = 0,
413 .maximum = 100,
414 .step = 1,
415#define SATURATION_DEF 50
416 .default_value = SATURATION_DEF,
417 },
418 .set = sd_setsaturation,
419 .get = sd_getsaturation,
420 },
421 {
422 {
423 .id = V4L2_CID_POWER_LINE_FREQUENCY,
424 .type = V4L2_CTRL_TYPE_MENU,
425 .name = "Light frequency filter",
426 .minimum = 0,
427 .maximum = 2, /* 0: 0, 1: 50Hz, 2:60Hz */
428 .step = 1,
429#define FREQ_DEF 1
430 .default_value = FREQ_DEF,
431 },
432 .set = sd_setfreq,
433 .get = sd_getfreq,
434 },
435 {
436 {
437#define V4L2_CID_COMP_TARGET V4L2_CID_PRIVATE_BASE
438 .id = V4L2_CID_COMP_TARGET,
439 .type = V4L2_CTRL_TYPE_MENU,
440 .name = "Compression Target",
441 .minimum = 0,
442 .maximum = 1,
443 .step = 1,
444#define COMP_TARGET_DEF CPIA_COMPRESSION_TARGET_QUALITY
445 .default_value = COMP_TARGET_DEF,
446 },
447 .set = sd_setcomptarget,
448 .get = sd_getcomptarget,
449 },
450};
451
452static const struct v4l2_pix_format mode[] = {
453 {160, 120, V4L2_PIX_FMT_CPIA1, V4L2_FIELD_NONE,
454 /* The sizeimage is trial and error, as with low framerates
455 the camera will pad out usb frames, making the image
456 data larger then strictly necessary */
457 .bytesperline = 160,
458 .sizeimage = 65536,
459 .colorspace = V4L2_COLORSPACE_SRGB,
460 .priv = 3},
461 {176, 144, V4L2_PIX_FMT_CPIA1, V4L2_FIELD_NONE,
462 .bytesperline = 172,
463 .sizeimage = 65536,
464 .colorspace = V4L2_COLORSPACE_SRGB,
465 .priv = 2},
466 {320, 240, V4L2_PIX_FMT_CPIA1, V4L2_FIELD_NONE,
467 .bytesperline = 320,
468 .sizeimage = 262144,
469 .colorspace = V4L2_COLORSPACE_SRGB,
470 .priv = 1},
471 {352, 288, V4L2_PIX_FMT_CPIA1, V4L2_FIELD_NONE,
472 .bytesperline = 352,
473 .sizeimage = 262144,
474 .colorspace = V4L2_COLORSPACE_SRGB,
475 .priv = 0},
476};
477
478/**********************************************************************
479 *
480 * General functions
481 *
482 **********************************************************************/
483
484static int cpia_usb_transferCmd(struct gspca_dev *gspca_dev, u8 *command)
485{
486 u8 requesttype;
487 unsigned int pipe;
488 int ret, databytes = command[6] | (command[7] << 8);
489 /* Sometimes we see spurious EPIPE errors */
490 int retries = 3;
491
492 if (command[0] == DATA_IN) {
493 pipe = usb_rcvctrlpipe(gspca_dev->dev, 0);
494 requesttype = USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE;
495 } else if (command[0] == DATA_OUT) {
496 pipe = usb_sndctrlpipe(gspca_dev->dev, 0);
497 requesttype = USB_TYPE_VENDOR | USB_RECIP_DEVICE;
498 } else {
499 PDEBUG(D_ERR, "Unexpected first byte of command: %x",
500 command[0]);
501 return -EINVAL;
502 }
503
504retry:
505 ret = usb_control_msg(gspca_dev->dev, pipe,
506 command[1],
507 requesttype,
508 command[2] | (command[3] << 8),
509 command[4] | (command[5] << 8),
510 gspca_dev->usb_buf, databytes, 1000);
511
512 if (ret < 0)
513 PDEBUG(D_ERR, "usb_control_msg %02x, error %d", command[1],
514 ret);
515
516 if (ret == -EPIPE && retries > 0) {
517 retries--;
518 goto retry;
519 }
520
521 return (ret < 0) ? ret : 0;
522}
523
524/* send an arbitrary command to the camera */
525static int do_command(struct gspca_dev *gspca_dev, u16 command,
526 u8 a, u8 b, u8 c, u8 d)
527{
528 struct sd *sd = (struct sd *) gspca_dev;
529 int ret, datasize;
530 u8 cmd[8];
531
532 switch (command) {
533 case CPIA_COMMAND_GetCPIAVersion:
534 case CPIA_COMMAND_GetPnPID:
535 case CPIA_COMMAND_GetCameraStatus:
536 case CPIA_COMMAND_GetVPVersion:
537 case CPIA_COMMAND_GetColourParams:
538 case CPIA_COMMAND_GetColourBalance:
539 case CPIA_COMMAND_GetExposure:
540 datasize = 8;
541 break;
542 case CPIA_COMMAND_ReadMCPorts:
543 case CPIA_COMMAND_ReadVCRegs:
544 datasize = 4;
545 break;
546 default:
547 datasize = 0;
548 break;
549 }
550
551 cmd[0] = command >> 8;
552 cmd[1] = command & 0xff;
553 cmd[2] = a;
554 cmd[3] = b;
555 cmd[4] = c;
556 cmd[5] = d;
557 cmd[6] = datasize;
558 cmd[7] = 0;
559
560 ret = cpia_usb_transferCmd(gspca_dev, cmd);
561 if (ret)
562 return ret;
563
564 switch (command) {
565 case CPIA_COMMAND_GetCPIAVersion:
566 sd->params.version.firmwareVersion = gspca_dev->usb_buf[0];
567 sd->params.version.firmwareRevision = gspca_dev->usb_buf[1];
568 sd->params.version.vcVersion = gspca_dev->usb_buf[2];
569 sd->params.version.vcRevision = gspca_dev->usb_buf[3];
570 break;
571 case CPIA_COMMAND_GetPnPID:
572 sd->params.pnpID.vendor =
573 gspca_dev->usb_buf[0] | (gspca_dev->usb_buf[1] << 8);
574 sd->params.pnpID.product =
575 gspca_dev->usb_buf[2] | (gspca_dev->usb_buf[3] << 8);
576 sd->params.pnpID.deviceRevision =
577 gspca_dev->usb_buf[4] | (gspca_dev->usb_buf[5] << 8);
578 break;
579 case CPIA_COMMAND_GetCameraStatus:
580 sd->params.status.systemState = gspca_dev->usb_buf[0];
581 sd->params.status.grabState = gspca_dev->usb_buf[1];
582 sd->params.status.streamState = gspca_dev->usb_buf[2];
583 sd->params.status.fatalError = gspca_dev->usb_buf[3];
584 sd->params.status.cmdError = gspca_dev->usb_buf[4];
585 sd->params.status.debugFlags = gspca_dev->usb_buf[5];
586 sd->params.status.vpStatus = gspca_dev->usb_buf[6];
587 sd->params.status.errorCode = gspca_dev->usb_buf[7];
588 break;
589 case CPIA_COMMAND_GetVPVersion:
590 sd->params.vpVersion.vpVersion = gspca_dev->usb_buf[0];
591 sd->params.vpVersion.vpRevision = gspca_dev->usb_buf[1];
592 sd->params.vpVersion.cameraHeadID =
593 gspca_dev->usb_buf[2] | (gspca_dev->usb_buf[3] << 8);
594 break;
595 case CPIA_COMMAND_GetColourParams:
596 sd->params.colourParams.brightness = gspca_dev->usb_buf[0];
597 sd->params.colourParams.contrast = gspca_dev->usb_buf[1];
598 sd->params.colourParams.saturation = gspca_dev->usb_buf[2];
599 break;
600 case CPIA_COMMAND_GetColourBalance:
601 sd->params.colourBalance.redGain = gspca_dev->usb_buf[0];
602 sd->params.colourBalance.greenGain = gspca_dev->usb_buf[1];
603 sd->params.colourBalance.blueGain = gspca_dev->usb_buf[2];
604 break;
605 case CPIA_COMMAND_GetExposure:
606 sd->params.exposure.gain = gspca_dev->usb_buf[0];
607 sd->params.exposure.fineExp = gspca_dev->usb_buf[1];
608 sd->params.exposure.coarseExpLo = gspca_dev->usb_buf[2];
609 sd->params.exposure.coarseExpHi = gspca_dev->usb_buf[3];
610 sd->params.exposure.redComp = gspca_dev->usb_buf[4];
611 sd->params.exposure.green1Comp = gspca_dev->usb_buf[5];
612 sd->params.exposure.green2Comp = gspca_dev->usb_buf[6];
613 sd->params.exposure.blueComp = gspca_dev->usb_buf[7];
614 break;
615
616 case CPIA_COMMAND_ReadMCPorts:
617 if (!sd->params.qx3.qx3_detected)
618 break;
619 /* test button press */
620 sd->params.qx3.button = ((gspca_dev->usb_buf[1] & 0x02) == 0);
621 if (sd->params.qx3.button) {
622 /* button pressed - unlock the latch */
623 do_command(gspca_dev, CPIA_COMMAND_WriteMCPort,
624 3, 0xDF, 0xDF, 0);
625 do_command(gspca_dev, CPIA_COMMAND_WriteMCPort,
626 3, 0xFF, 0xFF, 0);
627 }
628
629 /* test whether microscope is cradled */
630 sd->params.qx3.cradled = ((gspca_dev->usb_buf[2] & 0x40) == 0);
631 break;
632 }
633
634 return 0;
635}
636
637/* send a command to the camera with an additional data transaction */
638static int do_command_extended(struct gspca_dev *gspca_dev, u16 command,
639 u8 a, u8 b, u8 c, u8 d,
640 u8 e, u8 f, u8 g, u8 h,
641 u8 i, u8 j, u8 k, u8 l)
642{
643 u8 cmd[8];
644
645 cmd[0] = command >> 8;
646 cmd[1] = command & 0xff;
647 cmd[2] = a;
648 cmd[3] = b;
649 cmd[4] = c;
650 cmd[5] = d;
651 cmd[6] = 8;
652 cmd[7] = 0;
653 gspca_dev->usb_buf[0] = e;
654 gspca_dev->usb_buf[1] = f;
655 gspca_dev->usb_buf[2] = g;
656 gspca_dev->usb_buf[3] = h;
657 gspca_dev->usb_buf[4] = i;
658 gspca_dev->usb_buf[5] = j;
659 gspca_dev->usb_buf[6] = k;
660 gspca_dev->usb_buf[7] = l;
661
662 return cpia_usb_transferCmd(gspca_dev, cmd);
663}
664
665/* find_over_exposure
666 * Finds a suitable value of OverExposure for use with SetFlickerCtrl
667 * Some calculation is required because this value changes with the brightness
668 * set with SetColourParameters
669 *
670 * Parameters: Brightness - last brightness value set with SetColourParameters
671 *
672 * Returns: OverExposure value to use with SetFlickerCtrl
673 */
674#define FLICKER_MAX_EXPOSURE 250
675#define FLICKER_ALLOWABLE_OVER_EXPOSURE 146
676#define FLICKER_BRIGHTNESS_CONSTANT 59
677static int find_over_exposure(int brightness)
678{
679 int MaxAllowableOverExposure, OverExposure;
680
681 MaxAllowableOverExposure = FLICKER_MAX_EXPOSURE - brightness -
682 FLICKER_BRIGHTNESS_CONSTANT;
683
684 if (MaxAllowableOverExposure < FLICKER_ALLOWABLE_OVER_EXPOSURE)
685 OverExposure = MaxAllowableOverExposure;
686 else
687 OverExposure = FLICKER_ALLOWABLE_OVER_EXPOSURE;
688
689 return OverExposure;
690}
691#undef FLICKER_MAX_EXPOSURE
692#undef FLICKER_ALLOWABLE_OVER_EXPOSURE
693#undef FLICKER_BRIGHTNESS_CONSTANT
694
695/* initialise cam_data structure */
696static void reset_camera_params(struct gspca_dev *gspca_dev)
697{
698 struct sd *sd = (struct sd *) gspca_dev;
699 struct cam_params *params = &sd->params;
700
701 /* The following parameter values are the defaults from
702 * "Software Developer's Guide for CPiA Cameras". Any changes
703 * to the defaults are noted in comments. */
704 params->colourParams.brightness = BRIGHTNESS_DEF;
705 params->colourParams.contrast = CONTRAST_DEF;
706 params->colourParams.saturation = SATURATION_DEF;
707 params->exposure.gainMode = 4;
708 params->exposure.expMode = 2; /* AEC */
709 params->exposure.compMode = 1;
710 params->exposure.centreWeight = 1;
711 params->exposure.gain = 0;
712 params->exposure.fineExp = 0;
713 params->exposure.coarseExpLo = 185;
714 params->exposure.coarseExpHi = 0;
715 params->exposure.redComp = COMP_RED;
716 params->exposure.green1Comp = COMP_GREEN1;
717 params->exposure.green2Comp = COMP_GREEN2;
718 params->exposure.blueComp = COMP_BLUE;
719 params->colourBalance.balanceMode = 2; /* ACB */
720 params->colourBalance.redGain = 32;
721 params->colourBalance.greenGain = 6;
722 params->colourBalance.blueGain = 92;
723 params->apcor.gain1 = 0x18;
724 params->apcor.gain2 = 0x16;
725 params->apcor.gain4 = 0x24;
726 params->apcor.gain8 = 0x34;
727 params->flickerControl.flickerMode = 0;
728 params->flickerControl.disabled = 1;
729
730 params->flickerControl.coarseJump =
731 flicker_jumps[sd->mainsFreq]
732 [params->sensorFps.baserate]
733 [params->sensorFps.divisor];
734 params->flickerControl.allowableOverExposure =
735 find_over_exposure(params->colourParams.brightness);
736 params->vlOffset.gain1 = 20;
737 params->vlOffset.gain2 = 24;
738 params->vlOffset.gain4 = 26;
739 params->vlOffset.gain8 = 26;
740 params->compressionParams.hysteresis = 3;
741 params->compressionParams.threshMax = 11;
742 params->compressionParams.smallStep = 1;
743 params->compressionParams.largeStep = 3;
744 params->compressionParams.decimationHysteresis = 2;
745 params->compressionParams.frDiffStepThresh = 5;
746 params->compressionParams.qDiffStepThresh = 3;
747 params->compressionParams.decimationThreshMod = 2;
748 /* End of default values from Software Developer's Guide */
749
750 /* Set Sensor FPS to 15fps. This seems better than 30fps
751 * for indoor lighting. */
752 params->sensorFps.divisor = 1;
753 params->sensorFps.baserate = 1;
754
755 params->yuvThreshold.yThreshold = 6; /* From windows driver */
756 params->yuvThreshold.uvThreshold = 6; /* From windows driver */
757
758 params->format.subSample = SUBSAMPLE_420;
759 params->format.yuvOrder = YUVORDER_YUYV;
760
761 params->compression.mode = CPIA_COMPRESSION_AUTO;
762 params->compression.decimation = NO_DECIMATION;
763
764 params->compressionTarget.frTargeting = COMP_TARGET_DEF;
765 params->compressionTarget.targetFR = 15; /* From windows driver */
766 params->compressionTarget.targetQ = 5; /* From windows driver */
767
768 params->qx3.qx3_detected = 0;
769 params->qx3.toplight = 0;
770 params->qx3.bottomlight = 0;
771 params->qx3.button = 0;
772 params->qx3.cradled = 0;
773}
774
775static void printstatus(struct cam_params *params)
776{
777 PDEBUG(D_PROBE, "status: %02x %02x %02x %02x %02x %02x %02x %02x",
778 params->status.systemState, params->status.grabState,
779 params->status.streamState, params->status.fatalError,
780 params->status.cmdError, params->status.debugFlags,
781 params->status.vpStatus, params->status.errorCode);
782}
783
784static int goto_low_power(struct gspca_dev *gspca_dev)
785{
786 struct sd *sd = (struct sd *) gspca_dev;
787 int ret;
788
789 ret = do_command(gspca_dev, CPIA_COMMAND_GotoLoPower, 0, 0, 0, 0);
790 if (ret)
791 return ret;
792
793 do_command(gspca_dev, CPIA_COMMAND_GetCameraStatus, 0, 0, 0, 0);
794 if (ret)
795 return ret;
796
797 if (sd->params.status.systemState != LO_POWER_STATE) {
798 if (sd->params.status.systemState != WARM_BOOT_STATE) {
799 PDEBUG(D_ERR,
800 "unexpected state after lo power cmd: %02x",
801 sd->params.status.systemState);
802 printstatus(&sd->params);
803 }
804 return -EIO;
805 }
806
807 PDEBUG(D_CONF, "camera now in LOW power state");
808 return 0;
809}
810
811static int goto_high_power(struct gspca_dev *gspca_dev)
812{
813 struct sd *sd = (struct sd *) gspca_dev;
814 int ret;
815
816 ret = do_command(gspca_dev, CPIA_COMMAND_GotoHiPower, 0, 0, 0, 0);
817 if (ret)
818 return ret;
819
820 msleep_interruptible(40); /* windows driver does it too */
821
822 if (signal_pending(current))
823 return -EINTR;
824
825 do_command(gspca_dev, CPIA_COMMAND_GetCameraStatus, 0, 0, 0, 0);
826 if (ret)
827 return ret;
828
829 if (sd->params.status.systemState != HI_POWER_STATE) {
830 PDEBUG(D_ERR, "unexpected state after hi power cmd: %02x",
831 sd->params.status.systemState);
832 printstatus(&sd->params);
833 return -EIO;
834 }
835
836 PDEBUG(D_CONF, "camera now in HIGH power state");
837 return 0;
838}
839
840static int get_version_information(struct gspca_dev *gspca_dev)
841{
842 int ret;
843
844 /* GetCPIAVersion */
845 ret = do_command(gspca_dev, CPIA_COMMAND_GetCPIAVersion, 0, 0, 0, 0);
846 if (ret)
847 return ret;
848
849 /* GetPnPID */
850 return do_command(gspca_dev, CPIA_COMMAND_GetPnPID, 0, 0, 0, 0);
851}
852
853static int save_camera_state(struct gspca_dev *gspca_dev)
854{
855 int ret;
856
857 ret = do_command(gspca_dev, CPIA_COMMAND_GetColourBalance, 0, 0, 0, 0);
858 if (ret)
859 return ret;
860
861 return do_command(gspca_dev, CPIA_COMMAND_GetExposure, 0, 0, 0, 0);
862}
863
864int command_setformat(struct gspca_dev *gspca_dev)
865{
866 struct sd *sd = (struct sd *) gspca_dev;
867 int ret;
868
869 ret = do_command(gspca_dev, CPIA_COMMAND_SetFormat,
870 sd->params.format.videoSize,
871 sd->params.format.subSample,
872 sd->params.format.yuvOrder, 0);
873 if (ret)
874 return ret;
875
876 return do_command(gspca_dev, CPIA_COMMAND_SetROI,
877 sd->params.roi.colStart, sd->params.roi.colEnd,
878 sd->params.roi.rowStart, sd->params.roi.rowEnd);
879}
880
881int command_setcolourparams(struct gspca_dev *gspca_dev)
882{
883 struct sd *sd = (struct sd *) gspca_dev;
884 return do_command(gspca_dev, CPIA_COMMAND_SetColourParams,
885 sd->params.colourParams.brightness,
886 sd->params.colourParams.contrast,
887 sd->params.colourParams.saturation, 0);
888}
889
890int command_setapcor(struct gspca_dev *gspca_dev)
891{
892 struct sd *sd = (struct sd *) gspca_dev;
893 return do_command(gspca_dev, CPIA_COMMAND_SetApcor,
894 sd->params.apcor.gain1,
895 sd->params.apcor.gain2,
896 sd->params.apcor.gain4,
897 sd->params.apcor.gain8);
898}
899
900int command_setvloffset(struct gspca_dev *gspca_dev)
901{
902 struct sd *sd = (struct sd *) gspca_dev;
903 return do_command(gspca_dev, CPIA_COMMAND_SetVLOffset,
904 sd->params.vlOffset.gain1,
905 sd->params.vlOffset.gain2,
906 sd->params.vlOffset.gain4,
907 sd->params.vlOffset.gain8);
908}
909
910int command_setexposure(struct gspca_dev *gspca_dev)
911{
912 struct sd *sd = (struct sd *) gspca_dev;
913 int ret;
914
915 ret = do_command_extended(gspca_dev, CPIA_COMMAND_SetExposure,
916 sd->params.exposure.gainMode,
917 1,
918 sd->params.exposure.compMode,
919 sd->params.exposure.centreWeight,
920 sd->params.exposure.gain,
921 sd->params.exposure.fineExp,
922 sd->params.exposure.coarseExpLo,
923 sd->params.exposure.coarseExpHi,
924 sd->params.exposure.redComp,
925 sd->params.exposure.green1Comp,
926 sd->params.exposure.green2Comp,
927 sd->params.exposure.blueComp);
928 if (ret)
929 return ret;
930
931 if (sd->params.exposure.expMode != 1) {
932 ret = do_command_extended(gspca_dev, CPIA_COMMAND_SetExposure,
933 0,
934 sd->params.exposure.expMode,
935 0, 0,
936 sd->params.exposure.gain,
937 sd->params.exposure.fineExp,
938 sd->params.exposure.coarseExpLo,
939 sd->params.exposure.coarseExpHi,
940 0, 0, 0, 0);
941 }
942
943 return ret;
944}
945
946int command_setcolourbalance(struct gspca_dev *gspca_dev)
947{
948 struct sd *sd = (struct sd *) gspca_dev;
949
950 if (sd->params.colourBalance.balanceMode == 1) {
951 int ret;
952
953 ret = do_command(gspca_dev, CPIA_COMMAND_SetColourBalance,
954 1,
955 sd->params.colourBalance.redGain,
956 sd->params.colourBalance.greenGain,
957 sd->params.colourBalance.blueGain);
958 if (ret)
959 return ret;
960
961 return do_command(gspca_dev, CPIA_COMMAND_SetColourBalance,
962 3, 0, 0, 0);
963 }
964 if (sd->params.colourBalance.balanceMode == 2) {
965 return do_command(gspca_dev, CPIA_COMMAND_SetColourBalance,
966 2, 0, 0, 0);
967 }
968 if (sd->params.colourBalance.balanceMode == 3) {
969 return do_command(gspca_dev, CPIA_COMMAND_SetColourBalance,
970 3, 0, 0, 0);
971 }
972
973 return -EINVAL;
974}
975
976int command_setcompressiontarget(struct gspca_dev *gspca_dev)
977{
978 struct sd *sd = (struct sd *) gspca_dev;
979
980 return do_command(gspca_dev, CPIA_COMMAND_SetCompressionTarget,
981 sd->params.compressionTarget.frTargeting,
982 sd->params.compressionTarget.targetFR,
983 sd->params.compressionTarget.targetQ, 0);
984}
985
986int command_setyuvtresh(struct gspca_dev *gspca_dev)
987{
988 struct sd *sd = (struct sd *) gspca_dev;
989
990 return do_command(gspca_dev, CPIA_COMMAND_SetYUVThresh,
991 sd->params.yuvThreshold.yThreshold,
992 sd->params.yuvThreshold.uvThreshold, 0, 0);
993}
994
995int command_setcompressionparams(struct gspca_dev *gspca_dev)
996{
997 struct sd *sd = (struct sd *) gspca_dev;
998
999 return do_command_extended(gspca_dev,
1000 CPIA_COMMAND_SetCompressionParams,
1001 0, 0, 0, 0,
1002 sd->params.compressionParams.hysteresis,
1003 sd->params.compressionParams.threshMax,
1004 sd->params.compressionParams.smallStep,
1005 sd->params.compressionParams.largeStep,
1006 sd->params.compressionParams.decimationHysteresis,
1007 sd->params.compressionParams.frDiffStepThresh,
1008 sd->params.compressionParams.qDiffStepThresh,
1009 sd->params.compressionParams.decimationThreshMod);
1010}
1011
1012int command_setcompression(struct gspca_dev *gspca_dev)
1013{
1014 struct sd *sd = (struct sd *) gspca_dev;
1015
1016 return do_command(gspca_dev, CPIA_COMMAND_SetCompression,
1017 sd->params.compression.mode,
1018 sd->params.compression.decimation, 0, 0);
1019}
1020
1021int command_setsensorfps(struct gspca_dev *gspca_dev)
1022{
1023 struct sd *sd = (struct sd *) gspca_dev;
1024
1025 return do_command(gspca_dev, CPIA_COMMAND_SetSensorFPS,
1026 sd->params.sensorFps.divisor,
1027 sd->params.sensorFps.baserate, 0, 0);
1028}
1029
1030int command_setflickerctrl(struct gspca_dev *gspca_dev)
1031{
1032 struct sd *sd = (struct sd *) gspca_dev;
1033
1034 return do_command(gspca_dev, CPIA_COMMAND_SetFlickerCtrl,
1035 sd->params.flickerControl.flickerMode,
1036 sd->params.flickerControl.coarseJump,
1037 sd->params.flickerControl.allowableOverExposure,
1038 0);
1039}
1040
1041int command_setecptiming(struct gspca_dev *gspca_dev)
1042{
1043 struct sd *sd = (struct sd *) gspca_dev;
1044
1045 return do_command(gspca_dev, CPIA_COMMAND_SetECPTiming,
1046 sd->params.ecpTiming, 0, 0, 0);
1047}
1048
1049int command_pause(struct gspca_dev *gspca_dev)
1050{
1051 return do_command(gspca_dev, CPIA_COMMAND_EndStreamCap, 0, 0, 0, 0);
1052}
1053
1054int command_resume(struct gspca_dev *gspca_dev)
1055{
1056 struct sd *sd = (struct sd *) gspca_dev;
1057
1058 return do_command(gspca_dev, CPIA_COMMAND_InitStreamCap,
1059 0, sd->params.streamStartLine, 0, 0);
1060}
1061
1062int command_setlights(struct gspca_dev *gspca_dev)
1063{
1064 struct sd *sd = (struct sd *) gspca_dev;
1065 int ret, p1, p2;
1066
1067 if (!sd->params.qx3.qx3_detected)
1068 return 0;
1069
1070 p1 = (sd->params.qx3.bottomlight == 0) << 1;
1071 p2 = (sd->params.qx3.toplight == 0) << 3;
1072
1073 ret = do_command(gspca_dev, CPIA_COMMAND_WriteVCReg,
1074 0x90, 0x8F, 0x50, 0);
1075 if (ret)
1076 return ret;
1077
1078 return do_command(gspca_dev, CPIA_COMMAND_WriteMCPort, 2, 0,
1079 p1 | p2 | 0xE0, 0);
1080}
1081
1082static int set_flicker(struct gspca_dev *gspca_dev, int on, int apply)
1083{
1084 /* Everything in here is from the Windows driver */
1085/* define for compgain calculation */
1086#if 0
1087#define COMPGAIN(base, curexp, newexp) \
1088 (u8) ((((float) base - 128.0) * ((float) curexp / (float) newexp)) + 128.5)
1089#define EXP_FROM_COMP(basecomp, curcomp, curexp) \
1090 (u16)((float)curexp * (float)(u8)(curcomp + 128) / \
1091 (float)(u8)(basecomp - 128))
1092#else
1093 /* equivalent functions without floating point math */
1094#define COMPGAIN(base, curexp, newexp) \
1095 (u8)(128 + (((u32)(2*(base-128)*curexp + newexp)) / (2 * newexp)))
1096#define EXP_FROM_COMP(basecomp, curcomp, curexp) \
1097 (u16)(((u32)(curexp * (u8)(curcomp + 128)) / (u8)(basecomp - 128)))
1098#endif
1099
1100 struct sd *sd = (struct sd *) gspca_dev;
1101 int currentexp = sd->params.exposure.coarseExpLo +
1102 sd->params.exposure.coarseExpHi * 256;
1103 int ret, startexp;
1104
1105 if (on) {
1106 int cj = sd->params.flickerControl.coarseJump;
1107 sd->params.flickerControl.flickerMode = 1;
1108 sd->params.flickerControl.disabled = 0;
1109 if (sd->params.exposure.expMode != 2) {
1110 sd->params.exposure.expMode = 2;
1111 sd->exposure_status = EXPOSURE_NORMAL;
1112 }
1113 currentexp = currentexp << sd->params.exposure.gain;
1114 sd->params.exposure.gain = 0;
1115 /* round down current exposure to nearest value */
1116 startexp = (currentexp + ROUND_UP_EXP_FOR_FLICKER) / cj;
1117 if (startexp < 1)
1118 startexp = 1;
1119 startexp = (startexp * cj) - 1;
1120 if (FIRMWARE_VERSION(1, 2))
1121 while (startexp > MAX_EXP_102)
1122 startexp -= cj;
1123 else
1124 while (startexp > MAX_EXP)
1125 startexp -= cj;
1126 sd->params.exposure.coarseExpLo = startexp & 0xff;
1127 sd->params.exposure.coarseExpHi = startexp >> 8;
1128 if (currentexp > startexp) {
1129 if (currentexp > (2 * startexp))
1130 currentexp = 2 * startexp;
1131 sd->params.exposure.redComp =
1132 COMPGAIN(COMP_RED, currentexp, startexp);
1133 sd->params.exposure.green1Comp =
1134 COMPGAIN(COMP_GREEN1, currentexp, startexp);
1135 sd->params.exposure.green2Comp =
1136 COMPGAIN(COMP_GREEN2, currentexp, startexp);
1137 sd->params.exposure.blueComp =
1138 COMPGAIN(COMP_BLUE, currentexp, startexp);
1139 } else {
1140 sd->params.exposure.redComp = COMP_RED;
1141 sd->params.exposure.green1Comp = COMP_GREEN1;
1142 sd->params.exposure.green2Comp = COMP_GREEN2;
1143 sd->params.exposure.blueComp = COMP_BLUE;
1144 }
1145 if (FIRMWARE_VERSION(1, 2))
1146 sd->params.exposure.compMode = 0;
1147 else
1148 sd->params.exposure.compMode = 1;
1149
1150 sd->params.apcor.gain1 = 0x18;
1151 sd->params.apcor.gain2 = 0x18;
1152 sd->params.apcor.gain4 = 0x16;
1153 sd->params.apcor.gain8 = 0x14;
1154 } else {
1155 sd->params.flickerControl.flickerMode = 0;
1156 sd->params.flickerControl.disabled = 1;
1157 /* Average equivalent coarse for each comp channel */
1158 startexp = EXP_FROM_COMP(COMP_RED,
1159 sd->params.exposure.redComp, currentexp);
1160 startexp += EXP_FROM_COMP(COMP_GREEN1,
1161 sd->params.exposure.green1Comp, currentexp);
1162 startexp += EXP_FROM_COMP(COMP_GREEN2,
1163 sd->params.exposure.green2Comp, currentexp);
1164 startexp += EXP_FROM_COMP(COMP_BLUE,
1165 sd->params.exposure.blueComp, currentexp);
1166 startexp = startexp >> 2;
1167 while (startexp > MAX_EXP && sd->params.exposure.gain <
1168 sd->params.exposure.gainMode - 1) {
1169 startexp = startexp >> 1;
1170 ++sd->params.exposure.gain;
1171 }
1172 if (FIRMWARE_VERSION(1, 2) && startexp > MAX_EXP_102)
1173 startexp = MAX_EXP_102;
1174 if (startexp > MAX_EXP)
1175 startexp = MAX_EXP;
1176 sd->params.exposure.coarseExpLo = startexp & 0xff;
1177 sd->params.exposure.coarseExpHi = startexp >> 8;
1178 sd->params.exposure.redComp = COMP_RED;
1179 sd->params.exposure.green1Comp = COMP_GREEN1;
1180 sd->params.exposure.green2Comp = COMP_GREEN2;
1181 sd->params.exposure.blueComp = COMP_BLUE;
1182 sd->params.exposure.compMode = 1;
1183 sd->params.apcor.gain1 = 0x18;
1184 sd->params.apcor.gain2 = 0x16;
1185 sd->params.apcor.gain4 = 0x24;
1186 sd->params.apcor.gain8 = 0x34;
1187 }
1188 sd->params.vlOffset.gain1 = 20;
1189 sd->params.vlOffset.gain2 = 24;
1190 sd->params.vlOffset.gain4 = 26;
1191 sd->params.vlOffset.gain8 = 26;
1192
1193 if (apply) {
1194 ret = command_setexposure(gspca_dev);
1195 if (ret)
1196 return ret;
1197
1198 ret = command_setapcor(gspca_dev);
1199 if (ret)
1200 return ret;
1201
1202 ret = command_setvloffset(gspca_dev);
1203 if (ret)
1204 return ret;
1205
1206 ret = command_setflickerctrl(gspca_dev);
1207 if (ret)
1208 return ret;
1209 }
1210
1211 return 0;
1212#undef EXP_FROM_COMP
1213#undef COMPGAIN
1214}
1215
1216/* monitor the exposure and adjust the sensor frame rate if needed */
1217static void monitor_exposure(struct gspca_dev *gspca_dev)
1218{
1219 struct sd *sd = (struct sd *) gspca_dev;
1220 u8 exp_acc, bcomp, gain, coarseL, cmd[8];
1221 int ret, light_exp, dark_exp, very_dark_exp;
1222 int old_exposure, new_exposure, framerate;
1223 int setfps = 0, setexp = 0, setflicker = 0;
1224
1225 /* get necessary stats and register settings from camera */
1226 /* do_command can't handle this, so do it ourselves */
1227 cmd[0] = CPIA_COMMAND_ReadVPRegs >> 8;
1228 cmd[1] = CPIA_COMMAND_ReadVPRegs & 0xff;
1229 cmd[2] = 30;
1230 cmd[3] = 4;
1231 cmd[4] = 9;
1232 cmd[5] = 8;
1233 cmd[6] = 8;
1234 cmd[7] = 0;
1235 ret = cpia_usb_transferCmd(gspca_dev, cmd);
1236 if (ret) {
1237 PDEBUG(D_ERR, "ReadVPRegs(30,4,9,8) - failed: %d", ret);
1238 return;
1239 }
1240 exp_acc = gspca_dev->usb_buf[0];
1241 bcomp = gspca_dev->usb_buf[1];
1242 gain = gspca_dev->usb_buf[2];
1243 coarseL = gspca_dev->usb_buf[3];
1244
1245 light_exp = sd->params.colourParams.brightness +
1246 TC - 50 + EXP_ACC_LIGHT;
1247 if (light_exp > 255)
1248 light_exp = 255;
1249 dark_exp = sd->params.colourParams.brightness +
1250 TC - 50 - EXP_ACC_DARK;
1251 if (dark_exp < 0)
1252 dark_exp = 0;
1253 very_dark_exp = dark_exp / 2;
1254
1255 old_exposure = sd->params.exposure.coarseExpHi * 256 +
1256 sd->params.exposure.coarseExpLo;
1257
1258 if (!sd->params.flickerControl.disabled) {
1259 /* Flicker control on */
1260 int max_comp = FIRMWARE_VERSION(1, 2) ? MAX_COMP :
1261 HIGH_COMP_102;
1262 bcomp += 128; /* decode */
1263 if (bcomp >= max_comp && exp_acc < dark_exp) {
1264 /* dark */
1265 if (exp_acc < very_dark_exp) {
1266 /* very dark */
1267 if (sd->exposure_status == EXPOSURE_VERY_DARK)
1268 ++sd->exposure_count;
1269 else {
1270 sd->exposure_status =
1271 EXPOSURE_VERY_DARK;
1272 sd->exposure_count = 1;
1273 }
1274 } else {
1275 /* just dark */
1276 if (sd->exposure_status == EXPOSURE_DARK)
1277 ++sd->exposure_count;
1278 else {
1279 sd->exposure_status = EXPOSURE_DARK;
1280 sd->exposure_count = 1;
1281 }
1282 }
1283 } else if (old_exposure <= LOW_EXP || exp_acc > light_exp) {
1284 /* light */
1285 if (old_exposure <= VERY_LOW_EXP) {
1286 /* very light */
1287 if (sd->exposure_status == EXPOSURE_VERY_LIGHT)
1288 ++sd->exposure_count;
1289 else {
1290 sd->exposure_status =
1291 EXPOSURE_VERY_LIGHT;
1292 sd->exposure_count = 1;
1293 }
1294 } else {
1295 /* just light */
1296 if (sd->exposure_status == EXPOSURE_LIGHT)
1297 ++sd->exposure_count;
1298 else {
1299 sd->exposure_status = EXPOSURE_LIGHT;
1300 sd->exposure_count = 1;
1301 }
1302 }
1303 } else {
1304 /* not dark or light */
1305 sd->exposure_status = EXPOSURE_NORMAL;
1306 }
1307 } else {
1308 /* Flicker control off */
1309 if (old_exposure >= MAX_EXP && exp_acc < dark_exp) {
1310 /* dark */
1311 if (exp_acc < very_dark_exp) {
1312 /* very dark */
1313 if (sd->exposure_status == EXPOSURE_VERY_DARK)
1314 ++sd->exposure_count;
1315 else {
1316 sd->exposure_status =
1317 EXPOSURE_VERY_DARK;
1318 sd->exposure_count = 1;
1319 }
1320 } else {
1321 /* just dark */
1322 if (sd->exposure_status == EXPOSURE_DARK)
1323 ++sd->exposure_count;
1324 else {
1325 sd->exposure_status = EXPOSURE_DARK;
1326 sd->exposure_count = 1;
1327 }
1328 }
1329 } else if (old_exposure <= LOW_EXP || exp_acc > light_exp) {
1330 /* light */
1331 if (old_exposure <= VERY_LOW_EXP) {
1332 /* very light */
1333 if (sd->exposure_status == EXPOSURE_VERY_LIGHT)
1334 ++sd->exposure_count;
1335 else {
1336 sd->exposure_status =
1337 EXPOSURE_VERY_LIGHT;
1338 sd->exposure_count = 1;
1339 }
1340 } else {
1341 /* just light */
1342 if (sd->exposure_status == EXPOSURE_LIGHT)
1343 ++sd->exposure_count;
1344 else {
1345 sd->exposure_status = EXPOSURE_LIGHT;
1346 sd->exposure_count = 1;
1347 }
1348 }
1349 } else {
1350 /* not dark or light */
1351 sd->exposure_status = EXPOSURE_NORMAL;
1352 }
1353 }
1354
1355 framerate = atomic_read(&sd->fps);
1356 if (framerate > 30 || framerate < 1)
1357 framerate = 1;
1358
1359 if (!sd->params.flickerControl.disabled) {
1360 /* Flicker control on */
1361 if ((sd->exposure_status == EXPOSURE_VERY_DARK ||
1362 sd->exposure_status == EXPOSURE_DARK) &&
1363 sd->exposure_count >= DARK_TIME * framerate &&
1364 sd->params.sensorFps.divisor < 3) {
1365
1366 /* dark for too long */
1367 ++sd->params.sensorFps.divisor;
1368 setfps = 1;
1369
1370 sd->params.flickerControl.coarseJump =
1371 flicker_jumps[sd->mainsFreq]
1372 [sd->params.sensorFps.baserate]
1373 [sd->params.sensorFps.divisor];
1374 setflicker = 1;
1375
1376 new_exposure = sd->params.flickerControl.coarseJump-1;
1377 while (new_exposure < old_exposure / 2)
1378 new_exposure +=
1379 sd->params.flickerControl.coarseJump;
1380 sd->params.exposure.coarseExpLo = new_exposure & 0xff;
1381 sd->params.exposure.coarseExpHi = new_exposure >> 8;
1382 setexp = 1;
1383 sd->exposure_status = EXPOSURE_NORMAL;
1384 PDEBUG(D_CONF, "Automatically decreasing sensor_fps");
1385
1386 } else if ((sd->exposure_status == EXPOSURE_VERY_LIGHT ||
1387 sd->exposure_status == EXPOSURE_LIGHT) &&
1388 sd->exposure_count >= LIGHT_TIME * framerate &&
1389 sd->params.sensorFps.divisor > 0) {
1390
1391 /* light for too long */
1392 int max_exp = FIRMWARE_VERSION(1, 2) ? MAX_EXP_102 :
1393 MAX_EXP;
1394 --sd->params.sensorFps.divisor;
1395 setfps = 1;
1396
1397 sd->params.flickerControl.coarseJump =
1398 flicker_jumps[sd->mainsFreq]
1399 [sd->params.sensorFps.baserate]
1400 [sd->params.sensorFps.divisor];
1401 setflicker = 1;
1402
1403 new_exposure = sd->params.flickerControl.coarseJump-1;
1404 while (new_exposure < 2 * old_exposure &&
1405 new_exposure +
1406 sd->params.flickerControl.coarseJump < max_exp)
1407 new_exposure +=
1408 sd->params.flickerControl.coarseJump;
1409 sd->params.exposure.coarseExpLo = new_exposure & 0xff;
1410 sd->params.exposure.coarseExpHi = new_exposure >> 8;
1411 setexp = 1;
1412 sd->exposure_status = EXPOSURE_NORMAL;
1413 PDEBUG(D_CONF, "Automatically increasing sensor_fps");
1414 }
1415 } else {
1416 /* Flicker control off */
1417 if ((sd->exposure_status == EXPOSURE_VERY_DARK ||
1418 sd->exposure_status == EXPOSURE_DARK) &&
1419 sd->exposure_count >= DARK_TIME * framerate &&
1420 sd->params.sensorFps.divisor < 3) {
1421
1422 /* dark for too long */
1423 ++sd->params.sensorFps.divisor;
1424 setfps = 1;
1425
1426 if (sd->params.exposure.gain > 0) {
1427 --sd->params.exposure.gain;
1428 setexp = 1;
1429 }
1430 sd->exposure_status = EXPOSURE_NORMAL;
1431 PDEBUG(D_CONF, "Automatically decreasing sensor_fps");
1432
1433 } else if ((sd->exposure_status == EXPOSURE_VERY_LIGHT ||
1434 sd->exposure_status == EXPOSURE_LIGHT) &&
1435 sd->exposure_count >= LIGHT_TIME * framerate &&
1436 sd->params.sensorFps.divisor > 0) {
1437
1438 /* light for too long */
1439 --sd->params.sensorFps.divisor;
1440 setfps = 1;
1441
1442 if (sd->params.exposure.gain <
1443 sd->params.exposure.gainMode - 1) {
1444 ++sd->params.exposure.gain;
1445 setexp = 1;
1446 }
1447 sd->exposure_status = EXPOSURE_NORMAL;
1448 PDEBUG(D_CONF, "Automatically increasing sensor_fps");
1449 }
1450 }
1451
1452 if (setexp)
1453 command_setexposure(gspca_dev);
1454
1455 if (setfps)
1456 command_setsensorfps(gspca_dev);
1457
1458 if (setflicker)
1459 command_setflickerctrl(gspca_dev);
1460}
1461
1462/*-----------------------------------------------------------------*/
1463/* if flicker is switched off, this function switches it back on.It checks,
1464 however, that conditions are suitable before restarting it.
1465 This should only be called for firmware version 1.2.
1466
1467 It also adjust the colour balance when an exposure step is detected - as
1468 long as flicker is running
1469*/
1470static void restart_flicker(struct gspca_dev *gspca_dev)
1471{
1472 struct sd *sd = (struct sd *) gspca_dev;
1473 int cam_exposure, old_exp;
1474
1475 if (!FIRMWARE_VERSION(1, 2))
1476 return;
1477
1478 cam_exposure = atomic_read(&sd->cam_exposure);
1479
1480 if (sd->params.flickerControl.flickerMode == 0 ||
1481 cam_exposure == 0)
1482 return;
1483
1484 old_exp = sd->params.exposure.coarseExpLo +
1485 sd->params.exposure.coarseExpHi*256;
1486 /*
1487 see how far away camera exposure is from a valid
1488 flicker exposure value
1489 */
1490 cam_exposure %= sd->params.flickerControl.coarseJump;
1491 if (!sd->params.flickerControl.disabled &&
1492 cam_exposure <= sd->params.flickerControl.coarseJump - 3) {
1493 /* Flicker control auto-disabled */
1494 sd->params.flickerControl.disabled = 1;
1495 }
1496
1497 if (sd->params.flickerControl.disabled &&
1498 old_exp > sd->params.flickerControl.coarseJump +
1499 ROUND_UP_EXP_FOR_FLICKER) {
1500 /* exposure is now high enough to switch
1501 flicker control back on */
1502 set_flicker(gspca_dev, 1, 1);
1503 }
1504}
1505
1506/* this function is called at probe time */
1507static int sd_config(struct gspca_dev *gspca_dev,
1508 const struct usb_device_id *id)
1509{
1510 struct cam *cam;
1511
1512 reset_camera_params(gspca_dev);
1513
1514 PDEBUG(D_PROBE, "cpia CPiA camera detected (vid/pid 0x%04X:0x%04X)",
1515 id->idVendor, id->idProduct);
1516
1517 cam = &gspca_dev->cam;
1518 cam->cam_mode = mode;
1519 cam->nmodes = ARRAY_SIZE(mode);
1520
1521 sd_setfreq(gspca_dev, FREQ_DEF);
1522
1523 return 0;
1524}
1525
1526/* -- start the camera -- */
1527static int sd_start(struct gspca_dev *gspca_dev)
1528{
1529 struct sd *sd = (struct sd *) gspca_dev;
1530 int priv, ret;
1531
1532 /* Start the camera in low power mode */
1533 if (goto_low_power(gspca_dev)) {
1534 if (sd->params.status.systemState != WARM_BOOT_STATE) {
1535 PDEBUG(D_ERR, "unexpected systemstate: %02x",
1536 sd->params.status.systemState);
1537 printstatus(&sd->params);
1538 return -ENODEV;
1539 }
1540
1541 /* FIXME: this is just dirty trial and error */
1542 ret = goto_high_power(gspca_dev);
1543 if (ret)
1544 return ret;
1545
1546 ret = do_command(gspca_dev, CPIA_COMMAND_DiscardFrame,
1547 0, 0, 0, 0);
1548 if (ret)
1549 return ret;
1550
1551 ret = goto_low_power(gspca_dev);
1552 if (ret)
1553 return ret;
1554 }
1555
1556 /* procedure described in developer's guide p3-28 */
1557
1558 /* Check the firmware version. */
1559 sd->params.version.firmwareVersion = 0;
1560 get_version_information(gspca_dev);
1561 if (sd->params.version.firmwareVersion != 1) {
1562 PDEBUG(D_ERR, "only firmware version 1 is supported (got: %d)",
1563 sd->params.version.firmwareVersion);
1564 return -ENODEV;
1565 }
1566
1567 /* A bug in firmware 1-02 limits gainMode to 2 */
1568 if (sd->params.version.firmwareRevision <= 2 &&
1569 sd->params.exposure.gainMode > 2) {
1570 sd->params.exposure.gainMode = 2;
1571 }
1572
1573 /* set QX3 detected flag */
1574 sd->params.qx3.qx3_detected = (sd->params.pnpID.vendor == 0x0813 &&
1575 sd->params.pnpID.product == 0x0001);
1576
1577 /* The fatal error checking should be done after
1578 * the camera powers up (developer's guide p 3-38) */
1579
1580 /* Set streamState before transition to high power to avoid bug
1581 * in firmware 1-02 */
1582 ret = do_command(gspca_dev, CPIA_COMMAND_ModifyCameraStatus,
1583 STREAMSTATE, 0, STREAM_NOT_READY, 0);
1584 if (ret)
1585 return ret;
1586
1587 /* GotoHiPower */
1588 ret = goto_high_power(gspca_dev);
1589 if (ret)
1590 return ret;
1591
1592 /* Check the camera status */
1593 ret = do_command(gspca_dev, CPIA_COMMAND_GetCameraStatus, 0, 0, 0, 0);
1594 if (ret)
1595 return ret;
1596
1597 if (sd->params.status.fatalError) {
1598 PDEBUG(D_ERR, "fatal_error: %04x, vp_status: %04x",
1599 sd->params.status.fatalError,
1600 sd->params.status.vpStatus);
1601 return -EIO;
1602 }
1603
1604 /* VPVersion can't be retrieved before the camera is in HiPower,
1605 * so get it here instead of in get_version_information. */
1606 ret = do_command(gspca_dev, CPIA_COMMAND_GetVPVersion, 0, 0, 0, 0);
1607 if (ret)
1608 return ret;
1609
1610 /* Determine video mode settings */
1611 sd->params.streamStartLine = 120;
1612
1613 priv = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv;
1614 if (priv & 0x01) { /* crop */
1615 sd->params.roi.colStart = 2;
1616 sd->params.roi.rowStart = 6;
1617 } else {
1618 sd->params.roi.colStart = 0;
1619 sd->params.roi.rowStart = 0;
1620 }
1621
1622 if (priv & 0x02) { /* quarter */
1623 sd->params.format.videoSize = VIDEOSIZE_QCIF;
1624 sd->params.roi.colStart /= 2;
1625 sd->params.roi.rowStart /= 2;
1626 sd->params.streamStartLine /= 2;
1627 } else
1628 sd->params.format.videoSize = VIDEOSIZE_CIF;
1629
1630 sd->params.roi.colEnd = sd->params.roi.colStart +
1631 (gspca_dev->width >> 3);
1632 sd->params.roi.rowEnd = sd->params.roi.rowStart +
1633 (gspca_dev->height >> 2);
1634
1635 /* And now set the camera to a known state */
1636 ret = do_command(gspca_dev, CPIA_COMMAND_SetGrabMode,
1637 CPIA_GRAB_CONTINEOUS, 0, 0, 0);
1638 if (ret)
1639 return ret;
1640 /* We start with compression disabled, as we need one uncompressed
1641 frame to handle later compressed frames */
1642 ret = do_command(gspca_dev, CPIA_COMMAND_SetCompression,
1643 CPIA_COMPRESSION_NONE,
1644 NO_DECIMATION, 0, 0);
1645 if (ret)
1646 return ret;
1647 ret = command_setcompressiontarget(gspca_dev);
1648 if (ret)
1649 return ret;
1650 ret = command_setcolourparams(gspca_dev);
1651 if (ret)
1652 return ret;
1653 ret = command_setformat(gspca_dev);
1654 if (ret)
1655 return ret;
1656 ret = command_setyuvtresh(gspca_dev);
1657 if (ret)
1658 return ret;
1659 ret = command_setecptiming(gspca_dev);
1660 if (ret)
1661 return ret;
1662 ret = command_setcompressionparams(gspca_dev);
1663 if (ret)
1664 return ret;
1665 ret = command_setexposure(gspca_dev);
1666 if (ret)
1667 return ret;
1668 ret = command_setcolourbalance(gspca_dev);
1669 if (ret)
1670 return ret;
1671 ret = command_setsensorfps(gspca_dev);
1672 if (ret)
1673 return ret;
1674 ret = command_setapcor(gspca_dev);
1675 if (ret)
1676 return ret;
1677 ret = command_setflickerctrl(gspca_dev);
1678 if (ret)
1679 return ret;
1680 ret = command_setvloffset(gspca_dev);
1681 if (ret)
1682 return ret;
1683
1684 /* Start stream */
1685 ret = command_resume(gspca_dev);
1686 if (ret)
1687 return ret;
1688
1689 /* Wait 6 frames before turning compression on for the sensor to get
1690 all settings and AEC/ACB to settle */
1691 sd->first_frame = 6;
1692 sd->exposure_status = EXPOSURE_NORMAL;
1693 sd->exposure_count = 0;
1694 atomic_set(&sd->cam_exposure, 0);
1695 atomic_set(&sd->fps, 0);
1696
1697 return 0;
1698}
1699
1700static void sd_stopN(struct gspca_dev *gspca_dev)
1701{
1702 command_pause(gspca_dev);
1703
1704 /* save camera state for later open (developers guide ch 3.5.3) */
1705 save_camera_state(gspca_dev);
1706
1707 /* GotoLoPower */
1708 goto_low_power(gspca_dev);
1709
1710 /* Update the camera status */
1711 do_command(gspca_dev, CPIA_COMMAND_GetCameraStatus, 0, 0, 0, 0);
1712}
1713
1714/* this function is called at probe and resume time */
1715static int sd_init(struct gspca_dev *gspca_dev)
1716{
1717 struct sd *sd = (struct sd *) gspca_dev;
1718 int ret;
1719
1720 /* Start / Stop the camera to make sure we are talking to
1721 a supported camera, and to get some information from it
1722 to print. */
1723 ret = sd_start(gspca_dev);
1724 if (ret)
1725 return ret;
1726
1727 sd_stopN(gspca_dev);
1728
1729 PDEBUG(D_PROBE, "CPIA Version: %d.%02d (%d.%d)",
1730 sd->params.version.firmwareVersion,
1731 sd->params.version.firmwareRevision,
1732 sd->params.version.vcVersion,
1733 sd->params.version.vcRevision);
1734 PDEBUG(D_PROBE, "CPIA PnP-ID: %04x:%04x:%04x",
1735 sd->params.pnpID.vendor, sd->params.pnpID.product,
1736 sd->params.pnpID.deviceRevision);
1737 PDEBUG(D_PROBE, "VP-Version: %d.%d %04x",
1738 sd->params.vpVersion.vpVersion,
1739 sd->params.vpVersion.vpRevision,
1740 sd->params.vpVersion.cameraHeadID);
1741
1742 return 0;
1743}
1744
1745static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1746 u8 *data,
1747 int len)
1748{
1749 struct sd *sd = (struct sd *) gspca_dev;
1750
1751 /* Check for SOF */
1752 if (len >= 64 &&
1753 data[0] == MAGIC_0 && data[1] == MAGIC_1 &&
1754 data[16] == sd->params.format.videoSize &&
1755 data[17] == sd->params.format.subSample &&
1756 data[18] == sd->params.format.yuvOrder &&
1757 data[24] == sd->params.roi.colStart &&
1758 data[25] == sd->params.roi.colEnd &&
1759 data[26] == sd->params.roi.rowStart &&
1760 data[27] == sd->params.roi.rowEnd) {
1761 struct gspca_frame *frame = gspca_get_i_frame(gspca_dev);
1762
1763 atomic_set(&sd->cam_exposure, data[39] * 2);
1764 atomic_set(&sd->fps, data[41]);
1765
1766 if (frame == NULL) {
1767 gspca_dev->last_packet_type = DISCARD_PACKET;
1768 return;
1769 }
1770
1771 /* Check for proper EOF for last frame */
1772 if ((frame->data_end - frame->data) > 4 &&
1773 frame->data_end[-4] == 0xff &&
1774 frame->data_end[-3] == 0xff &&
1775 frame->data_end[-2] == 0xff &&
1776 frame->data_end[-1] == 0xff)
1777 gspca_frame_add(gspca_dev, LAST_PACKET,
1778 NULL, 0);
1779
1780 gspca_frame_add(gspca_dev, FIRST_PACKET, data, len);
1781 return;
1782 }
1783
1784 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
1785}
1786
1787static void sd_dq_callback(struct gspca_dev *gspca_dev)
1788{
1789 struct sd *sd = (struct sd *) gspca_dev;
1790
1791 /* Set the normal compression settings once we have captured a
1792 few uncompressed frames (and AEC has hopefully settled) */
1793 if (sd->first_frame) {
1794 sd->first_frame--;
1795 if (sd->first_frame == 0)
1796 command_setcompression(gspca_dev);
1797 }
1798
1799 /* Switch flicker control back on if it got turned off */
1800 restart_flicker(gspca_dev);
1801
1802 /* If AEC is enabled, monitor the exposure and
1803 adjust the sensor frame rate if needed */
1804 if (sd->params.exposure.expMode == 2)
1805 monitor_exposure(gspca_dev);
1806
1807 /* Update our knowledge of the camera state */
1808 do_command(gspca_dev, CPIA_COMMAND_GetExposure, 0, 0, 0, 0);
1809 if (sd->params.qx3.qx3_detected)
1810 do_command(gspca_dev, CPIA_COMMAND_ReadMCPorts, 0, 0, 0, 0);
1811}
1812
1813static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
1814{
1815 struct sd *sd = (struct sd *) gspca_dev;
1816 int ret;
1817
1818 sd->params.colourParams.brightness = val;
1819 sd->params.flickerControl.allowableOverExposure =
1820 find_over_exposure(sd->params.colourParams.brightness);
1821 if (gspca_dev->streaming) {
1822 ret = command_setcolourparams(gspca_dev);
1823 if (ret)
1824 return ret;
1825 return command_setflickerctrl(gspca_dev);
1826 }
1827 return 0;
1828}
1829
1830static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
1831{
1832 struct sd *sd = (struct sd *) gspca_dev;
1833
1834 *val = sd->params.colourParams.brightness;
1835 return 0;
1836}
1837
1838static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
1839{
1840 struct sd *sd = (struct sd *) gspca_dev;
1841
1842 sd->params.colourParams.contrast = val;
1843 if (gspca_dev->streaming)
1844 return command_setcolourparams(gspca_dev);
1845
1846 return 0;
1847}
1848
1849static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
1850{
1851 struct sd *sd = (struct sd *) gspca_dev;
1852
1853 *val = sd->params.colourParams.contrast;
1854 return 0;
1855}
1856
1857static int sd_setsaturation(struct gspca_dev *gspca_dev, __s32 val)
1858{
1859 struct sd *sd = (struct sd *) gspca_dev;
1860
1861 sd->params.colourParams.saturation = val;
1862 if (gspca_dev->streaming)
1863 return command_setcolourparams(gspca_dev);
1864
1865 return 0;
1866}
1867
1868static int sd_getsaturation(struct gspca_dev *gspca_dev, __s32 *val)
1869{
1870 struct sd *sd = (struct sd *) gspca_dev;
1871
1872 *val = sd->params.colourParams.saturation;
1873 return 0;
1874}
1875
1876static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val)
1877{
1878 struct sd *sd = (struct sd *) gspca_dev;
1879 int on;
1880
1881 switch (val) {
1882 case 0: /* V4L2_CID_POWER_LINE_FREQUENCY_DISABLED */
1883 on = 0;
1884 break;
1885 case 1: /* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */
1886 on = 1;
1887 sd->mainsFreq = 0;
1888 break;
1889 case 2: /* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */
1890 on = 1;
1891 sd->mainsFreq = 1;
1892 break;
1893 default:
1894 return -EINVAL;
1895 }
1896
1897 sd->freq = val;
1898 sd->params.flickerControl.coarseJump =
1899 flicker_jumps[sd->mainsFreq]
1900 [sd->params.sensorFps.baserate]
1901 [sd->params.sensorFps.divisor];
1902
1903 return set_flicker(gspca_dev, on, gspca_dev->streaming);
1904}
1905
1906static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val)
1907{
1908 struct sd *sd = (struct sd *) gspca_dev;
1909
1910 *val = sd->freq;
1911 return 0;
1912}
1913
1914static int sd_setcomptarget(struct gspca_dev *gspca_dev, __s32 val)
1915{
1916 struct sd *sd = (struct sd *) gspca_dev;
1917
1918 sd->params.compressionTarget.frTargeting = val;
1919 if (gspca_dev->streaming)
1920 return command_setcompressiontarget(gspca_dev);
1921
1922 return 0;
1923}
1924
1925static int sd_getcomptarget(struct gspca_dev *gspca_dev, __s32 *val)
1926{
1927 struct sd *sd = (struct sd *) gspca_dev;
1928
1929 *val = sd->params.compressionTarget.frTargeting;
1930 return 0;
1931}
1932
1933static int sd_querymenu(struct gspca_dev *gspca_dev,
1934 struct v4l2_querymenu *menu)
1935{
1936 switch (menu->id) {
1937 case V4L2_CID_POWER_LINE_FREQUENCY:
1938 switch (menu->index) {
1939 case 0: /* V4L2_CID_POWER_LINE_FREQUENCY_DISABLED */
1940 strcpy((char *) menu->name, "NoFliker");
1941 return 0;
1942 case 1: /* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */
1943 strcpy((char *) menu->name, "50 Hz");
1944 return 0;
1945 case 2: /* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */
1946 strcpy((char *) menu->name, "60 Hz");
1947 return 0;
1948 }
1949 break;
1950 case V4L2_CID_COMP_TARGET:
1951 switch (menu->index) {
1952 case CPIA_COMPRESSION_TARGET_QUALITY:
1953 strcpy((char *) menu->name, "Quality");
1954 return 0;
1955 case CPIA_COMPRESSION_TARGET_FRAMERATE:
1956 strcpy((char *) menu->name, "Framerate");
1957 return 0;
1958 }
1959 break;
1960 }
1961 return -EINVAL;
1962}
1963
1964/* sub-driver description */
1965static const struct sd_desc sd_desc = {
1966 .name = MODULE_NAME,
1967 .ctrls = sd_ctrls,
1968 .nctrls = ARRAY_SIZE(sd_ctrls),
1969 .config = sd_config,
1970 .init = sd_init,
1971 .start = sd_start,
1972 .stopN = sd_stopN,
1973 .dq_callback = sd_dq_callback,
1974 .pkt_scan = sd_pkt_scan,
1975 .querymenu = sd_querymenu,
1976};
1977
1978/* -- module initialisation -- */
1979static const __devinitdata struct usb_device_id device_table[] = {
1980 {USB_DEVICE(0x0553, 0x0002)},
1981 {USB_DEVICE(0x0813, 0x0001)},
1982 {}
1983};
1984MODULE_DEVICE_TABLE(usb, device_table);
1985
1986/* -- device connect -- */
1987static int sd_probe(struct usb_interface *intf,
1988 const struct usb_device_id *id)
1989{
1990 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
1991 THIS_MODULE);
1992}
1993
1994static struct usb_driver sd_driver = {
1995 .name = MODULE_NAME,
1996 .id_table = device_table,
1997 .probe = sd_probe,
1998 .disconnect = gspca_disconnect,
1999#ifdef CONFIG_PM
2000 .suspend = gspca_suspend,
2001 .resume = gspca_resume,
2002#endif
2003};
2004
2005/* -- module insert / remove -- */
2006static int __init sd_mod_init(void)
2007{
2008 int ret;
2009 ret = usb_register(&sd_driver);
2010 if (ret < 0)
2011 return ret;
2012 PDEBUG(D_PROBE, "registered");
2013 return 0;
2014}
2015static void __exit sd_mod_exit(void)
2016{
2017 usb_deregister(&sd_driver);
2018 PDEBUG(D_PROBE, "deregistered");
2019}
2020
2021module_init(sd_mod_init);
2022module_exit(sd_mod_exit);
diff --git a/drivers/media/video/gspca/etoms.c b/drivers/media/video/gspca/etoms.c
index fdf4c0ec5e7a..ecd4d743d2bc 100644
--- a/drivers/media/video/gspca/etoms.c
+++ b/drivers/media/video/gspca/etoms.c
@@ -52,7 +52,7 @@ static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val);
52static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val); 52static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
53static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val); 53static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val);
54 54
55static struct ctrl sd_ctrls[] = { 55static const struct ctrl sd_ctrls[] = {
56 { 56 {
57 { 57 {
58 .id = V4L2_CID_BRIGHTNESS, 58 .id = V4L2_CID_BRIGHTNESS,
@@ -851,7 +851,7 @@ static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val)
851} 851}
852 852
853/* sub-driver description */ 853/* sub-driver description */
854static struct sd_desc sd_desc = { 854static const struct sd_desc sd_desc = {
855 .name = MODULE_NAME, 855 .name = MODULE_NAME,
856 .ctrls = sd_ctrls, 856 .ctrls = sd_ctrls,
857 .nctrls = ARRAY_SIZE(sd_ctrls), 857 .nctrls = ARRAY_SIZE(sd_ctrls),
diff --git a/drivers/media/video/gspca/gl860/gl860.c b/drivers/media/video/gspca/gl860/gl860.c
index 4878c8f66543..9e42476c0eaf 100644
--- a/drivers/media/video/gspca/gl860/gl860.c
+++ b/drivers/media/video/gspca/gl860/gl860.c
@@ -161,7 +161,7 @@ static int gl860_build_control_table(struct gspca_dev *gspca_dev)
161 161
162/*==================== sud-driver structure initialisation =================*/ 162/*==================== sud-driver structure initialisation =================*/
163 163
164static struct sd_desc sd_desc_mi1320 = { 164static const struct sd_desc sd_desc_mi1320 = {
165 .name = MODULE_NAME, 165 .name = MODULE_NAME,
166 .ctrls = sd_ctrls_mi1320, 166 .ctrls = sd_ctrls_mi1320,
167 .nctrls = GL860_NCTRLS, 167 .nctrls = GL860_NCTRLS,
@@ -174,7 +174,7 @@ static struct sd_desc sd_desc_mi1320 = {
174 .dq_callback = sd_callback, 174 .dq_callback = sd_callback,
175}; 175};
176 176
177static struct sd_desc sd_desc_mi2020 = { 177static const struct sd_desc sd_desc_mi2020 = {
178 .name = MODULE_NAME, 178 .name = MODULE_NAME,
179 .ctrls = sd_ctrls_mi2020, 179 .ctrls = sd_ctrls_mi2020,
180 .nctrls = GL860_NCTRLS, 180 .nctrls = GL860_NCTRLS,
@@ -187,7 +187,7 @@ static struct sd_desc sd_desc_mi2020 = {
187 .dq_callback = sd_callback, 187 .dq_callback = sd_callback,
188}; 188};
189 189
190static struct sd_desc sd_desc_mi2020b = { 190static const struct sd_desc sd_desc_mi2020b = {
191 .name = MODULE_NAME, 191 .name = MODULE_NAME,
192 .ctrls = sd_ctrls_mi2020b, 192 .ctrls = sd_ctrls_mi2020b,
193 .nctrls = GL860_NCTRLS, 193 .nctrls = GL860_NCTRLS,
@@ -200,7 +200,7 @@ static struct sd_desc sd_desc_mi2020b = {
200 .dq_callback = sd_callback, 200 .dq_callback = sd_callback,
201}; 201};
202 202
203static struct sd_desc sd_desc_ov2640 = { 203static const struct sd_desc sd_desc_ov2640 = {
204 .name = MODULE_NAME, 204 .name = MODULE_NAME,
205 .ctrls = sd_ctrls_ov2640, 205 .ctrls = sd_ctrls_ov2640,
206 .nctrls = GL860_NCTRLS, 206 .nctrls = GL860_NCTRLS,
@@ -213,7 +213,7 @@ static struct sd_desc sd_desc_ov2640 = {
213 .dq_callback = sd_callback, 213 .dq_callback = sd_callback,
214}; 214};
215 215
216static struct sd_desc sd_desc_ov9655 = { 216static const struct sd_desc sd_desc_ov9655 = {
217 .name = MODULE_NAME, 217 .name = MODULE_NAME,
218 .ctrls = sd_ctrls_ov9655, 218 .ctrls = sd_ctrls_ov9655,
219 .nctrls = GL860_NCTRLS, 219 .nctrls = GL860_NCTRLS,
diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c
index bd6214d4ab3b..222af479150b 100644
--- a/drivers/media/video/gspca/gspca.c
+++ b/drivers/media/video/gspca/gspca.c
@@ -3,6 +3,9 @@
3 * 3 *
4 * Copyright (C) 2008-2009 Jean-Francois Moine (http://moinejf.free.fr) 4 * Copyright (C) 2008-2009 Jean-Francois Moine (http://moinejf.free.fr)
5 * 5 *
6 * Camera button input handling by Márton Németh
7 * Copyright (C) 2009-2010 Márton Németh <nm127@freemail.hu>
8 *
6 * This program is free software; you can redistribute it and/or modify it 9 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the 10 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your 11 * Free Software Foundation; either version 2 of the License, or (at your
@@ -37,6 +40,11 @@
37 40
38#include "gspca.h" 41#include "gspca.h"
39 42
43#ifdef CONFIG_INPUT
44#include <linux/input.h>
45#include <linux/usb/input.h>
46#endif
47
40/* global values */ 48/* global values */
41#define DEF_NURBS 3 /* default number of URBs */ 49#define DEF_NURBS 3 /* default number of URBs */
42#if DEF_NURBS > MAX_NURBS 50#if DEF_NURBS > MAX_NURBS
@@ -47,7 +55,7 @@ MODULE_AUTHOR("Jean-Francois Moine <http://moinejf.free.fr>");
47MODULE_DESCRIPTION("GSPCA USB Camera Driver"); 55MODULE_DESCRIPTION("GSPCA USB Camera Driver");
48MODULE_LICENSE("GPL"); 56MODULE_LICENSE("GPL");
49 57
50#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 8, 0) 58#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 9, 0)
51 59
52#ifdef GSPCA_DEBUG 60#ifdef GSPCA_DEBUG
53int gspca_debug = D_ERR | D_PROBE; 61int gspca_debug = D_ERR | D_PROBE;
@@ -104,15 +112,185 @@ static const struct vm_operations_struct gspca_vm_ops = {
104 .close = gspca_vm_close, 112 .close = gspca_vm_close,
105}; 113};
106 114
115/*
116 * Input and interrupt endpoint handling functions
117 */
118#ifdef CONFIG_INPUT
119static void int_irq(struct urb *urb)
120{
121 struct gspca_dev *gspca_dev = (struct gspca_dev *) urb->context;
122 int ret;
123
124 ret = urb->status;
125 switch (ret) {
126 case 0:
127 if (gspca_dev->sd_desc->int_pkt_scan(gspca_dev,
128 urb->transfer_buffer, urb->actual_length) < 0) {
129 PDEBUG(D_ERR, "Unknown packet received");
130 }
131 break;
132
133 case -ENOENT:
134 case -ECONNRESET:
135 case -ENODEV:
136 case -ESHUTDOWN:
137 /* Stop is requested either by software or hardware is gone,
138 * keep the ret value non-zero and don't resubmit later.
139 */
140 break;
141
142 default:
143 PDEBUG(D_ERR, "URB error %i, resubmitting", urb->status);
144 urb->status = 0;
145 ret = 0;
146 }
147
148 if (ret == 0) {
149 ret = usb_submit_urb(urb, GFP_ATOMIC);
150 if (ret < 0)
151 PDEBUG(D_ERR, "Resubmit URB failed with error %i", ret);
152 }
153}
154
155static int gspca_input_connect(struct gspca_dev *dev)
156{
157 struct input_dev *input_dev;
158 int err = 0;
159
160 dev->input_dev = NULL;
161 if (dev->sd_desc->int_pkt_scan || dev->sd_desc->other_input) {
162 input_dev = input_allocate_device();
163 if (!input_dev)
164 return -ENOMEM;
165
166 usb_make_path(dev->dev, dev->phys, sizeof(dev->phys));
167 strlcat(dev->phys, "/input0", sizeof(dev->phys));
168
169 input_dev->name = dev->sd_desc->name;
170 input_dev->phys = dev->phys;
171
172 usb_to_input_id(dev->dev, &input_dev->id);
173
174 input_dev->evbit[0] = BIT_MASK(EV_KEY);
175 input_dev->keybit[BIT_WORD(KEY_CAMERA)] = BIT_MASK(KEY_CAMERA);
176 input_dev->dev.parent = &dev->dev->dev;
177
178 err = input_register_device(input_dev);
179 if (err) {
180 PDEBUG(D_ERR, "Input device registration failed "
181 "with error %i", err);
182 input_dev->dev.parent = NULL;
183 input_free_device(input_dev);
184 } else {
185 dev->input_dev = input_dev;
186 }
187 }
188
189 return err;
190}
191
192static int alloc_and_submit_int_urb(struct gspca_dev *gspca_dev,
193 struct usb_endpoint_descriptor *ep)
194{
195 unsigned int buffer_len;
196 int interval;
197 struct urb *urb;
198 struct usb_device *dev;
199 void *buffer = NULL;
200 int ret = -EINVAL;
201
202 buffer_len = ep->wMaxPacketSize;
203 interval = ep->bInterval;
204 PDEBUG(D_PROBE, "found int in endpoint: 0x%x, "
205 "buffer_len=%u, interval=%u",
206 ep->bEndpointAddress, buffer_len, interval);
207
208 dev = gspca_dev->dev;
209
210 urb = usb_alloc_urb(0, GFP_KERNEL);
211 if (!urb) {
212 ret = -ENOMEM;
213 goto error;
214 }
215
216 buffer = usb_buffer_alloc(dev, ep->wMaxPacketSize,
217 GFP_KERNEL, &urb->transfer_dma);
218 if (!buffer) {
219 ret = -ENOMEM;
220 goto error_buffer;
221 }
222 usb_fill_int_urb(urb, dev,
223 usb_rcvintpipe(dev, ep->bEndpointAddress),
224 buffer, buffer_len,
225 int_irq, (void *)gspca_dev, interval);
226 gspca_dev->int_urb = urb;
227 ret = usb_submit_urb(urb, GFP_KERNEL);
228 if (ret < 0) {
229 PDEBUG(D_ERR, "submit URB failed with error %i", ret);
230 goto error_submit;
231 }
232 return ret;
233
234error_submit:
235 usb_buffer_free(dev,
236 urb->transfer_buffer_length,
237 urb->transfer_buffer,
238 urb->transfer_dma);
239error_buffer:
240 usb_free_urb(urb);
241error:
242 return ret;
243}
244
245static void gspca_input_create_urb(struct gspca_dev *gspca_dev)
246{
247 struct usb_interface *intf;
248 struct usb_host_interface *intf_desc;
249 struct usb_endpoint_descriptor *ep;
250 int i;
251
252 if (gspca_dev->sd_desc->int_pkt_scan) {
253 intf = usb_ifnum_to_if(gspca_dev->dev, gspca_dev->iface);
254 intf_desc = intf->cur_altsetting;
255 for (i = 0; i < intf_desc->desc.bNumEndpoints; i++) {
256 ep = &intf_desc->endpoint[i].desc;
257 if (usb_endpoint_dir_in(ep) &&
258 usb_endpoint_xfer_int(ep)) {
259
260 alloc_and_submit_int_urb(gspca_dev, ep);
261 break;
262 }
263 }
264 }
265}
266
267static void gspca_input_destroy_urb(struct gspca_dev *gspca_dev)
268{
269 struct urb *urb;
270
271 urb = gspca_dev->int_urb;
272 if (urb) {
273 gspca_dev->int_urb = NULL;
274 usb_kill_urb(urb);
275 usb_buffer_free(gspca_dev->dev,
276 urb->transfer_buffer_length,
277 urb->transfer_buffer,
278 urb->transfer_dma);
279 usb_free_urb(urb);
280 }
281}
282#else
283#define gspca_input_connect(gspca_dev) 0
284#define gspca_input_create_urb(gspca_dev)
285#define gspca_input_destroy_urb(gspca_dev)
286#endif
287
107/* get the current input frame buffer */ 288/* get the current input frame buffer */
108struct gspca_frame *gspca_get_i_frame(struct gspca_dev *gspca_dev) 289struct gspca_frame *gspca_get_i_frame(struct gspca_dev *gspca_dev)
109{ 290{
110 struct gspca_frame *frame; 291 struct gspca_frame *frame;
111 int i;
112 292
113 i = gspca_dev->fr_i; 293 frame = gspca_dev->cur_frame;
114 i = gspca_dev->fr_queue[i];
115 frame = &gspca_dev->frame[i];
116 if ((frame->v4l2_buf.flags & BUF_ALL_FLAGS) 294 if ((frame->v4l2_buf.flags & BUF_ALL_FLAGS)
117 != V4L2_BUF_FLAG_QUEUED) 295 != V4L2_BUF_FLAG_QUEUED)
118 return NULL; 296 return NULL;
@@ -486,11 +664,13 @@ static struct usb_host_endpoint *get_ep(struct gspca_dev *gspca_dev)
486 i, ep->desc.bEndpointAddress); 664 i, ep->desc.bEndpointAddress);
487 gspca_dev->alt = i; /* memorize the current alt setting */ 665 gspca_dev->alt = i; /* memorize the current alt setting */
488 if (gspca_dev->nbalt > 1) { 666 if (gspca_dev->nbalt > 1) {
667 gspca_input_destroy_urb(gspca_dev);
489 ret = usb_set_interface(gspca_dev->dev, gspca_dev->iface, i); 668 ret = usb_set_interface(gspca_dev->dev, gspca_dev->iface, i);
490 if (ret < 0) { 669 if (ret < 0) {
491 err("set alt %d err %d", i, ret); 670 err("set alt %d err %d", i, ret);
492 return NULL; 671 ep = NULL;
493 } 672 }
673 gspca_input_create_urb(gspca_dev);
494 } 674 }
495 return ep; 675 return ep;
496} 676}
@@ -534,26 +714,22 @@ static int create_urbs(struct gspca_dev *gspca_dev,
534 nurbs = 1; 714 nurbs = 1;
535 } 715 }
536 716
537 gspca_dev->nurbs = nurbs;
538 for (n = 0; n < nurbs; n++) { 717 for (n = 0; n < nurbs; n++) {
539 urb = usb_alloc_urb(npkt, GFP_KERNEL); 718 urb = usb_alloc_urb(npkt, GFP_KERNEL);
540 if (!urb) { 719 if (!urb) {
541 err("usb_alloc_urb failed"); 720 err("usb_alloc_urb failed");
542 destroy_urbs(gspca_dev);
543 return -ENOMEM; 721 return -ENOMEM;
544 } 722 }
723 gspca_dev->urb[n] = urb;
545 urb->transfer_buffer = usb_buffer_alloc(gspca_dev->dev, 724 urb->transfer_buffer = usb_buffer_alloc(gspca_dev->dev,
546 bsize, 725 bsize,
547 GFP_KERNEL, 726 GFP_KERNEL,
548 &urb->transfer_dma); 727 &urb->transfer_dma);
549 728
550 if (urb->transfer_buffer == NULL) { 729 if (urb->transfer_buffer == NULL) {
551 usb_free_urb(urb); 730 err("usb_buffer_alloc failed");
552 err("usb_buffer_urb failed");
553 destroy_urbs(gspca_dev);
554 return -ENOMEM; 731 return -ENOMEM;
555 } 732 }
556 gspca_dev->urb[n] = urb;
557 urb->dev = gspca_dev->dev; 733 urb->dev = gspca_dev->dev;
558 urb->context = gspca_dev; 734 urb->context = gspca_dev;
559 urb->transfer_buffer_length = bsize; 735 urb->transfer_buffer_length = bsize;
@@ -585,6 +761,7 @@ static int create_urbs(struct gspca_dev *gspca_dev,
585static int gspca_init_transfer(struct gspca_dev *gspca_dev) 761static int gspca_init_transfer(struct gspca_dev *gspca_dev)
586{ 762{
587 struct usb_host_endpoint *ep; 763 struct usb_host_endpoint *ep;
764 struct urb *urb;
588 int n, ret; 765 int n, ret;
589 766
590 if (mutex_lock_interruptible(&gspca_dev->usb_lock)) 767 if (mutex_lock_interruptible(&gspca_dev->usb_lock))
@@ -595,6 +772,8 @@ static int gspca_init_transfer(struct gspca_dev *gspca_dev)
595 goto out; 772 goto out;
596 } 773 }
597 774
775 gspca_dev->usb_err = 0;
776
598 /* set the higher alternate setting and 777 /* set the higher alternate setting and
599 * loop until urb submit succeeds */ 778 * loop until urb submit succeeds */
600 if (gspca_dev->cam.reverse_alts) 779 if (gspca_dev->cam.reverse_alts)
@@ -613,10 +792,15 @@ static int gspca_init_transfer(struct gspca_dev *gspca_dev)
613 goto out; 792 goto out;
614 } 793 }
615 for (;;) { 794 for (;;) {
616 PDEBUG(D_STREAM, "init transfer alt %d", gspca_dev->alt); 795 if (!gspca_dev->cam.no_urb_create) {
617 ret = create_urbs(gspca_dev, ep); 796 PDEBUG(D_STREAM, "init transfer alt %d",
618 if (ret < 0) 797 gspca_dev->alt);
619 goto out; 798 ret = create_urbs(gspca_dev, ep);
799 if (ret < 0) {
800 destroy_urbs(gspca_dev);
801 goto out;
802 }
803 }
620 804
621 /* clear the bulk endpoint */ 805 /* clear the bulk endpoint */
622 if (gspca_dev->cam.bulk) 806 if (gspca_dev->cam.bulk)
@@ -636,8 +820,11 @@ static int gspca_init_transfer(struct gspca_dev *gspca_dev)
636 break; 820 break;
637 821
638 /* submit the URBs */ 822 /* submit the URBs */
639 for (n = 0; n < gspca_dev->nurbs; n++) { 823 for (n = 0; n < MAX_NURBS; n++) {
640 ret = usb_submit_urb(gspca_dev->urb[n], GFP_KERNEL); 824 urb = gspca_dev->urb[n];
825 if (urb == NULL)
826 break;
827 ret = usb_submit_urb(urb, GFP_KERNEL);
641 if (ret < 0) 828 if (ret < 0)
642 break; 829 break;
643 } 830 }
@@ -694,7 +881,9 @@ static void gspca_stream_off(struct gspca_dev *gspca_dev)
694 if (gspca_dev->sd_desc->stopN) 881 if (gspca_dev->sd_desc->stopN)
695 gspca_dev->sd_desc->stopN(gspca_dev); 882 gspca_dev->sd_desc->stopN(gspca_dev);
696 destroy_urbs(gspca_dev); 883 destroy_urbs(gspca_dev);
884 gspca_input_destroy_urb(gspca_dev);
697 gspca_set_alt0(gspca_dev); 885 gspca_set_alt0(gspca_dev);
886 gspca_input_create_urb(gspca_dev);
698 } 887 }
699 888
700 /* always call stop0 to free the subdriver's resources */ 889 /* always call stop0 to free the subdriver's resources */
@@ -2060,11 +2249,12 @@ int gspca_dev_probe(struct usb_interface *intf,
2060 PDEBUG(D_ERR, "Too many config"); 2249 PDEBUG(D_ERR, "Too many config");
2061 return -ENODEV; 2250 return -ENODEV;
2062 } 2251 }
2252
2253 /* the USB video interface must be the first one */
2063 interface = &intf->cur_altsetting->desc; 2254 interface = &intf->cur_altsetting->desc;
2064 if (interface->bInterfaceNumber > 0) { 2255 if (dev->config->desc.bNumInterfaces != 1 &&
2065 PDEBUG(D_ERR, "intf != 0"); 2256 interface->bInterfaceNumber != 0)
2066 return -ENODEV; 2257 return -ENODEV;
2067 }
2068 2258
2069 /* create the device */ 2259 /* create the device */
2070 if (dev_size < sizeof *gspca_dev) 2260 if (dev_size < sizeof *gspca_dev)
@@ -2096,6 +2286,10 @@ int gspca_dev_probe(struct usb_interface *intf,
2096 goto out; 2286 goto out;
2097 gspca_set_default_mode(gspca_dev); 2287 gspca_set_default_mode(gspca_dev);
2098 2288
2289 ret = gspca_input_connect(gspca_dev);
2290 if (ret)
2291 goto out;
2292
2099 mutex_init(&gspca_dev->usb_lock); 2293 mutex_init(&gspca_dev->usb_lock);
2100 mutex_init(&gspca_dev->read_lock); 2294 mutex_init(&gspca_dev->read_lock);
2101 mutex_init(&gspca_dev->queue_lock); 2295 mutex_init(&gspca_dev->queue_lock);
@@ -2116,8 +2310,15 @@ int gspca_dev_probe(struct usb_interface *intf,
2116 2310
2117 usb_set_intfdata(intf, gspca_dev); 2311 usb_set_intfdata(intf, gspca_dev);
2118 PDEBUG(D_PROBE, "%s created", video_device_node_name(&gspca_dev->vdev)); 2312 PDEBUG(D_PROBE, "%s created", video_device_node_name(&gspca_dev->vdev));
2313
2314 gspca_input_create_urb(gspca_dev);
2315
2119 return 0; 2316 return 0;
2120out: 2317out:
2318#ifdef CONFIG_INPUT
2319 if (gspca_dev->input_dev)
2320 input_unregister_device(gspca_dev->input_dev);
2321#endif
2121 kfree(gspca_dev->usb_buf); 2322 kfree(gspca_dev->usb_buf);
2122 kfree(gspca_dev); 2323 kfree(gspca_dev);
2123 return ret; 2324 return ret;
@@ -2133,6 +2334,9 @@ EXPORT_SYMBOL(gspca_dev_probe);
2133void gspca_disconnect(struct usb_interface *intf) 2334void gspca_disconnect(struct usb_interface *intf)
2134{ 2335{
2135 struct gspca_dev *gspca_dev = usb_get_intfdata(intf); 2336 struct gspca_dev *gspca_dev = usb_get_intfdata(intf);
2337#ifdef CONFIG_INPUT
2338 struct input_dev *input_dev;
2339#endif
2136 2340
2137 PDEBUG(D_PROBE, "%s disconnect", 2341 PDEBUG(D_PROBE, "%s disconnect",
2138 video_device_node_name(&gspca_dev->vdev)); 2342 video_device_node_name(&gspca_dev->vdev));
@@ -2144,6 +2348,15 @@ void gspca_disconnect(struct usb_interface *intf)
2144 wake_up_interruptible(&gspca_dev->wq); 2348 wake_up_interruptible(&gspca_dev->wq);
2145 } 2349 }
2146 2350
2351#ifdef CONFIG_INPUT
2352 gspca_input_destroy_urb(gspca_dev);
2353 input_dev = gspca_dev->input_dev;
2354 if (input_dev) {
2355 gspca_dev->input_dev = NULL;
2356 input_unregister_device(input_dev);
2357 }
2358#endif
2359
2147 /* the device is freed at exit of this function */ 2360 /* the device is freed at exit of this function */
2148 gspca_dev->dev = NULL; 2361 gspca_dev->dev = NULL;
2149 mutex_unlock(&gspca_dev->usb_lock); 2362 mutex_unlock(&gspca_dev->usb_lock);
@@ -2169,6 +2382,7 @@ int gspca_suspend(struct usb_interface *intf, pm_message_t message)
2169 if (gspca_dev->sd_desc->stopN) 2382 if (gspca_dev->sd_desc->stopN)
2170 gspca_dev->sd_desc->stopN(gspca_dev); 2383 gspca_dev->sd_desc->stopN(gspca_dev);
2171 destroy_urbs(gspca_dev); 2384 destroy_urbs(gspca_dev);
2385 gspca_input_destroy_urb(gspca_dev);
2172 gspca_set_alt0(gspca_dev); 2386 gspca_set_alt0(gspca_dev);
2173 if (gspca_dev->sd_desc->stop0) 2387 if (gspca_dev->sd_desc->stop0)
2174 gspca_dev->sd_desc->stop0(gspca_dev); 2388 gspca_dev->sd_desc->stop0(gspca_dev);
@@ -2182,6 +2396,7 @@ int gspca_resume(struct usb_interface *intf)
2182 2396
2183 gspca_dev->frozen = 0; 2397 gspca_dev->frozen = 0;
2184 gspca_dev->sd_desc->init(gspca_dev); 2398 gspca_dev->sd_desc->init(gspca_dev);
2399 gspca_input_create_urb(gspca_dev);
2185 if (gspca_dev->streaming) 2400 if (gspca_dev->streaming)
2186 return gspca_init_transfer(gspca_dev); 2401 return gspca_init_transfer(gspca_dev);
2187 return 0; 2402 return 0;
@@ -2205,6 +2420,8 @@ int gspca_auto_gain_n_exposure(struct gspca_dev *gspca_dev, int avg_lum,
2205 int retval = 0; 2420 int retval = 0;
2206 2421
2207 for (i = 0; i < gspca_dev->sd_desc->nctrls; i++) { 2422 for (i = 0; i < gspca_dev->sd_desc->nctrls; i++) {
2423 if (gspca_dev->ctrl_dis & (1 << i))
2424 continue;
2208 if (gspca_dev->sd_desc->ctrls[i].qctrl.id == V4L2_CID_GAIN) 2425 if (gspca_dev->sd_desc->ctrls[i].qctrl.id == V4L2_CID_GAIN)
2209 gain_ctrl = &gspca_dev->sd_desc->ctrls[i]; 2426 gain_ctrl = &gspca_dev->sd_desc->ctrls[i];
2210 if (gspca_dev->sd_desc->ctrls[i].qctrl.id == V4L2_CID_EXPOSURE) 2427 if (gspca_dev->sd_desc->ctrls[i].qctrl.id == V4L2_CID_EXPOSURE)
diff --git a/drivers/media/video/gspca/gspca.h b/drivers/media/video/gspca/gspca.h
index 59c7941da999..02c696a22be0 100644
--- a/drivers/media/video/gspca/gspca.h
+++ b/drivers/media/video/gspca/gspca.h
@@ -48,26 +48,27 @@ extern int gspca_debug;
48 48
49/* used to list framerates supported by a camera mode (resolution) */ 49/* used to list framerates supported by a camera mode (resolution) */
50struct framerates { 50struct framerates {
51 int *rates; 51 const u8 *rates;
52 int nrates; 52 int nrates;
53}; 53};
54 54
55/* device information - set at probe time */ 55/* device information - set at probe time */
56struct cam { 56struct cam {
57 int bulk_size; /* buffer size when image transfer by bulk */
58 const struct v4l2_pix_format *cam_mode; /* size nmodes */ 57 const struct v4l2_pix_format *cam_mode; /* size nmodes */
59 char nmodes;
60 const struct framerates *mode_framerates; /* must have size nmode, 58 const struct framerates *mode_framerates; /* must have size nmode,
61 * just like cam_mode */ 59 * just like cam_mode */
62 __u8 bulk_nurbs; /* number of URBs in bulk mode 60 u32 bulk_size; /* buffer size when image transfer by bulk */
61 u32 input_flags; /* value for ENUM_INPUT status flags */
62 u8 nmodes; /* size of cam_mode */
63 u8 no_urb_create; /* don't create transfer URBs */
64 u8 bulk_nurbs; /* number of URBs in bulk mode
63 * - cannot be > MAX_NURBS 65 * - cannot be > MAX_NURBS
64 * - when 0 and bulk_size != 0 means 66 * - when 0 and bulk_size != 0 means
65 * 1 URB and submit done by subdriver */ 67 * 1 URB and submit done by subdriver */
66 u8 bulk; /* image transfer by 0:isoc / 1:bulk */ 68 u8 bulk; /* image transfer by 0:isoc / 1:bulk */
67 u8 npkt; /* number of packets in an ISOC message 69 u8 npkt; /* number of packets in an ISOC message
68 * 0 is the default value: 32 packets */ 70 * 0 is the default value: 32 packets */
69 u32 input_flags; /* value for ENUM_INPUT status flags */ 71 u8 reverse_alts; /* Alt settings are in high to low order */
70 char reverse_alts; /* Alt settings are in high to low order */
71}; 72};
72 73
73struct gspca_dev; 74struct gspca_dev;
@@ -90,6 +91,9 @@ typedef int (*cam_qmnu_op) (struct gspca_dev *,
90typedef void (*cam_pkt_op) (struct gspca_dev *gspca_dev, 91typedef void (*cam_pkt_op) (struct gspca_dev *gspca_dev,
91 u8 *data, 92 u8 *data,
92 int len); 93 int len);
94typedef int (*cam_int_pkt_op) (struct gspca_dev *gspca_dev,
95 u8 *data,
96 int len);
93 97
94struct ctrl { 98struct ctrl {
95 struct v4l2_queryctrl qctrl; 99 struct v4l2_queryctrl qctrl;
@@ -125,6 +129,12 @@ struct sd_desc {
125 cam_reg_op get_register; 129 cam_reg_op get_register;
126#endif 130#endif
127 cam_ident_op get_chip_ident; 131 cam_ident_op get_chip_ident;
132#ifdef CONFIG_INPUT
133 cam_int_pkt_op int_pkt_scan;
134 /* other_input makes the gspca core create gspca_dev->input even when
135 int_pkt_scan is NULL, for cams with non interrupt driven buttons */
136 u8 other_input;
137#endif
128}; 138};
129 139
130/* packet types when moving from iso buf to frame buf */ 140/* packet types when moving from iso buf to frame buf */
@@ -147,6 +157,10 @@ struct gspca_dev {
147 struct module *module; /* subdriver handling the device */ 157 struct module *module; /* subdriver handling the device */
148 struct usb_device *dev; 158 struct usb_device *dev;
149 struct file *capt_file; /* file doing video capture */ 159 struct file *capt_file; /* file doing video capture */
160#ifdef CONFIG_INPUT
161 struct input_dev *input_dev;
162 char phys[64]; /* physical device path */
163#endif
150 164
151 struct cam cam; /* device information */ 165 struct cam cam; /* device information */
152 const struct sd_desc *sd_desc; /* subdriver description */ 166 const struct sd_desc *sd_desc; /* subdriver description */
@@ -156,6 +170,9 @@ struct gspca_dev {
156#define USB_BUF_SZ 64 170#define USB_BUF_SZ 64
157 __u8 *usb_buf; /* buffer for USB exchanges */ 171 __u8 *usb_buf; /* buffer for USB exchanges */
158 struct urb *urb[MAX_NURBS]; 172 struct urb *urb[MAX_NURBS];
173#ifdef CONFIG_INPUT
174 struct urb *int_urb;
175#endif
159 176
160 __u8 *frbuf; /* buffer for nframes */ 177 __u8 *frbuf; /* buffer for nframes */
161 struct gspca_frame frame[GSPCA_MAX_FRAMES]; 178 struct gspca_frame frame[GSPCA_MAX_FRAMES];
@@ -187,7 +204,6 @@ struct gspca_dev {
187 char users; /* number of opens */ 204 char users; /* number of opens */
188 char present; /* device connected */ 205 char present; /* device connected */
189 char nbufread; /* number of buffers for read() */ 206 char nbufread; /* number of buffers for read() */
190 char nurbs; /* number of allocated URBs */
191 char memory; /* memory type (V4L2_MEMORY_xxx) */ 207 char memory; /* memory type (V4L2_MEMORY_xxx) */
192 __u8 iface; /* USB interface number */ 208 __u8 iface; /* USB interface number */
193 __u8 alt; /* USB alternate setting */ 209 __u8 alt; /* USB alternate setting */
diff --git a/drivers/media/video/gspca/m5602/m5602_mt9m111.c b/drivers/media/video/gspca/m5602/m5602_mt9m111.c
index 8d071dff6944..c0722fa64606 100644
--- a/drivers/media/video/gspca/m5602/m5602_mt9m111.c
+++ b/drivers/media/video/gspca/m5602/m5602_mt9m111.c
@@ -48,7 +48,7 @@ static struct v4l2_pix_format mt9m111_modes[] = {
48 } 48 }
49}; 49};
50 50
51const static struct ctrl mt9m111_ctrls[] = { 51static const struct ctrl mt9m111_ctrls[] = {
52#define VFLIP_IDX 0 52#define VFLIP_IDX 0
53 { 53 {
54 { 54 {
@@ -171,7 +171,7 @@ int mt9m111_probe(struct sd *sd)
171 return -ENODEV; 171 return -ENODEV;
172 } 172 }
173 173
174 info("Probing for a mt9m111 sensor"); 174 PDEBUG(D_PROBE, "Probing for a mt9m111 sensor");
175 175
176 /* Do the preinit */ 176 /* Do the preinit */
177 for (i = 0; i < ARRAY_SIZE(preinit_mt9m111); i++) { 177 for (i = 0; i < ARRAY_SIZE(preinit_mt9m111); i++) {
diff --git a/drivers/media/video/gspca/m5602/m5602_ov7660.c b/drivers/media/video/gspca/m5602/m5602_ov7660.c
index 2a28b74cb3f9..62c1cbf06666 100644
--- a/drivers/media/video/gspca/m5602/m5602_ov7660.c
+++ b/drivers/media/video/gspca/m5602/m5602_ov7660.c
@@ -33,7 +33,7 @@ static int ov7660_set_hflip(struct gspca_dev *gspca_dev, __s32 val);
33static int ov7660_get_vflip(struct gspca_dev *gspca_dev, __s32 *val); 33static int ov7660_get_vflip(struct gspca_dev *gspca_dev, __s32 *val);
34static int ov7660_set_vflip(struct gspca_dev *gspca_dev, __s32 val); 34static int ov7660_set_vflip(struct gspca_dev *gspca_dev, __s32 val);
35 35
36const static struct ctrl ov7660_ctrls[] = { 36static const struct ctrl ov7660_ctrls[] = {
37#define GAIN_IDX 1 37#define GAIN_IDX 1
38 { 38 {
39 { 39 {
diff --git a/drivers/media/video/gspca/m5602/m5602_ov7660.h b/drivers/media/video/gspca/m5602/m5602_ov7660.h
index f5588ebe667c..4d9dcf29da2e 100644
--- a/drivers/media/video/gspca/m5602/m5602_ov7660.h
+++ b/drivers/media/video/gspca/m5602/m5602_ov7660.h
@@ -94,7 +94,7 @@ int ov7660_start(struct sd *sd);
94int ov7660_stop(struct sd *sd); 94int ov7660_stop(struct sd *sd);
95void ov7660_disconnect(struct sd *sd); 95void ov7660_disconnect(struct sd *sd);
96 96
97const static struct m5602_sensor ov7660 = { 97static const struct m5602_sensor ov7660 = {
98 .name = "ov7660", 98 .name = "ov7660",
99 .i2c_slave_id = 0x42, 99 .i2c_slave_id = 0x42,
100 .i2c_regW = 1, 100 .i2c_regW = 1,
diff --git a/drivers/media/video/gspca/m5602/m5602_ov9650.c b/drivers/media/video/gspca/m5602/m5602_ov9650.c
index 923cdd5f7a6b..069ba0044f8b 100644
--- a/drivers/media/video/gspca/m5602/m5602_ov9650.c
+++ b/drivers/media/video/gspca/m5602/m5602_ov9650.c
@@ -307,7 +307,7 @@ int ov9650_probe(struct sd *sd)
307 return -ENODEV; 307 return -ENODEV;
308 } 308 }
309 309
310 info("Probing for an ov9650 sensor"); 310 PDEBUG(D_PROBE, "Probing for an ov9650 sensor");
311 311
312 /* Run the pre-init before probing the sensor */ 312 /* Run the pre-init before probing the sensor */
313 for (i = 0; i < ARRAY_SIZE(preinit_ov9650) && !err; i++) { 313 for (i = 0; i < ARRAY_SIZE(preinit_ov9650) && !err; i++) {
diff --git a/drivers/media/video/gspca/m5602/m5602_po1030.c b/drivers/media/video/gspca/m5602/m5602_po1030.c
index 8d74d8065b79..925b87d66f40 100644
--- a/drivers/media/video/gspca/m5602/m5602_po1030.c
+++ b/drivers/media/video/gspca/m5602/m5602_po1030.c
@@ -205,7 +205,7 @@ int po1030_probe(struct sd *sd)
205 return -ENODEV; 205 return -ENODEV;
206 } 206 }
207 207
208 info("Probing for a po1030 sensor"); 208 PDEBUG(D_PROBE, "Probing for a po1030 sensor");
209 209
210 /* Run the pre-init to actually probe the unit */ 210 /* Run the pre-init to actually probe the unit */
211 for (i = 0; i < ARRAY_SIZE(preinit_po1030); i++) { 211 for (i = 0; i < ARRAY_SIZE(preinit_po1030); i++) {
diff --git a/drivers/media/video/gspca/m5602/m5602_s5k4aa.c b/drivers/media/video/gspca/m5602/m5602_s5k4aa.c
index 1b536f7d30cf..da0a38c78708 100644
--- a/drivers/media/video/gspca/m5602/m5602_s5k4aa.c
+++ b/drivers/media/video/gspca/m5602/m5602_s5k4aa.c
@@ -248,7 +248,7 @@ int s5k4aa_probe(struct sd *sd)
248 return -ENODEV; 248 return -ENODEV;
249 } 249 }
250 250
251 info("Probing for a s5k4aa sensor"); 251 PDEBUG(D_PROBE, "Probing for a s5k4aa sensor");
252 252
253 /* Preinit the sensor */ 253 /* Preinit the sensor */
254 for (i = 0; i < ARRAY_SIZE(preinit_s5k4aa) && !err; i++) { 254 for (i = 0; i < ARRAY_SIZE(preinit_s5k4aa) && !err; i++) {
diff --git a/drivers/media/video/gspca/m5602/m5602_s5k83a.c b/drivers/media/video/gspca/m5602/m5602_s5k83a.c
index 6b89f33a4ce0..fbd91545497a 100644
--- a/drivers/media/video/gspca/m5602/m5602_s5k83a.c
+++ b/drivers/media/video/gspca/m5602/m5602_s5k83a.c
@@ -143,7 +143,7 @@ int s5k83a_probe(struct sd *sd)
143 return -ENODEV; 143 return -ENODEV;
144 } 144 }
145 145
146 info("Probing for a s5k83a sensor"); 146 PDEBUG(D_PROBE, "Probing for a s5k83a sensor");
147 147
148 /* Preinit the sensor */ 148 /* Preinit the sensor */
149 for (i = 0; i < ARRAY_SIZE(preinit_s5k83a) && !err; i++) { 149 for (i = 0; i < ARRAY_SIZE(preinit_s5k83a) && !err; i++) {
diff --git a/drivers/media/video/gspca/mars.c b/drivers/media/video/gspca/mars.c
index 9cf8d68c71bf..3d9229e22b25 100644
--- a/drivers/media/video/gspca/mars.c
+++ b/drivers/media/video/gspca/mars.c
@@ -54,7 +54,7 @@ static int sd_getgamma(struct gspca_dev *gspca_dev, __s32 *val);
54static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val); 54static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val);
55static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val); 55static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val);
56 56
57static struct ctrl sd_ctrls[] = { 57static const struct ctrl sd_ctrls[] = {
58 { 58 {
59 { 59 {
60 .id = V4L2_CID_BRIGHTNESS, 60 .id = V4L2_CID_BRIGHTNESS,
diff --git a/drivers/media/video/gspca/mr97310a.c b/drivers/media/video/gspca/mr97310a.c
index 9154870e07d2..33744e724eaa 100644
--- a/drivers/media/video/gspca/mr97310a.c
+++ b/drivers/media/video/gspca/mr97310a.c
@@ -57,6 +57,14 @@
57#define MR97310A_GAIN_MAX 31 57#define MR97310A_GAIN_MAX 31
58#define MR97310A_GAIN_DEFAULT 25 58#define MR97310A_GAIN_DEFAULT 25
59 59
60#define MR97310A_CONTRAST_MIN 0
61#define MR97310A_CONTRAST_MAX 31
62#define MR97310A_CONTRAST_DEFAULT 23
63
64#define MR97310A_CS_GAIN_MIN 0
65#define MR97310A_CS_GAIN_MAX 0x7ff
66#define MR97310A_CS_GAIN_DEFAULT 0x110
67
60#define MR97310A_MIN_CLOCKDIV_MIN 3 68#define MR97310A_MIN_CLOCKDIV_MIN 3
61#define MR97310A_MIN_CLOCKDIV_MAX 8 69#define MR97310A_MIN_CLOCKDIV_MAX 8
62#define MR97310A_MIN_CLOCKDIV_DEFAULT 3 70#define MR97310A_MIN_CLOCKDIV_DEFAULT 3
@@ -82,7 +90,8 @@ struct sd {
82 90
83 int brightness; 91 int brightness;
84 u16 exposure; 92 u16 exposure;
85 u8 gain; 93 u32 gain;
94 u8 contrast;
86 u8 min_clockdiv; 95 u8 min_clockdiv;
87}; 96};
88 97
@@ -98,6 +107,8 @@ static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
98static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val); 107static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
99static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val); 108static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val);
100static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val); 109static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val);
110static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
111static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
101static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val); 112static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val);
102static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val); 113static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val);
103static int sd_setmin_clockdiv(struct gspca_dev *gspca_dev, __s32 val); 114static int sd_setmin_clockdiv(struct gspca_dev *gspca_dev, __s32 val);
@@ -105,11 +116,13 @@ static int sd_getmin_clockdiv(struct gspca_dev *gspca_dev, __s32 *val);
105static void setbrightness(struct gspca_dev *gspca_dev); 116static void setbrightness(struct gspca_dev *gspca_dev);
106static void setexposure(struct gspca_dev *gspca_dev); 117static void setexposure(struct gspca_dev *gspca_dev);
107static void setgain(struct gspca_dev *gspca_dev); 118static void setgain(struct gspca_dev *gspca_dev);
119static void setcontrast(struct gspca_dev *gspca_dev);
108 120
109/* V4L2 controls supported by the driver */ 121/* V4L2 controls supported by the driver */
110static struct ctrl sd_ctrls[] = { 122static const struct ctrl sd_ctrls[] = {
111/* Separate brightness control description for Argus QuickClix as it has 123/* Separate brightness control description for Argus QuickClix as it has
112 different limits from the other mr97310a cameras */ 124 * different limits from the other mr97310a cameras, and separate gain
125 * control for Sakar CyberPix camera. */
113 { 126 {
114#define NORM_BRIGHTNESS_IDX 0 127#define NORM_BRIGHTNESS_IDX 0
115 { 128 {
@@ -171,7 +184,37 @@ static struct ctrl sd_ctrls[] = {
171 .get = sd_getgain, 184 .get = sd_getgain,
172 }, 185 },
173 { 186 {
174#define MIN_CLOCKDIV_IDX 4 187#define SAKAR_CS_GAIN_IDX 4
188 {
189 .id = V4L2_CID_GAIN,
190 .type = V4L2_CTRL_TYPE_INTEGER,
191 .name = "Gain",
192 .minimum = MR97310A_CS_GAIN_MIN,
193 .maximum = MR97310A_CS_GAIN_MAX,
194 .step = 1,
195 .default_value = MR97310A_CS_GAIN_DEFAULT,
196 .flags = 0,
197 },
198 .set = sd_setgain,
199 .get = sd_getgain,
200 },
201 {
202#define CONTRAST_IDX 5
203 {
204 .id = V4L2_CID_CONTRAST,
205 .type = V4L2_CTRL_TYPE_INTEGER,
206 .name = "Contrast",
207 .minimum = MR97310A_CONTRAST_MIN,
208 .maximum = MR97310A_CONTRAST_MAX,
209 .step = 1,
210 .default_value = MR97310A_CONTRAST_DEFAULT,
211 .flags = 0,
212 },
213 .set = sd_setcontrast,
214 .get = sd_getcontrast,
215 },
216 {
217#define MIN_CLOCKDIV_IDX 6
175 { 218 {
176 .id = V4L2_CID_PRIVATE_BASE, 219 .id = V4L2_CID_PRIVATE_BASE,
177 .type = V4L2_CTRL_TYPE_INTEGER, 220 .type = V4L2_CTRL_TYPE_INTEGER,
@@ -327,7 +370,6 @@ static int zero_the_pointer(struct gspca_dev *gspca_dev)
327 if (err_code < 0) 370 if (err_code < 0)
328 return err_code; 371 return err_code;
329 372
330 err_code = mr_write(gspca_dev, 1);
331 data[0] = 0x19; 373 data[0] = 0x19;
332 data[1] = 0x51; 374 data[1] = 0x51;
333 err_code = mr_write(gspca_dev, 2); 375 err_code = mr_write(gspca_dev, 2);
@@ -437,6 +479,7 @@ static int sd_config(struct gspca_dev *gspca_dev,
437{ 479{
438 struct sd *sd = (struct sd *) gspca_dev; 480 struct sd *sd = (struct sd *) gspca_dev;
439 struct cam *cam; 481 struct cam *cam;
482 int gain_default = MR97310A_GAIN_DEFAULT;
440 int err_code; 483 int err_code;
441 484
442 cam = &gspca_dev->cam; 485 cam = &gspca_dev->cam;
@@ -460,12 +503,14 @@ static int sd_config(struct gspca_dev *gspca_dev,
460 if (err_code < 0) 503 if (err_code < 0)
461 return err_code; 504 return err_code;
462 505
506 /* Now, the query for sensor type. */
507 err_code = cam_get_response16(gspca_dev, 0x07, 1);
508 if (err_code < 0)
509 return err_code;
510
463 if (id->idProduct == 0x0110 || id->idProduct == 0x010e) { 511 if (id->idProduct == 0x0110 || id->idProduct == 0x010e) {
464 sd->cam_type = CAM_TYPE_CIF; 512 sd->cam_type = CAM_TYPE_CIF;
465 cam->nmodes--; 513 cam->nmodes--;
466 err_code = cam_get_response16(gspca_dev, 0x06, 1);
467 if (err_code < 0)
468 return err_code;
469 /* 514 /*
470 * All but one of the known CIF cameras share the same USB ID, 515 * All but one of the known CIF cameras share the same USB ID,
471 * but two different init routines are in use, and the control 516 * but two different init routines are in use, and the control
@@ -473,12 +518,12 @@ static int sd_config(struct gspca_dev *gspca_dev,
473 * of the two known varieties is connected! 518 * of the two known varieties is connected!
474 * 519 *
475 * A list of known CIF cameras follows. They all report either 520 * A list of known CIF cameras follows. They all report either
476 * 0002 for type 0 or 0003 for type 1. 521 * 0200 for type 0 or 0300 for type 1.
477 * If you have another to report, please do 522 * If you have another to report, please do
478 * 523 *
479 * Name sd->sensor_type reported by 524 * Name sd->sensor_type reported by
480 * 525 *
481 * Sakar Spy-shot 0 T. Kilgore 526 * Sakar 56379 Spy-shot 0 T. Kilgore
482 * Innovage 0 T. Kilgore 527 * Innovage 0 T. Kilgore
483 * Vivitar Mini 0 H. De Goede 528 * Vivitar Mini 0 H. De Goede
484 * Vivitar Mini 0 E. Rodriguez 529 * Vivitar Mini 0 E. Rodriguez
@@ -487,7 +532,7 @@ static int sd_config(struct gspca_dev *gspca_dev,
487 * Philips dig. keych. 1 T. Kilgore 532 * Philips dig. keych. 1 T. Kilgore
488 * Trust Spyc@m 100 1 A. Jacobs 533 * Trust Spyc@m 100 1 A. Jacobs
489 */ 534 */
490 switch (gspca_dev->usb_buf[1]) { 535 switch (gspca_dev->usb_buf[0]) {
491 case 2: 536 case 2:
492 sd->sensor_type = 0; 537 sd->sensor_type = 0;
493 break; 538 break;
@@ -504,20 +549,19 @@ static int sd_config(struct gspca_dev *gspca_dev,
504 } else { 549 } else {
505 sd->cam_type = CAM_TYPE_VGA; 550 sd->cam_type = CAM_TYPE_VGA;
506 551
507 err_code = cam_get_response16(gspca_dev, 0x07, 1);
508 if (err_code < 0)
509 return err_code;
510
511 /* 552 /*
512 * Here is a table of the responses to the previous command 553 * Here is a table of the responses to the query for sensor
513 * from the known MR97310A VGA cameras. 554 * type, from the known MR97310A VGA cameras. Six different
555 * cameras of which five share the same USB ID.
514 * 556 *
515 * Name gspca_dev->usb_buf[] sd->sensor_type 557 * Name gspca_dev->usb_buf[] sd->sensor_type
516 * sd->do_lcd_stop 558 * sd->do_lcd_stop
517 * Aiptek Pencam VGA+ 0300 0 1 559 * Aiptek Pencam VGA+ 0300 0 1
518 * ION digital 0350 0 1 560 * ION digital 0300 0 1
519 * Argus DC-1620 0450 1 0 561 * Argus DC-1620 0450 1 0
520 * Argus QuickClix 0420 1 1 562 * Argus QuickClix 0420 1 1
563 * Sakar 77379 Digital 0350 0 1
564 * Sakar 1638x CyberPix 0120 0 2
521 * 565 *
522 * Based upon these results, we assume default settings 566 * Based upon these results, we assume default settings
523 * and then correct as necessary, as follows. 567 * and then correct as necessary, as follows.
@@ -527,10 +571,12 @@ static int sd_config(struct gspca_dev *gspca_dev,
527 sd->sensor_type = 1; 571 sd->sensor_type = 1;
528 sd->do_lcd_stop = 0; 572 sd->do_lcd_stop = 0;
529 sd->adj_colors = 0; 573 sd->adj_colors = 0;
530 if ((gspca_dev->usb_buf[0] != 0x03) && 574 if (gspca_dev->usb_buf[0] == 0x01) {
575 sd->sensor_type = 2;
576 } else if ((gspca_dev->usb_buf[0] != 0x03) &&
531 (gspca_dev->usb_buf[0] != 0x04)) { 577 (gspca_dev->usb_buf[0] != 0x04)) {
532 PDEBUG(D_ERR, "Unknown VGA Sensor id Byte 0: %02x", 578 PDEBUG(D_ERR, "Unknown VGA Sensor id Byte 0: %02x",
533 gspca_dev->usb_buf[1]); 579 gspca_dev->usb_buf[0]);
534 PDEBUG(D_ERR, "Defaults assumed, may not work"); 580 PDEBUG(D_ERR, "Defaults assumed, may not work");
535 PDEBUG(D_ERR, "Please report this"); 581 PDEBUG(D_ERR, "Please report this");
536 } 582 }
@@ -560,7 +606,7 @@ static int sd_config(struct gspca_dev *gspca_dev,
560 PDEBUG(D_PROBE, "MR97310A VGA camera detected, sensor: %d", 606 PDEBUG(D_PROBE, "MR97310A VGA camera detected, sensor: %d",
561 sd->sensor_type); 607 sd->sensor_type);
562 } 608 }
563 /* Stop streaming as we've started it to probe the sensor type. */ 609 /* Stop streaming as we've started it only to probe the sensor type. */
564 sd_stopN(gspca_dev); 610 sd_stopN(gspca_dev);
565 611
566 if (force_sensor_type != -1) { 612 if (force_sensor_type != -1) {
@@ -574,9 +620,13 @@ static int sd_config(struct gspca_dev *gspca_dev,
574 /* No brightness for sensor_type 0 */ 620 /* No brightness for sensor_type 0 */
575 if (sd->sensor_type == 0) 621 if (sd->sensor_type == 0)
576 gspca_dev->ctrl_dis = (1 << NORM_BRIGHTNESS_IDX) | 622 gspca_dev->ctrl_dis = (1 << NORM_BRIGHTNESS_IDX) |
577 (1 << ARGUS_QC_BRIGHTNESS_IDX); 623 (1 << ARGUS_QC_BRIGHTNESS_IDX) |
624 (1 << CONTRAST_IDX) |
625 (1 << SAKAR_CS_GAIN_IDX);
578 else 626 else
579 gspca_dev->ctrl_dis = (1 << ARGUS_QC_BRIGHTNESS_IDX) | 627 gspca_dev->ctrl_dis = (1 << ARGUS_QC_BRIGHTNESS_IDX) |
628 (1 << CONTRAST_IDX) |
629 (1 << SAKAR_CS_GAIN_IDX) |
580 (1 << MIN_CLOCKDIV_IDX); 630 (1 << MIN_CLOCKDIV_IDX);
581 } else { 631 } else {
582 /* All controls need to be disabled if VGA sensor_type is 0 */ 632 /* All controls need to be disabled if VGA sensor_type is 0 */
@@ -585,17 +635,30 @@ static int sd_config(struct gspca_dev *gspca_dev,
585 (1 << ARGUS_QC_BRIGHTNESS_IDX) | 635 (1 << ARGUS_QC_BRIGHTNESS_IDX) |
586 (1 << EXPOSURE_IDX) | 636 (1 << EXPOSURE_IDX) |
587 (1 << GAIN_IDX) | 637 (1 << GAIN_IDX) |
638 (1 << CONTRAST_IDX) |
639 (1 << SAKAR_CS_GAIN_IDX) |
588 (1 << MIN_CLOCKDIV_IDX); 640 (1 << MIN_CLOCKDIV_IDX);
589 else if (sd->do_lcd_stop) 641 else if (sd->sensor_type == 2) {
642 gspca_dev->ctrl_dis = (1 << NORM_BRIGHTNESS_IDX) |
643 (1 << ARGUS_QC_BRIGHTNESS_IDX) |
644 (1 << GAIN_IDX) |
645 (1 << MIN_CLOCKDIV_IDX);
646 gain_default = MR97310A_CS_GAIN_DEFAULT;
647 } else if (sd->do_lcd_stop)
590 /* Argus QuickClix has different brightness limits */ 648 /* Argus QuickClix has different brightness limits */
591 gspca_dev->ctrl_dis = (1 << NORM_BRIGHTNESS_IDX); 649 gspca_dev->ctrl_dis = (1 << NORM_BRIGHTNESS_IDX) |
650 (1 << CONTRAST_IDX) |
651 (1 << SAKAR_CS_GAIN_IDX);
592 else 652 else
593 gspca_dev->ctrl_dis = (1 << ARGUS_QC_BRIGHTNESS_IDX); 653 gspca_dev->ctrl_dis = (1 << ARGUS_QC_BRIGHTNESS_IDX) |
654 (1 << CONTRAST_IDX) |
655 (1 << SAKAR_CS_GAIN_IDX);
594 } 656 }
595 657
596 sd->brightness = MR97310A_BRIGHTNESS_DEFAULT; 658 sd->brightness = MR97310A_BRIGHTNESS_DEFAULT;
597 sd->exposure = MR97310A_EXPOSURE_DEFAULT; 659 sd->exposure = MR97310A_EXPOSURE_DEFAULT;
598 sd->gain = MR97310A_GAIN_DEFAULT; 660 sd->gain = gain_default;
661 sd->contrast = MR97310A_CONTRAST_DEFAULT;
599 sd->min_clockdiv = MR97310A_MIN_CLOCKDIV_DEFAULT; 662 sd->min_clockdiv = MR97310A_MIN_CLOCKDIV_DEFAULT;
600 663
601 return 0; 664 return 0;
@@ -697,6 +760,12 @@ static int start_cif_cam(struct gspca_dev *gspca_dev)
697 {0x13, 0x00, {0x01}, 1}, 760 {0x13, 0x00, {0x01}, 1},
698 {0, 0, {0}, 0} 761 {0, 0, {0}, 0}
699 }; 762 };
763 /* Without this command the cam won't work with USB-UHCI */
764 gspca_dev->usb_buf[0] = 0x0a;
765 gspca_dev->usb_buf[1] = 0x00;
766 err_code = mr_write(gspca_dev, 2);
767 if (err_code < 0)
768 return err_code;
700 err_code = sensor_write_regs(gspca_dev, cif_sensor1_init_data, 769 err_code = sensor_write_regs(gspca_dev, cif_sensor1_init_data,
701 ARRAY_SIZE(cif_sensor1_init_data)); 770 ARRAY_SIZE(cif_sensor1_init_data));
702 } 771 }
@@ -717,6 +786,10 @@ static int start_vga_cam(struct gspca_dev *gspca_dev)
717 data[5] = 0x00; 786 data[5] = 0x00;
718 data[10] = 0x91; 787 data[10] = 0x91;
719 } 788 }
789 if (sd->sensor_type == 2) {
790 data[5] = 0x00;
791 data[10] = 0x18;
792 }
720 793
721 switch (gspca_dev->width) { 794 switch (gspca_dev->width) {
722 case 160: 795 case 160:
@@ -731,6 +804,10 @@ static int start_vga_cam(struct gspca_dev *gspca_dev)
731 data[4] = 0x78; /* reg 3, V size/4 */ 804 data[4] = 0x78; /* reg 3, V size/4 */
732 data[6] = 0x04; /* reg 5, H start */ 805 data[6] = 0x04; /* reg 5, H start */
733 data[8] = 0x03; /* reg 7, V start */ 806 data[8] = 0x03; /* reg 7, V start */
807 if (sd->sensor_type == 2) {
808 data[6] = 2;
809 data[8] = 1;
810 }
734 if (sd->do_lcd_stop) 811 if (sd->do_lcd_stop)
735 data[8] = 0x04; /* Bayer tile shifted */ 812 data[8] = 0x04; /* Bayer tile shifted */
736 break; 813 break;
@@ -753,7 +830,6 @@ static int start_vga_cam(struct gspca_dev *gspca_dev)
753 return err_code; 830 return err_code;
754 831
755 if (!sd->sensor_type) { 832 if (!sd->sensor_type) {
756 /* The only known sensor_type 0 cam is the Argus DC-1620 */
757 const struct sensor_w_data vga_sensor0_init_data[] = { 833 const struct sensor_w_data vga_sensor0_init_data[] = {
758 {0x01, 0x00, {0x0c, 0x00, 0x04}, 3}, 834 {0x01, 0x00, {0x0c, 0x00, 0x04}, 3},
759 {0x14, 0x00, {0x01, 0xe4, 0x02, 0x84}, 4}, 835 {0x14, 0x00, {0x01, 0xe4, 0x02, 0x84}, 4},
@@ -764,7 +840,7 @@ static int start_vga_cam(struct gspca_dev *gspca_dev)
764 }; 840 };
765 err_code = sensor_write_regs(gspca_dev, vga_sensor0_init_data, 841 err_code = sensor_write_regs(gspca_dev, vga_sensor0_init_data,
766 ARRAY_SIZE(vga_sensor0_init_data)); 842 ARRAY_SIZE(vga_sensor0_init_data));
767 } else { /* sd->sensor_type = 1 */ 843 } else if (sd->sensor_type == 1) {
768 const struct sensor_w_data color_adj[] = { 844 const struct sensor_w_data color_adj[] = {
769 {0x02, 0x00, {0x06, 0x59, 0x0c, 0x16, 0x00, 845 {0x02, 0x00, {0x06, 0x59, 0x0c, 0x16, 0x00,
770 /* adjusted blue, green, red gain correct 846 /* adjusted blue, green, red gain correct
@@ -802,6 +878,48 @@ static int start_vga_cam(struct gspca_dev *gspca_dev)
802 878
803 err_code = sensor_write_regs(gspca_dev, vga_sensor1_init_data, 879 err_code = sensor_write_regs(gspca_dev, vga_sensor1_init_data,
804 ARRAY_SIZE(vga_sensor1_init_data)); 880 ARRAY_SIZE(vga_sensor1_init_data));
881 } else { /* sensor type == 2 */
882 const struct sensor_w_data vga_sensor2_init_data[] = {
883
884 {0x01, 0x00, {0x48}, 1},
885 {0x02, 0x00, {0x22}, 1},
886 /* Reg 3 msb and 4 is lsb of the exposure setting*/
887 {0x05, 0x00, {0x10}, 1},
888 {0x06, 0x00, {0x00}, 1},
889 {0x07, 0x00, {0x00}, 1},
890 {0x08, 0x00, {0x00}, 1},
891 {0x09, 0x00, {0x00}, 1},
892 /* The following are used in the gain control
893 * which is BTW completely borked in the OEM driver
894 * The values for each color go from 0 to 0x7ff
895 *{0x0a, 0x00, {0x01}, 1}, green1 gain msb
896 *{0x0b, 0x00, {0x10}, 1}, green1 gain lsb
897 *{0x0c, 0x00, {0x01}, 1}, red gain msb
898 *{0x0d, 0x00, {0x10}, 1}, red gain lsb
899 *{0x0e, 0x00, {0x01}, 1}, blue gain msb
900 *{0x0f, 0x00, {0x10}, 1}, blue gain lsb
901 *{0x10, 0x00, {0x01}, 1}, green2 gain msb
902 *{0x11, 0x00, {0x10}, 1}, green2 gain lsb
903 */
904 {0x12, 0x00, {0x00}, 1},
905 {0x13, 0x00, {0x04}, 1}, /* weird effect on colors */
906 {0x14, 0x00, {0x00}, 1},
907 {0x15, 0x00, {0x06}, 1},
908 {0x16, 0x00, {0x01}, 1},
909 {0x17, 0x00, {0xe2}, 1}, /* vertical alignment */
910 {0x18, 0x00, {0x02}, 1},
911 {0x19, 0x00, {0x82}, 1}, /* don't mess with */
912 {0x1a, 0x00, {0x00}, 1},
913 {0x1b, 0x00, {0x20}, 1},
914 /* {0x1c, 0x00, {0x17}, 1}, contrast control */
915 {0x1d, 0x00, {0x80}, 1}, /* moving causes a mess */
916 {0x1e, 0x00, {0x08}, 1}, /* moving jams the camera */
917 {0x1f, 0x00, {0x0c}, 1},
918 {0x20, 0x00, {0x00}, 1},
919 {0, 0, {0}, 0}
920 };
921 err_code = sensor_write_regs(gspca_dev, vga_sensor2_init_data,
922 ARRAY_SIZE(vga_sensor2_init_data));
805 } 923 }
806 return err_code; 924 return err_code;
807} 925}
@@ -834,6 +952,7 @@ static int sd_start(struct gspca_dev *gspca_dev)
834 return err_code; 952 return err_code;
835 953
836 setbrightness(gspca_dev); 954 setbrightness(gspca_dev);
955 setcontrast(gspca_dev);
837 setexposure(gspca_dev); 956 setexposure(gspca_dev);
838 setgain(gspca_dev); 957 setgain(gspca_dev);
839 958
@@ -893,7 +1012,7 @@ static void setbrightness(struct gspca_dev *gspca_dev)
893static void setexposure(struct gspca_dev *gspca_dev) 1012static void setexposure(struct gspca_dev *gspca_dev)
894{ 1013{
895 struct sd *sd = (struct sd *) gspca_dev; 1014 struct sd *sd = (struct sd *) gspca_dev;
896 int exposure; 1015 int exposure = MR97310A_EXPOSURE_DEFAULT;
897 u8 buf[2]; 1016 u8 buf[2];
898 1017
899 if (gspca_dev->ctrl_dis & (1 << EXPOSURE_IDX)) 1018 if (gspca_dev->ctrl_dis & (1 << EXPOSURE_IDX))
@@ -905,6 +1024,11 @@ static void setexposure(struct gspca_dev *gspca_dev)
905 exposure = (sd->exposure * 9267) / 10000 + 300; 1024 exposure = (sd->exposure * 9267) / 10000 + 300;
906 sensor_write1(gspca_dev, 3, exposure >> 4); 1025 sensor_write1(gspca_dev, 3, exposure >> 4);
907 sensor_write1(gspca_dev, 4, exposure & 0x0f); 1026 sensor_write1(gspca_dev, 4, exposure & 0x0f);
1027 } else if (sd->sensor_type == 2) {
1028 exposure = sd->exposure;
1029 exposure >>= 3;
1030 sensor_write1(gspca_dev, 3, exposure >> 8);
1031 sensor_write1(gspca_dev, 4, exposure & 0xff);
908 } else { 1032 } else {
909 /* We have both a clock divider and an exposure register. 1033 /* We have both a clock divider and an exposure register.
910 We first calculate the clock divider, as that determines 1034 We first calculate the clock divider, as that determines
@@ -943,17 +1067,34 @@ static void setexposure(struct gspca_dev *gspca_dev)
943static void setgain(struct gspca_dev *gspca_dev) 1067static void setgain(struct gspca_dev *gspca_dev)
944{ 1068{
945 struct sd *sd = (struct sd *) gspca_dev; 1069 struct sd *sd = (struct sd *) gspca_dev;
1070 u8 gainreg;
946 1071
947 if (gspca_dev->ctrl_dis & (1 << GAIN_IDX)) 1072 if ((gspca_dev->ctrl_dis & (1 << GAIN_IDX)) &&
1073 (gspca_dev->ctrl_dis & (1 << SAKAR_CS_GAIN_IDX)))
948 return; 1074 return;
949 1075
950 if (sd->cam_type == CAM_TYPE_CIF && sd->sensor_type == 1) { 1076 if (sd->cam_type == CAM_TYPE_CIF && sd->sensor_type == 1)
951 sensor_write1(gspca_dev, 0x0e, sd->gain); 1077 sensor_write1(gspca_dev, 0x0e, sd->gain);
952 } else { 1078 else if (sd->cam_type == CAM_TYPE_VGA && sd->sensor_type == 2)
1079 for (gainreg = 0x0a; gainreg < 0x11; gainreg += 2) {
1080 sensor_write1(gspca_dev, gainreg, sd->gain >> 8);
1081 sensor_write1(gspca_dev, gainreg + 1, sd->gain & 0xff);
1082 }
1083 else
953 sensor_write1(gspca_dev, 0x10, sd->gain); 1084 sensor_write1(gspca_dev, 0x10, sd->gain);
954 }
955} 1085}
956 1086
1087static void setcontrast(struct gspca_dev *gspca_dev)
1088{
1089 struct sd *sd = (struct sd *) gspca_dev;
1090
1091 if (gspca_dev->ctrl_dis & (1 << CONTRAST_IDX))
1092 return;
1093
1094 sensor_write1(gspca_dev, 0x1c, sd->contrast);
1095}
1096
1097
957static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) 1098static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
958{ 1099{
959 struct sd *sd = (struct sd *) gspca_dev; 1100 struct sd *sd = (struct sd *) gspca_dev;
@@ -1008,6 +1149,25 @@ static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val)
1008 return 0; 1149 return 0;
1009} 1150}
1010 1151
1152static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
1153{
1154 struct sd *sd = (struct sd *) gspca_dev;
1155
1156 sd->contrast = val;
1157 if (gspca_dev->streaming)
1158 setcontrast(gspca_dev);
1159 return 0;
1160}
1161
1162
1163static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
1164{
1165 struct sd *sd = (struct sd *) gspca_dev;
1166
1167 *val = sd->contrast;
1168 return 0;
1169}
1170
1011static int sd_setmin_clockdiv(struct gspca_dev *gspca_dev, __s32 val) 1171static int sd_setmin_clockdiv(struct gspca_dev *gspca_dev, __s32 val)
1012{ 1172{
1013 struct sd *sd = (struct sd *) gspca_dev; 1173 struct sd *sd = (struct sd *) gspca_dev;
diff --git a/drivers/media/video/gspca/ov519.c b/drivers/media/video/gspca/ov519.c
index b4f965731244..bc4ced6c013b 100644
--- a/drivers/media/video/gspca/ov519.c
+++ b/drivers/media/video/gspca/ov519.c
@@ -38,6 +38,7 @@
38 */ 38 */
39#define MODULE_NAME "ov519" 39#define MODULE_NAME "ov519"
40 40
41#include <linux/input.h>
41#include "gspca.h" 42#include "gspca.h"
42 43
43MODULE_AUTHOR("Jean-Francois Moine <http://moinejf.free.fr>"); 44MODULE_AUTHOR("Jean-Francois Moine <http://moinejf.free.fr>");
@@ -70,6 +71,9 @@ struct sd {
70 char invert_led; 71 char invert_led;
71#define BRIDGE_INVERT_LED 8 72#define BRIDGE_INVERT_LED 8
72 73
74 char snapshot_pressed;
75 char snapshot_needs_reset;
76
73 /* Determined by sensor type */ 77 /* Determined by sensor type */
74 __u8 sif; 78 __u8 sif;
75 79
@@ -99,10 +103,12 @@ struct sd {
99#define SEN_OV66308AF 5 103#define SEN_OV66308AF 5
100#define SEN_OV7610 6 104#define SEN_OV7610 6
101#define SEN_OV7620 7 105#define SEN_OV7620 7
102#define SEN_OV7640 8 106#define SEN_OV7620AE 8
103#define SEN_OV7670 9 107#define SEN_OV7640 9
104#define SEN_OV76BE 10 108#define SEN_OV7648 10
105#define SEN_OV8610 11 109#define SEN_OV7670 11
110#define SEN_OV76BE 12
111#define SEN_OV8610 13
106 112
107 u8 sensor_addr; 113 u8 sensor_addr;
108 int sensor_width; 114 int sensor_width;
@@ -139,6 +145,7 @@ static void setautobrightness(struct sd *sd);
139static void setfreq(struct sd *sd); 145static void setfreq(struct sd *sd);
140 146
141static const struct ctrl sd_ctrls[] = { 147static const struct ctrl sd_ctrls[] = {
148#define BRIGHTNESS_IDX 0
142 { 149 {
143 { 150 {
144 .id = V4L2_CID_BRIGHTNESS, 151 .id = V4L2_CID_BRIGHTNESS,
@@ -153,6 +160,7 @@ static const struct ctrl sd_ctrls[] = {
153 .set = sd_setbrightness, 160 .set = sd_setbrightness,
154 .get = sd_getbrightness, 161 .get = sd_getbrightness,
155 }, 162 },
163#define CONTRAST_IDX 1
156 { 164 {
157 { 165 {
158 .id = V4L2_CID_CONTRAST, 166 .id = V4L2_CID_CONTRAST,
@@ -167,6 +175,7 @@ static const struct ctrl sd_ctrls[] = {
167 .set = sd_setcontrast, 175 .set = sd_setcontrast,
168 .get = sd_getcontrast, 176 .get = sd_getcontrast,
169 }, 177 },
178#define COLOR_IDX 2
170 { 179 {
171 { 180 {
172 .id = V4L2_CID_SATURATION, 181 .id = V4L2_CID_SATURATION,
@@ -2554,7 +2563,7 @@ static int ov7xx0_configure(struct sd *sd)
2554 /* I don't know what's different about the 76BE yet. */ 2563 /* I don't know what's different about the 76BE yet. */
2555 if (i2c_r(sd, 0x15) & 1) { 2564 if (i2c_r(sd, 0x15) & 1) {
2556 PDEBUG(D_PROBE, "Sensor is an OV7620AE"); 2565 PDEBUG(D_PROBE, "Sensor is an OV7620AE");
2557 sd->sensor = SEN_OV7620; 2566 sd->sensor = SEN_OV7620AE;
2558 } else { 2567 } else {
2559 PDEBUG(D_PROBE, "Sensor is an OV76BE"); 2568 PDEBUG(D_PROBE, "Sensor is an OV76BE");
2560 sd->sensor = SEN_OV76BE; 2569 sd->sensor = SEN_OV76BE;
@@ -2588,7 +2597,7 @@ static int ov7xx0_configure(struct sd *sd)
2588 break; 2597 break;
2589 case 0x48: 2598 case 0x48:
2590 PDEBUG(D_PROBE, "Sensor is an OV7648"); 2599 PDEBUG(D_PROBE, "Sensor is an OV7648");
2591 sd->sensor = SEN_OV7640; /* FIXME */ 2600 sd->sensor = SEN_OV7648;
2592 break; 2601 break;
2593 default: 2602 default:
2594 PDEBUG(D_PROBE, "Unknown sensor: 0x76%x", low); 2603 PDEBUG(D_PROBE, "Unknown sensor: 0x76%x", low);
@@ -2680,6 +2689,36 @@ static void ov51x_led_control(struct sd *sd, int on)
2680 } 2689 }
2681} 2690}
2682 2691
2692static void sd_reset_snapshot(struct gspca_dev *gspca_dev)
2693{
2694 struct sd *sd = (struct sd *) gspca_dev;
2695
2696 if (!sd->snapshot_needs_reset)
2697 return;
2698
2699 /* Note it is important that we clear sd->snapshot_needs_reset,
2700 before actually clearing the snapshot state in the bridge
2701 otherwise we might race with the pkt_scan interrupt handler */
2702 sd->snapshot_needs_reset = 0;
2703
2704 switch (sd->bridge) {
2705 case BRIDGE_OV511:
2706 case BRIDGE_OV511PLUS:
2707 reg_w(sd, R51x_SYS_SNAP, 0x02);
2708 reg_w(sd, R51x_SYS_SNAP, 0x00);
2709 break;
2710 case BRIDGE_OV518:
2711 case BRIDGE_OV518PLUS:
2712 reg_w(sd, R51x_SYS_SNAP, 0x02); /* Reset */
2713 reg_w(sd, R51x_SYS_SNAP, 0x01); /* Enable */
2714 break;
2715 case BRIDGE_OV519:
2716 reg_w(sd, R51x_SYS_RESET, 0x40);
2717 reg_w(sd, R51x_SYS_RESET, 0x00);
2718 break;
2719 }
2720}
2721
2683static int ov51x_upload_quan_tables(struct sd *sd) 2722static int ov51x_upload_quan_tables(struct sd *sd)
2684{ 2723{
2685 const unsigned char yQuanTable511[] = { 2724 const unsigned char yQuanTable511[] = {
@@ -3115,7 +3154,11 @@ static int sd_config(struct gspca_dev *gspca_dev,
3115 (1 << OV7670_FREQ_IDX); 3154 (1 << OV7670_FREQ_IDX);
3116 } 3155 }
3117 sd->quality = QUALITY_DEF; 3156 sd->quality = QUALITY_DEF;
3118 if (sd->sensor == SEN_OV7640 || sd->sensor == SEN_OV7670) 3157 if (sd->sensor == SEN_OV7640 ||
3158 sd->sensor == SEN_OV7648)
3159 gspca_dev->ctrl_dis |= (1 << AUTOBRIGHT_IDX) |
3160 (1 << CONTRAST_IDX);
3161 if (sd->sensor == SEN_OV7670)
3119 gspca_dev->ctrl_dis |= 1 << AUTOBRIGHT_IDX; 3162 gspca_dev->ctrl_dis |= 1 << AUTOBRIGHT_IDX;
3120 /* OV8610 Frequency filter control should work but needs testing */ 3163 /* OV8610 Frequency filter control should work but needs testing */
3121 if (sd->sensor == SEN_OV8610) 3164 if (sd->sensor == SEN_OV8610)
@@ -3169,10 +3212,12 @@ static int sd_init(struct gspca_dev *gspca_dev)
3169 return -EIO; 3212 return -EIO;
3170 break; 3213 break;
3171 case SEN_OV7620: 3214 case SEN_OV7620:
3215 case SEN_OV7620AE:
3172 if (write_i2c_regvals(sd, norm_7620, ARRAY_SIZE(norm_7620))) 3216 if (write_i2c_regvals(sd, norm_7620, ARRAY_SIZE(norm_7620)))
3173 return -EIO; 3217 return -EIO;
3174 break; 3218 break;
3175 case SEN_OV7640: 3219 case SEN_OV7640:
3220 case SEN_OV7648:
3176 if (write_i2c_regvals(sd, norm_7640, ARRAY_SIZE(norm_7640))) 3221 if (write_i2c_regvals(sd, norm_7640, ARRAY_SIZE(norm_7640)))
3177 return -EIO; 3222 return -EIO;
3178 break; 3223 break;
@@ -3246,7 +3291,9 @@ static int ov511_mode_init_regs(struct sd *sd)
3246 /* Note once the FIXME's in mode_init_ov_sensor_regs() are fixed 3291 /* Note once the FIXME's in mode_init_ov_sensor_regs() are fixed
3247 for more sensors we need to do this for them too */ 3292 for more sensors we need to do this for them too */
3248 case SEN_OV7620: 3293 case SEN_OV7620:
3294 case SEN_OV7620AE:
3249 case SEN_OV7640: 3295 case SEN_OV7640:
3296 case SEN_OV7648:
3250 case SEN_OV76BE: 3297 case SEN_OV76BE:
3251 if (sd->gspca_dev.width == 320) 3298 if (sd->gspca_dev.width == 320)
3252 interlaced = 1; 3299 interlaced = 1;
@@ -3377,7 +3424,7 @@ static int ov518_mode_init_regs(struct sd *sd)
3377 3424
3378 if (sd->bridge == BRIDGE_OV518PLUS) { 3425 if (sd->bridge == BRIDGE_OV518PLUS) {
3379 switch (sd->sensor) { 3426 switch (sd->sensor) {
3380 case SEN_OV7620: 3427 case SEN_OV7620AE:
3381 if (sd->gspca_dev.width == 320) { 3428 if (sd->gspca_dev.width == 320) {
3382 reg_w(sd, 0x20, 0x00); 3429 reg_w(sd, 0x20, 0x00);
3383 reg_w(sd, 0x21, 0x19); 3430 reg_w(sd, 0x21, 0x19);
@@ -3386,6 +3433,10 @@ static int ov518_mode_init_regs(struct sd *sd)
3386 reg_w(sd, 0x21, 0x1f); 3433 reg_w(sd, 0x21, 0x1f);
3387 } 3434 }
3388 break; 3435 break;
3436 case SEN_OV7620:
3437 reg_w(sd, 0x20, 0x00);
3438 reg_w(sd, 0x21, 0x19);
3439 break;
3389 default: 3440 default:
3390 reg_w(sd, 0x21, 0x19); 3441 reg_w(sd, 0x21, 0x19);
3391 } 3442 }
@@ -3488,7 +3539,8 @@ static int ov519_mode_init_regs(struct sd *sd)
3488 if (write_regvals(sd, mode_init_519, 3539 if (write_regvals(sd, mode_init_519,
3489 ARRAY_SIZE(mode_init_519))) 3540 ARRAY_SIZE(mode_init_519)))
3490 return -EIO; 3541 return -EIO;
3491 if (sd->sensor == SEN_OV7640) { 3542 if (sd->sensor == SEN_OV7640 ||
3543 sd->sensor == SEN_OV7648) {
3492 /* Select 8-bit input mode */ 3544 /* Select 8-bit input mode */
3493 reg_w_mask(sd, OV519_R20_DFR, 0x10, 0x10); 3545 reg_w_mask(sd, OV519_R20_DFR, 0x10, 0x10);
3494 } 3546 }
@@ -3503,6 +3555,9 @@ static int ov519_mode_init_regs(struct sd *sd)
3503 if (sd->sensor == SEN_OV7670 && 3555 if (sd->sensor == SEN_OV7670 &&
3504 sd->gspca_dev.cam.cam_mode[sd->gspca_dev.curr_mode].priv) 3556 sd->gspca_dev.cam.cam_mode[sd->gspca_dev.curr_mode].priv)
3505 reg_w(sd, OV519_R12_X_OFFSETL, 0x04); 3557 reg_w(sd, OV519_R12_X_OFFSETL, 0x04);
3558 else if (sd->sensor == SEN_OV7648 &&
3559 sd->gspca_dev.cam.cam_mode[sd->gspca_dev.curr_mode].priv)
3560 reg_w(sd, OV519_R12_X_OFFSETL, 0x01);
3506 else 3561 else
3507 reg_w(sd, OV519_R12_X_OFFSETL, 0x00); 3562 reg_w(sd, OV519_R12_X_OFFSETL, 0x00);
3508 reg_w(sd, OV519_R13_X_OFFSETH, 0x00); 3563 reg_w(sd, OV519_R13_X_OFFSETH, 0x00);
@@ -3520,6 +3575,7 @@ static int ov519_mode_init_regs(struct sd *sd)
3520 sd->clockdiv = 0; 3575 sd->clockdiv = 0;
3521 switch (sd->sensor) { 3576 switch (sd->sensor) {
3522 case SEN_OV7640: 3577 case SEN_OV7640:
3578 case SEN_OV7648:
3523 switch (sd->frame_rate) { 3579 switch (sd->frame_rate) {
3524 default: 3580 default:
3525/* case 30: */ 3581/* case 30: */
@@ -3649,6 +3705,7 @@ static int mode_init_ov_sensor_regs(struct sd *sd)
3649 i2c_w_mask(sd, 0x12, 0x04, 0x06); /* AWB: 1 Test pattern: 0 */ 3705 i2c_w_mask(sd, 0x12, 0x04, 0x06); /* AWB: 1 Test pattern: 0 */
3650 break; 3706 break;
3651 case SEN_OV7620: 3707 case SEN_OV7620:
3708 case SEN_OV7620AE:
3652 case SEN_OV76BE: 3709 case SEN_OV76BE:
3653 i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20); 3710 i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20);
3654 i2c_w_mask(sd, 0x28, qvga ? 0x00 : 0x20, 0x20); 3711 i2c_w_mask(sd, 0x28, qvga ? 0x00 : 0x20, 0x20);
@@ -3663,13 +3720,16 @@ static int mode_init_ov_sensor_regs(struct sd *sd)
3663 i2c_w(sd, 0x35, qvga ? 0x1e : 0x9e); 3720 i2c_w(sd, 0x35, qvga ? 0x1e : 0x9e);
3664 break; 3721 break;
3665 case SEN_OV7640: 3722 case SEN_OV7640:
3723 case SEN_OV7648:
3666 i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20); 3724 i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20);
3667 i2c_w_mask(sd, 0x28, qvga ? 0x00 : 0x20, 0x20); 3725 i2c_w_mask(sd, 0x28, qvga ? 0x00 : 0x20, 0x20);
3668/* i2c_w(sd, 0x24, qvga ? 0x20 : 0x3a); */ 3726 /* Setting this undocumented bit in qvga mode removes a very
3669/* i2c_w(sd, 0x25, qvga ? 0x30 : 0x60); */ 3727 annoying vertical shaking of the image */
3670/* i2c_w_mask(sd, 0x2d, qvga ? 0x40 : 0x00, 0x40); */ 3728 i2c_w_mask(sd, 0x2d, qvga ? 0x40 : 0x00, 0x40);
3671/* i2c_w_mask(sd, 0x67, qvga ? 0xf0 : 0x90, 0xf0); */ 3729 /* Unknown */
3672/* i2c_w_mask(sd, 0x74, qvga ? 0x20 : 0x00, 0x20); */ 3730 i2c_w_mask(sd, 0x67, qvga ? 0xf0 : 0x90, 0xf0);
3731 /* Allow higher automatic gain (to allow higher framerates) */
3732 i2c_w_mask(sd, 0x74, qvga ? 0x20 : 0x00, 0x20);
3673 i2c_w_mask(sd, 0x12, 0x04, 0x04); /* AWB: 1 */ 3733 i2c_w_mask(sd, 0x12, 0x04, 0x04); /* AWB: 1 */
3674 break; 3734 break;
3675 case SEN_OV7670: 3735 case SEN_OV7670:
@@ -3795,11 +3855,13 @@ static int set_ov_sensor_window(struct sd *sd)
3795 } 3855 }
3796 break; 3856 break;
3797 case SEN_OV7620: 3857 case SEN_OV7620:
3858 case SEN_OV7620AE:
3798 hwsbase = 0x2f; /* From 7620.SET (spec is wrong) */ 3859 hwsbase = 0x2f; /* From 7620.SET (spec is wrong) */
3799 hwebase = 0x2f; 3860 hwebase = 0x2f;
3800 vwsbase = vwebase = 0x05; 3861 vwsbase = vwebase = 0x05;
3801 break; 3862 break;
3802 case SEN_OV7640: 3863 case SEN_OV7640:
3864 case SEN_OV7648:
3803 hwsbase = 0x1a; 3865 hwsbase = 0x1a;
3804 hwebase = 0x1a; 3866 hwebase = 0x1a;
3805 vwsbase = vwebase = 0x03; 3867 vwsbase = vwebase = 0x03;
@@ -3893,6 +3955,12 @@ static int sd_start(struct gspca_dev *gspca_dev)
3893 setautobrightness(sd); 3955 setautobrightness(sd);
3894 setfreq(sd); 3956 setfreq(sd);
3895 3957
3958 /* Force clear snapshot state in case the snapshot button was
3959 pressed while we weren't streaming */
3960 sd->snapshot_needs_reset = 1;
3961 sd_reset_snapshot(gspca_dev);
3962 sd->snapshot_pressed = 0;
3963
3896 ret = ov51x_restart(sd); 3964 ret = ov51x_restart(sd);
3897 if (ret < 0) 3965 if (ret < 0)
3898 goto out; 3966 goto out;
@@ -3919,6 +3987,34 @@ static void sd_stop0(struct gspca_dev *gspca_dev)
3919 w9968cf_stop0(sd); 3987 w9968cf_stop0(sd);
3920} 3988}
3921 3989
3990static void ov51x_handle_button(struct gspca_dev *gspca_dev, u8 state)
3991{
3992 struct sd *sd = (struct sd *) gspca_dev;
3993
3994 if (sd->snapshot_pressed != state) {
3995#ifdef CONFIG_INPUT
3996 input_report_key(gspca_dev->input_dev, KEY_CAMERA, state);
3997 input_sync(gspca_dev->input_dev);
3998#endif
3999 if (state)
4000 sd->snapshot_needs_reset = 1;
4001
4002 sd->snapshot_pressed = state;
4003 } else {
4004 /* On the ov511 / ov519 we need to reset the button state
4005 multiple times, as resetting does not work as long as the
4006 button stays pressed */
4007 switch (sd->bridge) {
4008 case BRIDGE_OV511:
4009 case BRIDGE_OV511PLUS:
4010 case BRIDGE_OV519:
4011 if (state)
4012 sd->snapshot_needs_reset = 1;
4013 break;
4014 }
4015 }
4016}
4017
3922static void ov511_pkt_scan(struct gspca_dev *gspca_dev, 4018static void ov511_pkt_scan(struct gspca_dev *gspca_dev,
3923 u8 *in, /* isoc packet */ 4019 u8 *in, /* isoc packet */
3924 int len) /* iso packet length */ 4020 int len) /* iso packet length */
@@ -3940,6 +4036,7 @@ static void ov511_pkt_scan(struct gspca_dev *gspca_dev,
3940 */ 4036 */
3941 if (!(in[0] | in[1] | in[2] | in[3] | in[4] | in[5] | in[6] | in[7]) && 4037 if (!(in[0] | in[1] | in[2] | in[3] | in[4] | in[5] | in[6] | in[7]) &&
3942 (in[8] & 0x08)) { 4038 (in[8] & 0x08)) {
4039 ov51x_handle_button(gspca_dev, (in[8] >> 2) & 1);
3943 if (in[8] & 0x80) { 4040 if (in[8] & 0x80) {
3944 /* Frame end */ 4041 /* Frame end */
3945 if ((in[9] + 1) * 8 != gspca_dev->width || 4042 if ((in[9] + 1) * 8 != gspca_dev->width ||
@@ -3977,6 +4074,7 @@ static void ov518_pkt_scan(struct gspca_dev *gspca_dev,
3977 /* A false positive here is likely, until OVT gives me 4074 /* A false positive here is likely, until OVT gives me
3978 * the definitive SOF/EOF format */ 4075 * the definitive SOF/EOF format */
3979 if ((!(data[0] | data[1] | data[2] | data[3] | data[5])) && data[6]) { 4076 if ((!(data[0] | data[1] | data[2] | data[3] | data[5])) && data[6]) {
4077 ov51x_handle_button(gspca_dev, (data[6] >> 1) & 1);
3980 gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0); 4078 gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
3981 gspca_frame_add(gspca_dev, FIRST_PACKET, NULL, 0); 4079 gspca_frame_add(gspca_dev, FIRST_PACKET, NULL, 0);
3982 sd->packet_nr = 0; 4080 sd->packet_nr = 0;
@@ -4024,6 +4122,9 @@ static void ov519_pkt_scan(struct gspca_dev *gspca_dev,
4024 if (data[0] == 0xff && data[1] == 0xff && data[2] == 0xff) { 4122 if (data[0] == 0xff && data[1] == 0xff && data[2] == 0xff) {
4025 switch (data[3]) { 4123 switch (data[3]) {
4026 case 0x50: /* start of frame */ 4124 case 0x50: /* start of frame */
4125 /* Don't check the button state here, as the state
4126 usually (always ?) changes at EOF and checking it
4127 here leads to unnecessary snapshot state resets. */
4027#define HDRSZ 16 4128#define HDRSZ 16
4028 data += HDRSZ; 4129 data += HDRSZ;
4029 len -= HDRSZ; 4130 len -= HDRSZ;
@@ -4035,6 +4136,7 @@ static void ov519_pkt_scan(struct gspca_dev *gspca_dev,
4035 gspca_dev->last_packet_type = DISCARD_PACKET; 4136 gspca_dev->last_packet_type = DISCARD_PACKET;
4036 return; 4137 return;
4037 case 0x51: /* end of frame */ 4138 case 0x51: /* end of frame */
4139 ov51x_handle_button(gspca_dev, data[11] & 1);
4038 if (data[9] != 0) 4140 if (data[9] != 0)
4039 gspca_dev->last_packet_type = DISCARD_PACKET; 4141 gspca_dev->last_packet_type = DISCARD_PACKET;
4040 gspca_frame_add(gspca_dev, LAST_PACKET, 4142 gspca_frame_add(gspca_dev, LAST_PACKET,
@@ -4103,9 +4205,11 @@ static void setbrightness(struct gspca_dev *gspca_dev)
4103 case SEN_OV6630: 4205 case SEN_OV6630:
4104 case SEN_OV66308AF: 4206 case SEN_OV66308AF:
4105 case SEN_OV7640: 4207 case SEN_OV7640:
4208 case SEN_OV7648:
4106 i2c_w(sd, OV7610_REG_BRT, val); 4209 i2c_w(sd, OV7610_REG_BRT, val);
4107 break; 4210 break;
4108 case SEN_OV7620: 4211 case SEN_OV7620:
4212 case SEN_OV7620AE:
4109 /* 7620 doesn't like manual changes when in auto mode */ 4213 /* 7620 doesn't like manual changes when in auto mode */
4110 if (!sd->autobrightness) 4214 if (!sd->autobrightness)
4111 i2c_w(sd, OV7610_REG_BRT, val); 4215 i2c_w(sd, OV7610_REG_BRT, val);
@@ -4142,7 +4246,8 @@ static void setcontrast(struct gspca_dev *gspca_dev)
4142 i2c_w(sd, 0x64, ctab[val >> 5]); 4246 i2c_w(sd, 0x64, ctab[val >> 5]);
4143 break; 4247 break;
4144 } 4248 }
4145 case SEN_OV7620: { 4249 case SEN_OV7620:
4250 case SEN_OV7620AE: {
4146 static const __u8 ctab[] = { 4251 static const __u8 ctab[] = {
4147 0x01, 0x05, 0x09, 0x11, 0x15, 0x35, 0x37, 0x57, 4252 0x01, 0x05, 0x09, 0x11, 0x15, 0x35, 0x37, 0x57,
4148 0x5b, 0xa5, 0xa7, 0xc7, 0xc9, 0xcf, 0xef, 0xff 4253 0x5b, 0xa5, 0xa7, 0xc7, 0xc9, 0xcf, 0xef, 0xff
@@ -4152,10 +4257,6 @@ static void setcontrast(struct gspca_dev *gspca_dev)
4152 i2c_w(sd, 0x64, ctab[val >> 4]); 4257 i2c_w(sd, 0x64, ctab[val >> 4]);
4153 break; 4258 break;
4154 } 4259 }
4155 case SEN_OV7640:
4156 /* Use gain control instead. */
4157 i2c_w(sd, OV7610_REG_GAIN, val >> 2);
4158 break;
4159 case SEN_OV7670: 4260 case SEN_OV7670:
4160 /* check that this isn't just the same as ov7610 */ 4261 /* check that this isn't just the same as ov7610 */
4161 i2c_w(sd, OV7670_REG_CONTRAS, val >> 1); 4262 i2c_w(sd, OV7670_REG_CONTRAS, val >> 1);
@@ -4179,6 +4280,7 @@ static void setcolors(struct gspca_dev *gspca_dev)
4179 i2c_w(sd, OV7610_REG_SAT, val); 4280 i2c_w(sd, OV7610_REG_SAT, val);
4180 break; 4281 break;
4181 case SEN_OV7620: 4282 case SEN_OV7620:
4283 case SEN_OV7620AE:
4182 /* Use UV gamma control instead. Bits 0 & 7 are reserved. */ 4284 /* Use UV gamma control instead. Bits 0 & 7 are reserved. */
4183/* rc = ov_i2c_write(sd->dev, 0x62, (val >> 9) & 0x7e); 4285/* rc = ov_i2c_write(sd->dev, 0x62, (val >> 9) & 0x7e);
4184 if (rc < 0) 4286 if (rc < 0)
@@ -4186,6 +4288,7 @@ static void setcolors(struct gspca_dev *gspca_dev)
4186 i2c_w(sd, OV7610_REG_SAT, val); 4288 i2c_w(sd, OV7610_REG_SAT, val);
4187 break; 4289 break;
4188 case SEN_OV7640: 4290 case SEN_OV7640:
4291 case SEN_OV7648:
4189 i2c_w(sd, OV7610_REG_SAT, val & 0xf0); 4292 i2c_w(sd, OV7610_REG_SAT, val & 0xf0);
4190 break; 4293 break;
4191 case SEN_OV7670: 4294 case SEN_OV7670:
@@ -4198,7 +4301,8 @@ static void setcolors(struct gspca_dev *gspca_dev)
4198 4301
4199static void setautobrightness(struct sd *sd) 4302static void setautobrightness(struct sd *sd)
4200{ 4303{
4201 if (sd->sensor == SEN_OV7640 || sd->sensor == SEN_OV7670 || 4304 if (sd->sensor == SEN_OV7640 || sd->sensor == SEN_OV7648 ||
4305 sd->sensor == SEN_OV7670 ||
4202 sd->sensor == SEN_OV2610 || sd->sensor == SEN_OV3610) 4306 sd->sensor == SEN_OV2610 || sd->sensor == SEN_OV3610)
4203 return; 4307 return;
4204 4308
@@ -4475,9 +4579,13 @@ static const struct sd_desc sd_desc = {
4475 .stopN = sd_stopN, 4579 .stopN = sd_stopN,
4476 .stop0 = sd_stop0, 4580 .stop0 = sd_stop0,
4477 .pkt_scan = sd_pkt_scan, 4581 .pkt_scan = sd_pkt_scan,
4582 .dq_callback = sd_reset_snapshot,
4478 .querymenu = sd_querymenu, 4583 .querymenu = sd_querymenu,
4479 .get_jcomp = sd_get_jcomp, 4584 .get_jcomp = sd_get_jcomp,
4480 .set_jcomp = sd_set_jcomp, 4585 .set_jcomp = sd_set_jcomp,
4586#ifdef CONFIG_INPUT
4587 .other_input = 1,
4588#endif
4481}; 4589};
4482 4590
4483/* -- module initialisation -- */ 4591/* -- module initialisation -- */
@@ -4494,7 +4602,8 @@ static const __devinitdata struct usb_device_id device_table[] = {
4494 .driver_info = BRIDGE_OV519 | BRIDGE_INVERT_LED }, 4602 .driver_info = BRIDGE_OV519 | BRIDGE_INVERT_LED },
4495 {USB_DEVICE(0x045e, 0x028c), .driver_info = BRIDGE_OV519 }, 4603 {USB_DEVICE(0x045e, 0x028c), .driver_info = BRIDGE_OV519 },
4496 {USB_DEVICE(0x054c, 0x0154), .driver_info = BRIDGE_OV519 }, 4604 {USB_DEVICE(0x054c, 0x0154), .driver_info = BRIDGE_OV519 },
4497 {USB_DEVICE(0x054c, 0x0155), .driver_info = BRIDGE_OV519 }, 4605 {USB_DEVICE(0x054c, 0x0155),
4606 .driver_info = BRIDGE_OV519 | BRIDGE_INVERT_LED },
4498 {USB_DEVICE(0x05a9, 0x0511), .driver_info = BRIDGE_OV511 }, 4607 {USB_DEVICE(0x05a9, 0x0511), .driver_info = BRIDGE_OV511 },
4499 {USB_DEVICE(0x05a9, 0x0518), .driver_info = BRIDGE_OV518 }, 4608 {USB_DEVICE(0x05a9, 0x0518), .driver_info = BRIDGE_OV518 },
4500 {USB_DEVICE(0x05a9, 0x0519), .driver_info = BRIDGE_OV519 }, 4609 {USB_DEVICE(0x05a9, 0x0519), .driver_info = BRIDGE_OV519 },
diff --git a/drivers/media/video/gspca/ov534.c b/drivers/media/video/gspca/ov534.c
index 0a6b8f07a69d..957e05e2d08f 100644
--- a/drivers/media/video/gspca/ov534.c
+++ b/drivers/media/video/gspca/ov534.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * ov534 gspca driver 2 * ov534-ov772x gspca driver
3 * 3 *
4 * Copyright (C) 2008 Antonio Ospite <ospite@studenti.unina.it> 4 * Copyright (C) 2008 Antonio Ospite <ospite@studenti.unina.it>
5 * Copyright (C) 2008 Jim Paris <jim@jtan.com> 5 * Copyright (C) 2008 Jim Paris <jim@jtan.com>
@@ -68,12 +68,7 @@ struct sd {
68 s8 sharpness; 68 s8 sharpness;
69 u8 hflip; 69 u8 hflip;
70 u8 vflip; 70 u8 vflip;
71 u8 satur;
72 u8 lightfreq;
73 71
74 u8 sensor;
75#define SENSOR_OV772X 0
76#define SENSOR_OV965X 1
77}; 72};
78 73
79/* V4L2 controls supported by the driver */ 74/* V4L2 controls supported by the driver */
@@ -101,12 +96,8 @@ static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
101static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val); 96static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
102static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val); 97static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
103static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val); 98static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
104static int sd_setsatur(struct gspca_dev *gspca_dev, __s32 val);
105static int sd_getsatur(struct gspca_dev *gspca_dev, __s32 *val);
106static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val);
107static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val);
108 99
109static struct ctrl sd_ctrls_ov772x[] = { 100static const struct ctrl sd_ctrls[] = {
110 { /* 0 */ 101 { /* 0 */
111 { 102 {
112 .id = V4L2_CID_BRIGHTNESS, 103 .id = V4L2_CID_BRIGHTNESS,
@@ -115,8 +106,8 @@ static struct ctrl sd_ctrls_ov772x[] = {
115 .minimum = 0, 106 .minimum = 0,
116 .maximum = 255, 107 .maximum = 255,
117 .step = 1, 108 .step = 1,
118#define BRIGHTNESS_77_DEF 20 109#define BRIGHTNESS_DEF 20
119 .default_value = BRIGHTNESS_77_DEF, 110 .default_value = BRIGHTNESS_DEF,
120 }, 111 },
121 .set = sd_setbrightness, 112 .set = sd_setbrightness,
122 .get = sd_getbrightness, 113 .get = sd_getbrightness,
@@ -129,8 +120,8 @@ static struct ctrl sd_ctrls_ov772x[] = {
129 .minimum = 0, 120 .minimum = 0,
130 .maximum = 255, 121 .maximum = 255,
131 .step = 1, 122 .step = 1,
132#define CONTRAST_77_DEF 37 123#define CONTRAST_DEF 37
133 .default_value = CONTRAST_77_DEF, 124 .default_value = CONTRAST_DEF,
134 }, 125 },
135 .set = sd_setcontrast, 126 .set = sd_setcontrast,
136 .get = sd_getcontrast, 127 .get = sd_getcontrast,
@@ -157,8 +148,8 @@ static struct ctrl sd_ctrls_ov772x[] = {
157 .minimum = 0, 148 .minimum = 0,
158 .maximum = 255, 149 .maximum = 255,
159 .step = 1, 150 .step = 1,
160#define EXPO_77_DEF 120 151#define EXPO_DEF 120
161 .default_value = EXPO_77_DEF, 152 .default_value = EXPO_DEF,
162 }, 153 },
163 .set = sd_setexposure, 154 .set = sd_setexposure,
164 .get = sd_getexposure, 155 .get = sd_getexposure,
@@ -213,13 +204,13 @@ static struct ctrl sd_ctrls_ov772x[] = {
213 .minimum = 0, 204 .minimum = 0,
214 .maximum = 1, 205 .maximum = 1,
215 .step = 1, 206 .step = 1,
216#define AUTOGAIN_77_DEF 0 207#define AUTOGAIN_DEF 0
217 .default_value = AUTOGAIN_77_DEF, 208 .default_value = AUTOGAIN_DEF,
218 }, 209 },
219 .set = sd_setautogain, 210 .set = sd_setautogain,
220 .get = sd_getautogain, 211 .get = sd_getautogain,
221 }, 212 },
222#define AWB_77_IDX 8 213#define AWB_IDX 8
223 { /* 8 */ 214 { /* 8 */
224 { 215 {
225 .id = V4L2_CID_AUTO_WHITE_BALANCE, 216 .id = V4L2_CID_AUTO_WHITE_BALANCE,
@@ -242,8 +233,8 @@ static struct ctrl sd_ctrls_ov772x[] = {
242 .minimum = 0, 233 .minimum = 0,
243 .maximum = 63, 234 .maximum = 63,
244 .step = 1, 235 .step = 1,
245#define SHARPNESS_77_DEF 0 236#define SHARPNESS_DEF 0
246 .default_value = SHARPNESS_77_DEF, 237 .default_value = SHARPNESS_DEF,
247 }, 238 },
248 .set = sd_setsharpness, 239 .set = sd_setsharpness,
249 .get = sd_getsharpness, 240 .get = sd_getsharpness,
@@ -277,107 +268,6 @@ static struct ctrl sd_ctrls_ov772x[] = {
277 .get = sd_getvflip, 268 .get = sd_getvflip,
278 }, 269 },
279}; 270};
280static struct ctrl sd_ctrls_ov965x[] = {
281 { /* 0 */
282 {
283 .id = V4L2_CID_BRIGHTNESS,
284 .type = V4L2_CTRL_TYPE_INTEGER,
285 .name = "Brightness",
286 .minimum = 0,
287 .maximum = 15,
288 .step = 1,
289#define BRIGHTNESS_96_DEF 7
290 .default_value = BRIGHTNESS_96_DEF,
291 },
292 .set = sd_setbrightness,
293 .get = sd_getbrightness,
294 },
295 { /* 1 */
296 {
297 .id = V4L2_CID_CONTRAST,
298 .type = V4L2_CTRL_TYPE_INTEGER,
299 .name = "Contrast",
300 .minimum = 0,
301 .maximum = 15,
302 .step = 1,
303#define CONTRAST_96_DEF 3
304 .default_value = CONTRAST_96_DEF,
305 },
306 .set = sd_setcontrast,
307 .get = sd_getcontrast,
308 },
309 { /* 2 */
310 {
311 .id = V4L2_CID_AUTOGAIN,
312 .type = V4L2_CTRL_TYPE_BOOLEAN,
313 .name = "Autogain",
314 .minimum = 0,
315 .maximum = 1,
316 .step = 1,
317#define AUTOGAIN_96_DEF 1
318 .default_value = AUTOGAIN_96_DEF,
319 },
320 .set = sd_setautogain,
321 .get = sd_getautogain,
322 },
323#define EXPO_96_IDX 3
324 { /* 3 */
325 {
326 .id = V4L2_CID_EXPOSURE,
327 .type = V4L2_CTRL_TYPE_INTEGER,
328 .name = "Exposure",
329 .minimum = 0,
330 .maximum = 3,
331 .step = 1,
332#define EXPO_96_DEF 0
333 .default_value = EXPO_96_DEF,
334 },
335 .set = sd_setexposure,
336 .get = sd_getexposure,
337 },
338 { /* 4 */
339 {
340 .id = V4L2_CID_SHARPNESS,
341 .type = V4L2_CTRL_TYPE_INTEGER,
342 .name = "Sharpness",
343 .minimum = -1, /* -1 = auto */
344 .maximum = 4,
345 .step = 1,
346#define SHARPNESS_96_DEF -1
347 .default_value = SHARPNESS_96_DEF,
348 },
349 .set = sd_setsharpness,
350 .get = sd_getsharpness,
351 },
352 { /* 5 */
353 {
354 .id = V4L2_CID_SATURATION,
355 .type = V4L2_CTRL_TYPE_INTEGER,
356 .name = "Saturation",
357 .minimum = 0,
358 .maximum = 4,
359 .step = 1,
360#define SATUR_DEF 2
361 .default_value = SATUR_DEF,
362 },
363 .set = sd_setsatur,
364 .get = sd_getsatur,
365 },
366 {
367 {
368 .id = V4L2_CID_POWER_LINE_FREQUENCY,
369 .type = V4L2_CTRL_TYPE_MENU,
370 .name = "Light frequency filter",
371 .minimum = 0,
372 .maximum = 2, /* 0: 0, 1: 50Hz, 2:60Hz */
373 .step = 1,
374#define FREQ_DEF 0
375 .default_value = FREQ_DEF,
376 },
377 .set = sd_setfreq,
378 .get = sd_getfreq,
379 },
380};
381 271
382static const struct v4l2_pix_format ov772x_mode[] = { 272static const struct v4l2_pix_format ov772x_mode[] = {
383 {320, 240, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE, 273 {320, 240, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE,
@@ -392,35 +282,21 @@ static const struct v4l2_pix_format ov772x_mode[] = {
392 .priv = 0}, 282 .priv = 0},
393}; 283};
394 284
395static const struct v4l2_pix_format ov965x_mode[] = { 285static const u8 qvga_rates[] = {125, 100, 75, 60, 50, 40, 30};
396 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, 286static const u8 vga_rates[] = {60, 50, 40, 30, 15};
397 .bytesperline = 320, 287
398 .sizeimage = 320 * 240 * 3 / 8 + 590, 288static const struct framerates ov772x_framerates[] = {
399 .colorspace = V4L2_COLORSPACE_JPEG, 289 { /* 320x240 */
400 .priv = 4}, 290 .rates = qvga_rates,
401 {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, 291 .nrates = ARRAY_SIZE(qvga_rates),
402 .bytesperline = 640, 292 },
403 .sizeimage = 640 * 480 * 3 / 8 + 590, 293 { /* 640x480 */
404 .colorspace = V4L2_COLORSPACE_JPEG, 294 .rates = vga_rates,
405 .priv = 3}, 295 .nrates = ARRAY_SIZE(vga_rates),
406 {800, 600, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, 296 },
407 .bytesperline = 800,
408 .sizeimage = 800 * 600 * 3 / 8 + 590,
409 .colorspace = V4L2_COLORSPACE_JPEG,
410 .priv = 2},
411 {1024, 768, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
412 .bytesperline = 1024,
413 .sizeimage = 1024 * 768 * 3 / 8 + 590,
414 .colorspace = V4L2_COLORSPACE_JPEG,
415 .priv = 1},
416 {1280, 1024, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
417 .bytesperline = 1280,
418 .sizeimage = 1280 * 1024 * 3 / 8 + 590,
419 .colorspace = V4L2_COLORSPACE_JPEG,
420 .priv = 0},
421}; 297};
422 298
423static const u8 bridge_init_ov772x[][2] = { 299static const u8 bridge_init[][2] = {
424 { 0xc2, 0x0c }, 300 { 0xc2, 0x0c },
425 { 0x88, 0xf8 }, 301 { 0x88, 0xf8 },
426 { 0xc3, 0x69 }, 302 { 0xc3, 0x69 },
@@ -478,7 +354,7 @@ static const u8 bridge_init_ov772x[][2] = {
478 { 0xc1, 0x3c }, 354 { 0xc1, 0x3c },
479 { 0xc2, 0x0c }, 355 { 0xc2, 0x0c },
480}; 356};
481static const u8 sensor_init_ov772x[][2] = { 357static const u8 sensor_init[][2] = {
482 { 0x12, 0x80 }, 358 { 0x12, 0x80 },
483 { 0x11, 0x01 }, 359 { 0x11, 0x01 },
484/*fixme: better have a delay?*/ 360/*fixme: better have a delay?*/
@@ -571,7 +447,7 @@ static const u8 sensor_init_ov772x[][2] = {
571 { 0x8e, 0x00 }, /* De-noise threshold */ 447 { 0x8e, 0x00 }, /* De-noise threshold */
572 { 0x0c, 0xd0 } 448 { 0x0c, 0xd0 }
573}; 449};
574static const u8 bridge_start_ov772x_vga[][2] = { 450static const u8 bridge_start_vga[][2] = {
575 {0x1c, 0x00}, 451 {0x1c, 0x00},
576 {0x1d, 0x40}, 452 {0x1d, 0x40},
577 {0x1d, 0x02}, 453 {0x1d, 0x02},
@@ -582,7 +458,7 @@ static const u8 bridge_start_ov772x_vga[][2] = {
582 {0xc0, 0x50}, 458 {0xc0, 0x50},
583 {0xc1, 0x3c}, 459 {0xc1, 0x3c},
584}; 460};
585static const u8 sensor_start_ov772x_vga[][2] = { 461static const u8 sensor_start_vga[][2] = {
586 {0x12, 0x00}, 462 {0x12, 0x00},
587 {0x17, 0x26}, 463 {0x17, 0x26},
588 {0x18, 0xa0}, 464 {0x18, 0xa0},
@@ -592,7 +468,7 @@ static const u8 sensor_start_ov772x_vga[][2] = {
592 {0x2c, 0xf0}, 468 {0x2c, 0xf0},
593 {0x65, 0x20}, 469 {0x65, 0x20},
594}; 470};
595static const u8 bridge_start_ov772x_qvga[][2] = { 471static const u8 bridge_start_qvga[][2] = {
596 {0x1c, 0x00}, 472 {0x1c, 0x00},
597 {0x1d, 0x40}, 473 {0x1d, 0x40},
598 {0x1d, 0x02}, 474 {0x1d, 0x02},
@@ -603,7 +479,7 @@ static const u8 bridge_start_ov772x_qvga[][2] = {
603 {0xc0, 0x28}, 479 {0xc0, 0x28},
604 {0xc1, 0x1e}, 480 {0xc1, 0x1e},
605}; 481};
606static const u8 sensor_start_ov772x_qvga[][2] = { 482static const u8 sensor_start_qvga[][2] = {
607 {0x12, 0x40}, 483 {0x12, 0x40},
608 {0x17, 0x3f}, 484 {0x17, 0x3f},
609 {0x18, 0x50}, 485 {0x18, 0x50},
@@ -614,571 +490,6 @@ static const u8 sensor_start_ov772x_qvga[][2] = {
614 {0x65, 0x2f}, 490 {0x65, 0x2f},
615}; 491};
616 492
617static const u8 bridge_init_ov965x[][2] = {
618 {0x88, 0xf8},
619 {0x89, 0xff},
620 {0x76, 0x03},
621 {0x92, 0x03},
622 {0x95, 0x10},
623 {0xe2, 0x00},
624 {0xe7, 0x3e},
625 {0x8d, 0x1c},
626 {0x8e, 0x00},
627 {0x8f, 0x00},
628 {0x1f, 0x00},
629 {0xc3, 0xf9},
630 {0x89, 0xff},
631 {0x88, 0xf8},
632 {0x76, 0x03},
633 {0x92, 0x01},
634 {0x93, 0x18},
635 {0x1c, 0x0a},
636 {0x1d, 0x48},
637 {0xc0, 0x50},
638 {0xc1, 0x3c},
639 {0x34, 0x05},
640 {0xc2, 0x0c},
641 {0xc3, 0xf9},
642 {0x34, 0x05},
643 {0xe7, 0x2e},
644 {0x31, 0xf9},
645 {0x35, 0x02},
646 {0xd9, 0x10},
647 {0x25, 0x42},
648 {0x94, 0x11},
649};
650
651static const u8 sensor_init_ov965x[][2] = {
652 {0x12, 0x80}, /* com7 - SSCB reset */
653 {0x00, 0x00}, /* gain */
654 {0x01, 0x80}, /* blue */
655 {0x02, 0x80}, /* red */
656 {0x03, 0x1b}, /* vref */
657 {0x04, 0x03}, /* com1 - exposure low bits */
658 {0x0b, 0x57}, /* ver */
659 {0x0e, 0x61}, /* com5 */
660 {0x0f, 0x42}, /* com6 */
661 {0x11, 0x00}, /* clkrc */
662 {0x12, 0x02}, /* com7 - 15fps VGA YUYV */
663 {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */
664 {0x14, 0x28}, /* com9 */
665 {0x16, 0x24}, /* reg16 */
666 {0x17, 0x1d}, /* hstart*/
667 {0x18, 0xbd}, /* hstop */
668 {0x19, 0x01}, /* vstrt */
669 {0x1a, 0x81}, /* vstop*/
670 {0x1e, 0x04}, /* mvfp */
671 {0x24, 0x3c}, /* aew */
672 {0x25, 0x36}, /* aeb */
673 {0x26, 0x71}, /* vpt */
674 {0x27, 0x08}, /* bbias */
675 {0x28, 0x08}, /* gbbias */
676 {0x29, 0x15}, /* gr com */
677 {0x2a, 0x00}, /* exhch */
678 {0x2b, 0x00}, /* exhcl */
679 {0x2c, 0x08}, /* rbias */
680 {0x32, 0xff}, /* href */
681 {0x33, 0x00}, /* chlf */
682 {0x34, 0x3f}, /* aref1 */
683 {0x35, 0x00}, /* aref2 */
684 {0x36, 0xf8}, /* aref3 */
685 {0x38, 0x72}, /* adc2 */
686 {0x39, 0x57}, /* aref4 */
687 {0x3a, 0x80}, /* tslb - yuyv */
688 {0x3b, 0xc4}, /* com11 - night mode 1/4 frame rate */
689 {0x3d, 0x99}, /* com13 */
690 {0x3f, 0xc1}, /* edge */
691 {0x40, 0xc0}, /* com15 */
692 {0x41, 0x40}, /* com16 */
693 {0x42, 0xc0}, /* com17 */
694 {0x43, 0x0a}, /* rsvd */
695 {0x44, 0xf0},
696 {0x45, 0x46},
697 {0x46, 0x62},
698 {0x47, 0x2a},
699 {0x48, 0x3c},
700 {0x4a, 0xfc},
701 {0x4b, 0xfc},
702 {0x4c, 0x7f},
703 {0x4d, 0x7f},
704 {0x4e, 0x7f},
705 {0x4f, 0x98}, /* matrix */
706 {0x50, 0x98},
707 {0x51, 0x00},
708 {0x52, 0x28},
709 {0x53, 0x70},
710 {0x54, 0x98},
711 {0x58, 0x1a}, /* matrix coef sign */
712 {0x59, 0x85}, /* AWB control */
713 {0x5a, 0xa9},
714 {0x5b, 0x64},
715 {0x5c, 0x84},
716 {0x5d, 0x53},
717 {0x5e, 0x0e},
718 {0x5f, 0xf0}, /* AWB blue limit */
719 {0x60, 0xf0}, /* AWB red limit */
720 {0x61, 0xf0}, /* AWB green limit */
721 {0x62, 0x00}, /* lcc1 */
722 {0x63, 0x00}, /* lcc2 */
723 {0x64, 0x02}, /* lcc3 */
724 {0x65, 0x16}, /* lcc4 */
725 {0x66, 0x01}, /* lcc5 */
726 {0x69, 0x02}, /* hv */
727 {0x6b, 0x5a}, /* dbvl */
728 {0x6c, 0x04},
729 {0x6d, 0x55},
730 {0x6e, 0x00},
731 {0x6f, 0x9d},
732 {0x70, 0x21}, /* dnsth */
733 {0x71, 0x78},
734 {0x72, 0x00}, /* poidx */
735 {0x73, 0x01}, /* pckdv */
736 {0x74, 0x3a}, /* xindx */
737 {0x75, 0x35}, /* yindx */
738 {0x76, 0x01},
739 {0x77, 0x02},
740 {0x7a, 0x12}, /* gamma curve */
741 {0x7b, 0x08},
742 {0x7c, 0x16},
743 {0x7d, 0x30},
744 {0x7e, 0x5e},
745 {0x7f, 0x72},
746 {0x80, 0x82},
747 {0x81, 0x8e},
748 {0x82, 0x9a},
749 {0x83, 0xa4},
750 {0x84, 0xac},
751 {0x85, 0xb8},
752 {0x86, 0xc3},
753 {0x87, 0xd6},
754 {0x88, 0xe6},
755 {0x89, 0xf2},
756 {0x8a, 0x03},
757 {0x8c, 0x89}, /* com19 */
758 {0x14, 0x28}, /* com9 */
759 {0x90, 0x7d},
760 {0x91, 0x7b},
761 {0x9d, 0x03}, /* lcc6 */
762 {0x9e, 0x04}, /* lcc7 */
763 {0x9f, 0x7a},
764 {0xa0, 0x79},
765 {0xa1, 0x40}, /* aechm */
766 {0xa4, 0x50}, /* com21 */
767 {0xa5, 0x68}, /* com26 */
768 {0xa6, 0x4a}, /* AWB green */
769 {0xa8, 0xc1}, /* refa8 */
770 {0xa9, 0xef}, /* refa9 */
771 {0xaa, 0x92},
772 {0xab, 0x04},
773 {0xac, 0x80}, /* black level control */
774 {0xad, 0x80},
775 {0xae, 0x80},
776 {0xaf, 0x80},
777 {0xb2, 0xf2},
778 {0xb3, 0x20},
779 {0xb4, 0x20}, /* ctrlb4 */
780 {0xb5, 0x00},
781 {0xb6, 0xaf},
782 {0xbb, 0xae},
783 {0xbc, 0x7f}, /* ADC channel offsets */
784 {0xdb, 0x7f},
785 {0xbe, 0x7f},
786 {0xbf, 0x7f},
787 {0xc0, 0xe2},
788 {0xc1, 0xc0},
789 {0xc2, 0x01},
790 {0xc3, 0x4e},
791 {0xc6, 0x85},
792 {0xc7, 0x80}, /* com24 */
793 {0xc9, 0xe0},
794 {0xca, 0xe8},
795 {0xcb, 0xf0},
796 {0xcc, 0xd8},
797 {0xcd, 0xf1},
798 {0x4f, 0x98}, /* matrix */
799 {0x50, 0x98},
800 {0x51, 0x00},
801 {0x52, 0x28},
802 {0x53, 0x70},
803 {0x54, 0x98},
804 {0x58, 0x1a},
805 {0xff, 0x41}, /* read 41, write ff 00 */
806 {0x41, 0x40}, /* com16 */
807
808 {0xc5, 0x03}, /* 60 Hz banding filter */
809 {0x6a, 0x02}, /* 50 Hz banding filter */
810
811 {0x12, 0x62}, /* com7 - 30fps VGA YUV */
812 {0x36, 0xfa}, /* aref3 */
813 {0x69, 0x0a}, /* hv */
814 {0x8c, 0x89}, /* com22 */
815 {0x14, 0x28}, /* com9 */
816 {0x3e, 0x0c},
817 {0x41, 0x40}, /* com16 */
818 {0x72, 0x00},
819 {0x73, 0x00},
820 {0x74, 0x3a},
821 {0x75, 0x35},
822 {0x76, 0x01},
823 {0xc7, 0x80},
824 {0x03, 0x12}, /* vref */
825 {0x17, 0x16}, /* hstart */
826 {0x18, 0x02}, /* hstop */
827 {0x19, 0x01}, /* vstrt */
828 {0x1a, 0x3d}, /* vstop */
829 {0x32, 0xff}, /* href */
830 {0xc0, 0xaa},
831};
832
833static const u8 bridge_init_ov965x_2[][2] = {
834 {0x94, 0xaa},
835 {0xf1, 0x60},
836 {0xe5, 0x04},
837 {0xc0, 0x50},
838 {0xc1, 0x3c},
839 {0x8c, 0x00},
840 {0x8d, 0x1c},
841 {0x34, 0x05},
842
843 {0xc2, 0x0c},
844 {0xc3, 0xf9},
845 {0xda, 0x01},
846 {0x50, 0x00},
847 {0x51, 0xa0},
848 {0x52, 0x3c},
849 {0x53, 0x00},
850 {0x54, 0x00},
851 {0x55, 0x00},
852 {0x57, 0x00},
853 {0x5c, 0x00},
854 {0x5a, 0xa0},
855 {0x5b, 0x78},
856 {0x35, 0x02},
857 {0xd9, 0x10},
858 {0x94, 0x11},
859};
860
861static const u8 sensor_init_ov965x_2[][2] = {
862 {0x3b, 0xc4},
863 {0x1e, 0x04}, /* mvfp */
864 {0x13, 0xe0}, /* com8 */
865 {0x00, 0x00}, /* gain */
866 {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */
867 {0x11, 0x03}, /* clkrc */
868 {0x6b, 0x5a}, /* dblv */
869 {0x6a, 0x05},
870 {0xc5, 0x07},
871 {0xa2, 0x4b},
872 {0xa3, 0x3e},
873 {0x2d, 0x00},
874 {0xff, 0x42}, /* read 42, write ff 00 */
875 {0x42, 0xc0}, /* com17 */
876 {0x2d, 0x00},
877 {0xff, 0x42}, /* read 42, write ff 00 */
878 {0x42, 0xc1}, /* com17 */
879/* sharpness */
880 {0x3f, 0x01},
881 {0xff, 0x42}, /* read 42, write ff 00 */
882 {0x42, 0xc1}, /* com17 */
883/* saturation */
884 {0x4f, 0x98}, /* matrix */
885 {0x50, 0x98},
886 {0x51, 0x00},
887 {0x52, 0x28},
888 {0x53, 0x70},
889 {0x54, 0x98},
890 {0x58, 0x1a},
891 {0xff, 0x41}, /* read 41, write ff 00 */
892 {0x41, 0x40}, /* com16 */
893/* contrast */
894 {0x56, 0x40},
895/* brightness */
896 {0x55, 0x8f},
897/* expo */
898 {0x10, 0x25}, /* aech - exposure high bits */
899 {0xff, 0x13}, /* read 13, write ff 00 */
900 {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */
901};
902
903static const u8 sensor_start_ov965x_1_vga[][2] = { /* same for qvga */
904 {0x12, 0x62}, /* com7 - 30fps VGA YUV */
905 {0x36, 0xfa}, /* aref3 */
906 {0x69, 0x0a}, /* hv */
907 {0x8c, 0x89}, /* com22 */
908 {0x14, 0x28}, /* com9 */
909 {0x3e, 0x0c}, /* com14 */
910 {0x41, 0x40}, /* com16 */
911 {0x72, 0x00},
912 {0x73, 0x00},
913 {0x74, 0x3a},
914 {0x75, 0x35},
915 {0x76, 0x01},
916 {0xc7, 0x80}, /* com24 */
917 {0x03, 0x12}, /* vref */
918 {0x17, 0x16}, /* hstart */
919 {0x18, 0x02}, /* hstop */
920 {0x19, 0x01}, /* vstrt */
921 {0x1a, 0x3d}, /* vstop */
922 {0x32, 0xff}, /* href */
923 {0xc0, 0xaa},
924};
925
926static const u8 sensor_start_ov965x_1_svga[][2] = {
927 {0x12, 0x02}, /* com7 - YUYV - VGA 15 full resolution */
928 {0x36, 0xf8}, /* aref3 */
929 {0x69, 0x02}, /* hv */
930 {0x8c, 0x0d}, /* com22 */
931 {0x3e, 0x0c}, /* com14 */
932 {0x41, 0x40}, /* com16 */
933 {0x72, 0x00},
934 {0x73, 0x01},
935 {0x74, 0x3a},
936 {0x75, 0x35},
937 {0x76, 0x01},
938 {0xc7, 0x80}, /* com24 */
939 {0x03, 0x1b}, /* vref */
940 {0x17, 0x1d}, /* hstart */
941 {0x18, 0xbd}, /* hstop */
942 {0x19, 0x01}, /* vstrt */
943 {0x1a, 0x81}, /* vstop */
944 {0x32, 0xff}, /* href */
945 {0xc0, 0xe2},
946};
947
948static const u8 sensor_start_ov965x_1_xga[][2] = {
949 {0x12, 0x02}, /* com7 */
950 {0x36, 0xf8}, /* aref3 */
951 {0x69, 0x02}, /* hv */
952 {0x8c, 0x89}, /* com22 */
953 {0x14, 0x28}, /* com9 */
954 {0x3e, 0x0c}, /* com14 */
955 {0x41, 0x40}, /* com16 */
956 {0x72, 0x00},
957 {0x73, 0x01},
958 {0x74, 0x3a},
959 {0x75, 0x35},
960 {0x76, 0x01},
961 {0xc7, 0x80}, /* com24 */
962 {0x03, 0x1b}, /* vref */
963 {0x17, 0x1d}, /* hstart */
964 {0x18, 0xbd}, /* hstop */
965 {0x19, 0x01}, /* vstrt */
966 {0x1a, 0x81}, /* vstop */
967 {0x32, 0xff}, /* href */
968 {0xc0, 0xe2},
969};
970
971static const u8 sensor_start_ov965x_1_sxga[][2] = {
972 {0x12, 0x02}, /* com7 */
973 {0x36, 0xf8}, /* aref3 */
974 {0x69, 0x02}, /* hv */
975 {0x8c, 0x89}, /* com22 */
976 {0x14, 0x28}, /* com9 */
977 {0x3e, 0x0c}, /* com14 */
978 {0x41, 0x40}, /* com16 */
979 {0x72, 0x00},
980 {0x73, 0x01},
981 {0x74, 0x3a},
982 {0x75, 0x35},
983 {0x76, 0x01},
984 {0xc7, 0x80}, /* com24 */
985 {0x03, 0x1b}, /* vref */
986 {0x17, 0x1d}, /* hstart */
987 {0x18, 0x02}, /* hstop */
988 {0x19, 0x01}, /* vstrt */
989 {0x1a, 0x81}, /* vstop */
990 {0x32, 0xff}, /* href */
991 {0xc0, 0xe2},
992};
993
994static const u8 bridge_start_ov965x_qvga[][2] = {
995 {0x94, 0xaa},
996 {0xf1, 0x60},
997 {0xe5, 0x04},
998 {0xc0, 0x50},
999 {0xc1, 0x3c},
1000 {0x8c, 0x00},
1001 {0x8d, 0x1c},
1002 {0x34, 0x05},
1003
1004 {0xc2, 0x4c},
1005 {0xc3, 0xf9},
1006 {0xda, 0x00},
1007 {0x50, 0x00},
1008 {0x51, 0xa0},
1009 {0x52, 0x78},
1010 {0x53, 0x00},
1011 {0x54, 0x00},
1012 {0x55, 0x00},
1013 {0x57, 0x00},
1014 {0x5c, 0x00},
1015 {0x5a, 0x50},
1016 {0x5b, 0x3c},
1017 {0x35, 0x02},
1018 {0xd9, 0x10},
1019 {0x94, 0x11},
1020};
1021
1022static const u8 bridge_start_ov965x_vga[][2] = {
1023 {0x94, 0xaa},
1024 {0xf1, 0x60},
1025 {0xe5, 0x04},
1026 {0xc0, 0x50},
1027 {0xc1, 0x3c},
1028 {0x8c, 0x00},
1029 {0x8d, 0x1c},
1030 {0x34, 0x05},
1031 {0xc2, 0x0c},
1032 {0xc3, 0xf9},
1033 {0xda, 0x01},
1034 {0x50, 0x00},
1035 {0x51, 0xa0},
1036 {0x52, 0x3c},
1037 {0x53, 0x00},
1038 {0x54, 0x00},
1039 {0x55, 0x00},
1040 {0x57, 0x00},
1041 {0x5c, 0x00},
1042 {0x5a, 0xa0},
1043 {0x5b, 0x78},
1044 {0x35, 0x02},
1045 {0xd9, 0x10},
1046 {0x94, 0x11},
1047};
1048
1049static const u8 bridge_start_ov965x_svga[][2] = {
1050 {0x94, 0xaa},
1051 {0xf1, 0x60},
1052 {0xe5, 0x04},
1053 {0xc0, 0xa0},
1054 {0xc1, 0x80},
1055 {0x8c, 0x00},
1056 {0x8d, 0x1c},
1057 {0x34, 0x05},
1058 {0xc2, 0x4c},
1059 {0xc3, 0xf9},
1060 {0x50, 0x00},
1061 {0x51, 0x40},
1062 {0x52, 0x00},
1063 {0x53, 0x00},
1064 {0x54, 0x00},
1065 {0x55, 0x88},
1066 {0x57, 0x00},
1067 {0x5c, 0x00},
1068 {0x5a, 0xc8},
1069 {0x5b, 0x96},
1070 {0x35, 0x02},
1071 {0xd9, 0x10},
1072 {0xda, 0x00},
1073 {0x94, 0x11},
1074};
1075
1076static const u8 bridge_start_ov965x_xga[][2] = {
1077 {0x94, 0xaa},
1078 {0xf1, 0x60},
1079 {0xe5, 0x04},
1080 {0xc0, 0xa0},
1081 {0xc1, 0x80},
1082 {0x8c, 0x00},
1083 {0x8d, 0x1c},
1084 {0x34, 0x05},
1085 {0xc2, 0x4c},
1086 {0xc3, 0xf9},
1087 {0x50, 0x00},
1088 {0x51, 0x40},
1089 {0x52, 0x00},
1090 {0x53, 0x00},
1091 {0x54, 0x00},
1092 {0x55, 0x88},
1093 {0x57, 0x00},
1094 {0x5c, 0x01},
1095 {0x5a, 0x00},
1096 {0x5b, 0xc0},
1097 {0x35, 0x02},
1098 {0xd9, 0x10},
1099 {0xda, 0x01},
1100 {0x94, 0x11},
1101};
1102
1103static const u8 bridge_start_ov965x_sxga[][2] = {
1104 {0x94, 0xaa},
1105 {0xf1, 0x60},
1106 {0xe5, 0x04},
1107 {0xc0, 0xa0},
1108 {0xc1, 0x80},
1109 {0x8c, 0x00},
1110 {0x8d, 0x1c},
1111 {0x34, 0x05},
1112 {0xc2, 0x0c},
1113 {0xc3, 0xf9},
1114 {0xda, 0x00},
1115 {0x35, 0x02},
1116 {0xd9, 0x10},
1117 {0x94, 0x11},
1118};
1119
1120static const u8 sensor_start_ov965x_2_qvga[][2] = {
1121 {0x3b, 0xe4}, /* com11 - night mode 1/4 frame rate */
1122 {0x1e, 0x04}, /* mvfp */
1123 {0x13, 0xe0}, /* com8 */
1124 {0x00, 0x00},
1125 {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */
1126 {0x11, 0x01}, /* clkrc */
1127 {0x6b, 0x5a}, /* dblv */
1128 {0x6a, 0x02}, /* 50 Hz banding filter */
1129 {0xc5, 0x03}, /* 60 Hz banding filter */
1130 {0xa2, 0x96}, /* bd50 */
1131 {0xa3, 0x7d}, /* bd60 */
1132
1133 {0xff, 0x13}, /* read 13, write ff 00 */
1134 {0x13, 0xe7},
1135 {0x3a, 0x80}, /* tslb - yuyv */
1136};
1137
1138static const u8 sensor_start_ov965x_2_vga[][2] = {
1139 {0x3b, 0xc4}, /* com11 - night mode 1/4 frame rate */
1140 {0x1e, 0x04}, /* mvfp */
1141 {0x13, 0xe0}, /* com8 */
1142 {0x00, 0x00},
1143 {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */
1144 {0x11, 0x03}, /* clkrc */
1145 {0x6b, 0x5a}, /* dblv */
1146 {0x6a, 0x05}, /* 50 Hz banding filter */
1147 {0xc5, 0x07}, /* 60 Hz banding filter */
1148 {0xa2, 0x4b}, /* bd50 */
1149 {0xa3, 0x3e}, /* bd60 */
1150
1151 {0x2d, 0x00}, /* advfl */
1152};
1153
1154static const u8 sensor_start_ov965x_2_svga[][2] = { /* same for xga */
1155 {0x3b, 0xc4}, /* com11 - night mode 1/4 frame rate */
1156 {0x1e, 0x04}, /* mvfp */
1157 {0x13, 0xe0}, /* com8 */
1158 {0x00, 0x00},
1159 {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */
1160 {0x11, 0x01}, /* clkrc */
1161 {0x6b, 0x5a}, /* dblv */
1162 {0x6a, 0x0c}, /* 50 Hz banding filter */
1163 {0xc5, 0x0f}, /* 60 Hz banding filter */
1164 {0xa2, 0x4e}, /* bd50 */
1165 {0xa3, 0x41}, /* bd60 */
1166};
1167
1168static const u8 sensor_start_ov965x_2_sxga[][2] = {
1169 {0x13, 0xe0}, /* com8 */
1170 {0x00, 0x00},
1171 {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */
1172 {0x3b, 0xc4}, /* com11 - night mode 1/4 frame rate */
1173 {0x1e, 0x04}, /* mvfp */
1174 {0x11, 0x01}, /* clkrc */
1175 {0x6b, 0x5a}, /* dblv */
1176 {0x6a, 0x0c}, /* 50 Hz banding filter */
1177 {0xc5, 0x0f}, /* 60 Hz banding filter */
1178 {0xa2, 0x4e}, /* bd50 */
1179 {0xa3, 0x41}, /* bd60 */
1180};
1181
1182static void ov534_reg_write(struct gspca_dev *gspca_dev, u16 reg, u8 val) 493static void ov534_reg_write(struct gspca_dev *gspca_dev, u16 reg, u8 val)
1183{ 494{
1184 struct usb_device *udev = gspca_dev->dev; 495 struct usb_device *udev = gspca_dev->dev;
@@ -1360,14 +671,14 @@ static void set_frame_rate(struct gspca_dev *gspca_dev)
1360 PDEBUG(D_PROBE, "frame_rate: %d", r->fps); 671 PDEBUG(D_PROBE, "frame_rate: %d", r->fps);
1361} 672}
1362 673
1363static void setbrightness_77(struct gspca_dev *gspca_dev) 674static void setbrightness(struct gspca_dev *gspca_dev)
1364{ 675{
1365 struct sd *sd = (struct sd *) gspca_dev; 676 struct sd *sd = (struct sd *) gspca_dev;
1366 677
1367 sccb_reg_write(gspca_dev, 0x9B, sd->brightness); 678 sccb_reg_write(gspca_dev, 0x9B, sd->brightness);
1368} 679}
1369 680
1370static void setcontrast_77(struct gspca_dev *gspca_dev) 681static void setcontrast(struct gspca_dev *gspca_dev)
1371{ 682{
1372 struct sd *sd = (struct sd *) gspca_dev; 683 struct sd *sd = (struct sd *) gspca_dev;
1373 684
@@ -1401,7 +712,7 @@ static void setgain(struct gspca_dev *gspca_dev)
1401 sccb_reg_write(gspca_dev, 0x00, val); 712 sccb_reg_write(gspca_dev, 0x00, val);
1402} 713}
1403 714
1404static void setexposure_77(struct gspca_dev *gspca_dev) 715static void setexposure(struct gspca_dev *gspca_dev)
1405{ 716{
1406 struct sd *sd = (struct sd *) gspca_dev; 717 struct sd *sd = (struct sd *) gspca_dev;
1407 u8 val; 718 u8 val;
@@ -1432,7 +743,7 @@ static void sethue(struct gspca_dev *gspca_dev)
1432 sccb_reg_write(gspca_dev, 0x01, sd->hue); 743 sccb_reg_write(gspca_dev, 0x01, sd->hue);
1433} 744}
1434 745
1435static void setautogain_77(struct gspca_dev *gspca_dev) 746static void setautogain(struct gspca_dev *gspca_dev)
1436{ 747{
1437 struct sd *sd = (struct sd *) gspca_dev; 748 struct sd *sd = (struct sd *) gspca_dev;
1438 749
@@ -1457,7 +768,7 @@ static void setawb(struct gspca_dev *gspca_dev)
1457 sccb_reg_write(gspca_dev, 0x63, 0xaa); /* AWB off */ 768 sccb_reg_write(gspca_dev, 0x63, 0xaa); /* AWB off */
1458} 769}
1459 770
1460static void setsharpness_77(struct gspca_dev *gspca_dev) 771static void setsharpness(struct gspca_dev *gspca_dev)
1461{ 772{
1462 struct sd *sd = (struct sd *) gspca_dev; 773 struct sd *sd = (struct sd *) gspca_dev;
1463 u8 val; 774 u8 val;
@@ -1491,132 +802,6 @@ static void setvflip(struct gspca_dev *gspca_dev)
1491 sccb_reg_read(gspca_dev, 0x0c) & 0x7f); 802 sccb_reg_read(gspca_dev, 0x0c) & 0x7f);
1492} 803}
1493 804
1494/* ov965x specific controls */
1495static void setbrightness_96(struct gspca_dev *gspca_dev)
1496{
1497 struct sd *sd = (struct sd *) gspca_dev;
1498 u8 val;
1499
1500 val = sd->brightness;
1501 if (val < 8)
1502 val = 15 - val; /* f .. 8 */
1503 else
1504 val = val - 8; /* 0 .. 7 */
1505 sccb_reg_write(gspca_dev, 0x55, /* brtn - brightness adjustment */
1506 0x0f | (val << 4));
1507}
1508
1509static void setcontrast_96(struct gspca_dev *gspca_dev)
1510{
1511 struct sd *sd = (struct sd *) gspca_dev;
1512
1513 sccb_reg_write(gspca_dev, 0x56, /* cnst1 - contrast 1 ctrl coeff */
1514 sd->contrast << 4);
1515}
1516
1517static void setexposure_96(struct gspca_dev *gspca_dev)
1518{
1519 struct sd *sd = (struct sd *) gspca_dev;
1520 u8 val;
1521 static const u8 expo[4] = {0x00, 0x25, 0x38, 0x5e};
1522
1523 sccb_reg_write(gspca_dev, 0x10, /* aec[9:2] */
1524 expo[sd->exposure]);
1525 val = sccb_reg_read(gspca_dev, 0x13); /* com8 */
1526 sccb_reg_write(gspca_dev, 0xff, 0x00);
1527 sccb_reg_write(gspca_dev, 0x13, val);
1528 val = sccb_reg_read(gspca_dev, 0xa1); /* aech */
1529 sccb_reg_write(gspca_dev, 0xff, 0x00);
1530 sccb_reg_write(gspca_dev, 0xa1, val & 0xe0); /* aec[15:10] = 0 */
1531}
1532
1533static void setsharpness_96(struct gspca_dev *gspca_dev)
1534{
1535 struct sd *sd = (struct sd *) gspca_dev;
1536 s8 val;
1537
1538 val = sd->sharpness;
1539 if (val < 0) { /* auto */
1540 val = sccb_reg_read(gspca_dev, 0x42); /* com17 */
1541 sccb_reg_write(gspca_dev, 0xff, 0x00);
1542 sccb_reg_write(gspca_dev, 0x42, val | 0x40);
1543 /* Edge enhancement strength auto adjust */
1544 return;
1545 }
1546 if (val != 0)
1547 val = 1 << (val - 1);
1548 sccb_reg_write(gspca_dev, 0x3f, /* edge - edge enhance. factor */
1549 val);
1550 val = sccb_reg_read(gspca_dev, 0x42); /* com17 */
1551 sccb_reg_write(gspca_dev, 0xff, 0x00);
1552 sccb_reg_write(gspca_dev, 0x42, val & 0xbf);
1553}
1554
1555static void setautogain_96(struct gspca_dev *gspca_dev)
1556{
1557 struct sd *sd = (struct sd *) gspca_dev;
1558 u8 val;
1559
1560/*fixme: should adjust agc/awb/aec by different controls */
1561 val = sd->autogain;
1562 val = sccb_reg_read(gspca_dev, 0x13); /* com8 */
1563 sccb_reg_write(gspca_dev, 0xff, 0x00);
1564 if (sd->autogain)
1565 val |= 0x05; /* agc & aec */
1566 else
1567 val &= 0xfa;
1568 sccb_reg_write(gspca_dev, 0x13, val);
1569}
1570
1571static void setsatur(struct gspca_dev *gspca_dev)
1572{
1573 struct sd *sd = (struct sd *) gspca_dev;
1574 u8 val1, val2, val3;
1575 static const u8 matrix[5][2] = {
1576 {0x14, 0x38},
1577 {0x1e, 0x54},
1578 {0x28, 0x70},
1579 {0x32, 0x8c},
1580 {0x48, 0x90}
1581 };
1582
1583 val1 = matrix[sd->satur][0];
1584 val2 = matrix[sd->satur][1];
1585 val3 = val1 + val2;
1586 sccb_reg_write(gspca_dev, 0x4f, val3); /* matrix coeff */
1587 sccb_reg_write(gspca_dev, 0x50, val3);
1588 sccb_reg_write(gspca_dev, 0x51, 0x00);
1589 sccb_reg_write(gspca_dev, 0x52, val1);
1590 sccb_reg_write(gspca_dev, 0x53, val2);
1591 sccb_reg_write(gspca_dev, 0x54, val3);
1592 sccb_reg_write(gspca_dev, 0x58, 0x1a); /* mtxs - coeff signs */
1593 val1 = sccb_reg_read(gspca_dev, 0x41); /* com16 */
1594 sccb_reg_write(gspca_dev, 0xff, 0x00);
1595 sccb_reg_write(gspca_dev, 0x41, val1);
1596}
1597
1598static void setfreq(struct gspca_dev *gspca_dev)
1599{
1600 struct sd *sd = (struct sd *) gspca_dev;
1601 u8 val;
1602
1603 val = sccb_reg_read(gspca_dev, 0x13); /* com8 */
1604 sccb_reg_write(gspca_dev, 0xff, 0x00);
1605 if (sd->lightfreq == 0) {
1606 sccb_reg_write(gspca_dev, 0x13, val & 0xdf);
1607 return;
1608 }
1609 sccb_reg_write(gspca_dev, 0x13, val | 0x20);
1610
1611 val = sccb_reg_read(gspca_dev, 0x42); /* com17 */
1612 sccb_reg_write(gspca_dev, 0xff, 0x00);
1613 if (sd->lightfreq == 1)
1614 val |= 0x01;
1615 else
1616 val &= 0xfe;
1617 sccb_reg_write(gspca_dev, 0x42, val);
1618}
1619
1620/* this function is called at probe time */ 805/* this function is called at probe time */
1621static int sd_config(struct gspca_dev *gspca_dev, 806static int sd_config(struct gspca_dev *gspca_dev,
1622 const struct usb_device_id *id) 807 const struct usb_device_id *id)
@@ -1624,77 +809,50 @@ static int sd_config(struct gspca_dev *gspca_dev,
1624 struct sd *sd = (struct sd *) gspca_dev; 809 struct sd *sd = (struct sd *) gspca_dev;
1625 struct cam *cam; 810 struct cam *cam;
1626 811
1627 sd->sensor = id->driver_info;
1628
1629 cam = &gspca_dev->cam; 812 cam = &gspca_dev->cam;
1630 813
1631 if (sd->sensor == SENSOR_OV772X) { 814 cam->cam_mode = ov772x_mode;
1632 cam->cam_mode = ov772x_mode; 815 cam->nmodes = ARRAY_SIZE(ov772x_mode);
1633 cam->nmodes = ARRAY_SIZE(ov772x_mode); 816 cam->mode_framerates = ov772x_framerates;
1634 817
1635 cam->bulk = 1; 818 cam->bulk = 1;
1636 cam->bulk_size = 16384; 819 cam->bulk_size = 16384;
1637 cam->bulk_nurbs = 2; 820 cam->bulk_nurbs = 2;
1638 } else { /* ov965x */
1639 cam->cam_mode = ov965x_mode;
1640 cam->nmodes = ARRAY_SIZE(ov965x_mode);
1641 }
1642 821
1643 sd->frame_rate = 30; 822 sd->frame_rate = 30;
1644 823
1645 if (sd->sensor == SENSOR_OV772X) { 824 sd->brightness = BRIGHTNESS_DEF;
1646 sd->brightness = BRIGHTNESS_77_DEF; 825 sd->contrast = CONTRAST_DEF;
1647 sd->contrast = CONTRAST_77_DEF; 826 sd->gain = GAIN_DEF;
1648 sd->gain = GAIN_DEF; 827 sd->exposure = EXPO_DEF;
1649 sd->exposure = EXPO_77_DEF; 828 sd->redblc = RED_BALANCE_DEF;
1650 sd->redblc = RED_BALANCE_DEF; 829 sd->blueblc = BLUE_BALANCE_DEF;
1651 sd->blueblc = BLUE_BALANCE_DEF; 830 sd->hue = HUE_DEF;
1652 sd->hue = HUE_DEF; 831#if AUTOGAIN_DEF != 0
1653#if AUTOGAIN_77_DEF != 0 832 sd->autogain = AUTOGAIN_DEF;
1654 sd->autogain = AUTOGAIN_77_DEF;
1655#else 833#else
1656 gspca_dev->ctrl_inac |= (1 << AWB_77_IDX); 834 gspca_dev->ctrl_inac |= (1 << AWB_IDX);
1657#endif 835#endif
1658#if AWB_DEF != 0 836#if AWB_DEF != 0
1659 sd->awb = AWB_DEF 837 sd->awb = AWB_DEF
1660#endif 838#endif
1661#if SHARPNESS_77_DEF != 0 839#if SHARPNESS_DEF != 0
1662 sd->sharpness = SHARPNESS_77_DEF; 840 sd->sharpness = SHARPNESS_DEF;
1663#endif 841#endif
1664#if HFLIP_DEF != 0 842#if HFLIP_DEF != 0
1665 sd->hflip = HFLIP_DEF; 843 sd->hflip = HFLIP_DEF;
1666#endif 844#endif
1667#if VFLIP_DEF != 0 845#if VFLIP_DEF != 0
1668 sd->vflip = VFLIP_DEF; 846 sd->vflip = VFLIP_DEF;
1669#endif
1670 } else {
1671 sd->brightness = BRIGHTNESS_96_DEF;
1672 sd->contrast = CONTRAST_96_DEF;
1673#if AUTOGAIN_96_DEF != 0
1674 sd->autogain = AUTOGAIN_96_DEF;
1675 gspca_dev->ctrl_inac |= (1 << EXPO_96_IDX);
1676#endif 847#endif
1677#if EXPO_96_DEF != 0 848
1678 sd->exposure = EXPO_96_DEF;
1679#endif
1680#if SHARPNESS_96_DEF != 0
1681 sd->sharpness = SHARPNESS_96_DEF;
1682#endif
1683 sd->satur = SATUR_DEF;
1684 sd->lightfreq = FREQ_DEF;
1685 }
1686 return 0; 849 return 0;
1687} 850}
1688 851
1689/* this function is called at probe and resume time */ 852/* this function is called at probe and resume time */
1690static int sd_init(struct gspca_dev *gspca_dev) 853static int sd_init(struct gspca_dev *gspca_dev)
1691{ 854{
1692 struct sd *sd = (struct sd *) gspca_dev;
1693 u16 sensor_id; 855 u16 sensor_id;
1694 static const u8 sensor_addr[2] = {
1695 0x42, /* 0 SENSOR_OV772X */
1696 0x60, /* 1 SENSOR_OV965X */
1697 };
1698 856
1699 /* reset bridge */ 857 /* reset bridge */
1700 ov534_reg_write(gspca_dev, 0xe7, 0x3a); 858 ov534_reg_write(gspca_dev, 0xe7, 0x3a);
@@ -1702,8 +860,7 @@ static int sd_init(struct gspca_dev *gspca_dev)
1702 msleep(100); 860 msleep(100);
1703 861
1704 /* initialize the sensor address */ 862 /* initialize the sensor address */
1705 ov534_reg_write(gspca_dev, OV534_REG_ADDRESS, 863 ov534_reg_write(gspca_dev, OV534_REG_ADDRESS, 0x42);
1706 sensor_addr[sd->sensor]);
1707 864
1708 /* reset sensor */ 865 /* reset sensor */
1709 sccb_reg_write(gspca_dev, 0x12, 0x80); 866 sccb_reg_write(gspca_dev, 0x12, 0x80);
@@ -1717,64 +874,46 @@ static int sd_init(struct gspca_dev *gspca_dev)
1717 PDEBUG(D_PROBE, "Sensor ID: %04x", sensor_id); 874 PDEBUG(D_PROBE, "Sensor ID: %04x", sensor_id);
1718 875
1719 /* initialize */ 876 /* initialize */
1720 switch (sd->sensor) { 877 reg_w_array(gspca_dev, bridge_init,
1721 case SENSOR_OV772X: 878 ARRAY_SIZE(bridge_init));
1722 reg_w_array(gspca_dev, bridge_init_ov772x, 879 ov534_set_led(gspca_dev, 1);
1723 ARRAY_SIZE(bridge_init_ov772x)); 880 sccb_w_array(gspca_dev, sensor_init,
1724 ov534_set_led(gspca_dev, 1); 881 ARRAY_SIZE(sensor_init));
1725 sccb_w_array(gspca_dev, sensor_init_ov772x, 882 ov534_reg_write(gspca_dev, 0xe0, 0x09);
1726 ARRAY_SIZE(sensor_init_ov772x)); 883 ov534_set_led(gspca_dev, 0);
1727 ov534_reg_write(gspca_dev, 0xe0, 0x09); 884 set_frame_rate(gspca_dev);
1728 ov534_set_led(gspca_dev, 0);
1729 set_frame_rate(gspca_dev);
1730 break;
1731 default:
1732/* case SENSOR_OV965X: */
1733 reg_w_array(gspca_dev, bridge_init_ov965x,
1734 ARRAY_SIZE(bridge_init_ov965x));
1735 sccb_w_array(gspca_dev, sensor_init_ov965x,
1736 ARRAY_SIZE(sensor_init_ov965x));
1737 reg_w_array(gspca_dev, bridge_init_ov965x_2,
1738 ARRAY_SIZE(bridge_init_ov965x_2));
1739 sccb_w_array(gspca_dev, sensor_init_ov965x_2,
1740 ARRAY_SIZE(sensor_init_ov965x_2));
1741 ov534_reg_write(gspca_dev, 0xe0, 0x00);
1742 ov534_reg_write(gspca_dev, 0xe0, 0x01);
1743 ov534_set_led(gspca_dev, 0);
1744 ov534_reg_write(gspca_dev, 0xe0, 0x00);
1745 }
1746 885
1747 return 0; 886 return 0;
1748} 887}
1749 888
1750static int sd_start_ov772x(struct gspca_dev *gspca_dev) 889static int sd_start(struct gspca_dev *gspca_dev)
1751{ 890{
1752 int mode; 891 int mode;
1753 892
1754 mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv; 893 mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv;
1755 if (mode != 0) { /* 320x240 */ 894 if (mode != 0) { /* 320x240 */
1756 reg_w_array(gspca_dev, bridge_start_ov772x_qvga, 895 reg_w_array(gspca_dev, bridge_start_qvga,
1757 ARRAY_SIZE(bridge_start_ov772x_qvga)); 896 ARRAY_SIZE(bridge_start_qvga));
1758 sccb_w_array(gspca_dev, sensor_start_ov772x_qvga, 897 sccb_w_array(gspca_dev, sensor_start_qvga,
1759 ARRAY_SIZE(sensor_start_ov772x_qvga)); 898 ARRAY_SIZE(sensor_start_qvga));
1760 } else { /* 640x480 */ 899 } else { /* 640x480 */
1761 reg_w_array(gspca_dev, bridge_start_ov772x_vga, 900 reg_w_array(gspca_dev, bridge_start_vga,
1762 ARRAY_SIZE(bridge_start_ov772x_vga)); 901 ARRAY_SIZE(bridge_start_vga));
1763 sccb_w_array(gspca_dev, sensor_start_ov772x_vga, 902 sccb_w_array(gspca_dev, sensor_start_vga,
1764 ARRAY_SIZE(sensor_start_ov772x_vga)); 903 ARRAY_SIZE(sensor_start_vga));
1765 } 904 }
1766 set_frame_rate(gspca_dev); 905 set_frame_rate(gspca_dev);
1767 906
1768 setautogain_77(gspca_dev); 907 setautogain(gspca_dev);
1769 setawb(gspca_dev); 908 setawb(gspca_dev);
1770 setgain(gspca_dev); 909 setgain(gspca_dev);
1771 setredblc(gspca_dev); 910 setredblc(gspca_dev);
1772 setblueblc(gspca_dev); 911 setblueblc(gspca_dev);
1773 sethue(gspca_dev); 912 sethue(gspca_dev);
1774 setexposure_77(gspca_dev); 913 setexposure(gspca_dev);
1775 setbrightness_77(gspca_dev); 914 setbrightness(gspca_dev);
1776 setcontrast_77(gspca_dev); 915 setcontrast(gspca_dev);
1777 setsharpness_77(gspca_dev); 916 setsharpness(gspca_dev);
1778 setvflip(gspca_dev); 917 setvflip(gspca_dev);
1779 sethflip(gspca_dev); 918 sethflip(gspca_dev);
1780 919
@@ -1783,81 +922,12 @@ static int sd_start_ov772x(struct gspca_dev *gspca_dev)
1783 return 0; 922 return 0;
1784} 923}
1785 924
1786static int sd_start_ov965x(struct gspca_dev *gspca_dev) 925static void sd_stopN(struct gspca_dev *gspca_dev)
1787{
1788 int mode;
1789
1790 mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv;
1791 switch (mode) {
1792 default:
1793/* case 4: * 320x240 */
1794 sccb_w_array(gspca_dev, sensor_start_ov965x_1_vga,
1795 ARRAY_SIZE(sensor_start_ov965x_1_vga));
1796 reg_w_array(gspca_dev, bridge_start_ov965x_qvga,
1797 ARRAY_SIZE(bridge_start_ov965x_qvga));
1798 sccb_w_array(gspca_dev, sensor_start_ov965x_2_qvga,
1799 ARRAY_SIZE(sensor_start_ov965x_2_qvga));
1800 break;
1801 case 3: /* 640x480 */
1802 sccb_w_array(gspca_dev, sensor_start_ov965x_1_vga,
1803 ARRAY_SIZE(sensor_start_ov965x_1_vga));
1804 reg_w_array(gspca_dev, bridge_start_ov965x_vga,
1805 ARRAY_SIZE(bridge_start_ov965x_vga));
1806 sccb_w_array(gspca_dev, sensor_start_ov965x_2_vga,
1807 ARRAY_SIZE(sensor_start_ov965x_2_vga));
1808 break;
1809 case 2: /* 800x600 */
1810 sccb_w_array(gspca_dev, sensor_start_ov965x_1_svga,
1811 ARRAY_SIZE(sensor_start_ov965x_1_svga));
1812 reg_w_array(gspca_dev, bridge_start_ov965x_svga,
1813 ARRAY_SIZE(bridge_start_ov965x_svga));
1814 sccb_w_array(gspca_dev, sensor_start_ov965x_2_svga,
1815 ARRAY_SIZE(sensor_start_ov965x_2_svga));
1816 break;
1817 case 1: /* 1024x768 */
1818 sccb_w_array(gspca_dev, sensor_start_ov965x_1_xga,
1819 ARRAY_SIZE(sensor_start_ov965x_1_xga));
1820 reg_w_array(gspca_dev, bridge_start_ov965x_xga,
1821 ARRAY_SIZE(bridge_start_ov965x_xga));
1822 sccb_w_array(gspca_dev, sensor_start_ov965x_2_svga,
1823 ARRAY_SIZE(sensor_start_ov965x_2_svga));
1824 break;
1825 case 0: /* 1280x1024 */
1826 sccb_w_array(gspca_dev, sensor_start_ov965x_1_sxga,
1827 ARRAY_SIZE(sensor_start_ov965x_1_sxga));
1828 reg_w_array(gspca_dev, bridge_start_ov965x_sxga,
1829 ARRAY_SIZE(bridge_start_ov965x_sxga));
1830 sccb_w_array(gspca_dev, sensor_start_ov965x_2_sxga,
1831 ARRAY_SIZE(sensor_start_ov965x_2_sxga));
1832 break;
1833 }
1834 setfreq(gspca_dev);
1835 setautogain_96(gspca_dev);
1836 setbrightness_96(gspca_dev);
1837 setcontrast_96(gspca_dev);
1838 setexposure_96(gspca_dev);
1839 setsharpness_96(gspca_dev);
1840 setsatur(gspca_dev);
1841
1842 ov534_reg_write(gspca_dev, 0xe0, 0x00);
1843 ov534_reg_write(gspca_dev, 0xe0, 0x00);
1844 ov534_set_led(gspca_dev, 1);
1845 return 0;
1846}
1847
1848static void sd_stopN_ov772x(struct gspca_dev *gspca_dev)
1849{ 926{
1850 ov534_reg_write(gspca_dev, 0xe0, 0x09); 927 ov534_reg_write(gspca_dev, 0xe0, 0x09);
1851 ov534_set_led(gspca_dev, 0); 928 ov534_set_led(gspca_dev, 0);
1852} 929}
1853 930
1854static void sd_stopN_ov965x(struct gspca_dev *gspca_dev)
1855{
1856 ov534_reg_write(gspca_dev, 0xe0, 0x01);
1857 ov534_set_led(gspca_dev, 0);
1858 ov534_reg_write(gspca_dev, 0xe0, 0x00);
1859}
1860
1861/* Values for bmHeaderInfo (Video and Still Image Payload Headers, 2.4.3.3) */ 931/* Values for bmHeaderInfo (Video and Still Image Payload Headers, 2.4.3.3) */
1862#define UVC_STREAM_EOH (1 << 7) 932#define UVC_STREAM_EOH (1 << 7)
1863#define UVC_STREAM_ERR (1 << 6) 933#define UVC_STREAM_ERR (1 << 6)
@@ -1875,11 +945,9 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1875 __u32 this_pts; 945 __u32 this_pts;
1876 u16 this_fid; 946 u16 this_fid;
1877 int remaining_len = len; 947 int remaining_len = len;
1878 int payload_len;
1879 948
1880 payload_len = gspca_dev->cam.bulk ? 2048 : 2040;
1881 do { 949 do {
1882 len = min(remaining_len, payload_len); 950 len = min(remaining_len, 2048);
1883 951
1884 /* Payloads are prefixed with a UVC-style header. We 952 /* Payloads are prefixed with a UVC-style header. We
1885 consider a frame to start when the FID toggles, or the PTS 953 consider a frame to start when the FID toggles, or the PTS
@@ -1918,7 +986,17 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1918 data + 12, len - 12); 986 data + 12, len - 12);
1919 /* If this packet is marked as EOF, end the frame */ 987 /* If this packet is marked as EOF, end the frame */
1920 } else if (data[1] & UVC_STREAM_EOF) { 988 } else if (data[1] & UVC_STREAM_EOF) {
989 struct gspca_frame *frame;
990
1921 sd->last_pts = 0; 991 sd->last_pts = 0;
992 frame = gspca_get_i_frame(gspca_dev);
993 if (frame == NULL)
994 goto discard;
995 if (frame->data_end - frame->data + (len - 12) !=
996 gspca_dev->width * gspca_dev->height * 2) {
997 PDEBUG(D_PACK, "wrong sized frame");
998 goto discard;
999 }
1922 gspca_frame_add(gspca_dev, LAST_PACKET, 1000 gspca_frame_add(gspca_dev, LAST_PACKET,
1923 data + 12, len - 12); 1001 data + 12, len - 12);
1924 } else { 1002 } else {
@@ -1965,12 +1043,8 @@ static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val)
1965 struct sd *sd = (struct sd *) gspca_dev; 1043 struct sd *sd = (struct sd *) gspca_dev;
1966 1044
1967 sd->exposure = val; 1045 sd->exposure = val;
1968 if (gspca_dev->streaming) { 1046 if (gspca_dev->streaming)
1969 if (sd->sensor == SENSOR_OV772X) 1047 setexposure(gspca_dev);
1970 setexposure_77(gspca_dev);
1971 else
1972 setexposure_96(gspca_dev);
1973 }
1974 return 0; 1048 return 0;
1975} 1049}
1976 1050
@@ -1987,12 +1061,8 @@ static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
1987 struct sd *sd = (struct sd *) gspca_dev; 1061 struct sd *sd = (struct sd *) gspca_dev;
1988 1062
1989 sd->brightness = val; 1063 sd->brightness = val;
1990 if (gspca_dev->streaming) { 1064 if (gspca_dev->streaming)
1991 if (sd->sensor == SENSOR_OV772X) 1065 setbrightness(gspca_dev);
1992 setbrightness_77(gspca_dev);
1993 else
1994 setbrightness_96(gspca_dev);
1995 }
1996 return 0; 1066 return 0;
1997} 1067}
1998 1068
@@ -2009,12 +1079,8 @@ static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
2009 struct sd *sd = (struct sd *) gspca_dev; 1079 struct sd *sd = (struct sd *) gspca_dev;
2010 1080
2011 sd->contrast = val; 1081 sd->contrast = val;
2012 if (gspca_dev->streaming) { 1082 if (gspca_dev->streaming)
2013 if (sd->sensor == SENSOR_OV772X) 1083 setcontrast(gspca_dev);
2014 setcontrast_77(gspca_dev);
2015 else
2016 setcontrast_96(gspca_dev);
2017 }
2018 return 0; 1084 return 0;
2019} 1085}
2020 1086
@@ -2026,41 +1092,6 @@ static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
2026 return 0; 1092 return 0;
2027} 1093}
2028 1094
2029static int sd_setsatur(struct gspca_dev *gspca_dev, __s32 val)
2030{
2031 struct sd *sd = (struct sd *) gspca_dev;
2032
2033 sd->satur = val;
2034 if (gspca_dev->streaming)
2035 setsatur(gspca_dev);
2036 return 0;
2037}
2038
2039static int sd_getsatur(struct gspca_dev *gspca_dev, __s32 *val)
2040{
2041 struct sd *sd = (struct sd *) gspca_dev;
2042
2043 *val = sd->satur;
2044 return 0;
2045}
2046static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val)
2047{
2048 struct sd *sd = (struct sd *) gspca_dev;
2049
2050 sd->lightfreq = val;
2051 if (gspca_dev->streaming)
2052 setfreq(gspca_dev);
2053 return 0;
2054}
2055
2056static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val)
2057{
2058 struct sd *sd = (struct sd *) gspca_dev;
2059
2060 *val = sd->lightfreq;
2061 return 0;
2062}
2063
2064static int sd_setredblc(struct gspca_dev *gspca_dev, __s32 val) 1095static int sd_setredblc(struct gspca_dev *gspca_dev, __s32 val)
2065{ 1096{
2066 struct sd *sd = (struct sd *) gspca_dev; 1097 struct sd *sd = (struct sd *) gspca_dev;
@@ -2122,22 +1153,14 @@ static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
2122 sd->autogain = val; 1153 sd->autogain = val;
2123 1154
2124 if (gspca_dev->streaming) { 1155 if (gspca_dev->streaming) {
2125 if (sd->sensor == SENSOR_OV772X) { 1156
2126 1157 /* the auto white balance control works only
2127 /* the auto white balance control works only 1158 * when auto gain is set */
2128 * when auto gain is set */ 1159 if (val)
2129 if (val) 1160 gspca_dev->ctrl_inac &= ~(1 << AWB_IDX);
2130 gspca_dev->ctrl_inac &= ~(1 << AWB_77_IDX); 1161 else
2131 else 1162 gspca_dev->ctrl_inac |= (1 << AWB_IDX);
2132 gspca_dev->ctrl_inac |= (1 << AWB_77_IDX); 1163 setautogain(gspca_dev);
2133 setautogain_77(gspca_dev);
2134 } else {
2135 if (val)
2136 gspca_dev->ctrl_inac |= (1 << EXPO_96_IDX);
2137 else
2138 gspca_dev->ctrl_inac &= ~(1 << EXPO_96_IDX);
2139 setautogain_96(gspca_dev);
2140 }
2141 } 1164 }
2142 return 0; 1165 return 0;
2143} 1166}
@@ -2173,12 +1196,8 @@ static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val)
2173 struct sd *sd = (struct sd *) gspca_dev; 1196 struct sd *sd = (struct sd *) gspca_dev;
2174 1197
2175 sd->sharpness = val; 1198 sd->sharpness = val;
2176 if (gspca_dev->streaming) { 1199 if (gspca_dev->streaming)
2177 if (sd->sensor == SENSOR_OV772X) 1200 setsharpness(gspca_dev);
2178 setsharpness_77(gspca_dev);
2179 else
2180 setsharpness_96(gspca_dev);
2181 }
2182 return 0; 1201 return 0;
2183} 1202}
2184 1203
@@ -2257,7 +1276,7 @@ static int sd_set_streamparm(struct gspca_dev *gspca_dev,
2257 1276
2258 /* Set requested framerate */ 1277 /* Set requested framerate */
2259 sd->frame_rate = tpf->denominator / tpf->numerator; 1278 sd->frame_rate = tpf->denominator / tpf->numerator;
2260 if (gspca_dev->streaming && sd->sensor == SENSOR_OV772X) 1279 if (gspca_dev->streaming)
2261 set_frame_rate(gspca_dev); 1280 set_frame_rate(gspca_dev);
2262 1281
2263 /* Return the actual framerate */ 1282 /* Return the actual framerate */
@@ -2267,57 +1286,23 @@ static int sd_set_streamparm(struct gspca_dev *gspca_dev,
2267 return 0; 1286 return 0;
2268} 1287}
2269 1288
2270static int sd_querymenu(struct gspca_dev *gspca_dev,
2271 struct v4l2_querymenu *menu)
2272{
2273 switch (menu->id) {
2274 case V4L2_CID_POWER_LINE_FREQUENCY:
2275 switch (menu->index) {
2276 case 0: /* V4L2_CID_POWER_LINE_FREQUENCY_DISABLED */
2277 strcpy((char *) menu->name, "NoFliker");
2278 return 0;
2279 case 1: /* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */
2280 strcpy((char *) menu->name, "50 Hz");
2281 return 0;
2282 case 2: /* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */
2283 strcpy((char *) menu->name, "60 Hz");
2284 return 0;
2285 }
2286 break;
2287 }
2288 return -EINVAL;
2289}
2290
2291/* sub-driver description */ 1289/* sub-driver description */
2292static const struct sd_desc sd_desc_ov772x = { 1290static const struct sd_desc sd_desc = {
2293 .name = MODULE_NAME, 1291 .name = MODULE_NAME,
2294 .ctrls = sd_ctrls_ov772x, 1292 .ctrls = sd_ctrls,
2295 .nctrls = ARRAY_SIZE(sd_ctrls_ov772x), 1293 .nctrls = ARRAY_SIZE(sd_ctrls),
2296 .config = sd_config, 1294 .config = sd_config,
2297 .init = sd_init, 1295 .init = sd_init,
2298 .start = sd_start_ov772x, 1296 .start = sd_start,
2299 .stopN = sd_stopN_ov772x, 1297 .stopN = sd_stopN,
2300 .pkt_scan = sd_pkt_scan, 1298 .pkt_scan = sd_pkt_scan,
2301 .get_streamparm = sd_get_streamparm, 1299 .get_streamparm = sd_get_streamparm,
2302 .set_streamparm = sd_set_streamparm, 1300 .set_streamparm = sd_set_streamparm,
2303}; 1301};
2304 1302
2305static const struct sd_desc sd_desc_ov965x = {
2306 .name = MODULE_NAME,
2307 .ctrls = sd_ctrls_ov965x,
2308 .nctrls = ARRAY_SIZE(sd_ctrls_ov965x),
2309 .config = sd_config,
2310 .init = sd_init,
2311 .start = sd_start_ov965x,
2312 .stopN = sd_stopN_ov965x,
2313 .pkt_scan = sd_pkt_scan,
2314 .querymenu = sd_querymenu,
2315};
2316
2317/* -- module initialisation -- */ 1303/* -- module initialisation -- */
2318static const __devinitdata struct usb_device_id device_table[] = { 1304static const __devinitdata struct usb_device_id device_table[] = {
2319 {USB_DEVICE(0x06f8, 0x3003), .driver_info = SENSOR_OV965X}, 1305 {USB_DEVICE(0x1415, 0x2000)},
2320 {USB_DEVICE(0x1415, 0x2000), .driver_info = SENSOR_OV772X},
2321 {} 1306 {}
2322}; 1307};
2323 1308
@@ -2326,11 +1311,7 @@ MODULE_DEVICE_TABLE(usb, device_table);
2326/* -- device connect -- */ 1311/* -- device connect -- */
2327static int sd_probe(struct usb_interface *intf, const struct usb_device_id *id) 1312static int sd_probe(struct usb_interface *intf, const struct usb_device_id *id)
2328{ 1313{
2329 return gspca_dev_probe(intf, id, 1314 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
2330 id->driver_info == SENSOR_OV772X
2331 ? &sd_desc_ov772x
2332 : &sd_desc_ov965x,
2333 sizeof(struct sd),
2334 THIS_MODULE); 1315 THIS_MODULE);
2335} 1316}
2336 1317
diff --git a/drivers/media/video/gspca/ov534_9.c b/drivers/media/video/gspca/ov534_9.c
new file mode 100644
index 000000000000..bbe5a030e3b4
--- /dev/null
+++ b/drivers/media/video/gspca/ov534_9.c
@@ -0,0 +1,1477 @@
1/*
2 * ov534-ov965x gspca driver
3 *
4 * Copyright (C) 2009-2010 Jean-Francois Moine http://moinejf.free.fr
5 * Copyright (C) 2008 Antonio Ospite <ospite@studenti.unina.it>
6 * Copyright (C) 2008 Jim Paris <jim@jtan.com>
7 *
8 * Based on a prototype written by Mark Ferrell <majortrips@gmail.com>
9 * USB protocol reverse engineered by Jim Paris <jim@jtan.com>
10 * https://jim.sh/svn/jim/devl/playstation/ps3/eye/test/
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 * 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#define MODULE_NAME "ov534_9"
28
29#include "gspca.h"
30
31#define OV534_REG_ADDRESS 0xf1 /* sensor address */
32#define OV534_REG_SUBADDR 0xf2
33#define OV534_REG_WRITE 0xf3
34#define OV534_REG_READ 0xf4
35#define OV534_REG_OPERATION 0xf5
36#define OV534_REG_STATUS 0xf6
37
38#define OV534_OP_WRITE_3 0x37
39#define OV534_OP_WRITE_2 0x33
40#define OV534_OP_READ_2 0xf9
41
42#define CTRL_TIMEOUT 500
43
44MODULE_AUTHOR("Jean-Francois Moine <moinejf@free.fr>");
45MODULE_DESCRIPTION("GSPCA/OV534_9 USB Camera Driver");
46MODULE_LICENSE("GPL");
47
48/* specific webcam descriptor */
49struct sd {
50 struct gspca_dev gspca_dev; /* !! must be the first item */
51 __u32 last_pts;
52 u8 last_fid;
53
54 u8 brightness;
55 u8 contrast;
56 u8 autogain;
57 u8 exposure;
58 s8 sharpness;
59 u8 satur;
60 u8 freq;
61};
62
63/* V4L2 controls supported by the driver */
64static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
65static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
66static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
67static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
68static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
69static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val);
70static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val);
71static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val);
72static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val);
73static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val);
74static int sd_setsatur(struct gspca_dev *gspca_dev, __s32 val);
75static int sd_getsatur(struct gspca_dev *gspca_dev, __s32 *val);
76static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val);
77static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val);
78
79static const struct ctrl sd_ctrls[] = {
80 { /* 0 */
81 {
82 .id = V4L2_CID_BRIGHTNESS,
83 .type = V4L2_CTRL_TYPE_INTEGER,
84 .name = "Brightness",
85 .minimum = 0,
86 .maximum = 15,
87 .step = 1,
88#define BRIGHTNESS_DEF 7
89 .default_value = BRIGHTNESS_DEF,
90 },
91 .set = sd_setbrightness,
92 .get = sd_getbrightness,
93 },
94 { /* 1 */
95 {
96 .id = V4L2_CID_CONTRAST,
97 .type = V4L2_CTRL_TYPE_INTEGER,
98 .name = "Contrast",
99 .minimum = 0,
100 .maximum = 15,
101 .step = 1,
102#define CONTRAST_DEF 3
103 .default_value = CONTRAST_DEF,
104 },
105 .set = sd_setcontrast,
106 .get = sd_getcontrast,
107 },
108 { /* 2 */
109 {
110 .id = V4L2_CID_AUTOGAIN,
111 .type = V4L2_CTRL_TYPE_BOOLEAN,
112 .name = "Autogain",
113 .minimum = 0,
114 .maximum = 1,
115 .step = 1,
116#define AUTOGAIN_DEF 1
117 .default_value = AUTOGAIN_DEF,
118 },
119 .set = sd_setautogain,
120 .get = sd_getautogain,
121 },
122#define EXPO_IDX 3
123 { /* 3 */
124 {
125 .id = V4L2_CID_EXPOSURE,
126 .type = V4L2_CTRL_TYPE_INTEGER,
127 .name = "Exposure",
128 .minimum = 0,
129 .maximum = 3,
130 .step = 1,
131#define EXPO_DEF 0
132 .default_value = EXPO_DEF,
133 },
134 .set = sd_setexposure,
135 .get = sd_getexposure,
136 },
137 { /* 4 */
138 {
139 .id = V4L2_CID_SHARPNESS,
140 .type = V4L2_CTRL_TYPE_INTEGER,
141 .name = "Sharpness",
142 .minimum = -1, /* -1 = auto */
143 .maximum = 4,
144 .step = 1,
145#define SHARPNESS_DEF -1
146 .default_value = SHARPNESS_DEF,
147 },
148 .set = sd_setsharpness,
149 .get = sd_getsharpness,
150 },
151 { /* 5 */
152 {
153 .id = V4L2_CID_SATURATION,
154 .type = V4L2_CTRL_TYPE_INTEGER,
155 .name = "Saturation",
156 .minimum = 0,
157 .maximum = 4,
158 .step = 1,
159#define SATUR_DEF 2
160 .default_value = SATUR_DEF,
161 },
162 .set = sd_setsatur,
163 .get = sd_getsatur,
164 },
165 {
166 {
167 .id = V4L2_CID_POWER_LINE_FREQUENCY,
168 .type = V4L2_CTRL_TYPE_MENU,
169 .name = "Light frequency filter",
170 .minimum = 0,
171 .maximum = 2, /* 0: 0, 1: 50Hz, 2:60Hz */
172 .step = 1,
173#define FREQ_DEF 0
174 .default_value = FREQ_DEF,
175 },
176 .set = sd_setfreq,
177 .get = sd_getfreq,
178 },
179};
180
181static const struct v4l2_pix_format ov965x_mode[] = {
182#define QVGA_MODE 0
183 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
184 .bytesperline = 320,
185 .sizeimage = 320 * 240 * 3 / 8 + 590,
186 .colorspace = V4L2_COLORSPACE_JPEG},
187#define VGA_MODE 1
188 {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
189 .bytesperline = 640,
190 .sizeimage = 640 * 480 * 3 / 8 + 590,
191 .colorspace = V4L2_COLORSPACE_JPEG},
192#define SVGA_MODE 2
193 {800, 600, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
194 .bytesperline = 800,
195 .sizeimage = 800 * 600 * 3 / 8 + 590,
196 .colorspace = V4L2_COLORSPACE_JPEG},
197#define XGA_MODE 3
198 {1024, 768, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
199 .bytesperline = 1024,
200 .sizeimage = 1024 * 768 * 3 / 8 + 590,
201 .colorspace = V4L2_COLORSPACE_JPEG},
202#define SXGA_MODE 4
203 {1280, 1024, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
204 .bytesperline = 1280,
205 .sizeimage = 1280 * 1024 * 3 / 8 + 590,
206 .colorspace = V4L2_COLORSPACE_JPEG},
207};
208
209static const u8 bridge_init[][2] = {
210 {0x88, 0xf8},
211 {0x89, 0xff},
212 {0x76, 0x03},
213 {0x92, 0x03},
214 {0x95, 0x10},
215 {0xe2, 0x00},
216 {0xe7, 0x3e},
217 {0x8d, 0x1c},
218 {0x8e, 0x00},
219 {0x8f, 0x00},
220 {0x1f, 0x00},
221 {0xc3, 0xf9},
222 {0x89, 0xff},
223 {0x88, 0xf8},
224 {0x76, 0x03},
225 {0x92, 0x01},
226 {0x93, 0x18},
227 {0x1c, 0x0a},
228 {0x1d, 0x48},
229 {0xc0, 0x50},
230 {0xc1, 0x3c},
231 {0x34, 0x05},
232 {0xc2, 0x0c},
233 {0xc3, 0xf9},
234 {0x34, 0x05},
235 {0xe7, 0x2e},
236 {0x31, 0xf9},
237 {0x35, 0x02},
238 {0xd9, 0x10},
239 {0x25, 0x42},
240 {0x94, 0x11},
241};
242
243static const u8 sensor_init[][2] = {
244 {0x12, 0x80}, /* com7 - SSCB reset */
245 {0x00, 0x00}, /* gain */
246 {0x01, 0x80}, /* blue */
247 {0x02, 0x80}, /* red */
248 {0x03, 0x1b}, /* vref */
249 {0x04, 0x03}, /* com1 - exposure low bits */
250 {0x0b, 0x57}, /* ver */
251 {0x0e, 0x61}, /* com5 */
252 {0x0f, 0x42}, /* com6 */
253 {0x11, 0x00}, /* clkrc */
254 {0x12, 0x02}, /* com7 - 15fps VGA YUYV */
255 {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */
256 {0x14, 0x28}, /* com9 */
257 {0x16, 0x24}, /* reg16 */
258 {0x17, 0x1d}, /* hstart*/
259 {0x18, 0xbd}, /* hstop */
260 {0x19, 0x01}, /* vstrt */
261 {0x1a, 0x81}, /* vstop*/
262 {0x1e, 0x04}, /* mvfp */
263 {0x24, 0x3c}, /* aew */
264 {0x25, 0x36}, /* aeb */
265 {0x26, 0x71}, /* vpt */
266 {0x27, 0x08}, /* bbias */
267 {0x28, 0x08}, /* gbbias */
268 {0x29, 0x15}, /* gr com */
269 {0x2a, 0x00}, /* exhch */
270 {0x2b, 0x00}, /* exhcl */
271 {0x2c, 0x08}, /* rbias */
272 {0x32, 0xff}, /* href */
273 {0x33, 0x00}, /* chlf */
274 {0x34, 0x3f}, /* aref1 */
275 {0x35, 0x00}, /* aref2 */
276 {0x36, 0xf8}, /* aref3 */
277 {0x38, 0x72}, /* adc2 */
278 {0x39, 0x57}, /* aref4 */
279 {0x3a, 0x80}, /* tslb - yuyv */
280 {0x3b, 0xc4}, /* com11 - night mode 1/4 frame rate */
281 {0x3d, 0x99}, /* com13 */
282 {0x3f, 0xc1}, /* edge */
283 {0x40, 0xc0}, /* com15 */
284 {0x41, 0x40}, /* com16 */
285 {0x42, 0xc0}, /* com17 */
286 {0x43, 0x0a}, /* rsvd */
287 {0x44, 0xf0},
288 {0x45, 0x46},
289 {0x46, 0x62},
290 {0x47, 0x2a},
291 {0x48, 0x3c},
292 {0x4a, 0xfc},
293 {0x4b, 0xfc},
294 {0x4c, 0x7f},
295 {0x4d, 0x7f},
296 {0x4e, 0x7f},
297 {0x4f, 0x98}, /* matrix */
298 {0x50, 0x98},
299 {0x51, 0x00},
300 {0x52, 0x28},
301 {0x53, 0x70},
302 {0x54, 0x98},
303 {0x58, 0x1a}, /* matrix coef sign */
304 {0x59, 0x85}, /* AWB control */
305 {0x5a, 0xa9},
306 {0x5b, 0x64},
307 {0x5c, 0x84},
308 {0x5d, 0x53},
309 {0x5e, 0x0e},
310 {0x5f, 0xf0}, /* AWB blue limit */
311 {0x60, 0xf0}, /* AWB red limit */
312 {0x61, 0xf0}, /* AWB green limit */
313 {0x62, 0x00}, /* lcc1 */
314 {0x63, 0x00}, /* lcc2 */
315 {0x64, 0x02}, /* lcc3 */
316 {0x65, 0x16}, /* lcc4 */
317 {0x66, 0x01}, /* lcc5 */
318 {0x69, 0x02}, /* hv */
319 {0x6b, 0x5a}, /* dbvl */
320 {0x6c, 0x04},
321 {0x6d, 0x55},
322 {0x6e, 0x00},
323 {0x6f, 0x9d},
324 {0x70, 0x21}, /* dnsth */
325 {0x71, 0x78},
326 {0x72, 0x00}, /* poidx */
327 {0x73, 0x01}, /* pckdv */
328 {0x74, 0x3a}, /* xindx */
329 {0x75, 0x35}, /* yindx */
330 {0x76, 0x01},
331 {0x77, 0x02},
332 {0x7a, 0x12}, /* gamma curve */
333 {0x7b, 0x08},
334 {0x7c, 0x16},
335 {0x7d, 0x30},
336 {0x7e, 0x5e},
337 {0x7f, 0x72},
338 {0x80, 0x82},
339 {0x81, 0x8e},
340 {0x82, 0x9a},
341 {0x83, 0xa4},
342 {0x84, 0xac},
343 {0x85, 0xb8},
344 {0x86, 0xc3},
345 {0x87, 0xd6},
346 {0x88, 0xe6},
347 {0x89, 0xf2},
348 {0x8a, 0x03},
349 {0x8c, 0x89}, /* com19 */
350 {0x14, 0x28}, /* com9 */
351 {0x90, 0x7d},
352 {0x91, 0x7b},
353 {0x9d, 0x03}, /* lcc6 */
354 {0x9e, 0x04}, /* lcc7 */
355 {0x9f, 0x7a},
356 {0xa0, 0x79},
357 {0xa1, 0x40}, /* aechm */
358 {0xa4, 0x50}, /* com21 */
359 {0xa5, 0x68}, /* com26 */
360 {0xa6, 0x4a}, /* AWB green */
361 {0xa8, 0xc1}, /* refa8 */
362 {0xa9, 0xef}, /* refa9 */
363 {0xaa, 0x92},
364 {0xab, 0x04},
365 {0xac, 0x80}, /* black level control */
366 {0xad, 0x80},
367 {0xae, 0x80},
368 {0xaf, 0x80},
369 {0xb2, 0xf2},
370 {0xb3, 0x20},
371 {0xb4, 0x20}, /* ctrlb4 */
372 {0xb5, 0x00},
373 {0xb6, 0xaf},
374 {0xbb, 0xae},
375 {0xbc, 0x7f}, /* ADC channel offsets */
376 {0xdb, 0x7f},
377 {0xbe, 0x7f},
378 {0xbf, 0x7f},
379 {0xc0, 0xe2},
380 {0xc1, 0xc0},
381 {0xc2, 0x01},
382 {0xc3, 0x4e},
383 {0xc6, 0x85},
384 {0xc7, 0x80}, /* com24 */
385 {0xc9, 0xe0},
386 {0xca, 0xe8},
387 {0xcb, 0xf0},
388 {0xcc, 0xd8},
389 {0xcd, 0xf1},
390 {0x4f, 0x98}, /* matrix */
391 {0x50, 0x98},
392 {0x51, 0x00},
393 {0x52, 0x28},
394 {0x53, 0x70},
395 {0x54, 0x98},
396 {0x58, 0x1a},
397 {0xff, 0x41}, /* read 41, write ff 00 */
398 {0x41, 0x40}, /* com16 */
399
400 {0xc5, 0x03}, /* 60 Hz banding filter */
401 {0x6a, 0x02}, /* 50 Hz banding filter */
402
403 {0x12, 0x62}, /* com7 - 30fps VGA YUV */
404 {0x36, 0xfa}, /* aref3 */
405 {0x69, 0x0a}, /* hv */
406 {0x8c, 0x89}, /* com22 */
407 {0x14, 0x28}, /* com9 */
408 {0x3e, 0x0c},
409 {0x41, 0x40}, /* com16 */
410 {0x72, 0x00},
411 {0x73, 0x00},
412 {0x74, 0x3a},
413 {0x75, 0x35},
414 {0x76, 0x01},
415 {0xc7, 0x80},
416 {0x03, 0x12}, /* vref */
417 {0x17, 0x16}, /* hstart */
418 {0x18, 0x02}, /* hstop */
419 {0x19, 0x01}, /* vstrt */
420 {0x1a, 0x3d}, /* vstop */
421 {0x32, 0xff}, /* href */
422 {0xc0, 0xaa},
423};
424
425static const u8 bridge_init_2[][2] = {
426 {0x94, 0xaa},
427 {0xf1, 0x60},
428 {0xe5, 0x04},
429 {0xc0, 0x50},
430 {0xc1, 0x3c},
431 {0x8c, 0x00},
432 {0x8d, 0x1c},
433 {0x34, 0x05},
434
435 {0xc2, 0x0c},
436 {0xc3, 0xf9},
437 {0xda, 0x01},
438 {0x50, 0x00},
439 {0x51, 0xa0},
440 {0x52, 0x3c},
441 {0x53, 0x00},
442 {0x54, 0x00},
443 {0x55, 0x00},
444 {0x57, 0x00},
445 {0x5c, 0x00},
446 {0x5a, 0xa0},
447 {0x5b, 0x78},
448 {0x35, 0x02},
449 {0xd9, 0x10},
450 {0x94, 0x11},
451};
452
453static const u8 sensor_init_2[][2] = {
454 {0x3b, 0xc4},
455 {0x1e, 0x04}, /* mvfp */
456 {0x13, 0xe0}, /* com8 */
457 {0x00, 0x00}, /* gain */
458 {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */
459 {0x11, 0x03}, /* clkrc */
460 {0x6b, 0x5a}, /* dblv */
461 {0x6a, 0x05},
462 {0xc5, 0x07},
463 {0xa2, 0x4b},
464 {0xa3, 0x3e},
465 {0x2d, 0x00},
466 {0xff, 0x42}, /* read 42, write ff 00 */
467 {0x42, 0xc0}, /* com17 */
468 {0x2d, 0x00},
469 {0xff, 0x42}, /* read 42, write ff 00 */
470 {0x42, 0xc1}, /* com17 */
471/* sharpness */
472 {0x3f, 0x01},
473 {0xff, 0x42}, /* read 42, write ff 00 */
474 {0x42, 0xc1}, /* com17 */
475/* saturation */
476 {0x4f, 0x98}, /* matrix */
477 {0x50, 0x98},
478 {0x51, 0x00},
479 {0x52, 0x28},
480 {0x53, 0x70},
481 {0x54, 0x98},
482 {0x58, 0x1a},
483 {0xff, 0x41}, /* read 41, write ff 00 */
484 {0x41, 0x40}, /* com16 */
485/* contrast */
486 {0x56, 0x40},
487/* brightness */
488 {0x55, 0x8f},
489/* expo */
490 {0x10, 0x25}, /* aech - exposure high bits */
491 {0xff, 0x13}, /* read 13, write ff 00 */
492 {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */
493};
494
495static const u8 sensor_start_1_vga[][2] = { /* same for qvga */
496 {0x12, 0x62}, /* com7 - 30fps VGA YUV */
497 {0x36, 0xfa}, /* aref3 */
498 {0x69, 0x0a}, /* hv */
499 {0x8c, 0x89}, /* com22 */
500 {0x14, 0x28}, /* com9 */
501 {0x3e, 0x0c}, /* com14 */
502 {0x41, 0x40}, /* com16 */
503 {0x72, 0x00},
504 {0x73, 0x00},
505 {0x74, 0x3a},
506 {0x75, 0x35},
507 {0x76, 0x01},
508 {0xc7, 0x80}, /* com24 */
509 {0x03, 0x12}, /* vref */
510 {0x17, 0x16}, /* hstart */
511 {0x18, 0x02}, /* hstop */
512 {0x19, 0x01}, /* vstrt */
513 {0x1a, 0x3d}, /* vstop */
514 {0x32, 0xff}, /* href */
515 {0xc0, 0xaa},
516};
517
518static const u8 sensor_start_1_svga[][2] = {
519 {0x12, 0x02}, /* com7 - YUYV - VGA 15 full resolution */
520 {0x36, 0xf8}, /* aref3 */
521 {0x69, 0x02}, /* hv */
522 {0x8c, 0x0d}, /* com22 */
523 {0x3e, 0x0c}, /* com14 */
524 {0x41, 0x40}, /* com16 */
525 {0x72, 0x00},
526 {0x73, 0x01},
527 {0x74, 0x3a},
528 {0x75, 0x35},
529 {0x76, 0x01},
530 {0xc7, 0x80}, /* com24 */
531 {0x03, 0x1b}, /* vref */
532 {0x17, 0x1d}, /* hstart */
533 {0x18, 0xbd}, /* hstop */
534 {0x19, 0x01}, /* vstrt */
535 {0x1a, 0x81}, /* vstop */
536 {0x32, 0xff}, /* href */
537 {0xc0, 0xe2},
538};
539
540static const u8 sensor_start_1_xga[][2] = {
541 {0x12, 0x02}, /* com7 */
542 {0x36, 0xf8}, /* aref3 */
543 {0x69, 0x02}, /* hv */
544 {0x8c, 0x89}, /* com22 */
545 {0x14, 0x28}, /* com9 */
546 {0x3e, 0x0c}, /* com14 */
547 {0x41, 0x40}, /* com16 */
548 {0x72, 0x00},
549 {0x73, 0x01},
550 {0x74, 0x3a},
551 {0x75, 0x35},
552 {0x76, 0x01},
553 {0xc7, 0x80}, /* com24 */
554 {0x03, 0x1b}, /* vref */
555 {0x17, 0x1d}, /* hstart */
556 {0x18, 0xbd}, /* hstop */
557 {0x19, 0x01}, /* vstrt */
558 {0x1a, 0x81}, /* vstop */
559 {0x32, 0xff}, /* href */
560 {0xc0, 0xe2},
561};
562
563static const u8 sensor_start_1_sxga[][2] = {
564 {0x12, 0x02}, /* com7 */
565 {0x36, 0xf8}, /* aref3 */
566 {0x69, 0x02}, /* hv */
567 {0x8c, 0x89}, /* com22 */
568 {0x14, 0x28}, /* com9 */
569 {0x3e, 0x0c}, /* com14 */
570 {0x41, 0x40}, /* com16 */
571 {0x72, 0x00},
572 {0x73, 0x01},
573 {0x74, 0x3a},
574 {0x75, 0x35},
575 {0x76, 0x01},
576 {0xc7, 0x80}, /* com24 */
577 {0x03, 0x1b}, /* vref */
578 {0x17, 0x1d}, /* hstart */
579 {0x18, 0x02}, /* hstop */
580 {0x19, 0x01}, /* vstrt */
581 {0x1a, 0x81}, /* vstop */
582 {0x32, 0xff}, /* href */
583 {0xc0, 0xe2},
584};
585
586static const u8 bridge_start_qvga[][2] = {
587 {0x94, 0xaa},
588 {0xf1, 0x60},
589 {0xe5, 0x04},
590 {0xc0, 0x50},
591 {0xc1, 0x3c},
592 {0x8c, 0x00},
593 {0x8d, 0x1c},
594 {0x34, 0x05},
595
596 {0xc2, 0x4c},
597 {0xc3, 0xf9},
598 {0xda, 0x00},
599 {0x50, 0x00},
600 {0x51, 0xa0},
601 {0x52, 0x78},
602 {0x53, 0x00},
603 {0x54, 0x00},
604 {0x55, 0x00},
605 {0x57, 0x00},
606 {0x5c, 0x00},
607 {0x5a, 0x50},
608 {0x5b, 0x3c},
609 {0x35, 0x02},
610 {0xd9, 0x10},
611 {0x94, 0x11},
612};
613
614static const u8 bridge_start_vga[][2] = {
615 {0x94, 0xaa},
616 {0xf1, 0x60},
617 {0xe5, 0x04},
618 {0xc0, 0x50},
619 {0xc1, 0x3c},
620 {0x8c, 0x00},
621 {0x8d, 0x1c},
622 {0x34, 0x05},
623 {0xc2, 0x0c},
624 {0xc3, 0xf9},
625 {0xda, 0x01},
626 {0x50, 0x00},
627 {0x51, 0xa0},
628 {0x52, 0x3c},
629 {0x53, 0x00},
630 {0x54, 0x00},
631 {0x55, 0x00},
632 {0x57, 0x00},
633 {0x5c, 0x00},
634 {0x5a, 0xa0},
635 {0x5b, 0x78},
636 {0x35, 0x02},
637 {0xd9, 0x10},
638 {0x94, 0x11},
639};
640
641static const u8 bridge_start_svga[][2] = {
642 {0x94, 0xaa},
643 {0xf1, 0x60},
644 {0xe5, 0x04},
645 {0xc0, 0xa0},
646 {0xc1, 0x80},
647 {0x8c, 0x00},
648 {0x8d, 0x1c},
649 {0x34, 0x05},
650 {0xc2, 0x4c},
651 {0xc3, 0xf9},
652 {0x50, 0x00},
653 {0x51, 0x40},
654 {0x52, 0x00},
655 {0x53, 0x00},
656 {0x54, 0x00},
657 {0x55, 0x88},
658 {0x57, 0x00},
659 {0x5c, 0x00},
660 {0x5a, 0xc8},
661 {0x5b, 0x96},
662 {0x35, 0x02},
663 {0xd9, 0x10},
664 {0xda, 0x00},
665 {0x94, 0x11},
666};
667
668static const u8 bridge_start_xga[][2] = {
669 {0x94, 0xaa},
670 {0xf1, 0x60},
671 {0xe5, 0x04},
672 {0xc0, 0xa0},
673 {0xc1, 0x80},
674 {0x8c, 0x00},
675 {0x8d, 0x1c},
676 {0x34, 0x05},
677 {0xc2, 0x4c},
678 {0xc3, 0xf9},
679 {0x50, 0x00},
680 {0x51, 0x40},
681 {0x52, 0x00},
682 {0x53, 0x00},
683 {0x54, 0x00},
684 {0x55, 0x88},
685 {0x57, 0x00},
686 {0x5c, 0x01},
687 {0x5a, 0x00},
688 {0x5b, 0xc0},
689 {0x35, 0x02},
690 {0xd9, 0x10},
691 {0xda, 0x01},
692 {0x94, 0x11},
693};
694
695static const u8 bridge_start_sxga[][2] = {
696 {0x94, 0xaa},
697 {0xf1, 0x60},
698 {0xe5, 0x04},
699 {0xc0, 0xa0},
700 {0xc1, 0x80},
701 {0x8c, 0x00},
702 {0x8d, 0x1c},
703 {0x34, 0x05},
704 {0xc2, 0x0c},
705 {0xc3, 0xf9},
706 {0xda, 0x00},
707 {0x35, 0x02},
708 {0xd9, 0x10},
709 {0x94, 0x11},
710};
711
712static const u8 sensor_start_2_qvga[][2] = {
713 {0x3b, 0xe4}, /* com11 - night mode 1/4 frame rate */
714 {0x1e, 0x04}, /* mvfp */
715 {0x13, 0xe0}, /* com8 */
716 {0x00, 0x00},
717 {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */
718 {0x11, 0x01}, /* clkrc */
719 {0x6b, 0x5a}, /* dblv */
720 {0x6a, 0x02}, /* 50 Hz banding filter */
721 {0xc5, 0x03}, /* 60 Hz banding filter */
722 {0xa2, 0x96}, /* bd50 */
723 {0xa3, 0x7d}, /* bd60 */
724
725 {0xff, 0x13}, /* read 13, write ff 00 */
726 {0x13, 0xe7},
727 {0x3a, 0x80}, /* tslb - yuyv */
728};
729
730static const u8 sensor_start_2_vga[][2] = {
731 {0x3b, 0xc4}, /* com11 - night mode 1/4 frame rate */
732 {0x1e, 0x04}, /* mvfp */
733 {0x13, 0xe0}, /* com8 */
734 {0x00, 0x00},
735 {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */
736 {0x11, 0x03}, /* clkrc */
737 {0x6b, 0x5a}, /* dblv */
738 {0x6a, 0x05}, /* 50 Hz banding filter */
739 {0xc5, 0x07}, /* 60 Hz banding filter */
740 {0xa2, 0x4b}, /* bd50 */
741 {0xa3, 0x3e}, /* bd60 */
742
743 {0x2d, 0x00}, /* advfl */
744};
745
746static const u8 sensor_start_2_svga[][2] = { /* same for xga */
747 {0x3b, 0xc4}, /* com11 - night mode 1/4 frame rate */
748 {0x1e, 0x04}, /* mvfp */
749 {0x13, 0xe0}, /* com8 */
750 {0x00, 0x00},
751 {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */
752 {0x11, 0x01}, /* clkrc */
753 {0x6b, 0x5a}, /* dblv */
754 {0x6a, 0x0c}, /* 50 Hz banding filter */
755 {0xc5, 0x0f}, /* 60 Hz banding filter */
756 {0xa2, 0x4e}, /* bd50 */
757 {0xa3, 0x41}, /* bd60 */
758};
759
760static const u8 sensor_start_2_sxga[][2] = {
761 {0x13, 0xe0}, /* com8 */
762 {0x00, 0x00},
763 {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */
764 {0x3b, 0xc4}, /* com11 - night mode 1/4 frame rate */
765 {0x1e, 0x04}, /* mvfp */
766 {0x11, 0x01}, /* clkrc */
767 {0x6b, 0x5a}, /* dblv */
768 {0x6a, 0x0c}, /* 50 Hz banding filter */
769 {0xc5, 0x0f}, /* 60 Hz banding filter */
770 {0xa2, 0x4e}, /* bd50 */
771 {0xa3, 0x41}, /* bd60 */
772};
773
774static void reg_w_i(struct gspca_dev *gspca_dev, u16 reg, u8 val)
775{
776 struct usb_device *udev = gspca_dev->dev;
777 int ret;
778
779 if (gspca_dev->usb_err < 0)
780 return;
781 gspca_dev->usb_buf[0] = val;
782 ret = usb_control_msg(udev,
783 usb_sndctrlpipe(udev, 0),
784 0x01,
785 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
786 0x00, reg, gspca_dev->usb_buf, 1, CTRL_TIMEOUT);
787 if (ret < 0) {
788 PDEBUG(D_ERR, "reg_w failed %d", ret);
789 gspca_dev->usb_err = ret;
790 }
791}
792
793static void reg_w(struct gspca_dev *gspca_dev, u16 reg, u8 val)
794{
795 PDEBUG(D_USBO, "reg_w [%04x] = %02x", reg, val);
796 reg_w_i(gspca_dev, reg, val);
797}
798
799static u8 reg_r(struct gspca_dev *gspca_dev, u16 reg)
800{
801 struct usb_device *udev = gspca_dev->dev;
802 int ret;
803
804 if (gspca_dev->usb_err < 0)
805 return 0;
806 ret = usb_control_msg(udev,
807 usb_rcvctrlpipe(udev, 0),
808 0x01,
809 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
810 0x00, reg, gspca_dev->usb_buf, 1, CTRL_TIMEOUT);
811 PDEBUG(D_USBI, "reg_r [%04x] -> %02x", reg, gspca_dev->usb_buf[0]);
812 if (ret < 0) {
813 PDEBUG(D_ERR, "reg_r err %d", ret);
814 gspca_dev->usb_err = ret;
815 }
816 return gspca_dev->usb_buf[0];
817}
818
819static int sccb_check_status(struct gspca_dev *gspca_dev)
820{
821 u8 data;
822 int i;
823
824 for (i = 0; i < 5; i++) {
825 data = reg_r(gspca_dev, OV534_REG_STATUS);
826
827 switch (data) {
828 case 0x00:
829 return 1;
830 case 0x04:
831 return 0;
832 case 0x03:
833 break;
834 default:
835 PDEBUG(D_USBI|D_USBO,
836 "sccb status 0x%02x, attempt %d/5",
837 data, i + 1);
838 }
839 }
840 return 0;
841}
842
843static void sccb_write(struct gspca_dev *gspca_dev, u8 reg, u8 val)
844{
845 PDEBUG(D_USBO, "sccb_write [%02x] = %02x", reg, val);
846 reg_w_i(gspca_dev, OV534_REG_SUBADDR, reg);
847 reg_w_i(gspca_dev, OV534_REG_WRITE, val);
848 reg_w_i(gspca_dev, OV534_REG_OPERATION, OV534_OP_WRITE_3);
849
850 if (!sccb_check_status(gspca_dev))
851 PDEBUG(D_ERR, "sccb_write failed");
852}
853
854static u8 sccb_read(struct gspca_dev *gspca_dev, u16 reg)
855{
856 reg_w(gspca_dev, OV534_REG_SUBADDR, reg);
857 reg_w(gspca_dev, OV534_REG_OPERATION, OV534_OP_WRITE_2);
858 if (!sccb_check_status(gspca_dev))
859 PDEBUG(D_ERR, "sccb_read failed 1");
860
861 reg_w(gspca_dev, OV534_REG_OPERATION, OV534_OP_READ_2);
862 if (!sccb_check_status(gspca_dev))
863 PDEBUG(D_ERR, "sccb_read failed 2");
864
865 return reg_r(gspca_dev, OV534_REG_READ);
866}
867
868/* output a bridge sequence (reg - val) */
869static void reg_w_array(struct gspca_dev *gspca_dev,
870 const u8 (*data)[2], int len)
871{
872 while (--len >= 0) {
873 reg_w(gspca_dev, (*data)[0], (*data)[1]);
874 data++;
875 }
876}
877
878/* output a sensor sequence (reg - val) */
879static void sccb_w_array(struct gspca_dev *gspca_dev,
880 const u8 (*data)[2], int len)
881{
882 while (--len >= 0) {
883 if ((*data)[0] != 0xff) {
884 sccb_write(gspca_dev, (*data)[0], (*data)[1]);
885 } else {
886 sccb_read(gspca_dev, (*data)[1]);
887 sccb_write(gspca_dev, 0xff, 0x00);
888 }
889 data++;
890 }
891}
892
893/* Two bits control LED: 0x21 bit 7 and 0x23 bit 7.
894 * (direction and output)? */
895static void set_led(struct gspca_dev *gspca_dev, int status)
896{
897 u8 data;
898
899 PDEBUG(D_CONF, "led status: %d", status);
900
901 data = reg_r(gspca_dev, 0x21);
902 data |= 0x80;
903 reg_w(gspca_dev, 0x21, data);
904
905 data = reg_r(gspca_dev, 0x23);
906 if (status)
907 data |= 0x80;
908 else
909 data &= ~0x80;
910
911 reg_w(gspca_dev, 0x23, data);
912
913 if (!status) {
914 data = reg_r(gspca_dev, 0x21);
915 data &= ~0x80;
916 reg_w(gspca_dev, 0x21, data);
917 }
918}
919
920static void setbrightness(struct gspca_dev *gspca_dev)
921{
922 struct sd *sd = (struct sd *) gspca_dev;
923 u8 val;
924
925 val = sd->brightness;
926 if (val < 8)
927 val = 15 - val; /* f .. 8 */
928 else
929 val = val - 8; /* 0 .. 7 */
930 sccb_write(gspca_dev, 0x55, /* brtn - brightness adjustment */
931 0x0f | (val << 4));
932}
933
934static void setcontrast(struct gspca_dev *gspca_dev)
935{
936 struct sd *sd = (struct sd *) gspca_dev;
937
938 sccb_write(gspca_dev, 0x56, /* cnst1 - contrast 1 ctrl coeff */
939 sd->contrast << 4);
940}
941
942static void setautogain(struct gspca_dev *gspca_dev)
943{
944 struct sd *sd = (struct sd *) gspca_dev;
945 u8 val;
946
947/*fixme: should adjust agc/awb/aec by different controls */
948 val = sd->autogain;
949 val = sccb_read(gspca_dev, 0x13); /* com8 */
950 sccb_write(gspca_dev, 0xff, 0x00);
951 if (sd->autogain)
952 val |= 0x05; /* agc & aec */
953 else
954 val &= 0xfa;
955 sccb_write(gspca_dev, 0x13, val);
956}
957
958static void setexposure(struct gspca_dev *gspca_dev)
959{
960 struct sd *sd = (struct sd *) gspca_dev;
961 u8 val;
962 static const u8 expo[4] = {0x00, 0x25, 0x38, 0x5e};
963
964 sccb_write(gspca_dev, 0x10, /* aec[9:2] */
965 expo[sd->exposure]);
966
967 val = sccb_read(gspca_dev, 0x13); /* com8 */
968 sccb_write(gspca_dev, 0xff, 0x00);
969 sccb_write(gspca_dev, 0x13, val);
970
971 val = sccb_read(gspca_dev, 0xa1); /* aech */
972 sccb_write(gspca_dev, 0xff, 0x00);
973 sccb_write(gspca_dev, 0xa1, val & 0xe0); /* aec[15:10] = 0 */
974}
975
976static void setsharpness(struct gspca_dev *gspca_dev)
977{
978 struct sd *sd = (struct sd *) gspca_dev;
979 s8 val;
980
981 val = sd->sharpness;
982 if (val < 0) { /* auto */
983 val = sccb_read(gspca_dev, 0x42); /* com17 */
984 sccb_write(gspca_dev, 0xff, 0x00);
985 sccb_write(gspca_dev, 0x42, val | 0x40);
986 /* Edge enhancement strength auto adjust */
987 return;
988 }
989 if (val != 0)
990 val = 1 << (val - 1);
991 sccb_write(gspca_dev, 0x3f, /* edge - edge enhance. factor */
992 val);
993 val = sccb_read(gspca_dev, 0x42); /* com17 */
994 sccb_write(gspca_dev, 0xff, 0x00);
995 sccb_write(gspca_dev, 0x42, val & 0xbf);
996}
997
998static void setsatur(struct gspca_dev *gspca_dev)
999{
1000 struct sd *sd = (struct sd *) gspca_dev;
1001 u8 val1, val2, val3;
1002 static const u8 matrix[5][2] = {
1003 {0x14, 0x38},
1004 {0x1e, 0x54},
1005 {0x28, 0x70},
1006 {0x32, 0x8c},
1007 {0x48, 0x90}
1008 };
1009
1010 val1 = matrix[sd->satur][0];
1011 val2 = matrix[sd->satur][1];
1012 val3 = val1 + val2;
1013 sccb_write(gspca_dev, 0x4f, val3); /* matrix coeff */
1014 sccb_write(gspca_dev, 0x50, val3);
1015 sccb_write(gspca_dev, 0x51, 0x00);
1016 sccb_write(gspca_dev, 0x52, val1);
1017 sccb_write(gspca_dev, 0x53, val2);
1018 sccb_write(gspca_dev, 0x54, val3);
1019 sccb_write(gspca_dev, 0x58, 0x1a); /* mtxs - coeff signs */
1020
1021 val1 = sccb_read(gspca_dev, 0x41); /* com16 */
1022 sccb_write(gspca_dev, 0xff, 0x00);
1023 sccb_write(gspca_dev, 0x41, val1);
1024}
1025
1026static void setfreq(struct gspca_dev *gspca_dev)
1027{
1028 struct sd *sd = (struct sd *) gspca_dev;
1029 u8 val;
1030
1031 val = sccb_read(gspca_dev, 0x13); /* com8 */
1032 sccb_write(gspca_dev, 0xff, 0x00);
1033 if (sd->freq == 0) {
1034 sccb_write(gspca_dev, 0x13, val & 0xdf);
1035 return;
1036 }
1037 sccb_write(gspca_dev, 0x13, val | 0x20);
1038
1039 val = sccb_read(gspca_dev, 0x42); /* com17 */
1040 sccb_write(gspca_dev, 0xff, 0x00);
1041 if (sd->freq == 1)
1042 val |= 0x01;
1043 else
1044 val &= 0xfe;
1045 sccb_write(gspca_dev, 0x42, val);
1046}
1047
1048/* this function is called at probe time */
1049static int sd_config(struct gspca_dev *gspca_dev,
1050 const struct usb_device_id *id)
1051{
1052 struct sd *sd = (struct sd *) gspca_dev;
1053 struct cam *cam;
1054
1055 cam = &gspca_dev->cam;
1056
1057 cam->cam_mode = ov965x_mode;
1058 cam->nmodes = ARRAY_SIZE(ov965x_mode);
1059
1060 sd->brightness = BRIGHTNESS_DEF;
1061 sd->contrast = CONTRAST_DEF;
1062#if AUTOGAIN_DEF != 0
1063 sd->autogain = AUTOGAIN_DEF;
1064 gspca_dev->ctrl_inac |= (1 << EXPO_IDX);
1065#endif
1066#if EXPO_DEF != 0
1067 sd->exposure = EXPO_DEF;
1068#endif
1069#if SHARPNESS_DEF != 0
1070 sd->sharpness = SHARPNESS_DEF;
1071#endif
1072 sd->satur = SATUR_DEF;
1073 sd->freq = FREQ_DEF;
1074
1075 return 0;
1076}
1077
1078/* this function is called at probe and resume time */
1079static int sd_init(struct gspca_dev *gspca_dev)
1080{
1081 u16 sensor_id;
1082
1083 /* reset bridge */
1084 reg_w(gspca_dev, 0xe7, 0x3a);
1085 reg_w(gspca_dev, 0xe0, 0x08);
1086 msleep(100);
1087
1088 /* initialize the sensor address */
1089 reg_w(gspca_dev, OV534_REG_ADDRESS, 0x60);
1090
1091 /* reset sensor */
1092 sccb_write(gspca_dev, 0x12, 0x80);
1093 msleep(10);
1094
1095 /* probe the sensor */
1096 sccb_read(gspca_dev, 0x0a);
1097 sensor_id = sccb_read(gspca_dev, 0x0a) << 8;
1098 sccb_read(gspca_dev, 0x0b);
1099 sensor_id |= sccb_read(gspca_dev, 0x0b);
1100 PDEBUG(D_PROBE, "Sensor ID: %04x", sensor_id);
1101
1102 /* initialize */
1103 reg_w_array(gspca_dev, bridge_init,
1104 ARRAY_SIZE(bridge_init));
1105 sccb_w_array(gspca_dev, sensor_init,
1106 ARRAY_SIZE(sensor_init));
1107 reg_w_array(gspca_dev, bridge_init_2,
1108 ARRAY_SIZE(bridge_init_2));
1109 sccb_w_array(gspca_dev, sensor_init_2,
1110 ARRAY_SIZE(sensor_init_2));
1111 reg_w(gspca_dev, 0xe0, 0x00);
1112 reg_w(gspca_dev, 0xe0, 0x01);
1113 set_led(gspca_dev, 0);
1114 reg_w(gspca_dev, 0xe0, 0x00);
1115
1116 return gspca_dev->usb_err;
1117}
1118
1119static int sd_start(struct gspca_dev *gspca_dev)
1120{
1121 switch (gspca_dev->curr_mode) {
1122 case QVGA_MODE: /* 320x240 */
1123 sccb_w_array(gspca_dev, sensor_start_1_vga,
1124 ARRAY_SIZE(sensor_start_1_vga));
1125 reg_w_array(gspca_dev, bridge_start_qvga,
1126 ARRAY_SIZE(bridge_start_qvga));
1127 sccb_w_array(gspca_dev, sensor_start_2_qvga,
1128 ARRAY_SIZE(sensor_start_2_qvga));
1129 break;
1130 case VGA_MODE: /* 640x480 */
1131 sccb_w_array(gspca_dev, sensor_start_1_vga,
1132 ARRAY_SIZE(sensor_start_1_vga));
1133 reg_w_array(gspca_dev, bridge_start_vga,
1134 ARRAY_SIZE(bridge_start_vga));
1135 sccb_w_array(gspca_dev, sensor_start_2_vga,
1136 ARRAY_SIZE(sensor_start_2_vga));
1137 break;
1138 case SVGA_MODE: /* 800x600 */
1139 sccb_w_array(gspca_dev, sensor_start_1_svga,
1140 ARRAY_SIZE(sensor_start_1_svga));
1141 reg_w_array(gspca_dev, bridge_start_svga,
1142 ARRAY_SIZE(bridge_start_svga));
1143 sccb_w_array(gspca_dev, sensor_start_2_svga,
1144 ARRAY_SIZE(sensor_start_2_svga));
1145 break;
1146 case XGA_MODE: /* 1024x768 */
1147 sccb_w_array(gspca_dev, sensor_start_1_xga,
1148 ARRAY_SIZE(sensor_start_1_xga));
1149 reg_w_array(gspca_dev, bridge_start_xga,
1150 ARRAY_SIZE(bridge_start_xga));
1151 sccb_w_array(gspca_dev, sensor_start_2_svga,
1152 ARRAY_SIZE(sensor_start_2_svga));
1153 break;
1154 default:
1155/* case SXGA_MODE: * 1280x1024 */
1156 sccb_w_array(gspca_dev, sensor_start_1_sxga,
1157 ARRAY_SIZE(sensor_start_1_sxga));
1158 reg_w_array(gspca_dev, bridge_start_sxga,
1159 ARRAY_SIZE(bridge_start_sxga));
1160 sccb_w_array(gspca_dev, sensor_start_2_sxga,
1161 ARRAY_SIZE(sensor_start_2_sxga));
1162 break;
1163 }
1164 setfreq(gspca_dev);
1165 setautogain(gspca_dev);
1166 setbrightness(gspca_dev);
1167 setcontrast(gspca_dev);
1168 setexposure(gspca_dev);
1169 setsharpness(gspca_dev);
1170 setsatur(gspca_dev);
1171
1172 reg_w(gspca_dev, 0xe0, 0x00);
1173 reg_w(gspca_dev, 0xe0, 0x00);
1174 set_led(gspca_dev, 1);
1175 return gspca_dev->usb_err;
1176}
1177
1178static void sd_stopN(struct gspca_dev *gspca_dev)
1179{
1180 reg_w(gspca_dev, 0xe0, 0x01);
1181 set_led(gspca_dev, 0);
1182 reg_w(gspca_dev, 0xe0, 0x00);
1183}
1184
1185/* Values for bmHeaderInfo (Video and Still Image Payload Headers, 2.4.3.3) */
1186#define UVC_STREAM_EOH (1 << 7)
1187#define UVC_STREAM_ERR (1 << 6)
1188#define UVC_STREAM_STI (1 << 5)
1189#define UVC_STREAM_RES (1 << 4)
1190#define UVC_STREAM_SCR (1 << 3)
1191#define UVC_STREAM_PTS (1 << 2)
1192#define UVC_STREAM_EOF (1 << 1)
1193#define UVC_STREAM_FID (1 << 0)
1194
1195static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1196 u8 *data, int len)
1197{
1198 struct sd *sd = (struct sd *) gspca_dev;
1199 __u32 this_pts;
1200 u8 this_fid;
1201 int remaining_len = len;
1202
1203 do {
1204 len = min(remaining_len, 2040);
1205
1206 /* Payloads are prefixed with a UVC-style header. We
1207 consider a frame to start when the FID toggles, or the PTS
1208 changes. A frame ends when EOF is set, and we've received
1209 the correct number of bytes. */
1210
1211 /* Verify UVC header. Header length is always 12 */
1212 if (data[0] != 12 || len < 12) {
1213 PDEBUG(D_PACK, "bad header");
1214 goto discard;
1215 }
1216
1217 /* Check errors */
1218 if (data[1] & UVC_STREAM_ERR) {
1219 PDEBUG(D_PACK, "payload error");
1220 goto discard;
1221 }
1222
1223 /* Extract PTS and FID */
1224 if (!(data[1] & UVC_STREAM_PTS)) {
1225 PDEBUG(D_PACK, "PTS not present");
1226 goto discard;
1227 }
1228 this_pts = (data[5] << 24) | (data[4] << 16)
1229 | (data[3] << 8) | data[2];
1230 this_fid = data[1] & UVC_STREAM_FID;
1231
1232 /* If PTS or FID has changed, start a new frame. */
1233 if (this_pts != sd->last_pts || this_fid != sd->last_fid) {
1234 if (gspca_dev->last_packet_type == INTER_PACKET)
1235 gspca_frame_add(gspca_dev, LAST_PACKET,
1236 NULL, 0);
1237 sd->last_pts = this_pts;
1238 sd->last_fid = this_fid;
1239 gspca_frame_add(gspca_dev, FIRST_PACKET,
1240 data + 12, len - 12);
1241 /* If this packet is marked as EOF, end the frame */
1242 } else if (data[1] & UVC_STREAM_EOF) {
1243 sd->last_pts = 0;
1244 gspca_frame_add(gspca_dev, LAST_PACKET,
1245 data + 12, len - 12);
1246 } else {
1247
1248 /* Add the data from this payload */
1249 gspca_frame_add(gspca_dev, INTER_PACKET,
1250 data + 12, len - 12);
1251 }
1252
1253 /* Done this payload */
1254 goto scan_next;
1255
1256discard:
1257 /* Discard data until a new frame starts. */
1258 gspca_dev->last_packet_type = DISCARD_PACKET;
1259
1260scan_next:
1261 remaining_len -= len;
1262 data += len;
1263 } while (remaining_len > 0);
1264}
1265
1266/* controls */
1267static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
1268{
1269 struct sd *sd = (struct sd *) gspca_dev;
1270
1271 sd->brightness = val;
1272 if (gspca_dev->streaming)
1273 setbrightness(gspca_dev);
1274 return gspca_dev->usb_err;
1275}
1276
1277static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
1278{
1279 struct sd *sd = (struct sd *) gspca_dev;
1280
1281 *val = sd->brightness;
1282 return 0;
1283}
1284
1285static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
1286{
1287 struct sd *sd = (struct sd *) gspca_dev;
1288
1289 sd->contrast = val;
1290 if (gspca_dev->streaming)
1291 setcontrast(gspca_dev);
1292 return gspca_dev->usb_err;
1293}
1294
1295static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
1296{
1297 struct sd *sd = (struct sd *) gspca_dev;
1298
1299 *val = sd->contrast;
1300 return 0;
1301}
1302
1303static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
1304{
1305 struct sd *sd = (struct sd *) gspca_dev;
1306
1307 sd->autogain = val;
1308
1309 if (gspca_dev->streaming) {
1310 if (val)
1311 gspca_dev->ctrl_inac |= (1 << EXPO_IDX);
1312 else
1313 gspca_dev->ctrl_inac &= ~(1 << EXPO_IDX);
1314 setautogain(gspca_dev);
1315 }
1316 return gspca_dev->usb_err;
1317}
1318
1319static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val)
1320{
1321 struct sd *sd = (struct sd *) gspca_dev;
1322
1323 *val = sd->autogain;
1324 return 0;
1325}
1326
1327static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val)
1328{
1329 struct sd *sd = (struct sd *) gspca_dev;
1330
1331 sd->exposure = val;
1332 if (gspca_dev->streaming)
1333 setexposure(gspca_dev);
1334 return gspca_dev->usb_err;
1335}
1336
1337static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val)
1338{
1339 struct sd *sd = (struct sd *) gspca_dev;
1340
1341 *val = sd->exposure;
1342 return 0;
1343}
1344
1345static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val)
1346{
1347 struct sd *sd = (struct sd *) gspca_dev;
1348
1349 sd->sharpness = val;
1350 if (gspca_dev->streaming)
1351 setsharpness(gspca_dev);
1352 return gspca_dev->usb_err;
1353}
1354
1355static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val)
1356{
1357 struct sd *sd = (struct sd *) gspca_dev;
1358
1359 *val = sd->sharpness;
1360 return 0;
1361}
1362
1363static int sd_setsatur(struct gspca_dev *gspca_dev, __s32 val)
1364{
1365 struct sd *sd = (struct sd *) gspca_dev;
1366
1367 sd->satur = val;
1368 if (gspca_dev->streaming)
1369 setsatur(gspca_dev);
1370 return gspca_dev->usb_err;
1371}
1372
1373static int sd_getsatur(struct gspca_dev *gspca_dev, __s32 *val)
1374{
1375 struct sd *sd = (struct sd *) gspca_dev;
1376
1377 *val = sd->satur;
1378 return 0;
1379}
1380static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val)
1381{
1382 struct sd *sd = (struct sd *) gspca_dev;
1383
1384 sd->freq = val;
1385 if (gspca_dev->streaming)
1386 setfreq(gspca_dev);
1387 return gspca_dev->usb_err;
1388}
1389
1390static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val)
1391{
1392 struct sd *sd = (struct sd *) gspca_dev;
1393
1394 *val = sd->freq;
1395 return 0;
1396}
1397
1398static int sd_querymenu(struct gspca_dev *gspca_dev,
1399 struct v4l2_querymenu *menu)
1400{
1401 switch (menu->id) {
1402 case V4L2_CID_POWER_LINE_FREQUENCY:
1403 switch (menu->index) {
1404 case 0: /* V4L2_CID_POWER_LINE_FREQUENCY_DISABLED */
1405 strcpy((char *) menu->name, "NoFliker");
1406 return 0;
1407 case 1: /* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */
1408 strcpy((char *) menu->name, "50 Hz");
1409 return 0;
1410 case 2: /* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */
1411 strcpy((char *) menu->name, "60 Hz");
1412 return 0;
1413 }
1414 break;
1415 }
1416 return -EINVAL;
1417}
1418
1419/* sub-driver description */
1420static const struct sd_desc sd_desc = {
1421 .name = MODULE_NAME,
1422 .ctrls = sd_ctrls,
1423 .nctrls = ARRAY_SIZE(sd_ctrls),
1424 .config = sd_config,
1425 .init = sd_init,
1426 .start = sd_start,
1427 .stopN = sd_stopN,
1428 .pkt_scan = sd_pkt_scan,
1429 .querymenu = sd_querymenu,
1430};
1431
1432/* -- module initialisation -- */
1433static const __devinitdata struct usb_device_id device_table[] = {
1434 {USB_DEVICE(0x06f8, 0x3003)},
1435 {}
1436};
1437
1438MODULE_DEVICE_TABLE(usb, device_table);
1439
1440/* -- device connect -- */
1441static int sd_probe(struct usb_interface *intf, const struct usb_device_id *id)
1442{
1443 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
1444 THIS_MODULE);
1445}
1446
1447static struct usb_driver sd_driver = {
1448 .name = MODULE_NAME,
1449 .id_table = device_table,
1450 .probe = sd_probe,
1451 .disconnect = gspca_disconnect,
1452#ifdef CONFIG_PM
1453 .suspend = gspca_suspend,
1454 .resume = gspca_resume,
1455#endif
1456};
1457
1458/* -- module insert / remove -- */
1459static int __init sd_mod_init(void)
1460{
1461 int ret;
1462
1463 ret = usb_register(&sd_driver);
1464 if (ret < 0)
1465 return ret;
1466 PDEBUG(D_PROBE, "registered");
1467 return 0;
1468}
1469
1470static void __exit sd_mod_exit(void)
1471{
1472 usb_deregister(&sd_driver);
1473 PDEBUG(D_PROBE, "deregistered");
1474}
1475
1476module_init(sd_mod_init);
1477module_exit(sd_mod_exit);
diff --git a/drivers/media/video/gspca/pac207.c b/drivers/media/video/gspca/pac207.c
index 4706a823add0..0c87c3490b1e 100644
--- a/drivers/media/video/gspca/pac207.c
+++ b/drivers/media/video/gspca/pac207.c
@@ -25,6 +25,7 @@
25 25
26#define MODULE_NAME "pac207" 26#define MODULE_NAME "pac207"
27 27
28#include <linux/input.h>
28#include "gspca.h" 29#include "gspca.h"
29 30
30MODULE_AUTHOR("Hans de Goede <hdgoede@redhat.com>"); 31MODULE_AUTHOR("Hans de Goede <hdgoede@redhat.com>");
@@ -77,7 +78,7 @@ static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val);
77static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val); 78static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val);
78static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val); 79static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val);
79 80
80static struct ctrl sd_ctrls[] = { 81static const struct ctrl sd_ctrls[] = {
81#define SD_BRIGHTNESS 0 82#define SD_BRIGHTNESS 0
82 { 83 {
83 { 84 {
@@ -495,6 +496,25 @@ static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val)
495 return 0; 496 return 0;
496} 497}
497 498
499#ifdef CONFIG_INPUT
500static int sd_int_pkt_scan(struct gspca_dev *gspca_dev,
501 u8 *data, /* interrupt packet data */
502 int len) /* interrput packet length */
503{
504 int ret = -EINVAL;
505
506 if (len == 2 && data[0] == 0x5a && data[1] == 0x5a) {
507 input_report_key(gspca_dev->input_dev, KEY_CAMERA, 1);
508 input_sync(gspca_dev->input_dev);
509 input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0);
510 input_sync(gspca_dev->input_dev);
511 ret = 0;
512 }
513
514 return ret;
515}
516#endif
517
498/* sub-driver description */ 518/* sub-driver description */
499static const struct sd_desc sd_desc = { 519static const struct sd_desc sd_desc = {
500 .name = MODULE_NAME, 520 .name = MODULE_NAME,
@@ -506,6 +526,9 @@ static const struct sd_desc sd_desc = {
506 .stopN = sd_stopN, 526 .stopN = sd_stopN,
507 .dq_callback = pac207_do_auto_gain, 527 .dq_callback = pac207_do_auto_gain,
508 .pkt_scan = sd_pkt_scan, 528 .pkt_scan = sd_pkt_scan,
529#ifdef CONFIG_INPUT
530 .int_pkt_scan = sd_int_pkt_scan,
531#endif
509}; 532};
510 533
511/* -- module initialisation -- */ 534/* -- module initialisation -- */
diff --git a/drivers/media/video/gspca/pac7302.c b/drivers/media/video/gspca/pac7302.c
index de0b66c4b56e..2a68220d1ada 100644
--- a/drivers/media/video/gspca/pac7302.c
+++ b/drivers/media/video/gspca/pac7302.c
@@ -4,7 +4,9 @@
4 * 4 *
5 * V4L2 by Jean-Francois Moine <http://moinejf.free.fr> 5 * V4L2 by Jean-Francois Moine <http://moinejf.free.fr>
6 * 6 *
7 * Separated from Pixart PAC7311 library by Márton Németh <nm127@freemail.hu> 7 * Separated from Pixart PAC7311 library by Márton Németh
8 * Camera button input handling by Márton Németh <nm127@freemail.hu>
9 * Copyright (C) 2009-2010 Márton Németh <nm127@freemail.hu>
8 * 10 *
9 * This program is free software; you can redistribute it and/or modify 11 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by 12 * it under the terms of the GNU General Public License as published by
@@ -22,33 +24,26 @@
22 */ 24 */
23 25
24/* Some documentation about various registers as determined by trial and error. 26/* Some documentation about various registers as determined by trial and error.
25 When the register addresses differ between the 7202 and the 7311 the 2
26 different addresses are written as 7302addr/7311addr, when one of the 2
27 addresses is a - sign that register description is not valid for the
28 matching IC.
29 27
30 Register page 1: 28 Register page 1:
31 29
32 Address Description 30 Address Description
33 -/0x08 Unknown compressor related, must always be 8 except when not
34 in 640x480 resolution and page 4 reg 2 <= 3 then set it to 9 !
35 -/0x1b Auto white balance related, bit 0 is AWB enable (inverted)
36 bits 345 seem to toggle per color gains on/off (inverted)
37 0x78 Global control, bit 6 controls the LED (inverted) 31 0x78 Global control, bit 6 controls the LED (inverted)
38 -/0x80 JPEG compression ratio ? Best not touched
39 32
40 Register page 3/4: 33 Register page 3:
41 34
42 Address Description 35 Address Description
43 0x02 Clock divider 2-63, fps =~ 60 / val. Must be a multiple of 3 on 36 0x02 Clock divider 3-63, fps = 90 / val. Must be a multiple of 3 on
44 the 7302, so one of 3, 6, 9, ..., except when between 6 and 12? 37 the 7302, so one of 3, 6, 9, ..., except when between 6 and 12?
45 -/0x0f Master gain 1-245, low value = high gain 38 0x03 Variable framerate ctrl reg2==3: 0 -> ~30 fps, 255 -> ~22fps
46 0x10/- Master gain 0-31 39 0x04 Another var framerate ctrl reg2==3, reg3==0: 0 -> ~30 fps,
47 -/0x10 Another gain 0-15, limited influence (1-2x gain I guess) 40 63 -> ~27 fps, the 2 msb's must always be 1 !!
41 0x05 Another var framerate ctrl reg2==3, reg3==0, reg4==0xc0:
42 1 -> ~30 fps, 2 -> ~20 fps
43 0x0e Exposure bits 0-7, 0-448, 0 = use full frame time
44 0x0f Exposure bit 8, 0-448, 448 = no exposure at all
45 0x10 Master gain 0-31
48 0x21 Bitfield: 0-1 unused, 2-3 vflip/hflip, 4-5 unknown, 6-7 unused 46 0x21 Bitfield: 0-1 unused, 2-3 vflip/hflip, 4-5 unknown, 6-7 unused
49 -/0x27 Seems to toggle various gains on / off, Setting bit 7 seems to
50 completely disable the analog amplification block. Set to 0x68
51 for max gain, 0x14 for minimal gain.
52 47
53 The registers are accessed in the following functions: 48 The registers are accessed in the following functions:
54 49
@@ -68,6 +63,7 @@
68 63
69#define MODULE_NAME "pac7302" 64#define MODULE_NAME "pac7302"
70 65
66#include <linux/input.h>
71#include <media/v4l2-chip-ident.h> 67#include <media/v4l2-chip-ident.h>
72#include "gspca.h" 68#include "gspca.h"
73 69
@@ -86,8 +82,8 @@ struct sd {
86 unsigned char red_balance; 82 unsigned char red_balance;
87 unsigned char blue_balance; 83 unsigned char blue_balance;
88 unsigned char gain; 84 unsigned char gain;
89 unsigned char exposure;
90 unsigned char autogain; 85 unsigned char autogain;
86 unsigned short exposure;
91 __u8 hflip; 87 __u8 hflip;
92 __u8 vflip; 88 __u8 vflip;
93 u8 flags; 89 u8 flags;
@@ -124,8 +120,7 @@ static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val);
124static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val); 120static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val);
125static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val); 121static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val);
126 122
127static struct ctrl sd_ctrls[] = { 123static const struct ctrl sd_ctrls[] = {
128/* This control is pac7302 only */
129 { 124 {
130 { 125 {
131 .id = V4L2_CID_BRIGHTNESS, 126 .id = V4L2_CID_BRIGHTNESS,
@@ -141,7 +136,6 @@ static struct ctrl sd_ctrls[] = {
141 .set = sd_setbrightness, 136 .set = sd_setbrightness,
142 .get = sd_getbrightness, 137 .get = sd_getbrightness,
143 }, 138 },
144/* This control is for both the 7302 and the 7311 */
145 { 139 {
146 { 140 {
147 .id = V4L2_CID_CONTRAST, 141 .id = V4L2_CID_CONTRAST,
@@ -157,7 +151,6 @@ static struct ctrl sd_ctrls[] = {
157 .set = sd_setcontrast, 151 .set = sd_setcontrast,
158 .get = sd_getcontrast, 152 .get = sd_getcontrast,
159 }, 153 },
160/* This control is pac7302 only */
161 { 154 {
162 { 155 {
163 .id = V4L2_CID_SATURATION, 156 .id = V4L2_CID_SATURATION,
@@ -215,7 +208,6 @@ static struct ctrl sd_ctrls[] = {
215 .set = sd_setbluebalance, 208 .set = sd_setbluebalance,
216 .get = sd_getbluebalance, 209 .get = sd_getbluebalance,
217 }, 210 },
218/* All controls below are for both the 7302 and the 7311 */
219 { 211 {
220 { 212 {
221 .id = V4L2_CID_GAIN, 213 .id = V4L2_CID_GAIN,
@@ -238,11 +230,10 @@ static struct ctrl sd_ctrls[] = {
238 .type = V4L2_CTRL_TYPE_INTEGER, 230 .type = V4L2_CTRL_TYPE_INTEGER,
239 .name = "Exposure", 231 .name = "Exposure",
240 .minimum = 0, 232 .minimum = 0,
241#define EXPOSURE_MAX 255 233 .maximum = 1023,
242 .maximum = EXPOSURE_MAX,
243 .step = 1, 234 .step = 1,
244#define EXPOSURE_DEF 16 /* 32 ms / 30 fps */ 235#define EXPOSURE_DEF 66 /* 33 ms / 30 fps */
245#define EXPOSURE_KNEE 50 /* 100 ms / 10 fps */ 236#define EXPOSURE_KNEE 133 /* 66 ms / 15 fps */
246 .default_value = EXPOSURE_DEF, 237 .default_value = EXPOSURE_DEF,
247 }, 238 },
248 .set = sd_setexposure, 239 .set = sd_setexposure,
@@ -301,7 +292,6 @@ static const struct v4l2_pix_format vga_mode[] = {
301}; 292};
302 293
303#define LOAD_PAGE3 255 294#define LOAD_PAGE3 255
304#define LOAD_PAGE4 254
305#define END_OF_SEQUENCE 0 295#define END_OF_SEQUENCE 0
306 296
307/* pac 7302 */ 297/* pac 7302 */
@@ -379,7 +369,7 @@ static const __u8 start_7302[] = {
379#define SKIP 0xaa 369#define SKIP 0xaa
380/* page 3 - the value SKIP says skip the index - see reg_w_page() */ 370/* page 3 - the value SKIP says skip the index - see reg_w_page() */
381static const __u8 page3_7302[] = { 371static const __u8 page3_7302[] = {
382 0x90, 0x40, 0x03, 0x50, 0xc2, 0x01, 0x14, 0x16, 372 0x90, 0x40, 0x03, 0x00, 0xc0, 0x01, 0x14, 0x16,
383 0x14, 0x12, 0x00, 0x00, 0x00, 0x02, 0x33, 0x00, 373 0x14, 0x12, 0x00, 0x00, 0x00, 0x02, 0x33, 0x00,
384 0x0f, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 374 0x0f, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
385 0x00, 0x00, 0x00, 0x47, 0x01, 0xb3, 0x01, 0x00, 375 0x00, 0x00, 0x00, 0x47, 0x01, 0xb3, 0x01, 0x00,
@@ -388,7 +378,7 @@ static const __u8 page3_7302[] = {
388 0xa4, 0xb8, 0xe0, 0x2a, 0xf6, 0x00, 0x00, 0x00, 378 0xa4, 0xb8, 0xe0, 0x2a, 0xf6, 0x00, 0x00, 0x00,
389 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 379 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
390 0x00, 0xfc, 0x00, 0xf2, 0x1f, 0x04, 0x00, 0x00, 380 0x00, 0xfc, 0x00, 0xf2, 0x1f, 0x04, 0x00, 0x00,
391 0x00, 0x00, 0x00, 0xc0, 0xc0, 0x10, 0x00, 0x00, 381 SKIP, 0x00, 0x00, 0xc0, 0xc0, 0x10, 0x00, 0x00,
392 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 382 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
393 0x00, 0x40, 0xff, 0x03, 0x19, 0x00, 0x00, 0x00, 383 0x00, 0x40, 0xff, 0x03, 0x19, 0x00, 0x00, 0x00,
394 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 384 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@@ -401,12 +391,14 @@ static const __u8 page3_7302[] = {
401 0x00 391 0x00
402}; 392};
403 393
404static int reg_w_buf(struct gspca_dev *gspca_dev, 394static void reg_w_buf(struct gspca_dev *gspca_dev,
405 __u8 index, 395 __u8 index,
406 const char *buffer, int len) 396 const char *buffer, int len)
407{ 397{
408 int ret; 398 int ret;
409 399
400 if (gspca_dev->usb_err < 0)
401 return;
410 memcpy(gspca_dev->usb_buf, buffer, len); 402 memcpy(gspca_dev->usb_buf, buffer, len);
411 ret = usb_control_msg(gspca_dev->dev, 403 ret = usb_control_msg(gspca_dev->dev,
412 usb_sndctrlpipe(gspca_dev->dev, 0), 404 usb_sndctrlpipe(gspca_dev->dev, 0),
@@ -415,20 +407,23 @@ static int reg_w_buf(struct gspca_dev *gspca_dev,
415 0, /* value */ 407 0, /* value */
416 index, gspca_dev->usb_buf, len, 408 index, gspca_dev->usb_buf, len,
417 500); 409 500);
418 if (ret < 0) 410 if (ret < 0) {
419 PDEBUG(D_ERR, "reg_w_buf(): " 411 PDEBUG(D_ERR, "reg_w_buf(): "
420 "Failed to write registers to index 0x%x, error %i", 412 "Failed to write registers to index 0x%x, error %i",
421 index, ret); 413 index, ret);
422 return ret; 414 gspca_dev->usb_err = ret;
415 }
423} 416}
424 417
425 418
426static int reg_w(struct gspca_dev *gspca_dev, 419static void reg_w(struct gspca_dev *gspca_dev,
427 __u8 index, 420 __u8 index,
428 __u8 value) 421 __u8 value)
429{ 422{
430 int ret; 423 int ret;
431 424
425 if (gspca_dev->usb_err < 0)
426 return;
432 gspca_dev->usb_buf[0] = value; 427 gspca_dev->usb_buf[0] = value;
433 ret = usb_control_msg(gspca_dev->dev, 428 ret = usb_control_msg(gspca_dev->dev,
434 usb_sndctrlpipe(gspca_dev->dev, 0), 429 usb_sndctrlpipe(gspca_dev->dev, 0),
@@ -436,32 +431,32 @@ static int reg_w(struct gspca_dev *gspca_dev,
436 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 431 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
437 0, index, gspca_dev->usb_buf, 1, 432 0, index, gspca_dev->usb_buf, 1,
438 500); 433 500);
439 if (ret < 0) 434 if (ret < 0) {
440 PDEBUG(D_ERR, "reg_w(): " 435 PDEBUG(D_ERR, "reg_w(): "
441 "Failed to write register to index 0x%x, value 0x%x, error %i", 436 "Failed to write register to index 0x%x, value 0x%x, error %i",
442 index, value, ret); 437 index, value, ret);
443 return ret; 438 gspca_dev->usb_err = ret;
439 }
444} 440}
445 441
446static int reg_w_seq(struct gspca_dev *gspca_dev, 442static void reg_w_seq(struct gspca_dev *gspca_dev,
447 const __u8 *seq, int len) 443 const __u8 *seq, int len)
448{ 444{
449 int ret = 0;
450 while (--len >= 0) { 445 while (--len >= 0) {
451 if (0 <= ret) 446 reg_w(gspca_dev, seq[0], seq[1]);
452 ret = reg_w(gspca_dev, seq[0], seq[1]);
453 seq += 2; 447 seq += 2;
454 } 448 }
455 return ret;
456} 449}
457 450
458/* load the beginning of a page */ 451/* load the beginning of a page */
459static int reg_w_page(struct gspca_dev *gspca_dev, 452static void reg_w_page(struct gspca_dev *gspca_dev,
460 const __u8 *page, int len) 453 const __u8 *page, int len)
461{ 454{
462 int index; 455 int index;
463 int ret = 0; 456 int ret = 0;
464 457
458 if (gspca_dev->usb_err < 0)
459 return;
465 for (index = 0; index < len; index++) { 460 for (index = 0; index < len; index++) {
466 if (page[index] == SKIP) /* skip this index */ 461 if (page[index] == SKIP) /* skip this index */
467 continue; 462 continue;
@@ -477,56 +472,47 @@ static int reg_w_page(struct gspca_dev *gspca_dev,
477 "Failed to write register to index 0x%x, " 472 "Failed to write register to index 0x%x, "
478 "value 0x%x, error %i", 473 "value 0x%x, error %i",
479 index, page[index], ret); 474 index, page[index], ret);
475 gspca_dev->usb_err = ret;
480 break; 476 break;
481 } 477 }
482 } 478 }
483 return ret;
484} 479}
485 480
486/* output a variable sequence */ 481/* output a variable sequence */
487static int reg_w_var(struct gspca_dev *gspca_dev, 482static void reg_w_var(struct gspca_dev *gspca_dev,
488 const __u8 *seq, 483 const __u8 *seq,
489 const __u8 *page3, unsigned int page3_len, 484 const __u8 *page3, unsigned int page3_len)
490 const __u8 *page4, unsigned int page4_len)
491{ 485{
492 int index, len; 486 int index, len;
493 int ret = 0;
494 487
495 for (;;) { 488 for (;;) {
496 index = *seq++; 489 index = *seq++;
497 len = *seq++; 490 len = *seq++;
498 switch (len) { 491 switch (len) {
499 case END_OF_SEQUENCE: 492 case END_OF_SEQUENCE:
500 return ret; 493 return;
501 case LOAD_PAGE4:
502 ret = reg_w_page(gspca_dev, page4, page4_len);
503 break;
504 case LOAD_PAGE3: 494 case LOAD_PAGE3:
505 ret = reg_w_page(gspca_dev, page3, page3_len); 495 reg_w_page(gspca_dev, page3, page3_len);
506 break; 496 break;
507 default: 497 default:
508 if (len > USB_BUF_SZ) { 498 if (len > USB_BUF_SZ) {
509 PDEBUG(D_ERR|D_STREAM, 499 PDEBUG(D_ERR|D_STREAM,
510 "Incorrect variable sequence"); 500 "Incorrect variable sequence");
511 return -EINVAL; 501 return;
512 } 502 }
513 while (len > 0) { 503 while (len > 0) {
514 if (len < 8) { 504 if (len < 8) {
515 ret = reg_w_buf(gspca_dev, 505 reg_w_buf(gspca_dev,
516 index, seq, len); 506 index, seq, len);
517 if (ret < 0)
518 return ret;
519 seq += len; 507 seq += len;
520 break; 508 break;
521 } 509 }
522 ret = reg_w_buf(gspca_dev, index, seq, 8); 510 reg_w_buf(gspca_dev, index, seq, 8);
523 seq += 8; 511 seq += 8;
524 index += 8; 512 index += 8;
525 len -= 8; 513 len -= 8;
526 } 514 }
527 } 515 }
528 if (ret < 0)
529 return ret;
530 } 516 }
531 /* not reached */ 517 /* not reached */
532} 518}
@@ -560,11 +546,10 @@ static int sd_config(struct gspca_dev *gspca_dev,
560} 546}
561 547
562/* This function is used by pac7302 only */ 548/* This function is used by pac7302 only */
563static int setbrightcont(struct gspca_dev *gspca_dev) 549static void setbrightcont(struct gspca_dev *gspca_dev)
564{ 550{
565 struct sd *sd = (struct sd *) gspca_dev; 551 struct sd *sd = (struct sd *) gspca_dev;
566 int i, v; 552 int i, v;
567 int ret;
568 static const __u8 max[10] = 553 static const __u8 max[10] =
569 {0x29, 0x33, 0x42, 0x5a, 0x6e, 0x80, 0x9f, 0xbb, 554 {0x29, 0x33, 0x42, 0x5a, 0x6e, 0x80, 0x9f, 0xbb,
570 0xd4, 0xec}; 555 0xd4, 0xec};
@@ -572,7 +557,7 @@ static int setbrightcont(struct gspca_dev *gspca_dev)
572 {0x35, 0x33, 0x33, 0x2f, 0x2a, 0x25, 0x1e, 0x17, 557 {0x35, 0x33, 0x33, 0x2f, 0x2a, 0x25, 0x1e, 0x17,
573 0x11, 0x0b}; 558 0x11, 0x0b};
574 559
575 ret = reg_w(gspca_dev, 0xff, 0x00); /* page 0 */ 560 reg_w(gspca_dev, 0xff, 0x00); /* page 0 */
576 for (i = 0; i < 10; i++) { 561 for (i = 0; i < 10; i++) {
577 v = max[i]; 562 v = max[i];
578 v += (sd->brightness - BRIGHTNESS_MAX) 563 v += (sd->brightness - BRIGHTNESS_MAX)
@@ -582,136 +567,121 @@ static int setbrightcont(struct gspca_dev *gspca_dev)
582 v = 0; 567 v = 0;
583 else if (v > 0xff) 568 else if (v > 0xff)
584 v = 0xff; 569 v = 0xff;
585 if (0 <= ret) 570 reg_w(gspca_dev, 0xa2 + i, v);
586 ret = reg_w(gspca_dev, 0xa2 + i, v);
587 } 571 }
588 if (0 <= ret) 572 reg_w(gspca_dev, 0xdc, 0x01);
589 ret = reg_w(gspca_dev, 0xdc, 0x01);
590 return ret;
591} 573}
592 574
593/* This function is used by pac7302 only */ 575/* This function is used by pac7302 only */
594static int setcolors(struct gspca_dev *gspca_dev) 576static void setcolors(struct gspca_dev *gspca_dev)
595{ 577{
596 struct sd *sd = (struct sd *) gspca_dev; 578 struct sd *sd = (struct sd *) gspca_dev;
597 int i, v; 579 int i, v;
598 int ret;
599 static const int a[9] = 580 static const int a[9] =
600 {217, -212, 0, -101, 170, -67, -38, -315, 355}; 581 {217, -212, 0, -101, 170, -67, -38, -315, 355};
601 static const int b[9] = 582 static const int b[9] =
602 {19, 106, 0, 19, 106, 1, 19, 106, 1}; 583 {19, 106, 0, 19, 106, 1, 19, 106, 1};
603 584
604 ret = reg_w(gspca_dev, 0xff, 0x03); /* page 3 */ 585 reg_w(gspca_dev, 0xff, 0x03); /* page 3 */
605 if (0 <= ret) 586 reg_w(gspca_dev, 0x11, 0x01);
606 ret = reg_w(gspca_dev, 0x11, 0x01); 587 reg_w(gspca_dev, 0xff, 0x00); /* page 0 */
607 if (0 <= ret)
608 ret = reg_w(gspca_dev, 0xff, 0x00); /* page 0 */
609 for (i = 0; i < 9; i++) { 588 for (i = 0; i < 9; i++) {
610 v = a[i] * sd->colors / COLOR_MAX + b[i]; 589 v = a[i] * sd->colors / COLOR_MAX + b[i];
611 if (0 <= ret) 590 reg_w(gspca_dev, 0x0f + 2 * i, (v >> 8) & 0x07);
612 ret = reg_w(gspca_dev, 0x0f + 2 * i, (v >> 8) & 0x07); 591 reg_w(gspca_dev, 0x0f + 2 * i + 1, v);
613 if (0 <= ret)
614 ret = reg_w(gspca_dev, 0x0f + 2 * i + 1, v);
615 } 592 }
616 if (0 <= ret) 593 reg_w(gspca_dev, 0xdc, 0x01);
617 ret = reg_w(gspca_dev, 0xdc, 0x01);
618 PDEBUG(D_CONF|D_STREAM, "color: %i", sd->colors); 594 PDEBUG(D_CONF|D_STREAM, "color: %i", sd->colors);
619 return ret;
620} 595}
621 596
622static int setwhitebalance(struct gspca_dev *gspca_dev) 597static void setwhitebalance(struct gspca_dev *gspca_dev)
623{ 598{
624 struct sd *sd = (struct sd *) gspca_dev; 599 struct sd *sd = (struct sd *) gspca_dev;
625 int ret;
626 600
627 ret = reg_w(gspca_dev, 0xff, 0x00); /* page 0 */ 601 reg_w(gspca_dev, 0xff, 0x00); /* page 0 */
628 if (0 <= ret) 602 reg_w(gspca_dev, 0xc6, sd->white_balance);
629 ret = reg_w(gspca_dev, 0xc6, sd->white_balance);
630 603
631 if (0 <= ret) 604 reg_w(gspca_dev, 0xdc, 0x01);
632 ret = reg_w(gspca_dev, 0xdc, 0x01);
633 PDEBUG(D_CONF|D_STREAM, "white_balance: %i", sd->white_balance); 605 PDEBUG(D_CONF|D_STREAM, "white_balance: %i", sd->white_balance);
634 return ret;
635} 606}
636 607
637static int setredbalance(struct gspca_dev *gspca_dev) 608static void setredbalance(struct gspca_dev *gspca_dev)
638{ 609{
639 struct sd *sd = (struct sd *) gspca_dev; 610 struct sd *sd = (struct sd *) gspca_dev;
640 int ret;
641 611
642 ret = reg_w(gspca_dev, 0xff, 0x00); /* page 0 */ 612 reg_w(gspca_dev, 0xff, 0x00); /* page 0 */
643 if (0 <= ret) 613 reg_w(gspca_dev, 0xc5, sd->red_balance);
644 ret = reg_w(gspca_dev, 0xc5, sd->red_balance);
645 614
646 if (0 <= ret) 615 reg_w(gspca_dev, 0xdc, 0x01);
647 ret = reg_w(gspca_dev, 0xdc, 0x01);
648 PDEBUG(D_CONF|D_STREAM, "red_balance: %i", sd->red_balance); 616 PDEBUG(D_CONF|D_STREAM, "red_balance: %i", sd->red_balance);
649 return ret;
650} 617}
651 618
652static int setbluebalance(struct gspca_dev *gspca_dev) 619static void setbluebalance(struct gspca_dev *gspca_dev)
653{ 620{
654 struct sd *sd = (struct sd *) gspca_dev; 621 struct sd *sd = (struct sd *) gspca_dev;
655 int ret;
656 622
657 ret = reg_w(gspca_dev, 0xff, 0x00); /* page 0 */ 623 reg_w(gspca_dev, 0xff, 0x00); /* page 0 */
658 if (0 <= ret) 624 reg_w(gspca_dev, 0xc7, sd->blue_balance);
659 ret = reg_w(gspca_dev, 0xc7, sd->blue_balance);
660 625
661 if (0 <= ret) 626 reg_w(gspca_dev, 0xdc, 0x01);
662 ret = reg_w(gspca_dev, 0xdc, 0x01);
663 PDEBUG(D_CONF|D_STREAM, "blue_balance: %i", sd->blue_balance); 627 PDEBUG(D_CONF|D_STREAM, "blue_balance: %i", sd->blue_balance);
664 return ret;
665} 628}
666 629
667static int setgain(struct gspca_dev *gspca_dev) 630static void setgain(struct gspca_dev *gspca_dev)
668{ 631{
669 struct sd *sd = (struct sd *) gspca_dev; 632 struct sd *sd = (struct sd *) gspca_dev;
670 int ret;
671 633
672 ret = reg_w(gspca_dev, 0xff, 0x03); /* page 3 */ 634 reg_w(gspca_dev, 0xff, 0x03); /* page 3 */
673 if (0 <= ret) 635 reg_w(gspca_dev, 0x10, sd->gain >> 3);
674 ret = reg_w(gspca_dev, 0x10, sd->gain >> 3);
675 636
676 /* load registers to sensor (Bit 0, auto clear) */ 637 /* load registers to sensor (Bit 0, auto clear) */
677 if (0 <= ret) 638 reg_w(gspca_dev, 0x11, 0x01);
678 ret = reg_w(gspca_dev, 0x11, 0x01);
679 return ret;
680} 639}
681 640
682static int setexposure(struct gspca_dev *gspca_dev) 641static void setexposure(struct gspca_dev *gspca_dev)
683{ 642{
684 struct sd *sd = (struct sd *) gspca_dev; 643 struct sd *sd = (struct sd *) gspca_dev;
685 int ret; 644 __u8 clockdiv;
686 __u8 reg; 645 __u16 exposure;
687 646
688 /* register 2 of frame 3/4 contains the clock divider configuring the 647 /* register 2 of frame 3 contains the clock divider configuring the
689 no fps according to the formula: 60 / reg. sd->exposure is the 648 no fps according to the formula: 90 / reg. sd->exposure is the
690 desired exposure time in ms. */ 649 desired exposure time in 0.5 ms. */
691 reg = 120 * sd->exposure / 1000; 650 clockdiv = (90 * sd->exposure + 1999) / 2000;
692 if (reg < 2) 651
693 reg = 2; 652 /* Note clockdiv = 3 also works, but when running at 30 fps, depending
694 else if (reg > 63) 653 on the scene being recorded, the camera switches to another
695 reg = 63; 654 quantization table for certain JPEG blocks, and we don't know how
696 655 to decompress these blocks. So we cap the framerate at 15 fps */
697 /* On the pac7302 reg2 MUST be a multiple of 3, so round it to 656 if (clockdiv < 6)
698 the nearest multiple of 3, except when between 6 and 12? */ 657 clockdiv = 6;
699 if (reg < 6 || reg > 12) 658 else if (clockdiv > 63)
700 reg = ((reg + 1) / 3) * 3; 659 clockdiv = 63;
701 ret = reg_w(gspca_dev, 0xff, 0x03); /* page 3 */ 660
702 if (0 <= ret) 661 /* reg2 MUST be a multiple of 3, except when between 6 and 12?
703 ret = reg_w(gspca_dev, 0x02, reg); 662 Always round up, otherwise we cannot get the desired frametime
663 using the partial frame time exposure control */
664 if (clockdiv < 6 || clockdiv > 12)
665 clockdiv = ((clockdiv + 2) / 3) * 3;
666
667 /* frame exposure time in ms = 1000 * clockdiv / 90 ->
668 exposure = (sd->exposure / 2) * 448 / (1000 * clockdiv / 90) */
669 exposure = (sd->exposure * 45 * 448) / (1000 * clockdiv);
670 /* 0 = use full frametime, 448 = no exposure, reverse it */
671 exposure = 448 - exposure;
672
673 reg_w(gspca_dev, 0xff, 0x03); /* page 3 */
674 reg_w(gspca_dev, 0x02, clockdiv);
675 reg_w(gspca_dev, 0x0e, exposure & 0xff);
676 reg_w(gspca_dev, 0x0f, exposure >> 8);
704 677
705 /* load registers to sensor (Bit 0, auto clear) */ 678 /* load registers to sensor (Bit 0, auto clear) */
706 if (0 <= ret) 679 reg_w(gspca_dev, 0x11, 0x01);
707 ret = reg_w(gspca_dev, 0x11, 0x01);
708 return ret;
709} 680}
710 681
711static int sethvflip(struct gspca_dev *gspca_dev) 682static void sethvflip(struct gspca_dev *gspca_dev)
712{ 683{
713 struct sd *sd = (struct sd *) gspca_dev; 684 struct sd *sd = (struct sd *) gspca_dev;
714 int ret;
715 u8 data, hflip, vflip; 685 u8 data, hflip, vflip;
716 686
717 hflip = sd->hflip; 687 hflip = sd->hflip;
@@ -721,48 +691,37 @@ static int sethvflip(struct gspca_dev *gspca_dev)
721 if (sd->flags & FL_VFLIP) 691 if (sd->flags & FL_VFLIP)
722 vflip = !vflip; 692 vflip = !vflip;
723 693
724 ret = reg_w(gspca_dev, 0xff, 0x03); /* page 3 */ 694 reg_w(gspca_dev, 0xff, 0x03); /* page 3 */
725 data = (hflip ? 0x08 : 0x00) | (vflip ? 0x04 : 0x00); 695 data = (hflip ? 0x08 : 0x00) | (vflip ? 0x04 : 0x00);
726 if (0 <= ret) 696 reg_w(gspca_dev, 0x21, data);
727 ret = reg_w(gspca_dev, 0x21, data); 697
728 /* load registers to sensor (Bit 0, auto clear) */ 698 /* load registers to sensor (Bit 0, auto clear) */
729 if (0 <= ret) 699 reg_w(gspca_dev, 0x11, 0x01);
730 ret = reg_w(gspca_dev, 0x11, 0x01);
731 return ret;
732} 700}
733 701
734/* this function is called at probe and resume time for pac7302 */ 702/* this function is called at probe and resume time for pac7302 */
735static int sd_init(struct gspca_dev *gspca_dev) 703static int sd_init(struct gspca_dev *gspca_dev)
736{ 704{
737 return reg_w_seq(gspca_dev, init_7302, sizeof(init_7302)/2); 705 reg_w_seq(gspca_dev, init_7302, sizeof(init_7302)/2);
706 return gspca_dev->usb_err;
738} 707}
739 708
740static int sd_start(struct gspca_dev *gspca_dev) 709static int sd_start(struct gspca_dev *gspca_dev)
741{ 710{
742 struct sd *sd = (struct sd *) gspca_dev; 711 struct sd *sd = (struct sd *) gspca_dev;
743 int ret = 0;
744 712
745 sd->sof_read = 0; 713 sd->sof_read = 0;
746 714
747 ret = reg_w_var(gspca_dev, start_7302, 715 reg_w_var(gspca_dev, start_7302,
748 page3_7302, sizeof(page3_7302), 716 page3_7302, sizeof(page3_7302));
749 NULL, 0); 717 setbrightcont(gspca_dev);
750 if (0 <= ret) 718 setcolors(gspca_dev);
751 ret = setbrightcont(gspca_dev); 719 setwhitebalance(gspca_dev);
752 if (0 <= ret) 720 setredbalance(gspca_dev);
753 ret = setcolors(gspca_dev); 721 setbluebalance(gspca_dev);
754 if (0 <= ret) 722 setgain(gspca_dev);
755 ret = setwhitebalance(gspca_dev); 723 setexposure(gspca_dev);
756 if (0 <= ret) 724 sethvflip(gspca_dev);
757 ret = setredbalance(gspca_dev);
758 if (0 <= ret)
759 ret = setbluebalance(gspca_dev);
760 if (0 <= ret)
761 ret = setgain(gspca_dev);
762 if (0 <= ret)
763 ret = setexposure(gspca_dev);
764 if (0 <= ret)
765 ret = sethvflip(gspca_dev);
766 725
767 /* only resolution 640x480 is supported for pac7302 */ 726 /* only resolution 640x480 is supported for pac7302 */
768 727
@@ -771,34 +730,27 @@ static int sd_start(struct gspca_dev *gspca_dev)
771 atomic_set(&sd->avg_lum, -1); 730 atomic_set(&sd->avg_lum, -1);
772 731
773 /* start stream */ 732 /* start stream */
774 if (0 <= ret) 733 reg_w(gspca_dev, 0xff, 0x01);
775 ret = reg_w(gspca_dev, 0xff, 0x01); 734 reg_w(gspca_dev, 0x78, 0x01);
776 if (0 <= ret)
777 ret = reg_w(gspca_dev, 0x78, 0x01);
778 735
779 return ret; 736 return gspca_dev->usb_err;
780} 737}
781 738
782static void sd_stopN(struct gspca_dev *gspca_dev) 739static void sd_stopN(struct gspca_dev *gspca_dev)
783{ 740{
784 int ret;
785 741
786 /* stop stream */ 742 /* stop stream */
787 ret = reg_w(gspca_dev, 0xff, 0x01); 743 reg_w(gspca_dev, 0xff, 0x01);
788 if (0 <= ret) 744 reg_w(gspca_dev, 0x78, 0x00);
789 ret = reg_w(gspca_dev, 0x78, 0x00);
790} 745}
791 746
792/* called on streamoff with alt 0 and on disconnect for pac7302 */ 747/* called on streamoff with alt 0 and on disconnect for pac7302 */
793static void sd_stop0(struct gspca_dev *gspca_dev) 748static void sd_stop0(struct gspca_dev *gspca_dev)
794{ 749{
795 int ret;
796
797 if (!gspca_dev->present) 750 if (!gspca_dev->present)
798 return; 751 return;
799 ret = reg_w(gspca_dev, 0xff, 0x01); 752 reg_w(gspca_dev, 0xff, 0x01);
800 if (0 <= ret) 753 reg_w(gspca_dev, 0x78, 0x40);
801 ret = reg_w(gspca_dev, 0x78, 0x40);
802} 754}
803 755
804/* Include pac common sof detection functions */ 756/* Include pac common sof detection functions */
@@ -808,22 +760,13 @@ static void do_autogain(struct gspca_dev *gspca_dev)
808{ 760{
809 struct sd *sd = (struct sd *) gspca_dev; 761 struct sd *sd = (struct sd *) gspca_dev;
810 int avg_lum = atomic_read(&sd->avg_lum); 762 int avg_lum = atomic_read(&sd->avg_lum);
811 int desired_lum, deadzone; 763 int desired_lum;
764 const int deadzone = 30;
812 765
813 if (avg_lum == -1) 766 if (avg_lum == -1)
814 return; 767 return;
815 768
816 desired_lum = 270 + sd->brightness * 4; 769 desired_lum = 270 + sd->brightness;
817 /* Hack hack, with the 7202 the first exposure step is
818 pretty large, so if we're about to make the first
819 exposure increase make the deadzone large to avoid
820 oscilating */
821 if (desired_lum > avg_lum && sd->gain == GAIN_DEF &&
822 sd->exposure > EXPOSURE_DEF &&
823 sd->exposure < 42)
824 deadzone = 90;
825 else
826 deadzone = 30;
827 770
828 if (sd->autogain_ignore_frames > 0) 771 if (sd->autogain_ignore_frames > 0)
829 sd->autogain_ignore_frames--; 772 sd->autogain_ignore_frames--;
@@ -947,7 +890,7 @@ static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
947 sd->brightness = val; 890 sd->brightness = val;
948 if (gspca_dev->streaming) 891 if (gspca_dev->streaming)
949 setbrightcont(gspca_dev); 892 setbrightcont(gspca_dev);
950 return 0; 893 return gspca_dev->usb_err;
951} 894}
952 895
953static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val) 896static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
@@ -966,7 +909,7 @@ static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
966 if (gspca_dev->streaming) { 909 if (gspca_dev->streaming) {
967 setbrightcont(gspca_dev); 910 setbrightcont(gspca_dev);
968 } 911 }
969 return 0; 912 return gspca_dev->usb_err;
970} 913}
971 914
972static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val) 915static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
@@ -984,7 +927,7 @@ static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
984 sd->colors = val; 927 sd->colors = val;
985 if (gspca_dev->streaming) 928 if (gspca_dev->streaming)
986 setcolors(gspca_dev); 929 setcolors(gspca_dev);
987 return 0; 930 return gspca_dev->usb_err;
988} 931}
989 932
990static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val) 933static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
@@ -998,14 +941,11 @@ static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
998static int sd_setwhitebalance(struct gspca_dev *gspca_dev, __s32 val) 941static int sd_setwhitebalance(struct gspca_dev *gspca_dev, __s32 val)
999{ 942{
1000 struct sd *sd = (struct sd *) gspca_dev; 943 struct sd *sd = (struct sd *) gspca_dev;
1001 int ret = 0;
1002 944
1003 sd->white_balance = val; 945 sd->white_balance = val;
1004 if (gspca_dev->streaming) 946 if (gspca_dev->streaming)
1005 ret = setwhitebalance(gspca_dev); 947 setwhitebalance(gspca_dev);
1006 if (0 <= ret) 948 return gspca_dev->usb_err;
1007 ret = 0;
1008 return ret;
1009} 949}
1010 950
1011static int sd_getwhitebalance(struct gspca_dev *gspca_dev, __s32 *val) 951static int sd_getwhitebalance(struct gspca_dev *gspca_dev, __s32 *val)
@@ -1019,14 +959,11 @@ static int sd_getwhitebalance(struct gspca_dev *gspca_dev, __s32 *val)
1019static int sd_setredbalance(struct gspca_dev *gspca_dev, __s32 val) 959static int sd_setredbalance(struct gspca_dev *gspca_dev, __s32 val)
1020{ 960{
1021 struct sd *sd = (struct sd *) gspca_dev; 961 struct sd *sd = (struct sd *) gspca_dev;
1022 int ret = 0;
1023 962
1024 sd->red_balance = val; 963 sd->red_balance = val;
1025 if (gspca_dev->streaming) 964 if (gspca_dev->streaming)
1026 ret = setredbalance(gspca_dev); 965 setredbalance(gspca_dev);
1027 if (0 <= ret) 966 return gspca_dev->usb_err;
1028 ret = 0;
1029 return ret;
1030} 967}
1031 968
1032static int sd_getredbalance(struct gspca_dev *gspca_dev, __s32 *val) 969static int sd_getredbalance(struct gspca_dev *gspca_dev, __s32 *val)
@@ -1040,14 +977,11 @@ static int sd_getredbalance(struct gspca_dev *gspca_dev, __s32 *val)
1040static int sd_setbluebalance(struct gspca_dev *gspca_dev, __s32 val) 977static int sd_setbluebalance(struct gspca_dev *gspca_dev, __s32 val)
1041{ 978{
1042 struct sd *sd = (struct sd *) gspca_dev; 979 struct sd *sd = (struct sd *) gspca_dev;
1043 int ret = 0;
1044 980
1045 sd->blue_balance = val; 981 sd->blue_balance = val;
1046 if (gspca_dev->streaming) 982 if (gspca_dev->streaming)
1047 ret = setbluebalance(gspca_dev); 983 setbluebalance(gspca_dev);
1048 if (0 <= ret) 984 return gspca_dev->usb_err;
1049 ret = 0;
1050 return ret;
1051} 985}
1052 986
1053static int sd_getbluebalance(struct gspca_dev *gspca_dev, __s32 *val) 987static int sd_getbluebalance(struct gspca_dev *gspca_dev, __s32 *val)
@@ -1065,7 +999,7 @@ static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val)
1065 sd->gain = val; 999 sd->gain = val;
1066 if (gspca_dev->streaming) 1000 if (gspca_dev->streaming)
1067 setgain(gspca_dev); 1001 setgain(gspca_dev);
1068 return 0; 1002 return gspca_dev->usb_err;
1069} 1003}
1070 1004
1071static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val) 1005static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val)
@@ -1083,7 +1017,7 @@ static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val)
1083 sd->exposure = val; 1017 sd->exposure = val;
1084 if (gspca_dev->streaming) 1018 if (gspca_dev->streaming)
1085 setexposure(gspca_dev); 1019 setexposure(gspca_dev);
1086 return 0; 1020 return gspca_dev->usb_err;
1087} 1021}
1088 1022
1089static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val) 1023static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val)
@@ -1114,7 +1048,7 @@ static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
1114 } 1048 }
1115 } 1049 }
1116 1050
1117 return 0; 1051 return gspca_dev->usb_err;
1118} 1052}
1119 1053
1120static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val) 1054static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val)
@@ -1132,7 +1066,7 @@ static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val)
1132 sd->hflip = val; 1066 sd->hflip = val;
1133 if (gspca_dev->streaming) 1067 if (gspca_dev->streaming)
1134 sethvflip(gspca_dev); 1068 sethvflip(gspca_dev);
1135 return 0; 1069 return gspca_dev->usb_err;
1136} 1070}
1137 1071
1138static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val) 1072static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val)
@@ -1150,7 +1084,7 @@ static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val)
1150 sd->vflip = val; 1084 sd->vflip = val;
1151 if (gspca_dev->streaming) 1085 if (gspca_dev->streaming)
1152 sethvflip(gspca_dev); 1086 sethvflip(gspca_dev);
1153 return 0; 1087 return gspca_dev->usb_err;
1154} 1088}
1155 1089
1156static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val) 1090static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val)
@@ -1165,7 +1099,6 @@ static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val)
1165static int sd_dbg_s_register(struct gspca_dev *gspca_dev, 1099static int sd_dbg_s_register(struct gspca_dev *gspca_dev,
1166 struct v4l2_dbg_register *reg) 1100 struct v4l2_dbg_register *reg)
1167{ 1101{
1168 int ret = -EINVAL;
1169 __u8 index; 1102 __u8 index;
1170 __u8 value; 1103 __u8 value;
1171 1104
@@ -1185,14 +1118,12 @@ static int sd_dbg_s_register(struct gspca_dev *gspca_dev,
1185 /* Note that there shall be no access to other page 1118 /* Note that there shall be no access to other page
1186 by any other function between the page swith and 1119 by any other function between the page swith and
1187 the actual register write */ 1120 the actual register write */
1188 ret = reg_w(gspca_dev, 0xff, 0x00); /* page 0 */ 1121 reg_w(gspca_dev, 0xff, 0x00); /* page 0 */
1189 if (0 <= ret) 1122 reg_w(gspca_dev, index, value);
1190 ret = reg_w(gspca_dev, index, value);
1191 1123
1192 if (0 <= ret) 1124 reg_w(gspca_dev, 0xdc, 0x01);
1193 ret = reg_w(gspca_dev, 0xdc, 0x01);
1194 } 1125 }
1195 return ret; 1126 return gspca_dev->usb_err;
1196} 1127}
1197 1128
1198static int sd_chip_ident(struct gspca_dev *gspca_dev, 1129static int sd_chip_ident(struct gspca_dev *gspca_dev,
@@ -1210,8 +1141,39 @@ static int sd_chip_ident(struct gspca_dev *gspca_dev,
1210} 1141}
1211#endif 1142#endif
1212 1143
1144#ifdef CONFIG_INPUT
1145static int sd_int_pkt_scan(struct gspca_dev *gspca_dev,
1146 u8 *data, /* interrupt packet data */
1147 int len) /* interrput packet length */
1148{
1149 int ret = -EINVAL;
1150 u8 data0, data1;
1151
1152 if (len == 2) {
1153 data0 = data[0];
1154 data1 = data[1];
1155 if ((data0 == 0x00 && data1 == 0x11) ||
1156 (data0 == 0x22 && data1 == 0x33) ||
1157 (data0 == 0x44 && data1 == 0x55) ||
1158 (data0 == 0x66 && data1 == 0x77) ||
1159 (data0 == 0x88 && data1 == 0x99) ||
1160 (data0 == 0xaa && data1 == 0xbb) ||
1161 (data0 == 0xcc && data1 == 0xdd) ||
1162 (data0 == 0xee && data1 == 0xff)) {
1163 input_report_key(gspca_dev->input_dev, KEY_CAMERA, 1);
1164 input_sync(gspca_dev->input_dev);
1165 input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0);
1166 input_sync(gspca_dev->input_dev);
1167 ret = 0;
1168 }
1169 }
1170
1171 return ret;
1172}
1173#endif
1174
1213/* sub-driver description for pac7302 */ 1175/* sub-driver description for pac7302 */
1214static struct sd_desc sd_desc = { 1176static const struct sd_desc sd_desc = {
1215 .name = MODULE_NAME, 1177 .name = MODULE_NAME,
1216 .ctrls = sd_ctrls, 1178 .ctrls = sd_ctrls,
1217 .nctrls = ARRAY_SIZE(sd_ctrls), 1179 .nctrls = ARRAY_SIZE(sd_ctrls),
@@ -1226,6 +1188,9 @@ static struct sd_desc sd_desc = {
1226 .set_register = sd_dbg_s_register, 1188 .set_register = sd_dbg_s_register,
1227 .get_chip_ident = sd_chip_ident, 1189 .get_chip_ident = sd_chip_ident,
1228#endif 1190#endif
1191#ifdef CONFIG_INPUT
1192 .int_pkt_scan = sd_int_pkt_scan,
1193#endif
1229}; 1194};
1230 1195
1231/* -- module initialisation -- */ 1196/* -- module initialisation -- */
diff --git a/drivers/media/video/gspca/pac7311.c b/drivers/media/video/gspca/pac7311.c
index 42cfcdfd8f4f..44fed9686729 100644
--- a/drivers/media/video/gspca/pac7311.c
+++ b/drivers/media/video/gspca/pac7311.c
@@ -51,6 +51,7 @@
51 51
52#define MODULE_NAME "pac7311" 52#define MODULE_NAME "pac7311"
53 53
54#include <linux/input.h>
54#include "gspca.h" 55#include "gspca.h"
55 56
56MODULE_AUTHOR("Thomas Kaiser thomas@kaiser-linux.li"); 57MODULE_AUTHOR("Thomas Kaiser thomas@kaiser-linux.li");
@@ -88,7 +89,7 @@ static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val);
88static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val); 89static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val);
89static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val); 90static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val);
90 91
91static struct ctrl sd_ctrls[] = { 92static const struct ctrl sd_ctrls[] = {
92/* This control is for both the 7302 and the 7311 */ 93/* This control is for both the 7302 and the 7311 */
93 { 94 {
94 { 95 {
@@ -200,7 +201,6 @@ static const struct v4l2_pix_format vga_mode[] = {
200 .priv = 0}, 201 .priv = 0},
201}; 202};
202 203
203#define LOAD_PAGE3 255
204#define LOAD_PAGE4 254 204#define LOAD_PAGE4 254
205#define END_OF_SEQUENCE 0 205#define END_OF_SEQUENCE 0
206 206
@@ -259,12 +259,14 @@ static const __u8 page4_7311[] = {
259 0x23, 0x28, 0x04, 0x11, 0x00, 0x00 259 0x23, 0x28, 0x04, 0x11, 0x00, 0x00
260}; 260};
261 261
262static int reg_w_buf(struct gspca_dev *gspca_dev, 262static void reg_w_buf(struct gspca_dev *gspca_dev,
263 __u8 index, 263 __u8 index,
264 const char *buffer, int len) 264 const char *buffer, int len)
265{ 265{
266 int ret; 266 int ret;
267 267
268 if (gspca_dev->usb_err < 0)
269 return;
268 memcpy(gspca_dev->usb_buf, buffer, len); 270 memcpy(gspca_dev->usb_buf, buffer, len);
269 ret = usb_control_msg(gspca_dev->dev, 271 ret = usb_control_msg(gspca_dev->dev,
270 usb_sndctrlpipe(gspca_dev->dev, 0), 272 usb_sndctrlpipe(gspca_dev->dev, 0),
@@ -273,20 +275,23 @@ static int reg_w_buf(struct gspca_dev *gspca_dev,
273 0, /* value */ 275 0, /* value */
274 index, gspca_dev->usb_buf, len, 276 index, gspca_dev->usb_buf, len,
275 500); 277 500);
276 if (ret < 0) 278 if (ret < 0) {
277 PDEBUG(D_ERR, "reg_w_buf(): " 279 PDEBUG(D_ERR, "reg_w_buf(): "
278 "Failed to write registers to index 0x%x, error %i", 280 "Failed to write registers to index 0x%x, error %i",
279 index, ret); 281 index, ret);
280 return ret; 282 gspca_dev->usb_err = ret;
283 }
281} 284}
282 285
283 286
284static int reg_w(struct gspca_dev *gspca_dev, 287static void reg_w(struct gspca_dev *gspca_dev,
285 __u8 index, 288 __u8 index,
286 __u8 value) 289 __u8 value)
287{ 290{
288 int ret; 291 int ret;
289 292
293 if (gspca_dev->usb_err < 0)
294 return;
290 gspca_dev->usb_buf[0] = value; 295 gspca_dev->usb_buf[0] = value;
291 ret = usb_control_msg(gspca_dev->dev, 296 ret = usb_control_msg(gspca_dev->dev,
292 usb_sndctrlpipe(gspca_dev->dev, 0), 297 usb_sndctrlpipe(gspca_dev->dev, 0),
@@ -294,32 +299,32 @@ static int reg_w(struct gspca_dev *gspca_dev,
294 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 299 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
295 0, index, gspca_dev->usb_buf, 1, 300 0, index, gspca_dev->usb_buf, 1,
296 500); 301 500);
297 if (ret < 0) 302 if (ret < 0) {
298 PDEBUG(D_ERR, "reg_w(): " 303 PDEBUG(D_ERR, "reg_w(): "
299 "Failed to write register to index 0x%x, value 0x%x, error %i", 304 "Failed to write register to index 0x%x, value 0x%x, error %i",
300 index, value, ret); 305 index, value, ret);
301 return ret; 306 gspca_dev->usb_err = ret;
307 }
302} 308}
303 309
304static int reg_w_seq(struct gspca_dev *gspca_dev, 310static void reg_w_seq(struct gspca_dev *gspca_dev,
305 const __u8 *seq, int len) 311 const __u8 *seq, int len)
306{ 312{
307 int ret = 0;
308 while (--len >= 0) { 313 while (--len >= 0) {
309 if (0 <= ret) 314 reg_w(gspca_dev, seq[0], seq[1]);
310 ret = reg_w(gspca_dev, seq[0], seq[1]);
311 seq += 2; 315 seq += 2;
312 } 316 }
313 return ret;
314} 317}
315 318
316/* load the beginning of a page */ 319/* load the beginning of a page */
317static int reg_w_page(struct gspca_dev *gspca_dev, 320static void reg_w_page(struct gspca_dev *gspca_dev,
318 const __u8 *page, int len) 321 const __u8 *page, int len)
319{ 322{
320 int index; 323 int index;
321 int ret = 0; 324 int ret = 0;
322 325
326 if (gspca_dev->usb_err < 0)
327 return;
323 for (index = 0; index < len; index++) { 328 for (index = 0; index < len; index++) {
324 if (page[index] == SKIP) /* skip this index */ 329 if (page[index] == SKIP) /* skip this index */
325 continue; 330 continue;
@@ -335,56 +340,47 @@ static int reg_w_page(struct gspca_dev *gspca_dev,
335 "Failed to write register to index 0x%x, " 340 "Failed to write register to index 0x%x, "
336 "value 0x%x, error %i", 341 "value 0x%x, error %i",
337 index, page[index], ret); 342 index, page[index], ret);
343 gspca_dev->usb_err = ret;
338 break; 344 break;
339 } 345 }
340 } 346 }
341 return ret;
342} 347}
343 348
344/* output a variable sequence */ 349/* output a variable sequence */
345static int reg_w_var(struct gspca_dev *gspca_dev, 350static void reg_w_var(struct gspca_dev *gspca_dev,
346 const __u8 *seq, 351 const __u8 *seq,
347 const __u8 *page3, unsigned int page3_len,
348 const __u8 *page4, unsigned int page4_len) 352 const __u8 *page4, unsigned int page4_len)
349{ 353{
350 int index, len; 354 int index, len;
351 int ret = 0;
352 355
353 for (;;) { 356 for (;;) {
354 index = *seq++; 357 index = *seq++;
355 len = *seq++; 358 len = *seq++;
356 switch (len) { 359 switch (len) {
357 case END_OF_SEQUENCE: 360 case END_OF_SEQUENCE:
358 return ret; 361 return;
359 case LOAD_PAGE4: 362 case LOAD_PAGE4:
360 ret = reg_w_page(gspca_dev, page4, page4_len); 363 reg_w_page(gspca_dev, page4, page4_len);
361 break;
362 case LOAD_PAGE3:
363 ret = reg_w_page(gspca_dev, page3, page3_len);
364 break; 364 break;
365 default: 365 default:
366 if (len > USB_BUF_SZ) { 366 if (len > USB_BUF_SZ) {
367 PDEBUG(D_ERR|D_STREAM, 367 PDEBUG(D_ERR|D_STREAM,
368 "Incorrect variable sequence"); 368 "Incorrect variable sequence");
369 return -EINVAL; 369 return;
370 } 370 }
371 while (len > 0) { 371 while (len > 0) {
372 if (len < 8) { 372 if (len < 8) {
373 ret = reg_w_buf(gspca_dev, 373 reg_w_buf(gspca_dev,
374 index, seq, len); 374 index, seq, len);
375 if (ret < 0)
376 return ret;
377 seq += len; 375 seq += len;
378 break; 376 break;
379 } 377 }
380 ret = reg_w_buf(gspca_dev, index, seq, 8); 378 reg_w_buf(gspca_dev, index, seq, 8);
381 seq += 8; 379 seq += 8;
382 index += 8; 380 index += 8;
383 len -= 8; 381 len -= 8;
384 } 382 }
385 } 383 }
386 if (ret < 0)
387 return ret;
388 } 384 }
389 /* not reached */ 385 /* not reached */
390} 386}
@@ -412,46 +408,36 @@ static int sd_config(struct gspca_dev *gspca_dev,
412} 408}
413 409
414/* This function is used by pac7311 only */ 410/* This function is used by pac7311 only */
415static int setcontrast(struct gspca_dev *gspca_dev) 411static void setcontrast(struct gspca_dev *gspca_dev)
416{ 412{
417 struct sd *sd = (struct sd *) gspca_dev; 413 struct sd *sd = (struct sd *) gspca_dev;
418 int ret;
419 414
420 ret = reg_w(gspca_dev, 0xff, 0x04); 415 reg_w(gspca_dev, 0xff, 0x04);
421 if (0 <= ret) 416 reg_w(gspca_dev, 0x10, sd->contrast >> 4);
422 ret = reg_w(gspca_dev, 0x10, sd->contrast >> 4);
423 /* load registers to sensor (Bit 0, auto clear) */ 417 /* load registers to sensor (Bit 0, auto clear) */
424 if (0 <= ret) 418 reg_w(gspca_dev, 0x11, 0x01);
425 ret = reg_w(gspca_dev, 0x11, 0x01);
426 return ret;
427} 419}
428 420
429static int setgain(struct gspca_dev *gspca_dev) 421static void setgain(struct gspca_dev *gspca_dev)
430{ 422{
431 struct sd *sd = (struct sd *) gspca_dev; 423 struct sd *sd = (struct sd *) gspca_dev;
432 int gain = GAIN_MAX - sd->gain; 424 int gain = GAIN_MAX - sd->gain;
433 int ret;
434 425
435 if (gain < 1) 426 if (gain < 1)
436 gain = 1; 427 gain = 1;
437 else if (gain > 245) 428 else if (gain > 245)
438 gain = 245; 429 gain = 245;
439 ret = reg_w(gspca_dev, 0xff, 0x04); /* page 4 */ 430 reg_w(gspca_dev, 0xff, 0x04); /* page 4 */
440 if (0 <= ret) 431 reg_w(gspca_dev, 0x0e, 0x00);
441 ret = reg_w(gspca_dev, 0x0e, 0x00); 432 reg_w(gspca_dev, 0x0f, gain);
442 if (0 <= ret)
443 ret = reg_w(gspca_dev, 0x0f, gain);
444 433
445 /* load registers to sensor (Bit 0, auto clear) */ 434 /* load registers to sensor (Bit 0, auto clear) */
446 if (0 <= ret) 435 reg_w(gspca_dev, 0x11, 0x01);
447 ret = reg_w(gspca_dev, 0x11, 0x01);
448 return ret;
449} 436}
450 437
451static int setexposure(struct gspca_dev *gspca_dev) 438static void setexposure(struct gspca_dev *gspca_dev)
452{ 439{
453 struct sd *sd = (struct sd *) gspca_dev; 440 struct sd *sd = (struct sd *) gspca_dev;
454 int ret;
455 __u8 reg; 441 __u8 reg;
456 442
457 /* register 2 of frame 3/4 contains the clock divider configuring the 443 /* register 2 of frame 3/4 contains the clock divider configuring the
@@ -463,94 +449,72 @@ static int setexposure(struct gspca_dev *gspca_dev)
463 else if (reg > 63) 449 else if (reg > 63)
464 reg = 63; 450 reg = 63;
465 451
466 ret = reg_w(gspca_dev, 0xff, 0x04); /* page 4 */ 452 reg_w(gspca_dev, 0xff, 0x04); /* page 4 */
467 if (0 <= ret) 453 reg_w(gspca_dev, 0x02, reg);
468 ret = reg_w(gspca_dev, 0x02, reg); 454
469 /* Page 1 register 8 must always be 0x08 except when not in 455 /* Page 1 register 8 must always be 0x08 except when not in
470 640x480 mode and Page3/4 reg 2 <= 3 then it must be 9 */ 456 640x480 mode and Page3/4 reg 2 <= 3 then it must be 9 */
471 if (0 <= ret) 457 reg_w(gspca_dev, 0xff, 0x01);
472 ret = reg_w(gspca_dev, 0xff, 0x01);
473 if (gspca_dev->cam.cam_mode[(int)gspca_dev->curr_mode].priv && 458 if (gspca_dev->cam.cam_mode[(int)gspca_dev->curr_mode].priv &&
474 reg <= 3) { 459 reg <= 3) {
475 if (0 <= ret) 460 reg_w(gspca_dev, 0x08, 0x09);
476 ret = reg_w(gspca_dev, 0x08, 0x09);
477 } else { 461 } else {
478 if (0 <= ret) 462 reg_w(gspca_dev, 0x08, 0x08);
479 ret = reg_w(gspca_dev, 0x08, 0x08);
480 } 463 }
481 464
482 /* load registers to sensor (Bit 0, auto clear) */ 465 /* load registers to sensor (Bit 0, auto clear) */
483 if (0 <= ret) 466 reg_w(gspca_dev, 0x11, 0x01);
484 ret = reg_w(gspca_dev, 0x11, 0x01);
485 return ret;
486} 467}
487 468
488static int sethvflip(struct gspca_dev *gspca_dev) 469static void sethvflip(struct gspca_dev *gspca_dev)
489{ 470{
490 struct sd *sd = (struct sd *) gspca_dev; 471 struct sd *sd = (struct sd *) gspca_dev;
491 int ret;
492 __u8 data; 472 __u8 data;
493 473
494 ret = reg_w(gspca_dev, 0xff, 0x04); /* page 4 */ 474 reg_w(gspca_dev, 0xff, 0x04); /* page 4 */
495 data = (sd->hflip ? 0x04 : 0x00) | (sd->vflip ? 0x08 : 0x00); 475 data = (sd->hflip ? 0x04 : 0x00) | (sd->vflip ? 0x08 : 0x00);
496 if (0 <= ret) 476 reg_w(gspca_dev, 0x21, data);
497 ret = reg_w(gspca_dev, 0x21, data); 477
498 /* load registers to sensor (Bit 0, auto clear) */ 478 /* load registers to sensor (Bit 0, auto clear) */
499 if (0 <= ret) 479 reg_w(gspca_dev, 0x11, 0x01);
500 ret = reg_w(gspca_dev, 0x11, 0x01);
501 return ret;
502} 480}
503 481
504/* this function is called at probe and resume time for pac7311 */ 482/* this function is called at probe and resume time for pac7311 */
505static int sd_init(struct gspca_dev *gspca_dev) 483static int sd_init(struct gspca_dev *gspca_dev)
506{ 484{
507 return reg_w_seq(gspca_dev, init_7311, sizeof(init_7311)/2); 485 reg_w_seq(gspca_dev, init_7311, sizeof(init_7311)/2);
486 return gspca_dev->usb_err;
508} 487}
509 488
510static int sd_start(struct gspca_dev *gspca_dev) 489static int sd_start(struct gspca_dev *gspca_dev)
511{ 490{
512 struct sd *sd = (struct sd *) gspca_dev; 491 struct sd *sd = (struct sd *) gspca_dev;
513 int ret;
514 492
515 sd->sof_read = 0; 493 sd->sof_read = 0;
516 494
517 ret = reg_w_var(gspca_dev, start_7311, 495 reg_w_var(gspca_dev, start_7311,
518 NULL, 0,
519 page4_7311, sizeof(page4_7311)); 496 page4_7311, sizeof(page4_7311));
520 if (0 <= ret) 497 setcontrast(gspca_dev);
521 ret = setcontrast(gspca_dev); 498 setgain(gspca_dev);
522 if (0 <= ret) 499 setexposure(gspca_dev);
523 ret = setgain(gspca_dev); 500 sethvflip(gspca_dev);
524 if (0 <= ret)
525 ret = setexposure(gspca_dev);
526 if (0 <= ret)
527 ret = sethvflip(gspca_dev);
528 501
529 /* set correct resolution */ 502 /* set correct resolution */
530 switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) { 503 switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) {
531 case 2: /* 160x120 pac7311 */ 504 case 2: /* 160x120 pac7311 */
532 if (0 <= ret) 505 reg_w(gspca_dev, 0xff, 0x01);
533 ret = reg_w(gspca_dev, 0xff, 0x01); 506 reg_w(gspca_dev, 0x17, 0x20);
534 if (0 <= ret) 507 reg_w(gspca_dev, 0x87, 0x10);
535 ret = reg_w(gspca_dev, 0x17, 0x20);
536 if (0 <= ret)
537 ret = reg_w(gspca_dev, 0x87, 0x10);
538 break; 508 break;
539 case 1: /* 320x240 pac7311 */ 509 case 1: /* 320x240 pac7311 */
540 if (0 <= ret) 510 reg_w(gspca_dev, 0xff, 0x01);
541 ret = reg_w(gspca_dev, 0xff, 0x01); 511 reg_w(gspca_dev, 0x17, 0x30);
542 if (0 <= ret) 512 reg_w(gspca_dev, 0x87, 0x11);
543 ret = reg_w(gspca_dev, 0x17, 0x30);
544 if (0 <= ret)
545 ret = reg_w(gspca_dev, 0x87, 0x11);
546 break; 513 break;
547 case 0: /* 640x480 */ 514 case 0: /* 640x480 */
548 if (0 <= ret) 515 reg_w(gspca_dev, 0xff, 0x01);
549 ret = reg_w(gspca_dev, 0xff, 0x01); 516 reg_w(gspca_dev, 0x17, 0x00);
550 if (0 <= ret) 517 reg_w(gspca_dev, 0x87, 0x12);
551 ret = reg_w(gspca_dev, 0x17, 0x00);
552 if (0 <= ret)
553 ret = reg_w(gspca_dev, 0x87, 0x12);
554 break; 518 break;
555 } 519 }
556 520
@@ -559,37 +523,24 @@ static int sd_start(struct gspca_dev *gspca_dev)
559 atomic_set(&sd->avg_lum, -1); 523 atomic_set(&sd->avg_lum, -1);
560 524
561 /* start stream */ 525 /* start stream */
562 if (0 <= ret) 526 reg_w(gspca_dev, 0xff, 0x01);
563 ret = reg_w(gspca_dev, 0xff, 0x01); 527 reg_w(gspca_dev, 0x78, 0x05);
564 if (0 <= ret)
565 ret = reg_w(gspca_dev, 0x78, 0x05);
566 528
567 return ret; 529 return gspca_dev->usb_err;
568} 530}
569 531
570static void sd_stopN(struct gspca_dev *gspca_dev) 532static void sd_stopN(struct gspca_dev *gspca_dev)
571{ 533{
572 int ret; 534 reg_w(gspca_dev, 0xff, 0x04);
573 535 reg_w(gspca_dev, 0x27, 0x80);
574 ret = reg_w(gspca_dev, 0xff, 0x04); 536 reg_w(gspca_dev, 0x28, 0xca);
575 if (0 <= ret) 537 reg_w(gspca_dev, 0x29, 0x53);
576 ret = reg_w(gspca_dev, 0x27, 0x80); 538 reg_w(gspca_dev, 0x2a, 0x0e);
577 if (0 <= ret) 539 reg_w(gspca_dev, 0xff, 0x01);
578 ret = reg_w(gspca_dev, 0x28, 0xca); 540 reg_w(gspca_dev, 0x3e, 0x20);
579 if (0 <= ret) 541 reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_6=LED */
580 ret = reg_w(gspca_dev, 0x29, 0x53); 542 reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_6=LED */
581 if (0 <= ret) 543 reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_6=LED */
582 ret = reg_w(gspca_dev, 0x2a, 0x0e);
583 if (0 <= ret)
584 ret = reg_w(gspca_dev, 0xff, 0x01);
585 if (0 <= ret)
586 ret = reg_w(gspca_dev, 0x3e, 0x20);
587 if (0 <= ret)
588 ret = reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_6=LED */
589 if (0 <= ret)
590 ret = reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_6=LED */
591 if (0 <= ret)
592 ret = reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_6=LED */
593} 544}
594 545
595/* called on streamoff with alt 0 and on disconnect for 7311 */ 546/* called on streamoff with alt 0 and on disconnect for 7311 */
@@ -734,7 +685,7 @@ static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
734 if (gspca_dev->streaming) { 685 if (gspca_dev->streaming) {
735 setcontrast(gspca_dev); 686 setcontrast(gspca_dev);
736 } 687 }
737 return 0; 688 return gspca_dev->usb_err;
738} 689}
739 690
740static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val) 691static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
@@ -752,7 +703,7 @@ static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val)
752 sd->gain = val; 703 sd->gain = val;
753 if (gspca_dev->streaming) 704 if (gspca_dev->streaming)
754 setgain(gspca_dev); 705 setgain(gspca_dev);
755 return 0; 706 return gspca_dev->usb_err;
756} 707}
757 708
758static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val) 709static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val)
@@ -770,7 +721,7 @@ static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val)
770 sd->exposure = val; 721 sd->exposure = val;
771 if (gspca_dev->streaming) 722 if (gspca_dev->streaming)
772 setexposure(gspca_dev); 723 setexposure(gspca_dev);
773 return 0; 724 return gspca_dev->usb_err;
774} 725}
775 726
776static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val) 727static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val)
@@ -801,7 +752,7 @@ static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
801 } 752 }
802 } 753 }
803 754
804 return 0; 755 return gspca_dev->usb_err;
805} 756}
806 757
807static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val) 758static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val)
@@ -819,7 +770,7 @@ static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val)
819 sd->hflip = val; 770 sd->hflip = val;
820 if (gspca_dev->streaming) 771 if (gspca_dev->streaming)
821 sethvflip(gspca_dev); 772 sethvflip(gspca_dev);
822 return 0; 773 return gspca_dev->usb_err;
823} 774}
824 775
825static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val) 776static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val)
@@ -837,7 +788,7 @@ static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val)
837 sd->vflip = val; 788 sd->vflip = val;
838 if (gspca_dev->streaming) 789 if (gspca_dev->streaming)
839 sethvflip(gspca_dev); 790 sethvflip(gspca_dev);
840 return 0; 791 return gspca_dev->usb_err;
841} 792}
842 793
843static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val) 794static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val)
@@ -848,8 +799,39 @@ static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val)
848 return 0; 799 return 0;
849} 800}
850 801
802#ifdef CONFIG_INPUT
803static int sd_int_pkt_scan(struct gspca_dev *gspca_dev,
804 u8 *data, /* interrupt packet data */
805 int len) /* interrupt packet length */
806{
807 int ret = -EINVAL;
808 u8 data0, data1;
809
810 if (len == 2) {
811 data0 = data[0];
812 data1 = data[1];
813 if ((data0 == 0x00 && data1 == 0x11) ||
814 (data0 == 0x22 && data1 == 0x33) ||
815 (data0 == 0x44 && data1 == 0x55) ||
816 (data0 == 0x66 && data1 == 0x77) ||
817 (data0 == 0x88 && data1 == 0x99) ||
818 (data0 == 0xaa && data1 == 0xbb) ||
819 (data0 == 0xcc && data1 == 0xdd) ||
820 (data0 == 0xee && data1 == 0xff)) {
821 input_report_key(gspca_dev->input_dev, KEY_CAMERA, 1);
822 input_sync(gspca_dev->input_dev);
823 input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0);
824 input_sync(gspca_dev->input_dev);
825 ret = 0;
826 }
827 }
828
829 return ret;
830}
831#endif
832
851/* sub-driver description for pac7311 */ 833/* sub-driver description for pac7311 */
852static struct sd_desc sd_desc = { 834static const struct sd_desc sd_desc = {
853 .name = MODULE_NAME, 835 .name = MODULE_NAME,
854 .ctrls = sd_ctrls, 836 .ctrls = sd_ctrls,
855 .nctrls = ARRAY_SIZE(sd_ctrls), 837 .nctrls = ARRAY_SIZE(sd_ctrls),
@@ -860,6 +842,9 @@ static struct sd_desc sd_desc = {
860 .stop0 = sd_stop0, 842 .stop0 = sd_stop0,
861 .pkt_scan = sd_pkt_scan, 843 .pkt_scan = sd_pkt_scan,
862 .dq_callback = do_autogain, 844 .dq_callback = do_autogain,
845#ifdef CONFIG_INPUT
846 .int_pkt_scan = sd_int_pkt_scan,
847#endif
863}; 848};
864 849
865/* -- module initialisation -- */ 850/* -- module initialisation -- */
diff --git a/drivers/media/video/gspca/pac_common.h b/drivers/media/video/gspca/pac_common.h
index 20f67d9b8c06..8462a7c1a338 100644
--- a/drivers/media/video/gspca/pac_common.h
+++ b/drivers/media/video/gspca/pac_common.h
@@ -24,11 +24,10 @@
24 */ 24 */
25 25
26/* We calculate the autogain at the end of the transfer of a frame, at this 26/* We calculate the autogain at the end of the transfer of a frame, at this
27 moment a frame with the old settings is being transmitted, and a frame is 27 moment a frame with the old settings is being captured and transmitted. So
28 being captured with the old settings. So if we adjust the autogain we must 28 if we adjust the gain or exposure we must ignore atleast the next frame for
29 ignore atleast the 2 next frames for the new settings to come into effect 29 the new settings to come into effect before doing any other adjustments. */
30 before doing any other adjustments */ 30#define PAC_AUTOGAIN_IGNORE_FRAMES 2
31#define PAC_AUTOGAIN_IGNORE_FRAMES 3
32 31
33static const unsigned char pac_sof_marker[5] = 32static const unsigned char pac_sof_marker[5] =
34 { 0xff, 0xff, 0x00, 0xff, 0x96 }; 33 { 0xff, 0xff, 0x00, 0xff, 0x96 };
diff --git a/drivers/media/video/gspca/sn9c2028.c b/drivers/media/video/gspca/sn9c2028.c
new file mode 100644
index 000000000000..dda5fd4aa69e
--- /dev/null
+++ b/drivers/media/video/gspca/sn9c2028.c
@@ -0,0 +1,757 @@
1/*
2 * SN9C2028 library
3 *
4 * Copyright (C) 2009 Theodore Kilgore <kilgota@auburn.edu>
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 * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21#define MODULE_NAME "sn9c2028"
22
23#include "gspca.h"
24
25MODULE_AUTHOR("Theodore Kilgore");
26MODULE_DESCRIPTION("Sonix SN9C2028 USB Camera Driver");
27MODULE_LICENSE("GPL");
28
29/* specific webcam descriptor */
30struct sd {
31 struct gspca_dev gspca_dev; /* !! must be the first item */
32 u8 sof_read;
33 u16 model;
34};
35
36struct init_command {
37 unsigned char instruction[6];
38 unsigned char to_read; /* length to read. 0 means no reply requested */
39};
40
41/* V4L2 controls supported by the driver */
42static struct ctrl sd_ctrls[] = {
43};
44
45/* How to change the resolution of any of the VGA cams is unknown */
46static const struct v4l2_pix_format vga_mode[] = {
47 {640, 480, V4L2_PIX_FMT_SN9C2028, V4L2_FIELD_NONE,
48 .bytesperline = 640,
49 .sizeimage = 640 * 480 * 3 / 4,
50 .colorspace = V4L2_COLORSPACE_SRGB,
51 .priv = 0},
52};
53
54/* No way to change the resolution of the CIF cams is known */
55static const struct v4l2_pix_format cif_mode[] = {
56 {352, 288, V4L2_PIX_FMT_SN9C2028, V4L2_FIELD_NONE,
57 .bytesperline = 352,
58 .sizeimage = 352 * 288 * 3 / 4,
59 .colorspace = V4L2_COLORSPACE_SRGB,
60 .priv = 0},
61};
62
63/* the bytes to write are in gspca_dev->usb_buf */
64static int sn9c2028_command(struct gspca_dev *gspca_dev, u8 *command)
65{
66 int rc;
67
68 PDEBUG(D_USBO, "sending command %02x%02x%02x%02x%02x%02x", command[0],
69 command[1], command[2], command[3], command[4], command[5]);
70
71 memcpy(gspca_dev->usb_buf, command, 6);
72 rc = usb_control_msg(gspca_dev->dev,
73 usb_sndctrlpipe(gspca_dev->dev, 0),
74 USB_REQ_GET_CONFIGURATION,
75 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
76 2, 0, gspca_dev->usb_buf, 6, 500);
77 if (rc < 0) {
78 PDEBUG(D_ERR, "command write [%02x] error %d",
79 gspca_dev->usb_buf[0], rc);
80 return rc;
81 }
82
83 return 0;
84}
85
86static int sn9c2028_read1(struct gspca_dev *gspca_dev)
87{
88 int rc;
89
90 rc = usb_control_msg(gspca_dev->dev,
91 usb_rcvctrlpipe(gspca_dev->dev, 0),
92 USB_REQ_GET_STATUS,
93 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
94 1, 0, gspca_dev->usb_buf, 1, 500);
95 if (rc != 1) {
96 PDEBUG(D_ERR, "read1 error %d", rc);
97 return (rc < 0) ? rc : -EIO;
98 }
99 PDEBUG(D_USBI, "read1 response %02x", gspca_dev->usb_buf[0]);
100 return gspca_dev->usb_buf[0];
101}
102
103static int sn9c2028_read4(struct gspca_dev *gspca_dev, u8 *reading)
104{
105 int rc;
106 rc = usb_control_msg(gspca_dev->dev,
107 usb_rcvctrlpipe(gspca_dev->dev, 0),
108 USB_REQ_GET_STATUS,
109 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
110 4, 0, gspca_dev->usb_buf, 4, 500);
111 if (rc != 4) {
112 PDEBUG(D_ERR, "read4 error %d", rc);
113 return (rc < 0) ? rc : -EIO;
114 }
115 memcpy(reading, gspca_dev->usb_buf, 4);
116 PDEBUG(D_USBI, "read4 response %02x%02x%02x%02x", reading[0],
117 reading[1], reading[2], reading[3]);
118 return rc;
119}
120
121static int sn9c2028_long_command(struct gspca_dev *gspca_dev, u8 *command)
122{
123 int i, status;
124 __u8 reading[4];
125
126 status = sn9c2028_command(gspca_dev, command);
127 if (status < 0)
128 return status;
129
130 status = -1;
131 for (i = 0; i < 256 && status < 2; i++)
132 status = sn9c2028_read1(gspca_dev);
133 if (status != 2) {
134 PDEBUG(D_ERR, "long command status read error %d", status);
135 return (status < 0) ? status : -EIO;
136 }
137
138 memset(reading, 0, 4);
139 status = sn9c2028_read4(gspca_dev, reading);
140 if (status < 0)
141 return status;
142
143 /* in general, the first byte of the response is the first byte of
144 * the command, or'ed with 8 */
145 status = sn9c2028_read1(gspca_dev);
146 if (status < 0)
147 return status;
148
149 return 0;
150}
151
152static int sn9c2028_short_command(struct gspca_dev *gspca_dev, u8 *command)
153{
154 int err_code;
155
156 err_code = sn9c2028_command(gspca_dev, command);
157 if (err_code < 0)
158 return err_code;
159
160 err_code = sn9c2028_read1(gspca_dev);
161 if (err_code < 0)
162 return err_code;
163
164 return 0;
165}
166
167/* this function is called at probe time */
168static int sd_config(struct gspca_dev *gspca_dev,
169 const struct usb_device_id *id)
170{
171 struct sd *sd = (struct sd *) gspca_dev;
172 struct cam *cam = &gspca_dev->cam;
173
174 PDEBUG(D_PROBE, "SN9C2028 camera detected (vid/pid 0x%04X:0x%04X)",
175 id->idVendor, id->idProduct);
176
177 sd->model = id->idProduct;
178
179 switch (sd->model) {
180 case 0x7005:
181 PDEBUG(D_PROBE, "Genius Smart 300 camera");
182 break;
183 case 0x8000:
184 PDEBUG(D_PROBE, "DC31VC");
185 break;
186 case 0x8001:
187 PDEBUG(D_PROBE, "Spy camera");
188 break;
189 case 0x8003:
190 PDEBUG(D_PROBE, "CIF camera");
191 break;
192 case 0x8008:
193 PDEBUG(D_PROBE, "Mini-Shotz ms-350 camera");
194 break;
195 case 0x800a:
196 PDEBUG(D_PROBE, "Vivitar 3350b type camera");
197 cam->input_flags = V4L2_IN_ST_VFLIP | V4L2_IN_ST_HFLIP;
198 break;
199 }
200
201 switch (sd->model) {
202 case 0x8000:
203 case 0x8001:
204 case 0x8003:
205 cam->cam_mode = cif_mode;
206 cam->nmodes = ARRAY_SIZE(cif_mode);
207 break;
208 default:
209 cam->cam_mode = vga_mode;
210 cam->nmodes = ARRAY_SIZE(vga_mode);
211 }
212 return 0;
213}
214
215/* this function is called at probe and resume time */
216static int sd_init(struct gspca_dev *gspca_dev)
217{
218 int status = -1;
219
220 sn9c2028_read1(gspca_dev);
221 sn9c2028_read1(gspca_dev);
222 status = sn9c2028_read1(gspca_dev);
223
224 return (status < 0) ? status : 0;
225}
226
227static int run_start_commands(struct gspca_dev *gspca_dev,
228 struct init_command *cam_commands, int n)
229{
230 int i, err_code = -1;
231
232 for (i = 0; i < n; i++) {
233 switch (cam_commands[i].to_read) {
234 case 4:
235 err_code = sn9c2028_long_command(gspca_dev,
236 cam_commands[i].instruction);
237 break;
238 case 1:
239 err_code = sn9c2028_short_command(gspca_dev,
240 cam_commands[i].instruction);
241 break;
242 case 0:
243 err_code = sn9c2028_command(gspca_dev,
244 cam_commands[i].instruction);
245 break;
246 }
247 if (err_code < 0)
248 return err_code;
249 }
250 return 0;
251}
252
253static int start_spy_cam(struct gspca_dev *gspca_dev)
254{
255 struct init_command spy_start_commands[] = {
256 {{0x0c, 0x01, 0x00, 0x00, 0x00, 0x00}, 4},
257 {{0x13, 0x20, 0x01, 0x00, 0x00, 0x00}, 4},
258 {{0x13, 0x21, 0x01, 0x00, 0x00, 0x00}, 4},
259 {{0x13, 0x22, 0x01, 0x04, 0x00, 0x00}, 4},
260 {{0x13, 0x23, 0x01, 0x03, 0x00, 0x00}, 4},
261 {{0x13, 0x24, 0x01, 0x00, 0x00, 0x00}, 4},
262 {{0x13, 0x25, 0x01, 0x16, 0x00, 0x00}, 4}, /* width 352 */
263 {{0x13, 0x26, 0x01, 0x12, 0x00, 0x00}, 4}, /* height 288 */
264 /* {{0x13, 0x27, 0x01, 0x28, 0x00, 0x00}, 4}, */
265 {{0x13, 0x27, 0x01, 0x68, 0x00, 0x00}, 4},
266 {{0x13, 0x28, 0x01, 0x09, 0x00, 0x00}, 4}, /* red gain ?*/
267 /* {{0x13, 0x28, 0x01, 0x00, 0x00, 0x00}, 4}, */
268 {{0x13, 0x29, 0x01, 0x00, 0x00, 0x00}, 4},
269 /* {{0x13, 0x29, 0x01, 0x0c, 0x00, 0x00}, 4}, */
270 {{0x13, 0x2a, 0x01, 0x00, 0x00, 0x00}, 4},
271 {{0x13, 0x2b, 0x01, 0x00, 0x00, 0x00}, 4},
272 /* {{0x13, 0x2c, 0x01, 0x02, 0x00, 0x00}, 4}, */
273 {{0x13, 0x2c, 0x01, 0x02, 0x00, 0x00}, 4},
274 {{0x13, 0x2d, 0x01, 0x02, 0x00, 0x00}, 4},
275 /* {{0x13, 0x2e, 0x01, 0x09, 0x00, 0x00}, 4}, */
276 {{0x13, 0x2e, 0x01, 0x09, 0x00, 0x00}, 4},
277 {{0x13, 0x2f, 0x01, 0x07, 0x00, 0x00}, 4},
278 {{0x12, 0x34, 0x01, 0x00, 0x00, 0x00}, 4},
279 {{0x13, 0x34, 0x01, 0xa1, 0x00, 0x00}, 4},
280 {{0x13, 0x35, 0x01, 0x00, 0x00, 0x00}, 4},
281 {{0x11, 0x02, 0x06, 0x00, 0x00, 0x00}, 4},
282 {{0x11, 0x03, 0x13, 0x00, 0x00, 0x00}, 4}, /*don't mess with*/
283 /*{{0x11, 0x04, 0x06, 0x00, 0x00, 0x00}, 4}, observed */
284 {{0x11, 0x04, 0x00, 0x00, 0x00, 0x00}, 4}, /* brighter */
285 /*{{0x11, 0x05, 0x65, 0x00, 0x00, 0x00}, 4}, observed */
286 {{0x11, 0x05, 0x00, 0x00, 0x00, 0x00}, 4}, /* brighter */
287 {{0x11, 0x06, 0xb1, 0x00, 0x00, 0x00}, 4}, /* observed */
288 {{0x11, 0x07, 0x00, 0x00, 0x00, 0x00}, 4},
289 /*{{0x11, 0x08, 0x06, 0x00, 0x00, 0x00}, 4}, observed */
290 {{0x11, 0x08, 0x0b, 0x00, 0x00, 0x00}, 4},
291 {{0x11, 0x09, 0x01, 0x00, 0x00, 0x00}, 4},
292 {{0x11, 0x0a, 0x01, 0x00, 0x00, 0x00}, 4},
293 {{0x11, 0x0b, 0x01, 0x00, 0x00, 0x00}, 4},
294 {{0x11, 0x0c, 0x01, 0x00, 0x00, 0x00}, 4},
295 {{0x11, 0x0d, 0x00, 0x00, 0x00, 0x00}, 4},
296 {{0x11, 0x0e, 0x04, 0x00, 0x00, 0x00}, 4},
297 /* {{0x11, 0x0f, 0x00, 0x00, 0x00, 0x00}, 4}, */
298 /* brightness or gain. 0 is default. 4 is good
299 * indoors at night with incandescent lighting */
300 {{0x11, 0x0f, 0x04, 0x00, 0x00, 0x00}, 4},
301 {{0x11, 0x10, 0x06, 0x00, 0x00, 0x00}, 4}, /*hstart or hoffs*/
302 {{0x11, 0x11, 0x06, 0x00, 0x00, 0x00}, 4},
303 {{0x11, 0x12, 0x00, 0x00, 0x00, 0x00}, 4},
304 {{0x11, 0x14, 0x02, 0x00, 0x00, 0x00}, 4},
305 {{0x11, 0x13, 0x01, 0x00, 0x00, 0x00}, 4},
306 /* {{0x1b, 0x02, 0x06, 0x00, 0x00, 0x00}, 1}, observed */
307 {{0x1b, 0x02, 0x11, 0x00, 0x00, 0x00}, 1}, /* brighter */
308 /* {{0x1b, 0x13, 0x01, 0x00, 0x00, 0x00}, 1}, observed */
309 {{0x1b, 0x13, 0x11, 0x00, 0x00, 0x00}, 1},
310 {{0x20, 0x34, 0xa1, 0x00, 0x00, 0x00}, 1}, /* compresses */
311 /* Camera should start to capture now. */
312 };
313
314 return run_start_commands(gspca_dev, spy_start_commands,
315 ARRAY_SIZE(spy_start_commands));
316}
317
318static int start_cif_cam(struct gspca_dev *gspca_dev)
319{
320 struct init_command cif_start_commands[] = {
321 {{0x0c, 0x01, 0x00, 0x00, 0x00, 0x00}, 4},
322 /* The entire sequence below seems redundant */
323 /* {{0x13, 0x20, 0x01, 0x00, 0x00, 0x00}, 4},
324 {{0x13, 0x21, 0x01, 0x00, 0x00, 0x00}, 4},
325 {{0x13, 0x22, 0x01, 0x06, 0x00, 0x00}, 4},
326 {{0x13, 0x23, 0x01, 0x02, 0x00, 0x00}, 4},
327 {{0x13, 0x24, 0x01, 0x00, 0x00, 0x00}, 4},
328 {{0x13, 0x25, 0x01, 0x16, 0x00, 0x00}, 4}, width?
329 {{0x13, 0x26, 0x01, 0x12, 0x00, 0x00}, 4}, height?
330 {{0x13, 0x27, 0x01, 0x68, 0x00, 0x00}, 4}, subsample?
331 {{0x13, 0x28, 0x01, 0x00, 0x00, 0x00}, 4},
332 {{0x13, 0x29, 0x01, 0x20, 0x00, 0x00}, 4},
333 {{0x13, 0x2a, 0x01, 0x00, 0x00, 0x00}, 4},
334 {{0x13, 0x2b, 0x01, 0x00, 0x00, 0x00}, 4},
335 {{0x13, 0x2c, 0x01, 0x02, 0x00, 0x00}, 4},
336 {{0x13, 0x2d, 0x01, 0x03, 0x00, 0x00}, 4},
337 {{0x13, 0x2e, 0x01, 0x0f, 0x00, 0x00}, 4},
338 {{0x13, 0x2f, 0x01, 0x0c, 0x00, 0x00}, 4},
339 {{0x12, 0x34, 0x01, 0x00, 0x00, 0x00}, 4},
340 {{0x13, 0x34, 0x01, 0xa1, 0x00, 0x00}, 4},
341 {{0x13, 0x35, 0x01, 0x00, 0x00, 0x00}, 4},*/
342 {{0x1b, 0x21, 0x00, 0x00, 0x00, 0x00}, 1},
343 {{0x1b, 0x17, 0x00, 0x00, 0x00, 0x00}, 1},
344 {{0x1b, 0x19, 0x00, 0x00, 0x00, 0x00}, 1},
345 {{0x1b, 0x02, 0x06, 0x00, 0x00, 0x00}, 1},
346 {{0x1b, 0x03, 0x5a, 0x00, 0x00, 0x00}, 1},
347 {{0x1b, 0x04, 0x27, 0x00, 0x00, 0x00}, 1},
348 {{0x1b, 0x05, 0x01, 0x00, 0x00, 0x00}, 1},
349 {{0x1b, 0x12, 0x14, 0x00, 0x00, 0x00}, 1},
350 {{0x1b, 0x13, 0x00, 0x00, 0x00, 0x00}, 1},
351 {{0x1b, 0x14, 0x00, 0x00, 0x00, 0x00}, 1},
352 {{0x1b, 0x15, 0x00, 0x00, 0x00, 0x00}, 1},
353 {{0x1b, 0x16, 0x00, 0x00, 0x00, 0x00}, 1},
354 {{0x1b, 0x77, 0xa2, 0x00, 0x00, 0x00}, 1},
355 {{0x1b, 0x06, 0x0f, 0x00, 0x00, 0x00}, 1},
356 {{0x1b, 0x07, 0x14, 0x00, 0x00, 0x00}, 1},
357 {{0x1b, 0x08, 0x0f, 0x00, 0x00, 0x00}, 1},
358 {{0x1b, 0x09, 0x10, 0x00, 0x00, 0x00}, 1},
359 {{0x1b, 0x0e, 0x00, 0x00, 0x00, 0x00}, 1},
360 {{0x1b, 0x0f, 0x00, 0x00, 0x00, 0x00}, 1},
361 {{0x1b, 0x12, 0x07, 0x00, 0x00, 0x00}, 1},
362 {{0x1b, 0x10, 0x1f, 0x00, 0x00, 0x00}, 1},
363 {{0x1b, 0x11, 0x01, 0x00, 0x00, 0x00}, 1},
364 {{0x13, 0x25, 0x01, 0x16, 0x00, 0x00}, 1}, /* width/8 */
365 {{0x13, 0x26, 0x01, 0x12, 0x00, 0x00}, 1}, /* height/8 */
366 /* {{0x13, 0x27, 0x01, 0x68, 0x00, 0x00}, 4}, subsample?
367 * {{0x13, 0x28, 0x01, 0x1e, 0x00, 0x00}, 4}, does nothing
368 * {{0x13, 0x27, 0x01, 0x20, 0x00, 0x00}, 4}, */
369 /* {{0x13, 0x29, 0x01, 0x22, 0x00, 0x00}, 4},
370 * causes subsampling
371 * but not a change in the resolution setting! */
372 {{0x13, 0x2c, 0x01, 0x02, 0x00, 0x00}, 4},
373 {{0x13, 0x2d, 0x01, 0x01, 0x00, 0x00}, 4},
374 {{0x13, 0x2e, 0x01, 0x08, 0x00, 0x00}, 4},
375 {{0x13, 0x2f, 0x01, 0x06, 0x00, 0x00}, 4},
376 {{0x13, 0x28, 0x01, 0x00, 0x00, 0x00}, 4},
377 {{0x1b, 0x04, 0x6d, 0x00, 0x00, 0x00}, 1},
378 {{0x1b, 0x05, 0x03, 0x00, 0x00, 0x00}, 1},
379 {{0x20, 0x36, 0x06, 0x00, 0x00, 0x00}, 1},
380 {{0x1b, 0x0e, 0x01, 0x00, 0x00, 0x00}, 1},
381 {{0x12, 0x27, 0x01, 0x00, 0x00, 0x00}, 4},
382 {{0x1b, 0x0f, 0x00, 0x00, 0x00, 0x00}, 1},
383 {{0x20, 0x36, 0x05, 0x00, 0x00, 0x00}, 1},
384 {{0x1b, 0x10, 0x0f, 0x00, 0x00, 0x00}, 1},
385 {{0x1b, 0x02, 0x06, 0x00, 0x00, 0x00}, 1},
386 {{0x1b, 0x11, 0x01, 0x00, 0x00, 0x00}, 1},
387 {{0x20, 0x34, 0xa1, 0x00, 0x00, 0x00}, 1},/* use compression */
388 /* Camera should start to capture now. */
389 };
390
391 return run_start_commands(gspca_dev, cif_start_commands,
392 ARRAY_SIZE(cif_start_commands));
393}
394
395static int start_ms350_cam(struct gspca_dev *gspca_dev)
396{
397 struct init_command ms350_start_commands[] = {
398 {{0x0c, 0x01, 0x00, 0x00, 0x00, 0x00}, 4},
399 {{0x16, 0x01, 0x00, 0x00, 0x00, 0x00}, 4},
400 {{0x13, 0x20, 0x01, 0x00, 0x00, 0x00}, 4},
401 {{0x13, 0x21, 0x01, 0x00, 0x00, 0x00}, 4},
402 {{0x13, 0x22, 0x01, 0x04, 0x00, 0x00}, 4},
403 {{0x13, 0x23, 0x01, 0x03, 0x00, 0x00}, 4},
404 {{0x13, 0x24, 0x01, 0x00, 0x00, 0x00}, 4},
405 {{0x13, 0x25, 0x01, 0x16, 0x00, 0x00}, 4},
406 {{0x13, 0x26, 0x01, 0x12, 0x00, 0x00}, 4},
407 {{0x13, 0x27, 0x01, 0x28, 0x00, 0x00}, 4},
408 {{0x13, 0x28, 0x01, 0x09, 0x00, 0x00}, 4},
409 {{0x13, 0x29, 0x01, 0x00, 0x00, 0x00}, 4},
410 {{0x13, 0x2a, 0x01, 0x00, 0x00, 0x00}, 4},
411 {{0x13, 0x2b, 0x01, 0x00, 0x00, 0x00}, 4},
412 {{0x13, 0x2c, 0x01, 0x02, 0x00, 0x00}, 4},
413 {{0x13, 0x2d, 0x01, 0x03, 0x00, 0x00}, 4},
414 {{0x13, 0x2e, 0x01, 0x0f, 0x00, 0x00}, 4},
415 {{0x13, 0x2f, 0x01, 0x0c, 0x00, 0x00}, 4},
416 {{0x12, 0x34, 0x01, 0x00, 0x00, 0x00}, 4},
417 {{0x13, 0x34, 0x01, 0xa1, 0x00, 0x00}, 4},
418 {{0x13, 0x35, 0x01, 0x00, 0x00, 0x00}, 4},
419 {{0x11, 0x00, 0x01, 0x00, 0x00, 0x00}, 4},
420 {{0x11, 0x01, 0x70, 0x00, 0x00, 0x00}, 4},
421 {{0x11, 0x02, 0x05, 0x00, 0x00, 0x00}, 4},
422 {{0x11, 0x03, 0x5d, 0x00, 0x00, 0x00}, 4},
423 {{0x11, 0x04, 0x07, 0x00, 0x00, 0x00}, 4},
424 {{0x11, 0x05, 0x25, 0x00, 0x00, 0x00}, 4},
425 {{0x11, 0x06, 0x00, 0x00, 0x00, 0x00}, 4},
426 {{0x11, 0x07, 0x09, 0x00, 0x00, 0x00}, 4},
427 {{0x11, 0x08, 0x01, 0x00, 0x00, 0x00}, 4},
428 {{0x11, 0x09, 0x00, 0x00, 0x00, 0x00}, 4},
429 {{0x11, 0x0a, 0x00, 0x00, 0x00, 0x00}, 4},
430 {{0x11, 0x0b, 0x01, 0x00, 0x00, 0x00}, 4},
431 {{0x11, 0x0c, 0x00, 0x00, 0x00, 0x00}, 4},
432 {{0x11, 0x0d, 0x0c, 0x00, 0x00, 0x00}, 4},
433 {{0x11, 0x0e, 0x01, 0x00, 0x00, 0x00}, 4},
434 {{0x11, 0x0f, 0x00, 0x00, 0x00, 0x00}, 4},
435 {{0x11, 0x10, 0x00, 0x00, 0x00, 0x00}, 4},
436 {{0x11, 0x11, 0x00, 0x00, 0x00, 0x00}, 4},
437 {{0x11, 0x12, 0x00, 0x00, 0x00, 0x00}, 4},
438 {{0x11, 0x13, 0x63, 0x00, 0x00, 0x00}, 4},
439 {{0x11, 0x15, 0x70, 0x00, 0x00, 0x00}, 4},
440 {{0x11, 0x18, 0x00, 0x00, 0x00, 0x00}, 4},
441 {{0x11, 0x11, 0x01, 0x00, 0x00, 0x00}, 4},
442 {{0x13, 0x25, 0x01, 0x28, 0x00, 0x00}, 4}, /* width */
443 {{0x13, 0x26, 0x01, 0x1e, 0x00, 0x00}, 4}, /* height */
444 {{0x13, 0x28, 0x01, 0x09, 0x00, 0x00}, 4}, /* vstart? */
445 {{0x13, 0x27, 0x01, 0x28, 0x00, 0x00}, 4},
446 {{0x13, 0x29, 0x01, 0x40, 0x00, 0x00}, 4}, /* hstart? */
447 {{0x13, 0x2c, 0x01, 0x02, 0x00, 0x00}, 4},
448 {{0x13, 0x2d, 0x01, 0x03, 0x00, 0x00}, 4},
449 {{0x13, 0x2e, 0x01, 0x0f, 0x00, 0x00}, 4},
450 {{0x13, 0x2f, 0x01, 0x0c, 0x00, 0x00}, 4},
451 {{0x1b, 0x02, 0x05, 0x00, 0x00, 0x00}, 1},
452 {{0x1b, 0x11, 0x01, 0x00, 0x00, 0x00}, 1},
453 {{0x20, 0x18, 0x00, 0x00, 0x00, 0x00}, 1},
454 {{0x1b, 0x02, 0x0a, 0x00, 0x00, 0x00}, 1},
455 {{0x1b, 0x11, 0x01, 0x00, 0x00, 0x00}, 0},
456 /* Camera should start to capture now. */
457 };
458
459 return run_start_commands(gspca_dev, ms350_start_commands,
460 ARRAY_SIZE(ms350_start_commands));
461}
462
463static int start_genius_cam(struct gspca_dev *gspca_dev)
464{
465 struct init_command genius_start_commands[] = {
466 {{0x0c, 0x01, 0x00, 0x00, 0x00, 0x00}, 4},
467 {{0x16, 0x01, 0x00, 0x00, 0x00, 0x00}, 4},
468 {{0x10, 0x00, 0x00, 0x00, 0x00, 0x00}, 4},
469 {{0x13, 0x25, 0x01, 0x16, 0x00, 0x00}, 4},
470 {{0x13, 0x26, 0x01, 0x12, 0x00, 0x00}, 4},
471 /* "preliminary" width and height settings */
472 {{0x13, 0x28, 0x01, 0x0e, 0x00, 0x00}, 4},
473 {{0x13, 0x27, 0x01, 0x20, 0x00, 0x00}, 4},
474 {{0x13, 0x29, 0x01, 0x22, 0x00, 0x00}, 4},
475 {{0x13, 0x2c, 0x01, 0x02, 0x00, 0x00}, 4},
476 {{0x13, 0x2d, 0x01, 0x02, 0x00, 0x00}, 4},
477 {{0x13, 0x2e, 0x01, 0x09, 0x00, 0x00}, 4},
478 {{0x13, 0x2f, 0x01, 0x07, 0x00, 0x00}, 4},
479 {{0x11, 0x20, 0x00, 0x00, 0x00, 0x00}, 4},
480 {{0x11, 0x21, 0x2d, 0x00, 0x00, 0x00}, 4},
481 {{0x11, 0x22, 0x00, 0x00, 0x00, 0x00}, 4},
482 {{0x11, 0x23, 0x03, 0x00, 0x00, 0x00}, 4},
483 {{0x11, 0x10, 0x00, 0x00, 0x00, 0x00}, 4},
484 {{0x11, 0x11, 0x64, 0x00, 0x00, 0x00}, 4},
485 {{0x11, 0x12, 0x00, 0x00, 0x00, 0x00}, 4},
486 {{0x11, 0x13, 0x91, 0x00, 0x00, 0x00}, 4},
487 {{0x11, 0x14, 0x01, 0x00, 0x00, 0x00}, 4},
488 {{0x11, 0x15, 0x20, 0x00, 0x00, 0x00}, 4},
489 {{0x11, 0x16, 0x01, 0x00, 0x00, 0x00}, 4},
490 {{0x11, 0x17, 0x60, 0x00, 0x00, 0x00}, 4},
491 {{0x11, 0x20, 0x00, 0x00, 0x00, 0x00}, 4},
492 {{0x11, 0x21, 0x2d, 0x00, 0x00, 0x00}, 4},
493 {{0x11, 0x22, 0x00, 0x00, 0x00, 0x00}, 4},
494 {{0x11, 0x23, 0x03, 0x00, 0x00, 0x00}, 4},
495 {{0x11, 0x25, 0x00, 0x00, 0x00, 0x00}, 4},
496 {{0x11, 0x26, 0x02, 0x00, 0x00, 0x00}, 4},
497 {{0x11, 0x27, 0x88, 0x00, 0x00, 0x00}, 4},
498 {{0x11, 0x30, 0x38, 0x00, 0x00, 0x00}, 4},
499 {{0x11, 0x31, 0x2a, 0x00, 0x00, 0x00}, 4},
500 {{0x11, 0x32, 0x2a, 0x00, 0x00, 0x00}, 4},
501 {{0x11, 0x33, 0x2a, 0x00, 0x00, 0x00}, 4},
502 {{0x11, 0x34, 0x02, 0x00, 0x00, 0x00}, 4},
503 {{0x11, 0x5b, 0x0a, 0x00, 0x00, 0x00}, 4},
504 {{0x13, 0x25, 0x01, 0x28, 0x00, 0x00}, 4}, /* real width */
505 {{0x13, 0x26, 0x01, 0x1e, 0x00, 0x00}, 4}, /* real height */
506 {{0x13, 0x28, 0x01, 0x0e, 0x00, 0x00}, 4},
507 {{0x13, 0x27, 0x01, 0x20, 0x00, 0x00}, 4},
508 {{0x13, 0x29, 0x01, 0x62, 0x00, 0x00}, 4},
509 {{0x13, 0x2c, 0x01, 0x02, 0x00, 0x00}, 4},
510 {{0x13, 0x2d, 0x01, 0x03, 0x00, 0x00}, 4},
511 {{0x13, 0x2e, 0x01, 0x0f, 0x00, 0x00}, 4},
512 {{0x13, 0x2f, 0x01, 0x0c, 0x00, 0x00}, 4},
513 {{0x11, 0x20, 0x00, 0x00, 0x00, 0x00}, 4},
514 {{0x11, 0x21, 0x2a, 0x00, 0x00, 0x00}, 4},
515 {{0x11, 0x22, 0x00, 0x00, 0x00, 0x00}, 4},
516 {{0x11, 0x23, 0x28, 0x00, 0x00, 0x00}, 4},
517 {{0x11, 0x10, 0x00, 0x00, 0x00, 0x00}, 4},
518 {{0x11, 0x11, 0x04, 0x00, 0x00, 0x00}, 4},
519 {{0x11, 0x12, 0x00, 0x00, 0x00, 0x00}, 4},
520 {{0x11, 0x13, 0x03, 0x00, 0x00, 0x00}, 4},
521 {{0x11, 0x14, 0x01, 0x00, 0x00, 0x00}, 4},
522 {{0x11, 0x15, 0xe0, 0x00, 0x00, 0x00}, 4},
523 {{0x11, 0x16, 0x02, 0x00, 0x00, 0x00}, 4},
524 {{0x11, 0x17, 0x80, 0x00, 0x00, 0x00}, 4},
525 {{0x1c, 0x20, 0x00, 0x2a, 0x00, 0x00}, 1},
526 {{0x1c, 0x20, 0x00, 0x2a, 0x00, 0x00}, 1},
527 {{0x20, 0x34, 0xa1, 0x00, 0x00, 0x00}, 0}
528 /* Camera should start to capture now. */
529 };
530
531 return run_start_commands(gspca_dev, genius_start_commands,
532 ARRAY_SIZE(genius_start_commands));
533}
534
535static int start_vivitar_cam(struct gspca_dev *gspca_dev)
536{
537 struct init_command vivitar_start_commands[] = {
538 {{0x0c, 0x01, 0x00, 0x00, 0x00, 0x00}, 4},
539 {{0x13, 0x20, 0x01, 0x00, 0x00, 0x00}, 4},
540 {{0x13, 0x21, 0x01, 0x00, 0x00, 0x00}, 4},
541 {{0x13, 0x22, 0x01, 0x01, 0x00, 0x00}, 4},
542 {{0x13, 0x23, 0x01, 0x01, 0x00, 0x00}, 4},
543 {{0x13, 0x24, 0x01, 0x00, 0x00, 0x00}, 4},
544 {{0x13, 0x25, 0x01, 0x28, 0x00, 0x00}, 4},
545 {{0x13, 0x26, 0x01, 0x1e, 0x00, 0x00}, 4},
546 {{0x13, 0x27, 0x01, 0x20, 0x00, 0x00}, 4},
547 {{0x13, 0x28, 0x01, 0x0a, 0x00, 0x00}, 4},
548 /*
549 * Above is changed from OEM 0x0b. Fixes Bayer tiling.
550 * Presumably gives a vertical shift of one row.
551 */
552 {{0x13, 0x29, 0x01, 0x20, 0x00, 0x00}, 4},
553 /* Above seems to do horizontal shift. */
554 {{0x13, 0x2a, 0x01, 0x00, 0x00, 0x00}, 4},
555 {{0x13, 0x2b, 0x01, 0x00, 0x00, 0x00}, 4},
556 {{0x13, 0x2c, 0x01, 0x02, 0x00, 0x00}, 4},
557 {{0x13, 0x2d, 0x01, 0x03, 0x00, 0x00}, 4},
558 {{0x13, 0x2e, 0x01, 0x0f, 0x00, 0x00}, 4},
559 {{0x13, 0x2f, 0x01, 0x0c, 0x00, 0x00}, 4},
560 /* Above three commands seem to relate to brightness. */
561 {{0x12, 0x34, 0x01, 0x00, 0x00, 0x00}, 4},
562 {{0x13, 0x34, 0x01, 0xa1, 0x00, 0x00}, 4},
563 {{0x13, 0x35, 0x01, 0x00, 0x00, 0x00}, 4},
564 {{0x1b, 0x12, 0x80, 0x00, 0x00, 0x00}, 1},
565 {{0x1b, 0x01, 0x77, 0x00, 0x00, 0x00}, 1},
566 {{0x1b, 0x02, 0x3a, 0x00, 0x00, 0x00}, 1},
567 {{0x1b, 0x12, 0x78, 0x00, 0x00, 0x00}, 1},
568 {{0x1b, 0x13, 0x00, 0x00, 0x00, 0x00}, 1},
569 {{0x1b, 0x14, 0x80, 0x00, 0x00, 0x00}, 1},
570 {{0x1b, 0x15, 0x34, 0x00, 0x00, 0x00}, 1},
571 {{0x1b, 0x1b, 0x04, 0x00, 0x00, 0x00}, 1},
572 {{0x1b, 0x20, 0x44, 0x00, 0x00, 0x00}, 1},
573 {{0x1b, 0x23, 0xee, 0x00, 0x00, 0x00}, 1},
574 {{0x1b, 0x26, 0xa0, 0x00, 0x00, 0x00}, 1},
575 {{0x1b, 0x27, 0x9a, 0x00, 0x00, 0x00}, 1},
576 {{0x1b, 0x28, 0xa0, 0x00, 0x00, 0x00}, 1},
577 {{0x1b, 0x29, 0x30, 0x00, 0x00, 0x00}, 1},
578 {{0x1b, 0x2a, 0x80, 0x00, 0x00, 0x00}, 1},
579 {{0x1b, 0x2b, 0x00, 0x00, 0x00, 0x00}, 1},
580 {{0x1b, 0x2f, 0x3d, 0x00, 0x00, 0x00}, 1},
581 {{0x1b, 0x30, 0x24, 0x00, 0x00, 0x00}, 1},
582 {{0x1b, 0x32, 0x86, 0x00, 0x00, 0x00}, 1},
583 {{0x1b, 0x60, 0xa9, 0x00, 0x00, 0x00}, 1},
584 {{0x1b, 0x61, 0x42, 0x00, 0x00, 0x00}, 1},
585 {{0x1b, 0x65, 0x00, 0x00, 0x00, 0x00}, 1},
586 {{0x1b, 0x69, 0x38, 0x00, 0x00, 0x00}, 1},
587 {{0x1b, 0x6f, 0x88, 0x00, 0x00, 0x00}, 1},
588 {{0x1b, 0x70, 0x0b, 0x00, 0x00, 0x00}, 1},
589 {{0x1b, 0x71, 0x00, 0x00, 0x00, 0x00}, 1},
590 {{0x1b, 0x74, 0x21, 0x00, 0x00, 0x00}, 1},
591 {{0x1b, 0x75, 0x86, 0x00, 0x00, 0x00}, 1},
592 {{0x1b, 0x76, 0x00, 0x00, 0x00, 0x00}, 1},
593 {{0x1b, 0x7d, 0xf3, 0x00, 0x00, 0x00}, 1},
594 {{0x1b, 0x17, 0x1c, 0x00, 0x00, 0x00}, 1},
595 {{0x1b, 0x18, 0xc0, 0x00, 0x00, 0x00}, 1},
596 {{0x1b, 0x19, 0x05, 0x00, 0x00, 0x00}, 1},
597 {{0x1b, 0x1a, 0xf6, 0x00, 0x00, 0x00}, 1},
598 /* {{0x13, 0x25, 0x01, 0x28, 0x00, 0x00}, 4},
599 {{0x13, 0x26, 0x01, 0x1e, 0x00, 0x00}, 4},
600 {{0x13, 0x28, 0x01, 0x0b, 0x00, 0x00}, 4}, */
601 {{0x20, 0x36, 0x06, 0x00, 0x00, 0x00}, 1},
602 {{0x1b, 0x10, 0x26, 0x00, 0x00, 0x00}, 1},
603 {{0x12, 0x27, 0x01, 0x00, 0x00, 0x00}, 4},
604 {{0x1b, 0x76, 0x03, 0x00, 0x00, 0x00}, 1},
605 {{0x20, 0x36, 0x05, 0x00, 0x00, 0x00}, 1},
606 {{0x1b, 0x00, 0x3f, 0x00, 0x00, 0x00}, 1},
607 /* Above is brightness; OEM driver setting is 0x10 */
608 {{0x12, 0x27, 0x01, 0x00, 0x00, 0x00}, 4},
609 {{0x20, 0x29, 0x30, 0x00, 0x00, 0x00}, 1},
610 {{0x20, 0x34, 0xa1, 0x00, 0x00, 0x00}, 1}
611 };
612
613 return run_start_commands(gspca_dev, vivitar_start_commands,
614 ARRAY_SIZE(vivitar_start_commands));
615}
616
617static int sd_start(struct gspca_dev *gspca_dev)
618{
619 struct sd *sd = (struct sd *) gspca_dev;
620 int err_code;
621
622 sd->sof_read = 0;
623
624 switch (sd->model) {
625 case 0x7005:
626 err_code = start_genius_cam(gspca_dev);
627 break;
628 case 0x8001:
629 err_code = start_spy_cam(gspca_dev);
630 break;
631 case 0x8003:
632 err_code = start_cif_cam(gspca_dev);
633 break;
634 case 0x8008:
635 err_code = start_ms350_cam(gspca_dev);
636 break;
637 case 0x800a:
638 err_code = start_vivitar_cam(gspca_dev);
639 break;
640 default:
641 PDEBUG(D_ERR, "Starting unknown camera, please report this");
642 return -ENXIO;
643 }
644
645 return err_code;
646}
647
648static void sd_stopN(struct gspca_dev *gspca_dev)
649{
650 int result;
651 __u8 data[6];
652
653 result = sn9c2028_read1(gspca_dev);
654 if (result < 0)
655 PDEBUG(D_ERR, "Camera Stop read failed");
656
657 memset(data, 0, 6);
658 data[0] = 0x14;
659 result = sn9c2028_command(gspca_dev, data);
660 if (result < 0)
661 PDEBUG(D_ERR, "Camera Stop command failed");
662}
663
664/* Include sn9c2028 sof detection functions */
665#include "sn9c2028.h"
666
667static void sd_pkt_scan(struct gspca_dev *gspca_dev,
668 __u8 *data, /* isoc packet */
669 int len) /* iso packet length */
670{
671 unsigned char *sof;
672
673 sof = sn9c2028_find_sof(gspca_dev, data, len);
674 if (sof) {
675 int n;
676
677 /* finish decoding current frame */
678 n = sof - data;
679 if (n > sizeof sn9c2028_sof_marker)
680 n -= sizeof sn9c2028_sof_marker;
681 else
682 n = 0;
683 gspca_frame_add(gspca_dev, LAST_PACKET, data, n);
684 /* Start next frame. */
685 gspca_frame_add(gspca_dev, FIRST_PACKET,
686 sn9c2028_sof_marker, sizeof sn9c2028_sof_marker);
687 len -= sof - data;
688 data = sof;
689 }
690 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
691}
692
693/* sub-driver description */
694static const struct sd_desc sd_desc = {
695 .name = MODULE_NAME,
696 .ctrls = sd_ctrls,
697 .nctrls = ARRAY_SIZE(sd_ctrls),
698 .config = sd_config,
699 .init = sd_init,
700 .start = sd_start,
701 .stopN = sd_stopN,
702 .pkt_scan = sd_pkt_scan,
703};
704
705/* -- module initialisation -- */
706static const __devinitdata struct usb_device_id device_table[] = {
707 {USB_DEVICE(0x0458, 0x7005)}, /* Genius Smart 300, version 2 */
708 /* The Genius Smart is untested. I can't find an owner ! */
709 /* {USB_DEVICE(0x0c45, 0x8000)}, DC31VC, Don't know this camera */
710 {USB_DEVICE(0x0c45, 0x8001)}, /* Wild Planet digital spy cam */
711 {USB_DEVICE(0x0c45, 0x8003)}, /* Several small CIF cameras */
712 /* {USB_DEVICE(0x0c45, 0x8006)}, Unknown VGA camera */
713 {USB_DEVICE(0x0c45, 0x8008)}, /* Mini-Shotz ms-350 */
714 {USB_DEVICE(0x0c45, 0x800a)}, /* Vivicam 3350B */
715 {}
716};
717MODULE_DEVICE_TABLE(usb, device_table);
718
719/* -- device connect -- */
720static int sd_probe(struct usb_interface *intf,
721 const struct usb_device_id *id)
722{
723 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
724 THIS_MODULE);
725}
726
727static struct usb_driver sd_driver = {
728 .name = MODULE_NAME,
729 .id_table = device_table,
730 .probe = sd_probe,
731 .disconnect = gspca_disconnect,
732#ifdef CONFIG_PM
733 .suspend = gspca_suspend,
734 .resume = gspca_resume,
735#endif
736};
737
738/* -- module insert / remove -- */
739static int __init sd_mod_init(void)
740{
741 int ret;
742
743 ret = usb_register(&sd_driver);
744 if (ret < 0)
745 return ret;
746 PDEBUG(D_PROBE, "registered");
747 return 0;
748}
749
750static void __exit sd_mod_exit(void)
751{
752 usb_deregister(&sd_driver);
753 PDEBUG(D_PROBE, "deregistered");
754}
755
756module_init(sd_mod_init);
757module_exit(sd_mod_exit);
diff --git a/drivers/media/video/gspca/sn9c2028.h b/drivers/media/video/gspca/sn9c2028.h
new file mode 100644
index 000000000000..8fd1d3e05665
--- /dev/null
+++ b/drivers/media/video/gspca/sn9c2028.h
@@ -0,0 +1,51 @@
1/*
2 * SN9C2028 common functions
3 *
4 * Copyright (C) 2009 Theodore Kilgore <kilgota@auburn,edu>
5 *
6 * Based closely upon the file gspca/pac_common.h
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 *
22 */
23
24static const unsigned char sn9c2028_sof_marker[5] =
25 { 0xff, 0xff, 0x00, 0xc4, 0xc4 };
26
27static unsigned char *sn9c2028_find_sof(struct gspca_dev *gspca_dev,
28 unsigned char *m, int len)
29{
30 struct sd *sd = (struct sd *) gspca_dev;
31 int i;
32
33 /* Search for the SOF marker (fixed part) in the header */
34 for (i = 0; i < len; i++) {
35 if (m[i] == sn9c2028_sof_marker[sd->sof_read]) {
36 sd->sof_read++;
37 if (sd->sof_read == sizeof(sn9c2028_sof_marker)) {
38 PDEBUG(D_FRAM,
39 "SOF found, bytes to analyze: %u."
40 " Frame starts at byte #%u",
41 len, i + 1);
42 sd->sof_read = 0;
43 return m + i + 1;
44 }
45 } else {
46 sd->sof_read = 0;
47 }
48 }
49
50 return NULL;
51}
diff --git a/drivers/media/video/gspca/sn9c20x.c b/drivers/media/video/gspca/sn9c20x.c
index 0ca1c06652b1..4a1bc08f82b9 100644
--- a/drivers/media/video/gspca/sn9c20x.c
+++ b/drivers/media/video/gspca/sn9c20x.c
@@ -129,7 +129,7 @@ static int sd_getexposure(struct gspca_dev *gspca_dev, s32 *val);
129static int sd_setautoexposure(struct gspca_dev *gspca_dev, s32 val); 129static int sd_setautoexposure(struct gspca_dev *gspca_dev, s32 val);
130static int sd_getautoexposure(struct gspca_dev *gspca_dev, s32 *val); 130static int sd_getautoexposure(struct gspca_dev *gspca_dev, s32 *val);
131 131
132static struct ctrl sd_ctrls[] = { 132static const struct ctrl sd_ctrls[] = {
133 { 133 {
134#define BRIGHTNESS_IDX 0 134#define BRIGHTNESS_IDX 0
135 { 135 {
@@ -1506,36 +1506,36 @@ static int set_cmatrix(struct gspca_dev *gspca_dev)
1506 struct sd *sd = (struct sd *) gspca_dev; 1506 struct sd *sd = (struct sd *) gspca_dev;
1507 s32 hue_coord, hue_index = 180 + sd->hue; 1507 s32 hue_coord, hue_index = 180 + sd->hue;
1508 u8 cmatrix[21]; 1508 u8 cmatrix[21];
1509 memset(cmatrix, 0, 21);
1510 1509
1510 memset(cmatrix, 0, sizeof cmatrix);
1511 cmatrix[2] = (sd->contrast * 0x25 / 0x100) + 0x26; 1511 cmatrix[2] = (sd->contrast * 0x25 / 0x100) + 0x26;
1512 cmatrix[0] = 0x13 + (cmatrix[2] - 0x26) * 0x13 / 0x25; 1512 cmatrix[0] = 0x13 + (cmatrix[2] - 0x26) * 0x13 / 0x25;
1513 cmatrix[4] = 0x07 + (cmatrix[2] - 0x26) * 0x07 / 0x25; 1513 cmatrix[4] = 0x07 + (cmatrix[2] - 0x26) * 0x07 / 0x25;
1514 cmatrix[18] = sd->brightness - 0x80; 1514 cmatrix[18] = sd->brightness - 0x80;
1515 1515
1516 hue_coord = (hsv_red_x[hue_index] * sd->saturation) >> 8; 1516 hue_coord = (hsv_red_x[hue_index] * sd->saturation) >> 8;
1517 cmatrix[6] = (unsigned char)(hue_coord & 0xff); 1517 cmatrix[6] = hue_coord;
1518 cmatrix[7] = (unsigned char)((hue_coord >> 8) & 0x0f); 1518 cmatrix[7] = (hue_coord >> 8) & 0x0f;
1519 1519
1520 hue_coord = (hsv_red_y[hue_index] * sd->saturation) >> 8; 1520 hue_coord = (hsv_red_y[hue_index] * sd->saturation) >> 8;
1521 cmatrix[8] = (unsigned char)(hue_coord & 0xff); 1521 cmatrix[8] = hue_coord;
1522 cmatrix[9] = (unsigned char)((hue_coord >> 8) & 0x0f); 1522 cmatrix[9] = (hue_coord >> 8) & 0x0f;
1523 1523
1524 hue_coord = (hsv_green_x[hue_index] * sd->saturation) >> 8; 1524 hue_coord = (hsv_green_x[hue_index] * sd->saturation) >> 8;
1525 cmatrix[10] = (unsigned char)(hue_coord & 0xff); 1525 cmatrix[10] = hue_coord;
1526 cmatrix[11] = (unsigned char)((hue_coord >> 8) & 0x0f); 1526 cmatrix[11] = (hue_coord >> 8) & 0x0f;
1527 1527
1528 hue_coord = (hsv_green_y[hue_index] * sd->saturation) >> 8; 1528 hue_coord = (hsv_green_y[hue_index] * sd->saturation) >> 8;
1529 cmatrix[12] = (unsigned char)(hue_coord & 0xff); 1529 cmatrix[12] = hue_coord;
1530 cmatrix[13] = (unsigned char)((hue_coord >> 8) & 0x0f); 1530 cmatrix[13] = (hue_coord >> 8) & 0x0f;
1531 1531
1532 hue_coord = (hsv_blue_x[hue_index] * sd->saturation) >> 8; 1532 hue_coord = (hsv_blue_x[hue_index] * sd->saturation) >> 8;
1533 cmatrix[14] = (unsigned char)(hue_coord & 0xff); 1533 cmatrix[14] = hue_coord;
1534 cmatrix[15] = (unsigned char)((hue_coord >> 8) & 0x0f); 1534 cmatrix[15] = (hue_coord >> 8) & 0x0f;
1535 1535
1536 hue_coord = (hsv_blue_y[hue_index] * sd->saturation) >> 8; 1536 hue_coord = (hsv_blue_y[hue_index] * sd->saturation) >> 8;
1537 cmatrix[16] = (unsigned char)(hue_coord & 0xff); 1537 cmatrix[16] = hue_coord;
1538 cmatrix[17] = (unsigned char)((hue_coord >> 8) & 0x0f); 1538 cmatrix[17] = (hue_coord >> 8) & 0x0f;
1539 1539
1540 return reg_w(gspca_dev, 0x10e1, cmatrix, 21); 1540 return reg_w(gspca_dev, 0x10e1, cmatrix, 21);
1541} 1541}
@@ -2015,6 +2015,7 @@ static int sd_config(struct gspca_dev *gspca_dev,
2015 default: 2015 default:
2016 cam->cam_mode = vga_mode; 2016 cam->cam_mode = vga_mode;
2017 cam->nmodes = ARRAY_SIZE(vga_mode); 2017 cam->nmodes = ARRAY_SIZE(vga_mode);
2018 break;
2018 } 2019 }
2019 2020
2020 sd->old_step = 0; 2021 sd->old_step = 0;
@@ -2319,7 +2320,7 @@ static void do_autogain(struct gspca_dev *gspca_dev, u16 avg_lum)
2319 } 2320 }
2320 } 2321 }
2321 if (avg_lum > MAX_AVG_LUM) { 2322 if (avg_lum > MAX_AVG_LUM) {
2322 if (sd->gain >= 1) { 2323 if (sd->gain > 0) {
2323 sd->gain--; 2324 sd->gain--;
2324 set_gain(gspca_dev); 2325 set_gain(gspca_dev);
2325 } 2326 }
@@ -2347,7 +2348,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
2347{ 2348{
2348 struct sd *sd = (struct sd *) gspca_dev; 2349 struct sd *sd = (struct sd *) gspca_dev;
2349 int avg_lum; 2350 int avg_lum;
2350 static unsigned char frame_header[] = 2351 static u8 frame_header[] =
2351 {0xff, 0xff, 0x00, 0xc4, 0xc4, 0x96}; 2352 {0xff, 0xff, 0x00, 0xc4, 0xc4, 0x96};
2352 if (len == 64 && memcmp(data, frame_header, 6) == 0) { 2353 if (len == 64 && memcmp(data, frame_header, 6) == 0) {
2353 avg_lum = ((data[35] >> 2) & 3) | 2354 avg_lum = ((data[35] >> 2) & 3) |
diff --git a/drivers/media/video/gspca/sonixb.c b/drivers/media/video/gspca/sonixb.c
index ddff2b5ee5c2..785eeb4c2014 100644
--- a/drivers/media/video/gspca/sonixb.c
+++ b/drivers/media/video/gspca/sonixb.c
@@ -42,6 +42,7 @@ Reg Use
42 42
43#define MODULE_NAME "sonixb" 43#define MODULE_NAME "sonixb"
44 44
45#include <linux/input.h>
45#include "gspca.h" 46#include "gspca.h"
46 47
47MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>"); 48MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
@@ -53,9 +54,11 @@ struct sd {
53 struct gspca_dev gspca_dev; /* !! must be the first item */ 54 struct gspca_dev gspca_dev; /* !! must be the first item */
54 atomic_t avg_lum; 55 atomic_t avg_lum;
55 int prev_avg_lum; 56 int prev_avg_lum;
57 int exp_too_low_cnt;
58 int exp_too_high_cnt;
56 59
60 unsigned short exposure;
57 unsigned char gain; 61 unsigned char gain;
58 unsigned char exposure;
59 unsigned char brightness; 62 unsigned char brightness;
60 unsigned char autogain; 63 unsigned char autogain;
61 unsigned char autogain_ignore_frames; 64 unsigned char autogain_ignore_frames;
@@ -73,8 +76,9 @@ struct sd {
73#define SENSOR_OV7630 2 76#define SENSOR_OV7630 2
74#define SENSOR_PAS106 3 77#define SENSOR_PAS106 3
75#define SENSOR_PAS202 4 78#define SENSOR_PAS202 4
76#define SENSOR_TAS5110 5 79#define SENSOR_TAS5110C 5
77#define SENSOR_TAS5130CXX 6 80#define SENSOR_TAS5110D 6
81#define SENSOR_TAS5130CXX 7
78 __u8 reg11; 82 __u8 reg11;
79}; 83};
80 84
@@ -95,13 +99,15 @@ struct sensor_data {
95/* sensor_data flags */ 99/* sensor_data flags */
96#define F_GAIN 0x01 /* has gain */ 100#define F_GAIN 0x01 /* has gain */
97#define F_SIF 0x02 /* sif or vga */ 101#define F_SIF 0x02 /* sif or vga */
102#define F_COARSE_EXPO 0x04 /* exposure control is coarse */
98 103
99/* priv field of struct v4l2_pix_format flags (do not use low nibble!) */ 104/* priv field of struct v4l2_pix_format flags (do not use low nibble!) */
100#define MODE_RAW 0x10 /* raw bayer mode */ 105#define MODE_RAW 0x10 /* raw bayer mode */
101#define MODE_REDUCED_SIF 0x20 /* vga mode (320x240 / 160x120) on sif cam */ 106#define MODE_REDUCED_SIF 0x20 /* vga mode (320x240 / 160x120) on sif cam */
102 107
103/* ctrl_dis helper macros */ 108/* ctrl_dis helper macros */
104#define NO_EXPO ((1 << EXPOSURE_IDX) | (1 << AUTOGAIN_IDX)) 109#define NO_EXPO ((1 << EXPOSURE_IDX) | (1 << COARSE_EXPOSURE_IDX) | \
110 (1 << AUTOGAIN_IDX))
105#define NO_FREQ (1 << FREQ_IDX) 111#define NO_FREQ (1 << FREQ_IDX)
106#define NO_BRIGHTNESS (1 << BRIGHTNESS_IDX) 112#define NO_BRIGHTNESS (1 << BRIGHTNESS_IDX)
107 113
@@ -127,11 +133,10 @@ struct sensor_data {
127} 133}
128 134
129/* We calculate the autogain at the end of the transfer of a frame, at this 135/* We calculate the autogain at the end of the transfer of a frame, at this
130 moment a frame with the old settings is being transmitted, and a frame is 136 moment a frame with the old settings is being captured and transmitted. So
131 being captured with the old settings. So if we adjust the autogain we must 137 if we adjust the gain or exposure we must ignore atleast the next frame for
132 ignore atleast the 2 next frames for the new settings to come into effect 138 the new settings to come into effect before doing any other adjustments. */
133 before doing any other adjustments */ 139#define AUTOGAIN_IGNORE_FRAMES 1
134#define AUTOGAIN_IGNORE_FRAMES 3
135 140
136/* V4L2 controls supported by the driver */ 141/* V4L2 controls supported by the driver */
137static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val); 142static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
@@ -145,7 +150,7 @@ static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val);
145static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val); 150static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val);
146static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val); 151static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val);
147 152
148static struct ctrl sd_ctrls[] = { 153static const struct ctrl sd_ctrls[] = {
149#define BRIGHTNESS_IDX 0 154#define BRIGHTNESS_IDX 0
150 { 155 {
151 { 156 {
@@ -171,7 +176,7 @@ static struct ctrl sd_ctrls[] = {
171 .maximum = 255, 176 .maximum = 255,
172 .step = 1, 177 .step = 1,
173#define GAIN_DEF 127 178#define GAIN_DEF 127
174#define GAIN_KNEE 200 179#define GAIN_KNEE 230
175 .default_value = GAIN_DEF, 180 .default_value = GAIN_DEF,
176 }, 181 },
177 .set = sd_setgain, 182 .set = sd_setgain,
@@ -183,10 +188,10 @@ static struct ctrl sd_ctrls[] = {
183 .id = V4L2_CID_EXPOSURE, 188 .id = V4L2_CID_EXPOSURE,
184 .type = V4L2_CTRL_TYPE_INTEGER, 189 .type = V4L2_CTRL_TYPE_INTEGER,
185 .name = "Exposure", 190 .name = "Exposure",
186#define EXPOSURE_DEF 16 /* 32 ms / 30 fps */ 191#define EXPOSURE_DEF 66 /* 33 ms / 30 fps (except on PASXXX) */
187#define EXPOSURE_KNEE 50 /* 100 ms / 10 fps */ 192#define EXPOSURE_KNEE 200 /* 100 ms / 10 fps (except on PASXXX) */
188 .minimum = 0, 193 .minimum = 0,
189 .maximum = 255, 194 .maximum = 1023,
190 .step = 1, 195 .step = 1,
191 .default_value = EXPOSURE_DEF, 196 .default_value = EXPOSURE_DEF,
192 .flags = 0, 197 .flags = 0,
@@ -194,7 +199,23 @@ static struct ctrl sd_ctrls[] = {
194 .set = sd_setexposure, 199 .set = sd_setexposure,
195 .get = sd_getexposure, 200 .get = sd_getexposure,
196 }, 201 },
197#define AUTOGAIN_IDX 3 202#define COARSE_EXPOSURE_IDX 3
203 {
204 {
205 .id = V4L2_CID_EXPOSURE,
206 .type = V4L2_CTRL_TYPE_INTEGER,
207 .name = "Exposure",
208#define COARSE_EXPOSURE_DEF 2 /* 30 fps */
209 .minimum = 2,
210 .maximum = 15,
211 .step = 1,
212 .default_value = COARSE_EXPOSURE_DEF,
213 .flags = 0,
214 },
215 .set = sd_setexposure,
216 .get = sd_getexposure,
217 },
218#define AUTOGAIN_IDX 4
198 { 219 {
199 { 220 {
200 .id = V4L2_CID_AUTOGAIN, 221 .id = V4L2_CID_AUTOGAIN,
@@ -210,7 +231,7 @@ static struct ctrl sd_ctrls[] = {
210 .set = sd_setautogain, 231 .set = sd_setautogain,
211 .get = sd_getautogain, 232 .get = sd_getautogain,
212 }, 233 },
213#define FREQ_IDX 4 234#define FREQ_IDX 5
214 { 235 {
215 { 236 {
216 .id = V4L2_CID_POWER_LINE_FREQUENCY, 237 .id = V4L2_CID_POWER_LINE_FREQUENCY,
@@ -219,7 +240,7 @@ static struct ctrl sd_ctrls[] = {
219 .minimum = 0, 240 .minimum = 0,
220 .maximum = 2, /* 0: 0, 1: 50Hz, 2:60Hz */ 241 .maximum = 2, /* 0: 0, 1: 50Hz, 2:60Hz */
221 .step = 1, 242 .step = 1,
222#define FREQ_DEF 1 243#define FREQ_DEF 0
223 .default_value = FREQ_DEF, 244 .default_value = FREQ_DEF,
224 }, 245 },
225 .set = sd_setfreq, 246 .set = sd_setfreq,
@@ -345,7 +366,7 @@ static const __u8 initOv7630[] = {
345}; 366};
346static const __u8 initOv7630_3[] = { 367static const __u8 initOv7630_3[] = {
347 0x44, 0x44, 0x00, 0x1a, 0x20, 0x20, 0x20, 0x80, /* r01 .. r08 */ 368 0x44, 0x44, 0x00, 0x1a, 0x20, 0x20, 0x20, 0x80, /* r01 .. r08 */
348 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, /* r09 .. r10 */ 369 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* r09 .. r10 */
349 0x00, 0x02, 0x01, 0x0a, /* r11 .. r14 */ 370 0x00, 0x02, 0x01, 0x0a, /* r11 .. r14 */
350 0x28, 0x1e, /* H & V sizes r15 .. r16 */ 371 0x28, 0x1e, /* H & V sizes r15 .. r16 */
351 0x68, 0x8f, MCK_INIT1, /* r17 .. r19 */ 372 0x68, 0x8f, MCK_INIT1, /* r17 .. r19 */
@@ -387,6 +408,30 @@ static const __u8 initPas106[] = {
387 0x18, 0x10, 0x02, 0x02, 0x09, 0x07 408 0x18, 0x10, 0x02, 0x02, 0x09, 0x07
388}; 409};
389/* compression 0x86 mckinit1 0x2b */ 410/* compression 0x86 mckinit1 0x2b */
411
412/* "Known" PAS106B registers:
413 0x02 clock divider
414 0x03 Variable framerate bits 4-11
415 0x04 Var framerate bits 0-3, one must leave the 4 msb's at 0 !!
416 The variable framerate control must never be set lower then 300,
417 which sets the framerate at 90 / reg02, otherwise vsync is lost.
418 0x05 Shutter Time Line Offset, this can be used as an exposure control:
419 0 = use full frame time, 255 = no exposure at all
420 Note this may never be larger then "var-framerate control" / 2 - 2.
421 When var-framerate control is < 514, no exposure is reached at the max
422 allowed value for the framerate control value, rather then at 255.
423 0x06 Shutter Time Pixel Offset, like reg05 this influences exposure, but
424 only a very little bit, leave at 0xcd
425 0x07 offset sign bit (bit0 1 > negative offset)
426 0x08 offset
427 0x09 Blue Gain
428 0x0a Green1 Gain
429 0x0b Green2 Gain
430 0x0c Red Gain
431 0x0e Global gain
432 0x13 Write 1 to commit settings to sensor
433*/
434
390static const __u8 pas106_sensor_init[][8] = { 435static const __u8 pas106_sensor_init[][8] = {
391 /* Pixel Clock Divider 6 */ 436 /* Pixel Clock Divider 6 */
392 { 0xa1, 0x40, 0x02, 0x04, 0x00, 0x00, 0x00, 0x14 }, 437 { 0xa1, 0x40, 0x02, 0x04, 0x00, 0x00, 0x00, 0x14 },
@@ -433,37 +478,55 @@ static const __u8 initPas202[] = {
433 0x44, 0x44, 0x21, 0x30, 0x00, 0x00, 0x00, 0x80, 0x40, 0x00, 0x00, 0x00, 478 0x44, 0x44, 0x21, 0x30, 0x00, 0x00, 0x00, 0x80, 0x40, 0x00, 0x00, 0x00,
434 0x00, 0x00, 479 0x00, 0x00,
435 0x00, 0x00, 0x00, 0x06, 0x03, 0x0a, 480 0x00, 0x00, 0x00, 0x06, 0x03, 0x0a,
436 0x28, 0x1e, 0x28, 0x89, 0x20, 481 0x28, 0x1e, 0x20, 0x89, 0x20,
437 0x00, 0x00, 0x02, 0x03, 0x0f, 0x0c 482 0x00, 0x00, 0x02, 0x03, 0x0f, 0x0c
438}; 483};
484
485/* "Known" PAS202BCB registers:
486 0x02 clock divider
487 0x04 Variable framerate bits 6-11 (*)
488 0x05 Var framerate bits 0-5, one must leave the 2 msb's at 0 !!
489 0x07 Blue Gain
490 0x08 Green Gain
491 0x09 Red Gain
492 0x0b offset sign bit (bit0 1 > negative offset)
493 0x0c offset
494 0x0e Unknown image is slightly brighter when bit 0 is 0, if reg0f is 0 too,
495 leave at 1 otherwise we get a jump in our exposure control
496 0x0f Exposure 0-255, 0 = use full frame time, 255 = no exposure at all
497 0x10 Master gain 0 - 31
498 0x11 write 1 to apply changes
499 (*) The variable framerate control must never be set lower then 500
500 which sets the framerate at 30 / reg02, otherwise vsync is lost.
501*/
439static const __u8 pas202_sensor_init[][8] = { 502static const __u8 pas202_sensor_init[][8] = {
440 {0xa0, 0x40, 0x02, 0x03, 0x00, 0x00, 0x00, 0x10}, 503 /* Set the clock divider to 4 -> 30 / 4 = 7.5 fps, we would like
504 to set it lower, but for some reason the bridge starts missing
505 vsync's then */
506 {0xa0, 0x40, 0x02, 0x04, 0x00, 0x00, 0x00, 0x10},
441 {0xd0, 0x40, 0x04, 0x07, 0x34, 0x00, 0x09, 0x10}, 507 {0xd0, 0x40, 0x04, 0x07, 0x34, 0x00, 0x09, 0x10},
442 {0xd0, 0x40, 0x08, 0x01, 0x00, 0x00, 0x01, 0x10}, 508 {0xd0, 0x40, 0x08, 0x01, 0x00, 0x00, 0x01, 0x10},
443 {0xd0, 0x40, 0x0C, 0x00, 0x0C, 0x00, 0x32, 0x10}, 509 {0xd0, 0x40, 0x0C, 0x00, 0x0C, 0x01, 0x32, 0x10},
444 {0xd0, 0x40, 0x10, 0x00, 0x01, 0x00, 0x63, 0x10}, 510 {0xd0, 0x40, 0x10, 0x00, 0x01, 0x00, 0x63, 0x10},
445 {0xa0, 0x40, 0x15, 0x70, 0x01, 0x00, 0x63, 0x10}, 511 {0xa0, 0x40, 0x15, 0x70, 0x01, 0x00, 0x63, 0x10},
446 {0xa0, 0x40, 0x18, 0x00, 0x01, 0x00, 0x63, 0x10}, 512 {0xa0, 0x40, 0x18, 0x00, 0x01, 0x00, 0x63, 0x10},
447 {0xa0, 0x40, 0x11, 0x01, 0x01, 0x00, 0x63, 0x10}, 513 {0xa0, 0x40, 0x11, 0x01, 0x01, 0x00, 0x63, 0x10},
448 {0xa0, 0x40, 0x03, 0x56, 0x01, 0x00, 0x63, 0x10}, 514 {0xa0, 0x40, 0x03, 0x56, 0x01, 0x00, 0x63, 0x10},
449 {0xa0, 0x40, 0x11, 0x01, 0x01, 0x00, 0x63, 0x10}, 515 {0xa0, 0x40, 0x11, 0x01, 0x01, 0x00, 0x63, 0x10},
450 {0xb0, 0x40, 0x04, 0x07, 0x2a, 0x00, 0x63, 0x10},
451 {0xb0, 0x40, 0x0e, 0x00, 0x3d, 0x00, 0x63, 0x10},
452
453 {0xa0, 0x40, 0x11, 0x01, 0x3d, 0x00, 0x63, 0x16},
454 {0xa0, 0x40, 0x10, 0x08, 0x3d, 0x00, 0x63, 0x15},
455 {0xa0, 0x40, 0x02, 0x04, 0x3d, 0x00, 0x63, 0x16},
456 {0xa0, 0x40, 0x11, 0x01, 0x3d, 0x00, 0x63, 0x16},
457 {0xb0, 0x40, 0x0e, 0x00, 0x31, 0x00, 0x63, 0x16},
458 {0xa0, 0x40, 0x11, 0x01, 0x31, 0x00, 0x63, 0x16},
459 {0xa0, 0x40, 0x10, 0x0e, 0x31, 0x00, 0x63, 0x15},
460 {0xa0, 0x40, 0x11, 0x01, 0x31, 0x00, 0x63, 0x16},
461}; 516};
462 517
463static const __u8 initTas5110[] = { 518static const __u8 initTas5110c[] = {
464 0x44, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x11, 0x00, 0x00, 0x00, 519 0x44, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x11, 0x00, 0x00, 0x00,
465 0x00, 0x00, 520 0x00, 0x00,
466 0x00, 0x01, 0x00, 0x45, 0x09, 0x0a, 521 0x00, 0x00, 0x00, 0x45, 0x09, 0x0a,
522 0x16, 0x12, 0x60, 0x86, 0x2b,
523 0x14, 0x0a, 0x02, 0x02, 0x09, 0x07
524};
525/* Same as above, except a different hstart */
526static const __u8 initTas5110d[] = {
527 0x44, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x11, 0x00, 0x00, 0x00,
528 0x00, 0x00,
529 0x00, 0x00, 0x00, 0x41, 0x09, 0x0a,
467 0x16, 0x12, 0x60, 0x86, 0x2b, 530 0x16, 0x12, 0x60, 0x86, 0x2b,
468 0x14, 0x0a, 0x02, 0x02, 0x09, 0x07 531 0x14, 0x0a, 0x02, 0x02, 0x09, 0x07
469}; 532};
@@ -476,7 +539,7 @@ static const __u8 tas5110_sensor_init[][8] = {
476static const __u8 initTas5130[] = { 539static const __u8 initTas5130[] = {
477 0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x11, 0x00, 0x00, 0x00, 540 0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x11, 0x00, 0x00, 0x00,
478 0x00, 0x00, 541 0x00, 0x00,
479 0x00, 0x01, 0x00, 0x68, 0x0c, 0x0a, 542 0x00, 0x00, 0x00, 0x68, 0x0c, 0x0a,
480 0x28, 0x1e, 0x60, COMP, MCK_INIT, 543 0x28, 0x1e, 0x60, COMP, MCK_INIT,
481 0x18, 0x10, 0x04, 0x03, 0x11, 0x0c 544 0x18, 0x10, 0x04, 0x03, 0x11, 0x0c
482}; 545};
@@ -493,12 +556,14 @@ SENS(initHv7131, NULL, hv7131_sensor_init, NULL, NULL, 0, NO_EXPO|NO_FREQ, 0),
493SENS(initOv6650, NULL, ov6650_sensor_init, NULL, NULL, F_GAIN|F_SIF, 0, 0x60), 556SENS(initOv6650, NULL, ov6650_sensor_init, NULL, NULL, F_GAIN|F_SIF, 0, 0x60),
494SENS(initOv7630, initOv7630_3, ov7630_sensor_init, NULL, ov7630_sensor_init_3, 557SENS(initOv7630, initOv7630_3, ov7630_sensor_init, NULL, ov7630_sensor_init_3,
495 F_GAIN, 0, 0x21), 558 F_GAIN, 0, 0x21),
496SENS(initPas106, NULL, pas106_sensor_init, NULL, NULL, F_SIF, NO_EXPO|NO_FREQ, 559SENS(initPas106, NULL, pas106_sensor_init, NULL, NULL, F_GAIN|F_SIF, NO_FREQ,
497 0), 560 0),
498SENS(initPas202, initPas202, pas202_sensor_init, NULL, NULL, 0, 561SENS(initPas202, initPas202, pas202_sensor_init, NULL, NULL, F_GAIN,
499 NO_EXPO|NO_FREQ, 0), 562 NO_FREQ, 0),
500SENS(initTas5110, NULL, tas5110_sensor_init, NULL, NULL, F_GAIN|F_SIF, 563SENS(initTas5110c, NULL, tas5110_sensor_init, NULL, NULL,
501 NO_BRIGHTNESS|NO_FREQ, 0), 564 F_GAIN|F_SIF|F_COARSE_EXPO, NO_BRIGHTNESS|NO_FREQ, 0),
565SENS(initTas5110d, NULL, tas5110_sensor_init, NULL, NULL,
566 F_GAIN|F_SIF|F_COARSE_EXPO, NO_BRIGHTNESS|NO_FREQ, 0),
502SENS(initTas5130, NULL, tas5130_sensor_init, NULL, NULL, 0, NO_EXPO|NO_FREQ, 567SENS(initTas5130, NULL, tas5130_sensor_init, NULL, NULL, 0, NO_EXPO|NO_FREQ,
503 0), 568 0),
504}; 569};
@@ -587,42 +652,28 @@ static void setbrightness(struct gspca_dev *gspca_dev)
587 goto err; 652 goto err;
588 break; 653 break;
589 } 654 }
590 case SENSOR_PAS106: { 655 case SENSOR_PAS106:
591 __u8 i2c1[] =
592 {0xa1, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14};
593
594 i2c1[3] = sd->brightness >> 3;
595 i2c1[2] = 0x0e;
596 if (i2c_w(gspca_dev, i2c1) < 0)
597 goto err;
598 i2c1[3] = 0x01;
599 i2c1[2] = 0x13;
600 if (i2c_w(gspca_dev, i2c1) < 0)
601 goto err;
602 break;
603 }
604 case SENSOR_PAS202: { 656 case SENSOR_PAS202: {
605 /* __u8 i2cpexpo1[] = 657 __u8 i2cpbright[] =
606 {0xb0, 0x40, 0x04, 0x07, 0x2a, 0x00, 0x63, 0x16}; */ 658 {0xb0, 0x40, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x16};
607 __u8 i2cpexpo[] = 659 __u8 i2cpdoit[] =
608 {0xb0, 0x40, 0x0e, 0x01, 0xab, 0x00, 0x63, 0x16}; 660 {0xa0, 0x40, 0x11, 0x01, 0x00, 0x00, 0x00, 0x16};
609 __u8 i2cp202[] = 661
610 {0xa0, 0x40, 0x10, 0x0e, 0x31, 0x00, 0x63, 0x15}; 662 /* PAS106 uses reg 7 and 8 instead of b and c */
611 static __u8 i2cpdoit[] = 663 if (sd->sensor == SENSOR_PAS106) {
612 {0xa0, 0x40, 0x11, 0x01, 0x31, 0x00, 0x63, 0x16}; 664 i2cpbright[2] = 7;
613 665 i2cpdoit[2] = 0x13;
614 /* change reg 0x10 */ 666 }
615 i2cpexpo[4] = 0xff - sd->brightness; 667
616/* if(i2c_w(gspca_dev,i2cpexpo1) < 0) 668 if (sd->brightness < 127) {
617 goto err; */ 669 /* change reg 0x0b, signreg */
618/* if(i2c_w(gspca_dev,i2cpdoit) < 0) 670 i2cpbright[3] = 0x01;
619 goto err; */ 671 /* set reg 0x0c, offset */
620 if (i2c_w(gspca_dev, i2cpexpo) < 0) 672 i2cpbright[4] = 127 - sd->brightness;
621 goto err; 673 } else
622 if (i2c_w(gspca_dev, i2cpdoit) < 0) 674 i2cpbright[4] = sd->brightness - 127;
623 goto err; 675
624 i2cp202[3] = sd->brightness >> 3; 676 if (i2c_w(gspca_dev, i2cpbright) < 0)
625 if (i2c_w(gspca_dev, i2cp202) < 0)
626 goto err; 677 goto err;
627 if (i2c_w(gspca_dev, i2cpdoit) < 0) 678 if (i2c_w(gspca_dev, i2cpdoit) < 0)
628 goto err; 679 goto err;
@@ -652,7 +703,8 @@ static void setsensorgain(struct gspca_dev *gspca_dev)
652 703
653 switch (sd->sensor) { 704 switch (sd->sensor) {
654 705
655 case SENSOR_TAS5110: { 706 case SENSOR_TAS5110C:
707 case SENSOR_TAS5110D: {
656 __u8 i2c[] = 708 __u8 i2c[] =
657 {0x30, 0x11, 0x02, 0x20, 0x70, 0x00, 0x00, 0x10}; 709 {0x30, 0x11, 0x02, 0x20, 0x70, 0x00, 0x00, 0x10};
658 710
@@ -674,6 +726,37 @@ static void setsensorgain(struct gspca_dev *gspca_dev)
674 goto err; 726 goto err;
675 break; 727 break;
676 } 728 }
729 case SENSOR_PAS106:
730 case SENSOR_PAS202: {
731 __u8 i2cpgain[] =
732 {0xa0, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x15};
733 __u8 i2cpcolorgain[] =
734 {0xc0, 0x40, 0x07, 0x00, 0x00, 0x00, 0x00, 0x15};
735 __u8 i2cpdoit[] =
736 {0xa0, 0x40, 0x11, 0x01, 0x00, 0x00, 0x00, 0x16};
737
738 /* PAS106 uses different regs (and has split green gains) */
739 if (sd->sensor == SENSOR_PAS106) {
740 i2cpgain[2] = 0x0e;
741 i2cpcolorgain[0] = 0xd0;
742 i2cpcolorgain[2] = 0x09;
743 i2cpdoit[2] = 0x13;
744 }
745
746 i2cpgain[3] = sd->gain >> 3;
747 i2cpcolorgain[3] = sd->gain >> 4;
748 i2cpcolorgain[4] = sd->gain >> 4;
749 i2cpcolorgain[5] = sd->gain >> 4;
750 i2cpcolorgain[6] = sd->gain >> 4;
751
752 if (i2c_w(gspca_dev, i2cpgain) < 0)
753 goto err;
754 if (i2c_w(gspca_dev, i2cpcolorgain) < 0)
755 goto err;
756 if (i2c_w(gspca_dev, i2cpdoit) < 0)
757 goto err;
758 break;
759 }
677 } 760 }
678 return; 761 return;
679err: 762err:
@@ -684,19 +767,21 @@ static void setgain(struct gspca_dev *gspca_dev)
684{ 767{
685 struct sd *sd = (struct sd *) gspca_dev; 768 struct sd *sd = (struct sd *) gspca_dev;
686 __u8 gain; 769 __u8 gain;
687 __u8 rgb_value; 770 __u8 buf[2] = { 0, 0 };
771
772 if (sensor_data[sd->sensor].flags & F_GAIN) {
773 /* Use the sensor gain to do the actual gain */
774 setsensorgain(gspca_dev);
775 return;
776 }
688 777
689 gain = sd->gain >> 4; 778 gain = sd->gain >> 4;
690 779
691 /* red and blue gain */ 780 /* red and blue gain */
692 rgb_value = gain << 4 | gain; 781 buf[0] = gain << 4 | gain;
693 reg_w(gspca_dev, 0x10, &rgb_value, 1);
694 /* green gain */ 782 /* green gain */
695 rgb_value = gain; 783 buf[1] = gain;
696 reg_w(gspca_dev, 0x11, &rgb_value, 1); 784 reg_w(gspca_dev, 0x10, buf, 2);
697
698 if (sensor_data[sd->sensor].flags & F_GAIN)
699 setsensorgain(gspca_dev);
700} 785}
701 786
702static void setexposure(struct gspca_dev *gspca_dev) 787static void setexposure(struct gspca_dev *gspca_dev)
@@ -704,17 +789,12 @@ static void setexposure(struct gspca_dev *gspca_dev)
704 struct sd *sd = (struct sd *) gspca_dev; 789 struct sd *sd = (struct sd *) gspca_dev;
705 790
706 switch (sd->sensor) { 791 switch (sd->sensor) {
707 case SENSOR_TAS5110: { 792 case SENSOR_TAS5110C:
708 __u8 reg; 793 case SENSOR_TAS5110D: {
709
710 /* register 19's high nibble contains the sn9c10x clock divider 794 /* register 19's high nibble contains the sn9c10x clock divider
711 The high nibble configures the no fps according to the 795 The high nibble configures the no fps according to the
712 formula: 60 / high_nibble. With a maximum of 30 fps */ 796 formula: 60 / high_nibble. With a maximum of 30 fps */
713 reg = 120 * sd->exposure / 1000; 797 __u8 reg = sd->exposure;
714 if (reg < 2)
715 reg = 2;
716 else if (reg > 15)
717 reg = 15;
718 reg = (reg << 4) | 0x0b; 798 reg = (reg << 4) | 0x0b;
719 reg_w(gspca_dev, 0x19, &reg, 1); 799 reg_w(gspca_dev, 0x19, &reg, 1);
720 break; 800 break;
@@ -750,20 +830,21 @@ static void setexposure(struct gspca_dev *gspca_dev)
750 } else 830 } else
751 reg10_max = 0x41; 831 reg10_max = 0x41;
752 832
753 reg11 = (60 * sd->exposure + 999) / 1000; 833 reg11 = (15 * sd->exposure + 999) / 1000;
754 if (reg11 < 1) 834 if (reg11 < 1)
755 reg11 = 1; 835 reg11 = 1;
756 else if (reg11 > 16) 836 else if (reg11 > 16)
757 reg11 = 16; 837 reg11 = 16;
758 838
759 /* In 640x480, if the reg11 has less than 3, the image is 839 /* In 640x480, if the reg11 has less than 4, the image is
760 unstable (not enough bandwidth). */ 840 unstable (the bridge goes into a higher compression mode
761 if (gspca_dev->width == 640 && reg11 < 3) 841 which we have not reverse engineered yet). */
762 reg11 = 3; 842 if (gspca_dev->width == 640 && reg11 < 4)
843 reg11 = 4;
763 844
764 /* frame exposure time in ms = 1000 * reg11 / 30 -> 845 /* frame exposure time in ms = 1000 * reg11 / 30 ->
765 reg10 = sd->exposure * 2 * reg10_max / (1000 * reg11 / 30) */ 846 reg10 = (sd->exposure / 2) * reg10_max / (1000 * reg11 / 30) */
766 reg10 = (sd->exposure * 60 * reg10_max) / (1000 * reg11); 847 reg10 = (sd->exposure * 15 * reg10_max) / (1000 * reg11);
767 848
768 /* Don't allow this to get below 10 when using autogain, the 849 /* Don't allow this to get below 10 when using autogain, the
769 steps become very large (relatively) when below 10 causing 850 steps become very large (relatively) when below 10 causing
@@ -786,10 +867,85 @@ static void setexposure(struct gspca_dev *gspca_dev)
786 if (i2c_w(gspca_dev, i2c) == 0) 867 if (i2c_w(gspca_dev, i2c) == 0)
787 sd->reg11 = reg11; 868 sd->reg11 = reg11;
788 else 869 else
789 PDEBUG(D_ERR, "i2c error exposure"); 870 goto err;
871 break;
872 }
873 case SENSOR_PAS202: {
874 __u8 i2cpframerate[] =
875 {0xb0, 0x40, 0x04, 0x00, 0x00, 0x00, 0x00, 0x16};
876 __u8 i2cpexpo[] =
877 {0xa0, 0x40, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x16};
878 const __u8 i2cpdoit[] =
879 {0xa0, 0x40, 0x11, 0x01, 0x00, 0x00, 0x00, 0x16};
880 int framerate_ctrl;
881
882 /* The exposure knee for the autogain algorithm is 200
883 (100 ms / 10 fps on other sensors), for values below this
884 use the control for setting the partial frame expose time,
885 above that use variable framerate. This way we run at max
886 framerate (640x480@7.5 fps, 320x240@10fps) until the knee
887 is reached. Using the variable framerate control above 200
888 is better then playing around with both clockdiv + partial
889 frame exposure times (like we are doing with the ov chips),
890 as that sometimes leads to jumps in the exposure control,
891 which are bad for auto exposure. */
892 if (sd->exposure < 200) {
893 i2cpexpo[3] = 255 - (sd->exposure * 255) / 200;
894 framerate_ctrl = 500;
895 } else {
896 /* The PAS202's exposure control goes from 0 - 4095,
897 but anything below 500 causes vsync issues, so scale
898 our 200-1023 to 500-4095 */
899 framerate_ctrl = (sd->exposure - 200) * 1000 / 229 +
900 500;
901 }
902
903 i2cpframerate[3] = framerate_ctrl >> 6;
904 i2cpframerate[4] = framerate_ctrl & 0x3f;
905 if (i2c_w(gspca_dev, i2cpframerate) < 0)
906 goto err;
907 if (i2c_w(gspca_dev, i2cpexpo) < 0)
908 goto err;
909 if (i2c_w(gspca_dev, i2cpdoit) < 0)
910 goto err;
911 break;
912 }
913 case SENSOR_PAS106: {
914 __u8 i2cpframerate[] =
915 {0xb1, 0x40, 0x03, 0x00, 0x00, 0x00, 0x00, 0x14};
916 __u8 i2cpexpo[] =
917 {0xa1, 0x40, 0x05, 0x00, 0x00, 0x00, 0x00, 0x14};
918 const __u8 i2cpdoit[] =
919 {0xa1, 0x40, 0x13, 0x01, 0x00, 0x00, 0x00, 0x14};
920 int framerate_ctrl;
921
922 /* For values below 150 use partial frame exposure, above
923 that use framerate ctrl */
924 if (sd->exposure < 150) {
925 i2cpexpo[3] = 150 - sd->exposure;
926 framerate_ctrl = 300;
927 } else {
928 /* The PAS106's exposure control goes from 0 - 4095,
929 but anything below 300 causes vsync issues, so scale
930 our 150-1023 to 300-4095 */
931 framerate_ctrl = (sd->exposure - 150) * 1000 / 230 +
932 300;
933 }
934
935 i2cpframerate[3] = framerate_ctrl >> 4;
936 i2cpframerate[4] = framerate_ctrl & 0x0f;
937 if (i2c_w(gspca_dev, i2cpframerate) < 0)
938 goto err;
939 if (i2c_w(gspca_dev, i2cpexpo) < 0)
940 goto err;
941 if (i2c_w(gspca_dev, i2cpdoit) < 0)
942 goto err;
790 break; 943 break;
791 } 944 }
792 } 945 }
946 return;
947err:
948 PDEBUG(D_ERR, "i2c error exposure");
793} 949}
794 950
795static void setfreq(struct gspca_dev *gspca_dev) 951static void setfreq(struct gspca_dev *gspca_dev)
@@ -823,30 +979,43 @@ static void setfreq(struct gspca_dev *gspca_dev)
823 } 979 }
824} 980}
825 981
982#include "coarse_expo_autogain.h"
983
826static void do_autogain(struct gspca_dev *gspca_dev) 984static void do_autogain(struct gspca_dev *gspca_dev)
827{ 985{
828 int deadzone, desired_avg_lum; 986 int deadzone, desired_avg_lum, result;
829 struct sd *sd = (struct sd *) gspca_dev; 987 struct sd *sd = (struct sd *) gspca_dev;
830 int avg_lum = atomic_read(&sd->avg_lum); 988 int avg_lum = atomic_read(&sd->avg_lum);
831 989
832 if (avg_lum == -1) 990 if (avg_lum == -1 || !sd->autogain)
833 return; 991 return;
834 992
993 if (sd->autogain_ignore_frames > 0) {
994 sd->autogain_ignore_frames--;
995 return;
996 }
997
835 /* SIF / VGA sensors have a different autoexposure area and thus 998 /* SIF / VGA sensors have a different autoexposure area and thus
836 different avg_lum values for the same picture brightness */ 999 different avg_lum values for the same picture brightness */
837 if (sensor_data[sd->sensor].flags & F_SIF) { 1000 if (sensor_data[sd->sensor].flags & F_SIF) {
838 deadzone = 1000; 1001 deadzone = 500;
839 desired_avg_lum = 7000; 1002 /* SIF sensors tend to overexpose, so keep this small */
1003 desired_avg_lum = 5000;
840 } else { 1004 } else {
841 deadzone = 3000; 1005 deadzone = 1500;
842 desired_avg_lum = 23000; 1006 desired_avg_lum = 18000;
843 } 1007 }
844 1008
845 if (sd->autogain_ignore_frames > 0) 1009 if (sensor_data[sd->sensor].flags & F_COARSE_EXPO)
846 sd->autogain_ignore_frames--; 1010 result = gspca_coarse_grained_expo_autogain(gspca_dev, avg_lum,
847 else if (gspca_auto_gain_n_exposure(gspca_dev, avg_lum, 1011 sd->brightness * desired_avg_lum / 127,
848 sd->brightness * desired_avg_lum / 127, 1012 deadzone);
849 deadzone, GAIN_KNEE, EXPOSURE_KNEE)) { 1013 else
1014 result = gspca_auto_gain_n_exposure(gspca_dev, avg_lum,
1015 sd->brightness * desired_avg_lum / 127,
1016 deadzone, GAIN_KNEE, EXPOSURE_KNEE);
1017
1018 if (result) {
850 PDEBUG(D_FRAM, "autogain: gain changed: gain: %d expo: %d", 1019 PDEBUG(D_FRAM, "autogain: gain changed: gain: %d expo: %d",
851 (int)sd->gain, (int)sd->exposure); 1020 (int)sd->gain, (int)sd->exposure);
852 sd->autogain_ignore_frames = AUTOGAIN_IGNORE_FRAMES; 1021 sd->autogain_ignore_frames = AUTOGAIN_IGNORE_FRAMES;
@@ -881,7 +1050,13 @@ static int sd_config(struct gspca_dev *gspca_dev,
881 1050
882 sd->brightness = BRIGHTNESS_DEF; 1051 sd->brightness = BRIGHTNESS_DEF;
883 sd->gain = GAIN_DEF; 1052 sd->gain = GAIN_DEF;
884 sd->exposure = EXPOSURE_DEF; 1053 if (sensor_data[sd->sensor].flags & F_COARSE_EXPO) {
1054 sd->exposure = COARSE_EXPOSURE_DEF;
1055 gspca_dev->ctrl_dis |= (1 << EXPOSURE_IDX);
1056 } else {
1057 sd->exposure = EXPOSURE_DEF;
1058 gspca_dev->ctrl_dis |= (1 << COARSE_EXPOSURE_IDX);
1059 }
885 if (gspca_dev->ctrl_dis & (1 << AUTOGAIN_IDX)) 1060 if (gspca_dev->ctrl_dis & (1 << AUTOGAIN_IDX))
886 sd->autogain = 0; /* Disable do_autogain callback */ 1061 sd->autogain = 0; /* Disable do_autogain callback */
887 else 1062 else
@@ -917,9 +1092,6 @@ static int sd_start(struct gspca_dev *gspca_dev)
917 reg12_19[6] = sn9c10x[0x18 - 1] | (mode << 4); 1092 reg12_19[6] = sn9c10x[0x18 - 1] | (mode << 4);
918 /* Special cases where reg 17 and or 19 value depends on mode */ 1093 /* Special cases where reg 17 and or 19 value depends on mode */
919 switch (sd->sensor) { 1094 switch (sd->sensor) {
920 case SENSOR_PAS202:
921 reg12_19[5] = mode ? 0x24 : 0x20;
922 break;
923 case SENSOR_TAS5130CXX: 1095 case SENSOR_TAS5130CXX:
924 /* probably not mode specific at all most likely the upper 1096 /* probably not mode specific at all most likely the upper
925 nibble of 0x19 is exposure (clock divider) just as with 1097 nibble of 0x19 is exposure (clock divider) just as with
@@ -955,6 +1127,16 @@ static int sd_start(struct gspca_dev *gspca_dev)
955 sensor_data[sd->sensor].sensor_bridge_init_size[ 1127 sensor_data[sd->sensor].sensor_bridge_init_size[
956 sd->bridge]); 1128 sd->bridge]);
957 1129
1130 /* Mode specific sensor setup */
1131 switch (sd->sensor) {
1132 case SENSOR_PAS202: {
1133 const __u8 i2cpclockdiv[] =
1134 {0xa0, 0x40, 0x02, 0x03, 0x00, 0x00, 0x00, 0x10};
1135 /* clockdiv from 4 to 3 (7.5 -> 10 fps) when in low res mode */
1136 if (mode)
1137 i2c_w(gspca_dev, i2cpclockdiv);
1138 }
1139 }
958 /* H_size V_size 0x28, 0x1e -> 640x480. 0x16, 0x12 -> 352x288 */ 1140 /* H_size V_size 0x28, 0x1e -> 640x480. 0x16, 0x12 -> 352x288 */
959 reg_w(gspca_dev, 0x15, &reg12_19[3], 2); 1141 reg_w(gspca_dev, 0x15, &reg12_19[3], 2);
960 /* compression register */ 1142 /* compression register */
@@ -985,6 +1167,8 @@ static int sd_start(struct gspca_dev *gspca_dev)
985 1167
986 sd->frames_to_drop = 0; 1168 sd->frames_to_drop = 0;
987 sd->autogain_ignore_frames = 0; 1169 sd->autogain_ignore_frames = 0;
1170 sd->exp_too_high_cnt = 0;
1171 sd->exp_too_low_cnt = 0;
988 atomic_set(&sd->avg_lum, -1); 1172 atomic_set(&sd->avg_lum, -1);
989 return 0; 1173 return 0;
990} 1174}
@@ -1143,11 +1327,14 @@ static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
1143 struct sd *sd = (struct sd *) gspca_dev; 1327 struct sd *sd = (struct sd *) gspca_dev;
1144 1328
1145 sd->autogain = val; 1329 sd->autogain = val;
1330 sd->exp_too_high_cnt = 0;
1331 sd->exp_too_low_cnt = 0;
1332
1146 /* when switching to autogain set defaults to make sure 1333 /* when switching to autogain set defaults to make sure
1147 we are on a valid point of the autogain gain / 1334 we are on a valid point of the autogain gain /
1148 exposure knee graph, and give this change time to 1335 exposure knee graph, and give this change time to
1149 take effect before doing autogain. */ 1336 take effect before doing autogain. */
1150 if (sd->autogain) { 1337 if (sd->autogain && !(sensor_data[sd->sensor].flags & F_COARSE_EXPO)) {
1151 sd->exposure = EXPOSURE_DEF; 1338 sd->exposure = EXPOSURE_DEF;
1152 sd->gain = GAIN_DEF; 1339 sd->gain = GAIN_DEF;
1153 if (gspca_dev->streaming) { 1340 if (gspca_dev->streaming) {
@@ -1207,6 +1394,25 @@ static int sd_querymenu(struct gspca_dev *gspca_dev,
1207 return -EINVAL; 1394 return -EINVAL;
1208} 1395}
1209 1396
1397#ifdef CONFIG_INPUT
1398static int sd_int_pkt_scan(struct gspca_dev *gspca_dev,
1399 u8 *data, /* interrupt packet data */
1400 int len) /* interrupt packet length */
1401{
1402 int ret = -EINVAL;
1403
1404 if (len == 1 && data[0] == 1) {
1405 input_report_key(gspca_dev->input_dev, KEY_CAMERA, 1);
1406 input_sync(gspca_dev->input_dev);
1407 input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0);
1408 input_sync(gspca_dev->input_dev);
1409 ret = 0;
1410 }
1411
1412 return ret;
1413}
1414#endif
1415
1210/* sub-driver description */ 1416/* sub-driver description */
1211static const struct sd_desc sd_desc = { 1417static const struct sd_desc sd_desc = {
1212 .name = MODULE_NAME, 1418 .name = MODULE_NAME,
@@ -1219,6 +1425,9 @@ static const struct sd_desc sd_desc = {
1219 .pkt_scan = sd_pkt_scan, 1425 .pkt_scan = sd_pkt_scan,
1220 .querymenu = sd_querymenu, 1426 .querymenu = sd_querymenu,
1221 .dq_callback = do_autogain, 1427 .dq_callback = do_autogain,
1428#ifdef CONFIG_INPUT
1429 .int_pkt_scan = sd_int_pkt_scan,
1430#endif
1222}; 1431};
1223 1432
1224/* -- module initialisation -- */ 1433/* -- module initialisation -- */
@@ -1227,21 +1436,21 @@ static const struct sd_desc sd_desc = {
1227 1436
1228 1437
1229static const struct usb_device_id device_table[] __devinitconst = { 1438static const struct usb_device_id device_table[] __devinitconst = {
1230 {USB_DEVICE(0x0c45, 0x6001), SB(TAS5110, 102)}, /* TAS5110C1B */ 1439 {USB_DEVICE(0x0c45, 0x6001), SB(TAS5110C, 102)}, /* TAS5110C1B */
1231 {USB_DEVICE(0x0c45, 0x6005), SB(TAS5110, 101)}, /* TAS5110C1B */ 1440 {USB_DEVICE(0x0c45, 0x6005), SB(TAS5110C, 101)}, /* TAS5110C1B */
1232#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE 1441#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
1233 {USB_DEVICE(0x0c45, 0x6007), SB(TAS5110, 101)}, /* TAS5110D */ 1442 {USB_DEVICE(0x0c45, 0x6007), SB(TAS5110D, 101)}, /* TAS5110D */
1443#endif
1234 {USB_DEVICE(0x0c45, 0x6009), SB(PAS106, 101)}, 1444 {USB_DEVICE(0x0c45, 0x6009), SB(PAS106, 101)},
1235 {USB_DEVICE(0x0c45, 0x600d), SB(PAS106, 101)}, 1445 {USB_DEVICE(0x0c45, 0x600d), SB(PAS106, 101)},
1236#endif
1237 {USB_DEVICE(0x0c45, 0x6011), SB(OV6650, 101)}, 1446 {USB_DEVICE(0x0c45, 0x6011), SB(OV6650, 101)},
1238#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE 1447#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
1239 {USB_DEVICE(0x0c45, 0x6019), SB(OV7630, 101)}, 1448 {USB_DEVICE(0x0c45, 0x6019), SB(OV7630, 101)},
1240 {USB_DEVICE(0x0c45, 0x6024), SB(TAS5130CXX, 102)}, 1449 {USB_DEVICE(0x0c45, 0x6024), SB(TAS5130CXX, 102)},
1241 {USB_DEVICE(0x0c45, 0x6025), SB(TAS5130CXX, 102)}, 1450 {USB_DEVICE(0x0c45, 0x6025), SB(TAS5130CXX, 102)},
1451#endif
1242 {USB_DEVICE(0x0c45, 0x6028), SB(PAS202, 102)}, 1452 {USB_DEVICE(0x0c45, 0x6028), SB(PAS202, 102)},
1243 {USB_DEVICE(0x0c45, 0x6029), SB(PAS106, 102)}, 1453 {USB_DEVICE(0x0c45, 0x6029), SB(PAS106, 102)},
1244#endif
1245 {USB_DEVICE(0x0c45, 0x602c), SB(OV7630, 102)}, 1454 {USB_DEVICE(0x0c45, 0x602c), SB(OV7630, 102)},
1246 {USB_DEVICE(0x0c45, 0x602d), SB(HV7131R, 102)}, 1455 {USB_DEVICE(0x0c45, 0x602d), SB(HV7131R, 102)},
1247#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE 1456#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
diff --git a/drivers/media/video/gspca/sonixj.c b/drivers/media/video/gspca/sonixj.c
index 0bd36a00dd2a..83d5773d4629 100644
--- a/drivers/media/video/gspca/sonixj.c
+++ b/drivers/media/video/gspca/sonixj.c
@@ -21,6 +21,7 @@
21 21
22#define MODULE_NAME "sonixj" 22#define MODULE_NAME "sonixj"
23 23
24#include <linux/input.h>
24#include "gspca.h" 25#include "gspca.h"
25#include "jpeg.h" 26#include "jpeg.h"
26 27
@@ -45,6 +46,7 @@ struct sd {
45 u8 red; 46 u8 red;
46 u8 gamma; 47 u8 gamma;
47 u8 vflip; /* ov7630/ov7648 only */ 48 u8 vflip; /* ov7630/ov7648 only */
49 u8 sharpness;
48 u8 infrared; /* mt9v111 only */ 50 u8 infrared; /* mt9v111 only */
49 u8 freq; /* ov76xx only */ 51 u8 freq; /* ov76xx only */
50 u8 quality; /* image quality */ 52 u8 quality; /* image quality */
@@ -64,16 +66,17 @@ struct sd {
64#define BRIDGE_SN9C110 2 66#define BRIDGE_SN9C110 2
65#define BRIDGE_SN9C120 3 67#define BRIDGE_SN9C120 3
66 u8 sensor; /* Type of image sensor chip */ 68 u8 sensor; /* Type of image sensor chip */
67#define SENSOR_HV7131R 0 69#define SENSOR_ADCM1700 0
68#define SENSOR_MI0360 1 70#define SENSOR_HV7131R 1
69#define SENSOR_MO4000 2 71#define SENSOR_MI0360 2
70#define SENSOR_MT9V111 3 72#define SENSOR_MO4000 3
71#define SENSOR_OM6802 4 73#define SENSOR_MT9V111 4
72#define SENSOR_OV7630 5 74#define SENSOR_OM6802 5
73#define SENSOR_OV7648 6 75#define SENSOR_OV7630 6
74#define SENSOR_OV7660 7 76#define SENSOR_OV7648 7
75#define SENSOR_PO1030 8 77#define SENSOR_OV7660 8
76#define SENSOR_SP80708 9 78#define SENSOR_PO1030 9
79#define SENSOR_SP80708 10
77 u8 i2c_addr; 80 u8 i2c_addr;
78 81
79 u8 *jpeg_hdr; 82 u8 *jpeg_hdr;
@@ -96,12 +99,14 @@ static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
96static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val); 99static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val);
97static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val); 100static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val);
98static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val); 101static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val);
102static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val);
103static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val);
99static int sd_setinfrared(struct gspca_dev *gspca_dev, __s32 val); 104static int sd_setinfrared(struct gspca_dev *gspca_dev, __s32 val);
100static int sd_getinfrared(struct gspca_dev *gspca_dev, __s32 *val); 105static int sd_getinfrared(struct gspca_dev *gspca_dev, __s32 *val);
101static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val); 106static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val);
102static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val); 107static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val);
103 108
104static struct ctrl sd_ctrls[] = { 109static const struct ctrl sd_ctrls[] = {
105#define BRIGHTNESS_IDX 0 110#define BRIGHTNESS_IDX 0
106 { 111 {
107 { 112 {
@@ -225,8 +230,23 @@ static struct ctrl sd_ctrls[] = {
225 .set = sd_setvflip, 230 .set = sd_setvflip,
226 .get = sd_getvflip, 231 .get = sd_getvflip,
227 }, 232 },
233#define SHARPNESS_IDX 8
234 {
235 {
236 .id = V4L2_CID_SHARPNESS,
237 .type = V4L2_CTRL_TYPE_INTEGER,
238 .name = "Sharpness",
239 .minimum = 0,
240 .maximum = 255,
241 .step = 1,
242#define SHARPNESS_DEF 90
243 .default_value = SHARPNESS_DEF,
244 },
245 .set = sd_setsharpness,
246 .get = sd_getsharpness,
247 },
228/* mt9v111 only */ 248/* mt9v111 only */
229#define INFRARED_IDX 8 249#define INFRARED_IDX 9
230 { 250 {
231 { 251 {
232 .id = V4L2_CID_INFRARED, 252 .id = V4L2_CID_INFRARED,
@@ -242,7 +262,7 @@ static struct ctrl sd_ctrls[] = {
242 .get = sd_getinfrared, 262 .get = sd_getinfrared,
243 }, 263 },
244/* ov7630/ov7648/ov7660 only */ 264/* ov7630/ov7648/ov7660 only */
245#define FREQ_IDX 9 265#define FREQ_IDX 10
246 { 266 {
247 { 267 {
248 .id = V4L2_CID_POWER_LINE_FREQUENCY, 268 .id = V4L2_CID_POWER_LINE_FREQUENCY,
@@ -261,28 +281,37 @@ static struct ctrl sd_ctrls[] = {
261 281
262/* table of the disabled controls */ 282/* table of the disabled controls */
263static __u32 ctrl_dis[] = { 283static __u32 ctrl_dis[] = {
284 (1 << INFRARED_IDX) | (1 << VFLIP_IDX) | (1 << FREQ_IDX) |
285 (1 << AUTOGAIN_IDX), /* SENSOR_ADCM1700 0 */
286 (1 << INFRARED_IDX) | (1 << FREQ_IDX),
287 /* SENSOR_HV7131R 1 */
264 (1 << INFRARED_IDX) | (1 << VFLIP_IDX) | (1 << FREQ_IDX), 288 (1 << INFRARED_IDX) | (1 << VFLIP_IDX) | (1 << FREQ_IDX),
265 /* SENSOR_HV7131R 0 */ 289 /* SENSOR_MI0360 2 */
266 (1 << INFRARED_IDX) | (1 << VFLIP_IDX) | (1 << FREQ_IDX), 290 (1 << INFRARED_IDX) | (1 << VFLIP_IDX) | (1 << FREQ_IDX),
267 /* SENSOR_MI0360 1 */ 291 /* SENSOR_MO4000 3 */
268 (1 << INFRARED_IDX) | (1 << VFLIP_IDX) | (1 << FREQ_IDX),
269 /* SENSOR_MO4000 2 */
270 (1 << VFLIP_IDX) | (1 << FREQ_IDX), 292 (1 << VFLIP_IDX) | (1 << FREQ_IDX),
271 /* SENSOR_MT9V111 3 */ 293 /* SENSOR_MT9V111 4 */
272 (1 << INFRARED_IDX) | (1 << VFLIP_IDX) | (1 << FREQ_IDX), 294 (1 << INFRARED_IDX) | (1 << VFLIP_IDX) | (1 << FREQ_IDX),
273 /* SENSOR_OM6802 4 */ 295 /* SENSOR_OM6802 5 */
274 (1 << INFRARED_IDX), 296 (1 << INFRARED_IDX),
275 /* SENSOR_OV7630 5 */ 297 /* SENSOR_OV7630 6 */
276 (1 << INFRARED_IDX), 298 (1 << INFRARED_IDX),
277 /* SENSOR_OV7648 6 */ 299 /* SENSOR_OV7648 7 */
278 (1 << AUTOGAIN_IDX) | (1 << INFRARED_IDX) | (1 << VFLIP_IDX), 300 (1 << AUTOGAIN_IDX) | (1 << INFRARED_IDX) | (1 << VFLIP_IDX),
279 /* SENSOR_OV7660 7 */ 301 /* SENSOR_OV7660 8 */
280 (1 << AUTOGAIN_IDX) | (1 << INFRARED_IDX) | (1 << VFLIP_IDX) | 302 (1 << AUTOGAIN_IDX) | (1 << INFRARED_IDX) | (1 << VFLIP_IDX) |
281 (1 << FREQ_IDX), /* SENSOR_PO1030 8 */ 303 (1 << FREQ_IDX), /* SENSOR_PO1030 9 */
282 (1 << AUTOGAIN_IDX) | (1 << INFRARED_IDX) | (1 << VFLIP_IDX) | 304 (1 << AUTOGAIN_IDX) | (1 << INFRARED_IDX) | (1 << VFLIP_IDX) |
283 (1 << FREQ_IDX), /* SENSOR_SP80708 9 */ 305 (1 << FREQ_IDX), /* SENSOR_SP80708 10 */
284}; 306};
285 307
308static const struct v4l2_pix_format cif_mode[] = {
309 {352, 288, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
310 .bytesperline = 352,
311 .sizeimage = 352 * 288 * 4 / 8 + 590,
312 .colorspace = V4L2_COLORSPACE_JPEG,
313 .priv = 0},
314};
286static const struct v4l2_pix_format vga_mode[] = { 315static const struct v4l2_pix_format vga_mode[] = {
287 {160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, 316 {160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
288 .bytesperline = 160, 317 .bytesperline = 160,
@@ -302,6 +331,17 @@ static const struct v4l2_pix_format vga_mode[] = {
302 .priv = 0}, 331 .priv = 0},
303}; 332};
304 333
334static const u8 sn_adcm1700[0x1c] = {
335/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
336 0x00, 0x43, 0x60, 0x00, 0x1a, 0x00, 0x00, 0x00,
337/* reg8 reg9 rega regb regc regd rege regf */
338 0x80, 0x51, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
339/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
340 0x03, 0x00, 0x05, 0x01, 0x05, 0x16, 0x12, 0x42,
341/* reg18 reg19 reg1a reg1b */
342 0x06, 0x00, 0x00, 0x00
343};
344
305/*Data from sn9c102p+hv7131r */ 345/*Data from sn9c102p+hv7131r */
306static const u8 sn_hv7131[0x1c] = { 346static const u8 sn_hv7131[0x1c] = {
307/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */ 347/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
@@ -415,6 +455,7 @@ static const u8 sn_sp80708[0x1c] = {
415 455
416/* sequence specific to the sensors - !! index = SENSOR_xxx */ 456/* sequence specific to the sensors - !! index = SENSOR_xxx */
417static const u8 *sn_tb[] = { 457static const u8 *sn_tb[] = {
458 sn_adcm1700,
418 sn_hv7131, 459 sn_hv7131,
419 sn_mi0360, 460 sn_mi0360,
420 sn_mo4000, 461 sn_mo4000,
@@ -432,6 +473,11 @@ static const u8 gamma_def[17] = {
432 0x00, 0x2d, 0x46, 0x5a, 0x6c, 0x7c, 0x8b, 0x99, 473 0x00, 0x2d, 0x46, 0x5a, 0x6c, 0x7c, 0x8b, 0x99,
433 0xa6, 0xb2, 0xbf, 0xca, 0xd5, 0xe0, 0xeb, 0xf5, 0xff 474 0xa6, 0xb2, 0xbf, 0xca, 0xd5, 0xe0, 0xeb, 0xf5, 0xff
434}; 475};
476/* gamma for sensor ADCM1700 */
477static const u8 gamma_spec_0[17] = {
478 0x0f, 0x39, 0x5a, 0x74, 0x86, 0x95, 0xa6, 0xb4,
479 0xbd, 0xc4, 0xcc, 0xd4, 0xd5, 0xde, 0xe4, 0xed, 0xf5
480};
435/* gamma for sensors HV7131R and MT9V111 */ 481/* gamma for sensors HV7131R and MT9V111 */
436static const u8 gamma_spec_1[17] = { 482static const u8 gamma_spec_1[17] = {
437 0x08, 0x3a, 0x52, 0x65, 0x75, 0x83, 0x91, 0x9d, 483 0x08, 0x3a, 0x52, 0x65, 0x75, 0x83, 0x91, 0x9d,
@@ -450,6 +496,42 @@ static const u8 reg84[] = {
450 0x3e, 0x00, 0xcd, 0x0f, 0xf7, 0x0f, /* VR VG VB */ 496 0x3e, 0x00, 0xcd, 0x0f, 0xf7, 0x0f, /* VR VG VB */
451 0x00, 0x00, 0x00 /* YUV offsets */ 497 0x00, 0x00, 0x00 /* YUV offsets */
452}; 498};
499static const u8 adcm1700_sensor_init[][8] = {
500 {0xa0, 0x51, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x10},
501 {0xb0, 0x51, 0x04, 0x08, 0x00, 0x00, 0x00, 0x10}, /* reset */
502 {0xdd, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
503 {0xb0, 0x51, 0x04, 0x00, 0x00, 0x00, 0x00, 0x10},
504 {0xdd, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
505 {0xb0, 0x51, 0x0c, 0xe0, 0x2e, 0x00, 0x00, 0x10},
506 {0xb0, 0x51, 0x10, 0x02, 0x02, 0x00, 0x00, 0x10},
507 {0xb0, 0x51, 0x14, 0x0e, 0x0e, 0x00, 0x00, 0x10},
508 {0xb0, 0x51, 0x1c, 0x00, 0x80, 0x00, 0x00, 0x10},
509 {0xb0, 0x51, 0x20, 0x01, 0x00, 0x00, 0x00, 0x10},
510 {0xdd, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
511 {0xb0, 0x51, 0x04, 0x04, 0x00, 0x00, 0x00, 0x10},
512 {0xdd, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
513 {0xb0, 0x51, 0x04, 0x01, 0x00, 0x00, 0x00, 0x10},
514 {0xa0, 0x51, 0xfe, 0x10, 0x00, 0x00, 0x00, 0x10},
515 {0xb0, 0x51, 0x14, 0x01, 0x00, 0x00, 0x00, 0x10},
516 {0xb0, 0x51, 0x32, 0x00, 0x00, 0x00, 0x00, 0x10},
517 {}
518};
519static const u8 adcm1700_sensor_param1[][8] = {
520 {0xb0, 0x51, 0x26, 0xf9, 0x01, 0x00, 0x00, 0x10}, /* exposure? */
521 {0xd0, 0x51, 0x1e, 0x8e, 0x8e, 0x8e, 0x8e, 0x10},
522
523 {0xa0, 0x51, 0xfe, 0x01, 0x00, 0x00, 0x00, 0x10},
524 {0xb0, 0x51, 0x00, 0x02, 0x00, 0x00, 0x00, 0x10},
525 {0xa0, 0x51, 0xfe, 0x10, 0x00, 0x00, 0x00, 0x10},
526 {0xb0, 0x51, 0x32, 0x00, 0x72, 0x00, 0x00, 0x10},
527 {0xd0, 0x51, 0x1e, 0xbe, 0xd7, 0xe8, 0xbe, 0x10}, /* exposure? */
528
529 {0xa0, 0x51, 0xfe, 0x01, 0x00, 0x00, 0x00, 0x10},
530 {0xb0, 0x51, 0x00, 0x02, 0x00, 0x00, 0x00, 0x10},
531 {0xa0, 0x51, 0xfe, 0x10, 0x00, 0x00, 0x00, 0x10},
532 {0xb0, 0x51, 0x32, 0x00, 0xa2, 0x00, 0x00, 0x10},
533 {}
534};
453static const u8 hv7131r_sensor_init[][8] = { 535static const u8 hv7131r_sensor_init[][8] = {
454 {0xc1, 0x11, 0x01, 0x08, 0x01, 0x00, 0x00, 0x10}, 536 {0xc1, 0x11, 0x01, 0x08, 0x01, 0x00, 0x00, 0x10},
455 {0xb1, 0x11, 0x34, 0x17, 0x7f, 0x00, 0x00, 0x10}, 537 {0xb1, 0x11, 0x34, 0x17, 0x7f, 0x00, 0x00, 0x10},
@@ -986,17 +1068,18 @@ static const u8 sp80708_sensor_param1[][8] = {
986 {} 1068 {}
987}; 1069};
988 1070
989static const u8 (*sensor_init[10])[8] = { 1071static const u8 (*sensor_init[11])[8] = {
990 hv7131r_sensor_init, /* HV7131R 0 */ 1072 adcm1700_sensor_init, /* ADCM1700 0 */
991 mi0360_sensor_init, /* MI0360 1 */ 1073 hv7131r_sensor_init, /* HV7131R 1 */
992 mo4000_sensor_init, /* MO4000 2 */ 1074 mi0360_sensor_init, /* MI0360 2 */
993 mt9v111_sensor_init, /* MT9V111 3 */ 1075 mo4000_sensor_init, /* MO4000 3 */
994 om6802_sensor_init, /* OM6802 4 */ 1076 mt9v111_sensor_init, /* MT9V111 4 */
995 ov7630_sensor_init, /* OV7630 5 */ 1077 om6802_sensor_init, /* OM6802 5 */
996 ov7648_sensor_init, /* OV7648 6 */ 1078 ov7630_sensor_init, /* OV7630 6 */
997 ov7660_sensor_init, /* OV7660 7 */ 1079 ov7648_sensor_init, /* OV7648 7 */
998 po1030_sensor_init, /* PO1030 8 */ 1080 ov7660_sensor_init, /* OV7660 8 */
999 sp80708_sensor_init, /* SP80708 9 */ 1081 po1030_sensor_init, /* PO1030 9 */
1082 sp80708_sensor_init, /* SP80708 10 */
1000}; 1083};
1001 1084
1002/* read <len> bytes to gspca_dev->usb_buf */ 1085/* read <len> bytes to gspca_dev->usb_buf */
@@ -1064,6 +1147,7 @@ static void i2c_w1(struct gspca_dev *gspca_dev, u8 reg, u8 val)
1064 1147
1065 PDEBUG(D_USBO, "i2c_w2 [%02x] = %02x", reg, val); 1148 PDEBUG(D_USBO, "i2c_w2 [%02x] = %02x", reg, val);
1066 switch (sd->sensor) { 1149 switch (sd->sensor) {
1150 case SENSOR_ADCM1700:
1067 case SENSOR_OM6802: /* i2c command = a0 (100 kHz) */ 1151 case SENSOR_OM6802: /* i2c command = a0 (100 kHz) */
1068 gspca_dev->usb_buf[0] = 0x80 | (2 << 4); 1152 gspca_dev->usb_buf[0] = 0x80 | (2 << 4);
1069 break; 1153 break;
@@ -1110,6 +1194,7 @@ static void i2c_r(struct gspca_dev *gspca_dev, u8 reg, int len)
1110 u8 mode[8]; 1194 u8 mode[8];
1111 1195
1112 switch (sd->sensor) { 1196 switch (sd->sensor) {
1197 case SENSOR_ADCM1700:
1113 case SENSOR_OM6802: /* i2c command = 90 (100 kHz) */ 1198 case SENSOR_OM6802: /* i2c command = 90 (100 kHz) */
1114 mode[0] = 0x80 | 0x10; 1199 mode[0] = 0x80 | 0x10;
1115 break; 1200 break;
@@ -1260,7 +1345,8 @@ static void bridge_init(struct gspca_dev *gspca_dev,
1260 {0x00, 0x40, 0x38, 0x30, 0x00, 0x20}; 1345 {0x00, 0x40, 0x38, 0x30, 0x00, 0x20};
1261 static const u8 regd4[] = {0x60, 0x00, 0x00}; 1346 static const u8 regd4[] = {0x60, 0x00, 0x00};
1262 1347
1263 reg_w1(gspca_dev, 0xf1, 0x00); 1348 /* sensor clock already enabled in sd_init */
1349 /* reg_w1(gspca_dev, 0xf1, 0x00); */
1264 reg_w1(gspca_dev, 0x01, sn9c1xx[1]); 1350 reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
1265 1351
1266 /* configure gpio */ 1352 /* configure gpio */
@@ -1284,6 +1370,12 @@ static void bridge_init(struct gspca_dev *gspca_dev,
1284 reg_w(gspca_dev, 0x03, &sn9c1xx[3], 0x0f); 1370 reg_w(gspca_dev, 0x03, &sn9c1xx[3], 0x0f);
1285 1371
1286 switch (sd->sensor) { 1372 switch (sd->sensor) {
1373 case SENSOR_ADCM1700:
1374 reg_w1(gspca_dev, 0x01, 0x43);
1375 reg_w1(gspca_dev, 0x17, 0x62);
1376 reg_w1(gspca_dev, 0x01, 0x42);
1377 reg_w1(gspca_dev, 0x01, 0x42);
1378 break;
1287 case SENSOR_MT9V111: 1379 case SENSOR_MT9V111:
1288 reg_w1(gspca_dev, 0x01, 0x61); 1380 reg_w1(gspca_dev, 0x01, 0x61);
1289 reg_w1(gspca_dev, 0x17, 0x61); 1381 reg_w1(gspca_dev, 0x17, 0x61);
@@ -1357,14 +1449,19 @@ static int sd_config(struct gspca_dev *gspca_dev,
1357 struct sd *sd = (struct sd *) gspca_dev; 1449 struct sd *sd = (struct sd *) gspca_dev;
1358 struct cam *cam; 1450 struct cam *cam;
1359 1451
1360 cam = &gspca_dev->cam;
1361 cam->cam_mode = vga_mode;
1362 cam->nmodes = ARRAY_SIZE(vga_mode);
1363 cam->npkt = 24; /* 24 packets per ISOC message */
1364
1365 sd->bridge = id->driver_info >> 16; 1452 sd->bridge = id->driver_info >> 16;
1366 sd->sensor = id->driver_info; 1453 sd->sensor = id->driver_info;
1367 1454
1455 cam = &gspca_dev->cam;
1456 if (sd->sensor == SENSOR_ADCM1700) {
1457 cam->cam_mode = cif_mode;
1458 cam->nmodes = ARRAY_SIZE(cif_mode);
1459 } else {
1460 cam->cam_mode = vga_mode;
1461 cam->nmodes = ARRAY_SIZE(vga_mode);
1462 }
1463 cam->npkt = 24; /* 24 packets per ISOC message */
1464
1368 sd->brightness = BRIGHTNESS_DEF; 1465 sd->brightness = BRIGHTNESS_DEF;
1369 sd->contrast = CONTRAST_DEF; 1466 sd->contrast = CONTRAST_DEF;
1370 sd->colors = COLOR_DEF; 1467 sd->colors = COLOR_DEF;
@@ -1374,6 +1471,14 @@ static int sd_config(struct gspca_dev *gspca_dev,
1374 sd->autogain = AUTOGAIN_DEF; 1471 sd->autogain = AUTOGAIN_DEF;
1375 sd->ag_cnt = -1; 1472 sd->ag_cnt = -1;
1376 sd->vflip = VFLIP_DEF; 1473 sd->vflip = VFLIP_DEF;
1474 switch (sd->sensor) {
1475 case SENSOR_OM6802:
1476 sd->sharpness = 0x10;
1477 break;
1478 default:
1479 sd->sharpness = SHARPNESS_DEF;
1480 break;
1481 }
1377 sd->infrared = INFRARED_DEF; 1482 sd->infrared = INFRARED_DEF;
1378 sd->freq = FREQ_DEF; 1483 sd->freq = FREQ_DEF;
1379 sd->quality = QUALITY_DEF; 1484 sd->quality = QUALITY_DEF;
@@ -1433,7 +1538,9 @@ static int sd_init(struct gspca_dev *gspca_dev)
1433 break; 1538 break;
1434 } 1539 }
1435 1540
1436 reg_w1(gspca_dev, 0xf1, 0x01); 1541 /* Note we do not disable the sensor clock here (power saving mode),
1542 as that also disables the button on the cam. */
1543 reg_w1(gspca_dev, 0xf1, 0x00);
1437 1544
1438 /* set the i2c address */ 1545 /* set the i2c address */
1439 sn9c1xx = sn_tb[sd->sensor]; 1546 sn9c1xx = sn_tb[sd->sensor];
@@ -1543,6 +1650,10 @@ static void setbrightness(struct gspca_dev *gspca_dev)
1543 1650
1544 k2 = ((int) sd->brightness - 0x8000) >> 10; 1651 k2 = ((int) sd->brightness - 0x8000) >> 10;
1545 switch (sd->sensor) { 1652 switch (sd->sensor) {
1653 case SENSOR_ADCM1700:
1654 if (k2 > 0x1f)
1655 k2 = 0; /* only positive Y offset */
1656 break;
1546 case SENSOR_HV7131R: 1657 case SENSOR_HV7131R:
1547 expo = sd->brightness << 4; 1658 expo = sd->brightness << 4;
1548 if (expo > 0x002dc6c0) 1659 if (expo > 0x002dc6c0)
@@ -1625,6 +1736,9 @@ static void setgamma(struct gspca_dev *gspca_dev)
1625 }; 1736 };
1626 1737
1627 switch (sd->sensor) { 1738 switch (sd->sensor) {
1739 case SENSOR_ADCM1700:
1740 gamma_base = gamma_spec_0;
1741 break;
1628 case SENSOR_HV7131R: 1742 case SENSOR_HV7131R:
1629 case SENSOR_MT9V111: 1743 case SENSOR_MT9V111:
1630 gamma_base = gamma_spec_1; 1744 gamma_base = gamma_spec_1;
@@ -1670,23 +1784,39 @@ static void setautogain(struct gspca_dev *gspca_dev)
1670 sd->ag_cnt = -1; 1784 sd->ag_cnt = -1;
1671} 1785}
1672 1786
1673/* ov7630/ov7648 only */ 1787/* hv7131r/ov7630/ov7648 only */
1674static void setvflip(struct sd *sd) 1788static void setvflip(struct sd *sd)
1675{ 1789{
1676 u8 comn; 1790 u8 comn;
1677 1791
1678 if (sd->gspca_dev.ctrl_dis & (1 << VFLIP_IDX)) 1792 if (sd->gspca_dev.ctrl_dis & (1 << VFLIP_IDX))
1679 return; 1793 return;
1680 if (sd->sensor == SENSOR_OV7630) { 1794 switch (sd->sensor) {
1795 case SENSOR_HV7131R:
1796 comn = 0x18; /* clkdiv = 1, ablcen = 1 */
1797 if (sd->vflip)
1798 comn |= 0x01;
1799 i2c_w1(&sd->gspca_dev, 0x01, comn); /* sctra */
1800 break;
1801 case SENSOR_OV7630:
1681 comn = 0x02; 1802 comn = 0x02;
1682 if (!sd->vflip) 1803 if (!sd->vflip)
1683 comn |= 0x80; 1804 comn |= 0x80;
1684 } else { 1805 i2c_w1(&sd->gspca_dev, 0x75, comn);
1806 break;
1807 default:
1808/* case SENSOR_OV7648: */
1685 comn = 0x06; 1809 comn = 0x06;
1686 if (sd->vflip) 1810 if (sd->vflip)
1687 comn |= 0x80; 1811 comn |= 0x80;
1812 i2c_w1(&sd->gspca_dev, 0x75, comn);
1813 break;
1688 } 1814 }
1689 i2c_w1(&sd->gspca_dev, 0x75, comn); 1815}
1816
1817static void setsharpness(struct sd *sd)
1818{
1819 reg_w1(&sd->gspca_dev, 0x99, sd->sharpness);
1690} 1820}
1691 1821
1692static void setinfrared(struct sd *sd) 1822static void setinfrared(struct sd *sd)
@@ -1804,6 +1934,8 @@ static int sd_start(struct gspca_dev *gspca_dev)
1804 int mode; 1934 int mode;
1805 static const u8 C0[] = { 0x2d, 0x2d, 0x3a, 0x05, 0x04, 0x3f }; 1935 static const u8 C0[] = { 0x2d, 0x2d, 0x3a, 0x05, 0x04, 0x3f };
1806 static const u8 CA[] = { 0x28, 0xd8, 0x14, 0xec }; 1936 static const u8 CA[] = { 0x28, 0xd8, 0x14, 0xec };
1937 static const u8 CA_adcm1700[] =
1938 { 0x14, 0xec, 0x0a, 0xf6 };
1807 static const u8 CE[] = { 0x32, 0xdd, 0x2d, 0xdd }; /* MI0360 */ 1939 static const u8 CE[] = { 0x32, 0xdd, 0x2d, 0xdd }; /* MI0360 */
1808 static const u8 CE_ov76xx[] = 1940 static const u8 CE_ov76xx[] =
1809 { 0x32, 0xdd, 0x32, 0xdd }; 1941 { 0x32, 0xdd, 0x32, 0xdd };
@@ -1824,6 +1956,9 @@ static int sd_start(struct gspca_dev *gspca_dev)
1824 i2c_w_seq(gspca_dev, sensor_init[sd->sensor]); 1956 i2c_w_seq(gspca_dev, sensor_init[sd->sensor]);
1825 1957
1826 switch (sd->sensor) { 1958 switch (sd->sensor) {
1959 case SENSOR_ADCM1700:
1960 reg2 = 0x60;
1961 break;
1827 case SENSOR_OM6802: 1962 case SENSOR_OM6802:
1828 reg2 = 0x71; 1963 reg2 = 0x71;
1829 break; 1964 break;
@@ -1842,17 +1977,28 @@ static int sd_start(struct gspca_dev *gspca_dev)
1842 reg_w1(gspca_dev, 0x12, sn9c1xx[0x12]); 1977 reg_w1(gspca_dev, 0x12, sn9c1xx[0x12]);
1843 reg_w1(gspca_dev, 0x13, sn9c1xx[0x13]); 1978 reg_w1(gspca_dev, 0x13, sn9c1xx[0x13]);
1844 reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]); 1979 reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]);
1845 reg_w1(gspca_dev, 0xd2, 0x6a); /* DC29 */ 1980 if (sd->sensor == SENSOR_ADCM1700) {
1846 reg_w1(gspca_dev, 0xd3, 0x50); 1981 reg_w1(gspca_dev, 0xd2, 0x3a); /* AE_H_SIZE = 116 */
1982 reg_w1(gspca_dev, 0xd3, 0x30); /* AE_V_SIZE = 96 */
1983 } else {
1984 reg_w1(gspca_dev, 0xd2, 0x6a); /* AE_H_SIZE = 212 */
1985 reg_w1(gspca_dev, 0xd3, 0x50); /* AE_V_SIZE = 160 */
1986 }
1847 reg_w1(gspca_dev, 0xc6, 0x00); 1987 reg_w1(gspca_dev, 0xc6, 0x00);
1848 reg_w1(gspca_dev, 0xc7, 0x00); 1988 reg_w1(gspca_dev, 0xc7, 0x00);
1849 reg_w1(gspca_dev, 0xc8, 0x50); 1989 if (sd->sensor == SENSOR_ADCM1700) {
1850 reg_w1(gspca_dev, 0xc9, 0x3c); 1990 reg_w1(gspca_dev, 0xc8, 0x2c); /* AW_H_STOP = 352 */
1991 reg_w1(gspca_dev, 0xc9, 0x24); /* AW_V_STOP = 288 */
1992 } else {
1993 reg_w1(gspca_dev, 0xc8, 0x50); /* AW_H_STOP = 640 */
1994 reg_w1(gspca_dev, 0xc9, 0x3c); /* AW_V_STOP = 480 */
1995 }
1851 reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]); 1996 reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]);
1852 switch (sd->sensor) { 1997 switch (sd->sensor) {
1853 case SENSOR_MT9V111: 1998 case SENSOR_MT9V111:
1854 reg17 = 0xe0; 1999 reg17 = 0xe0;
1855 break; 2000 break;
2001 case SENSOR_ADCM1700:
1856 case SENSOR_OV7630: 2002 case SENSOR_OV7630:
1857 reg17 = 0xe2; 2003 reg17 = 0xe2;
1858 break; 2004 break;
@@ -1870,44 +2016,39 @@ static int sd_start(struct gspca_dev *gspca_dev)
1870 break; 2016 break;
1871 } 2017 }
1872 reg_w1(gspca_dev, 0x17, reg17); 2018 reg_w1(gspca_dev, 0x17, reg17);
1873/* set reg1 was here */ 2019
1874 reg_w1(gspca_dev, 0x05, sn9c1xx[5]); /* red */ 2020 reg_w1(gspca_dev, 0x05, 0x00); /* red */
1875 reg_w1(gspca_dev, 0x07, sn9c1xx[7]); /* green */ 2021 reg_w1(gspca_dev, 0x07, 0x00); /* green */
1876 reg_w1(gspca_dev, 0x06, sn9c1xx[6]); /* blue */ 2022 reg_w1(gspca_dev, 0x06, 0x00); /* blue */
1877 reg_w1(gspca_dev, 0x14, sn9c1xx[0x14]); 2023 reg_w1(gspca_dev, 0x14, sn9c1xx[0x14]);
1878 2024
1879 setgamma(gspca_dev); 2025 setgamma(gspca_dev);
1880 2026
2027/*fixme: 8 times with all zeroes and 1 or 2 times with normal values */
1881 for (i = 0; i < 8; i++) 2028 for (i = 0; i < 8; i++)
1882 reg_w(gspca_dev, 0x84, reg84, sizeof reg84); 2029 reg_w(gspca_dev, 0x84, reg84, sizeof reg84);
1883 switch (sd->sensor) { 2030 switch (sd->sensor) {
2031 case SENSOR_ADCM1700:
2032 case SENSOR_OV7660:
2033 case SENSOR_SP80708:
2034 reg_w1(gspca_dev, 0x9a, 0x05);
2035 break;
1884 case SENSOR_MT9V111: 2036 case SENSOR_MT9V111:
1885 reg_w1(gspca_dev, 0x9a, 0x07); 2037 reg_w1(gspca_dev, 0x9a, 0x07);
1886 reg_w1(gspca_dev, 0x99, 0x59);
1887 break;
1888 case SENSOR_OM6802:
1889 reg_w1(gspca_dev, 0x9a, 0x08);
1890 reg_w1(gspca_dev, 0x99, 0x10);
1891 break; 2038 break;
1892 case SENSOR_OV7648: 2039 case SENSOR_OV7648:
1893 reg_w1(gspca_dev, 0x9a, 0x0a); 2040 reg_w1(gspca_dev, 0x9a, 0x0a);
1894 reg_w1(gspca_dev, 0x99, 0x60);
1895 break;
1896 case SENSOR_OV7660:
1897 case SENSOR_SP80708:
1898 reg_w1(gspca_dev, 0x9a, 0x05);
1899 reg_w1(gspca_dev, 0x99, 0x59);
1900 break; 2041 break;
1901 default: 2042 default:
1902 reg_w1(gspca_dev, 0x9a, 0x08); 2043 reg_w1(gspca_dev, 0x9a, 0x08);
1903 reg_w1(gspca_dev, 0x99, 0x59);
1904 break; 2044 break;
1905 } 2045 }
2046 setsharpness(sd);
1906 2047
1907 reg_w(gspca_dev, 0x84, reg84, sizeof reg84); 2048 reg_w(gspca_dev, 0x84, reg84, sizeof reg84);
1908 reg_w1(gspca_dev, 0x05, sn9c1xx[5]); /* red */ 2049 reg_w1(gspca_dev, 0x05, 0x20); /* red */
1909 reg_w1(gspca_dev, 0x07, sn9c1xx[7]); /* green */ 2050 reg_w1(gspca_dev, 0x07, 0x20); /* green */
1910 reg_w1(gspca_dev, 0x06, sn9c1xx[6]); /* blue */ 2051 reg_w1(gspca_dev, 0x06, 0x20); /* blue */
1911 2052
1912 init = NULL; 2053 init = NULL;
1913 mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv; 2054 mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv;
@@ -1917,6 +2058,11 @@ static int sd_start(struct gspca_dev *gspca_dev)
1917 reg1 = 0x06; /* 640x480: clk 24Mhz, video trf enable */ 2058 reg1 = 0x06; /* 640x480: clk 24Mhz, video trf enable */
1918 reg17 = 0x61; /* 0x:20: enable sensor clock */ 2059 reg17 = 0x61; /* 0x:20: enable sensor clock */
1919 switch (sd->sensor) { 2060 switch (sd->sensor) {
2061 case SENSOR_ADCM1700:
2062 init = adcm1700_sensor_param1;
2063 reg1 = 0x46;
2064 reg17 = 0xe2;
2065 break;
1920 case SENSOR_MO4000: 2066 case SENSOR_MO4000:
1921 if (mode) { 2067 if (mode) {
1922/* reg1 = 0x46; * 320 clk 48Mhz 60fp/s */ 2068/* reg1 = 0x46; * 320 clk 48Mhz 60fp/s */
@@ -1940,7 +2086,6 @@ static int sd_start(struct gspca_dev *gspca_dev)
1940 reg17 = 0x64; /* 640 MCKSIZE */ 2086 reg17 = 0x64; /* 640 MCKSIZE */
1941 break; 2087 break;
1942 case SENSOR_OV7630: 2088 case SENSOR_OV7630:
1943 setvflip(sd);
1944 reg17 = 0xe2; 2089 reg17 = 0xe2;
1945 reg1 = 0x44; 2090 reg1 = 0x44;
1946 break; 2091 break;
@@ -1986,8 +2131,12 @@ static int sd_start(struct gspca_dev *gspca_dev)
1986 } 2131 }
1987 2132
1988 reg_w(gspca_dev, 0xc0, C0, 6); 2133 reg_w(gspca_dev, 0xc0, C0, 6);
1989 reg_w(gspca_dev, 0xca, CA, 4); 2134 if (sd->sensor == SENSOR_ADCM1700)
2135 reg_w(gspca_dev, 0xca, CA_adcm1700, 4);
2136 else
2137 reg_w(gspca_dev, 0xca, CA, 4);
1990 switch (sd->sensor) { 2138 switch (sd->sensor) {
2139 case SENSOR_ADCM1700:
1991 case SENSOR_OV7630: 2140 case SENSOR_OV7630:
1992 case SENSOR_OV7648: 2141 case SENSOR_OV7648:
1993 case SENSOR_OV7660: 2142 case SENSOR_OV7660:
@@ -2008,11 +2157,7 @@ static int sd_start(struct gspca_dev *gspca_dev)
2008 reg_w1(gspca_dev, 0x17, reg17); 2157 reg_w1(gspca_dev, 0x17, reg17);
2009 reg_w1(gspca_dev, 0x01, reg1); 2158 reg_w1(gspca_dev, 0x01, reg1);
2010 2159
2011 switch (sd->sensor) { 2160 setvflip(sd);
2012 case SENSOR_OV7630:
2013 setvflip(sd);
2014 break;
2015 }
2016 setbrightness(gspca_dev); 2161 setbrightness(gspca_dev);
2017 setcontrast(gspca_dev); 2162 setcontrast(gspca_dev);
2018 setautogain(gspca_dev); 2163 setautogain(gspca_dev);
@@ -2056,7 +2201,8 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
2056 reg_w1(gspca_dev, 0x17, sn9c1xx[0x17]); 2201 reg_w1(gspca_dev, 0x17, sn9c1xx[0x17]);
2057 reg_w1(gspca_dev, 0x01, sn9c1xx[1]); 2202 reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
2058 reg_w1(gspca_dev, 0x01, data); 2203 reg_w1(gspca_dev, 0x01, data);
2059 reg_w1(gspca_dev, 0xf1, 0x00); 2204 /* Don't disable sensor clock as that disables the button on the cam */
2205 /* reg_w1(gspca_dev, 0xf1, 0x01); */
2060} 2206}
2061 2207
2062static void sd_stop0(struct gspca_dev *gspca_dev) 2208static void sd_stop0(struct gspca_dev *gspca_dev)
@@ -2288,6 +2434,24 @@ static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val)
2288 return 0; 2434 return 0;
2289} 2435}
2290 2436
2437static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val)
2438{
2439 struct sd *sd = (struct sd *) gspca_dev;
2440
2441 sd->sharpness = val;
2442 if (gspca_dev->streaming)
2443 setsharpness(sd);
2444 return 0;
2445}
2446
2447static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val)
2448{
2449 struct sd *sd = (struct sd *) gspca_dev;
2450
2451 *val = sd->sharpness;
2452 return 0;
2453}
2454
2291static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val) 2455static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val)
2292{ 2456{
2293 struct sd *sd = (struct sd *) gspca_dev; 2457 struct sd *sd = (struct sd *) gspca_dev;
@@ -2391,6 +2555,25 @@ static int sd_querymenu(struct gspca_dev *gspca_dev,
2391 return -EINVAL; 2555 return -EINVAL;
2392} 2556}
2393 2557
2558#ifdef CONFIG_INPUT
2559static int sd_int_pkt_scan(struct gspca_dev *gspca_dev,
2560 u8 *data, /* interrupt packet data */
2561 int len) /* interrupt packet length */
2562{
2563 int ret = -EINVAL;
2564
2565 if (len == 1 && data[0] == 1) {
2566 input_report_key(gspca_dev->input_dev, KEY_CAMERA, 1);
2567 input_sync(gspca_dev->input_dev);
2568 input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0);
2569 input_sync(gspca_dev->input_dev);
2570 ret = 0;
2571 }
2572
2573 return ret;
2574}
2575#endif
2576
2394/* sub-driver description */ 2577/* sub-driver description */
2395static const struct sd_desc sd_desc = { 2578static const struct sd_desc sd_desc = {
2396 .name = MODULE_NAME, 2579 .name = MODULE_NAME,
@@ -2406,6 +2589,9 @@ static const struct sd_desc sd_desc = {
2406 .get_jcomp = sd_get_jcomp, 2589 .get_jcomp = sd_get_jcomp,
2407 .set_jcomp = sd_set_jcomp, 2590 .set_jcomp = sd_set_jcomp,
2408 .querymenu = sd_querymenu, 2591 .querymenu = sd_querymenu,
2592#ifdef CONFIG_INPUT
2593 .int_pkt_scan = sd_int_pkt_scan,
2594#endif
2409}; 2595};
2410 2596
2411/* -- module initialisation -- */ 2597/* -- module initialisation -- */
@@ -2472,6 +2658,7 @@ static const __devinitdata struct usb_device_id device_table[] = {
2472/* {USB_DEVICE(0x0c45, 0x6142), BS(SN9C120, PO2030N)}, *sn9c120b*/ 2658/* {USB_DEVICE(0x0c45, 0x6142), BS(SN9C120, PO2030N)}, *sn9c120b*/
2473 {USB_DEVICE(0x0c45, 0x6143), BS(SN9C120, SP80708)}, /*sn9c120b*/ 2659 {USB_DEVICE(0x0c45, 0x6143), BS(SN9C120, SP80708)}, /*sn9c120b*/
2474 {USB_DEVICE(0x0c45, 0x6148), BS(SN9C120, OM6802)}, /*sn9c120b*/ 2660 {USB_DEVICE(0x0c45, 0x6148), BS(SN9C120, OM6802)}, /*sn9c120b*/
2661 {USB_DEVICE(0x0c45, 0x614a), BS(SN9C120, ADCM1700)}, /*sn9c120b*/
2475 {} 2662 {}
2476}; 2663};
2477MODULE_DEVICE_TABLE(usb, device_table); 2664MODULE_DEVICE_TABLE(usb, device_table);
diff --git a/drivers/media/video/gspca/spca500.c b/drivers/media/video/gspca/spca500.c
index fe46868a87f2..b866c73c97db 100644
--- a/drivers/media/video/gspca/spca500.c
+++ b/drivers/media/video/gspca/spca500.c
@@ -68,7 +68,7 @@ static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
68static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val); 68static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val);
69static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val); 69static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val);
70 70
71static struct ctrl sd_ctrls[] = { 71static const struct ctrl sd_ctrls[] = {
72 { 72 {
73 { 73 {
74 .id = V4L2_CID_BRIGHTNESS, 74 .id = V4L2_CID_BRIGHTNESS,
@@ -1047,7 +1047,7 @@ static int sd_get_jcomp(struct gspca_dev *gspca_dev,
1047} 1047}
1048 1048
1049/* sub-driver description */ 1049/* sub-driver description */
1050static struct sd_desc sd_desc = { 1050static const struct sd_desc sd_desc = {
1051 .name = MODULE_NAME, 1051 .name = MODULE_NAME,
1052 .ctrls = sd_ctrls, 1052 .ctrls = sd_ctrls,
1053 .nctrls = ARRAY_SIZE(sd_ctrls), 1053 .nctrls = ARRAY_SIZE(sd_ctrls),
diff --git a/drivers/media/video/gspca/spca501.c b/drivers/media/video/gspca/spca501.c
index 6761a3048a98..c99333933e32 100644
--- a/drivers/media/video/gspca/spca501.c
+++ b/drivers/media/video/gspca/spca501.c
@@ -59,7 +59,7 @@ static int sd_getblue_balance(struct gspca_dev *gspca_dev, __s32 *val);
59static int sd_setred_balance(struct gspca_dev *gspca_dev, __s32 val); 59static int sd_setred_balance(struct gspca_dev *gspca_dev, __s32 val);
60static int sd_getred_balance(struct gspca_dev *gspca_dev, __s32 *val); 60static int sd_getred_balance(struct gspca_dev *gspca_dev, __s32 *val);
61 61
62static struct ctrl sd_ctrls[] = { 62static const struct ctrl sd_ctrls[] = {
63#define MY_BRIGHTNESS 0 63#define MY_BRIGHTNESS 0
64 { 64 {
65 { 65 {
diff --git a/drivers/media/video/gspca/spca505.c b/drivers/media/video/gspca/spca505.c
index 0f9232ff1281..c576eed73abe 100644
--- a/drivers/media/video/gspca/spca505.c
+++ b/drivers/media/video/gspca/spca505.c
@@ -42,7 +42,7 @@ struct sd {
42static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val); 42static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
43static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val); 43static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
44 44
45static struct ctrl sd_ctrls[] = { 45static const struct ctrl sd_ctrls[] = {
46 { 46 {
47 { 47 {
48 .id = V4L2_CID_BRIGHTNESS, 48 .id = V4L2_CID_BRIGHTNESS,
diff --git a/drivers/media/video/gspca/spca506.c b/drivers/media/video/gspca/spca506.c
index 39257e4e074f..89fec4c500af 100644
--- a/drivers/media/video/gspca/spca506.c
+++ b/drivers/media/video/gspca/spca506.c
@@ -51,7 +51,7 @@ static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val);
51static int sd_sethue(struct gspca_dev *gspca_dev, __s32 val); 51static int sd_sethue(struct gspca_dev *gspca_dev, __s32 val);
52static int sd_gethue(struct gspca_dev *gspca_dev, __s32 *val); 52static int sd_gethue(struct gspca_dev *gspca_dev, __s32 *val);
53 53
54static struct ctrl sd_ctrls[] = { 54static const struct ctrl sd_ctrls[] = {
55#define SD_BRIGHTNESS 0 55#define SD_BRIGHTNESS 0
56 { 56 {
57 { 57 {
@@ -673,7 +673,7 @@ static int sd_gethue(struct gspca_dev *gspca_dev, __s32 *val)
673} 673}
674 674
675/* sub-driver description */ 675/* sub-driver description */
676static struct sd_desc sd_desc = { 676static const struct sd_desc sd_desc = {
677 .name = MODULE_NAME, 677 .name = MODULE_NAME,
678 .ctrls = sd_ctrls, 678 .ctrls = sd_ctrls,
679 .nctrls = ARRAY_SIZE(sd_ctrls), 679 .nctrls = ARRAY_SIZE(sd_ctrls),
diff --git a/drivers/media/video/gspca/spca508.c b/drivers/media/video/gspca/spca508.c
index 4d8e6cf75d55..15b2eef8a3f6 100644
--- a/drivers/media/video/gspca/spca508.c
+++ b/drivers/media/video/gspca/spca508.c
@@ -45,7 +45,7 @@ struct sd {
45static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val); 45static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
46static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val); 46static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
47 47
48static struct ctrl sd_ctrls[] = { 48static const struct ctrl sd_ctrls[] = {
49 { 49 {
50 { 50 {
51 .id = V4L2_CID_BRIGHTNESS, 51 .id = V4L2_CID_BRIGHTNESS,
diff --git a/drivers/media/video/gspca/spca561.c b/drivers/media/video/gspca/spca561.c
index 58c2f0039af1..dc7f2b0fbc79 100644
--- a/drivers/media/video/gspca/spca561.c
+++ b/drivers/media/video/gspca/spca561.c
@@ -922,7 +922,7 @@ static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val)
922} 922}
923 923
924/* control tables */ 924/* control tables */
925static struct ctrl sd_ctrls_12a[] = { 925static const struct ctrl sd_ctrls_12a[] = {
926 { 926 {
927 { 927 {
928 .id = V4L2_CID_HUE, 928 .id = V4L2_CID_HUE,
@@ -964,7 +964,7 @@ static struct ctrl sd_ctrls_12a[] = {
964 }, 964 },
965}; 965};
966 966
967static struct ctrl sd_ctrls_72a[] = { 967static const struct ctrl sd_ctrls_72a[] = {
968 { 968 {
969 { 969 {
970 .id = V4L2_CID_HUE, 970 .id = V4L2_CID_HUE,
diff --git a/drivers/media/video/gspca/sq905c.c b/drivers/media/video/gspca/sq905c.c
index d70b156872d6..e64662052992 100644
--- a/drivers/media/video/gspca/sq905c.c
+++ b/drivers/media/video/gspca/sq905c.c
@@ -47,6 +47,7 @@ MODULE_LICENSE("GPL");
47 47
48/* Commands. These go in the "value" slot. */ 48/* Commands. These go in the "value" slot. */
49#define SQ905C_CLEAR 0xa0 /* clear everything */ 49#define SQ905C_CLEAR 0xa0 /* clear everything */
50#define SQ905C_GET_ID 0x14f4 /* Read version number */
50#define SQ905C_CAPTURE_LOW 0xa040 /* Starts capture at 160x120 */ 51#define SQ905C_CAPTURE_LOW 0xa040 /* Starts capture at 160x120 */
51#define SQ905C_CAPTURE_MED 0x1440 /* Starts capture at 320x240 */ 52#define SQ905C_CAPTURE_MED 0x1440 /* Starts capture at 320x240 */
52#define SQ905C_CAPTURE_HI 0x2840 /* Starts capture at 320x240 */ 53#define SQ905C_CAPTURE_HI 0x2840 /* Starts capture at 320x240 */
@@ -101,6 +102,26 @@ static int sq905c_command(struct gspca_dev *gspca_dev, u16 command, u16 index)
101 return 0; 102 return 0;
102} 103}
103 104
105static int sq905c_read(struct gspca_dev *gspca_dev, u16 command, u16 index,
106 int size)
107{
108 int ret;
109
110 ret = usb_control_msg(gspca_dev->dev,
111 usb_rcvctrlpipe(gspca_dev->dev, 0),
112 USB_REQ_SYNCH_FRAME, /* request */
113 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
114 command, index, gspca_dev->usb_buf, size,
115 SQ905C_CMD_TIMEOUT);
116 if (ret < 0) {
117 PDEBUG(D_ERR, "%s: usb_control_msg failed (%d)",
118 __func__, ret);
119 return ret;
120 }
121
122 return 0;
123}
124
104/* This function is called as a workqueue function and runs whenever the camera 125/* This function is called as a workqueue function and runs whenever the camera
105 * is streaming data. Because it is a workqueue function it is allowed to sleep 126 * is streaming data. Because it is a workqueue function it is allowed to sleep
106 * so we can use synchronous USB calls. To avoid possible collisions with other 127 * so we can use synchronous USB calls. To avoid possible collisions with other
@@ -183,13 +204,34 @@ static int sd_config(struct gspca_dev *gspca_dev,
183{ 204{
184 struct cam *cam = &gspca_dev->cam; 205 struct cam *cam = &gspca_dev->cam;
185 struct sd *dev = (struct sd *) gspca_dev; 206 struct sd *dev = (struct sd *) gspca_dev;
207 int ret;
186 208
187 PDEBUG(D_PROBE, 209 PDEBUG(D_PROBE,
188 "SQ9050 camera detected" 210 "SQ9050 camera detected"
189 " (vid/pid 0x%04X:0x%04X)", id->idVendor, id->idProduct); 211 " (vid/pid 0x%04X:0x%04X)", id->idVendor, id->idProduct);
212
213 ret = sq905c_command(gspca_dev, SQ905C_GET_ID, 0);
214 if (ret < 0) {
215 PDEBUG(D_ERR, "Get version command failed");
216 return ret;
217 }
218
219 ret = sq905c_read(gspca_dev, 0xf5, 0, 20);
220 if (ret < 0) {
221 PDEBUG(D_ERR, "Reading version command failed");
222 return ret;
223 }
224 /* Note we leave out the usb id and the manufacturing date */
225 PDEBUG(D_PROBE,
226 "SQ9050 ID string: %02x - %02x %02x %02x %02x %02x %02x",
227 gspca_dev->usb_buf[3],
228 gspca_dev->usb_buf[14], gspca_dev->usb_buf[15],
229 gspca_dev->usb_buf[16], gspca_dev->usb_buf[17],
230 gspca_dev->usb_buf[18], gspca_dev->usb_buf[19]);
231
190 cam->cam_mode = sq905c_mode; 232 cam->cam_mode = sq905c_mode;
191 cam->nmodes = 2; 233 cam->nmodes = 2;
192 if (id->idProduct == 0x9050) 234 if (gspca_dev->usb_buf[15] == 0)
193 cam->nmodes = 1; 235 cam->nmodes = 1;
194 /* We don't use the buffer gspca allocates so make it small. */ 236 /* We don't use the buffer gspca allocates so make it small. */
195 cam->bulk_size = 32; 237 cam->bulk_size = 32;
@@ -258,6 +300,7 @@ static int sd_start(struct gspca_dev *gspca_dev)
258static const __devinitdata struct usb_device_id device_table[] = { 300static const __devinitdata struct usb_device_id device_table[] = {
259 {USB_DEVICE(0x2770, 0x905c)}, 301 {USB_DEVICE(0x2770, 0x905c)},
260 {USB_DEVICE(0x2770, 0x9050)}, 302 {USB_DEVICE(0x2770, 0x9050)},
303 {USB_DEVICE(0x2770, 0x9052)},
261 {USB_DEVICE(0x2770, 0x913d)}, 304 {USB_DEVICE(0x2770, 0x913d)},
262 {} 305 {}
263}; 306};
diff --git a/drivers/media/video/gspca/stk014.c b/drivers/media/video/gspca/stk014.c
index 2e2935532d99..0fb534210a2c 100644
--- a/drivers/media/video/gspca/stk014.c
+++ b/drivers/media/video/gspca/stk014.c
@@ -53,7 +53,7 @@ static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val);
53static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val); 53static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val);
54static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val); 54static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val);
55 55
56static struct ctrl sd_ctrls[] = { 56static const struct ctrl sd_ctrls[] = {
57 { 57 {
58 { 58 {
59 .id = V4L2_CID_BRIGHTNESS, 59 .id = V4L2_CID_BRIGHTNESS,
diff --git a/drivers/media/video/gspca/stv0680.c b/drivers/media/video/gspca/stv0680.c
index 2a69d7ccb50d..e50dd7693f74 100644
--- a/drivers/media/video/gspca/stv0680.c
+++ b/drivers/media/video/gspca/stv0680.c
@@ -45,7 +45,7 @@ struct sd {
45}; 45};
46 46
47/* V4L2 controls supported by the driver */ 47/* V4L2 controls supported by the driver */
48static struct ctrl sd_ctrls[] = { 48static const struct ctrl sd_ctrls[] = {
49}; 49};
50 50
51static int stv_sndctrl(struct gspca_dev *gspca_dev, int set, u8 req, u16 val, 51static int stv_sndctrl(struct gspca_dev *gspca_dev, int set, u8 req, u16 val,
@@ -53,24 +53,28 @@ static int stv_sndctrl(struct gspca_dev *gspca_dev, int set, u8 req, u16 val,
53{ 53{
54 int ret = -1; 54 int ret = -1;
55 u8 req_type = 0; 55 u8 req_type = 0;
56 unsigned int pipe = 0;
56 57
57 switch (set) { 58 switch (set) {
58 case 0: /* 0xc1 */ 59 case 0: /* 0xc1 */
59 req_type = USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_ENDPOINT; 60 req_type = USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_ENDPOINT;
61 pipe = usb_rcvctrlpipe(gspca_dev->dev, 0);
60 break; 62 break;
61 case 1: /* 0x41 */ 63 case 1: /* 0x41 */
62 req_type = USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_ENDPOINT; 64 req_type = USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_ENDPOINT;
65 pipe = usb_sndctrlpipe(gspca_dev->dev, 0);
63 break; 66 break;
64 case 2: /* 0x80 */ 67 case 2: /* 0x80 */
65 req_type = USB_DIR_IN | USB_RECIP_DEVICE; 68 req_type = USB_DIR_IN | USB_RECIP_DEVICE;
69 pipe = usb_rcvctrlpipe(gspca_dev->dev, 0);
66 break; 70 break;
67 case 3: /* 0x40 */ 71 case 3: /* 0x40 */
68 req_type = USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE; 72 req_type = USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE;
73 pipe = usb_sndctrlpipe(gspca_dev->dev, 0);
69 break; 74 break;
70 } 75 }
71 76
72 ret = usb_control_msg(gspca_dev->dev, 77 ret = usb_control_msg(gspca_dev->dev, pipe,
73 usb_rcvctrlpipe(gspca_dev->dev, 0),
74 req, req_type, 78 req, req_type,
75 val, 0, gspca_dev->usb_buf, size, 500); 79 val, 0, gspca_dev->usb_buf, size, 500);
76 80
@@ -138,6 +142,10 @@ static int sd_config(struct gspca_dev *gspca_dev,
138 struct sd *sd = (struct sd *) gspca_dev; 142 struct sd *sd = (struct sd *) gspca_dev;
139 struct cam *cam = &gspca_dev->cam; 143 struct cam *cam = &gspca_dev->cam;
140 144
145 /* Give the camera some time to settle, otherwise initalization will
146 fail on hotplug, and yes it really needs a full second. */
147 msleep(1000);
148
141 /* ping camera to be sure STV0680 is present */ 149 /* ping camera to be sure STV0680 is present */
142 if (stv_sndctrl(gspca_dev, 0, 0x88, 0x5678, 0x02) != 0x02 || 150 if (stv_sndctrl(gspca_dev, 0, 0x88, 0x5678, 0x02) != 0x02 ||
143 gspca_dev->usb_buf[0] != 0x56 || gspca_dev->usb_buf[1] != 0x78) { 151 gspca_dev->usb_buf[0] != 0x56 || gspca_dev->usb_buf[1] != 0x78) {
@@ -169,6 +177,8 @@ static int sd_config(struct gspca_dev *gspca_dev,
169 PDEBUG(D_PROBE, "Camera supports CIF mode"); 177 PDEBUG(D_PROBE, "Camera supports CIF mode");
170 if (gspca_dev->usb_buf[7] & 0x02) 178 if (gspca_dev->usb_buf[7] & 0x02)
171 PDEBUG(D_PROBE, "Camera supports VGA mode"); 179 PDEBUG(D_PROBE, "Camera supports VGA mode");
180 if (gspca_dev->usb_buf[7] & 0x04)
181 PDEBUG(D_PROBE, "Camera supports QCIF mode");
172 if (gspca_dev->usb_buf[7] & 0x08) 182 if (gspca_dev->usb_buf[7] & 0x08)
173 PDEBUG(D_PROBE, "Camera supports QVGA mode"); 183 PDEBUG(D_PROBE, "Camera supports QVGA mode");
174 184
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx.c b/drivers/media/video/gspca/stv06xx/stv06xx.c
index 5d0241bb1611..af73da34c83f 100644
--- a/drivers/media/video/gspca/stv06xx/stv06xx.c
+++ b/drivers/media/video/gspca/stv06xx/stv06xx.c
@@ -27,6 +27,7 @@
27 * P/N 861040-0000: Sensor ST VV6410 ASIC STV0610 - QuickCam Web 27 * P/N 861040-0000: Sensor ST VV6410 ASIC STV0610 - QuickCam Web
28 */ 28 */
29 29
30#include <linux/input.h>
30#include "stv06xx_sensor.h" 31#include "stv06xx_sensor.h"
31 32
32MODULE_AUTHOR("Erik Andrén"); 33MODULE_AUTHOR("Erik Andrén");
@@ -219,6 +220,7 @@ static void stv06xx_dump_bridge(struct sd *sd)
219 info("Read 0x%x from address 0x%x", data, i); 220 info("Read 0x%x from address 0x%x", data, i);
220 } 221 }
221 222
223 info("Testing stv06xx bridge registers for writability");
222 for (i = 0x1400; i < 0x160f; i++) { 224 for (i = 0x1400; i < 0x160f; i++) {
223 stv06xx_read_bridge(sd, i, &data); 225 stv06xx_read_bridge(sd, i, &data);
224 buf = data; 226 buf = data;
@@ -229,7 +231,7 @@ static void stv06xx_dump_bridge(struct sd *sd)
229 info("Register 0x%x is read/write", i); 231 info("Register 0x%x is read/write", i);
230 else if (data != buf) 232 else if (data != buf)
231 info("Register 0x%x is read/write," 233 info("Register 0x%x is read/write,"
232 "but only partially", i); 234 " but only partially", i);
233 else 235 else
234 info("Register 0x%x is read-only", i); 236 info("Register 0x%x is read-only", i);
235 237
@@ -426,6 +428,29 @@ frame_data:
426 } 428 }
427} 429}
428 430
431#ifdef CONFIG_INPUT
432static int sd_int_pkt_scan(struct gspca_dev *gspca_dev,
433 u8 *data, /* interrupt packet data */
434 int len) /* interrupt packet length */
435{
436 int ret = -EINVAL;
437
438 if (len == 1 && data[0] == 0x80) {
439 input_report_key(gspca_dev->input_dev, KEY_CAMERA, 1);
440 input_sync(gspca_dev->input_dev);
441 ret = 0;
442 }
443
444 if (len == 1 && data[0] == 0x88) {
445 input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0);
446 input_sync(gspca_dev->input_dev);
447 ret = 0;
448 }
449
450 return ret;
451}
452#endif
453
429static int stv06xx_config(struct gspca_dev *gspca_dev, 454static int stv06xx_config(struct gspca_dev *gspca_dev,
430 const struct usb_device_id *id); 455 const struct usb_device_id *id);
431 456
@@ -436,7 +461,10 @@ static const struct sd_desc sd_desc = {
436 .init = stv06xx_init, 461 .init = stv06xx_init,
437 .start = stv06xx_start, 462 .start = stv06xx_start,
438 .stopN = stv06xx_stopN, 463 .stopN = stv06xx_stopN,
439 .pkt_scan = stv06xx_pkt_scan 464 .pkt_scan = stv06xx_pkt_scan,
465#ifdef CONFIG_INPUT
466 .int_pkt_scan = sd_int_pkt_scan,
467#endif
440}; 468};
441 469
442/* This function is called at probe time */ 470/* This function is called at probe time */
diff --git a/drivers/media/video/gspca/sunplus.c b/drivers/media/video/gspca/sunplus.c
index 306b7d75b4aa..0c786e00ebcf 100644
--- a/drivers/media/video/gspca/sunplus.c
+++ b/drivers/media/video/gspca/sunplus.c
@@ -67,7 +67,7 @@ static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val);
67static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val); 67static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
68static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val); 68static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val);
69 69
70static struct ctrl sd_ctrls[] = { 70static const struct ctrl sd_ctrls[] = {
71 { 71 {
72 { 72 {
73 .id = V4L2_CID_BRIGHTNESS, 73 .id = V4L2_CID_BRIGHTNESS,
@@ -267,142 +267,6 @@ static const struct cmd spca504A_clicksmart420_open_data[] = {
267 {0x06, 0x0000, 0x0000}, 267 {0x06, 0x0000, 0x0000},
268 {0x00, 0x0004, 0x2880}, 268 {0x00, 0x0004, 0x2880},
269 {0x00, 0x0001, 0x2881}, 269 {0x00, 0x0001, 0x2881},
270/* look like setting a qTable */
271 {0x00, 0x0006, 0x2800},
272 {0x00, 0x0004, 0x2801},
273 {0x00, 0x0004, 0x2802},
274 {0x00, 0x0006, 0x2803},
275 {0x00, 0x000a, 0x2804},
276 {0x00, 0x0010, 0x2805},
277 {0x00, 0x0014, 0x2806},
278 {0x00, 0x0018, 0x2807},
279 {0x00, 0x0005, 0x2808},
280 {0x00, 0x0005, 0x2809},
281 {0x00, 0x0006, 0x280a},
282 {0x00, 0x0008, 0x280b},
283 {0x00, 0x000a, 0x280c},
284 {0x00, 0x0017, 0x280d},
285 {0x00, 0x0018, 0x280e},
286 {0x00, 0x0016, 0x280f},
287
288 {0x00, 0x0006, 0x2810},
289 {0x00, 0x0005, 0x2811},
290 {0x00, 0x0006, 0x2812},
291 {0x00, 0x000a, 0x2813},
292 {0x00, 0x0010, 0x2814},
293 {0x00, 0x0017, 0x2815},
294 {0x00, 0x001c, 0x2816},
295 {0x00, 0x0016, 0x2817},
296 {0x00, 0x0006, 0x2818},
297 {0x00, 0x0007, 0x2819},
298 {0x00, 0x0009, 0x281a},
299 {0x00, 0x000c, 0x281b},
300 {0x00, 0x0014, 0x281c},
301 {0x00, 0x0023, 0x281d},
302 {0x00, 0x0020, 0x281e},
303 {0x00, 0x0019, 0x281f},
304
305 {0x00, 0x0007, 0x2820},
306 {0x00, 0x0009, 0x2821},
307 {0x00, 0x000f, 0x2822},
308 {0x00, 0x0016, 0x2823},
309 {0x00, 0x001b, 0x2824},
310 {0x00, 0x002c, 0x2825},
311 {0x00, 0x0029, 0x2826},
312 {0x00, 0x001f, 0x2827},
313 {0x00, 0x000a, 0x2828},
314 {0x00, 0x000e, 0x2829},
315 {0x00, 0x0016, 0x282a},
316 {0x00, 0x001a, 0x282b},
317 {0x00, 0x0020, 0x282c},
318 {0x00, 0x002a, 0x282d},
319 {0x00, 0x002d, 0x282e},
320 {0x00, 0x0025, 0x282f},
321
322 {0x00, 0x0014, 0x2830},
323 {0x00, 0x001a, 0x2831},
324 {0x00, 0x001f, 0x2832},
325 {0x00, 0x0023, 0x2833},
326 {0x00, 0x0029, 0x2834},
327 {0x00, 0x0030, 0x2835},
328 {0x00, 0x0030, 0x2836},
329 {0x00, 0x0028, 0x2837},
330 {0x00, 0x001d, 0x2838},
331 {0x00, 0x0025, 0x2839},
332 {0x00, 0x0026, 0x283a},
333 {0x00, 0x0027, 0x283b},
334 {0x00, 0x002d, 0x283c},
335 {0x00, 0x0028, 0x283d},
336 {0x00, 0x0029, 0x283e},
337 {0x00, 0x0028, 0x283f},
338
339 {0x00, 0x0007, 0x2840},
340 {0x00, 0x0007, 0x2841},
341 {0x00, 0x000a, 0x2842},
342 {0x00, 0x0013, 0x2843},
343 {0x00, 0x0028, 0x2844},
344 {0x00, 0x0028, 0x2845},
345 {0x00, 0x0028, 0x2846},
346 {0x00, 0x0028, 0x2847},
347 {0x00, 0x0007, 0x2848},
348 {0x00, 0x0008, 0x2849},
349 {0x00, 0x000a, 0x284a},
350 {0x00, 0x001a, 0x284b},
351 {0x00, 0x0028, 0x284c},
352 {0x00, 0x0028, 0x284d},
353 {0x00, 0x0028, 0x284e},
354 {0x00, 0x0028, 0x284f},
355
356 {0x00, 0x000a, 0x2850},
357 {0x00, 0x000a, 0x2851},
358 {0x00, 0x0016, 0x2852},
359 {0x00, 0x0028, 0x2853},
360 {0x00, 0x0028, 0x2854},
361 {0x00, 0x0028, 0x2855},
362 {0x00, 0x0028, 0x2856},
363 {0x00, 0x0028, 0x2857},
364 {0x00, 0x0013, 0x2858},
365 {0x00, 0x001a, 0x2859},
366 {0x00, 0x0028, 0x285a},
367 {0x00, 0x0028, 0x285b},
368 {0x00, 0x0028, 0x285c},
369 {0x00, 0x0028, 0x285d},
370 {0x00, 0x0028, 0x285e},
371 {0x00, 0x0028, 0x285f},
372
373 {0x00, 0x0028, 0x2860},
374 {0x00, 0x0028, 0x2861},
375 {0x00, 0x0028, 0x2862},
376 {0x00, 0x0028, 0x2863},
377 {0x00, 0x0028, 0x2864},
378 {0x00, 0x0028, 0x2865},
379 {0x00, 0x0028, 0x2866},
380 {0x00, 0x0028, 0x2867},
381 {0x00, 0x0028, 0x2868},
382 {0x00, 0x0028, 0x2869},
383 {0x00, 0x0028, 0x286a},
384 {0x00, 0x0028, 0x286b},
385 {0x00, 0x0028, 0x286c},
386 {0x00, 0x0028, 0x286d},
387 {0x00, 0x0028, 0x286e},
388 {0x00, 0x0028, 0x286f},
389
390 {0x00, 0x0028, 0x2870},
391 {0x00, 0x0028, 0x2871},
392 {0x00, 0x0028, 0x2872},
393 {0x00, 0x0028, 0x2873},
394 {0x00, 0x0028, 0x2874},
395 {0x00, 0x0028, 0x2875},
396 {0x00, 0x0028, 0x2876},
397 {0x00, 0x0028, 0x2877},
398 {0x00, 0x0028, 0x2878},
399 {0x00, 0x0028, 0x2879},
400 {0x00, 0x0028, 0x287a},
401 {0x00, 0x0028, 0x287b},
402 {0x00, 0x0028, 0x287c},
403 {0x00, 0x0028, 0x287d},
404 {0x00, 0x0028, 0x287e},
405 {0x00, 0x0028, 0x287f},
406 270
407 {0xa0, 0x0000, 0x0503}, 271 {0xa0, 0x0000, 0x0503},
408}; 272};
@@ -622,6 +486,20 @@ static void spca504_acknowledged_command(struct gspca_dev *gspca_dev,
622 PDEBUG(D_FRAM, "after wait 0x%04x", notdone); 486 PDEBUG(D_FRAM, "after wait 0x%04x", notdone);
623} 487}
624 488
489static void spca504_read_info(struct gspca_dev *gspca_dev)
490{
491 int i;
492 u8 info[6];
493
494 for (i = 0; i < 6; i++)
495 info[i] = reg_r_1(gspca_dev, i);
496 PDEBUG(D_STREAM,
497 "Read info: %d %d %d %d %d %d."
498 " Should be 1,0,2,2,0,0",
499 info[0], info[1], info[2],
500 info[3], info[4], info[5]);
501}
502
625static void spca504A_acknowledged_command(struct gspca_dev *gspca_dev, 503static void spca504A_acknowledged_command(struct gspca_dev *gspca_dev,
626 u8 req, 504 u8 req,
627 u16 idx, u16 val, u16 endcode, u8 count) 505 u16 idx, u16 val, u16 endcode, u8 count)
@@ -881,8 +759,6 @@ static int sd_config(struct gspca_dev *gspca_dev,
881static int sd_init(struct gspca_dev *gspca_dev) 759static int sd_init(struct gspca_dev *gspca_dev)
882{ 760{
883 struct sd *sd = (struct sd *) gspca_dev; 761 struct sd *sd = (struct sd *) gspca_dev;
884 int i;
885 u8 info[6];
886 762
887 switch (sd->bridge) { 763 switch (sd->bridge) {
888 case BRIDGE_SPCA504B: 764 case BRIDGE_SPCA504B:
@@ -924,15 +800,8 @@ static int sd_init(struct gspca_dev *gspca_dev)
924/* case BRIDGE_SPCA504: */ 800/* case BRIDGE_SPCA504: */
925 PDEBUG(D_STREAM, "Opening SPCA504"); 801 PDEBUG(D_STREAM, "Opening SPCA504");
926 if (sd->subtype == AiptekMiniPenCam13) { 802 if (sd->subtype == AiptekMiniPenCam13) {
927 /*****************************/ 803 spca504_read_info(gspca_dev);
928 for (i = 0; i < 6; i++) 804
929 info[i] = reg_r_1(gspca_dev, i);
930 PDEBUG(D_STREAM,
931 "Read info: %d %d %d %d %d %d."
932 " Should be 1,0,2,2,0,0",
933 info[0], info[1], info[2],
934 info[3], info[4], info[5]);
935 /* spca504a aiptek */
936 /* Set AE AWB Banding Type 3-> 50Hz 2-> 60Hz */ 805 /* Set AE AWB Banding Type 3-> 50Hz 2-> 60Hz */
937 spca504A_acknowledged_command(gspca_dev, 0x24, 806 spca504A_acknowledged_command(gspca_dev, 0x24,
938 8, 3, 0x9e, 1); 807 8, 3, 0x9e, 1);
@@ -971,8 +840,6 @@ static int sd_start(struct gspca_dev *gspca_dev)
971{ 840{
972 struct sd *sd = (struct sd *) gspca_dev; 841 struct sd *sd = (struct sd *) gspca_dev;
973 int enable; 842 int enable;
974 int i;
975 u8 info[6];
976 843
977 /* create the JPEG header */ 844 /* create the JPEG header */
978 sd->jpeg_hdr = kmalloc(JPEG_HDR_SZ, GFP_KERNEL); 845 sd->jpeg_hdr = kmalloc(JPEG_HDR_SZ, GFP_KERNEL);
@@ -1008,14 +875,8 @@ static int sd_start(struct gspca_dev *gspca_dev)
1008 break; 875 break;
1009 case BRIDGE_SPCA504: 876 case BRIDGE_SPCA504:
1010 if (sd->subtype == AiptekMiniPenCam13) { 877 if (sd->subtype == AiptekMiniPenCam13) {
1011 for (i = 0; i < 6; i++) 878 spca504_read_info(gspca_dev);
1012 info[i] = reg_r_1(gspca_dev, i); 879
1013 PDEBUG(D_STREAM,
1014 "Read info: %d %d %d %d %d %d."
1015 " Should be 1,0,2,2,0,0",
1016 info[0], info[1], info[2],
1017 info[3], info[4], info[5]);
1018 /* spca504a aiptek */
1019 /* Set AE AWB Banding Type 3-> 50Hz 2-> 60Hz */ 880 /* Set AE AWB Banding Type 3-> 50Hz 2-> 60Hz */
1020 spca504A_acknowledged_command(gspca_dev, 0x24, 881 spca504A_acknowledged_command(gspca_dev, 0x24,
1021 8, 3, 0x9e, 1); 882 8, 3, 0x9e, 1);
@@ -1026,13 +887,7 @@ static int sd_start(struct gspca_dev *gspca_dev)
1026 0, 0, 0x9d, 1); 887 0, 0, 0x9d, 1);
1027 } else { 888 } else {
1028 spca504_acknowledged_command(gspca_dev, 0x24, 8, 3); 889 spca504_acknowledged_command(gspca_dev, 0x24, 8, 3);
1029 for (i = 0; i < 6; i++) 890 spca504_read_info(gspca_dev);
1030 info[i] = reg_r_1(gspca_dev, i);
1031 PDEBUG(D_STREAM,
1032 "Read info: %d %d %d %d %d %d."
1033 " Should be 1,0,2,2,0,0",
1034 info[0], info[1], info[2],
1035 info[3], info[4], info[5]);
1036 spca504_acknowledged_command(gspca_dev, 0x24, 8, 3); 891 spca504_acknowledged_command(gspca_dev, 0x24, 8, 3);
1037 spca504_acknowledged_command(gspca_dev, 0x24, 0, 0); 892 spca504_acknowledged_command(gspca_dev, 0x24, 0, 0);
1038 } 893 }
@@ -1336,6 +1191,7 @@ static const __devinitdata struct usb_device_id device_table[] = {
1336 {USB_DEVICE(0x04fc, 0x5330), BS(SPCA533, 0)}, 1191 {USB_DEVICE(0x04fc, 0x5330), BS(SPCA533, 0)},
1337 {USB_DEVICE(0x04fc, 0x5360), BS(SPCA536, 0)}, 1192 {USB_DEVICE(0x04fc, 0x5360), BS(SPCA536, 0)},
1338 {USB_DEVICE(0x04fc, 0xffff), BS(SPCA504B, 0)}, 1193 {USB_DEVICE(0x04fc, 0xffff), BS(SPCA504B, 0)},
1194 {USB_DEVICE(0x052b, 0x1507), BS(SPCA533, MegapixV4)},
1339 {USB_DEVICE(0x052b, 0x1513), BS(SPCA533, MegapixV4)}, 1195 {USB_DEVICE(0x052b, 0x1513), BS(SPCA533, MegapixV4)},
1340 {USB_DEVICE(0x052b, 0x1803), BS(SPCA533, MegaImageVI)}, 1196 {USB_DEVICE(0x052b, 0x1803), BS(SPCA533, MegaImageVI)},
1341 {USB_DEVICE(0x0546, 0x3155), BS(SPCA533, 0)}, 1197 {USB_DEVICE(0x0546, 0x3155), BS(SPCA533, 0)},
diff --git a/drivers/media/video/gspca/t613.c b/drivers/media/video/gspca/t613.c
index 55ef6a744427..668a7536af90 100644
--- a/drivers/media/video/gspca/t613.c
+++ b/drivers/media/video/gspca/t613.c
@@ -52,6 +52,7 @@ struct sd {
52#define SENSOR_OM6802 0 52#define SENSOR_OM6802 0
53#define SENSOR_OTHER 1 53#define SENSOR_OTHER 1
54#define SENSOR_TAS5130A 2 54#define SENSOR_TAS5130A 2
55#define SENSOR_LT168G 3 /* must verify if this is the actual model */
55}; 56};
56 57
57/* V4L2 controls supported by the driver */ 58/* V4L2 controls supported by the driver */
@@ -78,7 +79,7 @@ static int sd_geteffect(struct gspca_dev *gspca_dev, __s32 *val);
78static int sd_querymenu(struct gspca_dev *gspca_dev, 79static int sd_querymenu(struct gspca_dev *gspca_dev,
79 struct v4l2_querymenu *menu); 80 struct v4l2_querymenu *menu);
80 81
81static struct ctrl sd_ctrls[] = { 82static const struct ctrl sd_ctrls[] = {
82 { 83 {
83 { 84 {
84 .id = V4L2_CID_BRIGHTNESS, 85 .id = V4L2_CID_BRIGHTNESS,
@@ -306,6 +307,17 @@ static const u8 n4_tas5130a[] = {
306 0xbe, 0x36, 0xbf, 0xff, 0xc2, 0x88, 0xc5, 0xc8, 307 0xbe, 0x36, 0xbf, 0xff, 0xc2, 0x88, 0xc5, 0xc8,
307 0xc6, 0xda 308 0xc6, 0xda
308}; 309};
310static const u8 n4_lt168g[] = {
311 0x66, 0x01, 0x7f, 0x00, 0x80, 0x7c, 0x81, 0x28,
312 0x83, 0x44, 0x84, 0x20, 0x86, 0x20, 0x8a, 0x70,
313 0x8b, 0x58, 0x8c, 0x88, 0x8d, 0xa0, 0x8e, 0xb3,
314 0x8f, 0x24, 0xa1, 0xb0, 0xa2, 0x38, 0xa5, 0x20,
315 0xa6, 0x4a, 0xa8, 0xe8, 0xaf, 0x38, 0xb0, 0x68,
316 0xb1, 0x44, 0xb2, 0x88, 0xbb, 0x86, 0xbd, 0x40,
317 0xbe, 0x26, 0xc1, 0x05, 0xc2, 0x88, 0xc5, 0xc0,
318 0xda, 0x8e, 0xdb, 0xca, 0xdc, 0xa8, 0xdd, 0x8c,
319 0xde, 0x44, 0xdf, 0x0c, 0xe9, 0x80
320};
309 321
310static const struct additional_sensor_data sensor_data[] = { 322static const struct additional_sensor_data sensor_data[] = {
311 { /* 0: OM6802 */ 323 { /* 0: OM6802 */
@@ -380,6 +392,23 @@ static const struct additional_sensor_data sensor_data[] = {
380 .stream = 392 .stream =
381 {0x0b, 0x04, 0x0a, 0x40}, 393 {0x0b, 0x04, 0x0a, 0x40},
382 }, 394 },
395 { /* 3: LT168G */
396 .n3 = {0x61, 0xc2, 0x65, 0x68, 0x60, 0x00},
397 .n4 = n4_lt168g,
398 .n4sz = sizeof n4_lt168g,
399 .reg80 = 0x7c,
400 .reg8e = 0xb3,
401 .nset8 = {0xa8, 0xf0, 0xc6, 0xba, 0xc0, 0x00},
402 .data1 = {0xc0, 0x38, 0x08, 0x10, 0xc0, 0x30, 0x10, 0x40,
403 0xb0, 0xf4},
404 .data2 = {0x40, 0x80, 0xc0, 0x50, 0xa0, 0xf0, 0x53, 0xa6,
405 0xff},
406 .data3 = {0x40, 0x80, 0xc0, 0x50, 0xa0, 0xf0, 0x53, 0xa6,
407 0xff},
408 .data4 = {0x66, 0x41, 0xa8, 0xf0},
409 .data5 = {0x0c, 0x03, 0xab, 0x4b, 0x81, 0x2b},
410 .stream = {0x0b, 0x04, 0x0a, 0x28},
411 },
383}; 412};
384 413
385#define MAX_EFFECTS 7 414#define MAX_EFFECTS 7
@@ -716,6 +745,10 @@ static int sd_init(struct gspca_dev *gspca_dev)
716 PDEBUG(D_PROBE, "sensor tas5130a"); 745 PDEBUG(D_PROBE, "sensor tas5130a");
717 sd->sensor = SENSOR_TAS5130A; 746 sd->sensor = SENSOR_TAS5130A;
718 break; 747 break;
748 case 0x0802:
749 PDEBUG(D_PROBE, "sensor lt168g");
750 sd->sensor = SENSOR_LT168G;
751 break;
719 case 0x0803: 752 case 0x0803:
720 PDEBUG(D_PROBE, "sensor 'other'"); 753 PDEBUG(D_PROBE, "sensor 'other'");
721 sd->sensor = SENSOR_OTHER; 754 sd->sensor = SENSOR_OTHER;
@@ -758,6 +791,13 @@ static int sd_init(struct gspca_dev *gspca_dev)
758 reg_w_buf(gspca_dev, sensor->n3, sizeof sensor->n3); 791 reg_w_buf(gspca_dev, sensor->n3, sizeof sensor->n3);
759 reg_w_buf(gspca_dev, sensor->n4, sensor->n4sz); 792 reg_w_buf(gspca_dev, sensor->n4, sensor->n4sz);
760 793
794 if (sd->sensor == SENSOR_LT168G) {
795 test_byte = reg_r(gspca_dev, 0x80);
796 PDEBUG(D_STREAM, "Reg 0x%02x = 0x%02x", 0x80,
797 test_byte);
798 reg_w(gspca_dev, 0x6c80);
799 }
800
761 reg_w_ixbuf(gspca_dev, 0xd0, sensor->data1, sizeof sensor->data1); 801 reg_w_ixbuf(gspca_dev, 0xd0, sensor->data1, sizeof sensor->data1);
762 reg_w_ixbuf(gspca_dev, 0xc7, sensor->data2, sizeof sensor->data2); 802 reg_w_ixbuf(gspca_dev, 0xc7, sensor->data2, sizeof sensor->data2);
763 reg_w_ixbuf(gspca_dev, 0xe0, sensor->data3, sizeof sensor->data3); 803 reg_w_ixbuf(gspca_dev, 0xe0, sensor->data3, sizeof sensor->data3);
@@ -782,6 +822,13 @@ static int sd_init(struct gspca_dev *gspca_dev)
782 reg_w_buf(gspca_dev, sensor->nset8, sizeof sensor->nset8); 822 reg_w_buf(gspca_dev, sensor->nset8, sizeof sensor->nset8);
783 reg_w_buf(gspca_dev, sensor->stream, sizeof sensor->stream); 823 reg_w_buf(gspca_dev, sensor->stream, sizeof sensor->stream);
784 824
825 if (sd->sensor == SENSOR_LT168G) {
826 test_byte = reg_r(gspca_dev, 0x80);
827 PDEBUG(D_STREAM, "Reg 0x%02x = 0x%02x", 0x80,
828 test_byte);
829 reg_w(gspca_dev, 0x6c80);
830 }
831
785 reg_w_ixbuf(gspca_dev, 0xd0, sensor->data1, sizeof sensor->data1); 832 reg_w_ixbuf(gspca_dev, 0xd0, sensor->data1, sizeof sensor->data1);
786 reg_w_ixbuf(gspca_dev, 0xc7, sensor->data2, sizeof sensor->data2); 833 reg_w_ixbuf(gspca_dev, 0xc7, sensor->data2, sizeof sensor->data2);
787 reg_w_ixbuf(gspca_dev, 0xe0, sensor->data3, sizeof sensor->data3); 834 reg_w_ixbuf(gspca_dev, 0xe0, sensor->data3, sizeof sensor->data3);
@@ -888,6 +935,8 @@ static int sd_start(struct gspca_dev *gspca_dev)
888 case SENSOR_OM6802: 935 case SENSOR_OM6802:
889 om6802_sensor_init(gspca_dev); 936 om6802_sensor_init(gspca_dev);
890 break; 937 break;
938 case SENSOR_LT168G:
939 break;
891 case SENSOR_OTHER: 940 case SENSOR_OTHER:
892 break; 941 break;
893 default: 942 default:
diff --git a/drivers/media/video/gspca/tv8532.c b/drivers/media/video/gspca/tv8532.c
index b74a3b6489c7..c7b6eb1e04d5 100644
--- a/drivers/media/video/gspca/tv8532.c
+++ b/drivers/media/video/gspca/tv8532.c
@@ -39,7 +39,7 @@ struct sd {
39static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val); 39static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
40static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val); 40static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
41 41
42static struct ctrl sd_ctrls[] = { 42static const struct ctrl sd_ctrls[] = {
43 { 43 {
44 { 44 {
45 .id = V4L2_CID_BRIGHTNESS, 45 .id = V4L2_CID_BRIGHTNESS,
diff --git a/drivers/media/video/gspca/vc032x.c b/drivers/media/video/gspca/vc032x.c
index 71921c878424..4989f9afb46e 100644
--- a/drivers/media/video/gspca/vc032x.c
+++ b/drivers/media/video/gspca/vc032x.c
@@ -32,10 +32,13 @@ MODULE_LICENSE("GPL");
32struct sd { 32struct sd {
33 struct gspca_dev gspca_dev; /* !! must be the first item */ 33 struct gspca_dev gspca_dev; /* !! must be the first item */
34 34
35 u8 brightness;
36 u8 contrast;
37 u8 colors;
35 u8 hflip; 38 u8 hflip;
36 u8 vflip; 39 u8 vflip;
37 u8 lightfreq; 40 u8 lightfreq;
38 u8 sharpness; 41 s8 sharpness;
39 42
40 u8 image_offset; 43 u8 image_offset;
41 44
@@ -52,6 +55,7 @@ struct sd {
52#define SENSOR_OV7670 6 55#define SENSOR_OV7670 6
53#define SENSOR_PO1200 7 56#define SENSOR_PO1200 7
54#define SENSOR_PO3130NC 8 57#define SENSOR_PO3130NC 8
58#define SENSOR_POxxxx 9
55 u8 flags; 59 u8 flags;
56#define FL_SAMSUNG 0x01 /* SamsungQ1 (2 sensors) */ 60#define FL_SAMSUNG 0x01 /* SamsungQ1 (2 sensors) */
57#define FL_HFLIP 0x02 /* mirrored by default */ 61#define FL_HFLIP 0x02 /* mirrored by default */
@@ -59,6 +63,12 @@ struct sd {
59}; 63};
60 64
61/* V4L2 controls supported by the driver */ 65/* V4L2 controls supported by the driver */
66static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
67static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
68static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
69static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
70static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val);
71static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val);
62static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val); 72static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val);
63static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val); 73static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val);
64static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val); 74static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val);
@@ -68,9 +78,54 @@ static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val);
68static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val); 78static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val);
69static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val); 79static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val);
70 80
71static struct ctrl sd_ctrls[] = { 81static const struct ctrl sd_ctrls[] = {
82#define BRIGHTNESS_IDX 0
83 {
84 {
85 .id = V4L2_CID_BRIGHTNESS,
86 .type = V4L2_CTRL_TYPE_INTEGER,
87 .name = "Brightness",
88 .minimum = 0,
89 .maximum = 255,
90 .step = 1,
91#define BRIGHTNESS_DEF 128
92 .default_value = BRIGHTNESS_DEF,
93 },
94 .set = sd_setbrightness,
95 .get = sd_getbrightness,
96 },
97#define CONTRAST_IDX 1
98 {
99 {
100 .id = V4L2_CID_CONTRAST,
101 .type = V4L2_CTRL_TYPE_INTEGER,
102 .name = "Contrast",
103 .minimum = 0,
104 .maximum = 255,
105 .step = 1,
106#define CONTRAST_DEF 127
107 .default_value = CONTRAST_DEF,
108 },
109 .set = sd_setcontrast,
110 .get = sd_getcontrast,
111 },
112#define COLORS_IDX 2
113 {
114 {
115 .id = V4L2_CID_SATURATION,
116 .type = V4L2_CTRL_TYPE_INTEGER,
117 .name = "Saturation",
118 .minimum = 1,
119 .maximum = 127,
120 .step = 1,
121#define COLOR_DEF 63
122 .default_value = COLOR_DEF,
123 },
124 .set = sd_setcolors,
125 .get = sd_getcolors,
126 },
72/* next 2 controls work with some sensors only */ 127/* next 2 controls work with some sensors only */
73#define HFLIP_IDX 0 128#define HFLIP_IDX 3
74 { 129 {
75 { 130 {
76 .id = V4L2_CID_HFLIP, 131 .id = V4L2_CID_HFLIP,
@@ -85,7 +140,7 @@ static struct ctrl sd_ctrls[] = {
85 .set = sd_sethflip, 140 .set = sd_sethflip,
86 .get = sd_gethflip, 141 .get = sd_gethflip,
87 }, 142 },
88#define VFLIP_IDX 1 143#define VFLIP_IDX 4
89 { 144 {
90 { 145 {
91 .id = V4L2_CID_VFLIP, 146 .id = V4L2_CID_VFLIP,
@@ -100,7 +155,7 @@ static struct ctrl sd_ctrls[] = {
100 .set = sd_setvflip, 155 .set = sd_setvflip,
101 .get = sd_getvflip, 156 .get = sd_getvflip,
102 }, 157 },
103#define LIGHTFREQ_IDX 2 158#define LIGHTFREQ_IDX 5
104 { 159 {
105 { 160 {
106 .id = V4L2_CID_POWER_LINE_FREQUENCY, 161 .id = V4L2_CID_POWER_LINE_FREQUENCY,
@@ -115,17 +170,16 @@ static struct ctrl sd_ctrls[] = {
115 .set = sd_setfreq, 170 .set = sd_setfreq,
116 .get = sd_getfreq, 171 .get = sd_getfreq,
117 }, 172 },
118/* po1200 only */ 173#define SHARPNESS_IDX 6
119#define SHARPNESS_IDX 3
120 { 174 {
121 { 175 {
122 .id = V4L2_CID_SHARPNESS, 176 .id = V4L2_CID_SHARPNESS,
123 .type = V4L2_CTRL_TYPE_INTEGER, 177 .type = V4L2_CTRL_TYPE_INTEGER,
124 .name = "Sharpness", 178 .name = "Sharpness",
125 .minimum = 0, 179 .minimum = -1,
126 .maximum = 2, 180 .maximum = 2,
127 .step = 1, 181 .step = 1,
128#define SHARPNESS_DEF 1 182#define SHARPNESS_DEF -1
129 .default_value = SHARPNESS_DEF, 183 .default_value = SHARPNESS_DEF,
130 }, 184 },
131 .set = sd_setsharpness, 185 .set = sd_setsharpness,
@@ -133,6 +187,42 @@ static struct ctrl sd_ctrls[] = {
133 }, 187 },
134}; 188};
135 189
190/* table of the disabled controls */
191static u32 ctrl_dis[] = {
192/* SENSOR_HV7131R 0 */
193 (1 << BRIGHTNESS_IDX) | (1 << CONTRAST_IDX) | (1 << COLORS_IDX)
194 | (1 << HFLIP_IDX) | (1 << VFLIP_IDX) | (1 << LIGHTFREQ_IDX)
195 | (1 << SHARPNESS_IDX),
196/* SENSOR_MI0360 1 */
197 (1 << BRIGHTNESS_IDX) | (1 << CONTRAST_IDX) | (1 << COLORS_IDX)
198 | (1 << HFLIP_IDX) | (1 << VFLIP_IDX) | (1 << LIGHTFREQ_IDX)
199 | (1 << SHARPNESS_IDX),
200/* SENSOR_MI1310_SOC 2 */
201 (1 << BRIGHTNESS_IDX) | (1 << CONTRAST_IDX) | (1 << COLORS_IDX)
202 | (1 << LIGHTFREQ_IDX) | (1 << SHARPNESS_IDX),
203/* SENSOR_MI1320 3 */
204 (1 << BRIGHTNESS_IDX) | (1 << CONTRAST_IDX) | (1 << COLORS_IDX)
205 | (1 << LIGHTFREQ_IDX) | (1 << SHARPNESS_IDX),
206/* SENSOR_MI1320_SOC 4 */
207 (1 << BRIGHTNESS_IDX) | (1 << CONTRAST_IDX) | (1 << COLORS_IDX)
208 | (1 << LIGHTFREQ_IDX) | (1 << SHARPNESS_IDX),
209/* SENSOR_OV7660 5 */
210 (1 << BRIGHTNESS_IDX) | (1 << CONTRAST_IDX) | (1 << COLORS_IDX)
211 | (1 << LIGHTFREQ_IDX) | (1 << SHARPNESS_IDX),
212/* SENSOR_OV7670 6 */
213 (1 << BRIGHTNESS_IDX) | (1 << CONTRAST_IDX) | (1 << COLORS_IDX)
214 | (1 << SHARPNESS_IDX),
215/* SENSOR_PO1200 7 */
216 (1 << BRIGHTNESS_IDX) | (1 << CONTRAST_IDX) | (1 << COLORS_IDX)
217 | (1 << LIGHTFREQ_IDX),
218/* SENSOR_PO3130NC 8 */
219 (1 << BRIGHTNESS_IDX) | (1 << CONTRAST_IDX) | (1 << COLORS_IDX)
220 | (1 << HFLIP_IDX) | (1 << VFLIP_IDX) | (1 << LIGHTFREQ_IDX)
221 | (1 << SHARPNESS_IDX),
222/* SENSOR_POxxxx 9 */
223 (1 << HFLIP_IDX) | (1 << VFLIP_IDX) | (1 << LIGHTFREQ_IDX),
224};
225
136static const struct v4l2_pix_format vc0321_mode[] = { 226static const struct v4l2_pix_format vc0321_mode[] = {
137 {320, 240, V4L2_PIX_FMT_YVYU, V4L2_FIELD_NONE, 227 {320, 240, V4L2_PIX_FMT_YVYU, V4L2_FIELD_NONE,
138 .bytesperline = 320, 228 .bytesperline = 320,
@@ -215,7 +305,7 @@ static const u8 mi0360_initVGA_JPG[][4] = {
215 {0xb3, 0x15, 0x00, 0xcc}, 305 {0xb3, 0x15, 0x00, 0xcc},
216 {0xb3, 0x16, 0x02, 0xcc}, 306 {0xb3, 0x16, 0x02, 0xcc},
217 {0xb3, 0x17, 0x7f, 0xcc}, 307 {0xb3, 0x17, 0x7f, 0xcc},
218 {0xb3, 0x35, 0xdd, 0xcc}, 308 {0xb3, 0x35, 0xdd, 0xcc}, /* i2c add: 5d */
219 {0xb3, 0x34, 0x02, 0xcc}, 309 {0xb3, 0x34, 0x02, 0xcc},
220 {0xb3, 0x00, 0x25, 0xcc}, 310 {0xb3, 0x00, 0x25, 0xcc},
221 {0xbc, 0x00, 0x71, 0xcc}, 311 {0xbc, 0x00, 0x71, 0xcc},
@@ -435,7 +525,7 @@ static const u8 mi1310_socinitVGA_JPG[][4] = {
435 {0xb3, 0x08, 0x01, 0xcc}, 525 {0xb3, 0x08, 0x01, 0xcc},
436 {0xb3, 0x09, 0x0c, 0xcc}, 526 {0xb3, 0x09, 0x0c, 0xcc},
437 {0xb3, 0x34, 0x02, 0xcc}, 527 {0xb3, 0x34, 0x02, 0xcc},
438 {0xb3, 0x35, 0xdd, 0xcc}, 528 {0xb3, 0x35, 0xdd, 0xcc}, /* i2c add: 5d */
439 {0xb3, 0x02, 0x00, 0xcc}, 529 {0xb3, 0x02, 0x00, 0xcc},
440 {0xb3, 0x03, 0x0a, 0xcc}, 530 {0xb3, 0x03, 0x0a, 0xcc},
441 {0xb3, 0x04, 0x05, 0xcc}, 531 {0xb3, 0x04, 0x05, 0xcc},
@@ -860,7 +950,8 @@ static const u8 mi1320_initVGA_data[][4] = {
860 {0xb0, 0x16, 0x03, 0xcc}, {0xb3, 0x05, 0x00, 0xcc}, 950 {0xb0, 0x16, 0x03, 0xcc}, {0xb3, 0x05, 0x00, 0xcc},
861 {0xb3, 0x06, 0x00, 0xcc}, {0xb3, 0x08, 0x01, 0xcc}, 951 {0xb3, 0x06, 0x00, 0xcc}, {0xb3, 0x08, 0x01, 0xcc},
862 {0xb3, 0x09, 0x0c, 0xcc}, {0xb3, 0x34, 0x02, 0xcc}, 952 {0xb3, 0x09, 0x0c, 0xcc}, {0xb3, 0x34, 0x02, 0xcc},
863 {0xb3, 0x35, 0xc8, 0xcc}, {0xb3, 0x02, 0x00, 0xcc}, 953 {0xb3, 0x35, 0xc8, 0xcc}, /* i2c add: 48 */
954 {0xb3, 0x02, 0x00, 0xcc},
864 {0xb3, 0x03, 0x0a, 0xcc}, {0xb3, 0x04, 0x05, 0xcc}, 955 {0xb3, 0x03, 0x0a, 0xcc}, {0xb3, 0x04, 0x05, 0xcc},
865 {0xb3, 0x20, 0x00, 0xcc}, {0xb3, 0x21, 0x00, 0xcc}, 956 {0xb3, 0x20, 0x00, 0xcc}, {0xb3, 0x21, 0x00, 0xcc},
866 {0xb3, 0x22, 0x03, 0xcc}, {0xb3, 0x23, 0xc0, 0xcc}, 957 {0xb3, 0x22, 0x03, 0xcc}, {0xb3, 0x23, 0xc0, 0xcc},
@@ -901,7 +992,8 @@ static const u8 mi1320_initVGA_data[][4] = {
901 {0xc3, 0x01, 0x03, 0xbb}, {0xc4, 0x00, 0x04, 0xbb}, 992 {0xc3, 0x01, 0x03, 0xbb}, {0xc4, 0x00, 0x04, 0xbb},
902 {0xf0, 0x00, 0x00, 0xbb}, {0x05, 0x01, 0x13, 0xbb}, 993 {0xf0, 0x00, 0x00, 0xbb}, {0x05, 0x01, 0x13, 0xbb},
903 {0x06, 0x00, 0x11, 0xbb}, {0x07, 0x00, 0x85, 0xbb}, 994 {0x06, 0x00, 0x11, 0xbb}, {0x07, 0x00, 0x85, 0xbb},
904 {0x08, 0x00, 0x27, 0xbb}, {0x20, 0x01, 0x03, 0xbb}, 995 {0x08, 0x00, 0x27, 0xbb},
996 {0x20, 0x01, 0x00, 0xbb}, /* h/v flips - was 03 */
905 {0x21, 0x80, 0x00, 0xbb}, {0x22, 0x0d, 0x0f, 0xbb}, 997 {0x21, 0x80, 0x00, 0xbb}, {0x22, 0x0d, 0x0f, 0xbb},
906 {0x24, 0x80, 0x00, 0xbb}, {0x59, 0x00, 0xff, 0xbb}, 998 {0x24, 0x80, 0x00, 0xbb}, {0x59, 0x00, 0xff, 0xbb},
907 {0xf0, 0x00, 0x02, 0xbb}, {0x39, 0x03, 0x0d, 0xbb}, 999 {0xf0, 0x00, 0x02, 0xbb}, {0x39, 0x03, 0x0d, 0xbb},
@@ -1012,7 +1104,7 @@ static const u8 mi1320_soc_InitVGA[][4] = {
1012 {0xb3, 0x08, 0x01, 0xcc}, 1104 {0xb3, 0x08, 0x01, 0xcc},
1013 {0xb3, 0x09, 0x0c, 0xcc}, 1105 {0xb3, 0x09, 0x0c, 0xcc},
1014 {0xb3, 0x34, 0x02, 0xcc}, 1106 {0xb3, 0x34, 0x02, 0xcc},
1015 {0xb3, 0x35, 0xc8, 0xcc}, 1107 {0xb3, 0x35, 0xc8, 0xcc}, /* i2c add: 48 */
1016 {0xb3, 0x02, 0x00, 0xcc}, 1108 {0xb3, 0x02, 0x00, 0xcc},
1017 {0xb3, 0x03, 0x0a, 0xcc}, 1109 {0xb3, 0x03, 0x0a, 0xcc},
1018 {0xb3, 0x04, 0x05, 0xcc}, 1110 {0xb3, 0x04, 0x05, 0xcc},
@@ -1359,7 +1451,8 @@ static const u8 po3130_initVGA_data[][4] = {
1359 {0xb3, 0x23, 0xe8, 0xcc}, {0xb8, 0x08, 0xe8, 0xcc}, 1451 {0xb3, 0x23, 0xe8, 0xcc}, {0xb8, 0x08, 0xe8, 0xcc},
1360 {0xb3, 0x14, 0x00, 0xcc}, {0xb3, 0x15, 0x00, 0xcc}, 1452 {0xb3, 0x14, 0x00, 0xcc}, {0xb3, 0x15, 0x00, 0xcc},
1361 {0xb3, 0x16, 0x02, 0xcc}, {0xb3, 0x17, 0x7f, 0xcc}, 1453 {0xb3, 0x16, 0x02, 0xcc}, {0xb3, 0x17, 0x7f, 0xcc},
1362 {0xb3, 0x34, 0x01, 0xcc}, {0xb3, 0x35, 0xf6, 0xcc}, 1454 {0xb3, 0x34, 0x01, 0xcc},
1455 {0xb3, 0x35, 0xf6, 0xcc}, /* i2c add: 76 */
1363 {0xb3, 0x00, 0x27, 0xcc}, {0xbc, 0x00, 0x71, 0xcc}, 1456 {0xb3, 0x00, 0x27, 0xcc}, {0xbc, 0x00, 0x71, 0xcc},
1364 {0xb8, 0x00, 0x21, 0xcc}, {0xb8, 0x27, 0x20, 0xcc}, 1457 {0xb8, 0x00, 0x21, 0xcc}, {0xb8, 0x27, 0x20, 0xcc},
1365 {0xb8, 0x01, 0x79, 0xcc}, {0xb8, 0x81, 0x09, 0xcc}, 1458 {0xb8, 0x01, 0x79, 0xcc}, {0xb8, 0x81, 0x09, 0xcc},
@@ -1561,7 +1654,7 @@ static const u8 hv7131r_initVGA_data[][4] = {
1561 {0xb3, 0x16, 0x02, 0xcc}, 1654 {0xb3, 0x16, 0x02, 0xcc},
1562 {0xb3, 0x17, 0x7f, 0xcc}, 1655 {0xb3, 0x17, 0x7f, 0xcc},
1563 {0xb3, 0x34, 0x01, 0xcc}, 1656 {0xb3, 0x34, 0x01, 0xcc},
1564 {0xb3, 0x35, 0x91, 0xcc}, 1657 {0xb3, 0x35, 0x91, 0xcc}, /* i2c add: 11 */
1565 {0xb3, 0x00, 0x27, 0xcc}, 1658 {0xb3, 0x00, 0x27, 0xcc},
1566 {0xbc, 0x00, 0x73, 0xcc}, 1659 {0xbc, 0x00, 0x73, 0xcc},
1567 {0xb8, 0x00, 0x23, 0xcc}, 1660 {0xb8, 0x00, 0x23, 0xcc},
@@ -1747,7 +1840,8 @@ static const u8 ov7660_initVGA_data[][4] = {
1747 {0xb3, 0x23, 0xe0, 0xcc}, {0xb3, 0x1d, 0x01, 0xcc}, 1840 {0xb3, 0x23, 0xe0, 0xcc}, {0xb3, 0x1d, 0x01, 0xcc},
1748 {0xb3, 0x1f, 0x02, 0xcc}, 1841 {0xb3, 0x1f, 0x02, 0xcc},
1749 {0xb3, 0x34, 0x01, 0xcc}, 1842 {0xb3, 0x34, 0x01, 0xcc},
1750 {0xb3, 0x35, 0xa1, 0xcc}, {0xb3, 0x00, 0x26, 0xcc}, 1843 {0xb3, 0x35, 0xa1, 0xcc}, /* i2c add: 21 */
1844 {0xb3, 0x00, 0x26, 0xcc},
1751 {0xb8, 0x00, 0x33, 0xcc}, /* 13 */ 1845 {0xb8, 0x00, 0x33, 0xcc}, /* 13 */
1752 {0xb8, 0x01, 0x7d, 0xcc}, 1846 {0xb8, 0x01, 0x7d, 0xcc},
1753 {0xbc, 0x00, 0x73, 0xcc}, {0xb8, 0x81, 0x09, 0xcc}, 1847 {0xbc, 0x00, 0x73, 0xcc}, {0xb8, 0x81, 0x09, 0xcc},
@@ -1883,7 +1977,8 @@ static const u8 ov7670_initVGA_JPG[][4] = {
1883 {0x00, 0x00, 0x10, 0xdd}, 1977 {0x00, 0x00, 0x10, 0xdd},
1884 {0xb0, 0x04, 0x02, 0xcc}, {0x00, 0x00, 0x10, 0xdd}, 1978 {0xb0, 0x04, 0x02, 0xcc}, {0x00, 0x00, 0x10, 0xdd},
1885 {0xb3, 0x00, 0x66, 0xcc}, {0xb3, 0x00, 0x67, 0xcc}, 1979 {0xb3, 0x00, 0x66, 0xcc}, {0xb3, 0x00, 0x67, 0xcc},
1886 {0xb3, 0x35, 0xa1, 0xcc}, {0xb3, 0x34, 0x01, 0xcc}, 1980 {0xb3, 0x35, 0xa1, 0xcc}, /* i2c add: 21 */
1981 {0xb3, 0x34, 0x01, 0xcc},
1887 {0xb3, 0x05, 0x01, 0xcc}, {0xb3, 0x06, 0x01, 0xcc}, 1982 {0xb3, 0x05, 0x01, 0xcc}, {0xb3, 0x06, 0x01, 0xcc},
1888 {0xb3, 0x08, 0x01, 0xcc}, {0xb3, 0x09, 0x0c, 0xcc}, 1983 {0xb3, 0x08, 0x01, 0xcc}, {0xb3, 0x09, 0x0c, 0xcc},
1889 {0xb3, 0x02, 0x02, 0xcc}, {0xb3, 0x03, 0x1f, 0xcc}, 1984 {0xb3, 0x02, 0x02, 0xcc}, {0xb3, 0x03, 0x1f, 0xcc},
@@ -2181,7 +2276,7 @@ static const u8 po1200_initVGA_data[][4] = {
2181 {0xb0, 0x54, 0x13, 0xcc}, 2276 {0xb0, 0x54, 0x13, 0xcc},
2182 {0xb3, 0x00, 0x67, 0xcc}, 2277 {0xb3, 0x00, 0x67, 0xcc},
2183 {0xb3, 0x34, 0x01, 0xcc}, 2278 {0xb3, 0x34, 0x01, 0xcc},
2184 {0xb3, 0x35, 0xdc, 0xcc}, 2279 {0xb3, 0x35, 0xdc, 0xcc}, /* i2c add: 5c */
2185 {0x00, 0x03, 0x00, 0xaa}, 2280 {0x00, 0x03, 0x00, 0xaa},
2186 {0x00, 0x12, 0x05, 0xaa}, 2281 {0x00, 0x12, 0x05, 0xaa},
2187 {0x00, 0x13, 0x02, 0xaa}, 2282 {0x00, 0x13, 0x02, 0xaa},
@@ -2408,6 +2503,251 @@ static const u8 po1200_initVGA_data[][4] = {
2408 {0x00, 0xb6, 0x39, 0xaa}, 2503 {0x00, 0xb6, 0x39, 0xaa},
2409 {0x00, 0xb7, 0x24, 0xaa}, 2504 {0x00, 0xb7, 0x24, 0xaa},
2410/*write 89 0400 1415*/ 2505/*write 89 0400 1415*/
2506 {}
2507};
2508
2509static const u8 poxxxx_init_common[][4] = {
2510 {0xb3, 0x00, 0x04, 0xcc},
2511 {0x00, 0x00, 0x10, 0xdd},
2512 {0xb3, 0x00, 0x64, 0xcc},
2513 {0x00, 0x00, 0x10, 0xdd},
2514 {0xb3, 0x00, 0x65, 0xcc},
2515 {0x00, 0x00, 0x10, 0xdd},
2516 {0xb3, 0x00, 0x67, 0xcc},
2517 {0xb0, 0x03, 0x09, 0xcc},
2518 {0xb3, 0x05, 0x00, 0xcc},
2519 {0xb3, 0x06, 0x00, 0xcc},
2520 {0xb3, 0x5c, 0x01, 0xcc},
2521 {0xb3, 0x08, 0x01, 0xcc},
2522 {0xb3, 0x09, 0x0c, 0xcc},
2523 {0xb3, 0x34, 0x01, 0xcc},
2524 {0xb3, 0x35, 0xf6, 0xcc}, /* i2c add: 76 */
2525 {0xb3, 0x02, 0xb0, 0xcc},
2526 {0xb3, 0x03, 0x18, 0xcc},
2527 {0xb3, 0x04, 0x15, 0xcc},
2528 {0xb3, 0x20, 0x00, 0xcc},
2529 {0xb3, 0x21, 0x00, 0xcc},
2530 {0xb3, 0x22, 0x04, 0xcc},
2531 {0xb3, 0x23, 0x00, 0xcc},
2532 {0xb3, 0x14, 0x00, 0xcc},
2533 {0xb3, 0x15, 0x00, 0xcc},
2534 {0xb3, 0x16, 0x04, 0xcc},
2535 {0xb3, 0x17, 0xff, 0xcc},
2536 {0xb3, 0x2c, 0x03, 0xcc},
2537 {0xb3, 0x2d, 0x56, 0xcc},
2538 {0xb3, 0x2e, 0x02, 0xcc},
2539 {0xb3, 0x2f, 0x0a, 0xcc},
2540 {0xb3, 0x40, 0x00, 0xcc},
2541 {0xb3, 0x41, 0x34, 0xcc},
2542 {0xb3, 0x42, 0x01, 0xcc},
2543 {0xb3, 0x43, 0xe0, 0xcc},
2544 {0xbc, 0x00, 0x71, 0xcc},
2545 {0xbc, 0x01, 0x01, 0xcc},
2546 {0xb3, 0x01, 0x41, 0xcc},
2547 {0xb3, 0x4d, 0x00, 0xcc},
2548 {0x00, 0x0b, 0x2a, 0xaa},
2549 {0x00, 0x0e, 0x03, 0xaa},
2550 {0x00, 0x0f, 0xea, 0xaa},
2551 {0x00, 0x12, 0x08, 0xaa},
2552 {0x00, 0x1e, 0x06, 0xaa},
2553 {0x00, 0x21, 0x00, 0xaa},
2554 {0x00, 0x31, 0x1f, 0xaa},
2555 {0x00, 0x33, 0x38, 0xaa},
2556 {0x00, 0x36, 0xc0, 0xaa},
2557 {0x00, 0x37, 0xc8, 0xaa},
2558 {0x00, 0x3b, 0x36, 0xaa},
2559 {0x00, 0x4b, 0xfe, 0xaa},
2560 {0x00, 0x4d, 0x2e, 0xaa},
2561 {0x00, 0x51, 0x1c, 0xaa},
2562 {0x00, 0x52, 0x01, 0xaa},
2563 {0x00, 0x55, 0x0a, 0xaa},
2564 {0x00, 0x56, 0x0a, 0xaa},
2565 {0x00, 0x57, 0x07, 0xaa},
2566 {0x00, 0x58, 0x07, 0xaa},
2567 {0x00, 0x59, 0x04, 0xaa},
2568 {0x00, 0x70, 0x68, 0xaa},
2569 {0x00, 0x71, 0x04, 0xaa},
2570 {0x00, 0x72, 0x10, 0xaa},
2571 {0x00, 0x80, 0x71, 0xaa},
2572 {0x00, 0x81, 0x08, 0xaa},
2573 {0x00, 0x82, 0x00, 0xaa},
2574 {0x00, 0x83, 0x55, 0xaa},
2575 {0x00, 0x84, 0x06, 0xaa},
2576 {0x00, 0x85, 0x06, 0xaa},
2577 {0x00, 0x8b, 0x25, 0xaa},
2578 {0x00, 0x8c, 0x00, 0xaa},
2579 {0x00, 0x8d, 0x86, 0xaa},
2580 {0x00, 0x8e, 0x82, 0xaa},
2581 {0x00, 0x8f, 0x2d, 0xaa},
2582 {0x00, 0x90, 0x8b, 0xaa},
2583 {0x00, 0x91, 0x81, 0xaa},
2584 {0x00, 0x92, 0x81, 0xaa},
2585 {0x00, 0x93, 0x23, 0xaa},
2586 {0x00, 0xa3, 0x2a, 0xaa},
2587 {0x00, 0xa4, 0x03, 0xaa},
2588 {0x00, 0xa5, 0xea, 0xaa},
2589 {0x00, 0xb0, 0x68, 0xaa},
2590 {0x00, 0xbc, 0x04, 0xaa},
2591 {0x00, 0xbe, 0x3b, 0xaa},
2592 {0x00, 0x4e, 0x40, 0xaa},
2593 {0x00, 0x06, 0x04, 0xaa},
2594 {0x00, 0x07, 0x03, 0xaa},
2595 {0x00, 0xcd, 0x18, 0xaa},
2596 {0x00, 0x28, 0x03, 0xaa},
2597 {0x00, 0x29, 0xef, 0xaa},
2598/* reinit on alt 2 (qvga) or alt7 (vga) */
2599 {0xb3, 0x05, 0x00, 0xcc},
2600 {0xb3, 0x06, 0x00, 0xcc},
2601 {0xb8, 0x00, 0x01, 0xcc},
2602
2603 {0x00, 0x1d, 0x85, 0xaa},
2604 {0x00, 0x1e, 0xc6, 0xaa},
2605 {0x00, 0x00, 0x40, 0xdd},
2606 {0x00, 0x1d, 0x05, 0xaa},
2607
2608 {0x00, 0xd6, 0x22, 0xaa}, /* gamma 0 */
2609 {0x00, 0x73, 0x00, 0xaa},
2610 {0x00, 0x74, 0x0a, 0xaa},
2611 {0x00, 0x75, 0x16, 0xaa},
2612 {0x00, 0x76, 0x25, 0xaa},
2613 {0x00, 0x77, 0x34, 0xaa},
2614 {0x00, 0x78, 0x49, 0xaa},
2615 {0x00, 0x79, 0x5a, 0xaa},
2616 {0x00, 0x7a, 0x7f, 0xaa},
2617 {0x00, 0x7b, 0x9b, 0xaa},
2618 {0x00, 0x7c, 0xba, 0xaa},
2619 {0x00, 0x7d, 0xd4, 0xaa},
2620 {0x00, 0x7e, 0xea, 0xaa},
2621
2622 {0x00, 0xd6, 0x62, 0xaa}, /* gamma 1 */
2623 {0x00, 0x73, 0x00, 0xaa},
2624 {0x00, 0x74, 0x0a, 0xaa},
2625 {0x00, 0x75, 0x16, 0xaa},
2626 {0x00, 0x76, 0x25, 0xaa},
2627 {0x00, 0x77, 0x34, 0xaa},
2628 {0x00, 0x78, 0x49, 0xaa},
2629 {0x00, 0x79, 0x5a, 0xaa},
2630 {0x00, 0x7a, 0x7f, 0xaa},
2631 {0x00, 0x7b, 0x9b, 0xaa},
2632 {0x00, 0x7c, 0xba, 0xaa},
2633 {0x00, 0x7d, 0xd4, 0xaa},
2634 {0x00, 0x7e, 0xea, 0xaa},
2635
2636 {0x00, 0xd6, 0xa2, 0xaa}, /* gamma 2 */
2637 {0x00, 0x73, 0x00, 0xaa},
2638 {0x00, 0x74, 0x0a, 0xaa},
2639 {0x00, 0x75, 0x16, 0xaa},
2640 {0x00, 0x76, 0x25, 0xaa},
2641 {0x00, 0x77, 0x34, 0xaa},
2642 {0x00, 0x78, 0x49, 0xaa},
2643 {0x00, 0x79, 0x5a, 0xaa},
2644 {0x00, 0x7a, 0x7f, 0xaa},
2645 {0x00, 0x7b, 0x9b, 0xaa},
2646 {0x00, 0x7c, 0xba, 0xaa},
2647 {0x00, 0x7d, 0xd4, 0xaa},
2648 {0x00, 0x7e, 0xea, 0xaa},
2649
2650 {0x00, 0xaa, 0xff, 0xaa}, /* back light comp */
2651 {0x00, 0xc4, 0x03, 0xaa},
2652 {0x00, 0xc5, 0x19, 0xaa},
2653 {0x00, 0xc6, 0x03, 0xaa},
2654 {0x00, 0xc7, 0x91, 0xaa},
2655 {0x00, 0xc8, 0x01, 0xaa},
2656 {0x00, 0xc9, 0xdd, 0xaa},
2657 {0x00, 0xca, 0x02, 0xaa},
2658 {0x00, 0xcb, 0x37, 0xaa},
2659
2660/* read d1 */
2661 {0x00, 0xd1, 0x3c, 0xaa},
2662 {0x00, 0xb8, 0x28, 0xaa},
2663 {0x00, 0xb9, 0x1e, 0xaa},
2664 {0x00, 0xb6, 0x14, 0xaa},
2665 {0x00, 0xb7, 0x0f, 0xaa},
2666 {0x00, 0x5c, 0x10, 0xaa},
2667 {0x00, 0x5d, 0x18, 0xaa},
2668 {0x00, 0x5e, 0x24, 0xaa},
2669 {0x00, 0x5f, 0x24, 0xaa},
2670 {0x00, 0x86, 0x1a, 0xaa},
2671 {0x00, 0x60, 0x00, 0xaa},
2672 {0x00, 0x61, 0x1b, 0xaa},
2673 {0x00, 0x62, 0x30, 0xaa},
2674 {0x00, 0x63, 0x40, 0xaa},
2675 {0x00, 0x87, 0x1a, 0xaa},
2676 {0x00, 0x64, 0x00, 0xaa},
2677 {0x00, 0x65, 0x08, 0xaa},
2678 {0x00, 0x66, 0x10, 0xaa},
2679 {0x00, 0x67, 0x20, 0xaa},
2680 {0x00, 0x88, 0x10, 0xaa},
2681 {0x00, 0x68, 0x00, 0xaa},
2682 {0x00, 0x69, 0x08, 0xaa},
2683 {0x00, 0x6a, 0x0f, 0xaa},
2684 {0x00, 0x6b, 0x0f, 0xaa},
2685 {0x00, 0x89, 0x07, 0xaa},
2686 {0x00, 0xd5, 0x4c, 0xaa},
2687 {0x00, 0x0a, 0x00, 0xaa},
2688 {0x00, 0x0b, 0x2a, 0xaa},
2689 {0x00, 0x0e, 0x03, 0xaa},
2690 {0x00, 0x0f, 0xea, 0xaa},
2691 {0x00, 0xa2, 0x00, 0xaa},
2692 {0x00, 0xa3, 0x2a, 0xaa},
2693 {0x00, 0xa4, 0x03, 0xaa},
2694 {0x00, 0xa5, 0xea, 0xaa},
2695 {}
2696};
2697static const u8 poxxxx_initVGA[][4] = {
2698 {0x00, 0x20, 0x11, 0xaa},
2699 {0x00, 0x33, 0x38, 0xaa},
2700 {0x00, 0xbb, 0x0d, 0xaa},
2701 {0xb3, 0x22, 0x01, 0xcc},
2702 {0xb3, 0x23, 0xe0, 0xcc},
2703 {0xb3, 0x16, 0x02, 0xcc},
2704 {0xb3, 0x17, 0x7f, 0xcc},
2705 {0xb3, 0x02, 0xb0, 0xcc},
2706 {0xb3, 0x06, 0x00, 0xcc},
2707 {0xb3, 0x5c, 0x01, 0xcc},
2708 {0x00, 0x04, 0x06, 0xaa},
2709 {0x00, 0x05, 0x3f, 0xaa},
2710 {0x00, 0x04, 0x00, 0xdd}, /* delay 1s */
2711 {}
2712};
2713static const u8 poxxxx_initQVGA[][4] = {
2714 {0x00, 0x20, 0x33, 0xaa},
2715 {0x00, 0x33, 0x38, 0xaa},
2716 {0x00, 0xbb, 0x0d, 0xaa},
2717 {0xb3, 0x22, 0x00, 0xcc},
2718 {0xb3, 0x23, 0xf0, 0xcc},
2719 {0xb3, 0x16, 0x01, 0xcc},
2720 {0xb3, 0x17, 0x3f, 0xcc},
2721 {0xb3, 0x02, 0xb0, 0xcc},
2722 {0xb3, 0x06, 0x01, 0xcc},
2723 {0xb3, 0x5c, 0x00, 0xcc},
2724 {0x00, 0x04, 0x06, 0xaa},
2725 {0x00, 0x05, 0x3f, 0xaa},
2726 {0x00, 0x04, 0x00, 0xdd}, /* delay 1s */
2727 {}
2728};
2729static const u8 poxxxx_init_end_1[][4] = {
2730 {0x00, 0x47, 0x25, 0xaa},
2731 {0x00, 0x48, 0x80, 0xaa},
2732 {0x00, 0x49, 0x1f, 0xaa},
2733 {0x00, 0x4a, 0x40, 0xaa},
2734 {0x00, 0x44, 0x40, 0xaa},
2735 {0x00, 0xab, 0x4a, 0xaa},
2736 {0x00, 0xb1, 0x00, 0xaa},
2737 {0x00, 0xb2, 0x04, 0xaa},
2738 {0x00, 0xb3, 0x08, 0xaa},
2739 {0x00, 0xb4, 0x0b, 0xaa},
2740 {0x00, 0xb5, 0x0d, 0xaa},
2741 {0x00, 0x59, 0x7e, 0xaa}, /* sharpness */
2742 {0x00, 0x16, 0x00, 0xaa}, /* white balance */
2743 {0x00, 0x18, 0x00, 0xaa},
2744 {}
2745};
2746static const u8 poxxxx_init_end_2[][4] = {
2747 {0x00, 0x1d, 0x85, 0xaa},
2748 {0x00, 0x1e, 0x06, 0xaa},
2749 {0x00, 0x1d, 0x05, 0xaa},
2750 {}
2411}; 2751};
2412 2752
2413struct sensor_info { 2753struct sensor_info {
@@ -2420,33 +2760,89 @@ struct sensor_info {
2420 u8 op; 2760 u8 op;
2421}; 2761};
2422 2762
2423static const struct sensor_info sensor_info_data[] = { 2763/* probe values */
2424/* sensorId, I2cAdd, IdAdd, VpId, m1, m2, op */ 2764static const struct sensor_info vc0321_probe_data[] = {
2765/* sensorId, I2cAdd, IdAdd, VpId, m1, m2, op */
2766/* 0 OV9640 */
2425 {-1, 0x80 | 0x30, 0x0a, 0x0000, 0x25, 0x24, 0x05}, 2767 {-1, 0x80 | 0x30, 0x0a, 0x0000, 0x25, 0x24, 0x05},
2768/* 1 ICM108T (may respond on IdAdd == 0x83 - tested in vc032x_probe_sensor) */
2426 {-1, 0x80 | 0x20, 0x82, 0x0000, 0x24, 0x25, 0x01}, 2769 {-1, 0x80 | 0x20, 0x82, 0x0000, 0x24, 0x25, 0x01},
2427/* (tested in vc032x_probe_sensor) */ 2770/* 2 PO2130 (may detect PO3130NC - tested in vc032x_probe_sensor)*/
2428/* {-1, 0x80 | 0x20, 0x83, 0x0000, 0x24, 0x25, 0x01}, */ 2771 {-1, 0x80 | 0x76, 0x00, 0x0000, 0x24, 0x25, 0x01},
2429 {SENSOR_PO3130NC, 0x80 | 0x76, 0x00, 0x3130, 0x24, 0x25, 0x01}, 2772/* 3 MI1310 */
2773 {-1, 0x80 | 0x5d, 0x00, 0x0000, 0x24, 0x25, 0x01},
2774/* 4 MI360 - tested in vc032x_probe_sensor */
2775/* {SENSOR_MI0360, 0x80 | 0x5d, 0x00, 0x8243, 0x24, 0x25, 0x01}, */
2776/* 5 7131R */
2777 {SENSOR_HV7131R, 0x80 | 0x11, 0x00, 0x0209, 0x24, 0x25, 0x01},
2778/* 6 OV7649 */
2779 {-1, 0x80 | 0x21, 0x0a, 0x0000, 0x21, 0x20, 0x05},
2780/* 7 PAS302BCW */
2781 {-1, 0x80 | 0x40, 0x00, 0x0000, 0x20, 0x22, 0x05},
2782/* 8 OV7660 */
2783 {SENSOR_OV7660, 0x80 | 0x21, 0x0a, 0x7660, 0x26, 0x26, 0x05},
2784/* 9 PO3130NC - (tested in vc032x_probe_sensor) */
2785/* {SENSOR_PO3130NC, 0x80 | 0x76, 0x00, 0x3130, 0x24, 0x25, 0x01}, */
2786/* 10 PO1030KC */
2787 {-1, 0x80 | 0x6e, 0x00, 0x0000, 0x24, 0x25, 0x01},
2788/* 11 MI1310_SOC */
2430 {SENSOR_MI1310_SOC, 0x80 | 0x5d, 0x00, 0x143a, 0x24, 0x25, 0x01}, 2789 {SENSOR_MI1310_SOC, 0x80 | 0x5d, 0x00, 0x143a, 0x24, 0x25, 0x01},
2431/* (tested in vc032x_probe_sensor) */ 2790/* 12 OV9650 */
2791 {-1, 0x80 | 0x30, 0x0a, 0x0000, 0x25, 0x24, 0x05},
2792/* 13 S5K532 */
2793 {-1, 0x80 | 0x11, 0x39, 0x0000, 0x24, 0x25, 0x01},
2794/* 14 MI360_SOC - ??? */
2795/* 15 PO1200N */
2796 {SENSOR_PO1200, 0x80 | 0x5c, 0x00, 0x1200, 0x67, 0x67, 0x01},
2797/* 16 PO3030K */
2798 {-1, 0x80 | 0x18, 0x00, 0x0000, 0x24, 0x25, 0x01},
2799/* 17 PO2030 */
2800 {-1, 0x80 | 0x6e, 0x00, 0x0000, 0x24, 0x25, 0x01},
2801/* ?? */
2802 {-1, 0x80 | 0x56, 0x01, 0x0000, 0x64, 0x67, 0x01},
2803 {SENSOR_MI1320, 0x80 | 0x48, 0x00, 0x148c, 0x64, 0x65, 0x01},
2804};
2805static const struct sensor_info vc0323_probe_data[] = {
2806/* sensorId, I2cAdd, IdAdd, VpId, m1, m2, op */
2807/* 0 OV9640 */
2808 {-1, 0x80 | 0x30, 0x0a, 0x0000, 0x25, 0x24, 0x05},
2809/* 1 ICM108T (may respond on IdAdd == 0x83 - tested in vc032x_probe_sensor) */
2810 {-1, 0x80 | 0x20, 0x82, 0x0000, 0x24, 0x25, 0x01},
2811/* 2 PO2130 (may detect PO3130NC - tested in vc032x_probe_sensor)*/
2812 {-1, 0x80 | 0x76, 0x00, 0x0000, 0x24, 0x25, 0x01},
2813/* 3 MI1310 */
2814 {-1, 0x80 | 0x5d, 0x00, 0x0000, 0x24, 0x25, 0x01},
2815/* 4 MI360 - tested in vc032x_probe_sensor */
2432/* {SENSOR_MI0360, 0x80 | 0x5d, 0x00, 0x8243, 0x24, 0x25, 0x01}, */ 2816/* {SENSOR_MI0360, 0x80 | 0x5d, 0x00, 0x8243, 0x24, 0x25, 0x01}, */
2817/* 5 7131R */
2433 {SENSOR_HV7131R, 0x80 | 0x11, 0x00, 0x0209, 0x24, 0x25, 0x01}, 2818 {SENSOR_HV7131R, 0x80 | 0x11, 0x00, 0x0209, 0x24, 0x25, 0x01},
2819/* 6 OV7649 */
2434 {-1, 0x80 | 0x21, 0x0a, 0x0000, 0x21, 0x20, 0x05}, 2820 {-1, 0x80 | 0x21, 0x0a, 0x0000, 0x21, 0x20, 0x05},
2821/* 7 PAS302BCW */
2435 {-1, 0x80 | 0x40, 0x00, 0x0000, 0x20, 0x22, 0x05}, 2822 {-1, 0x80 | 0x40, 0x00, 0x0000, 0x20, 0x22, 0x05},
2823/* 8 OV7660 */
2436 {SENSOR_OV7660, 0x80 | 0x21, 0x0a, 0x7660, 0x26, 0x26, 0x05}, 2824 {SENSOR_OV7660, 0x80 | 0x21, 0x0a, 0x7660, 0x26, 0x26, 0x05},
2437/* {SENSOR_PO3130NC, 0x80 | 0x76, 0x00, 0x0000, 0x24, 0x25, 0x01}, */ 2825/* 9 PO3130NC - (tested in vc032x_probe_sensor) */
2826/* {SENSOR_PO3130NC, 0x80 | 0x76, 0x00, 0x3130, 0x24, 0x25, 0x01}, */
2827/* 10 PO1030KC */
2438 {-1, 0x80 | 0x6e, 0x00, 0x0000, 0x24, 0x25, 0x01}, 2828 {-1, 0x80 | 0x6e, 0x00, 0x0000, 0x24, 0x25, 0x01},
2439/* {SENSOR_MI1310_SOC, 0x80 | 0x5d, 0x00, 0x0000, 0x24, 0x25, 0x01}, */ 2829/* 11 MI1310_SOC */
2440/* {-1, 0x80 | 0x30, 0x0a, 0x0000, 0x25, 0x24, 0x05}, */ 2830 {SENSOR_MI1310_SOC, 0x80 | 0x5d, 0x00, 0x143a, 0x24, 0x25, 0x01},
2831/* 12 OV9650 */
2832 {-1, 0x80 | 0x30, 0x0a, 0x0000, 0x25, 0x24, 0x05},
2833/* 13 S5K532 */
2441 {-1, 0x80 | 0x11, 0x39, 0x0000, 0x24, 0x25, 0x01}, 2834 {-1, 0x80 | 0x11, 0x39, 0x0000, 0x24, 0x25, 0x01},
2835/* 14 MI360_SOC - ??? */
2836/* 15 PO1200N */
2442 {SENSOR_PO1200, 0x80 | 0x5c, 0x00, 0x1200, 0x67, 0x67, 0x01}, 2837 {SENSOR_PO1200, 0x80 | 0x5c, 0x00, 0x1200, 0x67, 0x67, 0x01},
2838/* 16 ?? */
2443 {-1, 0x80 | 0x2d, 0x00, 0x0000, 0x65, 0x67, 0x01}, 2839 {-1, 0x80 | 0x2d, 0x00, 0x0000, 0x65, 0x67, 0x01},
2840/* 17 PO2030 */
2444 {-1, 0x80 | 0x6e, 0x00, 0x0000, 0x24, 0x25, 0x01}, 2841 {-1, 0x80 | 0x6e, 0x00, 0x0000, 0x24, 0x25, 0x01},
2842/* ?? */
2445 {-1, 0x80 | 0x56, 0x01, 0x0000, 0x64, 0x67, 0x01}, 2843 {-1, 0x80 | 0x56, 0x01, 0x0000, 0x64, 0x67, 0x01},
2446 {SENSOR_MI1320_SOC, 0x80 | 0x48, 0x00, 0x148c, 0x64, 0x67, 0x01}, 2844 {SENSOR_MI1320_SOC, 0x80 | 0x48, 0x00, 0x148c, 0x64, 0x67, 0x01},
2447/*fixme: previously detected?*/ 2845/*fixme: not in the ms-win probe - may be found before? */
2448 {SENSOR_MI1320, 0x80 | 0x48, 0x00, 0x148c, 0x64, 0x65, 0x01},
2449/*fixme: not in the ms-win probe - may be found before?*/
2450 {SENSOR_OV7670, 0x80 | 0x21, 0x0a, 0x7673, 0x66, 0x67, 0x05}, 2846 {SENSOR_OV7670, 0x80 | 0x21, 0x0a, 0x7673, 0x66, 0x67, 0x05},
2451}; 2847};
2452 2848
@@ -2520,7 +2916,7 @@ static int vc032x_probe_sensor(struct gspca_dev *gspca_dev)
2520{ 2916{
2521 struct sd *sd = (struct sd *) gspca_dev; 2917 struct sd *sd = (struct sd *) gspca_dev;
2522 struct usb_device *dev = gspca_dev->dev; 2918 struct usb_device *dev = gspca_dev->dev;
2523 int i; 2919 int i, n;
2524 u16 value; 2920 u16 value;
2525 const struct sensor_info *ptsensor_info; 2921 const struct sensor_info *ptsensor_info;
2526 2922
@@ -2531,9 +2927,16 @@ static int vc032x_probe_sensor(struct gspca_dev *gspca_dev)
2531 } 2927 }
2532 2928
2533 reg_r(gspca_dev, 0xa1, 0xbfcf, 1); 2929 reg_r(gspca_dev, 0xa1, 0xbfcf, 1);
2534 PDEBUG(D_PROBE, "check sensor header %02x", gspca_dev->usb_buf[0]); 2930 PDEBUG(D_PROBE, "vc032%d check sensor header %02x",
2535 for (i = 0; i < ARRAY_SIZE(sensor_info_data); i++) { 2931 sd->bridge == BRIDGE_VC0321 ? 1 : 3, gspca_dev->usb_buf[0]);
2536 ptsensor_info = &sensor_info_data[i]; 2932 if (sd->bridge == BRIDGE_VC0321) {
2933 ptsensor_info = vc0321_probe_data;
2934 n = ARRAY_SIZE(vc0321_probe_data);
2935 } else {
2936 ptsensor_info = vc0323_probe_data;
2937 n = ARRAY_SIZE(vc0323_probe_data);
2938 }
2939 for (i = 0; i < n; i++) {
2537 reg_w(dev, 0xa0, 0x02, 0xb334); 2940 reg_w(dev, 0xa0, 0x02, 0xb334);
2538 reg_w(dev, 0xa0, ptsensor_info->m1, 0xb300); 2941 reg_w(dev, 0xa0, ptsensor_info->m1, 0xb300);
2539 reg_w(dev, 0xa0, ptsensor_info->m2, 0xb300); 2942 reg_w(dev, 0xa0, ptsensor_info->m2, 0xb300);
@@ -2551,13 +2954,15 @@ static int vc032x_probe_sensor(struct gspca_dev *gspca_dev)
2551 return ptsensor_info->sensorId; 2954 return ptsensor_info->sensorId;
2552 2955
2553 switch (value) { 2956 switch (value) {
2957 case 0x3130:
2958 return SENSOR_PO3130NC;
2554 case 0x7673: 2959 case 0x7673:
2555 return SENSOR_OV7670; 2960 return SENSOR_OV7670;
2556 case 0x8243: 2961 case 0x8243:
2557 return SENSOR_MI0360; 2962 return SENSOR_MI0360;
2558 } 2963 }
2559/*fixme: should return here*/
2560 } 2964 }
2965 ptsensor_info++;
2561 } 2966 }
2562 return -1; 2967 return -1;
2563} 2968}
@@ -2619,7 +3024,7 @@ static void usb_exchange(struct gspca_dev *gspca_dev,
2619 i2c_write(gspca_dev, data[i][0], &data[i][1], 2); 3024 i2c_write(gspca_dev, data[i][0], &data[i][1], 2);
2620 break; 3025 break;
2621 case 0xdd: 3026 case 0xdd:
2622 msleep(data[i][2] + 10); 3027 msleep(data[i][1] * 256 + data[i][2] + 10);
2623 break; 3028 break;
2624 } 3029 }
2625 i++; 3030 i++;
@@ -2646,12 +3051,17 @@ static int sd_config(struct gspca_dev *gspca_dev,
2646 64, /* OV7670 6 */ 3051 64, /* OV7670 6 */
2647 128, /* PO1200 7 */ 3052 128, /* PO1200 7 */
2648 128, /* PO3130NC 8 */ 3053 128, /* PO3130NC 8 */
3054 128, /* POxxxx 9 */
2649 }; 3055 };
2650 3056
2651 cam = &gspca_dev->cam; 3057 cam = &gspca_dev->cam;
2652 sd->bridge = id->driver_info >> 8; 3058 sd->bridge = id->driver_info >> 8;
2653 sd->flags = id->driver_info & 0xff; 3059 sd->flags = id->driver_info & 0xff;
2654 sensor = vc032x_probe_sensor(gspca_dev); 3060 if (id->idVendor == 0x046d &&
3061 (id->idProduct == 0x0892 || id->idProduct == 0x0896))
3062 sensor = SENSOR_POxxxx;
3063 else
3064 sensor = vc032x_probe_sensor(gspca_dev);
2655 switch (sensor) { 3065 switch (sensor) {
2656 case -1: 3066 case -1:
2657 PDEBUG(D_PROBE, "Unknown sensor..."); 3067 PDEBUG(D_PROBE, "Unknown sensor...");
@@ -2684,6 +3094,9 @@ static int sd_config(struct gspca_dev *gspca_dev,
2684 case SENSOR_PO3130NC: 3094 case SENSOR_PO3130NC:
2685 PDEBUG(D_PROBE, "Find Sensor PO3130NC"); 3095 PDEBUG(D_PROBE, "Find Sensor PO3130NC");
2686 break; 3096 break;
3097 case SENSOR_POxxxx:
3098 PDEBUG(D_PROBE, "Sensor POxxxx");
3099 break;
2687 } 3100 }
2688 sd->sensor = sensor; 3101 sd->sensor = sensor;
2689 3102
@@ -2712,28 +3125,19 @@ static int sd_config(struct gspca_dev *gspca_dev,
2712 } 3125 }
2713 cam->npkt = npkt[sd->sensor]; 3126 cam->npkt = npkt[sd->sensor];
2714 3127
3128 sd->brightness = BRIGHTNESS_DEF;
3129 sd->contrast = CONTRAST_DEF;
3130 sd->colors = COLOR_DEF;
2715 sd->hflip = HFLIP_DEF; 3131 sd->hflip = HFLIP_DEF;
2716 sd->vflip = VFLIP_DEF; 3132 sd->vflip = VFLIP_DEF;
2717 if (sd->sensor == SENSOR_OV7670)
2718 sd->flags |= FL_HFLIP | FL_VFLIP;
2719 sd->lightfreq = FREQ_DEF; 3133 sd->lightfreq = FREQ_DEF;
2720 if (sd->sensor != SENSOR_OV7670)
2721 gspca_dev->ctrl_dis = (1 << LIGHTFREQ_IDX);
2722 switch (sd->sensor) {
2723 case SENSOR_MI1310_SOC:
2724 case SENSOR_MI1320_SOC:
2725 case SENSOR_OV7660:
2726 case SENSOR_OV7670:
2727 case SENSOR_PO1200:
2728 break;
2729 default:
2730 gspca_dev->ctrl_dis = (1 << HFLIP_IDX)
2731 | (1 << VFLIP_IDX);
2732 break;
2733 }
2734
2735 sd->sharpness = SHARPNESS_DEF; 3134 sd->sharpness = SHARPNESS_DEF;
2736 3135
3136 gspca_dev->ctrl_dis = ctrl_dis[sd->sensor];
3137
3138 if (sd->sensor == SENSOR_OV7670)
3139 sd->flags |= FL_HFLIP | FL_VFLIP;
3140
2737 if (sd->bridge == BRIDGE_VC0321) { 3141 if (sd->bridge == BRIDGE_VC0321) {
2738 reg_r(gspca_dev, 0x8a, 0, 3); 3142 reg_r(gspca_dev, 0x8a, 0, 3);
2739 reg_w(dev, 0x87, 0x00, 0x0f0f); 3143 reg_w(dev, 0x87, 0x00, 0x0f0f);
@@ -2747,10 +3151,55 @@ static int sd_config(struct gspca_dev *gspca_dev,
2747/* this function is called at probe and resume time */ 3151/* this function is called at probe and resume time */
2748static int sd_init(struct gspca_dev *gspca_dev) 3152static int sd_init(struct gspca_dev *gspca_dev)
2749{ 3153{
3154 struct sd *sd = (struct sd *) gspca_dev;
3155
3156 if (sd->sensor == SENSOR_POxxxx) {
3157 reg_r(gspca_dev, 0xa1, 0xb300, 1);
3158 if (gspca_dev->usb_buf[0] != 0) {
3159 reg_w(gspca_dev->dev, 0xa0, 0x26, 0xb300);
3160 reg_w(gspca_dev->dev, 0xa0, 0x04, 0xb300);
3161 reg_w(gspca_dev->dev, 0xa0, 0x00, 0xb300);
3162 }
3163 }
2750 return 0; 3164 return 0;
2751} 3165}
2752 3166
2753/* some sensors only */ 3167static void setbrightness(struct gspca_dev *gspca_dev)
3168{
3169 struct sd *sd = (struct sd *) gspca_dev;
3170 u8 data;
3171
3172 if (gspca_dev->ctrl_dis & (1 << BRIGHTNESS_IDX))
3173 return;
3174 data = sd->brightness;
3175 if (data >= 0x80)
3176 data &= 0x7f;
3177 else
3178 data = 0xff ^ data;
3179 i2c_write(gspca_dev, 0x98, &data, 1);
3180}
3181
3182static void setcontrast(struct gspca_dev *gspca_dev)
3183{
3184 struct sd *sd = (struct sd *) gspca_dev;
3185
3186 if (gspca_dev->ctrl_dis & (1 << CONTRAST_IDX))
3187 return;
3188 i2c_write(gspca_dev, 0x99, &sd->contrast, 1);
3189}
3190
3191static void setcolors(struct gspca_dev *gspca_dev)
3192{
3193 struct sd *sd = (struct sd *) gspca_dev;
3194 u8 data;
3195
3196 if (gspca_dev->ctrl_dis & (1 << COLORS_IDX))
3197 return;
3198 data = sd->colors - (sd->colors >> 3) - 1;
3199 i2c_write(gspca_dev, 0x94, &data, 1);
3200 i2c_write(gspca_dev, 0x95, &sd->colors, 1);
3201}
3202
2754static void sethvflip(struct gspca_dev *gspca_dev) 3203static void sethvflip(struct gspca_dev *gspca_dev)
2755{ 3204{
2756 struct sd *sd = (struct sd *) gspca_dev; 3205 struct sd *sd = (struct sd *) gspca_dev;
@@ -2764,6 +3213,7 @@ static void sethvflip(struct gspca_dev *gspca_dev)
2764 vflip = !vflip; 3213 vflip = !vflip;
2765 switch (sd->sensor) { 3214 switch (sd->sensor) {
2766 case SENSOR_MI1310_SOC: 3215 case SENSOR_MI1310_SOC:
3216 case SENSOR_MI1320:
2767 case SENSOR_MI1320_SOC: 3217 case SENSOR_MI1320_SOC:
2768 data[0] = data[1] = 0; /* select page 0 */ 3218 data[0] = data[1] = 0; /* select page 0 */
2769 i2c_write(gspca_dev, 0xf0, data, 2); 3219 i2c_write(gspca_dev, 0xf0, data, 2);
@@ -2801,18 +3251,29 @@ static void setlightfreq(struct gspca_dev *gspca_dev)
2801 usb_exchange(gspca_dev, ov7660_freq_tb[sd->lightfreq]); 3251 usb_exchange(gspca_dev, ov7660_freq_tb[sd->lightfreq]);
2802} 3252}
2803 3253
2804/* po1200 only */
2805static void setsharpness(struct gspca_dev *gspca_dev) 3254static void setsharpness(struct gspca_dev *gspca_dev)
2806{ 3255{
2807 struct sd *sd = (struct sd *) gspca_dev; 3256 struct sd *sd = (struct sd *) gspca_dev;
2808 u8 data; 3257 u8 data;
2809 3258
2810 if (sd->sensor != SENSOR_PO1200) 3259 switch (sd->sensor) {
2811 return; 3260 case SENSOR_PO1200:
2812 data = 0; 3261 data = 0;
2813 i2c_write(gspca_dev, 0x03, &data, 1); 3262 i2c_write(gspca_dev, 0x03, &data, 1);
2814 data = 0xb5 + sd->sharpness * 3; 3263 if (sd->sharpness < 0)
2815 i2c_write(gspca_dev, 0x61, &data, 1); 3264 data = 0x6a;
3265 else
3266 data = 0xb5 + sd->sharpness * 3;
3267 i2c_write(gspca_dev, 0x61, &data, 1);
3268 break;
3269 case SENSOR_POxxxx:
3270 if (sd->sharpness < 0)
3271 data = 0x7e; /* def = max */
3272 else
3273 data = 0x60 + sd->sharpness * 0x0f;
3274 i2c_write(gspca_dev, 0x59, &data, 1);
3275 break;
3276 }
2816} 3277}
2817 3278
2818static int sd_start(struct gspca_dev *gspca_dev) 3279static int sd_start(struct gspca_dev *gspca_dev)
@@ -2922,12 +3383,27 @@ static int sd_start(struct gspca_dev *gspca_dev)
2922 usb_exchange(gspca_dev, init); 3383 usb_exchange(gspca_dev, init);
2923 init = po3130_rundata; 3384 init = po3130_rundata;
2924 break; 3385 break;
2925 default: 3386 case SENSOR_PO1200:
2926/* case SENSOR_PO1200: */
2927 GammaT = po1200_gamma; 3387 GammaT = po1200_gamma;
2928 MatrixT = po1200_matrix; 3388 MatrixT = po1200_matrix;
2929 init = po1200_initVGA_data; 3389 init = po1200_initVGA_data;
2930 break; 3390 break;
3391 default:
3392/* case SENSOR_POxxxx: */
3393 usb_exchange(gspca_dev, poxxxx_init_common);
3394 if (mode)
3395 init = poxxxx_initQVGA;
3396 else
3397 init = poxxxx_initVGA;
3398 usb_exchange(gspca_dev, init);
3399 reg_r(gspca_dev, 0x8c, 0x0000, 3);
3400 reg_w(gspca_dev->dev, 0xa0,
3401 gspca_dev->usb_buf[2] & 1 ? 0 : 1,
3402 0xb35c);
3403 msleep(300);
3404/*fixme: i2c read 04 and 05*/
3405 init = poxxxx_init_end_1;
3406 break;
2931 } 3407 }
2932 usb_exchange(gspca_dev, init); 3408 usb_exchange(gspca_dev, init);
2933 if (GammaT && MatrixT) { 3409 if (GammaT && MatrixT) {
@@ -2936,7 +3412,6 @@ static int sd_start(struct gspca_dev *gspca_dev)
2936 put_tab_to_reg(gspca_dev, GammaT, 17, 0xb86c); 3412 put_tab_to_reg(gspca_dev, GammaT, 17, 0xb86c);
2937 put_tab_to_reg(gspca_dev, MatrixT, 9, 0xb82c); 3413 put_tab_to_reg(gspca_dev, MatrixT, 9, 0xb82c);
2938 3414
2939 /* set the led on 0x0892 0x0896 */
2940 switch (sd->sensor) { 3415 switch (sd->sensor) {
2941 case SENSOR_PO1200: 3416 case SENSOR_PO1200:
2942 case SENSOR_HV7131R: 3417 case SENSOR_HV7131R:
@@ -2945,16 +3420,22 @@ static int sd_start(struct gspca_dev *gspca_dev)
2945 case SENSOR_MI1310_SOC: 3420 case SENSOR_MI1310_SOC:
2946 reg_w(gspca_dev->dev, 0x89, 0x058c, 0x0000); 3421 reg_w(gspca_dev->dev, 0x89, 0x058c, 0x0000);
2947 break; 3422 break;
2948 default:
2949 if (!(sd->flags & FL_SAMSUNG))
2950 reg_w(gspca_dev->dev, 0x89, 0xffff, 0xfdff);
2951 break;
2952 } 3423 }
2953 msleep(100); 3424 msleep(100);
2954 setsharpness(gspca_dev); 3425 setsharpness(gspca_dev);
2955 sethvflip(gspca_dev); 3426 sethvflip(gspca_dev);
2956 setlightfreq(gspca_dev); 3427 setlightfreq(gspca_dev);
2957 } 3428 }
3429 if (sd->sensor == SENSOR_POxxxx) {
3430 setcolors(gspca_dev);
3431 setbrightness(gspca_dev);
3432 setcontrast(gspca_dev);
3433
3434 /* led on */
3435 msleep(80);
3436 reg_w(gspca_dev->dev, 0x89, 0xffff, 0xfdff);
3437 usb_exchange(gspca_dev, poxxxx_init_end_2);
3438 }
2958 return 0; 3439 return 0;
2959} 3440}
2960 3441
@@ -2963,10 +3444,17 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
2963 struct usb_device *dev = gspca_dev->dev; 3444 struct usb_device *dev = gspca_dev->dev;
2964 struct sd *sd = (struct sd *) gspca_dev; 3445 struct sd *sd = (struct sd *) gspca_dev;
2965 3446
2966 if (sd->sensor == SENSOR_MI1310_SOC) 3447 switch (sd->sensor) {
3448 case SENSOR_MI1310_SOC:
2967 reg_w(dev, 0x89, 0x058c, 0x00ff); 3449 reg_w(dev, 0x89, 0x058c, 0x00ff);
2968 else if (!(sd->flags & FL_SAMSUNG)) 3450 break;
2969 reg_w(dev, 0x89, 0xffff, 0xffff); 3451 case SENSOR_POxxxx:
3452 return;
3453 default:
3454 if (!(sd->flags & FL_SAMSUNG))
3455 reg_w(dev, 0x89, 0xffff, 0xffff);
3456 break;
3457 }
2970 reg_w(dev, 0xa0, 0x01, 0xb301); 3458 reg_w(dev, 0xa0, 0x01, 0xb301);
2971 reg_w(dev, 0xa0, 0x09, 0xb003); 3459 reg_w(dev, 0xa0, 0x09, 0xb003);
2972} 3460}
@@ -2984,6 +3472,12 @@ static void sd_stop0(struct gspca_dev *gspca_dev)
2984 reg_w(dev, 0x89, 0x058c, 0x00ff); 3472 reg_w(dev, 0x89, 0x058c, 0x00ff);
2985 else if (!(sd->flags & FL_SAMSUNG)) 3473 else if (!(sd->flags & FL_SAMSUNG))
2986 reg_w(dev, 0x89, 0xffff, 0xffff); 3474 reg_w(dev, 0x89, 0xffff, 0xffff);
3475
3476 if (sd->sensor == SENSOR_POxxxx) {
3477 reg_w(dev, 0xa0, 0x26, 0xb300);
3478 reg_w(dev, 0xa0, 0x04, 0xb300);
3479 reg_w(dev, 0xa0, 0x00, 0xb300);
3480 }
2987} 3481}
2988 3482
2989static void sd_pkt_scan(struct gspca_dev *gspca_dev, 3483static void sd_pkt_scan(struct gspca_dev *gspca_dev,
@@ -3020,6 +3514,60 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
3020 gspca_frame_add(gspca_dev, INTER_PACKET, data, len); 3514 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
3021} 3515}
3022 3516
3517static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
3518{
3519 struct sd *sd = (struct sd *) gspca_dev;
3520
3521 sd->brightness = val;
3522 if (gspca_dev->streaming)
3523 setbrightness(gspca_dev);
3524 return 0;
3525}
3526
3527static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
3528{
3529 struct sd *sd = (struct sd *) gspca_dev;
3530
3531 *val = sd->brightness;
3532 return 0;
3533}
3534
3535static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
3536{
3537 struct sd *sd = (struct sd *) gspca_dev;
3538
3539 sd->contrast = val;
3540 if (gspca_dev->streaming)
3541 setcontrast(gspca_dev);
3542 return 0;
3543}
3544
3545static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
3546{
3547 struct sd *sd = (struct sd *) gspca_dev;
3548
3549 *val = sd->contrast;
3550 return 0;
3551}
3552
3553static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
3554{
3555 struct sd *sd = (struct sd *) gspca_dev;
3556
3557 sd->colors = val;
3558 if (gspca_dev->streaming)
3559 setcolors(gspca_dev);
3560 return 0;
3561}
3562
3563static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
3564{
3565 struct sd *sd = (struct sd *) gspca_dev;
3566
3567 *val = sd->colors;
3568 return 0;
3569}
3570
3023static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val) 3571static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val)
3024{ 3572{
3025 struct sd *sd = (struct sd *) gspca_dev; 3573 struct sd *sd = (struct sd *) gspca_dev;
diff --git a/drivers/media/video/gspca/zc3xx.c b/drivers/media/video/gspca/zc3xx.c
index 1a800fc1c00e..50986da3d912 100644
--- a/drivers/media/video/gspca/zc3xx.c
+++ b/drivers/media/video/gspca/zc3xx.c
@@ -1,9 +1,8 @@
1/* 1/*
2 * Z-Star/Vimicro zc301/zc302p/vc30x library 2 * Z-Star/Vimicro zc301/zc302p/vc30x library
3 * Copyright (C) 2004 2005 2006 Michel Xhaard
4 * mxhaard@magic.fr
5 * 3 *
6 * V4L2 by Jean-Francois Moine <http://moinejf.free.fr> 4 * Copyright (C) 2009-2010 Jean-Francois Moine <http://moinejf.free.fr>
5 * Copyright (C) 2004 2005 2006 Michel Xhaard mxhaard@magic.fr
7 * 6 *
8 * This program is free software; you can redistribute it and/or modify 7 * 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 8 * it under the terms of the GNU General Public License as published by
@@ -22,10 +21,11 @@
22 21
23#define MODULE_NAME "zc3xx" 22#define MODULE_NAME "zc3xx"
24 23
24#include <linux/input.h>
25#include "gspca.h" 25#include "gspca.h"
26#include "jpeg.h" 26#include "jpeg.h"
27 27
28MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>, " 28MODULE_AUTHOR("Jean-Francois Moine <http://moinejf.free.fr>, "
29 "Serge A. Suchkov <Serge.A.S@tochka.ru>"); 29 "Serge A. Suchkov <Serge.A.S@tochka.ru>");
30MODULE_DESCRIPTION("GSPCA ZC03xx/VC3xx USB Camera Driver"); 30MODULE_DESCRIPTION("GSPCA ZC03xx/VC3xx USB Camera Driver");
31MODULE_LICENSE("GPL"); 31MODULE_LICENSE("GPL");
@@ -39,18 +39,18 @@ static int force_sensor = -1;
39struct sd { 39struct sd {
40 struct gspca_dev gspca_dev; /* !! must be the first item */ 40 struct gspca_dev gspca_dev; /* !! must be the first item */
41 41
42 __u8 brightness; 42 u8 brightness;
43 __u8 contrast; 43 u8 contrast;
44 __u8 gamma; 44 u8 gamma;
45 __u8 autogain; 45 u8 autogain;
46 __u8 lightfreq; 46 u8 lightfreq;
47 __u8 sharpness; 47 u8 sharpness;
48 u8 quality; /* image quality */ 48 u8 quality; /* image quality */
49#define QUALITY_MIN 40 49#define QUALITY_MIN 40
50#define QUALITY_MAX 60 50#define QUALITY_MAX 60
51#define QUALITY_DEF 50 51#define QUALITY_DEF 50
52 52
53 signed char sensor; /* Type of image sensor chip */ 53 u8 sensor; /* Type of image sensor chip */
54/* !! values used in different tables */ 54/* !! values used in different tables */
55#define SENSOR_ADCM2700 0 55#define SENSOR_ADCM2700 0
56#define SENSOR_CS2102 1 56#define SENSOR_CS2102 1
@@ -92,9 +92,8 @@ static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val);
92static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val); 92static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val);
93static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val); 93static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val);
94 94
95static struct ctrl sd_ctrls[] = { 95static const struct ctrl sd_ctrls[] = {
96#define BRIGHTNESS_IDX 0 96#define BRIGHTNESS_IDX 0
97#define SD_BRIGHTNESS 0
98 { 97 {
99 { 98 {
100 .id = V4L2_CID_BRIGHTNESS, 99 .id = V4L2_CID_BRIGHTNESS,
@@ -103,26 +102,26 @@ static struct ctrl sd_ctrls[] = {
103 .minimum = 0, 102 .minimum = 0,
104 .maximum = 255, 103 .maximum = 255,
105 .step = 1, 104 .step = 1,
106 .default_value = 128, 105#define BRIGHTNESS_DEF 128
106 .default_value = BRIGHTNESS_DEF,
107 }, 107 },
108 .set = sd_setbrightness, 108 .set = sd_setbrightness,
109 .get = sd_getbrightness, 109 .get = sd_getbrightness,
110 }, 110 },
111#define SD_CONTRAST 1
112 { 111 {
113 { 112 {
114 .id = V4L2_CID_CONTRAST, 113 .id = V4L2_CID_CONTRAST,
115 .type = V4L2_CTRL_TYPE_INTEGER, 114 .type = V4L2_CTRL_TYPE_INTEGER,
116 .name = "Contrast", 115 .name = "Contrast",
117 .minimum = 0, 116 .minimum = 0,
118 .maximum = 256, 117 .maximum = 255,
119 .step = 1, 118 .step = 1,
120 .default_value = 128, 119#define CONTRAST_DEF 128
120 .default_value = CONTRAST_DEF,
121 }, 121 },
122 .set = sd_setcontrast, 122 .set = sd_setcontrast,
123 .get = sd_getcontrast, 123 .get = sd_getcontrast,
124 }, 124 },
125#define SD_GAMMA 2
126 { 125 {
127 { 126 {
128 .id = V4L2_CID_GAMMA, 127 .id = V4L2_CID_GAMMA,
@@ -136,7 +135,6 @@ static struct ctrl sd_ctrls[] = {
136 .set = sd_setgamma, 135 .set = sd_setgamma,
137 .get = sd_getgamma, 136 .get = sd_getgamma,
138 }, 137 },
139#define SD_AUTOGAIN 3
140 { 138 {
141 { 139 {
142 .id = V4L2_CID_AUTOGAIN, 140 .id = V4L2_CID_AUTOGAIN,
@@ -145,13 +143,13 @@ static struct ctrl sd_ctrls[] = {
145 .minimum = 0, 143 .minimum = 0,
146 .maximum = 1, 144 .maximum = 1,
147 .step = 1, 145 .step = 1,
148 .default_value = 1, 146#define AUTOGAIN_DEF 1
147 .default_value = AUTOGAIN_DEF,
149 }, 148 },
150 .set = sd_setautogain, 149 .set = sd_setautogain,
151 .get = sd_getautogain, 150 .get = sd_getautogain,
152 }, 151 },
153#define LIGHTFREQ_IDX 4 152#define LIGHTFREQ_IDX 4
154#define SD_FREQ 4
155 { 153 {
156 { 154 {
157 .id = V4L2_CID_POWER_LINE_FREQUENCY, 155 .id = V4L2_CID_POWER_LINE_FREQUENCY,
@@ -160,12 +158,12 @@ static struct ctrl sd_ctrls[] = {
160 .minimum = 0, 158 .minimum = 0,
161 .maximum = 2, /* 0: 0, 1: 50Hz, 2:60Hz */ 159 .maximum = 2, /* 0: 0, 1: 50Hz, 2:60Hz */
162 .step = 1, 160 .step = 1,
163 .default_value = 1, 161#define FREQ_DEF 0
162 .default_value = FREQ_DEF,
164 }, 163 },
165 .set = sd_setfreq, 164 .set = sd_setfreq,
166 .get = sd_getfreq, 165 .get = sd_getfreq,
167 }, 166 },
168#define SD_SHARPNESS 5
169 { 167 {
170 { 168 {
171 .id = V4L2_CID_SHARPNESS, 169 .id = V4L2_CID_SHARPNESS,
@@ -174,7 +172,8 @@ static struct ctrl sd_ctrls[] = {
174 .minimum = 0, 172 .minimum = 0,
175 .maximum = 3, 173 .maximum = 3,
176 .step = 1, 174 .step = 1,
177 .default_value = 2, 175#define SHARPNESS_DEF 2
176 .default_value = SHARPNESS_DEF,
178 }, 177 },
179 .set = sd_setsharpness, 178 .set = sd_setsharpness,
180 .get = sd_getsharpness, 179 .get = sd_getsharpness,
@@ -194,6 +193,19 @@ static const struct v4l2_pix_format vga_mode[] = {
194 .priv = 0}, 193 .priv = 0},
195}; 194};
196 195
196static const struct v4l2_pix_format broken_vga_mode[] = {
197 {320, 232, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
198 .bytesperline = 320,
199 .sizeimage = 320 * 232 * 4 / 8 + 590,
200 .colorspace = V4L2_COLORSPACE_JPEG,
201 .priv = 1},
202 {640, 472, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
203 .bytesperline = 640,
204 .sizeimage = 640 * 472 * 3 / 8 + 590,
205 .colorspace = V4L2_COLORSPACE_JPEG,
206 .priv = 0},
207};
208
197static const struct v4l2_pix_format sif_mode[] = { 209static const struct v4l2_pix_format sif_mode[] = {
198 {176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, 210 {176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
199 .bytesperline = 176, 211 .bytesperline = 176,
@@ -209,9 +221,9 @@ static const struct v4l2_pix_format sif_mode[] = {
209 221
210/* usb exchanges */ 222/* usb exchanges */
211struct usb_action { 223struct usb_action {
212 __u8 req; 224 u8 req;
213 __u8 val; 225 u8 val;
214 __u16 idx; 226 u16 idx;
215}; 227};
216 228
217static const struct usb_action adcm2700_Initial[] = { 229static const struct usb_action adcm2700_Initial[] = {
@@ -421,7 +433,7 @@ static const struct usb_action adcm2700_NoFliker[] = {
421 {0xaa, 0xfe, 0x0010}, /* 00,fe,10,aa */ 433 {0xaa, 0xfe, 0x0010}, /* 00,fe,10,aa */
422 {} 434 {}
423}; 435};
424static const struct usb_action cs2102_Initial[] = { /* 320x240 */ 436static const struct usb_action cs2102_InitialScale[] = { /* 320x240 */
425 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, 437 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
426 {0xa0, 0x10, ZC3XX_R002_CLOCKSELECT}, 438 {0xa0, 0x10, ZC3XX_R002_CLOCKSELECT},
427 {0xa0, 0x00, ZC3XX_R010_CMOSSENSORSELECT}, 439 {0xa0, 0x00, ZC3XX_R010_CMOSSENSORSELECT},
@@ -473,7 +485,7 @@ static const struct usb_action cs2102_Initial[] = { /* 320x240 */
473 {} 485 {}
474}; 486};
475 487
476static const struct usb_action cs2102_InitialScale[] = { /* 640x480 */ 488static const struct usb_action cs2102_Initial[] = { /* 640x480 */
477 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, 489 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
478 {0xa0, 0x00, ZC3XX_R002_CLOCKSELECT}, 490 {0xa0, 0x00, ZC3XX_R002_CLOCKSELECT},
479 {0xa0, 0x00, ZC3XX_R010_CMOSSENSORSELECT}, 491 {0xa0, 0x00, ZC3XX_R010_CMOSSENSORSELECT},
@@ -524,7 +536,7 @@ static const struct usb_action cs2102_InitialScale[] = { /* 640x480 */
524 {0xa0, 0x00, 0x01ad}, 536 {0xa0, 0x00, 0x01ad},
525 {} 537 {}
526}; 538};
527static const struct usb_action cs2102_50HZ[] = { 539static const struct usb_action cs2102_50HZScale[] = {
528 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, 540 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
529 {0xaa, 0x23, 0x0001}, 541 {0xaa, 0x23, 0x0001},
530 {0xaa, 0x24, 0x005f}, 542 {0xaa, 0x24, 0x005f},
@@ -546,7 +558,7 @@ static const struct usb_action cs2102_50HZ[] = {
546 {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, 558 {0xa0, 0xff, ZC3XX_R020_HSYNC_3},
547 {} 559 {}
548}; 560};
549static const struct usb_action cs2102_50HZScale[] = { 561static const struct usb_action cs2102_50HZ[] = {
550 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, 562 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
551 {0xaa, 0x23, 0x0000}, 563 {0xaa, 0x23, 0x0000},
552 {0xaa, 0x24, 0x00af}, 564 {0xaa, 0x24, 0x00af},
@@ -568,7 +580,7 @@ static const struct usb_action cs2102_50HZScale[] = {
568 {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, 580 {0xa0, 0xff, ZC3XX_R020_HSYNC_3},
569 {} 581 {}
570}; 582};
571static const struct usb_action cs2102_60HZ[] = { 583static const struct usb_action cs2102_60HZScale[] = {
572 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, 584 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
573 {0xaa, 0x23, 0x0001}, 585 {0xaa, 0x23, 0x0001},
574 {0xaa, 0x24, 0x0055}, 586 {0xaa, 0x24, 0x0055},
@@ -590,7 +602,7 @@ static const struct usb_action cs2102_60HZ[] = {
590 {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, 602 {0xa0, 0xff, ZC3XX_R020_HSYNC_3},
591 {} 603 {}
592}; 604};
593static const struct usb_action cs2102_60HZScale[] = { 605static const struct usb_action cs2102_60HZ[] = {
594 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, 606 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
595 {0xaa, 0x23, 0x0000}, 607 {0xaa, 0x23, 0x0000},
596 {0xaa, 0x24, 0x00aa}, 608 {0xaa, 0x24, 0x00aa},
@@ -612,7 +624,7 @@ static const struct usb_action cs2102_60HZScale[] = {
612 {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, 624 {0xa0, 0xff, ZC3XX_R020_HSYNC_3},
613 {} 625 {}
614}; 626};
615static const struct usb_action cs2102_NoFliker[] = { 627static const struct usb_action cs2102_NoFlikerScale[] = {
616 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, 628 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
617 {0xaa, 0x23, 0x0001}, 629 {0xaa, 0x23, 0x0001},
618 {0xaa, 0x24, 0x005f}, 630 {0xaa, 0x24, 0x005f},
@@ -634,7 +646,7 @@ static const struct usb_action cs2102_NoFliker[] = {
634 {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, 646 {0xa0, 0xff, ZC3XX_R020_HSYNC_3},
635 {} 647 {}
636}; 648};
637static const struct usb_action cs2102_NoFlikerScale[] = { 649static const struct usb_action cs2102_NoFliker[] = {
638 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, 650 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
639 {0xaa, 0x23, 0x0000}, 651 {0xaa, 0x23, 0x0000},
640 {0xaa, 0x24, 0x00af}, 652 {0xaa, 0x24, 0x00af},
@@ -658,7 +670,7 @@ static const struct usb_action cs2102_NoFlikerScale[] = {
658}; 670};
659 671
660/* CS2102_KOCOM */ 672/* CS2102_KOCOM */
661static const struct usb_action cs2102K_Initial[] = { 673static const struct usb_action cs2102K_InitialScale[] = {
662 {0xa0, 0x11, ZC3XX_R002_CLOCKSELECT}, 674 {0xa0, 0x11, ZC3XX_R002_CLOCKSELECT},
663 {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, 675 {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},
664 {0xa0, 0x08, ZC3XX_R010_CMOSSENSORSELECT}, 676 {0xa0, 0x08, ZC3XX_R010_CMOSSENSORSELECT},
@@ -917,7 +929,7 @@ static const struct usb_action cs2102K_Initial[] = {
917 {} 929 {}
918}; 930};
919 931
920static const struct usb_action cs2102K_InitialScale[] = { 932static const struct usb_action cs2102K_Initial[] = {
921 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, 933 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
922 {0xa0, 0x00, ZC3XX_R002_CLOCKSELECT}, 934 {0xa0, 0x00, ZC3XX_R002_CLOCKSELECT},
923 {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, 935 {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},
@@ -1495,7 +1507,7 @@ static const struct usb_action gc0305_NoFliker[] = {
1495 {} 1507 {}
1496}; 1508};
1497 1509
1498static const struct usb_action hdcs2020xb_Initial[] = { 1510static const struct usb_action hdcs2020b_InitialScale[] = {
1499 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, 1511 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
1500 {0xa0, 0x11, ZC3XX_R002_CLOCKSELECT}, 1512 {0xa0, 0x11, ZC3XX_R002_CLOCKSELECT},
1501 {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* qtable 0x05 */ 1513 {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* qtable 0x05 */
@@ -1627,7 +1639,7 @@ static const struct usb_action hdcs2020xb_Initial[] = {
1627 {0xa0, 0x40, ZC3XX_R118_BGAIN}, 1639 {0xa0, 0x40, ZC3XX_R118_BGAIN},
1628 {} 1640 {}
1629}; 1641};
1630static const struct usb_action hdcs2020xb_InitialScale[] = { 1642static const struct usb_action hdcs2020b_Initial[] = {
1631 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, 1643 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
1632 {0xa0, 0x00, ZC3XX_R002_CLOCKSELECT}, 1644 {0xa0, 0x00, ZC3XX_R002_CLOCKSELECT},
1633 {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, 1645 {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},
@@ -1819,7 +1831,7 @@ static const struct usb_action hdcs2020b_NoFliker[] = {
1819 {} 1831 {}
1820}; 1832};
1821 1833
1822static const struct usb_action hv7131bxx_Initial[] = { /* 320x240 */ 1834static const struct usb_action hv7131b_InitialScale[] = { /* 320x240 */
1823 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, 1835 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
1824 {0xa0, 0x10, ZC3XX_R002_CLOCKSELECT}, 1836 {0xa0, 0x10, ZC3XX_R002_CLOCKSELECT},
1825 {0xa0, 0x00, ZC3XX_R010_CMOSSENSORSELECT}, 1837 {0xa0, 0x00, ZC3XX_R010_CMOSSENSORSELECT},
@@ -1866,7 +1878,7 @@ static const struct usb_action hv7131bxx_Initial[] = { /* 320x240 */
1866 {} 1878 {}
1867}; 1879};
1868 1880
1869static const struct usb_action hv7131bxx_InitialScale[] = { /* 640x480*/ 1881static const struct usb_action hv7131b_Initial[] = { /* 640x480*/
1870 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, 1882 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
1871 {0xa0, 0x00, ZC3XX_R002_CLOCKSELECT}, 1883 {0xa0, 0x00, ZC3XX_R002_CLOCKSELECT},
1872 {0xa0, 0x00, ZC3XX_R010_CMOSSENSORSELECT}, 1884 {0xa0, 0x00, ZC3XX_R010_CMOSSENSORSELECT},
@@ -2063,7 +2075,7 @@ static const struct usb_action hv7131b_NoFlikerScale[] = { /* 320x240 */
2063 {} 2075 {}
2064}; 2076};
2065 2077
2066static const struct usb_action hv7131cxx_Initial[] = { 2078static const struct usb_action hv7131r_InitialScale[] = {
2067 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, 2079 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
2068 {0xa0, 0x10, ZC3XX_R002_CLOCKSELECT}, 2080 {0xa0, 0x10, ZC3XX_R002_CLOCKSELECT},
2069 {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, 2081 {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT},
@@ -2157,7 +2169,7 @@ static const struct usb_action hv7131cxx_Initial[] = {
2157 {} 2169 {}
2158}; 2170};
2159 2171
2160static const struct usb_action hv7131cxx_InitialScale[] = { 2172static const struct usb_action hv7131r_Initial[] = {
2161 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, 2173 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
2162 2174
2163 {0xa0, 0x00, ZC3XX_R002_CLOCKSELECT}, /* diff */ 2175 {0xa0, 0x00, ZC3XX_R002_CLOCKSELECT}, /* diff */
@@ -2259,7 +2271,7 @@ static const struct usb_action hv7131cxx_InitialScale[] = {
2259 {} 2271 {}
2260}; 2272};
2261 2273
2262static const struct usb_action icm105axx_Initial[] = { 2274static const struct usb_action icm105a_InitialScale[] = {
2263 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, 2275 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
2264 {0xa0, 0x10, ZC3XX_R002_CLOCKSELECT}, 2276 {0xa0, 0x10, ZC3XX_R002_CLOCKSELECT},
2265 {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, 2277 {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},
@@ -2436,7 +2448,7 @@ static const struct usb_action icm105axx_Initial[] = {
2436 {} 2448 {}
2437}; 2449};
2438 2450
2439static const struct usb_action icm105axx_InitialScale[] = { 2451static const struct usb_action icm105a_Initial[] = {
2440 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, 2452 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
2441 {0xa0, 0x00, ZC3XX_R002_CLOCKSELECT}, 2453 {0xa0, 0x00, ZC3XX_R002_CLOCKSELECT},
2442 {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, 2454 {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},
@@ -2615,7 +2627,7 @@ static const struct usb_action icm105axx_InitialScale[] = {
2615 {0xa0, 0x40, ZC3XX_R118_BGAIN}, 2627 {0xa0, 0x40, ZC3XX_R118_BGAIN},
2616 {} 2628 {}
2617}; 2629};
2618static const struct usb_action icm105a_50HZ[] = { 2630static const struct usb_action icm105a_50HZScale[] = {
2619 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */ 2631 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
2620 {0xaa, 0x0d, 0x0003}, /* 00,0d,03,aa */ 2632 {0xaa, 0x0d, 0x0003}, /* 00,0d,03,aa */
2621 {0xaa, 0x0c, 0x0020}, /* 00,0c,20,aa */ 2633 {0xaa, 0x0c, 0x0020}, /* 00,0c,20,aa */
@@ -2646,7 +2658,7 @@ static const struct usb_action icm105a_50HZ[] = {
2646 {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc */ 2658 {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc */
2647 {} 2659 {}
2648}; 2660};
2649static const struct usb_action icm105a_50HZScale[] = { 2661static const struct usb_action icm105a_50HZ[] = {
2650 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */ 2662 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
2651 {0xaa, 0x0d, 0x0003}, /* 00,0d,03,aa */ 2663 {0xaa, 0x0d, 0x0003}, /* 00,0d,03,aa */
2652 {0xaa, 0x0c, 0x008c}, /* 00,0c,8c,aa */ 2664 {0xaa, 0x0c, 0x008c}, /* 00,0c,8c,aa */
@@ -2679,7 +2691,7 @@ static const struct usb_action icm105a_50HZScale[] = {
2679 {0xa0, 0xc0, ZC3XX_R1A8_DIGITALGAIN}, /* 01,a8,c0,cc */ 2691 {0xa0, 0xc0, ZC3XX_R1A8_DIGITALGAIN}, /* 01,a8,c0,cc */
2680 {} 2692 {}
2681}; 2693};
2682static const struct usb_action icm105a_60HZ[] = { 2694static const struct usb_action icm105a_60HZScale[] = {
2683 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */ 2695 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
2684 {0xaa, 0x0d, 0x0003}, /* 00,0d,03,aa */ 2696 {0xaa, 0x0d, 0x0003}, /* 00,0d,03,aa */
2685 {0xaa, 0x0c, 0x0004}, /* 00,0c,04,aa */ 2697 {0xaa, 0x0c, 0x0004}, /* 00,0c,04,aa */
@@ -2710,7 +2722,7 @@ static const struct usb_action icm105a_60HZ[] = {
2710 {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc */ 2722 {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc */
2711 {} 2723 {}
2712}; 2724};
2713static const struct usb_action icm105a_60HZScale[] = { 2725static const struct usb_action icm105a_60HZ[] = {
2714 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */ 2726 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
2715 {0xaa, 0x0d, 0x0003}, /* 00,0d,03,aa */ 2727 {0xaa, 0x0d, 0x0003}, /* 00,0d,03,aa */
2716 {0xaa, 0x0c, 0x0008}, /* 00,0c,08,aa */ 2728 {0xaa, 0x0c, 0x0008}, /* 00,0c,08,aa */
@@ -2743,7 +2755,7 @@ static const struct usb_action icm105a_60HZScale[] = {
2743 {0xa0, 0xc0, ZC3XX_R1A8_DIGITALGAIN}, /* 01,a8,c0,cc */ 2755 {0xa0, 0xc0, ZC3XX_R1A8_DIGITALGAIN}, /* 01,a8,c0,cc */
2744 {} 2756 {}
2745}; 2757};
2746static const struct usb_action icm105a_NoFliker[] = { 2758static const struct usb_action icm105a_NoFlikerScale[] = {
2747 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */ 2759 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
2748 {0xaa, 0x0d, 0x0003}, /* 00,0d,03,aa */ 2760 {0xaa, 0x0d, 0x0003}, /* 00,0d,03,aa */
2749 {0xaa, 0x0c, 0x0004}, /* 00,0c,04,aa */ 2761 {0xaa, 0x0c, 0x0004}, /* 00,0c,04,aa */
@@ -2774,7 +2786,7 @@ static const struct usb_action icm105a_NoFliker[] = {
2774 {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc */ 2786 {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc */
2775 {} 2787 {}
2776}; 2788};
2777static const struct usb_action icm105a_NoFlikerScale[] = { 2789static const struct usb_action icm105a_NoFliker[] = {
2778 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */ 2790 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
2779 {0xaa, 0x0d, 0x0003}, /* 00,0d,03,aa */ 2791 {0xaa, 0x0d, 0x0003}, /* 00,0d,03,aa */
2780 {0xaa, 0x0c, 0x0004}, /* 00,0c,04,aa */ 2792 {0xaa, 0x0c, 0x0004}, /* 00,0c,04,aa */
@@ -2808,7 +2820,7 @@ static const struct usb_action icm105a_NoFlikerScale[] = {
2808 {} 2820 {}
2809}; 2821};
2810 2822
2811static const struct usb_action MC501CB_InitialScale[] = { 2823static const struct usb_action mc501cb_Initial[] = {
2812 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, /* 00,00,01,cc */ 2824 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, /* 00,00,01,cc */
2813 {0xa0, 0x00, ZC3XX_R002_CLOCKSELECT}, /* 00,02,00,cc */ 2825 {0xa0, 0x00, ZC3XX_R002_CLOCKSELECT}, /* 00,02,00,cc */
2814 {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */ 2826 {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */
@@ -2928,7 +2940,7 @@ static const struct usb_action MC501CB_InitialScale[] = {
2928 {} 2940 {}
2929}; 2941};
2930 2942
2931static const struct usb_action MC501CB_Initial[] = { /* 320x240 */ 2943static const struct usb_action mc501cb_InitialScale[] = { /* 320x240 */
2932 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, /* 00,00,01,cc */ 2944 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, /* 00,00,01,cc */
2933 {0xa0, 0x10, ZC3XX_R002_CLOCKSELECT}, /* 00,02,10,cc */ 2945 {0xa0, 0x10, ZC3XX_R002_CLOCKSELECT}, /* 00,02,10,cc */
2934 {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */ 2946 {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */
@@ -3047,7 +3059,7 @@ static const struct usb_action MC501CB_Initial[] = { /* 320x240 */
3047 {} 3059 {}
3048}; 3060};
3049 3061
3050static const struct usb_action MC501CB_50HZ[] = { 3062static const struct usb_action mc501cb_50HZScale[] = {
3051 {0xaa, 0x03, 0x0003}, /* 00,03,03,aa */ 3063 {0xaa, 0x03, 0x0003}, /* 00,03,03,aa */
3052 {0xaa, 0x10, 0x00fc}, /* 00,10,fc,aa */ 3064 {0xaa, 0x10, 0x00fc}, /* 00,10,fc,aa */
3053 {0xaa, 0x36, 0x001d}, /* 00,36,1D,aa */ 3065 {0xaa, 0x36, 0x001d}, /* 00,36,1D,aa */
@@ -3064,7 +3076,7 @@ static const struct usb_action MC501CB_50HZ[] = {
3064 {} 3076 {}
3065}; 3077};
3066 3078
3067static const struct usb_action MC501CB_50HZScale[] = { 3079static const struct usb_action mc501cb_50HZ[] = {
3068 {0xaa, 0x03, 0x0003}, /* 00,03,03,aa */ 3080 {0xaa, 0x03, 0x0003}, /* 00,03,03,aa */
3069 {0xaa, 0x10, 0x00fc}, /* 00,10,fc,aa */ 3081 {0xaa, 0x10, 0x00fc}, /* 00,10,fc,aa */
3070 {0xaa, 0x36, 0x003a}, /* 00,36,3A,aa */ 3082 {0xaa, 0x36, 0x003a}, /* 00,36,3A,aa */
@@ -3081,7 +3093,7 @@ static const struct usb_action MC501CB_50HZScale[] = {
3081 {} 3093 {}
3082}; 3094};
3083 3095
3084static const struct usb_action MC501CB_60HZ[] = { 3096static const struct usb_action mc501cb_60HZScale[] = {
3085 {0xaa, 0x03, 0x0003}, /* 00,03,03,aa */ 3097 {0xaa, 0x03, 0x0003}, /* 00,03,03,aa */
3086 {0xaa, 0x10, 0x00fc}, /* 00,10,fc,aa */ 3098 {0xaa, 0x10, 0x00fc}, /* 00,10,fc,aa */
3087 {0xaa, 0x36, 0x0018}, /* 00,36,18,aa */ 3099 {0xaa, 0x36, 0x0018}, /* 00,36,18,aa */
@@ -3098,7 +3110,7 @@ static const struct usb_action MC501CB_60HZ[] = {
3098 {} 3110 {}
3099}; 3111};
3100 3112
3101static const struct usb_action MC501CB_60HZScale[] = { 3113static const struct usb_action mc501cb_60HZ[] = {
3102 {0xaa, 0x03, 0x0003}, /* 00,03,03,aa */ 3114 {0xaa, 0x03, 0x0003}, /* 00,03,03,aa */
3103 {0xaa, 0x10, 0x00fc}, /* 00,10,fc,aa */ 3115 {0xaa, 0x10, 0x00fc}, /* 00,10,fc,aa */
3104 {0xaa, 0x36, 0x0030}, /* 00,36,30,aa */ 3116 {0xaa, 0x36, 0x0030}, /* 00,36,30,aa */
@@ -3115,7 +3127,7 @@ static const struct usb_action MC501CB_60HZScale[] = {
3115 {} 3127 {}
3116}; 3128};
3117 3129
3118static const struct usb_action MC501CB_NoFliker[] = { 3130static const struct usb_action mc501cb_NoFlikerScale[] = {
3119 {0xaa, 0x03, 0x0003}, /* 00,03,03,aa */ 3131 {0xaa, 0x03, 0x0003}, /* 00,03,03,aa */
3120 {0xaa, 0x10, 0x00fc}, /* 00,10,fc,aa */ 3132 {0xaa, 0x10, 0x00fc}, /* 00,10,fc,aa */
3121 {0xaa, 0x36, 0x0018}, /* 00,36,18,aa */ 3133 {0xaa, 0x36, 0x0018}, /* 00,36,18,aa */
@@ -3132,7 +3144,7 @@ static const struct usb_action MC501CB_NoFliker[] = {
3132 {} 3144 {}
3133}; 3145};
3134 3146
3135static const struct usb_action MC501CB_NoFlikerScale[] = { 3147static const struct usb_action mc501cb_NoFliker[] = {
3136 {0xaa, 0x03, 0x0003}, /* 00,03,03,aa */ 3148 {0xaa, 0x03, 0x0003}, /* 00,03,03,aa */
3137 {0xaa, 0x10, 0x00fc}, /* 00,10,fc,aa */ 3149 {0xaa, 0x10, 0x00fc}, /* 00,10,fc,aa */
3138 {0xaa, 0x36, 0x0030}, /* 00,36,30,aa */ 3150 {0xaa, 0x36, 0x0030}, /* 00,36,30,aa */
@@ -3144,8 +3156,8 @@ static const struct usb_action MC501CB_NoFlikerScale[] = {
3144 {} 3156 {}
3145}; 3157};
3146 3158
3147/* from zs211.inf - HKR,%OV7620%,Initial - 640x480 */ 3159/* from zs211.inf */
3148static const struct usb_action OV7620_mode0[] = { 3160static const struct usb_action ov7620_Initial[] = { /* 640x480 */
3149 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, /* 00,00,01,cc */ 3161 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, /* 00,00,01,cc */
3150 {0xa0, 0x40, ZC3XX_R002_CLOCKSELECT}, /* 00,02,40,cc */ 3162 {0xa0, 0x40, ZC3XX_R002_CLOCKSELECT}, /* 00,02,40,cc */
3151 {0xa0, 0x00, ZC3XX_R008_CLOCKSETTING}, /* 00,08,00,cc */ 3163 {0xa0, 0x00, ZC3XX_R008_CLOCKSETTING}, /* 00,08,00,cc */
@@ -3214,9 +3226,7 @@ static const struct usb_action OV7620_mode0[] = {
3214 {0xa0, 0x50, ZC3XX_R1A8_DIGITALGAIN}, /* 01,a8,50,cc */ 3226 {0xa0, 0x50, ZC3XX_R1A8_DIGITALGAIN}, /* 01,a8,50,cc */
3215 {} 3227 {}
3216}; 3228};
3217 3229static const struct usb_action ov7620_InitialScale[] = { /* 320x240 */
3218/* from zs211.inf - HKR,%OV7620%,InitialScale - 320x240 */
3219static const struct usb_action OV7620_mode1[] = {
3220 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, /* 00,00,01,cc */ 3230 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, /* 00,00,01,cc */
3221 {0xa0, 0x50, ZC3XX_R002_CLOCKSELECT}, /* 00,02,50,cc */ 3231 {0xa0, 0x50, ZC3XX_R002_CLOCKSELECT}, /* 00,02,50,cc */
3222 {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* 00,08,00,cc */ 3232 {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* 00,08,00,cc */
@@ -3287,9 +3297,7 @@ static const struct usb_action OV7620_mode1[] = {
3287 {0xa0, 0x50, ZC3XX_R1A8_DIGITALGAIN}, /* 01,a8,50,cc */ 3297 {0xa0, 0x50, ZC3XX_R1A8_DIGITALGAIN}, /* 01,a8,50,cc */
3288 {} 3298 {}
3289}; 3299};
3290 3300static const struct usb_action ov7620_50HZ[] = {
3291/* from zs211.inf - HKR,%OV7620%\AE,50HZ */
3292static const struct usb_action OV7620_50HZ[] = {
3293 {0xaa, 0x13, 0x00a3}, /* 00,13,a3,aa */ 3301 {0xaa, 0x13, 0x00a3}, /* 00,13,a3,aa */
3294 {0xdd, 0x00, 0x0100}, /* 00,01,00,dd */ 3302 {0xdd, 0x00, 0x0100}, /* 00,01,00,dd */
3295 {0xaa, 0x2b, 0x0096}, /* 00,2b,96,aa */ 3303 {0xaa, 0x2b, 0x0096}, /* 00,2b,96,aa */
@@ -3307,9 +3315,7 @@ static const struct usb_action OV7620_50HZ[] = {
3307 if mode0 (640x480) */ 3315 if mode0 (640x480) */
3308 {} 3316 {}
3309}; 3317};
3310 3318static const struct usb_action ov7620_60HZ[] = {
3311/* from zs211.inf - HKR,%OV7620%\AE,60HZ */
3312static const struct usb_action OV7620_60HZ[] = {
3313 {0xaa, 0x13, 0x00a3}, /* 00,13,a3,aa */ 3319 {0xaa, 0x13, 0x00a3}, /* 00,13,a3,aa */
3314 /* (bug in zs211.inf) */ 3320 /* (bug in zs211.inf) */
3315 {0xdd, 0x00, 0x0100}, /* 00,01,00,dd */ 3321 {0xdd, 0x00, 0x0100}, /* 00,01,00,dd */
@@ -3331,9 +3337,7 @@ static const struct usb_action OV7620_60HZ[] = {
3331 {0xa1, 0x01, 0x0037}, */ 3337 {0xa1, 0x01, 0x0037}, */
3332 {} 3338 {}
3333}; 3339};
3334 3340static const struct usb_action ov7620_NoFliker[] = {
3335/* from zs211.inf - HKR,%OV7620%\AE,NoFliker */
3336static const struct usb_action OV7620_NoFliker[] = {
3337 {0xaa, 0x13, 0x00a3}, /* 00,13,a3,aa */ 3341 {0xaa, 0x13, 0x00a3}, /* 00,13,a3,aa */
3338 /* (bug in zs211.inf) */ 3342 /* (bug in zs211.inf) */
3339 {0xdd, 0x00, 0x0100}, /* 00,01,00,dd */ 3343 {0xdd, 0x00, 0x0100}, /* 00,01,00,dd */
@@ -3354,7 +3358,7 @@ static const struct usb_action OV7620_NoFliker[] = {
3354 {} 3358 {}
3355}; 3359};
3356 3360
3357static const struct usb_action ov7630c_Initial[] = { 3361static const struct usb_action ov7630c_InitialScale[] = {
3358 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, 3362 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
3359 {0xa0, 0x10, ZC3XX_R002_CLOCKSELECT}, 3363 {0xa0, 0x10, ZC3XX_R002_CLOCKSELECT},
3360 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, 3364 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
@@ -3511,7 +3515,7 @@ static const struct usb_action ov7630c_Initial[] = {
3511 {} 3515 {}
3512}; 3516};
3513 3517
3514static const struct usb_action ov7630c_InitialScale[] = { 3518static const struct usb_action ov7630c_Initial[] = {
3515 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, 3519 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
3516 {0xa0, 0x00, ZC3XX_R002_CLOCKSELECT}, 3520 {0xa0, 0x00, ZC3XX_R002_CLOCKSELECT},
3517 {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, 3521 {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},
@@ -3682,7 +3686,7 @@ static const struct usb_action pas106b_Initial_com[] = {
3682 {} 3686 {}
3683}; 3687};
3684 3688
3685static const struct usb_action pas106b_Initial[] = { /* 176x144 */ 3689static const struct usb_action pas106b_InitialScale[] = { /* 176x144 */
3686/* JPEG control */ 3690/* JPEG control */
3687 {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, 3691 {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},
3688/* Sream and Sensor specific */ 3692/* Sream and Sensor specific */
@@ -3800,7 +3804,7 @@ static const struct usb_action pas106b_Initial[] = { /* 176x144 */
3800 {} 3804 {}
3801}; 3805};
3802 3806
3803static const struct usb_action pas106b_InitialScale[] = { /* 352x288 */ 3807static const struct usb_action pas106b_Initial[] = { /* 352x288 */
3804/* JPEG control */ 3808/* JPEG control */
3805 {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, 3809 {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},
3806/* Sream and Sensor specific */ 3810/* Sream and Sensor specific */
@@ -3972,10 +3976,10 @@ static const struct usb_action pas106b_NoFliker[] = {
3972 {} 3976 {}
3973}; 3977};
3974 3978
3975/* from usbvm31b.inf */ 3979/* from lvWIMv.inf 046d:08a2/:08aa 2007/06/03 */
3976static const struct usb_action pas202b_Initial[] = { /* 640x480 */ 3980static const struct usb_action pas202b_Initial[] = { /* 640x480 */
3977 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, /* 00,00,01,cc */ 3981 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, /* 00,00,01,cc */
3978 {0xa0, 0x00, ZC3XX_R008_CLOCKSETTING}, /* 00,08,00,cc */ 3982 {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},
3979 {0xa0, 0x0e, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,0e,cc */ 3983 {0xa0, 0x0e, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,0e,cc */
3980 {0xa0, 0x00, ZC3XX_R002_CLOCKSELECT}, /* 00,02,00,cc */ 3984 {0xa0, 0x00, ZC3XX_R002_CLOCKSELECT}, /* 00,02,00,cc */
3981 {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, /* 00,03,02,cc */ 3985 {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, /* 00,03,02,cc */
@@ -4000,7 +4004,7 @@ static const struct usb_action pas202b_Initial[] = { /* 640x480 */
4000 {0xaa, 0x09, 0x0006}, /* 00,09,06,aa */ 4004 {0xaa, 0x09, 0x0006}, /* 00,09,06,aa */
4001 {0xaa, 0x0a, 0x0001}, /* 00,0a,01,aa */ 4005 {0xaa, 0x0a, 0x0001}, /* 00,0a,01,aa */
4002 {0xaa, 0x0b, 0x0001}, /* 00,0b,01,aa */ 4006 {0xaa, 0x0b, 0x0001}, /* 00,0b,01,aa */
4003 {0xaa, 0x0c, 0x0008}, /* 00,0c,08,aa */ 4007 {0xaa, 0x0c, 0x0006},
4004 {0xaa, 0x0d, 0x0000}, /* 00,0d,00,aa */ 4008 {0xaa, 0x0d, 0x0000}, /* 00,0d,00,aa */
4005 {0xaa, 0x10, 0x0000}, /* 00,10,00,aa */ 4009 {0xaa, 0x10, 0x0000}, /* 00,10,00,aa */
4006 {0xaa, 0x12, 0x0005}, /* 00,12,05,aa */ 4010 {0xaa, 0x12, 0x0005}, /* 00,12,05,aa */
@@ -4019,13 +4023,13 @@ static const struct usb_action pas202b_Initial[] = { /* 640x480 */
4019}; 4023};
4020static const struct usb_action pas202b_InitialScale[] = { /* 320x240 */ 4024static const struct usb_action pas202b_InitialScale[] = { /* 320x240 */
4021 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, /* 00,00,01,cc */ 4025 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, /* 00,00,01,cc */
4022 {0xa0, 0x00, ZC3XX_R008_CLOCKSETTING}, /* 00,08,00,cc */ 4026 {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},
4023 {0xa0, 0x0e, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,0e,cc */ 4027 {0xa0, 0x0e, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,0e,cc */
4024 {0xa0, 0x10, ZC3XX_R002_CLOCKSELECT}, /* 00,02,10,cc */ 4028 {0xa0, 0x10, ZC3XX_R002_CLOCKSELECT}, /* 00,02,10,cc */
4025 {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, /* 00,03,02,cc */ 4029 {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, /* 00,03,02,cc */
4026 {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, /* 00,04,80,cc */ 4030 {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, /* 00,04,80,cc */
4027 {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, /* 00,05,01,cc */ 4031 {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, /* 00,05,01,cc */
4028 {0xa0, 0xd0, ZC3XX_R006_FRAMEHEIGHTLOW}, /* 00,06,d0,cc */ 4032 {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW},
4029 {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, /* 00,01,01,cc */ 4033 {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, /* 00,01,01,cc */
4030 {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,03,cc */ 4034 {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,03,cc */
4031 {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,01,cc */ 4035 {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,01,cc */
@@ -4035,7 +4039,7 @@ static const struct usb_action pas202b_InitialScale[] = { /* 320x240 */
4035 {0xa0, 0x08, ZC3XX_R11A_FIRSTYLOW}, /* 01,1a,08,cc */ 4039 {0xa0, 0x08, ZC3XX_R11A_FIRSTYLOW}, /* 01,1a,08,cc */
4036 {0xa0, 0x02, ZC3XX_R11C_FIRSTXLOW}, /* 01,1c,02,cc */ 4040 {0xa0, 0x02, ZC3XX_R11C_FIRSTXLOW}, /* 01,1c,02,cc */
4037 {0xa0, 0x01, ZC3XX_R09B_WINHEIGHTHIGH}, /* 00,9b,01,cc */ 4041 {0xa0, 0x01, ZC3XX_R09B_WINHEIGHTHIGH}, /* 00,9b,01,cc */
4038 {0xa0, 0xd8, ZC3XX_R09C_WINHEIGHTLOW}, /* 00,9c,d8,cc */ 4042 {0xa0, 0xe8, ZC3XX_R09C_WINHEIGHTLOW},
4039 {0xa0, 0x02, ZC3XX_R09D_WINWIDTHHIGH}, /* 00,9d,02,cc */ 4043 {0xa0, 0x02, ZC3XX_R09D_WINWIDTHHIGH}, /* 00,9d,02,cc */
4040 {0xa0, 0x88, ZC3XX_R09E_WINWIDTHLOW}, /* 00,9e,88,cc */ 4044 {0xa0, 0x88, ZC3XX_R09E_WINWIDTHLOW}, /* 00,9e,88,cc */
4041 {0xaa, 0x02, 0x0002}, /* 00,02,02,aa */ 4045 {0xaa, 0x02, 0x0002}, /* 00,02,02,aa */
@@ -4044,7 +4048,7 @@ static const struct usb_action pas202b_InitialScale[] = { /* 320x240 */
4044 {0xaa, 0x09, 0x0006}, /* 00,09,06,aa */ 4048 {0xaa, 0x09, 0x0006}, /* 00,09,06,aa */
4045 {0xaa, 0x0a, 0x0001}, /* 00,0a,01,aa */ 4049 {0xaa, 0x0a, 0x0001}, /* 00,0a,01,aa */
4046 {0xaa, 0x0b, 0x0001}, /* 00,0b,01,aa */ 4050 {0xaa, 0x0b, 0x0001}, /* 00,0b,01,aa */
4047 {0xaa, 0x0c, 0x0008}, /* 00,0c,08,aa */ 4051 {0xaa, 0x0c, 0x0006},
4048 {0xaa, 0x0d, 0x0000}, /* 00,0d,00,aa */ 4052 {0xaa, 0x0d, 0x0000}, /* 00,0d,00,aa */
4049 {0xaa, 0x10, 0x0000}, /* 00,10,00,aa */ 4053 {0xaa, 0x10, 0x0000}, /* 00,10,00,aa */
4050 {0xaa, 0x12, 0x0005}, /* 00,12,05,aa */ 4054 {0xaa, 0x12, 0x0005}, /* 00,12,05,aa */
@@ -4059,6 +4063,8 @@ static const struct usb_action pas202b_InitialScale[] = { /* 320x240 */
4059 {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, /* 02,50,08,cc */ 4063 {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, /* 02,50,08,cc */
4060 {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, /* 03,01,08,cc */ 4064 {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, /* 03,01,08,cc */
4061 {0xa0, 0x70, ZC3XX_R18D_YTARGET}, /* 01,8d,70,cc */ 4065 {0xa0, 0x70, ZC3XX_R18D_YTARGET}, /* 01,8d,70,cc */
4066 {0xa0, 0xff, ZC3XX_R097_WINYSTARTHIGH},
4067 {0xa0, 0xfe, ZC3XX_R098_WINYSTARTLOW},
4062 {} 4068 {}
4063}; 4069};
4064static const struct usb_action pas202b_50HZ[] = { 4070static const struct usb_action pas202b_50HZ[] = {
@@ -4066,22 +4072,22 @@ static const struct usb_action pas202b_50HZ[] = {
4066 {0xa0, 0x20, ZC3XX_R087_EXPTIMEMID}, /* 00,87,20,cc */ 4072 {0xa0, 0x20, ZC3XX_R087_EXPTIMEMID}, /* 00,87,20,cc */
4067 {0xa0, 0x21, ZC3XX_R088_EXPTIMELOW}, /* 00,88,21,cc */ 4073 {0xa0, 0x21, ZC3XX_R088_EXPTIMELOW}, /* 00,88,21,cc */
4068 {0xaa, 0x20, 0x0002}, /* 00,20,02,aa */ 4074 {0xaa, 0x20, 0x0002}, /* 00,20,02,aa */
4069 {0xaa, 0x21, 0x0068}, /* 00,21,68,aa */ 4075 {0xaa, 0x21, 0x001b},
4070 {0xaa, 0x03, 0x0044}, /* 00,03,44,aa */ 4076 {0xaa, 0x03, 0x0044}, /* 00,03,44,aa */
4071 {0xaa, 0x04, 0x0009}, /* 00,04,09,aa */ 4077 {0xaa, 0x04, 0x0008},
4072 {0xaa, 0x05, 0x0028}, /* 00,05,28,aa */ 4078 {0xaa, 0x05, 0x001b},
4073 {0xaa, 0x0e, 0x0001}, /* 00,0e,01,aa */ 4079 {0xaa, 0x0e, 0x0001}, /* 00,0e,01,aa */
4074 {0xaa, 0x0f, 0x0000}, /* 00,0f,00,aa */ 4080 {0xaa, 0x0f, 0x0000}, /* 00,0f,00,aa */
4075 {0xa0, 0x14, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,14,cc */ 4081 {0xa0, 0x1c, ZC3XX_R1A9_DIGITALLIMITDIFF},
4076 {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,24,cc */ 4082 {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,24,cc */
4077 {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */ 4083 {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */
4078 {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,07,cc */ 4084 {0xa0, 0x02, ZC3XX_R191_EXPOSURELIMITMID},
4079 {0xa0, 0xd2, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,d2,cc */ 4085 {0xa0, 0x1b, ZC3XX_R192_EXPOSURELIMITLOW},
4080 {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ 4086 {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
4081 {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */ 4087 {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */
4082 {0xa0, 0x4d, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,4d,cc */ 4088 {0xa0, 0x4d, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,4d,cc */
4083 {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */ 4089 {0xa0, 0x0e, ZC3XX_R18C_AEFREEZE},
4084 {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */ 4090 {0xa0, 0x1b, ZC3XX_R18F_AEUNFREEZE},
4085 {0xa0, 0x44, ZC3XX_R01D_HSYNC_0}, /* 00,1d,44,cc */ 4091 {0xa0, 0x44, ZC3XX_R01D_HSYNC_0}, /* 00,1d,44,cc */
4086 {0xa0, 0x6f, ZC3XX_R01E_HSYNC_1}, /* 00,1e,6f,cc */ 4092 {0xa0, 0x6f, ZC3XX_R01E_HSYNC_1}, /* 00,1e,6f,cc */
4087 {0xa0, 0xad, ZC3XX_R01F_HSYNC_2}, /* 00,1f,ad,cc */ 4093 {0xa0, 0xad, ZC3XX_R01F_HSYNC_2}, /* 00,1f,ad,cc */
@@ -4094,23 +4100,23 @@ static const struct usb_action pas202b_50HZScale[] = {
4094 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */ 4100 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
4095 {0xa0, 0x20, ZC3XX_R087_EXPTIMEMID}, /* 00,87,20,cc */ 4101 {0xa0, 0x20, ZC3XX_R087_EXPTIMEMID}, /* 00,87,20,cc */
4096 {0xa0, 0x21, ZC3XX_R088_EXPTIMELOW}, /* 00,88,21,cc */ 4102 {0xa0, 0x21, ZC3XX_R088_EXPTIMELOW}, /* 00,88,21,cc */
4097 {0xaa, 0x20, 0x0002}, /* 00,20,02,aa */ 4103 {0xaa, 0x20, 0x0004},
4098 {0xaa, 0x21, 0x006c}, /* 00,21,6c,aa */ 4104 {0xaa, 0x21, 0x003d},
4099 {0xaa, 0x03, 0x0041}, /* 00,03,41,aa */ 4105 {0xaa, 0x03, 0x0041}, /* 00,03,41,aa */
4100 {0xaa, 0x04, 0x0009}, /* 00,04,09,aa */ 4106 {0xaa, 0x04, 0x0010},
4101 {0xaa, 0x05, 0x002c}, /* 00,05,2c,aa */ 4107 {0xaa, 0x05, 0x003d},
4102 {0xaa, 0x0e, 0x0001}, /* 00,0e,01,aa */ 4108 {0xaa, 0x0e, 0x0001}, /* 00,0e,01,aa */
4103 {0xaa, 0x0f, 0x0000}, /* 00,0f,00,aa */ 4109 {0xaa, 0x0f, 0x0000}, /* 00,0f,00,aa */
4104 {0xa0, 0x14, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,14,cc */ 4110 {0xa0, 0x1c, ZC3XX_R1A9_DIGITALLIMITDIFF},
4105 {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,24,cc */ 4111 {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,24,cc */
4106 {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */ 4112 {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */
4107 {0xa0, 0x0f, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,0f,cc */ 4113 {0xa0, 0x04, ZC3XX_R191_EXPOSURELIMITMID},
4108 {0xa0, 0xbe, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,be,cc */ 4114 {0xa0, 0x3d, ZC3XX_R192_EXPOSURELIMITLOW},
4109 {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ 4115 {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
4110 {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */ 4116 {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */
4111 {0xa0, 0x9b, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,9b,cc */ 4117 {0xa0, 0x9b, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,9b,cc */
4112 {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */ 4118 {0xa0, 0x0e, ZC3XX_R18C_AEFREEZE},
4113 {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */ 4119 {0xa0, 0x1b, ZC3XX_R18F_AEUNFREEZE},
4114 {0xa0, 0x41, ZC3XX_R01D_HSYNC_0}, /* 00,1d,41,cc */ 4120 {0xa0, 0x41, ZC3XX_R01D_HSYNC_0}, /* 00,1d,41,cc */
4115 {0xa0, 0x6f, ZC3XX_R01E_HSYNC_1}, /* 00,1e,6f,cc */ 4121 {0xa0, 0x6f, ZC3XX_R01E_HSYNC_1}, /* 00,1e,6f,cc */
4116 {0xa0, 0xad, ZC3XX_R01F_HSYNC_2}, /* 00,1f,ad,cc */ 4122 {0xa0, 0xad, ZC3XX_R01F_HSYNC_2}, /* 00,1f,ad,cc */
@@ -4130,16 +4136,16 @@ static const struct usb_action pas202b_60HZ[] = {
4130 {0xaa, 0x05, 0x0000}, /* 00,05,00,aa */ 4136 {0xaa, 0x05, 0x0000}, /* 00,05,00,aa */
4131 {0xaa, 0x0e, 0x0001}, /* 00,0e,01,aa */ 4137 {0xaa, 0x0e, 0x0001}, /* 00,0e,01,aa */
4132 {0xaa, 0x0f, 0x0000}, /* 00,0f,00,aa */ 4138 {0xaa, 0x0f, 0x0000}, /* 00,0f,00,aa */
4133 {0xa0, 0x14, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,14,cc */ 4139 {0xa0, 0x1c, ZC3XX_R1A9_DIGITALLIMITDIFF},
4134 {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,24,cc */ 4140 {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,24,cc */
4135 {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */ 4141 {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */
4136 {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,07,cc */ 4142 {0xa0, 0x02, ZC3XX_R191_EXPOSURELIMITMID},
4137 {0xa0, 0xc0, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,c0,cc */ 4143 {0xa0, 0x00, ZC3XX_R192_EXPOSURELIMITLOW},
4138 {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ 4144 {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
4139 {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */ 4145 {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */
4140 {0xa0, 0x40, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,40,cc */ 4146 {0xa0, 0x40, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,40,cc */
4141 {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */ 4147 {0xa0, 0x0e, ZC3XX_R18C_AEFREEZE},
4142 {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */ 4148 {0xa0, 0x1b, ZC3XX_R18F_AEUNFREEZE},
4143 {0xa0, 0x45, ZC3XX_R01D_HSYNC_0}, /* 00,1d,45,cc */ 4149 {0xa0, 0x45, ZC3XX_R01D_HSYNC_0}, /* 00,1d,45,cc */
4144 {0xa0, 0x8e, ZC3XX_R01E_HSYNC_1}, /* 00,1e,8e,cc */ 4150 {0xa0, 0x8e, ZC3XX_R01E_HSYNC_1}, /* 00,1e,8e,cc */
4145 {0xa0, 0xc1, ZC3XX_R01F_HSYNC_2}, /* 00,1f,c1,cc */ 4151 {0xa0, 0xc1, ZC3XX_R01F_HSYNC_2}, /* 00,1f,c1,cc */
@@ -4152,23 +4158,23 @@ static const struct usb_action pas202b_60HZScale[] = {
4152 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */ 4158 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
4153 {0xa0, 0x20, ZC3XX_R087_EXPTIMEMID}, /* 00,87,20,cc */ 4159 {0xa0, 0x20, ZC3XX_R087_EXPTIMEMID}, /* 00,87,20,cc */
4154 {0xa0, 0x21, ZC3XX_R088_EXPTIMELOW}, /* 00,88,21,cc */ 4160 {0xa0, 0x21, ZC3XX_R088_EXPTIMELOW}, /* 00,88,21,cc */
4155 {0xaa, 0x20, 0x0002}, /* 00,20,02,aa */ 4161 {0xaa, 0x20, 0x0004},
4156 {0xaa, 0x21, 0x0004}, /* 00,21,04,aa */ 4162 {0xaa, 0x21, 0x0008},
4157 {0xaa, 0x03, 0x0042}, /* 00,03,42,aa */ 4163 {0xaa, 0x03, 0x0042}, /* 00,03,42,aa */
4158 {0xaa, 0x04, 0x0008}, /* 00,04,08,aa */ 4164 {0xaa, 0x04, 0x0010},
4159 {0xaa, 0x05, 0x0004}, /* 00,05,04,aa */ 4165 {0xaa, 0x05, 0x0008},
4160 {0xaa, 0x0e, 0x0001}, /* 00,0e,01,aa */ 4166 {0xaa, 0x0e, 0x0001}, /* 00,0e,01,aa */
4161 {0xaa, 0x0f, 0x0000}, /* 00,0f,00,aa */ 4167 {0xaa, 0x0f, 0x0000}, /* 00,0f,00,aa */
4162 {0xa0, 0x14, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,14,cc */ 4168 {0xa0, 0x1c, ZC3XX_R1A9_DIGITALLIMITDIFF},
4163 {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,24,cc */ 4169 {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,24,cc */
4164 {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */ 4170 {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */
4165 {0xa0, 0x0f, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,0f,cc */ 4171 {0xa0, 0x04, ZC3XX_R191_EXPOSURELIMITMID},
4166 {0xa0, 0x9f, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,9f,cc */ 4172 {0xa0, 0x08, ZC3XX_R192_EXPOSURELIMITLOW},
4167 {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ 4173 {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
4168 {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */ 4174 {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */
4169 {0xa0, 0x81, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,81,cc */ 4175 {0xa0, 0x81, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,81,cc */
4170 {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */ 4176 {0xa0, 0x0e, ZC3XX_R18C_AEFREEZE},
4171 {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */ 4177 {0xa0, 0x1b, ZC3XX_R18F_AEUNFREEZE},
4172 {0xa0, 0x42, ZC3XX_R01D_HSYNC_0}, /* 00,1d,42,cc */ 4178 {0xa0, 0x42, ZC3XX_R01D_HSYNC_0}, /* 00,1d,42,cc */
4173 {0xa0, 0x6f, ZC3XX_R01E_HSYNC_1}, /* 00,1e,6f,cc */ 4179 {0xa0, 0x6f, ZC3XX_R01E_HSYNC_1}, /* 00,1e,6f,cc */
4174 {0xa0, 0xaf, ZC3XX_R01F_HSYNC_2}, /* 00,1f,af,cc */ 4180 {0xa0, 0xaf, ZC3XX_R01F_HSYNC_2}, /* 00,1f,af,cc */
@@ -4182,22 +4188,22 @@ static const struct usb_action pas202b_NoFliker[] = {
4182 {0xa0, 0x20, ZC3XX_R087_EXPTIMEMID}, /* 00,87,20,cc */ 4188 {0xa0, 0x20, ZC3XX_R087_EXPTIMEMID}, /* 00,87,20,cc */
4183 {0xa0, 0x21, ZC3XX_R088_EXPTIMELOW}, /* 00,88,21,cc */ 4189 {0xa0, 0x21, ZC3XX_R088_EXPTIMELOW}, /* 00,88,21,cc */
4184 {0xaa, 0x20, 0x0002}, /* 00,20,02,aa */ 4190 {0xaa, 0x20, 0x0002}, /* 00,20,02,aa */
4185 {0xaa, 0x21, 0x0020}, /* 00,21,20,aa */ 4191 {0xaa, 0x21, 0x0006},
4186 {0xaa, 0x03, 0x0040}, /* 00,03,40,aa */ 4192 {0xaa, 0x03, 0x0040}, /* 00,03,40,aa */
4187 {0xaa, 0x04, 0x0008}, /* 00,04,08,aa */ 4193 {0xaa, 0x04, 0x0008}, /* 00,04,08,aa */
4188 {0xaa, 0x05, 0x0020}, /* 00,05,20,aa */ 4194 {0xaa, 0x05, 0x0006},
4189 {0xaa, 0x0e, 0x0001}, /* 00,0e,01,aa */ 4195 {0xaa, 0x0e, 0x0001}, /* 00,0e,01,aa */
4190 {0xaa, 0x0f, 0x0000}, /* 00,0f,00,aa */ 4196 {0xaa, 0x0f, 0x0000}, /* 00,0f,00,aa */
4191 {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */ 4197 {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */
4192 {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,07,cc */ 4198 {0xa0, 0x02, ZC3XX_R191_EXPOSURELIMITMID},
4193 {0xa0, 0xf0, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,f0,cc */ 4199 {0xa0, 0x06, ZC3XX_R192_EXPOSURELIMITLOW},
4194 {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ 4200 {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
4195 {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */ 4201 {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */
4196 {0xa0, 0x02, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,02,cc */ 4202 {0xa0, 0x01, ZC3XX_R197_ANTIFLICKERLOW},
4197 {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */ 4203 {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */
4198 {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */ 4204 {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */
4199 {0xa0, 0x00, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,00,cc */ 4205 {0xa0, 0x00, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,00,cc */
4200 {0xa0, 0x00, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,00,cc */ 4206 {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP},
4201 {0xa0, 0x40, ZC3XX_R01D_HSYNC_0}, /* 00,1d,40,cc */ 4207 {0xa0, 0x40, ZC3XX_R01D_HSYNC_0}, /* 00,1d,40,cc */
4202 {0xa0, 0x60, ZC3XX_R01E_HSYNC_1}, /* 00,1e,60,cc */ 4208 {0xa0, 0x60, ZC3XX_R01E_HSYNC_1}, /* 00,1e,60,cc */
4203 {0xa0, 0x90, ZC3XX_R01F_HSYNC_2}, /* 00,1f,90,cc */ 4209 {0xa0, 0x90, ZC3XX_R01F_HSYNC_2}, /* 00,1f,90,cc */
@@ -4210,23 +4216,23 @@ static const struct usb_action pas202b_NoFlikerScale[] = {
4210 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */ 4216 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
4211 {0xa0, 0x20, ZC3XX_R087_EXPTIMEMID}, /* 00,87,20,cc */ 4217 {0xa0, 0x20, ZC3XX_R087_EXPTIMEMID}, /* 00,87,20,cc */
4212 {0xa0, 0x21, ZC3XX_R088_EXPTIMELOW}, /* 00,88,21,cc */ 4218 {0xa0, 0x21, ZC3XX_R088_EXPTIMELOW}, /* 00,88,21,cc */
4213 {0xaa, 0x20, 0x0002}, /* 00,20,02,aa */ 4219 {0xaa, 0x20, 0x0004},
4214 {0xaa, 0x21, 0x0010}, /* 00,21,10,aa */ 4220 {0xaa, 0x21, 0x000c},
4215 {0xaa, 0x03, 0x0040}, /* 00,03,40,aa */ 4221 {0xaa, 0x03, 0x0040}, /* 00,03,40,aa */
4216 {0xaa, 0x04, 0x0008}, /* 00,04,08,aa */ 4222 {0xaa, 0x04, 0x0010},
4217 {0xaa, 0x05, 0x0010}, /* 00,05,10,aa */ 4223 {0xaa, 0x05, 0x000c},
4218 {0xaa, 0x0e, 0x0001}, /* 00,0e,01,aa */ 4224 {0xaa, 0x0e, 0x0001}, /* 00,0e,01,aa */
4219 {0xaa, 0x0f, 0x0000}, /* 00,0f,00,aa */ 4225 {0xaa, 0x0f, 0x0000}, /* 00,0f,00,aa */
4220 {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */ 4226 {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */
4221 {0xa0, 0x0f, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,0f,cc */ 4227 {0xa0, 0x04, ZC3XX_R191_EXPOSURELIMITMID},
4222 {0xa0, 0xf0, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,f0,cc */ 4228 {0xa0, 0x0c, ZC3XX_R192_EXPOSURELIMITLOW},
4223 {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ 4229 {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
4224 {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */ 4230 {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */
4225 {0xa0, 0x02, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,02,cc */ 4231 {0xa0, 0x02, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,02,cc */
4226 {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */ 4232 {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */
4227 {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */ 4233 {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */
4228 {0xa0, 0x00, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,00,cc */ 4234 {0xa0, 0x00, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,00,cc */
4229 {0xa0, 0x00, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,00,cc */ 4235 {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP},
4230 {0xa0, 0x40, ZC3XX_R01D_HSYNC_0}, /* 00,1d,40,cc */ 4236 {0xa0, 0x40, ZC3XX_R01D_HSYNC_0}, /* 00,1d,40,cc */
4231 {0xa0, 0x60, ZC3XX_R01E_HSYNC_1}, /* 00,1e,60,cc */ 4237 {0xa0, 0x60, ZC3XX_R01E_HSYNC_1}, /* 00,1e,60,cc */
4232 {0xa0, 0x90, ZC3XX_R01F_HSYNC_2}, /* 00,1f,90,cc */ 4238 {0xa0, 0x90, ZC3XX_R01F_HSYNC_2}, /* 00,1f,90,cc */
@@ -4713,8 +4719,8 @@ static const struct usb_action pb0330_NoFlikerScale[] = {
4713 {} 4719 {}
4714}; 4720};
4715 4721
4716/* from oem9.inf - HKR,%PO2030%,Initial - 640x480 - (close to CS2102) */ 4722/* from oem9.inf */
4717static const struct usb_action PO2030_mode0[] = { 4723static const struct usb_action po2030_Initial[] = { /* 640x480 */
4718 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, /* 00,00,01,cc */ 4724 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, /* 00,00,01,cc */
4719 {0xa0, 0x04, ZC3XX_R002_CLOCKSELECT}, /* 00,02,04,cc */ 4725 {0xa0, 0x04, ZC3XX_R002_CLOCKSELECT}, /* 00,02,04,cc */
4720 {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */ 4726 {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */
@@ -4790,8 +4796,8 @@ static const struct usb_action PO2030_mode0[] = {
4790 {} 4796 {}
4791}; 4797};
4792 4798
4793/* from oem9.inf - HKR,%PO2030%,InitialScale - 320x240 */ 4799/* from oem9.inf */
4794static const struct usb_action PO2030_mode1[] = { 4800static const struct usb_action po2030_InitialScale[] = { /* 320x240 */
4795 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, /* 00,00,01,cc */ 4801 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, /* 00,00,01,cc */
4796 {0xa0, 0x10, ZC3XX_R002_CLOCKSELECT}, /* 00,02,10,cc */ 4802 {0xa0, 0x10, ZC3XX_R002_CLOCKSELECT}, /* 00,02,10,cc */
4797 {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */ 4803 {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */
@@ -4867,7 +4873,7 @@ static const struct usb_action PO2030_mode1[] = {
4867 {} 4873 {}
4868}; 4874};
4869 4875
4870static const struct usb_action PO2030_50HZ[] = { 4876static const struct usb_action po2030_50HZ[] = {
4871 {0xaa, 0x8d, 0x0008}, /* 00,8d,08,aa */ 4877 {0xaa, 0x8d, 0x0008}, /* 00,8d,08,aa */
4872 {0xaa, 0x1a, 0x0001}, /* 00,1a,01,aa */ 4878 {0xaa, 0x1a, 0x0001}, /* 00,1a,01,aa */
4873 {0xaa, 0x1b, 0x000a}, /* 00,1b,0a,aa */ 4879 {0xaa, 0x1b, 0x000a}, /* 00,1b,0a,aa */
@@ -4889,7 +4895,7 @@ static const struct usb_action PO2030_50HZ[] = {
4889 {} 4895 {}
4890}; 4896};
4891 4897
4892static const struct usb_action PO2030_60HZ[] = { 4898static const struct usb_action po2030_60HZ[] = {
4893 {0xaa, 0x8d, 0x0008}, /* 00,8d,08,aa */ 4899 {0xaa, 0x8d, 0x0008}, /* 00,8d,08,aa */
4894 {0xaa, 0x1a, 0x0000}, /* 00,1a,00,aa */ 4900 {0xaa, 0x1a, 0x0000}, /* 00,1a,00,aa */
4895 {0xaa, 0x1b, 0x00de}, /* 00,1b,de,aa */ 4901 {0xaa, 0x1b, 0x00de}, /* 00,1b,de,aa */
@@ -4912,7 +4918,7 @@ static const struct usb_action PO2030_60HZ[] = {
4912 {} 4918 {}
4913}; 4919};
4914 4920
4915static const struct usb_action PO2030_NoFliker[] = { 4921static const struct usb_action po2030_NoFliker[] = {
4916 {0xa0, 0x02, ZC3XX_R180_AUTOCORRECTENABLE}, /* 01,80,02,cc */ 4922 {0xa0, 0x02, ZC3XX_R180_AUTOCORRECTENABLE}, /* 01,80,02,cc */
4917 {0xaa, 0x8d, 0x000d}, /* 00,8d,0d,aa */ 4923 {0xaa, 0x8d, 0x000d}, /* 00,8d,0d,aa */
4918 {0xaa, 0x1a, 0x0000}, /* 00,1a,00,aa */ 4924 {0xaa, 0x1a, 0x0000}, /* 00,1a,00,aa */
@@ -4924,7 +4930,7 @@ static const struct usb_action PO2030_NoFliker[] = {
4924}; 4930};
4925 4931
4926/* TEST */ 4932/* TEST */
4927static const struct usb_action tas5130CK_Initial[] = { 4933static const struct usb_action tas5130cK_InitialScale[] = {
4928 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, 4934 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
4929 {0xa0, 0x01, 0x003b}, 4935 {0xa0, 0x01, 0x003b},
4930 {0xa0, 0x0e, 0x003a}, 4936 {0xa0, 0x0e, 0x003a},
@@ -5127,7 +5133,7 @@ static const struct usb_action tas5130CK_Initial[] = {
5127 {} 5133 {}
5128}; 5134};
5129 5135
5130static const struct usb_action tas5130CK_InitialScale[] = { 5136static const struct usb_action tas5130cK_Initial[] = {
5131 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, 5137 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
5132 {0xa0, 0x01, 0x003b}, 5138 {0xa0, 0x01, 0x003b},
5133 {0xa0, 0x0e, 0x003a}, 5139 {0xa0, 0x0e, 0x003a},
@@ -5560,7 +5566,7 @@ static const struct usb_action tas5130cxx_NoFlikerScale[] = {
5560 {} 5566 {}
5561}; 5567};
5562 5568
5563static const struct usb_action tas5130c_vf0250_Initial[] = { 5569static const struct usb_action tas5130c_vf0250_InitialScale[] = {
5564 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, /* 00,00,01,cc, */ 5570 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, /* 00,00,01,cc, */
5565 {0xa0, 0x02, ZC3XX_R008_CLOCKSETTING}, /* 00,08,02,cc, */ 5571 {0xa0, 0x02, ZC3XX_R008_CLOCKSETTING}, /* 00,08,02,cc, */
5566 {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc, */ 5572 {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc, */
@@ -5627,7 +5633,7 @@ static const struct usb_action tas5130c_vf0250_Initial[] = {
5627 {} 5633 {}
5628}; 5634};
5629 5635
5630static const struct usb_action tas5130c_vf0250_InitialScale[] = { 5636static const struct usb_action tas5130c_vf0250_Initial[] = {
5631 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, /* 00,00,01,cc, */ 5637 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, /* 00,00,01,cc, */
5632 {0xa0, 0x02, ZC3XX_R008_CLOCKSETTING}, /* 00,08,02,cc, */ 5638 {0xa0, 0x02, ZC3XX_R008_CLOCKSETTING}, /* 00,08,02,cc, */
5633 {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc, */ 5639 {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc, */
@@ -5692,8 +5698,7 @@ static const struct usb_action tas5130c_vf0250_InitialScale[] = {
5692 {0xa0, 0x65, ZC3XX_R118_BGAIN}, /* 01,18,65,cc */ 5698 {0xa0, 0x65, ZC3XX_R118_BGAIN}, /* 01,18,65,cc */
5693 {} 5699 {}
5694}; 5700};
5695/* "50HZ" light frequency banding filter */ 5701static const struct usb_action tas5130c_vf0250_50HZScale[] = {
5696static const struct usb_action tas5130c_vf0250_50HZ[] = {
5697 {0xaa, 0x82, 0x0000}, /* 00,82,00,aa */ 5702 {0xaa, 0x82, 0x0000}, /* 00,82,00,aa */
5698 {0xaa, 0x83, 0x0001}, /* 00,83,01,aa */ 5703 {0xaa, 0x83, 0x0001}, /* 00,83,01,aa */
5699 {0xaa, 0x84, 0x00aa}, /* 00,84,aa,aa */ 5704 {0xaa, 0x84, 0x00aa}, /* 00,84,aa,aa */
@@ -5717,8 +5722,7 @@ static const struct usb_action tas5130c_vf0250_50HZ[] = {
5717 {} 5722 {}
5718}; 5723};
5719 5724
5720/* "50HZScale" light frequency banding filter */ 5725static const struct usb_action tas5130c_vf0250_50HZ[] = {
5721static const struct usb_action tas5130c_vf0250_50HZScale[] = {
5722 {0xaa, 0x82, 0x0000}, /* 00,82,00,aa */ 5726 {0xaa, 0x82, 0x0000}, /* 00,82,00,aa */
5723 {0xaa, 0x83, 0x0003}, /* 00,83,03,aa */ 5727 {0xaa, 0x83, 0x0003}, /* 00,83,03,aa */
5724 {0xaa, 0x84, 0x0054}, /* 00,84,54,aa */ 5728 {0xaa, 0x84, 0x0054}, /* 00,84,54,aa */
@@ -5742,8 +5746,7 @@ static const struct usb_action tas5130c_vf0250_50HZScale[] = {
5742 {} 5746 {}
5743}; 5747};
5744 5748
5745/* "60HZ" light frequency banding filter */ 5749static const struct usb_action tas5130c_vf0250_60HZScale[] = {
5746static const struct usb_action tas5130c_vf0250_60HZ[] = {
5747 {0xaa, 0x82, 0x0000}, /* 00,82,00,aa */ 5750 {0xaa, 0x82, 0x0000}, /* 00,82,00,aa */
5748 {0xaa, 0x83, 0x0001}, /* 00,83,01,aa */ 5751 {0xaa, 0x83, 0x0001}, /* 00,83,01,aa */
5749 {0xaa, 0x84, 0x0062}, /* 00,84,62,aa */ 5752 {0xaa, 0x84, 0x0062}, /* 00,84,62,aa */
@@ -5767,8 +5770,7 @@ static const struct usb_action tas5130c_vf0250_60HZ[] = {
5767 {} 5770 {}
5768}; 5771};
5769 5772
5770/* "60HZScale" light frequency banding ilter */ 5773static const struct usb_action tas5130c_vf0250_60HZ[] = {
5771static const struct usb_action tas5130c_vf0250_60HZScale[] = {
5772 {0xaa, 0x82, 0x0000}, /* 00,82,00,aa */ 5774 {0xaa, 0x82, 0x0000}, /* 00,82,00,aa */
5773 {0xaa, 0x83, 0x0002}, /* 00,83,02,aa */ 5775 {0xaa, 0x83, 0x0002}, /* 00,83,02,aa */
5774 {0xaa, 0x84, 0x00c4}, /* 00,84,c4,aa */ 5776 {0xaa, 0x84, 0x00c4}, /* 00,84,c4,aa */
@@ -5792,8 +5794,7 @@ static const struct usb_action tas5130c_vf0250_60HZScale[] = {
5792 {} 5794 {}
5793}; 5795};
5794 5796
5795/* "NoFliker" light frequency banding flter */ 5797static const struct usb_action tas5130c_vf0250_NoFlikerScale[] = {
5796static const struct usb_action tas5130c_vf0250_NoFliker[] = {
5797 {0xa0, 0x0c, ZC3XX_R100_OPERATIONMODE}, /* 01,00,0c,cc, */ 5798 {0xa0, 0x0c, ZC3XX_R100_OPERATIONMODE}, /* 01,00,0c,cc, */
5798 {0xaa, 0x82, 0x0000}, /* 00,82,00,aa */ 5799 {0xaa, 0x82, 0x0000}, /* 00,82,00,aa */
5799 {0xaa, 0x83, 0x0000}, /* 00,83,00,aa */ 5800 {0xaa, 0x83, 0x0000}, /* 00,83,00,aa */
@@ -5815,8 +5816,7 @@ static const struct usb_action tas5130c_vf0250_NoFliker[] = {
5815 {} 5816 {}
5816}; 5817};
5817 5818
5818/* "NoFlikerScale" light frequency banding filter */ 5819static const struct usb_action tas5130c_vf0250_NoFliker[] = {
5819static const struct usb_action tas5130c_vf0250_NoFlikerScale[] = {
5820 {0xa0, 0x0c, ZC3XX_R100_OPERATIONMODE}, /* 01,00,0c,cc, */ 5820 {0xa0, 0x0c, ZC3XX_R100_OPERATIONMODE}, /* 01,00,0c,cc, */
5821 {0xaa, 0x82, 0x0000}, /* 00,82,00,aa */ 5821 {0xaa, 0x82, 0x0000}, /* 00,82,00,aa */
5822 {0xaa, 0x83, 0x0000}, /* 00,83,00,aa */ 5822 {0xaa, 0x83, 0x0000}, /* 00,83,00,aa */
@@ -5839,7 +5839,7 @@ static const struct usb_action tas5130c_vf0250_NoFlikerScale[] = {
5839}; 5839};
5840 5840
5841static u8 reg_r_i(struct gspca_dev *gspca_dev, 5841static u8 reg_r_i(struct gspca_dev *gspca_dev,
5842 __u16 index) 5842 u16 index)
5843{ 5843{
5844 usb_control_msg(gspca_dev->dev, 5844 usb_control_msg(gspca_dev->dev,
5845 usb_rcvctrlpipe(gspca_dev->dev, 0), 5845 usb_rcvctrlpipe(gspca_dev->dev, 0),
@@ -5852,7 +5852,7 @@ static u8 reg_r_i(struct gspca_dev *gspca_dev,
5852} 5852}
5853 5853
5854static u8 reg_r(struct gspca_dev *gspca_dev, 5854static u8 reg_r(struct gspca_dev *gspca_dev,
5855 __u16 index) 5855 u16 index)
5856{ 5856{
5857 u8 ret; 5857 u8 ret;
5858 5858
@@ -5862,8 +5862,8 @@ static u8 reg_r(struct gspca_dev *gspca_dev,
5862} 5862}
5863 5863
5864static void reg_w_i(struct usb_device *dev, 5864static void reg_w_i(struct usb_device *dev,
5865 __u8 value, 5865 u8 value,
5866 __u16 index) 5866 u16 index)
5867{ 5867{
5868 usb_control_msg(dev, 5868 usb_control_msg(dev,
5869 usb_sndctrlpipe(dev, 0), 5869 usb_sndctrlpipe(dev, 0),
@@ -5874,18 +5874,18 @@ static void reg_w_i(struct usb_device *dev,
5874} 5874}
5875 5875
5876static void reg_w(struct usb_device *dev, 5876static void reg_w(struct usb_device *dev,
5877 __u8 value, 5877 u8 value,
5878 __u16 index) 5878 u16 index)
5879{ 5879{
5880 PDEBUG(D_USBO, "reg w [%04x] = %02x", index, value); 5880 PDEBUG(D_USBO, "reg w [%04x] = %02x", index, value);
5881 reg_w_i(dev, value, index); 5881 reg_w_i(dev, value, index);
5882} 5882}
5883 5883
5884static __u16 i2c_read(struct gspca_dev *gspca_dev, 5884static u16 i2c_read(struct gspca_dev *gspca_dev,
5885 __u8 reg) 5885 u8 reg)
5886{ 5886{
5887 __u8 retbyte; 5887 u8 retbyte;
5888 __u16 retval; 5888 u16 retval;
5889 5889
5890 reg_w_i(gspca_dev->dev, reg, 0x0092); 5890 reg_w_i(gspca_dev->dev, reg, 0x0092);
5891 reg_w_i(gspca_dev->dev, 0x02, 0x0090); /* <- read command */ 5891 reg_w_i(gspca_dev->dev, 0x02, 0x0090); /* <- read command */
@@ -5900,12 +5900,12 @@ static __u16 i2c_read(struct gspca_dev *gspca_dev,
5900 return retval; 5900 return retval;
5901} 5901}
5902 5902
5903static __u8 i2c_write(struct gspca_dev *gspca_dev, 5903static u8 i2c_write(struct gspca_dev *gspca_dev,
5904 __u8 reg, 5904 u8 reg,
5905 __u8 valL, 5905 u8 valL,
5906 __u8 valH) 5906 u8 valH)
5907{ 5907{
5908 __u8 retbyte; 5908 u8 retbyte;
5909 5909
5910 reg_w_i(gspca_dev->dev, reg, 0x92); 5910 reg_w_i(gspca_dev->dev, reg, 0x92);
5911 reg_w_i(gspca_dev->dev, valL, 0x93); 5911 reg_w_i(gspca_dev->dev, valL, 0x93);
@@ -5957,24 +5957,24 @@ static void setmatrix(struct gspca_dev *gspca_dev)
5957{ 5957{
5958 struct sd *sd = (struct sd *) gspca_dev; 5958 struct sd *sd = (struct sd *) gspca_dev;
5959 int i; 5959 int i;
5960 const __u8 *matrix; 5960 const u8 *matrix;
5961 static const u8 adcm2700_matrix[9] = 5961 static const u8 adcm2700_matrix[9] =
5962/* {0x66, 0xed, 0xed, 0xed, 0x66, 0xed, 0xed, 0xed, 0x66}; */ 5962/* {0x66, 0xed, 0xed, 0xed, 0x66, 0xed, 0xed, 0xed, 0x66}; */
5963/*ms-win*/ 5963/*ms-win*/
5964 {0x74, 0xed, 0xed, 0xed, 0x74, 0xed, 0xed, 0xed, 0x74}; 5964 {0x74, 0xed, 0xed, 0xed, 0x74, 0xed, 0xed, 0xed, 0x74};
5965 static const __u8 gc0305_matrix[9] = 5965 static const u8 gc0305_matrix[9] =
5966 {0x50, 0xf8, 0xf8, 0xf8, 0x50, 0xf8, 0xf8, 0xf8, 0x50}; 5966 {0x50, 0xf8, 0xf8, 0xf8, 0x50, 0xf8, 0xf8, 0xf8, 0x50};
5967 static const __u8 ov7620_matrix[9] = 5967 static const u8 ov7620_matrix[9] =
5968 {0x58, 0xf4, 0xf4, 0xf4, 0x58, 0xf4, 0xf4, 0xf4, 0x58}; 5968 {0x58, 0xf4, 0xf4, 0xf4, 0x58, 0xf4, 0xf4, 0xf4, 0x58};
5969 static const __u8 pas202b_matrix[9] = 5969 static const u8 pas202b_matrix[9] =
5970 {0x4c, 0xf5, 0xff, 0xf9, 0x51, 0xf5, 0xfb, 0xed, 0x5f}; 5970 {0x4c, 0xf5, 0xff, 0xf9, 0x51, 0xf5, 0xfb, 0xed, 0x5f};
5971 static const __u8 po2030_matrix[9] = 5971 static const u8 po2030_matrix[9] =
5972 {0x60, 0xf0, 0xf0, 0xf0, 0x60, 0xf0, 0xf0, 0xf0, 0x60}; 5972 {0x60, 0xf0, 0xf0, 0xf0, 0x60, 0xf0, 0xf0, 0xf0, 0x60};
5973 static const u8 tas5130c_matrix[9] = 5973 static const u8 tas5130c_matrix[9] =
5974 {0x68, 0xec, 0xec, 0xec, 0x68, 0xec, 0xec, 0xec, 0x68}; 5974 {0x68, 0xec, 0xec, 0xec, 0x68, 0xec, 0xec, 0xec, 0x68};
5975 static const __u8 vf0250_matrix[9] = 5975 static const u8 vf0250_matrix[9] =
5976 {0x7b, 0xea, 0xea, 0xea, 0x7b, 0xea, 0xea, 0xea, 0x7b}; 5976 {0x7b, 0xea, 0xea, 0xea, 0x7b, 0xea, 0xea, 0xea, 0x7b};
5977 static const __u8 *matrix_tb[SENSOR_MAX] = { 5977 static const u8 *matrix_tb[SENSOR_MAX] = {
5978 adcm2700_matrix, /* SENSOR_ADCM2700 0 */ 5978 adcm2700_matrix, /* SENSOR_ADCM2700 0 */
5979 ov7620_matrix, /* SENSOR_CS2102 1 */ 5979 ov7620_matrix, /* SENSOR_CS2102 1 */
5980 NULL, /* SENSOR_CS2102K 2 */ 5980 NULL, /* SENSOR_CS2102K 2 */
@@ -6006,11 +6006,12 @@ static void setmatrix(struct gspca_dev *gspca_dev)
6006static void setbrightness(struct gspca_dev *gspca_dev) 6006static void setbrightness(struct gspca_dev *gspca_dev)
6007{ 6007{
6008 struct sd *sd = (struct sd *) gspca_dev; 6008 struct sd *sd = (struct sd *) gspca_dev;
6009 __u8 brightness; 6009 u8 brightness;
6010 6010
6011 switch (sd->sensor) { 6011 switch (sd->sensor) {
6012 case SENSOR_GC0305: 6012 case SENSOR_GC0305:
6013 case SENSOR_OV7620: 6013 case SENSOR_OV7620:
6014 case SENSOR_PAS202B:
6014 case SENSOR_PO2030: 6015 case SENSOR_PO2030:
6015 return; 6016 return;
6016 } 6017 }
@@ -6034,7 +6035,7 @@ static void setsharpness(struct gspca_dev *gspca_dev)
6034 struct sd *sd = (struct sd *) gspca_dev; 6035 struct sd *sd = (struct sd *) gspca_dev;
6035 struct usb_device *dev = gspca_dev->dev; 6036 struct usb_device *dev = gspca_dev->dev;
6036 int sharpness; 6037 int sharpness;
6037 static const __u8 sharpness_tb[][2] = { 6038 static const u8 sharpness_tb[][2] = {
6038 {0x02, 0x03}, 6039 {0x02, 0x03},
6039 {0x04, 0x07}, 6040 {0x04, 0x07},
6040 {0x08, 0x0f}, 6041 {0x08, 0x0f},
@@ -6053,118 +6054,69 @@ static void setcontrast(struct gspca_dev *gspca_dev)
6053{ 6054{
6054 struct sd *sd = (struct sd *) gspca_dev; 6055 struct sd *sd = (struct sd *) gspca_dev;
6055 struct usb_device *dev = gspca_dev->dev; 6056 struct usb_device *dev = gspca_dev->dev;
6056 const __u8 *Tgamma, *Tgradient; 6057 const u8 *Tgamma;
6057 int g, i, k; 6058 int g, i, k, adj, gp;
6058 static const __u8 kgamma_tb[16] = /* delta for contrast */ 6059 u8 gr[16];
6060 static const u8 delta_tb[16] = /* delta for contrast */
6059 {0x15, 0x0d, 0x0a, 0x09, 0x08, 0x08, 0x08, 0x08, 6061 {0x15, 0x0d, 0x0a, 0x09, 0x08, 0x08, 0x08, 0x08,
6060 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08}; 6062 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08};
6061 static const __u8 kgrad_tb[16] = 6063 static const u8 gamma_tb[6][16] = {
6062 {0x1b, 0x06, 0x03, 0x02, 0x00, 0x00, 0x00, 0x00,
6063 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x06, 0x04};
6064 static const __u8 Tgamma_1[16] =
6065 {0x00, 0x00, 0x03, 0x0d, 0x1b, 0x2e, 0x45, 0x5f, 6064 {0x00, 0x00, 0x03, 0x0d, 0x1b, 0x2e, 0x45, 0x5f,
6066 0x79, 0x93, 0xab, 0xc1, 0xd4, 0xe5, 0xf3, 0xff}; 6065 0x79, 0x93, 0xab, 0xc1, 0xd4, 0xe5, 0xf3, 0xff},
6067 static const __u8 Tgradient_1[16] =
6068 {0x00, 0x01, 0x05, 0x0b, 0x10, 0x15, 0x18, 0x1a,
6069 0x1a, 0x18, 0x16, 0x14, 0x12, 0x0f, 0x0d, 0x06};
6070 static const __u8 Tgamma_2[16] =
6071 {0x01, 0x0c, 0x1f, 0x3a, 0x53, 0x6d, 0x85, 0x9c, 6066 {0x01, 0x0c, 0x1f, 0x3a, 0x53, 0x6d, 0x85, 0x9c,
6072 0xb0, 0xc2, 0xd1, 0xde, 0xe9, 0xf2, 0xf9, 0xff}; 6067 0xb0, 0xc2, 0xd1, 0xde, 0xe9, 0xf2, 0xf9, 0xff},
6073 static const __u8 Tgradient_2[16] =
6074 {0x05, 0x0f, 0x16, 0x1a, 0x19, 0x19, 0x17, 0x15,
6075 0x12, 0x10, 0x0e, 0x0b, 0x09, 0x08, 0x06, 0x03};
6076 static const __u8 Tgamma_3[16] =
6077 {0x04, 0x16, 0x30, 0x4e, 0x68, 0x81, 0x98, 0xac, 6068 {0x04, 0x16, 0x30, 0x4e, 0x68, 0x81, 0x98, 0xac,
6078 0xbe, 0xcd, 0xda, 0xe4, 0xed, 0xf5, 0xfb, 0xff}; 6069 0xbe, 0xcd, 0xda, 0xe4, 0xed, 0xf5, 0xfb, 0xff},
6079 static const __u8 Tgradient_3[16] =
6080 {0x0c, 0x16, 0x1b, 0x1c, 0x19, 0x18, 0x15, 0x12,
6081 0x10, 0x0d, 0x0b, 0x09, 0x08, 0x06, 0x05, 0x03};
6082 static const __u8 Tgamma_4[16] =
6083 {0x13, 0x38, 0x59, 0x79, 0x92, 0xa7, 0xb9, 0xc8, 6070 {0x13, 0x38, 0x59, 0x79, 0x92, 0xa7, 0xb9, 0xc8,
6084 0xd4, 0xdf, 0xe7, 0xee, 0xf4, 0xf9, 0xfc, 0xff}; 6071 0xd4, 0xdf, 0xe7, 0xee, 0xf4, 0xf9, 0xfc, 0xff},
6085 static const __u8 Tgradient_4[16] =
6086 {0x26, 0x22, 0x20, 0x1c, 0x16, 0x13, 0x10, 0x0d,
6087 0x0b, 0x09, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02};
6088 static const __u8 Tgamma_5[16] =
6089 {0x20, 0x4b, 0x6e, 0x8d, 0xa3, 0xb5, 0xc5, 0xd2, 6072 {0x20, 0x4b, 0x6e, 0x8d, 0xa3, 0xb5, 0xc5, 0xd2,
6090 0xdc, 0xe5, 0xec, 0xf2, 0xf6, 0xfa, 0xfd, 0xff}; 6073 0xdc, 0xe5, 0xec, 0xf2, 0xf6, 0xfa, 0xfd, 0xff},
6091 static const __u8 Tgradient_5[16] =
6092 {0x37, 0x26, 0x20, 0x1a, 0x14, 0x10, 0x0e, 0x0b,
6093 0x09, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x02};
6094 static const __u8 Tgamma_6[16] = /* ?? was gamma 5 */
6095 {0x24, 0x44, 0x64, 0x84, 0x9d, 0xb2, 0xc4, 0xd3, 6074 {0x24, 0x44, 0x64, 0x84, 0x9d, 0xb2, 0xc4, 0xd3,
6096 0xe0, 0xeb, 0xf4, 0xff, 0xff, 0xff, 0xff, 0xff}; 6075 0xe0, 0xeb, 0xf4, 0xff, 0xff, 0xff, 0xff, 0xff},
6097 static const __u8 Tgradient_6[16] =
6098 {0x18, 0x20, 0x20, 0x1c, 0x16, 0x13, 0x10, 0x0e,
6099 0x0b, 0x09, 0x07, 0x00, 0x00, 0x00, 0x00, 0x01};
6100 static const __u8 *gamma_tb[] = {
6101 NULL, Tgamma_1, Tgamma_2,
6102 Tgamma_3, Tgamma_4, Tgamma_5, Tgamma_6
6103 }; 6076 };
6104 static const __u8 *gradient_tb[] = {
6105 NULL, Tgradient_1, Tgradient_2,
6106 Tgradient_3, Tgradient_4, Tgradient_5, Tgradient_6
6107 };
6108#ifdef GSPCA_DEBUG
6109 __u8 v[16];
6110#endif
6111 6077
6112 Tgamma = gamma_tb[sd->gamma]; 6078 Tgamma = gamma_tb[sd->gamma - 1];
6113 Tgradient = gradient_tb[sd->gamma];
6114 6079
6115 k = (sd->contrast - 128) /* -128 / 128 */ 6080 k = ((int) sd->contrast - 128); /* -128 / 128 */
6116 * Tgamma[0]; 6081 adj = 0;
6117 PDEBUG(D_CONF, "gamma:%d contrast:%d gamma coeff: %d/128", 6082 gp = 0;
6118 sd->gamma, sd->contrast, k);
6119 for (i = 0; i < 16; i++) { 6083 for (i = 0; i < 16; i++) {
6120 g = Tgamma[i] + kgamma_tb[i] * k / 128; 6084 g = Tgamma[i] - delta_tb[i] * k / 128 - adj / 2;
6121 if (g > 0xff) 6085 if (g > 0xff)
6122 g = 0xff; 6086 g = 0xff;
6123 else if (g <= 0) 6087 else if (g <= 0)
6124 g = 1; 6088 g = 1;
6125 reg_w(dev, g, 0x0120 + i); /* gamma */ 6089 reg_w(dev, g, 0x0120 + i); /* gamma */
6126#ifdef GSPCA_DEBUG 6090 if (k > 0)
6127 if (gspca_debug & D_CONF) 6091 adj--;
6128 v[i] = g; 6092 else
6129#endif 6093 adj++;
6130 } 6094
6131 PDEBUG(D_CONF, "tb: %02x %02x %02x %02x %02x %02x %02x %02x", 6095 if (i != 0) {
6132 v[0], v[1], v[2], v[3], v[4], v[5], v[6], v[7]); 6096 if (gp == 0)
6133 PDEBUG(D_CONF, " %02x %02x %02x %02x %02x %02x %02x %02x", 6097 gr[i - 1] = 0;
6134 v[8], v[9], v[10], v[11], v[12], v[13], v[14], v[15]);
6135 for (i = 0; i < 16; i++) {
6136 g = Tgradient[i] - kgrad_tb[i] * k / 128;
6137 if (g > 0xff)
6138 g = 0xff;
6139 else if (g <= 0) {
6140 if (i != 15)
6141 g = 0;
6142 else 6098 else
6143 g = 1; 6099 gr[i - 1] = g - gp;
6144 } 6100 }
6145 reg_w(dev, g, 0x0130 + i); /* gradient */ 6101 gp = g;
6146#ifdef GSPCA_DEBUG
6147 if (gspca_debug & D_CONF)
6148 v[i] = g;
6149#endif
6150 } 6102 }
6151 PDEBUG(D_CONF, " %02x %02x %02x %02x %02x %02x %02x %02x", 6103 gr[15] = gr[14] / 2;
6152 v[0], v[1], v[2], v[3], v[4], v[5], v[6], v[7]); 6104 for (i = 0; i < 16; i++)
6153 PDEBUG(D_CONF, " %02x %02x %02x %02x %02x %02x %02x %02x", 6105 reg_w(dev, gr[i], 0x0130 + i); /* gradient */
6154 v[8], v[9], v[10], v[11], v[12], v[13], v[14], v[15]);
6155} 6106}
6156 6107
6157static void setquality(struct gspca_dev *gspca_dev) 6108static void setquality(struct gspca_dev *gspca_dev)
6158{ 6109{
6159 struct sd *sd = (struct sd *) gspca_dev; 6110 struct sd *sd = (struct sd *) gspca_dev;
6160 struct usb_device *dev = gspca_dev->dev; 6111 struct usb_device *dev = gspca_dev->dev;
6161 __u8 frxt; 6112 u8 frxt;
6162 6113
6163 switch (sd->sensor) { 6114 switch (sd->sensor) {
6164 case SENSOR_ADCM2700: 6115 case SENSOR_ADCM2700:
6165 case SENSOR_GC0305: 6116 case SENSOR_GC0305:
6166 case SENSOR_HV7131B: 6117 case SENSOR_HV7131B:
6167 case SENSOR_OV7620: 6118 case SENSOR_OV7620:
6119 case SENSOR_PAS202B:
6168 case SENSOR_PO2030: 6120 case SENSOR_PO2030:
6169 return; 6121 return;
6170 } 6122 }
@@ -6218,9 +6170,9 @@ static int setlightfreq(struct gspca_dev *gspca_dev)
6218 hdcs2020b_50HZ, hdcs2020b_50HZ, 6170 hdcs2020b_50HZ, hdcs2020b_50HZ,
6219 hdcs2020b_60HZ, hdcs2020b_60HZ}, 6171 hdcs2020b_60HZ, hdcs2020b_60HZ},
6220/* SENSOR_HV7131B 5 */ 6172/* SENSOR_HV7131B 5 */
6221 {hv7131b_NoFlikerScale, hv7131b_NoFliker, 6173 {hv7131b_NoFliker, hv7131b_NoFlikerScale,
6222 hv7131b_50HZScale, hv7131b_50HZ, 6174 hv7131b_50HZ, hv7131b_50HZScale,
6223 hv7131b_60HZScale, hv7131b_60HZ}, 6175 hv7131b_60HZ, hv7131b_60HZScale},
6224/* SENSOR_HV7131C 6 */ 6176/* SENSOR_HV7131C 6 */
6225 {NULL, NULL, 6177 {NULL, NULL,
6226 NULL, NULL, 6178 NULL, NULL,
@@ -6230,17 +6182,17 @@ static int setlightfreq(struct gspca_dev *gspca_dev)
6230 icm105a_50HZ, icm105a_50HZScale, 6182 icm105a_50HZ, icm105a_50HZScale,
6231 icm105a_60HZ, icm105a_60HZScale}, 6183 icm105a_60HZ, icm105a_60HZScale},
6232/* SENSOR_MC501CB 8 */ 6184/* SENSOR_MC501CB 8 */
6233 {MC501CB_NoFliker, MC501CB_NoFlikerScale, 6185 {mc501cb_NoFliker, mc501cb_NoFlikerScale,
6234 MC501CB_50HZ, MC501CB_50HZScale, 6186 mc501cb_50HZ, mc501cb_50HZScale,
6235 MC501CB_60HZ, MC501CB_60HZScale}, 6187 mc501cb_60HZ, mc501cb_60HZScale},
6236/* SENSOR_MI0360SOC 9 */ 6188/* SENSOR_MI0360SOC 9 */
6237 {mi360soc_AENoFlikerScale, mi360soc_AENoFliker, 6189 {mi360soc_AENoFliker, mi360soc_AENoFlikerScale,
6238 mi360soc_AE50HZScale, mi360soc_AE50HZ, 6190 mi360soc_AE50HZ, mi360soc_AE50HZScale,
6239 mi360soc_AE60HZScale, mi360soc_AE60HZ}, 6191 mi360soc_AE60HZ, mi360soc_AE60HZScale},
6240/* SENSOR_OV7620 10 */ 6192/* SENSOR_OV7620 10 */
6241 {OV7620_NoFliker, OV7620_NoFliker, 6193 {ov7620_NoFliker, ov7620_NoFliker,
6242 OV7620_50HZ, OV7620_50HZ, 6194 ov7620_50HZ, ov7620_50HZ,
6243 OV7620_60HZ, OV7620_60HZ}, 6195 ov7620_60HZ, ov7620_60HZ},
6244/* SENSOR_OV7630C 11 */ 6196/* SENSOR_OV7630C 11 */
6245 {NULL, NULL, 6197 {NULL, NULL,
6246 NULL, NULL, 6198 NULL, NULL,
@@ -6258,17 +6210,17 @@ static int setlightfreq(struct gspca_dev *gspca_dev)
6258 pb0330_50HZScale, pb0330_50HZ, 6210 pb0330_50HZScale, pb0330_50HZ,
6259 pb0330_60HZScale, pb0330_60HZ}, 6211 pb0330_60HZScale, pb0330_60HZ},
6260/* SENSOR_PO2030 15 */ 6212/* SENSOR_PO2030 15 */
6261 {PO2030_NoFliker, PO2030_NoFliker, 6213 {po2030_NoFliker, po2030_NoFliker,
6262 PO2030_50HZ, PO2030_50HZ, 6214 po2030_50HZ, po2030_50HZ,
6263 PO2030_60HZ, PO2030_60HZ}, 6215 po2030_60HZ, po2030_60HZ},
6264/* SENSOR_TAS5130CK 16 */ 6216/* SENSOR_TAS5130CK 16 */
6265 {tas5130cxx_NoFlikerScale, tas5130cxx_NoFliker, 6217 {tas5130cxx_NoFliker, tas5130cxx_NoFlikerScale,
6266 tas5130cxx_50HZScale, tas5130cxx_50HZ, 6218 tas5130cxx_50HZ, tas5130cxx_50HZScale,
6267 tas5130cxx_60HZScale, tas5130cxx_60HZ}, 6219 tas5130cxx_60HZ, tas5130cxx_60HZScale},
6268/* SENSOR_TAS5130CXX 17 */ 6220/* SENSOR_TAS5130CXX 17 */
6269 {tas5130cxx_NoFlikerScale, tas5130cxx_NoFliker, 6221 {tas5130cxx_NoFliker, tas5130cxx_NoFlikerScale,
6270 tas5130cxx_50HZScale, tas5130cxx_50HZ, 6222 tas5130cxx_50HZ, tas5130cxx_50HZScale,
6271 tas5130cxx_60HZScale, tas5130cxx_60HZ}, 6223 tas5130cxx_60HZ, tas5130cxx_60HZScale},
6272/* SENSOR_TAS5130C_VF0250 18 */ 6224/* SENSOR_TAS5130C_VF0250 18 */
6273 {tas5130c_vf0250_NoFliker, tas5130c_vf0250_NoFlikerScale, 6225 {tas5130c_vf0250_NoFliker, tas5130c_vf0250_NoFlikerScale,
6274 tas5130c_vf0250_50HZ, tas5130c_vf0250_50HZScale, 6226 tas5130c_vf0250_50HZ, tas5130c_vf0250_50HZScale,
@@ -6277,9 +6229,9 @@ static int setlightfreq(struct gspca_dev *gspca_dev)
6277 6229
6278 i = sd->lightfreq * 2; 6230 i = sd->lightfreq * 2;
6279 mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv; 6231 mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
6280 if (!mode) 6232 if (mode)
6281 i++; /* 640x480 */ 6233 i++; /* 320x240 */
6282 zc3_freq = freq_tb[(int) sd->sensor][i]; 6234 zc3_freq = freq_tb[sd->sensor][i];
6283 if (zc3_freq != NULL) { 6235 if (zc3_freq != NULL) {
6284 usb_exchange(gspca_dev, zc3_freq); 6236 usb_exchange(gspca_dev, zc3_freq);
6285 switch (sd->sensor) { 6237 switch (sd->sensor) {
@@ -6297,6 +6249,9 @@ static int setlightfreq(struct gspca_dev *gspca_dev)
6297 reg_w(gspca_dev->dev, 0x44, 0x0002); 6249 reg_w(gspca_dev->dev, 0x44, 0x0002);
6298 } 6250 }
6299 break; 6251 break;
6252 case SENSOR_PAS202B:
6253 reg_w(gspca_dev->dev, 0x00, 0x01a7);
6254 break;
6300 } 6255 }
6301 } 6256 }
6302 return 0; 6257 return 0;
@@ -6305,7 +6260,7 @@ static int setlightfreq(struct gspca_dev *gspca_dev)
6305static void setautogain(struct gspca_dev *gspca_dev) 6260static void setautogain(struct gspca_dev *gspca_dev)
6306{ 6261{
6307 struct sd *sd = (struct sd *) gspca_dev; 6262 struct sd *sd = (struct sd *) gspca_dev;
6308 __u8 autoval; 6263 u8 autoval;
6309 6264
6310 if (sd->autogain) 6265 if (sd->autogain)
6311 autoval = 0x42; 6266 autoval = 0x42;
@@ -6333,6 +6288,12 @@ static void send_unknown(struct usb_device *dev, int sensor)
6333 reg_w(dev, 0x02, 0x003b); 6288 reg_w(dev, 0x02, 0x003b);
6334 reg_w(dev, 0x00, 0x0038); 6289 reg_w(dev, 0x00, 0x0038);
6335 break; 6290 break;
6291 case SENSOR_PAS202B:
6292 reg_w(dev, 0x03, 0x003b);
6293 reg_w(dev, 0x0c, 0x003a);
6294 reg_w(dev, 0x0b, 0x0039);
6295 reg_w(dev, 0x0b, 0x0038);
6296 break;
6336 } 6297 }
6337} 6298}
6338 6299
@@ -6349,7 +6310,7 @@ static void start_2wr_probe(struct usb_device *dev, int sensor)
6349 6310
6350static int sif_probe(struct gspca_dev *gspca_dev) 6311static int sif_probe(struct gspca_dev *gspca_dev)
6351{ 6312{
6352 __u16 checkword; 6313 u16 checkword;
6353 6314
6354 start_2wr_probe(gspca_dev->dev, 0x0f); /* PAS106 */ 6315 start_2wr_probe(gspca_dev->dev, 0x0f); /* PAS106 */
6355 reg_w(gspca_dev->dev, 0x08, 0x008d); 6316 reg_w(gspca_dev->dev, 0x08, 0x008d);
@@ -6392,6 +6353,7 @@ static int vga_2wr_probe(struct gspca_dev *gspca_dev)
6392 } 6353 }
6393 6354
6394 start_2wr_probe(dev, 0x08); /* HDCS2020 */ 6355 start_2wr_probe(dev, 0x08); /* HDCS2020 */
6356 i2c_write(gspca_dev, 0x1c, 0x00, 0x00);
6395 i2c_write(gspca_dev, 0x15, 0xaa, 0x00); 6357 i2c_write(gspca_dev, 0x15, 0xaa, 0x00);
6396 retword = i2c_read(gspca_dev, 0x15); 6358 retword = i2c_read(gspca_dev, 0x15);
6397 if (retword != 0) 6359 if (retword != 0)
@@ -6420,8 +6382,10 @@ static int vga_2wr_probe(struct gspca_dev *gspca_dev)
6420 i2c_write(gspca_dev, 0x03, 0xaa, 0x00); 6382 i2c_write(gspca_dev, 0x03, 0xaa, 0x00);
6421 msleep(50); 6383 msleep(50);
6422 retword = i2c_read(gspca_dev, 0x03); 6384 retword = i2c_read(gspca_dev, 0x03);
6423 if (retword != 0) 6385 if (retword != 0) {
6386 send_unknown(dev, SENSOR_PAS202B);
6424 return 0x0e; /* PAS202BCB */ 6387 return 0x0e; /* PAS202BCB */
6388 }
6425 6389
6426 start_2wr_probe(dev, 0x02); /* TAS5130C */ 6390 start_2wr_probe(dev, 0x02); /* TAS5130C */
6427 i2c_write(gspca_dev, 0x01, 0xaa, 0x00); 6391 i2c_write(gspca_dev, 0x01, 0xaa, 0x00);
@@ -6457,8 +6421,8 @@ ov_check:
6457} 6421}
6458 6422
6459struct sensor_by_chipset_revision { 6423struct sensor_by_chipset_revision {
6460 __u16 revision; 6424 u16 revision;
6461 __u8 internal_sensor_id; 6425 u8 internal_sensor_id;
6462}; 6426};
6463static const struct sensor_by_chipset_revision chipset_revision_sensor[] = { 6427static const struct sensor_by_chipset_revision chipset_revision_sensor[] = {
6464 {0xc000, 0x12}, /* TAS5130C */ 6428 {0xc000, 0x12}, /* TAS5130C */
@@ -6467,6 +6431,7 @@ static const struct sensor_by_chipset_revision chipset_revision_sensor[] = {
6467 {0x8001, 0x13}, 6431 {0x8001, 0x13},
6468 {0x8000, 0x14}, /* CS2102K */ 6432 {0x8000, 0x14}, /* CS2102K */
6469 {0x8400, 0x15}, /* TAS5130K */ 6433 {0x8400, 0x15}, /* TAS5130K */
6434 {0xe400, 0x15},
6470}; 6435};
6471 6436
6472static int vga_3wr_probe(struct gspca_dev *gspca_dev) 6437static int vga_3wr_probe(struct gspca_dev *gspca_dev)
@@ -6474,7 +6439,7 @@ static int vga_3wr_probe(struct gspca_dev *gspca_dev)
6474 struct sd *sd = (struct sd *) gspca_dev; 6439 struct sd *sd = (struct sd *) gspca_dev;
6475 struct usb_device *dev = gspca_dev->dev; 6440 struct usb_device *dev = gspca_dev->dev;
6476 int i; 6441 int i;
6477 __u8 retbyte; 6442 u8 retbyte;
6478 u16 retword; 6443 u16 retword;
6479 6444
6480/*fixme: lack of 8b=b3 (11,12)-> 10, 8b=e0 (14,15,16)-> 12 found in gspcav1*/ 6445/*fixme: lack of 8b=b3 (11,12)-> 10, 8b=e0 (14,15,16)-> 12 found in gspcav1*/
@@ -6622,8 +6587,7 @@ static int sd_config(struct gspca_dev *gspca_dev,
6622 struct sd *sd = (struct sd *) gspca_dev; 6587 struct sd *sd = (struct sd *) gspca_dev;
6623 struct cam *cam; 6588 struct cam *cam;
6624 int sensor; 6589 int sensor;
6625 int vga = 1; /* 1: vga, 0: sif */ 6590 static const u8 gamma[SENSOR_MAX] = {
6626 static const __u8 gamma[SENSOR_MAX] = {
6627 4, /* SENSOR_ADCM2700 0 */ 6591 4, /* SENSOR_ADCM2700 0 */
6628 4, /* SENSOR_CS2102 1 */ 6592 4, /* SENSOR_CS2102 1 */
6629 5, /* SENSOR_CS2102K 2 */ 6593 5, /* SENSOR_CS2102K 2 */
@@ -6644,9 +6608,30 @@ static int sd_config(struct gspca_dev *gspca_dev,
6644 3, /* SENSOR_TAS5130CXX 17 */ 6608 3, /* SENSOR_TAS5130CXX 17 */
6645 3, /* SENSOR_TAS5130C_VF0250 18 */ 6609 3, /* SENSOR_TAS5130C_VF0250 18 */
6646 }; 6610 };
6611 static const u8 mode_tb[SENSOR_MAX] = {
6612 2, /* SENSOR_ADCM2700 0 */
6613 1, /* SENSOR_CS2102 1 */
6614 1, /* SENSOR_CS2102K 2 */
6615 1, /* SENSOR_GC0305 3 */
6616 1, /* SENSOR_HDCS2020b 4 */
6617 1, /* SENSOR_HV7131B 5 */
6618 1, /* SENSOR_HV7131C 6 */
6619 1, /* SENSOR_ICM105A 7 */
6620 2, /* SENSOR_MC501CB 8 */
6621 1, /* SENSOR_MI0360SOC 9 */
6622 2, /* SENSOR_OV7620 10 */
6623 1, /* SENSOR_OV7630C 11 */
6624 0, /* SENSOR_PAS106 12 */
6625 1, /* SENSOR_PAS202B 13 */
6626 1, /* SENSOR_PB0330 14 */
6627 1, /* SENSOR_PO2030 15 */
6628 1, /* SENSOR_TAS5130CK 16 */
6629 1, /* SENSOR_TAS5130CXX 17 */
6630 1, /* SENSOR_TAS5130C_VF0250 18 */
6631 };
6647 6632
6648 /* define some sensors from the vendor/product */ 6633 /* define some sensors from the vendor/product */
6649 sd->sharpness = 2; 6634 sd->sharpness = SHARPNESS_DEF;
6650 sd->sensor = id->driver_info; 6635 sd->sensor = id->driver_info;
6651 sensor = zcxx_probeSensor(gspca_dev); 6636 sensor = zcxx_probeSensor(gspca_dev);
6652 if (sensor >= 0) 6637 if (sensor >= 0)
@@ -6671,8 +6656,21 @@ static int sd_config(struct gspca_dev *gspca_dev,
6671 } 6656 }
6672 break; 6657 break;
6673 case 0: 6658 case 0:
6674 PDEBUG(D_PROBE, "Find Sensor HV7131B"); 6659 /* check the sensor type */
6675 sd->sensor = SENSOR_HV7131B; 6660 sensor = i2c_read(gspca_dev, 0x00);
6661 PDEBUG(D_PROBE, "Sensor hv7131 type %d", sensor);
6662 switch (sensor) {
6663 case 0: /* hv7131b */
6664 case 1: /* hv7131e */
6665 PDEBUG(D_PROBE, "Find Sensor HV7131B");
6666 sd->sensor = SENSOR_HV7131B;
6667 break;
6668 default:
6669/* case 2: * hv7131r */
6670 PDEBUG(D_PROBE, "Find Sensor HV7131R(c)");
6671 sd->sensor = SENSOR_HV7131C;
6672 break;
6673 }
6676 break; 6674 break;
6677 case 0x02: 6675 case 0x02:
6678 PDEBUG(D_PROBE, "Sensor TAS5130C"); 6676 PDEBUG(D_PROBE, "Sensor TAS5130C");
@@ -6699,12 +6697,11 @@ static int sd_config(struct gspca_dev *gspca_dev,
6699 case 0x0e: 6697 case 0x0e:
6700 PDEBUG(D_PROBE, "Find Sensor PAS202B"); 6698 PDEBUG(D_PROBE, "Find Sensor PAS202B");
6701 sd->sensor = SENSOR_PAS202B; 6699 sd->sensor = SENSOR_PAS202B;
6702 sd->sharpness = 1; 6700/* sd->sharpness = 1; */
6703 break; 6701 break;
6704 case 0x0f: 6702 case 0x0f:
6705 PDEBUG(D_PROBE, "Find Sensor PAS106"); 6703 PDEBUG(D_PROBE, "Find Sensor PAS106");
6706 sd->sensor = SENSOR_PAS106; 6704 sd->sensor = SENSOR_PAS106;
6707 vga = 0; /* SIF */
6708 break; 6705 break;
6709 case 0x10: 6706 case 0x10:
6710 case 0x12: 6707 case 0x12:
@@ -6770,31 +6767,38 @@ static int sd_config(struct gspca_dev *gspca_dev,
6770 if (sensor < 0x20) { 6767 if (sensor < 0x20) {
6771 if (sensor == -1 || sensor == 0x10 || sensor == 0x12) 6768 if (sensor == -1 || sensor == 0x10 || sensor == 0x12)
6772 reg_w(gspca_dev->dev, 0x02, 0x0010); 6769 reg_w(gspca_dev->dev, 0x02, 0x0010);
6773 else
6774 reg_w(gspca_dev->dev, sensor & 0x0f, 0x0010);
6775 reg_r(gspca_dev, 0x0010); 6770 reg_r(gspca_dev, 0x0010);
6776 } 6771 }
6777 6772
6778 cam = &gspca_dev->cam; 6773 cam = &gspca_dev->cam;
6779/*fixme:test*/ 6774/*fixme:test*/
6780 gspca_dev->nbalt--; 6775 gspca_dev->nbalt--;
6781 if (vga) { 6776 switch (mode_tb[sd->sensor]) {
6782 cam->cam_mode = vga_mode; 6777 case 0:
6783 cam->nmodes = ARRAY_SIZE(vga_mode);
6784 } else {
6785 cam->cam_mode = sif_mode; 6778 cam->cam_mode = sif_mode;
6786 cam->nmodes = ARRAY_SIZE(sif_mode); 6779 cam->nmodes = ARRAY_SIZE(sif_mode);
6780 break;
6781 case 1:
6782 cam->cam_mode = vga_mode;
6783 cam->nmodes = ARRAY_SIZE(vga_mode);
6784 break;
6785 default:
6786/* case 2: */
6787 cam->cam_mode = broken_vga_mode;
6788 cam->nmodes = ARRAY_SIZE(broken_vga_mode);
6789 break;
6787 } 6790 }
6788 sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value; 6791 sd->brightness = BRIGHTNESS_DEF;
6789 sd->contrast = sd_ctrls[SD_CONTRAST].qctrl.default_value; 6792 sd->contrast = CONTRAST_DEF;
6790 sd->gamma = gamma[(int) sd->sensor]; 6793 sd->gamma = gamma[sd->sensor];
6791 sd->autogain = sd_ctrls[SD_AUTOGAIN].qctrl.default_value; 6794 sd->autogain = AUTOGAIN_DEF;
6792 sd->lightfreq = sd_ctrls[SD_FREQ].qctrl.default_value; 6795 sd->lightfreq = FREQ_DEF;
6793 sd->quality = QUALITY_DEF; 6796 sd->quality = QUALITY_DEF;
6794 6797
6795 switch (sd->sensor) { 6798 switch (sd->sensor) {
6796 case SENSOR_GC0305: 6799 case SENSOR_GC0305:
6797 case SENSOR_OV7620: 6800 case SENSOR_OV7620:
6801 case SENSOR_PAS202B:
6798 case SENSOR_PO2030: 6802 case SENSOR_PO2030:
6799 gspca_dev->ctrl_dis = (1 << BRIGHTNESS_IDX); 6803 gspca_dev->ctrl_dis = (1 << BRIGHTNESS_IDX);
6800 break; 6804 break;
@@ -6805,14 +6809,13 @@ static int sd_config(struct gspca_dev *gspca_dev,
6805 break; 6809 break;
6806 } 6810 }
6807 6811
6808 /* switch the led off */
6809 reg_w(gspca_dev->dev, 0x01, 0x0000);
6810 return 0; 6812 return 0;
6811} 6813}
6812 6814
6813/* this function is called at probe and resume time */ 6815/* this function is called at probe and resume time */
6814static int sd_init(struct gspca_dev *gspca_dev) 6816static int sd_init(struct gspca_dev *gspca_dev)
6815{ 6817{
6818 /* switch off the led */
6816 reg_w(gspca_dev->dev, 0x01, 0x0000); 6819 reg_w(gspca_dev->dev, 0x01, 0x0000);
6817 return 0; 6820 return 0;
6818} 6821}
@@ -6821,28 +6824,27 @@ static int sd_start(struct gspca_dev *gspca_dev)
6821{ 6824{
6822 struct sd *sd = (struct sd *) gspca_dev; 6825 struct sd *sd = (struct sd *) gspca_dev;
6823 struct usb_device *dev = gspca_dev->dev; 6826 struct usb_device *dev = gspca_dev->dev;
6824 const struct usb_action *zc3_init;
6825 int mode; 6827 int mode;
6826 static const struct usb_action *init_tb[SENSOR_MAX][2] = { 6828 static const struct usb_action *init_tb[SENSOR_MAX][2] = {
6827 {adcm2700_Initial, adcm2700_InitialScale}, /* 0 */ 6829 {adcm2700_Initial, adcm2700_InitialScale}, /* 0 */
6828 {cs2102_InitialScale, cs2102_Initial}, /* 1 */ 6830 {cs2102_Initial, cs2102_InitialScale}, /* 1 */
6829 {cs2102K_InitialScale, cs2102K_Initial}, /* 2 */ 6831 {cs2102K_Initial, cs2102K_InitialScale}, /* 2 */
6830 {gc0305_Initial, gc0305_InitialScale}, /* 3 */ 6832 {gc0305_Initial, gc0305_InitialScale}, /* 3 */
6831 {hdcs2020xb_InitialScale, hdcs2020xb_Initial}, /* 4 */ 6833 {hdcs2020b_Initial, hdcs2020b_InitialScale}, /* 4 */
6832 {hv7131bxx_InitialScale, hv7131bxx_Initial}, /* 5 */ 6834 {hv7131b_Initial, hv7131b_InitialScale}, /* 5 */
6833 {hv7131cxx_InitialScale, hv7131cxx_Initial}, /* 6 */ 6835 {hv7131r_Initial, hv7131r_InitialScale}, /* 6 */
6834 {icm105axx_InitialScale, icm105axx_Initial}, /* 7 */ 6836 {icm105a_Initial, icm105a_InitialScale}, /* 7 */
6835 {MC501CB_InitialScale, MC501CB_Initial}, /* 8 */ 6837 {mc501cb_Initial, mc501cb_InitialScale}, /* 8 */
6836 {mi0360soc_Initial, mi0360soc_InitialScale}, /* 9 */ 6838 {mi0360soc_Initial, mi0360soc_InitialScale}, /* 9 */
6837 {OV7620_mode0, OV7620_mode1}, /* 10 */ 6839 {ov7620_Initial, ov7620_InitialScale}, /* 10 */
6838 {ov7630c_InitialScale, ov7630c_Initial}, /* 11 */ 6840 {ov7630c_Initial, ov7630c_InitialScale}, /* 11 */
6839 {pas106b_InitialScale, pas106b_Initial}, /* 12 */ 6841 {pas106b_Initial, pas106b_InitialScale}, /* 12 */
6840 {pas202b_Initial, pas202b_InitialScale}, /* 13 */ 6842 {pas202b_Initial, pas202b_InitialScale}, /* 13 */
6841 {pb0330_Initial, pb0330_InitialScale}, /* 14 */ 6843 {pb0330_Initial, pb0330_InitialScale}, /* 14 */
6842 {PO2030_mode0, PO2030_mode1}, /* 15 */ 6844 {po2030_Initial, po2030_InitialScale}, /* 15 */
6843 {tas5130CK_InitialScale, tas5130CK_Initial}, /* 16 */ 6845 {tas5130cK_Initial, tas5130cK_InitialScale}, /* 16 */
6844 {tas5130cxx_Initial, tas5130cxx_InitialScale}, /* 17 */ 6846 {tas5130cxx_Initial, tas5130cxx_InitialScale}, /* 17 */
6845 {tas5130c_vf0250_InitialScale, tas5130c_vf0250_Initial}, 6847 {tas5130c_vf0250_Initial, tas5130c_vf0250_InitialScale},
6846 /* 18 */ 6848 /* 18 */
6847 }; 6849 };
6848 6850
@@ -6854,8 +6856,7 @@ static int sd_start(struct gspca_dev *gspca_dev)
6854 0x21); /* JPEG 422 */ 6856 0x21); /* JPEG 422 */
6855 jpeg_set_qual(sd->jpeg_hdr, sd->quality); 6857 jpeg_set_qual(sd->jpeg_hdr, sd->quality);
6856 6858
6857 mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv; 6859 mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv;
6858 zc3_init = init_tb[(int) sd->sensor][mode];
6859 switch (sd->sensor) { 6860 switch (sd->sensor) {
6860 case SENSOR_HV7131C: 6861 case SENSOR_HV7131C:
6861 zcxx_probeSensor(gspca_dev); 6862 zcxx_probeSensor(gspca_dev);
@@ -6864,7 +6865,7 @@ static int sd_start(struct gspca_dev *gspca_dev)
6864 usb_exchange(gspca_dev, pas106b_Initial_com); 6865 usb_exchange(gspca_dev, pas106b_Initial_com);
6865 break; 6866 break;
6866 } 6867 }
6867 usb_exchange(gspca_dev, zc3_init); 6868 usb_exchange(gspca_dev, init_tb[sd->sensor][mode]);
6868 6869
6869 switch (sd->sensor) { 6870 switch (sd->sensor) {
6870 case SENSOR_ADCM2700: 6871 case SENSOR_ADCM2700:
@@ -6883,6 +6884,11 @@ static int sd_start(struct gspca_dev *gspca_dev)
6883 reg_w(dev, 0x02, 0x003b); 6884 reg_w(dev, 0x02, 0x003b);
6884 reg_w(dev, 0x00, 0x0038); 6885 reg_w(dev, 0x00, 0x0038);
6885 break; 6886 break;
6887 case SENSOR_PAS202B:
6888 reg_w(dev, 0x03, 0x003b);
6889 reg_w(dev, 0x0c, 0x003a);
6890 reg_w(dev, 0x0b, 0x0039);
6891 break;
6886 } 6892 }
6887 6893
6888 setmatrix(gspca_dev); 6894 setmatrix(gspca_dev);
@@ -6961,13 +6967,13 @@ static int sd_start(struct gspca_dev *gspca_dev)
6961 switch (sd->sensor) { 6967 switch (sd->sensor) {
6962 case SENSOR_PO2030: 6968 case SENSOR_PO2030:
6963 msleep(50); 6969 msleep(50);
6964 reg_r(gspca_dev, 0x0008);
6965 reg_r(gspca_dev, 0x0007);
6966 /*fall thru*/
6967 case SENSOR_PAS202B:
6968 reg_w(dev, 0x00, 0x0007); /* (from win traces) */ 6970 reg_w(dev, 0x00, 0x0007); /* (from win traces) */
6969 reg_w(dev, 0x02, ZC3XX_R008_CLOCKSETTING); 6971 reg_w(dev, 0x02, ZC3XX_R008_CLOCKSETTING);
6970 break; 6972 break;
6973 case SENSOR_PAS202B:
6974 reg_w(dev, 0x32, 0x0007); /* (from win traces) */
6975 reg_w(dev, 0x02, ZC3XX_R008_CLOCKSETTING);
6976 break;
6971 } 6977 }
6972 return 0; 6978 return 0;
6973} 6979}
@@ -7165,6 +7171,22 @@ static int sd_get_jcomp(struct gspca_dev *gspca_dev,
7165 return 0; 7171 return 0;
7166} 7172}
7167 7173
7174#ifdef CONFIG_INPUT
7175static int sd_int_pkt_scan(struct gspca_dev *gspca_dev,
7176 u8 *data, /* interrupt packet data */
7177 int len) /* interrput packet length */
7178{
7179 if (len == 8 && data[4] == 1) {
7180 input_report_key(gspca_dev->input_dev, KEY_CAMERA, 1);
7181 input_sync(gspca_dev->input_dev);
7182 input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0);
7183 input_sync(gspca_dev->input_dev);
7184 }
7185
7186 return 0;
7187}
7188#endif
7189
7168static const struct sd_desc sd_desc = { 7190static const struct sd_desc sd_desc = {
7169 .name = MODULE_NAME, 7191 .name = MODULE_NAME,
7170 .ctrls = sd_ctrls, 7192 .ctrls = sd_ctrls,
@@ -7177,6 +7199,9 @@ static const struct sd_desc sd_desc = {
7177 .querymenu = sd_querymenu, 7199 .querymenu = sd_querymenu,
7178 .get_jcomp = sd_get_jcomp, 7200 .get_jcomp = sd_get_jcomp,
7179 .set_jcomp = sd_set_jcomp, 7201 .set_jcomp = sd_set_jcomp,
7202#ifdef CONFIG_INPUT
7203 .int_pkt_scan = sd_int_pkt_scan,
7204#endif
7180}; 7205};
7181 7206
7182static const __devinitdata struct usb_device_id device_table[] = { 7207static const __devinitdata struct usb_device_id device_table[] = {
diff --git a/drivers/media/video/hdpvr/hdpvr-core.c b/drivers/media/video/hdpvr/hdpvr-core.c
index 51f393d03a46..2fc9865fd486 100644
--- a/drivers/media/video/hdpvr/hdpvr-core.c
+++ b/drivers/media/video/hdpvr/hdpvr-core.c
@@ -39,12 +39,12 @@ int hdpvr_debug;
39module_param(hdpvr_debug, int, S_IRUGO|S_IWUSR); 39module_param(hdpvr_debug, int, S_IRUGO|S_IWUSR);
40MODULE_PARM_DESC(hdpvr_debug, "enable debugging output"); 40MODULE_PARM_DESC(hdpvr_debug, "enable debugging output");
41 41
42uint default_video_input = HDPVR_VIDEO_INPUTS; 42static uint default_video_input = HDPVR_VIDEO_INPUTS;
43module_param(default_video_input, uint, S_IRUGO|S_IWUSR); 43module_param(default_video_input, uint, S_IRUGO|S_IWUSR);
44MODULE_PARM_DESC(default_video_input, "default video input: 0=Component / " 44MODULE_PARM_DESC(default_video_input, "default video input: 0=Component / "
45 "1=S-Video / 2=Composite"); 45 "1=S-Video / 2=Composite");
46 46
47uint default_audio_input = HDPVR_AUDIO_INPUTS; 47static uint default_audio_input = HDPVR_AUDIO_INPUTS;
48module_param(default_audio_input, uint, S_IRUGO|S_IWUSR); 48module_param(default_audio_input, uint, S_IRUGO|S_IWUSR);
49MODULE_PARM_DESC(default_audio_input, "default audio input: 0=RCA back / " 49MODULE_PARM_DESC(default_audio_input, "default audio input: 0=RCA back / "
50 "1=RCA front / 2=S/PDIF"); 50 "1=RCA front / 2=S/PDIF");
@@ -59,6 +59,7 @@ static struct usb_device_id hdpvr_table[] = {
59 { USB_DEVICE(HD_PVR_VENDOR_ID, HD_PVR_PRODUCT_ID) }, 59 { USB_DEVICE(HD_PVR_VENDOR_ID, HD_PVR_PRODUCT_ID) },
60 { USB_DEVICE(HD_PVR_VENDOR_ID, HD_PVR_PRODUCT_ID1) }, 60 { USB_DEVICE(HD_PVR_VENDOR_ID, HD_PVR_PRODUCT_ID1) },
61 { USB_DEVICE(HD_PVR_VENDOR_ID, HD_PVR_PRODUCT_ID2) }, 61 { USB_DEVICE(HD_PVR_VENDOR_ID, HD_PVR_PRODUCT_ID2) },
62 { USB_DEVICE(HD_PVR_VENDOR_ID, HD_PVR_PRODUCT_ID3) },
62 { } /* Terminating entry */ 63 { } /* Terminating entry */
63}; 64};
64MODULE_DEVICE_TABLE(usb, hdpvr_table); 65MODULE_DEVICE_TABLE(usb, hdpvr_table);
diff --git a/drivers/media/video/hdpvr/hdpvr-video.c b/drivers/media/video/hdpvr/hdpvr-video.c
index fdd782039e9d..196f82de48f0 100644
--- a/drivers/media/video/hdpvr/hdpvr-video.c
+++ b/drivers/media/video/hdpvr/hdpvr-video.c
@@ -302,7 +302,8 @@ static int hdpvr_start_streaming(struct hdpvr_device *dev)
302/* function expects dev->io_mutex to be hold by caller */ 302/* function expects dev->io_mutex to be hold by caller */
303static int hdpvr_stop_streaming(struct hdpvr_device *dev) 303static int hdpvr_stop_streaming(struct hdpvr_device *dev)
304{ 304{
305 uint actual_length, c = 0; 305 int actual_length;
306 uint c = 0;
306 u8 *buf; 307 u8 *buf;
307 308
308 if (dev->status == STATUS_IDLE) 309 if (dev->status == STATUS_IDLE)
@@ -572,7 +573,7 @@ static int vidioc_querycap(struct file *file, void *priv,
572 struct hdpvr_device *dev = video_drvdata(file); 573 struct hdpvr_device *dev = video_drvdata(file);
573 574
574 strcpy(cap->driver, "hdpvr"); 575 strcpy(cap->driver, "hdpvr");
575 strcpy(cap->card, "Haupauge HD PVR"); 576 strcpy(cap->card, "Hauppauge HD PVR");
576 usb_make_path(dev->udev, cap->bus_info, sizeof(cap->bus_info)); 577 usb_make_path(dev->udev, cap->bus_info, sizeof(cap->bus_info));
577 cap->version = HDPVR_VERSION; 578 cap->version = HDPVR_VERSION;
578 cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | 579 cap->capabilities = V4L2_CAP_VIDEO_CAPTURE |
diff --git a/drivers/media/video/hdpvr/hdpvr.h b/drivers/media/video/hdpvr/hdpvr.h
index 1edd8759121e..49ae25d83d10 100644
--- a/drivers/media/video/hdpvr/hdpvr.h
+++ b/drivers/media/video/hdpvr/hdpvr.h
@@ -30,6 +30,7 @@
30#define HD_PVR_PRODUCT_ID 0x4900 30#define HD_PVR_PRODUCT_ID 0x4900
31#define HD_PVR_PRODUCT_ID1 0x4901 31#define HD_PVR_PRODUCT_ID1 0x4901
32#define HD_PVR_PRODUCT_ID2 0x4902 32#define HD_PVR_PRODUCT_ID2 0x4902
33#define HD_PVR_PRODUCT_ID3 0x4982
33 34
34#define UNSET (-1U) 35#define UNSET (-1U)
35 36
diff --git a/drivers/media/video/hexium_gemini.c b/drivers/media/video/hexium_gemini.c
index 60d992ee2589..e620a3a92f25 100644
--- a/drivers/media/video/hexium_gemini.c
+++ b/drivers/media/video/hexium_gemini.c
@@ -352,9 +352,13 @@ static struct saa7146_ext_vv vv_data;
352static int hexium_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_data *info) 352static int hexium_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_data *info)
353{ 353{
354 struct hexium *hexium = (struct hexium *) dev->ext_priv; 354 struct hexium *hexium = (struct hexium *) dev->ext_priv;
355 int ret;
355 356
356 DEB_EE((".\n")); 357 DEB_EE((".\n"));
357 358
359 ret = saa7146_vv_devinit(dev);
360 if (ret)
361 return ret;
358 hexium = kzalloc(sizeof(struct hexium), GFP_KERNEL); 362 hexium = kzalloc(sizeof(struct hexium), GFP_KERNEL);
359 if (NULL == hexium) { 363 if (NULL == hexium) {
360 printk("hexium_gemini: not enough kernel memory in hexium_attach().\n"); 364 printk("hexium_gemini: not enough kernel memory in hexium_attach().\n");
@@ -400,9 +404,10 @@ static int hexium_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_d
400 vv_data.ops.vidioc_enum_input = vidioc_enum_input; 404 vv_data.ops.vidioc_enum_input = vidioc_enum_input;
401 vv_data.ops.vidioc_g_input = vidioc_g_input; 405 vv_data.ops.vidioc_g_input = vidioc_g_input;
402 vv_data.ops.vidioc_s_input = vidioc_s_input; 406 vv_data.ops.vidioc_s_input = vidioc_s_input;
403 if (0 != saa7146_register_device(&hexium->video_dev, dev, "hexium gemini", VFL_TYPE_GRABBER)) { 407 ret = saa7146_register_device(&hexium->video_dev, dev, "hexium gemini", VFL_TYPE_GRABBER);
408 if (ret < 0) {
404 printk("hexium_gemini: cannot register capture v4l2 device. skipping.\n"); 409 printk("hexium_gemini: cannot register capture v4l2 device. skipping.\n");
405 return -1; 410 return ret;
406 } 411 }
407 412
408 printk("hexium_gemini: found 'hexium gemini' frame grabber-%d.\n", hexium_num); 413 printk("hexium_gemini: found 'hexium gemini' frame grabber-%d.\n", hexium_num);
diff --git a/drivers/media/video/hexium_orion.c b/drivers/media/video/hexium_orion.c
index 938a1f8f880a..fe596a1c12a8 100644
--- a/drivers/media/video/hexium_orion.c
+++ b/drivers/media/video/hexium_orion.c
@@ -216,6 +216,10 @@ static int hexium_probe(struct saa7146_dev *dev)
216 return -EFAULT; 216 return -EFAULT;
217 } 217 }
218 218
219 err = saa7146_vv_devinit(dev);
220 if (err)
221 return err;
222
219 hexium = kzalloc(sizeof(struct hexium), GFP_KERNEL); 223 hexium = kzalloc(sizeof(struct hexium), GFP_KERNEL);
220 if (NULL == hexium) { 224 if (NULL == hexium) {
221 printk("hexium_orion: hexium_probe: not enough kernel memory.\n"); 225 printk("hexium_orion: hexium_probe: not enough kernel memory.\n");
diff --git a/drivers/media/video/ir-kbd-i2c.c b/drivers/media/video/ir-kbd-i2c.c
index b86e35386cee..da18d698e7f2 100644
--- a/drivers/media/video/ir-kbd-i2c.c
+++ b/drivers/media/video/ir-kbd-i2c.c
@@ -299,7 +299,7 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id)
299{ 299{
300 struct ir_scancode_table *ir_codes = NULL; 300 struct ir_scancode_table *ir_codes = NULL;
301 const char *name = NULL; 301 const char *name = NULL;
302 int ir_type = 0; 302 u64 ir_type = 0;
303 struct IR_i2c *ir; 303 struct IR_i2c *ir;
304 struct input_dev *input_dev; 304 struct input_dev *input_dev;
305 struct i2c_adapter *adap = client->adapter; 305 struct i2c_adapter *adap = client->adapter;
@@ -331,6 +331,7 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id)
331 ir_codes = &ir_codes_pv951_table; 331 ir_codes = &ir_codes_pv951_table;
332 break; 332 break;
333 case 0x18: 333 case 0x18:
334 case 0x1f:
334 case 0x1a: 335 case 0x1a:
335 name = "Hauppauge"; 336 name = "Hauppauge";
336 ir->get_key = get_key_haup; 337 ir->get_key = get_key_haup;
@@ -446,7 +447,7 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id)
446 input_dev->name = ir->name; 447 input_dev->name = ir->name;
447 input_dev->phys = ir->phys; 448 input_dev->phys = ir->phys;
448 449
449 err = ir_input_register(ir->input, ir->ir_codes); 450 err = ir_input_register(ir->input, ir->ir_codes, NULL);
450 if (err) 451 if (err)
451 goto err_out_free; 452 goto err_out_free;
452 453
diff --git a/drivers/media/video/ivtv/ivtv-cards.c b/drivers/media/video/ivtv/ivtv-cards.c
index 79d0fe4990d6..ca1fd3227a93 100644
--- a/drivers/media/video/ivtv/ivtv-cards.c
+++ b/drivers/media/video/ivtv/ivtv-cards.c
@@ -1210,6 +1210,53 @@ static const struct ivtv_card ivtv_card_buffalo = {
1210 .i2c = &ivtv_i2c_std, 1210 .i2c = &ivtv_i2c_std,
1211}; 1211};
1212 1212
1213/* ------------------------------------------------------------------------- */
1214/* Sony Kikyou */
1215
1216static const struct ivtv_card_pci_info ivtv_pci_kikyou[] = {
1217 { PCI_DEVICE_ID_IVTV16, IVTV_PCI_ID_SONY, 0x813d },
1218 { 0, 0, 0 }
1219};
1220
1221static const struct ivtv_card ivtv_card_kikyou = {
1222 .type = IVTV_CARD_KIKYOU,
1223 .name = "Sony VAIO Giga Pocket (ENX Kikyou)",
1224 .v4l2_capabilities = IVTV_CAP_ENCODER,
1225 .hw_video = IVTV_HW_SAA7115,
1226 .hw_audio = IVTV_HW_GPIO,
1227 .hw_audio_ctrl = IVTV_HW_GPIO,
1228 .hw_all = IVTV_HW_GPIO | IVTV_HW_SAA7115 | IVTV_HW_TUNER,
1229 .video_inputs = {
1230 { IVTV_CARD_INPUT_VID_TUNER, 0, IVTV_SAA71XX_COMPOSITE1 },
1231 { IVTV_CARD_INPUT_COMPOSITE1, 1, IVTV_SAA71XX_COMPOSITE1 },
1232 { IVTV_CARD_INPUT_SVIDEO1, 1, IVTV_SAA71XX_SVIDEO1 },
1233 },
1234 .audio_inputs = {
1235 { IVTV_CARD_INPUT_AUD_TUNER, IVTV_GPIO_TUNER },
1236 { IVTV_CARD_INPUT_LINE_IN1, IVTV_GPIO_LINE_IN },
1237 { IVTV_CARD_INPUT_LINE_IN2, IVTV_GPIO_LINE_IN },
1238 },
1239 .gpio_init = { .direction = 0x03e1, .initial_value = 0x0320 },
1240 .gpio_audio_input = { .mask = 0x0060,
1241 .tuner = 0x0020,
1242 .linein = 0x0000,
1243 .radio = 0x0060 },
1244 .gpio_audio_mute = { .mask = 0x0000,
1245 .mute = 0x0000 }, /* 0x200? Disable for now. */
1246 .gpio_audio_mode = { .mask = 0x0080,
1247 .mono = 0x0000,
1248 .stereo = 0x0000, /* SAP */
1249 .lang1 = 0x0080,
1250 .lang2 = 0x0000,
1251 .both = 0x0080 },
1252 .tuners = {
1253 { .std = V4L2_STD_ALL, .tuner = TUNER_SONY_BTF_PXN01Z },
1254 },
1255 .pci_list = ivtv_pci_kikyou,
1256 .i2c = &ivtv_i2c_std,
1257};
1258
1259
1213static const struct ivtv_card *ivtv_card_list[] = { 1260static const struct ivtv_card *ivtv_card_list[] = {
1214 &ivtv_card_pvr250, 1261 &ivtv_card_pvr250,
1215 &ivtv_card_pvr350, 1262 &ivtv_card_pvr350,
@@ -1238,6 +1285,7 @@ static const struct ivtv_card *ivtv_card_list[] = {
1238 &ivtv_card_aver_m104, 1285 &ivtv_card_aver_m104,
1239 &ivtv_card_buffalo, 1286 &ivtv_card_buffalo,
1240 &ivtv_card_aver_ultra1500mce, 1287 &ivtv_card_aver_ultra1500mce,
1288 &ivtv_card_kikyou,
1241 1289
1242 /* Variations of standard cards but with the same PCI IDs. 1290 /* Variations of standard cards but with the same PCI IDs.
1243 These cards must come last in this list. */ 1291 These cards must come last in this list. */
diff --git a/drivers/media/video/ivtv/ivtv-cards.h b/drivers/media/video/ivtv/ivtv-cards.h
index 6148827ec885..78eca992e1fd 100644
--- a/drivers/media/video/ivtv/ivtv-cards.h
+++ b/drivers/media/video/ivtv/ivtv-cards.h
@@ -51,7 +51,8 @@
51#define IVTV_CARD_AVER_M104 24 /* AverMedia M104 miniPCI card */ 51#define IVTV_CARD_AVER_M104 24 /* AverMedia M104 miniPCI card */
52#define IVTV_CARD_BUFFALO_MV5L 25 /* Buffalo PC-MV5L/PCI card */ 52#define IVTV_CARD_BUFFALO_MV5L 25 /* Buffalo PC-MV5L/PCI card */
53#define IVTV_CARD_AVER_ULTRA1500MCE 26 /* AVerMedia UltraTV 1500 MCE */ 53#define IVTV_CARD_AVER_ULTRA1500MCE 26 /* AVerMedia UltraTV 1500 MCE */
54#define IVTV_CARD_LAST 26 54#define IVTV_CARD_KIKYOU 27 /* Sony VAIO Giga Pocket (ENX Kikyou) */
55#define IVTV_CARD_LAST 27
55 56
56/* Variants of existing cards but with the same PCI IDs. The driver 57/* Variants of existing cards but with the same PCI IDs. The driver
57 detects these based on other device information. 58 detects these based on other device information.
@@ -86,6 +87,7 @@
86#define IVTV_PCI_ID_MELCO 0x1154 87#define IVTV_PCI_ID_MELCO 0x1154
87#define IVTV_PCI_ID_GOTVIEW1 0xffac 88#define IVTV_PCI_ID_GOTVIEW1 0xffac
88#define IVTV_PCI_ID_GOTVIEW2 0xffad 89#define IVTV_PCI_ID_GOTVIEW2 0xffad
90#define IVTV_PCI_ID_SONY 0x104d
89 91
90/* hardware flags, no gaps allowed */ 92/* hardware flags, no gaps allowed */
91#define IVTV_HW_CX25840 (1 << 0) 93#define IVTV_HW_CX25840 (1 << 0)
diff --git a/drivers/media/video/ivtv/ivtv-driver.c b/drivers/media/video/ivtv/ivtv-driver.c
index 347c3344f56d..9a250548be4d 100644
--- a/drivers/media/video/ivtv/ivtv-driver.c
+++ b/drivers/media/video/ivtv/ivtv-driver.c
@@ -193,6 +193,7 @@ MODULE_PARM_DESC(cardtype,
193 "\t\t\t25 = AverMedia M104 (not yet working)\n" 193 "\t\t\t25 = AverMedia M104 (not yet working)\n"
194 "\t\t\t26 = Buffalo PC-MV5L/PCI\n" 194 "\t\t\t26 = Buffalo PC-MV5L/PCI\n"
195 "\t\t\t27 = AVerMedia UltraTV 1500 MCE\n" 195 "\t\t\t27 = AVerMedia UltraTV 1500 MCE\n"
196 "\t\t\t28 = Sony VAIO Giga Pocket (ENX Kikyou)\n"
196 "\t\t\t 0 = Autodetect (default)\n" 197 "\t\t\t 0 = Autodetect (default)\n"
197 "\t\t\t-1 = Ignore this card\n\t\t"); 198 "\t\t\t-1 = Ignore this card\n\t\t");
198MODULE_PARM_DESC(pal, "Set PAL standard: BGH, DK, I, M, N, Nc, 60"); 199MODULE_PARM_DESC(pal, "Set PAL standard: BGH, DK, I, M, N, Nc, 60");
diff --git a/drivers/media/video/ivtv/ivtv-firmware.c b/drivers/media/video/ivtv/ivtv-firmware.c
index c1b7ec475c27..a71e8ba306b0 100644
--- a/drivers/media/video/ivtv/ivtv-firmware.c
+++ b/drivers/media/video/ivtv/ivtv-firmware.c
@@ -258,7 +258,7 @@ void ivtv_init_mpeg_decoder(struct ivtv *itv)
258 IVTV_ERR("ivtv_init_mpeg_decoder failed to start playback\n"); 258 IVTV_ERR("ivtv_init_mpeg_decoder failed to start playback\n");
259 return; 259 return;
260 } 260 }
261 ivtv_api_get_data(&itv->dec_mbox, IVTV_MBOX_DMA, data); 261 ivtv_api_get_data(&itv->dec_mbox, IVTV_MBOX_DMA, 2, data);
262 mem_offset = itv->dec_mem + data[1]; 262 mem_offset = itv->dec_mem + data[1];
263 263
264 if ((readbytes = load_fw_direct(IVTV_DECODE_INIT_MPEG_FILENAME, 264 if ((readbytes = load_fw_direct(IVTV_DECODE_INIT_MPEG_FILENAME,
diff --git a/drivers/media/video/ivtv/ivtv-irq.c b/drivers/media/video/ivtv/ivtv-irq.c
index cd9db0bf33bf..12d36ca91d53 100644
--- a/drivers/media/video/ivtv/ivtv-irq.c
+++ b/drivers/media/video/ivtv/ivtv-irq.c
@@ -562,7 +562,7 @@ static void ivtv_irq_enc_dma_complete(struct ivtv *itv)
562 u32 data[CX2341X_MBOX_MAX_DATA]; 562 u32 data[CX2341X_MBOX_MAX_DATA];
563 struct ivtv_stream *s; 563 struct ivtv_stream *s;
564 564
565 ivtv_api_get_data(&itv->enc_mbox, IVTV_MBOX_DMA_END, data); 565 ivtv_api_get_data(&itv->enc_mbox, IVTV_MBOX_DMA_END, 2, data);
566 IVTV_DEBUG_HI_IRQ("ENC DMA COMPLETE %x %d (%d)\n", data[0], data[1], itv->cur_dma_stream); 566 IVTV_DEBUG_HI_IRQ("ENC DMA COMPLETE %x %d (%d)\n", data[0], data[1], itv->cur_dma_stream);
567 567
568 del_timer(&itv->dma_timer); 568 del_timer(&itv->dma_timer);
@@ -638,7 +638,7 @@ static void ivtv_irq_dma_err(struct ivtv *itv)
638 u32 data[CX2341X_MBOX_MAX_DATA]; 638 u32 data[CX2341X_MBOX_MAX_DATA];
639 639
640 del_timer(&itv->dma_timer); 640 del_timer(&itv->dma_timer);
641 ivtv_api_get_data(&itv->enc_mbox, IVTV_MBOX_DMA_END, data); 641 ivtv_api_get_data(&itv->enc_mbox, IVTV_MBOX_DMA_END, 2, data);
642 IVTV_DEBUG_WARN("DMA ERROR %08x %08x %08x %d\n", data[0], data[1], 642 IVTV_DEBUG_WARN("DMA ERROR %08x %08x %08x %d\n", data[0], data[1],
643 read_reg(IVTV_REG_DMASTATUS), itv->cur_dma_stream); 643 read_reg(IVTV_REG_DMASTATUS), itv->cur_dma_stream);
644 write_reg(read_reg(IVTV_REG_DMASTATUS) & 3, IVTV_REG_DMASTATUS); 644 write_reg(read_reg(IVTV_REG_DMASTATUS) & 3, IVTV_REG_DMASTATUS);
@@ -669,7 +669,7 @@ static void ivtv_irq_enc_start_cap(struct ivtv *itv)
669 struct ivtv_stream *s; 669 struct ivtv_stream *s;
670 670
671 /* Get DMA destination and size arguments from card */ 671 /* Get DMA destination and size arguments from card */
672 ivtv_api_get_data(&itv->enc_mbox, IVTV_MBOX_DMA, data); 672 ivtv_api_get_data(&itv->enc_mbox, IVTV_MBOX_DMA, 7, data);
673 IVTV_DEBUG_HI_IRQ("ENC START CAP %d: %08x %08x\n", data[0], data[1], data[2]); 673 IVTV_DEBUG_HI_IRQ("ENC START CAP %d: %08x %08x\n", data[0], data[1], data[2]);
674 674
675 if (data[0] > 2 || data[1] == 0 || data[2] == 0) { 675 if (data[0] > 2 || data[1] == 0 || data[2] == 0) {
@@ -713,9 +713,9 @@ static void ivtv_irq_dec_data_req(struct ivtv *itv)
713 struct ivtv_stream *s; 713 struct ivtv_stream *s;
714 714
715 /* YUV or MPG */ 715 /* YUV or MPG */
716 ivtv_api_get_data(&itv->dec_mbox, IVTV_MBOX_DMA, data);
717 716
718 if (test_bit(IVTV_F_I_DEC_YUV, &itv->i_flags)) { 717 if (test_bit(IVTV_F_I_DEC_YUV, &itv->i_flags)) {
718 ivtv_api_get_data(&itv->dec_mbox, IVTV_MBOX_DMA, 2, data);
719 itv->dma_data_req_size = 719 itv->dma_data_req_size =
720 1080 * ((itv->yuv_info.v4l2_src_h + 31) & ~31); 720 1080 * ((itv->yuv_info.v4l2_src_h + 31) & ~31);
721 itv->dma_data_req_offset = data[1]; 721 itv->dma_data_req_offset = data[1];
@@ -724,6 +724,7 @@ static void ivtv_irq_dec_data_req(struct ivtv *itv)
724 s = &itv->streams[IVTV_DEC_STREAM_TYPE_YUV]; 724 s = &itv->streams[IVTV_DEC_STREAM_TYPE_YUV];
725 } 725 }
726 else { 726 else {
727 ivtv_api_get_data(&itv->dec_mbox, IVTV_MBOX_DMA, 3, data);
727 itv->dma_data_req_size = min_t(u32, data[2], 0x10000); 728 itv->dma_data_req_size = min_t(u32, data[2], 0x10000);
728 itv->dma_data_req_offset = data[1]; 729 itv->dma_data_req_offset = data[1];
729 s = &itv->streams[IVTV_DEC_STREAM_TYPE_MPG]; 730 s = &itv->streams[IVTV_DEC_STREAM_TYPE_MPG];
@@ -940,9 +941,10 @@ irqreturn_t ivtv_irq_handler(int irq, void *dev_id)
940 ivtv_dma_enc_start(s); 941 ivtv_dma_enc_start(s);
941 break; 942 break;
942 } 943 }
943 if (i == IVTV_MAX_STREAMS && test_and_clear_bit(IVTV_F_I_UDMA_PENDING, &itv->i_flags)) { 944
945 if (i == IVTV_MAX_STREAMS &&
946 test_bit(IVTV_F_I_UDMA_PENDING, &itv->i_flags))
944 ivtv_udma_start(itv); 947 ivtv_udma_start(itv);
945 }
946 } 948 }
947 949
948 if ((combo & IVTV_IRQ_DMA) && !test_bit(IVTV_F_I_PIO, &itv->i_flags)) { 950 if ((combo & IVTV_IRQ_DMA) && !test_bit(IVTV_F_I_PIO, &itv->i_flags)) {
diff --git a/drivers/media/video/ivtv/ivtv-mailbox.c b/drivers/media/video/ivtv/ivtv-mailbox.c
index 1b5c0ac09a85..84577f6f41a2 100644
--- a/drivers/media/video/ivtv/ivtv-mailbox.c
+++ b/drivers/media/video/ivtv/ivtv-mailbox.c
@@ -369,10 +369,11 @@ int ivtv_vapi(struct ivtv *itv, int cmd, int args, ...)
369} 369}
370 370
371/* This one is for stuff that can't sleep.. irq handlers, etc.. */ 371/* This one is for stuff that can't sleep.. irq handlers, etc.. */
372void ivtv_api_get_data(struct ivtv_mailbox_data *mbdata, int mb, u32 data[]) 372void ivtv_api_get_data(struct ivtv_mailbox_data *mbdata, int mb,
373 int argc, u32 data[])
373{ 374{
375 volatile u32 __iomem *p = mbdata->mbox[mb].data;
374 int i; 376 int i;
375 377 for (i = 0; i < argc; i++, p++)
376 for (i = 0; i < CX2341X_MBOX_MAX_DATA; i++) 378 data[i] = readl(p);
377 data[i] = readl(&mbdata->mbox[mb].data[i]);
378} 379}
diff --git a/drivers/media/video/ivtv/ivtv-mailbox.h b/drivers/media/video/ivtv/ivtv-mailbox.h
index 6ef12091e3f3..8247662c928e 100644
--- a/drivers/media/video/ivtv/ivtv-mailbox.h
+++ b/drivers/media/video/ivtv/ivtv-mailbox.h
@@ -24,7 +24,8 @@
24#define IVTV_MBOX_DMA_END 8 24#define IVTV_MBOX_DMA_END 8
25#define IVTV_MBOX_DMA 9 25#define IVTV_MBOX_DMA 9
26 26
27void ivtv_api_get_data(struct ivtv_mailbox_data *mbox, int mb, u32 data[]); 27void ivtv_api_get_data(struct ivtv_mailbox_data *mbdata, int mb,
28 int argc, u32 data[]);
28int ivtv_api(struct ivtv *itv, int cmd, int args, u32 data[]); 29int ivtv_api(struct ivtv *itv, int cmd, int args, u32 data[]);
29int ivtv_vapi_result(struct ivtv *itv, u32 data[CX2341X_MBOX_MAX_DATA], int cmd, int args, ...); 30int ivtv_vapi_result(struct ivtv *itv, u32 data[CX2341X_MBOX_MAX_DATA], int cmd, int args, ...);
30int ivtv_vapi(struct ivtv *itv, int cmd, int args, ...); 31int ivtv_vapi(struct ivtv *itv, int cmd, int args, ...);
diff --git a/drivers/media/video/ivtv/ivtv-streams.c b/drivers/media/video/ivtv/ivtv-streams.c
index e12c6022373e..1f9387f6ca24 100644
--- a/drivers/media/video/ivtv/ivtv-streams.c
+++ b/drivers/media/video/ivtv/ivtv-streams.c
@@ -577,10 +577,14 @@ int ivtv_start_v4l2_encode_stream(struct ivtv_stream *s)
577 clear_bit(IVTV_F_I_EOS, &itv->i_flags); 577 clear_bit(IVTV_F_I_EOS, &itv->i_flags);
578 578
579 /* Initialize Digitizer for Capture */ 579 /* Initialize Digitizer for Capture */
580 /* Avoid tinny audio problem - ensure audio clocks are going */
581 v4l2_subdev_call(itv->sd_audio, audio, s_stream, 1);
582 /* Avoid unpredictable PCI bus hang - disable video clocks */
580 v4l2_subdev_call(itv->sd_video, video, s_stream, 0); 583 v4l2_subdev_call(itv->sd_video, video, s_stream, 0);
581 ivtv_msleep_timeout(300, 1); 584 ivtv_msleep_timeout(150, 1);
582 ivtv_vapi(itv, CX2341X_ENC_INITIALIZE_INPUT, 0); 585 ivtv_vapi(itv, CX2341X_ENC_INITIALIZE_INPUT, 0);
583 v4l2_subdev_call(itv->sd_video, video, s_stream, 1); 586 v4l2_subdev_call(itv->sd_video, video, s_stream, 1);
587 ivtv_msleep_timeout(150, 1);
584 } 588 }
585 589
586 /* begin_capture */ 590 /* begin_capture */
diff --git a/drivers/media/video/ivtv/ivtv-udma.c b/drivers/media/video/ivtv/ivtv-udma.c
index d07ad6c39024..1daf1dd65bf7 100644
--- a/drivers/media/video/ivtv/ivtv-udma.c
+++ b/drivers/media/video/ivtv/ivtv-udma.c
@@ -213,6 +213,7 @@ void ivtv_udma_start(struct ivtv *itv)
213 write_reg_sync(read_reg(IVTV_REG_DMAXFER) | 0x01, IVTV_REG_DMAXFER); 213 write_reg_sync(read_reg(IVTV_REG_DMAXFER) | 0x01, IVTV_REG_DMAXFER);
214 set_bit(IVTV_F_I_DMA, &itv->i_flags); 214 set_bit(IVTV_F_I_DMA, &itv->i_flags);
215 set_bit(IVTV_F_I_UDMA, &itv->i_flags); 215 set_bit(IVTV_F_I_UDMA, &itv->i_flags);
216 clear_bit(IVTV_F_I_UDMA_PENDING, &itv->i_flags);
216} 217}
217 218
218void ivtv_udma_prepare(struct ivtv *itv) 219void ivtv_udma_prepare(struct ivtv *itv)
diff --git a/drivers/media/video/mt9t112.c b/drivers/media/video/mt9t112.c
index fc4dd6045720..7438f8d775ba 100644
--- a/drivers/media/video/mt9t112.c
+++ b/drivers/media/video/mt9t112.c
@@ -514,7 +514,7 @@ static int mt9t112_init_pll(const struct i2c_client *client)
514 /* poll to verify out of standby. Must Poll this bit */ 514 /* poll to verify out of standby. Must Poll this bit */
515 for (i = 0; i < 100; i++) { 515 for (i = 0; i < 100; i++) {
516 mt9t112_reg_read(data, client, 0x0018); 516 mt9t112_reg_read(data, client, 0x0018);
517 if (0x4000 & data) 517 if (!(0x4000 & data))
518 break; 518 break;
519 519
520 mdelay(10); 520 mdelay(10);
diff --git a/drivers/media/video/mt9v022.c b/drivers/media/video/mt9v022.c
index 91df7ec91fb6..1a34d2993e94 100644
--- a/drivers/media/video/mt9v022.c
+++ b/drivers/media/video/mt9v022.c
@@ -257,19 +257,18 @@ static int mt9v022_set_bus_param(struct soc_camera_device *icd,
257static unsigned long mt9v022_query_bus_param(struct soc_camera_device *icd) 257static unsigned long mt9v022_query_bus_param(struct soc_camera_device *icd)
258{ 258{
259 struct soc_camera_link *icl = to_soc_camera_link(icd); 259 struct soc_camera_link *icl = to_soc_camera_link(icd);
260 unsigned int width_flag; 260 unsigned int flags = SOCAM_MASTER | SOCAM_SLAVE |
261 SOCAM_PCLK_SAMPLE_RISING | SOCAM_PCLK_SAMPLE_FALLING |
262 SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_HSYNC_ACTIVE_LOW |
263 SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_LOW |
264 SOCAM_DATA_ACTIVE_HIGH;
261 265
262 if (icl->query_bus_param) 266 if (icl->query_bus_param)
263 width_flag = icl->query_bus_param(icl) & 267 flags |= icl->query_bus_param(icl) & SOCAM_DATAWIDTH_MASK;
264 SOCAM_DATAWIDTH_MASK;
265 else 268 else
266 width_flag = SOCAM_DATAWIDTH_10; 269 flags |= SOCAM_DATAWIDTH_10;
267 270
268 return SOCAM_PCLK_SAMPLE_RISING | SOCAM_PCLK_SAMPLE_FALLING | 271 return soc_camera_apply_sensor_flags(icl, flags);
269 SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_HSYNC_ACTIVE_LOW |
270 SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_LOW |
271 SOCAM_DATA_ACTIVE_HIGH | SOCAM_MASTER | SOCAM_SLAVE |
272 width_flag;
273} 272}
274 273
275static int mt9v022_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) 274static int mt9v022_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
diff --git a/drivers/media/video/mxb.c b/drivers/media/video/mxb.c
index c1fc6dc776f5..9f01f14e4aa2 100644
--- a/drivers/media/video/mxb.c
+++ b/drivers/media/video/mxb.c
@@ -169,7 +169,11 @@ static struct saa7146_extension extension;
169static int mxb_probe(struct saa7146_dev *dev) 169static int mxb_probe(struct saa7146_dev *dev)
170{ 170{
171 struct mxb *mxb = NULL; 171 struct mxb *mxb = NULL;
172 int err;
172 173
174 err = saa7146_vv_devinit(dev);
175 if (err)
176 return err;
173 mxb = kzalloc(sizeof(struct mxb), GFP_KERNEL); 177 mxb = kzalloc(sizeof(struct mxb), GFP_KERNEL);
174 if (mxb == NULL) { 178 if (mxb == NULL) {
175 DEB_D(("not enough kernel memory.\n")); 179 DEB_D(("not enough kernel memory.\n"));
@@ -294,7 +298,7 @@ static int mxb_init_done(struct saa7146_dev* dev)
294 /* select tuner-output on saa7111a */ 298 /* select tuner-output on saa7111a */
295 i = 0; 299 i = 0;
296 saa7111a_call(mxb, video, s_routing, SAA7115_COMPOSITE0, 300 saa7111a_call(mxb, video, s_routing, SAA7115_COMPOSITE0,
297 SAA7111_FMT_CCIR | SAA7111_VBI_BYPASS, 0); 301 SAA7111_FMT_CCIR, 0);
298 302
299 /* select a tuner type */ 303 /* select a tuner type */
300 tun_setup.mode_mask = T_ANALOG_TV; 304 tun_setup.mode_mask = T_ANALOG_TV;
@@ -518,8 +522,8 @@ static int vidioc_s_input(struct file *file, void *fh, unsigned int input)
518 return err; 522 return err;
519 523
520 /* switch video in saa7111a */ 524 /* switch video in saa7111a */
521 if (saa7111a_call(mxb, video, s_routing, i, 0, 0)) 525 if (saa7111a_call(mxb, video, s_routing, i, SAA7111_FMT_CCIR, 0))
522 printk(KERN_ERR "VIDIOC_S_INPUT: could not address saa7111a #1.\n"); 526 printk(KERN_ERR "VIDIOC_S_INPUT: could not address saa7111a.\n");
523 527
524 /* switch the audio-source only if necessary */ 528 /* switch the audio-source only if necessary */
525 if (0 == mxb->cur_mute) 529 if (0 == mxb->cur_mute)
diff --git a/drivers/media/video/ov772x.c b/drivers/media/video/ov772x.c
index 3a45e945a528..7f8ece30c77b 100644
--- a/drivers/media/video/ov772x.c
+++ b/drivers/media/video/ov772x.c
@@ -547,7 +547,6 @@ static const struct v4l2_queryctrl ov772x_controls[] = {
547 }, 547 },
548}; 548};
549 549
550
551/* 550/*
552 * general function 551 * general function
553 */ 552 */
@@ -634,7 +633,12 @@ static unsigned long ov772x_query_bus_param(struct soc_camera_device *icd)
634 struct soc_camera_link *icl = to_soc_camera_link(icd); 633 struct soc_camera_link *icl = to_soc_camera_link(icd);
635 unsigned long flags = SOCAM_PCLK_SAMPLE_RISING | SOCAM_MASTER | 634 unsigned long flags = SOCAM_PCLK_SAMPLE_RISING | SOCAM_MASTER |
636 SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_HSYNC_ACTIVE_HIGH | 635 SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_HSYNC_ACTIVE_HIGH |
637 SOCAM_DATA_ACTIVE_HIGH | priv->info->buswidth; 636 SOCAM_DATA_ACTIVE_HIGH;
637
638 if (priv->info->flags & OV772X_FLAG_8BIT)
639 flags |= SOCAM_DATAWIDTH_8;
640 else
641 flags |= SOCAM_DATAWIDTH_10;
638 642
639 return soc_camera_apply_sensor_flags(icl, flags); 643 return soc_camera_apply_sensor_flags(icl, flags);
640} 644}
@@ -1040,15 +1044,6 @@ static int ov772x_video_probe(struct soc_camera_device *icd,
1040 return -ENODEV; 1044 return -ENODEV;
1041 1045
1042 /* 1046 /*
1043 * ov772x only use 8 or 10 bit bus width
1044 */
1045 if (SOCAM_DATAWIDTH_10 != priv->info->buswidth &&
1046 SOCAM_DATAWIDTH_8 != priv->info->buswidth) {
1047 dev_err(&client->dev, "bus width error\n");
1048 return -ENODEV;
1049 }
1050
1051 /*
1052 * check and show product ID and manufacturer ID 1047 * check and show product ID and manufacturer ID
1053 */ 1048 */
1054 pid = i2c_smbus_read_byte_data(client, PID); 1049 pid = i2c_smbus_read_byte_data(client, PID);
@@ -1130,7 +1125,6 @@ static int ov772x_probe(struct i2c_client *client,
1130 const struct i2c_device_id *did) 1125 const struct i2c_device_id *did)
1131{ 1126{
1132 struct ov772x_priv *priv; 1127 struct ov772x_priv *priv;
1133 struct ov772x_camera_info *info;
1134 struct soc_camera_device *icd = client->dev.platform_data; 1128 struct soc_camera_device *icd = client->dev.platform_data;
1135 struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); 1129 struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
1136 struct soc_camera_link *icl; 1130 struct soc_camera_link *icl;
@@ -1145,8 +1139,6 @@ static int ov772x_probe(struct i2c_client *client,
1145 if (!icl || !icl->priv) 1139 if (!icl || !icl->priv)
1146 return -EINVAL; 1140 return -EINVAL;
1147 1141
1148 info = icl->priv;
1149
1150 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { 1142 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
1151 dev_err(&adapter->dev, 1143 dev_err(&adapter->dev,
1152 "I2C-Adapter doesn't support " 1144 "I2C-Adapter doesn't support "
@@ -1158,7 +1150,7 @@ static int ov772x_probe(struct i2c_client *client,
1158 if (!priv) 1150 if (!priv)
1159 return -ENOMEM; 1151 return -ENOMEM;
1160 1152
1161 priv->info = info; 1153 priv->info = icl->priv;
1162 1154
1163 v4l2_i2c_subdev_init(&priv->subdev, client, &ov772x_subdev_ops); 1155 v4l2_i2c_subdev_init(&priv->subdev, client, &ov772x_subdev_ops);
1164 1156
diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h b/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h
index de5485f506b1..cb4057bb07a0 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h
+++ b/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h
@@ -233,8 +233,9 @@ struct pvr2_hdw {
233 int state_encoder_waitok; /* Encoder pre-wait done */ 233 int state_encoder_waitok; /* Encoder pre-wait done */
234 int state_encoder_runok; /* Encoder has run for >= .25 sec */ 234 int state_encoder_runok; /* Encoder has run for >= .25 sec */
235 int state_decoder_run; /* Decoder is running */ 235 int state_decoder_run; /* Decoder is running */
236 int state_decoder_ready; /* Decoder is stabilized & streamable */
236 int state_usbstream_run; /* FX2 is streaming */ 237 int state_usbstream_run; /* FX2 is streaming */
237 int state_decoder_quiescent; /* Decoder idle for > 50msec */ 238 int state_decoder_quiescent; /* Decoder idle for minimal interval */
238 int state_pipeline_config; /* Pipeline is configured */ 239 int state_pipeline_config; /* Pipeline is configured */
239 int state_pipeline_req; /* Somebody wants to stream */ 240 int state_pipeline_req; /* Somebody wants to stream */
240 int state_pipeline_pause; /* Pipeline must be paused */ 241 int state_pipeline_pause; /* Pipeline must be paused */
@@ -255,9 +256,16 @@ struct pvr2_hdw {
255 void (*state_func)(void *); 256 void (*state_func)(void *);
256 void *state_data; 257 void *state_data;
257 258
258 /* Timer for measuring decoder settling time */ 259 /* Timer for measuring required decoder settling time before we're
260 allowed to fire it up again. */
259 struct timer_list quiescent_timer; 261 struct timer_list quiescent_timer;
260 262
263 /* Timer for measuring decoder stabilization time, which is the
264 amount of time we need to let the decoder run before we can
265 trust its output (otherwise the encoder might see garbage and
266 then fail to start correctly). */
267 struct timer_list decoder_stabilization_timer;
268
261 /* Timer for measuring encoder pre-wait time */ 269 /* Timer for measuring encoder pre-wait time */
262 struct timer_list encoder_wait_timer; 270 struct timer_list encoder_wait_timer;
263 271
diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/drivers/media/video/pvrusb2/pvrusb2-hdw.c
index 1bbdab08fe0e..712b300f723f 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-hdw.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-hdw.c
@@ -48,11 +48,13 @@
48 before we are allowed to start it running. */ 48 before we are allowed to start it running. */
49#define TIME_MSEC_DECODER_WAIT 50 49#define TIME_MSEC_DECODER_WAIT 50
50 50
51/* This defines a minimum interval that the decoder must be allowed to run
52 before we can safely begin using its streaming output. */
53#define TIME_MSEC_DECODER_STABILIZATION_WAIT 300
54
51/* This defines a minimum interval that the encoder must remain quiet 55/* This defines a minimum interval that the encoder must remain quiet
52 before we are allowed to configure it. I had this originally set to 56 before we are allowed to configure it. */
53 50msec, but Martin Dauskardt <martin.dauskardt@gmx.de> reports that 57#define TIME_MSEC_ENCODER_WAIT 50
54 things work better when it's set to 100msec. */
55#define TIME_MSEC_ENCODER_WAIT 100
56 58
57/* This defines the minimum interval that the encoder must successfully run 59/* This defines the minimum interval that the encoder must successfully run
58 before we consider that the encoder has run at least once since its 60 before we consider that the encoder has run at least once since its
@@ -334,6 +336,7 @@ static int pvr2_hdw_get_eeprom_addr(struct pvr2_hdw *hdw);
334static void pvr2_hdw_internal_find_stdenum(struct pvr2_hdw *hdw); 336static void pvr2_hdw_internal_find_stdenum(struct pvr2_hdw *hdw);
335static void pvr2_hdw_internal_set_std_avail(struct pvr2_hdw *hdw); 337static void pvr2_hdw_internal_set_std_avail(struct pvr2_hdw *hdw);
336static void pvr2_hdw_quiescent_timeout(unsigned long); 338static void pvr2_hdw_quiescent_timeout(unsigned long);
339static void pvr2_hdw_decoder_stabilization_timeout(unsigned long);
337static void pvr2_hdw_encoder_wait_timeout(unsigned long); 340static void pvr2_hdw_encoder_wait_timeout(unsigned long);
338static void pvr2_hdw_encoder_run_timeout(unsigned long); 341static void pvr2_hdw_encoder_run_timeout(unsigned long);
339static int pvr2_issue_simple_cmd(struct pvr2_hdw *,u32); 342static int pvr2_issue_simple_cmd(struct pvr2_hdw *,u32);
@@ -1705,6 +1708,7 @@ static int pvr2_decoder_enable(struct pvr2_hdw *hdw,int enablefl)
1705 pvr2_trace(PVR2_TRACE_CHIPS, "subdev v4l2 stream=%s", 1708 pvr2_trace(PVR2_TRACE_CHIPS, "subdev v4l2 stream=%s",
1706 (enablefl ? "on" : "off")); 1709 (enablefl ? "on" : "off"));
1707 v4l2_device_call_all(&hdw->v4l2_dev, 0, video, s_stream, enablefl); 1710 v4l2_device_call_all(&hdw->v4l2_dev, 0, video, s_stream, enablefl);
1711 v4l2_device_call_all(&hdw->v4l2_dev, 0, audio, s_stream, enablefl);
1708 if (hdw->decoder_client_id) { 1712 if (hdw->decoder_client_id) {
1709 /* We get here if the encoder has been noticed. Otherwise 1713 /* We get here if the encoder has been noticed. Otherwise
1710 we'll issue a warning to the user (which should 1714 we'll issue a warning to the user (which should
@@ -2461,6 +2465,11 @@ struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf,
2461 hdw->quiescent_timer.data = (unsigned long)hdw; 2465 hdw->quiescent_timer.data = (unsigned long)hdw;
2462 hdw->quiescent_timer.function = pvr2_hdw_quiescent_timeout; 2466 hdw->quiescent_timer.function = pvr2_hdw_quiescent_timeout;
2463 2467
2468 init_timer(&hdw->decoder_stabilization_timer);
2469 hdw->decoder_stabilization_timer.data = (unsigned long)hdw;
2470 hdw->decoder_stabilization_timer.function =
2471 pvr2_hdw_decoder_stabilization_timeout;
2472
2464 init_timer(&hdw->encoder_wait_timer); 2473 init_timer(&hdw->encoder_wait_timer);
2465 hdw->encoder_wait_timer.data = (unsigned long)hdw; 2474 hdw->encoder_wait_timer.data = (unsigned long)hdw;
2466 hdw->encoder_wait_timer.function = pvr2_hdw_encoder_wait_timeout; 2475 hdw->encoder_wait_timer.function = pvr2_hdw_encoder_wait_timeout;
@@ -2674,6 +2683,7 @@ struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf,
2674 fail: 2683 fail:
2675 if (hdw) { 2684 if (hdw) {
2676 del_timer_sync(&hdw->quiescent_timer); 2685 del_timer_sync(&hdw->quiescent_timer);
2686 del_timer_sync(&hdw->decoder_stabilization_timer);
2677 del_timer_sync(&hdw->encoder_run_timer); 2687 del_timer_sync(&hdw->encoder_run_timer);
2678 del_timer_sync(&hdw->encoder_wait_timer); 2688 del_timer_sync(&hdw->encoder_wait_timer);
2679 if (hdw->workqueue) { 2689 if (hdw->workqueue) {
@@ -2741,6 +2751,7 @@ void pvr2_hdw_destroy(struct pvr2_hdw *hdw)
2741 hdw->workqueue = NULL; 2751 hdw->workqueue = NULL;
2742 } 2752 }
2743 del_timer_sync(&hdw->quiescent_timer); 2753 del_timer_sync(&hdw->quiescent_timer);
2754 del_timer_sync(&hdw->decoder_stabilization_timer);
2744 del_timer_sync(&hdw->encoder_run_timer); 2755 del_timer_sync(&hdw->encoder_run_timer);
2745 del_timer_sync(&hdw->encoder_wait_timer); 2756 del_timer_sync(&hdw->encoder_wait_timer);
2746 if (hdw->fw_buffer) { 2757 if (hdw->fw_buffer) {
@@ -4452,7 +4463,7 @@ static int state_check_enable_encoder_run(struct pvr2_hdw *hdw)
4452 4463
4453 switch (hdw->pathway_state) { 4464 switch (hdw->pathway_state) {
4454 case PVR2_PATHWAY_ANALOG: 4465 case PVR2_PATHWAY_ANALOG:
4455 if (hdw->state_decoder_run) { 4466 if (hdw->state_decoder_run && hdw->state_decoder_ready) {
4456 /* In analog mode, if the decoder is running, then 4467 /* In analog mode, if the decoder is running, then
4457 run the encoder. */ 4468 run the encoder. */
4458 return !0; 4469 return !0;
@@ -4519,6 +4530,17 @@ static void pvr2_hdw_quiescent_timeout(unsigned long data)
4519} 4530}
4520 4531
4521 4532
4533/* Timeout function for decoder stabilization timer. */
4534static void pvr2_hdw_decoder_stabilization_timeout(unsigned long data)
4535{
4536 struct pvr2_hdw *hdw = (struct pvr2_hdw *)data;
4537 hdw->state_decoder_ready = !0;
4538 trace_stbit("state_decoder_ready", hdw->state_decoder_ready);
4539 hdw->state_stale = !0;
4540 queue_work(hdw->workqueue, &hdw->workpoll);
4541}
4542
4543
4522/* Timeout function for encoder wait timer. */ 4544/* Timeout function for encoder wait timer. */
4523static void pvr2_hdw_encoder_wait_timeout(unsigned long data) 4545static void pvr2_hdw_encoder_wait_timeout(unsigned long data)
4524{ 4546{
@@ -4557,8 +4579,13 @@ static int state_eval_decoder_run(struct pvr2_hdw *hdw)
4557 } 4579 }
4558 hdw->state_decoder_quiescent = 0; 4580 hdw->state_decoder_quiescent = 0;
4559 hdw->state_decoder_run = 0; 4581 hdw->state_decoder_run = 0;
4560 /* paranoia - solve race if timer just completed */ 4582 /* paranoia - solve race if timer(s) just completed */
4561 del_timer_sync(&hdw->quiescent_timer); 4583 del_timer_sync(&hdw->quiescent_timer);
4584 /* Kill the stabilization timer, in case we're killing the
4585 encoder before the previous stabilization interval has
4586 been properly timed. */
4587 del_timer_sync(&hdw->decoder_stabilization_timer);
4588 hdw->state_decoder_ready = 0;
4562 } else { 4589 } else {
4563 if (!hdw->state_decoder_quiescent) { 4590 if (!hdw->state_decoder_quiescent) {
4564 if (!timer_pending(&hdw->quiescent_timer)) { 4591 if (!timer_pending(&hdw->quiescent_timer)) {
@@ -4596,10 +4623,21 @@ static int state_eval_decoder_run(struct pvr2_hdw *hdw)
4596 if (hdw->flag_decoder_missed) return 0; 4623 if (hdw->flag_decoder_missed) return 0;
4597 if (pvr2_decoder_enable(hdw,!0) < 0) return 0; 4624 if (pvr2_decoder_enable(hdw,!0) < 0) return 0;
4598 hdw->state_decoder_quiescent = 0; 4625 hdw->state_decoder_quiescent = 0;
4626 hdw->state_decoder_ready = 0;
4599 hdw->state_decoder_run = !0; 4627 hdw->state_decoder_run = !0;
4628 if (hdw->decoder_client_id == PVR2_CLIENT_ID_SAA7115) {
4629 hdw->decoder_stabilization_timer.expires =
4630 jiffies +
4631 (HZ * TIME_MSEC_DECODER_STABILIZATION_WAIT /
4632 1000);
4633 add_timer(&hdw->decoder_stabilization_timer);
4634 } else {
4635 hdw->state_decoder_ready = !0;
4636 }
4600 } 4637 }
4601 trace_stbit("state_decoder_quiescent",hdw->state_decoder_quiescent); 4638 trace_stbit("state_decoder_quiescent",hdw->state_decoder_quiescent);
4602 trace_stbit("state_decoder_run",hdw->state_decoder_run); 4639 trace_stbit("state_decoder_run",hdw->state_decoder_run);
4640 trace_stbit("state_decoder_ready", hdw->state_decoder_ready);
4603 return !0; 4641 return !0;
4604} 4642}
4605 4643
@@ -4797,7 +4835,8 @@ static unsigned int pvr2_hdw_report_unlocked(struct pvr2_hdw *hdw,int which,
4797 buf,acnt, 4835 buf,acnt,
4798 "worker:%s%s%s%s%s%s%s", 4836 "worker:%s%s%s%s%s%s%s",
4799 (hdw->state_decoder_run ? 4837 (hdw->state_decoder_run ?
4800 " <decode:run>" : 4838 (hdw->state_decoder_ready ?
4839 "<decode:run>" : " <decode:start>") :
4801 (hdw->state_decoder_quiescent ? 4840 (hdw->state_decoder_quiescent ?
4802 "" : " <decode:stop>")), 4841 "" : " <decode:stop>")),
4803 (hdw->state_decoder_quiescent ? 4842 (hdw->state_decoder_quiescent ?
diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw.h b/drivers/media/video/pvrusb2/pvrusb2-hdw.h
index 56e70eae20c1..51d3009ab57f 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-hdw.h
+++ b/drivers/media/video/pvrusb2/pvrusb2-hdw.h
@@ -306,6 +306,7 @@ struct pvr2_hdw_debug_info {
306 int state_encoder_ok; 306 int state_encoder_ok;
307 int state_encoder_run; 307 int state_encoder_run;
308 int state_decoder_run; 308 int state_decoder_run;
309 int state_decoder_ready;
309 int state_usbstream_run; 310 int state_usbstream_run;
310 int state_decoder_quiescent; 311 int state_decoder_quiescent;
311 int state_pipeline_config; 312 int state_pipeline_config;
diff --git a/drivers/media/video/pwc/pwc-ctrl.c b/drivers/media/video/pwc/pwc-ctrl.c
index 50b415e07eda..f7f7e04cf485 100644
--- a/drivers/media/video/pwc/pwc-ctrl.c
+++ b/drivers/media/video/pwc/pwc-ctrl.c
@@ -753,7 +753,7 @@ int pwc_set_shutter_speed(struct pwc_device *pdev, int mode, int value)
753 buf[0] = 0xff; /* fixed */ 753 buf[0] = 0xff; /* fixed */
754 754
755 ret = send_control_msg(pdev, 755 ret = send_control_msg(pdev,
756 SET_LUM_CTL, SHUTTER_MODE_FORMATTER, &buf, sizeof(buf)); 756 SET_LUM_CTL, SHUTTER_MODE_FORMATTER, &buf, 1);
757 757
758 if (!mode && ret >= 0) { 758 if (!mode && ret >= 0) {
759 if (value < 0) 759 if (value < 0)
diff --git a/drivers/media/video/pxa_camera.c b/drivers/media/video/pxa_camera.c
index 294f860ce2b0..322ac4eecf0a 100644
--- a/drivers/media/video/pxa_camera.c
+++ b/drivers/media/video/pxa_camera.c
@@ -898,18 +898,8 @@ static void recalculate_fifo_timeout(struct pxa_camera_dev *pcdev,
898 898
899static void pxa_camera_activate(struct pxa_camera_dev *pcdev) 899static void pxa_camera_activate(struct pxa_camera_dev *pcdev)
900{ 900{
901 struct pxacamera_platform_data *pdata = pcdev->pdata;
902 struct device *dev = pcdev->soc_host.v4l2_dev.dev;
903 u32 cicr4 = 0; 901 u32 cicr4 = 0;
904 902
905 dev_dbg(dev, "Registered platform device at %p data %p\n",
906 pcdev, pdata);
907
908 if (pdata && pdata->init) {
909 dev_dbg(dev, "%s: Init gpios\n", __func__);
910 pdata->init(dev);
911 }
912
913 /* disable all interrupts */ 903 /* disable all interrupts */
914 __raw_writel(0x3ff, pcdev->base + CICR0); 904 __raw_writel(0x3ff, pcdev->base + CICR0);
915 905
diff --git a/drivers/media/video/rj54n1cb0c.c b/drivers/media/video/rj54n1cb0c.c
index 805226e0d9c1..9277194cd821 100644
--- a/drivers/media/video/rj54n1cb0c.c
+++ b/drivers/media/video/rj54n1cb0c.c
@@ -165,7 +165,7 @@ struct rj54n1_reg_val {
165 u8 val; 165 u8 val;
166}; 166};
167 167
168const static struct rj54n1_reg_val bank_4[] = { 168static const struct rj54n1_reg_val bank_4[] = {
169 {0x417, 0}, 169 {0x417, 0},
170 {0x42c, 0}, 170 {0x42c, 0},
171 {0x42d, 0xf0}, 171 {0x42d, 0xf0},
@@ -186,7 +186,7 @@ const static struct rj54n1_reg_val bank_4[] = {
186 {0x4fe, 2}, 186 {0x4fe, 2},
187}; 187};
188 188
189const static struct rj54n1_reg_val bank_5[] = { 189static const struct rj54n1_reg_val bank_5[] = {
190 {0x514, 0}, 190 {0x514, 0},
191 {0x516, 0}, 191 {0x516, 0},
192 {0x518, 0}, 192 {0x518, 0},
@@ -207,7 +207,7 @@ const static struct rj54n1_reg_val bank_5[] = {
207 {0x5fe, 2}, 207 {0x5fe, 2},
208}; 208};
209 209
210const static struct rj54n1_reg_val bank_7[] = { 210static const struct rj54n1_reg_val bank_7[] = {
211 {0x70a, 0}, 211 {0x70a, 0},
212 {0x714, 0xff}, 212 {0x714, 0xff},
213 {0x715, 0xff}, 213 {0x715, 0xff},
@@ -215,7 +215,7 @@ const static struct rj54n1_reg_val bank_7[] = {
215 {0x7FE, 2}, 215 {0x7FE, 2},
216}; 216};
217 217
218const static struct rj54n1_reg_val bank_8[] = { 218static const struct rj54n1_reg_val bank_8[] = {
219 {0x800, 0x00}, 219 {0x800, 0x00},
220 {0x801, 0x01}, 220 {0x801, 0x01},
221 {0x802, 0x61}, 221 {0x802, 0x61},
@@ -403,12 +403,12 @@ const static struct rj54n1_reg_val bank_8[] = {
403 {0x8FE, 2}, 403 {0x8FE, 2},
404}; 404};
405 405
406const static struct rj54n1_reg_val bank_10[] = { 406static const struct rj54n1_reg_val bank_10[] = {
407 {0x10bf, 0x69} 407 {0x10bf, 0x69}
408}; 408};
409 409
410/* Clock dividers - these are default register values, divider = register + 1 */ 410/* Clock dividers - these are default register values, divider = register + 1 */
411const static struct rj54n1_clock_div clk_div = { 411static const struct rj54n1_clock_div clk_div = {
412 .ratio_tg = 3 /* default: 5 */, 412 .ratio_tg = 3 /* default: 5 */,
413 .ratio_t = 4 /* default: 1 */, 413 .ratio_t = 4 /* default: 1 */,
414 .ratio_r = 4 /* default: 0 */, 414 .ratio_r = 4 /* default: 0 */,
diff --git a/drivers/media/video/saa7115.c b/drivers/media/video/saa7115.c
index 44873a016c2c..c0a7f8a369f4 100644
--- a/drivers/media/video/saa7115.c
+++ b/drivers/media/video/saa7115.c
@@ -104,6 +104,10 @@ static int saa711x_has_reg(const int id, const u8 reg)
104 if (id == V4L2_IDENT_SAA7111) 104 if (id == V4L2_IDENT_SAA7111)
105 return reg < 0x20 && reg != 0x01 && reg != 0x0f && 105 return reg < 0x20 && reg != 0x01 && reg != 0x0f &&
106 (reg < 0x13 || reg > 0x19) && reg != 0x1d && reg != 0x1e; 106 (reg < 0x13 || reg > 0x19) && reg != 0x1d && reg != 0x1e;
107 if (id == V4L2_IDENT_SAA7111A)
108 return reg < 0x20 && reg != 0x01 && reg != 0x0f &&
109 reg != 0x14 && reg != 0x18 && reg != 0x19 &&
110 reg != 0x1d && reg != 0x1e;
107 111
108 /* common for saa7113/4/5/8 */ 112 /* common for saa7113/4/5/8 */
109 if (unlikely((reg >= 0x3b && reg <= 0x3f) || reg == 0x5c || reg == 0x5f || 113 if (unlikely((reg >= 0x3b && reg <= 0x3f) || reg == 0x5c || reg == 0x5f ||
@@ -954,8 +958,7 @@ static void saa711x_set_v4lstd(struct v4l2_subdev *sd, v4l2_std_id std)
954 011 NTSC N (3.58MHz) PAL M (3.58MHz) 958 011 NTSC N (3.58MHz) PAL M (3.58MHz)
955 100 reserved NTSC-Japan (3.58MHz) 959 100 reserved NTSC-Japan (3.58MHz)
956 */ 960 */
957 if (state->ident == V4L2_IDENT_SAA7111 || 961 if (state->ident <= V4L2_IDENT_SAA7113) {
958 state->ident == V4L2_IDENT_SAA7113) {
959 u8 reg = saa711x_read(sd, R_0E_CHROMA_CNTL_1) & 0x8f; 962 u8 reg = saa711x_read(sd, R_0E_CHROMA_CNTL_1) & 0x8f;
960 963
961 if (std == V4L2_STD_PAL_M) { 964 if (std == V4L2_STD_PAL_M) {
@@ -1232,22 +1235,19 @@ static int saa711x_s_routing(struct v4l2_subdev *sd,
1232 u32 input, u32 output, u32 config) 1235 u32 input, u32 output, u32 config)
1233{ 1236{
1234 struct saa711x_state *state = to_state(sd); 1237 struct saa711x_state *state = to_state(sd);
1235 u8 mask = (state->ident == V4L2_IDENT_SAA7111) ? 0xf8 : 0xf0; 1238 u8 mask = (state->ident <= V4L2_IDENT_SAA7111A) ? 0xf8 : 0xf0;
1236 1239
1237 v4l2_dbg(1, debug, sd, "decoder set input %d output %d\n", 1240 v4l2_dbg(1, debug, sd, "decoder set input %d output %d\n",
1238 input, output); 1241 input, output);
1239 1242
1240 /* saa7111/3 does not have these inputs */ 1243 /* saa7111/3 does not have these inputs */
1241 if ((state->ident == V4L2_IDENT_SAA7113 || 1244 if (state->ident <= V4L2_IDENT_SAA7113 &&
1242 state->ident == V4L2_IDENT_SAA7111) &&
1243 (input == SAA7115_COMPOSITE4 || 1245 (input == SAA7115_COMPOSITE4 ||
1244 input == SAA7115_COMPOSITE5)) { 1246 input == SAA7115_COMPOSITE5)) {
1245 return -EINVAL; 1247 return -EINVAL;
1246 } 1248 }
1247 if (input > SAA7115_SVIDEO3) 1249 if (input > SAA7115_SVIDEO3)
1248 return -EINVAL; 1250 return -EINVAL;
1249 if (output > SAA7115_IPORT_ON)
1250 return -EINVAL;
1251 if (state->input == input && state->output == output) 1251 if (state->input == input && state->output == output)
1252 return 0; 1252 return 0;
1253 v4l2_dbg(1, debug, sd, "now setting %s input %s output\n", 1253 v4l2_dbg(1, debug, sd, "now setting %s input %s output\n",
@@ -1256,7 +1256,7 @@ static int saa711x_s_routing(struct v4l2_subdev *sd,
1256 state->input = input; 1256 state->input = input;
1257 1257
1258 /* saa7111 has slightly different input numbering */ 1258 /* saa7111 has slightly different input numbering */
1259 if (state->ident == V4L2_IDENT_SAA7111) { 1259 if (state->ident <= V4L2_IDENT_SAA7111A) {
1260 if (input >= SAA7115_COMPOSITE4) 1260 if (input >= SAA7115_COMPOSITE4)
1261 input -= 2; 1261 input -= 2;
1262 /* saa7111 specific */ 1262 /* saa7111 specific */
@@ -1292,7 +1292,7 @@ static int saa711x_s_gpio(struct v4l2_subdev *sd, u32 val)
1292{ 1292{
1293 struct saa711x_state *state = to_state(sd); 1293 struct saa711x_state *state = to_state(sd);
1294 1294
1295 if (state->ident != V4L2_IDENT_SAA7111) 1295 if (state->ident > V4L2_IDENT_SAA7111A)
1296 return -EINVAL; 1296 return -EINVAL;
1297 saa711x_write(sd, 0x11, (saa711x_read(sd, 0x11) & 0x7f) | 1297 saa711x_write(sd, 0x11, (saa711x_read(sd, 0x11) & 0x7f) |
1298 (val ? 0x80 : 0)); 1298 (val ? 0x80 : 0));
@@ -1596,6 +1596,10 @@ static int saa711x_probe(struct i2c_client *client,
1596 switch (chip_id) { 1596 switch (chip_id) {
1597 case '1': 1597 case '1':
1598 state->ident = V4L2_IDENT_SAA7111; 1598 state->ident = V4L2_IDENT_SAA7111;
1599 if (saa711x_read(sd, R_00_CHIP_VERSION) & 0xf0) {
1600 v4l_info(client, "saa7111a variant found\n");
1601 state->ident = V4L2_IDENT_SAA7111A;
1602 }
1599 break; 1603 break;
1600 case '3': 1604 case '3':
1601 state->ident = V4L2_IDENT_SAA7113; 1605 state->ident = V4L2_IDENT_SAA7113;
@@ -1612,7 +1616,7 @@ static int saa711x_probe(struct i2c_client *client,
1612 default: 1616 default:
1613 state->ident = V4L2_IDENT_SAA7111; 1617 state->ident = V4L2_IDENT_SAA7111;
1614 v4l2_info(sd, "WARNING: Chip is not known - Falling back to saa7111\n"); 1618 v4l2_info(sd, "WARNING: Chip is not known - Falling back to saa7111\n");
1615 1619 break;
1616 } 1620 }
1617 1621
1618 state->audclk_freq = 48000; 1622 state->audclk_freq = 48000;
@@ -1623,6 +1627,7 @@ static int saa711x_probe(struct i2c_client *client,
1623 state->crystal_freq = SAA7115_FREQ_24_576_MHZ; 1627 state->crystal_freq = SAA7115_FREQ_24_576_MHZ;
1624 switch (state->ident) { 1628 switch (state->ident) {
1625 case V4L2_IDENT_SAA7111: 1629 case V4L2_IDENT_SAA7111:
1630 case V4L2_IDENT_SAA7111A:
1626 saa711x_writeregs(sd, saa7111_init); 1631 saa711x_writeregs(sd, saa7111_init);
1627 break; 1632 break;
1628 case V4L2_IDENT_SAA7113: 1633 case V4L2_IDENT_SAA7113:
@@ -1632,7 +1637,7 @@ static int saa711x_probe(struct i2c_client *client,
1632 state->crystal_freq = SAA7115_FREQ_32_11_MHZ; 1637 state->crystal_freq = SAA7115_FREQ_32_11_MHZ;
1633 saa711x_writeregs(sd, saa7115_init_auto_input); 1638 saa711x_writeregs(sd, saa7115_init_auto_input);
1634 } 1639 }
1635 if (state->ident != V4L2_IDENT_SAA7111) 1640 if (state->ident > V4L2_IDENT_SAA7111A)
1636 saa711x_writeregs(sd, saa7115_init_misc); 1641 saa711x_writeregs(sd, saa7115_init_misc);
1637 saa711x_set_v4lstd(sd, V4L2_STD_NTSC); 1642 saa711x_set_v4lstd(sd, V4L2_STD_NTSC);
1638 1643
diff --git a/drivers/media/video/saa7127.c b/drivers/media/video/saa7127.c
index 2fe7a701b954..250ef84cf5ca 100644
--- a/drivers/media/video/saa7127.c
+++ b/drivers/media/video/saa7127.c
@@ -181,7 +181,7 @@ static const struct i2c_reg_value saa7127_init_config_common[] = {
181#define SAA7127_60HZ_DAC_CONTROL 0x15 181#define SAA7127_60HZ_DAC_CONTROL 0x15
182static const struct i2c_reg_value saa7127_init_config_60hz[] = { 182static const struct i2c_reg_value saa7127_init_config_60hz[] = {
183 { SAA7127_REG_BURST_START, 0x19 }, 183 { SAA7127_REG_BURST_START, 0x19 },
184 /* BURST_END is also used as a chip ID in saa7127_detect_client */ 184 /* BURST_END is also used as a chip ID in saa7127_probe */
185 { SAA7127_REG_BURST_END, 0x1d }, 185 { SAA7127_REG_BURST_END, 0x1d },
186 { SAA7127_REG_CHROMA_PHASE, 0xa3 }, 186 { SAA7127_REG_CHROMA_PHASE, 0xa3 },
187 { SAA7127_REG_GAINU, 0x98 }, 187 { SAA7127_REG_GAINU, 0x98 },
@@ -200,10 +200,10 @@ static const struct i2c_reg_value saa7127_init_config_60hz[] = {
200 { 0, 0 } 200 { 0, 0 }
201}; 201};
202 202
203#define SAA7127_50HZ_DAC_CONTROL 0x02 203#define SAA7127_50HZ_PAL_DAC_CONTROL 0x02
204static struct i2c_reg_value saa7127_init_config_50hz[] = { 204static struct i2c_reg_value saa7127_init_config_50hz_pal[] = {
205 { SAA7127_REG_BURST_START, 0x21 }, 205 { SAA7127_REG_BURST_START, 0x21 },
206 /* BURST_END is also used as a chip ID in saa7127_detect_client */ 206 /* BURST_END is also used as a chip ID in saa7127_probe */
207 { SAA7127_REG_BURST_END, 0x1d }, 207 { SAA7127_REG_BURST_END, 0x1d },
208 { SAA7127_REG_CHROMA_PHASE, 0x3f }, 208 { SAA7127_REG_CHROMA_PHASE, 0x3f },
209 { SAA7127_REG_GAINU, 0x7d }, 209 { SAA7127_REG_GAINU, 0x7d },
@@ -222,6 +222,28 @@ static struct i2c_reg_value saa7127_init_config_50hz[] = {
222 { 0, 0 } 222 { 0, 0 }
223}; 223};
224 224
225#define SAA7127_50HZ_SECAM_DAC_CONTROL 0x08
226static struct i2c_reg_value saa7127_init_config_50hz_secam[] = {
227 { SAA7127_REG_BURST_START, 0x21 },
228 /* BURST_END is also used as a chip ID in saa7127_probe */
229 { SAA7127_REG_BURST_END, 0x1d },
230 { SAA7127_REG_CHROMA_PHASE, 0x3f },
231 { SAA7127_REG_GAINU, 0x6a },
232 { SAA7127_REG_GAINV, 0x81 },
233 { SAA7127_REG_BLACK_LEVEL, 0x33 },
234 { SAA7127_REG_BLANKING_LEVEL, 0x35 },
235 { SAA7127_REG_VBI_BLANKING, 0x35 },
236 { SAA7127_REG_DAC_CONTROL, 0x08 },
237 { SAA7127_REG_BURST_AMP, 0x2f },
238 { SAA7127_REG_SUBC3, 0xb2 },
239 { SAA7127_REG_SUBC2, 0x3b },
240 { SAA7127_REG_SUBC1, 0xa3 },
241 { SAA7127_REG_SUBC0, 0x28 },
242 { SAA7127_REG_MULTI, 0x90 },
243 { SAA7127_REG_CLOSED_CAPTION, 0x00 },
244 { 0, 0 }
245};
246
225/* 247/*
226 ********************************************************************** 248 **********************************************************************
227 * 249 *
@@ -463,10 +485,21 @@ static int saa7127_set_std(struct v4l2_subdev *sd, v4l2_std_id std)
463 v4l2_dbg(1, debug, sd, "Selecting 60 Hz video Standard\n"); 485 v4l2_dbg(1, debug, sd, "Selecting 60 Hz video Standard\n");
464 inittab = saa7127_init_config_60hz; 486 inittab = saa7127_init_config_60hz;
465 state->reg_61 = SAA7127_60HZ_DAC_CONTROL; 487 state->reg_61 = SAA7127_60HZ_DAC_CONTROL;
488
489 } else if (state->ident == V4L2_IDENT_SAA7129 &&
490 (std & V4L2_STD_SECAM) &&
491 !(std & (V4L2_STD_625_50 & ~V4L2_STD_SECAM))) {
492
493 /* If and only if SECAM, with a SAA712[89] */
494 v4l2_dbg(1, debug, sd,
495 "Selecting 50 Hz SECAM video Standard\n");
496 inittab = saa7127_init_config_50hz_secam;
497 state->reg_61 = SAA7127_50HZ_SECAM_DAC_CONTROL;
498
466 } else { 499 } else {
467 v4l2_dbg(1, debug, sd, "Selecting 50 Hz video Standard\n"); 500 v4l2_dbg(1, debug, sd, "Selecting 50 Hz PAL video Standard\n");
468 inittab = saa7127_init_config_50hz; 501 inittab = saa7127_init_config_50hz_pal;
469 state->reg_61 = SAA7127_50HZ_DAC_CONTROL; 502 state->reg_61 = SAA7127_50HZ_PAL_DAC_CONTROL;
470 } 503 }
471 504
472 /* Write Table */ 505 /* Write Table */
diff --git a/drivers/media/video/saa7134/saa7134-cards.c b/drivers/media/video/saa7134/saa7134-cards.c
index 03f572708b85..297833fb3b4a 100644
--- a/drivers/media/video/saa7134/saa7134-cards.c
+++ b/drivers/media/video/saa7134/saa7134-cards.c
@@ -4160,7 +4160,7 @@ struct saa7134_board saa7134_boards[] = {
4160 .amux = LINE2, 4160 .amux = LINE2,
4161 }, 4161 },
4162 }, 4162 },
4163 [SAA7134_BOARD_BEHOLD_505RDS] = { 4163 [SAA7134_BOARD_BEHOLD_505RDS_MK5] = {
4164 /* Beholder Intl. Ltd. 2008 */ 4164 /* Beholder Intl. Ltd. 2008 */
4165 /*Dmitry Belimov <d.belimov@gmail.com> */ 4165 /*Dmitry Belimov <d.belimov@gmail.com> */
4166 .name = "Beholder BeholdTV 505 RDS", 4166 .name = "Beholder BeholdTV 505 RDS",
@@ -5320,6 +5320,41 @@ struct saa7134_board saa7134_boards[] = {
5320 .vmux = 8, 5320 .vmux = 8,
5321 } }, 5321 } },
5322 }, 5322 },
5323 [SAA7134_BOARD_BEHOLD_505RDS_MK3] = {
5324 /* Beholder Intl. Ltd. 2008 */
5325 /*Dmitry Belimov <d.belimov@gmail.com> */
5326 .name = "Beholder BeholdTV 505 RDS",
5327 .audio_clock = 0x00200000,
5328 .tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
5329 .radio_type = UNSET,
5330 .tuner_addr = ADDR_UNSET,
5331 .radio_addr = ADDR_UNSET,
5332 .rds_addr = 0x10,
5333 .tda9887_conf = TDA9887_PRESENT,
5334 .gpiomask = 0x00008000,
5335 .inputs = {{
5336 .name = name_tv,
5337 .vmux = 3,
5338 .amux = LINE2,
5339 .tv = 1,
5340 }, {
5341 .name = name_comp1,
5342 .vmux = 1,
5343 .amux = LINE1,
5344 }, {
5345 .name = name_svideo,
5346 .vmux = 8,
5347 .amux = LINE1,
5348 } },
5349 .mute = {
5350 .name = name_mute,
5351 .amux = LINE1,
5352 },
5353 .radio = {
5354 .name = name_radio,
5355 .amux = LINE2,
5356 },
5357 },
5323 5358
5324}; 5359};
5325 5360
@@ -6235,7 +6270,13 @@ struct pci_device_id saa7134_pci_tbl[] = {
6235 .device = PCI_DEVICE_ID_PHILIPS_SAA7130, 6270 .device = PCI_DEVICE_ID_PHILIPS_SAA7130,
6236 .subvendor = 0x0000, 6271 .subvendor = 0x0000,
6237 .subdevice = 0x505B, 6272 .subdevice = 0x505B,
6238 .driver_data = SAA7134_BOARD_BEHOLD_505RDS, 6273 .driver_data = SAA7134_BOARD_BEHOLD_505RDS_MK5,
6274 }, {
6275 .vendor = PCI_VENDOR_ID_PHILIPS,
6276 .device = PCI_DEVICE_ID_PHILIPS_SAA7130,
6277 .subvendor = 0x0000,
6278 .subdevice = 0x5051,
6279 .driver_data = SAA7134_BOARD_BEHOLD_505RDS_MK3,
6239 },{ 6280 },{
6240 .vendor = PCI_VENDOR_ID_PHILIPS, 6281 .vendor = PCI_VENDOR_ID_PHILIPS,
6241 .device = PCI_DEVICE_ID_PHILIPS_SAA7130, 6282 .device = PCI_DEVICE_ID_PHILIPS_SAA7130,
@@ -6792,7 +6833,8 @@ int saa7134_board_init1(struct saa7134_dev *dev)
6792 case SAA7134_BOARD_BEHOLD_407FM: 6833 case SAA7134_BOARD_BEHOLD_407FM:
6793 case SAA7134_BOARD_BEHOLD_409: 6834 case SAA7134_BOARD_BEHOLD_409:
6794 case SAA7134_BOARD_BEHOLD_505FM: 6835 case SAA7134_BOARD_BEHOLD_505FM:
6795 case SAA7134_BOARD_BEHOLD_505RDS: 6836 case SAA7134_BOARD_BEHOLD_505RDS_MK5:
6837 case SAA7134_BOARD_BEHOLD_505RDS_MK3:
6796 case SAA7134_BOARD_BEHOLD_507_9FM: 6838 case SAA7134_BOARD_BEHOLD_507_9FM:
6797 case SAA7134_BOARD_BEHOLD_507RDS_MK3: 6839 case SAA7134_BOARD_BEHOLD_507RDS_MK3:
6798 case SAA7134_BOARD_BEHOLD_507RDS_MK5: 6840 case SAA7134_BOARD_BEHOLD_507RDS_MK5:
@@ -6953,8 +6995,8 @@ int saa7134_board_init1(struct saa7134_dev *dev)
6953 break; 6995 break;
6954 case SAA7134_BOARD_VIDEOMATE_S350: 6996 case SAA7134_BOARD_VIDEOMATE_S350:
6955 dev->has_remote = SAA7134_REMOTE_GPIO; 6997 dev->has_remote = SAA7134_REMOTE_GPIO;
6956 saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, 0x00008000, 0x00008000); 6998 saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, 0x0000C000, 0x0000C000);
6957 saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0x00008000, 0x00008000); 6999 saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0x0000C000, 0x0000C000);
6958 break; 7000 break;
6959 } 7001 }
6960 return 0; 7002 return 0;
diff --git a/drivers/media/video/saa7134/saa7134-input.c b/drivers/media/video/saa7134/saa7134-input.c
index f8e985989ca0..9499000f66b6 100644
--- a/drivers/media/video/saa7134/saa7134-input.c
+++ b/drivers/media/video/saa7134/saa7134-input.c
@@ -460,7 +460,7 @@ int saa7134_input_init1(struct saa7134_dev *dev)
460 int polling = 0; 460 int polling = 0;
461 int rc5_gpio = 0; 461 int rc5_gpio = 0;
462 int nec_gpio = 0; 462 int nec_gpio = 0;
463 int ir_type = IR_TYPE_OTHER; 463 u64 ir_type = IR_TYPE_OTHER;
464 int err; 464 int err;
465 465
466 if (dev->has_remote != SAA7134_REMOTE_GPIO) 466 if (dev->has_remote != SAA7134_REMOTE_GPIO)
@@ -568,7 +568,8 @@ int saa7134_input_init1(struct saa7134_dev *dev)
568 case SAA7134_BOARD_BEHOLD_407FM: 568 case SAA7134_BOARD_BEHOLD_407FM:
569 case SAA7134_BOARD_BEHOLD_409: 569 case SAA7134_BOARD_BEHOLD_409:
570 case SAA7134_BOARD_BEHOLD_505FM: 570 case SAA7134_BOARD_BEHOLD_505FM:
571 case SAA7134_BOARD_BEHOLD_505RDS: 571 case SAA7134_BOARD_BEHOLD_505RDS_MK5:
572 case SAA7134_BOARD_BEHOLD_505RDS_MK3:
572 case SAA7134_BOARD_BEHOLD_507_9FM: 573 case SAA7134_BOARD_BEHOLD_507_9FM:
573 case SAA7134_BOARD_BEHOLD_507RDS_MK3: 574 case SAA7134_BOARD_BEHOLD_507RDS_MK3:
574 case SAA7134_BOARD_BEHOLD_507RDS_MK5: 575 case SAA7134_BOARD_BEHOLD_507RDS_MK5:
@@ -728,7 +729,7 @@ int saa7134_input_init1(struct saa7134_dev *dev)
728 dev->remote = ir; 729 dev->remote = ir;
729 saa7134_ir_start(dev, ir); 730 saa7134_ir_start(dev, ir);
730 731
731 err = ir_input_register(ir->dev, ir_codes); 732 err = ir_input_register(ir->dev, ir_codes, NULL);
732 if (err) 733 if (err)
733 goto err_out_stop; 734 goto err_out_stop;
734 735
diff --git a/drivers/media/video/saa7134/saa7134-video.c b/drivers/media/video/saa7134/saa7134-video.c
index cb732640ac4a..31138d3e51bb 100644
--- a/drivers/media/video/saa7134/saa7134-video.c
+++ b/drivers/media/video/saa7134/saa7134-video.c
@@ -205,7 +205,7 @@ static struct saa7134_format formats[] = {
205 205
206#define NORM_525_60 \ 206#define NORM_525_60 \
207 .h_start = 0, \ 207 .h_start = 0, \
208 .h_stop = 703, \ 208 .h_stop = 719, \
209 .video_v_start = 23, \ 209 .video_v_start = 23, \
210 .video_v_stop = 262, \ 210 .video_v_stop = 262, \
211 .vbi_v_start_0 = 10, \ 211 .vbi_v_start_0 = 10, \
diff --git a/drivers/media/video/saa7134/saa7134.h b/drivers/media/video/saa7134/saa7134.h
index 53b7e0b8a2fb..bf130967ed17 100644
--- a/drivers/media/video/saa7134/saa7134.h
+++ b/drivers/media/video/saa7134/saa7134.h
@@ -282,7 +282,7 @@ struct saa7134_format {
282#define SAA7134_BOARD_HAUPPAUGE_HVR1120 156 282#define SAA7134_BOARD_HAUPPAUGE_HVR1120 156
283#define SAA7134_BOARD_AVERMEDIA_STUDIO_507UA 157 283#define SAA7134_BOARD_AVERMEDIA_STUDIO_507UA 157
284#define SAA7134_BOARD_AVERMEDIA_CARDBUS_501 158 284#define SAA7134_BOARD_AVERMEDIA_CARDBUS_501 158
285#define SAA7134_BOARD_BEHOLD_505RDS 159 285#define SAA7134_BOARD_BEHOLD_505RDS_MK5 159
286#define SAA7134_BOARD_BEHOLD_507RDS_MK3 160 286#define SAA7134_BOARD_BEHOLD_507RDS_MK3 160
287#define SAA7134_BOARD_BEHOLD_507RDS_MK5 161 287#define SAA7134_BOARD_BEHOLD_507RDS_MK5 161
288#define SAA7134_BOARD_BEHOLD_607FM_MK5 162 288#define SAA7134_BOARD_BEHOLD_607FM_MK5 162
@@ -299,6 +299,7 @@ struct saa7134_format {
299#define SAA7134_BOARD_ZOLID_HYBRID_PCI 173 299#define SAA7134_BOARD_ZOLID_HYBRID_PCI 173
300#define SAA7134_BOARD_ASUS_EUROPA_HYBRID 174 300#define SAA7134_BOARD_ASUS_EUROPA_HYBRID 174
301#define SAA7134_BOARD_LEADTEK_WINFAST_DTV1000S 175 301#define SAA7134_BOARD_LEADTEK_WINFAST_DTV1000S 175
302#define SAA7134_BOARD_BEHOLD_505RDS_MK3 176
302 303
303#define SAA7134_MAXBOARDS 32 304#define SAA7134_MAXBOARDS 32
304#define SAA7134_INPUT_MAX 8 305#define SAA7134_INPUT_MAX 8
diff --git a/drivers/media/video/saa7164/saa7164-api.c b/drivers/media/video/saa7164/saa7164-api.c
index 6f094a96ac81..1d487c150340 100644
--- a/drivers/media/video/saa7164/saa7164-api.c
+++ b/drivers/media/video/saa7164/saa7164-api.c
@@ -523,7 +523,7 @@ int saa7164_api_i2c_write(struct saa7164_i2c *bus, u8 addr, u32 datalen,
523 } 523 }
524 524
525 reglen = saa7164_i2caddr_to_reglen(bus, addr); 525 reglen = saa7164_i2caddr_to_reglen(bus, addr);
526 if (unitid < 0) { 526 if (reglen < 0) {
527 printk(KERN_ERR 527 printk(KERN_ERR
528 "%s() error, cannot translate regaddr to reglen\n", 528 "%s() error, cannot translate regaddr to reglen\n",
529 __func__); 529 __func__);
diff --git a/drivers/media/video/sh_mobile_ceu_camera.c b/drivers/media/video/sh_mobile_ceu_camera.c
index f09c7140d6b2..fb88c63188f3 100644
--- a/drivers/media/video/sh_mobile_ceu_camera.c
+++ b/drivers/media/video/sh_mobile_ceu_camera.c
@@ -1748,6 +1748,22 @@ static void sh_mobile_ceu_init_videobuf(struct videobuf_queue *q,
1748 icd); 1748 icd);
1749} 1749}
1750 1750
1751static int sh_mobile_ceu_get_parm(struct soc_camera_device *icd,
1752 struct v4l2_streamparm *parm)
1753{
1754 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1755
1756 return v4l2_subdev_call(sd, video, g_parm, parm);
1757}
1758
1759static int sh_mobile_ceu_set_parm(struct soc_camera_device *icd,
1760 struct v4l2_streamparm *parm)
1761{
1762 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1763
1764 return v4l2_subdev_call(sd, video, s_parm, parm);
1765}
1766
1751static int sh_mobile_ceu_get_ctrl(struct soc_camera_device *icd, 1767static int sh_mobile_ceu_get_ctrl(struct soc_camera_device *icd,
1752 struct v4l2_control *ctrl) 1768 struct v4l2_control *ctrl)
1753{ 1769{
@@ -1808,6 +1824,8 @@ static struct soc_camera_host_ops sh_mobile_ceu_host_ops = {
1808 .try_fmt = sh_mobile_ceu_try_fmt, 1824 .try_fmt = sh_mobile_ceu_try_fmt,
1809 .set_ctrl = sh_mobile_ceu_set_ctrl, 1825 .set_ctrl = sh_mobile_ceu_set_ctrl,
1810 .get_ctrl = sh_mobile_ceu_get_ctrl, 1826 .get_ctrl = sh_mobile_ceu_get_ctrl,
1827 .set_parm = sh_mobile_ceu_set_parm,
1828 .get_parm = sh_mobile_ceu_get_parm,
1811 .reqbufs = sh_mobile_ceu_reqbufs, 1829 .reqbufs = sh_mobile_ceu_reqbufs,
1812 .poll = sh_mobile_ceu_poll, 1830 .poll = sh_mobile_ceu_poll,
1813 .querycap = sh_mobile_ceu_querycap, 1831 .querycap = sh_mobile_ceu_querycap,
diff --git a/drivers/media/video/sn9c102/Kconfig b/drivers/media/video/sn9c102/Kconfig
index f71f272776de..6ebaf2940d06 100644
--- a/drivers/media/video/sn9c102/Kconfig
+++ b/drivers/media/video/sn9c102/Kconfig
@@ -1,7 +1,10 @@
1config USB_SN9C102 1config USB_SN9C102
2 tristate "USB SN9C1xx PC Camera Controller support" 2 tristate "USB SN9C1xx PC Camera Controller support (DEPRECATED)"
3 depends on VIDEO_V4L2 3 depends on VIDEO_V4L2
4 ---help--- 4 ---help---
5 This driver is DEPRECATED please use the gspca sonixb and
6 sonixj modules instead.
7
5 Say Y here if you want support for cameras based on SONiX SN9C101, 8 Say Y here if you want support for cameras based on SONiX SN9C101,
6 SN9C102, SN9C103, SN9C105 and SN9C120 PC Camera Controllers. 9 SN9C102, SN9C103, SN9C105 and SN9C120 PC Camera Controllers.
7 10
diff --git a/drivers/media/video/sn9c102/sn9c102_devtable.h b/drivers/media/video/sn9c102/sn9c102_devtable.h
index 36ee43a9ee95..cc40d6ba9f22 100644
--- a/drivers/media/video/sn9c102/sn9c102_devtable.h
+++ b/drivers/media/video/sn9c102/sn9c102_devtable.h
@@ -45,20 +45,24 @@ static const struct usb_device_id sn9c102_id_table[] = {
45 { SN9C102_USB_DEVICE(0x0c45, 0x6005, BRIDGE_SN9C102), }, 45 { SN9C102_USB_DEVICE(0x0c45, 0x6005, BRIDGE_SN9C102), },
46#endif 46#endif
47 { SN9C102_USB_DEVICE(0x0c45, 0x6007, BRIDGE_SN9C102), }, 47 { SN9C102_USB_DEVICE(0x0c45, 0x6007, BRIDGE_SN9C102), },
48#if !defined CONFIG_USB_GSPCA && !defined CONFIG_USB_GSPCA_MODULE
48 { SN9C102_USB_DEVICE(0x0c45, 0x6009, BRIDGE_SN9C102), }, 49 { SN9C102_USB_DEVICE(0x0c45, 0x6009, BRIDGE_SN9C102), },
49 { SN9C102_USB_DEVICE(0x0c45, 0x600d, BRIDGE_SN9C102), }, 50 { SN9C102_USB_DEVICE(0x0c45, 0x600d, BRIDGE_SN9C102), },
50/* { SN9C102_USB_DEVICE(0x0c45, 0x6011, BRIDGE_SN9C102), }, OV6650 */ 51/* { SN9C102_USB_DEVICE(0x0c45, 0x6011, BRIDGE_SN9C102), }, OV6650 */
52#endif
51 { SN9C102_USB_DEVICE(0x0c45, 0x6019, BRIDGE_SN9C102), }, 53 { SN9C102_USB_DEVICE(0x0c45, 0x6019, BRIDGE_SN9C102), },
52 { SN9C102_USB_DEVICE(0x0c45, 0x6024, BRIDGE_SN9C102), }, 54 { SN9C102_USB_DEVICE(0x0c45, 0x6024, BRIDGE_SN9C102), },
53 { SN9C102_USB_DEVICE(0x0c45, 0x6025, BRIDGE_SN9C102), }, 55 { SN9C102_USB_DEVICE(0x0c45, 0x6025, BRIDGE_SN9C102), },
56#if !defined CONFIG_USB_GSPCA && !defined CONFIG_USB_GSPCA_MODULE
54 { SN9C102_USB_DEVICE(0x0c45, 0x6028, BRIDGE_SN9C102), }, 57 { SN9C102_USB_DEVICE(0x0c45, 0x6028, BRIDGE_SN9C102), },
55 { SN9C102_USB_DEVICE(0x0c45, 0x6029, BRIDGE_SN9C102), }, 58 { SN9C102_USB_DEVICE(0x0c45, 0x6029, BRIDGE_SN9C102), },
59#endif
56 { SN9C102_USB_DEVICE(0x0c45, 0x602a, BRIDGE_SN9C102), }, 60 { SN9C102_USB_DEVICE(0x0c45, 0x602a, BRIDGE_SN9C102), },
57 { SN9C102_USB_DEVICE(0x0c45, 0x602b, BRIDGE_SN9C102), }, 61 { SN9C102_USB_DEVICE(0x0c45, 0x602b, BRIDGE_SN9C102), },
58#if !defined CONFIG_USB_GSPCA && !defined CONFIG_USB_GSPCA_MODULE 62#if !defined CONFIG_USB_GSPCA && !defined CONFIG_USB_GSPCA_MODULE
59 { SN9C102_USB_DEVICE(0x0c45, 0x602c, BRIDGE_SN9C102), }, 63 { SN9C102_USB_DEVICE(0x0c45, 0x602c, BRIDGE_SN9C102), },
60#endif
61/* { SN9C102_USB_DEVICE(0x0c45, 0x602d, BRIDGE_SN9C102), }, HV7131R */ 64/* { SN9C102_USB_DEVICE(0x0c45, 0x602d, BRIDGE_SN9C102), }, HV7131R */
65#endif
62 { SN9C102_USB_DEVICE(0x0c45, 0x602e, BRIDGE_SN9C102), }, 66 { SN9C102_USB_DEVICE(0x0c45, 0x602e, BRIDGE_SN9C102), },
63 { SN9C102_USB_DEVICE(0x0c45, 0x6030, BRIDGE_SN9C102), }, 67 { SN9C102_USB_DEVICE(0x0c45, 0x6030, BRIDGE_SN9C102), },
64 /* SN9C103 */ 68 /* SN9C103 */
diff --git a/drivers/media/video/soc_camera.c b/drivers/media/video/soc_camera.c
index 6b3fbcca7747..80f6bfa2632b 100644
--- a/drivers/media/video/soc_camera.c
+++ b/drivers/media/video/soc_camera.c
@@ -781,6 +781,32 @@ static int soc_camera_s_crop(struct file *file, void *fh,
781 return ret; 781 return ret;
782} 782}
783 783
784static int soc_camera_g_parm(struct file *file, void *fh,
785 struct v4l2_streamparm *a)
786{
787 struct soc_camera_file *icf = file->private_data;
788 struct soc_camera_device *icd = icf->icd;
789 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
790
791 if (ici->ops->get_parm)
792 return ici->ops->get_parm(icd, a);
793
794 return -ENOIOCTLCMD;
795}
796
797static int soc_camera_s_parm(struct file *file, void *fh,
798 struct v4l2_streamparm *a)
799{
800 struct soc_camera_file *icf = file->private_data;
801 struct soc_camera_device *icd = icf->icd;
802 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
803
804 if (ici->ops->set_parm)
805 return ici->ops->set_parm(icd, a);
806
807 return -ENOIOCTLCMD;
808}
809
784static int soc_camera_g_chip_ident(struct file *file, void *fh, 810static int soc_camera_g_chip_ident(struct file *file, void *fh,
785 struct v4l2_dbg_chip_ident *id) 811 struct v4l2_dbg_chip_ident *id)
786{ 812{
@@ -846,10 +872,8 @@ static int soc_camera_init_i2c(struct soc_camera_device *icd,
846 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); 872 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
847 struct i2c_adapter *adap = i2c_get_adapter(icl->i2c_adapter_id); 873 struct i2c_adapter *adap = i2c_get_adapter(icl->i2c_adapter_id);
848 struct v4l2_subdev *subdev; 874 struct v4l2_subdev *subdev;
849 int ret;
850 875
851 if (!adap) { 876 if (!adap) {
852 ret = -ENODEV;
853 dev_err(&icd->dev, "Cannot get I2C adapter #%d. No driver?\n", 877 dev_err(&icd->dev, "Cannot get I2C adapter #%d. No driver?\n",
854 icl->i2c_adapter_id); 878 icl->i2c_adapter_id);
855 goto ei2cga; 879 goto ei2cga;
@@ -859,10 +883,8 @@ static int soc_camera_init_i2c(struct soc_camera_device *icd,
859 883
860 subdev = v4l2_i2c_new_subdev_board(&ici->v4l2_dev, adap, 884 subdev = v4l2_i2c_new_subdev_board(&ici->v4l2_dev, adap,
861 icl->module_name, icl->board_info, NULL); 885 icl->module_name, icl->board_info, NULL);
862 if (!subdev) { 886 if (!subdev)
863 ret = -ENOMEM;
864 goto ei2cnd; 887 goto ei2cnd;
865 }
866 888
867 client = subdev->priv; 889 client = subdev->priv;
868 890
@@ -873,7 +895,7 @@ static int soc_camera_init_i2c(struct soc_camera_device *icd,
873ei2cnd: 895ei2cnd:
874 i2c_put_adapter(adap); 896 i2c_put_adapter(adap);
875ei2cga: 897ei2cga:
876 return ret; 898 return -ENODEV;
877} 899}
878 900
879static void soc_camera_free_i2c(struct soc_camera_device *icd) 901static void soc_camera_free_i2c(struct soc_camera_device *icd)
@@ -1260,6 +1282,8 @@ static const struct v4l2_ioctl_ops soc_camera_ioctl_ops = {
1260 .vidioc_cropcap = soc_camera_cropcap, 1282 .vidioc_cropcap = soc_camera_cropcap,
1261 .vidioc_g_crop = soc_camera_g_crop, 1283 .vidioc_g_crop = soc_camera_g_crop,
1262 .vidioc_s_crop = soc_camera_s_crop, 1284 .vidioc_s_crop = soc_camera_s_crop,
1285 .vidioc_g_parm = soc_camera_g_parm,
1286 .vidioc_s_parm = soc_camera_s_parm,
1263 .vidioc_g_chip_ident = soc_camera_g_chip_ident, 1287 .vidioc_g_chip_ident = soc_camera_g_chip_ident,
1264#ifdef CONFIG_VIDEO_ADV_DEBUG 1288#ifdef CONFIG_VIDEO_ADV_DEBUG
1265 .vidioc_g_register = soc_camera_g_register, 1289 .vidioc_g_register = soc_camera_g_register,
diff --git a/drivers/media/video/soc_mediabus.c b/drivers/media/video/soc_mediabus.c
index f8d5c87dc2aa..8b63b6545e76 100644
--- a/drivers/media/video/soc_mediabus.c
+++ b/drivers/media/video/soc_mediabus.c
@@ -24,91 +24,106 @@ static const struct soc_mbus_pixelfmt mbus_fmt[] = {
24 .bits_per_sample = 8, 24 .bits_per_sample = 8,
25 .packing = SOC_MBUS_PACKING_2X8_PADHI, 25 .packing = SOC_MBUS_PACKING_2X8_PADHI,
26 .order = SOC_MBUS_ORDER_LE, 26 .order = SOC_MBUS_ORDER_LE,
27 }, [MBUS_IDX(YVYU8_2X8_LE)] = { 27 },
28 [MBUS_IDX(YVYU8_2X8_LE)] = {
28 .fourcc = V4L2_PIX_FMT_YVYU, 29 .fourcc = V4L2_PIX_FMT_YVYU,
29 .name = "YVYU", 30 .name = "YVYU",
30 .bits_per_sample = 8, 31 .bits_per_sample = 8,
31 .packing = SOC_MBUS_PACKING_2X8_PADHI, 32 .packing = SOC_MBUS_PACKING_2X8_PADHI,
32 .order = SOC_MBUS_ORDER_LE, 33 .order = SOC_MBUS_ORDER_LE,
33 }, [MBUS_IDX(YUYV8_2X8_BE)] = { 34 },
35 [MBUS_IDX(YUYV8_2X8_BE)] = {
34 .fourcc = V4L2_PIX_FMT_UYVY, 36 .fourcc = V4L2_PIX_FMT_UYVY,
35 .name = "UYVY", 37 .name = "UYVY",
36 .bits_per_sample = 8, 38 .bits_per_sample = 8,
37 .packing = SOC_MBUS_PACKING_2X8_PADHI, 39 .packing = SOC_MBUS_PACKING_2X8_PADHI,
38 .order = SOC_MBUS_ORDER_LE, 40 .order = SOC_MBUS_ORDER_LE,
39 }, [MBUS_IDX(YVYU8_2X8_BE)] = { 41 },
42 [MBUS_IDX(YVYU8_2X8_BE)] = {
40 .fourcc = V4L2_PIX_FMT_VYUY, 43 .fourcc = V4L2_PIX_FMT_VYUY,
41 .name = "VYUY", 44 .name = "VYUY",
42 .bits_per_sample = 8, 45 .bits_per_sample = 8,
43 .packing = SOC_MBUS_PACKING_2X8_PADHI, 46 .packing = SOC_MBUS_PACKING_2X8_PADHI,
44 .order = SOC_MBUS_ORDER_LE, 47 .order = SOC_MBUS_ORDER_LE,
45 }, [MBUS_IDX(RGB555_2X8_PADHI_LE)] = { 48 },
49 [MBUS_IDX(RGB555_2X8_PADHI_LE)] = {
46 .fourcc = V4L2_PIX_FMT_RGB555, 50 .fourcc = V4L2_PIX_FMT_RGB555,
47 .name = "RGB555", 51 .name = "RGB555",
48 .bits_per_sample = 8, 52 .bits_per_sample = 8,
49 .packing = SOC_MBUS_PACKING_2X8_PADHI, 53 .packing = SOC_MBUS_PACKING_2X8_PADHI,
50 .order = SOC_MBUS_ORDER_LE, 54 .order = SOC_MBUS_ORDER_LE,
51 }, [MBUS_IDX(RGB555_2X8_PADHI_BE)] = { 55 },
56 [MBUS_IDX(RGB555_2X8_PADHI_BE)] = {
52 .fourcc = V4L2_PIX_FMT_RGB555X, 57 .fourcc = V4L2_PIX_FMT_RGB555X,
53 .name = "RGB555X", 58 .name = "RGB555X",
54 .bits_per_sample = 8, 59 .bits_per_sample = 8,
55 .packing = SOC_MBUS_PACKING_2X8_PADHI, 60 .packing = SOC_MBUS_PACKING_2X8_PADHI,
56 .order = SOC_MBUS_ORDER_LE, 61 .order = SOC_MBUS_ORDER_LE,
57 }, [MBUS_IDX(RGB565_2X8_LE)] = { 62 },
63 [MBUS_IDX(RGB565_2X8_LE)] = {
58 .fourcc = V4L2_PIX_FMT_RGB565, 64 .fourcc = V4L2_PIX_FMT_RGB565,
59 .name = "RGB565", 65 .name = "RGB565",
60 .bits_per_sample = 8, 66 .bits_per_sample = 8,
61 .packing = SOC_MBUS_PACKING_2X8_PADHI, 67 .packing = SOC_MBUS_PACKING_2X8_PADHI,
62 .order = SOC_MBUS_ORDER_LE, 68 .order = SOC_MBUS_ORDER_LE,
63 }, [MBUS_IDX(RGB565_2X8_BE)] = { 69 },
70 [MBUS_IDX(RGB565_2X8_BE)] = {
64 .fourcc = V4L2_PIX_FMT_RGB565X, 71 .fourcc = V4L2_PIX_FMT_RGB565X,
65 .name = "RGB565X", 72 .name = "RGB565X",
66 .bits_per_sample = 8, 73 .bits_per_sample = 8,
67 .packing = SOC_MBUS_PACKING_2X8_PADHI, 74 .packing = SOC_MBUS_PACKING_2X8_PADHI,
68 .order = SOC_MBUS_ORDER_LE, 75 .order = SOC_MBUS_ORDER_LE,
69 }, [MBUS_IDX(SBGGR8_1X8)] = { 76 },
77 [MBUS_IDX(SBGGR8_1X8)] = {
70 .fourcc = V4L2_PIX_FMT_SBGGR8, 78 .fourcc = V4L2_PIX_FMT_SBGGR8,
71 .name = "Bayer 8 BGGR", 79 .name = "Bayer 8 BGGR",
72 .bits_per_sample = 8, 80 .bits_per_sample = 8,
73 .packing = SOC_MBUS_PACKING_NONE, 81 .packing = SOC_MBUS_PACKING_NONE,
74 .order = SOC_MBUS_ORDER_LE, 82 .order = SOC_MBUS_ORDER_LE,
75 }, [MBUS_IDX(SBGGR10_1X10)] = { 83 },
84 [MBUS_IDX(SBGGR10_1X10)] = {
76 .fourcc = V4L2_PIX_FMT_SBGGR10, 85 .fourcc = V4L2_PIX_FMT_SBGGR10,
77 .name = "Bayer 10 BGGR", 86 .name = "Bayer 10 BGGR",
78 .bits_per_sample = 10, 87 .bits_per_sample = 10,
79 .packing = SOC_MBUS_PACKING_EXTEND16, 88 .packing = SOC_MBUS_PACKING_EXTEND16,
80 .order = SOC_MBUS_ORDER_LE, 89 .order = SOC_MBUS_ORDER_LE,
81 }, [MBUS_IDX(GREY8_1X8)] = { 90 },
91 [MBUS_IDX(GREY8_1X8)] = {
82 .fourcc = V4L2_PIX_FMT_GREY, 92 .fourcc = V4L2_PIX_FMT_GREY,
83 .name = "Grey", 93 .name = "Grey",
84 .bits_per_sample = 8, 94 .bits_per_sample = 8,
85 .packing = SOC_MBUS_PACKING_NONE, 95 .packing = SOC_MBUS_PACKING_NONE,
86 .order = SOC_MBUS_ORDER_LE, 96 .order = SOC_MBUS_ORDER_LE,
87 }, [MBUS_IDX(Y10_1X10)] = { 97 },
98 [MBUS_IDX(Y10_1X10)] = {
88 .fourcc = V4L2_PIX_FMT_Y10, 99 .fourcc = V4L2_PIX_FMT_Y10,
89 .name = "Grey 10bit", 100 .name = "Grey 10bit",
90 .bits_per_sample = 10, 101 .bits_per_sample = 10,
91 .packing = SOC_MBUS_PACKING_EXTEND16, 102 .packing = SOC_MBUS_PACKING_EXTEND16,
92 .order = SOC_MBUS_ORDER_LE, 103 .order = SOC_MBUS_ORDER_LE,
93 }, [MBUS_IDX(SBGGR10_2X8_PADHI_LE)] = { 104 },
105 [MBUS_IDX(SBGGR10_2X8_PADHI_LE)] = {
94 .fourcc = V4L2_PIX_FMT_SBGGR10, 106 .fourcc = V4L2_PIX_FMT_SBGGR10,
95 .name = "Bayer 10 BGGR", 107 .name = "Bayer 10 BGGR",
96 .bits_per_sample = 8, 108 .bits_per_sample = 8,
97 .packing = SOC_MBUS_PACKING_2X8_PADHI, 109 .packing = SOC_MBUS_PACKING_2X8_PADHI,
98 .order = SOC_MBUS_ORDER_LE, 110 .order = SOC_MBUS_ORDER_LE,
99 }, [MBUS_IDX(SBGGR10_2X8_PADLO_LE)] = { 111 },
112 [MBUS_IDX(SBGGR10_2X8_PADLO_LE)] = {
100 .fourcc = V4L2_PIX_FMT_SBGGR10, 113 .fourcc = V4L2_PIX_FMT_SBGGR10,
101 .name = "Bayer 10 BGGR", 114 .name = "Bayer 10 BGGR",
102 .bits_per_sample = 8, 115 .bits_per_sample = 8,
103 .packing = SOC_MBUS_PACKING_2X8_PADLO, 116 .packing = SOC_MBUS_PACKING_2X8_PADLO,
104 .order = SOC_MBUS_ORDER_LE, 117 .order = SOC_MBUS_ORDER_LE,
105 }, [MBUS_IDX(SBGGR10_2X8_PADHI_BE)] = { 118 },
119 [MBUS_IDX(SBGGR10_2X8_PADHI_BE)] = {
106 .fourcc = V4L2_PIX_FMT_SBGGR10, 120 .fourcc = V4L2_PIX_FMT_SBGGR10,
107 .name = "Bayer 10 BGGR", 121 .name = "Bayer 10 BGGR",
108 .bits_per_sample = 8, 122 .bits_per_sample = 8,
109 .packing = SOC_MBUS_PACKING_2X8_PADHI, 123 .packing = SOC_MBUS_PACKING_2X8_PADHI,
110 .order = SOC_MBUS_ORDER_BE, 124 .order = SOC_MBUS_ORDER_BE,
111 }, [MBUS_IDX(SBGGR10_2X8_PADLO_BE)] = { 125 },
126 [MBUS_IDX(SBGGR10_2X8_PADLO_BE)] = {
112 .fourcc = V4L2_PIX_FMT_SBGGR10, 127 .fourcc = V4L2_PIX_FMT_SBGGR10,
113 .name = "Bayer 10 BGGR", 128 .name = "Bayer 10 BGGR",
114 .bits_per_sample = 8, 129 .bits_per_sample = 8,
@@ -134,7 +149,8 @@ EXPORT_SYMBOL(soc_mbus_bytes_per_line);
134const struct soc_mbus_pixelfmt *soc_mbus_get_fmtdesc( 149const struct soc_mbus_pixelfmt *soc_mbus_get_fmtdesc(
135 enum v4l2_mbus_pixelcode code) 150 enum v4l2_mbus_pixelcode code)
136{ 151{
137 if ((unsigned int)(code - V4L2_MBUS_FMT_FIXED) > ARRAY_SIZE(mbus_fmt)) 152 if (code - V4L2_MBUS_FMT_FIXED > ARRAY_SIZE(mbus_fmt) ||
153 code <= V4L2_MBUS_FMT_FIXED)
138 return NULL; 154 return NULL;
139 return mbus_fmt + code - V4L2_MBUS_FMT_FIXED - 1; 155 return mbus_fmt + code - V4L2_MBUS_FMT_FIXED - 1;
140} 156}
diff --git a/drivers/media/video/tlg2300/Kconfig b/drivers/media/video/tlg2300/Kconfig
new file mode 100644
index 000000000000..2c29ec659b4e
--- /dev/null
+++ b/drivers/media/video/tlg2300/Kconfig
@@ -0,0 +1,16 @@
1config VIDEO_TLG2300
2 tristate "Telegent TLG2300 USB video capture support"
3 depends on VIDEO_DEV && I2C && INPUT && SND && DVB_CORE
4 select VIDEO_TUNER
5 select VIDEO_TVEEPROM
6 select VIDEO_IR
7 select VIDEOBUF_VMALLOC
8 select SND_PCM
9 select VIDEOBUF_DVB
10
11 ---help---
12 This is a video4linux driver for Telegent tlg2300 based TV cards.
13 The driver supports V4L2, DVB-T and radio.
14
15 To compile this driver as a module, choose M here: the
16 module will be called poseidon
diff --git a/drivers/media/video/tlg2300/Makefile b/drivers/media/video/tlg2300/Makefile
new file mode 100644
index 000000000000..81bb7fdd1e3d
--- /dev/null
+++ b/drivers/media/video/tlg2300/Makefile
@@ -0,0 +1,9 @@
1poseidon-objs := pd-video.o pd-alsa.o pd-dvb.o pd-radio.o pd-main.o
2
3obj-$(CONFIG_VIDEO_TLG2300) += poseidon.o
4
5EXTRA_CFLAGS += -Idrivers/media/video
6EXTRA_CFLAGS += -Idrivers/media/common/tuners
7EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core
8EXTRA_CFLAGS += -Idrivers/media/dvb/frontends
9
diff --git a/drivers/media/video/tlg2300/pd-alsa.c b/drivers/media/video/tlg2300/pd-alsa.c
new file mode 100644
index 000000000000..6f42621ad478
--- /dev/null
+++ b/drivers/media/video/tlg2300/pd-alsa.c
@@ -0,0 +1,332 @@
1#include <linux/kernel.h>
2#include <linux/usb.h>
3#include <linux/init.h>
4#include <linux/sound.h>
5#include <linux/spinlock.h>
6#include <linux/soundcard.h>
7#include <linux/slab.h>
8#include <linux/vmalloc.h>
9#include <linux/proc_fs.h>
10#include <linux/module.h>
11#include <sound/core.h>
12#include <sound/pcm.h>
13#include <sound/pcm_params.h>
14#include <sound/info.h>
15#include <sound/initval.h>
16#include <sound/control.h>
17#include <media/v4l2-common.h>
18#include "pd-common.h"
19#include "vendorcmds.h"
20
21static void complete_handler_audio(struct urb *urb);
22#define AUDIO_EP (0x83)
23#define AUDIO_BUF_SIZE (512)
24#define PERIOD_SIZE (1024 * 8)
25#define PERIOD_MIN (4)
26#define PERIOD_MAX PERIOD_MIN
27
28static struct snd_pcm_hardware snd_pd_hw_capture = {
29 .info = SNDRV_PCM_INFO_BLOCK_TRANSFER |
30 SNDRV_PCM_INFO_MMAP |
31 SNDRV_PCM_INFO_INTERLEAVED |
32 SNDRV_PCM_INFO_MMAP_VALID,
33
34 .formats = SNDRV_PCM_FMTBIT_S16_LE,
35 .rates = SNDRV_PCM_RATE_48000,
36
37 .rate_min = 48000,
38 .rate_max = 48000,
39 .channels_min = 2,
40 .channels_max = 2,
41 .buffer_bytes_max = PERIOD_SIZE * PERIOD_MIN,
42 .period_bytes_min = PERIOD_SIZE,
43 .period_bytes_max = PERIOD_SIZE,
44 .periods_min = PERIOD_MIN,
45 .periods_max = PERIOD_MAX,
46 /*
47 .buffer_bytes_max = 62720 * 8,
48 .period_bytes_min = 64,
49 .period_bytes_max = 12544,
50 .periods_min = 2,
51 .periods_max = 98
52 */
53};
54
55static int snd_pd_capture_open(struct snd_pcm_substream *substream)
56{
57 struct poseidon *p = snd_pcm_substream_chip(substream);
58 struct poseidon_audio *pa = &p->audio;
59 struct snd_pcm_runtime *runtime = substream->runtime;
60
61 if (!p)
62 return -ENODEV;
63 pa->users++;
64 pa->card_close = 0;
65 pa->capture_pcm_substream = substream;
66 runtime->private_data = p;
67
68 runtime->hw = snd_pd_hw_capture;
69 snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
70 usb_autopm_get_interface(p->interface);
71 kref_get(&p->kref);
72 return 0;
73}
74
75static int snd_pd_pcm_close(struct snd_pcm_substream *substream)
76{
77 struct poseidon *p = snd_pcm_substream_chip(substream);
78 struct poseidon_audio *pa = &p->audio;
79
80 pa->users--;
81 pa->card_close = 1;
82 usb_autopm_put_interface(p->interface);
83 kref_put(&p->kref, poseidon_delete);
84 return 0;
85}
86
87static int snd_pd_hw_capture_params(struct snd_pcm_substream *substream,
88 struct snd_pcm_hw_params *hw_params)
89{
90 struct snd_pcm_runtime *runtime = substream->runtime;
91 unsigned int size;
92
93 size = params_buffer_bytes(hw_params);
94 if (runtime->dma_area) {
95 if (runtime->dma_bytes > size)
96 return 0;
97 vfree(runtime->dma_area);
98 }
99 runtime->dma_area = vmalloc(size);
100 if (!runtime->dma_area)
101 return -ENOMEM;
102 else
103 runtime->dma_bytes = size;
104 return 0;
105}
106
107static int audio_buf_free(struct poseidon *p)
108{
109 struct poseidon_audio *pa = &p->audio;
110 int i;
111
112 for (i = 0; i < AUDIO_BUFS; i++)
113 if (pa->urb_array[i])
114 usb_kill_urb(pa->urb_array[i]);
115 free_all_urb_generic(pa->urb_array, AUDIO_BUFS);
116 logpm();
117 return 0;
118}
119
120static int snd_pd_hw_capture_free(struct snd_pcm_substream *substream)
121{
122 struct poseidon *p = snd_pcm_substream_chip(substream);
123
124 logpm();
125 audio_buf_free(p);
126 return 0;
127}
128
129static int snd_pd_prepare(struct snd_pcm_substream *substream)
130{
131 return 0;
132}
133
134#define AUDIO_TRAILER_SIZE (16)
135static inline void handle_audio_data(struct urb *urb, int *period_elapsed)
136{
137 struct poseidon_audio *pa = urb->context;
138 struct snd_pcm_runtime *runtime = pa->capture_pcm_substream->runtime;
139
140 int stride = runtime->frame_bits >> 3;
141 int len = urb->actual_length / stride;
142 unsigned char *cp = urb->transfer_buffer;
143 unsigned int oldptr = pa->rcv_position;
144
145 if (urb->actual_length == AUDIO_BUF_SIZE - 4)
146 len -= (AUDIO_TRAILER_SIZE / stride);
147
148 /* do the copy */
149 if (oldptr + len >= runtime->buffer_size) {
150 unsigned int cnt = runtime->buffer_size - oldptr;
151
152 memcpy(runtime->dma_area + oldptr * stride, cp, cnt * stride);
153 memcpy(runtime->dma_area, (cp + cnt * stride),
154 (len * stride - cnt * stride));
155 } else
156 memcpy(runtime->dma_area + oldptr * stride, cp, len * stride);
157
158 /* update the statas */
159 snd_pcm_stream_lock(pa->capture_pcm_substream);
160 pa->rcv_position += len;
161 if (pa->rcv_position >= runtime->buffer_size)
162 pa->rcv_position -= runtime->buffer_size;
163
164 pa->copied_position += (len);
165 if (pa->copied_position >= runtime->period_size) {
166 pa->copied_position -= runtime->period_size;
167 *period_elapsed = 1;
168 }
169 snd_pcm_stream_unlock(pa->capture_pcm_substream);
170}
171
172static void complete_handler_audio(struct urb *urb)
173{
174 struct poseidon_audio *pa = urb->context;
175 struct snd_pcm_substream *substream = pa->capture_pcm_substream;
176 int period_elapsed = 0;
177 int ret;
178
179 if (1 == pa->card_close || pa->capture_stream != STREAM_ON)
180 return;
181
182 if (urb->status != 0) {
183 /*if (urb->status == -ESHUTDOWN)*/
184 return;
185 }
186
187 if (substream) {
188 if (urb->actual_length) {
189 handle_audio_data(urb, &period_elapsed);
190 if (period_elapsed)
191 snd_pcm_period_elapsed(substream);
192 }
193 }
194
195 ret = usb_submit_urb(urb, GFP_ATOMIC);
196 if (ret < 0)
197 log("audio urb failed (errcod = %i)", ret);
198 return;
199}
200
201static int fire_audio_urb(struct poseidon *p)
202{
203 int i, ret = 0;
204 struct poseidon_audio *pa = &p->audio;
205
206 alloc_bulk_urbs_generic(pa->urb_array, AUDIO_BUFS,
207 p->udev, AUDIO_EP,
208 AUDIO_BUF_SIZE, GFP_ATOMIC,
209 complete_handler_audio, pa);
210
211 for (i = 0; i < AUDIO_BUFS; i++) {
212 ret = usb_submit_urb(pa->urb_array[i], GFP_KERNEL);
213 if (ret)
214 log("urb err : %d", ret);
215 }
216 log();
217 return ret;
218}
219
220static int snd_pd_capture_trigger(struct snd_pcm_substream *substream, int cmd)
221{
222 struct poseidon *p = snd_pcm_substream_chip(substream);
223 struct poseidon_audio *pa = &p->audio;
224
225 if (debug_mode)
226 log("cmd %d, audio stat : %d\n", cmd, pa->capture_stream);
227
228 switch (cmd) {
229 case SNDRV_PCM_TRIGGER_RESUME:
230 case SNDRV_PCM_TRIGGER_START:
231 if (pa->capture_stream == STREAM_ON)
232 return 0;
233
234 pa->rcv_position = pa->copied_position = 0;
235 pa->capture_stream = STREAM_ON;
236
237 if (in_hibernation(p))
238 return 0;
239 fire_audio_urb(p);
240 return 0;
241
242 case SNDRV_PCM_TRIGGER_SUSPEND:
243 pa->capture_stream = STREAM_SUSPEND;
244 return 0;
245 case SNDRV_PCM_TRIGGER_STOP:
246 pa->capture_stream = STREAM_OFF;
247 return 0;
248 default:
249 return -EINVAL;
250 }
251}
252
253static snd_pcm_uframes_t
254snd_pd_capture_pointer(struct snd_pcm_substream *substream)
255{
256 struct poseidon *p = snd_pcm_substream_chip(substream);
257 struct poseidon_audio *pa = &p->audio;
258 return pa->rcv_position;
259}
260
261static struct page *snd_pcm_pd_get_page(struct snd_pcm_substream *subs,
262 unsigned long offset)
263{
264 void *pageptr = subs->runtime->dma_area + offset;
265 return vmalloc_to_page(pageptr);
266}
267
268static struct snd_pcm_ops pcm_capture_ops = {
269 .open = snd_pd_capture_open,
270 .close = snd_pd_pcm_close,
271 .ioctl = snd_pcm_lib_ioctl,
272 .hw_params = snd_pd_hw_capture_params,
273 .hw_free = snd_pd_hw_capture_free,
274 .prepare = snd_pd_prepare,
275 .trigger = snd_pd_capture_trigger,
276 .pointer = snd_pd_capture_pointer,
277 .page = snd_pcm_pd_get_page,
278};
279
280#ifdef CONFIG_PM
281int pm_alsa_suspend(struct poseidon *p)
282{
283 logpm(p);
284 audio_buf_free(p);
285 return 0;
286}
287
288int pm_alsa_resume(struct poseidon *p)
289{
290 logpm(p);
291 fire_audio_urb(p);
292 return 0;
293}
294#endif
295
296int poseidon_audio_init(struct poseidon *p)
297{
298 struct poseidon_audio *pa = &p->audio;
299 struct snd_card *card;
300 struct snd_pcm *pcm;
301 int ret;
302
303 ret = snd_card_create(-1, "Telegent", THIS_MODULE, 0, &card);
304 if (ret != 0)
305 return ret;
306
307 ret = snd_pcm_new(card, "poseidon audio", 0, 0, 1, &pcm);
308 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &pcm_capture_ops);
309 pcm->info_flags = 0;
310 pcm->private_data = p;
311 strcpy(pcm->name, "poseidon audio capture");
312
313 strcpy(card->driver, "ALSA driver");
314 strcpy(card->shortname, "poseidon Audio");
315 strcpy(card->longname, "poseidon ALSA Audio");
316
317 if (snd_card_register(card)) {
318 snd_card_free(card);
319 return -ENOMEM;
320 }
321 pa->card = card;
322 return 0;
323}
324
325int poseidon_audio_free(struct poseidon *p)
326{
327 struct poseidon_audio *pa = &p->audio;
328
329 if (pa->card)
330 snd_card_free(pa->card);
331 return 0;
332}
diff --git a/drivers/media/video/tlg2300/pd-common.h b/drivers/media/video/tlg2300/pd-common.h
new file mode 100644
index 000000000000..46066bdc73f9
--- /dev/null
+++ b/drivers/media/video/tlg2300/pd-common.h
@@ -0,0 +1,282 @@
1#ifndef PD_COMMON_H
2#define PD_COMMON_H
3
4#include <linux/version.h>
5#include <linux/fs.h>
6#include <linux/wait.h>
7#include <linux/list.h>
8#include <linux/videodev2.h>
9#include <linux/semaphore.h>
10#include <linux/usb.h>
11#include <linux/poll.h>
12#include <media/videobuf-vmalloc.h>
13#include <media/v4l2-device.h>
14
15#include "dvb_frontend.h"
16#include "dvbdev.h"
17#include "dvb_demux.h"
18#include "dmxdev.h"
19
20#define SBUF_NUM 8
21#define MAX_BUFFER_NUM 6
22#define PK_PER_URB 32
23#define ISO_PKT_SIZE 3072
24
25#define POSEIDON_STATE_NONE (0x0000)
26#define POSEIDON_STATE_ANALOG (0x0001)
27#define POSEIDON_STATE_FM (0x0002)
28#define POSEIDON_STATE_DVBT (0x0004)
29#define POSEIDON_STATE_VBI (0x0008)
30#define POSEIDON_STATE_DISCONNECT (0x0080)
31
32#define PM_SUSPEND_DELAY 3
33
34#define V4L_PAL_VBI_LINES 18
35#define V4L_NTSC_VBI_LINES 12
36#define V4L_PAL_VBI_FRAMESIZE (V4L_PAL_VBI_LINES * 1440 * 2)
37#define V4L_NTSC_VBI_FRAMESIZE (V4L_NTSC_VBI_LINES * 1440 * 2)
38
39#define TUNER_FREQ_MIN (45000000)
40#define TUNER_FREQ_MAX (862000000)
41
42struct vbi_data {
43 struct video_device *v_dev;
44 struct video_data *video;
45 struct front_face *front;
46
47 unsigned int copied;
48 unsigned int vbi_size; /* the whole size of two fields */
49 int users;
50};
51
52/*
53 * This is the running context of the video, it is useful for
54 * resume()
55 */
56struct running_context {
57 u32 freq; /* VIDIOC_S_FREQUENCY */
58 int audio_idx; /* VIDIOC_S_TUNER */
59 v4l2_std_id tvnormid; /* VIDIOC_S_STD */
60 int sig_index; /* VIDIOC_S_INPUT */
61 struct v4l2_pix_format pix; /* VIDIOC_S_FMT */
62};
63
64struct video_data {
65 /* v4l2 video device */
66 struct video_device *v_dev;
67
68 /* the working context */
69 struct running_context context;
70
71 /* for data copy */
72 int field_count;
73
74 char *dst;
75 int lines_copied;
76 int prev_left;
77
78 int lines_per_field;
79 int lines_size;
80
81 /* for communication */
82 u8 endpoint_addr;
83 struct urb *urb_array[SBUF_NUM];
84 struct vbi_data *vbi;
85 struct poseidon *pd;
86 struct front_face *front;
87
88 int is_streaming;
89 int users;
90
91 /* for bubble handler */
92 struct work_struct bubble_work;
93};
94
95enum pcm_stream_state {
96 STREAM_OFF,
97 STREAM_ON,
98 STREAM_SUSPEND,
99};
100
101#define AUDIO_BUFS (3)
102#define CAPTURE_STREAM_EN 1
103struct poseidon_audio {
104 struct urb *urb_array[AUDIO_BUFS];
105 unsigned int copied_position;
106 struct snd_pcm_substream *capture_pcm_substream;
107
108 unsigned int rcv_position;
109 struct snd_card *card;
110 int card_close;
111
112 int users;
113 int pm_state;
114 enum pcm_stream_state capture_stream;
115};
116
117struct radio_data {
118 __u32 fm_freq;
119 int users;
120 unsigned int is_radio_streaming;
121 int pre_emphasis;
122 struct video_device *fm_dev;
123};
124
125#define DVB_SBUF_NUM 4
126#define DVB_URB_BUF_SIZE 0x2000
127struct pd_dvb_adapter {
128 struct dvb_adapter dvb_adap;
129 struct dvb_frontend dvb_fe;
130 struct dmxdev dmxdev;
131 struct dvb_demux demux;
132
133 atomic_t users;
134 atomic_t active_feed;
135
136 /* data transfer */
137 s32 is_streaming;
138 struct urb *urb_array[DVB_SBUF_NUM];
139 struct poseidon *pd_device;
140 u8 ep_addr;
141 u8 reserved[3];
142
143 /* data for power resume*/
144 struct dvb_frontend_parameters fe_param;
145
146 /* for channel scanning */
147 int prev_freq;
148 int bandwidth;
149 unsigned long last_jiffies;
150};
151
152struct front_face {
153 /* use this field to distinguish VIDEO and VBI */
154 enum v4l2_buf_type type;
155
156 /* for host */
157 struct videobuf_queue q;
158
159 /* the bridge for host and device */
160 struct videobuf_buffer *curr_frame;
161
162 /* for device */
163 spinlock_t queue_lock;
164 struct list_head active;
165 struct poseidon *pd;
166};
167
168struct poseidon {
169 struct list_head device_list;
170
171 struct mutex lock;
172 struct kref kref;
173
174 /* for V4L2 */
175 struct v4l2_device v4l2_dev;
176
177 /* hardware info */
178 struct usb_device *udev;
179 struct usb_interface *interface;
180 int cur_transfer_mode;
181
182 struct video_data video_data; /* video */
183 struct vbi_data vbi_data; /* vbi */
184 struct poseidon_audio audio; /* audio (alsa) */
185 struct radio_data radio_data; /* FM */
186 struct pd_dvb_adapter dvb_data; /* DVB */
187
188 u32 state;
189 struct file *file_for_stream; /* the active stream*/
190
191#ifdef CONFIG_PM
192 int (*pm_suspend)(struct poseidon *);
193 int (*pm_resume)(struct poseidon *);
194 pm_message_t msg;
195
196 struct work_struct pm_work;
197 u8 portnum;
198#endif
199};
200
201struct poseidon_format {
202 char *name;
203 int fourcc; /* video4linux 2 */
204 int depth; /* bit/pixel */
205 int flags;
206};
207
208struct poseidon_tvnorm {
209 v4l2_std_id v4l2_id;
210 char name[12];
211 u32 tlg_tvnorm;
212};
213
214/* video */
215int pd_video_init(struct poseidon *);
216void pd_video_exit(struct poseidon *);
217int stop_all_video_stream(struct poseidon *);
218
219/* alsa audio */
220int poseidon_audio_init(struct poseidon *);
221int poseidon_audio_free(struct poseidon *);
222#ifdef CONFIG_PM
223int pm_alsa_suspend(struct poseidon *);
224int pm_alsa_resume(struct poseidon *);
225#endif
226
227/* dvb */
228int pd_dvb_usb_device_init(struct poseidon *);
229void pd_dvb_usb_device_exit(struct poseidon *);
230void pd_dvb_usb_device_cleanup(struct poseidon *);
231int pd_dvb_get_adapter_num(struct pd_dvb_adapter *);
232void dvb_stop_streaming(struct pd_dvb_adapter *);
233
234/* FM */
235int poseidon_fm_init(struct poseidon *);
236int poseidon_fm_exit(struct poseidon *);
237struct video_device *vdev_init(struct poseidon *, struct video_device *);
238
239/* vendor command ops */
240int send_set_req(struct poseidon*, u8, s32, s32*);
241int send_get_req(struct poseidon*, u8, s32, void*, s32*, s32);
242s32 set_tuner_mode(struct poseidon*, unsigned char);
243
244/* bulk urb alloc/free */
245int alloc_bulk_urbs_generic(struct urb **urb_array, int num,
246 struct usb_device *udev, u8 ep_addr,
247 int buf_size, gfp_t gfp_flags,
248 usb_complete_t complete_fn, void *context);
249void free_all_urb_generic(struct urb **urb_array, int num);
250
251/* misc */
252void poseidon_delete(struct kref *kref);
253void destroy_video_device(struct video_device **v_dev);
254extern int debug_mode;
255void set_debug_mode(struct video_device *vfd, int debug_mode);
256
257#ifdef CONFIG_PM
258#define in_hibernation(pd) (pd->msg.event == PM_EVENT_FREEZE)
259#else
260#define in_hibernation(pd) (0)
261#endif
262#define get_pm_count(p) (atomic_read(&(p)->interface->pm_usage_cnt))
263
264#define log(a, ...) printk(KERN_DEBUG "\t[ %s : %.3d ] "a"\n", \
265 __func__, __LINE__, ## __VA_ARGS__)
266
267/* for power management */
268#define logpm(pd) do {\
269 if (debug_mode & 0x10)\
270 log();\
271 } while (0)
272
273#define logs(f) do { \
274 if ((debug_mode & 0x4) && \
275 (f)->type == V4L2_BUF_TYPE_VBI_CAPTURE) \
276 log("type : VBI");\
277 \
278 if ((debug_mode & 0x8) && \
279 (f)->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) \
280 log("type : VIDEO");\
281 } while (0)
282#endif
diff --git a/drivers/media/video/tlg2300/pd-dvb.c b/drivers/media/video/tlg2300/pd-dvb.c
new file mode 100644
index 000000000000..4133aee568bf
--- /dev/null
+++ b/drivers/media/video/tlg2300/pd-dvb.c
@@ -0,0 +1,593 @@
1#include "pd-common.h"
2#include <linux/kernel.h>
3#include <linux/usb.h>
4#include <linux/dvb/dmx.h>
5#include <linux/delay.h>
6
7#include "vendorcmds.h"
8#include <linux/sched.h>
9#include <asm/atomic.h>
10
11static void dvb_urb_cleanup(struct pd_dvb_adapter *pd_dvb);
12
13static int dvb_bandwidth[][2] = {
14 { TLG_BW_8, BANDWIDTH_8_MHZ },
15 { TLG_BW_7, BANDWIDTH_7_MHZ },
16 { TLG_BW_6, BANDWIDTH_6_MHZ }
17};
18static int dvb_bandwidth_length = ARRAY_SIZE(dvb_bandwidth);
19
20static s32 dvb_start_streaming(struct pd_dvb_adapter *pd_dvb);
21static int poseidon_check_mode_dvbt(struct poseidon *pd)
22{
23 s32 ret = 0, cmd_status = 0;
24
25 set_current_state(TASK_INTERRUPTIBLE);
26 schedule_timeout(HZ/4);
27
28 ret = usb_set_interface(pd->udev, 0, BULK_ALTERNATE_IFACE);
29 if (ret != 0)
30 return ret;
31
32 ret = set_tuner_mode(pd, TLG_MODE_CAPS_DVB_T);
33 if (ret)
34 return ret;
35
36 /* signal source */
37 ret = send_set_req(pd, SGNL_SRC_SEL, TLG_SIG_SRC_ANTENNA, &cmd_status);
38 if (ret|cmd_status)
39 return ret;
40
41 return 0;
42}
43
44/* acquire :
45 * 1 == open
46 * 0 == release
47 */
48static int poseidon_ts_bus_ctrl(struct dvb_frontend *fe, int acquire)
49{
50 struct poseidon *pd = fe->demodulator_priv;
51 struct pd_dvb_adapter *pd_dvb;
52 int ret = 0;
53
54 if (!pd)
55 return -ENODEV;
56
57 pd_dvb = container_of(fe, struct pd_dvb_adapter, dvb_fe);
58 if (acquire) {
59 mutex_lock(&pd->lock);
60 if (pd->state & POSEIDON_STATE_DISCONNECT) {
61 ret = -ENODEV;
62 goto open_out;
63 }
64
65 if (pd->state && !(pd->state & POSEIDON_STATE_DVBT)) {
66 ret = -EBUSY;
67 goto open_out;
68 }
69
70 usb_autopm_get_interface(pd->interface);
71 if (0 == pd->state) {
72 ret = poseidon_check_mode_dvbt(pd);
73 if (ret < 0) {
74 usb_autopm_put_interface(pd->interface);
75 goto open_out;
76 }
77 pd->state |= POSEIDON_STATE_DVBT;
78 pd_dvb->bandwidth = 0;
79 pd_dvb->prev_freq = 0;
80 }
81 atomic_inc(&pd_dvb->users);
82 kref_get(&pd->kref);
83open_out:
84 mutex_unlock(&pd->lock);
85 } else {
86 dvb_stop_streaming(pd_dvb);
87
88 if (atomic_dec_and_test(&pd_dvb->users)) {
89 mutex_lock(&pd->lock);
90 pd->state &= ~POSEIDON_STATE_DVBT;
91 mutex_unlock(&pd->lock);
92 }
93 kref_put(&pd->kref, poseidon_delete);
94 usb_autopm_put_interface(pd->interface);
95 }
96 return ret;
97}
98
99static void poseidon_fe_release(struct dvb_frontend *fe)
100{
101 struct poseidon *pd = fe->demodulator_priv;
102
103#ifdef CONFIG_PM
104 pd->pm_suspend = NULL;
105 pd->pm_resume = NULL;
106#endif
107}
108
109static s32 poseidon_fe_sleep(struct dvb_frontend *fe)
110{
111 return 0;
112}
113
114/*
115 * return true if we can satisfy the conditions, else return false.
116 */
117static bool check_scan_ok(__u32 freq, int bandwidth,
118 struct pd_dvb_adapter *adapter)
119{
120 if (bandwidth < 0)
121 return false;
122
123 if (adapter->prev_freq == freq
124 && adapter->bandwidth == bandwidth) {
125 long nl = jiffies - adapter->last_jiffies;
126 unsigned int msec ;
127
128 msec = jiffies_to_msecs(abs(nl));
129 return msec > 15000 ? true : false;
130 }
131 return true;
132}
133
134/*
135 * Check if the firmware delays too long for an invalid frequency.
136 */
137static int fw_delay_overflow(struct pd_dvb_adapter *adapter)
138{
139 long nl = jiffies - adapter->last_jiffies;
140 unsigned int msec ;
141
142 msec = jiffies_to_msecs(abs(nl));
143 return msec > 800 ? true : false;
144}
145
146static int poseidon_set_fe(struct dvb_frontend *fe,
147 struct dvb_frontend_parameters *fep)
148{
149 s32 ret = 0, cmd_status = 0;
150 s32 i, bandwidth = -1;
151 struct poseidon *pd = fe->demodulator_priv;
152 struct pd_dvb_adapter *pd_dvb = &pd->dvb_data;
153
154 if (in_hibernation(pd))
155 return -EBUSY;
156
157 mutex_lock(&pd->lock);
158 for (i = 0; i < dvb_bandwidth_length; i++)
159 if (fep->u.ofdm.bandwidth == dvb_bandwidth[i][1])
160 bandwidth = dvb_bandwidth[i][0];
161
162 if (check_scan_ok(fep->frequency, bandwidth, pd_dvb)) {
163 ret = send_set_req(pd, TUNE_FREQ_SELECT,
164 fep->frequency / 1000, &cmd_status);
165 if (ret | cmd_status) {
166 log("error line");
167 goto front_out;
168 }
169
170 ret = send_set_req(pd, DVBT_BANDW_SEL,
171 bandwidth, &cmd_status);
172 if (ret | cmd_status) {
173 log("error line");
174 goto front_out;
175 }
176
177 ret = send_set_req(pd, TAKE_REQUEST, 0, &cmd_status);
178 if (ret | cmd_status) {
179 log("error line");
180 goto front_out;
181 }
182
183 /* save the context for future */
184 memcpy(&pd_dvb->fe_param, fep, sizeof(*fep));
185 pd_dvb->bandwidth = bandwidth;
186 pd_dvb->prev_freq = fep->frequency;
187 pd_dvb->last_jiffies = jiffies;
188 }
189front_out:
190 mutex_unlock(&pd->lock);
191 return ret;
192}
193
194#ifdef CONFIG_PM
195static int pm_dvb_suspend(struct poseidon *pd)
196{
197 struct pd_dvb_adapter *pd_dvb = &pd->dvb_data;
198 dvb_stop_streaming(pd_dvb);
199 dvb_urb_cleanup(pd_dvb);
200 msleep(500);
201 return 0;
202}
203
204static int pm_dvb_resume(struct poseidon *pd)
205{
206 struct pd_dvb_adapter *pd_dvb = &pd->dvb_data;
207
208 poseidon_check_mode_dvbt(pd);
209 msleep(300);
210 poseidon_set_fe(&pd_dvb->dvb_fe, &pd_dvb->fe_param);
211
212 dvb_start_streaming(pd_dvb);
213 return 0;
214}
215#endif
216
217static s32 poseidon_fe_init(struct dvb_frontend *fe)
218{
219 struct poseidon *pd = fe->demodulator_priv;
220 struct pd_dvb_adapter *pd_dvb = &pd->dvb_data;
221
222#ifdef CONFIG_PM
223 pd->pm_suspend = pm_dvb_suspend;
224 pd->pm_resume = pm_dvb_resume;
225#endif
226 memset(&pd_dvb->fe_param, 0,
227 sizeof(struct dvb_frontend_parameters));
228 return 0;
229}
230
231static int poseidon_get_fe(struct dvb_frontend *fe,
232 struct dvb_frontend_parameters *fep)
233{
234 struct poseidon *pd = fe->demodulator_priv;
235 struct pd_dvb_adapter *pd_dvb = &pd->dvb_data;
236
237 memcpy(fep, &pd_dvb->fe_param, sizeof(*fep));
238 return 0;
239}
240
241static int poseidon_fe_get_tune_settings(struct dvb_frontend *fe,
242 struct dvb_frontend_tune_settings *tune)
243{
244 tune->min_delay_ms = 1000;
245 return 0;
246}
247
248static int poseidon_read_status(struct dvb_frontend *fe, fe_status_t *stat)
249{
250 struct poseidon *pd = fe->demodulator_priv;
251 s32 ret = -1, cmd_status;
252 struct tuner_dtv_sig_stat_s status = {};
253
254 if (in_hibernation(pd))
255 return -EBUSY;
256 mutex_lock(&pd->lock);
257
258 ret = send_get_req(pd, TUNER_STATUS, TLG_MODE_DVB_T,
259 &status, &cmd_status, sizeof(status));
260 if (ret | cmd_status) {
261 log("get tuner status error");
262 goto out;
263 }
264
265 if (debug_mode)
266 log("P : %d, L %d, LB :%d", status.sig_present,
267 status.sig_locked, status.sig_lock_busy);
268
269 if (status.sig_lock_busy) {
270 goto out;
271 } else if (status.sig_present || status.sig_locked) {
272 *stat |= FE_HAS_LOCK | FE_HAS_SIGNAL | FE_HAS_CARRIER
273 | FE_HAS_SYNC | FE_HAS_VITERBI;
274 } else {
275 if (fw_delay_overflow(&pd->dvb_data))
276 *stat |= FE_TIMEDOUT;
277 }
278out:
279 mutex_unlock(&pd->lock);
280 return ret;
281}
282
283static int poseidon_read_ber(struct dvb_frontend *fe, u32 *ber)
284{
285 struct poseidon *pd = fe->demodulator_priv;
286 struct tuner_ber_rate_s tlg_ber = {};
287 s32 ret = -1, cmd_status;
288
289 mutex_lock(&pd->lock);
290 ret = send_get_req(pd, TUNER_BER_RATE, 0,
291 &tlg_ber, &cmd_status, sizeof(tlg_ber));
292 if (ret | cmd_status)
293 goto out;
294 *ber = tlg_ber.ber_rate;
295out:
296 mutex_unlock(&pd->lock);
297 return ret;
298}
299
300static s32 poseidon_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
301{
302 struct poseidon *pd = fe->demodulator_priv;
303 struct tuner_dtv_sig_stat_s status = {};
304 s32 ret = 0, cmd_status;
305
306 mutex_lock(&pd->lock);
307 ret = send_get_req(pd, TUNER_STATUS, TLG_MODE_DVB_T,
308 &status, &cmd_status, sizeof(status));
309 if (ret | cmd_status)
310 goto out;
311 if ((status.sig_present || status.sig_locked) && !status.sig_strength)
312 *strength = 0xFFFF;
313 else
314 *strength = status.sig_strength;
315out:
316 mutex_unlock(&pd->lock);
317 return ret;
318}
319
320static int poseidon_read_snr(struct dvb_frontend *fe, u16 *snr)
321{
322 return 0;
323}
324
325static int poseidon_read_unc_blocks(struct dvb_frontend *fe, u32 *unc)
326{
327 *unc = 0;
328 return 0;
329}
330
331static struct dvb_frontend_ops poseidon_frontend_ops = {
332 .info = {
333 .name = "Poseidon DVB-T",
334 .type = FE_OFDM,
335 .frequency_min = 174000000,
336 .frequency_max = 862000000,
337 .frequency_stepsize = 62500,/* FIXME */
338 .caps = FE_CAN_INVERSION_AUTO |
339 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
340 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
341 FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 |
342 FE_CAN_QAM_AUTO | FE_CAN_TRANSMISSION_MODE_AUTO |
343 FE_CAN_GUARD_INTERVAL_AUTO |
344 FE_CAN_RECOVER |
345 FE_CAN_HIERARCHY_AUTO,
346 },
347
348 .release = poseidon_fe_release,
349
350 .init = poseidon_fe_init,
351 .sleep = poseidon_fe_sleep,
352
353 .set_frontend = poseidon_set_fe,
354 .get_frontend = poseidon_get_fe,
355 .get_tune_settings = poseidon_fe_get_tune_settings,
356
357 .read_status = poseidon_read_status,
358 .read_ber = poseidon_read_ber,
359 .read_signal_strength = poseidon_read_signal_strength,
360 .read_snr = poseidon_read_snr,
361 .read_ucblocks = poseidon_read_unc_blocks,
362
363 .ts_bus_ctrl = poseidon_ts_bus_ctrl,
364};
365
366static void dvb_urb_irq(struct urb *urb)
367{
368 struct pd_dvb_adapter *pd_dvb = urb->context;
369 int len = urb->transfer_buffer_length;
370 struct dvb_demux *demux = &pd_dvb->demux;
371 s32 ret;
372
373 if (!pd_dvb->is_streaming || urb->status) {
374 if (urb->status == -EPROTO)
375 goto resend;
376 return;
377 }
378
379 if (urb->actual_length == len)
380 dvb_dmx_swfilter(demux, urb->transfer_buffer, len);
381 else if (urb->actual_length == len - 4) {
382 int offset;
383 u8 *buf = urb->transfer_buffer;
384
385 /*
386 * The packet size is 512,
387 * last packet contains 456 bytes tsp data
388 */
389 for (offset = 456; offset < len; offset += 512) {
390 if (!strncmp(buf + offset, "DVHS", 4)) {
391 dvb_dmx_swfilter(demux, buf, offset);
392 if (len > offset + 52 + 4) {
393 /*16 bytes trailer + 36 bytes padding */
394 buf += offset + 52;
395 len -= offset + 52 + 4;
396 dvb_dmx_swfilter(demux, buf, len);
397 }
398 break;
399 }
400 }
401 }
402
403resend:
404 ret = usb_submit_urb(urb, GFP_ATOMIC);
405 if (ret)
406 log(" usb_submit_urb failed: error %d", ret);
407}
408
409static int dvb_urb_init(struct pd_dvb_adapter *pd_dvb)
410{
411 if (pd_dvb->urb_array[0])
412 return 0;
413
414 alloc_bulk_urbs_generic(pd_dvb->urb_array, DVB_SBUF_NUM,
415 pd_dvb->pd_device->udev, pd_dvb->ep_addr,
416 DVB_URB_BUF_SIZE, GFP_KERNEL,
417 dvb_urb_irq, pd_dvb);
418 return 0;
419}
420
421static void dvb_urb_cleanup(struct pd_dvb_adapter *pd_dvb)
422{
423 free_all_urb_generic(pd_dvb->urb_array, DVB_SBUF_NUM);
424}
425
426static s32 dvb_start_streaming(struct pd_dvb_adapter *pd_dvb)
427{
428 struct poseidon *pd = pd_dvb->pd_device;
429 int ret = 0;
430
431 if (pd->state & POSEIDON_STATE_DISCONNECT)
432 return -ENODEV;
433
434 mutex_lock(&pd->lock);
435 if (!pd_dvb->is_streaming) {
436 s32 i, cmd_status = 0;
437 /*
438 * Once upon a time, there was a difficult bug lying here.
439 * ret = send_set_req(pd, TAKE_REQUEST, 0, &cmd_status);
440 */
441
442 ret = send_set_req(pd, PLAY_SERVICE, 1, &cmd_status);
443 if (ret | cmd_status)
444 goto out;
445
446 ret = dvb_urb_init(pd_dvb);
447 if (ret < 0)
448 goto out;
449
450 pd_dvb->is_streaming = 1;
451 for (i = 0; i < DVB_SBUF_NUM; i++) {
452 ret = usb_submit_urb(pd_dvb->urb_array[i],
453 GFP_KERNEL);
454 if (ret) {
455 log(" submit urb error %d", ret);
456 goto out;
457 }
458 }
459 }
460out:
461 mutex_unlock(&pd->lock);
462 return ret;
463}
464
465void dvb_stop_streaming(struct pd_dvb_adapter *pd_dvb)
466{
467 struct poseidon *pd = pd_dvb->pd_device;
468
469 mutex_lock(&pd->lock);
470 if (pd_dvb->is_streaming) {
471 s32 i, ret, cmd_status = 0;
472
473 pd_dvb->is_streaming = 0;
474
475 for (i = 0; i < DVB_SBUF_NUM; i++)
476 if (pd_dvb->urb_array[i])
477 usb_kill_urb(pd_dvb->urb_array[i]);
478
479 ret = send_set_req(pd, PLAY_SERVICE, TLG_TUNE_PLAY_SVC_STOP,
480 &cmd_status);
481 if (ret | cmd_status)
482 log("error");
483 }
484 mutex_unlock(&pd->lock);
485}
486
487static int pd_start_feed(struct dvb_demux_feed *feed)
488{
489 struct pd_dvb_adapter *pd_dvb = feed->demux->priv;
490 int ret = 0;
491
492 if (!pd_dvb)
493 return -1;
494 if (atomic_inc_return(&pd_dvb->active_feed) == 1)
495 ret = dvb_start_streaming(pd_dvb);
496 return ret;
497}
498
499static int pd_stop_feed(struct dvb_demux_feed *feed)
500{
501 struct pd_dvb_adapter *pd_dvb = feed->demux->priv;
502
503 if (!pd_dvb)
504 return -1;
505 if (atomic_dec_and_test(&pd_dvb->active_feed))
506 dvb_stop_streaming(pd_dvb);
507 return 0;
508}
509
510DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
511int pd_dvb_usb_device_init(struct poseidon *pd)
512{
513 struct pd_dvb_adapter *pd_dvb = &pd->dvb_data;
514 struct dvb_demux *dvbdemux;
515 int ret = 0;
516
517 pd_dvb->ep_addr = 0x82;
518 atomic_set(&pd_dvb->users, 0);
519 atomic_set(&pd_dvb->active_feed, 0);
520 pd_dvb->pd_device = pd;
521
522 ret = dvb_register_adapter(&pd_dvb->dvb_adap,
523 "Poseidon dvbt adapter",
524 THIS_MODULE,
525 NULL /* for hibernation correctly*/,
526 adapter_nr);
527 if (ret < 0)
528 goto error1;
529
530 /* register frontend */
531 pd_dvb->dvb_fe.demodulator_priv = pd;
532 memcpy(&pd_dvb->dvb_fe.ops, &poseidon_frontend_ops,
533 sizeof(struct dvb_frontend_ops));
534 ret = dvb_register_frontend(&pd_dvb->dvb_adap, &pd_dvb->dvb_fe);
535 if (ret < 0)
536 goto error2;
537
538 /* register demux device */
539 dvbdemux = &pd_dvb->demux;
540 dvbdemux->dmx.capabilities = DMX_TS_FILTERING | DMX_SECTION_FILTERING;
541 dvbdemux->priv = pd_dvb;
542 dvbdemux->feednum = dvbdemux->filternum = 64;
543 dvbdemux->start_feed = pd_start_feed;
544 dvbdemux->stop_feed = pd_stop_feed;
545 dvbdemux->write_to_decoder = NULL;
546
547 ret = dvb_dmx_init(dvbdemux);
548 if (ret < 0)
549 goto error3;
550
551 pd_dvb->dmxdev.filternum = pd_dvb->demux.filternum;
552 pd_dvb->dmxdev.demux = &pd_dvb->demux.dmx;
553 pd_dvb->dmxdev.capabilities = 0;
554
555 ret = dvb_dmxdev_init(&pd_dvb->dmxdev, &pd_dvb->dvb_adap);
556 if (ret < 0)
557 goto error3;
558 return 0;
559
560error3:
561 dvb_unregister_frontend(&pd_dvb->dvb_fe);
562error2:
563 dvb_unregister_adapter(&pd_dvb->dvb_adap);
564error1:
565 return ret;
566}
567
568void pd_dvb_usb_device_exit(struct poseidon *pd)
569{
570 struct pd_dvb_adapter *pd_dvb = &pd->dvb_data;
571
572 while (atomic_read(&pd_dvb->users) != 0
573 || atomic_read(&pd_dvb->active_feed) != 0) {
574 set_current_state(TASK_INTERRUPTIBLE);
575 schedule_timeout(HZ);
576 }
577 dvb_dmxdev_release(&pd_dvb->dmxdev);
578 dvb_unregister_frontend(&pd_dvb->dvb_fe);
579 dvb_unregister_adapter(&pd_dvb->dvb_adap);
580 pd_dvb_usb_device_cleanup(pd);
581}
582
583void pd_dvb_usb_device_cleanup(struct poseidon *pd)
584{
585 struct pd_dvb_adapter *pd_dvb = &pd->dvb_data;
586
587 dvb_urb_cleanup(pd_dvb);
588}
589
590int pd_dvb_get_adapter_num(struct pd_dvb_adapter *pd_dvb)
591{
592 return pd_dvb->dvb_adap.num;
593}
diff --git a/drivers/media/video/tlg2300/pd-main.c b/drivers/media/video/tlg2300/pd-main.c
new file mode 100644
index 000000000000..2cf0ebf9f28b
--- /dev/null
+++ b/drivers/media/video/tlg2300/pd-main.c
@@ -0,0 +1,539 @@
1/*
2 * device driver for Telegent tlg2300 based TV cards
3 *
4 * Author :
5 * Kang Yong <kangyong@telegent.com>
6 * Zhang Xiaobing <xbzhang@telegent.com>
7 * Huang Shijie <zyziii@telegent.com> or <shijie8@gmail.com>
8 *
9 * (c) 2009 Telegent Systems
10 * (c) 2010 Telegent Systems
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/version.h>
28#include <linux/kernel.h>
29#include <linux/errno.h>
30#include <linux/init.h>
31#include <linux/slab.h>
32#include <linux/module.h>
33#include <linux/kref.h>
34#include <linux/suspend.h>
35#include <linux/usb/quirks.h>
36#include <linux/ctype.h>
37#include <linux/string.h>
38#include <linux/types.h>
39#include <linux/firmware.h>
40#include <linux/smp_lock.h>
41
42#include "vendorcmds.h"
43#include "pd-common.h"
44
45#define VENDOR_ID 0x1B24
46#define PRODUCT_ID 0x4001
47static struct usb_device_id id_table[] = {
48 { USB_DEVICE_AND_INTERFACE_INFO(VENDOR_ID, PRODUCT_ID, 255, 1, 0) },
49 { USB_DEVICE_AND_INTERFACE_INFO(VENDOR_ID, PRODUCT_ID, 255, 1, 1) },
50 { },
51};
52MODULE_DEVICE_TABLE(usb, id_table);
53
54int debug_mode;
55module_param(debug_mode, int, 0644);
56MODULE_PARM_DESC(debug_mode, "0 = disable, 1 = enable, 2 = verbose");
57
58const char *firmware_name = "tlg2300_firmware.bin";
59struct usb_driver poseidon_driver;
60static LIST_HEAD(pd_device_list);
61
62/*
63 * send set request to USB firmware.
64 */
65s32 send_set_req(struct poseidon *pd, u8 cmdid, s32 param, s32 *cmd_status)
66{
67 s32 ret;
68 s8 data[32] = {};
69 u16 lower_16, upper_16;
70
71 if (pd->state & POSEIDON_STATE_DISCONNECT)
72 return -ENODEV;
73
74 mdelay(30);
75
76 if (param == 0) {
77 upper_16 = lower_16 = 0;
78 } else {
79 /* send 32 bit param as two 16 bit param,little endian */
80 lower_16 = (unsigned short)(param & 0xffff);
81 upper_16 = (unsigned short)((param >> 16) & 0xffff);
82 }
83 ret = usb_control_msg(pd->udev,
84 usb_rcvctrlpipe(pd->udev, 0),
85 REQ_SET_CMD | cmdid,
86 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
87 lower_16,
88 upper_16,
89 &data,
90 sizeof(*cmd_status),
91 USB_CTRL_GET_TIMEOUT);
92
93 if (!ret) {
94 return -ENXIO;
95 } else {
96 /* 1st 4 bytes into cmd_status */
97 memcpy((char *)cmd_status, &(data[0]), sizeof(*cmd_status));
98 }
99 return 0;
100}
101
102/*
103 * send get request to Poseidon firmware.
104 */
105s32 send_get_req(struct poseidon *pd, u8 cmdid, s32 param,
106 void *buf, s32 *cmd_status, s32 datalen)
107{
108 s32 ret;
109 s8 data[128] = {};
110 u16 lower_16, upper_16;
111
112 if (pd->state & POSEIDON_STATE_DISCONNECT)
113 return -ENODEV;
114
115 mdelay(30);
116 if (param == 0) {
117 upper_16 = lower_16 = 0;
118 } else {
119 /*send 32 bit param as two 16 bit param, little endian */
120 lower_16 = (unsigned short)(param & 0xffff);
121 upper_16 = (unsigned short)((param >> 16) & 0xffff);
122 }
123 ret = usb_control_msg(pd->udev,
124 usb_rcvctrlpipe(pd->udev, 0),
125 REQ_GET_CMD | cmdid,
126 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
127 lower_16,
128 upper_16,
129 &data,
130 (datalen + sizeof(*cmd_status)),
131 USB_CTRL_GET_TIMEOUT);
132
133 if (ret < 0) {
134 return -ENXIO;
135 } else {
136 /* 1st 4 bytes into cmd_status, remaining data into cmd_data */
137 memcpy((char *)cmd_status, &data[0], sizeof(*cmd_status));
138 memcpy((char *)buf, &data[sizeof(*cmd_status)], datalen);
139 }
140 return 0;
141}
142
143static int pm_notifier_block(struct notifier_block *nb,
144 unsigned long event, void *dummy)
145{
146 struct poseidon *pd = NULL;
147 struct list_head *node, *next;
148
149 switch (event) {
150 case PM_POST_HIBERNATION:
151 list_for_each_safe(node, next, &pd_device_list) {
152 struct usb_device *udev;
153 struct usb_interface *iface;
154 int rc = 0;
155
156 pd = container_of(node, struct poseidon, device_list);
157 udev = pd->udev;
158 iface = pd->interface;
159
160 /* It will cause the system to reload the firmware */
161 rc = usb_lock_device_for_reset(udev, iface);
162 if (rc >= 0) {
163 usb_reset_device(udev);
164 usb_unlock_device(udev);
165 }
166 }
167 break;
168 default:
169 break;
170 }
171 log("event :%ld\n", event);
172 return 0;
173}
174
175static struct notifier_block pm_notifer = {
176 .notifier_call = pm_notifier_block,
177};
178
179int set_tuner_mode(struct poseidon *pd, unsigned char mode)
180{
181 s32 ret, cmd_status;
182
183 if (pd->state & POSEIDON_STATE_DISCONNECT)
184 return -ENODEV;
185
186 ret = send_set_req(pd, TUNE_MODE_SELECT, mode, &cmd_status);
187 if (ret || cmd_status)
188 return -ENXIO;
189 return 0;
190}
191
192void poseidon_delete(struct kref *kref)
193{
194 struct poseidon *pd = container_of(kref, struct poseidon, kref);
195
196 if (!pd)
197 return;
198 list_del_init(&pd->device_list);
199
200 pd_dvb_usb_device_cleanup(pd);
201 /* clean_audio_data(&pd->audio_data);*/
202
203 if (pd->udev) {
204 usb_put_dev(pd->udev);
205 pd->udev = NULL;
206 }
207 if (pd->interface) {
208 usb_put_intf(pd->interface);
209 pd->interface = NULL;
210 }
211 kfree(pd);
212 log();
213}
214
215static int firmware_download(struct usb_device *udev)
216{
217 int ret = 0, actual_length;
218 const struct firmware *fw = NULL;
219 void *fwbuf = NULL;
220 size_t fwlength = 0, offset;
221 size_t max_packet_size;
222
223 ret = request_firmware(&fw, firmware_name, &udev->dev);
224 if (ret) {
225 log("download err : %d", ret);
226 return ret;
227 }
228
229 fwlength = fw->size;
230
231 fwbuf = kzalloc(fwlength, GFP_KERNEL);
232 if (!fwbuf) {
233 ret = -ENOMEM;
234 goto out;
235 }
236 memcpy(fwbuf, fw->data, fwlength);
237
238 max_packet_size = udev->ep_out[0x1]->desc.wMaxPacketSize;
239 log("\t\t download size : %d", (int)max_packet_size);
240
241 for (offset = 0; offset < fwlength; offset += max_packet_size) {
242 actual_length = 0;
243 ret = usb_bulk_msg(udev,
244 usb_sndbulkpipe(udev, 0x01), /* ep 1 */
245 fwbuf + offset,
246 min(max_packet_size, fwlength - offset),
247 &actual_length,
248 HZ * 10);
249 if (ret)
250 break;
251 }
252 kfree(fwbuf);
253out:
254 release_firmware(fw);
255 return ret;
256}
257
258static inline struct poseidon *get_pd(struct usb_interface *intf)
259{
260 return usb_get_intfdata(intf);
261}
262
263#ifdef CONFIG_PM
264/* one-to-one map : poseidon{} <----> usb_device{}'s port */
265static inline void set_map_flags(struct poseidon *pd, struct usb_device *udev)
266{
267 pd->portnum = udev->portnum;
268}
269
270static inline int get_autopm_ref(struct poseidon *pd)
271{
272 return pd->video_data.users + pd->vbi_data.users + pd->audio.users
273 + atomic_read(&pd->dvb_data.users) + pd->radio_data.users;
274}
275
276/* fixup something for poseidon */
277static inline struct poseidon *fixup(struct poseidon *pd)
278{
279 int count;
280
281 /* old udev and interface have gone, so put back reference . */
282 count = get_autopm_ref(pd);
283 log("count : %d, ref count : %d", count, get_pm_count(pd));
284 while (count--)
285 usb_autopm_put_interface(pd->interface);
286 /*usb_autopm_set_interface(pd->interface); */
287
288 usb_put_dev(pd->udev);
289 usb_put_intf(pd->interface);
290 log("event : %d\n", pd->msg.event);
291 return pd;
292}
293
294static struct poseidon *find_old_poseidon(struct usb_device *udev)
295{
296 struct poseidon *pd;
297
298 list_for_each_entry(pd, &pd_device_list, device_list) {
299 if (pd->portnum == udev->portnum && in_hibernation(pd))
300 return fixup(pd);
301 }
302 return NULL;
303}
304
305/* Is the card working now ? */
306static inline int is_working(struct poseidon *pd)
307{
308 return get_pm_count(pd) > 0;
309}
310
311static int poseidon_suspend(struct usb_interface *intf, pm_message_t msg)
312{
313 struct poseidon *pd = get_pd(intf);
314
315 if (!pd)
316 return 0;
317 if (!is_working(pd)) {
318 if (get_pm_count(pd) <= 0 && !in_hibernation(pd)) {
319 pd->msg.event = PM_EVENT_AUTO_SUSPEND;
320 pd->pm_resume = NULL; /* a good guard */
321 printk(KERN_DEBUG "\n\t+ TLG2300 auto suspend +\n\n");
322 }
323 return 0;
324 }
325 pd->msg = msg; /* save it here */
326 logpm(pd);
327 return pd->pm_suspend ? pd->pm_suspend(pd) : 0;
328}
329
330static int poseidon_resume(struct usb_interface *intf)
331{
332 struct poseidon *pd = get_pd(intf);
333
334 if (!pd)
335 return 0;
336 printk(KERN_DEBUG "\n\t ++ TLG2300 resume ++\n\n");
337
338 if (!is_working(pd)) {
339 if (PM_EVENT_AUTO_SUSPEND == pd->msg.event)
340 pd->msg = PMSG_ON;
341 return 0;
342 }
343 if (in_hibernation(pd)) {
344 logpm(pd);
345 return 0;
346 }
347 logpm(pd);
348 return pd->pm_resume ? pd->pm_resume(pd) : 0;
349}
350
351static void hibernation_resume(struct work_struct *w)
352{
353 struct poseidon *pd = container_of(w, struct poseidon, pm_work);
354 int count;
355
356 pd->msg.event = 0; /* clear it here */
357 pd->state &= ~POSEIDON_STATE_DISCONNECT;
358
359 /* set the new interface's reference */
360 count = get_autopm_ref(pd);
361 while (count--)
362 usb_autopm_get_interface(pd->interface);
363
364 /* resume the context */
365 logpm(pd);
366 if (pd->pm_resume)
367 pd->pm_resume(pd);
368}
369#else /* CONFIG_PM is not enabled: */
370static inline struct poseidon *find_old_poseidon(struct usb_device *udev)
371{
372 return NULL;
373}
374
375static inline void set_map_flags(struct poseidon *pd, struct usb_device *udev)
376{
377}
378#endif
379
380static bool check_firmware(struct usb_device *udev, int *down_firmware)
381{
382 void *buf;
383 int ret;
384 struct cmd_firmware_vers_s *cmd_firm;
385
386 buf = kzalloc(sizeof(*cmd_firm) + sizeof(u32), GFP_KERNEL);
387 if (!buf)
388 return -ENOMEM;
389 ret = usb_control_msg(udev,
390 usb_rcvctrlpipe(udev, 0),
391 REQ_GET_CMD | GET_FW_ID,
392 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
393 0,
394 0,
395 buf,
396 sizeof(*cmd_firm) + sizeof(u32),
397 USB_CTRL_GET_TIMEOUT);
398 kfree(buf);
399
400 if (ret < 0) {
401 *down_firmware = 1;
402 return firmware_download(udev);
403 }
404 return ret;
405}
406
407static int poseidon_probe(struct usb_interface *interface,
408 const struct usb_device_id *id)
409{
410 struct usb_device *udev = interface_to_usbdev(interface);
411 struct poseidon *pd = NULL;
412 int ret = 0;
413 int new_one = 0;
414
415 /* download firmware */
416 check_firmware(udev, &ret);
417 if (ret)
418 return 0;
419
420 /* Do I recovery from the hibernate ? */
421 pd = find_old_poseidon(udev);
422 if (!pd) {
423 pd = kzalloc(sizeof(*pd), GFP_KERNEL);
424 if (!pd)
425 return -ENOMEM;
426 kref_init(&pd->kref);
427 set_map_flags(pd, udev);
428 new_one = 1;
429 }
430
431 pd->udev = usb_get_dev(udev);
432 pd->interface = usb_get_intf(interface);
433 usb_set_intfdata(interface, pd);
434
435 if (new_one) {
436 struct device *dev = &interface->dev;
437
438 logpm(pd);
439 mutex_init(&pd->lock);
440
441 /* register v4l2 device */
442 snprintf(pd->v4l2_dev.name, sizeof(pd->v4l2_dev.name), "%s %s",
443 dev->driver->name, dev_name(dev));
444 ret = v4l2_device_register(NULL, &pd->v4l2_dev);
445
446 /* register devices in directory /dev */
447 ret = pd_video_init(pd);
448 poseidon_audio_init(pd);
449 poseidon_fm_init(pd);
450 pd_dvb_usb_device_init(pd);
451
452 INIT_LIST_HEAD(&pd->device_list);
453 list_add_tail(&pd->device_list, &pd_device_list);
454 }
455
456 device_init_wakeup(&udev->dev, 1);
457#ifdef CONFIG_PM
458 pd->udev->autosuspend_disabled = 0;
459 pd->udev->autosuspend_delay = HZ * PM_SUSPEND_DELAY;
460
461 if (in_hibernation(pd)) {
462 INIT_WORK(&pd->pm_work, hibernation_resume);
463 schedule_work(&pd->pm_work);
464 }
465#endif
466 return 0;
467}
468
469static void poseidon_disconnect(struct usb_interface *interface)
470{
471 struct poseidon *pd = get_pd(interface);
472
473 if (!pd)
474 return;
475 logpm(pd);
476 if (in_hibernation(pd))
477 return;
478
479 mutex_lock(&pd->lock);
480 pd->state |= POSEIDON_STATE_DISCONNECT;
481 mutex_unlock(&pd->lock);
482
483 /* stop urb transferring */
484 stop_all_video_stream(pd);
485 dvb_stop_streaming(&pd->dvb_data);
486
487 /*unregister v4l2 device */
488 v4l2_device_unregister(&pd->v4l2_dev);
489
490 lock_kernel();
491 {
492 pd_dvb_usb_device_exit(pd);
493 poseidon_fm_exit(pd);
494
495 poseidon_audio_free(pd);
496 pd_video_exit(pd);
497 }
498 unlock_kernel();
499
500 usb_set_intfdata(interface, NULL);
501 kref_put(&pd->kref, poseidon_delete);
502}
503
504struct usb_driver poseidon_driver = {
505 .name = "poseidon",
506 .probe = poseidon_probe,
507 .disconnect = poseidon_disconnect,
508 .id_table = id_table,
509#ifdef CONFIG_PM
510 .suspend = poseidon_suspend,
511 .resume = poseidon_resume,
512#endif
513 .supports_autosuspend = 1,
514};
515
516static int __init poseidon_init(void)
517{
518 int ret;
519
520 ret = usb_register(&poseidon_driver);
521 if (ret)
522 return ret;
523 register_pm_notifier(&pm_notifer);
524 return ret;
525}
526
527static void __exit poseidon_exit(void)
528{
529 log();
530 unregister_pm_notifier(&pm_notifer);
531 usb_deregister(&poseidon_driver);
532}
533
534module_init(poseidon_init);
535module_exit(poseidon_exit);
536
537MODULE_AUTHOR("Telegent Systems");
538MODULE_DESCRIPTION("For tlg2300-based USB device ");
539MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/tlg2300/pd-radio.c b/drivers/media/video/tlg2300/pd-radio.c
new file mode 100644
index 000000000000..755766b15157
--- /dev/null
+++ b/drivers/media/video/tlg2300/pd-radio.c
@@ -0,0 +1,420 @@
1#include <linux/init.h>
2#include <linux/list.h>
3#include <linux/module.h>
4#include <linux/kernel.h>
5#include <linux/bitmap.h>
6#include <linux/usb.h>
7#include <linux/i2c.h>
8#include <media/v4l2-dev.h>
9#include <linux/version.h>
10#include <linux/mm.h>
11#include <linux/mutex.h>
12#include <media/v4l2-ioctl.h>
13#include <linux/sched.h>
14
15#include "pd-common.h"
16#include "vendorcmds.h"
17
18static int set_frequency(struct poseidon *p, __u32 frequency);
19static int poseidon_fm_close(struct file *filp);
20static int poseidon_fm_open(struct file *filp);
21
22#define TUNER_FREQ_MIN_FM 76000000
23#define TUNER_FREQ_MAX_FM 108000000
24
25#define MAX_PREEMPHASIS (V4L2_PREEMPHASIS_75_uS + 1)
26static int preemphasis[MAX_PREEMPHASIS] = {
27 TLG_TUNE_ASTD_NONE, /* V4L2_PREEMPHASIS_DISABLED */
28 TLG_TUNE_ASTD_FM_EUR, /* V4L2_PREEMPHASIS_50_uS */
29 TLG_TUNE_ASTD_FM_US, /* V4L2_PREEMPHASIS_75_uS */
30};
31
32static int poseidon_check_mode_radio(struct poseidon *p)
33{
34 int ret;
35 u32 status;
36
37 set_current_state(TASK_INTERRUPTIBLE);
38 schedule_timeout(HZ/2);
39 ret = usb_set_interface(p->udev, 0, BULK_ALTERNATE_IFACE);
40 if (ret < 0)
41 goto out;
42
43 ret = set_tuner_mode(p, TLG_MODE_FM_RADIO);
44 if (ret != 0)
45 goto out;
46
47 ret = send_set_req(p, SGNL_SRC_SEL, TLG_SIG_SRC_ANTENNA, &status);
48 ret = send_set_req(p, TUNER_AUD_ANA_STD,
49 p->radio_data.pre_emphasis, &status);
50 ret |= send_set_req(p, TUNER_AUD_MODE,
51 TLG_TUNE_TVAUDIO_MODE_STEREO, &status);
52 ret |= send_set_req(p, AUDIO_SAMPLE_RATE_SEL,
53 ATV_AUDIO_RATE_48K, &status);
54 ret |= send_set_req(p, TUNE_FREQ_SELECT, TUNER_FREQ_MIN_FM, &status);
55out:
56 return ret;
57}
58
59#ifdef CONFIG_PM
60static int pm_fm_suspend(struct poseidon *p)
61{
62 logpm(p);
63 pm_alsa_suspend(p);
64 usb_set_interface(p->udev, 0, 0);
65 msleep(300);
66 return 0;
67}
68
69static int pm_fm_resume(struct poseidon *p)
70{
71 logpm(p);
72 poseidon_check_mode_radio(p);
73 set_frequency(p, p->radio_data.fm_freq);
74 pm_alsa_resume(p);
75 return 0;
76}
77#endif
78
79static int poseidon_fm_open(struct file *filp)
80{
81 struct video_device *vfd = video_devdata(filp);
82 struct poseidon *p = video_get_drvdata(vfd);
83 int ret = 0;
84
85 if (!p)
86 return -1;
87
88 mutex_lock(&p->lock);
89 if (p->state & POSEIDON_STATE_DISCONNECT) {
90 ret = -ENODEV;
91 goto out;
92 }
93
94 if (p->state && !(p->state & POSEIDON_STATE_FM)) {
95 ret = -EBUSY;
96 goto out;
97 }
98
99 usb_autopm_get_interface(p->interface);
100 if (0 == p->state) {
101 /* default pre-emphasis */
102 if (p->radio_data.pre_emphasis == 0)
103 p->radio_data.pre_emphasis = TLG_TUNE_ASTD_FM_EUR;
104 set_debug_mode(vfd, debug_mode);
105
106 ret = poseidon_check_mode_radio(p);
107 if (ret < 0) {
108 usb_autopm_put_interface(p->interface);
109 goto out;
110 }
111 p->state |= POSEIDON_STATE_FM;
112 }
113 p->radio_data.users++;
114 kref_get(&p->kref);
115 filp->private_data = p;
116out:
117 mutex_unlock(&p->lock);
118 return ret;
119}
120
121static int poseidon_fm_close(struct file *filp)
122{
123 struct poseidon *p = filp->private_data;
124 struct radio_data *fm = &p->radio_data;
125 uint32_t status;
126
127 mutex_lock(&p->lock);
128 fm->users--;
129 if (0 == fm->users)
130 p->state &= ~POSEIDON_STATE_FM;
131
132 if (fm->is_radio_streaming && filp == p->file_for_stream) {
133 fm->is_radio_streaming = 0;
134 send_set_req(p, PLAY_SERVICE, TLG_TUNE_PLAY_SVC_STOP, &status);
135 }
136 usb_autopm_put_interface(p->interface);
137 mutex_unlock(&p->lock);
138
139 kref_put(&p->kref, poseidon_delete);
140 filp->private_data = NULL;
141 return 0;
142}
143
144static int vidioc_querycap(struct file *file, void *priv,
145 struct v4l2_capability *v)
146{
147 struct poseidon *p = file->private_data;
148
149 strlcpy(v->driver, "tele-radio", sizeof(v->driver));
150 strlcpy(v->card, "Telegent Poseidon", sizeof(v->card));
151 usb_make_path(p->udev, v->bus_info, sizeof(v->bus_info));
152 v->version = KERNEL_VERSION(0, 0, 1);
153 v->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO;
154 return 0;
155}
156
157static const struct v4l2_file_operations poseidon_fm_fops = {
158 .owner = THIS_MODULE,
159 .open = poseidon_fm_open,
160 .release = poseidon_fm_close,
161 .ioctl = video_ioctl2,
162};
163
164int tlg_fm_vidioc_g_tuner(struct file *file, void *priv, struct v4l2_tuner *vt)
165{
166 struct tuner_fm_sig_stat_s fm_stat = {};
167 int ret, status, count = 5;
168 struct poseidon *p = file->private_data;
169
170 if (vt->index != 0)
171 return -EINVAL;
172
173 vt->type = V4L2_TUNER_RADIO;
174 vt->capability = V4L2_TUNER_CAP_STEREO;
175 vt->rangelow = TUNER_FREQ_MIN_FM / 62500;
176 vt->rangehigh = TUNER_FREQ_MAX_FM / 62500;
177 vt->rxsubchans = V4L2_TUNER_SUB_STEREO;
178 vt->audmode = V4L2_TUNER_MODE_STEREO;
179 vt->signal = 0;
180 vt->afc = 0;
181
182 mutex_lock(&p->lock);
183 ret = send_get_req(p, TUNER_STATUS, TLG_MODE_FM_RADIO,
184 &fm_stat, &status, sizeof(fm_stat));
185
186 while (fm_stat.sig_lock_busy && count-- && !ret) {
187 set_current_state(TASK_INTERRUPTIBLE);
188 schedule_timeout(HZ);
189
190 ret = send_get_req(p, TUNER_STATUS, TLG_MODE_FM_RADIO,
191 &fm_stat, &status, sizeof(fm_stat));
192 }
193 mutex_unlock(&p->lock);
194
195 if (ret || status) {
196 vt->signal = 0;
197 } else if ((fm_stat.sig_present || fm_stat.sig_locked)
198 && fm_stat.sig_strength == 0) {
199 vt->signal = 0xffff;
200 } else
201 vt->signal = (fm_stat.sig_strength * 255 / 10) << 8;
202
203 return 0;
204}
205
206int fm_get_freq(struct file *file, void *priv, struct v4l2_frequency *argp)
207{
208 struct poseidon *p = file->private_data;
209
210 argp->frequency = p->radio_data.fm_freq;
211 return 0;
212}
213
214static int set_frequency(struct poseidon *p, __u32 frequency)
215{
216 __u32 freq ;
217 int ret, status;
218
219 mutex_lock(&p->lock);
220
221 ret = send_set_req(p, TUNER_AUD_ANA_STD,
222 p->radio_data.pre_emphasis, &status);
223
224 freq = (frequency * 125) * 500 / 1000;/* kHZ */
225 if (freq < TUNER_FREQ_MIN_FM/1000 || freq > TUNER_FREQ_MAX_FM/1000) {
226 ret = -EINVAL;
227 goto error;
228 }
229
230 ret = send_set_req(p, TUNE_FREQ_SELECT, freq, &status);
231 if (ret < 0)
232 goto error ;
233 ret = send_set_req(p, TAKE_REQUEST, 0, &status);
234
235 set_current_state(TASK_INTERRUPTIBLE);
236 schedule_timeout(HZ/4);
237 if (!p->radio_data.is_radio_streaming) {
238 ret = send_set_req(p, TAKE_REQUEST, 0, &status);
239 ret = send_set_req(p, PLAY_SERVICE,
240 TLG_TUNE_PLAY_SVC_START, &status);
241 p->radio_data.is_radio_streaming = 1;
242 }
243 p->radio_data.fm_freq = frequency;
244error:
245 mutex_unlock(&p->lock);
246 return ret;
247}
248
249int fm_set_freq(struct file *file, void *priv, struct v4l2_frequency *argp)
250{
251 struct poseidon *p = file->private_data;
252
253 p->file_for_stream = file;
254#ifdef CONFIG_PM
255 p->pm_suspend = pm_fm_suspend;
256 p->pm_resume = pm_fm_resume;
257#endif
258 return set_frequency(p, argp->frequency);
259}
260
261int tlg_fm_vidioc_g_ctrl(struct file *file, void *priv,
262 struct v4l2_control *arg)
263{
264 return 0;
265}
266
267int tlg_fm_vidioc_g_exts_ctrl(struct file *file, void *fh,
268 struct v4l2_ext_controls *ctrls)
269{
270 struct poseidon *p = file->private_data;
271 int i;
272
273 if (ctrls->ctrl_class != V4L2_CTRL_CLASS_FM_TX)
274 return -EINVAL;
275
276 for (i = 0; i < ctrls->count; i++) {
277 struct v4l2_ext_control *ctrl = ctrls->controls + i;
278
279 if (ctrl->id != V4L2_CID_TUNE_PREEMPHASIS)
280 continue;
281
282 if (i < MAX_PREEMPHASIS)
283 ctrl->value = p->radio_data.pre_emphasis;
284 }
285 return 0;
286}
287
288int tlg_fm_vidioc_s_exts_ctrl(struct file *file, void *fh,
289 struct v4l2_ext_controls *ctrls)
290{
291 int i;
292
293 if (ctrls->ctrl_class != V4L2_CTRL_CLASS_FM_TX)
294 return -EINVAL;
295
296 for (i = 0; i < ctrls->count; i++) {
297 struct v4l2_ext_control *ctrl = ctrls->controls + i;
298
299 if (ctrl->id != V4L2_CID_TUNE_PREEMPHASIS)
300 continue;
301
302 if (ctrl->value >= 0 && ctrl->value < MAX_PREEMPHASIS) {
303 struct poseidon *p = file->private_data;
304 int pre_emphasis = preemphasis[ctrl->value];
305 u32 status;
306
307 send_set_req(p, TUNER_AUD_ANA_STD,
308 pre_emphasis, &status);
309 p->radio_data.pre_emphasis = pre_emphasis;
310 }
311 }
312 return 0;
313}
314
315int tlg_fm_vidioc_s_ctrl(struct file *file, void *priv,
316 struct v4l2_control *ctrl)
317{
318 return 0;
319}
320
321int tlg_fm_vidioc_queryctrl(struct file *file, void *priv,
322 struct v4l2_queryctrl *ctrl)
323{
324 if (!(ctrl->id & V4L2_CTRL_FLAG_NEXT_CTRL))
325 return -EINVAL;
326
327 ctrl->id &= ~V4L2_CTRL_FLAG_NEXT_CTRL;
328 if (ctrl->id != V4L2_CID_TUNE_PREEMPHASIS) {
329 /* return the next supported control */
330 ctrl->id = V4L2_CID_TUNE_PREEMPHASIS;
331 v4l2_ctrl_query_fill(ctrl, V4L2_PREEMPHASIS_DISABLED,
332 V4L2_PREEMPHASIS_75_uS, 1,
333 V4L2_PREEMPHASIS_50_uS);
334 ctrl->flags = V4L2_CTRL_FLAG_UPDATE;
335 return 0;
336 }
337 return -EINVAL;
338}
339
340int tlg_fm_vidioc_querymenu(struct file *file, void *fh,
341 struct v4l2_querymenu *qmenu)
342{
343 return v4l2_ctrl_query_menu(qmenu, NULL, NULL);
344}
345
346static int vidioc_s_tuner(struct file *file, void *priv, struct v4l2_tuner *vt)
347{
348 return vt->index > 0 ? -EINVAL : 0;
349}
350static int vidioc_s_audio(struct file *file, void *priv, struct v4l2_audio *va)
351{
352 return (va->index != 0) ? -EINVAL : 0;
353}
354
355static int vidioc_g_audio(struct file *file, void *priv, struct v4l2_audio *a)
356{
357 a->index = 0;
358 a->mode = 0;
359 a->capability = V4L2_AUDCAP_STEREO;
360 strcpy(a->name, "Radio");
361 return 0;
362}
363
364static int vidioc_s_input(struct file *filp, void *priv, u32 i)
365{
366 return (i != 0) ? -EINVAL : 0;
367}
368
369static int vidioc_g_input(struct file *filp, void *priv, u32 *i)
370{
371 return (*i != 0) ? -EINVAL : 0;
372}
373
374static const struct v4l2_ioctl_ops poseidon_fm_ioctl_ops = {
375 .vidioc_querycap = vidioc_querycap,
376 .vidioc_g_audio = vidioc_g_audio,
377 .vidioc_s_audio = vidioc_s_audio,
378 .vidioc_g_input = vidioc_g_input,
379 .vidioc_s_input = vidioc_s_input,
380 .vidioc_queryctrl = tlg_fm_vidioc_queryctrl,
381 .vidioc_querymenu = tlg_fm_vidioc_querymenu,
382 .vidioc_g_ctrl = tlg_fm_vidioc_g_ctrl,
383 .vidioc_s_ctrl = tlg_fm_vidioc_s_ctrl,
384 .vidioc_s_ext_ctrls = tlg_fm_vidioc_s_exts_ctrl,
385 .vidioc_g_ext_ctrls = tlg_fm_vidioc_g_exts_ctrl,
386 .vidioc_s_tuner = vidioc_s_tuner,
387 .vidioc_g_tuner = tlg_fm_vidioc_g_tuner,
388 .vidioc_g_frequency = fm_get_freq,
389 .vidioc_s_frequency = fm_set_freq,
390};
391
392static struct video_device poseidon_fm_template = {
393 .name = "Telegent-Radio",
394 .fops = &poseidon_fm_fops,
395 .minor = -1,
396 .release = video_device_release,
397 .ioctl_ops = &poseidon_fm_ioctl_ops,
398};
399
400int poseidon_fm_init(struct poseidon *p)
401{
402 struct video_device *fm_dev;
403
404 fm_dev = vdev_init(p, &poseidon_fm_template);
405 if (fm_dev == NULL)
406 return -1;
407
408 if (video_register_device(fm_dev, VFL_TYPE_RADIO, -1) < 0) {
409 video_device_release(fm_dev);
410 return -1;
411 }
412 p->radio_data.fm_dev = fm_dev;
413 return 0;
414}
415
416int poseidon_fm_exit(struct poseidon *p)
417{
418 destroy_video_device(&p->radio_data.fm_dev);
419 return 0;
420}
diff --git a/drivers/media/video/tlg2300/pd-video.c b/drivers/media/video/tlg2300/pd-video.c
new file mode 100644
index 000000000000..becfba6a3041
--- /dev/null
+++ b/drivers/media/video/tlg2300/pd-video.c
@@ -0,0 +1,1667 @@
1#include <linux/fs.h>
2#include <linux/vmalloc.h>
3#include <linux/videodev2.h>
4#include <linux/usb.h>
5#include <linux/mm.h>
6#include <linux/sched.h>
7
8#include <media/v4l2-ioctl.h>
9#include <media/v4l2-dev.h>
10
11#include "pd-common.h"
12#include "vendorcmds.h"
13
14static int pm_video_suspend(struct poseidon *pd);
15static int pm_video_resume(struct poseidon *pd);
16static void iso_bubble_handler(struct work_struct *w);
17
18int usb_transfer_mode;
19module_param(usb_transfer_mode, int, 0644);
20MODULE_PARM_DESC(usb_transfer_mode, "0 = Bulk, 1 = Isochronous");
21
22static const struct poseidon_format poseidon_formats[] = {
23 { "YUV 422", V4L2_PIX_FMT_YUYV, 16, 0},
24 { "RGB565", V4L2_PIX_FMT_RGB565, 16, 0},
25};
26
27static const struct poseidon_tvnorm poseidon_tvnorms[] = {
28 { V4L2_STD_PAL_D, "PAL-D", TLG_TUNE_VSTD_PAL_D },
29 { V4L2_STD_PAL_B, "PAL-B", TLG_TUNE_VSTD_PAL_B },
30 { V4L2_STD_PAL_G, "PAL-G", TLG_TUNE_VSTD_PAL_G },
31 { V4L2_STD_PAL_H, "PAL-H", TLG_TUNE_VSTD_PAL_H },
32 { V4L2_STD_PAL_I, "PAL-I", TLG_TUNE_VSTD_PAL_I },
33 { V4L2_STD_PAL_M, "PAL-M", TLG_TUNE_VSTD_PAL_M },
34 { V4L2_STD_PAL_N, "PAL-N", TLG_TUNE_VSTD_PAL_N_COMBO },
35 { V4L2_STD_PAL_Nc, "PAL-Nc", TLG_TUNE_VSTD_PAL_N_COMBO },
36 { V4L2_STD_NTSC_M, "NTSC-M", TLG_TUNE_VSTD_NTSC_M },
37 { V4L2_STD_NTSC_M_JP, "NTSC-JP", TLG_TUNE_VSTD_NTSC_M_J },
38 { V4L2_STD_SECAM_B, "SECAM-B", TLG_TUNE_VSTD_SECAM_B },
39 { V4L2_STD_SECAM_D, "SECAM-D", TLG_TUNE_VSTD_SECAM_D },
40 { V4L2_STD_SECAM_G, "SECAM-G", TLG_TUNE_VSTD_SECAM_G },
41 { V4L2_STD_SECAM_H, "SECAM-H", TLG_TUNE_VSTD_SECAM_H },
42 { V4L2_STD_SECAM_K, "SECAM-K", TLG_TUNE_VSTD_SECAM_K },
43 { V4L2_STD_SECAM_K1, "SECAM-K1", TLG_TUNE_VSTD_SECAM_K1 },
44 { V4L2_STD_SECAM_L, "SECAM-L", TLG_TUNE_VSTD_SECAM_L },
45 { V4L2_STD_SECAM_LC, "SECAM-LC", TLG_TUNE_VSTD_SECAM_L1 },
46};
47static const unsigned int POSEIDON_TVNORMS = ARRAY_SIZE(poseidon_tvnorms);
48
49struct pd_audio_mode {
50 u32 tlg_audio_mode;
51 u32 v4l2_audio_sub;
52 u32 v4l2_audio_mode;
53};
54
55static const struct pd_audio_mode pd_audio_modes[] = {
56 { TLG_TUNE_TVAUDIO_MODE_MONO, V4L2_TUNER_SUB_MONO,
57 V4L2_TUNER_MODE_MONO },
58 { TLG_TUNE_TVAUDIO_MODE_STEREO, V4L2_TUNER_SUB_STEREO,
59 V4L2_TUNER_MODE_STEREO },
60 { TLG_TUNE_TVAUDIO_MODE_LANG_A, V4L2_TUNER_SUB_LANG1,
61 V4L2_TUNER_MODE_LANG1 },
62 { TLG_TUNE_TVAUDIO_MODE_LANG_B, V4L2_TUNER_SUB_LANG2,
63 V4L2_TUNER_MODE_LANG2 },
64 { TLG_TUNE_TVAUDIO_MODE_LANG_C, V4L2_TUNER_SUB_LANG1,
65 V4L2_TUNER_MODE_LANG1_LANG2 }
66};
67static const unsigned int POSEIDON_AUDIOMODS = ARRAY_SIZE(pd_audio_modes);
68
69struct pd_input {
70 char *name;
71 uint32_t tlg_src;
72};
73
74static const struct pd_input pd_inputs[] = {
75 { "TV Antenna", TLG_SIG_SRC_ANTENNA },
76 { "TV Cable", TLG_SIG_SRC_CABLE },
77 { "TV SVideo", TLG_SIG_SRC_SVIDEO },
78 { "TV Composite", TLG_SIG_SRC_COMPOSITE }
79};
80static const unsigned int POSEIDON_INPUTS = ARRAY_SIZE(pd_inputs);
81
82struct poseidon_control {
83 struct v4l2_queryctrl v4l2_ctrl;
84 enum cmd_custom_param_id vc_id;
85};
86
87static struct poseidon_control controls[] = {
88 {
89 { V4L2_CID_BRIGHTNESS, V4L2_CTRL_TYPE_INTEGER,
90 "brightness", 0, 10000, 1, 100, 0, },
91 CUST_PARM_ID_BRIGHTNESS_CTRL
92 }, {
93 { V4L2_CID_CONTRAST, V4L2_CTRL_TYPE_INTEGER,
94 "contrast", 0, 10000, 1, 100, 0, },
95 CUST_PARM_ID_CONTRAST_CTRL,
96 }, {
97 { V4L2_CID_HUE, V4L2_CTRL_TYPE_INTEGER,
98 "hue", 0, 10000, 1, 100, 0, },
99 CUST_PARM_ID_HUE_CTRL,
100 }, {
101 { V4L2_CID_SATURATION, V4L2_CTRL_TYPE_INTEGER,
102 "saturation", 0, 10000, 1, 100, 0, },
103 CUST_PARM_ID_SATURATION_CTRL,
104 },
105};
106
107struct video_std_to_audio_std {
108 v4l2_std_id video_std;
109 int audio_std;
110};
111
112static const struct video_std_to_audio_std video_to_audio_map[] = {
113 /* country : { 27, 32, 33, 34, 36, 44, 45, 46, 47, 48, 64,
114 65, 86, 351, 352, 353, 354, 358, 372, 852, 972 } */
115 { (V4L2_STD_PAL_I | V4L2_STD_PAL_B | V4L2_STD_PAL_D |
116 V4L2_STD_SECAM_L | V4L2_STD_SECAM_D), TLG_TUNE_ASTD_NICAM },
117
118 /* country : { 1, 52, 54, 55, 886 } */
119 {V4L2_STD_NTSC_M | V4L2_STD_PAL_N | V4L2_STD_PAL_M, TLG_TUNE_ASTD_BTSC},
120
121 /* country : { 81 } */
122 { V4L2_STD_NTSC_M_JP, TLG_TUNE_ASTD_EIAJ },
123
124 /* other country : TLG_TUNE_ASTD_A2 */
125};
126static const unsigned int map_size = ARRAY_SIZE(video_to_audio_map);
127
128static int get_audio_std(v4l2_std_id v4l2_std)
129{
130 int i = 0;
131
132 for (; i < map_size; i++) {
133 if (v4l2_std & video_to_audio_map[i].video_std)
134 return video_to_audio_map[i].audio_std;
135 }
136 return TLG_TUNE_ASTD_A2;
137}
138
139static int vidioc_querycap(struct file *file, void *fh,
140 struct v4l2_capability *cap)
141{
142 struct front_face *front = fh;
143 struct poseidon *p = front->pd;
144
145 logs(front);
146
147 strcpy(cap->driver, "tele-video");
148 strcpy(cap->card, "Telegent Poseidon");
149 usb_make_path(p->udev, cap->bus_info, sizeof(cap->bus_info));
150 cap->version = KERNEL_VERSION(0, 0, 1);
151 cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_TUNER |
152 V4L2_CAP_AUDIO | V4L2_CAP_STREAMING |
153 V4L2_CAP_READWRITE | V4L2_CAP_VBI_CAPTURE;
154 return 0;
155}
156
157/*====================================================================*/
158static void init_copy(struct video_data *video, bool index)
159{
160 struct front_face *front = video->front;
161
162 video->field_count = index;
163 video->lines_copied = 0;
164 video->prev_left = 0 ;
165 video->dst = (char *)videobuf_to_vmalloc(front->curr_frame)
166 + index * video->lines_size;
167 video->vbi->copied = 0; /* set it here */
168}
169
170static bool get_frame(struct front_face *front, int *need_init)
171{
172 struct videobuf_buffer *vb = front->curr_frame;
173
174 if (vb)
175 return true;
176
177 spin_lock(&front->queue_lock);
178 if (!list_empty(&front->active)) {
179 vb = list_entry(front->active.next,
180 struct videobuf_buffer, queue);
181 if (need_init)
182 *need_init = 1;
183 front->curr_frame = vb;
184 list_del_init(&vb->queue);
185 }
186 spin_unlock(&front->queue_lock);
187
188 return !!vb;
189}
190
191/* check if the video's buffer is ready */
192static bool get_video_frame(struct front_face *front, struct video_data *video)
193{
194 int need_init = 0;
195 bool ret = true;
196
197 ret = get_frame(front, &need_init);
198 if (ret && need_init)
199 init_copy(video, 0);
200 return ret;
201}
202
203static void submit_frame(struct front_face *front)
204{
205 struct videobuf_buffer *vb = front->curr_frame;
206
207 if (vb == NULL)
208 return;
209
210 front->curr_frame = NULL;
211 vb->state = VIDEOBUF_DONE;
212 vb->field_count++;
213 do_gettimeofday(&vb->ts);
214
215 wake_up(&vb->done);
216}
217
218/*
219 * A frame is composed of two fields. If we receive all the two fields,
220 * call the submit_frame() to submit the whole frame to applications.
221 */
222static void end_field(struct video_data *video)
223{
224 /* logs(video->front); */
225 if (1 == video->field_count)
226 submit_frame(video->front);
227 else
228 init_copy(video, 1);
229}
230
231static void copy_video_data(struct video_data *video, char *src,
232 unsigned int count)
233{
234#define copy_data(len) \
235 do { \
236 if (++video->lines_copied > video->lines_per_field) \
237 goto overflow; \
238 memcpy(video->dst, src, len);\
239 video->dst += len + video->lines_size; \
240 src += len; \
241 count -= len; \
242 } while (0)
243
244 while (count && count >= video->lines_size) {
245 if (video->prev_left) {
246 copy_data(video->prev_left);
247 video->prev_left = 0;
248 continue;
249 }
250 copy_data(video->lines_size);
251 }
252 if (count && count < video->lines_size) {
253 memcpy(video->dst, src, count);
254
255 video->prev_left = video->lines_size - count;
256 video->dst += count;
257 }
258 return;
259
260overflow:
261 end_field(video);
262}
263
264static void check_trailer(struct video_data *video, char *src, int count)
265{
266 struct vbi_data *vbi = video->vbi;
267 int offset; /* trailer's offset */
268 char *buf;
269
270 offset = (video->context.pix.sizeimage / 2 + vbi->vbi_size / 2)
271 - (vbi->copied + video->lines_size * video->lines_copied);
272 if (video->prev_left)
273 offset -= (video->lines_size - video->prev_left);
274
275 if (offset > count || offset <= 0)
276 goto short_package;
277
278 buf = src + offset;
279
280 /* trailer : (VFHS) + U32 + U32 + field_num */
281 if (!strncmp(buf, "VFHS", 4)) {
282 int field_num = *((u32 *)(buf + 12));
283
284 if ((field_num & 1) ^ video->field_count) {
285 init_copy(video, video->field_count);
286 return;
287 }
288 copy_video_data(video, src, offset);
289 }
290short_package:
291 end_field(video);
292}
293
294/* ========== Check this more carefully! =========== */
295static inline void copy_vbi_data(struct vbi_data *vbi,
296 char *src, unsigned int count)
297{
298 struct front_face *front = vbi->front;
299
300 if (front && get_frame(front, NULL)) {
301 char *buf = videobuf_to_vmalloc(front->curr_frame);
302
303 if (vbi->video->field_count)
304 buf += (vbi->vbi_size / 2);
305 memcpy(buf + vbi->copied, src, count);
306 }
307 vbi->copied += count;
308}
309
310/*
311 * Copy the normal data (VBI or VIDEO) without the trailer.
312 * VBI is not interlaced, while VIDEO is interlaced.
313 */
314static inline void copy_vbi_video_data(struct video_data *video,
315 char *src, unsigned int count)
316{
317 struct vbi_data *vbi = video->vbi;
318 unsigned int vbi_delta = (vbi->vbi_size / 2) - vbi->copied;
319
320 if (vbi_delta >= count) {
321 copy_vbi_data(vbi, src, count);
322 } else {
323 if (vbi_delta) {
324 copy_vbi_data(vbi, src, vbi_delta);
325
326 /* we receive the two fields of the VBI*/
327 if (vbi->front && video->field_count)
328 submit_frame(vbi->front);
329 }
330 copy_video_data(video, src + vbi_delta, count - vbi_delta);
331 }
332}
333
334static void urb_complete_bulk(struct urb *urb)
335{
336 struct front_face *front = urb->context;
337 struct video_data *video = &front->pd->video_data;
338 char *src = (char *)urb->transfer_buffer;
339 int count = urb->actual_length;
340 int ret = 0;
341
342 if (!video->is_streaming || urb->status) {
343 if (urb->status == -EPROTO)
344 goto resend_it;
345 return;
346 }
347 if (!get_video_frame(front, video))
348 goto resend_it;
349
350 if (count == urb->transfer_buffer_length)
351 copy_vbi_video_data(video, src, count);
352 else
353 check_trailer(video, src, count);
354
355resend_it:
356 ret = usb_submit_urb(urb, GFP_ATOMIC);
357 if (ret)
358 log(" submit failed: error %d", ret);
359}
360
361/************************* for ISO *********************/
362#define GET_SUCCESS (0)
363#define GET_TRAILER (1)
364#define GET_TOO_MUCH_BUBBLE (2)
365#define GET_NONE (3)
366static int get_chunk(int start, struct urb *urb,
367 int *head, int *tail, int *bubble_err)
368{
369 struct usb_iso_packet_descriptor *pkt = NULL;
370 int ret = GET_SUCCESS;
371
372 for (*head = *tail = -1; start < urb->number_of_packets; start++) {
373 pkt = &urb->iso_frame_desc[start];
374
375 /* handle the bubble of the Hub */
376 if (-EOVERFLOW == pkt->status) {
377 if (++*bubble_err > urb->number_of_packets / 3)
378 return GET_TOO_MUCH_BUBBLE;
379 continue;
380 }
381
382 /* This is the gap */
383 if (pkt->status || pkt->actual_length <= 0
384 || pkt->actual_length > ISO_PKT_SIZE) {
385 if (*head != -1)
386 break;
387 continue;
388 }
389
390 /* a good isochronous packet */
391 if (pkt->actual_length == ISO_PKT_SIZE) {
392 if (*head == -1)
393 *head = start;
394 *tail = start;
395 continue;
396 }
397
398 /* trailer is here */
399 if (pkt->actual_length < ISO_PKT_SIZE) {
400 if (*head == -1) {
401 *head = start;
402 *tail = start;
403 return GET_TRAILER;
404 }
405 break;
406 }
407 }
408
409 if (*head == -1 && *tail == -1)
410 ret = GET_NONE;
411 return ret;
412}
413
414/*
415 * |__|------|___|-----|_______|
416 * ^ ^
417 * | |
418 * gap gap
419 */
420static void urb_complete_iso(struct urb *urb)
421{
422 struct front_face *front = urb->context;
423 struct video_data *video = &front->pd->video_data;
424 int bubble_err = 0, head = 0, tail = 0;
425 char *src = (char *)urb->transfer_buffer;
426 int ret = 0;
427
428 if (!video->is_streaming)
429 return;
430
431 do {
432 if (!get_video_frame(front, video))
433 goto out;
434
435 switch (get_chunk(head, urb, &head, &tail, &bubble_err)) {
436 case GET_SUCCESS:
437 copy_vbi_video_data(video, src + (head * ISO_PKT_SIZE),
438 (tail - head + 1) * ISO_PKT_SIZE);
439 break;
440 case GET_TRAILER:
441 check_trailer(video, src + (head * ISO_PKT_SIZE),
442 ISO_PKT_SIZE);
443 break;
444 case GET_NONE:
445 goto out;
446 case GET_TOO_MUCH_BUBBLE:
447 log("\t We got too much bubble");
448 schedule_work(&video->bubble_work);
449 return;
450 }
451 } while (head = tail + 1, head < urb->number_of_packets);
452
453out:
454 ret = usb_submit_urb(urb, GFP_ATOMIC);
455 if (ret)
456 log("usb_submit_urb err : %d", ret);
457}
458/*============================= [ end ] =====================*/
459
460static int prepare_iso_urb(struct video_data *video)
461{
462 struct usb_device *udev = video->pd->udev;
463 int i;
464
465 if (video->urb_array[0])
466 return 0;
467
468 for (i = 0; i < SBUF_NUM; i++) {
469 struct urb *urb;
470 void *mem;
471 int j;
472
473 urb = usb_alloc_urb(PK_PER_URB, GFP_KERNEL);
474 if (urb == NULL)
475 goto out;
476
477 video->urb_array[i] = urb;
478 mem = usb_buffer_alloc(udev,
479 ISO_PKT_SIZE * PK_PER_URB,
480 GFP_KERNEL,
481 &urb->transfer_dma);
482
483 urb->complete = urb_complete_iso; /* handler */
484 urb->dev = udev;
485 urb->context = video->front;
486 urb->pipe = usb_rcvisocpipe(udev,
487 video->endpoint_addr);
488 urb->interval = 1;
489 urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP;
490 urb->number_of_packets = PK_PER_URB;
491 urb->transfer_buffer = mem;
492 urb->transfer_buffer_length = PK_PER_URB * ISO_PKT_SIZE;
493
494 for (j = 0; j < PK_PER_URB; j++) {
495 urb->iso_frame_desc[j].offset = ISO_PKT_SIZE * j;
496 urb->iso_frame_desc[j].length = ISO_PKT_SIZE;
497 }
498 }
499 return 0;
500out:
501 for (; i > 0; i--)
502 ;
503 return -ENOMEM;
504}
505
506/* return the succeeded number of the allocation */
507int alloc_bulk_urbs_generic(struct urb **urb_array, int num,
508 struct usb_device *udev, u8 ep_addr,
509 int buf_size, gfp_t gfp_flags,
510 usb_complete_t complete_fn, void *context)
511{
512 struct urb *urb;
513 void *mem;
514 int i;
515
516 for (i = 0; i < num; i++) {
517 urb = usb_alloc_urb(0, gfp_flags);
518 if (urb == NULL)
519 return i;
520
521 mem = usb_buffer_alloc(udev, buf_size, gfp_flags,
522 &urb->transfer_dma);
523 if (mem == NULL)
524 return i;
525
526 usb_fill_bulk_urb(urb, udev, usb_rcvbulkpipe(udev, ep_addr),
527 mem, buf_size, complete_fn, context);
528 urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
529 urb_array[i] = urb;
530 }
531 return i;
532}
533
534void free_all_urb_generic(struct urb **urb_array, int num)
535{
536 int i;
537 struct urb *urb;
538
539 for (i = 0; i < num; i++) {
540 urb = urb_array[i];
541 if (urb) {
542 usb_buffer_free(urb->dev,
543 urb->transfer_buffer_length,
544 urb->transfer_buffer,
545 urb->transfer_dma);
546 usb_free_urb(urb);
547 urb_array[i] = NULL;
548 }
549 }
550}
551
552static int prepare_bulk_urb(struct video_data *video)
553{
554 if (video->urb_array[0])
555 return 0;
556
557 alloc_bulk_urbs_generic(video->urb_array, SBUF_NUM,
558 video->pd->udev, video->endpoint_addr,
559 0x2000, GFP_KERNEL,
560 urb_complete_bulk, video->front);
561 return 0;
562}
563
564/* free the URBs */
565static void free_all_urb(struct video_data *video)
566{
567 free_all_urb_generic(video->urb_array, SBUF_NUM);
568}
569
570static void pd_buf_release(struct videobuf_queue *q, struct videobuf_buffer *vb)
571{
572 videobuf_vmalloc_free(vb);
573 vb->state = VIDEOBUF_NEEDS_INIT;
574}
575
576static void pd_buf_queue(struct videobuf_queue *q, struct videobuf_buffer *vb)
577{
578 struct front_face *front = q->priv_data;
579 vb->state = VIDEOBUF_QUEUED;
580 list_add_tail(&vb->queue, &front->active);
581}
582
583static int pd_buf_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
584 enum v4l2_field field)
585{
586 struct front_face *front = q->priv_data;
587 int rc;
588
589 switch (front->type) {
590 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
591 if (VIDEOBUF_NEEDS_INIT == vb->state) {
592 struct v4l2_pix_format *pix;
593
594 pix = &front->pd->video_data.context.pix;
595 vb->size = pix->sizeimage; /* real frame size */
596 vb->width = pix->width;
597 vb->height = pix->height;
598 rc = videobuf_iolock(q, vb, NULL);
599 if (rc < 0)
600 return rc;
601 }
602 break;
603 case V4L2_BUF_TYPE_VBI_CAPTURE:
604 if (VIDEOBUF_NEEDS_INIT == vb->state) {
605 vb->size = front->pd->vbi_data.vbi_size;
606 rc = videobuf_iolock(q, vb, NULL);
607 if (rc < 0)
608 return rc;
609 }
610 break;
611 default:
612 return -EINVAL;
613 }
614 vb->field = field;
615 vb->state = VIDEOBUF_PREPARED;
616 return 0;
617}
618
619int fire_all_urb(struct video_data *video)
620{
621 int i, ret;
622
623 video->is_streaming = 1;
624
625 for (i = 0; i < SBUF_NUM; i++) {
626 ret = usb_submit_urb(video->urb_array[i], GFP_KERNEL);
627 if (ret)
628 log("(%d) failed: error %d", i, ret);
629 }
630 return ret;
631}
632
633static int start_video_stream(struct poseidon *pd)
634{
635 struct video_data *video = &pd->video_data;
636 s32 cmd_status;
637
638 send_set_req(pd, TAKE_REQUEST, 0, &cmd_status);
639 send_set_req(pd, PLAY_SERVICE, TLG_TUNE_PLAY_SVC_START, &cmd_status);
640
641 if (pd->cur_transfer_mode) {
642 prepare_iso_urb(video);
643 INIT_WORK(&video->bubble_work, iso_bubble_handler);
644 } else {
645 /* The bulk mode does not need a bubble handler */
646 prepare_bulk_urb(video);
647 }
648 fire_all_urb(video);
649 return 0;
650}
651
652static int pd_buf_setup(struct videobuf_queue *q, unsigned int *count,
653 unsigned int *size)
654{
655 struct front_face *front = q->priv_data;
656 struct poseidon *pd = front->pd;
657
658 switch (front->type) {
659 default:
660 return -EINVAL;
661 case V4L2_BUF_TYPE_VIDEO_CAPTURE: {
662 struct video_data *video = &pd->video_data;
663 struct v4l2_pix_format *pix = &video->context.pix;
664
665 *size = PAGE_ALIGN(pix->sizeimage);/* page aligned frame size */
666 if (*count < 4)
667 *count = 4;
668 if (1) {
669 /* same in different altersetting */
670 video->endpoint_addr = 0x82;
671 video->vbi = &pd->vbi_data;
672 video->vbi->video = video;
673 video->pd = pd;
674 video->lines_per_field = pix->height / 2;
675 video->lines_size = pix->width * 2;
676 video->front = front;
677 }
678 return start_video_stream(pd);
679 }
680
681 case V4L2_BUF_TYPE_VBI_CAPTURE: {
682 struct vbi_data *vbi = &pd->vbi_data;
683
684 *size = PAGE_ALIGN(vbi->vbi_size);
685 log("size : %d", *size);
686 if (*count == 0)
687 *count = 4;
688 }
689 break;
690 }
691 return 0;
692}
693
694static struct videobuf_queue_ops pd_video_qops = {
695 .buf_setup = pd_buf_setup,
696 .buf_prepare = pd_buf_prepare,
697 .buf_queue = pd_buf_queue,
698 .buf_release = pd_buf_release,
699};
700
701static int vidioc_enum_fmt(struct file *file, void *fh,
702 struct v4l2_fmtdesc *f)
703{
704 if (ARRAY_SIZE(poseidon_formats) <= f->index)
705 return -EINVAL;
706 f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
707 f->flags = 0;
708 f->pixelformat = poseidon_formats[f->index].fourcc;
709 strcpy(f->description, poseidon_formats[f->index].name);
710 return 0;
711}
712
713static int vidioc_g_fmt(struct file *file, void *fh, struct v4l2_format *f)
714{
715 struct front_face *front = fh;
716 struct poseidon *pd = front->pd;
717
718 logs(front);
719 f->fmt.pix = pd->video_data.context.pix;
720 return 0;
721}
722
723static int vidioc_try_fmt(struct file *file, void *fh,
724 struct v4l2_format *f)
725{
726 return 0;
727}
728
729/*
730 * VLC calls VIDIOC_S_STD before VIDIOC_S_FMT, while
731 * Mplayer calls them in the reverse order.
732 */
733static int pd_vidioc_s_fmt(struct poseidon *pd, struct v4l2_pix_format *pix)
734{
735 struct video_data *video = &pd->video_data;
736 struct running_context *context = &video->context;
737 struct v4l2_pix_format *pix_def = &context->pix;
738 s32 ret = 0, cmd_status = 0, vid_resol;
739
740 /* set the pixel format to firmware */
741 if (pix->pixelformat == V4L2_PIX_FMT_RGB565) {
742 vid_resol = TLG_TUNER_VID_FORMAT_RGB_565;
743 } else {
744 pix->pixelformat = V4L2_PIX_FMT_YUYV;
745 vid_resol = TLG_TUNER_VID_FORMAT_YUV;
746 }
747 ret = send_set_req(pd, VIDEO_STREAM_FMT_SEL,
748 vid_resol, &cmd_status);
749
750 /* set the resolution to firmware */
751 vid_resol = TLG_TUNE_VID_RES_720;
752 switch (pix->width) {
753 case 704:
754 vid_resol = TLG_TUNE_VID_RES_704;
755 break;
756 default:
757 pix->width = 720;
758 case 720:
759 break;
760 }
761 ret |= send_set_req(pd, VIDEO_ROSOLU_SEL,
762 vid_resol, &cmd_status);
763 if (ret || cmd_status) {
764 mutex_unlock(&pd->lock);
765 return -EBUSY;
766 }
767
768 pix_def->pixelformat = pix->pixelformat; /* save it */
769 pix->height = (context->tvnormid & V4L2_STD_525_60) ? 480 : 576;
770
771 /* Compare with the default setting */
772 if ((pix_def->width != pix->width)
773 || (pix_def->height != pix->height)) {
774 pix_def->width = pix->width;
775 pix_def->height = pix->height;
776 pix_def->bytesperline = pix->width * 2;
777 pix_def->sizeimage = pix->width * pix->height * 2;
778 }
779 *pix = *pix_def;
780
781 return 0;
782}
783
784static int vidioc_s_fmt(struct file *file, void *fh, struct v4l2_format *f)
785{
786 struct front_face *front = fh;
787 struct poseidon *pd = front->pd;
788
789 logs(front);
790 /* stop VBI here */
791 if (V4L2_BUF_TYPE_VIDEO_CAPTURE != f->type)
792 return -EINVAL;
793
794 mutex_lock(&pd->lock);
795 if (pd->file_for_stream == NULL)
796 pd->file_for_stream = file;
797 else if (file != pd->file_for_stream) {
798 mutex_unlock(&pd->lock);
799 return -EINVAL;
800 }
801
802 pd_vidioc_s_fmt(pd, &f->fmt.pix);
803 mutex_unlock(&pd->lock);
804 return 0;
805}
806
807static int vidioc_g_fmt_vbi(struct file *file, void *fh,
808 struct v4l2_format *v4l2_f)
809{
810 struct front_face *front = fh;
811 struct poseidon *pd = front->pd;
812 struct v4l2_vbi_format *vbi_fmt = &v4l2_f->fmt.vbi;
813
814 vbi_fmt->samples_per_line = 720 * 2;
815 vbi_fmt->sampling_rate = 6750000 * 4;
816 vbi_fmt->sample_format = V4L2_PIX_FMT_GREY;
817 vbi_fmt->offset = 64 * 4; /*FIXME: why offset */
818 if (pd->video_data.context.tvnormid & V4L2_STD_525_60) {
819 vbi_fmt->start[0] = 10;
820 vbi_fmt->start[1] = 264;
821 vbi_fmt->count[0] = V4L_NTSC_VBI_LINES;
822 vbi_fmt->count[1] = V4L_NTSC_VBI_LINES;
823 } else {
824 vbi_fmt->start[0] = 6;
825 vbi_fmt->start[1] = 314;
826 vbi_fmt->count[0] = V4L_PAL_VBI_LINES;
827 vbi_fmt->count[1] = V4L_PAL_VBI_LINES;
828 }
829 vbi_fmt->flags = V4L2_VBI_UNSYNC;
830 logs(front);
831 return 0;
832}
833
834static int set_std(struct poseidon *pd, v4l2_std_id *norm)
835{
836 struct video_data *video = &pd->video_data;
837 struct vbi_data *vbi = &pd->vbi_data;
838 struct running_context *context;
839 struct v4l2_pix_format *pix;
840 s32 i, ret = 0, cmd_status, param;
841 int height;
842
843 for (i = 0; i < POSEIDON_TVNORMS; i++) {
844 if (*norm & poseidon_tvnorms[i].v4l2_id) {
845 param = poseidon_tvnorms[i].tlg_tvnorm;
846 log("name : %s", poseidon_tvnorms[i].name);
847 goto found;
848 }
849 }
850 return -EINVAL;
851found:
852 mutex_lock(&pd->lock);
853 ret = send_set_req(pd, VIDEO_STD_SEL, param, &cmd_status);
854 if (ret || cmd_status)
855 goto out;
856
857 /* Set vbi size and check the height of the frame */
858 context = &video->context;
859 context->tvnormid = poseidon_tvnorms[i].v4l2_id;
860 if (context->tvnormid & V4L2_STD_525_60) {
861 vbi->vbi_size = V4L_NTSC_VBI_FRAMESIZE;
862 height = 480;
863 } else {
864 vbi->vbi_size = V4L_PAL_VBI_FRAMESIZE;
865 height = 576;
866 }
867
868 pix = &context->pix;
869 if (pix->height != height) {
870 pix->height = height;
871 pix->sizeimage = pix->width * pix->height * 2;
872 }
873
874out:
875 mutex_unlock(&pd->lock);
876 return ret;
877}
878
879int vidioc_s_std(struct file *file, void *fh, v4l2_std_id *norm)
880{
881 struct front_face *front = fh;
882 logs(front);
883 return set_std(front->pd, norm);
884}
885
886static int vidioc_enum_input(struct file *file, void *fh, struct v4l2_input *in)
887{
888 struct front_face *front = fh;
889
890 if (in->index < 0 || in->index >= POSEIDON_INPUTS)
891 return -EINVAL;
892 strcpy(in->name, pd_inputs[in->index].name);
893 in->type = V4L2_INPUT_TYPE_TUNER;
894
895 /*
896 * the audio input index mixed with this video input,
897 * Poseidon only have one audio/video, set to "0"
898 */
899 in->audioset = 0;
900 in->tuner = 0;
901 in->std = V4L2_STD_ALL;
902 in->status = 0;
903 logs(front);
904 return 0;
905}
906
907static int vidioc_g_input(struct file *file, void *fh, unsigned int *i)
908{
909 struct front_face *front = fh;
910 struct poseidon *pd = front->pd;
911 struct running_context *context = &pd->video_data.context;
912
913 logs(front);
914 *i = context->sig_index;
915 return 0;
916}
917
918/* We can support several inputs */
919static int vidioc_s_input(struct file *file, void *fh, unsigned int i)
920{
921 struct front_face *front = fh;
922 struct poseidon *pd = front->pd;
923 s32 ret, cmd_status;
924
925 if (i < 0 || i >= POSEIDON_INPUTS)
926 return -EINVAL;
927 ret = send_set_req(pd, SGNL_SRC_SEL,
928 pd_inputs[i].tlg_src, &cmd_status);
929 if (ret)
930 return ret;
931
932 pd->video_data.context.sig_index = i;
933 return 0;
934}
935
936static struct poseidon_control *check_control_id(__u32 id)
937{
938 struct poseidon_control *control = &controls[0];
939 int array_size = ARRAY_SIZE(controls);
940
941 for (; control < &controls[array_size]; control++)
942 if (control->v4l2_ctrl.id == id)
943 return control;
944 return NULL;
945}
946
947static int vidioc_queryctrl(struct file *file, void *fh,
948 struct v4l2_queryctrl *a)
949{
950 struct poseidon_control *control = NULL;
951
952 control = check_control_id(a->id);
953 if (!control)
954 return -EINVAL;
955
956 *a = control->v4l2_ctrl;
957 return 0;
958}
959
960static int vidioc_g_ctrl(struct file *file, void *fh, struct v4l2_control *ctrl)
961{
962 struct front_face *front = fh;
963 struct poseidon *pd = front->pd;
964 struct poseidon_control *control = NULL;
965 struct tuner_custom_parameter_s tuner_param;
966 s32 ret = 0, cmd_status;
967
968 control = check_control_id(ctrl->id);
969 if (!control)
970 return -EINVAL;
971
972 mutex_lock(&pd->lock);
973 ret = send_get_req(pd, TUNER_CUSTOM_PARAMETER, control->vc_id,
974 &tuner_param, &cmd_status, sizeof(tuner_param));
975 mutex_unlock(&pd->lock);
976
977 if (ret || cmd_status)
978 return -1;
979
980 ctrl->value = tuner_param.param_value;
981 return 0;
982}
983
984static int vidioc_s_ctrl(struct file *file, void *fh, struct v4l2_control *a)
985{
986 struct tuner_custom_parameter_s param = {0};
987 struct poseidon_control *control = NULL;
988 struct front_face *front = fh;
989 struct poseidon *pd = front->pd;
990 s32 ret = 0, cmd_status, params;
991
992 control = check_control_id(a->id);
993 if (!control)
994 return -EINVAL;
995
996 param.param_value = a->value;
997 param.param_id = control->vc_id;
998 params = *(s32 *)&param; /* temp code */
999
1000 mutex_lock(&pd->lock);
1001 ret = send_set_req(pd, TUNER_CUSTOM_PARAMETER, params, &cmd_status);
1002 ret = send_set_req(pd, TAKE_REQUEST, 0, &cmd_status);
1003 mutex_unlock(&pd->lock);
1004
1005 set_current_state(TASK_INTERRUPTIBLE);
1006 schedule_timeout(HZ/4);
1007 return ret;
1008}
1009
1010/* Audio ioctls */
1011static int vidioc_enumaudio(struct file *file, void *fh, struct v4l2_audio *a)
1012{
1013 if (0 != a->index)
1014 return -EINVAL;
1015 a->capability = V4L2_AUDCAP_STEREO;
1016 strcpy(a->name, "USB audio in");
1017 /*Poseidon have no AVL function.*/
1018 a->mode = 0;
1019 return 0;
1020}
1021
1022int vidioc_g_audio(struct file *file, void *fh, struct v4l2_audio *a)
1023{
1024 a->index = 0;
1025 a->capability = V4L2_AUDCAP_STEREO;
1026 strcpy(a->name, "USB audio in");
1027 a->mode = 0;
1028 return 0;
1029}
1030
1031int vidioc_s_audio(struct file *file, void *fh, struct v4l2_audio *a)
1032{
1033 return (0 == a->index) ? 0 : -EINVAL;
1034}
1035
1036/* Tuner ioctls */
1037static int vidioc_g_tuner(struct file *file, void *fh, struct v4l2_tuner *tuner)
1038{
1039 struct front_face *front = fh;
1040 struct poseidon *pd = front->pd;
1041 struct tuner_atv_sig_stat_s atv_stat;
1042 s32 count = 5, ret, cmd_status;
1043 int index;
1044
1045 if (0 != tuner->index)
1046 return -EINVAL;
1047
1048 mutex_lock(&pd->lock);
1049 ret = send_get_req(pd, TUNER_STATUS, TLG_MODE_ANALOG_TV,
1050 &atv_stat, &cmd_status, sizeof(atv_stat));
1051
1052 while (atv_stat.sig_lock_busy && count-- && !ret) {
1053 set_current_state(TASK_INTERRUPTIBLE);
1054 schedule_timeout(HZ);
1055
1056 ret = send_get_req(pd, TUNER_STATUS, TLG_MODE_ANALOG_TV,
1057 &atv_stat, &cmd_status, sizeof(atv_stat));
1058 }
1059 mutex_unlock(&pd->lock);
1060
1061 if (debug_mode)
1062 log("P:%d,S:%d", atv_stat.sig_present, atv_stat.sig_strength);
1063
1064 if (ret || cmd_status)
1065 tuner->signal = 0;
1066 else if (atv_stat.sig_present && !atv_stat.sig_strength)
1067 tuner->signal = 0xFFFF;
1068 else
1069 tuner->signal = (atv_stat.sig_strength * 255 / 10) << 8;
1070
1071 strcpy(tuner->name, "Telegent Systems");
1072 tuner->type = V4L2_TUNER_ANALOG_TV;
1073 tuner->rangelow = TUNER_FREQ_MIN / 62500;
1074 tuner->rangehigh = TUNER_FREQ_MAX / 62500;
1075 tuner->capability = V4L2_TUNER_CAP_NORM | V4L2_TUNER_CAP_STEREO |
1076 V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2;
1077 index = pd->video_data.context.audio_idx;
1078 tuner->rxsubchans = pd_audio_modes[index].v4l2_audio_sub;
1079 tuner->audmode = pd_audio_modes[index].v4l2_audio_mode;
1080 tuner->afc = 0;
1081 logs(front);
1082 return 0;
1083}
1084
1085static int pd_vidioc_s_tuner(struct poseidon *pd, int index)
1086{
1087 s32 ret = 0, cmd_status, param, audiomode;
1088
1089 mutex_lock(&pd->lock);
1090 param = pd_audio_modes[index].tlg_audio_mode;
1091 ret = send_set_req(pd, TUNER_AUD_MODE, param, &cmd_status);
1092 audiomode = get_audio_std(pd->video_data.context.tvnormid);
1093 ret |= send_set_req(pd, TUNER_AUD_ANA_STD, audiomode,
1094 &cmd_status);
1095 if (!ret)
1096 pd->video_data.context.audio_idx = index;
1097 mutex_unlock(&pd->lock);
1098 return ret;
1099}
1100
1101static int vidioc_s_tuner(struct file *file, void *fh, struct v4l2_tuner *a)
1102{
1103 struct front_face *front = fh;
1104 struct poseidon *pd = front->pd;
1105 int index;
1106
1107 if (0 != a->index)
1108 return -EINVAL;
1109 logs(front);
1110 for (index = 0; index < POSEIDON_AUDIOMODS; index++)
1111 if (a->audmode == pd_audio_modes[index].v4l2_audio_mode)
1112 return pd_vidioc_s_tuner(pd, index);
1113 return -EINVAL;
1114}
1115
1116static int vidioc_g_frequency(struct file *file, void *fh,
1117 struct v4l2_frequency *freq)
1118{
1119 struct front_face *front = fh;
1120 struct poseidon *pd = front->pd;
1121 struct running_context *context = &pd->video_data.context;
1122
1123 if (0 != freq->tuner)
1124 return -EINVAL;
1125 freq->frequency = context->freq;
1126 freq->type = V4L2_TUNER_ANALOG_TV;
1127 return 0;
1128}
1129
1130static int set_frequency(struct poseidon *pd, __u32 frequency)
1131{
1132 s32 ret = 0, param, cmd_status;
1133 struct running_context *context = &pd->video_data.context;
1134
1135 param = frequency * 62500 / 1000;
1136 if (param < TUNER_FREQ_MIN/1000 || param > TUNER_FREQ_MAX / 1000)
1137 return -EINVAL;
1138
1139 mutex_lock(&pd->lock);
1140 ret = send_set_req(pd, TUNE_FREQ_SELECT, param, &cmd_status);
1141 ret = send_set_req(pd, TAKE_REQUEST, 0, &cmd_status);
1142
1143 msleep(250); /* wait for a while until the hardware is ready. */
1144 context->freq = frequency;
1145 mutex_unlock(&pd->lock);
1146 return ret;
1147}
1148
1149static int vidioc_s_frequency(struct file *file, void *fh,
1150 struct v4l2_frequency *freq)
1151{
1152 struct front_face *front = fh;
1153 struct poseidon *pd = front->pd;
1154
1155 logs(front);
1156#ifdef CONFIG_PM
1157 pd->pm_suspend = pm_video_suspend;
1158 pd->pm_resume = pm_video_resume;
1159#endif
1160 return set_frequency(pd, freq->frequency);
1161}
1162
1163static int vidioc_reqbufs(struct file *file, void *fh,
1164 struct v4l2_requestbuffers *b)
1165{
1166 struct front_face *front = file->private_data;
1167 logs(front);
1168 return videobuf_reqbufs(&front->q, b);
1169}
1170
1171static int vidioc_querybuf(struct file *file, void *fh, struct v4l2_buffer *b)
1172{
1173 struct front_face *front = file->private_data;
1174 logs(front);
1175 return videobuf_querybuf(&front->q, b);
1176}
1177
1178static int vidioc_qbuf(struct file *file, void *fh, struct v4l2_buffer *b)
1179{
1180 struct front_face *front = file->private_data;
1181 return videobuf_qbuf(&front->q, b);
1182}
1183
1184static int vidioc_dqbuf(struct file *file, void *fh, struct v4l2_buffer *b)
1185{
1186 struct front_face *front = file->private_data;
1187 return videobuf_dqbuf(&front->q, b, file->f_flags & O_NONBLOCK);
1188}
1189
1190/* Just stop the URBs, do not free the URBs */
1191int usb_transfer_stop(struct video_data *video)
1192{
1193 if (video->is_streaming) {
1194 int i;
1195 s32 cmd_status;
1196 struct poseidon *pd = video->pd;
1197
1198 video->is_streaming = 0;
1199 for (i = 0; i < SBUF_NUM; ++i) {
1200 if (video->urb_array[i])
1201 usb_kill_urb(video->urb_array[i]);
1202 }
1203
1204 send_set_req(pd, PLAY_SERVICE, TLG_TUNE_PLAY_SVC_STOP,
1205 &cmd_status);
1206 }
1207 return 0;
1208}
1209
1210int stop_all_video_stream(struct poseidon *pd)
1211{
1212 struct video_data *video = &pd->video_data;
1213 struct vbi_data *vbi = &pd->vbi_data;
1214
1215 mutex_lock(&pd->lock);
1216 if (video->is_streaming) {
1217 struct front_face *front = video->front;
1218
1219 /* stop the URBs */
1220 usb_transfer_stop(video);
1221 free_all_urb(video);
1222
1223 /* stop the host side of VIDEO */
1224 videobuf_stop(&front->q);
1225 videobuf_mmap_free(&front->q);
1226
1227 /* stop the host side of VBI */
1228 front = vbi->front;
1229 if (front) {
1230 videobuf_stop(&front->q);
1231 videobuf_mmap_free(&front->q);
1232 }
1233 }
1234 mutex_unlock(&pd->lock);
1235 return 0;
1236}
1237
1238/*
1239 * The bubbles can seriously damage the video's quality,
1240 * though it occurs in very rare situation.
1241 */
1242static void iso_bubble_handler(struct work_struct *w)
1243{
1244 struct video_data *video;
1245 struct poseidon *pd;
1246
1247 video = container_of(w, struct video_data, bubble_work);
1248 pd = video->pd;
1249
1250 mutex_lock(&pd->lock);
1251 usb_transfer_stop(video);
1252 msleep(500);
1253 start_video_stream(pd);
1254 mutex_unlock(&pd->lock);
1255}
1256
1257
1258static int vidioc_streamon(struct file *file, void *fh,
1259 enum v4l2_buf_type type)
1260{
1261 struct front_face *front = fh;
1262
1263 logs(front);
1264 if (unlikely(type != front->type))
1265 return -EINVAL;
1266 return videobuf_streamon(&front->q);
1267}
1268
1269static int vidioc_streamoff(struct file *file, void *fh,
1270 enum v4l2_buf_type type)
1271{
1272 struct front_face *front = file->private_data;
1273
1274 logs(front);
1275 if (unlikely(type != front->type))
1276 return -EINVAL;
1277 return videobuf_streamoff(&front->q);
1278}
1279
1280/* Set the firmware's default values : need altersetting */
1281static int pd_video_checkmode(struct poseidon *pd)
1282{
1283 s32 ret = 0, cmd_status, audiomode;
1284
1285 set_current_state(TASK_INTERRUPTIBLE);
1286 schedule_timeout(HZ/2);
1287
1288 /* choose the altersetting */
1289 ret = usb_set_interface(pd->udev, 0,
1290 (pd->cur_transfer_mode ?
1291 ISO_3K_BULK_ALTERNATE_IFACE :
1292 BULK_ALTERNATE_IFACE));
1293 if (ret < 0)
1294 goto error;
1295
1296 /* set default parameters for PAL-D , with the VBI enabled*/
1297 ret = set_tuner_mode(pd, TLG_MODE_ANALOG_TV);
1298 ret |= send_set_req(pd, SGNL_SRC_SEL,
1299 TLG_SIG_SRC_ANTENNA, &cmd_status);
1300 ret |= send_set_req(pd, VIDEO_STD_SEL,
1301 TLG_TUNE_VSTD_PAL_D, &cmd_status);
1302 ret |= send_set_req(pd, VIDEO_STREAM_FMT_SEL,
1303 TLG_TUNER_VID_FORMAT_YUV, &cmd_status);
1304 ret |= send_set_req(pd, VIDEO_ROSOLU_SEL,
1305 TLG_TUNE_VID_RES_720, &cmd_status);
1306 ret |= send_set_req(pd, TUNE_FREQ_SELECT, TUNER_FREQ_MIN, &cmd_status);
1307 ret |= send_set_req(pd, VBI_DATA_SEL, 1, &cmd_status);/* enable vbi */
1308
1309 /* set the audio */
1310 audiomode = get_audio_std(pd->video_data.context.tvnormid);
1311 ret |= send_set_req(pd, TUNER_AUD_ANA_STD, audiomode, &cmd_status);
1312 ret |= send_set_req(pd, TUNER_AUD_MODE,
1313 TLG_TUNE_TVAUDIO_MODE_STEREO, &cmd_status);
1314 ret |= send_set_req(pd, AUDIO_SAMPLE_RATE_SEL,
1315 ATV_AUDIO_RATE_48K, &cmd_status);
1316error:
1317 return ret;
1318}
1319
1320#ifdef CONFIG_PM
1321static int pm_video_suspend(struct poseidon *pd)
1322{
1323 /* stop audio */
1324 pm_alsa_suspend(pd);
1325
1326 /* stop and free all the URBs */
1327 usb_transfer_stop(&pd->video_data);
1328 free_all_urb(&pd->video_data);
1329
1330 /* reset the interface */
1331 usb_set_interface(pd->udev, 0, 0);
1332 msleep(300);
1333 return 0;
1334}
1335
1336static int restore_v4l2_context(struct poseidon *pd,
1337 struct running_context *context)
1338{
1339 struct front_face *front = pd->video_data.front;
1340
1341 pd_video_checkmode(pd);
1342
1343 set_std(pd, &context->tvnormid);
1344 vidioc_s_input(NULL, front, context->sig_index);
1345 pd_vidioc_s_tuner(pd, context->audio_idx);
1346 pd_vidioc_s_fmt(pd, &context->pix);
1347 set_frequency(pd, context->freq);
1348 return 0;
1349}
1350
1351static int pm_video_resume(struct poseidon *pd)
1352{
1353 struct video_data *video = &pd->video_data;
1354
1355 /* resume the video */
1356 /* [1] restore the origin V4L2 parameters */
1357 restore_v4l2_context(pd, &video->context);
1358
1359 /* [2] initiate video copy variables */
1360 if (video->front->curr_frame)
1361 init_copy(video, 0);
1362
1363 /* [3] fire urbs */
1364 start_video_stream(pd);
1365
1366 /* resume the audio */
1367 pm_alsa_resume(pd);
1368 return 0;
1369}
1370#endif
1371
1372void set_debug_mode(struct video_device *vfd, int debug_mode)
1373{
1374 vfd->debug = 0;
1375 if (debug_mode & 0x1)
1376 vfd->debug = V4L2_DEBUG_IOCTL;
1377 if (debug_mode & 0x2)
1378 vfd->debug = V4L2_DEBUG_IOCTL | V4L2_DEBUG_IOCTL_ARG;
1379}
1380
1381static void init_video_context(struct running_context *context)
1382{
1383 context->sig_index = 0;
1384 context->audio_idx = 1; /* stereo */
1385 context->tvnormid = V4L2_STD_PAL_D;
1386 context->pix = (struct v4l2_pix_format) {
1387 .width = 720,
1388 .height = 576,
1389 .pixelformat = V4L2_PIX_FMT_YUYV,
1390 .field = V4L2_FIELD_INTERLACED,
1391 .bytesperline = 720 * 2,
1392 .sizeimage = 720 * 576 * 2,
1393 .colorspace = V4L2_COLORSPACE_SMPTE170M,
1394 .priv = 0
1395 };
1396}
1397
1398static int pd_video_open(struct file *file)
1399{
1400 struct video_device *vfd = video_devdata(file);
1401 struct poseidon *pd = video_get_drvdata(vfd);
1402 struct front_face *front = NULL;
1403 int ret = -ENOMEM;
1404
1405 mutex_lock(&pd->lock);
1406 usb_autopm_get_interface(pd->interface);
1407
1408 if (vfd->vfl_type == VFL_TYPE_GRABBER
1409 && !(pd->state & POSEIDON_STATE_ANALOG)) {
1410 front = kzalloc(sizeof(struct front_face), GFP_KERNEL);
1411 if (!front)
1412 goto out;
1413
1414 pd->cur_transfer_mode = usb_transfer_mode;/* bulk or iso */
1415 init_video_context(&pd->video_data.context);
1416
1417 ret = pd_video_checkmode(pd);
1418 if (ret < 0) {
1419 kfree(front);
1420 ret = -1;
1421 goto out;
1422 }
1423
1424 pd->state |= POSEIDON_STATE_ANALOG;
1425 front->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1426 pd->video_data.users++;
1427 set_debug_mode(vfd, debug_mode);
1428
1429 videobuf_queue_vmalloc_init(&front->q, &pd_video_qops,
1430 NULL, &front->queue_lock,
1431 V4L2_BUF_TYPE_VIDEO_CAPTURE,
1432 V4L2_FIELD_INTERLACED,/* video is interlacd */
1433 sizeof(struct videobuf_buffer),/*it's enough*/
1434 front);
1435 } else if (vfd->vfl_type == VFL_TYPE_VBI
1436 && !(pd->state & POSEIDON_STATE_VBI)) {
1437 front = kzalloc(sizeof(struct front_face), GFP_KERNEL);
1438 if (!front)
1439 goto out;
1440
1441 pd->state |= POSEIDON_STATE_VBI;
1442 front->type = V4L2_BUF_TYPE_VBI_CAPTURE;
1443 pd->vbi_data.front = front;
1444 pd->vbi_data.users++;
1445
1446 videobuf_queue_vmalloc_init(&front->q, &pd_video_qops,
1447 NULL, &front->queue_lock,
1448 V4L2_BUF_TYPE_VBI_CAPTURE,
1449 V4L2_FIELD_NONE, /* vbi is NONE mode */
1450 sizeof(struct videobuf_buffer),
1451 front);
1452 } else {
1453 /* maybe add FM support here */
1454 log("other ");
1455 ret = -EINVAL;
1456 goto out;
1457 }
1458
1459 front->pd = pd;
1460 front->curr_frame = NULL;
1461 INIT_LIST_HEAD(&front->active);
1462 spin_lock_init(&front->queue_lock);
1463
1464 file->private_data = front;
1465 kref_get(&pd->kref);
1466
1467 mutex_unlock(&pd->lock);
1468 return 0;
1469out:
1470 usb_autopm_put_interface(pd->interface);
1471 mutex_unlock(&pd->lock);
1472 return ret;
1473}
1474
1475static int pd_video_release(struct file *file)
1476{
1477 struct front_face *front = file->private_data;
1478 struct poseidon *pd = front->pd;
1479 s32 cmd_status = 0;
1480
1481 logs(front);
1482 mutex_lock(&pd->lock);
1483
1484 if (front->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
1485 pd->state &= ~POSEIDON_STATE_ANALOG;
1486
1487 /* stop the device, and free the URBs */
1488 usb_transfer_stop(&pd->video_data);
1489 free_all_urb(&pd->video_data);
1490
1491 /* stop the firmware */
1492 send_set_req(pd, PLAY_SERVICE, TLG_TUNE_PLAY_SVC_STOP,
1493 &cmd_status);
1494
1495 pd->file_for_stream = NULL;
1496 pd->video_data.users--;
1497 } else if (front->type == V4L2_BUF_TYPE_VBI_CAPTURE) {
1498 pd->state &= ~POSEIDON_STATE_VBI;
1499 pd->vbi_data.front = NULL;
1500 pd->vbi_data.users--;
1501 }
1502 videobuf_stop(&front->q);
1503 videobuf_mmap_free(&front->q);
1504
1505 usb_autopm_put_interface(pd->interface);
1506 mutex_unlock(&pd->lock);
1507
1508 kfree(front);
1509 file->private_data = NULL;
1510 kref_put(&pd->kref, poseidon_delete);
1511 return 0;
1512}
1513
1514static int pd_video_mmap(struct file *file, struct vm_area_struct *vma)
1515{
1516 struct front_face *front = file->private_data;
1517 return videobuf_mmap_mapper(&front->q, vma);
1518}
1519
1520unsigned int pd_video_poll(struct file *file, poll_table *table)
1521{
1522 struct front_face *front = file->private_data;
1523 return videobuf_poll_stream(file, &front->q, table);
1524}
1525
1526ssize_t pd_video_read(struct file *file, char __user *buffer,
1527 size_t count, loff_t *ppos)
1528{
1529 struct front_face *front = file->private_data;
1530 return videobuf_read_stream(&front->q, buffer, count, ppos,
1531 0, file->f_flags & O_NONBLOCK);
1532}
1533
1534/* This struct works for both VIDEO and VBI */
1535static const struct v4l2_file_operations pd_video_fops = {
1536 .owner = THIS_MODULE,
1537 .open = pd_video_open,
1538 .release = pd_video_release,
1539 .read = pd_video_read,
1540 .poll = pd_video_poll,
1541 .mmap = pd_video_mmap,
1542 .ioctl = video_ioctl2, /* maybe changed in future */
1543};
1544
1545static const struct v4l2_ioctl_ops pd_video_ioctl_ops = {
1546 .vidioc_querycap = vidioc_querycap,
1547
1548 /* Video format */
1549 .vidioc_g_fmt_vid_cap = vidioc_g_fmt,
1550 .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt,
1551 .vidioc_s_fmt_vid_cap = vidioc_s_fmt,
1552 .vidioc_g_fmt_vbi_cap = vidioc_g_fmt_vbi, /* VBI */
1553 .vidioc_try_fmt_vid_cap = vidioc_try_fmt,
1554
1555 /* Input */
1556 .vidioc_g_input = vidioc_g_input,
1557 .vidioc_s_input = vidioc_s_input,
1558 .vidioc_enum_input = vidioc_enum_input,
1559
1560 /* Audio ioctls */
1561 .vidioc_enumaudio = vidioc_enumaudio,
1562 .vidioc_g_audio = vidioc_g_audio,
1563 .vidioc_s_audio = vidioc_s_audio,
1564
1565 /* Tuner ioctls */
1566 .vidioc_g_tuner = vidioc_g_tuner,
1567 .vidioc_s_tuner = vidioc_s_tuner,
1568 .vidioc_s_std = vidioc_s_std,
1569 .vidioc_g_frequency = vidioc_g_frequency,
1570 .vidioc_s_frequency = vidioc_s_frequency,
1571
1572 /* Buffer handlers */
1573 .vidioc_reqbufs = vidioc_reqbufs,
1574 .vidioc_querybuf = vidioc_querybuf,
1575 .vidioc_qbuf = vidioc_qbuf,
1576 .vidioc_dqbuf = vidioc_dqbuf,
1577
1578 /* Stream on/off */
1579 .vidioc_streamon = vidioc_streamon,
1580 .vidioc_streamoff = vidioc_streamoff,
1581
1582 /* Control handling */
1583 .vidioc_queryctrl = vidioc_queryctrl,
1584 .vidioc_g_ctrl = vidioc_g_ctrl,
1585 .vidioc_s_ctrl = vidioc_s_ctrl,
1586};
1587
1588static struct video_device pd_video_template = {
1589 .name = "Telegent-Video",
1590 .fops = &pd_video_fops,
1591 .minor = -1,
1592 .release = video_device_release,
1593 .tvnorms = V4L2_STD_ALL,
1594 .ioctl_ops = &pd_video_ioctl_ops,
1595};
1596
1597struct video_device *vdev_init(struct poseidon *pd, struct video_device *tmp)
1598{
1599 struct video_device *vfd;
1600
1601 vfd = video_device_alloc();
1602 if (vfd == NULL)
1603 return NULL;
1604 *vfd = *tmp;
1605 vfd->minor = -1;
1606 vfd->v4l2_dev = &pd->v4l2_dev;
1607 /*vfd->parent = &(pd->udev->dev); */
1608 vfd->release = video_device_release;
1609 video_set_drvdata(vfd, pd);
1610 return vfd;
1611}
1612
1613void destroy_video_device(struct video_device **v_dev)
1614{
1615 struct video_device *dev = *v_dev;
1616
1617 if (dev == NULL)
1618 return;
1619
1620 if (video_is_registered(dev))
1621 video_unregister_device(dev);
1622 else
1623 video_device_release(dev);
1624 *v_dev = NULL;
1625}
1626
1627void pd_video_exit(struct poseidon *pd)
1628{
1629 struct video_data *video = &pd->video_data;
1630 struct vbi_data *vbi = &pd->vbi_data;
1631
1632 destroy_video_device(&video->v_dev);
1633 destroy_video_device(&vbi->v_dev);
1634 log();
1635}
1636
1637int pd_video_init(struct poseidon *pd)
1638{
1639 struct video_data *video = &pd->video_data;
1640 struct vbi_data *vbi = &pd->vbi_data;
1641 int ret = -ENOMEM;
1642
1643 video->v_dev = vdev_init(pd, &pd_video_template);
1644 if (video->v_dev == NULL)
1645 goto out;
1646
1647 ret = video_register_device(video->v_dev, VFL_TYPE_GRABBER, -1);
1648 if (ret != 0)
1649 goto out;
1650
1651 /* VBI uses the same template as video */
1652 vbi->v_dev = vdev_init(pd, &pd_video_template);
1653 if (vbi->v_dev == NULL) {
1654 ret = -ENOMEM;
1655 goto out;
1656 }
1657 ret = video_register_device(vbi->v_dev, VFL_TYPE_VBI, -1);
1658 if (ret != 0)
1659 goto out;
1660 log("register VIDEO/VBI devices");
1661 return 0;
1662out:
1663 log("VIDEO/VBI devices register failed, : %d", ret);
1664 pd_video_exit(pd);
1665 return ret;
1666}
1667
diff --git a/drivers/media/video/tlg2300/vendorcmds.h b/drivers/media/video/tlg2300/vendorcmds.h
new file mode 100644
index 000000000000..ba6f4ae3b2c2
--- /dev/null
+++ b/drivers/media/video/tlg2300/vendorcmds.h
@@ -0,0 +1,243 @@
1#ifndef VENDOR_CMD_H_
2#define VENDOR_CMD_H_
3
4#define BULK_ALTERNATE_IFACE (2)
5#define ISO_3K_BULK_ALTERNATE_IFACE (1)
6#define REQ_SET_CMD (0X00)
7#define REQ_GET_CMD (0X80)
8
9enum tlg__analog_audio_standard {
10 TLG_TUNE_ASTD_NONE = 0x00000000,
11 TLG_TUNE_ASTD_A2 = 0x00000001,
12 TLG_TUNE_ASTD_NICAM = 0x00000002,
13 TLG_TUNE_ASTD_EIAJ = 0x00000004,
14 TLG_TUNE_ASTD_BTSC = 0x00000008,
15 TLG_TUNE_ASTD_FM_US = 0x00000010,
16 TLG_TUNE_ASTD_FM_EUR = 0x00000020,
17 TLG_TUNE_ASTD_ALL = 0x0000003f
18};
19
20/*
21 * identifiers for Custom Parameter messages.
22 * @typedef cmd_custom_param_id_t
23 */
24enum cmd_custom_param_id {
25 CUST_PARM_ID_NONE = 0x00,
26 CUST_PARM_ID_BRIGHTNESS_CTRL = 0x01,
27 CUST_PARM_ID_CONTRAST_CTRL = 0x02,
28 CUST_PARM_ID_HUE_CTRL = 0x03,
29 CUST_PARM_ID_SATURATION_CTRL = 0x04,
30 CUST_PARM_ID_AUDIO_SNR_THRESHOLD = 0x10,
31 CUST_PARM_ID_AUDIO_AGC_THRESHOLD = 0x11,
32 CUST_PARM_ID_MAX
33};
34
35struct tuner_custom_parameter_s {
36 uint16_t param_id; /* Parameter identifier */
37 uint16_t param_value; /* Parameter value */
38};
39
40struct tuner_ber_rate_s {
41 uint32_t ber_rate; /* BER sample rate in seconds */
42};
43
44struct tuner_atv_sig_stat_s {
45 uint32_t sig_present;
46 uint32_t sig_locked;
47 uint32_t sig_lock_busy;
48 uint32_t sig_strength; /* milliDb */
49 uint32_t tv_audio_chan; /* mono/stereo/sap*/
50 uint32_t mvision_stat; /* macrovision status */
51};
52
53struct tuner_dtv_sig_stat_s {
54 uint32_t sig_present; /* Boolean*/
55 uint32_t sig_locked; /* Boolean */
56 uint32_t sig_lock_busy; /* Boolean (Can this time-out?) */
57 uint32_t sig_strength; /* milliDb*/
58};
59
60struct tuner_fm_sig_stat_s {
61 uint32_t sig_present; /* Boolean*/
62 uint32_t sig_locked; /* Boolean */
63 uint32_t sig_lock_busy; /* Boolean */
64 uint32_t sig_stereo_mono;/* TBD*/
65 uint32_t sig_strength; /* milliDb*/
66};
67
68enum _tag_tlg_tune_srv_cmd {
69 TLG_TUNE_PLAY_SVC_START = 1,
70 TLG_TUNE_PLAY_SVC_STOP
71};
72
73enum _tag_tune_atv_audio_mode_caps {
74 TLG_TUNE_TVAUDIO_MODE_MONO = 0x00000001,
75 TLG_TUNE_TVAUDIO_MODE_STEREO = 0x00000002,
76 TLG_TUNE_TVAUDIO_MODE_LANG_A = 0x00000010,/* Primary language*/
77 TLG_TUNE_TVAUDIO_MODE_LANG_B = 0x00000020,/* 2nd avail language*/
78 TLG_TUNE_TVAUDIO_MODE_LANG_C = 0x00000040
79};
80
81
82enum _tag_tuner_atv_audio_rates {
83 ATV_AUDIO_RATE_NONE = 0x00,/* Audio not supported*/
84 ATV_AUDIO_RATE_32K = 0x01,/* Audio rate = 32 KHz*/
85 ATV_AUDIO_RATE_48K = 0x02, /* Audio rate = 48 KHz*/
86 ATV_AUDIO_RATE_31_25K = 0x04 /* Audio rate = 31.25KHz */
87};
88
89enum _tag_tune_atv_vid_res_caps {
90 TLG_TUNE_VID_RES_NONE = 0x00000000,
91 TLG_TUNE_VID_RES_720 = 0x00000001,
92 TLG_TUNE_VID_RES_704 = 0x00000002,
93 TLG_TUNE_VID_RES_360 = 0x00000004
94};
95
96enum _tag_tuner_analog_video_format {
97 TLG_TUNER_VID_FORMAT_YUV = 0x00000001,
98 TLG_TUNER_VID_FORMAT_YCRCB = 0x00000002,
99 TLG_TUNER_VID_FORMAT_RGB_565 = 0x00000004,
100};
101
102enum tlg_ext_audio_support {
103 TLG_EXT_AUDIO_NONE = 0x00,/* No external audio input supported */
104 TLG_EXT_AUDIO_LR = 0x01/* LR external audio inputs supported*/
105};
106
107enum {
108 TLG_MODE_NONE = 0x00, /* No Mode specified*/
109 TLG_MODE_ANALOG_TV = 0x01, /* Analog Television mode*/
110 TLG_MODE_ANALOG_TV_UNCOMP = 0x01, /* Analog Television mode*/
111 TLG_MODE_ANALOG_TV_COMP = 0x02, /* Analog TV mode (compressed)*/
112 TLG_MODE_FM_RADIO = 0x04, /* FM Radio mode*/
113 TLG_MODE_DVB_T = 0x08, /* Digital TV (DVB-T)*/
114};
115
116enum tlg_signal_sources_t {
117 TLG_SIG_SRC_NONE = 0x00,/* Signal source not specified */
118 TLG_SIG_SRC_ANTENNA = 0x01,/* Signal src is: Antenna */
119 TLG_SIG_SRC_CABLE = 0x02,/* Signal src is: Coax Cable*/
120 TLG_SIG_SRC_SVIDEO = 0x04,/* Signal src is: S_VIDEO */
121 TLG_SIG_SRC_COMPOSITE = 0x08 /* Signal src is: Composite Video */
122};
123
124enum tuner_analog_video_standard {
125 TLG_TUNE_VSTD_NONE = 0x00000000,
126 TLG_TUNE_VSTD_NTSC_M = 0x00000001,
127 TLG_TUNE_VSTD_NTSC_M_J = 0x00000002,/* Japan */
128 TLG_TUNE_VSTD_PAL_B = 0x00000010,
129 TLG_TUNE_VSTD_PAL_D = 0x00000020,
130 TLG_TUNE_VSTD_PAL_G = 0x00000040,
131 TLG_TUNE_VSTD_PAL_H = 0x00000080,
132 TLG_TUNE_VSTD_PAL_I = 0x00000100,
133 TLG_TUNE_VSTD_PAL_M = 0x00000200,
134 TLG_TUNE_VSTD_PAL_N = 0x00000400,
135 TLG_TUNE_VSTD_SECAM_B = 0x00001000,
136 TLG_TUNE_VSTD_SECAM_D = 0x00002000,
137 TLG_TUNE_VSTD_SECAM_G = 0x00004000,
138 TLG_TUNE_VSTD_SECAM_H = 0x00008000,
139 TLG_TUNE_VSTD_SECAM_K = 0x00010000,
140 TLG_TUNE_VSTD_SECAM_K1 = 0x00020000,
141 TLG_TUNE_VSTD_SECAM_L = 0x00040000,
142 TLG_TUNE_VSTD_SECAM_L1 = 0x00080000,
143 TLG_TUNE_VSTD_PAL_N_COMBO = 0x00100000
144};
145
146enum tlg_mode_caps {
147 TLG_MODE_CAPS_NONE = 0x00, /* No Mode specified */
148 TLG_MODE_CAPS_ANALOG_TV_UNCOMP = 0x01, /* Analog TV mode */
149 TLG_MODE_CAPS_ANALOG_TV_COMP = 0x02, /* Analog TV (compressed)*/
150 TLG_MODE_CAPS_FM_RADIO = 0x04, /* FM Radio mode */
151 TLG_MODE_CAPS_DVB_T = 0x08, /* Digital TV (DVB-T) */
152};
153
154enum poseidon_vendor_cmds {
155 LAST_CMD_STAT = 0x00,
156 GET_CHIP_ID = 0x01,
157 GET_FW_ID = 0x02,
158 PRODUCT_CAPS = 0x03,
159
160 TUNE_MODE_CAP_ATV = 0x10,
161 TUNE_MODE_CAP_ATVCOMP = 0X10,
162 TUNE_MODE_CAP_DVBT = 0x10,
163 TUNE_MODE_CAP_FM = 0x10,
164 TUNE_MODE_SELECT = 0x11,
165 TUNE_FREQ_SELECT = 0x12,
166 SGNL_SRC_SEL = 0x13,
167
168 VIDEO_STD_SEL = 0x14,
169 VIDEO_STREAM_FMT_SEL = 0x15,
170 VIDEO_ROSOLU_AVAIL = 0x16,
171 VIDEO_ROSOLU_SEL = 0x17,
172 VIDEO_CONT_PROTECT = 0x20,
173
174 VCR_TIMING_MODSEL = 0x21,
175 EXT_AUDIO_CAP = 0x22,
176 EXT_AUDIO_SEL = 0x23,
177 TEST_PATTERN_SEL = 0x24,
178 VBI_DATA_SEL = 0x25,
179 AUDIO_SAMPLE_RATE_CAP = 0x28,
180 AUDIO_SAMPLE_RATE_SEL = 0x29,
181 TUNER_AUD_MODE = 0x2a,
182 TUNER_AUD_MODE_AVAIL = 0x2b,
183 TUNER_AUD_ANA_STD = 0x2c,
184 TUNER_CUSTOM_PARAMETER = 0x2f,
185
186 DVBT_TUNE_MODE_SEL = 0x30,
187 DVBT_BANDW_CAP = 0x31,
188 DVBT_BANDW_SEL = 0x32,
189 DVBT_GUARD_INTERV_CAP = 0x33,
190 DVBT_GUARD_INTERV_SEL = 0x34,
191 DVBT_MODULATION_CAP = 0x35,
192 DVBT_MODULATION_SEL = 0x36,
193 DVBT_INNER_FEC_RATE_CAP = 0x37,
194 DVBT_INNER_FEC_RATE_SEL = 0x38,
195 DVBT_TRANS_MODE_CAP = 0x39,
196 DVBT_TRANS_MODE_SEL = 0x3a,
197 DVBT_SEARCH_RANG = 0x3c,
198
199 TUNER_SETUP_ANALOG = 0x40,
200 TUNER_SETUP_DIGITAL = 0x41,
201 TUNER_SETUP_FM_RADIO = 0x42,
202 TAKE_REQUEST = 0x43, /* Take effect of the command */
203 PLAY_SERVICE = 0x44, /* Play start or Play stop */
204 TUNER_STATUS = 0x45,
205 TUNE_PROP_DVBT = 0x46,
206 ERR_RATE_STATS = 0x47,
207 TUNER_BER_RATE = 0x48,
208
209 SCAN_CAPS = 0x50,
210 SCAN_SETUP = 0x51,
211 SCAN_SERVICE = 0x52,
212 SCAN_STATS = 0x53,
213
214 PID_SET = 0x58,
215 PID_UNSET = 0x59,
216 PID_LIST = 0x5a,
217
218 IRD_CAP = 0x60,
219 IRD_MODE_SEL = 0x61,
220 IRD_SETUP = 0x62,
221
222 PTM_MODE_CAP = 0x70,
223 PTM_MODE_SEL = 0x71,
224 PTM_SERVICE = 0x72,
225 TUNER_REG_SCRIPT = 0x73,
226 CMD_CHIP_RST = 0x74,
227};
228
229enum tlg_bw {
230 TLG_BW_5 = 5,
231 TLG_BW_6 = 6,
232 TLG_BW_7 = 7,
233 TLG_BW_8 = 8,
234 TLG_BW_12 = 12,
235 TLG_BW_15 = 15
236};
237
238struct cmd_firmware_vers_s {
239 uint8_t fw_rev_major;
240 uint8_t fw_rev_minor;
241 uint16_t fw_patch;
242};
243#endif /* VENDOR_CMD_H_ */
diff --git a/drivers/media/video/tuner-core.c b/drivers/media/video/tuner-core.c
index 5b3eaa16afd2..c4dab6cfd948 100644
--- a/drivers/media/video/tuner-core.c
+++ b/drivers/media/video/tuner-core.c
@@ -1078,6 +1078,7 @@ static int tuner_probe(struct i2c_client *client,
1078 1078
1079 goto register_client; 1079 goto register_client;
1080 } 1080 }
1081 kfree(t);
1081 return -ENODEV; 1082 return -ENODEV;
1082 case 0x42: 1083 case 0x42:
1083 case 0x43: 1084 case 0x43:
diff --git a/drivers/media/video/tveeprom.c b/drivers/media/video/tveeprom.c
index d533ea57e7b1..0a877497b93f 100644
--- a/drivers/media/video/tveeprom.c
+++ b/drivers/media/video/tveeprom.c
@@ -680,10 +680,7 @@ void tveeprom_hauppauge_analog(struct i2c_client *c, struct tveeprom *tvee,
680 tveeprom_info("Hauppauge model %d, rev %s, serial# %d\n", 680 tveeprom_info("Hauppauge model %d, rev %s, serial# %d\n",
681 tvee->model, tvee->rev_str, tvee->serial_number); 681 tvee->model, tvee->rev_str, tvee->serial_number);
682 if (tvee->has_MAC_address == 1) 682 if (tvee->has_MAC_address == 1)
683 tveeprom_info("MAC address is %02X-%02X-%02X-%02X-%02X-%02X\n", 683 tveeprom_info("MAC address is %pM\n", tvee->MAC_address);
684 tvee->MAC_address[0], tvee->MAC_address[1],
685 tvee->MAC_address[2], tvee->MAC_address[3],
686 tvee->MAC_address[4], tvee->MAC_address[5]);
687 tveeprom_info("tuner model is %s (idx %d, type %d)\n", 684 tveeprom_info("tuner model is %s (idx %d, type %d)\n",
688 t_name1, tuner1, tvee->tuner_type); 685 t_name1, tuner1, tvee->tuner_type);
689 tveeprom_info("TV standards%s%s%s%s%s%s%s%s (eeprom 0x%02x)\n", 686 tveeprom_info("TV standards%s%s%s%s%s%s%s%s (eeprom 0x%02x)\n",
diff --git a/drivers/media/video/tvp7002.c b/drivers/media/video/tvp7002.c
new file mode 100644
index 000000000000..5a878bca02d4
--- /dev/null
+++ b/drivers/media/video/tvp7002.c
@@ -0,0 +1,1187 @@
1/* Texas Instruments Triple 8-/10-BIT 165-/110-MSPS Video and Graphics
2 * Digitizer with Horizontal PLL registers
3 *
4 * Copyright (C) 2009 Texas Instruments Inc
5 * Author: Santiago Nunez-Corrales <santiago.nunez@ridgerun.com>
6 *
7 * This code is partially based upon the TVP5150 driver
8 * written by Mauro Carvalho Chehab (mchehab@infradead.org),
9 * the TVP514x driver written by Vaibhav Hiremath <hvaibhav@ti.com>
10 * and the TVP7002 driver in the TI LSP 2.10.00.14. Revisions by
11 * Muralidharan Karicheri and Snehaprabha Narnakaje (TI).
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#include <linux/delay.h>
28#include <linux/i2c.h>
29#include <linux/videodev2.h>
30#include <media/tvp7002.h>
31#include <media/v4l2-device.h>
32#include <media/v4l2-chip-ident.h>
33#include <media/v4l2-common.h>
34#include "tvp7002_reg.h"
35
36MODULE_DESCRIPTION("TI TVP7002 Video and Graphics Digitizer driver");
37MODULE_AUTHOR("Santiago Nunez-Corrales <santiago.nunez@ridgerun.com>");
38MODULE_LICENSE("GPL");
39
40/* Module Name */
41#define TVP7002_MODULE_NAME "tvp7002"
42
43/* I2C retry attempts */
44#define I2C_RETRY_COUNT (5)
45
46/* End of registers */
47#define TVP7002_EOR 0x5c
48
49/* Read write definition for registers */
50#define TVP7002_READ 0
51#define TVP7002_WRITE 1
52#define TVP7002_RESERVED 2
53
54/* Interlaced vs progressive mask and shift */
55#define TVP7002_IP_SHIFT 5
56#define TVP7002_INPR_MASK (0x01 << TVP7002_IP_SHIFT)
57
58/* Shift for CPL and LPF registers */
59#define TVP7002_CL_SHIFT 8
60#define TVP7002_CL_MASK 0x0f
61
62/* Debug functions */
63static int debug;
64module_param(debug, bool, 0644);
65MODULE_PARM_DESC(debug, "Debug level (0-2)");
66
67/* Structure for register values */
68struct i2c_reg_value {
69 u8 reg;
70 u8 value;
71 u8 type;
72};
73
74/*
75 * Register default values (according to tvp7002 datasheet)
76 * In the case of read-only registers, the value (0xff) is
77 * never written. R/W functionality is controlled by the
78 * writable bit in the register struct definition.
79 */
80static const struct i2c_reg_value tvp7002_init_default[] = {
81 { TVP7002_CHIP_REV, 0xff, TVP7002_READ },
82 { TVP7002_HPLL_FDBK_DIV_MSBS, 0x67, TVP7002_WRITE },
83 { TVP7002_HPLL_FDBK_DIV_LSBS, 0x20, TVP7002_WRITE },
84 { TVP7002_HPLL_CRTL, 0xa0, TVP7002_WRITE },
85 { TVP7002_HPLL_PHASE_SEL, 0x80, TVP7002_WRITE },
86 { TVP7002_CLAMP_START, 0x32, TVP7002_WRITE },
87 { TVP7002_CLAMP_W, 0x20, TVP7002_WRITE },
88 { TVP7002_HSYNC_OUT_W, 0x60, TVP7002_WRITE },
89 { TVP7002_B_FINE_GAIN, 0x00, TVP7002_WRITE },
90 { TVP7002_G_FINE_GAIN, 0x00, TVP7002_WRITE },
91 { TVP7002_R_FINE_GAIN, 0x00, TVP7002_WRITE },
92 { TVP7002_B_FINE_OFF_MSBS, 0x80, TVP7002_WRITE },
93 { TVP7002_G_FINE_OFF_MSBS, 0x80, TVP7002_WRITE },
94 { TVP7002_R_FINE_OFF_MSBS, 0x80, TVP7002_WRITE },
95 { TVP7002_SYNC_CTL_1, 0x20, TVP7002_WRITE },
96 { TVP7002_HPLL_AND_CLAMP_CTL, 0x2e, TVP7002_WRITE },
97 { TVP7002_SYNC_ON_G_THRS, 0x5d, TVP7002_WRITE },
98 { TVP7002_SYNC_SEPARATOR_THRS, 0x47, TVP7002_WRITE },
99 { TVP7002_HPLL_PRE_COAST, 0x00, TVP7002_WRITE },
100 { TVP7002_HPLL_POST_COAST, 0x00, TVP7002_WRITE },
101 { TVP7002_SYNC_DETECT_STAT, 0xff, TVP7002_READ },
102 { TVP7002_OUT_FORMATTER, 0x47, TVP7002_WRITE },
103 { TVP7002_MISC_CTL_1, 0x01, TVP7002_WRITE },
104 { TVP7002_MISC_CTL_2, 0x00, TVP7002_WRITE },
105 { TVP7002_MISC_CTL_3, 0x01, TVP7002_WRITE },
106 { TVP7002_IN_MUX_SEL_1, 0x00, TVP7002_WRITE },
107 { TVP7002_IN_MUX_SEL_2, 0x67, TVP7002_WRITE },
108 { TVP7002_B_AND_G_COARSE_GAIN, 0x77, TVP7002_WRITE },
109 { TVP7002_R_COARSE_GAIN, 0x07, TVP7002_WRITE },
110 { TVP7002_FINE_OFF_LSBS, 0x00, TVP7002_WRITE },
111 { TVP7002_B_COARSE_OFF, 0x10, TVP7002_WRITE },
112 { TVP7002_G_COARSE_OFF, 0x10, TVP7002_WRITE },
113 { TVP7002_R_COARSE_OFF, 0x10, TVP7002_WRITE },
114 { TVP7002_HSOUT_OUT_START, 0x08, TVP7002_WRITE },
115 { TVP7002_MISC_CTL_4, 0x00, TVP7002_WRITE },
116 { TVP7002_B_DGTL_ALC_OUT_LSBS, 0xff, TVP7002_READ },
117 { TVP7002_G_DGTL_ALC_OUT_LSBS, 0xff, TVP7002_READ },
118 { TVP7002_R_DGTL_ALC_OUT_LSBS, 0xff, TVP7002_READ },
119 { TVP7002_AUTO_LVL_CTL_ENABLE, 0x80, TVP7002_WRITE },
120 { TVP7002_DGTL_ALC_OUT_MSBS, 0xff, TVP7002_READ },
121 { TVP7002_AUTO_LVL_CTL_FILTER, 0x53, TVP7002_WRITE },
122 { 0x29, 0x08, TVP7002_RESERVED },
123 { TVP7002_FINE_CLAMP_CTL, 0x07, TVP7002_WRITE },
124 /* PWR_CTL is controlled only by the probe and reset functions */
125 { TVP7002_PWR_CTL, 0x00, TVP7002_RESERVED },
126 { TVP7002_ADC_SETUP, 0x50, TVP7002_WRITE },
127 { TVP7002_COARSE_CLAMP_CTL, 0x00, TVP7002_WRITE },
128 { TVP7002_SOG_CLAMP, 0x80, TVP7002_WRITE },
129 { TVP7002_RGB_COARSE_CLAMP_CTL, 0x00, TVP7002_WRITE },
130 { TVP7002_SOG_COARSE_CLAMP_CTL, 0x04, TVP7002_WRITE },
131 { TVP7002_ALC_PLACEMENT, 0x5a, TVP7002_WRITE },
132 { 0x32, 0x18, TVP7002_RESERVED },
133 { 0x33, 0x60, TVP7002_RESERVED },
134 { TVP7002_MVIS_STRIPPER_W, 0xff, TVP7002_RESERVED },
135 { TVP7002_VSYNC_ALGN, 0x10, TVP7002_WRITE },
136 { TVP7002_SYNC_BYPASS, 0x00, TVP7002_WRITE },
137 { TVP7002_L_FRAME_STAT_LSBS, 0xff, TVP7002_READ },
138 { TVP7002_L_FRAME_STAT_MSBS, 0xff, TVP7002_READ },
139 { TVP7002_CLK_L_STAT_LSBS, 0xff, TVP7002_READ },
140 { TVP7002_CLK_L_STAT_MSBS, 0xff, TVP7002_READ },
141 { TVP7002_HSYNC_W, 0xff, TVP7002_READ },
142 { TVP7002_VSYNC_W, 0xff, TVP7002_READ },
143 { TVP7002_L_LENGTH_TOL, 0x03, TVP7002_WRITE },
144 { 0x3e, 0x60, TVP7002_RESERVED },
145 { TVP7002_VIDEO_BWTH_CTL, 0x01, TVP7002_WRITE },
146 { TVP7002_AVID_START_PIXEL_LSBS, 0x01, TVP7002_WRITE },
147 { TVP7002_AVID_START_PIXEL_MSBS, 0x2c, TVP7002_WRITE },
148 { TVP7002_AVID_STOP_PIXEL_LSBS, 0x06, TVP7002_WRITE },
149 { TVP7002_AVID_STOP_PIXEL_MSBS, 0x2c, TVP7002_WRITE },
150 { TVP7002_VBLK_F_0_START_L_OFF, 0x05, TVP7002_WRITE },
151 { TVP7002_VBLK_F_1_START_L_OFF, 0x00, TVP7002_WRITE },
152 { TVP7002_VBLK_F_0_DURATION, 0x1e, TVP7002_WRITE },
153 { TVP7002_VBLK_F_1_DURATION, 0x00, TVP7002_WRITE },
154 { TVP7002_FBIT_F_0_START_L_OFF, 0x00, TVP7002_WRITE },
155 { TVP7002_FBIT_F_1_START_L_OFF, 0x00, TVP7002_WRITE },
156 { TVP7002_YUV_Y_G_COEF_LSBS, 0xe3, TVP7002_WRITE },
157 { TVP7002_YUV_Y_G_COEF_MSBS, 0x16, TVP7002_WRITE },
158 { TVP7002_YUV_Y_B_COEF_LSBS, 0x4f, TVP7002_WRITE },
159 { TVP7002_YUV_Y_B_COEF_MSBS, 0x02, TVP7002_WRITE },
160 { TVP7002_YUV_Y_R_COEF_LSBS, 0xce, TVP7002_WRITE },
161 { TVP7002_YUV_Y_R_COEF_MSBS, 0x06, TVP7002_WRITE },
162 { TVP7002_YUV_U_G_COEF_LSBS, 0xab, TVP7002_WRITE },
163 { TVP7002_YUV_U_G_COEF_MSBS, 0xf3, TVP7002_WRITE },
164 { TVP7002_YUV_U_B_COEF_LSBS, 0x00, TVP7002_WRITE },
165 { TVP7002_YUV_U_B_COEF_MSBS, 0x10, TVP7002_WRITE },
166 { TVP7002_YUV_U_R_COEF_LSBS, 0x55, TVP7002_WRITE },
167 { TVP7002_YUV_U_R_COEF_MSBS, 0xfc, TVP7002_WRITE },
168 { TVP7002_YUV_V_G_COEF_LSBS, 0x78, TVP7002_WRITE },
169 { TVP7002_YUV_V_G_COEF_MSBS, 0xf1, TVP7002_WRITE },
170 { TVP7002_YUV_V_B_COEF_LSBS, 0x88, TVP7002_WRITE },
171 { TVP7002_YUV_V_B_COEF_MSBS, 0xfe, TVP7002_WRITE },
172 { TVP7002_YUV_V_R_COEF_LSBS, 0x00, TVP7002_WRITE },
173 { TVP7002_YUV_V_R_COEF_MSBS, 0x10, TVP7002_WRITE },
174 /* This signals end of register values */
175 { TVP7002_EOR, 0xff, TVP7002_RESERVED }
176};
177
178/* Register parameters for 480P */
179static const struct i2c_reg_value tvp7002_parms_480P[] = {
180 { TVP7002_HPLL_FDBK_DIV_MSBS, 0x35, TVP7002_WRITE },
181 { TVP7002_HPLL_FDBK_DIV_LSBS, 0x0a, TVP7002_WRITE },
182 { TVP7002_HPLL_CRTL, 0x02, TVP7002_WRITE },
183 { TVP7002_HPLL_PHASE_SEL, 0x14, TVP7002_WRITE },
184 { TVP7002_AVID_START_PIXEL_LSBS, 0x91, TVP7002_WRITE },
185 { TVP7002_AVID_START_PIXEL_MSBS, 0x00, TVP7002_WRITE },
186 { TVP7002_AVID_STOP_PIXEL_LSBS, 0x0B, TVP7002_WRITE },
187 { TVP7002_AVID_STOP_PIXEL_MSBS, 0x00, TVP7002_WRITE },
188 { TVP7002_VBLK_F_0_START_L_OFF, 0x03, TVP7002_WRITE },
189 { TVP7002_VBLK_F_1_START_L_OFF, 0x01, TVP7002_WRITE },
190 { TVP7002_VBLK_F_0_DURATION, 0x13, TVP7002_WRITE },
191 { TVP7002_VBLK_F_1_DURATION, 0x13, TVP7002_WRITE },
192 { TVP7002_ALC_PLACEMENT, 0x18, TVP7002_WRITE },
193 { TVP7002_CLAMP_START, 0x06, TVP7002_WRITE },
194 { TVP7002_CLAMP_W, 0x10, TVP7002_WRITE },
195 { TVP7002_HPLL_PRE_COAST, 0x03, TVP7002_WRITE },
196 { TVP7002_HPLL_POST_COAST, 0x03, TVP7002_WRITE },
197 { TVP7002_EOR, 0xff, TVP7002_RESERVED }
198};
199
200/* Register parameters for 576P */
201static const struct i2c_reg_value tvp7002_parms_576P[] = {
202 { TVP7002_HPLL_FDBK_DIV_MSBS, 0x36, TVP7002_WRITE },
203 { TVP7002_HPLL_FDBK_DIV_LSBS, 0x00, TVP7002_WRITE },
204 { TVP7002_HPLL_CRTL, 0x18, TVP7002_WRITE },
205 { TVP7002_HPLL_PHASE_SEL, 0x14, TVP7002_WRITE },
206 { TVP7002_AVID_START_PIXEL_LSBS, 0x9B, TVP7002_WRITE },
207 { TVP7002_AVID_START_PIXEL_MSBS, 0x00, TVP7002_WRITE },
208 { TVP7002_AVID_STOP_PIXEL_LSBS, 0x0F, TVP7002_WRITE },
209 { TVP7002_AVID_STOP_PIXEL_MSBS, 0x00, TVP7002_WRITE },
210 { TVP7002_VBLK_F_0_START_L_OFF, 0x00, TVP7002_WRITE },
211 { TVP7002_VBLK_F_1_START_L_OFF, 0x00, TVP7002_WRITE },
212 { TVP7002_VBLK_F_0_DURATION, 0x2D, TVP7002_WRITE },
213 { TVP7002_VBLK_F_1_DURATION, 0x00, TVP7002_WRITE },
214 { TVP7002_ALC_PLACEMENT, 0x18, TVP7002_WRITE },
215 { TVP7002_CLAMP_START, 0x06, TVP7002_WRITE },
216 { TVP7002_CLAMP_W, 0x10, TVP7002_WRITE },
217 { TVP7002_HPLL_PRE_COAST, 0x03, TVP7002_WRITE },
218 { TVP7002_HPLL_POST_COAST, 0x03, TVP7002_WRITE },
219 { TVP7002_EOR, 0xff, TVP7002_RESERVED }
220};
221
222/* Register parameters for 1080I60 */
223static const struct i2c_reg_value tvp7002_parms_1080I60[] = {
224 { TVP7002_HPLL_FDBK_DIV_MSBS, 0x89, TVP7002_WRITE },
225 { TVP7002_HPLL_FDBK_DIV_LSBS, 0x08, TVP7002_WRITE },
226 { TVP7002_HPLL_CRTL, 0x98, TVP7002_WRITE },
227 { TVP7002_HPLL_PHASE_SEL, 0x14, TVP7002_WRITE },
228 { TVP7002_AVID_START_PIXEL_LSBS, 0x06, TVP7002_WRITE },
229 { TVP7002_AVID_START_PIXEL_MSBS, 0x01, TVP7002_WRITE },
230 { TVP7002_AVID_STOP_PIXEL_LSBS, 0x8a, TVP7002_WRITE },
231 { TVP7002_AVID_STOP_PIXEL_MSBS, 0x08, TVP7002_WRITE },
232 { TVP7002_VBLK_F_0_START_L_OFF, 0x02, TVP7002_WRITE },
233 { TVP7002_VBLK_F_1_START_L_OFF, 0x02, TVP7002_WRITE },
234 { TVP7002_VBLK_F_0_DURATION, 0x16, TVP7002_WRITE },
235 { TVP7002_VBLK_F_1_DURATION, 0x17, TVP7002_WRITE },
236 { TVP7002_ALC_PLACEMENT, 0x5a, TVP7002_WRITE },
237 { TVP7002_CLAMP_START, 0x32, TVP7002_WRITE },
238 { TVP7002_CLAMP_W, 0x20, TVP7002_WRITE },
239 { TVP7002_HPLL_PRE_COAST, 0x01, TVP7002_WRITE },
240 { TVP7002_HPLL_POST_COAST, 0x00, TVP7002_WRITE },
241 { TVP7002_EOR, 0xff, TVP7002_RESERVED }
242};
243
244/* Register parameters for 1080P60 */
245static const struct i2c_reg_value tvp7002_parms_1080P60[] = {
246 { TVP7002_HPLL_FDBK_DIV_MSBS, 0x89, TVP7002_WRITE },
247 { TVP7002_HPLL_FDBK_DIV_LSBS, 0x08, TVP7002_WRITE },
248 { TVP7002_HPLL_CRTL, 0xE0, TVP7002_WRITE },
249 { TVP7002_HPLL_PHASE_SEL, 0x14, TVP7002_WRITE },
250 { TVP7002_AVID_START_PIXEL_LSBS, 0x06, TVP7002_WRITE },
251 { TVP7002_AVID_START_PIXEL_MSBS, 0x01, TVP7002_WRITE },
252 { TVP7002_AVID_STOP_PIXEL_LSBS, 0x8a, TVP7002_WRITE },
253 { TVP7002_AVID_STOP_PIXEL_MSBS, 0x08, TVP7002_WRITE },
254 { TVP7002_VBLK_F_0_START_L_OFF, 0x02, TVP7002_WRITE },
255 { TVP7002_VBLK_F_1_START_L_OFF, 0x02, TVP7002_WRITE },
256 { TVP7002_VBLK_F_0_DURATION, 0x16, TVP7002_WRITE },
257 { TVP7002_VBLK_F_1_DURATION, 0x17, TVP7002_WRITE },
258 { TVP7002_ALC_PLACEMENT, 0x5a, TVP7002_WRITE },
259 { TVP7002_CLAMP_START, 0x32, TVP7002_WRITE },
260 { TVP7002_CLAMP_W, 0x20, TVP7002_WRITE },
261 { TVP7002_HPLL_PRE_COAST, 0x01, TVP7002_WRITE },
262 { TVP7002_HPLL_POST_COAST, 0x00, TVP7002_WRITE },
263 { TVP7002_EOR, 0xff, TVP7002_RESERVED }
264};
265
266/* Register parameters for 1080I50 */
267static const struct i2c_reg_value tvp7002_parms_1080I50[] = {
268 { TVP7002_HPLL_FDBK_DIV_MSBS, 0xa5, TVP7002_WRITE },
269 { TVP7002_HPLL_FDBK_DIV_LSBS, 0x00, TVP7002_WRITE },
270 { TVP7002_HPLL_CRTL, 0x98, TVP7002_WRITE },
271 { TVP7002_HPLL_PHASE_SEL, 0x14, TVP7002_WRITE },
272 { TVP7002_AVID_START_PIXEL_LSBS, 0x06, TVP7002_WRITE },
273 { TVP7002_AVID_START_PIXEL_MSBS, 0x01, TVP7002_WRITE },
274 { TVP7002_AVID_STOP_PIXEL_LSBS, 0x8a, TVP7002_WRITE },
275 { TVP7002_AVID_STOP_PIXEL_MSBS, 0x08, TVP7002_WRITE },
276 { TVP7002_VBLK_F_0_START_L_OFF, 0x02, TVP7002_WRITE },
277 { TVP7002_VBLK_F_1_START_L_OFF, 0x02, TVP7002_WRITE },
278 { TVP7002_VBLK_F_0_DURATION, 0x16, TVP7002_WRITE },
279 { TVP7002_VBLK_F_1_DURATION, 0x17, TVP7002_WRITE },
280 { TVP7002_ALC_PLACEMENT, 0x5a, TVP7002_WRITE },
281 { TVP7002_CLAMP_START, 0x32, TVP7002_WRITE },
282 { TVP7002_CLAMP_W, 0x20, TVP7002_WRITE },
283 { TVP7002_HPLL_PRE_COAST, 0x01, TVP7002_WRITE },
284 { TVP7002_HPLL_POST_COAST, 0x00, TVP7002_WRITE },
285 { TVP7002_EOR, 0xff, TVP7002_RESERVED }
286};
287
288/* Register parameters for 720P60 */
289static const struct i2c_reg_value tvp7002_parms_720P60[] = {
290 { TVP7002_HPLL_FDBK_DIV_MSBS, 0x67, TVP7002_WRITE },
291 { TVP7002_HPLL_FDBK_DIV_LSBS, 0x02, TVP7002_WRITE },
292 { TVP7002_HPLL_CRTL, 0xa0, TVP7002_WRITE },
293 { TVP7002_HPLL_PHASE_SEL, 0x16, TVP7002_WRITE },
294 { TVP7002_AVID_START_PIXEL_LSBS, 0x47, TVP7002_WRITE },
295 { TVP7002_AVID_START_PIXEL_MSBS, 0x01, TVP7002_WRITE },
296 { TVP7002_AVID_STOP_PIXEL_LSBS, 0x4B, TVP7002_WRITE },
297 { TVP7002_AVID_STOP_PIXEL_MSBS, 0x06, TVP7002_WRITE },
298 { TVP7002_VBLK_F_0_START_L_OFF, 0x05, TVP7002_WRITE },
299 { TVP7002_VBLK_F_1_START_L_OFF, 0x00, TVP7002_WRITE },
300 { TVP7002_VBLK_F_0_DURATION, 0x2D, TVP7002_WRITE },
301 { TVP7002_VBLK_F_1_DURATION, 0x00, TVP7002_WRITE },
302 { TVP7002_ALC_PLACEMENT, 0x5a, TVP7002_WRITE },
303 { TVP7002_CLAMP_START, 0x32, TVP7002_WRITE },
304 { TVP7002_CLAMP_W, 0x20, TVP7002_WRITE },
305 { TVP7002_HPLL_PRE_COAST, 0x00, TVP7002_WRITE },
306 { TVP7002_HPLL_POST_COAST, 0x00, TVP7002_WRITE },
307 { TVP7002_EOR, 0xff, TVP7002_RESERVED }
308};
309
310/* Register parameters for 720P50 */
311static const struct i2c_reg_value tvp7002_parms_720P50[] = {
312 { TVP7002_HPLL_FDBK_DIV_MSBS, 0x7b, TVP7002_WRITE },
313 { TVP7002_HPLL_FDBK_DIV_LSBS, 0x0c, TVP7002_WRITE },
314 { TVP7002_HPLL_CRTL, 0x98, TVP7002_WRITE },
315 { TVP7002_HPLL_PHASE_SEL, 0x16, TVP7002_WRITE },
316 { TVP7002_AVID_START_PIXEL_LSBS, 0x47, TVP7002_WRITE },
317 { TVP7002_AVID_START_PIXEL_MSBS, 0x01, TVP7002_WRITE },
318 { TVP7002_AVID_STOP_PIXEL_LSBS, 0x4B, TVP7002_WRITE },
319 { TVP7002_AVID_STOP_PIXEL_MSBS, 0x06, TVP7002_WRITE },
320 { TVP7002_VBLK_F_0_START_L_OFF, 0x05, TVP7002_WRITE },
321 { TVP7002_VBLK_F_1_START_L_OFF, 0x00, TVP7002_WRITE },
322 { TVP7002_VBLK_F_0_DURATION, 0x2D, TVP7002_WRITE },
323 { TVP7002_VBLK_F_1_DURATION, 0x00, TVP7002_WRITE },
324 { TVP7002_ALC_PLACEMENT, 0x5a, TVP7002_WRITE },
325 { TVP7002_CLAMP_START, 0x32, TVP7002_WRITE },
326 { TVP7002_CLAMP_W, 0x20, TVP7002_WRITE },
327 { TVP7002_HPLL_PRE_COAST, 0x01, TVP7002_WRITE },
328 { TVP7002_HPLL_POST_COAST, 0x00, TVP7002_WRITE },
329 { TVP7002_EOR, 0xff, TVP7002_RESERVED }
330};
331
332/* Struct list for available formats */
333static const struct v4l2_fmtdesc tvp7002_fmt_list[] = {
334 {
335 .index = 0,
336 .type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
337 .flags = 0,
338 .description = "8-bit UYVY 4:2:2 Format",
339 .pixelformat = V4L2_PIX_FMT_UYVY,
340 },
341};
342
343#define NUM_FORMATS ARRAY_SIZE(tvp7002_fmt_list)
344
345/* Preset definition for handling device operation */
346struct tvp7002_preset_definition {
347 u32 preset;
348 const struct i2c_reg_value *p_settings;
349 enum v4l2_colorspace color_space;
350 enum v4l2_field scanmode;
351 u16 progressive;
352 u16 lines_per_frame;
353 u16 cpl_min;
354 u16 cpl_max;
355};
356
357/* Struct list for digital video presets */
358static const struct tvp7002_preset_definition tvp7002_presets[] = {
359 {
360 V4L2_DV_720P60,
361 tvp7002_parms_720P60,
362 V4L2_COLORSPACE_REC709,
363 V4L2_FIELD_NONE,
364 1,
365 0x2EE,
366 135,
367 153
368 },
369 {
370 V4L2_DV_1080I60,
371 tvp7002_parms_1080I60,
372 V4L2_COLORSPACE_REC709,
373 V4L2_FIELD_INTERLACED,
374 0,
375 0x465,
376 181,
377 205
378 },
379 {
380 V4L2_DV_1080I50,
381 tvp7002_parms_1080I50,
382 V4L2_COLORSPACE_REC709,
383 V4L2_FIELD_INTERLACED,
384 0,
385 0x465,
386 217,
387 245
388 },
389 {
390 V4L2_DV_720P50,
391 tvp7002_parms_720P50,
392 V4L2_COLORSPACE_REC709,
393 V4L2_FIELD_NONE,
394 1,
395 0x2EE,
396 163,
397 183
398 },
399 {
400 V4L2_DV_1080P60,
401 tvp7002_parms_1080P60,
402 V4L2_COLORSPACE_REC709,
403 V4L2_FIELD_NONE,
404 1,
405 0x465,
406 90,
407 102
408 },
409 {
410 V4L2_DV_480P59_94,
411 tvp7002_parms_480P,
412 V4L2_COLORSPACE_SMPTE170M,
413 V4L2_FIELD_NONE,
414 1,
415 0x20D,
416 0xffff,
417 0xffff
418 },
419 {
420 V4L2_DV_576P50,
421 tvp7002_parms_576P,
422 V4L2_COLORSPACE_SMPTE170M,
423 V4L2_FIELD_NONE,
424 1,
425 0x271,
426 0xffff,
427 0xffff
428 }
429};
430
431#define NUM_PRESETS ARRAY_SIZE(tvp7002_presets)
432
433/* Device definition */
434struct tvp7002 {
435 struct v4l2_subdev sd;
436 const struct tvp7002_config *pdata;
437
438 int ver;
439 int streaming;
440
441 struct v4l2_pix_format pix;
442 const struct tvp7002_preset_definition *current_preset;
443 u8 gain;
444};
445
446/*
447 * to_tvp7002 - Obtain device handler TVP7002
448 * @sd: ptr to v4l2_subdev struct
449 *
450 * Returns device handler tvp7002.
451 */
452static inline struct tvp7002 *to_tvp7002(struct v4l2_subdev *sd)
453{
454 return container_of(sd, struct tvp7002, sd);
455}
456
457/*
458 * tvp7002_read - Read a value from a register in an TVP7002
459 * @sd: ptr to v4l2_subdev struct
460 * @reg: TVP7002 register address
461 * @dst: pointer to 8-bit destination
462 *
463 * Returns value read if successful, or non-zero (-1) otherwise.
464 */
465static int tvp7002_read(struct v4l2_subdev *sd, u8 addr, u8 *dst)
466{
467 struct i2c_client *c = v4l2_get_subdevdata(sd);
468 int retry;
469 int error;
470
471 for (retry = 0; retry < I2C_RETRY_COUNT; retry++) {
472 error = i2c_smbus_read_byte_data(c, addr);
473
474 if (error >= 0) {
475 *dst = (u8)error;
476 return 0;
477 }
478
479 msleep_interruptible(10);
480 }
481 v4l2_err(sd, "TVP7002 read error %d\n", error);
482 return error;
483}
484
485/*
486 * tvp7002_read_err() - Read a register value with error code
487 * @sd: pointer to standard V4L2 sub-device structure
488 * @reg: destination register
489 * @val: value to be read
490 * @error: pointer to error value
491 *
492 * Read a value in a register and save error value in pointer.
493 * Also update the register table if successful
494 */
495static inline void tvp7002_read_err(struct v4l2_subdev *sd, u8 reg,
496 u8 *dst, int *err)
497{
498 if (!*err)
499 *err = tvp7002_read(sd, reg, dst);
500}
501
502/*
503 * tvp7002_write() - Write a value to a register in TVP7002
504 * @sd: ptr to v4l2_subdev struct
505 * @addr: TVP7002 register address
506 * @value: value to be written to the register
507 *
508 * Write a value to a register in an TVP7002 decoder device.
509 * Returns zero if successful, or non-zero otherwise.
510 */
511static int tvp7002_write(struct v4l2_subdev *sd, u8 addr, u8 value)
512{
513 struct i2c_client *c;
514 int retry;
515 int error;
516
517 c = v4l2_get_subdevdata(sd);
518
519 for (retry = 0; retry < I2C_RETRY_COUNT; retry++) {
520 error = i2c_smbus_write_byte_data(c, addr, value);
521
522 if (error >= 0)
523 return 0;
524
525 v4l2_warn(sd, "Write: retry ... %d\n", retry);
526 msleep_interruptible(10);
527 }
528 v4l2_err(sd, "TVP7002 write error %d\n", error);
529 return error;
530}
531
532/*
533 * tvp7002_write_err() - Write a register value with error code
534 * @sd: pointer to standard V4L2 sub-device structure
535 * @reg: destination register
536 * @val: value to be written
537 * @error: pointer to error value
538 *
539 * Write a value in a register and save error value in pointer.
540 * Also update the register table if successful
541 */
542static inline void tvp7002_write_err(struct v4l2_subdev *sd, u8 reg,
543 u8 val, int *err)
544{
545 if (!*err)
546 *err = tvp7002_write(sd, reg, val);
547}
548
549/*
550 * tvp7002_g_chip_ident() - Get chip identification number
551 * @sd: ptr to v4l2_subdev struct
552 * @chip: ptr to v4l2_dbg_chip_ident struct
553 *
554 * Obtains the chip's identification number.
555 * Returns zero or -EINVAL if read operation fails.
556 */
557static int tvp7002_g_chip_ident(struct v4l2_subdev *sd,
558 struct v4l2_dbg_chip_ident *chip)
559{
560 u8 rev;
561 int error;
562 struct i2c_client *client = v4l2_get_subdevdata(sd);
563
564 error = tvp7002_read(sd, TVP7002_CHIP_REV, &rev);
565
566 if (error < 0)
567 return error;
568
569 return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_TVP7002, rev);
570}
571
572/*
573 * tvp7002_write_inittab() - Write initialization values
574 * @sd: ptr to v4l2_subdev struct
575 * @regs: ptr to i2c_reg_value struct
576 *
577 * Write initialization values.
578 * Returns zero or -EINVAL if read operation fails.
579 */
580static int tvp7002_write_inittab(struct v4l2_subdev *sd,
581 const struct i2c_reg_value *regs)
582{
583 int error = 0;
584
585 /* Initialize the first (defined) registers */
586 while (TVP7002_EOR != regs->reg) {
587 if (TVP7002_WRITE == regs->type)
588 tvp7002_write_err(sd, regs->reg, regs->value, &error);
589 regs++;
590 }
591
592 return error;
593}
594
595/*
596 * tvp7002_s_dv_preset() - Set digital video preset
597 * @sd: ptr to v4l2_subdev struct
598 * @std: ptr to v4l2_dv_preset struct
599 *
600 * Set the digital video preset for a TVP7002 decoder device.
601 * Returns zero when successful or -EINVAL if register access fails.
602 */
603static int tvp7002_s_dv_preset(struct v4l2_subdev *sd,
604 struct v4l2_dv_preset *dv_preset)
605{
606 struct tvp7002 *device = to_tvp7002(sd);
607 u32 preset;
608 int i;
609
610 for (i = 0; i < NUM_PRESETS; i++) {
611 preset = tvp7002_presets[i].preset;
612 if (preset == dv_preset->preset) {
613 device->current_preset = &tvp7002_presets[i];
614 return tvp7002_write_inittab(sd, tvp7002_presets[i].p_settings);
615 }
616 }
617
618 return -EINVAL;
619}
620
621/*
622 * tvp7002_g_ctrl() - Get a control
623 * @sd: ptr to v4l2_subdev struct
624 * @ctrl: ptr to v4l2_control struct
625 *
626 * Get a control for a TVP7002 decoder device.
627 * Returns zero when successful or -EINVAL if register access fails.
628 */
629static int tvp7002_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
630{
631 struct tvp7002 *device = to_tvp7002(sd);
632
633 switch (ctrl->id) {
634 case V4L2_CID_GAIN:
635 ctrl->value = device->gain;
636 return 0;
637 default:
638 return -EINVAL;
639 }
640}
641
642/*
643 * tvp7002_s_ctrl() - Set a control
644 * @sd: ptr to v4l2_subdev struct
645 * @ctrl: ptr to v4l2_control struct
646 *
647 * Set a control in TVP7002 decoder device.
648 * Returns zero when successful or -EINVAL if register access fails.
649 */
650static int tvp7002_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
651{
652 struct tvp7002 *device = to_tvp7002(sd);
653 int error = 0;
654
655 switch (ctrl->id) {
656 case V4L2_CID_GAIN:
657 tvp7002_write_err(sd, TVP7002_R_FINE_GAIN,
658 ctrl->value & 0xff, &error);
659 tvp7002_write_err(sd, TVP7002_G_FINE_GAIN,
660 ctrl->value & 0xff, &error);
661 tvp7002_write_err(sd, TVP7002_B_FINE_GAIN,
662 ctrl->value & 0xff, &error);
663
664 if (error < 0)
665 return error;
666
667 /* Set only after knowing there is no error */
668 device->gain = ctrl->value & 0xff;
669 return 0;
670 default:
671 return -EINVAL;
672 }
673}
674
675/*
676 * tvp7002_queryctrl() - Query a control
677 * @sd: ptr to v4l2_subdev struct
678 * @ctrl: ptr to v4l2_queryctrl struct
679 *
680 * Query a control of a TVP7002 decoder device.
681 * Returns zero when successful or -EINVAL if register read fails.
682 */
683static int tvp7002_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc)
684{
685 switch (qc->id) {
686 case V4L2_CID_GAIN:
687 /*
688 * Gain is supported [0-255, default=0, step=1]
689 */
690 return v4l2_ctrl_query_fill(qc, 0, 255, 1, 0);
691 default:
692 return -EINVAL;
693 }
694}
695
696/*
697 * tvp7002_try_fmt_cap() - V4L2 decoder interface handler for try_fmt
698 * @sd: pointer to standard V4L2 sub-device structure
699 * @f: pointer to standard V4L2 VIDIOC_TRY_FMT ioctl structure
700 *
701 * Implement the VIDIOC_TRY_FMT ioctl for the CAPTURE buffer type. This
702 * ioctl is used to negotiate the image capture size and pixel format
703 * without actually making it take effect.
704 */
705static int tvp7002_try_fmt_cap(struct v4l2_subdev *sd, struct v4l2_format *f)
706{
707 struct tvp7002 *device = to_tvp7002(sd);
708 struct v4l2_dv_enum_preset e_preset;
709 struct v4l2_pix_format *pix;
710 int error = 0;
711
712 pix = &f->fmt.pix;
713
714 /* Calculate height and width based on current standard */
715 error = v4l_fill_dv_preset_info(device->current_preset->preset, &e_preset);
716 if (error)
717 return -EINVAL;
718
719 pix->width = e_preset.width;
720 pix->height = e_preset.height;
721 pix->pixelformat = V4L2_PIX_FMT_UYVY;
722 pix->field = device->current_preset->scanmode;
723 pix->bytesperline = pix->width * 2;
724 pix->sizeimage = pix->bytesperline * pix->height;
725 pix->colorspace = device->current_preset->color_space;
726 pix->priv = 0;
727
728 v4l2_dbg(1, debug, sd, "Try FMT: pixelformat - %s, bytesperline - %d"
729 "Width - %d, Height - %d", "8-bit UYVY 4:2:2 Format",
730 pix->bytesperline, pix->width, pix->height);
731 return error;
732}
733
734/*
735 * tvp7002_s_fmt() - V4L2 decoder interface handler for s_fmt
736 * @sd: pointer to standard V4L2 sub-device structure
737 * @f: pointer to standard V4L2 VIDIOC_S_FMT ioctl structure
738 *
739 * If the requested format is supported, configures the HW to use that
740 * format, returns error code if format not supported or HW can't be
741 * correctly configured.
742 */
743static int tvp7002_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
744{
745 struct tvp7002 *decoder = to_tvp7002(sd);
746 int rval;
747
748 rval = tvp7002_try_fmt_cap(sd, f);
749 if (!rval)
750 decoder->pix = f->fmt.pix;
751 return rval;
752}
753
754/*
755 * tvp7002_g_fmt() - V4L2 decoder interface handler for tvp7002_g_fmt
756 * @sd: pointer to standard V4L2 sub-device structure
757 * @f: pointer to standard V4L2 v4l2_format structure
758 *
759 * Returns the decoder's current pixel format in the v4l2_format
760 * parameter.
761 */
762static int tvp7002_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
763{
764 struct tvp7002 *decoder = to_tvp7002(sd);
765
766 f->fmt.pix = decoder->pix;
767
768 v4l2_dbg(1, debug, sd, "Current FMT: bytesperline - %d"
769 "Width - %d, Height - %d",
770 decoder->pix.bytesperline,
771 decoder->pix.width, decoder->pix.height);
772 return 0;
773}
774
775/*
776 * tvp7002_query_dv_preset() - query DV preset
777 * @sd: pointer to standard V4L2 sub-device structure
778 * @std_id: standard V4L2 v4l2_dv_preset
779 *
780 * Returns the current DV preset by TVP7002. If no active input is
781 * detected, returns -EINVAL
782 */
783static int tvp7002_query_dv_preset(struct v4l2_subdev *sd,
784 struct v4l2_dv_preset *qpreset)
785{
786 const struct tvp7002_preset_definition *presets = tvp7002_presets;
787 struct v4l2_dv_enum_preset e_preset;
788 struct tvp7002 *device;
789 u8 progressive;
790 u32 lpfr;
791 u32 cpln;
792 int error = 0;
793 u8 lpf_lsb;
794 u8 lpf_msb;
795 u8 cpl_lsb;
796 u8 cpl_msb;
797 int index;
798
799 device = to_tvp7002(sd);
800
801 /* Read standards from device registers */
802 tvp7002_read_err(sd, TVP7002_L_FRAME_STAT_LSBS, &lpf_lsb, &error);
803 tvp7002_read_err(sd, TVP7002_L_FRAME_STAT_MSBS, &lpf_msb, &error);
804
805 if (error < 0)
806 return error;
807
808 tvp7002_read_err(sd, TVP7002_CLK_L_STAT_LSBS, &cpl_lsb, &error);
809 tvp7002_read_err(sd, TVP7002_CLK_L_STAT_MSBS, &cpl_msb, &error);
810
811 if (error < 0)
812 return error;
813
814 /* Get lines per frame, clocks per line and interlaced/progresive */
815 lpfr = lpf_lsb | ((TVP7002_CL_MASK & lpf_msb) << TVP7002_CL_SHIFT);
816 cpln = cpl_lsb | ((TVP7002_CL_MASK & cpl_msb) << TVP7002_CL_SHIFT);
817 progressive = (lpf_msb & TVP7002_INPR_MASK) >> TVP7002_IP_SHIFT;
818
819 /* Do checking of video modes */
820 for (index = 0; index < NUM_PRESETS; index++, presets++)
821 if (lpfr == presets->lines_per_frame &&
822 progressive == presets->progressive) {
823 if (presets->cpl_min == 0xffff)
824 break;
825 if (cpln >= presets->cpl_min && cpln <= presets->cpl_max)
826 break;
827 }
828
829 if (index == NUM_PRESETS) {
830 v4l2_err(sd, "querystd error, lpf = %x, cpl = %x\n",
831 lpfr, cpln);
832 return -EINVAL;
833 }
834
835 if (v4l_fill_dv_preset_info(presets->preset, &e_preset))
836 return -EINVAL;
837
838 /* Set values in found preset */
839 qpreset->preset = presets->preset;
840
841 /* Update lines per frame and clocks per line info */
842 v4l2_dbg(1, debug, sd, "Current preset: %d %d",
843 e_preset.width, e_preset.height);
844 return 0;
845}
846
847#ifdef CONFIG_VIDEO_ADV_DEBUG
848/*
849 * tvp7002_g_register() - Get the value of a register
850 * @sd: ptr to v4l2_subdev struct
851 * @vreg: ptr to v4l2_dbg_register struct
852 *
853 * Get the value of a TVP7002 decoder device register.
854 * Returns zero when successful, -EINVAL if register read fails or
855 * access to I2C client fails, -EPERM if the call is not allowed
856 * by diabled CAP_SYS_ADMIN.
857 */
858static int tvp7002_g_register(struct v4l2_subdev *sd,
859 struct v4l2_dbg_register *reg)
860{
861 struct i2c_client *client = v4l2_get_subdevdata(sd);
862 u8 val;
863 int ret;
864
865 if (!v4l2_chip_match_i2c_client(client, &reg->match))
866 return -EINVAL;
867 if (!capable(CAP_SYS_ADMIN))
868 return -EPERM;
869
870 ret = tvp7002_read(sd, reg->reg & 0xff, &val);
871 reg->val = val;
872 return ret;
873}
874
875/*
876 * tvp7002_s_register() - set a control
877 * @sd: ptr to v4l2_subdev struct
878 * @ctrl: ptr to v4l2_control struct
879 *
880 * Get the value of a TVP7002 decoder device register.
881 * Returns zero when successful, -EINVAL if register read fails or
882 * -EPERM if call not allowed.
883 */
884static int tvp7002_s_register(struct v4l2_subdev *sd,
885 struct v4l2_dbg_register *reg)
886{
887 struct i2c_client *client = v4l2_get_subdevdata(sd);
888
889 if (!v4l2_chip_match_i2c_client(client, &reg->match))
890 return -EINVAL;
891 if (!capable(CAP_SYS_ADMIN))
892 return -EPERM;
893
894 return tvp7002_write(sd, reg->reg & 0xff, reg->val & 0xff);
895}
896#endif
897
898/*
899 * tvp7002_enum_fmt() - Enum supported formats
900 * @sd: pointer to standard V4L2 sub-device structure
901 * @enable: pointer to format struct
902 *
903 * Enumerate supported formats.
904 */
905
906static int tvp7002_enum_fmt(struct v4l2_subdev *sd,
907 struct v4l2_fmtdesc *fmtdesc)
908{
909 /* Check requested format index is within range */
910 if (fmtdesc->index < 0 || fmtdesc->index >= NUM_FORMATS)
911 return -EINVAL;
912 *fmtdesc = tvp7002_fmt_list[fmtdesc->index];
913
914 return 0;
915}
916
917/*
918 * tvp7002_s_stream() - V4L2 decoder i/f handler for s_stream
919 * @sd: pointer to standard V4L2 sub-device structure
920 * @enable: streaming enable or disable
921 *
922 * Sets streaming to enable or disable, if possible.
923 */
924static int tvp7002_s_stream(struct v4l2_subdev *sd, int enable)
925{
926 struct tvp7002 *device = to_tvp7002(sd);
927 int error = 0;
928
929 if (device->streaming == enable)
930 return 0;
931
932 if (enable) {
933 /* Set output state on (low impedance means stream on) */
934 error = tvp7002_write(sd, TVP7002_MISC_CTL_2, 0x00);
935 device->streaming = enable;
936 } else {
937 /* Set output state off (high impedance means stream off) */
938 error = tvp7002_write(sd, TVP7002_MISC_CTL_2, 0x03);
939 if (error)
940 v4l2_dbg(1, debug, sd, "Unable to stop streaming\n");
941
942 device->streaming = enable;
943 }
944
945 return error;
946}
947
948/*
949 * tvp7002_log_status() - Print information about register settings
950 * @sd: ptr to v4l2_subdev struct
951 *
952 * Log register values of a TVP7002 decoder device.
953 * Returns zero or -EINVAL if read operation fails.
954 */
955static int tvp7002_log_status(struct v4l2_subdev *sd)
956{
957 const struct tvp7002_preset_definition *presets = tvp7002_presets;
958 struct tvp7002 *device = to_tvp7002(sd);
959 struct v4l2_dv_enum_preset e_preset;
960 struct v4l2_dv_preset detected;
961 int i;
962
963 detected.preset = V4L2_DV_INVALID;
964 /* Find my current standard*/
965 tvp7002_query_dv_preset(sd, &detected);
966
967 /* Print standard related code values */
968 for (i = 0; i < NUM_PRESETS; i++, presets++)
969 if (presets->preset == detected.preset)
970 break;
971
972 if (v4l_fill_dv_preset_info(device->current_preset->preset, &e_preset))
973 return -EINVAL;
974
975 v4l2_info(sd, "Selected DV Preset: %s\n", e_preset.name);
976 v4l2_info(sd, " Pixels per line: %u\n", e_preset.width);
977 v4l2_info(sd, " Lines per frame: %u\n\n", e_preset.height);
978 if (i == NUM_PRESETS) {
979 v4l2_info(sd, "Detected DV Preset: None\n");
980 } else {
981 if (v4l_fill_dv_preset_info(presets->preset, &e_preset))
982 return -EINVAL;
983 v4l2_info(sd, "Detected DV Preset: %s\n", e_preset.name);
984 v4l2_info(sd, " Pixels per line: %u\n", e_preset.width);
985 v4l2_info(sd, " Lines per frame: %u\n\n", e_preset.height);
986 }
987 v4l2_info(sd, "Streaming enabled: %s\n",
988 device->streaming ? "yes" : "no");
989
990 /* Print the current value of the gain control */
991 v4l2_info(sd, "Gain: %u\n", device->gain);
992
993 return 0;
994}
995
996/* V4L2 core operation handlers */
997static const struct v4l2_subdev_core_ops tvp7002_core_ops = {
998 .g_chip_ident = tvp7002_g_chip_ident,
999 .log_status = tvp7002_log_status,
1000 .g_ctrl = tvp7002_g_ctrl,
1001 .s_ctrl = tvp7002_s_ctrl,
1002 .queryctrl = tvp7002_queryctrl,
1003#ifdef CONFIG_VIDEO_ADV_DEBUG
1004 .g_register = tvp7002_g_register,
1005 .s_register = tvp7002_s_register,
1006#endif
1007};
1008
1009/* Specific video subsystem operation handlers */
1010static const struct v4l2_subdev_video_ops tvp7002_video_ops = {
1011 .s_dv_preset = tvp7002_s_dv_preset,
1012 .query_dv_preset = tvp7002_query_dv_preset,
1013 .s_stream = tvp7002_s_stream,
1014 .g_fmt = tvp7002_g_fmt,
1015 .s_fmt = tvp7002_s_fmt,
1016 .enum_fmt = tvp7002_enum_fmt,
1017};
1018
1019/* V4L2 top level operation handlers */
1020static const struct v4l2_subdev_ops tvp7002_ops = {
1021 .core = &tvp7002_core_ops,
1022 .video = &tvp7002_video_ops,
1023};
1024
1025static struct tvp7002 tvp7002_dev = {
1026 .streaming = 0,
1027
1028 .pix = {
1029 .width = 1280,
1030 .height = 720,
1031 .pixelformat = V4L2_PIX_FMT_UYVY,
1032 .field = V4L2_FIELD_NONE,
1033 .bytesperline = 1280 * 2,
1034 .sizeimage = 1280 * 2 * 720,
1035 .colorspace = V4L2_COLORSPACE_REC709,
1036 },
1037
1038 .current_preset = tvp7002_presets,
1039 .gain = 0,
1040};
1041
1042/*
1043 * tvp7002_probe - Probe a TVP7002 device
1044 * @sd: ptr to v4l2_subdev struct
1045 * @ctrl: ptr to i2c_device_id struct
1046 *
1047 * Initialize the TVP7002 device
1048 * Returns zero when successful, -EINVAL if register read fails or
1049 * -EIO if i2c access is not available.
1050 */
1051static int tvp7002_probe(struct i2c_client *c, const struct i2c_device_id *id)
1052{
1053 struct v4l2_subdev *sd;
1054 struct tvp7002 *device;
1055 struct v4l2_dv_preset preset;
1056 int polarity_a;
1057 int polarity_b;
1058 u8 revision;
1059
1060 int error;
1061
1062 /* Check if the adapter supports the needed features */
1063 if (!i2c_check_functionality(c->adapter,
1064 I2C_FUNC_SMBUS_READ_BYTE | I2C_FUNC_SMBUS_WRITE_BYTE_DATA))
1065 return -EIO;
1066
1067 if (!c->dev.platform_data) {
1068 v4l_err(c, "No platform data!!\n");
1069 return -ENODEV;
1070 }
1071
1072 device = kmalloc(sizeof(struct tvp7002), GFP_KERNEL);
1073
1074 if (!device)
1075 return -ENOMEM;
1076
1077 *device = tvp7002_dev;
1078 sd = &device->sd;
1079 device->pdata = c->dev.platform_data;
1080
1081 /* Tell v4l2 the device is ready */
1082 v4l2_i2c_subdev_init(sd, c, &tvp7002_ops);
1083 v4l_info(c, "tvp7002 found @ 0x%02x (%s)\n",
1084 c->addr, c->adapter->name);
1085
1086 error = tvp7002_read(sd, TVP7002_CHIP_REV, &revision);
1087 if (error < 0)
1088 goto found_error;
1089
1090 /* Get revision number */
1091 v4l2_info(sd, "Rev. %02x detected.\n", revision);
1092 if (revision != 0x02)
1093 v4l2_info(sd, "Unknown revision detected.\n");
1094
1095 /* Initializes TVP7002 to its default values */
1096 error = tvp7002_write_inittab(sd, tvp7002_init_default);
1097
1098 if (error < 0)
1099 goto found_error;
1100
1101 /* Set polarity information after registers have been set */
1102 polarity_a = 0x20 | device->pdata->hs_polarity << 5
1103 | device->pdata->vs_polarity << 2;
1104 error = tvp7002_write(sd, TVP7002_SYNC_CTL_1, polarity_a);
1105 if (error < 0)
1106 goto found_error;
1107
1108 polarity_b = 0x01 | device->pdata->fid_polarity << 2
1109 | device->pdata->sog_polarity << 1
1110 | device->pdata->clk_polarity;
1111 error = tvp7002_write(sd, TVP7002_MISC_CTL_3, polarity_b);
1112 if (error < 0)
1113 goto found_error;
1114
1115 /* Set registers according to default video mode */
1116 preset.preset = device->current_preset->preset;
1117 error = tvp7002_s_dv_preset(sd, &preset);
1118
1119found_error:
1120 if (error < 0)
1121 kfree(device);
1122
1123 return error;
1124}
1125
1126/*
1127 * tvp7002_remove - Remove TVP7002 device support
1128 * @c: ptr to i2c_client struct
1129 *
1130 * Reset the TVP7002 device
1131 * Returns zero.
1132 */
1133static int tvp7002_remove(struct i2c_client *c)
1134{
1135 struct v4l2_subdev *sd = i2c_get_clientdata(c);
1136 struct tvp7002 *device = to_tvp7002(sd);
1137
1138 v4l2_dbg(1, debug, sd, "Removing tvp7002 adapter"
1139 "on address 0x%x\n", c->addr);
1140
1141 v4l2_device_unregister_subdev(sd);
1142 kfree(device);
1143 return 0;
1144}
1145
1146/* I2C Device ID table */
1147static const struct i2c_device_id tvp7002_id[] = {
1148 { "tvp7002", 0 },
1149 { }
1150};
1151MODULE_DEVICE_TABLE(i2c, tvp7002_id);
1152
1153/* I2C driver data */
1154static struct i2c_driver tvp7002_driver = {
1155 .driver = {
1156 .owner = THIS_MODULE,
1157 .name = TVP7002_MODULE_NAME,
1158 },
1159 .probe = tvp7002_probe,
1160 .remove = tvp7002_remove,
1161 .id_table = tvp7002_id,
1162};
1163
1164/*
1165 * tvp7002_init - Initialize driver via I2C interface
1166 *
1167 * Register the TVP7002 driver.
1168 * Return 0 on success or error code on failure.
1169 */
1170static int __init tvp7002_init(void)
1171{
1172 return i2c_add_driver(&tvp7002_driver);
1173}
1174
1175/*
1176 * tvp7002_exit - Remove driver via I2C interface
1177 *
1178 * Unregister the TVP7002 driver.
1179 * Returns nothing.
1180 */
1181static void __exit tvp7002_exit(void)
1182{
1183 i2c_del_driver(&tvp7002_driver);
1184}
1185
1186module_init(tvp7002_init);
1187module_exit(tvp7002_exit);
diff --git a/drivers/media/video/tvp7002_reg.h b/drivers/media/video/tvp7002_reg.h
new file mode 100644
index 000000000000..0e34ca9bccf3
--- /dev/null
+++ b/drivers/media/video/tvp7002_reg.h
@@ -0,0 +1,150 @@
1/* Texas Instruments Triple 8-/10-BIT 165-/110-MSPS Video and Graphics
2 * Digitizer with Horizontal PLL registers
3 *
4 * Copyright (C) 2009 Texas Instruments Inc
5 * Author: Santiago Nunez-Corrales <santiago.nunez@ridgerun.com>
6 *
7 * This code is partially based upon the TVP5150 driver
8 * written by Mauro Carvalho Chehab (mchehab@infradead.org),
9 * the TVP514x driver written by Vaibhav Hiremath <hvaibhav@ti.com>
10 * and the TVP7002 driver in the TI LSP 2.10.00.14
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/* Naming conventions
28 * ------------------
29 *
30 * FDBK: Feedback
31 * DIV: Divider
32 * CTL: Control
33 * SEL: Select
34 * IN: Input
35 * OUT: Output
36 * R: Red
37 * G: Green
38 * B: Blue
39 * OFF: Offset
40 * THRS: Threshold
41 * DGTL: Digital
42 * LVL: Level
43 * PWR: Power
44 * MVIS: Macrovision
45 * W: Width
46 * H: Height
47 * ALGN: Alignment
48 * CLK: Clocks
49 * TOL: Tolerance
50 * BWTH: Bandwidth
51 * COEF: Coefficient
52 * STAT: Status
53 * AUTO: Automatic
54 * FLD: Field
55 * L: Line
56 */
57
58#define TVP7002_CHIP_REV 0x00
59#define TVP7002_HPLL_FDBK_DIV_MSBS 0x01
60#define TVP7002_HPLL_FDBK_DIV_LSBS 0x02
61#define TVP7002_HPLL_CRTL 0x03
62#define TVP7002_HPLL_PHASE_SEL 0x04
63#define TVP7002_CLAMP_START 0x05
64#define TVP7002_CLAMP_W 0x06
65#define TVP7002_HSYNC_OUT_W 0x07
66#define TVP7002_B_FINE_GAIN 0x08
67#define TVP7002_G_FINE_GAIN 0x09
68#define TVP7002_R_FINE_GAIN 0x0a
69#define TVP7002_B_FINE_OFF_MSBS 0x0b
70#define TVP7002_G_FINE_OFF_MSBS 0x0c
71#define TVP7002_R_FINE_OFF_MSBS 0x0d
72#define TVP7002_SYNC_CTL_1 0x0e
73#define TVP7002_HPLL_AND_CLAMP_CTL 0x0f
74#define TVP7002_SYNC_ON_G_THRS 0x10
75#define TVP7002_SYNC_SEPARATOR_THRS 0x11
76#define TVP7002_HPLL_PRE_COAST 0x12
77#define TVP7002_HPLL_POST_COAST 0x13
78#define TVP7002_SYNC_DETECT_STAT 0x14
79#define TVP7002_OUT_FORMATTER 0x15
80#define TVP7002_MISC_CTL_1 0x16
81#define TVP7002_MISC_CTL_2 0x17
82#define TVP7002_MISC_CTL_3 0x18
83#define TVP7002_IN_MUX_SEL_1 0x19
84#define TVP7002_IN_MUX_SEL_2 0x1a
85#define TVP7002_B_AND_G_COARSE_GAIN 0x1b
86#define TVP7002_R_COARSE_GAIN 0x1c
87#define TVP7002_FINE_OFF_LSBS 0x1d
88#define TVP7002_B_COARSE_OFF 0x1e
89#define TVP7002_G_COARSE_OFF 0x1f
90#define TVP7002_R_COARSE_OFF 0x20
91#define TVP7002_HSOUT_OUT_START 0x21
92#define TVP7002_MISC_CTL_4 0x22
93#define TVP7002_B_DGTL_ALC_OUT_LSBS 0x23
94#define TVP7002_G_DGTL_ALC_OUT_LSBS 0x24
95#define TVP7002_R_DGTL_ALC_OUT_LSBS 0x25
96#define TVP7002_AUTO_LVL_CTL_ENABLE 0x26
97#define TVP7002_DGTL_ALC_OUT_MSBS 0x27
98#define TVP7002_AUTO_LVL_CTL_FILTER 0x28
99/* Reserved 0x29*/
100#define TVP7002_FINE_CLAMP_CTL 0x2a
101#define TVP7002_PWR_CTL 0x2b
102#define TVP7002_ADC_SETUP 0x2c
103#define TVP7002_COARSE_CLAMP_CTL 0x2d
104#define TVP7002_SOG_CLAMP 0x2e
105#define TVP7002_RGB_COARSE_CLAMP_CTL 0x2f
106#define TVP7002_SOG_COARSE_CLAMP_CTL 0x30
107#define TVP7002_ALC_PLACEMENT 0x31
108/* Reserved 0x32 */
109/* Reserved 0x33 */
110#define TVP7002_MVIS_STRIPPER_W 0x34
111#define TVP7002_VSYNC_ALGN 0x35
112#define TVP7002_SYNC_BYPASS 0x36
113#define TVP7002_L_FRAME_STAT_LSBS 0x37
114#define TVP7002_L_FRAME_STAT_MSBS 0x38
115#define TVP7002_CLK_L_STAT_LSBS 0x39
116#define TVP7002_CLK_L_STAT_MSBS 0x3a
117#define TVP7002_HSYNC_W 0x3b
118#define TVP7002_VSYNC_W 0x3c
119#define TVP7002_L_LENGTH_TOL 0x3d
120/* Reserved 0x3e */
121#define TVP7002_VIDEO_BWTH_CTL 0x3f
122#define TVP7002_AVID_START_PIXEL_LSBS 0x40
123#define TVP7002_AVID_START_PIXEL_MSBS 0x41
124#define TVP7002_AVID_STOP_PIXEL_LSBS 0x42
125#define TVP7002_AVID_STOP_PIXEL_MSBS 0x43
126#define TVP7002_VBLK_F_0_START_L_OFF 0x44
127#define TVP7002_VBLK_F_1_START_L_OFF 0x45
128#define TVP7002_VBLK_F_0_DURATION 0x46
129#define TVP7002_VBLK_F_1_DURATION 0x47
130#define TVP7002_FBIT_F_0_START_L_OFF 0x48
131#define TVP7002_FBIT_F_1_START_L_OFF 0x49
132#define TVP7002_YUV_Y_G_COEF_LSBS 0x4a
133#define TVP7002_YUV_Y_G_COEF_MSBS 0x4b
134#define TVP7002_YUV_Y_B_COEF_LSBS 0x4c
135#define TVP7002_YUV_Y_B_COEF_MSBS 0x4d
136#define TVP7002_YUV_Y_R_COEF_LSBS 0x4e
137#define TVP7002_YUV_Y_R_COEF_MSBS 0x4f
138#define TVP7002_YUV_U_G_COEF_LSBS 0x50
139#define TVP7002_YUV_U_G_COEF_MSBS 0x51
140#define TVP7002_YUV_U_B_COEF_LSBS 0x52
141#define TVP7002_YUV_U_B_COEF_MSBS 0x53
142#define TVP7002_YUV_U_R_COEF_LSBS 0x54
143#define TVP7002_YUV_U_R_COEF_MSBS 0x55
144#define TVP7002_YUV_V_G_COEF_LSBS 0x56
145#define TVP7002_YUV_V_G_COEF_MSBS 0x57
146#define TVP7002_YUV_V_B_COEF_LSBS 0x58
147#define TVP7002_YUV_V_B_COEF_MSBS 0x59
148#define TVP7002_YUV_V_R_COEF_LSBS 0x5a
149#define TVP7002_YUV_V_R_COEF_MSBS 0x5b
150
diff --git a/drivers/media/video/tw9910.c b/drivers/media/video/tw9910.c
index 5b801a6e1eea..76be733eabfd 100644
--- a/drivers/media/video/tw9910.c
+++ b/drivers/media/video/tw9910.c
@@ -233,10 +233,10 @@ struct tw9910_hsync_ctrl {
233}; 233};
234 234
235struct tw9910_priv { 235struct tw9910_priv {
236 struct v4l2_subdev subdev; 236 struct v4l2_subdev subdev;
237 struct tw9910_video_info *info; 237 struct tw9910_video_info *info;
238 const struct tw9910_scale_ctrl *scale; 238 const struct tw9910_scale_ctrl *scale;
239 u32 revision; 239 u32 revision;
240}; 240};
241 241
242static const struct tw9910_scale_ctrl tw9910_ntsc_scales[] = { 242static const struct tw9910_scale_ctrl tw9910_ntsc_scales[] = {
diff --git a/drivers/media/video/usbvision/usbvision-video.c b/drivers/media/video/usbvision/usbvision-video.c
index 1054546db908..7c17ec63c5da 100644
--- a/drivers/media/video/usbvision/usbvision-video.c
+++ b/drivers/media/video/usbvision/usbvision-video.c
@@ -1487,7 +1487,7 @@ static int __devinit usbvision_register_video(struct usb_usbvision *usbvision)
1487 usbvision->vbi = usbvision_vdev_init(usbvision, 1487 usbvision->vbi = usbvision_vdev_init(usbvision,
1488 &usbvision_vbi_template, 1488 &usbvision_vbi_template,
1489 "USBVision VBI"); 1489 "USBVision VBI");
1490 if (usbvision->vdev == NULL) { 1490 if (usbvision->vbi == NULL) {
1491 goto err_exit; 1491 goto err_exit;
1492 } 1492 }
1493 if (video_register_device(usbvision->vbi, 1493 if (video_register_device(usbvision->vbi,
diff --git a/drivers/media/video/uvc/uvc_ctrl.c b/drivers/media/video/uvc/uvc_ctrl.c
index ec8ef8c5560a..3b2e7800d56f 100644
--- a/drivers/media/video/uvc/uvc_ctrl.c
+++ b/drivers/media/video/uvc/uvc_ctrl.c
@@ -23,9 +23,13 @@
23 23
24#include "uvcvideo.h" 24#include "uvcvideo.h"
25 25
26#define UVC_CTRL_NDATA 2
27#define UVC_CTRL_DATA_CURRENT 0 26#define UVC_CTRL_DATA_CURRENT 0
28#define UVC_CTRL_DATA_BACKUP 1 27#define UVC_CTRL_DATA_BACKUP 1
28#define UVC_CTRL_DATA_MIN 2
29#define UVC_CTRL_DATA_MAX 3
30#define UVC_CTRL_DATA_RES 4
31#define UVC_CTRL_DATA_DEF 5
32#define UVC_CTRL_DATA_LAST 6
29 33
30/* ------------------------------------------------------------------------ 34/* ------------------------------------------------------------------------
31 * Controls 35 * Controls
@@ -755,6 +759,49 @@ struct uvc_control *uvc_find_control(struct uvc_video_chain *chain,
755 return ctrl; 759 return ctrl;
756} 760}
757 761
762static int uvc_ctrl_populate_cache(struct uvc_video_chain *chain,
763 struct uvc_control *ctrl)
764{
765 int ret;
766
767 if (ctrl->info->flags & UVC_CONTROL_GET_DEF) {
768 ret = uvc_query_ctrl(chain->dev, UVC_GET_DEF, ctrl->entity->id,
769 chain->dev->intfnum, ctrl->info->selector,
770 uvc_ctrl_data(ctrl, UVC_CTRL_DATA_DEF),
771 ctrl->info->size);
772 if (ret < 0)
773 return ret;
774 }
775
776 if (ctrl->info->flags & UVC_CONTROL_GET_MIN) {
777 ret = uvc_query_ctrl(chain->dev, UVC_GET_MIN, ctrl->entity->id,
778 chain->dev->intfnum, ctrl->info->selector,
779 uvc_ctrl_data(ctrl, UVC_CTRL_DATA_MIN),
780 ctrl->info->size);
781 if (ret < 0)
782 return ret;
783 }
784 if (ctrl->info->flags & UVC_CONTROL_GET_MAX) {
785 ret = uvc_query_ctrl(chain->dev, UVC_GET_MAX, ctrl->entity->id,
786 chain->dev->intfnum, ctrl->info->selector,
787 uvc_ctrl_data(ctrl, UVC_CTRL_DATA_MAX),
788 ctrl->info->size);
789 if (ret < 0)
790 return ret;
791 }
792 if (ctrl->info->flags & UVC_CONTROL_GET_RES) {
793 ret = uvc_query_ctrl(chain->dev, UVC_GET_RES, ctrl->entity->id,
794 chain->dev->intfnum, ctrl->info->selector,
795 uvc_ctrl_data(ctrl, UVC_CTRL_DATA_RES),
796 ctrl->info->size);
797 if (ret < 0)
798 return ret;
799 }
800
801 ctrl->cached = 1;
802 return 0;
803}
804
758int uvc_query_v4l2_ctrl(struct uvc_video_chain *chain, 805int uvc_query_v4l2_ctrl(struct uvc_video_chain *chain,
759 struct v4l2_queryctrl *v4l2_ctrl) 806 struct v4l2_queryctrl *v4l2_ctrl)
760{ 807{
@@ -762,17 +809,12 @@ int uvc_query_v4l2_ctrl(struct uvc_video_chain *chain,
762 struct uvc_control_mapping *mapping; 809 struct uvc_control_mapping *mapping;
763 struct uvc_menu_info *menu; 810 struct uvc_menu_info *menu;
764 unsigned int i; 811 unsigned int i;
765 __u8 *data;
766 int ret; 812 int ret;
767 813
768 ctrl = uvc_find_control(chain, v4l2_ctrl->id, &mapping); 814 ctrl = uvc_find_control(chain, v4l2_ctrl->id, &mapping);
769 if (ctrl == NULL) 815 if (ctrl == NULL)
770 return -EINVAL; 816 return -EINVAL;
771 817
772 data = kmalloc(ctrl->info->size, GFP_KERNEL);
773 if (data == NULL)
774 return -ENOMEM;
775
776 memset(v4l2_ctrl, 0, sizeof *v4l2_ctrl); 818 memset(v4l2_ctrl, 0, sizeof *v4l2_ctrl);
777 v4l2_ctrl->id = mapping->id; 819 v4l2_ctrl->id = mapping->id;
778 v4l2_ctrl->type = mapping->v4l2_type; 820 v4l2_ctrl->type = mapping->v4l2_type;
@@ -782,14 +824,15 @@ int uvc_query_v4l2_ctrl(struct uvc_video_chain *chain,
782 if (!(ctrl->info->flags & UVC_CONTROL_SET_CUR)) 824 if (!(ctrl->info->flags & UVC_CONTROL_SET_CUR))
783 v4l2_ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY; 825 v4l2_ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY;
784 826
785 if (ctrl->info->flags & UVC_CONTROL_GET_DEF) { 827 if (!ctrl->cached) {
786 ret = uvc_query_ctrl(chain->dev, UVC_GET_DEF, ctrl->entity->id, 828 ret = uvc_ctrl_populate_cache(chain, ctrl);
787 chain->dev->intfnum, ctrl->info->selector,
788 data, ctrl->info->size);
789 if (ret < 0) 829 if (ret < 0)
790 goto out; 830 return ret;
791 v4l2_ctrl->default_value = 831 }
792 mapping->get(mapping, UVC_GET_DEF, data); 832
833 if (ctrl->info->flags & UVC_CONTROL_GET_DEF) {
834 v4l2_ctrl->default_value = mapping->get(mapping, UVC_GET_DEF,
835 uvc_ctrl_data(ctrl, UVC_CTRL_DATA_DEF));
793 } 836 }
794 837
795 switch (mapping->v4l2_type) { 838 switch (mapping->v4l2_type) {
@@ -806,56 +849,37 @@ int uvc_query_v4l2_ctrl(struct uvc_video_chain *chain,
806 } 849 }
807 } 850 }
808 851
809 ret = 0; 852 return 0;
810 goto out;
811 853
812 case V4L2_CTRL_TYPE_BOOLEAN: 854 case V4L2_CTRL_TYPE_BOOLEAN:
813 v4l2_ctrl->minimum = 0; 855 v4l2_ctrl->minimum = 0;
814 v4l2_ctrl->maximum = 1; 856 v4l2_ctrl->maximum = 1;
815 v4l2_ctrl->step = 1; 857 v4l2_ctrl->step = 1;
816 ret = 0; 858 return 0;
817 goto out;
818 859
819 case V4L2_CTRL_TYPE_BUTTON: 860 case V4L2_CTRL_TYPE_BUTTON:
820 v4l2_ctrl->minimum = 0; 861 v4l2_ctrl->minimum = 0;
821 v4l2_ctrl->maximum = 0; 862 v4l2_ctrl->maximum = 0;
822 v4l2_ctrl->step = 0; 863 v4l2_ctrl->step = 0;
823 ret = 0; 864 return 0;
824 goto out;
825 865
826 default: 866 default:
827 break; 867 break;
828 } 868 }
829 869
830 if (ctrl->info->flags & UVC_CONTROL_GET_MIN) { 870 if (ctrl->info->flags & UVC_CONTROL_GET_MIN)
831 ret = uvc_query_ctrl(chain->dev, UVC_GET_MIN, ctrl->entity->id, 871 v4l2_ctrl->minimum = mapping->get(mapping, UVC_GET_MIN,
832 chain->dev->intfnum, ctrl->info->selector, 872 uvc_ctrl_data(ctrl, UVC_CTRL_DATA_MIN));
833 data, ctrl->info->size);
834 if (ret < 0)
835 goto out;
836 v4l2_ctrl->minimum = mapping->get(mapping, UVC_GET_MIN, data);
837 }
838 if (ctrl->info->flags & UVC_CONTROL_GET_MAX) {
839 ret = uvc_query_ctrl(chain->dev, UVC_GET_MAX, ctrl->entity->id,
840 chain->dev->intfnum, ctrl->info->selector,
841 data, ctrl->info->size);
842 if (ret < 0)
843 goto out;
844 v4l2_ctrl->maximum = mapping->get(mapping, UVC_GET_MAX, data);
845 }
846 if (ctrl->info->flags & UVC_CONTROL_GET_RES) {
847 ret = uvc_query_ctrl(chain->dev, UVC_GET_RES, ctrl->entity->id,
848 chain->dev->intfnum, ctrl->info->selector,
849 data, ctrl->info->size);
850 if (ret < 0)
851 goto out;
852 v4l2_ctrl->step = mapping->get(mapping, UVC_GET_RES, data);
853 }
854 873
855 ret = 0; 874 if (ctrl->info->flags & UVC_CONTROL_GET_MAX)
856out: 875 v4l2_ctrl->maximum = mapping->get(mapping, UVC_GET_MAX,
857 kfree(data); 876 uvc_ctrl_data(ctrl, UVC_CTRL_DATA_MAX));
858 return ret; 877
878 if (ctrl->info->flags & UVC_CONTROL_GET_RES)
879 v4l2_ctrl->step = mapping->get(mapping, UVC_GET_RES,
880 uvc_ctrl_data(ctrl, UVC_CTRL_DATA_RES));
881
882 return 0;
859} 883}
860 884
861 885
@@ -997,19 +1021,57 @@ int uvc_ctrl_set(struct uvc_video_chain *chain,
997{ 1021{
998 struct uvc_control *ctrl; 1022 struct uvc_control *ctrl;
999 struct uvc_control_mapping *mapping; 1023 struct uvc_control_mapping *mapping;
1000 s32 value = xctrl->value; 1024 s32 value;
1025 u32 step;
1026 s32 min;
1027 s32 max;
1001 int ret; 1028 int ret;
1002 1029
1003 ctrl = uvc_find_control(chain, xctrl->id, &mapping); 1030 ctrl = uvc_find_control(chain, xctrl->id, &mapping);
1004 if (ctrl == NULL || (ctrl->info->flags & UVC_CONTROL_SET_CUR) == 0) 1031 if (ctrl == NULL || (ctrl->info->flags & UVC_CONTROL_SET_CUR) == 0)
1005 return -EINVAL; 1032 return -EINVAL;
1006 1033
1007 if (mapping->v4l2_type == V4L2_CTRL_TYPE_MENU) { 1034 /* Clamp out of range values. */
1008 if (value < 0 || value >= mapping->menu_count) 1035 switch (mapping->v4l2_type) {
1009 return -EINVAL; 1036 case V4L2_CTRL_TYPE_INTEGER:
1010 value = mapping->menu_info[value].value; 1037 if (!ctrl->cached) {
1038 ret = uvc_ctrl_populate_cache(chain, ctrl);
1039 if (ret < 0)
1040 return ret;
1041 }
1042
1043 min = mapping->get(mapping, UVC_GET_MIN,
1044 uvc_ctrl_data(ctrl, UVC_CTRL_DATA_MIN));
1045 max = mapping->get(mapping, UVC_GET_MAX,
1046 uvc_ctrl_data(ctrl, UVC_CTRL_DATA_MAX));
1047 step = mapping->get(mapping, UVC_GET_RES,
1048 uvc_ctrl_data(ctrl, UVC_CTRL_DATA_RES));
1049
1050 xctrl->value = min + (xctrl->value - min + step/2) / step * step;
1051 xctrl->value = clamp(xctrl->value, min, max);
1052 value = xctrl->value;
1053 break;
1054
1055 case V4L2_CTRL_TYPE_BOOLEAN:
1056 xctrl->value = clamp(xctrl->value, 0, 1);
1057 value = xctrl->value;
1058 break;
1059
1060 case V4L2_CTRL_TYPE_MENU:
1061 if (xctrl->value < 0 || xctrl->value >= mapping->menu_count)
1062 return -ERANGE;
1063 value = mapping->menu_info[xctrl->value].value;
1064 break;
1065
1066 default:
1067 value = xctrl->value;
1068 break;
1011 } 1069 }
1012 1070
1071 /* If the mapping doesn't span the whole UVC control, the current value
1072 * needs to be loaded from the device to perform the read-modify-write
1073 * operation.
1074 */
1013 if (!ctrl->loaded && (ctrl->info->size * 8) != mapping->size) { 1075 if (!ctrl->loaded && (ctrl->info->size * 8) != mapping->size) {
1014 if ((ctrl->info->flags & UVC_CONTROL_GET_CUR) == 0) { 1076 if ((ctrl->info->flags & UVC_CONTROL_GET_CUR) == 0) {
1015 memset(uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT), 1077 memset(uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT),
@@ -1027,6 +1089,7 @@ int uvc_ctrl_set(struct uvc_video_chain *chain,
1027 ctrl->loaded = 1; 1089 ctrl->loaded = 1;
1028 } 1090 }
1029 1091
1092 /* Backup the current value in case we need to rollback later. */
1030 if (!ctrl->dirty) { 1093 if (!ctrl->dirty) {
1031 memcpy(uvc_ctrl_data(ctrl, UVC_CTRL_DATA_BACKUP), 1094 memcpy(uvc_ctrl_data(ctrl, UVC_CTRL_DATA_BACKUP),
1032 uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT), 1095 uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT),
@@ -1080,10 +1143,8 @@ int uvc_xu_ctrl_query(struct uvc_video_chain *chain,
1080 } 1143 }
1081 1144
1082 if (!found) { 1145 if (!found) {
1083 uvc_trace(UVC_TRACE_CONTROL, 1146 uvc_trace(UVC_TRACE_CONTROL, "Control %pUl/%u not found.\n",
1084 "Control " UVC_GUID_FORMAT "/%u not found.\n", 1147 entity->extension.guidExtensionCode, xctrl->selector);
1085 UVC_GUID_ARGS(entity->extension.guidExtensionCode),
1086 xctrl->selector);
1087 return -EINVAL; 1148 return -EINVAL;
1088 } 1149 }
1089 1150
@@ -1159,9 +1220,9 @@ int uvc_ctrl_resume_device(struct uvc_device *dev)
1159 (ctrl->info->flags & UVC_CONTROL_RESTORE) == 0) 1220 (ctrl->info->flags & UVC_CONTROL_RESTORE) == 0)
1160 continue; 1221 continue;
1161 1222
1162 printk(KERN_INFO "restoring control " UVC_GUID_FORMAT 1223 printk(KERN_INFO "restoring control %pUl/%u/%u\n",
1163 "/%u/%u\n", UVC_GUID_ARGS(ctrl->info->entity), 1224 ctrl->info->entity, ctrl->info->index,
1164 ctrl->info->index, ctrl->info->selector); 1225 ctrl->info->selector);
1165 ctrl->dirty = 1; 1226 ctrl->dirty = 1;
1166 } 1227 }
1167 1228
@@ -1215,47 +1276,43 @@ static void uvc_ctrl_add_ctrl(struct uvc_device *dev,
1215 ret = uvc_query_ctrl(dev, UVC_GET_LEN, ctrl->entity->id, 1276 ret = uvc_query_ctrl(dev, UVC_GET_LEN, ctrl->entity->id,
1216 dev->intfnum, info->selector, (__u8 *)&size, 2); 1277 dev->intfnum, info->selector, (__u8 *)&size, 2);
1217 if (ret < 0) { 1278 if (ret < 0) {
1218 uvc_trace(UVC_TRACE_CONTROL, "GET_LEN failed on " 1279 uvc_trace(UVC_TRACE_CONTROL,
1219 "control " UVC_GUID_FORMAT "/%u (%d).\n", 1280 "GET_LEN failed on control %pUl/%u (%d).\n",
1220 UVC_GUID_ARGS(info->entity), info->selector, 1281 info->entity, info->selector, ret);
1221 ret);
1222 return; 1282 return;
1223 } 1283 }
1224 1284
1225 if (info->size != le16_to_cpu(size)) { 1285 if (info->size != le16_to_cpu(size)) {
1226 uvc_trace(UVC_TRACE_CONTROL, "Control " UVC_GUID_FORMAT 1286 uvc_trace(UVC_TRACE_CONTROL, "Control %pUl/%u size "
1227 "/%u size doesn't match user supplied " 1287 "doesn't match user supplied value.\n",
1228 "value.\n", UVC_GUID_ARGS(info->entity), 1288 info->entity, info->selector);
1229 info->selector);
1230 return; 1289 return;
1231 } 1290 }
1232 1291
1233 ret = uvc_query_ctrl(dev, UVC_GET_INFO, ctrl->entity->id, 1292 ret = uvc_query_ctrl(dev, UVC_GET_INFO, ctrl->entity->id,
1234 dev->intfnum, info->selector, &inf, 1); 1293 dev->intfnum, info->selector, &inf, 1);
1235 if (ret < 0) { 1294 if (ret < 0) {
1236 uvc_trace(UVC_TRACE_CONTROL, "GET_INFO failed on " 1295 uvc_trace(UVC_TRACE_CONTROL,
1237 "control " UVC_GUID_FORMAT "/%u (%d).\n", 1296 "GET_INFO failed on control %pUl/%u (%d).\n",
1238 UVC_GUID_ARGS(info->entity), info->selector, 1297 info->entity, info->selector, ret);
1239 ret);
1240 return; 1298 return;
1241 } 1299 }
1242 1300
1243 flags = info->flags; 1301 flags = info->flags;
1244 if (((flags & UVC_CONTROL_GET_CUR) && !(inf & (1 << 0))) || 1302 if (((flags & UVC_CONTROL_GET_CUR) && !(inf & (1 << 0))) ||
1245 ((flags & UVC_CONTROL_SET_CUR) && !(inf & (1 << 1)))) { 1303 ((flags & UVC_CONTROL_SET_CUR) && !(inf & (1 << 1)))) {
1246 uvc_trace(UVC_TRACE_CONTROL, "Control " 1304 uvc_trace(UVC_TRACE_CONTROL, "Control %pUl/%u flags "
1247 UVC_GUID_FORMAT "/%u flags don't match " 1305 "don't match supported operations.\n",
1248 "supported operations.\n", 1306 info->entity, info->selector);
1249 UVC_GUID_ARGS(info->entity), info->selector);
1250 return; 1307 return;
1251 } 1308 }
1252 } 1309 }
1253 1310
1254 ctrl->info = info; 1311 ctrl->info = info;
1255 ctrl->data = kmalloc(ctrl->info->size * UVC_CTRL_NDATA, GFP_KERNEL); 1312 ctrl->data = kmalloc(ctrl->info->size * UVC_CTRL_DATA_LAST, GFP_KERNEL);
1256 uvc_trace(UVC_TRACE_CONTROL, "Added control " UVC_GUID_FORMAT "/%u " 1313 uvc_trace(UVC_TRACE_CONTROL, "Added control %pUl/%u to device %s "
1257 "to device %s entity %u\n", UVC_GUID_ARGS(ctrl->info->entity), 1314 "entity %u\n", ctrl->info->entity, ctrl->info->selector,
1258 ctrl->info->selector, dev->udev->devpath, entity->id); 1315 dev->udev->devpath, entity->id);
1259} 1316}
1260 1317
1261/* 1318/*
@@ -1281,17 +1338,16 @@ int uvc_ctrl_add_info(struct uvc_control_info *info)
1281 continue; 1338 continue;
1282 1339
1283 if (ctrl->selector == info->selector) { 1340 if (ctrl->selector == info->selector) {
1284 uvc_trace(UVC_TRACE_CONTROL, "Control " 1341 uvc_trace(UVC_TRACE_CONTROL,
1285 UVC_GUID_FORMAT "/%u is already defined.\n", 1342 "Control %pUl/%u is already defined.\n",
1286 UVC_GUID_ARGS(info->entity), info->selector); 1343 info->entity, info->selector);
1287 ret = -EEXIST; 1344 ret = -EEXIST;
1288 goto end; 1345 goto end;
1289 } 1346 }
1290 if (ctrl->index == info->index) { 1347 if (ctrl->index == info->index) {
1291 uvc_trace(UVC_TRACE_CONTROL, "Control " 1348 uvc_trace(UVC_TRACE_CONTROL,
1292 UVC_GUID_FORMAT "/%u would overwrite index " 1349 "Control %pUl/%u would overwrite index %d.\n",
1293 "%d.\n", UVC_GUID_ARGS(info->entity), 1350 info->entity, info->selector, info->index);
1294 info->selector, info->index);
1295 ret = -EEXIST; 1351 ret = -EEXIST;
1296 goto end; 1352 goto end;
1297 } 1353 }
@@ -1332,10 +1388,9 @@ int uvc_ctrl_add_mapping(struct uvc_control_mapping *mapping)
1332 continue; 1388 continue;
1333 1389
1334 if (info->size * 8 < mapping->size + mapping->offset) { 1390 if (info->size * 8 < mapping->size + mapping->offset) {
1335 uvc_trace(UVC_TRACE_CONTROL, "Mapping '%s' would " 1391 uvc_trace(UVC_TRACE_CONTROL,
1336 "overflow control " UVC_GUID_FORMAT "/%u\n", 1392 "Mapping '%s' would overflow control %pUl/%u\n",
1337 mapping->name, UVC_GUID_ARGS(info->entity), 1393 mapping->name, info->entity, info->selector);
1338 info->selector);
1339 ret = -EOVERFLOW; 1394 ret = -EOVERFLOW;
1340 goto end; 1395 goto end;
1341 } 1396 }
@@ -1354,9 +1409,9 @@ int uvc_ctrl_add_mapping(struct uvc_control_mapping *mapping)
1354 1409
1355 mapping->ctrl = info; 1410 mapping->ctrl = info;
1356 list_add_tail(&mapping->list, &info->mappings); 1411 list_add_tail(&mapping->list, &info->mappings);
1357 uvc_trace(UVC_TRACE_CONTROL, "Adding mapping %s to control " 1412 uvc_trace(UVC_TRACE_CONTROL,
1358 UVC_GUID_FORMAT "/%u.\n", mapping->name, 1413 "Adding mapping %s to control %pUl/%u.\n",
1359 UVC_GUID_ARGS(info->entity), info->selector); 1414 mapping->name, info->entity, info->selector);
1360 1415
1361 ret = 0; 1416 ret = 0;
1362 break; 1417 break;
@@ -1378,6 +1433,7 @@ uvc_ctrl_prune_entity(struct uvc_device *dev, struct uvc_entity *entity)
1378 struct usb_device_id id; 1433 struct usb_device_id id;
1379 u8 index; 1434 u8 index;
1380 } blacklist[] = { 1435 } blacklist[] = {
1436 { { USB_DEVICE(0x13d3, 0x509b) }, 9 }, /* Gain */
1381 { { USB_DEVICE(0x1c4f, 0x3000) }, 6 }, /* WB Temperature */ 1437 { { USB_DEVICE(0x1c4f, 0x3000) }, 6 }, /* WB Temperature */
1382 { { USB_DEVICE(0x5986, 0x0241) }, 2 }, /* Hue */ 1438 { { USB_DEVICE(0x5986, 0x0241) }, 2 }, /* Hue */
1383 }; 1439 };
diff --git a/drivers/media/video/uvc/uvc_driver.c b/drivers/media/video/uvc/uvc_driver.c
index 391cccca7ffc..a814820a3f6e 100644
--- a/drivers/media/video/uvc/uvc_driver.c
+++ b/drivers/media/video/uvc/uvc_driver.c
@@ -43,8 +43,9 @@
43#define DRIVER_VERSION "v0.1.0" 43#define DRIVER_VERSION "v0.1.0"
44#endif 44#endif
45 45
46unsigned int uvc_clock_param = CLOCK_MONOTONIC;
46unsigned int uvc_no_drop_param; 47unsigned int uvc_no_drop_param;
47static unsigned int uvc_quirks_param; 48static unsigned int uvc_quirks_param = -1;
48unsigned int uvc_trace_param; 49unsigned int uvc_trace_param;
49unsigned int uvc_timeout_param = UVC_CTRL_STREAMING_TIMEOUT; 50unsigned int uvc_timeout_param = UVC_CTRL_STREAMING_TIMEOUT;
50 51
@@ -59,6 +60,11 @@ static struct uvc_format_desc uvc_fmts[] = {
59 .fcc = V4L2_PIX_FMT_YUYV, 60 .fcc = V4L2_PIX_FMT_YUYV,
60 }, 61 },
61 { 62 {
63 .name = "YUV 4:2:2 (YUYV)",
64 .guid = UVC_GUID_FORMAT_YUY2_ISIGHT,
65 .fcc = V4L2_PIX_FMT_YUYV,
66 },
67 {
62 .name = "YUV 4:2:0 (NV12)", 68 .name = "YUV 4:2:0 (NV12)",
63 .guid = UVC_GUID_FORMAT_NV12, 69 .guid = UVC_GUID_FORMAT_NV12,
64 .fcc = V4L2_PIX_FMT_NV12, 70 .fcc = V4L2_PIX_FMT_NV12,
@@ -309,11 +315,10 @@ static int uvc_parse_format(struct uvc_device *dev,
309 sizeof format->name); 315 sizeof format->name);
310 format->fcc = fmtdesc->fcc; 316 format->fcc = fmtdesc->fcc;
311 } else { 317 } else {
312 uvc_printk(KERN_INFO, "Unknown video format " 318 uvc_printk(KERN_INFO, "Unknown video format %pUl\n",
313 UVC_GUID_FORMAT "\n", 319 &buffer[5]);
314 UVC_GUID_ARGS(&buffer[5])); 320 snprintf(format->name, sizeof(format->name), "%pUl\n",
315 snprintf(format->name, sizeof format->name, 321 &buffer[5]);
316 UVC_GUID_FORMAT, UVC_GUID_ARGS(&buffer[5]));
317 format->fcc = 0; 322 format->fcc = 0;
318 } 323 }
319 324
@@ -1750,7 +1755,8 @@ static int uvc_probe(struct usb_interface *intf,
1750 dev->udev = usb_get_dev(udev); 1755 dev->udev = usb_get_dev(udev);
1751 dev->intf = usb_get_intf(intf); 1756 dev->intf = usb_get_intf(intf);
1752 dev->intfnum = intf->cur_altsetting->desc.bInterfaceNumber; 1757 dev->intfnum = intf->cur_altsetting->desc.bInterfaceNumber;
1753 dev->quirks = id->driver_info | uvc_quirks_param; 1758 dev->quirks = (uvc_quirks_param == -1)
1759 ? id->driver_info : uvc_quirks_param;
1754 1760
1755 if (udev->product != NULL) 1761 if (udev->product != NULL)
1756 strlcpy(dev->name, udev->product, sizeof dev->name); 1762 strlcpy(dev->name, udev->product, sizeof dev->name);
@@ -1773,9 +1779,9 @@ static int uvc_probe(struct usb_interface *intf,
1773 le16_to_cpu(udev->descriptor.idVendor), 1779 le16_to_cpu(udev->descriptor.idVendor),
1774 le16_to_cpu(udev->descriptor.idProduct)); 1780 le16_to_cpu(udev->descriptor.idProduct));
1775 1781
1776 if (uvc_quirks_param != 0) { 1782 if (dev->quirks != id->driver_info) {
1777 uvc_printk(KERN_INFO, "Forcing device quirks 0x%x by module " 1783 uvc_printk(KERN_INFO, "Forcing device quirks to 0x%x by module "
1778 "parameter for testing purpose.\n", uvc_quirks_param); 1784 "parameter for testing purpose.\n", dev->quirks);
1779 uvc_printk(KERN_INFO, "Please report required quirks to the " 1785 uvc_printk(KERN_INFO, "Please report required quirks to the "
1780 "linux-uvc-devel mailing list.\n"); 1786 "linux-uvc-devel mailing list.\n");
1781 } 1787 }
@@ -1892,6 +1898,45 @@ static int uvc_reset_resume(struct usb_interface *intf)
1892} 1898}
1893 1899
1894/* ------------------------------------------------------------------------ 1900/* ------------------------------------------------------------------------
1901 * Module parameters
1902 */
1903
1904static int uvc_clock_param_get(char *buffer, struct kernel_param *kp)
1905{
1906 if (uvc_clock_param == CLOCK_MONOTONIC)
1907 return sprintf(buffer, "CLOCK_MONOTONIC");
1908 else
1909 return sprintf(buffer, "CLOCK_REALTIME");
1910}
1911
1912static int uvc_clock_param_set(const char *val, struct kernel_param *kp)
1913{
1914 if (strncasecmp(val, "clock_", strlen("clock_")) == 0)
1915 val += strlen("clock_");
1916
1917 if (strcasecmp(val, "monotonic") == 0)
1918 uvc_clock_param = CLOCK_MONOTONIC;
1919 else if (strcasecmp(val, "realtime") == 0)
1920 uvc_clock_param = CLOCK_REALTIME;
1921 else
1922 return -EINVAL;
1923
1924 return 0;
1925}
1926
1927module_param_call(clock, uvc_clock_param_set, uvc_clock_param_get,
1928 &uvc_clock_param, S_IRUGO|S_IWUSR);
1929MODULE_PARM_DESC(clock, "Video buffers timestamp clock");
1930module_param_named(nodrop, uvc_no_drop_param, uint, S_IRUGO|S_IWUSR);
1931MODULE_PARM_DESC(nodrop, "Don't drop incomplete frames");
1932module_param_named(quirks, uvc_quirks_param, uint, S_IRUGO|S_IWUSR);
1933MODULE_PARM_DESC(quirks, "Forced device quirks");
1934module_param_named(trace, uvc_trace_param, uint, S_IRUGO|S_IWUSR);
1935MODULE_PARM_DESC(trace, "Trace level bitmask");
1936module_param_named(timeout, uvc_timeout_param, uint, S_IRUGO|S_IWUSR);
1937MODULE_PARM_DESC(timeout, "Streaming control requests timeout");
1938
1939/* ------------------------------------------------------------------------
1895 * Driver initialization and cleanup 1940 * Driver initialization and cleanup
1896 */ 1941 */
1897 1942
@@ -2197,15 +2242,6 @@ static void __exit uvc_cleanup(void)
2197module_init(uvc_init); 2242module_init(uvc_init);
2198module_exit(uvc_cleanup); 2243module_exit(uvc_cleanup);
2199 2244
2200module_param_named(nodrop, uvc_no_drop_param, uint, S_IRUGO|S_IWUSR);
2201MODULE_PARM_DESC(nodrop, "Don't drop incomplete frames");
2202module_param_named(quirks, uvc_quirks_param, uint, S_IRUGO|S_IWUSR);
2203MODULE_PARM_DESC(quirks, "Forced device quirks");
2204module_param_named(trace, uvc_trace_param, uint, S_IRUGO|S_IWUSR);
2205MODULE_PARM_DESC(trace, "Trace level bitmask");
2206module_param_named(timeout, uvc_timeout_param, uint, S_IRUGO|S_IWUSR);
2207MODULE_PARM_DESC(timeout, "Streaming control requests timeout");
2208
2209MODULE_AUTHOR(DRIVER_AUTHOR); 2245MODULE_AUTHOR(DRIVER_AUTHOR);
2210MODULE_DESCRIPTION(DRIVER_DESC); 2246MODULE_DESCRIPTION(DRIVER_DESC);
2211MODULE_LICENSE("GPL"); 2247MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/uvc/uvc_queue.c b/drivers/media/video/uvc/uvc_queue.c
index ea11839cba4a..4a925a31b0e0 100644
--- a/drivers/media/video/uvc/uvc_queue.c
+++ b/drivers/media/video/uvc/uvc_queue.c
@@ -502,7 +502,6 @@ struct uvc_buffer *uvc_queue_next_buffer(struct uvc_video_queue *queue,
502 spin_unlock_irqrestore(&queue->irqlock, flags); 502 spin_unlock_irqrestore(&queue->irqlock, flags);
503 503
504 buf->buf.sequence = queue->sequence++; 504 buf->buf.sequence = queue->sequence++;
505 do_gettimeofday(&buf->buf.timestamp);
506 505
507 wake_up(&buf->wait); 506 wake_up(&buf->wait);
508 return nextbuf; 507 return nextbuf;
diff --git a/drivers/media/video/uvc/uvc_v4l2.c b/drivers/media/video/uvc/uvc_v4l2.c
index 23239a4adefe..43152aa52227 100644
--- a/drivers/media/video/uvc/uvc_v4l2.c
+++ b/drivers/media/video/uvc/uvc_v4l2.c
@@ -539,7 +539,7 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
539 xctrl.id = ctrl->id; 539 xctrl.id = ctrl->id;
540 xctrl.value = ctrl->value; 540 xctrl.value = ctrl->value;
541 541
542 uvc_ctrl_begin(chain); 542 ret = uvc_ctrl_begin(chain);
543 if (ret < 0) 543 if (ret < 0)
544 return ret; 544 return ret;
545 545
@@ -549,6 +549,8 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
549 return ret; 549 return ret;
550 } 550 }
551 ret = uvc_ctrl_commit(chain); 551 ret = uvc_ctrl_commit(chain);
552 if (ret == 0)
553 ctrl->value = xctrl.value;
552 break; 554 break;
553 } 555 }
554 556
diff --git a/drivers/media/video/uvc/uvc_video.c b/drivers/media/video/uvc/uvc_video.c
index 7dcf534a0cf3..6b0666be370f 100644
--- a/drivers/media/video/uvc/uvc_video.c
+++ b/drivers/media/video/uvc/uvc_video.c
@@ -410,6 +410,8 @@ static int uvc_video_decode_start(struct uvc_streaming *stream,
410 * when the EOF bit is set to force synchronisation on the next packet. 410 * when the EOF bit is set to force synchronisation on the next packet.
411 */ 411 */
412 if (buf->state != UVC_BUF_STATE_ACTIVE) { 412 if (buf->state != UVC_BUF_STATE_ACTIVE) {
413 struct timespec ts;
414
413 if (fid == stream->last_fid) { 415 if (fid == stream->last_fid) {
414 uvc_trace(UVC_TRACE_FRAME, "Dropping payload (out of " 416 uvc_trace(UVC_TRACE_FRAME, "Dropping payload (out of "
415 "sync).\n"); 417 "sync).\n");
@@ -419,6 +421,14 @@ static int uvc_video_decode_start(struct uvc_streaming *stream,
419 return -ENODATA; 421 return -ENODATA;
420 } 422 }
421 423
424 if (uvc_clock_param == CLOCK_MONOTONIC)
425 ktime_get_ts(&ts);
426 else
427 ktime_get_real_ts(&ts);
428
429 buf->buf.timestamp.tv_sec = ts.tv_sec;
430 buf->buf.timestamp.tv_usec = ts.tv_nsec / NSEC_PER_USEC;
431
422 /* TODO: Handle PTS and SCR. */ 432 /* TODO: Handle PTS and SCR. */
423 buf->state = UVC_BUF_STATE_ACTIVE; 433 buf->state = UVC_BUF_STATE_ACTIVE;
424 } 434 }
diff --git a/drivers/media/video/uvc/uvcvideo.h b/drivers/media/video/uvc/uvcvideo.h
index 2337585001ea..2bba059259e6 100644
--- a/drivers/media/video/uvc/uvcvideo.h
+++ b/drivers/media/video/uvc/uvcvideo.h
@@ -113,6 +113,9 @@ struct uvc_xu_control {
113#define UVC_GUID_FORMAT_YUY2 \ 113#define UVC_GUID_FORMAT_YUY2 \
114 { 'Y', 'U', 'Y', '2', 0x00, 0x00, 0x10, 0x00, \ 114 { 'Y', 'U', 'Y', '2', 0x00, 0x00, 0x10, 0x00, \
115 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71} 115 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
116#define UVC_GUID_FORMAT_YUY2_ISIGHT \
117 { 'Y', 'U', 'Y', '2', 0x00, 0x00, 0x10, 0x00, \
118 0x80, 0x00, 0x00, 0x00, 0x00, 0x38, 0x9b, 0x71}
116#define UVC_GUID_FORMAT_NV12 \ 119#define UVC_GUID_FORMAT_NV12 \
117 { 'N', 'V', '1', '2', 0x00, 0x00, 0x10, 0x00, \ 120 { 'N', 'V', '1', '2', 0x00, 0x00, 0x10, 0x00, \
118 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71} 121 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
@@ -149,7 +152,7 @@ struct uvc_xu_control {
149#define UVC_MAX_STATUS_SIZE 16 152#define UVC_MAX_STATUS_SIZE 16
150 153
151#define UVC_CTRL_CONTROL_TIMEOUT 300 154#define UVC_CTRL_CONTROL_TIMEOUT 300
152#define UVC_CTRL_STREAMING_TIMEOUT 3000 155#define UVC_CTRL_STREAMING_TIMEOUT 5000
153 156
154/* Devices quirks */ 157/* Devices quirks */
155#define UVC_QUIRK_STATUS_INTERVAL 0x00000001 158#define UVC_QUIRK_STATUS_INTERVAL 0x00000001
@@ -242,7 +245,8 @@ struct uvc_control {
242 uvc_control_info. */ 245 uvc_control_info. */
243 __u8 dirty : 1, 246 __u8 dirty : 1,
244 loaded : 1, 247 loaded : 1,
245 modified : 1; 248 modified : 1,
249 cached : 1;
246 250
247 __u8 *data; 251 __u8 *data;
248}; 252};
@@ -533,6 +537,7 @@ struct uvc_driver {
533#define UVC_WARN_MINMAX 0 537#define UVC_WARN_MINMAX 0
534#define UVC_WARN_PROBE_DEF 1 538#define UVC_WARN_PROBE_DEF 1
535 539
540extern unsigned int uvc_clock_param;
536extern unsigned int uvc_no_drop_param; 541extern unsigned int uvc_no_drop_param;
537extern unsigned int uvc_trace_param; 542extern unsigned int uvc_trace_param;
538extern unsigned int uvc_timeout_param; 543extern unsigned int uvc_timeout_param;
@@ -552,16 +557,6 @@ extern unsigned int uvc_timeout_param;
552#define uvc_printk(level, msg...) \ 557#define uvc_printk(level, msg...) \
553 printk(level "uvcvideo: " msg) 558 printk(level "uvcvideo: " msg)
554 559
555#define UVC_GUID_FORMAT "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-" \
556 "%02x%02x%02x%02x%02x%02x"
557#define UVC_GUID_ARGS(guid) \
558 (guid)[3], (guid)[2], (guid)[1], (guid)[0], \
559 (guid)[5], (guid)[4], \
560 (guid)[7], (guid)[6], \
561 (guid)[8], (guid)[9], \
562 (guid)[10], (guid)[11], (guid)[12], \
563 (guid)[13], (guid)[14], (guid)[15]
564
565/* -------------------------------------------------------------------------- 560/* --------------------------------------------------------------------------
566 * Internal functions. 561 * Internal functions.
567 */ 562 */
diff --git a/drivers/media/video/v4l2-compat-ioctl32.c b/drivers/media/video/v4l2-compat-ioctl32.c
index c4150bd26337..f77f84bfe714 100644
--- a/drivers/media/video/v4l2-compat-ioctl32.c
+++ b/drivers/media/video/v4l2-compat-ioctl32.c
@@ -288,7 +288,7 @@ static int get_v4l2_window32(struct v4l2_window *kp, struct v4l2_window32 __user
288 288
289static int put_v4l2_window32(struct v4l2_window *kp, struct v4l2_window32 __user *up) 289static int put_v4l2_window32(struct v4l2_window *kp, struct v4l2_window32 __user *up)
290{ 290{
291 if (copy_to_user(&up->w, &kp->w, sizeof(up->w)) || 291 if (copy_to_user(&up->w, &kp->w, sizeof(kp->w)) ||
292 put_user(kp->field, &up->field) || 292 put_user(kp->field, &up->field) ||
293 put_user(kp->chromakey, &up->chromakey) || 293 put_user(kp->chromakey, &up->chromakey) ||
294 put_user(kp->clipcount, &up->clipcount)) 294 put_user(kp->clipcount, &up->clipcount))
@@ -475,6 +475,9 @@ static int get_v4l2_buffer32(struct v4l2_buffer *kp, struct v4l2_buffer32 __user
475 return -EFAULT; 475 return -EFAULT;
476 switch (kp->memory) { 476 switch (kp->memory) {
477 case V4L2_MEMORY_MMAP: 477 case V4L2_MEMORY_MMAP:
478 if (get_user(kp->length, &up->length) ||
479 get_user(kp->m.offset, &up->m.offset))
480 return -EFAULT;
478 break; 481 break;
479 case V4L2_MEMORY_USERPTR: 482 case V4L2_MEMORY_USERPTR:
480 { 483 {
diff --git a/drivers/media/video/videobuf-dma-sg.c b/drivers/media/video/videobuf-dma-sg.c
index fa78555b118b..fcd045e7a1c1 100644
--- a/drivers/media/video/videobuf-dma-sg.c
+++ b/drivers/media/video/videobuf-dma-sg.c
@@ -418,6 +418,8 @@ static void *__videobuf_alloc(size_t size)
418 struct videobuf_buffer *vb; 418 struct videobuf_buffer *vb;
419 419
420 vb = kzalloc(size+sizeof(*mem),GFP_KERNEL); 420 vb = kzalloc(size+sizeof(*mem),GFP_KERNEL);
421 if (!vb)
422 return vb;
421 423
422 mem = vb->priv = ((char *)vb)+size; 424 mem = vb->priv = ((char *)vb)+size;
423 mem->magic=MAGIC_SG_MEM; 425 mem->magic=MAGIC_SG_MEM;
diff --git a/drivers/media/video/videobuf-vmalloc.c b/drivers/media/video/videobuf-vmalloc.c
index d6e6a28fb6b8..136e09383c06 100644
--- a/drivers/media/video/videobuf-vmalloc.c
+++ b/drivers/media/video/videobuf-vmalloc.c
@@ -138,6 +138,8 @@ static void *__videobuf_alloc(size_t size)
138 struct videobuf_buffer *vb; 138 struct videobuf_buffer *vb;
139 139
140 vb = kzalloc(size+sizeof(*mem),GFP_KERNEL); 140 vb = kzalloc(size+sizeof(*mem),GFP_KERNEL);
141 if (!vb)
142 return vb;
141 143
142 mem = vb->priv = ((char *)vb)+size; 144 mem = vb->priv = ((char *)vb)+size;
143 mem->magic=MAGIC_VMAL_MEM; 145 mem->magic=MAGIC_VMAL_MEM;
diff --git a/drivers/media/video/vivi.c b/drivers/media/video/vivi.c
index 37632a064966..cdbe70385c12 100644
--- a/drivers/media/video/vivi.c
+++ b/drivers/media/video/vivi.c
@@ -1371,7 +1371,7 @@ static int __init vivi_create_instance(int inst)
1371 /* Now that everything is fine, let's add it to device list */ 1371 /* Now that everything is fine, let's add it to device list */
1372 list_add_tail(&dev->vivi_devlist, &vivi_devlist); 1372 list_add_tail(&dev->vivi_devlist, &vivi_devlist);
1373 1373
1374 if (video_nr >= 0) 1374 if (video_nr != -1)
1375 video_nr++; 1375 video_nr++;
1376 1376
1377 dev->vfd = vfd; 1377 dev->vfd = vfd;
diff --git a/drivers/media/video/zc0301/Kconfig b/drivers/media/video/zc0301/Kconfig
index edb00293cd59..a7e610e0be9e 100644
--- a/drivers/media/video/zc0301/Kconfig
+++ b/drivers/media/video/zc0301/Kconfig
@@ -1,7 +1,11 @@
1config USB_ZC0301 1config USB_ZC0301
2 tristate "USB ZC0301[P] Image Processor and Control Chip support" 2 tristate "USB ZC0301[P] webcam support (DEPRECATED)"
3 depends on VIDEO_V4L2 3 depends on VIDEO_V4L2
4 default n
4 ---help--- 5 ---help---
6 This driver is DEPRECATED please use the gspca zc3xx module
7 instead.
8
5 Say Y here if you want support for cameras based on the ZC0301 or 9 Say Y here if you want support for cameras based on the ZC0301 or
6 ZC0301P Image Processors and Control Chips. 10 ZC0301P Image Processors and Control Chips.
7 11
diff --git a/drivers/media/video/zoran/zoran_device.c b/drivers/media/video/zoran/zoran_device.c
index f6c2fb4fc3b4..e6ad4b205611 100644
--- a/drivers/media/video/zoran/zoran_device.c
+++ b/drivers/media/video/zoran/zoran_device.c
@@ -1196,7 +1196,8 @@ zoran_reap_stat_com (struct zoran *zr)
1196static void zoran_restart(struct zoran *zr) 1196static void zoran_restart(struct zoran *zr)
1197{ 1197{
1198 /* Now the stat_comm buffer is ready for restart */ 1198 /* Now the stat_comm buffer is ready for restart */
1199 int status = 0, mode; 1199 unsigned int status = 0;
1200 int mode;
1200 1201
1201 if (zr->codec_mode == BUZ_MODE_MOTION_COMPRESS) { 1202 if (zr->codec_mode == BUZ_MODE_MOTION_COMPRESS) {
1202 decoder_call(zr, video, g_input_status, &status); 1203 decoder_call(zr, video, g_input_status, &status);
@@ -1228,7 +1229,7 @@ error_handler (struct zoran *zr,
1228 u32 astat, 1229 u32 astat,
1229 u32 stat) 1230 u32 stat)
1230{ 1231{
1231 int i, j; 1232 int i;
1232 1233
1233 /* This is JPEG error handling part */ 1234 /* This is JPEG error handling part */
1234 if (zr->codec_mode != BUZ_MODE_MOTION_COMPRESS && 1235 if (zr->codec_mode != BUZ_MODE_MOTION_COMPRESS &&
@@ -1279,6 +1280,7 @@ error_handler (struct zoran *zr,
1279 /* Report error */ 1280 /* Report error */
1280 if (zr36067_debug > 1 && zr->num_errors <= 8) { 1281 if (zr36067_debug > 1 && zr->num_errors <= 8) {
1281 long frame; 1282 long frame;
1283 int j;
1282 1284
1283 frame = zr->jpg_pend[zr->jpg_dma_tail & BUZ_MASK_FRAME]; 1285 frame = zr->jpg_pend[zr->jpg_dma_tail & BUZ_MASK_FRAME];
1284 printk(KERN_ERR 1286 printk(KERN_ERR
diff --git a/drivers/media/video/zoran/zoran_driver.c b/drivers/media/video/zoran/zoran_driver.c
index 2ddffed019ee..ec41303544e5 100644
--- a/drivers/media/video/zoran/zoran_driver.c
+++ b/drivers/media/video/zoran/zoran_driver.c
@@ -324,7 +324,7 @@ static int jpg_fbuffer_alloc(struct zoran_fh *fh)
324 /* Allocate fragment table for this buffer */ 324 /* Allocate fragment table for this buffer */
325 325
326 mem = (void *)get_zeroed_page(GFP_KERNEL); 326 mem = (void *)get_zeroed_page(GFP_KERNEL);
327 if (mem == 0) { 327 if (!mem) {
328 dprintk(1, 328 dprintk(1,
329 KERN_ERR 329 KERN_ERR
330 "%s: %s - get_zeroed_page (frag_tab) failed for buffer %d\n", 330 "%s: %s - get_zeroed_page (frag_tab) failed for buffer %d\n",
@@ -1444,7 +1444,7 @@ zoran_set_norm (struct zoran *zr,
1444 } 1444 }
1445 1445
1446 if (norm == V4L2_STD_ALL) { 1446 if (norm == V4L2_STD_ALL) {
1447 int status = 0; 1447 unsigned int status = 0;
1448 v4l2_std_id std = 0; 1448 v4l2_std_id std = 0;
1449 1449
1450 decoder_call(zr, video, querystd, &std); 1450 decoder_call(zr, video, querystd, &std);
diff --git a/drivers/media/video/zr364xx.c b/drivers/media/video/zr364xx.c
index f0eae83e3d89..3d4bac252902 100644
--- a/drivers/media/video/zr364xx.c
+++ b/drivers/media/video/zr364xx.c
@@ -78,6 +78,7 @@
78#define METHOD0 0 78#define METHOD0 0
79#define METHOD1 1 79#define METHOD1 1
80#define METHOD2 2 80#define METHOD2 2
81#define METHOD3 3
81 82
82 83
83/* Module parameters */ 84/* Module parameters */
@@ -114,7 +115,7 @@ static struct usb_device_id device_table[] = {
114 {USB_DEVICE(0x06d6, 0x003b), .driver_info = METHOD0 }, 115 {USB_DEVICE(0x06d6, 0x003b), .driver_info = METHOD0 },
115 {USB_DEVICE(0x0a17, 0x004e), .driver_info = METHOD2 }, 116 {USB_DEVICE(0x0a17, 0x004e), .driver_info = METHOD2 },
116 {USB_DEVICE(0x041e, 0x405d), .driver_info = METHOD2 }, 117 {USB_DEVICE(0x041e, 0x405d), .driver_info = METHOD2 },
117 {USB_DEVICE(0x08ca, 0x2102), .driver_info = METHOD2 }, 118 {USB_DEVICE(0x08ca, 0x2102), .driver_info = METHOD3 },
118 {USB_DEVICE(0x06d6, 0x003d), .driver_info = METHOD0 }, 119 {USB_DEVICE(0x06d6, 0x003d), .driver_info = METHOD0 },
119 {} /* Terminating entry */ 120 {} /* Terminating entry */
120}; 121};
@@ -302,7 +303,7 @@ static message m2[] = {
302}; 303};
303 304
304/* init table */ 305/* init table */
305static message *init[3] = { m0, m1, m2 }; 306static message *init[4] = { m0, m1, m2, m2 };
306 307
307 308
308/* JPEG static data in header (Huffman table, etc) */ 309/* JPEG static data in header (Huffman table, etc) */
@@ -967,6 +968,22 @@ static int zr364xx_vidioc_s_fmt_vid_cap(struct file *file, void *priv,
967 m0d1[0] = mode; 968 m0d1[0] = mode;
968 m1[2].value = 0xf000 + mode; 969 m1[2].value = 0xf000 + mode;
969 m2[1].value = 0xf000 + mode; 970 m2[1].value = 0xf000 + mode;
971
972 /* special case for METHOD3, the modes are different */
973 if (cam->method == METHOD3) {
974 switch (mode) {
975 case 1:
976 m2[1].value = 0xf000 + 4;
977 break;
978 case 2:
979 m2[1].value = 0xf000 + 0;
980 break;
981 default:
982 m2[1].value = 0xf000 + 1;
983 break;
984 }
985 }
986
970 header2[437] = cam->height / 256; 987 header2[437] = cam->height / 256;
971 header2[438] = cam->height % 256; 988 header2[438] = cam->height % 256;
972 header2[439] = cam->width / 256; 989 header2[439] = cam->width / 256;
@@ -1582,6 +1599,22 @@ static int zr364xx_probe(struct usb_interface *intf,
1582 m0d1[0] = mode; 1599 m0d1[0] = mode;
1583 m1[2].value = 0xf000 + mode; 1600 m1[2].value = 0xf000 + mode;
1584 m2[1].value = 0xf000 + mode; 1601 m2[1].value = 0xf000 + mode;
1602
1603 /* special case for METHOD3, the modes are different */
1604 if (cam->method == METHOD3) {
1605 switch (mode) {
1606 case 1:
1607 m2[1].value = 0xf000 + 4;
1608 break;
1609 case 2:
1610 m2[1].value = 0xf000 + 0;
1611 break;
1612 default:
1613 m2[1].value = 0xf000 + 1;
1614 break;
1615 }
1616 }
1617
1585 header2[437] = cam->height / 256; 1618 header2[437] = cam->height / 256;
1586 header2[438] = cam->height % 256; 1619 header2[438] = cam->height % 256;
1587 header2[439] = cam->width / 256; 1620 header2[439] = cam->width / 256;